This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch 5/7] Add readelf/objdump support for dumping .debug_cu_index and .debug_tu_index sections.


This patch updates readelf to support dumping debug information in .dwp files.
I've also added options --debug-dump=addr and --debug-dump=cu_index to dump
the .debug_addr section and the .debug_cu/tu_index sections, respectively.

The tricky part of this patch is that a dwp file will contain many
sets of .debug_info/types and related sections, so when we're dumping
one .debug_info section, we need to use the matching .debug_abbrev
section. The indexes in .debug_cu_index and .debug_tu_index list these
sets of section numbers, and I've added a new entry point in dwarf.c
that will find the set (actually "a" set, since some sections might
belong to multiple sets) that contains a given section, and readelf
will then restrict subsequent calls to load_debug_section to members
of that set (falling back to the entire file for singleton sections
like .debug_str). This feature should also come in handy if/when GCC
starts generating debug info for comdat functions in the comdat groups
for those functions.

I've also updated objdump to support the new options, but I haven't updated
it to handle .dwp files correctly. The dwp file format is specifically ELF,
and it uses ELF section indexes directly in its index sections.

binutils/
	* dwarf.c (do_debug_addr, do_debug_cu_index): New global flags.
	(load_debug_info): Fix typo.
	(cu_tu_indexes_read, shndx_pool, shndx_pool_size, shndx_pool_used):
	New global variables.
	(prealloc_cu_tu_list, add_shndx_to_cu_tu_entry, end_cu_tu_entry)
	(process_cu_tu_index, load_cu_tu_indexes, find_cu_tu_set)
	(display_cu_index): New functions.
	(dwarf_select_sections_by_names): Add "debug_addr", "cu_index".
	Sort entries alphabetically.
	(dwarf_select_sections_all): Set do_debug_addr, do_debug_cu_index.
	(debug_displays): Add .debug_cu_index, .debug_tu_index.
	Clean up formatting.
	* dwarf.h (dwarf_section_display_enum): Add dwp_cu_index,
	dwp_tu_index.
	(do_debug_addr, do_debug_cu_index): New global flags.
	(find_cu_tu_set): New function declaration.
	* objdump.c (usage): Add --dwarf=addr, --dwarf=cu_index.
	* readelf.c (find_section_in_set): New function.
	(usage): Add --debug-dump=addr, --debug_dump=cu_index.
	(process_section_headers): Check do_debug_addr and do_debug_cu_index.
	(section_subset): New global variable.
	(load_debug_section): Restrict search to section subset.
	(display_debug_section): Add section index as paramter.  Select subset
	of sections when dumping a .dwp file.  Update caller.
---
 binutils/dwarf.c   |  289 ++++++++++++++++++++++++++++++++++++++++++++--------
 binutils/dwarf.h   |    6 ++
 binutils/objdump.c |    3 +-
 binutils/readelf.c |   51 ++++++++--
 4 files changed, 299 insertions(+), 50 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index fa6860c..8127ee3 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -62,6 +62,8 @@ int do_gdb_index;
 int do_trace_info;
 int do_trace_abbrevs;
 int do_trace_aranges;
+int do_debug_addr;
+int do_debug_cu_index;
 int do_wide;
 
 int dwarf_cutoff_level = -1;
@@ -2313,7 +2315,7 @@ load_debug_info (void * file)
   warned_about_missing_comp_units = FALSE;
 
   /* If we have already tried and failed to load the .debug_info
-     section then do not bother to repear the task.  */
+     section then do not bother to repeat the task.  */
   if (num_debug_info_entries == DEBUG_INFO_UNAVAILABLE)
     return 0;
 
@@ -5850,6 +5852,200 @@ display_gdb_index (struct dwarf_section *section,
   return 1;
 }
 
