]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
gdb/jit: skip jit symbol lookup if already detected the symbols don't exist
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index 798782c3a8209c467a90c1d0fb4ab82d93865e49..2406304fe35a832ac53aa7b1a367f3f7afed4264 100644 (file)
@@ -234,6 +234,7 @@ static bfd_boolean do_archive_index = FALSE;
 static bfd_boolean check_all = FALSE;
 static bfd_boolean is_32bit_elf = FALSE;
 static bfd_boolean decompress_dumps = FALSE;
+static bfd_boolean do_not_show_symbol_truncation = FALSE;
 
 static char *dump_ctf_parent_name;
 static char *dump_ctf_symtab_name;
@@ -533,15 +534,19 @@ print_vma (bfd_vma vma, print_mode mode)
 
    Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
 
+   If truncation will happen and do_not_show_symbol_truncation is FALSE then display
+   abs(WIDTH) - 5 characters followed by "[...]".
+
    If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
    padding as necessary.
 
    Returns the number of emitted characters.  */
 
 static unsigned int
-print_symbol (signed int width, const char *symbol)
+print_symbol (signed int width, const char * symbol)
 {
   bfd_boolean extra_padding = FALSE;
+  bfd_boolean do_dots = FALSE;
   signed int num_printed = 0;
 #ifdef HAVE_MBSTATE_T
   mbstate_t state;
@@ -562,7 +567,17 @@ print_symbol (signed int width, const char *symbol)
        This simplifies the code below.  */
     width_remaining = INT_MAX;
   else
-    width_remaining = width;
+    {
+      width_remaining = width;
+      if (! do_not_show_symbol_truncation
+         && (int) strlen (symbol) > width)
+       {
+         width_remaining -= 5;
+         if ((int) width_remaining < 0)
+           width_remaining = 0;
+         do_dots = TRUE;
+       }
+    }
 
 #ifdef HAVE_MBSTATE_T
   /* Initialise the multibyte conversion state.  */
@@ -618,6 +633,9 @@ print_symbol (signed int width, const char *symbol)
        }
     }
 
+  if (do_dots)
+    num_printed += printf ("[...]");
+
   if (extra_padding && num_printed < width)
     {
       /* Fill in the remaining spaces.  */
@@ -4502,14 +4520,17 @@ static struct option options[] =
   {"dwarf-start",      required_argument, 0, OPTION_DWARF_START},
   {"dwarf-check",      no_argument, 0, OPTION_DWARF_CHECK},
 
+#ifdef ENABLE_LIBCTF
   {"ctf",             required_argument, 0, OPTION_CTF_DUMP},
 
   {"ctf-symbols",      required_argument, 0, OPTION_CTF_SYMBOLS},
   {"ctf-strings",      required_argument, 0, OPTION_CTF_STRINGS},
   {"ctf-parent",       required_argument, 0, OPTION_CTF_PARENT},
+#endif
 
   {"version",         no_argument, 0, 'v'},
   {"wide",            no_argument, 0, 'W'},
+  {"silent-truncation",no_argument, 0, 'T'},
   {"help",            no_argument, 0, 'H'},
   {0,                 no_argument, 0, 0}
 };
@@ -4548,9 +4569,9 @@ usage (FILE * stream)
   -R --relocated-dump=<number|name>\n\
                          Dump the contents of section <number|name> as relocated bytes\n\
   -z --decompress        Decompress section before dumping it\n\
-  -w[lLiaprmfFsoRtUuTgAckK] or\n\
+  -w[lLiaprmfFsoORtUuTgAckK] or\n\
   --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
-               =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
+               =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
                =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
                =addr,=cu_index,=links,=follow-links]\n\
                          Display the contents of DWARF debug sections\n"));
@@ -4558,6 +4579,7 @@ usage (FILE * stream)
   --dwarf-depth=N        Do not display DIEs at depth N or greater\n\
   --dwarf-start=N        Display DIEs starting with N, at the same depth\n\
                          or deeper\n"));
