PR27719, lang_mark_undefineds trashes memory
authorAlan Modra <amodra@gmail.com>
Sun, 11 Apr 2021 14:04:21 +0000 (23:34 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 12 Apr 2021 02:27:03 +0000 (11:57 +0930)
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.

ld/ChangeLog
ld/emultempl/armelf.em
ld/emultempl/solaris2.em
ld/ldlang.c
ld/plugin.c

index c07105db3184391668c35d7627493b4ad44c089a..aad02a2086af20bcd11ea8cb58b52663284d2d29 100644 (file)
@@ -1,3 +1,13 @@
+2021-04-12  Alan Modra  <amodra@gmail.com>
+
+       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  <amodra@gmail.com>
 
        * testsuite/ld-powerpc/inlinepcrel-1.d: Update expected output.
index bcb60d252ce31db45e25406d140d7fdcdaf00fa1..7aec17e5ede95e488350910875b0b1bf4fb4e3d1 100644 (file)
@@ -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,
index 9fb739c598b1b5a42de15e0d2bbe0b4d1e629199..e2b4fd63b7bc2b85709b4288af90eebe21ff56c4 100644 (file)
@@ -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++)
        {
index 891089932367f53e26234ace901adb76ce18aff2..37b64c89ee1d48b10647a07996a21d1f27ecf59a 100644 (file)
@@ -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;
index adaba32edaa19d4e6ec0fa73385d8348f18efcfb..98a83bc9593e111d0502d339ffa60fdd55c32489 100644 (file)
@@ -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);