* elflink.c (_bfd_elf_gc_mark_rsec): Mark weakdef syms too.
authorAlan Modra <amodra@gmail.com>
Wed, 8 Feb 2012 10:12:20 +0000 (10:12 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 8 Feb 2012 10:12:20 +0000 (10:12 +0000)
(_bfd_elf_fix_symbol_flags): When a weakdef is def_regular, clear
the correct h->u.weakdef.

bfd/ChangeLog
bfd/elflink.c

index 6d56dd4eeedeae6c26d778766aa80de52ae5fb80..4b896f2ab10b0f47e17914ff526678fe06bf95d8 100644 (file)
@@ -1,3 +1,9 @@
+2012-02-08  Alan Modra  <amodra@gmail.com>
+
+       * elflink.c (_bfd_elf_gc_mark_rsec): Mark weakdef syms too.
+       (_bfd_elf_fix_symbol_flags): When a weakdef is def_regular, clear
+       the correct h->u.weakdef.
+
 2012-02-07  Alan Modra  <amodra@gmail.com>
 
        * elf.c (elf_find_function): Don't use internal_elf_sym.
index 1d1ca0bce44987d3383ea7e0188cc85719a4a1ef..7f9ec609b53276217550d2bddf98f8f00c77e707 100644 (file)
@@ -2510,23 +2510,21 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
      over to the real definition.  */
   if (h->u.weakdef != NULL)
     {
-      struct elf_link_hash_entry *weakdef;
-
-      weakdef = h->u.weakdef;
-      while (h->root.type == bfd_link_hash_indirect)
-       h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
-      BFD_ASSERT (h->root.type == bfd_link_hash_defined
-                 || h->root.type == bfd_link_hash_defweak);
-      BFD_ASSERT (weakdef->def_dynamic);
-
       /* If the real definition is defined by a regular object file,
         don't do anything special.  See the longer description in
         _bfd_elf_adjust_dynamic_symbol, below.  */
-      if (weakdef->def_regular)
+      if (h->u.weakdef->def_regular)
        h->u.weakdef = NULL;
       else
        {
+         struct elf_link_hash_entry *weakdef = h->u.weakdef;
+
+         while (h->root.type == bfd_link_hash_indirect)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+         BFD_ASSERT (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak);
+         BFD_ASSERT (weakdef->def_dynamic);
          BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
                      || weakdef->root.type == bfd_link_hash_defweak);
          (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
@@ -11575,6 +11573,12 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
             || h->root.type == bfd_link_hash_warning)
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
       h->mark = 1;
+      /* If this symbol is weak and there is a non-weak definition, we
+        keep the non-weak definition because many backends put
+        dynamic reloc info on the non-weak definition for code
+        handling copy relocs.  */
+      if (h->u.weakdef != NULL)
+       h->u.weakdef->mark = 1;
       return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
     }