From: H.J. Lu Date: Fri, 5 Apr 2024 23:37:58 +0000 (-0700) Subject: elf: Use elf_link_first_hash_entry for first_hash X-Git-Tag: gdb-15-branchpoint~480 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=816fd3dced1b2e94789b6d7d1d1fab1988e8e05d;p=thirdparty%2Fbinutils-gdb.git elf: Use elf_link_first_hash_entry for first_hash Add elf_link_first_hash_entry and use it for first_hash. Free first_hash before freeing the main hash table. PR ld/31482 PR ld/31489 * elf-bfd.h (elf_link_hash_table): Change first_hash to bfd_hash_table. * elflink.c (elf_link_first_hash_entry): New. (elf_link_first_hash_newfunc): Likewise. (elf_link_add_to_first_hash): Updated. (elf_link_add_object_symbols): Initialize first_hash with elf_link_first_hash_newfunc. (elf_link_add_object_symbols): Updated. (elf_link_add_archive_symbols): Likewise. (_bfd_elf_link_hash_table_free): Free first_hash before freeing the main hash table. --- diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index cf043d6d154..85e66488955 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -739,7 +739,7 @@ struct elf_link_hash_table /* Hash table of symbols which are first defined in archives or shared objects when there are any IR inputs. */ - struct bfd_link_hash_table *first_hash; + struct bfd_hash_table *first_hash; /* Short-cuts to get to dynamic linker sections. */ asection *sgot; diff --git a/bfd/elflink.c b/bfd/elflink.c index 3db517ca1cd..e41b3d6dad7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4261,6 +4261,45 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) return true; } +/* An entry in the first definition hash table. */ + +struct elf_link_first_hash_entry +{ + struct bfd_hash_entry root; + /* The object of the first definition. */ + bfd *abfd; +}; + +/* The function to create a new entry in the first definition hash + table. */ + +static struct bfd_hash_entry * +elf_link_first_hash_newfunc (struct bfd_hash_entry *entry, + struct bfd_hash_table *table, + const char *string) +{ + struct elf_link_first_hash_entry *ret = + (struct elf_link_first_hash_entry *) entry; + + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (ret == NULL) + ret = (struct elf_link_first_hash_entry *) + bfd_hash_allocate (table, + sizeof (struct elf_link_first_hash_entry)); + if (ret == NULL) + return NULL; + + /* Call the allocation method of the superclass. */ + ret = ((struct elf_link_first_hash_entry *) + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, + string)); + if (ret != NULL) + ret->abfd = NULL; + + return (struct bfd_hash_entry *) ret; +} + /* Add the symbol NAME from ABFD to first hash. */ static void @@ -4272,19 +4311,16 @@ elf_link_add_to_first_hash (bfd *abfd, struct bfd_link_info *info, if (htab->first_hash == NULL) return; - struct bfd_link_hash_entry *e - = bfd_link_hash_lookup (htab->first_hash, name, true, false, true); + struct elf_link_first_hash_entry *e + = ((struct elf_link_first_hash_entry *) + bfd_hash_lookup (htab->first_hash, name, true, false)); if (e == NULL) info->callbacks->einfo (_("%F%P: %pB: failed to add %s to first hash\n"), abfd, name); - if (e->type == bfd_link_hash_new) - { - /* Change the type to bfd_link_hash_undefined and store ABFD in - u.undef->abfd. */ - e->type = bfd_link_hash_undefined; - e->u.undef.abfd = abfd; - } + if (e->abfd == NULL) + /* Store ABFD in abfd. */ + e->abfd = abfd; } /* Add symbols from an ELF object file to the linker hash table. */ @@ -4341,11 +4377,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) && htab->first_hash == NULL) { /* Initialize first_hash for an IR input. */ - htab->first_hash = (struct bfd_link_hash_table *) - xmalloc (sizeof (struct bfd_link_hash_table)); - if (!bfd_hash_table_init (&htab->first_hash->table, - _bfd_link_hash_newfunc, - sizeof (struct bfd_link_hash_entry))) + htab->first_hash = (struct bfd_hash_table *) + xmalloc (sizeof (struct bfd_hash_table)); + if (!bfd_hash_table_init + (htab->first_hash, elf_link_first_hash_newfunc, + sizeof (struct elf_link_first_hash_entry))) info->callbacks->einfo (_("%F%P: first_hash failed to initialize: %E\n")); } @@ -5219,10 +5255,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) /* When reloading --as-needed shared objects for new symbols added from IR inputs, if this shared object has the first definition, use it. */ - struct bfd_link_hash_entry *e - = bfd_link_hash_lookup (htab->first_hash, name, - false, false, true); - if (e != NULL && e->u.undef.abfd == abfd) + struct elf_link_first_hash_entry *e + = ((struct elf_link_first_hash_entry *) + bfd_hash_lookup (htab->first_hash, name, false, + false)); + if (e != NULL && e->abfd == abfd) definition = true; } } @@ -6222,11 +6259,11 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) struct elf_link_hash_table *htab = elf_hash_table (info); if (htab->first_hash == NULL) continue; - struct bfd_link_hash_entry *e - = bfd_link_hash_lookup (htab->first_hash, - symdef->name, false, false, - true); - if (e == NULL || e->u.undef.abfd != abfd) + struct elf_link_first_hash_entry *e + = ((struct elf_link_first_hash_entry *) + bfd_hash_lookup (htab->first_hash, symdef->name, + false, false)); + if (e == NULL || e->abfd != abfd) continue; } @@ -8308,12 +8345,12 @@ _bfd_elf_link_hash_table_free (bfd *obfd) if (htab->dynstr != NULL) _bfd_elf_strtab_free (htab->dynstr); _bfd_merge_sections_free (htab->merge_info); - _bfd_generic_link_hash_table_free (obfd); if (htab->first_hash != NULL) { - bfd_hash_table_free (&htab->first_hash->table); + bfd_hash_table_free (htab->first_hash); free (htab->first_hash); } + _bfd_generic_link_hash_table_free (obfd); } /* This is a hook for the ELF emulation code in the generic linker to