diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp | 103 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | 18 |
8 files changed, 143 insertions, 89 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index 90bc2a2e556..ae3faa700c1 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -93,19 +93,17 @@ Error loadSectionContribs(FixedStreamArray<ContribType> &Output, return Error::success(); } -DbiStream::DbiStream(PDBFile &File) - : Pdb(File), - Stream(llvm::make_unique<IndexedStreamData>(StreamDBI, File), File), - Header(nullptr) { +DbiStream::DbiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream) + : Pdb(File), Stream(std::move(Stream)), Header(nullptr) { static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!"); } DbiStream::~DbiStream() {} Error DbiStream::reload() { - StreamReader Reader(Stream); + StreamReader Reader(*Stream); - if (Stream.getLength() < sizeof(HeaderInfo)) + if (Stream->getLength() < sizeof(HeaderInfo)) return make_error<RawError>(raw_error_code::corrupt_file, "DBI Stream does not contain a header."); if (auto EC = Reader.readObject(Header)) @@ -123,15 +121,15 @@ Error DbiStream::reload() { return make_error<RawError>(raw_error_code::feature_unsupported, "Unsupported DBI version."); - auto InfoStream = Pdb.getPDBInfoStream(); - if (auto EC = InfoStream.takeError()) - return EC; + auto IS = Pdb.getPDBInfoStream(); + if (!IS) + return IS.takeError(); - if (Header->Age != InfoStream.get().getAge()) + if (Header->Age != IS->getAge()) return make_error<RawError>(raw_error_code::corrupt_file, "DBI Age does not match PDB Age."); - if (Stream.getLength() != + if (Stream->getLength() != sizeof(HeaderInfo) + Header->ModiSubstreamSize + Header->SecContrSubstreamSize + Header->SectionMapSize + Header->FileInfoSize + Header->TypeServerSize + @@ -296,19 +294,22 @@ Error DbiStream::initializeSectionHeadersData() { if (StreamNum >= Pdb.getNumStreams()) return make_error<RawError>(raw_error_code::no_stream); - SectionHeaderStream.reset(new MappedBlockStream( - llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb)); + auto SHS = MappedBlockStream::createIndexedStream(StreamNum, Pdb); + if (!SHS) + return SHS.takeError(); - size_t StreamLen = SectionHeaderStream->getLength(); + size_t StreamLen = (*SHS)->getLength(); if (StreamLen % sizeof(object::coff_section)) return make_error<RawError>(raw_error_code::corrupt_file, "Corrupted section header stream."); size_t NumSections = StreamLen / sizeof(object::coff_section); - codeview::StreamReader Reader(*SectionHeaderStream); + codeview::StreamReader Reader(**SHS); if (auto EC = Reader.readArray(SectionHeaders, NumSections)) return make_error<RawError>(raw_error_code::corrupt_file, "Could not read a bitmap."); + + SectionHeaderStream = std::move(*SHS); return Error::success(); } @@ -318,19 +319,21 @@ Error DbiStream::initializeFpoRecords() { if (StreamNum >= Pdb.getNumStreams()) return make_error<RawError>(raw_error_code::no_stream); - FpoStream.reset(new MappedBlockStream( - llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb)); + auto FS = MappedBlockStream::createIndexedStream(StreamNum, Pdb); + if (!FS) + return FS.takeError(); - size_t StreamLen = FpoStream->getLength(); + size_t StreamLen = (*FS)->getLength(); if (StreamLen % sizeof(object::FpoData)) return make_error<RawError>(raw_error_code::corrupt_file, "Corrupted New FPO stream."); size_t NumRecords = StreamLen / sizeof(object::FpoData); - codeview::StreamReader Reader(*FpoStream); + codeview::StreamReader Reader(**FS); if (auto EC = Reader.readArray(FpoRecords, NumRecords)) return make_error<RawError>(raw_error_code::corrupt_file, "Corrupted New FPO stream."); + FpoStream = std::move(*FS); return Error::success(); } @@ -418,10 +421,10 @@ Error DbiStream::initializeFileInfo() { uint32_t NumFiles = ModFileCountArray[I]; ModuleInfos[I].SourceFiles.resize(NumFiles); for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) { - if (auto Name = getFileNameForIndex(NextFileIndex)) - ModuleInfos[I].SourceFiles[J] = Name.get(); - else - return Name.takeError(); + auto ThisName = getFileNameForIndex(NextFileIndex); + if (!ThisName) + return ThisName.takeError(); + ModuleInfos[I].SourceFiles[J] = *ThisName; } } diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp index 0f2fd24395c..00671edf8e3 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp @@ -19,11 +19,11 @@ using namespace llvm; using namespace llvm::pdb; -InfoStream::InfoStream(const PDBFile &File) - : Stream(llvm::make_unique<IndexedStreamData>(StreamPDB, File), File) {} +InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream) + : Stream(std::move(Stream)) {} Error InfoStream::reload() { - codeview::StreamReader Reader(Stream); + codeview::StreamReader Reader(*Stream); struct Header { support::ulittle32_t Version; diff --git a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp index 3428ff83471..cae33768af6 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp @@ -8,13 +8,27 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Raw/DirectoryStreamData.h" #include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h" +#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" using namespace llvm; using namespace llvm::pdb; +namespace { +// This exists so that we can use make_unique while still keeping the +// constructor of MappedBlockStream private, forcing users to go through +// the `create` interface. +class MappedBlockStreamImpl : public MappedBlockStream { +public: + MappedBlockStreamImpl(std::unique_ptr<IPDBStreamData> Data, + const IPDBFile &File) + : MappedBlockStream(std::move(Data), File) {} +}; +} + MappedBlockStream::MappedBlockStream(std::unique_ptr<IPDBStreamData> Data, const IPDBFile &Pdb) : Pdb(Pdb), Data(std::move(Data)) {} @@ -122,3 +136,19 @@ Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t MappedBlockStream::getNumBytesCopied() const { return static_cast<uint32_t>(Pool.getBytesAllocated()); } + +Expected<std::unique_ptr<MappedBlockStream>> +MappedBlockStream::createIndexedStream(uint32_t StreamIdx, + const IPDBFile &File) { + if (StreamIdx >= File.getNumStreams()) + return make_error<RawError>(raw_error_code::no_stream); + + auto Data = llvm::make_unique<IndexedStreamData>(StreamIdx, File); + return llvm::make_unique<MappedBlockStreamImpl>(std::move(Data), File); +} + +Expected<std::unique_ptr<MappedBlockStream>> +MappedBlockStream::createDirectoryStream(const PDBFile &File) { + auto Data = llvm::make_unique<DirectoryStreamData>(File); + return llvm::make_unique<MappedBlockStreamImpl>(std::move(Data), File); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp index 57c455e0a00..89673d247f2 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -19,15 +19,14 @@ using namespace llvm; using namespace llvm::pdb; -ModStream::ModStream(const PDBFile &File, const ModInfo &Module) - : Mod(Module), Stream(llvm::make_unique<IndexedStreamData>( - Module.getModuleStreamIndex(), File), - File) {} +ModStream::ModStream(const ModInfo &Module, + std::unique_ptr<MappedBlockStream> Stream) + : Mod(Module), Stream(std::move(Stream)) {} ModStream::~ModStream() {} Error ModStream::reload() { - codeview::StreamReader Reader(Stream); + codeview::StreamReader Reader(*Stream); uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize(); uint32_t C11Size = Mod.getLineInfoByteSize(); diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index 2796abf3ea5..086105b4ded 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -13,6 +13,7 @@ #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/DirectoryStreamData.h" #include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/NameHashTable.h" @@ -54,19 +55,6 @@ struct SuperBlock { support::ulittle32_t BlockMapAddr; }; -class DirectoryStreamData : public IPDBStreamData { -public: - DirectoryStreamData(const PDBFile &File) : File(File) {} - - virtual uint32_t getLength() { return File.getNumDirectoryBytes(); } - virtual llvm::ArrayRef<llvm::support::ulittle32_t> getStreamBlocks() { - return File.getDirectoryBlockArray(); - } - -private: - const PDBFile &File; -}; - typedef codeview::FixedStreamArray<support::ulittle32_t> ulittle_array; } @@ -222,9 +210,10 @@ Error PDBFile::parseStreamData() { // is exactly what we are attempting to parse. By specifying a custom // subclass of IPDBStreamData which only accesses the fields that have already // been parsed, we can avoid this and reuse MappedBlockStream. - auto SD = llvm::make_unique<DirectoryStreamData>(*this); - DirectoryStream = llvm::make_unique<MappedBlockStream>(std::move(SD), *this); - codeview::StreamReader Reader(*DirectoryStream); + auto DS = MappedBlockStream::createDirectoryStream(*this); + if (!DS) + return DS.takeError(); + codeview::StreamReader Reader(**DS); if (auto EC = Reader.readInteger(NumStreams)) return EC; @@ -241,6 +230,7 @@ Error PDBFile::parseStreamData() { // We should have read exactly SB->NumDirectoryBytes bytes. assert(Reader.bytesRemaining() == 0); + DirectoryStream = std::move(*DS); return Error::success(); } @@ -253,36 +243,52 @@ llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const { Expected<InfoStream &> PDBFile::getPDBInfoStream() { if (!Info) { - Info.reset(new InfoStream(*this)); - if (auto EC = Info->reload()) + auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this); + if (!InfoS) + return InfoS.takeError(); + auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS)); + if (auto EC = TempInfo->reload()) return std::move(EC); + Info = std::move(TempInfo); } return *Info; } Expected<DbiStream &> PDBFile::getPDBDbiStream() { if (!Dbi) { - Dbi.reset(new DbiStream(*this)); - if (auto EC = Dbi->reload()) + auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, *this); + if (!DbiS) + return DbiS.takeError(); + auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(*DbiS)); + if (auto EC = TempDbi->reload()) return std::move(EC); + Dbi = std::move(TempDbi); } return *Dbi; } Expected<TpiStream &> PDBFile::getPDBTpiStream() { if (!Tpi) { - Tpi.reset(new TpiStream(*this, StreamTPI)); - if (auto EC = Tpi->reload()) + auto TpiS = MappedBlockStream::createIndexedStream(StreamTPI, *this); + if (!TpiS) + return TpiS.takeError(); + auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS)); + if (auto EC = TempTpi->reload()) return std::move(EC); + Tpi = std::move(TempTpi); } return *Tpi; } Expected<TpiStream &> PDBFile::getPDBIpiStream() { if (!Ipi) { - Ipi.reset(new TpiStream(*this, StreamIPI)); - if (auto EC = Ipi->reload()) + auto IpiS = MappedBlockStream::createIndexedStream(StreamIPI, *this); + if (!IpiS) + return IpiS.takeError(); + auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS)); + if (auto EC = TempIpi->reload()) return std::move(EC); + Ipi = std::move(TempIpi); } return *Ipi; } @@ -290,13 +296,20 @@ Expected<TpiStream &> PDBFile::getPDBIpiStream() { Expected<PublicsStream &> PDBFile::getPDBPublicsStream() { if (!Publics) { auto DbiS = getPDBDbiStream(); - if (auto EC = DbiS.takeError()) - return std::move(EC); + if (!DbiS) + return DbiS.takeError(); + uint32_t PublicsStreamNum = DbiS->getPublicSymbolStreamIndex(); - Publics.reset(new PublicsStream(*this, PublicsStreamNum)); - if (auto EC = Publics->reload()) + auto PublicS = + MappedBlockStream::createIndexedStream(PublicsStreamNum, *this); + if (!PublicS) + return PublicS.takeError(); + auto TempPublics = + llvm::make_unique<PublicsStream>(*this, std::move(*PublicS)); + if (auto EC = TempPublics->reload()) return std::move(EC); + Publics = std::move(TempPublics); } return *Publics; } @@ -304,38 +317,46 @@ Expected<PublicsStream &> PDBFile::getPDBPublicsStream() { Expected<SymbolStream &> PDBFile::getPDBSymbolStream() { if (!Symbols) { auto DbiS = getPDBDbiStream(); - if (auto EC = DbiS.takeError()) - return std::move(EC); + if (!DbiS) + return DbiS.takeError(); + uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex(); - Symbols.reset(new SymbolStream(*this, SymbolStreamNum)); - if (auto EC = Symbols->reload()) + auto SymbolS = + MappedBlockStream::createIndexedStream(SymbolStreamNum, *this); + if (!SymbolS) + return SymbolS.takeError(); + auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS)); + if (auto EC = TempSymbols->reload()) return std::move(EC); + Symbols = std::move(TempSymbols); } return *Symbols; } Expected<NameHashTable &> PDBFile::getStringTable() { if (!StringTable || !StringTableStream) { - auto InfoS = getPDBInfoStream(); - if (auto EC = InfoS.takeError()) - return std::move(EC); - auto &IS = InfoS.get(); - uint32_t NameStreamIndex = IS.getNamedStreamIndex("/names"); + auto IS = getPDBInfoStream(); + if (!IS) + return IS.takeError(); + + uint32_t NameStreamIndex = IS->getNamedStreamIndex("/names"); if (NameStreamIndex == 0) return make_error<RawError>(raw_error_code::no_stream); if (NameStreamIndex >= getNumStreams()) return make_error<RawError>(raw_error_code::no_stream); - auto SD = llvm::make_unique<IndexedStreamData>(NameStreamIndex, *this); - auto S = llvm::make_unique<MappedBlockStream>(std::move(SD), *this); - codeview::StreamReader Reader(*S); + auto NS = MappedBlockStream::createIndexedStream(NameStreamIndex, *this); + if (!NS) + return NS.takeError(); + + codeview::StreamReader Reader(**NS); auto N = llvm::make_unique<NameHashTable>(); if (auto EC = N->load(Reader)) return std::move(EC); StringTable = std::move(N); - StringTableStream = std::move(S); + StringTableStream = std::move(*NS); } return *StringTable; } diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp index e3e100806ee..f768c01d4eb 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -71,9 +71,9 @@ struct PublicsStream::GSIHashHeader { ulittle32_t NumBuckets; }; -PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum) - : Pdb(File), StreamNum(StreamNum), - Stream(llvm::make_unique<IndexedStreamData>(StreamNum, File), File) {} +PublicsStream::PublicsStream(PDBFile &File, + std::unique_ptr<MappedBlockStream> Stream) + : Pdb(File), Stream(std::move(Stream)) {} PublicsStream::~PublicsStream() {} @@ -86,7 +86,7 @@ uint32_t PublicsStream::getAddrMap() const { return Header->AddrMap; } // we skip over the hash table which we believe contains information about // public symbols. Error PublicsStream::reload() { - codeview::StreamReader Reader(Stream); + codeview::StreamReader Reader(*Stream); // Check stream size. if (Reader.bytesRemaining() < sizeof(HeaderInfo) + sizeof(GSIHashHeader)) diff --git a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp index b6267a7f3f4..c8e93c26a7d 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp @@ -24,16 +24,15 @@ using namespace llvm; using namespace llvm::support; using namespace llvm::pdb; -SymbolStream::SymbolStream(const PDBFile &File, uint32_t StreamNum) - : MappedStream(llvm::make_unique<IndexedStreamData>(StreamNum, File), - File) {} +SymbolStream::SymbolStream(std::unique_ptr<MappedBlockStream> Stream) + : Stream(std::move(Stream)) {} SymbolStream::~SymbolStream() {} Error SymbolStream::reload() { - codeview::StreamReader Reader(MappedStream); + codeview::StreamReader Reader(*Stream); - if (auto EC = Reader.readArray(SymbolRecords, MappedStream.getLength())) + if (auto EC = Reader.readArray(SymbolRecords, Stream->getLength())) return EC; return Error::success(); diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp index f34a513f499..245e314bdaf 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -62,15 +62,14 @@ struct TpiStream::HeaderInfo { EmbeddedBuf HashAdjBuffer; }; -TpiStream::TpiStream(const PDBFile &File, uint32_t StreamIdx) - : Pdb(File), - Stream(llvm::make_unique<IndexedStreamData>(StreamIdx, File), File), - HashFunction(nullptr) {} +TpiStream::TpiStream(const PDBFile &File, + std::unique_ptr<MappedBlockStream> Stream) + : Pdb(File), Stream(std::move(Stream)), HashFunction(nullptr) {} TpiStream::~TpiStream() {} Error TpiStream::reload() { - codeview::StreamReader Reader(Stream); + codeview::StreamReader Reader(*Stream); if (Reader.bytesRemaining() < sizeof(HeaderInfo)) return make_error<RawError>(raw_error_code::corrupt_file, @@ -108,9 +107,11 @@ Error TpiStream::reload() { return make_error<RawError>(raw_error_code::corrupt_file, "Invalid TPI hash stream index."); - HashStream.reset(new MappedBlockStream( - llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb)); - codeview::StreamReader HSR(*HashStream); + auto HS = + MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb); + if (!HS) + return HS.takeError(); + codeview::StreamReader HSR(**HS); uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t); if (NumHashValues != NumTypeRecords()) @@ -133,6 +134,7 @@ Error TpiStream::reload() { if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments)) return EC; + HashStream = std::move(*HS); return Error::success(); } |