fix some elf linker memory leaks
Alan Modra
amodra@bigpond.net.au
Fri Aug 8 08:00:00 GMT 2008
* 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.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.461
diff -u -p -r1.461 elf.c
--- bfd/elf.c 7 Aug 2008 20:04:32 -0000 1.461
+++ bfd/elf.c 8 Aug 2008 07:29:01 -0000
@@ -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;
}
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.307
diff -u -p -r1.307 elflink.c
--- bfd/elflink.c 7 Aug 2008 20:04:32 -0000 1.307
+++ bfd/elflink.c 8 Aug 2008 07:29:09 -0000
@@ -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,
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,
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 *ou
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 *ou
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, asectio
offset += sections[n]->size;
}
+ free (sections);
return TRUE;
}
--
Alan Modra
Australia Development Lab, IBM
More information about the Binutils
mailing list