forked from OSchip/llvm-project
Add command-line flags for DWARF dumping.
Flags for dumping specific DWARF sections added in lib/DebugInfo and llvm-dwarfdump. llvm-svn: 173480
This commit is contained in:
parent
a19fa86a70
commit
7a94daa170
|
@ -92,6 +92,22 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// Selects which debug sections get dumped.
|
||||
enum DIDumpType {
|
||||
DIDT_Null,
|
||||
DIDT_All,
|
||||
DIDT_Abbrev,
|
||||
DIDT_AbbrevDwo,
|
||||
DIDT_Aranges,
|
||||
DIDT_Info,
|
||||
DIDT_InfoDwo,
|
||||
DIDT_Line,
|
||||
DIDT_Ranges,
|
||||
DIDT_Str,
|
||||
DIDT_StrDwo,
|
||||
DIDT_StrOffsetsDwo
|
||||
};
|
||||
|
||||
// In place of applying the relocations to the data we've read from disk we use
|
||||
// a separate mapping table to the side and checking that at locations in the
|
||||
// dwarf where we expect relocated values. This adds a bit of complexity to the
|
||||
|
@ -106,7 +122,7 @@ public:
|
|||
/// getDWARFContext - get a context for binary DWARF data.
|
||||
static DIContext *getDWARFContext(object::ObjectFile *);
|
||||
|
||||
virtual void dump(raw_ostream &OS) = 0;
|
||||
virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
|
||||
|
||||
virtual DILineInfo getLineInfoForAddress(uint64_t Address,
|
||||
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
|
||||
|
|
|
@ -19,80 +19,100 @@ using namespace dwarf;
|
|||
|
||||
typedef DWARFDebugLine::LineTable DWARFLineTable;
|
||||
|
||||
void DWARFContext::dump(raw_ostream &OS) {
|
||||
OS << ".debug_abbrev contents:\n";
|
||||
getDebugAbbrev()->dump(OS);
|
||||
void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Abbrev) {
|
||||
OS << ".debug_abbrev contents:\n";
|
||||
getDebugAbbrev()->dump(OS);
|
||||
}
|
||||
|
||||
OS << "\n.debug_info contents:\n";
|
||||
for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
|
||||
getCompileUnitAtIndex(i)->dump(OS);
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Info) {
|
||||
OS << "\n.debug_info contents:\n";
|
||||
for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
|
||||
getCompileUnitAtIndex(i)->dump(OS);
|
||||
}
|
||||
|
||||
OS << "\n.debug_aranges contents:\n";
|
||||
DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
|
||||
uint32_t offset = 0;
|
||||
DWARFDebugArangeSet set;
|
||||
while (set.extract(arangesData, &offset))
|
||||
set.dump(OS);
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
|
||||
OS << "\n.debug_aranges contents:\n";
|
||||
DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
|
||||
DWARFDebugArangeSet set;
|
||||
while (set.extract(arangesData, &offset))
|
||||
set.dump(OS);
|
||||
}
|
||||
|
||||
uint8_t savedAddressByteSize = 0;
|
||||
OS << "\n.debug_line contents:\n";
|
||||
for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
|
||||
DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
|
||||
savedAddressByteSize = cu->getAddressByteSize();
|
||||
unsigned stmtOffset =
|
||||
cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
|
||||
-1U);
|
||||
if (stmtOffset != -1U) {
|
||||
DataExtractor lineData(getLineSection(), isLittleEndian(),
|
||||
savedAddressByteSize);
|
||||
DWARFDebugLine::DumpingState state(OS);
|
||||
DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Line) {
|
||||
OS << "\n.debug_line contents:\n";
|
||||
for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
|
||||
DWARFCompileUnit *cu = getCompileUnitAtIndex(i);
|
||||
savedAddressByteSize = cu->getAddressByteSize();
|
||||
unsigned stmtOffset =
|
||||
cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
|
||||
-1U);
|
||||
if (stmtOffset != -1U) {
|
||||
DataExtractor lineData(getLineSection(), isLittleEndian(),
|
||||
savedAddressByteSize);
|
||||
DWARFDebugLine::DumpingState state(OS);
|
||||
DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OS << "\n.debug_str contents:\n";
|
||||
DataExtractor strData(getStringSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
uint32_t strOffset = 0;
|
||||
while (const char *s = strData.getCStr(&offset)) {
|
||||
OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
|
||||
strOffset = offset;
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Str) {
|
||||
OS << "\n.debug_str contents:\n";
|
||||
DataExtractor strData(getStringSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
uint32_t strOffset = 0;
|
||||
while (const char *s = strData.getCStr(&offset)) {
|
||||
OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
|
||||
strOffset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
OS << "\n.debug_ranges contents:\n";
|
||||
// In fact, different compile units may have different address byte
|
||||
// sizes, but for simplicity we just use the address byte size of the last
|
||||
// compile unit (there is no easy and fast way to associate address range
|
||||
// list and the compile unit it describes).
|
||||
DataExtractor rangesData(getRangeSection(), isLittleEndian(),
|
||||
savedAddressByteSize);
|
||||
offset = 0;
|
||||
DWARFDebugRangeList rangeList;
|
||||
while (rangeList.extract(rangesData, &offset))
|
||||
rangeList.dump(OS);
|
||||
|
||||
OS << "\n.debug_abbrev.dwo contents:\n";
|
||||
getDebugAbbrevDWO()->dump(OS);
|
||||
|
||||
OS << "\n.debug_info.dwo contents:\n";
|
||||
for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
|
||||
getDWOCompileUnitAtIndex(i)->dump(OS);
|
||||
|
||||
OS << "\n.debug_str.dwo contents:\n";
|
||||
DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
uint32_t strDWOOffset = 0;
|
||||
while (const char *s = strDWOData.getCStr(&offset)) {
|
||||
OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
|
||||
strDWOOffset = offset;
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_Ranges) {
|
||||
OS << "\n.debug_ranges contents:\n";
|
||||
// In fact, different compile units may have different address byte
|
||||
// sizes, but for simplicity we just use the address byte size of the last
|
||||
// compile unit (there is no easy and fast way to associate address range
|
||||
// list and the compile unit it describes).
|
||||
DataExtractor rangesData(getRangeSection(), isLittleEndian(),
|
||||
savedAddressByteSize);
|
||||
offset = 0;
|
||||
DWARFDebugRangeList rangeList;
|
||||
while (rangeList.extract(rangesData, &offset))
|
||||
rangeList.dump(OS);
|
||||
}
|
||||
|
||||
OS << "\n.debug_str_offsets.dwo contents:\n";
|
||||
DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
while (offset < getStringOffsetDWOSection().size()) {
|
||||
OS << format("0x%8.8x: ", offset);
|
||||
OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) {
|
||||
OS << "\n.debug_abbrev.dwo contents:\n";
|
||||
getDebugAbbrevDWO()->dump(OS);
|
||||
}
|
||||
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_InfoDwo) {
|
||||
OS << "\n.debug_info.dwo contents:\n";
|
||||
for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
|
||||
getDWOCompileUnitAtIndex(i)->dump(OS);
|
||||
}
|
||||
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_StrDwo) {
|
||||
OS << "\n.debug_str.dwo contents:\n";
|
||||
DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
uint32_t strDWOOffset = 0;
|
||||
while (const char *s = strDWOData.getCStr(&offset)) {
|
||||
OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
|
||||
strDWOOffset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
|
||||
OS << "\n.debug_str_offsets.dwo contents:\n";
|
||||
DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
|
||||
offset = 0;
|
||||
while (offset < getStringOffsetDWOSection().size()) {
|
||||
OS << format("0x%8.8x: ", offset);
|
||||
OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class DWARFContext : public DIContext {
|
|||
|
||||
public:
|
||||
DWARFContext() {}
|
||||
virtual void dump(raw_ostream &OS);
|
||||
virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All);
|
||||
|
||||
/// Get the number of compile units in this context.
|
||||
unsigned getNumCompileUnits() {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test.elf-x86-64 -debug-dump=all | FileCheck %s -check-prefix DUMP_ALL
|
||||
; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test.elf-x86-64 -debug-dump=info | FileCheck %s -check-prefix DUMP_INFO
|
||||
; RUN: llvm-dwarfdump %p/Inputs/dwarfdump-test.elf-x86-64 -debug-dump=ranges | FileCheck %s -check-prefix DUMP_RANGES
|
||||
|
||||
; DUMP_ALL: .debug_info
|
||||
; DUMP_ALL: .debug_ranges
|
||||
|
||||
; DUMP_INFO: .debug_info
|
||||
; DUMP_INFO-NOT: .debug_ranges
|
||||
|
||||
; DUMP_RANGES-NOT: .debug_info
|
||||
; DUMP_RANGES: .debug_ranges
|
||||
|
|
@ -52,6 +52,23 @@ static cl::opt<bool>
|
|||
PrintInlining("inlining", cl::init(false),
|
||||
cl::desc("Print all inlined frames for a given address"));
|
||||
|
||||
static cl::opt<DIDumpType>
|
||||
DumpType("debug-dump", cl::init(DIDT_All),
|
||||
cl::desc("Dump of debug sections:"),
|
||||
cl::values(
|
||||
clEnumValN(DIDT_All, "all", "Dump all debug sections"),
|
||||
clEnumValN(DIDT_Abbrev, "abbrev", ".debug_abbrev"),
|
||||
clEnumValN(DIDT_AbbrevDwo, "abbrev.dwo", ".debug_abbrev.dwo"),
|
||||
clEnumValN(DIDT_Aranges, "aranges", ".debug_aranges"),
|
||||
clEnumValN(DIDT_Info, "info", ".debug_info"),
|
||||
clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
|
||||
clEnumValN(DIDT_Line, "line", ".debug_line"),
|
||||
clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"),
|
||||
clEnumValN(DIDT_Str, "str", ".debug_str"),
|
||||
clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
|
||||
clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"),
|
||||
clEnumValEnd));
|
||||
|
||||
static void PrintDILineInfo(DILineInfo dli) {
|
||||
if (PrintFunctions)
|
||||
outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
|
||||
|
@ -75,7 +92,7 @@ static void DumpInput(const StringRef &Filename) {
|
|||
outs() << Filename
|
||||
<< ":\tfile format " << Obj->getFileFormatName() << "\n\n";
|
||||
// Dump the complete DWARF structure.
|
||||
DICtx->dump(outs());
|
||||
DICtx->dump(outs(), DumpType);
|
||||
} else {
|
||||
// Print line info for the specified address.
|
||||
int SpecFlags = DILineInfoSpecifier::FileLineInfo |
|
||||
|
|
Loading…
Reference in New Issue