mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 04:49:54 +08:00
* elflink.h (elf_merge_symbol): In the case of a new defined
symbol overriding an old defined symbol, return the hash table entry which we modify, even if it is the target of an indirection. (elf_link_add_object_symbols): If the real name of the symbol gets overridden, convert the versioned symbol into an indirect symbol to the real symbol.
This commit is contained in:
@ -1,5 +1,13 @@
|
|||||||
Mon Jun 23 18:03:27 1997 Ian Lance Taylor <ian@cygnus.com>
|
Mon Jun 23 18:03:27 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* elflink.h (elf_merge_symbol): In the case of a new defined
|
||||||
|
symbol overriding an old defined symbol, return the hash table
|
||||||
|
entry which we modify, even if it is the target of an
|
||||||
|
indirection.
|
||||||
|
(elf_link_add_object_symbols): If the real name of the symbol gets
|
||||||
|
overridden, convert the versioned symbol into an indirect symbol
|
||||||
|
to the real symbol.
|
||||||
|
|
||||||
* elflink.h (elf_merge_symbol): New static function, broken out of
|
* elflink.h (elf_merge_symbol): New static function, broken out of
|
||||||
elf_link_add_object_symbols.
|
elf_link_add_object_symbols.
|
||||||
(elf_link_add_object_symbols): Call it.
|
(elf_link_add_object_symbols): Call it.
|
||||||
|
@ -568,6 +568,13 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
|||||||
NULL, so that it is correct for a regular symbol. */
|
NULL, so that it is correct for a regular symbol. */
|
||||||
|
|
||||||
h->verinfo.vertree = NULL;
|
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. */
|
||||||
|
*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
|
||||||
@ -1376,26 +1383,70 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
bfd_ind_section_ptr, (bfd_vma) 0, name, false,
|
bfd_ind_section_ptr, (bfd_vma) 0, name, false,
|
||||||
collect, (struct bfd_link_hash_entry **) &hi)))
|
collect, (struct bfd_link_hash_entry **) &hi)))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* In this case the symbol named SHORTNAME is
|
||||||
|
overriding the indirect symbol we want to
|
||||||
|
add. We were planning on making SHORTNAME an
|
||||||
|
indirect symbol referring to NAME. SHORTNAME
|
||||||
|
is the name without a version. NAME is the
|
||||||
|
fully versioned name, and it is the default
|
||||||
|
version.
|
||||||
|
|
||||||
|
Overriding means that we already saw a
|
||||||
|
definition for the symbol SHORTNAME in a
|
||||||
|
regular object, and it is overriding the
|
||||||
|
symbol defined in the dynamic object.
|
||||||
|
|
||||||
|
When this happens, we actually want to change
|
||||||
|
NAME, the symbol we just added, to refer to
|
||||||
|
SHORTNAME. This will cause references to
|
||||||
|
NAME in the shared object to become
|
||||||
|
references to SHORTNAME in the regular
|
||||||
|
object. This is what we expect when we
|
||||||
|
override a function in a shared object: that
|
||||||
|
the references in the shared object will be
|
||||||
|
mapped to the definition in the regular
|
||||||
|
object. */
|
||||||
|
|
||||||
|
h->root.type = bfd_link_hash_indirect;
|
||||||
|
h->root.u.i.link = (struct bfd_link_hash_entry *) hi;
|
||||||
|
if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
|
||||||
|
{
|
||||||
|
h->elf_link_hash_flags &=~ ELF_LINK_HASH_DEF_DYNAMIC;
|
||||||
|
hi->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
|
||||||
|
if (! _bfd_elf_link_record_dynamic_symbol (info, hi))
|
||||||
|
goto error_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now set HI to H, so that the following code
|
||||||
|
will set the other fields correctly. */
|
||||||
|
hi = h;
|
||||||
|
}
|
||||||
|
|
||||||
/* If there is a duplicate definition somewhere,
|
/* If there is a duplicate definition somewhere,
|
||||||
then HI may not point to an indirect symbol.
|
then HI may not point to an indirect symbol. We
|
||||||
We will have reported an error to the user in
|
will have reported an error to the user in that
|
||||||
that case. */
|
case. */
|
||||||
|
|
||||||
if (hi->root.type == bfd_link_hash_indirect)
|
if (hi->root.type == bfd_link_hash_indirect)
|
||||||
{
|
{
|
||||||
/* If the symbol became indirect, then we
|
struct elf_link_hash_entry *ht;
|
||||||
assume that we have not seen a definition
|
|
||||||
before. */
|
/* If the symbol became indirect, then we assume
|
||||||
|
that we have not seen a definition before. */
|
||||||
BFD_ASSERT ((hi->elf_link_hash_flags
|
BFD_ASSERT ((hi->elf_link_hash_flags
|
||||||
& (ELF_LINK_HASH_DEF_DYNAMIC
|
& (ELF_LINK_HASH_DEF_DYNAMIC
|
||||||
| ELF_LINK_HASH_DEF_REGULAR))
|
| ELF_LINK_HASH_DEF_REGULAR))
|
||||||
== 0);
|
== 0);
|
||||||
|
|
||||||
|
ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
|
||||||
|
|
||||||
/* Copy down any references that we may have
|
/* Copy down any references that we may have
|
||||||
already seen to the symbol which just
|
already seen to the symbol which just became
|
||||||
became indirect. */
|
indirect. */
|
||||||
h->elf_link_hash_flags |=
|
ht->elf_link_hash_flags |=
|
||||||
(hi->elf_link_hash_flags
|
(hi->elf_link_hash_flags
|
||||||
& (ELF_LINK_HASH_REF_DYNAMIC
|
& (ELF_LINK_HASH_REF_DYNAMIC
|
||||||
| ELF_LINK_HASH_REF_REGULAR));
|
| ELF_LINK_HASH_REF_REGULAR));
|
||||||
@ -1403,27 +1454,27 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
/* Copy over the global table offset entry.
|
/* Copy over the global table offset entry.
|
||||||
This may have been already set up by a
|
This may have been already set up by a
|
||||||
check_relocs routine. */
|
check_relocs routine. */
|
||||||
if (h->got_offset == (bfd_vma) -1)
|
if (ht->got_offset == (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
h->got_offset = hi->got_offset;
|
ht->got_offset = hi->got_offset;
|
||||||
hi->got_offset = (bfd_vma) -1;
|
hi->got_offset = (bfd_vma) -1;
|
||||||
}
|
}
|
||||||
BFD_ASSERT (hi->got_offset == (bfd_vma) -1);
|
BFD_ASSERT (hi->got_offset == (bfd_vma) -1);
|
||||||
|
|
||||||
if (h->dynindx == -1)
|
if (ht->dynindx == -1)
|
||||||
{
|
{
|
||||||
h->dynindx = hi->dynindx;
|
ht->dynindx = hi->dynindx;
|
||||||
h->dynstr_index = hi->dynstr_index;
|
ht->dynstr_index = hi->dynstr_index;
|
||||||
hi->dynindx = -1;
|
hi->dynindx = -1;
|
||||||
hi->dynstr_index = 0;
|
hi->dynstr_index = 0;
|
||||||
}
|
}
|
||||||
BFD_ASSERT (hi->dynindx == -1);
|
BFD_ASSERT (hi->dynindx == -1);
|
||||||
|
|
||||||
/* FIXME: There may be other information to
|
/* FIXME: There may be other information to copy
|
||||||
copy over for particular targets. */
|
over for particular targets. */
|
||||||
|
|
||||||
/* See if the new flags lead us to realize
|
/* See if the new flags lead us to realize that
|
||||||
that the symbol must be dynamic. */
|
the symbol must be dynamic. */
|
||||||
if (! dynsym)
|
if (! dynsym)
|
||||||
{
|
{
|
||||||
if (! dynamic)
|
if (! dynamic)
|
||||||
@ -1442,7 +1493,6 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* We also need to define an indirection from the
|
/* We also need to define an indirection from the
|
||||||
nondefault version of the symbol. */
|
nondefault version of the symbol. */
|
||||||
@ -1460,7 +1510,16 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
&type_change_ok, &size_change_ok))
|
&type_change_ok, &size_change_ok))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
if (! override)
|
if (override)
|
||||||
|
{
|
||||||
|
/* Here SHORTNAME is a versioned name, so we
|
||||||
|
don't expect to see the type of override we
|
||||||
|
do in the case above. */
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
("%s: warning: unexpected redefinition of `%s'",
|
||||||
|
bfd_get_filename (abfd), shortname);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (! (_bfd_generic_link_add_one_symbol
|
if (! (_bfd_generic_link_add_one_symbol
|
||||||
(info, abfd, shortname, BSF_INDIRECT,
|
(info, abfd, shortname, BSF_INDIRECT,
|
||||||
|
Reference in New Issue
Block a user