summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h7
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h2
-rw-r--r--llvm/include/llvm/Support/BinaryByteStream.h12
-rw-r--r--llvm/lib/DebugInfo/MSF/MSFBuilder.cpp78
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp86
-rw-r--r--llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp16
6 files changed, 118 insertions, 83 deletions
diff --git a/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h b/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h
index c06a0b4687d..3de98c4ecba 100644
--- a/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h
+++ b/llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h
@@ -20,6 +20,8 @@
#include <vector>
namespace llvm {
+class FileBufferByteStream;
+class WritableBinaryStream;
namespace msf {
class MSFBuilder {
@@ -109,7 +111,10 @@ public:
/// Finalize the layout and build the headers and structures that describe the
/// MSF layout and can be written directly to the MSF file.
- Expected<MSFLayout> build();
+ Expected<MSFLayout> generateLayout();
+
+ /// Write the MSF layout to the underlying file.
+ Expected<FileBufferByteStream> commit(StringRef Path, MSFLayout &Layout);
BumpPtrAllocator &getAllocator() { return Allocator; }
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
index 58dda71bf35..7f9c4cf9fa8 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
@@ -76,7 +76,7 @@ private:
std::unique_ptr<MemoryBuffer> Content;
};
- Expected<msf::MSFLayout> finalizeMsfLayout();
+ Error finalizeMsfLayout();
Expected<uint32_t> allocateNamedStream(StringRef Name, uint32_t Size);
void commitFpm(WritableBinaryStream &MsfBuffer, const msf::MSFLayout &Layout);
diff --git a/llvm/include/llvm/Support/BinaryByteStream.h b/llvm/include/llvm/Support/BinaryByteStream.h
index f39ac4e2413..9808d3b7215 100644
--- a/llvm/include/llvm/Support/BinaryByteStream.h
+++ b/llvm/include/llvm/Support/BinaryByteStream.h
@@ -222,6 +222,12 @@ private:
return Error::success();
}
+ /// Returns a pointer to the start of the buffer.
+ uint8_t *getBufferStart() const { return FileBuffer->getBufferStart(); }
+
+ /// Returns a pointer to the end of the buffer.
+ uint8_t *getBufferEnd() const { return FileBuffer->getBufferEnd(); }
+
private:
std::unique_ptr<FileOutputBuffer> FileBuffer;
};
@@ -253,6 +259,12 @@ public:
Error commit() override { return Impl.commit(); }
+ /// Returns a pointer to the start of the buffer.
+ uint8_t *getBufferStart() const { return Impl.getBufferStart(); }
+
+ /// Returns a pointer to the end of the buffer.
+ uint8_t *getBufferEnd() const { return Impl.getBufferEnd(); }
+
private:
StreamImpl Impl;
};
diff --git a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
index 919f870b34a..71609919558 100644
--- a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
+++ b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
@@ -7,11 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/MSF/MSFError.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -244,7 +248,7 @@ uint32_t MSFBuilder::computeDirectoryByteSize() const {
return Size;
}
-Expected<MSFLayout> MSFBuilder::build() {
+Expected<MSFLayout> MSFBuilder::generateLayout() {
SuperBlock *SB = Allocator.Allocate<SuperBlock>();
MSFLayout L;
L.SB = SB;
@@ -306,3 +310,73 @@ Expected<MSFLayout> MSFBuilder::build() {
return L;
}
+
+static void commitFpm(WritableBinaryStream &MsfBuffer, const MSFLayout &Layout,
+ BumpPtrAllocator &Allocator) {
+ 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);
+}
+
+Expected<FileBufferByteStream> MSFBuilder::commit(StringRef Path,
+ MSFLayout &Layout) {
+ Expected<MSFLayout> L = generateLayout();
+ if (!L)
+ return L.takeError();
+
+ Layout = std::move(*L);
+
+ uint64_t FileSize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
+ auto OutFileOrError = FileOutputBuffer::create(Path, FileSize);
+ if (auto EC = OutFileOrError.takeError())
+ return std::move(EC);
+
+ FileBufferByteStream Buffer(std::move(*OutFileOrError),
+ llvm::support::little);
+ BinaryStreamWriter Writer(Buffer);
+
+ if (auto EC = Writer.writeObject(*Layout.SB))
+ return std::move(EC);
+
+ commitFpm(Buffer, Layout, Allocator);
+
+ uint32_t BlockMapOffset =
+ msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
+ Writer.setOffset(BlockMapOffset);
+ if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
+ return std::move(EC);
+
+ auto DirStream = WritableMappedBlockStream::createDirectoryStream(
+ Layout, Buffer, Allocator);
+ BinaryStreamWriter DW(*DirStream);
+ if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
+ return std::move(EC);
+
+ if (auto EC = DW.writeArray(Layout.StreamSizes))
+ return std::move(EC);
+
+ for (const auto &Blocks : Layout.StreamMap) {
+ if (auto EC = DW.writeArray(Blocks))
+ return std::move(EC);
+ }
+
+ return std::move(Buffer);
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index 77048589e9f..e164e7cf1c5 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -122,7 +122,7 @@ void PDBFileBuilder::addInjectedSource(StringRef Name,
InjectedSources.push_back(std::move(Desc));
}
-Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
+Error PDBFileBuilder::finalizeMsfLayout() {
if (Ipi && Ipi->getRecordCount() > 0) {
// In theory newer PDBs always have an ID stream, but by saying that we're
@@ -141,7 +141,7 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
if (Gsi) {
if (auto EC = Gsi->finalizeMsfLayout())
- return std::move(EC);
+ return EC;
if (Dbi) {
Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex());
Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());
@@ -150,11 +150,11 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
}
if (Tpi) {
if (auto EC = Tpi->finalizeMsfLayout())
- return std::move(EC);
+ return EC;
}
if (Dbi) {
if (auto EC = Dbi->finalizeMsfLayout())
- return std::move(EC);
+ return EC;
}
SN = allocateNamedStream("/names", StringsLen);
if (!SN)
@@ -162,14 +162,14 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
if (Ipi) {
if (auto EC = Ipi->finalizeMsfLayout())
- return std::move(EC);
+ return EC;
}
// Do this last, since it relies on the named stream map being complete, and
// that can be updated by previous steps in the finalization.
if (Info) {
if (auto EC = Info->finalizeMsfLayout())
- return std::move(EC);
+ return EC;
}
if (!InjectedSources.empty()) {
@@ -210,10 +210,10 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
// that can be updated by previous steps in the finalization.
if (Info) {
if (auto EC = Info->finalizeMsfLayout())
- return std::move(EC);
+ return EC;
}
- return Msf->build();
+ return Error::success();
}
Expected<uint32_t> PDBFileBuilder::getNamedStreamIndex(StringRef Name) const {
@@ -223,31 +223,6 @@ 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);
-}
-
void PDBFileBuilder::commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer,
const msf::MSFLayout &Layout) {
assert(!InjectedSourceTable.empty());
@@ -289,45 +264,14 @@ void PDBFileBuilder::commitInjectedSources(WritableBinaryStream &MsfBuffer,
Error PDBFileBuilder::commit(StringRef Filename) {
assert(!Filename.empty());
- auto ExpectedLayout = finalizeMsfLayout();
- if (!ExpectedLayout)
- return ExpectedLayout.takeError();
- auto &Layout = *ExpectedLayout;
-
- uint64_t Filesize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
- auto OutFileOrError = FileOutputBuffer::create(Filename, Filesize);
- if (auto E = OutFileOrError.takeError())
- return E;
- FileOutputBuffer *FOB = OutFileOrError->get();
-
- 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);
- if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
- return EC;
-
- auto DirStream = WritableMappedBlockStream::createDirectoryStream(
- Layout, Buffer, Allocator);
- BinaryStreamWriter DW(*DirStream);
- if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
- return EC;
-
- if (auto EC = DW.writeArray(Layout.StreamSizes))
+ if (auto EC = finalizeMsfLayout())
return EC;
- for (const auto &Blocks : Layout.StreamMap) {
- if (auto EC = DW.writeArray(Blocks))
- return EC;
- }
+ MSFLayout Layout;
+ auto ExpectedMsfBuffer = Msf->commit(Filename, Layout);
+ if (!ExpectedMsfBuffer)
+ return ExpectedMsfBuffer.takeError();
+ FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
auto ExpectedSN = getNamedStreamIndex("/names");
if (!ExpectedSN)
@@ -380,7 +324,7 @@ Error PDBFileBuilder::commit(StringRef Filename) {
uint64_t InfoStreamFileOffset =
blockToOffset(InfoStreamBlocks.front(), Layout.SB->BlockSize);
InfoStreamHeader *H = reinterpret_cast<InfoStreamHeader *>(
- FOB->getBufferStart() + InfoStreamFileOffset);
+ Buffer.getBufferStart() + InfoStreamFileOffset);
commitInjectedSources(Buffer, Layout);
diff --git a/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp b/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
index 2e317796250..16247951804 100644
--- a/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
+++ b/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
@@ -112,7 +112,7 @@ TEST_F(MSFBuilderTest, TestAddStreamNoDirectoryBlockIncrease) {
EXPECT_THAT_EXPECTED(ExpectedMsf, Succeeded());
auto &Msf = *ExpectedMsf;
- auto ExpectedL1 = Msf.build();
+ auto ExpectedL1 = Msf.generateLayout();
EXPECT_THAT_EXPECTED(ExpectedL1, Succeeded());
MSFLayout &L1 = *ExpectedL1;
@@ -129,7 +129,7 @@ TEST_F(MSFBuilderTest, TestAddStreamNoDirectoryBlockIncrease) {
auto Blocks = Msf2.getStreamBlocks(0);
EXPECT_EQ(1U, Blocks.size());
- auto ExpectedL2 = Msf2.build();
+ auto ExpectedL2 = Msf2.generateLayout();
EXPECT_THAT_EXPECTED(ExpectedL2, Succeeded());
MSFLayout &L2 = *ExpectedL2;
auto NewDirBlocks = L2.DirectoryBlocks;
@@ -149,7 +149,7 @@ TEST_F(MSFBuilderTest, TestAddStreamWithDirectoryBlockIncrease) {
EXPECT_THAT_EXPECTED(Msf.addStream(4096 * 4096 / sizeof(uint32_t)),
Succeeded());
- auto ExpectedL1 = Msf.build();
+ auto ExpectedL1 = Msf.generateLayout();
EXPECT_THAT_EXPECTED(ExpectedL1, Succeeded());
MSFLayout &L1 = *ExpectedL1;
auto DirBlocks = L1.DirectoryBlocks;
@@ -289,7 +289,7 @@ TEST_F(MSFBuilderTest, BuildMsfLayout) {
}
++ExpectedNumBlocks; // The directory itself should use 1 block
- auto ExpectedLayout = Msf.build();
+ auto ExpectedLayout = Msf.generateLayout();
EXPECT_THAT_EXPECTED(ExpectedLayout, Succeeded());
MSFLayout &L = *ExpectedLayout;
EXPECT_EQ(4096U, L.SB->BlockSize);
@@ -316,7 +316,7 @@ TEST_F(MSFBuilderTest, UseDirectoryBlockHint) {
EXPECT_THAT_ERROR(Msf.setDirectoryBlocksHint({B + 1}), Succeeded());
EXPECT_THAT_EXPECTED(Msf.addStream(2048, {B + 2}), Succeeded());
- auto ExpectedLayout = Msf.build();
+ auto ExpectedLayout = Msf.generateLayout();
EXPECT_THAT_EXPECTED(ExpectedLayout, Succeeded());
MSFLayout &L = *ExpectedLayout;
EXPECT_EQ(msf::getMinimumBlockCount() + 2, L.SB->NumBlocks);
@@ -338,7 +338,7 @@ TEST_F(MSFBuilderTest, DirectoryBlockHintInsufficient) {
uint32_t Size = 4096 * 4096 / 4;
EXPECT_THAT_EXPECTED(Msf.addStream(Size), Succeeded());
- auto ExpectedLayout = Msf.build();
+ auto ExpectedLayout = Msf.generateLayout();
EXPECT_THAT_EXPECTED(ExpectedLayout, Succeeded());
MSFLayout &L = *ExpectedLayout;
EXPECT_EQ(2U, L.DirectoryBlocks.size());
@@ -356,7 +356,7 @@ TEST_F(MSFBuilderTest, DirectoryBlockHintOverestimated) {
ASSERT_THAT_EXPECTED(Msf.addStream(2048), Succeeded());
- auto ExpectedLayout = Msf.build();
+ auto ExpectedLayout = Msf.generateLayout();
ASSERT_THAT_EXPECTED(ExpectedLayout, Succeeded());
MSFLayout &L = *ExpectedLayout;
EXPECT_EQ(1U, L.DirectoryBlocks.size());
@@ -376,7 +376,7 @@ TEST_F(MSFBuilderTest, StreamDoesntUseFpmBlocks) {
Expected<uint32_t> SN = Msf.addStream(StreamSize);
ASSERT_THAT_EXPECTED(SN, Succeeded());
- auto ExpectedLayout = Msf.build();
+ auto ExpectedLayout = Msf.generateLayout();
ASSERT_THAT_EXPECTED(ExpectedLayout, Succeeded());
MSFLayout &L = *ExpectedLayout;
auto BlocksRef = L.StreamMap[*SN];
OpenPOWER on IntegriCloud