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
HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")
HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc")
-HANDLE_DWARF_SECTION(DebugFrames, ".debug_frames", "debug-frames")
+HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame")
HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro")
HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges")
HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames")
/// dumped.
struct DIDumpOptions {
unsigned DumpType = DIDT_All;
- bool DumpEH = false;
bool ShowChildren = false;
bool SummarizeTypes = false;
bool Verbose = false;
virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
- virtual bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All,
- DIDumpOptions DumpOpts = {}) {
+ virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
// No verifier? Just say things went well.
return true;
}
dump(OS, DumpOpts, DumpOffsets);
}
- bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All,
- DIDumpOptions DumpOpts = {}) override;
+ bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
Optional<uint64_t> DumpOffset;
uint64_t DumpType = DumpOpts.DumpType;
- bool DumpEH = DumpOpts.DumpEH;
unsigned RecDepth =
DumpOpts.ShowChildren ? std::numeric_limits<unsigned>::max() : 0;
getDebugLocDWO()->dump(OS, getRegisterInfo());
}
- if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrames,
+ if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
DObj->getDebugFrameSection())) {
getDebugFrame()->dump(OS);
}
- if (DumpEH && !getEHFrame()->empty()) {
- OS << "\n.eh_frame contents:\n";
+
+ if (shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
+ DObj->getEHFrameSection())) {
getEHFrame()->dump(OS);
}
return DWARFDie();
}
-bool DWARFContext::verify(raw_ostream &OS, unsigned DumpType,
- DIDumpOptions DumpOpts) {
+bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
bool Success = true;
DWARFVerifier verifier(OS, *this, DumpOpts);
Success &= verifier.handleDebugAbbrev();
- if (DumpType & DIDT_DebugInfo)
+ if (DumpOpts.DumpType & DIDT_DebugInfo)
Success &= verifier.handleDebugInfo();
- if (DumpType & DIDT_DebugLine)
+ if (DumpOpts.DumpType & DIDT_DebugLine)
Success &= verifier.handleDebugLine();
Success &= verifier.handleAccelTables();
return Success;
break;
}
case DW_CFA_def_cfa_expression:
+ // FIXME: Parse the actual instruction.
+ *Offset += Data.getULEB128(Offset);
+ break;
case DW_CFA_expression:
- case DW_CFA_val_expression:
- // TODO: implement this
- report_fatal_error("Values with expressions not implemented yet!");
+ case DW_CFA_val_expression: {
+ // FIXME: Parse the actual instruction.
+ Data.getULEB128(Offset);
+ *Offset += Data.getULEB128(Offset);
+ break;
+ }
}
}
}
-; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-32bit.elf.o --debug-frames | FileCheck %s -check-prefix FRAMES
+; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test-32bit.elf.o --debug-frame | FileCheck %s -check-prefix FRAMES
; Note: the input file was generated from Inputs/dwarfdump-test-32bit.elf.c
; FRAMES: .debug_frame
-; FRAMES-NOT: .eh_frame
; FRAMES: 00000000 00000010 ffffffff CIE
; FRAMES: Version: 1
; FRAMES-NOT: CIE
; FRAMES-NOT: FDE
-
+; FRAMES: .eh_frame
-; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump -debug-frames - | FileCheck %s
+; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
; IR reduced from a dummy:
; void foo() {}
# RUN: rm -rf %t
# RUN: mkdir -p %t
# RUN: llc -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o
-# RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frames - | FileCheck %s
+# RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
# This test is meant to verify that identical CIEs will get reused
# in the same file but also inbetween files. For this to happen, we
# CHECK-NOT: FDE
# CHECK: FDE cie=00000000 pc=00003000...00003
# CHECK-NOT: FDE
-
+# CHECK: .eh_frame contents:
# RUN: mkdir -p %t
# RUN: llc -filetype=obj %p/../Inputs/frame-dw2.ll -o %t/frame-dw2.o
# RUN: llc -filetype=obj %p/../Inputs/frame-dw4.ll -o %t/frame-dw4.o
-# RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frames - | FileCheck %s
+# RUN: llvm-dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
# Check the handling of multiple different CIEs. To have CIEs that
# appear to be different, use a dwarf2 version of the file along with
# CHECK-NOT: FDE
# CHECK: FDE cie=[[CIEDW2]] pc=00004000...00004
# CHECK-NOT: FDE
-
+# CHECK: .eh_frame contents:
#include "llvm/BinaryFormat/Dwarf.def"
#undef HANDLE_DWARF_SECTION
+static alias DumpDebugFrameAlias("eh-frame", desc("Alias for -debug-frame"),
+ aliasopt(DumpDebugFrame));
static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture"),
cat(DwarfDumpCategory));
static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
raw_ostream &stream = Quiet ? nulls() : outs();
stream << "Verifying " << Filename.str() << ":\tfile format "
<< Obj.getFileFormatName() << "\n";
- bool Result = DICtx->verify(stream, DumpType, getDumpOpts());
+ bool Result = DICtx->verify(stream, getDumpOpts());
if (Result)
stream << "No errors.\n";
else
// Dump the complete DWARF structure.
DIDumpOptions DumpOpts;
DumpOpts.DumpType = DwarfDumpType;
- DumpOpts.DumpEH = true;
DICtx->dump(outs(), DumpOpts);
}
}
mtime = nullptr;
name = nullptr;
for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
- const char *val = nullptr;
+ const char *val = nullptr;
xar_prop_get(xf, key, &val);
#if 0 // Useful for debugging.
outs() << "key: " << key << " value: " << val << "\n";
member_type = NULL;
member_size_string = NULL;
for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){
- const char *val = nullptr;
+ const char *val = nullptr;
xar_prop_get(xf, key, &val);
#if 0 // Useful for debugging.
outs() << "key: " << key << " value: " << val << "\n";
cl::opt<DIDumpType> llvm::DwarfDumpType(
"dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
- cl::values(clEnumValN(DIDT_DebugFrames, "frames", ".debug_frame")));
+ cl::values(clEnumValN(DIDT_DebugFrame, "frames", ".debug_frame")));
cl::opt<bool> PrintSource(
"source",
// Dump the complete DWARF structure.
DIDumpOptions DumpOpts;
DumpOpts.DumpType = DwarfDumpType;
- DumpOpts.DumpEH = true;
DICtx->dump(outs(), DumpOpts);
}
}
void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) {
SmallString<1024> Str;
raw_svector_ostream Strm(Str);
- EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
+ EXPECT_TRUE(DwarfContext.verify(Strm));
EXPECT_TRUE(Str.str().contains(Error));
}
void VerifyError(DWARFContext &DwarfContext, StringRef Error) {
SmallString<1024> Str;
raw_svector_ostream Strm(Str);
- EXPECT_FALSE(DwarfContext.verify(Strm, DIDT_All));
+ EXPECT_FALSE(DwarfContext.verify(Strm));
EXPECT_TRUE(Str.str().contains(Error));
}
void VerifySuccess(DWARFContext &DwarfContext) {
SmallString<1024> Str;
raw_svector_ostream Strm(Str);
- EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All));
+ EXPECT_TRUE(DwarfContext.verify(Strm));
}
TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {