Add support for decoding the DW_MACRO_define_strx and DW_MACRO_undef_strx operands...
authorNick Clifton <nickc@redhat.com>
Mon, 22 Jun 2020 16:44:56 +0000 (17:44 +0100)
committerNick Clifton <nickc@redhat.com>
Mon, 22 Jun 2020 16:44:56 +0000 (17:44 +0100)
PR 26112
* dwarf.c (display_debug_str_offsets): Add code to display the
contents of the .debug_str_offsets section.
(display_debug_macro): Add support for DW_MACRO_define_strx and
DW_MACRO_undef_strx.

binutils/ChangeLog
binutils/doc/binutils.texi
binutils/doc/debug.options.texi
binutils/dwarf.c
binutils/dwarf.h
binutils/objdump.c
binutils/readelf.c

index 700c1ea9397a580a65c38219702b95c0dac646cf..7537fcbadb08ce09bf1f12f67af1618d8a67f0b4 100644 (file)
@@ -1,3 +1,11 @@
+2020-06-22  Nick Clifton  <nickc@redhat.com>
+
+       PR 26112
+       * dwarf.c (display_debug_str_offsets): Add code to display the
+       contents of the .debug_str_offsets section.
+       (display_debug_macro): Add support for DW_MACRO_define_strx and
+       DW_MACRO_undef_strx.
+
 2020-06-22  Saagar Jha  <saagar@saagarjha.com>
 
        * od-macho.c: Dump linkedit data for new load commands.
index 901f9e343800af18a1686d71f8b3ec33949635c6..2cf81879df629388a6ca35b47bb4431a091d12ee 100644 (file)
@@ -2153,8 +2153,8 @@ objdump [@option{-a}|@option{--archive-headers}]
         [@option{-r}|@option{--reloc}]
         [@option{-R}|@option{--dynamic-reloc}]
         [@option{-s}|@option{--full-contents}]
-        [@option{-W[lLiaprmfFsoRtUuTgAckK]}|
-         @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]]
+        [@option{-W[lLiaprmfFsoORtUuTgAckK]}|
+         @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]]
         [@option{--ctf=}@var{section}]
         [@option{-G}|@option{--stabs}]
         [@option{-t}|@option{--syms}]
@@ -2704,8 +2704,8 @@ If it is necessary to disable the @option{visualize-jumps} option
 after it has previously been enabled then use
 @option{visualize-jumps=off}.
 
-@item -W[lLiaprmfFsoRtUuTgAckK]
-@itemx --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]
+@item -W[lLiaprmfFsoORtUuTgAckK]
+@itemx --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]
 @include debug.options.texi
 
 @item --dwarf-check
@@ -4714,8 +4714,8 @@ readelf [@option{-a}|@option{--all}]
         [@option{-R} <number or name>|@option{--relocated-dump=}<number or name>]
         [@option{-z}|@option{--decompress}]
         [@option{-c}|@option{--archive-index}]
-        [@option{-w[lLiaprmfFsoRtUuTgAckK]}|
-         @option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]]
+        [@option{-w[lLiaprmfFsoORtUuTgAckK]}|
+         @option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]]
         [@option{--dwarf-depth=@var{n}}]
         [@option{--dwarf-start=@var{n}}]
         [@option{--ctf=}@var{section}]
@@ -4907,8 +4907,8 @@ Displays the file symbol index information contained in the header part
 of binary archives.  Performs the same function as the @option{t}
 command to @command{ar}, but without using the BFD library.  @xref{ar}.
 
-@item -w[lLiaprmfFsoRtUuTgAckK]
-@itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]
+@item -w[lLiaprmfFsOoRtUuTgAckK]
+@itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links]
 @include debug.options.texi
 
 @include ctf.options.texi
index 7f07388b5672088f6f4c4db39c54062404dab4c9..31260c1d19ec8377a6baa2defbb951cd51b9e6b3 100644 (file)
@@ -80,6 +80,10 @@ Displays the contents of the @samp{.debug_macro} and/or
 Displays the contents of the @samp{.debug_loc} and/or
 @samp{.debug_loclists} sections.
 
+@item O
+@itemx =str-offsets
+Displays the contents of the @samp{.debug_str_offsets} section.
+
 @item p
 @itemx =pubnames
 Displays the contents of the @samp{.debug_pubnames} and/or
