* dwarf.c: #include "bfd_stdint.h".
authorDoug Evans <dje@google.com>
Fri, 3 Dec 2010 17:07:20 +0000 (17:07 +0000)
committerDoug Evans <dje@google.com>
Fri, 3 Dec 2010 17:07:20 +0000 (17:07 +0000)
(do_gdb_index): New global.
(display_gdb_index): New function.
(dwarf_select_sections_by_names) Add "gdb_index".
(dwarf_select_sections_all): Set do_gdb_index.
(debug_displays): Add .gdb_index.
* dwarf.h (do_gdb_index): Declare.
* objdump.c (usage): Add gdb_index.
* readelf.c (usage): Add gdb_index.
(process_section_headers): Process ".gdb_index".
* doc/binutils.texi (readelf): Document gdb_index dump.
(objdump): Ditto.

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

index 10a41408fd07be8380c3a8ad7ecf467f6bf94938..5e71463c11c84c9302c99167044854d4f40337a2 100644 (file)
@@ -1,3 +1,18 @@
+2010-12-03  Doug Evans  <dje@google.com>
+
+       * dwarf.c: #include "bfd_stdint.h".
+       (do_gdb_index): New global.
+       (display_gdb_index): New function.
+       (dwarf_select_sections_by_names) Add "gdb_index".
+       (dwarf_select_sections_all): Set do_gdb_index.
+       (debug_displays): Add .gdb_index.
+       * dwarf.h (do_gdb_index): Declare.
+       * objdump.c (usage): Add gdb_index.
+       * readelf.c (usage): Add gdb_index.
+       (process_section_headers): Process ".gdb_index".
+       * doc/binutils.texi (readelf): Document gdb_index dump.
+       (objdump): Ditto.
+
 2010-12-01  Kai Tietz  <kai.tietz@onevision.com>
 
        PR binutils/11065
index 9b9056f4442910bd089c8b7dec31ecf21361a3f2..d3285a5ead8b195ace020fdd3889218b00e1f75e 100644 (file)
@@ -1746,7 +1746,7 @@ objdump [@option{-a}|@option{--archive-headers}]
         [@option{-R}|@option{--dynamic-reloc}]
         [@option{-s}|@option{--full-contents}]
         [@option{-W[lLiaprmfFsoRt]}|
-         @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges]]
+         @option{--dwarf}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]]
         [@option{-G}|@option{--stabs}]
         [@option{-t}|@option{--syms}]
         [@option{-T}|@option{--dynamic-syms}]
@@ -2119,7 +2119,7 @@ Display @var{width} bytes on a single line when disassembling
 instructions.
 
 @item -W[lLiaprmfFsoRt]
-@itemx --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges]
+@itemx --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]
 @cindex DWARF
 @cindex debug symbols
 Displays the contents of the debug sections in the file, if any are
@@ -2127,7 +2127,7 @@ present.  If one of the optional letters or words follows the switch
 then only data found in those specific sections will be dumped.
 
 Note that there is no single letter option to display the content of
-trace sections.
+trace sections or .gdb_index.
 
 @item -G
 @itemx --stabs
@@ -3949,7 +3949,7 @@ readelf [@option{-a}|@option{--all}]
         [@option{-R} <number or name>|@option{--relocated-dump=}<number or name>]
         [@option{-c}|@option{--archive-index}]
         [@option{-w[lLiaprmfFsoRt]}|
-         @option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges]]
+         @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]]
         [@option{-I}|@option{--histogram}]
         [@option{-v}|@option{--version}]
         [@option{-W}|@option{--wide}]
@@ -4101,13 +4101,13 @@ 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[lLiaprmfFsoRt]
-@itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges]
+@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]
 Displays the contents of the debug sections in the file, if any are
 present.  If one of the optional letters or words follows the switch
 then only data found in those specific sections will be dumped.
 
 Note that there is no single letter option to display the content of
-trace sections.
+trace sections or .gdb_index.
 
 Note: the @option{=decodedline} option will display the interpreted
 contents of a .debug_line section whereas the @option{=rawline} option
index ac692465f4e88de7ce2b012e2cfb93651a9c9305..dd5ccbc35384567ffdcc06febb3439c081019571 100644 (file)
@@ -22,6 +22,7 @@
 #include "sysdep.h"
 #include "libiberty.h"
 #include "bfd.h"
+#include "bfd_stdint.h"
 #include "bucomm.h"
 #include "elfcomm.h"
 #include "elf/common.h"
@@ -56,6 +57,7 @@ int do_debug_frames_interp;
 int do_debug_macinfo;
 int do_debug_str;
 int do_debug_loc;
