diff options
Diffstat (limited to 'contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp')
-rw-r--r-- | contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp | 130 |
1 files changed, 88 insertions, 42 deletions
diff --git a/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp index 9063fd6..6fec0e3 100644 --- a/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp +++ b/contrib/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp @@ -11,92 +11,138 @@ #include "llvm/ADT/BitVector.h" -#include "llvm/DebugInfo/CodeView/StreamInterface.h" -#include "llvm/DebugInfo/CodeView/StreamWriter.h" +#include "llvm/DebugInfo/MSF/MSFBuilder.h" +#include "llvm/DebugInfo/MSF/StreamInterface.h" +#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/DebugInfo/PDB/GenericError.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" +#include "llvm/DebugInfo/PDB/Raw/TpiStream.h" +#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h" using namespace llvm; using namespace llvm::codeview; +using namespace llvm::msf; using namespace llvm::pdb; using namespace llvm::support; -PDBFileBuilder::PDBFileBuilder( - std::unique_ptr<codeview::StreamInterface> FileBuffer) - : File(llvm::make_unique<PDBFile>(std::move(FileBuffer))) {} +PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator) + : Allocator(Allocator) {} -Error PDBFileBuilder::initialize(const msf::SuperBlock &Super) { - auto ExpectedMsf = - MsfBuilder::create(File->Allocator, Super.BlockSize, Super.NumBlocks); +Error PDBFileBuilder::initialize(uint32_t BlockSize) { + auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize); if (!ExpectedMsf) return ExpectedMsf.takeError(); - - auto &MsfResult = *ExpectedMsf; - if (auto EC = MsfResult.setBlockMapAddr(Super.BlockMapAddr)) - return EC; - Msf = llvm::make_unique<MsfBuilder>(std::move(MsfResult)); - Msf->setFreePageMap(Super.FreeBlockMapBlock); - Msf->setUnknown1(Super.Unknown1); + Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf)); return Error::success(); } -MsfBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; } +MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; } InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() { if (!Info) - Info = llvm::make_unique<InfoStreamBuilder>(); + Info = llvm::make_unique<InfoStreamBuilder>(*Msf); return *Info; } DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() { if (!Dbi) - Dbi = llvm::make_unique<DbiStreamBuilder>(); + Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf); return *Dbi; } -Expected<std::unique_ptr<PDBFile>> PDBFileBuilder::build() { +TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() { + if (!Tpi) + Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI); + return *Tpi; +} + +TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() { + if (!Ipi) + Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI); + return *Ipi; +} + +Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const { if (Info) { - uint32_t Length = Info->calculateSerializedLength(); - if (auto EC = Msf->setStreamSize(StreamPDB, Length)) + if (auto EC = Info->finalizeMsfLayout()) return std::move(EC); } if (Dbi) { - uint32_t Length = Dbi->calculateSerializedLength(); - if (auto EC = Msf->setStreamSize(StreamDBI, Length)) + if (auto EC = Dbi->finalizeMsfLayout()) return std::move(EC); } + if (Tpi) { + if (auto EC = Tpi->finalizeMsfLayout()) + return std::move(EC); + } + if (Ipi) { + if (auto EC = Ipi->finalizeMsfLayout()) + return std::move(EC); + } + + return Msf->build(); +} - auto ExpectedLayout = Msf->build(); +Error PDBFileBuilder::commit(StringRef Filename) { + auto ExpectedLayout = finalizeMsfLayout(); if (!ExpectedLayout) return ExpectedLayout.takeError(); + auto &Layout = *ExpectedLayout; - const msf::Layout &L = *ExpectedLayout; - File->StreamMap = L.StreamMap; - File->StreamSizes = L.StreamSizes; - File->DirectoryBlocks = L.DirectoryBlocks; - File->SB = L.SB; + 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); + FileBufferByteStream Buffer(std::move(*OutFileOrError)); + StreamWriter Writer(Buffer); + + if (auto EC = Writer.writeObject(*Layout.SB)) + return EC; + uint32_t BlockMapOffset = + msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize); + Writer.setOffset(BlockMapOffset); + if (auto EC = Writer.writeArray(Layout.DirectoryBlocks)) + return EC; + + auto DirStream = + WritableMappedBlockStream::createDirectoryStream(Layout, Buffer); + StreamWriter DW(*DirStream); + if (auto EC = + DW.writeInteger(static_cast<uint32_t>(Layout.StreamSizes.size()))) + return EC; + + if (auto EC = DW.writeArray(Layout.StreamSizes)) + return EC; + + for (const auto &Blocks : Layout.StreamMap) { + if (auto EC = DW.writeArray(Blocks)) + return EC; + } if (Info) { - auto ExpectedInfo = Info->build(*File); - if (!ExpectedInfo) - return ExpectedInfo.takeError(); - File->Info = std::move(*ExpectedInfo); + if (auto EC = Info->commit(Layout, Buffer)) + return EC; } if (Dbi) { - auto ExpectedDbi = Dbi->build(*File); - if (!ExpectedDbi) - return ExpectedDbi.takeError(); - File->Dbi = std::move(*ExpectedDbi); + if (auto EC = Dbi->commit(Layout, Buffer)) + return EC; } - 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!"); + if (Tpi) { + if (auto EC = Tpi->commit(Layout, Buffer)) + return EC; + } + + if (Ipi) { + if (auto EC = Ipi->commit(Layout, Buffer)) + return EC; + } - return std::move(File); + return Buffer.commit(); } |