Use consistent type in binutils/dwarf.c
[binutils-gdb.git] / binutils / readelf.c
index 9d0104d979172b4fba7d041d71f1eb28d5fe237c..79724e0549467c28d3af0511554cce11adcff489 100644 (file)
@@ -238,6 +238,7 @@ static bool do_not_show_symbol_truncation = false;
 static bool do_demangle = false;       /* Pretty print C++ symbol names.  */
 static bool process_links = false;
 static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
+static int sym_base = 0;
 
 static char *dump_ctf_parent_name;
 static char *dump_ctf_symtab_name;
@@ -262,12 +263,13 @@ typedef struct filedata
   FILE *               handle;
   bfd_size_type        file_size;
   Elf_Internal_Ehdr    file_header;
+  unsigned long        archive_file_offset;
+  unsigned long        archive_file_size;
+  /* Everything below this point is cleared out by free_filedata.  */
   Elf_Internal_Shdr *  section_headers;
   Elf_Internal_Phdr *  program_headers;
   char *               string_table;
   unsigned long        string_table_length;
-  unsigned long        archive_file_offset;
-  unsigned long        archive_file_size;
   unsigned long        dynamic_addr;
   bfd_size_type        dynamic_size;
   size_t               dynamic_nent;
@@ -292,7 +294,7 @@ typedef struct filedata
   bfd_vma *            gnuchains;
   bfd_vma *            mipsxlat;
   bfd_vma              gnusymidx;
-  char                 program_interpreter[PATH_MAX];
+  char *               program_interpreter;
   bfd_vma              dynamic_info[DT_ENCODING];
   bfd_vma              dynamic_info_DT_GNU_HASH;
   bfd_vma              dynamic_info_DT_MIPS_XHASH;
@@ -312,12 +314,17 @@ typedef struct filedata
 typedef enum print_mode
 {
   HEX,
+  HEX_5,
   DEC,
   DEC_5,
   UNSIGNED,
+  UNSIGNED_5,
   PREFIX_HEX,
+  PREFIX_HEX_5,
   FULL_HEX,
-  LONG_HEX
+  LONG_HEX,
+  OCTAL,
+  OCTAL_5
 }
 print_mode;
 
@@ -351,10 +358,6 @@ static const char * get_symbol_version_string
 
 #define DT_VERSIONTAGIDX(tag)  (DT_VERNEEDNUM - (tag)) /* Reverse order!  */
 
-#define GET_ELF_SYMBOLS(file, section, sym_count)                      \
-  (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count)     \
-   : get_64bit_elf_symbols (file, section, sym_count))
-
 #define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
    (strtab != NULL && offset < strtab_size)
 #define VALID_DYNAMIC_NAME(filedata, offset) \
@@ -529,18 +532,34 @@ print_vma (bfd_vma vma, print_mode mode)
     case HEX:
       return nc + printf ("%" BFD_VMA_FMT "x", vma);
 
+    case PREFIX_HEX_5:
+      nc = printf ("0x");
+      /* Fall through.  */
+    case HEX_5:
+      return nc + printf ("%05" BFD_VMA_FMT "x", vma);
+
     case DEC:
       return printf ("%" BFD_VMA_FMT "d", vma);
 
     case UNSIGNED:
       return printf ("%" BFD_VMA_FMT "u", vma);
 
+    case UNSIGNED_5:
+      return printf ("%5" BFD_VMA_FMT "u", vma);
+
+    case OCTAL:
+      return printf ("%" BFD_VMA_FMT "o", vma);
+
+    case OCTAL_5:
+      return printf ("%5" BFD_VMA_FMT "o", vma);
+
     default:
       /* FIXME: Report unrecognised mode ?  */
       return 0;
     }
 }
 
+
 /* Display a symbol on stdout.  Handles the display of control characters and
    multibye characters (assuming the host environment supports them).
 
@@ -2583,7 +2602,7 @@ get_machine_name (unsigned e_machine)
     case EM_ARC_COMPACT3:      return "Synopsys ARCv2.3 32-bit";
     case EM_KVX:               return "Kalray VLIW core of the MPPA processor family";
     case EM_65816:             return "WDC 65816/65C816";
-    case EM_LOONGARCH:         return "Loongson Loongarch";
+    case EM_LOONGARCH:         return "LoongArch";
     case EM_KF32:              return "ChipON KungFu32";
 
       /* Large numbers...  */
