2003-04-25 Alan Modra <amodra@bigpond.net.au>
* 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.
This commit is contained in:
parent
635f10624f
commit
3c0a515daa
2 changed files with 36 additions and 15 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2003-04-25 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2003-04-24 Roland McGrath <roland@redhat.com>
|
2003-04-24 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
* elf.c (bfd_section_from_phdr): Map PT_GNU_EH_FRAME to "eh_frame_hdr".
|
* elf.c (bfd_section_from_phdr): Map PT_GNU_EH_FRAME to "eh_frame_hdr".
|
||||||
|
|
|
@ -479,6 +479,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
{
|
{
|
||||||
asection *sec;
|
asection *sec;
|
||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
|
struct elf_link_hash_entry *flip;
|
||||||
int bind;
|
int bind;
|
||||||
bfd *oldbfd;
|
bfd *oldbfd;
|
||||||
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
|
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
|
||||||
|
@ -769,6 +770,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
As above, we permit a non-weak definition in a shared object to
|
As above, we permit a non-weak definition in a shared object to
|
||||||
override a weak definition in a regular object. */
|
override a weak definition in a regular object. */
|
||||||
|
|
||||||
|
flip = NULL;
|
||||||
if (! newdyn
|
if (! newdyn
|
||||||
&& (newdef
|
&& (newdef
|
||||||
|| (bfd_is_com_section (sec)
|
|| (bfd_is_com_section (sec)
|
||||||
|
@ -797,19 +799,13 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
if (bfd_is_com_section (sec))
|
if (bfd_is_com_section (sec))
|
||||||
*type_change_ok = TRUE;
|
*type_change_ok = TRUE;
|
||||||
|
|
||||||
/* This union may have been set to be non-NULL when this symbol
|
if ((*sym_hash)->root.type == bfd_link_hash_indirect)
|
||||||
was seen in a dynamic object. We must force the union to be
|
flip = *sym_hash;
|
||||||
NULL, so that it is correct for a regular symbol. */
|
else
|
||||||
|
/* This union may have been set to be non-NULL when this symbol
|
||||||
h->verinfo.vertree = NULL;
|
was seen in a dynamic object. We must force the union to be
|
||||||
|
NULL, so that it is correct for a regular symbol. */
|
||||||
/* In this special case, if H is the target of an indirection,
|
h->verinfo.vertree = NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the special case of a new common symbol merging with an
|
/* Handle the special case of a new common symbol merging with an
|
||||||
|
@ -849,7 +845,26 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
*size_change_ok = TRUE;
|
*size_change_ok = TRUE;
|
||||||
*type_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
|
/* Handle the special case of a weak definition in a regular object
|
||||||
|
@ -883,7 +898,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
|
|
||||||
/* Handle the special case of a non-weak definition in a shared
|
/* Handle the special case of a non-weak definition in a shared
|
||||||
object followed by a weak definition in a regular object. In
|
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
|
this work we have to tell the caller to not treat the new symbol
|
||||||
as a definition. */
|
as a definition. */
|
||||||
if (olddef
|
if (olddef
|
||||||
|
|
Loading…
Reference in a new issue