From 158da0d39f40b9fc3afbe78ebac94b1a909ac8ba Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 18 Sep 2017 14:15:57 +0000 Subject: [PATCH] [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 --- include/llvm/BinaryFormat/Dwarf.def | 2 +- include/llvm/DebugInfo/DIContext.h | 4 +--- include/llvm/DebugInfo/DWARF/DWARFContext.h | 3 +-- lib/DebugInfo/DWARF/DWARFContext.cpp | 15 +++++++-------- lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 12 +++++++++--- test/DebugInfo/dwarfdump-debug-frame-simple.test | 5 ++--- test/MC/X86/i386-darwin-frame-register.ll | 2 +- test/tools/dsymutil/X86/frame-1.test | 4 ++-- test/tools/dsymutil/X86/frame-2.test | 4 ++-- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 4 +++- tools/llvm-objdump/MachODump.cpp | 5 ++--- tools/llvm-objdump/llvm-objdump.cpp | 3 +-- unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp | 6 +++--- 13 files changed, 35 insertions(+), 34 deletions(-) diff --git a/include/llvm/BinaryFormat/Dwarf.def b/include/llvm/BinaryFormat/Dwarf.def index fdbad6d02d2..8214fe2e120 100644 --- a/include/llvm/BinaryFormat/Dwarf.def +++ b/include/llvm/BinaryFormat/Dwarf.def @@ -833,7 +833,7 @@ HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info") 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") diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 9da31e6e173..0d9ea0028e9 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -138,7 +138,6 @@ enum DIDumpType : unsigned { /// dumped. struct DIDumpOptions { unsigned DumpType = DIDT_All; - bool DumpEH = false; bool ShowChildren = false; bool SummarizeTypes = false; bool Verbose = false; @@ -158,8 +157,7 @@ public: 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; } diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index e43a9ba8adf..7701f4ab621 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -131,8 +131,7 @@ public: 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::iterator_range; using tu_iterator_range = DWARFUnitSection::iterator_range; diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 373452a9278..353a5bad997 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -222,7 +222,6 @@ void DWARFContext::dump( Optional DumpOffset; uint64_t DumpType = DumpOpts.DumpType; - bool DumpEH = DumpOpts.DumpEH; unsigned RecDepth = DumpOpts.ShowChildren ? std::numeric_limits::max() : 0; @@ -299,12 +298,13 @@ void DWARFContext::dump( 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); } @@ -492,15 +492,14 @@ DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) { 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; diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index 475cf25b781..6e8b5f4f471 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -188,10 +188,16 @@ void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset, 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; + } } } } diff --git a/test/DebugInfo/dwarfdump-debug-frame-simple.test b/test/DebugInfo/dwarfdump-debug-frame-simple.test index 6d0987bece5..7193abc6cc0 100644 --- a/test/DebugInfo/dwarfdump-debug-frame-simple.test +++ b/test/DebugInfo/dwarfdump-debug-frame-simple.test @@ -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 ; FRAMES: .debug_frame -; FRAMES-NOT: .eh_frame ; FRAMES: 00000000 00000010 ffffffff CIE ; FRAMES: Version: 1 @@ -25,4 +24,4 @@ ; FRAMES-NOT: CIE ; FRAMES-NOT: FDE - +; FRAMES: .eh_frame diff --git a/test/MC/X86/i386-darwin-frame-register.ll b/test/MC/X86/i386-darwin-frame-register.ll index 5a433a99a59..c56e8e6b423 100644 --- a/test/MC/X86/i386-darwin-frame-register.ll +++ b/test/MC/X86/i386-darwin-frame-register.ll @@ -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: ; void foo() {} diff --git a/test/tools/dsymutil/X86/frame-1.test b/test/tools/dsymutil/X86/frame-1.test index 00f399bebe1..513694bed14 100644 --- a/test/tools/dsymutil/X86/frame-1.test +++ b/test/tools/dsymutil/X86/frame-1.test @@ -2,7 +2,7 @@ # 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 @@ -29,4 +29,4 @@ objects: # CHECK-NOT: FDE # CHECK: FDE cie=00000000 pc=00003000...00003 # CHECK-NOT: FDE - +# CHECK: .eh_frame contents: diff --git a/test/tools/dsymutil/X86/frame-2.test b/test/tools/dsymutil/X86/frame-2.test index 9d7389088a8..613ccb80eab 100644 --- a/test/tools/dsymutil/X86/frame-2.test +++ b/test/tools/dsymutil/X86/frame-2.test @@ -3,7 +3,7 @@ # 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 @@ -44,4 +44,4 @@ objects: # CHECK-NOT: FDE # CHECK: FDE cie=[[CIEDW2]] pc=00004000...00004 # CHECK-NOT: FDE - +# CHECK: .eh_frame contents: diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 725152161a6..c2bcd382ee3 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -122,6 +122,8 @@ static std::array, (unsigned)DIDT_ID_Count> DumpOffsets #include "llvm/BinaryFormat/Dwarf.def" #undef HANDLE_DWARF_SECTION +static alias DumpDebugFrameAlias("eh-frame", desc("Alias for -debug-frame"), + aliasopt(DumpDebugFrame)); static opt DumpUUID("uuid", desc("Show the UUID for each architecture"), cat(DwarfDumpCategory)); 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(); 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 diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 6d3f38333eb..e1e42c2e218 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -1279,7 +1279,6 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF, // Dump the complete DWARF structure. DIDumpOptions DumpOpts; DumpOpts.DumpType = DwarfDumpType; - DumpOpts.DumpEH = true; DICtx->dump(outs(), DumpOpts); } } @@ -5833,7 +5832,7 @@ static void PrintXarFilesSummary(const char *XarFilename, xar_t xar) { 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"; @@ -6023,7 +6022,7 @@ static void DumpBitcodeSection(MachOObjectFile *O, const char *sect, 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"; diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 266b556360b..5b16abf25c6 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -191,7 +191,7 @@ cl::opt PrintFaultMaps("fault-map-section", cl::opt 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 PrintSource( "source", @@ -2085,7 +2085,6 @@ static void DumpObject(ObjectFile *o, const Archive *a = nullptr) { // Dump the complete DWARF structure. DIDumpOptions DumpOpts; DumpOpts.DumpType = DwarfDumpType; - DumpOpts.DumpEH = true; DICtx->dump(outs(), DumpOpts); } } diff --git a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp index 57a61f73d83..4786cc25420 100644 --- a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -1662,21 +1662,21 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) { 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) {