forked from OSchip/llvm-project
Reland "Use ScopedPrinter in llvm-pdbdump"
This reverts r268508 and reinstates r268506 with an additional cast from TypeLeafKind to unsigned to allow conversion to HexNumber. llvm-svn: 268517
This commit is contained in:
parent
1a2b2f03e7
commit
b034526853
|
@ -193,6 +193,12 @@ public:
|
||||||
startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
|
startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... T> void printVersion(StringRef Label, T... Version) {
|
||||||
|
startLine() << Label << ": ";
|
||||||
|
printVersionInternal(Version...);
|
||||||
|
getOStream() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T> void printList(StringRef Label, const T &List) {
|
template <typename T> void printList(StringRef Label, const T &List) {
|
||||||
startLine() << Label << ": [";
|
startLine() << Label << ": [";
|
||||||
bool Comma = false;
|
bool Comma = false;
|
||||||
|
@ -230,6 +236,8 @@ public:
|
||||||
startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
|
startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printString(StringRef Value) { startLine() << Value << "\n"; }
|
||||||
|
|
||||||
void printString(StringRef Label, StringRef Value) {
|
void printString(StringRef Label, StringRef Value) {
|
||||||
startLine() << Label << ": " << Value << "\n";
|
startLine() << Label << ": " << Value << "\n";
|
||||||
}
|
}
|
||||||
|
@ -275,6 +283,10 @@ public:
|
||||||
printBinaryImpl(Label, StringRef(), V, true);
|
printBinaryImpl(Label, StringRef(), V, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> void printObject(StringRef Label, const T &Value) {
|
||||||
|
startLine() << Label << ": " << Value << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
raw_ostream &startLine() {
|
raw_ostream &startLine() {
|
||||||
printIndent();
|
printIndent();
|
||||||
return OS;
|
return OS;
|
||||||
|
@ -283,6 +295,16 @@ public:
|
||||||
raw_ostream &getOStream() { return OS; }
|
raw_ostream &getOStream() { return OS; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename T> void printVersionInternal(T Value) {
|
||||||
|
getOStream() << Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename S, typename T, typename... TArgs>
|
||||||
|
void printVersionInternal(S Value, T Value2, TArgs... Args) {
|
||||||
|
getOStream() << Value << ".";
|
||||||
|
printVersionInternal(Value2, Args...);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
|
static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
|
||||||
return lhs.Name < rhs.Name;
|
return lhs.Name < rhs.Name;
|
||||||
|
@ -304,6 +326,11 @@ ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
|
||||||
|
|
||||||
template<char Open, char Close>
|
template<char Open, char Close>
|
||||||
struct DelimitedScope {
|
struct DelimitedScope {
|
||||||
|
explicit DelimitedScope(ScopedPrinter &W) : W(W) {
|
||||||
|
W.startLine() << Open << '\n';
|
||||||
|
W.indent();
|
||||||
|
}
|
||||||
|
|
||||||
DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
|
DelimitedScope(ScopedPrinter &W, StringRef N) : W(W) {
|
||||||
W.startLine() << N;
|
W.startLine() << N;
|
||||||
if (!N.empty())
|
if (!N.empty())
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,6 +52,7 @@
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/PrettyStackTrace.h"
|
#include "llvm/Support/PrettyStackTrace.h"
|
||||||
#include "llvm/Support/Process.h"
|
#include "llvm/Support/Process.h"
|
||||||
|
#include "llvm/Support/ScopedPrinter.h"
|
||||||
#include "llvm/Support/Signals.h"
|
#include "llvm/Support/Signals.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
|
@ -104,6 +105,13 @@ cl::opt<bool> DumpStreamSizes("dump-stream-sizes",
|
||||||
cl::opt<bool> DumpStreamBlocks("dump-stream-blocks",
|
cl::opt<bool> DumpStreamBlocks("dump-stream-blocks",
|
||||||
cl::desc("dump PDB stream blocks"),
|
cl::desc("dump PDB stream blocks"),
|
||||||
cl::cat(OtherOptions));
|
cl::cat(OtherOptions));
|
||||||
|
cl::opt<bool> DumpTypeStream("dump-tpi-stream",
|
||||||
|
cl::desc("dump PDB TPI (Type Info) stream"),
|
||||||
|
cl::cat(OtherOptions));
|
||||||
|
cl::opt<bool>
|
||||||
|
DumpTpiRecordBytes("dump-tpi-record-bytes",
|
||||||
|
cl::desc("dump CodeView type record raw bytes"),
|
||||||
|
cl::cat(OtherOptions));
|
||||||
cl::opt<std::string> DumpStreamData("dump-stream", cl::desc("dump stream data"),
|
cl::opt<std::string> DumpStreamData("dump-stream", cl::desc("dump stream data"),
|
||||||
cl::cat(OtherOptions));
|
cl::cat(OtherOptions));
|
||||||
|
|
||||||
|
@ -149,183 +157,205 @@ cl::opt<bool> NoEnumDefs("no-enum-definitions",
|
||||||
cl::cat(FilterCategory));
|
cl::cat(FilterCategory));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpBytes(raw_ostream &S, StringRef Bytes, uint32_t BytesPerRow,
|
static void dumpFileHeaders(ScopedPrinter &P, PDBFile &File) {
|
||||||
uint32_t Indent) {
|
if (!opts::DumpHeaders)
|
||||||
S << "[";
|
return;
|
||||||
|
DictScope D(P, "FileHeaders");
|
||||||
while (!Bytes.empty()) {
|
P.printNumber("BlockSize", File.getBlockSize());
|
||||||
size_t BytesThisLine = std::min<size_t>(Bytes.size(), BytesPerRow);
|
P.printNumber("Unknown0", File.getUnknown0());
|
||||||
while (BytesThisLine > 0) {
|
P.printNumber("NumBlocks", File.getBlockCount());
|
||||||
S << format_hex_no_prefix(uint8_t(Bytes.front()), 2, true);
|
P.printNumber("NumDirectoryBytes", File.getNumDirectoryBytes());
|
||||||
Bytes = Bytes.drop_front();
|
P.printNumber("Unknown1", File.getUnknown1());
|
||||||
if (--BytesThisLine > 0)
|
P.printNumber("BlockMapAddr", File.getBlockMapIndex());
|
||||||
S << ' ';
|
P.printNumber("NumDirectoryBlocks", File.getNumDirectoryBlocks());
|
||||||
}
|
P.printNumber("BlockMapOffset", File.getBlockMapOffset());
|
||||||
if (!Bytes.empty()) {
|
|
||||||
S << '\n';
|
|
||||||
S.indent(Indent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
S << ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dumpStructure(RawSession &RS) {
|
|
||||||
PDBFile &File = RS.getPDBFile();
|
|
||||||
|
|
||||||
if (opts::DumpHeaders) {
|
|
||||||
outs() << "BlockSize: " << File.getBlockSize() << '\n';
|
|
||||||
outs() << "Unknown0: " << File.getUnknown0() << '\n';
|
|
||||||
outs() << "NumBlocks: " << File.getBlockCount() << '\n';
|
|
||||||
outs() << "NumDirectoryBytes: " << File.getNumDirectoryBytes() << '\n';
|
|
||||||
outs() << "Unknown1: " << File.getUnknown1() << '\n';
|
|
||||||
outs() << "BlockMapAddr: " << File.getBlockMapIndex() << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts::DumpHeaders)
|
|
||||||
outs() << "NumDirectoryBlocks: " << File.getNumDirectoryBlocks() << '\n';
|
|
||||||
|
|
||||||
if (opts::DumpHeaders)
|
|
||||||
outs() << "BlockMapOffset: " << File.getBlockMapOffset() << '\n';
|
|
||||||
|
|
||||||
// The directory is not contiguous. Instead, the block map contains a
|
// The directory is not contiguous. Instead, the block map contains a
|
||||||
// contiguous list of block numbers whose contents, when concatenated in
|
// contiguous list of block numbers whose contents, when concatenated in
|
||||||
// order, make up the directory.
|
// order, make up the directory.
|
||||||
auto DirectoryBlocks = File.getDirectoryBlockArray();
|
P.printList("DirectoryBlocks", File.getDirectoryBlockArray());
|
||||||
|
P.printNumber("NumStreams", File.getNumStreams());
|
||||||
|
}
|
||||||
|
|
||||||
if (opts::DumpHeaders) {
|
static void dumpStreamSizes(ScopedPrinter &P, PDBFile &File) {
|
||||||
outs() << "DirectoryBlocks: [";
|
if (!opts::DumpStreamSizes)
|
||||||
for (const auto &DirectoryBlockAddr : DirectoryBlocks) {
|
return;
|
||||||
if (&DirectoryBlockAddr != &DirectoryBlocks.front())
|
|
||||||
outs() << ", ";
|
|
||||||
outs() << DirectoryBlockAddr;
|
|
||||||
}
|
|
||||||
outs() << "]\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts::DumpHeaders)
|
ListScope L(P, "StreamSizes");
|
||||||
outs() << "NumStreams: " << File.getNumStreams() << '\n';
|
|
||||||
uint32_t StreamCount = File.getNumStreams();
|
uint32_t StreamCount = File.getNumStreams();
|
||||||
if (opts::DumpStreamSizes) {
|
for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
|
||||||
for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx)
|
std::string Name("Stream ");
|
||||||
outs() << "StreamSizes[" << StreamIdx
|
Name += to_string(StreamIdx);
|
||||||
<< "]: " << File.getStreamByteSize(StreamIdx) << '\n';
|
P.printNumber(Name, File.getStreamByteSize(StreamIdx));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (opts::DumpStreamBlocks) {
|
static void dumpStreamBlocks(ScopedPrinter &P, PDBFile &File) {
|
||||||
for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
|
if (!opts::DumpStreamBlocks)
|
||||||
outs() << "StreamBlocks[" << StreamIdx << "]: [";
|
return;
|
||||||
auto StreamBlocks = File.getStreamBlockList(StreamIdx);
|
|
||||||
for (size_t i = 0; i < StreamBlocks.size(); ++i) {
|
ListScope L(P, "StreamBlocks");
|
||||||
if (i != 0)
|
uint32_t StreamCount = File.getNumStreams();
|
||||||
outs() << ", ";
|
for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
|
||||||
outs() << StreamBlocks[i];
|
std::string Name("Stream ");
|
||||||
}
|
Name += to_string(StreamIdx);
|
||||||
outs() << "]\n";
|
auto StreamBlocks = File.getStreamBlockList(StreamIdx);
|
||||||
}
|
P.printList(Name, StreamBlocks);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpStreamData(ScopedPrinter &P, PDBFile &File) {
|
||||||
|
uint32_t StreamCount = File.getNumStreams();
|
||||||
StringRef DumpStreamStr = opts::DumpStreamData;
|
StringRef DumpStreamStr = opts::DumpStreamData;
|
||||||
uint32_t DumpStreamNum;
|
uint32_t DumpStreamNum;
|
||||||
if (!DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) &&
|
if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) ||
|
||||||
DumpStreamNum < StreamCount) {
|
DumpStreamNum >= StreamCount)
|
||||||
uint32_t StreamBytesRead = 0;
|
return;
|
||||||
uint32_t StreamSize = File.getStreamByteSize(DumpStreamNum);
|
|
||||||
auto StreamBlocks = File.getStreamBlockList(DumpStreamNum);
|
|
||||||
|
|
||||||
for (uint32_t StreamBlockAddr : StreamBlocks) {
|
uint32_t StreamBytesRead = 0;
|
||||||
uint32_t BytesLeftToReadInStream = StreamSize - StreamBytesRead;
|
uint32_t StreamSize = File.getStreamByteSize(DumpStreamNum);
|
||||||
if (BytesLeftToReadInStream == 0)
|
auto StreamBlocks = File.getStreamBlockList(DumpStreamNum);
|
||||||
break;
|
|
||||||
|
|
||||||
uint32_t BytesToReadInBlock = std::min(
|
for (uint32_t StreamBlockAddr : StreamBlocks) {
|
||||||
BytesLeftToReadInStream, static_cast<uint32_t>(File.getBlockSize()));
|
uint32_t BytesLeftToReadInStream = StreamSize - StreamBytesRead;
|
||||||
auto StreamBlockData =
|
if (BytesLeftToReadInStream == 0)
|
||||||
File.getBlockData(StreamBlockAddr, BytesToReadInBlock);
|
break;
|
||||||
|
|
||||||
outs() << StreamBlockData;
|
uint32_t BytesToReadInBlock = std::min(
|
||||||
StreamBytesRead += StreamBlockData.size();
|
BytesLeftToReadInStream, static_cast<uint32_t>(File.getBlockSize()));
|
||||||
}
|
auto StreamBlockData =
|
||||||
|
File.getBlockData(StreamBlockAddr, BytesToReadInBlock);
|
||||||
|
|
||||||
|
outs() << StreamBlockData;
|
||||||
|
StreamBytesRead += StreamBlockData.size();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpInfoStream(ScopedPrinter &P, PDBFile &File) {
|
||||||
InfoStream &IS = File.getPDBInfoStream();
|
InfoStream &IS = File.getPDBInfoStream();
|
||||||
outs() << "Version: " << IS.getVersion() << '\n';
|
|
||||||
outs() << "Signature: ";
|
|
||||||
outs().write_hex(IS.getSignature()) << '\n';
|
|
||||||
outs() << "Age: " << IS.getAge() << '\n';
|
|
||||||
outs() << "Guid: " << IS.getGuid() << '\n';
|
|
||||||
|
|
||||||
// Let's try to dump out the named stream "/names".
|
DictScope D(P, "PDB Stream");
|
||||||
uint32_t NameStreamIndex = IS.getNamedStreamIndex("/names");
|
P.printNumber("Version", IS.getVersion());
|
||||||
|
P.printHex("Signature", IS.getSignature());
|
||||||
|
P.printNumber("Age", IS.getAge());
|
||||||
|
P.printObject("Guid", IS.getGuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpNamedStream(ScopedPrinter &P, PDBFile &File, StringRef Stream) {
|
||||||
|
InfoStream &IS = File.getPDBInfoStream();
|
||||||
|
uint32_t NameStreamIndex = IS.getNamedStreamIndex(Stream);
|
||||||
|
|
||||||
if (NameStreamIndex != 0) {
|
if (NameStreamIndex != 0) {
|
||||||
|
std::string Name("Stream '");
|
||||||
|
Name += Stream;
|
||||||
|
Name += "'";
|
||||||
|
DictScope D(P, Name);
|
||||||
|
P.printNumber("Index", NameStreamIndex);
|
||||||
|
|
||||||
MappedBlockStream NameStream(NameStreamIndex, File);
|
MappedBlockStream NameStream(NameStreamIndex, File);
|
||||||
StreamReader Reader(NameStream);
|
StreamReader Reader(NameStream);
|
||||||
|
|
||||||
outs() << "NameStream: " << NameStreamIndex << '\n';
|
|
||||||
|
|
||||||
NameHashTable NameTable;
|
NameHashTable NameTable;
|
||||||
NameTable.load(Reader);
|
NameTable.load(Reader);
|
||||||
outs() << "NameStreamSignature: ";
|
P.printHex("Signature", NameTable.getSignature());
|
||||||
outs().write_hex(NameTable.getSignature()) << '\n';
|
P.printNumber("Version", NameTable.getHashVersion());
|
||||||
outs() << "NameStreamVersion: " << NameTable.getHashVersion() << '\n';
|
P.printNumber("Name Count", NameTable.getNameCount());
|
||||||
outs() << "Name Count: " << NameTable.getNameCount() << '\n';
|
ListScope L(P, "Names");
|
||||||
for (uint32_t ID : NameTable.name_ids()) {
|
for (uint32_t ID : NameTable.name_ids()) {
|
||||||
outs() << "Name: " << NameTable.getStringForID(ID) << '\n';
|
StringRef Str = NameTable.getStringForID(ID);
|
||||||
|
if (!Str.empty())
|
||||||
|
P.printString(Str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpDbiStream(ScopedPrinter &P, PDBFile &File) {
|
||||||
DbiStream &DS = File.getPDBDbiStream();
|
DbiStream &DS = File.getPDBDbiStream();
|
||||||
outs() << "Dbi Version: " << DS.getDbiVersion() << '\n';
|
|
||||||
outs() << "Age: " << DS.getAge() << '\n';
|
DictScope D(P, "DBI Stream");
|
||||||
outs() << "Incremental Linking: " << DS.isIncrementallyLinked() << '\n';
|
P.printNumber("Dbi Version", DS.getDbiVersion());
|
||||||
outs() << "Has CTypes: " << DS.hasCTypes() << '\n';
|
P.printNumber("Age", DS.getAge());
|
||||||
outs() << "Is Stripped: " << DS.isStripped() << '\n';
|
P.printBoolean("Incremental Linking", DS.isIncrementallyLinked());
|
||||||
outs() << "Machine Type: " << DS.getMachineType() << '\n';
|
P.printBoolean("Has CTypes", DS.hasCTypes());
|
||||||
outs() << "Number of Symbols: " << DS.getNumberOfSymbols() << '\n';
|
P.printBoolean("Is Stripped", DS.isStripped());
|
||||||
|
P.printObject("Machine Type", DS.getMachineType());
|
||||||
|
P.printNumber("Number of Symbols", DS.getNumberOfSymbols());
|
||||||
|
|
||||||
uint16_t Major = DS.getBuildMajorVersion();
|
uint16_t Major = DS.getBuildMajorVersion();
|
||||||
uint16_t Minor = DS.getBuildMinorVersion();
|
uint16_t Minor = DS.getBuildMinorVersion();
|
||||||
outs() << "Toolchain Version: " << Major << "." << Minor << '\n';
|
P.printVersion("Toolchain Version", Major, Minor);
|
||||||
outs() << "mspdb" << Major << Minor << ".dll version: " << Major << "."
|
|
||||||
<< Minor << "." << DS.getPdbDllVersion() << '\n';
|
|
||||||
|
|
||||||
outs() << "Modules: \n";
|
std::string DllName;
|
||||||
|
raw_string_ostream DllStream(DllName);
|
||||||
|
DllStream << "mspdb" << Major << Minor << ".dll version";
|
||||||
|
DllStream.flush();
|
||||||
|
P.printVersion(DllName, Major, Minor, DS.getPdbDllVersion());
|
||||||
|
|
||||||
|
ListScope L(P, "Modules");
|
||||||
for (auto &Modi : DS.modules()) {
|
for (auto &Modi : DS.modules()) {
|
||||||
outs() << Modi.Info.getModuleName() << '\n';
|
DictScope DD(P);
|
||||||
outs().indent(4) << "Debug Stream Index: "
|
P.printString("Name", Modi.Info.getModuleName());
|
||||||
<< Modi.Info.getModuleStreamIndex() << '\n';
|
P.printNumber("Debug Stream Index", Modi.Info.getModuleStreamIndex());
|
||||||
outs().indent(4) << "Object File: " << Modi.Info.getObjFileName() << '\n';
|
P.printString("Object File Name", Modi.Info.getObjFileName());
|
||||||
outs().indent(4) << "Num Files: " << Modi.Info.getNumberOfFiles() << '\n';
|
P.printNumber("Num Files", Modi.Info.getNumberOfFiles());
|
||||||
outs().indent(4) << "Source File Name Idx: "
|
P.printNumber("Source File Name Idx", Modi.Info.getSourceFileNameIndex());
|
||||||
<< Modi.Info.getSourceFileNameIndex() << '\n';
|
P.printNumber("Pdb File Name Idx", Modi.Info.getPdbFilePathNameIndex());
|
||||||
outs().indent(4) << "Pdb File Name Idx: "
|
P.printNumber("Line Info Byte Size", Modi.Info.getLineInfoByteSize());
|
||||||
<< Modi.Info.getPdbFilePathNameIndex() << '\n';
|
P.printNumber("C13 Line Info Byte Size",
|
||||||
outs().indent(4) << "Line Info Byte Size: "
|
Modi.Info.getC13LineInfoByteSize());
|
||||||
<< Modi.Info.getLineInfoByteSize() << '\n';
|
P.printNumber("Symbol Byte Size", Modi.Info.getSymbolDebugInfoByteSize());
|
||||||
outs().indent(4) << "C13 Line Info Byte Size: "
|
P.printNumber("Type Server Index", Modi.Info.getTypeServerIndex());
|
||||||
<< Modi.Info.getC13LineInfoByteSize() << '\n';
|
P.printBoolean("Has EC Info", Modi.Info.hasECInfo());
|
||||||
outs().indent(4) << "Symbol Byte Size: "
|
std::string FileListName =
|
||||||
<< Modi.Info.getSymbolDebugInfoByteSize() << '\n';
|
to_string(Modi.SourceFiles.size()) + " Contributing Source Files";
|
||||||
outs().indent(4) << "Type Server Index: " << Modi.Info.getTypeServerIndex()
|
ListScope LL(P, FileListName);
|
||||||
<< '\n';
|
for (auto File : Modi.SourceFiles)
|
||||||
outs().indent(4) << "Has EC Info: " << Modi.Info.hasECInfo() << '\n';
|
P.printString(File);
|
||||||
outs().indent(4) << Modi.SourceFiles.size()
|
|
||||||
<< " Contributing Source Files: \n";
|
|
||||||
for (auto File : Modi.SourceFiles) {
|
|
||||||
outs().indent(8) << File << '\n';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpTpiStream(ScopedPrinter &P, PDBFile &File) {
|
||||||
|
if (!opts::DumpTypeStream)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DictScope D(P, "Type Info Stream");
|
||||||
|
|
||||||
TpiStream &Tpi = File.getPDBTpiStream();
|
TpiStream &Tpi = File.getPDBTpiStream();
|
||||||
outs() << "TPI Version: " << Tpi.getTpiVersion() << '\n';
|
P.printNumber("TPI Version", Tpi.getTpiVersion());
|
||||||
outs() << "Record count: " << Tpi.NumTypeRecords() << '\n';
|
P.printNumber("Record count", Tpi.NumTypeRecords());
|
||||||
|
|
||||||
|
if (!opts::DumpTpiRecordBytes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListScope L(P, "Records");
|
||||||
for (auto &Type : Tpi.types()) {
|
for (auto &Type : Tpi.types()) {
|
||||||
outs().indent(2) << "Kind: 0x" << Type.Leaf;
|
DictScope DD(P, "");
|
||||||
outs().indent(2) << "Bytes: ";
|
P.printHex("Kind", unsigned(Type.Leaf));
|
||||||
dumpBytes(outs(), Type.LeafData, 16, 24);
|
P.printBinaryBlock("Bytes", Type.LeafData);
|
||||||
outs() << '\n';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dumpStructure(RawSession &RS) {
|
||||||
|
PDBFile &File = RS.getPDBFile();
|
||||||
|
ScopedPrinter P(outs());
|
||||||
|
|
||||||
|
dumpFileHeaders(P, File);
|
||||||
|
|
||||||
|
dumpStreamSizes(P, File);
|
||||||
|
|
||||||
|
dumpStreamBlocks(P, File);
|
||||||
|
|
||||||
|
dumpStreamData(P, File);
|
||||||
|
|
||||||
|
dumpInfoStream(P, File);
|
||||||
|
|
||||||
|
dumpNamedStream(P, File, "/names");
|
||||||
|
|
||||||
|
dumpDbiStream(P, File);
|
||||||
|
|
||||||
|
dumpTpiStream(P, File);
|
||||||
|
}
|
||||||
|
|
||||||
static void reportError(StringRef Path, PDB_ErrorCode Error) {
|
static void reportError(StringRef Path, PDB_ErrorCode Error) {
|
||||||
switch (Error) {
|
switch (Error) {
|
||||||
case PDB_ErrorCode::Success:
|
case PDB_ErrorCode::Success:
|
||||||
|
|
Loading…
Reference in New Issue