+#ifdef ENABLE_LIBCTF
   fprintf (stream, _("\
   --ctf=<number|name>    Display CTF info from section <number|name>\n\
   --ctf-parent=<number|name>\n\
@@ -4566,6 +4588,7 @@ usage (FILE * stream)
                          Use section <number|name> as the CTF external symtab\n\n\
   --ctf-strings=<number|name>\n\
                          Use section <number|name> as the CTF external strtab\n\n"));
+#endif
 
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
@@ -4575,6 +4598,7 @@ usage (FILE * stream)
   fprintf (stream, _("\
   -I --histogram         Display histogram of bucket list lengths\n\
   -W --wide              Allow output width to exceed 80 characters\n\
+  -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
   @<file>                Read options from <file>\n\
   -H --help              Display this information\n\
   -v --version           Display the version number of readelf\n"));
@@ -4669,7 +4693,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
     usage (stderr);
 
   while ((c = getopt_long
-         (argc, argv, "ADHILNR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
+         (argc, argv, "ADHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
     {
       switch (c)
        {
@@ -4828,6 +4852,9 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
        case 'W':
          do_wide = TRUE;
          break;
+       case 'T':
+         do_not_show_symbol_truncation = TRUE;
+         break;
        default:
          /* xgettext:c-format */
          error (_("Invalid option '-%c'\n"), c);
@@ -6388,7 +6415,7 @@ process_section_headers (Filedata * filedata)
       if ((do_debugging || do_debug_info || do_debug_abbrevs
           || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
           || do_debug_aranges || do_debug_frames || do_debug_macinfo
-          || do_debug_str || do_debug_loc || do_debug_ranges
+          || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
           || do_debug_addr || do_debug_cu_index || do_debug_links)
          && (const_strneq (name, ".debug_")
              || const_strneq (name, ".zdebug_")))
@@ -6415,6 +6442,7 @@ process_section_headers (Filedata * filedata)
              || (do_debug_macinfo  && const_strneq (name, "macinfo"))
              || (do_debug_macinfo  && const_strneq (name, "macro"))
              || (do_debug_str      && const_strneq (name, "str"))
+             || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
              || (do_debug_loc      && const_strneq (name, "loc"))
              || (do_debug_loc      && const_strneq (name, "loclists"))
              || (do_debug_addr     && const_strneq (name, "addr"))
@@ -7010,8 +7038,7 @@ process_section_groups (Filedata * filedata)
          if (symtab_sec != sec)
            {
              symtab_sec = sec;
-             if (symtab)
-               free (symtab);
+             free (symtab);
              symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
            }
 
@@ -7040,8 +7067,7 @@ process_section_groups (Filedata * filedata)
 
              group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
              strtab_sec = NULL;
-             if (strtab)
-               free (strtab);
+             free (strtab);
              strtab = NULL;
              strtab_size = 0;
            }
@@ -7051,8 +7077,7 @@ process_section_groups (Filedata * filedata)
              if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
                {
                  strtab_sec = NULL;
-                 if (strtab)
-                   free (strtab);
+                 free (strtab);
                  strtab = NULL;
                  strtab_size = 0;
                }
@@ -7060,8 +7085,7 @@ process_section_groups (Filedata * filedata)
                       != (sec = filedata->section_headers + symtab_sec->sh_link))
                {
                  strtab_sec = sec;
-                 if (strtab)
-                   free (strtab);
+                 free (strtab);
 
                  strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
                                              1, strtab_sec->sh_size,
@@ -7169,17 +7193,14 @@ process_section_groups (Filedata * filedata)
              group->root = g;
            }
 
-         if (start)
-           free (start);
+         free (start);
 
          group++;
        }
     }
 
-  if (symtab)
-    free (symtab);
-  if (strtab)
-    free (strtab);
+  free (symtab);
+  free (strtab);
   return TRUE;
 }
 
@@ -7367,8 +7388,7 @@ process_ia64_vms_dynamic_relocs (Filedata * filedata)
        }
     }
 
-  if (strtab != NULL)
-    free (strtab);
+  free (strtab);
 
   return res;
 }
@@ -7514,8 +7534,7 @@ process_relocs (Filedata * filedata)
                                    symtab, nsyms, strtab, strtablen,
                                    is_rela,
                                    symsec->sh_type == SHT_DYNSYM);
-                 if (strtab)
-                   free (strtab);
+                 free (strtab);
                  free (symtab);
                }
              else
@@ -8041,19 +8060,15 @@ ia64_process_unwind (Filedata * filedata)
              && aux.table_len > 0)
            dump_ia64_unwind (filedata, & aux);
 
-         if (aux.table)
-           free ((char *) aux.table);
-         if (aux.info)
-           free ((char *) aux.info);
+         free ((char *) aux.table);
+         free ((char *) aux.info);
          aux.table = NULL;
          aux.info = NULL;
        }
     }
 
-  if (aux.symtab)
-    free (aux.symtab);
-  if (aux.strtab)
-    free ((char *) aux.strtab);
+  free (aux.symtab);
+  free ((char *) aux.strtab);
 
   return res;
 }
