From: Alan Modra Date: Mon, 12 Apr 2021 07:46:58 +0000 (+0930) Subject: elf_backend_archive_symbol_lookup X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b585e899960202fbe3c137cbf765f75b088592fe;p=binutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cb85678a716..68224f86fe9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2021-04-12 Alan Modra + + * 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 * elfxx-riscv.c (riscv_parse_std_ext): Fixed the wrong versions of diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 296b80ad952..6f9d7375eaf 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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 *); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index c306954dacb..7873f97ab32 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -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); diff --git a/bfd/elflink.c b/bfd/elflink.c index e8f3a9edc62..3acf7951b5b 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -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;