Fix -gc-sections related abort

Alan Modra amodra@gmail.com
Wed Feb 8 10:12:00 GMT 2012


The _bfd_elf_gc_mark_rsec change here fixes
https://bugzilla.redhat.com/show_bug.cgi?id=788231, an abort in
ppc64_elf_relocate_section because the ppc64 backend checks that no
more than the allocated number of dynamic relocs are emitted.  If we
don't mark the weakdef we'll lose it, and any relocs on it, which is
why the reloc accounting went wrong.  I think this bug would affect
other backends too, but most don't bother checking properly for
under-allocation.

This patch also fixes a bug in _bfd_elf_fix_symbol_flags, introduced
nearly ten years ago.  I guess we don't hit that one very often.  ;-)

	* 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.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.432
diff -u -p -r1.432 elflink.c
--- bfd/elflink.c	7 Dec 2011 12:15:54 -0000	1.432
+++ bfd/elflink.c	8 Feb 2012 09:22:14 -0000
@@ -2510,23 +2510,21 @@ _bfd_elf_fix_symbol_flags (struct elf_li
      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_i
 	     || 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);
     }
 

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list