@@ -8238,6 +8253,7 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
   nentries = size / unw_ent_size;
   size = unw_ent_size * nentries;
 
+  aux->table_len = nentries;
   tep = aux->table = (struct hppa_unw_table_entry *)
       xcmalloc (nentries, sizeof (aux->table[0]));
 
@@ -8357,8 +8373,6 @@ slurp_hppa_unwind_table (Filedata *                  filedata,
       free (rela);
     }
 
-  aux->table_len = nentries;
-
   return TRUE;
 }
 
@@ -8423,16 +8437,13 @@ hppa_process_unwind (Filedata * filedata)
                res = FALSE;
            }
 
-         if (aux.table)
-           free ((char *) aux.table);
+         free ((char *) aux.table);
          aux.table = NULL;
        }
     }
 
-  if (aux.symtab)
-    free (aux.symtab);
-  if (aux.strtab)
-    free ((char *) aux.strtab);
+  free (aux.symtab);
+  free ((char *) aux.strtab);
 
   return res;
 }
@@ -8492,11 +8503,8 @@ arm_print_vma_and_name (Filedata *                 filedata,
 static void
 arm_free_section (struct arm_section *arm_sec)
 {
-  if (arm_sec->data != NULL)
-    free (arm_sec->data);
-
-  if (arm_sec->rela != NULL)
-    free (arm_sec->rela);
+  free (arm_sec->data);
+  free (arm_sec->rela);
 }
 
 /* 1) If SEC does not match the one cached in ARM_SEC, then free the current
@@ -9530,10 +9538,8 @@ arm_process_unwind (Filedata * filedata)
          }
       }
 
-  if (aux.symtab)
-    free (aux.symtab);
-  if (aux.strtab)
-    free ((char *) aux.strtab);
+  free (aux.symtab);
+  free ((char *) aux.strtab);
 
   return res;
 }
@@ -10062,16 +10068,10 @@ get_num_dynamic_syms (Filedata * filedata)
     no_hash:
       if (num_of_syms == 0)
        {
-         if (filedata->buckets)
-           {
-             free (filedata->buckets);
-             filedata->buckets = NULL;
-           }
-         if (filedata->chains)
-           {
-             free (filedata->chains);
-             filedata->chains = NULL;
-           }
+         free (filedata->buckets);
+         filedata->buckets = NULL;
+         free (filedata->chains);
+         filedata->chains = NULL;
          filedata->nbuckets = 0;
        }
     }
@@ -10229,21 +10229,12 @@ get_num_dynamic_syms (Filedata * filedata)
       if (num_of_syms == 0)
        {
        no_gnu_hash:
-         if (filedata->mipsxlat)
-           {
-             free (filedata->mipsxlat);
-             filedata->mipsxlat = NULL;
-           }
-         if (filedata->gnuchains)
-           {
-             free (filedata->gnuchains);
-             filedata->gnuchains = NULL;
-           }
-         if (filedata->gnubuckets)
-           {
-             free (filedata->gnubuckets);
-             filedata->gnubuckets = NULL;
-           }
+         free (filedata->mipsxlat);
+         filedata->mipsxlat = NULL;
+         free (filedata->gnuchains);
+         filedata->gnuchains = NULL;
+         free (filedata->gnubuckets);
+         filedata->gnubuckets = NULL;
          filedata->ngnubuckets = 0;
          filedata->ngnuchains = 0;
        }
@@ -12063,7 +12054,7 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
   enum versioned_symbol_info sym_info;
   unsigned short vna_other;
   Elf_Internal_Sym *psym = symtab + si;
-
+  
   printf ("%6ld: ", si);
   print_vma (psym->st_value, LONG_HEX);
   putchar (' ');
@@ -12084,9 +12075,10 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
        printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
     }
   printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
-  print_symbol (25, VALID_SYMBOL_NAME (strtab, strtab_size,
-                                      psym->st_name)
-               ? strtab + psym->st_name : _("<corrupt>"));
+
+  bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
+                                           psym->st_name);
+  const char * sstr = is_valid  ? strtab + psym->st_name : _("<corrupt>");
 
   version_string
     = get_symbol_version_string (filedata,
@@ -12094,6 +12086,22 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
                                  || section->sh_type == SHT_DYNSYM),
                                 strtab, strtab_size, si,
                                 psym, &sym_info, &vna_other);
+  
+  int len_avail = 21;
+  if (! do_wide && version_string != NULL)
+    {
+      char buffer[16];
+
+      len_avail -= 1 + strlen (version_string);
+
+      if (sym_info == symbol_undefined)
+       len_avail -= sprintf (buffer," (%d)", vna_other);
+      else if (sym_info != symbol_hidden)
+       len_avail -= 1;
+    }
+
+  print_symbol (len_avail, sstr);
+    
   if (version_string)
     {
       if (sym_info == symbol_undefined)
@@ -14167,6 +14175,7 @@ dump_section_as_bytes (Elf_Internal_Shdr *  section,
   return FALSE;
 }
 
+#ifdef ENABLE_LIBCTF
 static ctf_sect_t *
 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
 {
@@ -14181,8 +14190,9 @@ shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
    it is passed, or a pointer to newly-allocated storage, in which case
    dump_ctf() will free it when it no longer needs it.  */
 
-static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
-                                   char *s, void *arg)
+static char *
+dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
+                      char *s, void *arg)
 {
   const char *blanks = arg;
   char *new_s;
@@ -14192,6 +14202,55 @@ static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
   return new_s;
 }
 
