Free linker hash table from bfd_close.

Also tidies numerous error exit paths in various link_hash_table_create
functions that failed to free memory.

include/
	* bfdlink.h (struct bfd_link_hash_table): Add hash_table_free field.
bfd/
	* archive.c: Include bfdlink.h.
	(_bfd_archive_close_and_cleanup): Call linker hash_table_free.
	* bfd.c (struct bfd): Add is_linker_output field.
	* elf-bfd.h (_bfd_elf_link_hash_table_free): Update prototype.
	* linker.c (_bfd_link_hash_table_init): Set up hash_table_free,
	link.hash and is_linker_output.
	(_bfd_generic_link_hash_table_free): Replace bfd_link_hash_table*
	param with bfd*.  Assert is_linker_output and link.hash, and
	clear them before exit.
	* elf-m10300.c (elf32_mn10300_link_hash_table_free): Replace
	bfd_link_hash_table* param with bfd*.  Hack is_linker_output
	and link.hash so we can free two linker hash tables.
	(elf32_mn10300_link_hash_table_create): Create static_hash_table
	first.  Clean up on errors.  Set hash_table_free pointer.
	* elf32-arm.c (elf32_arm_link_hash_table_free): Replace
	bfd_link_hash_table* param with bfd*.
	(elf32_arm_link_hash_table_create): Clean up on errors.  Set
	hash_table_free pointer.
	* elf32-avr.c, * elf32-hppa.c, * elf32-i386.c, * elf32-m68hc1x.c,
	* elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c, * elf32-xgate.c,
	* elf64-ia64-vms.c, * elf64-ppc.c, * elf64-x86-64.c, * elflink.c,
	* elfnn-aarch64.c, * elfnn-ia64.c, * elfxx-sparc.c,
	* xcofflink.c: Similarly.
	* simple.c (bfd_simple_get_relocated_section_contents): Save and
	clear link.next before creating linker hash table.  Clean up on
	errors, and restore link.next on exit.
	* elf32-m68hc1x.h (m68hc11_elf_bfd_link_hash_table_free): Delete.
	* elf32-xgate.h (xgate_elf_bfd_link_hash_table_free): Delete.
	* elfxx-sparc.h (_bfd_sparc_elf_link_hash_table_free): Delete.
	* libcoff-in.h (_bfd_xcoff_bfd_link_hash_table_free): Delete.
	* hash.c (bfd_hash_table_init_n): Free table on error.
	* libbfd-in.h (_bfd_generic_link_hash_table_free): Update proto.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
	* libcoff.h: Regenerate.
This commit is contained in:
Alan Modra 2014-06-13 19:11:39 +09:30
parent caa4096e84
commit d495ab0d84
35 changed files with 237 additions and 129 deletions

View File

@ -1,3 +1,41 @@
2014-06-13 Alan Modra <amodra@gmail.com>
* archive.c: Include bfdlink.h.
(_bfd_archive_close_and_cleanup): Call linker hash_table_free.
* bfd.c (struct bfd): Add is_linker_output field.
* elf-bfd.h (_bfd_elf_link_hash_table_free): Update prototype.
* linker.c (_bfd_link_hash_table_init): Set up hash_table_free,
link.hash and is_linker_output.
(_bfd_generic_link_hash_table_free): Replace bfd_link_hash_table*
param with bfd*. Assert is_linker_output and link.hash, and
clear them before exit.
* elf-m10300.c (elf32_mn10300_link_hash_table_free): Replace
bfd_link_hash_table* param with bfd*. Hack is_linker_output
and link.hash so we can free two linker hash tables.
(elf32_mn10300_link_hash_table_create): Create static_hash_table
first. Clean up on errors. Set hash_table_free pointer.
* elf32-arm.c (elf32_arm_link_hash_table_free): Replace
bfd_link_hash_table* param with bfd*.
(elf32_arm_link_hash_table_create): Clean up on errors. Set
hash_table_free pointer.
* elf32-avr.c, * elf32-hppa.c, * elf32-i386.c, * elf32-m68hc1x.c,
* elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c, * elf32-xgate.c,
* elf64-ia64-vms.c, * elf64-ppc.c, * elf64-x86-64.c, * elflink.c,
* elfnn-aarch64.c, * elfnn-ia64.c, * elfxx-sparc.c,
* xcofflink.c: Similarly.
* simple.c (bfd_simple_get_relocated_section_contents): Save and
clear link.next before creating linker hash table. Clean up on
errors, and restore link.next on exit.
* elf32-m68hc1x.h (m68hc11_elf_bfd_link_hash_table_free): Delete.
* elf32-xgate.h (xgate_elf_bfd_link_hash_table_free): Delete.
* elfxx-sparc.h (_bfd_sparc_elf_link_hash_table_free): Delete.
* libcoff-in.h (_bfd_xcoff_bfd_link_hash_table_free): Delete.
* hash.c (bfd_hash_table_init_n): Free table on error.
* libbfd-in.h (_bfd_generic_link_hash_table_free): Update proto.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* libcoff.h: Regenerate.
2014-06-13 Alan Modra <amodra@gmail.com>
PR 17047

