llvm.org GIT mirror llvm / 939a4e8
Add command-line flags for DWARF dumping. Flags for dumping specific DWARF sections added in lib/DebugInfo and llvm-dwarfdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173480 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Bendersky 7 years ago
5 changed file(s) with 139 addition(s) and 73 deletion(s). Raw diff Collapse all Expand all
9191 }
9292 };
9393
94 /// Selects which debug sections get dumped.
95 enum DIDumpType {
96 DIDT_Null,
97 DIDT_All,
98 DIDT_Abbrev,
99 DIDT_AbbrevDwo,
100 DIDT_Aranges,
101 DIDT_Info,
102 DIDT_InfoDwo,
103 DIDT_Line,
104 DIDT_Ranges,
105 DIDT_Str,
106 DIDT_StrDwo,
107 DIDT_StrOffsetsDwo
108 };
109
94110 // In place of applying the relocations to the data we've read from disk we use
95111 // a separate mapping table to the side and checking that at locations in the
96112 // dwarf where we expect relocated values. This adds a bit of complexity to the
105121 /// getDWARFContext - get a context for binary DWARF data.
106122 static DIContext *getDWARFContext(object::ObjectFile *);
107123
108 virtual void dump(raw_ostream &OS) = 0;
124 virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
109125
110126 virtual DILineInfo getLineInfoForAddress(uint64_t Address,
111127 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
1818
1919 typedef DWARFDebugLine::LineTable DWARFLineTable;
2020
21 void DWARFContext::dump(raw_ostream &OS) {
22 OS << ".debug_abbrev contents:\n";
23 getDebugAbbrev()->dump(OS);
24
25 OS << "\n.debug_info contents:\n";
26 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
27 getCompileUnitAtIndex(i)->dump(OS);
28
29 OS << "\n.debug_aranges contents:\n";
30 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
21 void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
22 if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
23 OS << ".debug_abbrev contents:\n";
24 getDebugAbbrev()->dump(OS);
25 }
26
27 if (DumpType == DIDT_All || DumpType == DIDT_Info) {
28 OS << "\n.debug_info contents:\n";
29 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
30 getCompileUnitAtIndex(i)->dump(OS);
31 }
32
3133 uint32_t offset = 0;
32 DWARFDebugArangeSet set;
33 while (set.extract(arangesData, &offset))
34 set.dump(OS);
34 if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
35 OS << "\n.debug_aranges contents:\n";
36 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
37 DWARFDebugArangeSet set;
38 while (set.extract(arangesData, &offset))
39 set.dump(OS);
40 }
3541
3642 uint8_t savedAddressByteSize = 0;
37 OS << "\n.debug_line contents:\n";
38 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
39 DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
40 savedAddressByteSize = cu->getAddressByteSize();
41 unsigned stmtOffset =
42 cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
43 -1U);
44 if (stmtOffset != -1U) {
45 DataExtractor lineData(getLineSection(), isLittleEndian(),
43 if (DumpType == DIDT_All || DumpType == DIDT_Line) {
44 OS << "\n.debug_line contents:\n";
45 for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
46 DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
47 savedAddressByteSize = cu->getAddressByteSize();
48 unsigned stmtOffset =
49 cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
50 -1U);
51 if (stmtOffset != -1U) {
52 DataExtractor lineData(getLineSection(), isLittleEndian(),
53 savedAddressByteSize);
54 DWARFDebugLine::DumpingState state(OS);
55 DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
56 }
57 }
58 }
59
60 if (DumpType == DIDT_All || DumpType == DIDT_Str) {
61 OS << "\n.debug_str contents:\n";
62 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
63 offset = 0;
64 uint32_t strOffset = 0;
65 while (const char *s = strData.getCStr(&offset)) {
66 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
67 strOffset = offset;
68 }
69 }
70
71 if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
72 OS << "\n.debug_ranges contents:\n";
73 // In fact, different compile units may have different address byte
74 // sizes, but for simplicity we just use the address byte size of the last
75 // compile unit (there is no easy and fast way to associate address range
76 // list and the compile unit it describes).
77 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
4678 savedAddressByteSize);
47 DWARFDebugLine::DumpingState state(OS);
48 DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
49 }
50 }
51
52 OS << "\n.debug_str contents:\n";
53 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
54 offset = 0;
55 uint32_t strOffset = 0;
56 while (const char *s = strData.getCStr(&offset)) {
57 OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
58 strOffset = offset;
59 }
60
61 OS << "\n.debug_ranges contents:\n";
62 // In fact, different compile units may have different address byte
63 // sizes, but for simplicity we just use the address byte size of the last
64 // compile unit (there is no easy and fast way to associate address range
65 // list and the compile unit it describes).
66 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
67 savedAddressByteSize);
68 offset = 0;
69 DWARFDebugRangeList rangeList;
70 while (rangeList.extract(rangesData, &offset))
71 rangeList.dump(OS);
72
73 OS << "\n.debug_abbrev.dwo contents:\n";
74 getDebugAbbrevDWO()->dump(OS);
75
76 OS << "\n.debug_info.dwo contents:\n";
77 for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
78 getDWOCompileUnitAtIndex(i)->dump(OS);
79
80 OS << "\n.debug_str.dwo contents:\n";
81 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
82 offset = 0;
83 uint32_t strDWOOffset = 0;
84 while (const char *s = strDWOData.getCStr(&offset)) {
85 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
86 strDWOOffset = offset;
87 }
88
89 OS << "\n.debug_str_offsets.dwo contents:\n";
90 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
91 offset = 0;
92 while (offset < getStringOffsetDWOSection().size()) {
93 OS << format("0x%8.8x: ", offset);
94 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
79 offset = 0;
80 DWARFDebugRangeList rangeList;
81 while (rangeList.extract(rangesData, &offset))
82 rangeList.dump(OS);
83 }
84
85 if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) {
86 OS << "\n.debug_abbrev.dwo contents:\n";
87 getDebugAbbrevDWO()->dump(OS);
88 }
89
90 if (DumpType == DIDT_All || DumpType == DIDT_InfoDwo) {
91 OS << "\n.debug_info.dwo contents:\n";
92 for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
93 getDWOCompileUnitAtIndex(i)->dump(OS);
94 }
95
96 if (DumpType == DIDT_All || DumpType == DIDT_StrDwo) {
97 OS << "\n.debug_str.dwo contents:\n";
98 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
99 offset = 0;
100 uint32_t strDWOOffset = 0;
101 while (const char *s = strDWOData.getCStr(&offset)) {
102 OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
103 strDWOOffset = offset;
104 }
105 }
106
107 if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
108 OS << "\n.debug_str_offsets.dwo contents:\n";
109 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
110 offset = 0;
111 while (offset < getStringOffsetDWOSection().size()) {
112 OS << format("0x%8.8x: ", offset);
113 OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
114 }
95115 }
96116 }
97117
4444
4545 public:
4646 DWARFContext() {}
47 virtual void dump(raw_ostream &OS);
47 virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All);
4848
4949 /// Get the number of compile units in this context.
5050 unsigned getNumCompileUnits() {
0 ; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test.elf-x86-64 -debug-dump=all | FileCheck %s -check-prefix DUMP_ALL
1 ; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test.elf-x86-64 -debug-dump=info | FileCheck %s -check-prefix DUMP_INFO
2 ; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test.elf-x86-64 -debug-dump=ranges | FileCheck %s -check-prefix DUMP_RANGES
3
4 ; DUMP_ALL: .debug_info
5 ; DUMP_ALL: .debug_ranges
6
7 ; DUMP_INFO: .debug_info
8 ; DUMP_INFO-NOT: .debug_ranges
9
10 ; DUMP_RANGES-NOT: .debug_info
11 ; DUMP_RANGES: .debug_ranges
12
5151 PrintInlining("inlining", cl::init(false),
5252 cl::desc("Print all inlined frames for a given address"));
5353
54 static cl::opt
55 DumpType("debug-dump", cl::init(DIDT_All),
56 cl::desc("Dump of debug sections:"),
57 cl::values(
58 clEnumValN(DIDT_All, "all", "Dump all debug sections"),
59 clEnumValN(DIDT_Abbrev, "abbrev", ".debug_abbrev"),
60 clEnumValN(DIDT_AbbrevDwo, "abbrev.dwo", ".debug_abbrev.dwo"),
61 clEnumValN(DIDT_Aranges, "aranges", ".debug_aranges"),
62 clEnumValN(DIDT_Info, "info", ".debug_info"),
63 clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
64 clEnumValN(DIDT_Line, "line", ".debug_line"),
65 clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
66 clEnumValN(DIDT_Str, "str", ".debug_str"),
67 clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
68 clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"),
69 clEnumValEnd));
70
5471 static void PrintDILineInfo(DILineInfo dli) {
5572 if (PrintFunctions)
5673 outs() << (dli.getFunctionName() ? dli.getFunctionName() : "")
7491 outs() << Filename
7592 << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
7693 // Dump the complete DWARF structure.
77 DICtx->dump(outs());
94 DICtx->dump(outs(), DumpType);
7895 } else {
7996 // Print line info for the specified address.
8097 int SpecFlags = DILineInfoSpecifier::FileLineInfo |