+/* Dump one CTF archive member.  */
+
+static int
+dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
+{
+  ctf_file_t *parent = (ctf_file_t *) arg;
+  const char *things[] = {"Header", "Labels", "Data objects",
+                         "Function objects", "Variables", "Types", "Strings",
+                         ""};
+  const char **thing;
+  size_t i;
+
+  /* Only print out the name of non-default-named archive members.
+     The name .ctf appears everywhere, even for things that aren't
+     really archives, so printing it out is liable to be confusing.
+
+     The parent, if there is one, is the default-owned archive member:
+     avoid importing it into itself.  (This does no harm, but looks
+     confusing.)  */
+
+  if (strcmp (name, ".ctf") != 0)
+    {
+      printf (_("\nCTF archive member: %s:\n"), name);
+      ctf_import (ctf, parent);
+    }
+
+  for (i = 0, thing = things; *thing[0]; thing++, i++)
+    {
+      ctf_dump_state_t *s = NULL;
+      char *item;
+
+      printf ("\n  %s:\n", *thing);
+      while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
+                              (void *) "    ")) != NULL)
+       {
+         printf ("%s\n", item);
+         free (item);
+       }
+
+      if (ctf_errno (ctf))
+       {
+         error (_("Iteration failed: %s, %s\n"), *thing,
+                ctf_errmsg (ctf_errno (ctf)));
+         return 1;
+       }
+    }
+  return 0;
+}
+
 static bfd_boolean
 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
 {
@@ -14205,16 +14264,12 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
   ctf_sect_t          ctfsect, symsect, strsect, parentsect;
   ctf_sect_t *        symsectp = NULL;
   ctf_sect_t *        strsectp = NULL;
-  ctf_file_t *        ctf = NULL;
-  ctf_file_t *        parent = NULL;
+  ctf_archive_t *      ctfa = NULL;
+  ctf_archive_t *      parenta = NULL, *lookparent;
+  ctf_file_t *         parent = NULL;
 
-  const char *things[] = {"Header", "Labels", "Data objects",
-                         "Function objects", "Variables", "Types", "Strings",
-                         ""};
-  const char **thing;
   int err;
   bfd_boolean ret = FALSE;
-  size_t i;
 
   shdr_to_ctf_sect (&ctfsect, section, filedata);
   data = get_section_contents (section, filedata);
@@ -14273,9 +14328,11 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
       parentsect.cts_data = parentdata;
     }
 
-  /* Load the CTF file and dump it.  */
+  /* Load the CTF file and dump it.  It may be a raw CTF section, or an archive:
+     libctf papers over the difference, so we can pretend it is always an
+     archive.  Possibly open the parent as well, if one was specified.  */
 
-  if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
+  if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
     {
       error (_("CTF open failure: %s\n"), ctf_errmsg (err));
       goto fail;
@@ -14283,13 +14340,24 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
 
   if (parentdata)
     {
-      if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
+      if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
+                                     &err)) == NULL)
        {
          error (_("CTF open failure: %s\n"), ctf_errmsg (err));
          goto fail;
        }
+      lookparent = parenta;
+    }
+  else
+    lookparent = ctfa;
 
-      ctf_import (ctf, parent);
+  /* Assume that the applicable parent archive member is the default one.
+     (This is what all known implementations are expected to do, if they
+     put CTFs and their parents in archives together.)  */
+  if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
+    {
+      error (_("CTF open failure: %s\n"), ctf_errmsg (err));
+      goto fail;
     }
 
   ret = TRUE;
@@ -14297,36 +14365,20 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
   printf (_("\nDump of CTF section '%s':\n"),
          printable_section_name (filedata, section));
 
