]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
readelf section reading
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index cf2011753c8d853792e0763362056f698f17ead0..52d5302d07b59d19d747f5ccfd09621032b3dfb4 100644 (file)
@@ -357,10 +357,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) \
@@ -2605,7 +2601,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...  */
@@ -4613,78 +4609,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\
+                         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
@@ -4693,11 +4734,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)
@@ -4900,7 +4946,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;
@@ -5703,7 +5752,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)
@@ -5770,7 +5818,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)
@@ -5805,6 +5852,21 @@ 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 (filedata->file_header.e_shoff == 0)
+    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,
@@ -6041,6 +6103,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)
 {
@@ -6398,23 +6471,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.  */
@@ -6444,16 +6500,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
@@ -6562,7 +6610,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;
 
@@ -7117,7 +7165,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;
@@ -7288,7 +7336,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)
@@ -10225,6 +10273,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)
 {
@@ -10568,16 +10628,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)
@@ -10661,7 +10713,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)
@@ -11691,7 +11743,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;
 
@@ -12893,7 +12945,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;
 
@@ -14259,7 +14311,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)
        {
@@ -18676,6 +18728,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:
@@ -18696,6 +18754,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;
       }
@@ -21124,16 +21184,6 @@ get_file_header (Filedata * filedata)
       filedata->file_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
     }
 
-  if (filedata->file_header.e_shoff)
-    {
-      /* 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);
-    }
-
   return true;
 }
 
@@ -21244,19 +21294,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;
 
@@ -21332,8 +21371,15 @@ 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;
+    }
 
   if (! process_section_headers (filedata))
     {
@@ -21429,6 +21475,7 @@ process_object (Filedata * filedata)
   if (! process_arch_specific (filedata))
     res = false;
 
+ out:
   free_filedata (filedata);
 
   free_debug_memory ();