@@ -4523,7 +4542,8 @@ enum long_option_values
   OPTION_WITH_SYMBOL_VERSIONS,
   OPTION_RECURSE_LIMIT,
   OPTION_NO_RECURSE_LIMIT,
-  OPTION_NO_DEMANGLING
+  OPTION_NO_DEMANGLING,
+  OPTION_SYM_BASE
 };
 
 static struct option options[] =
@@ -4580,6 +4600,7 @@ static struct option options[] =
   {"ctf-strings",      required_argument, 0, OPTION_CTF_STRINGS},
   {"ctf-parent",       required_argument, 0, OPTION_CTF_PARENT},
 #endif
+  {"sym-base",        optional_argument, 0, OPTION_SYM_BASE},
 
   {0,                 no_argument, 0, 0}
 };
@@ -4589,75 +4610,123 @@ usage (FILE * stream)
 {
   fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
   fprintf (stream, _(" Display information about the contents of ELF format files\n"));
-  fprintf (stream, _(" Options are:\n\
-  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n\
-  -h --file-header       Display the ELF file header\n\
-  -l --program-headers   Display the program headers\n\
-     --segments          An alias for --program-headers\n\
-  -S --section-headers   Display the sections' header\n\
-     --sections          An alias for --section-headers\n\
-  -g --section-groups    Display the section groups\n\
-  -t --section-details   Display the section details\n\
-  -e --headers           Equivalent to: -h -l -S\n\
-  -s --syms              Display the symbol table\n\
-     --symbols           An alias for --syms\n\
-     --dyn-syms          Display the dynamic symbol table\n\
-     --lto-syms          Display LTO symbol tables\n\
+  fprintf (stream, _(" Options are:\n"));
+  fprintf (stream, _("\
+  -a --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
+  fprintf (stream, _("\
+  -h --file-header       Display the ELF file header\n"));
+  fprintf (stream, _("\
+  -l --program-headers   Display the program headers\n"));
+  fprintf (stream, _("\
+     --segments          An alias for --program-headers\n"));
+  fprintf (stream, _("\
+  -S --section-headers   Display the sections' header\n"));
+  fprintf (stream, _("\
+     --sections          An alias for --section-headers\n"));
+  fprintf (stream, _("\
+  -g --section-groups    Display the section groups\n"));
+  fprintf (stream, _("\
+  -t --section-details   Display the section details\n"));
+  fprintf (stream, _("\
+  -e --headers           Equivalent to: -h -l -S\n"));
+  fprintf (stream, _("\
+  -s --syms              Display the symbol table\n"));
+  fprintf (stream, _("\
+     --symbols           An alias for --syms\n"));
+  fprintf (stream, _("\
+     --dyn-syms          Display the dynamic symbol table\n"));
+  fprintf (stream, _("\
+     --lto-syms          Display LTO symbol tables\n"));
+  fprintf (stream, _("\
+     --sym-base=[0|8|10|16] \n\
+                         Force base for symbol sizes.  The options are \n\
+                         mixed (the default), octal, decimal, hexadecimal.\n"));
+  fprintf (stream, _("\
   -C --demangle[=STYLE]  Decode low-level symbol names into user-level names\n\
                           The STYLE, if specified, can be `auto' (the default),\n\
                           `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
-                          or `gnat'\n\
-     --no-demangle       Do not demangle low-level symbol names.  (This is the default)\n\
-     --recurse-limit     Enable a demangling recursion limit.  (This is the default)\n\
-     --no-recurse-limit  Disable a demangling recursion limit\n\
-  -n --notes             Display the core notes (if present)\n\
-  -r --relocs            Display the relocations (if present)\n\
-  -u --unwind            Display the unwind info (if present)\n\
-  -d --dynamic           Display the dynamic section (if present)\n\
-  -V --version-info      Display the version sections (if present)\n\
-  -A --arch-specific     Display architecture specific information (if any)\n\
-  -c --archive-index     Display the symbol/file index in an archive\n\
-  -D --use-dynamic       Use the dynamic section info when displaying symbols\n\
-  -L --lint|--enable-checks  Display warning messages for possible problems\n\
+                          or `gnat'\n"));
+  fprintf (stream, _("\
+     --no-demangle       Do not demangle low-level symbol names.  (default)\n"));
+  fprintf (stream, _("\
+     --recurse-limit     Enable a demangling recursion limit.  (default)\n"));
+  fprintf (stream, _("\
+     --no-recurse-limit  Disable a demangling recursion limit\n"));
+  fprintf (stream, _("\
+  -n --notes             Display the core notes (if present)\n"));
+  fprintf (stream, _("\
+  -r --relocs            Display the relocations (if present)\n"));
+  fprintf (stream, _("\
+  -u --unwind            Display the unwind info (if present)\n"));
+  fprintf (stream, _("\
+  -d --dynamic           Display the dynamic section (if present)\n"));
+  fprintf (stream, _("\
+  -V --version-info      Display the version sections (if present)\n"));
+  fprintf (stream, _("\
+  -A --arch-specific     Display architecture specific information (if any)\n"));
+  fprintf (stream, _("\
+  -c --archive-index     Display the symbol/file index in an archive\n"));
+  fprintf (stream, _("\
+  -D --use-dynamic       Use the dynamic section info when displaying symbols\n"));
+  fprintf (stream, _("\
+  -L --lint|--enable-checks\n\
+                         Display warning messages for possible problems\n"));
+  fprintf (stream, _("\
   -x --hex-dump=<number|name>\n\
-                         Dump the contents of section <number|name> as bytes\n\
+                         Dump the contents of section <number|name> as bytes\n"));
+  fprintf (stream, _("\
   -p --string-dump=<number|name>\n\
-                         Dump the contents of section <number|name> as strings\n\
+                         Dump the contents of section <number|name> as strings\n"));
+  fprintf (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[lLiaprmfFsoORtUuTgAc] or\n\
-  --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
-               =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
-               =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
-               =addr,=cu_index]\n\
-                         Display the contents of DWARF debug sections\n\
-  -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\
-  -P,--process-links     Display the contents of non-debug sections in separate debuginfo files.  (Implies -wK)\n"));
+                         Dump the relocated contents of section <number|name>\n"));
+  fprintf (stream, _("\
+  -z --decompress        Decompress section before dumping it\n"));
+  fprintf (stream, _("\
+  -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
+                  f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
+                  m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
+                  s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
+                  U/=trace_info]\n\
+                         Display the contents of DWARF debug sections\n"));
+  fprintf (stream, _("\
+  -wk --debug-dump=links Display the contents of sections that link to separate\n\
+                          debuginfo files\n"));
+  fprintf (stream, _("\
+  -P --process-links     Display the contents of non-debug sections in separate\n\
+                          debuginfo files.  (Implies -wK)\n"));
 #if DEFAULT_FOR_FOLLOW_LINKS
   fprintf (stream, _("\
-  -wK,--debug-dump=follow-links     Follow links to separate debug info files (default)\n\
-  -wN,--debug-dump=no-follow-links  Do not follow links to separate debug info files\n\
-"));
+  -wK --debug-dump=follow-links\n\
+                         Follow links to separate debug info files (default)\n"));
+  fprintf (stream, _("\
+  -wN --debug-dump=no-follow-links\n\
+                         Do not follow links to separate debug info files\n"));
 #else
   fprintf (stream, _("\
-  -wK,--debug-dump=follow-links     Follow links to separate debug info files\n\
-  -wN,--debug-dump=no-follow-links  Do not follow links to separate debug info files (default)\n\
-"));
+  -wK --debug-dump=follow-links\n\
+                         Follow links to separate debug info files\n"));
+  fprintf (stream, _("\
+  -wN --debug-dump=no-follow-links\n\
+                         Do not follow links to separate debug info files\n\
+                          (default)\n"));
 #endif
   fprintf (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"));
+  --dwarf-depth=N        Do not display DIEs at depth N or greater\n"));
+  fprintf (stream, _("\
+  --dwarf-start=N        Display DIEs starting at offset N\n"));
 #ifdef ENABLE_LIBCTF
   fprintf (stream, _("\
-  --ctf=<number|name>    Display CTF info from section <number|name>\n\
+  --ctf=<number|name>    Display CTF info from section <number|name>\n"));
+  fprintf (stream, _("\
   --ctf-parent=<number|name>\n\
-                         Use section <number|name> as the CTF parent\n\n\
+                         Use section <number|name> as the CTF parent\n"));
+  fprintf (stream, _("\
   --ctf-symbols=<number|name>\n\
-                         Use section <number|name> as the CTF external symtab\n\n\
+                         Use section <number|name> as the CTF external symtab\n"));
+  fprintf (stream, _("\
   --ctf-strings=<number|name>\n\
-                         Use section <number|name> as the CTF external strtab\n\n"));
+                         Use section <number|name> as the CTF external strtab\n"));
 #endif
 
 #ifdef SUPPORT_DISASSEMBLY
@@ -4666,11 +4735,16 @@ usage (FILE * stream)
                          Disassemble the contents of section <number|name>\n"));
 #endif
   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\
+  -I --histogram         Display histogram of bucket list lengths\n"));
+  fprintf (stream, _("\
+  -W --wide              Allow output width to exceed 80 characters\n"));
+  fprintf (stream, _("\
+  -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
+  fprintf (stream, _("\
+  @<file>                Read options from <file>\n"));
+  fprintf (stream, _("\
+  -H --help              Display this information\n"));
+  fprintf (stream, _("\
   -v --version           Display the version number of readelf\n"));
 
   if (REPORT_BUGS_TO[0] && stream == stdout)
@@ -4873,7 +4947,10 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
        case OPTION_DEBUG_DUMP:
          do_dump = true;
          if (optarg == NULL)
-           do_debugging = true;
+           {
+             do_debugging = true;
+             dwarf_select_sections_all ();
+           }
          else
            {
              do_debugging = false;
@@ -4962,6 +5039,26 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
          /* Ignored for backward compatibility.  */
          break;
 
+       case OPTION_SYM_BASE:
+         sym_base = 0;
+         if (optarg != NULL)
+           {
+             sym_base = strtoul (optarg, NULL, 0);
+             switch (sym_base)
+               {
+                 case 0:
+                 case 8:
+                 case 10:
+                 case 16:
+                   break;
+
+                 default:
+                   sym_base = 0;
+                   break;
+               }
+           }
+         break;
+
        default:
          /* xgettext:c-format */
          error (_("Invalid option '-%c'\n"), c);
@@ -5140,8 +5237,6 @@ process_file_header (Filedata * filedata)
        header->e_shstrndx = filedata->section_headers[0].sh_link;
       if (header->e_shstrndx >= header->e_shnum)
        header->e_shstrndx = SHN_UNDEF;
-      free (filedata->section_headers);
-      filedata->section_headers = NULL;
     }
 
   return true;
@@ -5538,22 +5633,21 @@ the .dynamic section is not the same as the dynamic segment\n"));
          break;
 
        case PT_INTERP:
-         if (fseek (filedata->handle,
-                    filedata->archive_file_offset + (long) segment->p_offset,
-                    SEEK_SET))
+         if (segment->p_offset >= filedata->file_size
+             || segment->p_filesz > filedata->file_size - segment->p_offset
+             || segment->p_filesz - 1 >= (size_t) -2
+             || fseek (filedata->handle,
+                       filedata->archive_file_offset + (long) segment->p_offset,
+                       SEEK_SET))
            error (_("Unable to find program interpreter name\n"));
          else
            {
-             char fmt [32];
-             int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
-
-             if (ret >= (int) sizeof (fmt) || ret < 0)
-               error (_("Internal error: failed to create format string to display program interpreter\n"));
-
-             filedata->program_interpreter[0] = 0;
-             if (fscanf (filedata->handle, fmt,
-                         filedata->program_interpreter) <= 0)
-               error (_("Unable to read program interpreter name\n"));
+             size_t len = segment->p_filesz;
+             free (filedata->program_interpreter);
+             filedata->program_interpreter = xmalloc (len + 1);
+             len = fread (filedata->program_interpreter, 1, len,
+                          filedata->handle);
+             filedata->program_interpreter[len] = 0;
 
              if (do_segments)
                printf (_("      [Requesting program interpreter: %s]\n"),
@@ -5657,7 +5751,6 @@ get_32bit_section_headers (Filedata * filedata, bool probe)
   if (shdrs == NULL)
     return false;
 
-  free (filedata->section_headers);
   filedata->section_headers = (Elf_Internal_Shdr *)
     cmalloc (num, sizeof (Elf_Internal_Shdr));
   if (filedata->section_headers == NULL)
@@ -5724,7 +5817,6 @@ get_64bit_section_headers (Filedata * filedata, bool probe)
   if (shdrs == NULL)
     return false;
 
-  free (filedata->section_headers);
   filedata->section_headers = (Elf_Internal_Shdr *)
     cmalloc (num, sizeof (Elf_Internal_Shdr));
   if (filedata->section_headers == NULL)
@@ -5759,6 +5851,18 @@ get_64bit_section_headers (Filedata * filedata, bool probe)
   return true;
 }
 
+static bool
+get_section_headers (Filedata *filedata, bool probe)
+{
+  if (filedata->section_headers != NULL)
+    return true;
+
+  if (is_32bit_elf)
+    return get_32bit_section_headers (filedata, probe);
+  else
+    return get_64bit_section_headers (filedata, probe);
+}
+
 static Elf_Internal_Sym *
 get_32bit_elf_symbols (Filedata *           filedata,
                       Elf_Internal_Shdr *  section,
@@ -5995,6 +6099,17 @@ get_64bit_elf_symbols (Filedata *           filedata,
   return isyms;
 }
 
+static Elf_Internal_Sym *
+get_elf_symbols (Filedata *filedata,
+                Elf_Internal_Shdr *section,
+                unsigned long *num_syms_return)
+{
+  if (is_32bit_elf)
+    return get_32bit_elf_symbols (filedata, section, num_syms_return);
+  else
+    return get_64bit_elf_symbols (filedata, section, num_syms_return);
+}
+
 static const char *
 get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
 {
@@ -6352,23 +6467,6 @@ process_section_headers (Filedata * filedata)
   Elf_Internal_Shdr * section;
   unsigned int i;
 
-  free (filedata->section_headers);
-  filedata->section_headers = NULL;
-  free (filedata->dynamic_symbols);
-  filedata->dynamic_symbols = NULL;
-  filedata->num_dynamic_syms = 0;
-  free (filedata->dynamic_strings);
-  filedata->dynamic_strings = NULL;
-  filedata->dynamic_strings_length = 0;
-  free (filedata->dynamic_syminfo);
-  filedata->dynamic_syminfo = NULL;
-  while (filedata->symtab_shndx_list != NULL)
-    {
-      elf_section_list *next = filedata->symtab_shndx_list->next;
-      free (filedata->symtab_shndx_list);
-      filedata->symtab_shndx_list = next;
-    }
-
   if (filedata->file_header.e_shnum == 0)
     {
       /* PR binutils/12467.  */
@@ -6398,16 +6496,8 @@ process_section_headers (Filedata * filedata)
                (unsigned long) filedata->file_header.e_shoff);
     }
 
-  if (is_32bit_elf)
-    {
-      if (! get_32bit_section_headers (filedata, false))
-       return false;
-    }
-  else
-    {
-      if (! get_64bit_section_headers (filedata, false))
-       return false;
-    }
+  if (!get_section_headers (filedata, false))
+    return false;
 
   /* Read in the string table, so that we have names to display.  */
   if (filedata->file_header.e_shstrndx != SHN_UNDEF
@@ -6516,7 +6606,7 @@ process_section_headers (Filedata * filedata)
 
          CHECK_ENTSIZE (section, i, Sym);
          filedata->dynamic_symbols
-           = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
+           = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
          filedata->dynamic_symtab_section = section;
          break;
 
@@ -7071,7 +7161,7 @@ get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
 {
   *strtab = NULL;
   *strtablen = 0;
-  *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
+  *symtab = get_elf_symbols (filedata, symsec, nsyms);
 
   if (*symtab == NULL)
     return false;
@@ -7214,7 +7304,7 @@ process_section_groups (Filedata * filedata)
 
   if (filedata->is_separate)
     printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
-      
+
   for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
        i < filedata->file_header.e_shnum;
        i++, section++)
@@ -7242,7 +7332,7 @@ process_section_groups (Filedata * filedata)
            {
              symtab_sec = sec;
              free (symtab);
-             symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
+             symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
            }
 
          if (symtab == NULL)
@@ -7665,7 +7755,6 @@ process_relocs (Filedata * filedata)
                printf
                  (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
                   name, rel_offset, rel_size);
-               
 
              dump_relocations (filedata,
                                offset_from_vma (filedata, rel_offset, rel_size),
@@ -9785,6 +9874,13 @@ arm_process_unwind (Filedata * filedata)
   return res;
 }
 
+static bool
+no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
+{
+  printf (_("No processor specific unwind information to decode\n"));
+  return true;
+}
+
 static bool
 process_unwind (Filedata * filedata)
 {
@@ -9798,6 +9894,8 @@ process_unwind (Filedata * filedata)
     { EM_IA_64, ia64_process_unwind },
     { EM_PARISC, hppa_process_unwind },
     { EM_TI_C6000, arm_process_unwind },
+    { EM_386, no_processor_specific_unwind },
+    { EM_X86_64, no_processor_specific_unwind },
     { 0, NULL }
   };
   int i;
@@ -10171,6 +10269,18 @@ get_64bit_dynamic_section (Filedata * filedata)
   return true;
 }
 
+static bool
+get_dynamic_section (Filedata *filedata)
+{
+  if (filedata->dynamic_section)
+    return true;
+
+  if (is_32bit_elf)
+    return get_32bit_dynamic_section (filedata);
+  else
+    return get_64bit_dynamic_section (filedata);
+}
+
 static void
 print_dynamic_flags (bfd_vma flags)
 {
@@ -10514,16 +10624,8 @@ process_dynamic_section (Filedata * filedata)
       return true;
     }
 
-  if (is_32bit_elf)
-    {
-      if (! get_32bit_dynamic_section (filedata))
-       return false;
-    }
-  else
-    {
-      if (! get_64bit_dynamic_section (filedata))
-       return false;
-    }
+  if (!get_dynamic_section (filedata))
+    return false;
 
   /* Find the appropriate symbol table.  */
   if (filedata->dynamic_symbols == NULL || do_histogram)
@@ -10607,7 +10709,7 @@ the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
 
                  section.sh_name = filedata->string_table_length;
                  filedata->dynamic_symbols
-                   = GET_ELF_SYMBOLS (filedata, &section,
+                   = get_elf_symbols (filedata, &section,
                                       &filedata->num_dynamic_syms);
                  if (filedata->dynamic_symbols == NULL
                      || filedata->num_dynamic_syms != num_of_syms)
@@ -11094,7 +11196,8 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
                    case DT_NEEDED:
                      printf (_("Shared library: [%s]"), name);
 
-                     if (streq (name, filedata->program_interpreter))
+                     if (filedata->program_interpreter
+                         && streq (name, filedata->program_interpreter))
                        printf (_(" program interpreter"));
                      break;
 
@@ -11353,7 +11456,7 @@ process_version_sections (Filedata * filedata)
                                section->sh_info),
                      printable_section_name (filedata, section),
                      section->sh_info);
-             
+
            printf (_(" Addr: 0x"));
            printf_vma (section->sh_addr);
            printf (_("  Offset: %#08lx  Link: %u (%s)\n"),
@@ -11500,7 +11603,7 @@ process_version_sections (Filedata * filedata)
                                section->sh_info),
                      printable_section_name (filedata, section),
                      section->sh_info);
-             
+
            printf (_(" Addr: 0x"));
            printf_vma (section->sh_addr);
            printf (_("  Offset: %#08lx  Link: %u (%s)\n"),
@@ -11636,7 +11739,7 @@ process_version_sections (Filedata * filedata)
 
            found = true;
 
-           symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
+           symbols = get_elf_symbols (filedata, link_section, & num_syms);
            if (symbols == NULL)
              break;
 
@@ -12372,6 +12475,28 @@ get_symbol_version_string (Filedata *                   filedata,
   return NULL;
 }
 
+/* Display a symbol size on stdout.  Format is based on --sym-base setting.  */
+
+static unsigned int
+print_dynamic_symbol_size (bfd_vma vma, int base)
+{
+  switch (base)
+    {
+    case 8:
+      return print_vma (vma, OCTAL_5);
+
+    case 10:
+      return print_vma (vma, UNSIGNED_5);
+
+    case 16:
+      return print_vma (vma, PREFIX_HEX_5);
+
+    case 0:
+    default:
+      return print_vma (vma, DEC_5);
+    }
+}
+
 static void
 print_dynamic_symbol (Filedata *filedata, unsigned long si,
                      Elf_Internal_Sym *symtab,
@@ -12381,12 +12506,14 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
   const char *version_string;
   enum versioned_symbol_info sym_info;
   unsigned short vna_other;
+  bool is_valid;
+  const char * sstr;
   Elf_Internal_Sym *psym = symtab + si;
 
   printf ("%6ld: ", si);
   print_vma (psym->st_value, LONG_HEX);
   putchar (' ');
-  print_vma (psym->st_size, DEC_5);
+  print_dynamic_symbol_size (psym->st_size, sym_base);
   printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
   printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
   if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
@@ -12404,8 +12531,20 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si,
     }
   printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
 
-  bool is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
-  const char * sstr = is_valid  ? strtab + psym->st_name : _("<corrupt>");
+  if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
+      && psym->st_shndx < filedata->file_header.e_shnum
+      && psym->st_name == 0)
+    {
+      is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
+      sstr = is_valid ?
+       SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
+       : _("<corrupt>");
+    }
+  else
+    {
+      is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
+      sstr = is_valid  ? strtab + psym->st_name : _("<corrupt>");
+    }
 
   version_string
     = get_symbol_version_string (filedata,
@@ -12526,7 +12665,7 @@ display_lto_symtab (Filedata *           filedata,
       else
        printf (_("\nLTO Symbol table '%s' is empty!\n"),
                printable_section_name (filedata, section));
-      
+
       return true;
     }
 
@@ -12802,7 +12941,7 @@ process_symbol_table (Filedata * filedata)
          else
            printf (_("   Num:    Value          Size Type    Bind   Vis      Ndx Name\n"));
 
-         symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
+         symtab = get_elf_symbols (filedata, section, & num_syms);
          if (symtab == NULL)
            continue;
 
@@ -14168,7 +14307,7 @@ apply_relocations (Filedata *                 filedata,
       if (filedata->file_header.e_machine == EM_SH)
        is_rela = false;
 
-      symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
+      symtab = get_elf_symbols (filedata, symsec, & num_syms);
 
       for (rp = relocs; rp < relocs + num_relocs; ++rp)
        {
@@ -15522,7 +15661,7 @@ process_section_contents (Filedata * filedata)
 
       if (filedata->is_separate && ! process_links)
        dump &= DEBUG_DUMP;
-      
+
 #ifdef SUPPORT_DISASSEMBLY
       if (dump & DISASS_DUMP)
        {
@@ -18585,6 +18724,12 @@ get_note_type (Filedata * filedata, unsigned e_type)
        return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
       case NT_ARM_HW_WATCH:
        return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
+      case NT_ARM_SVE:
+       return _("NT_ARM_SVE (AArch SVE registers)");
+      case NT_ARM_PAC_MASK:
+       return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
+      case NT_ARM_TAGGED_ADDR_CTRL:
+       return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
       case NT_ARC_V2:
        return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
       case NT_RISCV_CSR:
@@ -18605,6 +18750,8 @@ get_note_type (Filedata * filedata, unsigned e_type)
        return _("NT_SIGINFO (siginfo_t data)");
       case NT_FILE:
        return _("NT_FILE (mapped files)");
+      case NT_MEMTAG:
+       return _("NT_MEMTAG (memory tags)");
       default:
        break;
       }
@@ -19583,15 +19730,11 @@ get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
       /* NetBSD core "procinfo" structure.  */
       return _("NetBSD procinfo structure");
 
-#ifdef NT_NETBSDCORE_AUXV
     case NT_NETBSDCORE_AUXV:
       return _("NetBSD ELF auxiliary vector data");
-#endif
 
-#ifdef NT_NETBSDCORE_LWPSTATUS
     case NT_NETBSDCORE_LWPSTATUS:
       return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
-#endif
 
     default:
       /* As of Jan 2020 there are no other machine-independent notes
@@ -21037,17 +21180,50 @@ get_file_header (Filedata * filedata)
       filedata->file_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
     }
 
-  if (filedata->file_header.e_shoff)
+  return true;
+}
+
+static void
+free_filedata (Filedata *filedata)
+{
+  free (filedata->program_interpreter);
+  free (filedata->program_headers);
+  free (filedata->section_headers);
+  free (filedata->string_table);
+  free (filedata->dump.dump_sects);
+  free (filedata->dynamic_strings);
+  free (filedata->dynamic_symbols);
+  free (filedata->dynamic_syminfo);
+  free (filedata->dynamic_section);
+
+  while (filedata->symtab_shndx_list != NULL)
     {
-      /* There may be some extensions in the first section header.  Don't
-        bomb if we can't read it.  */
-      if (is_32bit_elf)
-       get_32bit_section_headers (filedata, true);
-      else
-       get_64bit_section_headers (filedata, true);
+      elf_section_list *next = filedata->symtab_shndx_list->next;
+      free (filedata->symtab_shndx_list);
+      filedata->symtab_shndx_list = next;
     }
 
-  return true;
+  free (filedata->section_headers_groups);
+
+  if (filedata->section_groups)
+    {
+      size_t i;
+      struct group_list * g;
+      struct group_list * next;
+
+      for (i = 0; i < filedata->group_count; i++)
+       {
+         for (g = filedata->section_groups [i].root; g != NULL; g = next)
+           {
+             next = g->next;
+             free (g);
+           }
+       }
+
+      free (filedata->section_groups);
+    }
+  memset (&filedata->section_headers, 0,
+         sizeof (Filedata) - offsetof (Filedata, section_headers));
 }
 
 static void
@@ -21064,6 +21240,7 @@ close_file (Filedata * filedata)
 void
 close_debug_file (void * data)
 {
+  free_filedata ((Filedata *) data);
   close_file ((Filedata *) data);
 }
 
@@ -21092,19 +21269,8 @@ open_file (const char * pathname, bool is_separate)
   if (! get_file_header (filedata))
     goto fail;
 
-  if (filedata->file_header.e_shoff)
-    {
-      bool res;
-
-      /* Read the section headers again, this time for real.  */
-      if (is_32bit_elf)
-       res = get_32bit_section_headers (filedata, false);
-      else
-       res = get_64bit_section_headers (filedata, false);
-
-      if (!res)
-       goto fail;
-    }
+  if (!get_section_headers (filedata, false))
+    goto fail;
 
   return filedata;
 
@@ -21180,8 +21346,20 @@ process_object (Filedata * filedata)
 
   initialise_dump_sects (filedata);
 
+  /* There may be some extensions in the first section header.  Don't
+     bomb if we can't read it.  */
+  get_section_headers (filedata, true);
+
   if (! process_file_header (filedata))
-    return false;
+    {
+      res = false;
+      goto out;
+    }
+
+  /* Throw away the single section header read above, so that we
+     re-read the entire set.  */
+  free (filedata->section_headers);
+  filedata->section_headers = NULL;
 
   if (! process_section_headers (filedata))
     {
@@ -21277,61 +21455,8 @@ process_object (Filedata * filedata)
   if (! process_arch_specific (filedata))
     res = false;
 
-  free (filedata->program_headers);
-  filedata->program_headers = NULL;
-
-  free (filedata->section_headers);
-  filedata->section_headers = NULL;
-
-  free (filedata->string_table);
-  filedata->string_table = NULL;
-  filedata->string_table_length = 0;
-
-  free (filedata->dump.dump_sects);
-  filedata->dump.dump_sects = NULL;
-  filedata->dump.num_dump_sects = 0;
-
-  free (filedata->dynamic_strings);
-  filedata->dynamic_strings = NULL;
-  filedata->dynamic_strings_length = 0;
-
-  free (filedata->dynamic_symbols);
-  filedata->dynamic_symbols = NULL;
-  filedata->num_dynamic_syms = 0;
-
-  free (filedata->dynamic_syminfo);
-  filedata->dynamic_syminfo = NULL;
-
-  free (filedata->dynamic_section);
-  filedata->dynamic_section = NULL;
-
-  while (filedata->symtab_shndx_list != NULL)
-    {
-      elf_section_list *next = filedata->symtab_shndx_list->next;
-      free (filedata->symtab_shndx_list);
-      filedata->symtab_shndx_list = next;
-    }
-
-  free (filedata->section_headers_groups);
-  filedata->section_headers_groups = NULL;
-
-  if (filedata->section_groups)
-    {
-      struct group_list * g;
-      struct group_list * next;
-
-      for (i = 0; i < filedata->group_count; i++)
-       {
-         for (g = filedata->section_groups [i].root; g != NULL; g = next)
-           {
-             next = g->next;
-             free (g);
-           }
-       }
-
-      free (filedata->section_groups);
-      filedata->section_groups = NULL;
-    }
+ out:
+  free_filedata (filedata);
 
   free_debug_memory ();