-  for (i = 0, thing = things; *thing[0]; thing++, i++)
-    {
-      ctf_dump_state_t *s = NULL;
-      char *item;
-
-      printf ("\n  %s:\n", *thing);
-      while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
-                              (void *) "    ")) != NULL)
-       {
-         printf ("%s\n", item);
-         free (item);
-       }
-
-      if (ctf_errno (ctf))
-       {
-         error (_("Iteration failed: %s, %s\n"), *thing,
-                  ctf_errmsg (ctf_errno (ctf)));
-         ret = FALSE;
-       }
-    }
+  if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
+    ret = FALSE;
 
  fail:
-  ctf_file_close (ctf);
   ctf_file_close (parent);
+  ctf_close (ctfa);
+  ctf_close (parenta);
   free (parentdata);
   free (data);
   free (symdata);
   free (strdata);
   return ret;
 }
+#endif
 
 static bfd_boolean
 load_specific_debug_section (enum dwarf_section_display_enum  debug,
@@ -14654,12 +14706,9 @@ free_debug_section (enum dwarf_section_display_enum debug)
   section->address = 0;
   section->size = 0;
 
-  if (section->reloc_info != NULL)
-    {
-      free (section->reloc_info);
-      section->reloc_info = NULL;
-      section->num_relocs = 0;
-    }
+  free (section->reloc_info);
+  section->reloc_info = NULL;
+  section->num_relocs = 0;
 }
 
 static bfd_boolean
@@ -14815,11 +14864,13 @@ process_section_contents (Filedata * filedata)
            res = FALSE;
        }
 
+#ifdef ENABLE_LIBCTF
       if (dump & CTF_DUMP)
        {
          if (! dump_section_as_ctf (section, filedata))
            res = FALSE;
        }
+#endif
     }
 
   /* Check to see if the user requested a
@@ -15405,6 +15456,44 @@ display_gnu_attribute (unsigned char * p,
   return display_tag_value (tag, p, end);
 }
 
+static unsigned char *
+display_m68k_gnu_attribute (unsigned char * p,
+                           unsigned int tag,
+                           const unsigned char * const end)
+{
+  unsigned int val;
+
+  if (tag == Tag_GNU_M68K_ABI_FP)
+    {
+      printf ("  Tag_GNU_M68K_ABI_FP: ");
+      if (p == end)
+       {
+         printf (_("<corrupt>\n"));
+         return p;
+       }
+      READ_ULEB (val, p, end);
+
+      if (val > 3)
+       printf ("(%#x), ", val);
+
+      switch (val & 3)
+       {
+       case 0:
+         printf (_("unspecified hard/soft float\n"));
+         break;
+       case 1:
+         printf (_("hard float\n"));
+         break;
+       case 2:
+         printf (_("soft float\n"));
+         break;
+       }
+      return p;
+    }
+
+  return display_tag_value (tag & 1, p, end);
+}
+
 static unsigned char *
 display_power_gnu_attribute (unsigned char * p,
                             unsigned int tag,
@@ -16763,8 +16852,7 @@ process_mips_specific (Filedata * filedata)
            }
 
        sgot_print_fail:
-         if (data)
-           free (data);
+         free (data);
        }
       return res;
     }
@@ -16934,47 +17022,28 @@ process_mips_specific (Filedata * filedata)
                                                 sect->sh_size, _("options"));
       if (eopt)
        {
-         Elf_Internal_Options * iopt;
-         Elf_Internal_Options * option;
-         Elf_Internal_Options * iopt_end;
-
-         iopt = (Elf_Internal_Options *)
-              cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
-         if (iopt == NULL)
-           {
-             error (_("Out of memory allocating space for MIPS options\n"));
-             free (eopt);
-             return FALSE;
-           }
+         Elf_Internal_Options option;
 
          offset = cnt = 0;
-         option = iopt;
-         iopt_end = iopt + (sect->sh_size / sizeof (eopt));
-         
          while (offset <= sect->sh_size - sizeof (* eopt))
            {
              Elf_External_Options * eoption;
+             unsigned int optsize;
 
              eoption = (Elf_External_Options *) ((char *) eopt + offset);
 
-             option->kind = BYTE_GET (eoption->kind);
-             option->size = BYTE_GET (eoption->size);
-             option->section = BYTE_GET (eoption->section);
-             option->info = BYTE_GET (eoption->info);
+             optsize = BYTE_GET (eoption->size);
 
              /* PR 17531: file: ffa0fa3b.  */