+int do_gdb_index;
 int do_trace_info;
 int do_trace_abbrevs;
 int do_trace_aranges;
@@ -4862,6 +4864,135 @@ display_debug_frames (struct dwarf_section *section,
 #undef LEB
 #undef SLEB
 
+static int
+display_gdb_index (struct dwarf_section *section,
+                  void *file ATTRIBUTE_UNUSED)
+{
+  unsigned char *start = section->start;
+  uint32_t version;
+  uint32_t cu_list_offset, tu_list_offset;
+  uint32_t address_table_offset, symbol_table_offset, constant_pool_offset;
+  unsigned int cu_list_elements, tu_list_elements;
+  unsigned int address_table_size, symbol_table_slots;
+  unsigned char *cu_list, *tu_list;
+  unsigned char *address_table, *symbol_table, *constant_pool;
+  unsigned int i;
+
+  /* The documentation for the format of this file is in gdb/dwarf2read.c.  */
+
+  printf (_("Contents of the %s section:\n"), section->name);
+
+  if (section->size < 6 * sizeof (uint32_t))
+    {
+      warn (_("Truncated header in the %s section.\n"), section->name);
+      return 0;
+    }
+
+  version = byte_get_little_endian (start, 4);
+  printf (_("Version %d\n"), version);
+
+  /* Prior versions are obsolete, and future versions may not be
+     backwards compatible.  */
+  if (version != 3)
+    {
+      warn (_("Unsupported version %u.\n"), version);
+      return 0;
+    }
+
+  cu_list_offset = byte_get_little_endian (start + 4, 4);
+  tu_list_offset = byte_get_little_endian (start + 8, 4);
+  address_table_offset = byte_get_little_endian (start + 12, 4);
+  symbol_table_offset = byte_get_little_endian (start + 16, 4);
+  constant_pool_offset = byte_get_little_endian (start + 20, 4);
+
+  if (cu_list_offset > section->size
+      || tu_list_offset > section->size
+      || address_table_offset > section->size
+      || symbol_table_offset > section->size
+      || constant_pool_offset > section->size)
+    {
+      warn (_("Corrupt header in the %s section.\n"), section->name);
+      return 0;
+    }
+
+  cu_list_elements = (tu_list_offset - cu_list_offset) / 8;
+  tu_list_elements = (address_table_offset - tu_list_offset) / 8;
+  address_table_size = symbol_table_offset - address_table_offset;
+  symbol_table_slots = (constant_pool_offset - symbol_table_offset) / 8;
+
+  cu_list = start + cu_list_offset;
+  tu_list = start + tu_list_offset;
+  address_table = start + address_table_offset;
+  symbol_table = start + symbol_table_offset;
+  constant_pool = start + constant_pool_offset;
+
+  printf (_("\nCU table:\n"));
+  for (i = 0; i < cu_list_elements; i += 2)
+    {
+      uint64_t cu_offset = byte_get_little_endian (cu_list + i * 8, 8);
+      uint64_t cu_length = byte_get_little_endian (cu_list + i * 8 + 8, 8);
+
+      printf (_("[%3u] 0x%lx - 0x%lx\n"), i / 2,
+             (unsigned long) cu_offset,
+             (unsigned long) (cu_offset + cu_length - 1));
+    }
+
+  printf (_("\nTU table:\n"));
+  for (i = 0; i < tu_list_elements; i += 3)
+    {
+      uint64_t tu_offset = byte_get_little_endian (tu_list + i * 8, 8);
+      uint64_t type_offset = byte_get_little_endian (tu_list + i * 8 + 8, 8);
+      uint64_t signature = byte_get_little_endian (tu_list + i * 8 + 16, 8);
+
+      printf (_("[%3u] 0x%lx 0x%lx "), i / 3,
+             (unsigned long) tu_offset,
+             (unsigned long) type_offset);
+      print_dwarf_vma (signature, 8);
+      printf ("\n");
+    }
+
+  printf (_("\nAddress table:\n"));
+  for (i = 0; i < address_table_size; i += 2 * 8 + 4)
+    {
+      uint64_t low = byte_get_little_endian (address_table + i, 8);
+      uint64_t high = byte_get_little_endian (address_table + i + 8, 8);
+      uint32_t cu_index = byte_get_little_endian (address_table + i + 16, 4);
+
+      print_dwarf_vma (low, 8);
+      print_dwarf_vma (high, 8);
+      printf (_("%u\n"), cu_index);
+    }
+
+  printf (_("\nSymbol table:\n"));
+  for (i = 0; i < symbol_table_slots; ++i)
+    {
+      uint32_t name_offset = byte_get_little_endian (symbol_table + i * 8, 4);
+      uint32_t cu_vector_offset = byte_get_little_endian (symbol_table + i * 8 + 4, 4);
+      uint32_t num_cus, cu;
+
+      if (name_offset != 0
+         || cu_vector_offset != 0)
+       {
+         unsigned int j;
+
+         printf ("[%3u] %s:", i, constant_pool + name_offset);
+         num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
+         for (j = 0; j < num_cus; ++j)
+           {
+             cu = byte_get_little_endian (constant_pool + cu_vector_offset + 4 + j * 4, 4);
+             /* Convert to TU number if it's for a type unit.  */
+             if (cu >= cu_list_elements)
+               printf (" T%u", cu - cu_list_elements);
+             else
+               printf (" %u", cu);
+           }
+         printf ("\n");
+       }
+    }
+
+  return 1;
+}
+
 static int
 display_debug_not_supported (struct dwarf_section *section,
                             void *file ATTRIBUTE_UNUSED)
@@ -4965,6 +5096,8 @@ dwarf_select_sections_by_names (const char *names)
         with earlier versions of readelf.  */
       { "ranges", & do_debug_aranges, 1 },
       { "str", & do_debug_str, 1 },
+      /* The special .gdb_index section.  */
+      { "gdb_index", & do_gdb_index, 1 },
       /* These trace_* sections are used by Itanium VMS.  */
       { "trace_abbrev", & do_trace_abbrevs, 1 },
       { "trace_aranges", & do_trace_aranges, 1 },
@@ -5089,6 +5222,7 @@ dwarf_select_sections_all (void)
   do_debug_macinfo = 1;
   do_debug_str = 1;
   do_debug_loc = 1;
+  do_gdb_index = 1;
   do_trace_info = 1;
   do_trace_abbrevs = 1;
   do_trace_aranges = 1;
@@ -5128,6 +5262,8 @@ struct dwarf_section_display debug_displays[] =
     display_debug_types,               &do_debug_info,         1 },
   { { ".debug_weaknames",      ".zdebug_weaknames",    NULL, NULL, 0, 0 },
     display_debug_not_supported,       NULL,                   0 },
