Binutils is broken by the linker change

Alan Modra amodra@bigpond.net.au
Thu Mar 18 23:01:00 GMT 2004


On Fri, Mar 19, 2004 at 08:39:36AM +1030, Alan Modra wrote:
> Oops.  Once again, I've proven how useless comments are.  Some of the
> "dead code" that I eliminated, which the comment said was dealing with
> "the special case of a weak definition in a regular object followed by a
> non-weak definition in a shared object", was actually dealing with weak
> and non-weak in two shared objects as well.  Reinstating the code..

I've also trimmed the old code down to handle just the case we need
to handle, ie. when two shared objects are involved, and added a comment
about why the generic code doesn't handle this particular case.

HJ, would you please add your testcase to the ld testsuite?

	* elflink.c (_bfd_elf_merge_symbol): Reinstate code to handle
	strong syms in one shared object overriding weak syms in another.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.57
diff -u -p -r1.57 elflink.c
--- bfd/elflink.c	18 Mar 2004 04:32:17 -0000	1.57
+++ bfd/elflink.c	18 Mar 2004 22:49:59 -0000
@@ -1153,6 +1153,30 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	}
     }
 
+  /* Handle the special case of a weak definition in one shared object
+     followed by a non-weak definition in another.  We are covering for
+     a deficiency of _bfd_generic_link_add_one_symbol here.  A new
+     strong definition of an indirect symbol is treated as a multiple
+     definition even when the indirect symbol points to a weak sym.  */
+  if (olddef
+      && oldweak
+      && olddyn
+      && newdef
+      && !newweak
+      && newdyn)
+    {
+      /* To make this work we have to frob the flags so that the rest
+	 of the code does not think we are using the old definition.  */
+      h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+      h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
+
+      /* If H is the target of an indirection, we want the caller to
+	 use H rather than the indirect symbol.  Otherwise if we are
+	 defining a new indirect symbol we will wind up attaching it
+	 to the entry we are overriding.  */
+      *sym_hash = h;
+    }
+
   return TRUE;
 }
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list