-             if (option->size < sizeof (* eopt)
-                 || offset + option->size > sect->sh_size)
+             if (optsize < sizeof (* eopt)
+                 || optsize > sect->sh_size - offset)
                {
                  error (_("Invalid size (%u) for MIPS option\n"),
-                        option->size);
-                 free (iopt);
+                        optsize);
                  free (eopt);
                  return FALSE;
                }
-             offset += option->size;
-
-             ++option;
+             offset += optsize;
              ++cnt;
            }
 
@@ -16983,18 +17052,25 @@ process_mips_specific (Filedata * filedata)
                            cnt),
                  printable_section_name (filedata, sect), cnt);
 
-         option = iopt;
          offset = 0;
-
          while (cnt-- > 0)
            {
              size_t len;
+             Elf_External_Options * eoption;
+
+             eoption = (Elf_External_Options *) ((char *) eopt + offset);
 
-             switch (option->kind)
+             option.kind = BYTE_GET (eoption->kind);
+             option.size = BYTE_GET (eoption->size);
+             option.section = BYTE_GET (eoption->section);
+             option.info = BYTE_GET (eoption->info);
+
+             switch (option.kind)
                {
                case ODK_NULL:
                  /* This shouldn't happen.  */
-                 printf (" NULL       %d %lx", option->section, option->info);
+                 printf (" NULL       %" PRId16 " %" PRIx32,
+                         option.section, option.info);
                  break;
 
                case ODK_REGINFO:
@@ -17005,7 +17081,8 @@ process_mips_specific (Filedata * filedata)
                      Elf32_RegInfo reginfo;
 
                      /* 32bit form.  */
-                     if (option + 2 > iopt_end)
+                     if (option.size < (sizeof (Elf_External_Options)
+                                        + sizeof (Elf32_External_RegInfo)))
                        {
                          printf (_("<corrupt>\n"));
                          error (_("Truncated MIPS REGINFO option\n"));
@@ -17013,7 +17090,7 @@ process_mips_specific (Filedata * filedata)
                          break;
                        }
 
-                     ereg = (Elf32_External_RegInfo *) (option + 1);
+                     ereg = (Elf32_External_RegInfo *) (eoption + 1);
 
                      reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
                      reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
@@ -17022,10 +17099,11 @@ process_mips_specific (Filedata * filedata)
                      reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
                      reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
 
-                     printf ("GPR %08lx  GP 0x%lx\n",
-                             reginfo.ri_gprmask,
-                             (unsigned long) reginfo.ri_gp_value);
-                     printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
+                     printf ("GPR %08" PRIx32 "  GP 0x%" PRIx32 "\n",
+                             reginfo.ri_gprmask, reginfo.ri_gp_value);
+                     printf ("          "
+                             "  CPR0 %08" PRIx32 "  CPR1 %08" PRIx32
+                             "  CPR2 %08" PRIx32 "  CPR3 %08" PRIx32 "\n",
                              reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
                              reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
                    }
@@ -17035,7 +17113,8 @@ process_mips_specific (Filedata * filedata)
                      Elf64_External_RegInfo * ereg;
                      Elf64_Internal_RegInfo reginfo;
 
-                     if (option + 2 > iopt_end)
+                     if (option.size < (sizeof (Elf_External_Options)
+                                        + sizeof (Elf64_External_RegInfo)))
                        {
                          printf (_("<corrupt>\n"));
                          error (_("Truncated MIPS REGINFO option\n"));
@@ -17043,7 +17122,7 @@ process_mips_specific (Filedata * filedata)
                          break;
                        }
 
-                     ereg = (Elf64_External_RegInfo *) (option + 1);
+                     ereg = (Elf64_External_RegInfo *) (eoption + 1);
                      reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
                      reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
                      reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
@@ -17051,54 +17130,53 @@ process_mips_specific (Filedata * filedata)
                      reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
                      reginfo.ri_gp_value   = BYTE_GET (ereg->ri_gp_value);
 
-                     printf ("GPR %08lx  GP 0x",
-                             reginfo.ri_gprmask);
-                     printf_vma (reginfo.ri_gp_value);
-                     printf ("\n");
-
-                     printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
+                     printf ("GPR %08" PRIx32 "  GP 0x%" PRIx64 "\n",
+                             reginfo.ri_gprmask, reginfo.ri_gp_value);
+                     printf ("          "
+                             "  CPR0 %08" PRIx32 "  CPR1 %08" PRIx32
+                             "  CPR2 %08" PRIx32 "  CPR3 %08" PRIx32 "\n",
                              reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
                              reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
                    }
-                 ++option;
+                 offset += option.size;
                  continue;
 
                case ODK_EXCEPTIONS:
                  fputs (" EXCEPTIONS fpe_min(", stdout);
-                 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
+                 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
                  fputs (") fpe_max(", stdout);
-                 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
+                 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
                  fputs (")", stdout);
 
-                 if (option->info & OEX_PAGE0)
+                 if (option.info & OEX_PAGE0)
                    fputs (" PAGE0", stdout);
-                 if (option->info & OEX_SMM)
+                 if (option.info & OEX_SMM)
                    fputs (" SMM", stdout);
-                 if (option->info & OEX_FPDBUG)
+                 if (option.info & OEX_FPDBUG)
                    fputs (" FPDBUG", stdout);
-                 if (option->info & OEX_DISMISS)
+                 if (option.info & OEX_DISMISS)
                    fputs (" DISMISS", stdout);
                  break;
 
                case ODK_PAD:
                  fputs (" PAD       ", stdout);
-                 if (option->info & OPAD_PREFIX)
+                 if (option.info & OPAD_PREFIX)
                    fputs (" PREFIX", stdout);
-                 if (option->info & OPAD_POSTFIX)
+                 if (option.info & OPAD_POSTFIX)
                    fputs (" POSTFIX", stdout);
-                 if (option->info & OPAD_SYMBOL)
+                 if (option.info & OPAD_SYMBOL)
                    fputs (" SYMBOL", stdout);
                  break;
 
                case ODK_HWPATCH:
                  fputs (" HWPATCH   ", stdout);
-                 if (option->info & OHW_R4KEOP)
+                 if (option.info & OHW_R4KEOP)
                    fputs (" R4KEOP", stdout);
-                 if (option->info & OHW_R8KPFETCH)
+                 if (option.info & OHW_R8KPFETCH)
                    fputs (" R8KPFETCH", stdout);
-                 if (option->info & OHW_R5KEOP)
+                 if (option.info & OHW_R5KEOP)
                    fputs (" R5KEOP", stdout);
-                 if (option->info & OHW_R5KCVTL)
+                 if (option.info & OHW_R5KCVTL)
                    fputs (" R5KCVTL", stdout);
                  break;
 
@@ -17114,43 +17192,43 @@ process_mips_specific (Filedata * filedata)
 
                case ODK_HWAND:
                  fputs (" HWAND     ", stdout);
-                 if (option->info & OHWA0_R4KEOP_CHECKED)
+                 if (option.info & OHWA0_R4KEOP_CHECKED)
                    fputs (" R4KEOP_CHECKED", stdout);
-                 if (option->info & OHWA0_R4KEOP_CLEAN)
+                 if (option.info & OHWA0_R4KEOP_CLEAN)
                    fputs (" R4KEOP_CLEAN", stdout);
                  break;
 
                case ODK_HWOR:
                  fputs (" HWOR      ", stdout);
-                 if (option->info & OHWA0_R4KEOP_CHECKED)
+                 if (option.info & OHWA0_R4KEOP_CHECKED)
                    fputs (" R4KEOP_CHECKED", stdout);
-                 if (option->info & OHWA0_R4KEOP_CLEAN)
+                 if (option.info & OHWA0_R4KEOP_CLEAN)
                    fputs (" R4KEOP_CLEAN", stdout);
                  break;
 
                case ODK_GP_GROUP:
-                 printf (" GP_GROUP  %#06lx  self-contained %#06lx",
-                         option->info & OGP_GROUP,
-                         (option->info & OGP_SELF) >> 16);
+                 printf (" GP_GROUP  %#06x  self-contained %#06x",
+                         option.info & OGP_GROUP,
+                         (option.info & OGP_SELF) >> 16);
                  break;
 
                case ODK_IDENT:
-                 printf (" IDENT     %#06lx  self-contained %#06lx",
-                         option->info & OGP_GROUP,
-                         (option->info & OGP_SELF) >> 16);
+                 printf (" IDENT     %#06x  self-contained %#06x",
+                         option.info & OGP_GROUP,
+                         (option.info & OGP_SELF) >> 16);
                  break;
 
                default:
                  /* This shouldn't happen.  */
-                 printf (" %3d ???     %d %lx",
-                         option->kind, option->section, option->info);
+                 printf (" %3d ???     %" PRId16 " %" PRIx32,
+                         option.kind, option.section, option.info);
                  break;
                }
 
              len = sizeof (* eopt);
-             while (len < option->size)
+             while (len < option.size)
                {
-                 unsigned char datum = * ((unsigned char *) eopt + offset + len);
+                 unsigned char datum = *((unsigned char *) eoption + len);
 
                  if (ISPRINT (datum))
                    printf ("%c", datum);
@@ -17160,10 +17238,8 @@ process_mips_specific (Filedata * filedata)
                }
              fputs ("\n", stdout);
 
-             offset += option->size;
-             ++option;
+             offset += option.size;
            }
