elf_backend_archive_symbol_lookup
elf_backend_archive_symbol_lookup might be called when the linker hash table has entries of type generic_link_hash_entry. This happens for instance when running the mmix target linker testsuite where the output is mmo but input is elf64-mmix. * elf-bfd.h (struct elf_backend_data): Return bfd_link_hash_entry* from elf_backend_archive_symbol_lookup. (_bfd_elf_archive_symbol_lookup): Return bfd_link_hash_entry*. * elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Likewise. Check we have a ppc_hash_table before accessing ppc_link_hash_entry fields. * elflink.c (_bfd_elf_archive_symbol_lookup): Return bfd_link_hash_entry*. (elf_link_add_archive_symbols): Adjust to suit.
This commit is contained in:
parent
f5b1097353
commit
b585e89996
4 changed files with 33 additions and 20 deletions
|
@ -1,3 +1,15 @@
|
|||
2021-04-12 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf-bfd.h (struct elf_backend_data): Return bfd_link_hash_entry*
|
||||
from elf_backend_archive_symbol_lookup.
|
||||
(_bfd_elf_archive_symbol_lookup): Return bfd_link_hash_entry*.
|
||||
* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Likewise. Check
|
||||
we have a ppc_hash_table before accessing ppc_link_hash_entry
|
||||
fields.
|
||||
* elflink.c (_bfd_elf_archive_symbol_lookup): Return
|
||||
bfd_link_hash_entry*.
|
||||
(elf_link_add_archive_symbols): Adjust to suit.
|
||||
|
||||
2021-04-12 Nelson Chu <nelson.chu@sifive.com>
|
||||
|
||||
* elfxx-riscv.c (riscv_parse_std_ext): Fixed the wrong versions of
|
||||
|
|
|
@ -975,7 +975,7 @@ struct elf_backend_data
|
|||
|
||||
/* A function to return the linker hash table entry of a symbol that
|
||||
might be satisfied by an archive symbol. */
|
||||
struct elf_link_hash_entry * (*elf_backend_archive_symbol_lookup)
|
||||
struct bfd_link_hash_entry * (*elf_backend_archive_symbol_lookup)
|
||||
(bfd *, struct bfd_link_info *, const char *);
|
||||
|
||||
/* Return true if local section symbols should have a non-null st_name.
|
||||
|
@ -2581,7 +2581,7 @@ extern bool _bfd_elf_relocs_compatible
|
|||
extern bool _bfd_elf_notice_as_needed
|
||||
(bfd *, struct bfd_link_info *, enum notice_asneeded_action);
|
||||
|
||||
extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
|
||||
extern struct bfd_link_hash_entry *_bfd_elf_archive_symbol_lookup
|
||||
(bfd *, struct bfd_link_info *, const char *);
|
||||
extern bool bfd_elf_link_add_symbols
|
||||
(bfd *, struct bfd_link_info *);
|
||||
|
|
|
@ -4196,20 +4196,21 @@ ppc64_elf_merge_symbol (struct elf_link_hash_entry *h,
|
|||
NAME is a symbol defined in an archive. Return a symbol in the hash
|
||||
table that might be satisfied by the archive symbols. */
|
||||
|
||||
static struct elf_link_hash_entry *
|
||||
static struct bfd_link_hash_entry *
|
||||
ppc64_elf_archive_symbol_lookup (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
const char *name)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
struct bfd_link_hash_entry *h;
|
||||
char *dot_name;
|
||||
size_t len;
|
||||
|
||||
h = _bfd_elf_archive_symbol_lookup (abfd, info, name);
|
||||
if (h != NULL
|
||||
&& ppc_hash_table (info) != NULL
|
||||
/* Don't return this sym if it is a fake function descriptor
|
||||
created by add_symbol_adjust. */
|
||||
&& !ppc_elf_hash_entry (h)->fake)
|
||||
&& !((struct ppc_link_hash_entry *) h)->fake)
|
||||
return h;
|
||||
|
||||
if (name[0] == '.')
|
||||
|
@ -4218,7 +4219,7 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
|
|||
len = strlen (name);
|
||||
dot_name = bfd_alloc (abfd, len + 2);
|
||||
if (dot_name == NULL)
|
||||
return (struct elf_link_hash_entry *) -1;
|
||||
return (struct bfd_link_hash_entry *) -1;
|
||||
dot_name[0] = '.';
|
||||
memcpy (dot_name + 1, name, len + 1);
|
||||
h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
|
||||
|
|
|
@ -5742,16 +5742,16 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
/* Return the linker hash table entry of a symbol that might be
|
||||
satisfied by an archive symbol. Return -1 on error. */
|
||||
|
||||
struct elf_link_hash_entry *
|
||||
struct bfd_link_hash_entry *
|
||||
_bfd_elf_archive_symbol_lookup (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
const char *name)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
struct bfd_link_hash_entry *h;
|
||||
char *p, *copy;
|
||||
size_t len, first;
|
||||
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), name, false, false, true);
|
||||
h = bfd_link_hash_lookup (info->hash, name, false, false, true);
|
||||
if (h != NULL)
|
||||
return h;
|
||||
|
||||
|
@ -5768,20 +5768,19 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd,
|
|||
len = strlen (name);
|
||||
copy = (char *) bfd_alloc (abfd, len);
|
||||
if (copy == NULL)
|
||||
return (struct elf_link_hash_entry *) -1;
|
||||
return (struct bfd_link_hash_entry *) -1;
|
||||
|
||||
first = p - name + 1;
|
||||
memcpy (copy, name, first);
|
||||
memcpy (copy + first, name + first + 1, len - first);
|
||||
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), copy, false, false, true);
|
||||
h = bfd_link_hash_lookup (info->hash, copy, false, false, true);
|
||||
if (h == NULL)
|
||||
{
|
||||
/* We also need to check references to the symbol without the
|
||||
version. */
|
||||
copy[first - 1] = '\0';
|
||||
h = elf_link_hash_lookup (elf_hash_table (info), copy,
|
||||
false, false, true);
|
||||
h = bfd_link_hash_lookup (info->hash, copy, false, false, true);
|
||||
}
|
||||
|
||||
bfd_release (abfd, copy);
|
||||
|
@ -5810,7 +5809,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
bool loop;
|
||||
size_t amt;
|
||||
const struct elf_backend_data *bed;
|
||||
struct elf_link_hash_entry * (*archive_symbol_lookup)
|
||||
struct bfd_link_hash_entry * (*archive_symbol_lookup)
|
||||
(bfd *, struct bfd_link_info *, const char *);
|
||||
|
||||
if (! bfd_has_map (abfd))
|
||||
|
@ -5851,7 +5850,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
symdefend = symdef + c;
|
||||
for (i = 0; symdef < symdefend; symdef++, i++)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
struct bfd_link_hash_entry *h;
|
||||
bfd *element;
|
||||
struct bfd_link_hash_entry *undefs_tail;
|
||||
symindex mark;
|
||||
|
@ -5865,21 +5864,22 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
}
|
||||
|
||||
h = archive_symbol_lookup (abfd, info, symdef->name);
|
||||
if (h == (struct elf_link_hash_entry *) -1)
|
||||
if (h == (struct bfd_link_hash_entry *) -1)
|
||||
goto error_return;
|
||||
|
||||
if (h == NULL)
|
||||
continue;
|
||||
|
||||
if (h->root.type == bfd_link_hash_undefined)
|
||||
if (h->type == bfd_link_hash_undefined)
|
||||
{
|
||||
/* If the archive element has already been loaded then one
|
||||
of the symbols defined by that element might have been
|
||||
made undefined due to being in a discarded section. */
|
||||
if (h->indx == -3)
|
||||
if (is_elf_hash_table (info->hash)
|
||||
&& ((struct elf_link_hash_entry *) h)->indx == -3)
|
||||
continue;
|
||||
}
|
||||
else if (h->root.type == bfd_link_hash_common)
|
||||
else if (h->type == bfd_link_hash_common)
|
||||
{
|
||||
/* We currently have a common symbol. The archive map contains
|
||||
a reference to this symbol, so we may want to include it. We
|
||||
|
@ -5898,7 +5898,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (h->root.type != bfd_link_hash_undefweak)
|
||||
if (h->type != bfd_link_hash_undefweak)
|
||||
/* Symbol must be defined. Don't check it again. */
|
||||
included[i] = true;
|
||||
continue;
|
||||
|
|
Loading…
Add table
Reference in a new issue