From: Cary Coutant Date: Wed, 24 Oct 2012 01:59:39 +0000 (+0000) Subject: binutils/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=657d0d47ba7fd3ae014a5b2b6e46ba6c8d1c461a;p=binutils-gdb.git 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. --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c09d9ef1669..9a737e538bd 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,30 @@ +2012-10-23 Cary Coutant + + * 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. + 2012-10-23 Tom Tromey * readelf.c (get_note_type): Handle NT_SIGINFO, NT_FILE. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index fa6860c021a..8127ee3d7a9 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 84f5080813f..2d00b839902 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 471ca95cd16..9164d83f700 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 4bed07a98e6..b4f9f4e5980 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