public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Fix -gc-sections related abort
@ 2012-02-08 10:12 Alan Modra
  0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2012-02-08 10:12 UTC (permalink / raw)
  To: binutils

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-02-08 10:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-08 10:12 Fix -gc-sections related abort Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).