* elf.c (bfd_elf_get_elf_syms): Don't leak memory on error.
authorAlan Modra <amodra@gmail.com>
Fri, 8 Aug 2008 08:00:14 +0000 (08:00 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 8 Aug 2008 08:00:14 +0000 (08:00 +0000)
* 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.

bfd/ChangeLog
bfd/elf.c
bfd/elflink.c

index ea94b0255a7fd0154accc8ab944883adc8752b16..bf4cad152edfe66593a5651c34eda58d31225a9a 100644 (file)
@@ -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.
index beb6d1b7d036211995009ce426e6be83b4b67705..7f9853e6540d7033eb3b5388f68152c509af80c8 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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 de7f3ba40f50e6f0435ca0394ba2b32b7dd95811..ec545f9cc9be6041a2dbb5ba210f69d0784d2a74 100644 (file)
@@ -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;
 }