PR ld/12762
authorAlan Modra <amodra@gmail.com>
Fri, 5 Aug 2011 03:17:12 +0000 (03:17 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 5 Aug 2011 03:17:12 +0000 (03:17 +0000)
bfd/
* elflink.c (_bfd_elf_section_already_linked): Return matched
status.  Remove COFF comdat section handling.
* linker.c (_bfd_generic_section_already_linked): Return matched
status.  Don't set SEC_GROUP in l_flags for plugin entries.
(bfd_section_already_linked): Update prototype.
* targets.c (_section_already_linked): Likewise.
* elf-bfd.h (_bfd_elf_section_already_linked): Likewise.
* libbfd-in.h (_bfd_generic_section_already_linked): Likewise.
(_bfd_nolink_section_already_linked): Update.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
ld/
* plugin.c (add_symbols): Exclude comdat_key symbols from symbol
table if already seen.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf-bfd.h
bfd/elflink.c
bfd/libbfd-in.h
bfd/libbfd.h
bfd/linker.c
bfd/targets.c
ld/ChangeLog
ld/plugin.c

index f6ccd5452d65b6b2846acb970d3063541a4b8996..82defd9ff126aee04f054d19db4f20addf01b88c 100644 (file)
@@ -1,3 +1,18 @@
+2011-08-05  Alan Modra  <amodra@gmail.com>
+
+       PR ld/12762
+       * elflink.c (_bfd_elf_section_already_linked): Return matched
+       status.  Remove COFF comdat section handling.
+       * linker.c (_bfd_generic_section_already_linked): Return matched
+       status.  Don't set SEC_GROUP in l_flags for plugin entries.
+       (bfd_section_already_linked): Update prototype.
+       * targets.c (_section_already_linked): Likewise.
+       * elf-bfd.h (_bfd_elf_section_already_linked): Likewise.
+       * libbfd-in.h (_bfd_generic_section_already_linked): Likewise.
+       (_bfd_nolink_section_already_linked): Update.
+       * libbfd.h: Regenerate.
+       * bfd-in2.h: Regenerate.
+
 2011-08-05  Alan Modra  <amodra@gmail.com>
 
        * elf32-ppc.c: Include dwarf2.h.
index ac8145d77664c6c24dc9d2c85cb5f7c7e9f67fe8..af13ca4adaf34206ece293de0ace9cab67f875c1 100644 (file)
@@ -6107,8 +6107,8 @@ typedef struct bfd_target
 
   /* Check if SEC has been already linked during a reloceatable or
      final link.  */
-  void (*_section_already_linked) (bfd *, struct already_linked *,
-                                   struct bfd_link_info *);
+  bfd_boolean (*_section_already_linked) (bfd *, struct already_linked *,
+                                          struct bfd_link_info *);
 
   /* Define a common symbol.  */
   bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
@@ -6177,7 +6177,7 @@ bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
 #define bfd_link_split_section(abfd, sec) \
        BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
 
-void bfd_section_already_linked (bfd *abfd,
+bfd_boolean bfd_section_already_linked (bfd *abfd,
     struct already_linked *data,
     struct bfd_link_info *info);
 
index e6ea5805efd03cf7397ba07ed6595c9485b9e64e..2c80f67be77ff1fcfe40902843cecb987cad9899 100644 (file)
@@ -1802,7 +1802,7 @@ extern bfd_boolean _bfd_elf_match_sections_by_type
 extern bfd_boolean bfd_elf_is_group_section
   (bfd *, const struct bfd_section *);
 struct already_linked;
-extern void _bfd_elf_section_already_linked
+extern bfd_boolean _bfd_elf_section_already_linked
   (bfd *, struct already_linked *, struct bfd_link_info *);
 extern void bfd_elf_set_group_contents
   (bfd *, asection *, void *);
index 2e592f5e0f7f40ccab9802b91e76f82418036c97..53765b626df330cb707f08ce8a33a8c025038863 100644 (file)
@@ -12515,7 +12515,7 @@ section_signature (asection *sec)
   return sec->name;
 }
 
-void
+bfd_boolean
 _bfd_elf_section_already_linked (bfd *abfd,
                                 struct already_linked *linked,
                                 struct bfd_link_info *info)
@@ -12525,6 +12525,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
   struct bfd_section_already_linked *l;
   struct bfd_section_already_linked_hash_entry *already_linked_list;
   asection *sec, *l_sec;
+  bfd_boolean matched;
 
   p = name = linked->comdat_key;
   if (name)
@@ -12536,20 +12537,20 @@ _bfd_elf_section_already_linked (bfd *abfd,
     {
       sec = linked->u.sec;
       if (sec->output_section == bfd_abs_section_ptr)
-       return;
+       return FALSE;
 
       flags = sec->flags;
 
       /* Return if it isn't a linkonce section.  A comdat group section
         also has SEC_LINK_ONCE set.  */
       if ((flags & SEC_LINK_ONCE) == 0)
-       return;
+       return FALSE;
 
       /* Don't put group member sections on our list of already linked
         sections.  They are handled as a group via their group section.
         */
       if (elf_sec_group (sec) != NULL)
-       return;
+       return FALSE;
 
       /* FIXME: When doing a relocatable link, we may have trouble
         copying relocations in other sections that refer to local symbols
@@ -12582,7 +12583,6 @@ _bfd_elf_section_already_linked (bfd *abfd,
 
   for (l = already_linked_list->entry; l != NULL; l = l->next)
     {
-      bfd_boolean l_coff_comdat_sec;
       flagword l_flags;
       bfd *l_owner;
       const char *l_name = l->linked.comdat_key;
@@ -12593,23 +12593,19 @@ _bfd_elf_section_already_linked (bfd *abfd,
          l_flags = (SEC_GROUP
                     | SEC_LINK_ONCE
                     | SEC_LINK_DUPLICATES_DISCARD);
-         l_coff_comdat_sec = FALSE;
        }
       else
        {
          l_sec = l->linked.u.sec;
          l_owner = l_sec->owner;
          l_flags = l_sec->flags;
-         l_coff_comdat_sec
-           = !!bfd_coff_get_comdat_section (l_sec->owner, l_sec);
          l_name = section_signature (l_sec);
        }
 
       /* We may have 2 different types of sections on the list: group
         sections and linkonce sections.  Match like sections.  */
       if ((flags & SEC_GROUP) == (l_flags & SEC_GROUP)
-         && strcmp (name, l_name) == 0
-         && !l_coff_comdat_sec)
+         && strcmp (name, l_name) == 0)
        {
          /* The section has already been linked.  See if we should
             issue a warning.  */
@@ -12629,7 +12625,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
                  && (l_owner->flags & BFD_PLUGIN) != 0)
                {
                  l->linked = *linked;
-                 return;
+                 return FALSE;
                }
              break;
 
@@ -12711,10 +12707,11 @@ _bfd_elf_section_already_linked (bfd *abfd,
                }
            }
 
-         return;
+         return TRUE;
        }
     }
 