View File

@ -140,6 +140,7 @@ SUBSECTION
#include "safe-ctype.h"
#include "hashtab.h"
#include "filenames.h"
#include "bfdlink.h"
#ifndef errno
extern int errno;
@ -2751,5 +2752,8 @@ _bfd_archive_close_and_cleanup (bfd *abfd)
}
}
}
if (abfd->is_linker_output)
(*abfd->link.hash->hash_table_free) (abfd);
return TRUE;
}

View File

@ -6488,6 +6488,9 @@ struct bfd
/* Set if only required symbols should be added in the link hash table for
this object. Used by VMS linkers. */
unsigned int selective_search : 1;
/* Set if this is the linker output BFD. */
unsigned int is_linker_output : 1;
};
/* See note beside bfd_set_section_userdata. */

View File

@ -313,6 +313,9 @@ CODE_FRAGMENT
. {* Set if only required symbols should be added in the link hash table for
. this object. Used by VMS linkers. *}
. unsigned int selective_search : 1;
.
. {* Set if this is the linker output BFD. *}
. unsigned int is_linker_output : 1;
.};
.
.{* See note beside bfd_set_section_userdata. *}

View File

@ -1816,7 +1816,7 @@ extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc
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 *);
(bfd *);
extern void _bfd_elf_link_hash_copy_indirect
(struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);

View File

@ -4601,15 +4601,16 @@ _bfd_mn10300_copy_indirect_symbol (struct bfd_link_info * info,
/* Destroy an mn10300 ELF linker hash table. */
static void
elf32_mn10300_link_hash_table_free (struct bfd_link_hash_table *hash)
elf32_mn10300_link_hash_table_free (bfd *obfd)
{
struct elf32_mn10300_link_hash_table *ret
= (struct elf32_mn10300_link_hash_table *) hash;
= (struct elf32_mn10300_link_hash_table *) obfd->link.hash;
_bfd_elf_link_hash_table_free
((struct bfd_link_hash_table *) ret->static_hash_table);
_bfd_elf_link_hash_table_free
((struct bfd_link_hash_table *) ret);
obfd->link.hash = &ret->static_hash_table->root.root;
_bfd_elf_link_hash_table_free (obfd);
obfd->is_linker_output = TRUE;
obfd->link.hash = &ret->root.root;
_bfd_elf_link_hash_table_free (obfd);
}
/* Create an mn10300 ELF linker hash table. */
@ -4624,17 +4625,6 @@ elf32_mn10300_link_hash_table_create (bfd *abfd)
if (ret == NULL)
return NULL;
if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
elf32_mn10300_link_hash_newfunc,
sizeof (struct elf32_mn10300_link_hash_entry),
MN10300_ELF_DATA))
{
free (ret);
return NULL;
}
ret->tls_ldm_got.offset = -1;
amt = sizeof (struct elf_link_hash_table);
ret->static_hash_table = bfd_zmalloc (amt);
if (ret->static_hash_table == NULL)
@ -4652,7 +4642,24 @@ elf32_mn10300_link_hash_table_create (bfd *abfd)
free (ret);
return NULL;
}
(void) elf32_mn10300_link_hash_table_free;
abfd->is_linker_output = FALSE;
abfd->link.hash = NULL;
if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
elf32_mn10300_link_hash_newfunc,
sizeof (struct elf32_mn10300_link_hash_entry),
MN10300_ELF_DATA))
{
abfd->is_linker_output = TRUE;
abfd->link.hash = &ret->static_hash_table->root.root;
_bfd_elf_link_hash_table_free (abfd);
free (ret);
return NULL;
}
ret->root.root.hash_table_free = elf32_mn10300_link_hash_table_free;
ret->tls_ldm_got.offset = -1;
return & ret->root.root;
}

