* 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.
(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 *);
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;
}
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);
}
= (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. */
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. */
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)
{
#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
= (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. */
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
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. */
htab_delete (htab->multi_got_.bfd2got);
htab->multi_got_.bfd2got = NULL;
}
+ _bfd_elf_link_hash_table_free (_htab);
}
/* Set the right machine number. */
= (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
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. */
#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
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. */
= (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
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. */
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. */
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
{
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;
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;
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. */
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. */
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;
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;
}
\f
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. */
#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
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);
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);
*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);
+ }
+}