diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2024-04-09 18:41:59 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2024-04-10 19:50:01 -0700 |
commit | c3460201a64b641e3a2089b7fca7ae17a9ddfb85 (patch) | |
tree | fbb669a56a9b501570ca833010d1cc1696b8a414 | |
parent | ea3002bc4d2a3c8ad284041f8a7dd08472c3f5fa (diff) | |
download | gdb-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.
-rw-r--r-- | bfd/elf-bfd.h | 1 | ||||
-rw-r--r-- | bfd/elflink.c | 16 | ||||
-rw-r--r-- | bfd/elfxx-x86.c | 2 |
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. */ |