diff options
author | Zachary Turner <zturner@google.com> | 2017-06-23 23:08:57 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2017-06-23 23:08:57 +0000 |
commit | 554302ac5bcfd14c1d035771c1b0ee0982698274 (patch) | |
tree | 6335b900fd24c8ab1e12369c619e214d6d080410 | |
parent | 374592322d2a4930dc7c233de6522a520b8bebce (diff) | |
download | llvm-554302ac5bcfd14c1d035771c1b0ee0982698274.tar.gz |
[llvm-pdbutil] Dump raw bytes of module symbols and debug chunks.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306179 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h | 19 | ||||
-rw-r--r-- | lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp | 36 | ||||
-rw-r--r-- | test/DebugInfo/PDB/module-bytes.test | 73 | ||||
-rw-r--r-- | tools/llvm-pdbutil/BytesOutputStyle.cpp | 109 | ||||
-rw-r--r-- | tools/llvm-pdbutil/BytesOutputStyle.h | 4 | ||||
-rw-r--r-- | tools/llvm-pdbutil/llvm-pdbutil.cpp | 14 | ||||
-rw-r--r-- | tools/llvm-pdbutil/llvm-pdbutil.h | 5 |
7 files changed, 245 insertions, 15 deletions
diff --git a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h index c744696ae25..5565cd5582b 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -41,9 +41,12 @@ public: iterator_range<codeview::CVSymbolArray::Iterator> symbols(bool *HadError) const; - const codeview::CVSymbolArray &getSymbolArray() const { - return SymbolsSubstream; - } + const codeview::CVSymbolArray &getSymbolArray() const { return SymbolArray; } + + BinarySubstreamRef getSymbolsSubstream() const; + BinarySubstreamRef getC11LinesSubstream() const; + BinarySubstreamRef getC13LinesSubstream() const; + BinarySubstreamRef getGlobalRefsSubstream() const; ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default; @@ -63,10 +66,12 @@ private: std::shared_ptr<msf::MappedBlockStream> Stream; - codeview::CVSymbolArray SymbolsSubstream; - BinaryStreamRef C11LinesSubstream; - BinaryStreamRef C13LinesSubstream; - BinaryStreamRef GlobalRefsSubstream; + codeview::CVSymbolArray SymbolArray; + + BinarySubstreamRef SymbolsSubstream; + BinarySubstreamRef C11LinesSubstream; + BinarySubstreamRef C13LinesSubstream; + BinarySubstreamRef GlobalRefsSubstream; codeview::DebugSubsectionArray Subsections; }; diff --git a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp index 4186f2eb6ba..83c56574a16 100644 --- a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp +++ b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp @@ -47,15 +47,19 @@ Error ModuleDebugStreamRef::reload() { if (auto EC = Reader.readInteger(Signature)) return EC; - if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4)) + if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4)) return EC; - - if (auto EC = Reader.readStreamRef(C11LinesSubstream, C11Size)) + if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size)) + return EC; + if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size)) return EC; - if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size)) + + BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData); + if (auto EC = + SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining())) return EC; - BinaryStreamReader SubsectionsReader(C13LinesSubstream); + BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData); if (auto EC = SubsectionsReader.readArray(Subsections, SubsectionsReader.bytesRemaining())) return EC; @@ -63,7 +67,7 @@ Error ModuleDebugStreamRef::reload() { uint32_t GlobalRefsSize; if (auto EC = Reader.readInteger(GlobalRefsSize)) return EC; - if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize)) + if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize)) return EC; if (Reader.bytesRemaining() > 0) return make_error<RawError>(raw_error_code::corrupt_file, @@ -72,9 +76,25 @@ Error ModuleDebugStreamRef::reload() { return Error::success(); } +BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const { + return SymbolsSubstream; +} + +BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const { + return C11LinesSubstream; +} + +BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const { + return C13LinesSubstream; +} + +BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const { + return GlobalRefsSubstream; +} + iterator_range<codeview::CVSymbolArray::Iterator> ModuleDebugStreamRef::symbols(bool *HadError) const { - return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end()); + return make_range(SymbolArray.begin(HadError), SymbolArray.end()); } llvm::iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator> @@ -83,7 +103,7 @@ ModuleDebugStreamRef::subsections() const { } bool ModuleDebugStreamRef::hasDebugSubsections() const { - return C13LinesSubstream.getLength() > 0; + return !C13LinesSubstream.empty(); } Error ModuleDebugStreamRef::commit() { return Error::success(); } diff --git a/test/DebugInfo/PDB/module-bytes.test b/test/DebugInfo/PDB/module-bytes.test new file mode 100644 index 00000000000..164ed204ea9 --- /dev/null +++ b/test/DebugInfo/PDB/module-bytes.test @@ -0,0 +1,73 @@ +; RUN: llvm-pdbutil bytes -chunks %p/Inputs/empty.pdb | FileCheck --check-prefix=CHUNKS %s +; RUN: llvm-pdbutil bytes -chunks -mod=0 %p/Inputs/empty.pdb | FileCheck --check-prefix=FILTERED-CHUNKS %s + +; RUN: llvm-pdbutil bytes -syms %p/Inputs/empty.pdb | FileCheck --check-prefix=SYMS %s +; RUN: llvm-pdbutil bytes -syms -mod=0 %p/Inputs/empty.pdb | FileCheck --check-prefix=FILTERED-SYMS %s + +CHUNKS: Debug Chunks +CHUNKS-NEXT: ============================================================ +CHUNKS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`: +CHUNKS-NEXT: Debug Chunks ( +CHUNKS-NEXT: 60D0: F2000000 30000000 10000000 01000000 0A000000 00000000 03000000 24000000 |....0.......................$...| +CHUNKS-NEXT: 60F0: 00000000 05000080 03000000 06000080 08000000 07000080 F4000000 18000000 |................................| +CHUNKS-NEXT: 6110: 56000000 1001A0A5 BD0D3ECD 93FC29D1 9DE826FB F4BC0000 |V.........>...)...&.....| +CHUNKS-NEXT: ) +CHUNKS-NEXT: Mod 0001 | `* Linker *`: +CHUNKS-NEXT: Debug Chunks ( +CHUNKS-NEXT: ) + +FILTERED-CHUNKS: Debug Chunks +FILTERED-CHUNKS-NEXT: ============================================================ +FILTERED-CHUNKS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`: +FILTERED-CHUNKS-NEXT: Debug Chunks ( +FILTERED-CHUNKS-NEXT: 60D0: F2000000 30000000 10000000 01000000 0A000000 00000000 03000000 24000000 |....0.......................$...| +FILTERED-CHUNKS-NEXT: 60F0: 00000000 05000080 03000000 06000080 08000000 07000080 F4000000 18000000 |................................| +FILTERED-CHUNKS-NEXT: 6110: 56000000 1001A0A5 BD0D3ECD 93FC29D1 9DE826FB F4BC0000 |V.........>...)...&.....| +FILTERED-CHUNKS-NEXT: ) +FILTERED-CHUNKS-NOT: Mod 0001 + +SYMS: Module Symbols +SYMS-NEXT: ============================================================ +SYMS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`: +SYMS-NEXT: Symbols ( +SYMS-NEXT: 6004: 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |6.......d:\src\llvm\test\DebugIn| +SYMS-NEXT: 6024: 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 01200000 |fo\PDB\Inputs\empty.obj.:.<.. ..| +SYMS-NEXT: 6044: 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 28522920 |......}y......}y..Microsoft (R) | +SYMS-NEXT: 6064: 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 C4000000 |Optimizing Compiler.*...........| +SYMS-NEXT: 6084: 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D 61696E00 |...........................main.| +SYMS-NEXT: 60A4: 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 12000000 |................................| +SYMS-NEXT: 60C4: 02000600 06004C11 0E100000 |......L.....| +SYMS-NEXT: ) +SYMS-NEXT: Mod 0001 | `* Linker *`: +SYMS-NEXT: Symbols ( +SYMS-NEXT: 7004: 12000111 00000000 2A204C69 6E6B6572 202A0000 2E003C11 07000000 03000000 |........* Linker *....<.........| +SYMS-NEXT: 7024: 00000000 00000C00 00007D79 00004D69 63726F73 6F667420 28522920 4C494E4B |..........}y..Microsoft (R) LINK| +SYMS-NEXT: 7044: 00000000 AA003D11 00637764 00643A5C 7372635C 6C6C766D 5C746573 745C4465 |......=..cwd.d:\src\llvm\test\De| +SYMS-NEXT: 7064: 62756749 6E666F5C 5044425C 496E7075 74730065 78650043 3A5C5072 6F677261 |bugInfo\PDB\Inputs.exe.C:\Progra| +SYMS-NEXT: 7084: 6D204669 6C657320 28783836 295C4D69 63726F73 6F667420 56697375 616C2053 |m Files (x86)\Microsoft Visual S| +SYMS-NEXT: 70A4: 74756469 6F203132 2E305C56 435C4249 4E5C6C69 6E6B2E65 78650070 64620064 |tudio 12.0\VC\BIN\link.exe.pdb.d| +SYMS-NEXT: 70C4: 3A5C7372 635C6C6C 766D5C74 6573745C 44656275 67496E66 6F5C5044 425C496E |:\src\llvm\test\DebugInfo\PDB\In| +SYMS-NEXT: 70E4: 70757473 5C656D70 74792E70 64620000 12002C11 00000500 05000000 10000000 |puts\empty.pdb....,.............| +SYMS-NEXT: 7104: 01000100 1A003611 01000C00 00100000 1A100000 20000060 2E746578 74000000 |......6............. ..`.text...| +SYMS-NEXT: 7124: 1A003711 1A100000 20000060 00000000 01002E74 65787424 6D6E0000 1A003611 |..7..... ..`.......text$mn....6.| +SYMS-NEXT: 7144: 02000C00 00300000 B2020000 40000040 2E726461 74610000 1A003711 43010000 |.....0......@..@.rdata....7.C...| +SYMS-NEXT: 7164: 40000040 00000000 02002E72 64617461 00000000 1A003711 00000000 40000040 |@..@.......rdata......7.....@..@| +SYMS-NEXT: 7184: 43010000 02002E65 64617461 00000000 1E003711 6E010000 40000040 44010000 |C......edata......7.n...@..@D...| +SYMS-NEXT: 71A4: 02002E72 64617461 24646562 75670000 1A003611 03000C00 00400000 04000000 |...rdata$debug....6......@......| +SYMS-NEXT: 71C4: 400000C0 2E646174 61000000 16003711 04000000 800000C0 00000000 03002E62 |@....data.....7................b| +SYMS-NEXT: 71E4: 73730000 1A003611 04000C00 00500000 08000000 40000042 2E72656C 6F630000 |ss....6......P......@..B.reloc..| +SYMS-NEXT: ) + +FILTERED-SYMS: Module Symbols +FILTERED-SYMS-NEXT: ============================================================ +FILTERED-SYMS-NEXT: Mod 0000 | `d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj`: +FILTERED-SYMS-NEXT: Symbols ( +FILTERED-SYMS-NEXT: 6004: 36000111 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |6.......d:\src\llvm\test\DebugIn| +FILTERED-SYMS-NEXT: 6024: 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 3A003C11 01200000 |fo\PDB\Inputs\empty.obj.:.<.. ..| +FILTERED-SYMS-NEXT: 6044: 07001200 00007D79 00001200 00007D79 00004D69 63726F73 6F667420 28522920 |......}y......}y..Microsoft (R) | +FILTERED-SYMS-NEXT: 6064: 4F707469 6D697A69 6E672043 6F6D7069 6C657200 2A001011 00000000 C4000000 |Optimizing Compiler.*...........| +FILTERED-SYMS-NEXT: 6084: 00000000 0A000000 03000000 08000000 01100000 10000000 0100016D 61696E00 |...........................main.| +FILTERED-SYMS-NEXT: 60A4: 1E001210 00000000 00000000 00000000 00000000 00000000 00000082 12000000 |................................| +FILTERED-SYMS-NEXT: 60C4: 02000600 06004C11 0E100000 |......L.....| +FILTERED-SYMS-NEXT: ) +FILTERED-SYMS-NOT: Mod 0001 diff --git a/tools/llvm-pdbutil/BytesOutputStyle.cpp b/tools/llvm-pdbutil/BytesOutputStyle.cpp index 288bef72104..da29ac02063 100644 --- a/tools/llvm-pdbutil/BytesOutputStyle.cpp +++ b/tools/llvm-pdbutil/BytesOutputStyle.cpp @@ -9,6 +9,7 @@ #include "BytesOutputStyle.h" +#include "FormatUtil.h" #include "StreamUtil.h" #include "llvm-pdbutil.h" @@ -17,6 +18,7 @@ #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" @@ -168,6 +170,21 @@ Error BytesOutputStyle::dump() { P.NewLine(); } + if (opts::bytes::ModuleSyms) { + dumpModuleSyms(); + P.NewLine(); + } + + if (opts::bytes::ModuleC11) { + dumpModuleC11(); + P.NewLine(); + } + + if (opts::bytes::ModuleC13) { + dumpModuleC13(); + P.NewLine(); + } + return Error::success(); } @@ -297,6 +314,98 @@ void BytesOutputStyle::dumpTypeIndex(uint32_t StreamIdx, } } +template <typename CallbackT> +static void iterateOneModule(PDBFile &File, LinePrinter &P, + const DbiModuleList &Modules, uint32_t I, + uint32_t Digits, uint32_t IndentLevel, + CallbackT Callback) { + auto Modi = Modules.getModuleDescriptor(I); + P.formatLine("Mod {0:4} | `{1}`: ", + fmt_align(I, AlignStyle::Right, std::max(Digits, 4U)), + Modi.getModuleName()); + + uint16_t ModiStream = Modi.getModuleStreamIndex(); + + AutoIndent Indent2(P, IndentLevel); + auto ModStreamData = MappedBlockStream::createIndexedStream( + File.getMsfLayout(), File.getMsfBuffer(), ModiStream, + File.getAllocator()); + ModuleDebugStreamRef ModStream(Modi, std::move(ModStreamData)); + if (auto EC = ModStream.reload()) { + P.formatLine("Could not parse debug information."); + return; + } + auto Layout = File.getStreamLayout(ModiStream); + Callback(I, ModStream, Layout); +} + +template <typename CallbackT> +static void iterateModules(PDBFile &File, LinePrinter &P, uint32_t IndentLevel, + CallbackT Callback) { + AutoIndent Indent(P); + if (!File.hasPDBDbiStream()) { + P.formatLine("DBI Stream not present"); + return; + } + + ExitOnError Err("Unexpected error processing modules"); + + auto &Stream = Err(File.getPDBDbiStream()); + + const DbiModuleList &Modules = Stream.modules(); + + if (opts::bytes::ModuleIndex.getNumOccurrences() > 0) { + iterateOneModule(File, P, Modules, opts::bytes::ModuleIndex, 1, IndentLevel, + Callback); + } else { + uint32_t Count = Modules.getModuleCount(); + uint32_t Digits = NumDigits(Count); + for (uint32_t I = 0; I < Count; ++I) { + iterateOneModule(File, P, Modules, I, Digits, IndentLevel, Callback); + } + } +} + +void BytesOutputStyle::dumpModuleSyms() { + printHeader(P, "Module Symbols"); + + AutoIndent Indent(P); + + iterateModules(File, P, 2, + [this](uint32_t Modi, const ModuleDebugStreamRef &Stream, + const MSFStreamLayout &Layout) { + auto Symbols = Stream.getSymbolsSubstream(); + P.formatMsfStreamData("Symbols", File, Layout, Symbols); + }); +} + +void BytesOutputStyle::dumpModuleC11() { + printHeader(P, "C11 Debug Chunks"); + + AutoIndent Indent(P); + + iterateModules(File, P, 2, + [this](uint32_t Modi, const ModuleDebugStreamRef &Stream, + const MSFStreamLayout &Layout) { + auto Chunks = Stream.getC11LinesSubstream(); + P.formatMsfStreamData("C11 Debug Chunks", File, Layout, + Chunks); + }); +} + +void BytesOutputStyle::dumpModuleC13() { + printHeader(P, "Debug Chunks"); + + AutoIndent Indent(P); + + iterateModules(File, P, 2, + [this](uint32_t Modi, const ModuleDebugStreamRef &Stream, + const MSFStreamLayout &Layout) { + auto Chunks = Stream.getC13LinesSubstream(); + P.formatMsfStreamData("Debug Chunks", File, Layout, Chunks); + }); +} + void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) { printHeader(P, "MSF Bytes"); diff --git a/tools/llvm-pdbutil/BytesOutputStyle.h b/tools/llvm-pdbutil/BytesOutputStyle.h index af7e636c6b2..c162163fdd0 100644 --- a/tools/llvm-pdbutil/BytesOutputStyle.h +++ b/tools/llvm-pdbutil/BytesOutputStyle.h @@ -44,6 +44,10 @@ private: void dumpTypeServerMap(); void dumpECData(); + void dumpModuleSyms(); + void dumpModuleC11(); + void dumpModuleC13(); + void dumpTypeIndex(uint32_t StreamIdx, ArrayRef<uint32_t> Indices); Expected<codeview::LazyRandomTypeCollection &> diff --git a/tools/llvm-pdbutil/llvm-pdbutil.cpp b/tools/llvm-pdbutil/llvm-pdbutil.cpp index 0586b6b5c4a..cb064c70f15 100644 --- a/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -271,6 +271,7 @@ cl::OptionCategory MsfBytes("MSF File Options"); cl::OptionCategory DbiBytes("Dbi Stream Options"); cl::OptionCategory PdbBytes("PDB Stream Options"); cl::OptionCategory Types("Type Options"); +cl::OptionCategory ModuleCategory("Module Options"); llvm::Optional<NumberRange> DumpBlockRange; llvm::Optional<NumberRange> DumpByteRange; @@ -317,6 +318,19 @@ cl::list<uint32_t> cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand), cl::cat(TypeCategory)); +cl::opt<uint32_t> ModuleIndex( + "mod", + cl::desc( + "Limit options in the Modules category to the specified module index"), + cl::Optional, cl::sub(BytesSubcommand), cl::cat(ModuleCategory)); +cl::opt<bool> ModuleSyms("syms", cl::desc("Dump symbol record substream"), + cl::sub(BytesSubcommand), cl::cat(ModuleCategory)); +cl::opt<bool> ModuleC11("c11-chunks", cl::Hidden, + cl::desc("Dump C11 CodeView debug chunks"), + cl::sub(BytesSubcommand), cl::cat(ModuleCategory)); +cl::opt<bool> ModuleC13("chunks", cl::desc("Dump C13 CodeView debug chunks"), + cl::sub(BytesSubcommand), cl::cat(ModuleCategory)); + cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input PDB files>"), cl::OneOrMore, cl::sub(BytesSubcommand)); diff --git a/tools/llvm-pdbutil/llvm-pdbutil.h b/tools/llvm-pdbutil/llvm-pdbutil.h index 67baf24c58d..ea62f18e2e1 100644 --- a/tools/llvm-pdbutil/llvm-pdbutil.h +++ b/tools/llvm-pdbutil/llvm-pdbutil.h @@ -113,6 +113,11 @@ extern llvm::cl::opt<bool> ECData; extern llvm::cl::list<uint32_t> TypeIndex; extern llvm::cl::list<uint32_t> IdIndex; +extern llvm::cl::opt<uint32_t> ModuleIndex; +extern llvm::cl::opt<bool> ModuleSyms; +extern llvm::cl::opt<bool> ModuleC11; +extern llvm::cl::opt<bool> ModuleC13; + } // namespace bytes namespace dump { |