This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Versioned symbol linking bug
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Tue, 25 Feb 2003 13:28:12 +1030
- Subject: Re: Versioned symbol linking bug
- References: <20030217164809.GA18104@nevyn.them.org>
Hi Daniel,
This patch cures your testcase, but I'm not game to install it
without a whole lot of testing, which I don't have time to do at
the moment.
* elflink.h (elf_merge_symbol): When we find a regular definition
for an indirect symbol, flip the indirection so that the old
direct symbol now points to the new definition.
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.206
diff -u -p -r1.206 elflink.h
--- bfd/elflink.h 17 Feb 2003 18:24:40 -0000 1.206
+++ bfd/elflink.h 25 Feb 2003 02:41:23 -0000
@@ -479,6 +479,7 @@ elf_merge_symbol (abfd, info, name, sym,
{
asection *sec;
struct elf_link_hash_entry *h;
+ struct elf_link_hash_entry *flip;
int bind;
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
@@ -769,6 +770,7 @@ elf_merge_symbol (abfd, info, name, sym,
As above, we permit a non-weak definition in a shared object to
override a weak definition in a regular object. */
+ flip = NULL;
if (! newdyn
&& (newdef
|| (bfd_is_com_section (sec)
@@ -797,19 +799,13 @@ elf_merge_symbol (abfd, info, name, sym,
if (bfd_is_com_section (sec))
*type_change_ok = TRUE;
- /* This union may have been set to be non-NULL when this symbol
- was seen in a dynamic object. We must force the union to be
- NULL, so that it is correct for a regular symbol. */
-
- h->verinfo.vertree = NULL;
-
- /* In this special case, if H is the target of an indirection,
- we want the caller to frob with H rather than with the
- indirect symbol. That will permit the caller to redefine the
- target of the indirection, rather than the indirect symbol
- itself. FIXME: This will break the -y option if we store a
- symbol with a different name. */
- *sym_hash = h;
+ if ((*sym_hash)->root.type == bfd_link_hash_indirect)
+ flip = *sym_hash;
+ else
+ /* This union may have been set to be non-NULL when this symbol
+ was seen in a dynamic object. We must force the union to be
+ NULL, so that it is correct for a regular symbol. */
+ h->verinfo.vertree = NULL;
}
/* Handle the special case of a new common symbol merging with an
@@ -849,7 +845,26 @@ elf_merge_symbol (abfd, info, name, sym,
*size_change_ok = TRUE;
*type_change_ok = TRUE;
- h->verinfo.vertree = NULL;
+ if ((*sym_hash)->root.type == bfd_link_hash_indirect)
+ flip = *sym_hash;
+ else
+ h->verinfo.vertree = NULL;
+ }
+
+ if (flip != NULL)
+ {
+ /* Handle the case where we had a versioned symbol in a dynamic
+ library and now find a definition in a normal object. In this
+ case, we make the versioned symbol point to the normal one. */
+ flip->root.type = h->root.type;
+ flip->root.u.undef.abfd = h->root.u.undef.abfd;
+ h->root.type = bfd_link_hash_indirect;
+ h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
+ if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
+ {
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
+ flip->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+ }
}
/* Handle the special case of a weak definition in a regular object
@@ -883,7 +898,7 @@ elf_merge_symbol (abfd, info, name, sym,
/* Handle the special case of a non-weak definition in a shared
object followed by a weak definition in a regular object. In
- this case we prefer to definition in the shared object. To make
+ this case we prefer the definition in the shared object. To make
this work we have to tell the caller to not treat the new symbol
as a definition. */
if (olddef
--
Alan Modra
IBM OzLabs - Linux Technology Centre