From dd7396825626c1f0331887821d5bcabbf8b7c3ff Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 23 Jun 2017 21:11:54 +0000 Subject: [PATCH] [llvm-pdbutil] Dump raw bytes of various DBI stream subsections. llvm-svn: 306160 --- .../llvm/DebugInfo/PDB/Native/DbiStream.h | 17 +++- llvm/include/llvm/Support/BinaryStreamRef.h | 3 + llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp | 52 +++++++--- llvm/test/DebugInfo/PDB/dbi-bytes.test | 59 +++++++++++ llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp | 98 +++++++++++++++++++ llvm/tools/llvm-pdbutil/BytesOutputStyle.h | 7 ++ llvm/tools/llvm-pdbutil/LinePrinter.cpp | 7 +- llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp | 25 ++++- llvm/tools/llvm-pdbutil/llvm-pdbutil.h | 8 ++ 9 files changed, 249 insertions(+), 27 deletions(-) create mode 100644 llvm/test/DebugInfo/PDB/dbi-bytes.test diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 7123e88cd642..3bf790726656 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -63,6 +63,13 @@ public: PDB_Machine getMachineType() const; + BinarySubstreamRef getSectionContributionData() const; + BinarySubstreamRef getSecMapSubstreamData() const; + BinarySubstreamRef getModiSubstreamData() const; + BinarySubstreamRef getFileInfoSubstreamData() const; + BinarySubstreamRef getTypeServerMapSubstreamData() const; + BinarySubstreamRef getECSubstreamData() const; + /// If the given stream type is present, returns its stream index. If it is /// not present, returns InvalidStreamIndex. uint32_t getDebugStreamIndex(DbgHeaderType Type) const; @@ -87,10 +94,12 @@ private: PDBStringTable ECNames; - BinaryStreamRef SecContrSubstream; - BinaryStreamRef SecMapSubstream; - BinaryStreamRef TypeServerMapSubstream; - BinaryStreamRef ECSubstream; + BinarySubstreamRef SecContrSubstream; + BinarySubstreamRef SecMapSubstream; + BinarySubstreamRef ModiSubstream; + BinarySubstreamRef FileInfoSubstream; + BinarySubstreamRef TypeServerMapSubstream; + BinarySubstreamRef ECSubstream; DbiModuleList Modules; diff --git a/llvm/include/llvm/Support/BinaryStreamRef.h b/llvm/include/llvm/Support/BinaryStreamRef.h index e57783d82c87..f288a2cb70be 100644 --- a/llvm/include/llvm/Support/BinaryStreamRef.h +++ b/llvm/include/llvm/Support/BinaryStreamRef.h @@ -169,6 +169,9 @@ public: struct BinarySubstreamRef { uint32_t Offset; // Offset in the parent stream BinaryStreamRef StreamData; // Stream Data + + uint32_t size() const { return StreamData.getLength(); } + bool empty() const { return size() == 0; } }; class WritableBinaryStreamRef diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp index 24322d942fac..a1f0671dec3e 100644 --- a/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -99,29 +99,27 @@ Error DbiStream::reload() { return make_error(raw_error_code::corrupt_file, "DBI type server substream not aligned."); - BinaryStreamRef ModInfoSubstream; - BinaryStreamRef FileInfoSubstream; - if (auto EC = - Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize)) + if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize)) return EC; - if (auto EC = Reader.readStreamRef(SecContrSubstream, + if (auto EC = Reader.readSubstream(SecContrSubstream, Header->SecContrSubstreamSize)) return EC; - if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize)) + if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize)) return EC; - if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize)) + if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize)) return EC; if (auto EC = - Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize)) + Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize)) return EC; - if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize)) + if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize)) return EC; if (auto EC = Reader.readArray( DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t))) return EC; - if (auto EC = Modules.initialize(ModInfoSubstream, FileInfoSubstream)) + if (auto EC = Modules.initialize(ModiSubstream.StreamData, + FileInfoSubstream.StreamData)) return EC; if (auto EC = initializeSectionContributionData()) @@ -137,8 +135,8 @@ Error DbiStream::reload() { return make_error(raw_error_code::corrupt_file, "Found unexpected bytes in DBI Stream."); - if (ECSubstream.getLength() > 0) { - BinaryStreamReader ECReader(ECSubstream); + if (!ECSubstream.empty()) { + BinaryStreamReader ECReader(ECSubstream.StreamData); if (auto EC = ECNames.reload(ECReader)) return EC; } @@ -228,10 +226,10 @@ void DbiStream::visitSectionContributions( } Error DbiStream::initializeSectionContributionData() { - if (SecContrSubstream.getLength() == 0) + if (SecContrSubstream.empty()) return Error::success(); - BinaryStreamReader SCReader(SecContrSubstream); + BinaryStreamReader SCReader(SecContrSubstream.StreamData); if (auto EC = SCReader.readEnum(SectionContribVersion)) return EC; @@ -302,11 +300,33 @@ Error DbiStream::initializeFpoRecords() { return Error::success(); } +BinarySubstreamRef DbiStream::getSectionContributionData() const { + return SecContrSubstream; +} + +BinarySubstreamRef DbiStream::getSecMapSubstreamData() const { + return SecMapSubstream; +} + +BinarySubstreamRef DbiStream::getModiSubstreamData() const { + return ModiSubstream; +} + +BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const { + return FileInfoSubstream; +} + +BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const { + return TypeServerMapSubstream; +} + +BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; } + Error DbiStream::initializeSectionMapData() { - if (SecMapSubstream.getLength() == 0) + if (SecMapSubstream.empty()) return Error::success(); - BinaryStreamReader SMReader(SecMapSubstream); + BinaryStreamReader SMReader(SecMapSubstream.StreamData); const SecMapHeader *Header; if (auto EC = SMReader.readObject(Header)) return EC; diff --git a/llvm/test/DebugInfo/PDB/dbi-bytes.test b/llvm/test/DebugInfo/PDB/dbi-bytes.test new file mode 100644 index 000000000000..3ed913e880ee --- /dev/null +++ b/llvm/test/DebugInfo/PDB/dbi-bytes.test @@ -0,0 +1,59 @@ +; RUN: llvm-pdbutil bytes -ec %p/Inputs/empty.pdb | FileCheck --check-prefix=EC %s +; RUN: llvm-pdbutil bytes -files %p/Inputs/empty.pdb | FileCheck --check-prefix=FILES %s +; RUN: llvm-pdbutil bytes -modi %p/Inputs/empty.pdb | FileCheck --check-prefix=MODI %s +; RUN: llvm-pdbutil bytes -sc %p/Inputs/empty.pdb | FileCheck --check-prefix=SC %s +; RUN: llvm-pdbutil bytes -sm %p/Inputs/empty.pdb | FileCheck --check-prefix=SM %s +; RUN: llvm-pdbutil bytes -type-server %p/Inputs/empty.pdb | FileCheck --check-prefix=TYPE-SERVER %s + +EC: Edit and Continue Data +EC-NEXT: ============================================================ +EC-NEXT: Edit and Continue Data ( +EC-NEXT: E280: FEEFFEEF 01000000 31000000 00643A5C 7372635C 6C6C766D 5C746573 745C4465 |........1....d:\src\llvm\test\De| +EC-NEXT: E2A0: 62756749 6E666F5C 5044425C 496E7075 74735C65 6D707479 2E706462 00020000 |bugInfo\PDB\Inputs\empty.pdb....| +EC-NEXT: E2C0: 00010000 00000000 00010000 00 |.............| +EC-NEXT: ) + +FILES: File Info +FILES-NEXT: ============================================================ +FILES-NEXT: File Info ( +FILES-NEXT: E240: 02000100 00000100 01000000 00000000 643A5C73 72635C6C 6C766D5C 74657374 |................d:\src\llvm\test| +FILES-NEXT: E260: 5C646562 7567696E 666F5C70 64625C69 6E707574 735C656D 7074792E 63707000 |\debuginfo\pdb\inputs\empty.cpp.| +FILES-NEXT: ) + +MODI: Module Infos +MODI-NEXT: ============================================================ +MODI-NEXT: Module Infos ( +MODI-NEXT: E040: 00000000 01000000 10000000 0A000000 20005060 00000000 347497D7 00000000 |................ .P`....4t......| +MODI-NEXT: E060: 00000C00 D0000000 00000000 58000000 01000000 D035E900 00000000 00000000 |............X........5..........| +MODI-NEXT: E080: 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E 666F5C50 44425C49 |d:\src\llvm\test\DebugInfo\PDB\I| +MODI-NEXT: E0A0: 6E707574 735C656D 7074792E 6F626A00 643A5C73 72635C6C 6C766D5C 74657374 |nputs\empty.obj.d:\src\llvm\test| +MODI-NEXT: E0C0: 5C446562 7567496E 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 |\DebugInfo\PDB\Inputs\empty.obj.| +MODI-NEXT: E0E0: 00000000 01000000 00000000 0A000000 20000060 01000000 00000000 00000000 |................ ..`............| +MODI-NEXT: E100: 00000E00 04020000 00000000 00000000 00000000 00000000 00000000 01000000 |................................| +MODI-NEXT: E120: 2A204C69 6E6B6572 202A0000 |* Linker *..| +MODI-NEXT: ) + +SC: Section Contributions +SC-NEXT: ============================================================ +SC-NEXT: Section Contributions ( +SC-NEXT: E12C: 2DBA2EF1 01002511 00000000 0A000000 20000060 01000000 00000000 00000000 |-.....%......... ..`............| +SC-NEXT: E14C: 01000000 10000000 0A000000 20005060 00000000 347497D7 00000000 02000000 |............ .P`....4t..........| +SC-NEXT: E16C: 00000000 38000000 40000040 01000000 00000000 00000000 02000000 44010000 |....8...@..@................D...| +SC-NEXT: E18C: 48000000 40003040 01000000 00000000 00000000 02000000 8C010000 14000000 |H...@.0@........................| +SC-NEXT: E1AC: 40003040 01000000 00000000 00000000 03000000 00000000 04000000 800030C0 |@.0@..........................0.| +SC-NEXT: E1CC: 00000000 00000000 00000000 |............| +SC-NEXT: ) + +SM: Section Map +SM-NEXT: ============================================================ +SM-NEXT: Section Map ( +SM-NEXT: E1D8: 05000500 0D010000 00000100 FFFFFFFF 00000000 1A100000 09010000 00000200 |................................| +SM-NEXT: E1F8: FFFFFFFF 00000000 B2020000 0B010000 00000300 FFFFFFFF 00000000 04000000 |................................| +SM-NEXT: E218: 09010000 00000400 FFFFFFFF 00000000 08000000 08020000 00000000 FFFFFFFF |................................| +SM-NEXT: E238: 00000000 FFFFFFFF |........| +SM-NEXT: ) + +TYPE-SERVER: Type Server Map +TYPE-SERVER-NEXT: ============================================================ +TYPE-SERVER-NEXT: Type Server Map ( +TYPE-SERVER-NEXT: ) diff --git a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp index 5cf15685fe32..166136affed1 100644 --- a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp @@ -13,6 +13,7 @@ #include "llvm-pdbutil.h" #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/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" @@ -122,6 +123,37 @@ Error BytesOutputStyle::dump() { dumpNameMap(); P.NewLine(); } + + if (opts::bytes::SectionContributions) { + dumpSectionContributions(); + P.NewLine(); + } + + if (opts::bytes::SectionMap) { + dumpSectionMap(); + P.NewLine(); + } + + if (opts::bytes::ModuleInfos) { + dumpModuleInfos(); + P.NewLine(); + } + + if (opts::bytes::FileInfo) { + dumpFileInfo(); + P.NewLine(); + } + + if (opts::bytes::TypeServerMap) { + dumpTypeServerMap(); + P.NewLine(); + } + + if (opts::bytes::ECData) { + dumpECData(); + P.NewLine(); + } + return Error::success(); } @@ -155,6 +187,72 @@ void BytesOutputStyle::dumpBlockRanges(uint32_t Min, uint32_t Max) { } } +void BytesOutputStyle::dumpSectionContributions() { + printHeader(P, "Section Contributions"); + + AutoIndent Indent(P); + + auto &DbiS = Err(File.getPDBDbiStream()); + BinarySubstreamRef NS = DbiS.getSectionContributionData(); + auto Layout = File.getStreamLayout(StreamDBI); + P.formatMsfStreamData("Section Contributions", File, Layout, NS); +} + +void BytesOutputStyle::dumpSectionMap() { + printHeader(P, "Section Map"); + + AutoIndent Indent(P); + + auto &DbiS = Err(File.getPDBDbiStream()); + BinarySubstreamRef NS = DbiS.getSecMapSubstreamData(); + auto Layout = File.getStreamLayout(StreamDBI); + P.formatMsfStreamData("Section Map", File, Layout, NS); +} + +void BytesOutputStyle::dumpModuleInfos() { + printHeader(P, "Module Infos"); + + AutoIndent Indent(P); + + auto &DbiS = Err(File.getPDBDbiStream()); + BinarySubstreamRef NS = DbiS.getModiSubstreamData(); + auto Layout = File.getStreamLayout(StreamDBI); + P.formatMsfStreamData("Module Infos", File, Layout, NS); +} + +void BytesOutputStyle::dumpFileInfo() { + printHeader(P, "File Info"); + + AutoIndent Indent(P); + + auto &DbiS = Err(File.getPDBDbiStream()); + BinarySubstreamRef NS = DbiS.getFileInfoSubstreamData(); + auto Layout = File.getStreamLayout(StreamDBI); + P.formatMsfStreamData("File Info", File, Layout, NS); +} + +void BytesOutputStyle::dumpTypeServerMap() { + printHeader(P, "Type Server Map"); + + AutoIndent Indent(P); + + auto &DbiS = Err(File.getPDBDbiStream()); + BinarySubstreamRef NS = DbiS.getTypeServerMapSubstreamData(); + auto Layout = File.getStreamLayout(StreamDBI); + P.formatMsfStreamData("Type Server Map", File, Layout, NS); +} + +void BytesOutputStyle::dumpECData() { + printHeader(P, "Edit and Continue Data"); + + AutoIndent Indent(P); + + auto &DbiS = Err(File.getPDBDbiStream()); + BinarySubstreamRef NS = DbiS.getECSubstreamData(); + auto Layout = File.getStreamLayout(StreamDBI); + P.formatMsfStreamData("Edit and Continue Data", File, Layout, NS); +} + void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) { printHeader(P, "MSF Bytes"); diff --git a/llvm/tools/llvm-pdbutil/BytesOutputStyle.h b/llvm/tools/llvm-pdbutil/BytesOutputStyle.h index 4cf6937d99b1..0895ee6532a0 100644 --- a/llvm/tools/llvm-pdbutil/BytesOutputStyle.h +++ b/llvm/tools/llvm-pdbutil/BytesOutputStyle.h @@ -33,6 +33,13 @@ private: void dumpByteRanges(uint32_t Min, uint32_t Max); void dumpStreamBytes(); + void dumpSectionContributions(); + void dumpSectionMap(); + void dumpModuleInfos(); + void dumpFileInfo(); + void dumpTypeServerMap(); + void dumpECData(); + PDBFile &File; LinePrinter P; ExitOnError Err; diff --git a/llvm/tools/llvm-pdbutil/LinePrinter.cpp b/llvm/tools/llvm-pdbutil/LinePrinter.cpp index a9761b4337b8..6e4d95af944a 100644 --- a/llvm/tools/llvm-pdbutil/LinePrinter.cpp +++ b/llvm/tools/llvm-pdbutil/LinePrinter.cpp @@ -146,18 +146,19 @@ static std::vector computeBlockRuns(uint32_t BlockSize, ArrayRef Blocks = Layout.Blocks; assert(!Blocks.empty()); uint32_t StreamBytesRemaining = Layout.Length; - Runs.emplace_back(Blocks[0]); + uint32_t CurrentBlock = Blocks[0]; + Runs.emplace_back(CurrentBlock); while (!Blocks.empty()) { Run *CurrentRun = &Runs.back(); uint32_t NextBlock = Blocks.front(); - if (NextBlock < CurrentRun->Block || (NextBlock - CurrentRun->Block > 1)) { + if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) { Runs.emplace_back(NextBlock); CurrentRun = &Runs.back(); } - uint32_t Used = std::min(BlockSize, StreamBytesRemaining); CurrentRun->ByteLen += Used; StreamBytesRemaining -= Used; + CurrentBlock = NextBlock; Blocks = Blocks.drop_front(); } return Runs; diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp index e1eb1b487b6c..48dabc8a57af 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -267,27 +267,44 @@ cl::list InputFilenames(cl::Positional, cl::OptionCategory FileOptions("Module & File Options"); namespace bytes { +cl::OptionCategory MsfBytes("MSF File Options"); +cl::OptionCategory DbiBytes("Dbi Stream Options"); +cl::OptionCategory PdbBytes("PDB Stream Options"); + llvm::Optional DumpBlockRange; llvm::Optional DumpByteRange; cl::opt DumpBlockRangeOpt( "block-range", cl::value_desc("start[-end]"), cl::desc("Dump binary data from specified range of blocks."), - cl::sub(BytesSubcommand)); + cl::sub(BytesSubcommand), cl::cat(MsfBytes)); cl::opt DumpByteRangeOpt("byte-range", cl::value_desc("start[-end]"), cl::desc("Dump binary data from specified range of bytes"), - cl::sub(BytesSubcommand)); + cl::sub(BytesSubcommand), cl::cat(MsfBytes)); cl::list DumpStreamData("stream-data", cl::CommaSeparated, cl::ZeroOrMore, cl::desc("Dump binary data from specified streams. Format " "is SN[:Start][@Size]"), - cl::sub(BytesSubcommand)); + cl::sub(BytesSubcommand), cl::cat(MsfBytes)); cl::opt NameMap("name-map", cl::desc("Dump bytes of PDB Name Map"), - cl::sub(BytesSubcommand)); + cl::sub(BytesSubcommand), cl::cat(PdbBytes)); + +cl::opt SectionContributions("sc", cl::desc("Dump section contributions"), + cl::sub(BytesSubcommand), cl::cat(DbiBytes)); +cl::opt SectionMap("sm", cl::desc("Dump section map"), + cl::sub(BytesSubcommand), cl::cat(DbiBytes)); +cl::opt ModuleInfos("modi", cl::desc("Dump module info"), + cl::sub(BytesSubcommand), cl::cat(DbiBytes)); +cl::opt FileInfo("files", cl::desc("Dump source file info"), + cl::sub(BytesSubcommand), cl::cat(DbiBytes)); +cl::opt TypeServerMap("type-server", cl::desc("Dump type server map"), + cl::sub(BytesSubcommand), cl::cat(DbiBytes)); +cl::opt ECData("ec", cl::desc("Dump edit and continue map"), + cl::sub(BytesSubcommand), cl::cat(DbiBytes)); cl::list InputFilenames(cl::Positional, cl::desc(""), diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h index 882104c1d0b9..b7fedd3ae439 100644 --- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h +++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h @@ -102,6 +102,14 @@ extern llvm::Optional DumpBlockRange; extern llvm::Optional DumpByteRange; extern llvm::cl::list DumpStreamData; extern llvm::cl::opt NameMap; + +extern llvm::cl::opt SectionContributions; +extern llvm::cl::opt SectionMap; +extern llvm::cl::opt ModuleInfos; +extern llvm::cl::opt FileInfo; +extern llvm::cl::opt TypeServerMap; +extern llvm::cl::opt ECData; + } // namespace bytes namespace dump {