readelf: segfault at readelf.c:12227
[deliverable/binutils-gdb.git] / binutils / readelf.c
index 9149bb8ce4d79653b614ef781354943f3bc76d28..ea30f883c5994180353bcb421c6716cd86cc05be 100644 (file)
@@ -2291,7 +2291,7 @@ get_dynamic_type (Filedata * filedata, unsigned long type)
 static char *
 get_file_type (unsigned e_type)
 {
-  static char buff[32];
+  static char buff[64];
 
   switch (e_type)
     {
@@ -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)
     {
@@ -6832,25 +6831,13 @@ get_group_flags (unsigned int flags)
   else if (flags == GRP_COMDAT)
     return "COMDAT ";
 
-  snprintf (buff, 14, _("[0x%x: "), flags);
-
-  flags &= ~ GRP_COMDAT;
-  if (flags & GRP_MASKOS)
-    {
-      strcat (buff, "<OS specific>");
-      flags &= ~ GRP_MASKOS;
-    }
-
-  if (flags & GRP_MASKPROC)
-    {
-      strcat (buff, "<PROC specific>");
-      flags &= ~ GRP_MASKPROC;
-    }
-
-  if (flags)
-    strcat (buff, "<unknown>");
+  snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
+           flags,
+           flags & GRP_MASKOS ? _("<OS specific>") : "",
+           flags & GRP_MASKPROC ? _("<PROC specific>") : "",
+           (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
+            ? _("<unknown>") : ""));
 
-  strcat (buff, "]");
   return buff;
 }
 
@@ -9981,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)
@@ -9997,7 +9986,7 @@ get_num_dynamic_syms (Filedata * filedata)
          if (chains)
            {
              free (chains);
-             buckets = NULL;
+             chains = NULL;
            }
          nbuckets = 0;
        }
@@ -10062,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)
@@ -10093,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;
            }
 
@@ -10166,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)
@@ -10270,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
@@ -11467,7 +11457,7 @@ process_version_sections (Filedata * filedata)
 static const char *
 get_symbol_binding (Filedata * filedata, unsigned int binding)
 {
-  static char buff[32];
+  static char buff[64];
 
   switch (binding)
     {
@@ -11494,7 +11484,7 @@ get_symbol_binding (Filedata * filedata, unsigned int binding)
 static const char *
 get_symbol_type (Filedata * filedata, unsigned int type)
 {
-  static char buff[32];
+  static char buff[64];
 
   switch (type)
     {
@@ -11691,7 +11681,7 @@ get_ppc64_symbol_other (unsigned int other)
   other >>= STO_PPC64_LOCAL_BIT;
   if (other <= 6)
     {
-      static char buf[32];
+      static char buf[64];
       if (other >= 2)
        other = ppc64_decode_local_entry (other);
       snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
@@ -11704,7 +11694,7 @@ static const char *
 get_symbol_other (Filedata * filedata, unsigned int other)
 {
   const char * result = NULL;
-  static char buff [32];
+  static char buff [64];
 
   if (other == 0)
     return "";
@@ -12198,6 +12188,7 @@ process_symbol_table (Filedata * filedata)
 
   free (buckets);
   buckets = NULL;
+  nbuckets = 0;
   free (chains);
   chains = NULL;
 
@@ -12272,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.028597 seconds and 4 git commands to generate.