aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-04-09 18:41:59 -0700
committerH.J. Lu <hjl.tools@gmail.com>2024-04-10 19:50:01 -0700
commitc3460201a64b641e3a2089b7fca7ae17a9ddfb85 (patch)
treefbb669a56a9b501570ca833010d1cc1696b8a414 /bfd
parentea3002bc4d2a3c8ad284041f8a7dd08472c3f5fa (diff)
downloadgdb-c3460201a64b641e3a2089b7fca7ae17a9ddfb85.zip
gdb-c3460201a64b641e3a2089b7fca7ae17a9ddfb85.tar.gz
gdb-c3460201a64b641e3a2089b7fca7ae17a9ddfb85.tar.bz2
elf: Fix a memory leak in _bfd_elf_add_dynamic_entry
Normally, the section contents is allocated by bfd_alloc which is freed when the object is closed. But the .dynamic section contents is allocated by bfd_realloc, which should be freed by calling free. Add a dynamic field to elf_link_hash_table for the .dynamic section and free its contents in _bfd_elf_link_hash_table_free. * elf-bfd.h (elf_link_hash_table): Add dynamic. * elflink.c (_bfd_elf_link_create_dynamic_sections): Set the dynamic field in elf_link_hash_table. (_bfd_elf_add_dynamic_entry): Use hash_table->dynamic. (_bfd_elf_strip_zero_sized_dynamic_sections): Likewise. (bfd_elf_add_dt_needed_tag): Likewise. (elf_finalize_dynstr): Likewise. (_bfd_elf_link_hash_table_free): Free htab->dynamic->contents. (bfd_elf_final_link): Use htab->dynamic. * elfxx-x86.c (_bfd_x86_elf_finish_dynamic_sections): Use htab->elf.dynamic.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/elf-bfd.h1
-rw-r--r--bfd/elflink.c16
-rw-r--r--bfd/elfxx-x86.c2
3 files changed, 12 insertions, 7 deletions
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 85e6648..ef5dcb5 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -757,6 +757,7 @@ struct elf_link_hash_table
asection *irelifunc;
asection *dynsym;
asection *srelrdyn;
+ asection *dynamic;
};
/* Returns TRUE if the hash table is a struct elf_link_hash_table. */
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c734702..22fddb8 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -355,6 +355,7 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
if (s == NULL
|| !bfd_set_section_alignment (s, bed->s->log_file_align))
return false;
+ elf_hash_table (info)->dynamic = s;
/* The special symbol _DYNAMIC is always set to the start of the
.dynamic section. We could set _DYNAMIC in a linker script, but we
@@ -3729,7 +3730,7 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
hash_table->dynamic_relocs = true;
bed = get_elf_backend_data (hash_table->dynobj);
- s = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+ s = hash_table->dynamic;
BFD_ASSERT (s != NULL);
newsize = s->size + bed->s->sizeof_dyn;
@@ -3772,7 +3773,7 @@ _bfd_elf_strip_zero_sized_dynamic_sections (struct bfd_link_info *info)
if (!hash_table->dynobj)
return true;
- sdynamic= bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+ sdynamic= hash_table->dynamic;
if (!sdynamic)
return true;
@@ -3872,7 +3873,7 @@ bfd_elf_add_dt_needed_tag (bfd *abfd, struct bfd_link_info *info)
bfd_byte *extdyn;
bed = get_elf_backend_data (hash_table->dynobj);
- sdyn = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+ sdyn = hash_table->dynamic;
if (sdyn != NULL && sdyn->size != 0)
for (extdyn = sdyn->contents;
extdyn < sdyn->contents + sdyn->size;
@@ -4017,7 +4018,7 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
info->callbacks->examine_strtab (dynstr);
bed = get_elf_backend_data (dynobj);
- sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ sdyn = hash_table->dynamic;
BFD_ASSERT (sdyn != NULL);
/* Update all .dynamic entries referencing .dynstr strings. */
@@ -8352,6 +8353,9 @@ _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);
+ /* NB: htab->dynamic->contents is always allocated by bfd_realloc. */
+ if (htab->dynamic != NULL)
+ free (htab->dynamic->contents);
if (htab->first_hash != NULL)
{
bfd_hash_table_free (htab->first_hash);
@@ -13420,7 +13424,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
bfd_byte *dyncon, *dynconend;
/* Fix up .dynamic entries. */
- o = bfd_get_linker_section (dynobj, ".dynamic");
+ o = htab->dynamic;
BFD_ASSERT (o != NULL);
dyncon = o->contents;
@@ -13654,7 +13658,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
/* Check for DT_TEXTREL (late, in case the backend removes it). */
if (bfd_link_textrel_check (info)
- && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL
+ && (o = htab->dynamic) != NULL
&& o->size != 0)
{
bfd_byte *dyncon, *dynconend;
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 7d189bc..725884e 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2715,7 +2715,7 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
return htab;
dynobj = htab->elf.dynobj;
- sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+ sdyn = htab->elf.dynamic;
/* GOT is always created in setup_gnu_properties. But it may not be
needed. .got.plt section may be needed for static IFUNC. */