summaryrefslogtreecommitdiff
path: root/tools/llvm-pdbdump/LLVMOutputStyle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-pdbdump/LLVMOutputStyle.cpp')
-rw-r--r--tools/llvm-pdbdump/LLVMOutputStyle.cpp172
1 files changed, 108 insertions, 64 deletions
diff --git a/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index ec1325ff23356..2dd4ef0fb30de 100644
--- a/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -39,6 +39,7 @@
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/Object/COFF.h"
@@ -609,11 +610,8 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
VerLabel = "IPI Version";
}
- bool IsSilentDatabaseBuild = !DumpRecordBytes && !DumpRecords && !DumpTpiHash;
- if (IsSilentDatabaseBuild) {
- outs().flush();
- errs() << "Building Type Information For " << Label << "\n";
- }
+ if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
+ return Error::success();
auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
: File.getPDBIpiStream();
@@ -623,38 +621,43 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
std::unique_ptr<DictScope> StreamScope;
std::unique_ptr<ListScope> RecordScope;
- if (!IsSilentDatabaseBuild) {
- StreamScope = llvm::make_unique<DictScope>(P, Label);
- P.printNumber(VerLabel, Tpi->getTpiVersion());
- P.printNumber("Record count", Tpi->NumTypeRecords());
- }
-
- TypeDatabase &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB;
+ StreamScope = llvm::make_unique<DictScope>(P, Label);
+ P.printNumber(VerLabel, Tpi->getTpiVersion());
+ P.printNumber("Record count", Tpi->getNumTypeRecords());
- TypeDatabaseVisitor DBV(StreamDB);
- CompactTypeDumpVisitor CTDV(StreamDB, &P);
- TypeDumpVisitor TDV(TypeDB, &P, false);
- if (StreamIdx == StreamIPI)
- TDV.setItemDB(ItemDB);
- RecordBytesVisitor RBV(P);
- TypeDeserializer Deserializer;
+ Optional<TypeDatabase> &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB;
- // We always need to deserialize and add it to the type database. This is
- // true if even if we're not dumping anything, because we could need the
- // type database for the purposes of dumping symbols.
- TypeVisitorCallbackPipeline Pipeline;
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(DBV);
+ std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors;
+ Visitors.push_back(make_unique<TypeDeserializer>());
+ if (!StreamDB.hasValue()) {
+ StreamDB.emplace(Tpi->getNumTypeRecords());
+ Visitors.push_back(make_unique<TypeDatabaseVisitor>(*StreamDB));
+ }
// If we're in dump mode, add a dumper with the appropriate detail level.
if (DumpRecords) {
+ std::unique_ptr<TypeVisitorCallbacks> Dumper;
if (opts::raw::CompactRecords)
- Pipeline.addCallbackToPipeline(CTDV);
- else
- Pipeline.addCallbackToPipeline(TDV);
+ Dumper = make_unique<CompactTypeDumpVisitor>(*StreamDB, &P);
+ else {
+ assert(TypeDB.hasValue());
+
+ auto X = make_unique<TypeDumpVisitor>(*TypeDB, &P, false);
+ if (StreamIdx == StreamIPI)
+ X->setItemDB(*ItemDB);
+ Dumper = std::move(X);
+ }
+ Visitors.push_back(std::move(Dumper));
}
if (DumpRecordBytes)
- Pipeline.addCallbackToPipeline(RBV);
+ Visitors.push_back(make_unique<RecordBytesVisitor>(P));
+
+ // We always need to deserialize and add it to the type database. This is
+ // true if even if we're not dumping anything, because we could need the
+ // type database for the purposes of dumping symbols.
+ TypeVisitorCallbackPipeline Pipeline;
+ for (const auto &V : Visitors)
+ Pipeline.addCallbackToPipeline(*V);
CVTypeVisitor Visitor(Pipeline);
@@ -680,7 +683,7 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
if (DumpTpiHash) {
DictScope DD(P, "Hash");
- P.printNumber("Number of Hash Buckets", Tpi->NumHashBuckets());
+ P.printNumber("Number of Hash Buckets", Tpi->getNumHashBuckets());
P.printNumber("Hash Key Size", Tpi->getHashKeySize());
P.printList("Values", Tpi->getHashValues());
@@ -700,19 +703,51 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
}
}
- if (!IsSilentDatabaseBuild) {
- ListScope L(P, "TypeIndexOffsets");
- for (const auto &IO : Tpi->getTypeIndexOffsets()) {
- P.printString(formatv("Index: {0:x}, Offset: {1:N}", IO.Type.getIndex(),
- (uint32_t)IO.Offset)
- .str());
- }
+ ListScope L(P, "TypeIndexOffsets");
+ for (const auto &IO : Tpi->getTypeIndexOffsets()) {
+ P.printString(formatv("Index: {0:x}, Offset: {1:N}", IO.Type.getIndex(),
+ (uint32_t)IO.Offset)
+ .str());
}
P.flush();
return Error::success();
}
+Error LLVMOutputStyle::buildTypeDatabase(uint32_t SN) {
+ assert(SN == StreamIPI || SN == StreamTPI);
+
+ auto &DB = (SN == StreamIPI) ? ItemDB : TypeDB;
+
+ if (DB.hasValue())
+ return Error::success();
+
+ auto Tpi =
+ (SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream();
+
+ if (!Tpi)
+ return Tpi.takeError();
+
+ DB.emplace(Tpi->getNumTypeRecords());
+
+ TypeVisitorCallbackPipeline Pipeline;
+ TypeDeserializer Deserializer;
+ TypeDatabaseVisitor DBV(*DB);
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(DBV);
+
+ auto HashValues = Tpi->getHashValues();
+ std::unique_ptr<TpiHashVerifier> HashVerifier;
+ if (!HashValues.empty()) {
+ HashVerifier =
+ make_unique<TpiHashVerifier>(HashValues, Tpi->getNumHashBuckets());
+ Pipeline.addCallbackToPipeline(*HashVerifier);
+ }
+
+ CVTypeVisitor Visitor(Pipeline);
+ return Visitor.visitTypeStream(Tpi->types(nullptr));
+}
+
Error LLVMOutputStyle::dumpDbiStream() {
bool DumpModules = opts::raw::DumpModules || opts::raw::DumpModuleSyms ||
opts::raw::DumpModuleFiles || opts::raw::DumpLineInfo;
@@ -750,43 +785,46 @@ Error LLVMOutputStyle::dumpDbiStream() {
if (DumpModules) {
ListScope L(P, "Modules");
- for (auto &Modi : DS->modules()) {
+ const DbiModuleList &Modules = DS->modules();
+ for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
+ const DbiModuleDescriptor &Modi = Modules.getModuleDescriptor(I);
DictScope DD(P);
- P.printString("Name", Modi.Info.getModuleName().str());
- P.printNumber("Debug Stream Index", Modi.Info.getModuleStreamIndex());
- P.printString("Object File Name", Modi.Info.getObjFileName().str());
- P.printNumber("Num Files", Modi.Info.getNumberOfFiles());
- P.printNumber("Source File Name Idx", Modi.Info.getSourceFileNameIndex());
- P.printNumber("Pdb File Name Idx", Modi.Info.getPdbFilePathNameIndex());
- P.printNumber("Line Info Byte Size", Modi.Info.getC11LineInfoByteSize());
- P.printNumber("C13 Line Info Byte Size",
- Modi.Info.getC13LineInfoByteSize());
- P.printNumber("Symbol Byte Size", Modi.Info.getSymbolDebugInfoByteSize());
- P.printNumber("Type Server Index", Modi.Info.getTypeServerIndex());
- P.printBoolean("Has EC Info", Modi.Info.hasECInfo());
+ P.printString("Name", Modi.getModuleName().str());
+ P.printNumber("Debug Stream Index", Modi.getModuleStreamIndex());
+ P.printString("Object File Name", Modi.getObjFileName().str());
+ P.printNumber("Num Files", Modi.getNumberOfFiles());
+ P.printNumber("Source File Name Idx", Modi.getSourceFileNameIndex());
+ P.printNumber("Pdb File Name Idx", Modi.getPdbFilePathNameIndex());
+ P.printNumber("Line Info Byte Size", Modi.getC11LineInfoByteSize());
+ P.printNumber("C13 Line Info Byte Size", Modi.getC13LineInfoByteSize());
+ P.printNumber("Symbol Byte Size", Modi.getSymbolDebugInfoByteSize());
+ P.printNumber("Type Server Index", Modi.getTypeServerIndex());
+ P.printBoolean("Has EC Info", Modi.hasECInfo());
if (opts::raw::DumpModuleFiles) {
- std::string FileListName =
- to_string(Modi.SourceFiles.size()) + " Contributing Source Files";
+ std::string FileListName = to_string(Modules.getSourceFileCount(I)) +
+ " Contributing Source Files";
ListScope LL(P, FileListName);
- for (auto File : Modi.SourceFiles)
- P.printString(File.str());
+ for (auto File : Modules.source_files(I))
+ P.printString(File);
}
- bool HasModuleDI =
- (Modi.Info.getModuleStreamIndex() < File.getNumStreams());
+ bool HasModuleDI = (Modi.getModuleStreamIndex() < File.getNumStreams());
bool ShouldDumpSymbols =
(opts::raw::DumpModuleSyms || opts::raw::DumpSymRecordBytes);
if (HasModuleDI && (ShouldDumpSymbols || opts::raw::DumpLineInfo)) {
auto ModStreamData = MappedBlockStream::createIndexedStream(
File.getMsfLayout(), File.getMsfBuffer(),
- Modi.Info.getModuleStreamIndex());
+ Modi.getModuleStreamIndex());
- ModuleDebugStreamRef ModS(Modi.Info, std::move(ModStreamData));
+ ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
if (auto EC = ModS.reload())
return EC;
if (ShouldDumpSymbols) {
+ if (auto EC = buildTypeDatabase(StreamTPI))
+ return EC;
+
ListScope SS(P, "Symbols");
- codeview::CVSymbolDumper SD(P, TypeDB, nullptr, false);
+ codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
bool HadError = false;
for (auto S : ModS.symbols(&HadError)) {
DictScope LL(P, "");
@@ -807,8 +845,10 @@ Error LLVMOutputStyle::dumpDbiStream() {
}
if (opts::raw::DumpLineInfo) {
ListScope SS(P, "LineInfo");
+ if (auto EC = buildTypeDatabase(StreamIPI))
+ return EC;
- C13RawVisitor V(P, File, ItemDB);
+ C13RawVisitor V(P, File, *ItemDB);
if (auto EC = codeview::visitModuleDebugFragments(
ModS.linesAndChecksums(), V))
return EC;
@@ -846,9 +886,10 @@ Error LLVMOutputStyle::dumpSectionContribs() {
{
DictScope DD(P, "Module");
P.printNumber("Index", SC.Imod);
- auto M = DS.modules();
- if (M.size() > SC.Imod) {
- P.printString("Name", M[SC.Imod].Info.getModuleName());
+ const DbiModuleList &Modules = DS.modules();
+ if (Modules.getModuleCount() > SC.Imod) {
+ P.printString("Name",
+ Modules.getModuleDescriptor(SC.Imod).getModuleName());
}
}
P.printNumber("Data CRC", SC.DataCrc);
@@ -925,7 +966,10 @@ Error LLVMOutputStyle::dumpPublicsStream() {
P.printList("Section Offsets", Publics->getSectionOffsets(),
printSectionOffset);
ListScope L(P, "Symbols");
- codeview::CVSymbolDumper SD(P, TypeDB, nullptr, false);
+ if (auto EC = buildTypeDatabase(StreamTPI))
+ return EC;
+
+ codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
bool HadError = false;
for (auto S : Publics->getSymbols(&HadError)) {
DictScope DD(P, "");