diff options
author | Zachary Turner <zturner@google.com> | 2016-07-11 21:45:26 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-07-11 21:45:26 +0000 |
commit | dbeaea7b357fb4343d01ffa466f3dcab1e57d392 (patch) | |
tree | f1fd778564c5e85b31e96504ee26b49424b00823 /llvm/lib/DebugInfo/PDB | |
parent | f6b93824677a9aaab59989f7f402010fda6bd63c (diff) | |
download | bcm5719-llvm-dbeaea7b357fb4343d01ffa466f3dcab1e57d392.tar.gz bcm5719-llvm-dbeaea7b357fb4343d01ffa466f3dcab1e57d392.zip |
Refactor the PDB writing to use a builder approach
llvm-svn: 275110
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 3 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 47 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp | 76 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp | 69 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp | 127 |
7 files changed, 276 insertions, 121 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index ffeb56c28ed..669298952f2 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -29,16 +29,19 @@ endif() add_pdb_impl_folder(Raw Raw/DbiStream.cpp + Raw/DbiStreamBuilder.cpp Raw/EnumTables.cpp Raw/Hash.cpp Raw/IndexedStreamData.cpp Raw/InfoStream.cpp + Raw/InfoStreamBuilder.cpp Raw/MappedBlockStream.cpp Raw/ModInfo.cpp Raw/ModStream.cpp Raw/NameHashTable.cpp Raw/NameMap.cpp Raw/PDBFile.cpp + Raw/PDBFileBuilder.cpp Raw/PublicsStream.cpp Raw/RawError.cpp Raw/RawSession.cpp diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index ec807a29a03..bfe0251f4ce 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -11,6 +11,7 @@ #include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h" #include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" @@ -53,31 +54,16 @@ const uint16_t BuildMinorShift = 0; const uint16_t BuildMajorMask = 0x7F00; const uint16_t BuildMajorShift = 8; -} -struct DbiStream::HeaderInfo { - little32_t VersionSignature; - ulittle32_t VersionHeader; - ulittle32_t Age; // Should match InfoStream. - ulittle16_t GlobalSymbolStreamIndex; // Global symbol stream # - ulittle16_t BuildNumber; // See DbiBuildNo structure. - ulittle16_t PublicSymbolStreamIndex; // Public symbols stream # - ulittle16_t PdbDllVersion; // version of mspdbNNN.dll - ulittle16_t SymRecordStreamIndex; // Symbol records stream # - ulittle16_t PdbDllRbld; // rbld number of mspdbNNN.dll - little32_t ModiSubstreamSize; // Size of module info stream - little32_t SecContrSubstreamSize; // Size of sec. contribution stream - little32_t SectionMapSize; // Size of sec. map substream - little32_t FileInfoSize; // Size of file info substream - little32_t TypeServerSize; // Size of type server map - ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server - little32_t OptionalDbgHdrSize; // Size of DbgHeader info - little32_t ECSubstreamSize; // Size of EC stream (what is EC?) - ulittle16_t Flags; // See DbiFlags enum. - ulittle16_t MachineType; // See PDB_MachineType enum. - - ulittle32_t Reserved; // Pad to 64 bytes +struct FileInfoSubstreamHeader { + ulittle16_t NumModules; // Total # of modules, should match number of + // records in the ModuleInfo substream. + ulittle16_t NumSourceFiles; // Total # of source files. This value is not + // accurate because PDB actually supports more + // than 64k source files, so we ignore it and + // compute the value from other stream fields. }; +} template <typename ContribType> static Error loadSectionContribs(FixedStreamArray<ContribType> &Output, @@ -218,6 +204,8 @@ uint16_t DbiStream::getGlobalSymbolStreamIndex() const { return Header->GlobalSymbolStreamIndex; } +uint16_t DbiStream::getFlags() const { return Header->Flags; } + bool DbiStream::isIncrementallyLinked() const { return (Header->Flags & FlagIncrementalMask) != 0; } @@ -230,6 +218,8 @@ bool DbiStream::isStripped() const { return (Header->Flags & FlagStrippedMask) != 0; } +uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; } + uint16_t DbiStream::getBuildMajorVersion() const { return (Header->BuildNumber & BuildMajorMask) >> BuildMajorShift; } @@ -238,6 +228,8 @@ uint16_t DbiStream::getBuildMinorVersion() const { return (Header->BuildNumber & BuildMinorMask) >> BuildMinorShift; } +uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; } + uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; } uint32_t DbiStream::getSymRecordStreamIndex() const { @@ -353,15 +345,6 @@ Error DbiStream::initializeSectionMapData() { } Error DbiStream::initializeFileInfo() { - struct FileInfoSubstreamHeader { - ulittle16_t NumModules; // Total # of modules, should match number of - // records in the ModuleInfo substream. - ulittle16_t NumSourceFiles; // Total # of source files. This value is not - // accurate because PDB actually supports more - // than 64k source files, so we ignore it and - // compute the value from other stream fields. - }; - // The layout of the FileInfoSubstream is like this: // struct { // ulittle16_t NumModules; diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp new file mode 100644 index 00000000000..ff5ce61c212 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp @@ -0,0 +1,76 @@ +//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" + +#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +DbiStreamBuilder::DbiStreamBuilder(PDBFile &File) + : File(File), Age(1), BuildNumber(0), PdbDllVersion(0), PdbDllRbld(0), + Flags(0), MachineType(PDB_Machine::x86) {} + +void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; } + +void DbiStreamBuilder::setAge(uint32_t A) { Age = A; } + +void DbiStreamBuilder::setBuildNumber(uint16_t B) { BuildNumber = B; } + +void DbiStreamBuilder::setPdbDllVersion(uint16_t V) { PdbDllVersion = V; } + +void DbiStreamBuilder::setPdbDllRbld(uint16_t R) { PdbDllRbld = R; } + +void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; } + +void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; } + +Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build() { + if (!VerHeader.hasValue()) + return make_error<RawError>(raw_error_code::unspecified, + "Missing DBI Stream Version"); + + auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, File); + if (!DbiS) + return DbiS.takeError(); + auto DS = std::move(*DbiS); + DbiStream::HeaderInfo *H = + static_cast<DbiStream::HeaderInfo *>(DS->getAllocator().Allocate( + sizeof(DbiStream::HeaderInfo), + llvm::AlignOf<DbiStream::HeaderInfo>::Alignment)); + H->VersionHeader = *VerHeader; + H->VersionSignature = -1; + H->Age = Age; + H->BuildNumber = BuildNumber; + H->Flags = Flags; + H->PdbDllRbld = PdbDllRbld; + H->PdbDllVersion = PdbDllVersion; + H->MachineType = static_cast<uint16_t>(MachineType); + + H->ECSubstreamSize = 0; + H->FileInfoSize = 0; + H->ModiSubstreamSize = 0; + H->OptionalDbgHdrSize = 0; + H->SecContrSubstreamSize = 0; + H->SectionMapSize = 0; + H->TypeServerSize = 0; + H->SymRecordStreamIndex = DbiStream::InvalidStreamIndex; + H->PublicSymbolStreamIndex = DbiStream::InvalidStreamIndex; + H->MFCTypeServerIndex = DbiStream::InvalidStreamIndex; + H->GlobalSymbolStreamIndex = DbiStream::InvalidStreamIndex; + + auto Dbi = llvm::make_unique<DbiStream>(File, std::move(DS)); + Dbi->Header = H; + return std::move(Dbi); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp index 5273118f7c2..e2f85ab880f 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp @@ -21,15 +21,6 @@ using namespace llvm; using namespace llvm::codeview; using namespace llvm::pdb; -namespace { -struct Header { - support::ulittle32_t Version; - support::ulittle32_t Signature; - support::ulittle32_t Age; - PDB_UniqueId Guid; -}; -} - InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream) : Stream(std::move(Stream)) {} @@ -84,16 +75,6 @@ uint32_t InfoStream::getAge() const { return Age; } PDB_UniqueId InfoStream::getGuid() const { return Guid; } -void InfoStream::setVersion(PdbRaw_ImplVer Ver) { - Version = static_cast<uint32_t>(Ver); -} - -void InfoStream::setSignature(uint32_t Sig) { Signature = Sig; } - -void InfoStream::setAge(uint32_t Age) { this->Age = Age; } - -void InfoStream::setGuid(PDB_UniqueId Guid) { this->Guid = Guid; } - Error InfoStream::commit() { StreamWriter Writer(*Stream); @@ -106,4 +87,4 @@ Error InfoStream::commit() { return EC; return NamedStreams.commit(Writer); -} +}
\ No newline at end of file diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp new file mode 100644 index 00000000000..21042e9a534 --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp @@ -0,0 +1,54 @@ +//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h" + +#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +InfoStreamBuilder::InfoStreamBuilder(IPDBFile &File) : File(File) {} + +void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; } + +void InfoStreamBuilder::setSignature(uint32_t S) { Sig = S; } + +void InfoStreamBuilder::setAge(uint32_t A) { Age = A; } + +void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; } + +Expected<std::unique_ptr<InfoStream>> InfoStreamBuilder::build() { + if (!Ver.hasValue()) + return make_error<RawError>(raw_error_code::unspecified, + "Missing PDB Stream Version"); + if (!Sig.hasValue()) + return make_error<RawError>(raw_error_code::unspecified, + "Missing PDB Stream Signature"); + if (!Age.hasValue()) + return make_error<RawError>(raw_error_code::unspecified, + "Missing PDB Stream Age"); + if (!Guid.hasValue()) + return make_error<RawError>(raw_error_code::unspecified, + "Missing PDB Stream Guid"); + + auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, File); + if (!InfoS) + return InfoS.takeError(); + auto Info = llvm::make_unique<InfoStream>(std::move(*InfoS)); + Info->Version = *Ver; + Info->Signature = *Sig; + Info->Age = *Age; + Info->Guid = *Guid; + return std::move(Info); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index ce2446cba80..2aa4d4c426f 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -173,17 +173,6 @@ llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const { return DirectoryBlocks; } -Expected<InfoStream &> PDBFile::emplacePDBInfoStream() { - if (Info) - Info.reset(); - - auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this); - if (!InfoS) - return InfoS.takeError(); - Info = llvm::make_unique<InfoStream>(std::move(*InfoS)); - return *Info; -} - Expected<InfoStream &> PDBFile::getPDBInfoStream() { if (!Info) { auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this); @@ -352,64 +341,6 @@ Error PDBFile::setSuperBlock(const SuperBlock *Block) { return Error::success(); } -void PDBFile::setStreamSizes(ArrayRef<support::ulittle32_t> Sizes) { - StreamSizes = Sizes; -} - -void PDBFile::setStreamMap( - std::vector<ArrayRef<support::ulittle32_t>> &Streams) { - StreamMap = Streams; -} - -void PDBFile::setDirectoryBlocks(ArrayRef<support::ulittle32_t> Directory) { - DirectoryBlocks = Directory; -} - -Error PDBFile::generateSimpleStreamMap() { - if (StreamSizes.empty()) - return Error::success(); - - static std::vector<std::vector<support::ulittle32_t>> StaticMap; - StreamMap.clear(); - StaticMap.clear(); - - // Figure out how many blocks are needed for all streams, and set the first - // used block to the highest block so that we can write the rest of the - // blocks contiguously. - uint32_t TotalFileBlocks = getBlockCount(); - std::vector<support::ulittle32_t> ReservedBlocks; - ReservedBlocks.push_back(support::ulittle32_t(0)); - ReservedBlocks.push_back(SB->BlockMapAddr); - ReservedBlocks.insert(ReservedBlocks.end(), DirectoryBlocks.begin(), - DirectoryBlocks.end()); - - uint32_t BlocksNeeded = 0; - for (auto Size : StreamSizes) - BlocksNeeded += bytesToBlocks(Size, getBlockSize()); - - support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded - - ReservedBlocks.size()); - - StaticMap.resize(StreamSizes.size()); - for (uint32_t S = 0; S < StreamSizes.size(); ++S) { - uint32_t Size = StreamSizes[S]; - uint32_t NumBlocks = bytesToBlocks(Size, getBlockSize()); - auto &ThisStream = StaticMap[S]; - for (uint32_t I = 0; I < NumBlocks;) { - NextBlock += 1; - if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) != - ReservedBlocks.end()) - continue; - - ++I; - assert(NextBlock < getBlockCount()); - ThisStream.push_back(NextBlock); - } - StreamMap.push_back(ThisStream); - } - return Error::success(); -} - Error PDBFile::commit() { StreamWriter Writer(*Buffer); diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp new file mode 100644 index 00000000000..f859c1fcc2e --- /dev/null +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp @@ -0,0 +1,127 @@ +//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h" + +#include "llvm/DebugInfo/CodeView/StreamInterface.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Raw/RawError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::pdb; + +PDBFileBuilder::PDBFileBuilder( + std::unique_ptr<codeview::StreamInterface> PdbFileBuffer) + : File(llvm::make_unique<PDBFile>(std::move(PdbFileBuffer))) {} + +Error PDBFileBuilder::setSuperBlock(const PDBFile::SuperBlock &B) { + auto SB = static_cast<PDBFile::SuperBlock *>( + File->Allocator.Allocate(sizeof(PDBFile::SuperBlock), + llvm::AlignOf<PDBFile::SuperBlock>::Alignment)); + ::memcpy(SB, &B, sizeof(PDBFile::SuperBlock)); + return File->setSuperBlock(SB); +} + +void PDBFileBuilder::setStreamSizes(ArrayRef<support::ulittle32_t> S) { + File->StreamSizes = S; +} + +void PDBFileBuilder::setDirectoryBlocks(ArrayRef<support::ulittle32_t> D) { + File->DirectoryBlocks = D; +} + +void PDBFileBuilder::setStreamMap( + const std::vector<ArrayRef<support::ulittle32_t>> &S) { + File->StreamMap = S; +} + +Error PDBFileBuilder::generateSimpleStreamMap() { + if (File->StreamSizes.empty()) + return Error::success(); + + static std::vector<std::vector<support::ulittle32_t>> StaticMap; + File->StreamMap.clear(); + StaticMap.clear(); + + // Figure out how many blocks are needed for all streams, and set the first + // used block to the highest block so that we can write the rest of the + // blocks contiguously. + uint32_t TotalFileBlocks = File->getBlockCount(); + std::vector<support::ulittle32_t> ReservedBlocks; + ReservedBlocks.push_back(support::ulittle32_t(0)); + ReservedBlocks.push_back(File->SB->BlockMapAddr); + ReservedBlocks.insert(ReservedBlocks.end(), File->DirectoryBlocks.begin(), + File->DirectoryBlocks.end()); + + uint32_t BlocksNeeded = 0; + for (auto Size : File->StreamSizes) + BlocksNeeded += File->bytesToBlocks(Size, File->getBlockSize()); + + support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded - + ReservedBlocks.size()); + + StaticMap.resize(File->StreamSizes.size()); + for (uint32_t S = 0; S < File->StreamSizes.size(); ++S) { + uint32_t Size = File->StreamSizes[S]; + uint32_t NumBlocks = File->bytesToBlocks(Size, File->getBlockSize()); + auto &ThisStream = StaticMap[S]; + for (uint32_t I = 0; I < NumBlocks;) { + NextBlock += 1; + if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) != + ReservedBlocks.end()) + continue; + + ++I; + assert(NextBlock < File->getBlockCount()); + ThisStream.push_back(NextBlock); + } + File->StreamMap.push_back(ThisStream); + } + return Error::success(); +} + +InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() { + if (!Info) + Info = llvm::make_unique<InfoStreamBuilder>(*File); + return *Info; +} + +DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() { + if (!Dbi) + Dbi = llvm::make_unique<DbiStreamBuilder>(*File); + return *Dbi; +} + +Expected<std::unique_ptr<PDBFile>> PDBFileBuilder::build() { + if (Info) { + auto ExpectedInfo = Info->build(); + if (!ExpectedInfo) + return ExpectedInfo.takeError(); + File->Info = std::move(*ExpectedInfo); + } + + if (Dbi) { + auto ExpectedDbi = Dbi->build(); + if (!ExpectedDbi) + return ExpectedDbi.takeError(); + File->Dbi = std::move(*ExpectedDbi); + } + + if (File->Info && File->Dbi && File->Info->getAge() != File->Dbi->getAge()) + return llvm::make_error<RawError>( + raw_error_code::corrupt_file, + "PDB Stream Age doesn't match Dbi Stream Age!"); + + return std::move(File); +} |