+/* Collection of CU/TU section sets from .debug_cu_index and .debug_tu_index
+   sections.  Each set is stored in SHNDX_POOL as a zero-terminated list of
+   section indexes comprising one set of debug sections from a .dwo file.  */
+
+int cu_tu_indexes_read = 0;
+unsigned int *shndx_pool = NULL;
+unsigned int shndx_pool_size = 0;
+unsigned int shndx_pool_used = 0;
+
+/* Pre-allocate enough space for the CU/TU sets needed.  */
+
+static void
+prealloc_cu_tu_list (unsigned int nshndx)
+{
+  if (shndx_pool == NULL)
+    {
+      shndx_pool_size = nshndx;
+      shndx_pool_used = 0;
+      shndx_pool = (unsigned int *) xcmalloc (shndx_pool_size,
+					      sizeof (unsigned int));
+    }
+  else
+    {
+      shndx_pool_size = shndx_pool_used + nshndx;
+      shndx_pool = (unsigned int *) xcrealloc (shndx_pool, shndx_pool_size,
+					       sizeof (unsigned int));
+    }
+}
+
+static void
+add_shndx_to_cu_tu_entry (unsigned int shndx)
+{
+  if (shndx_pool_used >= shndx_pool_size)
+    {
+      error (_("Internal error: out of space in the shndx pool.\n"));
+      return;
+    }
+  shndx_pool [shndx_pool_used++] = shndx;
+}
+
+static void
+end_cu_tu_entry (void)
+{
+  if (shndx_pool_used >= shndx_pool_size)
+    {
+      error (_("Internal error: out of space in the shndx pool.\n"));
+      return;
+    }
+  shndx_pool [shndx_pool_used++] = 0;
+}
+
+/* Process a CU or TU index.  If DO_DISPLAY is true, print the contents.  */
+
+static int
+process_cu_tu_index (struct dwarf_section *section, int do_display)
+{
+  unsigned char *phdr = section->start;
+  unsigned char *limit = phdr + section->size;
+  unsigned char *phash;
+  unsigned char *pindex;
+  unsigned char *ppool;
+  unsigned int version;
+  unsigned int nused;
+  unsigned int nslots;
+  unsigned int i;
+
+  version = byte_get (phdr, 4);
+  nused = byte_get (phdr + 8, 4);
+  nslots = byte_get (phdr + 12, 4);
+  phash = phdr + 16;
+  pindex = phash + nslots * 8;
+  ppool = pindex + nslots * 4;
+
+  if (!do_display)
+    prealloc_cu_tu_list((limit - ppool) / 4);
+
+  if (do_display)
+    {
+      printf (_("Contents of the %s section:\n\n"), section->name);
+      printf (_("  Version:                 %d\n"), version);
+      printf (_("  Number of used entries:  %d\n"), nused);
+      printf (_("  Number of slots:         %d\n\n"), nslots);
+    }
+
+  if (ppool > limit)
+    {
+      warn (_("Section %s too small for %d hash table entries\n"),
+	    section->name, nslots);
+      return 0;
+    }
+
+  for (i = 0; i < nslots; i++)
+    {
+      dwarf_vma signature_high;
+      dwarf_vma signature_low;
+      unsigned int j;
+      unsigned char *shndx_list;
+      unsigned int shndx;
+      char buf[64];
+
+      byte_get_64 (phash, &signature_high, &signature_low);
+      if (signature_high != 0 || signature_low != 0)
+	{
+	  j = byte_get (pindex, 4);
+	  shndx_list = ppool + j * 4;
+	  if (do_display)
+	    printf (_("  [%3d] Signature:  0x%s  Sections: "),
+		    i, dwarf_vmatoa64 (signature_high, signature_low,
+				       buf, sizeof (buf)));
+	  for (;;)
+	    {
+	      if (shndx_list >= limit)
+		{
+		  warn (_("Section %s too small for shndx pool\n"),
+			section->name);
+		  return 0;
+		}
+	      shndx = byte_get (shndx_list, 4);
+	      if (shndx == 0)
+		break;
+	      if (do_display)
+		printf (" %d", shndx);
+	      else
+		add_shndx_to_cu_tu_entry (shndx);
+	      shndx_list += 4;
+	    }
+	  if (do_display)
+	    printf ("\n");
+	  else
+	    end_cu_tu_entry ();
+	}
+      phash += 8;
+      pindex += 4;
+    }
+
+  if (do_display)
+      printf ("\n");
+
+  return 1;
+}
+
+/* Load the CU and TU indexes if present.  This will build a list of
+   section sets that we can use to associate a .debug_info.dwo section
+   with its associated .debug_abbrev.dwo section in a .dwp file.  */
+
+static void
+load_cu_tu_indexes (void *file)
+{
+  /* If we have already loaded (or tried to load) the CU and TU indexes
+     then do not bother to repeat the task.  */
+  if (cu_tu_indexes_read)
+    return;
+
+  if (load_debug_section (dwp_cu_index, file))
+    process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0);
+
+  if (load_debug_section (dwp_tu_index, file))
+    process_cu_tu_index (&debug_displays [dwp_tu_index].section, 0);
+
+  cu_tu_indexes_read = 1;
+}
+
+/* Find the set of sections that includes section SHNDX.  */
+
+unsigned int *
+find_cu_tu_set (void *file, unsigned int shndx)
+{
+  unsigned int i;
+
+  load_cu_tu_indexes (file);
+
+  /* Find SHNDX in the shndx pool.  */
+  for (i = 0; i < shndx_pool_used; i++)
+    if (shndx_pool [i] == shndx)
+      break;
+
+  if (i >= shndx_pool_used)
+    return NULL;
+
+  /* Now backup to find the first entry in the set.  */
+  while (i > 0 && shndx_pool [i - 1] != 0)
+    i--;
+
+  return shndx_pool + i;
+}
+
+/* Display a .debug_cu_index or .debug_tu_index section.  */
+
+static int
+display_cu_index (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED)
+{
+  return process_cu_tu_index (section, 1);
+}
+
 static int
 display_debug_not_supported (struct dwarf_section *section,
 			     void *file ATTRIBUTE_UNUSED)