View File

@ -3526,13 +3526,13 @@ elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
/* Destroy an ARM elf linker hash table. */
static void
elf32_arm_link_hash_table_free (struct bfd_link_hash_table *hash)
elf32_arm_link_hash_table_free (bfd *obfd)
{
struct elf32_arm_link_hash_table *ret
= (struct elf32_arm_link_hash_table *) hash;
= (struct elf32_arm_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (&ret->stub_hash_table);
_bfd_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create an ARM elf linker hash table. */
@ -3570,10 +3570,10 @@ elf32_arm_link_hash_table_create (bfd *abfd)
if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
sizeof (struct elf32_arm_stub_hash_entry)))
{
free (ret);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
(void) elf32_arm_link_hash_table_free;
ret->root.root.hash_table_free = elf32_arm_link_hash_table_free;
return &ret->root.root;
}

View File

@ -714,10 +714,10 @@ elf32_avr_link_hash_newfunc (struct bfd_hash_entry * entry,
/* Free the derived linker hash table. */
static void
elf32_avr_link_hash_table_free (struct bfd_link_hash_table *btab)
elf32_avr_link_hash_table_free (bfd *obfd)
{
struct elf32_avr_link_hash_table *htab
= (struct elf32_avr_link_hash_table *) btab;
= (struct elf32_avr_link_hash_table *) obfd->link.hash;
/* Free the address mapping table. */
if (htab->amt_stub_offsets != NULL)
@ -726,7 +726,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_elf_link_hash_table_free (btab);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create the derived linker hash table. The AVR ELF port uses the derived
@ -755,8 +755,11 @@ elf32_avr_link_hash_table_create (bfd *abfd)
/* Init the stub hash table too. */
if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
sizeof (struct elf32_avr_stub_hash_entry)))
return NULL;
(void) elf32_avr_link_hash_table_free;
{
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
htab->etab.root.hash_table_free = elf32_avr_link_hash_table_free;
return &htab->etab.root;
}

View File

@ -410,13 +410,13 @@ hppa_link_hash_newfunc (struct bfd_hash_entry *entry,
/* Free the derived linker hash table. */
static void
elf32_hppa_link_hash_table_free (struct bfd_link_hash_table *btab)
elf32_hppa_link_hash_table_free (bfd *obfd)
{
struct elf32_hppa_link_hash_table *htab
= (struct elf32_hppa_link_hash_table *) btab;
= (struct elf32_hppa_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (&htab->bstab);
_bfd_elf_link_hash_table_free (btab);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create the derived linker hash table. The PA ELF port uses the derived
@ -444,8 +444,11 @@ elf32_hppa_link_hash_table_create (bfd *abfd)
/* Init the stub hash table too. */
if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
sizeof (struct elf32_hppa_stub_hash_entry)))
return NULL;
(void) elf32_hppa_link_hash_table_free;
{
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
htab->etab.root.hash_table_free = elf32_hppa_link_hash_table_free;
htab->text_segment_base = (bfd_vma) -1;
htab->data_segment_base = (bfd_vma) -1;

View File

@ -930,16 +930,16 @@ elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab,
/* Destroy an i386 ELF linker hash table. */
static void
elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash)
elf_i386_link_hash_table_free (bfd *obfd)
{
struct elf_i386_link_hash_table *htab
= (struct elf_i386_link_hash_table *) hash;
= (struct elf_i386_link_hash_table *) obfd->link.hash;
if (htab->loc_hash_table)
htab_delete (htab->loc_hash_table);
if (htab->loc_hash_memory)
objalloc_free ((struct objalloc *) htab->loc_hash_memory);
_bfd_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create an i386 ELF linker hash table. */
@ -970,10 +970,10 @@ elf_i386_link_hash_table_create (bfd *abfd)
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
elf_i386_link_hash_table_free (abfd);
return NULL;
}
(void) elf_i386_link_hash_table_free;
ret->elf.root.hash_table_free = elf_i386_link_hash_table_free;
return &ret->elf.root;
}

View File