+  matched = FALSE;
   if (sec)
     {
       /* A single member comdat group section may be discarded by a
@@ -12742,6 +12739,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
                        first->output_section = bfd_abs_section_ptr;
                        first->kept_section = l_sec;
                        sec->output_section = bfd_abs_section_ptr;
+                       matched = TRUE;
                        break;
                      }
                  }
@@ -12767,6 +12765,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
                      {
                        sec->output_section = bfd_abs_section_ptr;
                        sec->kept_section = first;
+                       matched = TRUE;
                        break;
                      }
                  }
@@ -12799,7 +12798,10 @@ _bfd_elf_section_already_linked (bfd *abfd,
                    && CONST_STRNEQ (l_sec->name, ".gnu.linkonce.t."))
                  {
                    if (abfd != l_sec->owner)
-                     sec->output_section = bfd_abs_section_ptr;
+                     {
+                       sec->output_section = bfd_abs_section_ptr;
+                       matched = TRUE;
+                     }
                    break;
                  }
              }
@@ -12810,6 +12812,7 @@ _bfd_elf_section_already_linked (bfd *abfd,
   if (! bfd_section_already_linked_table_insert (already_linked_list,
                                                 linked))
     info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+  return matched;
 }
 
 bfd_boolean
index 0c98b47cbc58d13d77bec33445fc32a70b41727c..db39f3cfc65e03bd4f7378e6908cba52fc1720d6 100644 (file)
@@ -481,8 +481,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
 #define _bfd_nolink_bfd_link_split_section \
   ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
 #define _bfd_nolink_section_already_linked \
-  ((void (*) (bfd *, struct already_linked*, \
-             struct bfd_link_info *)) bfd_void)
+  ((bfd_boolean (*) (bfd *, struct already_linked*, \
+                    struct bfd_link_info *)) bfd_false)
 #define _bfd_nolink_bfd_define_common_symbol \
   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, \
                     struct bfd_link_hash_entry *)) bfd_false)
@@ -602,7 +602,7 @@ extern bfd_boolean _bfd_generic_final_link
 extern bfd_boolean _bfd_generic_link_split_section
   (bfd *, struct bfd_section *);
 
-extern void _bfd_generic_section_already_linked
+extern bfd_boolean _bfd_generic_section_already_linked
   (bfd *, struct already_linked *, struct bfd_link_info *);
 
 /* Generic reloc_link_order processing routine.  */
index 33069b0d0c57b04a96c1a7779000d78083780fdb..71188dcc1e938e31cace3ae73f02e912f8ee3f0d 100644 (file)
@@ -486,8 +486,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
 #define _bfd_nolink_bfd_link_split_section \
   ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
 #define _bfd_nolink_section_already_linked \
-  ((void (*) (bfd *, struct already_linked*, \
-             struct bfd_link_info *)) bfd_void)
+  ((bfd_boolean (*) (bfd *, struct already_linked*, \
+                    struct bfd_link_info *)) bfd_false)
 #define _bfd_nolink_bfd_define_common_symbol \
   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, \
                     struct bfd_link_hash_entry *)) bfd_false)
