diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elf.c | 7 | ||||
-rw-r--r-- | bfd/elflink.c | 28 |
3 files changed, 36 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ea94b02..bf4cad1 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2008-08-08 Alan Modra <amodra@bigpond.net.au> + + * elf.c (bfd_elf_get_elf_syms): Don't leak memory on error. + * elflink.c (_bfd_elf_link_read_relocs): bfd_release on error. + (elf_link_add_object_symbols): Don't leak memory on error. + (bfd_elf_size_dynsym_hash_dynstr): Likewise. + (elf_fixup_link_order): Free sections. + 2008-08-07 Richard Sandiford <rdsandiford@googlemail.com> * elf-bfd.h (elf_backend_data): Add a "rela_plts_and_copies_p" field. @@ -358,6 +358,7 @@ bfd_elf_get_elf_syms (bfd *ibfd, const bfd_byte *esym; Elf_External_Sym_Shndx *alloc_extshndx; Elf_External_Sym_Shndx *shndx; + Elf_Internal_Sym *alloc_intsym; Elf_Internal_Sym *isym; Elf_Internal_Sym *isymend; const struct elf_backend_data *bed; @@ -379,6 +380,7 @@ bfd_elf_get_elf_syms (bfd *ibfd, /* Read the symbols. */ alloc_ext = NULL; alloc_extshndx = NULL; + alloc_intsym = NULL; bed = get_elf_backend_data (ibfd); extsym_size = bed->s->sizeof_sym; amt = symcount * extsym_size; @@ -419,7 +421,8 @@ bfd_elf_get_elf_syms (bfd *ibfd, if (intsym_buf == NULL) { - intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym)); + alloc_intsym = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym)); + intsym_buf = alloc_intsym; if (intsym_buf == NULL) goto out; } @@ -435,6 +438,8 @@ bfd_elf_get_elf_syms (bfd *ibfd, (*_bfd_error_handler) (_("%B symbol number %lu references " "nonexistent SHT_SYMTAB_SHNDX section"), ibfd, (unsigned long) symoffset); + if (alloc_intsym != NULL) + free (alloc_intsym); intsym_buf = NULL; goto out; } diff --git a/bfd/elflink.c b/bfd/elflink.c index de7f3ba..ec545f9 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2178,7 +2178,7 @@ _bfd_elf_link_read_relocs (bfd *abfd, size = o->reloc_count; size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); if (keep_memory) - internal_relocs = bfd_alloc (abfd, size); + internal_relocs = alloc2 = bfd_alloc (abfd, size); else internal_relocs = alloc2 = bfd_malloc (size); if (internal_relocs == NULL) @@ -2226,7 +2226,12 @@ _bfd_elf_link_read_relocs (bfd *abfd, if (alloc1 != NULL) free (alloc1); if (alloc2 != NULL) - free (alloc2); + { + if (keep_memory) + bfd_release (abfd, alloc2); + else + free (alloc2); + } return NULL; } @@ -4626,7 +4631,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) if (hlook->dynindx != -1 && h->dynindx == -1) { if (! bfd_elf_link_record_dynamic_symbol (info, h)) - goto error_return; + { + err_free_sym_hash: + free (sorted_sym_hash); + goto error_return; + } } /* If the real definition is in the list of dynamic @@ -4637,7 +4646,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) if (h->dynindx != -1 && hlook->dynindx == -1) { if (! bfd_elf_link_record_dynamic_symbol (info, hlook)) - goto error_return; + goto err_free_sym_hash; } break; } @@ -6249,7 +6258,10 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) elf_link_hash_traverse (elf_hash_table (info), elf_collect_hash_codes, &hashinf); if (hashinf.error) - return FALSE; + { + free (hashcodes); + return FALSE; + } nsyms = hashinf.hashcodes - hashcodes; bucketcount @@ -6301,7 +6313,10 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) elf_link_hash_traverse (elf_hash_table (info), elf_collect_gnu_hash_codes, &cinfo); if (cinfo.error) - return FALSE; + { + free (cinfo.hashcodes); + return FALSE; + } bucketcount = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1); @@ -9847,6 +9862,7 @@ elf_fixup_link_order (bfd *abfd, asection *o) offset += sections[n]->size; } + free (sections); return TRUE; } |