[llvm-pdbdump] Dump the IPI stream and all records.

llvm-svn: 270661
This commit is contained in:
Zachary Turner 2016-05-25 04:35:22 +00:00
parent c789b631f3
commit c9972c64f5
6 changed files with 154 additions and 26 deletions

View File

@ -64,6 +64,7 @@ public:
Expected<InfoStream &> getPDBInfoStream();
Expected<DbiStream &> getPDBDbiStream();
Expected<TpiStream &> getPDBTpiStream();
Expected<TpiStream &> getPDBIpiStream();
Expected<PublicsStream &> getPDBPublicsStream();
Expected<SymbolStream &> getPDBSymbolStream();
@ -72,6 +73,7 @@ private:
std::unique_ptr<InfoStream> Info;
std::unique_ptr<DbiStream> Dbi;
std::unique_ptr<TpiStream> Tpi;
std::unique_ptr<TpiStream> Ipi;
std::unique_ptr<PublicsStream> Publics;
std::unique_ptr<SymbolStream> Symbols;
};

View File

@ -28,7 +28,7 @@ class TpiStream {
struct HeaderInfo;
public:
TpiStream(PDBFile &File);
TpiStream(PDBFile &File, uint32_t StreamIdx);
~TpiStream();
Error reload();

View File

@ -289,13 +289,22 @@ Expected<DbiStream &> PDBFile::getPDBDbiStream() {
Expected<TpiStream &> PDBFile::getPDBTpiStream() {
if (!Tpi) {
Tpi.reset(new TpiStream(*this));
Tpi.reset(new TpiStream(*this, StreamTPI));
if (auto EC = Tpi->reload())
return std::move(EC);
}
return *Tpi;
}
Expected<TpiStream &> PDBFile::getPDBIpiStream() {
if (!Ipi) {
Ipi.reset(new TpiStream(*this, StreamIPI));
if (auto EC = Ipi->reload())
return std::move(EC);
}
return *Ipi;
}
Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
if (!Publics) {
auto DbiS = getPDBDbiStream();

View File

@ -56,8 +56,8 @@ struct TpiStream::HeaderInfo {
EmbeddedBuf HashAdjBuffer;
};
TpiStream::TpiStream(PDBFile &File)
: Pdb(File), Stream(StreamTPI, File), HashFunction(nullptr) {}
TpiStream::TpiStream(PDBFile &File, uint32_t StreamIdx)
: Pdb(File), Stream(StreamIdx, File), HashFunction(nullptr) {}
TpiStream::~TpiStream() {}

View File

@ -1,6 +1,7 @@
; RUN: llvm-pdbdump -raw-headers -raw-tpi-records -raw-tpi-record-bytes -raw-module-syms \
; RUN: -raw-sym-record-bytes -raw-publics -raw-module-files -raw-stream-name=/names \
; RUN: -raw-stream-summary %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
; RUN: -raw-stream-summary -raw-ipi-records -raw-ipi-record-bytes %p/Inputs/empty.pdb \
; RUN: | FileCheck -check-prefix=EMPTY %s
; RUN: llvm-pdbdump -raw-headers -raw-stream-name=/names -raw-modules -raw-module-files \
; RUN: %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s
; RUN: llvm-pdbdump -raw-headers %p/Inputs/bad-block-size.pdb | FileCheck -check-prefix=BAD-BLOCK-SIZE %s
@ -34,7 +35,7 @@
; EMPTY-NEXT: Stream 13: [Named Stream "/names"] (239 bytes)
; EMPTY-NEXT: Stream 14: [Module "* Linker *"] (520 bytes)
; EMPTY-NEXT: Stream 15: [TPI Hash] (308 bytes)
; EMPTY-NEXT: Stream 16: [???] (68 bytes)
; EMPTY-NEXT: Stream 16: [IPI Hash] (68 bytes)
; EMPTY-NEXT: ]
; EMPTY-NEXT: PDB Stream {
; EMPTY-NEXT: Version: 20000404
@ -53,7 +54,7 @@
; EMPTY-NEXT: $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + =
; EMPTY-NEXT: ]
; EMPTY-NEXT: }
; EMPTY-NEXT: Type Info Stream {
; EMPTY-NEXT: Type Info Stream (TPI) {
; EMPTY-NEXT: TPI Version: 20040203
; EMPTY-NEXT: Record count: 75
; EMPTY-NEXT: Records [
@ -119,6 +120,82 @@
; EMPTY-NEXT: 0040: 0500626F 746800F1 |..both..|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY: Type Info Stream (IPI) {
; EMPTY-NEXT: IPI Version: 20040203
; EMPTY-NEXT: Record count: 15
; EMPTY-NEXT: Records [
; EMPTY-NEXT: {
; EMPTY-NEXT: UnknownLeaf (0x104B) {
; EMPTY-NEXT: TypeLeafKind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: UnknownType {
; EMPTY-NEXT: Kind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: Length: 16
; EMPTY-NEXT: }
; EMPTY-NEXT: }
; EMPTY-NEXT: Bytes (
; EMPTY-NEXT: 0000: 0B100000 01000000 E1010000 0100F2F1 |................|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY-NEXT: {
; EMPTY-NEXT: UnknownLeaf (0x104C) {
; EMPTY-NEXT: TypeLeafKind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: UnknownType {
; EMPTY-NEXT: Kind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: Length: 16
; EMPTY-NEXT: }
; EMPTY-NEXT: }
; EMPTY-NEXT: Bytes (
; EMPTY-NEXT: 0000: 17100000 01000000 C2000000 0100F2F1 |................|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY-NEXT: {
; EMPTY-NEXT: UnknownLeaf (0x104D) {
; EMPTY-NEXT: TypeLeafKind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: UnknownType {
; EMPTY-NEXT: Kind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: Length: 16
; EMPTY-NEXT: }
; EMPTY-NEXT: }
; EMPTY-NEXT: Bytes (
; EMPTY-NEXT: 0000: 21100000 01000000 5B020000 0100F2F1 |!.......[.......|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY-NEXT: {
; EMPTY-NEXT: UnknownLeaf (0x104E) {
; EMPTY-NEXT: TypeLeafKind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: UnknownType {
; EMPTY-NEXT: Kind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: Length: 16
; EMPTY-NEXT: }
; EMPTY-NEXT: }
; EMPTY-NEXT: Bytes (
; EMPTY-NEXT: 0000: 2C100000 01000000 B0040000 0100F2F1 |,...............|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY-NEXT: {
; EMPTY-NEXT: UnknownLeaf (0x104F) {
; EMPTY-NEXT: TypeLeafKind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: UnknownType {
; EMPTY-NEXT: Kind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: Length: 16
; EMPTY-NEXT: }
; EMPTY-NEXT: }
; EMPTY-NEXT: Bytes (
; EMPTY-NEXT: 0000: 3A100000 01000000 1C020000 0100F2F1 |:...............|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY-NEXT: {
; EMPTY-NEXT: UnknownLeaf (0x1050) {
; EMPTY-NEXT: TypeLeafKind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: UnknownType {
; EMPTY-NEXT: Kind: LF_UDT_MOD_SRC_LINE (0x1607)
; EMPTY-NEXT: Length: 16
; EMPTY-NEXT: }
; EMPTY-NEXT: }
; EMPTY-NEXT: Bytes (
; EMPTY-NEXT: 0000: 42100000 01000000 6C000000 0100F2F1 |B.......l.......|
; EMPTY-NEXT: )
; EMPTY-NEXT: }
; EMPTY: DBI Stream {
; EMPTY-NEXT: Dbi Version: 19990903
; EMPTY-NEXT: Age: 1

View File

@ -112,13 +112,22 @@ cl::opt<bool> DumpStreamBlocks("raw-stream-blocks",
cl::opt<bool> DumpStreamSummary("raw-stream-summary",
cl::desc("dump summary of the PDB streams"),
cl::cat(NativeOtions));
cl::opt<bool> DumpTpiRecords("raw-tpi-records",
cl::desc("dump CodeView type records"),
cl::cat(NativeOtions));
cl::opt<bool>
DumpTpiRecordBytes("raw-tpi-record-bytes",
cl::desc("dump CodeView type record raw bytes"),
cl::cat(NativeOtions));
DumpTpiRecords("raw-tpi-records",
cl::desc("dump CodeView type records from TPI stream"),
cl::cat(NativeOtions));
cl::opt<bool> DumpTpiRecordBytes(
"raw-tpi-record-bytes",
cl::desc("dump CodeView type record raw bytes from TPI stream"),
cl::cat(NativeOtions));
cl::opt<bool>
DumpIpiRecords("raw-ipi-records",
cl::desc("dump CodeView type records from IPI stream"),
cl::cat(NativeOtions));
cl::opt<bool> DumpIpiRecordBytes(
"raw-ipi-record-bytes",
cl::desc("dump CodeView type record raw bytes from IPI stream"),
cl::cat(NativeOtions));
cl::opt<std::string> DumpStreamDataIdx("raw-stream",
cl::desc("dump stream data"),
cl::cat(NativeOtions));
@ -213,11 +222,15 @@ static Error dumpStreamSummary(ScopedPrinter &P, PDBFile &File) {
auto TpiS = File.getPDBTpiStream();
if (auto EC = TpiS.takeError())
return EC;
auto IpiS = File.getPDBIpiStream();
if (auto EC = IpiS.takeError())
return EC;
auto InfoS = File.getPDBInfoStream();
if (auto EC = InfoS.takeError())
return EC;
DbiStream &DS = DbiS.get();
TpiStream &TS = TpiS.get();
TpiStream &TIS = IpiS.get();
InfoStream &IS = InfoS.get();
ListScope L(P, "Streams");
@ -255,6 +268,10 @@ static Error dumpStreamSummary(ScopedPrinter &P, PDBFile &File) {
Value = "TPI Hash";
else if (StreamIdx == TS.getTypeHashStreamAuxIndex())
Value = "TPI Aux Hash";
else if (StreamIdx == TIS.getTypeHashStreamIndex())
Value = "IPI Hash";
else if (StreamIdx == TIS.getTypeHashStreamAuxIndex())
Value = "IPI Aux Hash";
else {
auto ModIter = ModStreams.find(StreamIdx);
auto NSIter = NamedStreams.find(StreamIdx);
@ -454,17 +471,37 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
}
static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File,
codeview::CVTypeDumper &TD) {
codeview::CVTypeDumper &TD, uint32_t StreamIdx) {
assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
if (opts::DumpTpiRecordBytes || opts::DumpTpiRecords) {
DictScope D(P, "Type Info Stream");
bool DumpRecordBytes = false;
bool DumpRecords = false;
StringRef Label;
StringRef VerLabel;
if (StreamIdx == StreamTPI) {
DumpRecordBytes = opts::DumpTpiRecordBytes;
DumpRecords = opts::DumpTpiRecordBytes;
Label = "Type Info Stream (TPI)";
VerLabel = "TPI Version";
} else if (StreamIdx == StreamIPI) {
DumpRecordBytes = opts::DumpIpiRecordBytes;
DumpRecords = opts::DumpIpiRecords;
Label = "Type Info Stream (IPI)";
VerLabel = "IPI Version";
}
if (!DumpRecordBytes && !DumpRecords && !opts::DumpModuleSyms)
return Error::success();
auto TpiS = File.getPDBTpiStream();
auto TpiS = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
: File.getPDBIpiStream();
if (auto EC = TpiS.takeError())
return EC;
TpiStream &Tpi = TpiS.get();
P.printNumber("TPI Version", Tpi.getTpiVersion());
if (DumpRecords || DumpRecordBytes) {
DictScope D(P, Label);
P.printNumber(VerLabel, Tpi.getTpiVersion());
P.printNumber("Record count", Tpi.NumTypeRecords());
ListScope L(P, "Records");
@ -473,10 +510,10 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File,
for (auto &Type : Tpi.types(&HadError)) {
DictScope DD(P, "");
if (opts::DumpTpiRecords)
if (DumpRecords)
TD.dump(Type);
if (opts::DumpTpiRecordBytes)
if (DumpRecordBytes)
P.printBinaryBlock("Bytes", Type.Data);
}
if (HadError)
@ -489,10 +526,7 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File,
// but not types, use a null output stream.
ScopedPrinter *OldP = TD.getPrinter();
TD.setPrinter(nullptr);
auto TpiS = File.getPDBTpiStream();
if (auto EC = TpiS.takeError())
return EC;
TpiStream &Tpi = TpiS.get();
bool HadError = false;
for (auto &Type : Tpi.types(&HadError))
TD.dump(Type);
@ -502,7 +536,7 @@ static Error dumpTpiStream(ScopedPrinter &P, PDBFile &File,
return make_error<RawError>(raw_error_code::corrupt_file,
"TPI stream contained corrupt record");
}
P.flush();
return Error::success();
}
@ -559,7 +593,9 @@ static Error dumpStructure(RawSession &RS) {
return EC;
codeview::CVTypeDumper TD(P, false);
if (auto EC = dumpTpiStream(P, File, TD))
if (auto EC = dumpTpiStream(P, File, TD, StreamTPI))
return EC;
if (auto EC = dumpTpiStream(P, File, TD, StreamIPI))
return EC;
if (auto EC = dumpDbiStream(P, File, TD))
@ -595,6 +631,10 @@ bool isRawDumpEnabled() {
return true;
if (opts::DumpTpiRecords)
return true;
if (opts::DumpIpiRecords)
return true;
if (opts::DumpIpiRecordBytes)
return true;
return false;
}