-         free (iopt);
          free (eopt);
        }
       else
@@ -17396,8 +17472,7 @@ process_mips_specific (Filedata * filedata)
        }
 
     got_print_fail:
-      if (data)
-       free (data);
+      free (data);
     }
 
   if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
@@ -17474,8 +17549,7 @@ process_mips_specific (Filedata * filedata)
        }
       printf ("\n");
 
-      if (data)
-       free (data);
+      free (data);
       free (rels);
     }
 
@@ -18109,6 +18183,9 @@ decode_x86_feature_2 (unsigned int bitmask)
        case GNU_PROPERTY_X86_FEATURE_2_ZMM:
          printf ("ZMM");
          break;
+       case GNU_PROPERTY_X86_FEATURE_2_TMM:
+         printf ("TMM");
+         break;
        case GNU_PROPERTY_X86_FEATURE_2_FXSR:
          printf ("FXSR");
          break;
@@ -19747,11 +19824,8 @@ process_notes_at (Filedata *           filedata,
       if (! process_note (& inote, filedata))
        res = FALSE;
 
-      if (temp != NULL)
-       {
-         free (temp);
-         temp = NULL;
-       }
+      free (temp);
+      temp = NULL;
     }
 
   free (pnotes);
@@ -19984,6 +20058,10 @@ process_arch_specific (Filedata * filedata)
     case EM_NDS32:
       return process_nds32_specific (filedata);
 
