aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-04-05 16:37:58 -0700
committerH.J. Lu <hjl.tools@gmail.com>2024-04-05 16:49:09 -0700
commit816fd3dced1b2e94789b6d7d1d1fab1988e8e05d (patch)
tree7217b8b181591477c84c29ce493233a8b1764d7b /bfd
parentc0419c024bf922128131671e40de0aed736e38ed (diff)
downloadgdb-816fd3dced1b2e94789b6d7d1d1fab1988e8e05d.zip
gdb-816fd3dced1b2e94789b6d7d1d1fab1988e8e05d.tar.gz
gdb-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.h2
-rw-r--r--bfd/elflink.c87
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