@@ -5938,13 +6134,16 @@ dwarf_select_sections_by_names (const char *names)
       /* Please keep this table alpha- sorted.  */
       { "Ranges", & do_debug_ranges, 1 },
       { "abbrev", & do_debug_abbrevs, 1 },
+      { "addr", & do_debug_addr, 1 },
       { "aranges", & do_debug_aranges, 1 },
+      { "cu_index", & do_debug_cu_index, 1 },
+      { "decodedline", & do_debug_lines, FLAG_DEBUG_LINES_DECODED },
       { "frames", & do_debug_frames, 1 },
       { "frames-interp", & do_debug_frames_interp, 1 },
+      /* The special .gdb_index section.  */
+      { "gdb_index", & do_gdb_index, 1 },
       { "info", & do_debug_info, 1 },
       { "line", & do_debug_lines, FLAG_DEBUG_LINES_RAW }, /* For backwards compatibility.  */
-      { "rawline", & do_debug_lines, FLAG_DEBUG_LINES_RAW },
-      { "decodedline", & do_debug_lines, FLAG_DEBUG_LINES_DECODED },
       { "loc",  & do_debug_loc, 1 },
       { "macro", & do_debug_macinfo, 1 },
       { "pubnames", & do_debug_pubnames, 1 },
@@ -5952,9 +6151,8 @@ dwarf_select_sections_by_names (const char *names)
       /* This entry is for compatability
 	 with earlier versions of readelf.  */
       { "ranges", & do_debug_aranges, 1 },
