summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp31
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp13
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp9
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/MsfBuilder.cpp47
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp26
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp53
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp115
9 files changed, 166 insertions, 135 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index d4d6fa80bc6..b5a2bc1600f 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -42,6 +42,7 @@ add_pdb_impl_folder(Raw
Raw/MsfCommon.cpp
Raw/NameHashTable.cpp
Raw/NameMap.cpp
+ Raw/NameMapBuilder.cpp
Raw/PDBFile.cpp
Raw/PDBFileBuilder.cpp
Raw/PublicsStream.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index bfe0251f4ce..3c0586c728f 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -182,9 +182,11 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"Found unexpected bytes in DBI Stream.");
- StreamReader ECReader(ECSubstream);
- if (auto EC = ECNames.load(ECReader))
- return EC;
+ if (ECSubstream.getLength() > 0) {
+ StreamReader ECReader(ECSubstream);
+ if (auto EC = ECNames.load(ECReader))
+ return EC;
+ }
return Error::success();
}
@@ -267,6 +269,9 @@ void llvm::pdb::DbiStream::visitSectionContributions(
}
Error DbiStream::initializeSectionContributionData() {
+ if (SecContrSubstream.getLength() == 0)
+ return Error::success();
+
StreamReader SCReader(SecContrSubstream);
if (auto EC = SCReader.readEnum(SectionContribVersion))
return EC;
@@ -282,6 +287,9 @@ Error DbiStream::initializeSectionContributionData() {
// Initializes this->SectionHeaders.
Error DbiStream::initializeSectionHeadersData() {
+ if (DbgStreams.size() == 0)
+ return Error::success();
+
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
if (StreamNum >= Pdb.getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
@@ -307,6 +315,9 @@ Error DbiStream::initializeSectionHeadersData() {
// Initializes this->Fpos.
Error DbiStream::initializeFpoRecords() {
+ if (DbgStreams.size() == 0)
+ return Error::success();
+
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
// This means there is no FPO data.
@@ -335,6 +346,9 @@ Error DbiStream::initializeFpoRecords() {
}
Error DbiStream::initializeSectionMapData() {
+ if (SecMapSubstream.getLength() == 0)
+ return Error::success();
+
StreamReader SMReader(SecMapSubstream);
const SecMapHeader *Header;
if (auto EC = SMReader.readObject(Header))
@@ -357,6 +371,9 @@ Error DbiStream::initializeFileInfo() {
// with the caveat that `NumSourceFiles` cannot be trusted, so
// it is computed by summing `ModFileCounts`.
//
+ if (FileInfoSubstream.getLength() == 0)
+ return Error::success();
+
const FileInfoSubstreamHeader *FH;
StreamReader FISR(FileInfoSubstream);
if (auto EC = FISR.readObject(FH))
@@ -436,4 +453,10 @@ Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
return Name;
}
-Error DbiStream::commit() { return Error::success(); }
+Error DbiStream::commit() {
+ StreamWriter Writer(*Stream);
+ if (auto EC = Writer.writeObject(*Header))
+ return EC;
+
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
index ff5ce61c212..34ff8ae3a90 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
@@ -18,9 +18,9 @@ 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) {}
+DbiStreamBuilder::DbiStreamBuilder()
+ : Age(1), BuildNumber(0), PdbDllVersion(0), PdbDllRbld(0), Flags(0),
+ MachineType(PDB_Machine::x86) {}
void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
@@ -36,7 +36,12 @@ void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; }
void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
-Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build() {
+uint32_t DbiStreamBuilder::calculateSerializedLength() const {
+ // For now we only support serializing the header.
+ return sizeof(DbiStream::HeaderInfo);
+}
+
+Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build(PDBFile &File) {
if (!VerHeader.hasValue())
return make_error<RawError>(raw_error_code::unspecified,
"Missing DBI Stream Version");
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
index e2f85ab880f..c33a764587c 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
@@ -27,7 +27,7 @@ InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
Error InfoStream::reload() {
codeview::StreamReader Reader(*Stream);
- const Header *H;
+ const HeaderInfo *H;
if (auto EC = Reader.readObject(H))
return joinErrors(
std::move(EC),
@@ -78,7 +78,7 @@ PDB_UniqueId InfoStream::getGuid() const { return Guid; }
Error InfoStream::commit() {
StreamWriter Writer(*Stream);
- Header H;
+ HeaderInfo H;
H.Age = Age;
H.Signature = Signature;
H.Version = Version;
@@ -87,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
index 21042e9a534..5a0e835dd56 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
@@ -18,7 +18,7 @@ using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;
-InfoStreamBuilder::InfoStreamBuilder(IPDBFile &File) : File(File) {}
+InfoStreamBuilder::InfoStreamBuilder() {}
void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
@@ -28,7 +28,12 @@ void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
-Expected<std::unique_ptr<InfoStream>> InfoStreamBuilder::build() {
+uint32_t InfoStreamBuilder::calculateSerializedLength() const {
+ return sizeof(InfoStream::HeaderInfo) +
+ NamedStreams.calculateSerializedLength();
+}
+
+Expected<std::unique_ptr<InfoStream>> InfoStreamBuilder::build(PDBFile &File) {
if (!Ver.hasValue())
return make_error<RawError>(raw_error_code::unspecified,
"Missing PDB Stream Version");
diff --git a/llvm/lib/DebugInfo/PDB/Raw/MsfBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/MsfBuilder.cpp
index ab739d339a9..fecefbfeb8d 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/MsfBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/MsfBuilder.cpp
@@ -24,7 +24,7 @@ MsfBuilder::MsfBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,
BumpPtrAllocator &Allocator)
: Allocator(Allocator), IsGrowable(CanGrow), BlockSize(BlockSize),
MininumBlocks(MinBlockCount), BlockMapAddr(kDefaultBlockMapAddr),
- FreeBlocks(MinBlockCount + 2U, true) {
+ FreeBlocks(std::max(MinBlockCount, 2U), true) {
FreeBlocks[kSuperBlockBlock] = false;
FreeBlocks[BlockMapAddr] = false;
}
@@ -59,6 +59,25 @@ Error MsfBuilder::setBlockMapAddr(uint32_t Addr) {
return Error::success();
}
+void MsfBuilder::setUnknown0(uint32_t Unk0) { Unknown0 = Unk0; }
+
+void MsfBuilder::setUnknown1(uint32_t Unk1) { Unknown1 = Unk1; }
+
+Error MsfBuilder::setDirectoryBlocksHint(ArrayRef<uint32_t> DirBlocks) {
+ for (auto B : DirectoryBlocks)
+ FreeBlocks[B] = true;
+ for (auto B : DirBlocks) {
+ if (!isBlockFree(B)) {
+ return make_error<RawError>(raw_error_code::unspecified,
+ "Attempt to reuse an allocated block");
+ }
+ FreeBlocks[B] = false;
+ }
+
+ DirectoryBlocks = DirBlocks;
+ return Error::success();
+}
+
Error MsfBuilder::allocateBlocks(uint32_t NumBlocks,
MutableArrayRef<uint32_t> Blocks) {
if (NumBlocks == 0)
@@ -198,16 +217,28 @@ Expected<Layout> MsfBuilder::build() {
L.SB->BlockMapAddr = BlockMapAddr;
L.SB->BlockSize = BlockSize;
L.SB->NumDirectoryBytes = computeDirectoryByteSize();
- L.SB->Unknown0 = 0;
- L.SB->Unknown1 = 0;
+ L.SB->Unknown0 = Unknown0;
+ L.SB->Unknown1 = Unknown1;
uint32_t NumDirectoryBlocks =
bytesToBlocks(L.SB->NumDirectoryBytes, BlockSize);
- // The directory blocks should be re-allocated as a stable pointer.
- std::vector<uint32_t> DirectoryBlocks;
- DirectoryBlocks.resize(NumDirectoryBlocks);
- if (auto EC = allocateBlocks(NumDirectoryBlocks, DirectoryBlocks))
- return std::move(EC);
+ if (NumDirectoryBlocks > DirectoryBlocks.size()) {
+ // Our hint wasn't enough to satisfy the entire directory. Allocate
+ // remaining pages.
+ std::vector<uint32_t> ExtraBlocks;
+ uint32_t NumExtraBlocks = NumDirectoryBlocks - DirectoryBlocks.size();
+ ExtraBlocks.resize(NumExtraBlocks);
+ if (auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
+ return std::move(EC);
+ DirectoryBlocks.insert(DirectoryBlocks.end(), ExtraBlocks.begin(),
+ ExtraBlocks.end());
+ } else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
+ uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
+ for (auto B :
+ ArrayRef<uint32_t>(DirectoryBlocks).drop_back(NumUnnecessaryBlocks))
+ FreeBlocks[B] = true;
+ DirectoryBlocks.resize(NumDirectoryBlocks);
+ }
// Don't set the number of blocks in the file until after allocating Blocks
// for
diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
new file mode 100644
index 00000000000..fe033c368e7
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
@@ -0,0 +1,26 @@
+//===- NameMapBuilder.cpp - PDB Name Map Builder ----------------*- 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/NameMapBuilder.h"
+
+#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NameMapBuilder::NameMapBuilder() {}
+
+Expected<std::unique_ptr<NameMap>> NameMapBuilder::build() {
+ return llvm::make_unique<NameMap>();
+}
+
+uint32_t NameMapBuilder::calculateSerializedLength() const {
+ // For now we write an empty name map, nothing else.
+ return 5 * sizeof(uint32_t);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index 2aa4d4c426f..8b09dc57cde 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -53,7 +53,7 @@ uint32_t PDBFile::getBlockMapIndex() const { return SB->BlockMapAddr; }
uint32_t PDBFile::getUnknown1() const { return SB->Unknown1; }
uint32_t PDBFile::getNumDirectoryBlocks() const {
- return bytesToBlocks(SB->NumDirectoryBytes, SB->BlockSize);
+ return msf::bytesToBlocks(SB->NumDirectoryBytes, SB->BlockSize);
}
uint64_t PDBFile::getBlockMapOffset() const {
@@ -75,7 +75,7 @@ uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }
Expected<ArrayRef<uint8_t>> PDBFile::getBlockData(uint32_t BlockIndex,
uint32_t NumBytes) const {
- uint64_t StreamBlockOffset = blockToOffset(BlockIndex, getBlockSize());
+ uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());
ArrayRef<uint8_t> Result;
if (auto EC = Buffer->readBytes(StreamBlockOffset, NumBytes, Result))
@@ -94,7 +94,7 @@ Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
raw_error_code::invalid_block_address,
"setBlockData attempted to write out of block bounds.");
- uint64_t StreamBlockOffset = blockToOffset(BlockIndex, getBlockSize());
+ uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());
StreamBlockOffset += Offset;
return Buffer->writeBytes(StreamBlockOffset, Data);
}
@@ -143,7 +143,8 @@ Error PDBFile::parseStreamData() {
uint32_t StreamSize = getStreamByteSize(I);
// FIXME: What does StreamSize ~0U mean?
uint64_t NumExpectedStreamBlocks =
- StreamSize == UINT32_MAX ? 0 : bytesToBlocks(StreamSize, SB->BlockSize);
+ StreamSize == UINT32_MAX ? 0 : msf::bytesToBlocks(StreamSize,
+ SB->BlockSize);
// For convenience, we store the block array contiguously. This is because
// if someone calls setStreamMap(), it is more convenient to be able to call
@@ -293,51 +294,15 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
return *StringTable;
}
-Error PDBFile::setSuperBlock(const SuperBlock *Block) {
- SB = Block;
-
- // Check the magic bytes.
- if (memcmp(SB->MagicBytes, MsfMagic, sizeof(MsfMagic)) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "MSF magic header doesn't match");
-
- // We don't support blocksizes which aren't a multiple of four bytes.
- if (SB->BlockSize % sizeof(support::ulittle32_t) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Block size is not multiple of 4.");
-
- switch (SB->BlockSize) {
- case 512:
- case 1024:
- case 2048:
- case 4096:
- break;
- default:
- // An invalid block size suggests a corrupt PDB file.
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unsupported block size.");
- }
+Error PDBFile::setSuperBlock(const msf::SuperBlock *Block) {
+ if (auto EC = msf::validateSuperBlock(*Block))
+ return EC;
if (Buffer->getLength() % SB->BlockSize != 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"File size is not a multiple of block size");
- // We don't support directories whose sizes aren't a multiple of four bytes.
- if (SB->NumDirectoryBytes % sizeof(support::ulittle32_t) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Directory size is not multiple of 4.");
-
- // The number of blocks which comprise the directory is a simple function of
- // the number of bytes it contains.
- uint64_t NumDirectoryBlocks = getNumDirectoryBlocks();
-
- // The directory, as we understand it, is a block which consists of a list of
- // block numbers. It is unclear what would happen if the number of blocks
- // couldn't fit on a single block.
- if (NumDirectoryBlocks > SB->BlockSize / sizeof(support::ulittle32_t))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Too many directory blocks.");
-
+ SB = Block;
return Error::success();
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
index f859c1fcc2e..b1ae760c6fb 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
@@ -9,6 +9,8 @@
#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
+#include "llvm/ADT/BitVector.h"
+
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
#include "llvm/DebugInfo/CodeView/StreamWriter.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
@@ -20,99 +22,72 @@
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;
+using namespace llvm::support;
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);
- }
+ std::unique_ptr<codeview::StreamInterface> FileBuffer)
+ : File(llvm::make_unique<PDBFile>(std::move(FileBuffer))) {}
+
+Error PDBFileBuilder::initialize(const msf::SuperBlock &Super) {
+ auto ExpectedMsf =
+ MsfBuilder::create(File->Allocator, Super.BlockSize, Super.NumBlocks);
+ if (!ExpectedMsf)
+ return ExpectedMsf.takeError();
+
+ auto &MsfResult = *ExpectedMsf;
+ if (auto EC = MsfResult.setBlockMapAddr(Super.BlockMapAddr))
+ return EC;
+ MsfResult.setUnknown0(Super.Unknown0);
+ MsfResult.setUnknown1(Super.Unknown1);
+ Msf = llvm::make_unique<MsfBuilder>(std::move(MsfResult));
return Error::success();
}
+MsfBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
+
InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
if (!Info)
- Info = llvm::make_unique<InfoStreamBuilder>(*File);
+ Info = llvm::make_unique<InfoStreamBuilder>();
return *Info;
}
DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
if (!Dbi)
- Dbi = llvm::make_unique<DbiStreamBuilder>(*File);
+ Dbi = llvm::make_unique<DbiStreamBuilder>();
return *Dbi;
}
Expected<std::unique_ptr<PDBFile>> PDBFileBuilder::build() {
if (Info) {
- auto ExpectedInfo = Info->build();
+ uint32_t Length = Info->calculateSerializedLength();
+ if (auto EC = Msf->setStreamSize(StreamPDB, Length))
+ return std::move(EC);
+ }
+ if (Dbi) {
+ uint32_t Length = Dbi->calculateSerializedLength();
+ if (auto EC = Msf->setStreamSize(StreamDBI, Length))
+ return std::move(EC);
+ }
+
+ auto ExpectedLayout = Msf->build();
+ if (!ExpectedLayout)
+ return ExpectedLayout.takeError();
+
+ const msf::Layout &L = *ExpectedLayout;
+ File->StreamMap = L.StreamMap;
+ File->StreamSizes = L.StreamSizes;
+ File->DirectoryBlocks = L.DirectoryBlocks;
+ File->SB = L.SB;
+
+ if (Info) {
+ auto ExpectedInfo = Info->build(*File);
if (!ExpectedInfo)
return ExpectedInfo.takeError();
File->Info = std::move(*ExpectedInfo);
}
if (Dbi) {
- auto ExpectedDbi = Dbi->build();
+ auto ExpectedDbi = Dbi->build(*File);
if (!ExpectedDbi)
return ExpectedDbi.takeError();
File->Dbi = std::move(*ExpectedDbi);
OpenPOWER on IntegriCloud