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(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")
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<DWARFCompileUnit>::iterator_range;
|
||||
using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
|
||||
|
@ -222,7 +222,6 @@ void DWARFContext::dump(
|
||||
|
||||
Optional<uint64_t> DumpOffset;
|
||||
uint64_t DumpType = DumpOpts.DumpType;
|
||||
bool DumpEH = DumpOpts.DumpEH;
|
||||
unsigned RecDepth =
|
||||
DumpOpts.ShowChildren ? std::numeric_limits<unsigned>::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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -122,6 +122,8 @@ static std::array<llvm::Optional<uint64_t>, (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<bool> 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
|
||||
|
@ -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";
|
||||
|
@ -191,7 +191,7 @@ cl::opt<bool> PrintFaultMaps("fault-map-section",
|
||||
|
||||
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",
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user