diff options
Diffstat (limited to 'llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp')
-rw-r--r-- | llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp index f75a2411ac2..c4fecb80ea5 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -14,9 +14,9 @@ #include "StreamUtil.h" #include "llvm-pdbdump.h" +#include "llvm/DebugInfo/CodeView/CVTypeDumper.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" -#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h" @@ -25,6 +25,7 @@ #include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h" #include "llvm/DebugInfo/CodeView/SymbolDumper.h" #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" @@ -83,7 +84,7 @@ struct PageStats { class C13RawVisitor : public C13DebugFragmentVisitor { public: - C13RawVisitor(ScopedPrinter &P, PDBFile &F, LazyRandomTypeCollection &IPI) + C13RawVisitor(ScopedPrinter &P, PDBFile &F, TypeDatabase &IPI) : C13DebugFragmentVisitor(F), P(P), IPI(IPI) {} Error handleLines() override { @@ -159,7 +160,7 @@ public: if (auto EC = printFileName("FileName", L.Header->FileID)) return EC; - if (auto EC = dumpTypeRecord("Function", L.Header->Inlinee)) + if (auto EC = dumpTypeRecord("Function", IPI, L.Header->Inlinee)) return EC; P.printNumber("SourceLine", L.Header->SourceLineNum); if (IL.hasExtraFiles()) { @@ -175,11 +176,11 @@ public: } private: - Error dumpTypeRecord(StringRef Label, TypeIndex Index) { - CompactTypeDumpVisitor CTDV(IPI, Index, &P); + Error dumpTypeRecord(StringRef Label, TypeDatabase &DB, TypeIndex Index) { + CompactTypeDumpVisitor CTDV(DB, Index, &P); DictScope D(P, Label); - if (IPI.contains(Index)) { - CVType Type = IPI.getType(Index); + if (DB.contains(Index)) { + CVType &Type = DB.getTypeRecord(Index); if (auto EC = codeview::visitTypeRecord(Type, CTDV)) return EC; } else { @@ -198,7 +199,7 @@ private: } ScopedPrinter &P; - LazyRandomTypeCollection &IPI; + TypeDatabase &IPI; }; } @@ -608,19 +609,14 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { VerLabel = "IPI Version"; } + if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash) + return Error::success(); + auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream(); if (!Tpi) return Tpi.takeError(); - auto ExpectedTypes = initializeTypeDatabase(StreamIdx); - if (!ExpectedTypes) - return ExpectedTypes.takeError(); - auto &Types = *ExpectedTypes; - - if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash) - return Error::success(); - std::unique_ptr<DictScope> StreamScope; std::unique_ptr<ListScope> RecordScope; @@ -628,19 +624,25 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { P.printNumber(VerLabel, Tpi->getTpiVersion()); P.printNumber("Record count", Tpi->getNumTypeRecords()); + Optional<TypeDatabase> &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB; + std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors; + 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) - Dumper = make_unique<CompactTypeDumpVisitor>(Types, &P); + Dumper = make_unique<CompactTypeDumpVisitor>(*StreamDB, &P); else { - assert(TpiTypes); + assert(TypeDB.hasValue()); - auto X = make_unique<TypeDumpVisitor>(*TpiTypes, &P, false); + auto X = make_unique<TypeDumpVisitor>(*TypeDB, &P, false); if (StreamIdx == StreamIPI) - X->setIpiTypes(*IpiTypes); + X->setItemDB(*ItemDB); Dumper = std::move(X); } Visitors.push_back(std::move(Dumper)); @@ -658,17 +660,23 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { if (DumpRecords || DumpRecordBytes) RecordScope = llvm::make_unique<ListScope>(P, "Records"); - Optional<TypeIndex> I = Types.getFirst(); - do { + bool HadError = false; + + TypeIndex T(TypeIndex::FirstNonSimpleIndex); + for (auto Type : Tpi->types(&HadError)) { std::unique_ptr<DictScope> OneRecordScope; if ((DumpRecords || DumpRecordBytes) && !opts::raw::CompactRecords) OneRecordScope = llvm::make_unique<DictScope>(P, ""); - auto T = Types.getType(*I); - if (auto EC = codeview::visitTypeRecord(T, *I, Pipeline)) + if (auto EC = codeview::visitTypeRecord(Type, Pipeline)) return EC; - } while ((I = Types.getNext(*I))); + + ++T; + } + if (HadError) + return make_error<RawError>(raw_error_code::corrupt_file, + "TPI stream contained corrupt record"); if (DumpTpiHash) { DictScope DD(P, "Hash"); @@ -703,26 +711,35 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) { return Error::success(); } -Expected<codeview::LazyRandomTypeCollection &> -LLVMOutputStyle::initializeTypeDatabase(uint32_t SN) { - auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes; +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(); - if (!TypeCollection) { - // Initialize the type collection, even if we're not going to dump it. This - // way if some other part of the dumper decides it wants to use some or all - // of the records for whatever purposes, it can still access them lazily. - auto &Types = Tpi->typeArray(); - uint32_t Count = Tpi->getNumTypeRecords(); - auto Offsets = Tpi->getTypeIndexOffsets(); - TypeCollection = - llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets); - } + DB.emplace(Tpi->getNumTypeRecords()); + + TypeDatabaseVisitor DBV(*DB); + + auto HashValues = Tpi->getHashValues(); + if (HashValues.empty()) + return codeview::visitTypeStream(Tpi->typeArray(), DBV); - return *TypeCollection; + TypeVisitorCallbackPipeline Pipeline; + Pipeline.addCallbackToPipeline(DBV); + + TpiHashVerifier HashVerifier(HashValues, Tpi->getNumHashBuckets()); + Pipeline.addCallbackToPipeline(HashVerifier); + + return codeview::visitTypeStream(Tpi->typeArray(), Pipeline); } Error LLVMOutputStyle::dumpDbiStream() { @@ -797,13 +814,11 @@ Error LLVMOutputStyle::dumpDbiStream() { return EC; if (ShouldDumpSymbols) { - auto ExpectedTypes = initializeTypeDatabase(StreamTPI); - if (!ExpectedTypes) - return ExpectedTypes.takeError(); - auto &Types = *ExpectedTypes; + if (auto EC = buildTypeDatabase(StreamTPI)) + return EC; ListScope SS(P, "Symbols"); - codeview::CVSymbolDumper SD(P, Types, nullptr, false); + codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false); bool HadError = false; for (auto S : ModS.symbols(&HadError)) { DictScope LL(P, ""); @@ -824,11 +839,10 @@ Error LLVMOutputStyle::dumpDbiStream() { } if (opts::raw::DumpLineInfo) { ListScope SS(P, "LineInfo"); - auto ExpectedTypes = initializeTypeDatabase(StreamIPI); - if (!ExpectedTypes) - return ExpectedTypes.takeError(); - auto &IpiItems = *ExpectedTypes; - C13RawVisitor V(P, File, IpiItems); + if (auto EC = buildTypeDatabase(StreamIPI)) + return EC; + + C13RawVisitor V(P, File, *ItemDB); if (auto EC = codeview::visitModuleDebugFragments( ModS.linesAndChecksums(), V)) return EC; @@ -946,12 +960,10 @@ Error LLVMOutputStyle::dumpPublicsStream() { P.printList("Section Offsets", Publics->getSectionOffsets(), printSectionOffset); ListScope L(P, "Symbols"); - auto ExpectedTypes = initializeTypeDatabase(StreamTPI); - if (!ExpectedTypes) - return ExpectedTypes.takeError(); - auto &Tpi = *ExpectedTypes; + if (auto EC = buildTypeDatabase(StreamTPI)) + return EC; - codeview::CVSymbolDumper SD(P, Tpi, nullptr, false); + codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false); bool HadError = false; for (auto S : Publics->getSymbols(&HadError)) { DictScope DD(P, ""); |