@ -60,15 +60,15 @@ struct m68hc11_scan_param
/* Destroy a 68HC11/68HC12 ELF linker hash table. */
void
m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
static void
m68hc11_elf_bfd_link_hash_table_free (bfd *obfd)
{
struct m68hc11_elf_link_hash_table *ret
= (struct m68hc11_elf_link_hash_table *) hash;
= (struct m68hc11_elf_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (ret->stub_hash_table);
free (ret->stub_hash_table);
_bfd_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create a 68HC11/68HC12 ELF linker hash table. */
@ -97,12 +97,17 @@ m68hc11_elf_hash_table_create (bfd *abfd)
ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
if (ret->stub_hash_table == NULL)
{
free (ret);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
sizeof (struct elf32_m68hc11_stub_hash_entry)))
return NULL;
{
free (ret->stub_hash_table);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
ret->root.root.hash_table_free = m68hc11_elf_bfd_link_hash_table_free;
return ret;
}

View File

@ -136,7 +136,6 @@ struct m68hc11_elf_link_hash_table
extern struct m68hc11_elf_link_hash_table* m68hc11_elf_hash_table_create
(bfd*);
extern void m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table*);
extern void m68hc11_elf_get_bank_parameters (struct bfd_link_info*);

View File

@ -943,18 +943,18 @@ elf_m68k_link_hash_newfunc (struct bfd_hash_entry *entry,
/* Destroy an m68k ELF linker hash table. */
static void
elf_m68k_link_hash_table_free (struct bfd_link_hash_table *_htab)
elf_m68k_link_hash_table_free (bfd *obfd)
{
struct elf_m68k_link_hash_table *htab;
htab = (struct elf_m68k_link_hash_table *) _htab;
htab = (struct elf_m68k_link_hash_table *) obfd->link.hash;
if (htab->multi_got_.bfd2got != NULL)
{
htab_delete (htab->multi_got_.bfd2got);
htab->multi_got_.bfd2got = NULL;
}
_bfd_elf_link_hash_table_free (_htab);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create an m68k ELF linker hash table. */
@ -977,7 +977,7 @@ elf_m68k_link_hash_table_create (bfd *abfd)
free (ret);
return NULL;
}
(void) elf_m68k_link_hash_table_free;
ret->root.root.hash_table_free = elf_m68k_link_hash_table_free;
ret->multi_got_.global_symndx = 1;

View File

@ -1020,13 +1020,13 @@ metag_link_hash_newfunc (struct bfd_hash_entry *entry,
/* Free the derived linker hash table. */
static void
elf_metag_link_hash_table_free (struct bfd_link_hash_table *btab)
elf_metag_link_hash_table_free (bfd *obfd)
{
struct elf_metag_link_hash_table *htab
= (struct elf_metag_link_hash_table *) btab;
= (struct elf_metag_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (&htab->bstab);
_bfd_elf_link_hash_table_free (btab);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create the derived linker hash table. The Meta ELF port uses the derived
@ -1055,8 +1055,11 @@ elf_metag_link_hash_table_create (bfd *abfd)
/* Init the stub hash table too. */
if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
sizeof (struct elf_metag_stub_hash_entry)))
return NULL;
(void) elf_metag_link_hash_table_free;
{
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
htab->etab.root.hash_table_free = elf_metag_link_hash_table_free;
return &htab->etab.root;
}

View File

@ -5106,13 +5106,13 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
/* Free the derived linker hash table. */
static void
nios2_elf32_link_hash_table_free (struct bfd_link_hash_table *btab)
nios2_elf32_link_hash_table_free (bfd *obfd)
{
struct elf32_nios2_link_hash_table *htab
= (struct elf32_nios2_link_hash_table *) btab;
= (struct elf32_nios2_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (&htab->bstab);
_bfd_elf_link_hash_table_free (btab);
_bfd_elf_link_hash_table_free (obfd);
}
/* Implement bfd_elf32_bfd_link_hash_table_create. */
@ -5139,8 +5139,11 @@ nios2_elf32_link_hash_table_create (bfd *abfd)
/* Init the stub hash table too. */
if (!bfd_hash_table_init (&ret->bstab, stub_hash_newfunc,
sizeof (struct elf32_nios2_stub_hash_entry)))
return NULL;
(void) nios2_elf32_link_hash_table_free;
{
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
ret->root.root.hash_table_free = nios2_elf32_link_hash_table_free;
return &ret->root.root;
}

View File

@ -426,20 +426,20 @@ xgate_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
cache_ptr->howto = &elf_xgate_howto_table[r_type];
}
/* Free the derived linker hash table. */
/* Destroy an XGATE ELF linker hash table. */
void
xgate_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
static void
xgate_elf_bfd_link_hash_table_free (bfd *obfd)
{
struct xgate_elf_link_hash_table *ret =
(struct xgate_elf_link_hash_table *) hash;
(struct xgate_elf_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (ret->stub_hash_table);
free (ret->stub_hash_table);
_bfd_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create a XGATE ELF linker hash table. */
/* Create an XGATE ELF linker hash table. */
static struct bfd_link_hash_table*
xgate_elf_bfd_link_hash_table_create (bfd *abfd)
@ -464,7 +464,7 @@ xgate_elf_bfd_link_hash_table_create (bfd *abfd)
ret->stub_hash_table = (struct bfd_hash_table*) bfd_zmalloc (amt);
if (ret->stub_hash_table == NULL)
{
free (ret);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
@ -472,9 +472,10 @@ xgate_elf_bfd_link_hash_table_create (bfd *abfd)
sizeof(struct elf32_xgate_stub_hash_entry)))
{
free (ret->stub_hash_table);
free (ret);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
ret->root.root.hash_table_free = xgate_elf_bfd_link_hash_table_free;
return &ret->root.root;
}

View File

@ -100,7 +100,6 @@ struct xgate_elf_link_hash_table
extern struct xgate_elf_link_hash_table* xgate_elf_hash_table_create
(bfd *);
extern void xgate_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *);
extern void xgate_elf_get_bank_parameters (struct bfd_link_info *);

View File

@ -1023,10 +1023,10 @@ elf64_ia64_local_dyn_info_free (void **slot,
/* Destroy IA-64 linker hash table. */
static void
elf64_ia64_link_hash_table_free (struct bfd_link_hash_table *hash)
elf64_ia64_link_hash_table_free (bfd *obfd)
{
struct elf64_ia64_link_hash_table *ia64_info
= (struct elf64_ia64_link_hash_table *) hash;
= (struct elf64_ia64_link_hash_table *) obfd->link.hash;
if (ia64_info->loc_hash_table)
{
htab_traverse (ia64_info->loc_hash_table,
@ -1037,7 +1037,7 @@ elf64_ia64_link_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_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create the derived linker hash table. The IA-64 ELF port uses this
@ -1067,10 +1067,10 @@ elf64_ia64_hash_table_create (bfd *abfd)
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
elf64_ia64_link_hash_table_free (abfd);
return NULL;
}
(void) elf64_ia64_link_hash_table_free;
ret->root.root.hash_table_free = elf64_ia64_link_hash_table_free;
return &ret->root.root;
}

View File

@ -4144,15 +4144,16 @@ tocsave_htab_eq (const void *p1, const void *p2)
/* Destroy a ppc64 ELF linker hash table. */
static void
ppc64_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
ppc64_elf_link_hash_table_free (bfd *obfd)
{
struct ppc_link_hash_table *htab = (struct ppc_link_hash_table *) hash;
struct ppc_link_hash_table *htab;
bfd_hash_table_free (&htab->stub_hash_table);
bfd_hash_table_free (&htab->branch_hash_table);
htab = (struct ppc_link_hash_table *) obfd->link.hash;
if (htab->tocsave_htab)
htab_delete (htab->tocsave_htab);
_bfd_elf_link_hash_table_free (hash);
bfd_hash_table_free (&htab->branch_hash_table);
bfd_hash_table_free (&htab->stub_hash_table);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create a ppc64 ELF linker hash table. */
@ -4179,7 +4180,7 @@ ppc64_elf_link_hash_table_create (bfd *abfd)
if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc,
sizeof (struct ppc_stub_hash_entry)))
{
_bfd_elf_link_hash_table_free ((struct bfd_link_hash_table *) htab);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
@ -4188,7 +4189,7 @@ ppc64_elf_link_hash_table_create (bfd *abfd)
sizeof (struct ppc_branch_hash_entry)))
{
bfd_hash_table_free (&htab->stub_hash_table);
_bfd_elf_link_hash_table_free ((struct bfd_link_hash_table *) htab);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
@ -4198,12 +4199,10 @@ ppc64_elf_link_hash_table_create (bfd *abfd)
NULL);
if (htab->tocsave_htab == NULL)
{
bfd_hash_table_free (&htab->branch_hash_table);
bfd_hash_table_free (&htab->stub_hash_table);
_bfd_elf_link_hash_table_free ((struct bfd_link_hash_table *) htab);
ppc64_elf_link_hash_table_free (abfd);
return NULL;
}
(void) ppc64_elf_link_hash_table_free;
htab->elf.root.hash_table_free = ppc64_elf_link_hash_table_free;
/* Initializing two fields of the union is just cosmetic. We really
only care about glist, but when compiled on a 32-bit host the

View File

@ -970,16 +970,16 @@ elf_x86_64_get_local_sym_hash (struct elf_x86_64_link_hash_table *htab,
/* Destroy an X86-64 ELF linker hash table. */
static void
elf_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
elf_x86_64_link_hash_table_free (bfd *obfd)
{
struct elf_x86_64_link_hash_table *htab
= (struct elf_x86_64_link_hash_table *) hash;
= (struct elf_x86_64_link_hash_table *) obfd->link.hash;
if (htab->loc_hash_table)
htab_delete (htab->loc_hash_table);
if (htab->loc_hash_memory)
objalloc_free ((struct objalloc *) htab->loc_hash_memory);
_bfd_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create an X86-64 ELF linker hash table. */
@ -1027,10 +1027,10 @@ elf_x86_64_link_hash_table_create (bfd *abfd)
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
elf_x86_64_link_hash_table_free (abfd);
return NULL;
}
(void) elf_x86_64_link_hash_table_free;
ret->elf.root.hash_table_free = elf_x86_64_link_hash_table_free;
return &ret->elf.root;
}

View File

@ -6901,6 +6901,7 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
free (ret);
return NULL;
}
ret->root.hash_table_free = _bfd_elf_link_hash_table_free;
return &ret->root;
}
@ -6908,13 +6909,15 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
/* Destroy an ELF linker hash table. */
void
_bfd_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
_bfd_elf_link_hash_table_free (bfd *obfd)
{
struct elf_link_hash_table *htab = (struct elf_link_hash_table *) hash;
struct elf_link_hash_table *htab;
htab = (struct elf_link_hash_table *) obfd->link.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);
_bfd_generic_link_hash_table_free (obfd);
}
/* This is a hook for the ELF emulation code in the generic linker to

View File

@ -2058,10 +2058,10 @@ elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
/* Destroy an AArch64 elf linker hash table. */
static void
elfNN_aarch64_link_hash_table_free (struct bfd_link_hash_table *hash)
elfNN_aarch64_link_hash_table_free (bfd *obfd)
{
struct elf_aarch64_link_hash_table *ret
= (struct elf_aarch64_link_hash_table *) hash;
= (struct elf_aarch64_link_hash_table *) obfd->link.hash;
if (ret->loc_hash_table)
htab_delete (ret->loc_hash_table);
@ -2069,7 +2069,7 @@ elfNN_aarch64_link_hash_table_free (struct bfd_link_hash_table *hash)
objalloc_free ((struct objalloc *) ret->loc_hash_memory);
bfd_hash_table_free (&ret->stub_hash_table);
_bfd_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create an AArch64 elf linker hash table. */
@ -2100,7 +2100,7 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd)
if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
sizeof (struct elf_aarch64_stub_hash_entry)))
{
free (ret);
_bfd_elf_link_hash_table_free (abfd);
return NULL;
}
@ -2111,10 +2111,10 @@ elfNN_aarch64_link_hash_table_create (bfd *abfd)
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
elfNN_aarch64_link_hash_table_free (abfd);
return NULL;
}
(void) elfNN_aarch64_link_hash_table_free;
ret->root.root.hash_table_free = elfNN_aarch64_link_hash_table_free;
return &ret->root.root;
}