+      { "rawline", & do_debug_lines, FLAG_DEBUG_LINES_RAW },
       { "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 },
@@ -6083,73 +6281,78 @@ dwarf_select_sections_all (void)
   do_trace_info = 1;
   do_trace_abbrevs = 1;
   do_trace_aranges = 1;
+  do_debug_addr = 1;
+  do_debug_cu_index = 1;
 }
 
 struct dwarf_section_display debug_displays[] =
 {
-  { { ".debug_abbrev",	    ".zdebug_abbrev",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_abbrev",	    ".zdebug_abbrev",	NULL, NULL, 0, 0, 0 },
     display_debug_abbrev,   &do_debug_abbrevs,	0 },
-  { { ".debug_aranges",	    ".zdebug_aranges",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_aranges",	    ".zdebug_aranges",	NULL, NULL, 0, 0, 0 },
     display_debug_aranges,  &do_debug_aranges,	1 },
-  { { ".debug_frame",       ".zdebug_frame",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_frame",       ".zdebug_frame",	NULL, NULL, 0, 0, 0 },
     display_debug_frames,   &do_debug_frames,	1 },
   { { ".debug_info",	    ".zdebug_info",	NULL, NULL, 0, 0, abbrev },
     display_debug_info,	    &do_debug_info,	1 },
-  { { ".debug_line",	    ".zdebug_line",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_line",	    ".zdebug_line",	NULL, NULL, 0, 0, 0 },
     display_debug_lines,    &do_debug_lines,	1 },
-  { { ".debug_pubnames",    ".zdebug_pubnames",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_pubnames",    ".zdebug_pubnames",	NULL, NULL, 0, 0, 0 },
     display_debug_pubnames, &do_debug_pubnames,	0 },
-  { { ".eh_frame",	    "",			NULL, NULL, 0, 0, abbrev },
+  { { ".eh_frame",	    "",			NULL, NULL, 0, 0, 0 },
     display_debug_frames,   &do_debug_frames,	1 },
-  { { ".debug_macinfo",	    ".zdebug_macinfo",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_macinfo",	    ".zdebug_macinfo",	NULL, NULL, 0, 0, 0 },
     display_debug_macinfo,  &do_debug_macinfo,	0 },
-  { { ".debug_macro",	    ".zdebug_macro",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_macro",	    ".zdebug_macro",	NULL, NULL, 0, 0, 0 },
     display_debug_macro,    &do_debug_macinfo,	1 },
-  { { ".debug_str",	    ".zdebug_str",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_str",	    ".zdebug_str",	NULL, NULL, 0, 0, 0 },
     display_debug_str,	    &do_debug_str,	0 },
-  { { ".debug_loc",	    ".zdebug_loc",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_loc",	    ".zdebug_loc",	NULL, NULL, 0, 0, 0 },
     display_debug_loc,	    &do_debug_loc,	1 },
-  { { ".debug_pubtypes",    ".zdebug_pubtypes",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_pubtypes",    ".zdebug_pubtypes",	NULL, NULL, 0, 0, 0 },
     display_debug_pubnames, &do_debug_pubtypes,	0 },
-  { { ".debug_ranges",	    ".zdebug_ranges",	NULL, NULL, 0, 0, abbrev },
+  { { ".debug_ranges",	    ".zdebug_ranges",	NULL, NULL, 0, 0, 0 },
     display_debug_ranges,   &do_debug_ranges,	1 },
-  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, abbrev },
+  { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0 },
     display_debug_not_supported, NULL,		0 },
-  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, abbrev },
+  { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0 },
     display_debug_not_supported, NULL,		0 },
   { { ".debug_types",	    ".zdebug_types",	NULL, NULL, 0, 0, abbrev },
     display_debug_types,    &do_debug_info,	1 },
-  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, abbrev },
+  { { ".debug_weaknames",   ".zdebug_weaknames", NULL, NULL, 0, 0, 0 },
     display_debug_not_supported, NULL,		0 },
-  { { ".gdb_index",	    "",	                NULL, NULL, 0, 0, abbrev },
-    display_gdb_index,			&do_gdb_index,		0 },
+  { { ".gdb_index",	    "",	                NULL, NULL, 0, 0, 0 },
+    display_gdb_index,      &do_gdb_index,	0 },
   { { ".trace_info",	    "",			NULL, NULL, 0, 0, trace_abbrev },
-    display_trace_info,			&do_trace_info,		1 },
-  { { ".trace_abbrev",	    "",			NULL, NULL, 0, 0, abbrev },
-    display_debug_abbrev,		&do_trace_abbrevs,	0 },
-  { { ".trace_aranges",	    "",			NULL, NULL, 0, 0, abbrev },
-    display_debug_aranges,		&do_trace_aranges,	0 },
+    display_trace_info,	    &do_trace_info,	1 },
+  { { ".trace_abbrev",	    "",			NULL, NULL, 0, 0, 0 },
+    display_debug_abbrev,   &do_trace_abbrevs,	0 },
+  { { ".trace_aranges",	    "",			NULL, NULL, 0, 0, 0 },
+    display_debug_aranges,  &do_trace_aranges,	0 },
   { { ".debug_info.dwo",    ".zdebug_info.dwo",	NULL, NULL, 0, 0, abbrev_dwo },
-    display_debug_info,			&do_debug_info,		1 },
-  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, abbrev_dwo },
-    display_debug_abbrev,		&do_debug_abbrevs,	0 },
+    display_debug_info,	    &do_debug_info,	1 },
+  { { ".debug_abbrev.dwo",  ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0 },
+    display_debug_abbrev,   &do_debug_abbrevs,	0 },
   { { ".debug_types.dwo",   ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo },
-    display_debug_types,		&do_debug_info,		1 },
-  { { ".debug_line.dwo",   ".zdebug_line.dwo", NULL, NULL, 0, 0, abbrev_dwo },
-    display_debug_lines,   &do_debug_lines,	1 },
-  { { ".debug_loc.dwo",	    ".zdebug_loc.dwo",	NULL, NULL, 0, 0, abbrev_dwo },
+    display_debug_types,    &do_debug_info,	1 },
+  { { ".debug_line.dwo",    ".zdebug_line.dwo", NULL, NULL, 0, 0, 0 },
+    display_debug_lines,    &do_debug_lines,	1 },
+  { { ".debug_loc.dwo",	    ".zdebug_loc.dwo",	NULL, NULL, 0, 0, 0 },
     display_debug_loc,	    &do_debug_loc,	1 },
-  { { ".debug_macro.dwo",   ".zdebug_macro.dwo",NULL, NULL, 0, 0, abbrev },
+  { { ".debug_macro.dwo",   ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0 },
     display_debug_macro,    &do_debug_macinfo,	1 },
-  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo",NULL, NULL, 0, 0, abbrev },
+  { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0 },
     display_debug_macinfo,  &do_debug_macinfo,	0 },
-  { { ".debug_str.dwo",   ".zdebug_str.dwo", NULL, NULL, 0, 0, str_dwo },
-    display_debug_str,     &do_debug_str,	        1 },
-  { { ".debug_str_offsets",".zdebug_str_offsets", NULL, NULL, 0, 0, abbrev },
+  { { ".debug_str.dwo",     ".zdebug_str.dwo",  NULL, NULL, 0, 0, 0 },
+    display_debug_str,      &do_debug_str,	1 },
+  { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0 },
     display_debug_str_offsets, NULL,		0 },
-  { { ".debug_str_offsets.dwo",".zdebug_str_offsets.dwo", NULL, NULL, 0, 0,
-      abbrev },
+  { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0 },
     display_debug_str_offsets, NULL,		0 },
-  { { ".debug_addr",".zdebug_addr",             NULL, NULL, 0, 0, debug_addr },
-    display_debug_addr, NULL,		1 },
+  { { ".debug_addr",	    ".zdebug_addr",     NULL, NULL, 0, 0, 0 },
+    display_debug_addr,     &do_debug_addr,	1 },
+  { { ".debug_cu_index",    "",			NULL, NULL, 0, 0, 0 },
+    display_cu_index,       &do_debug_cu_index,	0 },
+  { { ".debug_tu_index",    "",			NULL, NULL, 0, 0, 0 },
+    display_cu_index,       &do_debug_cu_index,	0 },
 };
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 84f5080..2d00b83 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -143,6 +143,8 @@ enum dwarf_section_display_enum
   str_index,
   str_index_dwo,
   debug_addr,
+  dwp_cu_index,
+  dwp_tu_index,
   max
 };
 
@@ -218,6 +220,8 @@ extern int do_gdb_index;
 extern int do_trace_info;
 extern int do_trace_abbrevs;
 extern int do_trace_aranges;
+extern int do_debug_addr;
+extern int do_debug_cu_index;
 extern int do_wide;
 
 extern int dwarf_cutoff_level;
@@ -238,6 +242,8 @@ extern void dwarf_select_sections_by_names (const char *);
 extern void dwarf_select_sections_by_letters (const char *);
 extern void dwarf_select_sections_all (void);
 
+unsigned int * find_cu_tu_set (void *, unsigned int);
+
 void * cmalloc (size_t, size_t);
 void * xcmalloc (size_t, size_t);
 void * xcrealloc (void *, size_t, size_t);
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 23a6793..db30854 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -216,7 +216,8 @@ 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\
-          =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
+          =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
+          =addr,=cu_index]\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\
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 2fbf2ae..59f8b18 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -505,6 +505,24 @@ find_section_by_address (bfd_vma addr)
   return NULL;
 }
 