+    case EM_68K:
+      return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
+                                display_m68k_gnu_attribute);
+
     case EM_PPC:
     case EM_PPC64:
       return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
@@ -20305,38 +20383,23 @@ process_object (Filedata * filedata)
   filedata->string_table = NULL;
   filedata->string_table_length = 0;
 
-  if (filedata->dump.dump_sects != NULL)
-    {
-      free (filedata->dump.dump_sects);
-      filedata->dump.dump_sects = NULL;
-      filedata->dump.num_dump_sects = 0;
-    }
+  free (filedata->dump.dump_sects);
+  filedata->dump.dump_sects = NULL;
+  filedata->dump.num_dump_sects = 0;
 
-  if (filedata->dynamic_strings)
-    {
-      free (filedata->dynamic_strings);
-      filedata->dynamic_strings = NULL;
-      filedata->dynamic_strings_length = 0;
-    }
+  free (filedata->dynamic_strings);
+  filedata->dynamic_strings = NULL;
+  filedata->dynamic_strings_length = 0;
 
-  if (filedata->dynamic_symbols)
-    {
-      free (filedata->dynamic_symbols);
-      filedata->dynamic_symbols = NULL;
-      filedata->num_dynamic_syms = 0;
-    }
+  free (filedata->dynamic_symbols);
+  filedata->dynamic_symbols = NULL;
+  filedata->num_dynamic_syms = 0;
 
-  if (filedata->dynamic_syminfo)
-    {
-      free (filedata->dynamic_syminfo);
-      filedata->dynamic_syminfo = NULL;
-    }
+  free (filedata->dynamic_syminfo);
+  filedata->dynamic_syminfo = NULL;
 
-  if (filedata->dynamic_section)
-    {
-      free (filedata->dynamic_section);
-      filedata->dynamic_section = NULL;
-    }
+  free (filedata->dynamic_section);
+  filedata->dynamic_section = NULL;
 
   while (filedata->symtab_shndx_list != NULL)
     {
@@ -20345,11 +20408,8 @@ process_object (Filedata * filedata)
       filedata->symtab_shndx_list = next;
     }
 
-  if (filedata->section_headers_groups)
-    {
-      free (filedata->section_headers_groups);
-      filedata->section_headers_groups = NULL;
-    }
+  free (filedata->section_headers_groups);
+  filedata->section_headers_groups = NULL;
 
   if (filedata->section_groups)
     {
@@ -20810,8 +20870,7 @@ main (int argc, char ** argv)
     if (! process_file (argv[optind++]))
       err = TRUE;
 
-  if (cmdline.dump_sects != NULL)
-    free (cmdline.dump_sects);
+  free (cmdline.dump_sects);
 
   free (dump_ctf_symtab_name);
   free (dump_ctf_strtab_name);