From e4b7104b1e0c70613d0f553cb18d25c7343647d3 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 22 Jun 2020 17:44:56 +0100 Subject: [PATCH] Add support for decoding the DW_MACRO_define_strx and DW_MACRO_undef_strx operands found in DWARF-5 .debug_macro sections. 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 | 8 ++ binutils/doc/binutils.texi | 16 +-- binutils/doc/debug.options.texi | 4 + binutils/dwarf.c | 169 ++++++++++++++++++++++++++------ binutils/dwarf.h | 1 + binutils/objdump.c | 4 +- binutils/readelf.c | 7 +- 7 files changed, 168 insertions(+), 41 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 700c1ea939..7537fcbadb 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,11 @@ +2020-06-22 Nick Clifton + + 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 * od-macho.c: Dump linkedit data for new load commands. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 901f9e3438..2cf81879df 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -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} |@option{--relocated-dump=}] [@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 diff --git a/binutils/doc/debug.options.texi b/binutils/doc/debug.options.texi index 7f07388b56..31260c1d19 100644 --- a/binutils/doc/debug.options.texi +++ b/binutils/doc/debug.options.texi @@ -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 diff --git a/binutils/dwarf.c b/binutils/dwarf.c index c2e73f72fe..54acd53bd7 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -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 ? _("") : _("")); + if (str_section->start == NULL) + return (dwo ? _("") + : _("")); + + /* 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 _("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 _(""); } - if (str_section->start == NULL) - return (dwo ? _("") - : _("")); - - 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 (_(" 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 }, diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 0c9f366107..bb7f5536e3 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -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; diff --git a/binutils/objdump.c b/binutils/objdump.c index 9b3d5b7acb..c582feb70a 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -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\ diff --git a/binutils/readelf.c b/binutils/readelf.c index 101fd66ccb..9e4fa3327b 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -4548,9 +4548,9 @@ usage (FILE * stream) -R --relocated-dump=\n\ Dump the contents of section 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")) -- 2.34.1