This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: PR ld/14170: ld: assertion fail bfd/linker.c:641


On Sun, May 27, 2012 at 06:22:19AM -0700, H.J. Lu wrote:
> It looks OK, except for " if (h->def_dynamic)".  h->def_dynamic is
> always true when we get it.

So it is.  This is what I committed.  Please commit your testcase, or
even better, a variation that checks for OBJECT GLOBAL HIDDEN foo.

	PR ld/14170
	* elflink.c (_bfd_elf_merge_symbol): When a symbol defined in
	a dynamic library finds a new instance with non-default
	visibility in a regular object, correctly handle symbols
	already on the undefs list and undo dynamic symbol state when
	the new symbol is hidden or internal.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.445
diff -u -p -r1.445 elflink.c
--- bfd/elflink.c	25 May 2012 01:12:19 -0000	1.445
+++ bfd/elflink.c	27 May 2012 13:52:03 -0000
@@ -1216,15 +1216,15 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	    h = *sym_hash;
 	}
 
-      if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
-	  && bfd_is_und_section (sec))
+      /* If the old symbol was undefined before, then it will still be
+	 on the undefs list.  If the new symbol is undefined or
+	 common, we can't make it bfd_link_hash_new here, because new
+	 undefined or common symbols will be added to the undefs list
+	 by _bfd_generic_link_add_one_symbol.  Symbols may not be
+	 added twice to the undefs list.  Also, if the new symbol is
+	 undefweak then we don't want to lose the strong undef.  */
+      if (h->root.u.undef.next || info->hash->undefs_tail == &h->root)
 	{
-	  /* If the new symbol is undefined and the old symbol was
-	     also undefined before, we need to make sure
-	     _bfd_generic_link_add_one_symbol doesn't mess
-	     up the linker hash table undefs list.  Since the old
-	     definition came from a dynamic object, it is still on the
-	     undefs list.  */
 	  h->root.type = bfd_link_hash_undefined;
 	  h->root.u.undef.abfd = abfd;
 	}
@@ -1234,11 +1234,18 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	  h->root.u.undef.abfd = NULL;
 	}
 
-      if (h->def_dynamic)
+      if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED)
 	{
-	  h->def_dynamic = 0;
-	  h->ref_dynamic = 1;
+	  /* If the new symbol is hidden or internal, completely undo
+	     any dynamic link state.  */
+	  (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+	  h->forced_local = 0;
+	  h->ref_dynamic = 0;
 	}
+      else
+	h->ref_dynamic = 1;
+      h->def_dynamic = 0;
+      h->dynamic_def = 0;
       /* FIXME: Should we check type and size for protected symbol?  */
       h->size = 0;
       h->type = 0;


-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]