@@ -607,7 +607,7 @@ extern bfd_boolean _bfd_generic_final_link
 extern bfd_boolean _bfd_generic_link_split_section
   (bfd *, struct bfd_section *);
 
-extern void _bfd_generic_section_already_linked
+extern bfd_boolean _bfd_generic_section_already_linked
   (bfd *, struct already_linked *, struct bfd_link_info *);
 
 /* Generic reloc_link_order processing routine.  */
index 8700c05a5908558fb6636f35989dfb1dcea0f560..b3ccefd6e1100c33082b4b5489077f0e7690d123 100644 (file)
@@ -2888,13 +2888,13 @@ FUNCTION
        bfd_section_already_linked
 
 SYNOPSIS
-        void bfd_section_already_linked (bfd *abfd,
-                                        struct already_linked *data,
-                                        struct bfd_link_info *info);
+        bfd_boolean bfd_section_already_linked (bfd *abfd,
+                                               struct already_linked *data,
+                                               struct bfd_link_info *info);
 
 DESCRIPTION
        Check if @var{data} has been already linked during a reloceatable
-       or final link.
+       or final link.  Return TRUE if it has.
 
 .#define bfd_section_already_linked(abfd, data, info) \
 .       BFD_SEND (abfd, _section_already_linked, (abfd, data, info))
@@ -2990,7 +2990,7 @@ bfd_section_already_linked_table_free (void)
 
 /* This is used on non-ELF inputs.  */
 
-void
+bfd_boolean
 _bfd_generic_section_already_linked (bfd *abfd,
                                     struct already_linked *linked,
                                     struct bfd_link_info *info)
@@ -3006,7 +3006,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
   if (name)
     {
       sec = NULL;
-      flags = SEC_GROUP | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+      flags = SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
       s_comdat = NULL;
     }
   else
