1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[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

llvm-svn: 313530
This commit is contained in:
Jonas Devlieghere 2017-09-18 14:15:57 +00:00
parent e5d95e4259
commit 158da0d39f
13 changed files with 35 additions and 34 deletions

View File

@ -833,7 +833,7 @@ HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info")
HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types") HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")
HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line") HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc") 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(DebugMacro, ".debug_macro", "debug-macro")
HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges") HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges")
HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames") HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames")

View File

@ -138,7 +138,6 @@ enum DIDumpType : unsigned {
/// dumped. /// dumped.
struct DIDumpOptions { struct DIDumpOptions {
unsigned DumpType = DIDT_All; unsigned DumpType = DIDT_All;
bool DumpEH = false;
bool ShowChildren = false; bool ShowChildren = false;
bool SummarizeTypes = false; bool SummarizeTypes = false;
bool Verbose = false; bool Verbose = false;
@ -158,8 +157,7 @@ public:
virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0; virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
virtual bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All, virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
DIDumpOptions DumpOpts = {}) {
// No verifier? Just say things went well. // No verifier? Just say things went well.
return true; return true;
} }

View File

@ -131,8 +131,7 @@ public:
dump(OS, DumpOpts, DumpOffsets); dump(OS, DumpOpts, DumpOffsets);
} }
bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All, bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
DIDumpOptions DumpOpts = {}) override;
using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range; using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range; using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;

View File

@ -222,7 +222,6 @@ void DWARFContext::dump(
Optional<uint64_t> DumpOffset; Optional<uint64_t> DumpOffset;
uint64_t DumpType = DumpOpts.DumpType; uint64_t DumpType = DumpOpts.DumpType;
bool DumpEH = DumpOpts.DumpEH;
unsigned RecDepth = unsigned RecDepth =
DumpOpts.ShowChildren ? std::numeric_limits<unsigned>::max() : 0; DumpOpts.ShowChildren ? std::numeric_limits<unsigned>::max() : 0;
@ -299,12 +298,13 @@ void DWARFContext::dump(
getDebugLocDWO()->dump(OS, getRegisterInfo()); getDebugLocDWO()->dump(OS, getRegisterInfo());
} }
if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrames, if (shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
DObj->getDebugFrameSection())) { DObj->getDebugFrameSection())) {
getDebugFrame()->dump(OS); 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); getEHFrame()->dump(OS);
} }
@ -492,15 +492,14 @@ DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
return DWARFDie(); return DWARFDie();
} }
bool DWARFContext::verify(raw_ostream &OS, unsigned DumpType, bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
DIDumpOptions DumpOpts) {
bool Success = true; bool Success = true;
DWARFVerifier verifier(OS, *this, DumpOpts); DWARFVerifier verifier(OS, *this, DumpOpts);
Success &= verifier.handleDebugAbbrev(); Success &= verifier.handleDebugAbbrev();
if (DumpType & DIDT_DebugInfo) if (DumpOpts.DumpType & DIDT_DebugInfo)
Success &= verifier.handleDebugInfo(); Success &= verifier.handleDebugInfo();
if (DumpType & DIDT_DebugLine) if (DumpOpts.DumpType & DIDT_DebugLine)
Success &= verifier.handleDebugLine(); Success &= verifier.handleDebugLine();
Success &= verifier.handleAccelTables(); Success &= verifier.handleAccelTables();
return Success; return Success;

View File

@ -188,10 +188,16 @@ void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
break; break;
} }
case DW_CFA_def_cfa_expression: case DW_CFA_def_cfa_expression:
// FIXME: Parse the actual instruction.
*Offset += Data.getULEB128(Offset);
break;
case DW_CFA_expression: case DW_CFA_expression:
case DW_CFA_val_expression: case DW_CFA_val_expression: {
// TODO: implement this // FIXME: Parse the actual instruction.
report_fatal_error("Values with expressions not implemented yet!"); Data.getULEB128(Offset);
*Offset += Data.getULEB128(Offset);
break;
}
} }
} }
} }

View File

@ -1,8 +1,7 @@
; 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 ; Note: the input file was generated from Inputs/dwarfdump-test-32bit.elf.c
; FRAMES: .debug_frame ; FRAMES: .debug_frame
; FRAMES-NOT: .eh_frame
; FRAMES: 00000000 00000010 ffffffff CIE ; FRAMES: 00000000 00000010 ffffffff CIE
; FRAMES: Version: 1 ; FRAMES: Version: 1
@ -25,4 +24,4 @@
; FRAMES-NOT: CIE ; FRAMES-NOT: CIE
; FRAMES-NOT: FDE ; FRAMES-NOT: FDE
; FRAMES: .eh_frame

View File

@ -1,4 +1,4 @@
; 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: ; IR reduced from a dummy:
; void foo() {} ; void foo() {}

View File

@ -2,7 +2,7 @@
# RUN: rm -rf %t # RUN: rm -rf %t
# RUN: mkdir -p %t # 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-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 # 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 # in the same file but also inbetween files. For this to happen, we
@ -29,4 +29,4 @@ objects:
# CHECK-NOT: FDE # CHECK-NOT: FDE
# CHECK: FDE cie=00000000 pc=00003000...00003 # CHECK: FDE cie=00000000 pc=00003000...00003
# CHECK-NOT: FDE # CHECK-NOT: FDE
# CHECK: .eh_frame contents:

View File

