From: Eli Bendersky Date: Fri, 25 Jan 2013 20:26:43 +0000 (+0000) Subject: Add command-line flags for DWARF dumping. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=939a4e8b693820d161f362317f7dba9057e66cc7;p=oota-llvm.git Add command-line flags for DWARF dumping. Flags for dumping specific DWARF sections added in lib/DebugInfo and llvm-dwarfdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173480 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 5ebf4b09399..5cb1a17432d 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -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; diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index 13a527b7f80..39953499ce6 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -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); + } + } + } + + 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_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_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); + } + + if (DumpType == DIDT_All || DumpType == DIDT_AbbrevDwo) { + OS << "\n.debug_abbrev.dwo contents:\n"; + getDebugAbbrevDWO()->dump(OS); } - 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_InfoDwo) { + OS << "\n.debug_info.dwo contents:\n"; + for (unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i) + getDWOCompileUnitAtIndex(i)->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_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)); + } } } diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h index 7da5c85cd3b..8a4a3afec35 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -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() { diff --git a/test/DebugInfo/dwarfdump-dump-flags.test b/test/DebugInfo/dwarfdump-dump-flags.test new file mode 100644 index 00000000000..92b2d50f393 --- /dev/null +++ b/test/DebugInfo/dwarfdump-dump-flags.test @@ -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 + diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index ccaf466b3f0..06875005837 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -52,6 +52,23 @@ static cl::opt PrintInlining("inlining", cl::init(false), cl::desc("Print all inlined frames for a given address")); +static cl::opt +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() : "") @@ -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 |