llvm.org GIT mirror llvm / 6ad4356
[dwarfdump] Make .eh_frame an alias for .debug_frame This patch makes the `.eh_frame` extension an alias for `.debug_frame`. Up till now it was only possible to dump the section using objdump, but not with dwarfdump. Since the two are essentially interchangeable, we dump whichever of the two is present. As a workaround, this patch also adds parsing for 3 currently unimplemented CFA instructions: `DW_CFA_def_cfa_expression`, `DW_CFA_expression`, and `DW_CFA_val_expression`. Because I lack the required knowledge, I just parse the fields without actually creating the instructions. Finally, this also fixes the typo in the `.debug_frame` section name which incorrectly contained a trailing `s`. Differential revision: https://reviews.llvm.org/D37852 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313530 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 1 year, 11 months ago
13 changed file(s) with 35 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
832832 HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")
833833 HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
834834 HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc")
835 HANDLE_DWARF_SECTION(DebugFrames, ".debug_frames", "debug-frames")
835 HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame")
836836 HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro")
837837 HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges")
838838 HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames")
137137 /// dumped.
138138 struct DIDumpOptions {
139139 unsigned DumpType = DIDT_All;
140 bool DumpEH = false;
141140 bool ShowChildren = false;
142141 bool SummarizeTypes = false;
143142 bool Verbose = false;
157156
158157 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
159158
160 virtual bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All,
161 DIDumpOptions DumpOpts = {}) {
159 virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
162160 // No verifier? Just say things went well.
163161 return true;
164162 }
130130 dump(OS, DumpOpts, DumpOffsets);
131131 }
132132
133 bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All,
134 DIDumpOptions DumpOpts = {}) override;
133 bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
135134
136135 using cu_iterator_range = DWARFUnitSection::iterator_range;
137136 using tu_iterator_range = DWARFUnitSection::iterator_range;
221221
222222 Optional DumpOffset;
223223 uint64_t DumpType = DumpOpts.DumpType;
224 bool DumpEH = DumpOpts.DumpEH;
225224 unsigned RecDepth =
226225 DumpOpts.ShowChildren ? std::numeric_limits::max() : 0;
227226
298297 getDebugLocDWO()->dump(OS, getRegisterInfo());
299298 }
300299
301 if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrames,
300 if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
302301 DObj->getDebugFrameSection())) {
303302 getDebugFrame()->dump(OS);
304303 }
305 if (DumpEH && !getEHFrame()->empty()) {
306 OS << "\n.eh_frame contents:\n";
304
305 if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
306 DObj->getEHFrameSection())) {
307307 getEHFrame()->dump(OS);
308308 }
309309
491491 return DWARFDie();
492492 }
493493
494 bool DWARFContext::verify(raw_ostream &OS, unsigned DumpType,
495 DIDumpOptions DumpOpts) {
494 bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
496495 bool Success = true;
497496 DWARFVerifier verifier(OS, *this, DumpOpts);
498497
499498 Success &= verifier.handleDebugAbbrev();
500 if (DumpType & DIDT_DebugInfo)
499 if (DumpOpts.DumpType & DIDT_DebugInfo)
501500 Success &= verifier.handleDebugInfo();
502 if (DumpType & DIDT_DebugLine)
501 if (DumpOpts.DumpType & DIDT_DebugLine)
503502 Success &= verifier.handleDebugLine();
504503 Success &= verifier.handleAccelTables();
505504 return Success;
187187 break;
188188 }
189189 case DW_CFA_def_cfa_expression:
190 // FIXME: Parse the actual instruction.
191 *Offset += Data.getULEB128(Offset);
192 break;
190193 case DW_CFA_expression:
191 case DW_CFA_val_expression:
192 // TODO: implement this
193 report_fatal_error("Values with expressions not implemented yet!");
194 case DW_CFA_val_expression: {
195 // FIXME: Parse the actual instruction.
196 Data.getULEB128(Offset);
197 *Offset += Data.getULEB128(Offset);
198 break;
199 }
194200 }
195201 }
196202 }
None ; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-32bit.elf.o --debug-frames | FileCheck %s -check-prefix FRAMES
0 ; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-32bit.elf.o --debug-frame | FileCheck %s -check-prefix FRAMES
11 ; Note: the input file was generated from Inputs/dwarfdump-test-32bit.elf.c
22
33 ; FRAMES: .debug_frame
4 ; FRAMES-NOT: .eh_frame
54
65 ; FRAMES: 00000000 00000010 ffffffff CIE
76 ; FRAMES: Version: 1
2423
2524 ; FRAMES-NOT: CIE
2625 ; FRAMES-NOT: FDE
27
26 ; FRAMES: .eh_frame
None ; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump -debug-frames - | FileCheck %s
0 ; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
11
22 ; IR reduced from a dummy:
33 ; void foo() {}
11 # RUN: rm -rf %t
22 # RUN: mkdir -p %t
33 # RUN: llc -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o
4 # RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frames - | FileCheck %s
4 # RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
55
66 # This test is meant to verify that identical CIEs will get reused
77 # in the same file but also inbetween files. For this to happen, we
2828 # CHECK-NOT: FDE
2929 # CHECK: FDE cie=00000000 pc=00003000...00003
3030 # CHECK-NOT: FDE
31
31 # CHECK: .eh_frame contents:
22 # RUN: mkdir -p %t
33 # RUN: llc -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o
44 # RUN: llc -filetype=obj %p/../Inputs/frame-dw4.ll -o %t/frame-dw4.o
5 # RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frames - | FileCheck %s
5 # RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
66
77 # Check the handling of multiple different CIEs. To have CIEs that
88 # appear to be different, use a dwarf2 version of the file along with
4343 # CHECK-NOT: FDE
4444 # CHECK: FDE cie=[[CIEDW2]] pc=00004000...00004
4545 # CHECK-NOT: FDE
46
46 # CHECK: .eh_frame contents:
121121 #include "llvm/BinaryFormat/Dwarf.def"
122122 #undef HANDLE_DWARF_SECTION
123123
124 static alias DumpDebugFrameAlias("eh-frame", desc("Alias for -debug-frame"),
125 aliasopt(DumpDebugFrame));
124126 static opt DumpUUID("uuid", desc("Show the UUID for each architecture"),
125127 cat(DwarfDumpCategory));
126128 static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
185187 raw_ostream &stream = Quiet ? nulls() : outs();
186188 stream << "Verifying " << Filename.str() << ":\tfile format "
187189 << Obj.getFileFormatName() << "\n";
188 bool Result = DICtx->verify(stream, DumpType, getDumpOpts());
190 bool Result = DICtx->verify(stream, getDumpOpts());
189191 if (Result)
190192 stream << "No errors.\n";
191193 else
12781278 // Dump the complete DWARF structure.
12791279 DIDumpOptions DumpOpts;
12801280 DumpOpts.DumpType = DwarfDumpType;
1281 DumpOpts.DumpEH = true;
12821281 DICtx->dump(outs(), DumpOpts);
12831282 }
12841283 }
58325831 mtime = nullptr;
58335832 name = nullptr;
58345833 for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
5835 const char *val = nullptr;
5834 const char *val = nullptr;
58365835 xar_prop_get(xf, key, &val);
58375836 #if 0 // Useful for debugging.
58385837 outs() << "key: " << key << " value: " << val << "\n";
60226021 member_type = NULL;
60236022 member_size_string = NULL;
60246023 for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
6025 const char *val = nullptr;
6024 const char *val = nullptr;
60266025 xar_prop_get(xf, key, &val);
60276026 #if 0 // Useful for debugging.
60286027 outs() << "key: " << key << " value: " << val << "\n";
190190
191191 cl::opt llvm::DwarfDumpType(
192192 "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
193 cl::values(clEnumValN(DIDT_DebugFrames, "frames", ".debug_frame")));
193 cl::values(clEnumValN(DIDT_DebugFrame, "frames", ".debug_frame")));
194194
195195 cl::opt PrintSource(
196196 "source",
20842084 // Dump the complete DWARF structure.
20852085 DIDumpOptions DumpOpts;
20862086 DumpOpts.DumpType = DwarfDumpType;
2087 DumpOpts.DumpEH = true;
20882087 DICtx->dump(outs(), DumpOpts);
20892088 }
20902089 }
16611661 void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) {
16621662 SmallString<1024> Str;
16631663 raw_svector_ostream Strm(Str);
1664 EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
1664 EXPECT_TRUE(DwarfContext.verify(Strm));
16651665 EXPECT_TRUE(Str.str().contains(Error));
16661666 }
16671667
16681668 void VerifyError(DWARFContext &DwarfContext, StringRef Error) {
16691669 SmallString<1024> Str;
16701670 raw_svector_ostream Strm(Str);
1671 EXPECT_FALSE(DwarfContext.verify(Strm, DIDT_All));
1671 EXPECT_FALSE(DwarfContext.verify(Strm));
16721672 EXPECT_TRUE(Str.str().contains(Error));
16731673 }
16741674
16751675 void VerifySuccess(DWARFContext &DwarfContext) {
16761676 SmallString<1024> Str;
16771677 raw_svector_ostream Strm(Str);
1678 EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
1678 EXPECT_TRUE(DwarfContext.verify(Strm));
16791679 }
16801680
16811681 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {