forked from OSchip/llvm-project
[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
This commit is contained in:
parent
c236e5a0f1
commit
36efbfa6d8
|
@ -200,6 +200,10 @@ uint32_t MappedBlockStream::getLength() const { return StreamLayout.Length; }
|
||||||
|
|
||||||
bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
|
bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
|
||||||
ArrayRef<uint8_t> &Buffer) const {
|
ArrayRef<uint8_t> &Buffer) const {
|
||||||
|
if (Size == 0) {
|
||||||
|
Buffer = ArrayRef<uint8_t>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// Attempt to fulfill the request with a reference directly into the stream.
|
// 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
|
// 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
|
// all subsequent blocks are contiguous. For example, a 10k read with a 4k
|
||||||
|
|
|
@ -2,16 +2,22 @@
|
||||||
; RUN: not llvm-pdbdump raw -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s
|
; RUN: not llvm-pdbdump raw -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s
|
||||||
|
|
||||||
STREAM1: Stream Data {
|
STREAM1: Stream Data {
|
||||||
STREAM1-NEXT: Stream 1 (
|
STREAM1-NEXT: Stream {
|
||||||
STREAM1-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 |..1....T.....5VA|
|
STREAM1-NEXT: Index: 1
|
||||||
STREAM1-NEXT: 0010: 86A0A249 896F9988 FAE52FF0 22000000 |...I.o..../."...|
|
STREAM1-NEXT: Type: PDB Stream
|
||||||
STREAM1-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 |/LinkInfo./names|
|
STREAM1-NEXT: Size: 118
|
||||||
STREAM1-NEXT: 0030: 002F7372 632F6865 61646572 626C6F63 |./src/headerbloc|
|
STREAM1-NEXT: Blocks: [19]
|
||||||
STREAM1-NEXT: 0040: 6B000300 00000600 00000100 00001A00 |k...............|
|
STREAM1-NEXT: Data (
|
||||||
STREAM1-NEXT: 0050: 00000000 00001100 00000900 00000A00 |................|
|
STREAM1-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 |..1....T.....5VA|
|
||||||
STREAM1-NEXT: 0060: 00000D00 00000000 00000500 00000000 |................|
|
STREAM1-NEXT: 0010: 86A0A249 896F9988 FAE52FF0 22000000 |...I.o..../."...|
|
||||||
STREAM1-NEXT: 0070: 00004191 3201 |..A.2.|
|
STREAM1-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 |/LinkInfo./names|
|
||||||
STREAM1-NEXT: )
|
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: }
|
STREAM1-NEXT: }
|
||||||
|
|
||||||
INVALIDSTREAM: Native PDB Error: The specified stream could not be loaded.
|
INVALIDSTREAM: Native PDB Error: The specified stream could not be loaded.
|
||||||
|
|
|
@ -157,9 +157,9 @@ Error LLVMOutputStyle::dumpFileHeaders() {
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error LLVMOutputStyle::dumpStreamSummary() {
|
void LLVMOutputStyle::discoverStreamPurposes() {
|
||||||
if (!opts::raw::DumpStreamSummary)
|
if (!StreamPurposes.empty())
|
||||||
return Error::success();
|
return;
|
||||||
|
|
||||||
// It's OK if we fail to load some of these streams, we still attempt to print
|
// It's OK if we fail to load some of these streams, we still attempt to print
|
||||||
// what we can.
|
// what we can.
|
||||||
|
@ -168,7 +168,6 @@ Error LLVMOutputStyle::dumpStreamSummary() {
|
||||||
auto Ipi = File.getPDBIpiStream();
|
auto Ipi = File.getPDBIpiStream();
|
||||||
auto Info = File.getPDBInfoStream();
|
auto Info = File.getPDBInfoStream();
|
||||||
|
|
||||||
ListScope L(P, "Streams");
|
|
||||||
uint32_t StreamCount = File.getNumStreams();
|
uint32_t StreamCount = File.getNumStreams();
|
||||||
std::unordered_map<uint16_t, const ModuleInfoEx *> ModStreams;
|
std::unordered_map<uint16_t, const ModuleInfoEx *> ModStreams;
|
||||||
std::unordered_map<uint16_t, std::string> NamedStreams;
|
std::unordered_map<uint16_t, std::string> NamedStreams;
|
||||||
|
@ -185,9 +184,8 @@ Error LLVMOutputStyle::dumpStreamSummary() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StreamPurposes.resize(StreamCount);
|
||||||
for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
|
for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
|
||||||
std::string Label("Stream ");
|
|
||||||
Label += to_string(StreamIdx);
|
|
||||||
std::string Value;
|
std::string Value;
|
||||||
if (StreamIdx == OldMSFDirectory)
|
if (StreamIdx == OldMSFDirectory)
|
||||||
Value = "Old MSF Directory";
|
Value = "Old MSF Directory";
|
||||||
|
@ -258,11 +256,7 @@ Error LLVMOutputStyle::dumpStreamSummary() {
|
||||||
Value = "???";
|
Value = "???";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value = "[" + Value + "]";
|
StreamPurposes[StreamIdx] = Value;
|
||||||
Value =
|
|
||||||
Value + " (" + to_string(File.getStreamByteSize(StreamIdx)) + " bytes)";
|
|
||||||
|
|
||||||
P.printString(Label, Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume errors from missing streams.
|
// Consume errors from missing streams.
|
||||||
|
@ -274,6 +268,27 @@ Error LLVMOutputStyle::dumpStreamSummary() {
|
||||||
consumeError(Ipi.takeError());
|
consumeError(Ipi.takeError());
|
||||||
if (!Info)
|
if (!Info)
|
||||||
consumeError(Info.takeError());
|
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();
|
P.flush();
|
||||||
return Error::success();
|
return Error::success();
|
||||||
|
@ -377,6 +392,8 @@ Error LLVMOutputStyle::dumpStreamBytes() {
|
||||||
if (opts::raw::DumpStreamData.empty())
|
if (opts::raw::DumpStreamData.empty())
|
||||||
return Error::success();
|
return Error::success();
|
||||||
|
|
||||||
|
discoverStreamPurposes();
|
||||||
|
|
||||||
DictScope D(P, "Stream Data");
|
DictScope D(P, "Stream Data");
|
||||||
for (uint32_t SI : opts::raw::DumpStreamData) {
|
for (uint32_t SI : opts::raw::DumpStreamData) {
|
||||||
if (SI >= File.getNumStreams())
|
if (SI >= File.getNumStreams())
|
||||||
|
@ -386,15 +403,19 @@ Error LLVMOutputStyle::dumpStreamBytes() {
|
||||||
File.getMsfBuffer(), SI);
|
File.getMsfBuffer(), SI);
|
||||||
if (!S)
|
if (!S)
|
||||||
continue;
|
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);
|
StreamReader R(*S);
|
||||||
ArrayRef<uint8_t> StreamData;
|
ArrayRef<uint8_t> StreamData;
|
||||||
if (auto EC = R.readBytes(StreamData, S->getLength()))
|
if (auto EC = R.readBytes(StreamData, S->getLength()))
|
||||||
return EC;
|
return EC;
|
||||||
std::string Label;
|
P.printBinaryBlock("Data", StreamData);
|
||||||
llvm::raw_string_ostream Stream(Label);
|
|
||||||
Stream << "Stream " << SI;
|
|
||||||
Stream.flush();
|
|
||||||
P.printBinaryBlock(Label, StreamData);
|
|
||||||
}
|
}
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
Error dump() override;
|
Error dump() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void discoverStreamPurposes();
|
||||||
|
|
||||||
Error dumpFileHeaders();
|
Error dumpFileHeaders();
|
||||||
Error dumpStreamSummary();
|
Error dumpStreamSummary();
|
||||||
Error dumpFreePageMap();
|
Error dumpFreePageMap();
|
||||||
|
@ -47,6 +49,7 @@ private:
|
||||||
PDBFile &File;
|
PDBFile &File;
|
||||||
ScopedPrinter P;
|
ScopedPrinter P;
|
||||||
codeview::CVTypeDumper Dumper;
|
codeview::CVTypeDumper Dumper;
|
||||||
|
std::vector<std::string> StreamPurposes;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue