summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp2
-rw-r--r--llvm/lib/DebugInfo/CodeView/ModuleSubstream.cpp8
-rw-r--r--llvm/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp27
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeDumper.cpp2
-rw-r--r--llvm/lib/DebugInfo/Msf/ByteStream.cpp79
-rw-r--r--llvm/lib/DebugInfo/Msf/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/Msf/MappedBlockStream.cpp278
-rw-r--r--llvm/lib/DebugInfo/Msf/MsfBuilder.cpp5
-rw-r--r--llvm/lib/DebugInfo/Msf/StreamReader.cpp6
-rw-r--r--llvm/lib/DebugInfo/Msf/StreamWriter.cpp6
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp51
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp66
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp17
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp55
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp54
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp55
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp186
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp52
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp17
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp11
22 files changed, 457 insertions, 525 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 7e8f46b0a2a..874a154a954 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -475,7 +475,7 @@ void CodeViewDebug::emitTypeInformation() {
// comments. The MSVC linker doesn't do much type record validation,
// so the first link of an invalid type record can succeed while
// subsequent links will fail with LNK1285.
- ByteStream<> Stream({Record.bytes_begin(), Record.bytes_end()});
+ ByteStream Stream({Record.bytes_begin(), Record.bytes_end()});
CVTypeArray Types;
StreamReader Reader(Stream);
Error E = Reader.readArray(Types, Reader.getLength());
diff --git a/llvm/lib/DebugInfo/CodeView/ModuleSubstream.cpp b/llvm/lib/DebugInfo/CodeView/ModuleSubstream.cpp
index 5ab8212d3bd..6473338a272 100644
--- a/llvm/lib/DebugInfo/CodeView/ModuleSubstream.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ModuleSubstream.cpp
@@ -17,10 +17,12 @@ using namespace llvm::msf;
ModuleSubstream::ModuleSubstream() : Kind(ModuleSubstreamKind::None) {}
-ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind, StreamRef Data)
+ModuleSubstream::ModuleSubstream(ModuleSubstreamKind Kind,
+ ReadableStreamRef Data)
: Kind(Kind), Data(Data) {}
-Error ModuleSubstream::initialize(StreamRef Stream, ModuleSubstream &Info) {
+Error ModuleSubstream::initialize(ReadableStreamRef Stream,
+ ModuleSubstream &Info) {
const ModuleSubsectionHeader *Header;
StreamReader Reader(Stream);
if (auto EC = Reader.readObject(Header))
@@ -40,4 +42,4 @@ uint32_t ModuleSubstream::getRecordLength() const {
ModuleSubstreamKind ModuleSubstream::getSubstreamKind() const { return Kind; }
-StreamRef ModuleSubstream::getRecordData() const { return Data; }
+ReadableStreamRef ModuleSubstream::getRecordData() const { return Data; }
diff --git a/llvm/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp b/llvm/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp
index e6dcbc75a13..f5afe61efc2 100644
--- a/llvm/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp
+++ b/llvm/lib/DebugInfo/CodeView/ModuleSubstreamVisitor.cpp
@@ -15,46 +15,47 @@ using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
-Error IModuleSubstreamVisitor::visitSymbols(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitSymbols(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::Symbols, Data);
}
-Error IModuleSubstreamVisitor::visitLines(StreamRef Data,
+Error IModuleSubstreamVisitor::visitLines(ReadableStreamRef Data,
const LineSubstreamHeader *Header,
const LineInfoArray &Lines) {
return visitUnknown(ModuleSubstreamKind::Lines, Data);
}
-Error IModuleSubstreamVisitor::visitStringTable(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitStringTable(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::StringTable, Data);
}
Error IModuleSubstreamVisitor::visitFileChecksums(
- StreamRef Data, const FileChecksumArray &Checksums) {
+ ReadableStreamRef Data, const FileChecksumArray &Checksums) {
return visitUnknown(ModuleSubstreamKind::FileChecksums, Data);
}
-Error IModuleSubstreamVisitor::visitFrameData(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitFrameData(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::FrameData, Data);
}
-Error IModuleSubstreamVisitor::visitInlineeLines(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitInlineeLines(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::InlineeLines, Data);
}
-Error IModuleSubstreamVisitor::visitCrossScopeImports(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitCrossScopeImports(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::CrossScopeExports, Data);
}
-Error IModuleSubstreamVisitor::visitCrossScopeExports(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitCrossScopeExports(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::CrossScopeImports, Data);
}
-Error IModuleSubstreamVisitor::visitILLines(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitILLines(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::ILLines, Data);
}
-Error IModuleSubstreamVisitor::visitFuncMDTokenMap(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitFuncMDTokenMap(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::FuncMDTokenMap, Data);
}
-Error IModuleSubstreamVisitor::visitTypeMDTokenMap(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitTypeMDTokenMap(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::TypeMDTokenMap, Data);
}
-Error IModuleSubstreamVisitor::visitMergedAssemblyInput(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitMergedAssemblyInput(
+ ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::MergedAssemblyInput, Data);
}
-Error IModuleSubstreamVisitor::visitCoffSymbolRVA(StreamRef Data) {
+Error IModuleSubstreamVisitor::visitCoffSymbolRVA(ReadableStreamRef Data) {
return visitUnknown(ModuleSubstreamKind::CoffSymbolRVA, Data);
}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp b/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
index cf5adb6b75e..428914b59a9 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
@@ -681,7 +681,7 @@ Error CVTypeDumper::dump(const CVTypeArray &Types) {
}
Error CVTypeDumper::dump(ArrayRef<uint8_t> Data) {
- msf::ByteStream<> Stream(Data);
+ msf::ByteStream Stream(Data);
CVTypeArray Types;
msf::StreamReader Reader(Stream);
if (auto EC = Reader.readArray(Types, Reader.getLength()))
diff --git a/llvm/lib/DebugInfo/Msf/ByteStream.cpp b/llvm/lib/DebugInfo/Msf/ByteStream.cpp
deleted file mode 100644
index 32fcbccaacc..00000000000
--- a/llvm/lib/DebugInfo/Msf/ByteStream.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//===- ByteStream.cpp - Reads stream data from a byte sequence ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/Msf/ByteStream.h"
-#include "llvm/DebugInfo/Msf/MsfError.h"
-#include "llvm/DebugInfo/Msf/StreamReader.h"
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::msf;
-
-static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,
- ArrayRef<uint8_t> Dest) {
- return make_error<MsfError>(msf_error_code::not_writable,
- "ByteStream is immutable.");
-}
-
-static Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Src,
- MutableArrayRef<uint8_t> Dest) {
- if (Dest.size() < Src.size())
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
- if (Offset > Src.size() - Dest.size())
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
-
- ::memcpy(Dest.data() + Offset, Src.data(), Src.size());
- return Error::success();
-}
-
-template <bool Writable>
-Error ByteStream<Writable>::readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) const {
- if (Offset > Data.size())
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
- if (Data.size() < Size + Offset)
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
- Buffer = Data.slice(Offset, Size);
- return Error::success();
-}
-
-template <bool Writable>
-Error ByteStream<Writable>::readLongestContiguousChunk(
- uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
- if (Offset >= Data.size())
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
- Buffer = Data.slice(Offset);
- return Error::success();
-}
-
-template <bool Writable>
-Error ByteStream<Writable>::writeBytes(uint32_t Offset,
- ArrayRef<uint8_t> Buffer) const {
- return ::writeBytes(Offset, Buffer, Data);
-}
-
-template <bool Writable> uint32_t ByteStream<Writable>::getLength() const {
- return Data.size();
-}
-
-template <bool Writable> Error ByteStream<Writable>::commit() const {
- return Error::success();
-}
-
-template <bool Writable> StringRef ByteStream<Writable>::str() const {
- const char *CharData = reinterpret_cast<const char *>(Data.data());
- return StringRef(CharData, Data.size());
-}
-
-namespace llvm {
-namespace msf {
-template class ByteStream<true>;
-template class ByteStream<false>;
-}
-}
diff --git a/llvm/lib/DebugInfo/Msf/CMakeLists.txt b/llvm/lib/DebugInfo/Msf/CMakeLists.txt
index 3be398bbbeb..5342c54fd20 100644
--- a/llvm/lib/DebugInfo/Msf/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/Msf/CMakeLists.txt
@@ -1,5 +1,4 @@
add_llvm_library(LLVMDebugInfoMsf
- ByteStream.cpp
MappedBlockStream.cpp
MsfBuilder.cpp
MsfCommon.cpp
diff --git a/llvm/lib/DebugInfo/Msf/MappedBlockStream.cpp b/llvm/lib/DebugInfo/Msf/MappedBlockStream.cpp
index 06ca694174b..7d5be88c4d1 100644
--- a/llvm/lib/DebugInfo/Msf/MappedBlockStream.cpp
+++ b/llvm/lib/DebugInfo/Msf/MappedBlockStream.cpp
@@ -10,6 +10,7 @@
#include "llvm/DebugInfo/Msf/MappedBlockStream.h"
#include "llvm/DebugInfo/Msf/IMsfFile.h"
+#include "llvm/DebugInfo/Msf/MsfCommon.h"
#include "llvm/DebugInfo/Msf/MsfError.h"
#include "llvm/DebugInfo/Msf/MsfStreamLayout.h"
@@ -17,13 +18,11 @@ using namespace llvm;
using namespace llvm::msf;
namespace {
-// This exists so that we can use make_unique (which requires a public default
-// constructor, while still keeping the constructor of MappedBlockStream
-// protected, forcing users to go through the `create` interface.
-class MappedBlockStreamImpl : public MappedBlockStream {
+template <typename Base> class MappedBlockStreamImpl : public Base {
public:
- MappedBlockStreamImpl(const MsfStreamLayout &Layout, const IMsfFile &File)
- : MappedBlockStream(Layout, File) {}
+ template <typename... Args>
+ MappedBlockStreamImpl(Args &&... Params)
+ : Base(std::forward<Args>(Params)...) {}
};
}
@@ -33,16 +32,46 @@ static Interval intersect(const Interval &I1, const Interval &I2) {
std::min(I1.second, I2.second));
}
-MappedBlockStream::MappedBlockStream(const MsfStreamLayout &Layout,
- const IMsfFile &File)
- : Msf(File), Layout(Layout) {}
+MappedBlockStream::MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks,
+ const MsfStreamLayout &Layout,
+ const ReadableStream &MsfData)
+ : BlockSize(BlockSize), NumBlocks(NumBlocks), StreamLayout(Layout),
+ MsfData(MsfData) {}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createStream(uint32_t BlockSize, uint32_t NumBlocks,
+ const MsfStreamLayout &Layout,
+ const ReadableStream &MsfData) {
+ return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+ BlockSize, NumBlocks, Layout, MsfData);
+}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createIndexedStream(const MsfLayout &Layout,
+ const ReadableStream &MsfData,
+ uint32_t StreamIndex) {
+ MsfStreamLayout SL;
+ SL.Blocks = Layout.StreamMap[StreamIndex];
+ SL.Length = Layout.StreamSizes[StreamIndex];
+ return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+ Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createDirectoryStream(const MsfLayout &Layout,
+ const ReadableStream &MsfData) {
+ MsfStreamLayout SL;
+ SL.Blocks = Layout.DirectoryBlocks;
+ SL.Length = Layout.SB->NumDirectoryBytes;
+ return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const {
// Make sure we aren't trying to read beyond the end of the stream.
- if (Size > Layout.Length)
+ if (Size > StreamLayout.Length)
return make_error<MsfError>(msf_error_code::insufficient_buffer);
- if (Offset > Layout.Length - Size)
+ if (Offset > StreamLayout.Length - Size)
return make_error<MsfError>(msf_error_code::insufficient_buffer);
if (tryReadContiguously(Offset, Size, Buffer))
@@ -120,33 +149,33 @@ Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
Error MappedBlockStream::readLongestContiguousChunk(
uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
// Make sure we aren't trying to read beyond the end of the stream.
- if (Offset >= Layout.Length)
+ if (Offset >= StreamLayout.Length)
return make_error<MsfError>(msf_error_code::insufficient_buffer);
- uint32_t First = Offset / Msf.getBlockSize();
+ uint32_t First = Offset / BlockSize;
uint32_t Last = First;
- while (Last < Msf.getBlockCount() - 1) {
- if (Layout.Blocks[Last] != Layout.Blocks[Last + 1] - 1)
+ while (Last < NumBlocks - 1) {
+ if (StreamLayout.Blocks[Last] != StreamLayout.Blocks[Last + 1] - 1)
break;
++Last;
}
- uint32_t OffsetInFirstBlock = Offset % Msf.getBlockSize();
- uint32_t BytesFromFirstBlock = Msf.getBlockSize() - OffsetInFirstBlock;
+ uint32_t OffsetInFirstBlock = Offset % BlockSize;
+ uint32_t BytesFromFirstBlock = BlockSize - OffsetInFirstBlock;
uint32_t BlockSpan = Last - First + 1;
- uint32_t ByteSpan =
- BytesFromFirstBlock + (BlockSpan - 1) * Msf.getBlockSize();
- auto Result = Msf.getBlockData(Layout.Blocks[First], Msf.getBlockSize());
- if (!Result)
- return Result.takeError();
- Buffer = Result->drop_front(OffsetInFirstBlock);
- Buffer = ArrayRef<uint8_t>(Buffer.data(), ByteSpan);
+ uint32_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * BlockSize;
+
+ ArrayRef<uint8_t> BlockData;
+ uint32_t MsfOffset = blockToOffset(StreamLayout.Blocks[First], BlockSize);
+ if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData))
+ return EC;
+
+ BlockData = BlockData.drop_front(OffsetInFirstBlock);
+ Buffer = ArrayRef<uint8_t>(BlockData.data(), ByteSpan);
return Error::success();
}
-uint32_t MappedBlockStream::getLength() const { return Layout.Length; }
-
-Error MappedBlockStream::commit() const { return Error::success(); }
+uint32_t MappedBlockStream::getLength() const { return StreamLayout.Length; }
bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) const {
@@ -155,57 +184,60 @@ bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
// all subsequent blocks are contiguous. For example, a 10k read with a 4k
// block size can be filled with a reference if, from the starting offset,
// 3 blocks in a row are contiguous.
- uint32_t BlockNum = Offset / Msf.getBlockSize();
- uint32_t OffsetInBlock = Offset % Msf.getBlockSize();
- uint32_t BytesFromFirstBlock =
- std::min(Size, Msf.getBlockSize() - OffsetInBlock);
+ uint32_t BlockNum = Offset / BlockSize;
+ uint32_t OffsetInBlock = Offset % BlockSize;
+ uint32_t BytesFromFirstBlock = std::min(Size, BlockSize - OffsetInBlock);
uint32_t NumAdditionalBlocks =
- llvm::alignTo(Size - BytesFromFirstBlock, Msf.getBlockSize()) /
- Msf.getBlockSize();
+ llvm::alignTo(Size - BytesFromFirstBlock, BlockSize) / BlockSize;
uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
- uint32_t E = Layout.Blocks[BlockNum];
+ uint32_t E = StreamLayout.Blocks[BlockNum];
for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
- if (Layout.Blocks[I + BlockNum] != E)
+ if (StreamLayout.Blocks[I + BlockNum] != E)
return false;
}
- uint32_t FirstBlockAddr = Layout.Blocks[BlockNum];
- auto Result = Msf.getBlockData(FirstBlockAddr, Msf.getBlockSize());
- if (!Result) {
- consumeError(Result.takeError());
+ // Read out the entire block where the requested offset starts. Then drop
+ // bytes from the beginning so that the actual starting byte lines up with
+ // the requested starting byte. Then, since we know this is a contiguous
+ // cross-block span, explicitly resize the ArrayRef to cover the entire
+ // request length.
+ ArrayRef<uint8_t> BlockData;
+ uint32_t FirstBlockAddr = StreamLayout.Blocks[BlockNum];
+ uint32_t MsfOffset = blockToOffset(FirstBlockAddr, BlockSize);
+ if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData)) {
+ consumeError(std::move(EC));
return false;
}
- auto Data = Result->drop_front(OffsetInBlock);
- Buffer = ArrayRef<uint8_t>(Data.data(), Size);
+ BlockData = BlockData.drop_front(OffsetInBlock);
+ Buffer = ArrayRef<uint8_t>(BlockData.data(), Size);
return true;
}
Error MappedBlockStream::readBytes(uint32_t Offset,
MutableArrayRef<uint8_t> Buffer) const {
- uint32_t BlockNum = Offset / Msf.getBlockSize();
- uint32_t OffsetInBlock = Offset % Msf.getBlockSize();
+ uint32_t BlockNum = Offset / BlockSize;
+ uint32_t OffsetInBlock = Offset % BlockSize;
// Make sure we aren't trying to read beyond the end of the stream.
- if (Buffer.size() > Layout.Length)
+ if (Buffer.size() > StreamLayout.Length)
return make_error<MsfError>(msf_error_code::insufficient_buffer);
- if (Offset > Layout.Length - Buffer.size())
+ if (Offset > StreamLayout.Length - Buffer.size())
return make_error<MsfError>(msf_error_code::insufficient_buffer);
uint32_t BytesLeft = Buffer.size();
uint32_t BytesWritten = 0;
uint8_t *WriteBuffer = Buffer.data();
while (BytesLeft > 0) {
- uint32_t StreamBlockAddr = Layout.Blocks[BlockNum];
+ uint32_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];
- auto Result = Msf.getBlockData(StreamBlockAddr, Msf.getBlockSize());
- if (!Result)
- return Result.takeError();
+ ArrayRef<uint8_t> BlockData;
+ uint32_t Offset = blockToOffset(StreamBlockAddr, BlockSize);
+ if (auto EC = MsfData.readBytes(Offset, BlockSize, BlockData))
+ return EC;
- auto Data = *Result;
- const uint8_t *ChunkStart = Data.data() + OffsetInBlock;
- uint32_t BytesInChunk =
- std::min(BytesLeft, Msf.getBlockSize() - OffsetInBlock);
+ const uint8_t *ChunkStart = BlockData.data() + OffsetInBlock;
+ uint32_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);
::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);
BytesWritten += BytesInChunk;
@@ -217,36 +249,14 @@ Error MappedBlockStream::readBytes(uint32_t Offset,
return Error::success();
}
-Error MappedBlockStream::writeBytes(uint32_t Offset,
- ArrayRef<uint8_t> Buffer) const {
- // Make sure we aren't trying to write beyond the end of the stream.
- if (Buffer.size() > Layout.Length)
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
-
- if (Offset > Layout.Length - Buffer.size())
- return make_error<MsfError>(msf_error_code::insufficient_buffer);
-
- uint32_t BlockNum = Offset / Msf.getBlockSize();
- uint32_t OffsetInBlock = Offset % Msf.getBlockSize();
-
- uint32_t BytesLeft = Buffer.size();
- uint32_t BytesWritten = 0;
- while (BytesLeft > 0) {
- uint32_t StreamBlockAddr = Layout.Blocks[BlockNum];
- uint32_t BytesToWriteInChunk =
- std::min(BytesLeft, Msf.getBlockSize() - OffsetInBlock);
-
- const uint8_t *Chunk = Buffer.data() + BytesWritten;
- ArrayRef<uint8_t> ChunkData(Chunk, BytesToWriteInChunk);
- if (auto EC = Msf.setBlockData(StreamBlockAddr, OffsetInBlock, ChunkData))
- return EC;
+uint32_t MappedBlockStream::getNumBytesCopied() const {
+ return static_cast<uint32_t>(Pool.getBytesAllocated());
+}
- BytesLeft -= BytesToWriteInChunk;
- BytesWritten += BytesToWriteInChunk;
- ++BlockNum;
- OffsetInBlock = 0;
- }
+void MappedBlockStream::invalidateCache() { CacheMap.shrink_and_clear(); }
+void MappedBlockStream::fixCacheAfterWrite(uint32_t Offset,
+ ArrayRef<uint8_t> Data) const {
// If this write overlapped a read which previously came from the pool,
// someone may still be holding a pointer to that alloc which is now invalid.
// Compute the overlapping range and update the cache entry, so any
@@ -254,7 +264,7 @@ Error MappedBlockStream::writeBytes(uint32_t Offset,
for (const auto &MapEntry : CacheMap) {
// If the end of the written extent precedes the beginning of the cached
// extent, ignore this map entry.
- if (Offset + BytesWritten < MapEntry.first)
+ if (Offset + Data.size() < MapEntry.first)
continue;
for (const auto &Alloc : MapEntry.second) {
// If the end of the cached extent precedes the beginning of the written
@@ -263,7 +273,7 @@ Error MappedBlockStream::writeBytes(uint32_t Offset,
continue;
// If we get here, they are guaranteed to overlap.
- Interval WriteInterval = std::make_pair(Offset, Offset + BytesWritten);
+ Interval WriteInterval = std::make_pair(Offset, Offset + Data.size());
Interval CachedInterval =
std::make_pair(MapEntry.first, MapEntry.first + Alloc.size());
// If they overlap, we need to write the new data into the overlapping
@@ -276,35 +286,95 @@ Error MappedBlockStream::writeBytes(uint32_t Offset,
AbsoluteDifference(WriteInterval.first, Intersection.first);
uint32_t DestOffset =
AbsoluteDifference(CachedInterval.first, Intersection.first);
- ::memcpy(Alloc.data() + DestOffset, Buffer.data() + SrcOffset, Length);
+ ::memcpy(Alloc.data() + DestOffset, Data.data() + SrcOffset, Length);
}
}
+}
- return Error::success();
+WritableMappedBlockStream::WritableMappedBlockStream(
+ uint32_t BlockSize, uint32_t NumBlocks, const MsfStreamLayout &Layout,
+ const WritableStream &MsfData)
+ : ReadInterface(BlockSize, NumBlocks, Layout, MsfData),
+ WriteInterface(MsfData) {}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createStream(uint32_t BlockSize, uint32_t NumBlocks,
+ const MsfStreamLayout &Layout,
+ const WritableStream &MsfData) {
+ return llvm::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
+ BlockSize, NumBlocks, Layout, MsfData);
}
-uint32_t MappedBlockStream::getNumBytesCopied() const {
- return static_cast<uint32_t>(Pool.getBytesAllocated());
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createIndexedStream(const MsfLayout &Layout,
+ const WritableStream &MsfData,
+ uint32_t StreamIndex) {
+ MsfStreamLayout SL;
+ SL.Blocks = Layout.StreamMap[StreamIndex];
+ SL.Length = Layout.StreamSizes[StreamIndex];
+ return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createDirectoryStream(
+ const MsfLayout &Layout, const WritableStream &MsfData) {
+ MsfStreamLayout SL;
+ SL.Blocks = Layout.DirectoryBlocks;
+ SL.Length = Layout.SB->NumDirectoryBytes;
+ return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData);
+}
+
+Error WritableMappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) const {
+ return ReadInterface.readBytes(Offset, Size, Buffer);
+}
+
+Error WritableMappedBlockStream::readLongestContiguousChunk(
+ uint32_t Offset, ArrayRef<uint8_t> &Buffer) const {
+ return ReadInterface.readLongestContiguousChunk(Offset, Buffer);
}
-Expected<std::unique_ptr<MappedBlockStream>>
-MappedBlockStream::createIndexedStream(uint32_t StreamIdx,
- const IMsfFile &File) {
- if (StreamIdx >= File.getNumStreams())
- return make_error<MsfError>(msf_error_code::no_stream);
- MsfStreamLayout L;
- L.Blocks = File.getStreamBlockList(StreamIdx);
- L.Length = File.getStreamByteSize(StreamIdx);
- return llvm::make_unique<MappedBlockStreamImpl>(L, File);
+uint32_t WritableMappedBlockStream::getLength() const {
+ return ReadInterface.getLength();
}
-Expected<std::unique_ptr<MappedBlockStream>>
-MappedBlockStream::createDirectoryStream(uint32_t Length,
- ArrayRef<support::ulittle32_t> Blocks,
- const IMsfFile &File) {
- MsfStreamLayout L;
- L.Blocks = Blocks;
- L.Length = Length;
+Error WritableMappedBlockStream::writeBytes(uint32_t Offset,
+ ArrayRef<uint8_t> Buffer) const {
+ // Make sure we aren't trying to write beyond the end of the stream.
+ if (Buffer.size() > getStreamLength())
+ return make_error<MsfError>(msf_error_code::insufficient_buffer);
+
+ if (Offset > getStreamLayout().Length - Buffer.size())
+ return make_error<MsfError>(msf_error_code::insufficient_buffer);
+
+ uint32_t BlockNum = Offset / getBlockSize();
+ uint32_t OffsetInBlock = Offset % getBlockSize();
+
+ uint32_t BytesLeft = Buffer.size();
+ uint32_t BytesWritten = 0;
+ while (BytesLeft > 0) {
+ uint32_t StreamBlockAddr = getStreamLayout().Blocks[BlockNum];
+ uint32_t BytesToWriteInChunk =
+ std::min(BytesLeft, getBlockSize() - OffsetInBlock);
+
+ const uint8_t *Chunk = Buffer.data() + BytesWritten;
+ ArrayRef<uint8_t> ChunkData(Chunk, BytesToWriteInChunk);
+ uint32_t MsfOffset = blockToOffset(StreamBlockAddr, getBlockSize());
+ MsfOffset += OffsetInBlock;
+ if (auto EC = WriteInterface.writeBytes(MsfOffset, ChunkData))
+ return EC;
+
+ BytesLeft -= BytesToWriteInChunk;
+ BytesWritten += BytesToWriteInChunk;
+ ++BlockNum;
+ OffsetInBlock = 0;
+ }
+
+ ReadInterface.fixCacheAfterWrite(Offset, Buffer);
+
+ return Error::success();
+}
- return llvm::make_unique<MappedBlockStreamImpl>(L, File);
+Error WritableMappedBlockStream::commit() const {
+ return WriteInterface.commit();
}
diff --git a/llvm/lib/DebugInfo/Msf/MsfBuilder.cpp b/llvm/lib/DebugInfo/Msf/MsfBuilder.cpp
index 9a780d138aa..0128264b9ec 100644
--- a/llvm/lib/DebugInfo/Msf/MsfBuilder.cpp
+++ b/llvm/lib/DebugInfo/Msf/MsfBuilder.cpp
@@ -1,4 +1,3 @@
-//===- MSFBuilder.cpp - MSF Directory & Metadata Builder --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -218,9 +217,9 @@ uint32_t MsfBuilder::computeDirectoryByteSize() const {
return Size;
}
-Expected<Layout> MsfBuilder::build() {
+Expected<MsfLayout> MsfBuilder::build() {
SuperBlock *SB = Allocator.Allocate<SuperBlock>();
- Layout L;
+ MsfLayout L;
L.SB = SB;
std::memcpy(SB->MagicBytes, Magic, sizeof(Magic));
diff --git a/llvm/lib/DebugInfo/Msf/StreamReader.cpp b/llvm/lib/DebugInfo/Msf/StreamReader.cpp
index a2f0f49c3d9..1c7e8352130 100644
--- a/llvm/lib/DebugInfo/Msf/StreamReader.cpp
+++ b/llvm/lib/DebugInfo/Msf/StreamReader.cpp
@@ -15,7 +15,7 @@
using namespace llvm;
using namespace llvm::msf;
-StreamReader::StreamReader(StreamRef S) : Stream(S), Offset(0) {}
+StreamReader::StreamReader(ReadableStreamRef S) : Stream(S), Offset(0) {}
Error StreamReader::readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer) {
if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer))
@@ -80,11 +80,11 @@ Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) {
return Error::success();
}
-Error StreamReader::readStreamRef(StreamRef &Ref) {
+Error StreamReader::readStreamRef(ReadableStreamRef &Ref) {
return readStreamRef(Ref, bytesRemaining());
}
-Error StreamReader::readStreamRef(StreamRef &Ref, uint32_t Length) {
+Error StreamReader::readStreamRef(ReadableStreamRef &Ref, uint32_t Length) {
if (bytesRemaining() < Length)
return make_error<MsfError>(msf_error_code::insufficient_buffer);
Ref = Stream.slice(Offset, Length);
diff --git a/llvm/lib/DebugInfo/Msf/StreamWriter.cpp b/llvm/lib/DebugInfo/Msf/StreamWriter.cpp
index eb11012c475..40bc0394b11 100644
--- a/llvm/lib/DebugInfo/Msf/StreamWriter.cpp
+++ b/llvm/lib/DebugInfo/Msf/StreamWriter.cpp
@@ -16,7 +16,7 @@
using namespace llvm;
using namespace llvm::msf;
-StreamWriter::StreamWriter(StreamRef S) : Stream(S), Offset(0) {}
+StreamWriter::StreamWriter(WritableStreamRef S) : Stream(S), Offset(0) {}
Error StreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
if (auto EC = Stream.writeBytes(Offset, Buffer))
@@ -51,7 +51,7 @@ Error StreamWriter::writeFixedString(StringRef Str) {
return Error::success();
}
-Error StreamWriter::writeStreamRef(StreamRef Ref) {
+Error StreamWriter::writeStreamRef(ReadableStreamRef Ref) {
if (auto EC = writeStreamRef(Ref, Ref.getLength()))
return EC;
// Don't increment Offset here, it is done by the overloaded call to
@@ -59,7 +59,7 @@ Error StreamWriter::writeStreamRef(StreamRef Ref) {
return Error::success();
}
-Error StreamWriter::writeStreamRef(StreamRef Ref, uint32_t Length) {
+Error StreamWriter::writeStreamRef(ReadableStreamRef Ref, uint32_t Length) {
Ref = Ref.slice(0, Length);
StreamReader SrcReader(Ref);
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index 35f79c801ba..564246a332d 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -272,22 +272,21 @@ Error DbiStream::initializeSectionHeadersData() {
if (StreamNum >= Pdb.getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
- auto SHS = MappedBlockStream::createIndexedStream(StreamNum, Pdb);
- if (!SHS)
- return SHS.takeError();
+ auto SHS = MappedBlockStream::createIndexedStream(
+ Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum);
- size_t StreamLen = (*SHS)->getLength();
+ size_t StreamLen = SHS->getLength();
if (StreamLen % sizeof(object::coff_section))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted section header stream.");
size_t NumSections = StreamLen / sizeof(object::coff_section);
- msf::StreamReader Reader(**SHS);
+ msf::StreamReader Reader(*SHS);
if (auto EC = Reader.readArray(SectionHeaders, NumSections))
return make_error<RawError>(raw_error_code::corrupt_file,
"Could not read a bitmap.");
- SectionHeaderStream = std::move(*SHS);
+ SectionHeaderStream = std::move(SHS);
return Error::success();
}
@@ -305,21 +304,20 @@ Error DbiStream::initializeFpoRecords() {
if (StreamNum >= Pdb.getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
- auto FS = MappedBlockStream::createIndexedStream(StreamNum, Pdb);
- if (!FS)
- return FS.takeError();
+ auto FS = MappedBlockStream::createIndexedStream(
+ Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum);
- size_t StreamLen = (*FS)->getLength();
+ size_t StreamLen = FS->getLength();
if (StreamLen % sizeof(object::FpoData))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted New FPO stream.");
size_t NumRecords = StreamLen / sizeof(object::FpoData);
- msf::StreamReader Reader(**FS);
+ msf::StreamReader Reader(*FS);
if (auto EC = Reader.readArray(FpoRecords, NumRecords))
return make_error<RawError>(raw_error_code::corrupt_file,
"Corrupted New FPO stream.");
- FpoStream = std::move(*FS);
+ FpoStream = std::move(FS);
return Error::success();
}
@@ -421,32 +419,3 @@ Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
return std::move(EC);
return Name;
}
-
-Error DbiStream::commit() {
- StreamWriter Writer(*Stream);
- if (auto EC = Writer.writeObject(*Header))
- return EC;
-
- if (auto EC = Writer.writeStreamRef(ModInfoSubstream))
- return EC;
-
- if (auto EC = Writer.writeStreamRef(SecContrSubstream,
- SecContrSubstream.getLength()))
- return EC;
- if (auto EC =
- Writer.writeStreamRef(SecMapSubstream, SecMapSubstream.getLength()))
- return EC;
- if (auto EC = Writer.writeStreamRef(FileInfoSubstream,
- FileInfoSubstream.getLength()))
- return EC;
- if (auto EC = Writer.writeStreamRef(TypeServerMapSubstream,
- TypeServerMapSubstream.getLength()))
- return EC;
- if (auto EC = Writer.writeStreamRef(ECSubstream, ECSubstream.getLength()))
- return EC;
-
- if (Writer.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::invalid_format,
- "Unexpected bytes found in DBI Stream");
- return Error::success();
-}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
index 7a688cb8968..6e1282263f6 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
@@ -25,7 +25,7 @@ class ModiSubstreamBuilder {};
DbiStreamBuilder::DbiStreamBuilder(BumpPtrAllocator &Allocator)
: Allocator(Allocator), Age(1), BuildNumber(0), PdbDllVersion(0),
- PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86) {}
+ PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86), Header(nullptr) {}
void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
@@ -108,7 +108,7 @@ Error DbiStreamBuilder::generateModiSubstream() {
uint32_t Size = calculateModiSubstreamSize();
auto Data = Allocator.Allocate<uint8_t>(Size);
- ModInfoBuffer = ByteStream<true>(MutableArrayRef<uint8_t>(Data, Size));
+ ModInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
StreamWriter ModiWriter(ModInfoBuffer);
for (const auto &M : ModuleInfoList) {
@@ -134,9 +134,10 @@ Error DbiStreamBuilder::generateFileInfoSubstream() {
auto Data = Allocator.Allocate<uint8_t>(Size);
uint32_t NamesOffset = Size - NameSize;
- FileInfoBuffer = ByteStream<true>(MutableArrayRef<uint8_t>(Data, Size));
+ FileInfoBuffer = MutableByteStream(MutableArrayRef<uint8_t>(Data, Size));
- StreamRef MetadataBuffer = StreamRef(FileInfoBuffer).keep_front(NamesOffset);
+ WritableStreamRef MetadataBuffer =
+ WritableStreamRef(FileInfoBuffer).keep_front(NamesOffset);
StreamWriter MetadataWriter(MetadataBuffer);
uint16_t ModiCount = std::min<uint16_t>(UINT16_MAX, ModuleInfos.size());
@@ -159,7 +160,7 @@ Error DbiStreamBuilder::generateFileInfoSubstream() {
// A side effect of this is that this will actually compute the various
// file name offsets, so we can then go back and write the FileNameOffsets
// array to the other substream.
- NamesBuffer = StreamRef(FileInfoBuffer).drop_front(NamesOffset);
+ NamesBuffer = WritableStreamRef(FileInfoBuffer).drop_front(NamesOffset);
StreamWriter NameBufferWriter(NamesBuffer);
for (auto &Name : SourceFileNames) {
Name.second = NameBufferWriter.getOffset();
@@ -190,16 +191,11 @@ Error DbiStreamBuilder::generateFileInfoSubstream() {
return Error::success();
}
-Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build(PDBFile &File) {
- if (!VerHeader.hasValue())
- return make_error<RawError>(raw_error_code::unspecified,
- "Missing DBI Stream Version");
+Error DbiStreamBuilder::finalize() {
+ if (Header)
+ return Error::success();
- auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, File);
- if (!DbiS)
- return DbiS.takeError();
- auto DS = std::move(*DbiS);
- DbiStreamHeader *H = DS->getAllocator().Allocate<DbiStreamHeader>(1);
+ DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
if (auto EC = generateModiSubstream())
return std::move(EC);
@@ -227,13 +223,47 @@ Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build(PDBFile &File) {
H->MFCTypeServerIndex = kInvalidStreamIndex;
H->GlobalSymbolStreamIndex = kInvalidStreamIndex;
- auto Dbi = llvm::make_unique<DbiStream>(File, std::move(DS));
- Dbi->Header = H;
- Dbi->FileInfoSubstream = StreamRef(FileInfoBuffer);
- Dbi->ModInfoSubstream = StreamRef(ModInfoBuffer);
+ Header = H;
+ return Error::success();
+}
+
+Expected<std::unique_ptr<DbiStream>>
+DbiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
+ if (!VerHeader.hasValue())
+ return make_error<RawError>(raw_error_code::unspecified,
+ "Missing DBI Stream Version");
+ if (auto EC = finalize())
+ return std::move(EC);
+
+ auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(),
+ Buffer, StreamDBI);
+ auto Dbi = llvm::make_unique<DbiStream>(File, std::move(StreamData));
+ Dbi->Header = Header;
+ Dbi->FileInfoSubstream = ReadableStreamRef(FileInfoBuffer);
+ Dbi->ModInfoSubstream = ReadableStreamRef(ModInfoBuffer);
if (auto EC = Dbi->initializeModInfoArray())
return std::move(EC);
if (auto EC = Dbi->initializeFileInfo())
return std::move(EC);
return std::move(Dbi);
}
+
+Error DbiStreamBuilder::commit(const msf::MsfLayout &Layout,
+ const msf::WritableStream &Buffer) const {
+ auto InfoS =
+ WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamDBI);
+
+ StreamWriter Writer(*InfoS);
+ if (auto EC = Writer.writeObject(*Header))
+ return EC;
+
+ if (auto EC = Writer.writeStreamRef(ModInfoBuffer))
+ return EC;
+ if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
+ return EC;
+
+ if (Writer.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::invalid_format,
+ "Unexpected bytes found in DBI Stream");
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
index c55f51d7d4a..4df24f240f3 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp
@@ -15,6 +15,7 @@
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -27,7 +28,7 @@ InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
Error InfoStream::reload() {
StreamReader Reader(*Stream);
- const HeaderInfo *H;
+ const InfoStreamHeader *H;
if (auto EC = Reader.readObject(H))
return joinErrors(
std::move(EC),
@@ -74,17 +75,3 @@ uint32_t InfoStream::getSignature() const { return Signature; }
uint32_t InfoStream::getAge() const { return Age; }
PDB_UniqueId InfoStream::getGuid() const { return Guid; }
-
-Error InfoStream::commit() {
- StreamWriter Writer(*Stream);
-
- HeaderInfo 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/InfoStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
index 444aba6be0b..d20c37d9f29 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
@@ -13,13 +13,15 @@
#include "llvm/DebugInfo/Msf/StreamWriter.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
+#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
-InfoStreamBuilder::InfoStreamBuilder() {}
+InfoStreamBuilder::InfoStreamBuilder()
+ : Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0) {}
void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
@@ -34,35 +36,38 @@ NameMapBuilder &InfoStreamBuilder::getNamedStreamsBuilder() {
}
uint32_t InfoStreamBuilder::calculateSerializedLength() const {
- return sizeof(InfoStream::HeaderInfo) +
- NamedStreams.calculateSerializedLength();
+ return sizeof(InfoStreamHeader) + 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");
- 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;
+Expected<std::unique_ptr<InfoStream>>
+InfoStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
+ auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(),
+ Buffer, StreamPDB);
+ auto Info = llvm::make_unique<InfoStream>(std::move(StreamData));
+ Info->Version = Ver;
+ Info->Signature = Sig;
+ Info->Age = Age;
+ Info->Guid = Guid;
auto NS = NamedStreams.build();
if (!NS)
return NS.takeError();
Info->NamedStreams = **NS;
return std::move(Info);
}
+
+Error InfoStreamBuilder::commit(const msf::MsfLayout &Layout,
+ const msf::WritableStream &Buffer) const {
+ auto InfoS =
+ WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamPDB);
+ StreamWriter Writer(*InfoS);
+
+ InfoStreamHeader H;
+ H.Age = Age;
+ H.Signature = Sig;
+ H.Version = Ver;
+ H.Guid = Guid;
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+
+ return NamedStreams.commit(Writer);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
index 89a03ec3a4d..7b77bcda421 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp
@@ -27,7 +27,7 @@ ModInfo::ModInfo(const ModInfo &Info)
ModInfo::~ModInfo() {}
-Error ModInfo::initialize(StreamRef Stream, ModInfo &Info) {
+Error ModInfo::initialize(ReadableStreamRef Stream, ModInfo &Info) {
StreamReader Reader(Stream);
if (auto EC = Reader.readObject(Info.Layout))
return EC;
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
index 65d59a5e894..25bb9d15165 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp
@@ -36,7 +36,7 @@ Error ModStream::reload() {
return llvm::make_error<RawError>(raw_error_code::corrupt_file,
"Module has both C11 and C13 line info");
- StreamRef S;
+ ReadableStreamRef S;
uint32_t SymbolSubstreamSig = 0;
if (auto EC = Reader.readInteger(SymbolSubstreamSig))
diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
index e17600986c9..70b810f1522 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp
@@ -145,60 +145,6 @@ Error NameMap::load(StreamReader &Stream) {
return Error::success();
}
-Error NameMap::commit(StreamWriter &Writer) {
- // The first field is the number of bytes of string data. So add
- // up the length of all strings plus a null terminator for each
- // one.
- uint32_t NumBytes = 0;
- for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
- NumBytes += B->getKeyLength() + 1;
- }
-
- if (auto EC = Writer.writeInteger(NumBytes)) // Number of bytes of string data
- return EC;
- // Now all of the string data itself.
- for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
- if (auto EC = Writer.writeZeroString(B->getKey()))
- return EC;
- }
-
- if (auto EC = Writer.writeInteger(Mapping.size())) // Hash Size
- return EC;
-
- if (auto EC = Writer.writeInteger(Mapping.size())) // Max Number of Strings
- return EC;
-
- if (auto EC = Writer.writeInteger(Mapping.size())) // Num Present Words
- return EC;
-
- // For each entry in the mapping, write a bit mask which represents a bucket
- // to store it in. We don't use this, so the value we write isn't important
- // to us, it just has to be there.
- for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
- if (auto EC = Writer.writeInteger(1U))
- return EC;
- }
-
- if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words
- return EC;
-
- // Mappings of each word.
- uint32_t OffsetSoFar = 0;
- for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) {
- // This is a list of key value pairs where the key is the offset into the
- // strings buffer, and the value is a stream number. Write each pair.
- if (auto EC = Writer.writeInteger(OffsetSoFar))
- return EC;
-
- if (auto EC = Writer.writeInteger(B->second))
- return EC;
-
- OffsetSoFar += B->getKeyLength() + 1;
- }
-
- 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/NameMapBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
index 41c6c2cd810..3bb4503fe6a 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/NameMapBuilder.cpp
@@ -9,6 +9,7 @@
#include "llvm/DebugInfo/PDB/Raw/NameMapBuilder.h"
+#include "llvm/DebugInfo/Msf/StreamWriter.h"
#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
#include "llvm/Support/Endian.h"
@@ -48,3 +49,57 @@ uint32_t NameMapBuilder::calculateSerializedLength() const {
return TotalLength;
}
+
+Error NameMapBuilder::commit(msf::StreamWriter &Writer) const {
+ // The first field is the number of bytes of string data. So add
+ // up the length of all strings plus a null terminator for each
+ // one.
+ uint32_t NumBytes = 0;
+ for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+ NumBytes += B->getKeyLength() + 1;
+ }
+
+ if (auto EC = Writer.writeInteger(NumBytes)) // Number of bytes of string data
+ return EC;
+ // Now all of the string data itself.
+ for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+ if (auto EC = Writer.writeZeroString(B->getKey()))
+ return EC;
+ }
+
+ if (auto EC = Writer.writeInteger(Map.size())) // Hash Size
+ return EC;
+
+ if (auto EC = Writer.writeInteger(Map.size())) // Max Number of Strings
+ return EC;
+
+ if (auto EC = Writer.writeInteger(Map.size())) // Num Present Words
+ return EC;
+
+ // For each entry in the mapping, write a bit mask which represents a bucket
+ // to store it in. We don't use this, so the value we write isn't important
+ // to us, it just has to be there.
+ for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+ if (auto EC = Writer.writeInteger(1U))
+ return EC;
+ }
+
+ if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words
+ return EC;
+
+ // Mappings of each word.
+ uint32_t OffsetSoFar = 0;
+ for (auto B = Map.begin(), E = Map.end(); B != E; ++B) {
+ // This is a list of key value pairs where the key is the offset into the
+ // strings buffer, and the value is a stream number. Write each pair.
+ if (auto EC = Writer.writeInteger(OffsetSoFar))
+ return EC;
+
+ if (auto EC = Writer.writeInteger(B->second))
+ return EC;
+
+ OffsetSoFar += B->getKeyLength() + 1;
+ }
+
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index ea0a8c91304..3529860899e 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -34,48 +34,53 @@ namespace {
typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
}
-PDBFile::PDBFile(std::unique_ptr<StreamInterface> PdbFileBuffer,
+PDBFile::PDBFile(std::unique_ptr<ReadableStream> PdbFileBuffer,
BumpPtrAllocator &Allocator)
: Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}
PDBFile::~PDBFile() {}
-uint32_t PDBFile::getBlockSize() const { return MsfLayout.SB->BlockSize; }
+uint32_t PDBFile::getBlockSize() const { return ContainerLayout.SB->BlockSize; }
uint32_t PDBFile::getFreeBlockMapBlock() const {
- return MsfLayout.SB->FreeBlockMapBlock;
+ return ContainerLayout.SB->FreeBlockMapBlock;
}
-uint32_t PDBFile::getBlockCount() const { return MsfLayout.SB->NumBlocks; }
+uint32_t PDBFile::getBlockCount() const {
+ return ContainerLayout.SB->NumBlocks;
+}
uint32_t PDBFile::getNumDirectoryBytes() const {
- return MsfLayout.SB->NumDirectoryBytes;
+ return ContainerLayout.SB->NumDirectoryBytes;
}
uint32_t PDBFile::getBlockMapIndex() const {
- return MsfLayout.SB->BlockMapAddr;
+ return ContainerLayout.SB->BlockMapAddr;
}
-uint32_t PDBFile::getUnknown1() const { return MsfLayout.SB->Unknown1; }
+uint32_t PDBFile::getUnknown1() const { return ContainerLayout.SB->Unknown1; }
uint32_t PDBFile::getNumDirectoryBlocks() const {
- return msf::bytesToBlocks(MsfLayout.SB->NumDirectoryBytes,
- MsfLayout.SB->BlockSize);
+ return msf::bytesToBlocks(ContainerLayout.SB->NumDirectoryBytes,
+ ContainerLayout.SB->BlockSize);
}
uint64_t PDBFile::getBlockMapOffset() const {
- return (uint64_t)MsfLayout.SB->BlockMapAddr * MsfLayout.SB->BlockSize;
+ return (uint64_t)ContainerLayout.SB->BlockMapAddr *
+ ContainerLayout.SB->BlockSize;
}
-uint32_t PDBFile::getNumStreams() const { return MsfLayout.StreamSizes.size(); }
+uint32_t PDBFile::getNumStreams() const {
+ return ContainerLayout.StreamSizes.size();
+}
uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
- return MsfLayout.StreamSizes[StreamIndex];
+ return ContainerLayout.StreamSizes[StreamIndex];
}
ArrayRef<support::ulittle32_t>
PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
- return MsfLayout.StreamMap[StreamIndex];
+ return ContainerLayout.StreamMap[StreamIndex];
}
uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }
@@ -92,18 +97,8 @@ Expected<ArrayRef<uint8_t>> PDBFile::getBlockData(uint32_t BlockIndex,
Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
ArrayRef<uint8_t> Data) const {
- if (Offset >= getBlockSize())
- return make_error<RawError>(
- raw_error_code::invalid_block_address,
- "setBlockData attempted to write out of block bounds.");
- if (Data.size() > getBlockSize() - Offset)
- return make_error<RawError>(
- raw_error_code::invalid_block_address,
- "setBlockData attempted to write out of block bounds.");
-
- uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());
- StreamBlockOffset += Offset;
- return Buffer->writeBytes(StreamBlockOffset, Data);
+ return make_error<RawError>(raw_error_code::not_writable,
+ "PDBFile is immutable");
}
Error PDBFile::parseFileHeaders() {
@@ -122,18 +117,18 @@ Error PDBFile::parseFileHeaders() {
if (Buffer->getLength() % SB->BlockSize != 0)
return make_error<RawError>(raw_error_code::corrupt_file,
"File size is not a multiple of block size");
- MsfLayout.SB = SB;
+ ContainerLayout.SB = SB;
Reader.setOffset(getBlockMapOffset());
- if (auto EC =
- Reader.readArray(MsfLayout.DirectoryBlocks, getNumDirectoryBlocks()))
+ if (auto EC = Reader.readArray(ContainerLayout.DirectoryBlocks,
+ getNumDirectoryBlocks()))
return EC;
return Error::success();
}
Error PDBFile::parseStreamData() {
- assert(MsfLayout.SB);
+ assert(ContainerLayout.SB);
if (DirectoryStream)
return Error::success();
@@ -144,15 +139,12 @@ Error PDBFile::parseStreamData() {
// is exactly what we are attempting to parse. By specifying a custom
// subclass of IPDBStreamData which only accesses the fields that have already
// been parsed, we can avoid this and reuse MappedBlockStream.
- auto DS = MappedBlockStream::createDirectoryStream(
- MsfLayout.SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
- if (!DS)
- return DS.takeError();
- StreamReader Reader(**DS);
+ auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer);
+ StreamReader Reader(*DS);
if (auto EC = Reader.readInteger(NumStreams))
return EC;
- if (auto EC = Reader.readArray(MsfLayout.StreamSizes, NumStreams))
+ if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))
return EC;
for (uint32_t I = 0; I < NumStreams; ++I) {
uint32_t StreamSize = getStreamByteSize(I);
@@ -160,7 +152,7 @@ Error PDBFile::parseStreamData() {
uint64_t NumExpectedStreamBlocks =
StreamSize == UINT32_MAX
? 0
- : msf::bytesToBlocks(StreamSize, MsfLayout.SB->BlockSize);
+ : msf::bytesToBlocks(StreamSize, ContainerLayout.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
@@ -172,30 +164,30 @@ Error PDBFile::parseStreamData() {
if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
return EC;
for (uint32_t Block : Blocks) {
- uint64_t BlockEndOffset = (uint64_t)(Block + 1) * MsfLayout.SB->BlockSize;
+ uint64_t BlockEndOffset =
+ (uint64_t)(Block + 1) * ContainerLayout.SB->BlockSize;
if (BlockEndOffset > getFileSize())
return make_error<RawError>(raw_error_code::corrupt_file,
"Stream block map is corrupt.");
}
- MsfLayout.StreamMap.push_back(Blocks);
+ ContainerLayout.StreamMap.push_back(Blocks);
}
// We should have read exactly SB->NumDirectoryBytes bytes.
assert(Reader.bytesRemaining() == 0);
- DirectoryStream = std::move(*DS);
+ DirectoryStream = std::move(DS);
return Error::success();
}
llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
- return MsfLayout.DirectoryBlocks;
+ return ContainerLayout.DirectoryBlocks;
}
Expected<InfoStream &> PDBFile::getPDBInfoStream() {
if (!Info) {
- auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this);
- if (!InfoS)
- return InfoS.takeError();
- auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
+ auto InfoS = MappedBlockStream::createIndexedStream(ContainerLayout,
+ *Buffer, StreamPDB);
+ auto TempInfo = llvm::make_unique<InfoStream>(std::move(InfoS));
if (auto EC = TempInfo->reload())
return std::move(EC);
Info = std::move(TempInfo);
@@ -205,10 +197,9 @@ Expected<InfoStream &> PDBFile::getPDBInfoStream() {
Expected<DbiStream &> PDBFile::getPDBDbiStream() {
if (!Dbi) {
- auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, *this);
- if (!DbiS)
- return DbiS.takeError();
- auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(*DbiS));
+ auto DbiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+ StreamDBI);
+ auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(DbiS));
if (auto EC = TempDbi->reload())
return std::move(EC);
Dbi = std::move(TempDbi);
@@ -218,10 +209,9 @@ Expected<DbiStream &> PDBFile::getPDBDbiStream() {
Expected<TpiStream &> PDBFile::getPDBTpiStream() {
if (!Tpi) {
- auto TpiS = MappedBlockStream::createIndexedStream(StreamTPI, *this);
- if (!TpiS)
- return TpiS.takeError();
- auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
+ auto TpiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+ StreamTPI);
+ auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(TpiS));
if (auto EC = TempTpi->reload())
return std::move(EC);
Tpi = std::move(TempTpi);
@@ -231,10 +221,9 @@ Expected<TpiStream &> PDBFile::getPDBTpiStream() {
Expected<TpiStream &> PDBFile::getPDBIpiStream() {
if (!Ipi) {
- auto IpiS = MappedBlockStream::createIndexedStream(StreamIPI, *this);
- if (!IpiS)
- return IpiS.takeError();
- auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
+ auto IpiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+ StreamIPI);
+ auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(IpiS));
if (auto EC = TempIpi->reload())
return std::move(EC);
Ipi = std::move(TempIpi);
@@ -250,12 +239,10 @@ Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
uint32_t PublicsStreamNum = DbiS->getPublicSymbolStreamIndex();
- auto PublicS =
- MappedBlockStream::createIndexedStream(PublicsStreamNum, *this);
- if (!PublicS)
- return PublicS.takeError();
+ auto PublicS = MappedBlockStream::createIndexedStream(
+ ContainerLayout, *Buffer, PublicsStreamNum);
auto TempPublics =
- llvm::make_unique<PublicsStream>(*this, std::move(*PublicS));
+ llvm::make_unique<PublicsStream>(*this, std::move(PublicS));
if (auto EC = TempPublics->reload())
return std::move(EC);
Publics = std::move(TempPublics);
@@ -270,12 +257,10 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
return DbiS.takeError();
uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
+ auto SymbolS = MappedBlockStream::createIndexedStream(
+ ContainerLayout, *Buffer, SymbolStreamNum);
- auto SymbolS =
- MappedBlockStream::createIndexedStream(SymbolStreamNum, *this);
- if (!SymbolS)
- return SymbolS.takeError();
- auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
+ auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(SymbolS));
if (auto EC = TempSymbols->reload())
return std::move(EC);
Symbols = std::move(TempSymbols);
@@ -295,76 +280,15 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
return make_error<RawError>(raw_error_code::no_stream);
if (NameStreamIndex >= getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
+ auto NS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
+ NameStreamIndex);
- auto NS = MappedBlockStream::createIndexedStream(NameStreamIndex, *this);
- if (!NS)
- return NS.takeError();
-
- StreamReader Reader(**NS);
+ StreamReader Reader(*NS);
auto N = llvm::make_unique<NameHashTable>();
if (auto EC = N->load(Reader))
return std::move(EC);
StringTable = std::move(N);
- StringTableStream = std::move(*NS);
+ StringTableStream = std::move(NS);
}
return *StringTable;
}
-
-Error PDBFile::commit() {
- StreamWriter Writer(*Buffer);
-
- if (auto EC = Writer.writeObject(*MsfLayout.SB))
- return EC;
- Writer.setOffset(getBlockMapOffset());
- if (auto EC = Writer.writeArray(MsfLayout.DirectoryBlocks))
- return EC;
-
- auto DS = MappedBlockStream::createDirectoryStream(
- MsfLayout.SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
- if (!DS)
- return DS.takeError();
- auto DirStream = std::move(*DS);
- StreamWriter DW(*DirStream);
- if (auto EC = DW.writeInteger(this->getNumStreams()))
- return EC;
-
- if (auto EC = DW.writeArray(MsfLayout.StreamSizes))
- return EC;
-
- for (const auto &Blocks : MsfLayout.StreamMap) {
- if (auto EC = DW.writeArray(Blocks))
- 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();
-}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
index 5007a56f276..6715f3d3fa1 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
@@ -58,7 +58,7 @@ DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
return *Dbi;
}
-Expected<msf::Layout> PDBFileBuilder::finalizeMsfLayout() const {
+Expected<msf::MsfLayout> PDBFileBuilder::finalizeMsfLayout() const {
if (Info) {
uint32_t Length = Info->calculateSerializedLength();
if (auto EC = Msf->setStreamSize(StreamPDB, Length))
@@ -74,23 +74,23 @@ Expected<msf::Layout> PDBFileBuilder::finalizeMsfLayout() const {
}
Expected<std::unique_ptr<PDBFile>>
-PDBFileBuilder::build(std::unique_ptr<msf::StreamInterface> PdbFileBuffer) {
+PDBFileBuilder::build(std::unique_ptr<msf::WritableStream> PdbFileBuffer) {
auto ExpectedLayout = finalizeMsfLayout();
if (!ExpectedLayout)
return ExpectedLayout.takeError();
auto File = llvm::make_unique<PDBFile>(std::move(PdbFileBuffer), Allocator);
- File->MsfLayout = *ExpectedLayout;
+ File->ContainerLayout = *ExpectedLayout;
if (Info) {
- auto ExpectedInfo = Info->build(*File);
+ auto ExpectedInfo = Info->build(*File, *PdbFileBuffer);
if (!ExpectedInfo)
return ExpectedInfo.takeError();
File->Info = std::move(*ExpectedInfo);
}
if (Dbi) {
- auto ExpectedDbi = Dbi->build(*File);
+ auto ExpectedDbi = Dbi->build(*File, *PdbFileBuffer);
if (!ExpectedDbi)
return ExpectedDbi.takeError();
File->Dbi = std::move(*ExpectedDbi);
@@ -103,3 +103,45 @@ PDBFileBuilder::build(std::unique_ptr<msf::StreamInterface> PdbFileBuffer) {
return std::move(File);
}
+
+Error PDBFileBuilder::commit(const msf::WritableStream &Buffer) {
+ StreamWriter Writer(Buffer);
+ auto ExpectedLayout = finalizeMsfLayout();
+ if (!ExpectedLayout)
+ return ExpectedLayout.takeError();
+ auto &Layout = *ExpectedLayout;
+
+ 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(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) {
+ if (auto EC = Info->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Dbi) {
+ if (auto EC = Dbi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ return Buffer.commit();
+} \ No newline at end of file
diff --git a/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp b/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp
index e6d915fcaee..a83689f5741 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/RawSession.cpp
@@ -26,21 +26,6 @@ using namespace llvm;
using namespace llvm::msf;
using namespace llvm::pdb;
-namespace {
-// We need a class which behaves like an immutable ByteStream, but whose data
-// is backed by an llvm::MemoryBuffer. It also needs to own the underlying
-// MemoryBuffer, so this simple adapter is a good way to achieve that.
-class InputByteStream : public ByteStream<false> {
-public:
- explicit InputByteStream(std::unique_ptr<MemoryBuffer> Buffer)
- : ByteStream(ArrayRef<uint8_t>(Buffer->getBuffer().bytes_begin(),
- Buffer->getBuffer().bytes_end())),
- MemBuffer(std::move(Buffer)) {}
-
- std::unique_ptr<MemoryBuffer> MemBuffer;
-};
-}
-
RawSession::RawSession(std::unique_ptr<PDBFile> PdbFile,
std::unique_ptr<BumpPtrAllocator> Allocator)
: Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)) {}
@@ -57,7 +42,7 @@ Error RawSession::createFromPdb(StringRef Path,
return llvm::make_error<GenericError>(generic_error_code::invalid_path);
std::unique_ptr<MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
- auto Stream = llvm::make_unique<InputByteStream>(std::move(Buffer));
+ auto Stream = llvm::make_unique<MemoryBufferByteStream>(std::move(Buffer));
auto Allocator = llvm::make_unique<BumpPtrAllocator>();
auto File = llvm::make_unique<PDBFile>(std::move(Stream), *Allocator);
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index 6756580547a..a39a040705b 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -188,12 +188,9 @@ Error TpiStream::reload() {
if (Header->HashStreamIndex >= Pdb.getNumStreams())
return make_error<RawError>(raw_error_code::corrupt_file,
"Invalid TPI hash stream index.");
-
- auto HS =
- MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb);
- if (!HS)
- return HS.takeError();
- StreamReader HSR(**HS);
+ auto HS = MappedBlockStream::createIndexedStream(
+ Pdb.getMsfLayout(), Pdb.getMsfBuffer(), Header->HashStreamIndex);
+ StreamReader HSR(*HS);
uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
if (NumHashValues != NumTypeRecords())
@@ -216,7 +213,7 @@ Error TpiStream::reload() {
if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
return EC;
- HashStream = std::move(*HS);
+ HashStream = std::move(HS);
// TPI hash table is a parallel array for the type records.
// Verify that the hash values match with type records.
OpenPOWER on IntegriCloud