+  { { ".gdb_index",            "",                     NULL, NULL, 0, 0 },
+    display_gdb_index,                 &do_gdb_index,          0 },
   { { ".trace_info",           "",                     NULL, NULL, 0, 0 },
     display_trace_info,                        &do_trace_info,         1 },
   { { ".trace_abbrev",         "",                     NULL, NULL, 0, 0 },
index e9de4638ac4edd91c93cb5f404b18a7a86e25440..22ff496ca9ad9472de25357817b5a244b7d7952e 100644 (file)
@@ -107,6 +107,7 @@ extern int do_debug_frames_interp;
 extern int do_debug_macinfo;
 extern int do_debug_str;
 extern int do_debug_loc;
+extern int do_gdb_index;
 extern int do_trace_info;
 extern int do_trace_abbrevs;
 extern int do_trace_aranges;
index da68eebf9ab046447623653dd307a8133032a84e..0be662f1478202194daf30c5ee46d7f0d3a3aafd 100644 (file)
@@ -207,7 +207,7 @@ usage (FILE *stream, int status)
   -W[lLiaprmfFsoRt] or\n\
   --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
           =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
-          =trace_info,=trace_abbrev,=trace_aranges]\n\
+          =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
                            Display DWARF info in the file\n\
   -t, --syms               Display the contents of the symbol table(s)\n\
   -T, --dynamic-syms       Display the contents of the dynamic symbol table\n\
index 3f4167b0c20fbf6fb4c3114b745b2bb179280a17..b8ab55b989b2778e11526f2556d0a7b88e3cf9f0 100644 (file)
@@ -3141,7 +3141,7 @@ usage (FILE * stream)
   -w[lLiaprmfFsoRt] or\n\
   --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
                =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
-               =trace_info,=trace_abbrev,=trace_aranges]\n\
+               =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
                          Display the contents of DWARF2 debug sections\n"));
 #ifdef SUPPORT_DISASSEMBLY
   fprintf (stream, _("\
@@ -4564,6 +4564,8 @@ process_section_headers (FILE * file)
        request_dump_bynumber (i, DEBUG_DUMP);
       else if (do_debug_frames && streq (name, ".eh_frame"))
        request_dump_bynumber (i, DEBUG_DUMP);
+      else if (do_gdb_index && streq (name, ".gdb_index"))
+       request_dump_bynumber (i, DEBUG_DUMP);
       /* Trace sections for Itanium VMS.  */
       else if ((do_debugging || do_trace_info || do_trace_abbrevs
                 || do_trace_aranges)