View File

@ -1414,10 +1414,10 @@ elfNN_ia64_local_dyn_info_free (void **slot,
/* Destroy IA-64 linker hash table. */
static void
elfNN_ia64_link_hash_table_free (struct bfd_link_hash_table *hash)
elfNN_ia64_link_hash_table_free (bfd *obfd)
{
struct elfNN_ia64_link_hash_table *ia64_info
= (struct elfNN_ia64_link_hash_table *) hash;
= (struct elfNN_ia64_link_hash_table *) obfd->link.hash;
if (ia64_info->loc_hash_table)
{
htab_traverse (ia64_info->loc_hash_table,
@ -1428,7 +1428,7 @@ elfNN_ia64_link_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_elf_link_hash_table_free (hash);
_bfd_elf_link_hash_table_free (obfd);
}
/* Create the derived linker hash table. The IA-64 ELF port uses this
@ -1458,10 +1458,10 @@ elfNN_ia64_hash_table_create (bfd *abfd)
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
elfNN_ia64_link_hash_table_free (abfd);
return NULL;
}
(void) elfNN_ia64_link_hash_table_free;
ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free;
return &ret->root.root;
}

View File

@ -1104,17 +1104,17 @@ elf_sparc_get_local_sym_hash (struct _bfd_sparc_elf_link_hash_table *htab,
/* Destroy a SPARC ELF linker hash table. */
void
_bfd_sparc_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
static void
_bfd_sparc_elf_link_hash_table_free (bfd *obfd)
{
struct _bfd_sparc_elf_link_hash_table *htab
= (struct _bfd_sparc_elf_link_hash_table *) hash;
= (struct _bfd_sparc_elf_link_hash_table *) obfd->link.hash;
if (htab->loc_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 (obfd);
}
/* Create a SPARC ELF linker hash table. */
@ -1183,9 +1183,10 @@ _bfd_sparc_elf_link_hash_table_create (bfd *abfd)
ret->loc_hash_memory = objalloc_create ();
if (!ret->loc_hash_table || !ret->loc_hash_memory)
{
free (ret);
_bfd_sparc_elf_link_hash_table_free (abfd);
return NULL;
}
ret->elf.root.hash_table_free = _bfd_sparc_elf_link_hash_table_free;
return &ret->elf.root;
}

View File

@ -106,8 +106,6 @@ extern bfd_boolean _bfd_sparc_elf_mkobject
(bfd *);
extern struct bfd_link_hash_table *_bfd_sparc_elf_link_hash_table_create
(bfd *);
extern void _bfd_sparc_elf_link_hash_table_free
(struct bfd_link_hash_table *);
extern bfd_boolean _bfd_sparc_elf_create_dynamic_sections
(bfd *, struct bfd_link_info *);
extern void _bfd_sparc_elf_copy_indirect_symbol

View File

@ -392,6 +392,7 @@ bfd_hash_table_init_n (struct bfd_hash_table *table,
objalloc_alloc ((struct objalloc *) table->memory, alloc);
if (table->table == NULL)
{
bfd_hash_table_free (table);
bfd_set_error (bfd_error_no_memory);
return FALSE;
}

View File

@ -588,7 +588,7 @@ extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
/* Generic link hash table destruction routine. */
extern void _bfd_generic_link_hash_table_free
(struct bfd_link_hash_table *);
(bfd *);
/* Generic add symbol routine. */
extern bfd_boolean _bfd_generic_link_add_symbols

View File

@ -593,7 +593,7 @@ extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
/* Generic link hash table destruction routine. */
extern void _bfd_generic_link_hash_table_free
(struct bfd_link_hash_table *);
(bfd *);
/* Generic add symbol routine. */
extern bfd_boolean _bfd_generic_link_add_symbols

View File

@ -603,8 +603,6 @@ extern long _bfd_xcoff_canonicalize_dynamic_reloc
(bfd *, arelent **, asymbol **);
extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
(bfd *);
extern void _bfd_xcoff_bfd_link_hash_table_free
(struct bfd_link_hash_table *);
extern bfd_boolean _bfd_xcoff_bfd_link_add_symbols
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_xcoff_bfd_final_link

View File

@ -607,8 +607,6 @@ extern long _bfd_xcoff_canonicalize_dynamic_reloc
(bfd *, arelent **, asymbol **);
extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create
(bfd *);
extern void _bfd_xcoff_bfd_link_hash_table_free
(struct bfd_link_hash_table *);
extern bfd_boolean _bfd_xcoff_bfd_link_add_symbols
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_xcoff_bfd_final_link

View File

@ -482,11 +482,22 @@ _bfd_link_hash_table_init
const char *),
unsigned int entsize)
{
bfd_boolean ret;
BFD_ASSERT (!abfd->is_linker_output && !abfd->link.hash);
table->undefs = NULL;
table->undefs_tail = NULL;
table->type = bfd_link_generic_hash_table;
return bfd_hash_table_init (&table->table, newfunc, entsize);
ret = bfd_hash_table_init (&table->table, newfunc, entsize);
if (ret)
{
/* Arrange for destruction of this hash table on closing ABFD. */
table->hash_table_free = _bfd_generic_link_hash_table_free;
abfd->link.hash = table;
abfd->is_linker_output = TRUE;
}
return ret;
}
/* Look up a symbol in a link hash table. If follow is TRUE, we
@ -771,13 +782,16 @@ _bfd_generic_link_hash_table_create (bfd *abfd)
}
void
_bfd_generic_link_hash_table_free (struct bfd_link_hash_table *hash)
_bfd_generic_link_hash_table_free (bfd *obfd)
{
struct generic_link_hash_table *ret
= (struct generic_link_hash_table *) hash;
struct generic_link_hash_table *ret;
BFD_ASSERT (obfd->is_linker_output && obfd->link.hash);
ret = (struct generic_link_hash_table *) obfd->link.hash;
bfd_hash_table_free (&ret->root.table);
free (ret);
obfd->link.hash = NULL;
obfd->is_linker_output = FALSE;
}
/* Grab the symbols for an object file when doing a generic link. We

View File

@ -188,6 +188,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
bfd_byte *contents, *data;
int storage_needed;
struct saved_offsets saved_offsets;
bfd *link_next;
/* Don't apply relocation on executable and shared library. See
PR 4756. */
@ -209,6 +210,8 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
link_info.input_bfds = abfd;
link_info.input_bfds_tail = &abfd->link.next;
link_next = abfd->link.next;
abfd->link.next = NULL;
link_info.hash = _bfd_generic_link_hash_table_create (abfd);
link_info.callbacks = &callbacks;
callbacks.warning = simple_dummy_warning;
@ -232,7 +235,11 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
data = (bfd_byte *) bfd_malloc (amt);
if (data == NULL)
return NULL;
{
_bfd_generic_link_hash_table_free (abfd);
abfd->link.next = link_next;
return NULL;
}
outbuf = data;
}
@ -243,6 +250,8 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
{
if (data)
free (data);
_bfd_generic_link_hash_table_free (abfd);
abfd->link.next = link_next;
return NULL;
}
bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
@ -270,6 +279,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
free (saved_offsets.sections);
_bfd_generic_link_hash_table_free (link_info.hash);
_bfd_generic_link_hash_table_free (abfd);
abfd->link.next = link_next;
return contents;
}

