diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2024-04-05 16:37:58 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2024-04-05 16:49:09 -0700 |
commit | 816fd3dced1b2e94789b6d7d1d1fab1988e8e05d (patch) | |
tree | 7217b8b181591477c84c29ce493233a8b1764d7b /bfd | |
parent | c0419c024bf922128131671e40de0aed736e38ed (diff) | |
download | binutils-816fd3dced1b2e94789b6d7d1d1fab1988e8e05d.zip binutils-816fd3dced1b2e94789b6d7d1d1fab1988e8e05d.tar.gz binutils-816fd3dced1b2e94789b6d7d1d1fab1988e8e05d.tar.bz2 |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elflink.c | 87 |
2 files changed, 63 insertions, 26 deletions
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index cf043d6..85e6648 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 3db517c..e41b3d6 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 |