From: Alan Modra Date: Sun, 11 Apr 2021 14:04:21 +0000 (+0930) Subject: PR27719, lang_mark_undefineds trashes memory X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=fc304b889106f6d1bd720e969b95615992bf1961;p=deliverable%2Fbinutils-gdb.git PR27719, lang_mark_undefineds trashes memory It's not enough to test that the output is ELF before casting bfd_link_hash_entry to elf_link_hash_entry. Some ELF targets (d30v, dlx, pj, s12z, xgate) use the generic linker support in bfd/linker.c and thus their symbols are of type generic_link_hash_entry. Not all of the places this patch touches can result in wrong accesses, but I thought it worth ensuring that all occurrences of elf_link_hash_entry in ld/ were obviously correct. PR 27719 * ldlang.c (lang_mark_undefineds, undef_start_stop): Test that the symbol hash table is the correct type before accessing elf_link_hash_entry symbols. * plugin.c (is_visible_from_outside): Likewise. * emultempl/armelf.em (ld${EMULATION_NAME}_finish): Likewise. * emultempl/solaris2.em (elf_solaris2_before_allocation): Likewise. --- diff --git a/ld/ChangeLog b/ld/ChangeLog index c07105db31..aad02a2086 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2021-04-12 Alan Modra + + PR 27719 + * ldlang.c (lang_mark_undefineds, undef_start_stop): Test that + the symbol hash table is the correct type before accessing + elf_link_hash_entry symbols. + * plugin.c (is_visible_from_outside): Likewise. + * emultempl/armelf.em (ld${EMULATION_NAME}_finish): Likewise. + * emultempl/solaris2.em (elf_solaris2_before_allocation): Likewise. + 2021-04-09 Alan Modra * testsuite/ld-powerpc/inlinepcrel-1.d: Update expected output. diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index bcb60d252c..7aec17e5ed 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -463,7 +463,7 @@ gld${EMULATION_NAME}_finish (void) { struct elf_link_hash_entry * eh; - if (!entry_symbol.name) + if (!entry_symbol.name || !is_elf_hash_table (link_info.hash)) return; h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name, diff --git a/ld/emultempl/solaris2.em b/ld/emultempl/solaris2.em index 9fb739c598..e2b4fd63b7 100644 --- a/ld/emultempl/solaris2.em +++ b/ld/emultempl/solaris2.em @@ -64,7 +64,8 @@ elf_solaris2_before_allocation (void) const char **sym; /* Do this for both executables and shared objects. */ - if (!bfd_link_relocatable (&link_info)) + if (!bfd_link_relocatable (&link_info) + && is_elf_hash_table (link_info.hash)) { for (sym = global_syms; *sym != NULL; sym++) { diff --git a/ld/ldlang.c b/ld/ldlang.c index 8910899323..37b64c89ee 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -4009,7 +4009,7 @@ lang_mark_undefineds (void) { ldlang_undef_chain_list_type *ptr; - if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour) + if (is_elf_hash_table (link_info.hash)) for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next) { struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) @@ -6822,7 +6822,7 @@ undef_start_stop (struct bfd_link_hash_entry *h) } h->type = bfd_link_hash_undefined; h->u.undef.abfd = NULL; - if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour) + if (is_elf_hash_table (link_info.hash)) { const struct elf_backend_data *bed; struct elf_link_hash_entry *eh = (struct elf_link_hash_entry *) h; diff --git a/ld/plugin.c b/ld/plugin.c index adaba32eda..98a83bc959 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -636,7 +636,7 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym, blhe->root.string)) return false; /* Only ELF symbols really have visibility. */ - if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour) + if (is_elf_hash_table (link_info.hash)) { struct elf_link_hash_entry *el = (struct elf_link_hash_entry *)blhe; int vis = ELF_ST_VISIBILITY (el->other);