@@ -3014,7 +3014,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
       sec = linked->u.sec;
       flags = sec->flags;
       if ((flags & SEC_LINK_ONCE) == 0)
-       return;
+       return FALSE;
 
       s_comdat = bfd_coff_get_comdat_section (abfd, sec);
 
@@ -3049,9 +3049,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
          l_sec = NULL;
          l_owner = l->linked.u.abfd;
          l_comdat = NULL;
-         l_flags = (SEC_GROUP
-                    | SEC_LINK_ONCE
-                    | SEC_LINK_DUPLICATES_DISCARD);
+         l_flags = SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
        }
       else
        {
@@ -3100,7 +3098,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
                  && (l_owner->flags & BFD_PLUGIN) != 0)
                {
                  l->linked = *linked;
-                 return;
+                 return FALSE;
                }
              break;
 
@@ -3136,7 +3134,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
              sec->kept_section = l_sec;
            }
 
-         return;
+         return TRUE;
        }
     }
 
@@ -3144,6 +3142,7 @@ _bfd_generic_section_already_linked (bfd *abfd,
   if (! bfd_section_already_linked_table_insert (already_linked_list,
                                                 linked))
     info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
+  return FALSE;
 }
 
 /* Convert symbols in excluded output sections to use a kept section.  */
index c34ce69072af09ebb2a3c27985763fdf14493fef..3dfa145b458bbbba8f186f3fe8dff645eefef8be 100644 (file)
@@ -512,8 +512,8 @@ BFD_JUMP_TABLE macros.
 .
 .  {* Check if SEC has been already linked during a reloceatable or
 .     final link.  *}
-.  void (*_section_already_linked) (bfd *, struct already_linked *,
-.                                  struct bfd_link_info *);
+.  bfd_boolean (*_section_already_linked) (bfd *, struct already_linked *,
+.                                         struct bfd_link_info *);
 .
 .  {* Define a common symbol.  *}
 .  bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *,
index 2b217b5532113faa90dc047030d30b6c03acb2c6..bb23c7a65eb8ad12a91a360d9ad02b3b8b8f4b3c 100644 (file)
@@ -1,3 +1,9 @@
+2011-08-05  Alan Modra  <amodra@gmail.com>
+
+       PR ld/12762
+       * plugin.c (add_symbols): Exclude comdat_key symbols from symbol
+       table if already seen.
+
 2011-08-04  H.J. Lu  <hongjiu.lu@intel.com>
 
        * ldmain.c (main): Replace remove_output with ld_cleanup in
index 0a0ee0c0d386bd594aaafac4817d29eda7e70d3a..5ba1fca845a62394e6b00b9b664981a66f0d756e 100644 (file)
@@ -380,10 +380,11 @@ add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
 {
   asymbol **symptrs;
   bfd *abfd = handle;
-  int n;
+  int n, k;
+
   ASSERT (called_plugin);
   symptrs = xmalloc (nsyms * sizeof *symptrs);
-  for (n = 0; n < nsyms; n++)
+  for (n = 0, k = 0; n < nsyms; n++)
     {
       enum ld_plugin_status rv;
       asymbol *bfdsym;
@@ -393,15 +394,16 @@ add_symbols (void *handle, int nsyms, const struct ld_plugin_symbol *syms)
          struct already_linked linked;
          linked.comdat_key = xstrdup (syms[n].comdat_key);
          linked.u.abfd = abfd;
-         bfd_section_already_linked (abfd, &linked, &link_info);
+         if (bfd_section_already_linked (abfd, &linked, &link_info))
+           continue;
        }
       bfdsym = bfd_make_empty_symbol (abfd);
-      symptrs[n] = bfdsym;
+      symptrs[k++] = bfdsym;
       rv = asymbol_from_plugin_symbol (abfd, bfdsym, syms + n);
       if (rv != LDPS_OK)
        return rv;
     }
-  bfd_set_symtab (abfd, symptrs, nsyms);
+  bfd_set_symtab (abfd, symptrs, k);
   return LDPS_OK;
 }