index c2e73f72fe8495c395d68f666e0d8d3a8907b247..54acd53bd71853a80981fbcb6ea11a6cbb9a494d 100644 (file)
@@ -88,6 +88,7 @@ int do_debug_frames;
 int do_debug_frames_interp;
 int do_debug_macinfo;
 int do_debug_str;
+int do_debug_str_offsets;
 int do_debug_loc;
 int do_gdb_index;
 int do_trace_info;
@@ -726,28 +727,63 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
   enum dwarf_section_display_enum idx_sec_idx = dwo ? str_index_dwo : str_index;
   struct dwarf_section *index_section = &debug_displays [idx_sec_idx].section;
   struct dwarf_section *str_section = &debug_displays [str_sec_idx].section;
-  dwarf_vma index_offset = idx * offset_size;
+  dwarf_vma index_offset;
   dwarf_vma str_offset;
   const char * ret;
+  unsigned char *curr = index_section->start;
+  const unsigned char *end = curr + index_section->size;
+  dwarf_vma length;
 
   if (index_section->start == NULL)
     return (dwo ? _("<no .debug_str_offsets.dwo section>")
                : _("<no .debug_str_offsets section>"));
 
+  if (str_section->start == NULL)
+    return (dwo ? _("<no .debug_str.dwo section>")
+               : _("<no .debug_str section>"));
+
+  /* FIXME: We should cache the length...  */
+  SAFE_BYTE_GET_AND_INC (length, curr, 4, end);
+  if (length == 0xffffffff)
+    {
+      if (offset_size != 8)
+       warn (_("UGG"));
+      SAFE_BYTE_GET_AND_INC (length, curr, 8, end);
+    }
+  else if (offset_size != 4)
+    {
+      warn (_("ugg"));
+    }
+
+  /* Skip the version and padding bytes.
+     We assume that they are correct.  */
+  curr += 4;
+
+  /* FIXME: The code below assumes that there is only one table
+     in the .debug_str_offsets section, so check that now.  */
+  if ((offset_size == 4 && curr + length < (end - 8))
+      || (offset_size == 8 && curr + length < (end - 16)))
+    {
+      warn (_("index table size is too small %s vs %s\n"),
+           dwarf_vmatoa ("x", length),
+           dwarf_vmatoa ("x", index_section->size));
+      return _("<table too small");
+    }
+
+  index_offset = idx * offset_size;
+      
   if (this_set != NULL)
     index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS];
-  if (index_offset >= index_section->size)
+
+  if (index_offset >= length)
     {
-      warn (_("DW_FORM_GNU_str_index offset too big: %s\n"),
-           dwarf_vmatoa ("x", index_offset));
+      warn (_("DW_FORM_GNU_str_index offset too big: %s vs %s\n"),
+           dwarf_vmatoa ("x", index_offset),
+           dwarf_vmatoa ("x", length));
       return _("<index offset is too big>");
     }
 
