diff options
author | Zachary Turner <zturner@google.com> | 2016-07-06 18:05:57 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-07-06 18:05:57 +0000 |
commit | 8848a7a6b253b9bba64283d4d754c2b52138c48a (patch) | |
tree | cfd03e61893308c413012debf91315424ec968c4 /llvm/lib/DebugInfo/PDB | |
parent | 2ebe18b6098ea7ba78bba54c633d9c6c3357d786 (diff) | |
download | bcm5719-llvm-8848a7a6b253b9bba64283d4d754c2b52138c48a.tar.gz bcm5719-llvm-8848a7a6b253b9bba64283d4d754c2b52138c48a.zip |
[pdb] Round trip the PDB stream between YAML and binary PDB.
This gets writing of the PDB stream working.
llvm-svn: 274647
Diffstat (limited to 'llvm/lib/DebugInfo/PDB')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp | 51 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp | 94 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | 2 |
8 files changed, 164 insertions, 11 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index eba09bf0601..28250c588ff 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -452,3 +452,5 @@ Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const { return std::move(EC); return Name; } + +Error DbiStream::commit() { return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp index 00671edf8e3..5273118f7c2 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp @@ -11,27 +11,31 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" 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)) {} Error InfoStream::reload() { codeview::StreamReader Reader(*Stream); - struct Header { - support::ulittle32_t Version; - support::ulittle32_t Signature; - support::ulittle32_t Age; - PDB_UniqueId Guid; - }; - const Header *H; if (auto EC = Reader.readObject(H)) return joinErrors( @@ -39,9 +43,16 @@ Error InfoStream::reload() { make_error<RawError>(raw_error_code::corrupt_file, "PDB Stream does not contain a header.")); - if (H->Version < PdbRaw_ImplVer::PdbImplVC70) + switch (H->Version) { + case PdbImplVC70: + case PdbImplVC80: + case PdbImplVC110: + case PdbImplVC140: + break; + default: return make_error<RawError>(raw_error_code::corrupt_file, "Unsupported PDB stream version."); + } Version = H->Version; Signature = H->Signature; @@ -72,3 +83,27 @@ uint32_t InfoStream::getSignature() const { return Signature; } 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); + + Header H; + H.Age = Age; + H.Signature = Signature; + H.Version = Version; + H.Guid = Guid; + if (auto EC = Writer.writeObject(H)) + return EC; + + return NamedStreams.commit(Writer); +} diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp index e1c5e20067a..3415fcd4779 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -78,3 +78,5 @@ iterator_range<codeview::ModuleSubstreamArray::Iterator> ModStream::lines(bool *HadError) const { return llvm::make_range(LineInfo.begin(HadError), LineInfo.end()); } + +Error ModStream::commit() { return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp index 51ec66a1b9d..3638380eb22 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp @@ -10,9 +10,11 @@ #include "llvm/DebugInfo/PDB/Raw/NameMap.h" #include "llvm/ADT/SparseBitVector.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" using namespace llvm; +using namespace llvm::codeview; using namespace llvm::pdb; NameMap::NameMap() {} @@ -143,6 +145,24 @@ Error NameMap::load(codeview::StreamReader &Stream) { return Error::success(); } +Error NameMap::commit(codeview::StreamWriter &Writer) { + if (auto EC = Writer.writeInteger(0U)) // Number of bytes in table + return EC; + + if (auto EC = Writer.writeInteger(0U)) // Hash Size + return EC; + + if (auto EC = Writer.writeInteger(0U)) // Max Number of Strings + return EC; + + if (auto EC = Writer.writeInteger(0U)) // Num Present Words + return EC; + + if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words + return EC; + return Error::success(); +} + iterator_range<StringMapConstIterator<uint32_t>> NameMap::entries() const { return llvm::make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(), Mapping.end()); diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index cf0ef688b66..2d8e0d0ed91 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -89,7 +89,7 @@ Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset, return make_error<RawError>( raw_error_code::invalid_block_address, "setBlockData attempted to write out of block bounds."); - if (Data.size() >= getBlockSize() - Offset) + if (Data.size() > getBlockSize() - Offset) return make_error<RawError>( raw_error_code::invalid_block_address, "setBlockData attempted to write out of block bounds."); @@ -167,6 +167,17 @@ 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); @@ -340,12 +351,59 @@ void PDBFile::setStreamSizes(ArrayRef<support::ulittle32_t> Sizes) { } void PDBFile::setStreamMap( - ArrayRef<support::ulittle32_t> Directory, std::vector<ArrayRef<support::ulittle32_t>> &Streams) { - DirectoryBlocks = Directory; 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); @@ -371,5 +429,35 @@ Error PDBFile::commit() { return EC; } + if (Info) { + if (auto EC = Info->commit()) + return EC; + } + + if (Dbi) { + if (auto EC = Dbi->commit()) + return EC; + } + + if (Symbols) { + if (auto EC = Symbols->commit()) + return EC; + } + + if (Publics) { + if (auto EC = Publics->commit()) + return EC; + } + + if (Tpi) { + if (auto EC = Tpi->commit()) + return EC; + } + + if (Ipi) { + if (auto EC = Ipi->commit()) + return EC; + } + return Buffer->commit(); }
\ No newline at end of file diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp index f768c01d4eb..af3d2d026b4 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -169,3 +169,5 @@ PublicsStream::getSymbols(bool *HadError) const { return SS.getSymbols(HadError); } + +Error PublicsStream::commit() { return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp index c8e93c26a7d..41b2a64bfb1 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp @@ -42,3 +42,5 @@ iterator_range<codeview::CVSymbolArray::Iterator> SymbolStream::getSymbols(bool *HadError) const { return llvm::make_range(SymbolRecords.begin(HadError), SymbolRecords.end()); } + +Error SymbolStream::commit() { return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp index 7ff1e3dc8ce..8b44ec1b35e 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -269,3 +269,5 @@ iterator_range<CVTypeArray::Iterator> TpiStream::types(bool *HadError) const { return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end()); } + +Error TpiStream::commit() { return Error::success(); } |