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:
parent
e5d95e4259
commit
158da0d39f
@ -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")
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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() {}
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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";
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user