+/* Return a pointer to section NAME, or NULL if no such section exists,
+   restricted to the list of sections given in SET.  */
+
+static Elf_Internal_Shdr *
+find_section_in_set (const char * name, unsigned int * set)
+{
+  unsigned int i;
+
+  if (set != NULL)
+    {
+      while ((i = *set++) > 0)
+	if (streq (SECTION_NAME (section_headers + i), name))
+	  return section_headers + i;
+    }
+
+  return find_section (name);
+}
+
 /* Read an unsigned LEB128 encoded value from p.  Set *PLEN to the number of
    bytes read.  */
 
@@ -3244,7 +3262,8 @@ 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\
-               =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
+               =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
+               =addr,=cu_index]\n\
                          Display the contents of DWARF2 debug sections\n"));
   fprintf (stream, _("\
   --dwarf-depth=N        Do not display DIEs at depth N or greater\n\
@@ -4671,7 +4690,8 @@ process_section_headers (FILE * file)
       else 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_loc || do_debug_ranges
+		|| do_debug_addr || do_debug_cu_index)
 	       && (const_strneq (name, ".debug_")
                    || const_strneq (name, ".zdebug_")))
 	{
@@ -4694,6 +4714,9 @@ process_section_headers (FILE * file)
 	      || (do_debug_macinfo  && const_strneq (name, "macro"))
 	      || (do_debug_str      && const_strneq (name, "str"))
 	      || (do_debug_loc      && const_strneq (name, "loc"))
+	      || (do_debug_addr     && const_strneq (name, "addr"))
+	      || (do_debug_cu_index && const_strneq (name, "cu_index"))
+	      || (do_debug_cu_index && const_strneq (name, "tu_index"))
 	      )
 	    request_dump_bynumber (i, DEBUG_DUMP);
 	}
