From 36efbfa6d81b3d15144bb2d5683f654a6b4246d4 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 9 Sep 2016 19:00:49 +0000 Subject: [PATCH] [pdb] Print out some more info when dumping a raw stream. We have various command line options that print the type of a stream, the size of a stream, etc but nowhere that it can all be viewed together. Since a previous patch introduced the ability to dump the bytes of a stream, this seems like a good place to present a full view of the stream's properties including its size, what kind of data it represents, and the blocks it occupies. So I added the ability to print that information to the -stream-data command line option. llvm-svn: 281077 --- llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp | 4 ++ .../DebugInfo/PDB/pdbdump-raw-stream.test | 26 +++++---- llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp | 53 +++++++++++++------ llvm/tools/llvm-pdbdump/LLVMOutputStyle.h | 3 ++ 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp index bbcfbfca8103..403c02b42685 100644 --- a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp +++ b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp @@ -200,6 +200,10 @@ uint32_t MappedBlockStream::getLength() const { return StreamLayout.Length; } bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const { + if (Size == 0) { + Buffer = ArrayRef(); + return true; + } // Attempt to fulfill the request with a reference directly into the stream. // This can work even if the request crosses a block boundary, provided that // all subsequent blocks are contiguous. For example, a 10k read with a 4k diff --git a/llvm/test/DebugInfo/PDB/pdbdump-raw-stream.test b/llvm/test/DebugInfo/PDB/pdbdump-raw-stream.test index 57c1bce816a6..6b6624f16015 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-raw-stream.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-raw-stream.test @@ -2,16 +2,22 @@ ; RUN: not llvm-pdbdump raw -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s STREAM1: Stream Data { -STREAM1-NEXT: Stream 1 ( -STREAM1-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 |..1....T.....5VA| -STREAM1-NEXT: 0010: 86A0A249 896F9988 FAE52FF0 22000000 |...I.o..../."...| -STREAM1-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 |/LinkInfo./names| -STREAM1-NEXT: 0030: 002F7372 632F6865 61646572 626C6F63 |./src/headerbloc| -STREAM1-NEXT: 0040: 6B000300 00000600 00000100 00001A00 |k...............| -STREAM1-NEXT: 0050: 00000000 00001100 00000900 00000A00 |................| -STREAM1-NEXT: 0060: 00000D00 00000000 00000500 00000000 |................| -STREAM1-NEXT: 0070: 00004191 3201 |..A.2.| -STREAM1-NEXT: ) +STREAM1-NEXT: Stream { +STREAM1-NEXT: Index: 1 +STREAM1-NEXT: Type: PDB Stream +STREAM1-NEXT: Size: 118 +STREAM1-NEXT: Blocks: [19] +STREAM1-NEXT: Data ( +STREAM1-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 |..1....T.....5VA| +STREAM1-NEXT: 0010: 86A0A249 896F9988 FAE52FF0 22000000 |...I.o..../."...| +STREAM1-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 |/LinkInfo./names| +STREAM1-NEXT: 0030: 002F7372 632F6865 61646572 626C6F63 |./src/headerbloc| +STREAM1-NEXT: 0040: 6B000300 00000600 00000100 00001A00 |k...............| +STREAM1-NEXT: 0050: 00000000 00001100 00000900 00000A00 |................| +STREAM1-NEXT: 0060: 00000D00 00000000 00000500 00000000 |................| +STREAM1-NEXT: 0070: 00004191 3201 |..A.2.| +STREAM1-NEXT: ) +STREAM1-NEXT: } STREAM1-NEXT: } INVALIDSTREAM: Native PDB Error: The specified stream could not be loaded. diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp index a9706857a129..643b89630b16 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -157,9 +157,9 @@ Error LLVMOutputStyle::dumpFileHeaders() { return Error::success(); } -Error LLVMOutputStyle::dumpStreamSummary() { - if (!opts::raw::DumpStreamSummary) - return Error::success(); +void LLVMOutputStyle::discoverStreamPurposes() { + if (!StreamPurposes.empty()) + return; // It's OK if we fail to load some of these streams, we still attempt to print // what we can. @@ -168,7 +168,6 @@ Error LLVMOutputStyle::dumpStreamSummary() { auto Ipi = File.getPDBIpiStream(); auto Info = File.getPDBInfoStream(); - ListScope L(P, "Streams"); uint32_t StreamCount = File.getNumStreams(); std::unordered_map ModStreams; std::unordered_map NamedStreams; @@ -185,9 +184,8 @@ Error LLVMOutputStyle::dumpStreamSummary() { } } + StreamPurposes.resize(StreamCount); for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) { - std::string Label("Stream "); - Label += to_string(StreamIdx); std::string Value; if (StreamIdx == OldMSFDirectory) Value = "Old MSF Directory"; @@ -258,11 +256,7 @@ Error LLVMOutputStyle::dumpStreamSummary() { Value = "???"; } } - Value = "[" + Value + "]"; - Value = - Value + " (" + to_string(File.getStreamByteSize(StreamIdx)) + " bytes)"; - - P.printString(Label, Value); + StreamPurposes[StreamIdx] = Value; } // Consume errors from missing streams. @@ -274,6 +268,27 @@ Error LLVMOutputStyle::dumpStreamSummary() { consumeError(Ipi.takeError()); if (!Info) consumeError(Info.takeError()); +} + +Error LLVMOutputStyle::dumpStreamSummary() { + if (!opts::raw::DumpStreamSummary) + return Error::success(); + + discoverStreamPurposes(); + + uint32_t StreamCount = File.getNumStreams(); + + ListScope L(P, "Streams"); + for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) { + std::string Label("Stream "); + Label += to_string(StreamIdx); + + std::string Value = "[" + StreamPurposes[StreamIdx] + "] ("; + Value += to_string(File.getStreamByteSize(StreamIdx)); + Value += " bytes)"; + + P.printString(Label, Value); + } P.flush(); return Error::success(); @@ -377,6 +392,8 @@ Error LLVMOutputStyle::dumpStreamBytes() { if (opts::raw::DumpStreamData.empty()) return Error::success(); + discoverStreamPurposes(); + DictScope D(P, "Stream Data"); for (uint32_t SI : opts::raw::DumpStreamData) { if (SI >= File.getNumStreams()) @@ -386,15 +403,19 @@ Error LLVMOutputStyle::dumpStreamBytes() { File.getMsfBuffer(), SI); if (!S) continue; + DictScope DD(P, "Stream"); + + P.printNumber("Index", SI); + P.printString("Type", StreamPurposes[SI]); + P.printNumber("Size", S->getLength()); + auto Blocks = File.getMsfLayout().StreamMap[SI]; + P.printList("Blocks", Blocks); + StreamReader R(*S); ArrayRef StreamData; if (auto EC = R.readBytes(StreamData, S->getLength())) return EC; - std::string Label; - llvm::raw_string_ostream Stream(Label); - Stream << "Stream " << SI; - Stream.flush(); - P.printBinaryBlock(Label, StreamData); + P.printBinaryBlock("Data", StreamData); } return Error::success(); } diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h index 94430252f979..f5740ec458e2 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h @@ -25,6 +25,8 @@ public: Error dump() override; private: + void discoverStreamPurposes(); + Error dumpFileHeaders(); Error dumpStreamSummary(); Error dumpFreePageMap(); @@ -47,6 +49,7 @@ private: PDBFile &File; ScopedPrinter P; codeview::CVTypeDumper Dumper; + std::vector StreamPurposes; }; } }