diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/DebugInfo/MSF/MSFBuilder.h | 7 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/Support/BinaryByteStream.h | 12 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/MSF/MSFBuilder.cpp | 78 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp | 86 | ||||
-rw-r--r-- | llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp | 16 |
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]; |