@@ -10673,6 +10696,10 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   return 1;
 }
 
+/* If this is not NULL, load_debug_section will only look for sections
+   within the list of sections given here.  */
+unsigned int *section_subset = NULL;
+
 int
 load_debug_section (enum dwarf_section_display_enum debug, void * file)
 {
@@ -10680,18 +10707,24 @@ load_debug_section (enum dwarf_section_display_enum debug, void * file)
   Elf_Internal_Shdr * sec;
 
   /* Locate the debug section.  */
-  sec = find_section (section->uncompressed_name);
+  sec = find_section_in_set (section->uncompressed_name, section_subset);
   if (sec != NULL)
     section->name = section->uncompressed_name;
   else
     {
-      sec = find_section (section->compressed_name);
+      sec = find_section_in_set (section->compressed_name, section_subset);
       if (sec != NULL)
 	section->name = section->compressed_name;
     }
   if (sec == NULL)
     return 0;
 
+  /* If we're loading from a subset of sections, and we've loaded
+     a section matching this name before, it's likely that it's a
+     different one.  */
+  if (section_subset != NULL)
+    free_debug_section (debug);
+
   return load_specific_debug_section (debug, sec, (FILE *) file);
 }
 
@@ -10710,7 +10743,7 @@ free_debug_section (enum dwarf_section_display_enum debug)
 }
 
 static int
-display_debug_section (Elf_Internal_Shdr * section, FILE * file)
+display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
 {
   char * name = SECTION_NAME (section);
   bfd_size_type length;
@@ -10754,8 +10787,14 @@ display_debug_section (Elf_Internal_Shdr * section, FILE * file)
 	if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
                                          section, file))
 	  {
+	    /* If this debug section is part of a CU/TU set in a .dwp file,
+	       restrict load_debug_section to the sections in that set.  */
+	    section_subset = find_cu_tu_set (file, shndx);
+
 	    result &= debug_displays[i].display (sec, file);
 
+	    section_subset = NULL;
+
 	    if (secondary || (i != info && i != abbrev))
 	      free_debug_section ((enum dwarf_section_display_enum) i);
 	  }
@@ -10827,7 +10866,7 @@ process_section_contents (FILE * file)
 	dump_section_as_strings (section, file);
 
       if (dump_sects[i] & DEBUG_DUMP)
-	display_debug_section (section, file);
+	display_debug_section (i, section, file);
     }
 
   /* Check to see if the user requested a
-- 
1.7.9.6 (Apple Git-31.1)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]