* elflink.c (struct already_linked_section): Removed.
authorJakub Jelinek <jakub@redhat.com>
Fri, 15 Oct 2004 05:19:19 +0000 (05:19 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 15 Oct 2004 05:19:19 +0000 (05:19 +0000)
(try_match_symbols_in_sections, already_linked): Removed.
(_bfd_elf_section_already_linked): Skip ^\.gnu\.linkonce\.[^.]*\.
prefix of section names when finding already_linked_table
chain.  Compare section names.  Instead of calling already_linked,
do it inline and only for sections in the same already_linked_list.

bfd/ChangeLog
bfd/elflink.c

index 06c75bea7b29503faf12c0511e1acb63fe5dbc70..c7572056f6dbd43194687f048f0399cf7b3f7ceb 100644 (file)
@@ -1,3 +1,12 @@
+2004-10-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * elflink.c (struct already_linked_section): Removed.
+       (try_match_symbols_in_sections, already_linked): Removed.
+       (_bfd_elf_section_already_linked): Skip ^\.gnu\.linkonce\.[^.]*\.
+       prefix of section names when finding already_linked_table
+       chain.  Compare section names.  Instead of calling already_linked,
+       do it inline and only for sections in the same already_linked_list.
+
 2004-10-15  Alan Modra  <amodra@bigpond.net.au>
 
        * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info"
index 0687eca16dfbffee64cafb2eff20a0ffdb422b3d..75b8c9699b6501719aa5679395df36927a76776a 100644 (file)
@@ -9268,88 +9268,11 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
   return ret;
 }
 
-struct already_linked_section
-{
-  asection *sec;
-  asection *linked;
-};
-
-/* Check if the member of a single member comdat group matches a
-   linkonce section and vice versa.  */
-static bfd_boolean
-try_match_symbols_in_sections
-  (struct bfd_section_already_linked_hash_entry *h, void *info)
-{
-  struct bfd_section_already_linked *l;
-  struct already_linked_section *s
-    = (struct already_linked_section *) info;
-
-  if (elf_sec_group (s->sec) == NULL)
-    {
-      /* It is a linkonce section. Try to match it with the member of a
-        single member comdat group. */
-      for (l = h->entry; l != NULL; l = l->next)
-       if ((l->sec->flags & SEC_GROUP))
-         {
-           asection *first = elf_next_in_group (l->sec);
-
-           if (first != NULL
-               && elf_next_in_group (first) == first
-               && bfd_elf_match_symbols_in_sections (first, s->sec))
-             {
-               s->linked = first;
-               return FALSE;
-             }
-         }
-    }
-  else
-    {
-      /* It is the member of a single member comdat group. Try to match
-        it with a linkonce section.  */
-      for (l = h->entry; l != NULL; l = l->next)
-       if ((l->sec->flags & SEC_GROUP) == 0
-           && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL
-           && bfd_elf_match_symbols_in_sections (l->sec, s->sec))
-         {
-           s->linked = l->sec;
-           return FALSE;
-         }
-    }
-
-  return TRUE;
-}
-
-static bfd_boolean
-already_linked (asection *sec, asection *group)
-{
-  struct already_linked_section result;
-
-  result.sec = sec;
-  result.linked = NULL;
-
-  bfd_section_already_linked_table_traverse
-    (try_match_symbols_in_sections, &result);
-
-  if (result.linked)
-    {
-      sec->output_section = bfd_abs_section_ptr;
-      sec->kept_section = result.linked;
-
-      /* Also discard the group section.  */
-      if (group)
-       group->output_section = bfd_abs_section_ptr;
-
-      return TRUE;
-    }
-
-  return FALSE;
-}
-
 void
 _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
 {
   flagword flags;
-  const char *name;
+  const char *name, *p;
   struct bfd_section_already_linked *l;
   struct bfd_section_already_linked_hash_entry *already_linked_list;
   asection *group;
@@ -9399,7 +9322,13 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
 
   name = bfd_get_section_name (abfd, sec);
 
-  already_linked_list = bfd_section_already_linked_table_lookup (name);
+  if (strncmp (name, ".gnu.linkonce.", sizeof (".gnu.linkonce.") - 1) == 0
+      && (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
+    p++;
+  else
+    p = name;
+
+  already_linked_list = bfd_section_already_linked_table_lookup (p);
 
   for (l = already_linked_list->entry; l != NULL; l = l->next)
     {
@@ -9409,10 +9338,11 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
         a linkonce section with a linkonce section, and ignore comdat
         section.  */
       if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
+         && strcmp (name, l->sec->name) == 0
          && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
        {
          /* The section has already been linked.  See if we should
-             issue a warning.  */
+            issue a warning.  */
          switch (flags & SEC_LINK_DUPLICATES)
            {
            default:
@@ -9501,15 +9431,39 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
         section. We only record the discarded comdat group. Otherwise
         the undiscarded group will be discarded incorrectly later since
         itself has been recorded.  */
-      if (! already_linked (elf_next_in_group (sec), group))
+      for (l = already_linked_list->entry; l != NULL; l = l->next)
+       if ((l->sec->flags & SEC_GROUP) == 0
+           && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL
+           && bfd_elf_match_symbols_in_sections (l->sec,
+                                                 elf_next_in_group (sec)))
+         {
+           elf_next_in_group (sec)->output_section = bfd_abs_section_ptr;
+           elf_next_in_group (sec)->kept_section = l->sec;
+           group->output_section = bfd_abs_section_ptr;
+           break;
+         }
+      if (l == NULL)
        return;
     }
   else
     /* There is no direct match. But for linkonce section, we should
        check if there is a match with comdat group member. We always
        record the linkonce section, discarded or not.  */
-    already_linked (sec, group);
-  
+    for (l = already_linked_list->entry; l != NULL; l = l->next)
+      if (l->sec->flags & SEC_GROUP)
+       {
+         asection *first = elf_next_in_group (l->sec);
+
+         if (first != NULL
+             && elf_next_in_group (first) == first
+             && bfd_elf_match_symbols_in_sections (first, sec))
+           {
+             sec->output_section = bfd_abs_section_ptr;
+             sec->kept_section = l->sec;
+             break;
+           }
+       }
+
   /* This is the first section with this name.  Record it.  */
   bfd_section_already_linked_table_insert (already_linked_list, sec);
 }