-  if (str_section->start == NULL)
-    return (dwo ? _("<no .debug_str.dwo section>")
-               : _("<no .debug_str section>"));
-
-  str_offset = byte_get (index_section->start + index_offset, offset_size);
+  str_offset = byte_get (curr + index_offset, offset_size);
   str_offset -= str_section->address;
   if (str_offset >= str_section->size)
     {
@@ -3161,7 +3197,7 @@ process_debug_info (struct dwarf_section *           section,
       load_debug_section_with_follow (str_index_dwo, file);
       load_debug_section_with_follow (debug_addr, file);
     }
-
+  
   load_debug_section_with_follow (abbrev_sec, file);
   if (debug_displays [abbrev_sec].section.start == NULL)
     {
@@ -5382,6 +5418,7 @@ display_debug_macro (struct dwarf_section *section,
 
   load_debug_section_with_follow (str, file);
   load_debug_section_with_follow (line, file);
+  load_debug_section_with_follow (str_index, file);
 
   introduce (section, FALSE);
 
@@ -5488,6 +5525,22 @@ display_debug_macro (struct dwarf_section *section,
 
          switch (op)
            {
+           case DW_MACRO_define:
+             READ_ULEB (lineno, curr, end);
+             string = curr;
+             curr += strnlen ((char *) string, end - string) + 1;
+             printf (_(" DW_MACRO_define - lineno : %d macro : %s\n"),
+                     lineno, string);
+             break;
+
+           case DW_MACRO_undef:
+             READ_ULEB (lineno, curr, end);
+             string = curr;
+             curr += strnlen ((char *) string, end - string) + 1;
+             printf (_(" DW_MACRO_undef - lineno : %d macro : %s\n"),
+                     lineno, string);
+             break;
+
            case DW_MACRO_start_file:
              {
                unsigned int filenum;
@@ -5517,22 +5570,6 @@ display_debug_macro (struct dwarf_section *section,
              printf (_(" DW_MACRO_end_file\n"));
              break;
 
-           case DW_MACRO_define:
-             READ_ULEB (lineno, curr, end);
-             string = curr;
-             curr += strnlen ((char *) string, end - string) + 1;
-             printf (_(" DW_MACRO_define - lineno : %d macro : %s\n"),
-                     lineno, string);
-             break;
-
-           case DW_MACRO_undef:
-             READ_ULEB (lineno, curr, end);
-             string = curr;
-             curr += strnlen ((char *) string, end - string) + 1;
-             printf (_(" DW_MACRO_undef - lineno : %d macro : %s\n"),
-                     lineno, string);
-             break;
-
            case DW_MACRO_define_strp:
              READ_ULEB (lineno, curr, end);
              SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
@@ -5575,7 +5612,29 @@ display_debug_macro (struct dwarf_section *section,
                      (unsigned long) offset);
              break;
 
+           case DW_MACRO_define_strx:
+           case DW_MACRO_undef_strx:
+             READ_ULEB (lineno, curr, end);
+             READ_ULEB (offset, curr, end);
+             string = (const unsigned char *)
+               fetch_indexed_string (offset, NULL, offset_size, FALSE);
+             if (op == DW_MACRO_define_strx)
+               printf (" DW_MACRO_define_strx ");
+             else
+               printf (" DW_MACRO_undef_strx ");
+             if (do_wide)
+               printf (_("(with offset %s) "), dwarf_vmatoa (NULL, offset));
+             printf (_("lineno : %d macro : %s\n"),
+                     lineno, string);
+             break;
+
            default:
+             if (op >= DW_MACRO_lo_user && op <= DW_MACRO_hi_user)
+               {
+                 printf (_(" <Target Specific macro op: %#x - UNHANDLED"), op);
+                 break;
+               }
+
              if (extended_ops == NULL || extended_ops[op] == NULL)
                {
                  error (_(" Unknown macro opcode %02x seen\n"), op);
@@ -6784,6 +6843,57 @@ display_debug_str_offsets (struct dwarf_section *section,
       printf (_("\nThe %s section is empty.\n"), section->name);
       return 0;
     }
+
+  unsigned char *start = section->start;
+  unsigned char *end = start + section->size;
+  unsigned char *curr = start;
+
+  load_debug_section_with_follow (str, file);
+
+  introduce (section, FALSE);
+
+  while (curr < end)
+    {
+      dwarf_vma length;
+      dwarf_vma entry_length;
+
+      SAFE_BYTE_GET_AND_INC (length, curr, 4, end);
+      /* FIXME: We assume that this means 64-bit DWARF is being used.  */
+      if (length == 0xffffffff)
+       {
+         SAFE_BYTE_GET (length, curr, 8, end);
+         entry_length = 8;
+       }
+      else
+       entry_length = 4;
+
+      int version;
+      SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
+      if (version != 5)
+       warn (_("Unexpected version number in str_offset header: %#x\n"), version);
+
+      int padding;
+      SAFE_BYTE_GET_AND_INC (padding, curr, 2, end);
+      if (padding != 0)
+       warn (_("Unexpected value in str_offset header's padding field: %#x\n"), padding);
+
+      printf (_("    Length: %#lx\n"), (unsigned long) length);
+      printf (_("    Version: %#lx\n"), (unsigned long) version);
+      printf (_("       Index Offset   [String]\n"));
+
+      unsigned long index;
+      for (index = 0; length >= entry_length && curr < end; index ++)
+       {
+         dwarf_vma offset;
+         const unsigned char * string;
+
+         SAFE_BYTE_GET_AND_INC (offset, curr, entry_length, end);
+         string = fetch_indirect_string (offset);
+         printf ("    %8lu %s %s\n", index,
+                 dwarf_vmatoa (NULL, offset),
+                 string);
+       }
+    }
   /* TODO: Dump the contents.  This is made somewhat difficult by not knowing
      what the offset size is for this section.  */
   return 1;
@@ -10663,6 +10773,7 @@ dwarf_select_sections_by_names (const char *names)
       { "ranges", & do_debug_aranges, 1 },
       { "rawline", & do_debug_lines, FLAG_DEBUG_LINES_RAW },
       { "str", & do_debug_str, 1 },
+      { "str-offsets", & do_debug_str_offsets, 1 },
       /* These trace_* sections are used by Itanium VMS.  */
       { "trace_abbrev", & do_trace_abbrevs, 1 },
       { "trace_aranges", & do_trace_aranges, 1 },
@@ -10729,6 +10840,7 @@ dwarf_select_sections_by_letters (const char *letters)
       case 'l':        do_debug_lines |= FLAG_DEBUG_LINES_RAW; break;
       case 'L':        do_debug_lines |= FLAG_DEBUG_LINES_DECODED; break;
       case 'm': do_debug_macinfo = 1; break;
+      case 'O':        do_debug_str_offsets = 1; break;
       case 'o':        do_debug_loc = 1; break;
       case 'p':        do_debug_pubnames = 1; break;
       case 'R':        do_debug_ranges = 1; break;
@@ -10767,6 +10879,7 @@ dwarf_select_sections_all (void)
   do_debug_cu_index = 1;
   do_follow_links = 1;
   do_debug_links = 1;
+  do_debug_str_offsets = 1;
 }
 
 #define NO_ABBREVS   NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL
@@ -10811,8 +10924,8 @@ struct dwarf_section_display debug_displays[] =
   { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NO_ABBREVS },     display_debug_macro,    &do_debug_macinfo,  TRUE },
   { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NO_ABBREVS },   display_debug_macinfo,  &do_debug_macinfo,  FALSE },
   { { ".debug_str.dwo",     ".zdebug_str.dwo",  NO_ABBREVS },      display_debug_str,      &do_debug_str,      TRUE },
-  { { ".debug_str_offsets", ".zdebug_str_offsets", NO_ABBREVS },   display_debug_str_offsets, NULL,            FALSE },
-  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NO_ABBREVS }, display_debug_str_offsets, NULL,      FALSE },
+  { { ".debug_str_offsets", ".zdebug_str_offsets", NO_ABBREVS },   display_debug_str_offsets, &do_debug_str_offsets, TRUE },
+  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NO_ABBREVS }, display_debug_str_offsets, &do_debug_str_offsets, TRUE },
   { { ".debug_addr",       ".zdebug_addr",     NO_ABBREVS },      display_debug_addr,     &do_debug_addr,      TRUE },
   { { ".debug_cu_index",    "",                        NO_ABBREVS },      display_cu_index,       &do_debug_cu_index,  FALSE },
   { { ".debug_tu_index",    "",                        NO_ABBREVS },      display_cu_index,       &do_debug_cu_index,  FALSE },
index 0c9f3661073991ddfafda9b593bd47a600377105..bb7f5536e35842b07f48ec2f1975e28cdec4d445 100644 (file)
@@ -211,6 +211,7 @@ extern int do_debug_frames;
 extern int do_debug_frames_interp;
 extern int do_debug_macinfo;
 extern int do_debug_str;
+extern int do_debug_str_offsets;
 extern int do_debug_loc;
 extern int do_gdb_index;
 extern int do_trace_info;
index 9b3d5b7acb8defde4b252b1517a5f82f0918d2be..c582feb70a7301a79ac19a9f69078ec23d7c68a2 100644 (file)
@@ -229,9 +229,9 @@ usage (FILE *stream, int status)
   -g, --debugging          Display debug information in object file\n\
   -e, --debugging-tags     Display debug information using ctags style\n\
   -G, --stabs              Display (in raw form) any STABS info in the file\n\
-  -W[lLiaprmfFsoRtUuTgAckK] or\n\
+  -W[lLiaprmfFsoORtUuTgAckK] or\n\
   --dwarf[=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 DWARF info in the file\n\
index 101fd66ccb76999f9e7171ff7b17a44b705a98b3..9e4fa3327b175b43c034d41bd82a76f526264613 100644 (file)
@@ -4548,9 +4548,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"));
@@ -6388,7 +6388,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 +6415,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"))