View File

@ -573,14 +573,17 @@ xcoff_link_hash_newfunc (struct bfd_hash_entry *entry,
/* Destroy an XCOFF link hash table. */
void
_bfd_xcoff_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
static void
_bfd_xcoff_bfd_link_hash_table_free (bfd *obfd)
{
struct xcoff_link_hash_table *ret = (struct xcoff_link_hash_table *) hash;
struct xcoff_link_hash_table *ret;
_bfd_stringtab_free (ret->debug_strtab);
bfd_hash_table_free (&ret->root.table);
free (ret);
ret = (struct xcoff_link_hash_table *) obfd->link.hash;
if (ret->archive_info)
htab_delete (ret->archive_info);
if (ret->debug_strtab)
_bfd_stringtab_free (ret->debug_strtab);
_bfd_generic_link_hash_table_free (obfd);
}
/* Create an XCOFF link hash table. */
@ -604,6 +607,12 @@ _bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
ret->debug_strtab = _bfd_xcoff_stringtab_init ();
ret->archive_info = htab_create (37, xcoff_archive_info_hash,
xcoff_archive_info_eq, NULL);
if (!ret->debug_strtab || !ret->archive_info)
{
_bfd_xcoff_bfd_link_hash_table_free (abfd);
return NULL;
}
ret->root.hash_table_free = _bfd_xcoff_bfd_link_hash_table_free;
/* The linker will always generate a full a.out header. We need to
record that fact now, before the sizeof_headers routine could be

View File

@ -1,3 +1,7 @@
2014-06-13 Alan Modra <amodra@gmail.com>
* bfdlink.h (struct bfd_link_hash_table): Add hash_table_free field.
2014-06-13 Alan Modra <amodra@gmail.com>
* bfdlink.h: Update for bfd.link_next change.

View File

@ -167,6 +167,8 @@ struct bfd_link_hash_table
struct bfd_link_hash_entry *undefs;
/* Entries are added to the tail of the undefs list. */
struct bfd_link_hash_entry *undefs_tail;
/* Function to free the hash table on closing BFD. */
void (*hash_table_free) (bfd *);
/* The type of the link hash table. */
enum bfd_link_hash_table_type type;
};