readelf: segfault at readelf.c:12227
[deliverable/binutils-gdb.git] / binutils / readelf.c
index fb6f801b9fab53b3f1008abc60aff23d876a1fd6..ea30f883c5994180353bcb421c6716cd86cc05be 100644 (file)
@@ -6132,6 +6132,20 @@ process_section_headers (Filedata * filedata)
 
   free (filedata->section_headers);
   filedata->section_headers = NULL;
+  free (dynamic_symbols);
+  dynamic_symbols = NULL;
+  num_dynamic_syms = 0;
+  free (dynamic_strings);
+  dynamic_strings = NULL;
+  dynamic_strings_length = 0;
+  free (dynamic_syminfo);
+  dynamic_syminfo = NULL;
+  while (symtab_shndx_list != NULL)
+    {
+      elf_section_list *next = symtab_shndx_list->next;
+      free (symtab_shndx_list);
+      symtab_shndx_list = next;
+    }
 
   if (filedata->file_header.e_shnum == 0)
     {
@@ -6186,21 +6200,6 @@ process_section_headers (Filedata * filedata)
 
   /* Scan the sections for the dynamic symbol table
      and dynamic string table and debug sections.  */
-  free (dynamic_symbols);
-  dynamic_symbols = NULL;
-  num_dynamic_syms = 0;
-  free (dynamic_strings);
-  dynamic_strings = NULL;
-  dynamic_strings_length = 0;
-  free (dynamic_syminfo);
-  dynamic_syminfo = NULL;
-  while (symtab_shndx_list != NULL)
-    {
-      elf_section_list *next = symtab_shndx_list->next;
-      free (symtab_shndx_list);
-      symtab_shndx_list = next;
-    }
-
   eh_addr_size = is_32bit_elf ? 4 : 8;
   switch (filedata->file_header.e_machine)
     {
@@ -9969,12 +9968,14 @@ get_num_dynamic_syms (Filedata * filedata)
 
       nbuckets = byte_get (nb, hash_ent_size);
       nchains = byte_get (nc, hash_ent_size);
-      num_of_syms = nchains;
 
       buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
       chains  = get_dynamic_data (filedata, nchains, hash_ent_size);
 
-  no_hash:
+      if (buckets != NULL && chains != NULL)
+       num_of_syms = nchains;
+
+    no_hash:
       if (num_of_syms == 0)
        {
          if (buckets)
@@ -10050,7 +10051,7 @@ get_num_dynamic_syms (Filedata * filedata)
            if (gnubuckets[i] < gnusymidx)
              {
                gnu_hash_error = TRUE;
-               return FALSE;
+               goto no_gnu_hash;
              }
 
            if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
@@ -10081,7 +10082,7 @@ get_num_dynamic_syms (Filedata * filedata)
          if (fread (nb, 4, 1, filedata->handle) != 1)
            {
              error (_("Failed to determine last chain length\n"));
-         gnu_hash_error = TRUE;
+             gnu_hash_error = TRUE;
              goto no_gnu_hash;
            }
 
@@ -10154,7 +10155,7 @@ get_num_dynamic_syms (Filedata * filedata)
            while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
          }
 
-  no_gnu_hash:
+    no_gnu_hash:
       if (gnu_hash_error)
        {
          if (mipsxlat)
@@ -10258,7 +10259,8 @@ process_dynamic_section (Filedata * filedata)
 
                if (vma >= (seg->p_vaddr & -seg->p_align)
                    && vma <= seg->p_vaddr + seg->p_filesz
-                   && (num_of_syms = get_num_dynamic_syms (filedata)))
+                   && (num_of_syms = get_num_dynamic_syms (filedata)) != 0
+                   && dynamic_symbols == NULL)
                  {
                    /* Since we do not know how big the symbol table is,
                       we default to reading in up to the end of PT_LOAD
@@ -12186,6 +12188,7 @@ process_symbol_table (Filedata * filedata)
 
   free (buckets);
   buckets = NULL;
+  nbuckets = 0;
   free (chains);
   chains = NULL;
 
@@ -12260,16 +12263,29 @@ process_symbol_table (Filedata * filedata)
       free (lengths);
     }
   free (gnubuckets);
+  gnubuckets = NULL;
+  ngnubuckets = 0;
   free (gnuchains);
+  gnuchains = NULL;
+  ngnuchains = 0;
   free (mipsxlat);
+  mipsxlat = NULL;
   return TRUE;
 
  err_out:
   free (gnubuckets);
+  gnubuckets = NULL;
+  ngnubuckets = 0;
   free (gnuchains);
+  gnuchains = NULL;
+  ngnuchains = 0
   free (mipsxlat);
+  mipsxlat = NULL;
   free (buckets);
+  buckets = NULL;
+  nbuckets = 0;
   free (chains);
+  chains = NULL;
   return FALSE;
 }
 
This page took 0.027041 seconds and 4 git commands to generate.