diff options
Diffstat (limited to 'lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp')
| -rw-r--r-- | lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp index 9f35fd73629c..dee27c621fac 100644 --- a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp @@ -15,10 +15,10 @@ #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" -#include "llvm/DebugInfo/PDB/Native/PublicsStreamBuilder.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" @@ -74,10 +74,10 @@ PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; } -PublicsStreamBuilder &PDBFileBuilder::getPublicsBuilder() { - if (!Publics) - Publics = llvm::make_unique<PublicsStreamBuilder>(*Msf); - return *Publics; +GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() { + if (!Gsi) + Gsi = llvm::make_unique<GSIStreamBuilder>(*Msf); + return *Gsi; } Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) { @@ -122,12 +122,13 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() { if (auto EC = Ipi->finalizeMsfLayout()) return std::move(EC); } - if (Publics) { - if (auto EC = Publics->finalizeMsfLayout()) + if (Gsi) { + if (auto EC = Gsi->finalizeMsfLayout()) return std::move(EC); if (Dbi) { - Dbi->setPublicsStreamIndex(Publics->getStreamIndex()); - Dbi->setSymbolRecordStreamIndex(Publics->getRecordStreamIdx()); + Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex()); + Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex()); + Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIdx()); } } @@ -141,6 +142,31 @@ Expected<uint32_t> PDBFileBuilder::getNamedStreamIndex(StringRef Name) const { return SN; } +void PDBFileBuilder::commitFpm(WritableBinaryStream &MsfBuffer, + const MSFLayout &Layout) { + auto FpmStream = + WritableMappedBlockStream::createFpmStream(Layout, MsfBuffer, Allocator); + + // We only need to create the alt fpm stream so that it gets initialized. + WritableMappedBlockStream::createFpmStream(Layout, MsfBuffer, Allocator, + true); + + uint32_t BI = 0; + BinaryStreamWriter FpmWriter(*FpmStream); + while (BI < Layout.SB->NumBlocks) { + uint8_t ThisByte = 0; + for (uint32_t I = 0; I < 8; ++I) { + bool IsFree = + (BI < Layout.SB->NumBlocks) ? Layout.FreePageMap.test(BI) : true; + uint8_t Mask = uint8_t(IsFree) << I; + ThisByte |= Mask; + ++BI; + } + cantFail(FpmWriter.writeObject(ThisByte)); + } + assert(FpmWriter.bytesRemaining() == 0); +} + Error PDBFileBuilder::commit(StringRef Filename) { assert(!Filename.empty()); auto ExpectedLayout = finalizeMsfLayout(); @@ -150,15 +176,17 @@ Error PDBFileBuilder::commit(StringRef Filename) { uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks; auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize); - if (OutFileOrError.getError()) - return llvm::make_error<pdb::GenericError>(generic_error_code::invalid_path, - Filename); + if (auto E = OutFileOrError.takeError()) + return E; FileBufferByteStream Buffer(std::move(*OutFileOrError), llvm::support::little); BinaryStreamWriter Writer(Buffer); if (auto EC = Writer.writeObject(*Layout.SB)) return EC; + + commitFpm(Buffer, Layout); + uint32_t BlockMapOffset = msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize); Writer.setOffset(BlockMapOffset); @@ -209,11 +237,8 @@ Error PDBFileBuilder::commit(StringRef Filename) { return EC; } - if (Publics) { - auto PS = WritableMappedBlockStream::createIndexedStream( - Layout, Buffer, Publics->getStreamIndex(), Allocator); - BinaryStreamWriter PSWriter(*PS); - if (auto EC = Publics->commit(PSWriter)) + if (Gsi) { + if (auto EC = Gsi->commit(Layout, Buffer)) return EC; } |