@ -3,7 +3,7 @@
# RUN: mkdir -p %t # 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-dw2.ll -o %t/frame-dw2.o
# RUN: llc -filetype=obj %p/../Inputs/frame-dw4.ll -o %t/frame-dw4.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 # Check the handling of multiple different CIEs. To have CIEs that
# appear to be different, use a dwarf2 version of the file along with # appear to be different, use a dwarf2 version of the file along with
@ -44,4 +44,4 @@ objects:
# CHECK-NOT: FDE # CHECK-NOT: FDE
# CHECK: FDE cie=[[CIEDW2]] pc=00004000...00004 # CHECK: FDE cie=[[CIEDW2]] pc=00004000...00004
# CHECK-NOT: FDE # CHECK-NOT: FDE
# CHECK: .eh_frame contents:

View File

@ -122,6 +122,8 @@ static std::array<llvm::Optional<uint64_t>, (unsigned)DIDT_ID_Count> DumpOffsets
#include "llvm/BinaryFormat/Dwarf.def" #include "llvm/BinaryFormat/Dwarf.def"
#undef HANDLE_DWARF_SECTION #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"), static opt<bool> DumpUUID("uuid", desc("Show the UUID for each architecture"),
cat(DwarfDumpCategory)); cat(DwarfDumpCategory));
static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID)); static alias DumpUUIDAlias("u", desc("Alias for -uuid"), aliasopt(DumpUUID));
@ -186,7 +188,7 @@ static bool verifyObjectFile(ObjectFile &Obj, Twine Filename) {
raw_ostream &stream = Quiet ? nulls() : outs(); raw_ostream &stream = Quiet ? nulls() : outs();
stream << "Verifying " << Filename.str() << ":\tfile format " stream << "Verifying " << Filename.str() << ":\tfile format "
<< Obj.getFileFormatName() << "\n"; << Obj.getFileFormatName() << "\n";
bool Result = DICtx->verify(stream, DumpType, getDumpOpts()); bool Result = DICtx->verify(stream, getDumpOpts());
if (Result) if (Result)
stream << "No errors.\n"; stream << "No errors.\n";
else else

View File

@ -1279,7 +1279,6 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
// Dump the complete DWARF structure. // Dump the complete DWARF structure.
DIDumpOptions DumpOpts; DIDumpOptions DumpOpts;
DumpOpts.DumpType = DwarfDumpType; DumpOpts.DumpType = DwarfDumpType;
DumpOpts.DumpEH = true;
DICtx->dump(outs(), DumpOpts); DICtx->dump(outs(), DumpOpts);
} }
} }
@ -5833,7 +5832,7 @@ static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) {
mtime = nullptr; mtime = nullptr;
name = nullptr; name = nullptr;
for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){ 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); xar_prop_get(xf, key, &val);
#if 0 // Useful for debugging. #if 0 // Useful for debugging.
outs() << "key: " << key << " value: " << val << "\n"; outs() << "key: " << key << " value: " << val << "\n";
@ -6023,7 +6022,7 @@ static void DumpBitcodeSection(MachOObjectFile *O, const char *sect,
member_type = NULL; member_type = NULL;
member_size_string = NULL; member_size_string = NULL;
for(key = xar_prop_first(xf, xp); key; key = xar_prop_next(xp)){ 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); xar_prop_get(xf, key, &val);
#if 0 // Useful for debugging. #if 0 // Useful for debugging.
outs() << "key: " << key << " value: " << val << "\n"; outs() << "key: " << key << " value: " << val << "\n";

View File

@ -191,7 +191,7 @@ cl::opt<bool> PrintFaultMaps("fault-map-section",
cl::opt<DIDumpType> llvm::DwarfDumpType( cl::opt<DIDumpType> llvm::DwarfDumpType(
"dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"), "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( cl::opt<bool> PrintSource(
"source", "source",
@ -2085,7 +2085,6 @@ static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
// Dump the complete DWARF structure. // Dump the complete DWARF structure.
DIDumpOptions DumpOpts; DIDumpOptions DumpOpts;
DumpOpts.DumpType = DwarfDumpType; DumpOpts.DumpType = DwarfDumpType;
DumpOpts.DumpEH = true;
DICtx->dump(outs(), DumpOpts); DICtx->dump(outs(), DumpOpts);
} }
} }

View File

@ -1662,21 +1662,21 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) { void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) {
SmallString<1024> Str; SmallString<1024> Str;
raw_svector_ostream Strm(Str); raw_svector_ostream Strm(Str);
EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All)); EXPECT_TRUE(DwarfContext.verify(Strm));
EXPECT_TRUE(Str.str().contains(Error)); EXPECT_TRUE(Str.str().contains(Error));
} }
void VerifyError(DWARFContext &DwarfContext, StringRef Error) { void VerifyError(DWARFContext &DwarfContext, StringRef Error) {
SmallString<1024> Str; SmallString<1024> Str;
raw_svector_ostream Strm(Str); raw_svector_ostream Strm(Str);
EXPECT_FALSE(DwarfContext.verify(Strm, DIDT_All)); EXPECT_FALSE(DwarfContext.verify(Strm));
EXPECT_TRUE(Str.str().contains(Error)); EXPECT_TRUE(Str.str().contains(Error));
} }
void VerifySuccess(DWARFContext &DwarfContext) { void VerifySuccess(DWARFContext &DwarfContext) {
SmallString<1024> Str; SmallString<1024> Str;
raw_svector_ostream Strm(Str); raw_svector_ostream Strm(Str);
EXPECT_TRUE(DwarfContext.verify(Strm, DIDT_All)); EXPECT_TRUE(DwarfContext.verify(Strm));
} }
TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) { TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {