From 9f7c3e5e99a620b68f6b2d0f3b17329e40b8d781 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 11 Feb 2013 05:30:54 +0000 Subject: [PATCH] * elfcode.h (elf_checksum_contents): Free contents. * elf-bfd.h (_bfd_elf_link_hash_table_free): Declare. * elflink.c (_bfd_elf_link_hash_table_free): New function. (elf_final_link_free): New function, extracted from.. (bfd_elf_final_link): ..here. Always call _bfd_elf_write_section_eh_frame_hdr. * elfxx-target.h (bfd_elfNN_bfd_link_hash_table_free): Default to _bfd_elf_link_hash_table_free. * libbfd-in.h (_bfd_merge_sections_free): Declare. * libbfd.h: Regenerate. * merge.c (_bfd_merge_sections_free): New function. * elf-eh-frame.c (_bfd_elf_write_section_eh_frame_hdr): Free hdr_info->array. * elf-m10300.c (elf32_mn10300_link_hash_table_free): Call _bfd_elf_link_hash_table_free. * elf32-arm.c (elf32_arm_link_hash_table_free): Likewise. * elf32-avr.c (elf32_avr_link_hash_table_free): Likewise. * elf32-hppa.c (elf32_hppa_link_hash_table_free): Likewise. * elf32-i386.c (elf_i386_link_hash_table_free): Likewise. * elf32-m68hc1x.c (m68hc11_elf_hash_table_free): Likewise. * elf32-m68k.c (elf_m68k_link_hash_table_free): Likewise. * elf32-metag.c (elf_metag_link_hash_table_free): Likewise. * elf32-xgate.c (xgate_elf_bfd_link_hash_table_free): Likewise. * elf64-aarch64.c (elf64_aarch64_link_hash_table_free): Likewise. * elf64-ia64-vms.c (elf64_ia64_hash_table_free): Likewise. * elf64-ppc.c (ppc64_elf_link_hash_table_free): Likewise. * elf64-x86-64.c (elf_x86_64_link_hash_table_free): Likewise. * elfnn-ia64.c (elfNN_ia64_hash_table_free): Likewise. * elf32-cr16.c (elf32_cr16_link_hash_table_free): Delete. (bfd_elf32_bfd_link_hash_table_free): Don't define. * elf32-tic6x.c (elf32_tic6x_link_hash_table_free): Delete. (bfd_elf32_bfd_link_hash_table_free): Dont' define. --- bfd/elf-bfd.h | 2 + bfd/elf-eh-frame.c | 117 ++++++++++++++++++++++-------------------- bfd/elf-m10300.c | 4 +- bfd/elf32-arm.c | 2 +- bfd/elf32-avr.c | 2 +- bfd/elf32-cr16.c | 14 ----- bfd/elf32-hppa.c | 2 +- bfd/elf32-i386.c | 2 +- bfd/elf32-m68hc1x.c | 2 +- bfd/elf32-m68k.c | 1 + bfd/elf32-metag.c | 2 +- bfd/elf32-tic6x.c | 9 ---- bfd/elf32-xgate.c | 2 +- bfd/elf64-aarch64.c | 2 +- bfd/elf64-ia64-vms.c | 2 +- bfd/elf64-ppc.c | 2 +- bfd/elf64-x86-64.c | 2 +- bfd/elfcode.h | 27 ++++++---- bfd/elflink.c | 118 +++++++++++++++++++------------------------ bfd/elfnn-ia64.c | 2 +- bfd/elfxx-target.h | 2 +- bfd/libbfd-in.h | 4 ++ bfd/libbfd.h | 4 ++ bfd/merge.c | 14 +++++ 24 files changed, 172 insertions(+), 168 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index e3876257d9d..a93e0d40133 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1804,6 +1804,8 @@ extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create (bfd *); +extern void _bfd_elf_link_hash_table_free + (struct bfd_link_hash_table *); extern void _bfd_elf_link_hash_copy_indirect (struct bfd_link_info *, struct elf_link_hash_entry *, struct elf_link_hash_entry *); diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index a75d806165a..24ae741cb07 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -1770,74 +1770,81 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) struct elf_link_hash_table *htab; struct eh_frame_hdr_info *hdr_info; asection *sec; - bfd_byte *contents; - asection *eh_frame_sec; - bfd_size_type size; - bfd_boolean retval; - bfd_vma encoded_eh_frame; + bfd_boolean retval = TRUE; htab = elf_hash_table (info); hdr_info = &htab->eh_info; sec = hdr_info->hdr_sec; - if (sec == NULL) - return TRUE; - - size = EH_FRAME_HDR_SIZE; - if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count) - size += 4 + hdr_info->fde_count * 8; - contents = (bfd_byte *) bfd_malloc (size); - if (contents == NULL) - return FALSE; - eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame"); - if (eh_frame_sec == NULL) + if (info->eh_frame_hdr && sec != NULL) { - free (contents); - return FALSE; - } + bfd_byte *contents; + asection *eh_frame_sec; + bfd_size_type size; + bfd_vma encoded_eh_frame; + + size = EH_FRAME_HDR_SIZE; + if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count) + size += 4 + hdr_info->fde_count * 8; + contents = (bfd_byte *) bfd_malloc (size); + if (contents == NULL) + return FALSE; - memset (contents, 0, EH_FRAME_HDR_SIZE); - contents[0] = 1; /* Version. */ - contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address - (abfd, info, eh_frame_sec, 0, sec, 4, - &encoded_eh_frame); /* .eh_frame offset. */ + eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame"); + if (eh_frame_sec == NULL) + { + free (contents); + return FALSE; + } - if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count) - { - contents[2] = DW_EH_PE_udata4; /* FDE count encoding. */ - contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc. */ - } - else - { - contents[2] = DW_EH_PE_omit; - contents[3] = DW_EH_PE_omit; - } - bfd_put_32 (abfd, encoded_eh_frame, contents + 4); + memset (contents, 0, EH_FRAME_HDR_SIZE); + /* Version. */ + contents[0] = 1; + /* .eh_frame offset. */ + contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address + (abfd, info, eh_frame_sec, 0, sec, 4, &encoded_eh_frame); - if (contents[2] != DW_EH_PE_omit) - { - unsigned int i; + if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count) + { + /* FDE count encoding. */ + contents[2] = DW_EH_PE_udata4; + /* Search table encoding. */ + contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; + } + else + { + contents[2] = DW_EH_PE_omit; + contents[3] = DW_EH_PE_omit; + } + bfd_put_32 (abfd, encoded_eh_frame, contents + 4); - bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE); - qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array), - vma_compare); - for (i = 0; i < hdr_info->fde_count; i++) + if (contents[2] != DW_EH_PE_omit) { - bfd_put_32 (abfd, - hdr_info->array[i].initial_loc - - sec->output_section->vma, - contents + EH_FRAME_HDR_SIZE + i * 8 + 4); - bfd_put_32 (abfd, - hdr_info->array[i].fde - sec->output_section->vma, - contents + EH_FRAME_HDR_SIZE + i * 8 + 8); + unsigned int i; + + bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE); + qsort (hdr_info->array, hdr_info->fde_count, + sizeof (*hdr_info->array), vma_compare); + for (i = 0; i < hdr_info->fde_count; i++) + { + bfd_put_32 (abfd, + hdr_info->array[i].initial_loc + - sec->output_section->vma, + contents + EH_FRAME_HDR_SIZE + i * 8 + 4); + bfd_put_32 (abfd, + hdr_info->array[i].fde - sec->output_section->vma, + contents + EH_FRAME_HDR_SIZE + i * 8 + 8); + } } - } - /* FIXME: octets_per_byte. */ - retval = bfd_set_section_contents (abfd, sec->output_section, - contents, (file_ptr) sec->output_offset, - sec->size); - free (contents); + /* FIXME: octets_per_byte. */ + retval = bfd_set_section_contents (abfd, sec->output_section, contents, + (file_ptr) sec->output_offset, + sec->size); + free (contents); + } + if (hdr_info->array != NULL) + free (hdr_info->array); return retval; } diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index fb38f343151..6171febd864 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -4646,9 +4646,9 @@ elf32_mn10300_link_hash_table_free (struct bfd_link_hash_table *hash) struct elf32_mn10300_link_hash_table *ret = (struct elf32_mn10300_link_hash_table *) hash; - _bfd_generic_link_hash_table_free + _bfd_elf_link_hash_table_free ((struct bfd_link_hash_table *) ret->static_hash_table); - _bfd_generic_link_hash_table_free + _bfd_elf_link_hash_table_free ((struct bfd_link_hash_table *) ret); } diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index ee37915d0c0..97b1bf0296e 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3460,7 +3460,7 @@ elf32_arm_hash_table_free (struct bfd_link_hash_table *hash) = (struct elf32_arm_link_hash_table *) hash; bfd_hash_table_free (&ret->stub_hash_table); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Determine if we're dealing with a Thumb only architecture. */ diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 6cec6843b16..a2d440129a4 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -708,7 +708,7 @@ elf32_avr_link_hash_table_free (struct bfd_link_hash_table *btab) free (htab->amt_destination_addr); bfd_hash_table_free (&htab->bstab); - _bfd_generic_link_hash_table_free (btab); + _bfd_elf_link_hash_table_free (btab); } /* Calculates the effective distance of a pc relative jump/call. */ diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c index 4b3aa733b53..449775b2cb6 100644 --- a/bfd/elf32-cr16.c +++ b/bfd/elf32-cr16.c @@ -1676,18 +1676,6 @@ elf32_cr16_link_hash_table_create (bfd *abfd) return &ret->root; } -/* Free an cr16 ELF linker hash table. */ - -static void -elf32_cr16_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - struct elf_link_hash_table *ret - = (struct elf_link_hash_table *) hash; - - _bfd_generic_link_hash_table_free - ((struct bfd_link_hash_table *) ret); -} - static unsigned long elf_cr16_mach (flagword flags) { @@ -2973,8 +2961,6 @@ _bfd_cr16_elf_reloc_type_class (const Elf_Internal_Rela *rela) #define bfd_elf32_bfd_link_hash_table_create \ elf32_cr16_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free \ - elf32_cr16_link_hash_table_free #define elf_backend_create_dynamic_sections \ _bfd_cr16_elf_create_dynamic_sections diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 2c1b9dbaebf..5399d496bec 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -450,7 +450,7 @@ elf32_hppa_link_hash_table_free (struct bfd_link_hash_table *btab) = (struct elf32_hppa_link_hash_table *) btab; bfd_hash_table_free (&htab->bstab); - _bfd_generic_link_hash_table_free (btab); + _bfd_elf_link_hash_table_free (btab); } /* Build a name for an entry in the stub hash table. */ diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index b6004ef9870..16dd28eb01b 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -976,7 +976,7 @@ elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash) htab_delete (htab->loc_hash_table); if (htab->loc_hash_memory) objalloc_free ((struct objalloc *) htab->loc_hash_memory); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index 6cef46d0858..98c29944621 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -105,7 +105,7 @@ m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash) bfd_hash_table_free (ret->stub_hash_table); free (ret->stub_hash_table); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Assorted hash table functions. */ diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 26fef9fcacb..d47f7533e3f 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -982,6 +982,7 @@ elf_m68k_link_hash_table_free (struct bfd_link_hash_table *_htab) htab_delete (htab->multi_got_.bfd2got); htab->multi_got_.bfd2got = NULL; } + _bfd_elf_link_hash_table_free (_htab); } /* Set the right machine number. */ diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 821cea15523..2d42517a297 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -1057,7 +1057,7 @@ elf_metag_link_hash_table_free (struct bfd_link_hash_table *btab) = (struct elf_metag_link_hash_table *) btab; bfd_hash_table_free (&htab->bstab); - _bfd_generic_link_hash_table_free (btab); + _bfd_elf_link_hash_table_free (btab); } /* Section name for stubs is the associated section name plus this diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c index d376fe1d431..8f03003e2fa 100644 --- a/bfd/elf32-tic6x.c +++ b/bfd/elf32-tic6x.c @@ -1614,14 +1614,6 @@ elf32_tic6x_final_link (bfd *abfd, struct bfd_link_info *info) return TRUE; } -/* Destroy a C6X ELF linker hash table. */ - -static void -elf32_tic6x_link_hash_table_free (struct bfd_link_hash_table *hash) -{ - _bfd_generic_link_hash_table_free (hash); -} - /* Called to pass PARAMS to the backend. We store them in the hash table associated with INFO. */ @@ -4374,7 +4366,6 @@ elf32_tic6x_set_osabi (bfd *abfd, struct bfd_link_info *link_info) #define bfd_elf32_bfd_merge_private_bfd_data elf32_tic6x_merge_private_bfd_data #define bfd_elf32_mkobject elf32_tic6x_mkobject #define bfd_elf32_bfd_link_hash_table_create elf32_tic6x_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_free elf32_tic6x_link_hash_table_free #define bfd_elf32_new_section_hook elf32_tic6x_new_section_hook #define elf_backend_stack_align 8 #define elf_backend_can_gc_sections 1 diff --git a/bfd/elf32-xgate.c b/bfd/elf32-xgate.c index ad2190b3a2c..b822260277c 100644 --- a/bfd/elf32-xgate.c +++ b/bfd/elf32-xgate.c @@ -437,7 +437,7 @@ xgate_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash) bfd_hash_table_free (ret->stub_hash_table); free (ret->stub_hash_table); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Create a XGATE ELF linker hash table. */ diff --git a/bfd/elf64-aarch64.c b/bfd/elf64-aarch64.c index e588d82c241..4b8fe435237 100644 --- a/bfd/elf64-aarch64.c +++ b/bfd/elf64-aarch64.c @@ -2129,7 +2129,7 @@ elf64_aarch64_hash_table_free (struct bfd_link_hash_table *hash) = (struct elf64_aarch64_link_hash_table *) hash; bfd_hash_table_free (&ret->stub_hash_table); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } static bfd_vma diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c index 85a61928e22..6747e0c6e29 100644 --- a/bfd/elf64-ia64-vms.c +++ b/bfd/elf64-ia64-vms.c @@ -1072,7 +1072,7 @@ elf64_ia64_hash_table_free (struct bfd_link_hash_table *hash) objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory); elf_link_hash_traverse (&ia64_info->root, elf64_ia64_global_dyn_info_free, NULL); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Traverse both local and global hash tables. */ diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 310b9d6dbc3..82b3e4128d0 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4043,7 +4043,7 @@ ppc64_elf_link_hash_table_free (struct bfd_link_hash_table *hash) bfd_hash_table_free (&htab->branch_hash_table); if (htab->tocsave_htab) htab_delete (htab->tocsave_htab); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Satisfy the ELF linker by filling in some fields in our fake bfd. */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index f709c7a0985..045b2815c0a 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -944,7 +944,7 @@ elf_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash) htab_delete (htab->loc_hash_table); if (htab->loc_hash_memory) objalloc_free ((struct objalloc *) htab->loc_hash_memory); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 298ba3526df..63a33068c98 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1071,6 +1071,7 @@ elf_checksum_contents (bfd *abfd, { Elf_Internal_Shdr i_shdr; Elf_External_Shdr x_shdr; + bfd_byte *contents, *free_contents; i_shdr = *i_shdrp[count]; i_shdr.sh_offset = 0; @@ -1078,28 +1079,36 @@ elf_checksum_contents (bfd *abfd, elf_swap_shdr_out (abfd, &i_shdr, &x_shdr); (*process) (&x_shdr, sizeof x_shdr, arg); - /* PR ld/12451: - Process the section's contents, if it has some. Read them in if necessary. */ - if (i_shdr.contents) - (*process) (i_shdr.contents, i_shdr.sh_size, arg); - else if (i_shdr.sh_type != SHT_NOBITS) + /* Process the section's contents, if it has some. + PR ld/12451: Read them in if necessary. */ + if (i_shdr.sh_type == SHT_NOBITS) + continue; + free_contents = NULL; + contents = i_shdr.contents; + if (contents == NULL) { asection *sec; sec = bfd_section_from_elf_index (abfd, count); if (sec != NULL) { - if (sec->contents == NULL) + contents = sec->contents; + if (contents == NULL) { /* Force rereading from file. */ sec->flags &= ~SEC_IN_MEMORY; - if (! bfd_malloc_and_get_section (abfd, sec, & sec->contents)) + if (!bfd_malloc_and_get_section (abfd, sec, &free_contents)) continue; + contents = free_contents; } - if (sec->contents != NULL) - (*process) (sec->contents, i_shdr.sh_size, arg); } } + if (contents != NULL) + { + (*process) (contents, i_shdr.sh_size, arg); + if (free_contents != NULL) + free (free_contents); + } } return TRUE; diff --git a/bfd/elflink.c b/bfd/elflink.c index 1bae437fc33..d423ca41a21 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -6962,6 +6962,18 @@ _bfd_elf_link_hash_table_create (bfd *abfd) return &ret->root; } +/* Destroy an ELF linker hash table. */ + +void +_bfd_elf_link_hash_table_free (struct bfd_link_hash_table *hash) +{ + struct elf_link_hash_table *htab = (struct elf_link_hash_table *) hash; + if (htab->dynstr != NULL) + _bfd_elf_strtab_free (htab->dynstr); + _bfd_merge_sections_free (htab->merge_info); + _bfd_generic_link_hash_table_free (hash); +} + /* This is a hook for the ELF emulation code in the generic linker to tell the backend linker what file name to use for the DT_NEEDED entry for a dynamic object. */ @@ -10432,6 +10444,42 @@ elf_fixup_link_order (bfd *abfd, asection *o) return TRUE; } +static void +elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo) +{ + asection *o; + + if (flinfo->symstrtab != NULL) + _bfd_stringtab_free (flinfo->symstrtab); + if (flinfo->contents != NULL) + free (flinfo->contents); + if (flinfo->external_relocs != NULL) + free (flinfo->external_relocs); + if (flinfo->internal_relocs != NULL) + free (flinfo->internal_relocs); + if (flinfo->external_syms != NULL) + free (flinfo->external_syms); + if (flinfo->locsym_shndx != NULL) + free (flinfo->locsym_shndx); + if (flinfo->internal_syms != NULL) + free (flinfo->internal_syms); + if (flinfo->indices != NULL) + free (flinfo->indices); + if (flinfo->sections != NULL) + free (flinfo->sections); + if (flinfo->symbuf != NULL) + free (flinfo->symbuf); + if (flinfo->symshndxbuf != NULL) + free (flinfo->symshndxbuf); + for (o = obfd->sections; o != NULL; o = o->next) + { + struct bfd_elf_section_data *esdo = elf_section_data (o); + if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL) + free (esdo->rel.hashes); + if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL) + free (esdo->rela.hashes); + } +} /* Do the final step of an ELF link. */ @@ -11479,42 +11527,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) goto error_return; } - if (info->eh_frame_hdr) - { - if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) - goto error_return; - } + if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) + goto error_return; - if (flinfo.symstrtab != NULL) - _bfd_stringtab_free (flinfo.symstrtab); - if (flinfo.contents != NULL) - free (flinfo.contents); - if (flinfo.external_relocs != NULL) - free (flinfo.external_relocs); - if (flinfo.internal_relocs != NULL) - free (flinfo.internal_relocs); - if (flinfo.external_syms != NULL) - free (flinfo.external_syms); - if (flinfo.locsym_shndx != NULL) - free (flinfo.locsym_shndx); - if (flinfo.internal_syms != NULL) - free (flinfo.internal_syms); - if (flinfo.indices != NULL) - free (flinfo.indices); - if (flinfo.sections != NULL) - free (flinfo.sections); - if (flinfo.symbuf != NULL) - free (flinfo.symbuf); - if (flinfo.symshndxbuf != NULL) - free (flinfo.symshndxbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL) - free (esdo->rel.hashes); - if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL) - free (esdo->rela.hashes); - } + elf_final_link_free (abfd, &flinfo); elf_tdata (abfd)->linker = TRUE; @@ -11531,37 +11547,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) return TRUE; error_return: - if (flinfo.symstrtab != NULL) - _bfd_stringtab_free (flinfo.symstrtab); - if (flinfo.contents != NULL) - free (flinfo.contents); - if (flinfo.external_relocs != NULL) - free (flinfo.external_relocs); - if (flinfo.internal_relocs != NULL) - free (flinfo.internal_relocs); - if (flinfo.external_syms != NULL) - free (flinfo.external_syms); - if (flinfo.locsym_shndx != NULL) - free (flinfo.locsym_shndx); - if (flinfo.internal_syms != NULL) - free (flinfo.internal_syms); - if (flinfo.indices != NULL) - free (flinfo.indices); - if (flinfo.sections != NULL) - free (flinfo.sections); - if (flinfo.symbuf != NULL) - free (flinfo.symbuf); - if (flinfo.symshndxbuf != NULL) - free (flinfo.symshndxbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - if ((o->flags & SEC_RELOC) != 0 && esdo->rel.hashes != NULL) - free (esdo->rel.hashes); - if ((o->flags & SEC_RELOC) != 0 && esdo->rela.hashes != NULL) - free (esdo->rela.hashes); - } - + elf_final_link_free (abfd, &flinfo); return FALSE; } diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c index afa1e0448d3..864feba215f 100644 --- a/bfd/elfnn-ia64.c +++ b/bfd/elfnn-ia64.c @@ -1463,7 +1463,7 @@ elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash) objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory); elf_link_hash_traverse (&ia64_info->root, elfNN_ia64_global_dyn_info_free, NULL); - _bfd_generic_link_hash_table_free (hash); + _bfd_elf_link_hash_table_free (hash); } /* Traverse both local and global hash tables. */ diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 241743ab42c..e22b2b9a8b3 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -233,7 +233,7 @@ #endif #ifndef bfd_elfNN_bfd_link_hash_table_free -#define bfd_elfNN_bfd_link_hash_table_free _bfd_generic_link_hash_table_free +#define bfd_elfNN_bfd_link_hash_table_free _bfd_elf_link_hash_table_free #endif #ifdef elf_backend_relocate_section diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 80cb05104e0..52c1f5f88ca 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -707,6 +707,10 @@ extern bfd_boolean _bfd_write_merged_section extern bfd_vma _bfd_merged_section_offset (bfd *, asection **, void *, bfd_vma); +/* Tidy up when done. */ + +extern void _bfd_merge_sections_free (void *); + /* Create a string table. */ extern struct bfd_strtab_hash *_bfd_stringtab_init (void); diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 729fd11a815..bcd76a0f2aa 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -712,6 +712,10 @@ extern bfd_boolean _bfd_write_merged_section extern bfd_vma _bfd_merged_section_offset (bfd *, asection **, void *, bfd_vma); +/* Tidy up when done. */ + +extern void _bfd_merge_sections_free (void *); + /* Create a string table. */ extern struct bfd_strtab_hash *_bfd_stringtab_init (void); diff --git a/bfd/merge.c b/bfd/merge.c index aef3cf35a55..0e49faeaffe 100644 --- a/bfd/merge.c +++ b/bfd/merge.c @@ -885,3 +885,17 @@ _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec, *psec = entry->secinfo->sec; return entry->u.index + (secinfo->contents + offset - p); } + +/* Tidy up when done. */ + +void +_bfd_merge_sections_free (void *xsinfo) +{ + struct sec_merge_info *sinfo; + + for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next) + { + bfd_hash_table_free (&sinfo->htab->table); + free (sinfo->htab); + } +} -- 2.30.2