diff options
| -rw-r--r-- | llvm/include/llvm/DebugInfo/MSF/MSFCommon.h | 13 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/MSF/MSFStreamLayout.h | 4 | ||||
| -rw-r--r-- | llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h | 7 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp | 30 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp | 5 |
6 files changed, 65 insertions, 23 deletions
diff --git a/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h b/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h index 5cf784e5868..93a9c808b73 100644 --- a/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h +++ b/llvm/include/llvm/DebugInfo/MSF/MSFCommon.h @@ -84,6 +84,19 @@ inline uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize) { return BlockNumber * BlockSize; } +inline uint32_t getFpmIntervalLength(const MSFLayout &L) { + return L.SB->BlockSize; +} + +inline uint32_t getNumFpmIntervals(const MSFLayout &L) { + uint32_t Length = getFpmIntervalLength(L); + return llvm::alignTo(L.SB->NumBlocks, Length) / Length; +} + +inline uint32_t getFullFpmByteSize(const MSFLayout &L) { + return llvm::alignTo(L.SB->NumBlocks, 8) / 8; +} + Error validateSuperBlock(const SuperBlock &SB); } // namespace msf } // namespace llvm diff --git a/llvm/include/llvm/DebugInfo/MSF/MSFStreamLayout.h b/llvm/include/llvm/DebugInfo/MSF/MSFStreamLayout.h index 1b987aa04cf..bdde98f5266 100644 --- a/llvm/include/llvm/DebugInfo/MSF/MSFStreamLayout.h +++ b/llvm/include/llvm/DebugInfo/MSF/MSFStreamLayout.h @@ -10,10 +10,10 @@ #ifndef LLVM_DEBUGINFO_MSF_MSFSTREAMLAYOUT_H #define LLVM_DEBUGINFO_MSF_MSFSTREAMLAYOUT_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Endian.h" #include <cstdint> +#include <vector> namespace llvm { namespace msf { @@ -27,7 +27,7 @@ namespace msf { class MSFStreamLayout { public: uint32_t Length; - ArrayRef<support::ulittle32_t> Blocks; + std::vector<support::ulittle32_t> Blocks; }; } // namespace msf } // namespace llvm diff --git a/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h b/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h index aef6b011153..fff4e9cecef 100644 --- a/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h +++ b/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h @@ -39,7 +39,6 @@ struct MSFLayout; /// of bytes. class MappedBlockStream : public ReadableStream { friend class WritableMappedBlockStream; - public: static std::unique_ptr<MappedBlockStream> createStream(uint32_t BlockSize, uint32_t NumBlocks, @@ -50,6 +49,9 @@ public: uint32_t StreamIndex); static std::unique_ptr<MappedBlockStream> + createFpmStream(const MSFLayout &Layout, const ReadableStream &MsfData); + + static std::unique_ptr<MappedBlockStream> createDirectoryStream(const MSFLayout &Layout, const ReadableStream &MsfData); Error readBytes(uint32_t Offset, uint32_t Size, @@ -105,6 +107,9 @@ public: static std::unique_ptr<WritableMappedBlockStream> createDirectoryStream(const MSFLayout &Layout, const WritableStream &MsfData); + static std::unique_ptr<WritableMappedBlockStream> + createFpmStream(const MSFLayout &Layout, const WritableStream &MsfData); + Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef<uint8_t> &Buffer) const override; Error readLongestContiguousChunk(uint32_t Offset, diff --git a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp index 0a3b2b96ab4..bbcfbfca810 100644 --- a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp +++ b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp @@ -26,6 +26,19 @@ public: }; } +static void initializeFpmStreamLayout(const MSFLayout &Layout, + MSFStreamLayout &FpmLayout) { + uint32_t NumFpmIntervals = msf::getNumFpmIntervals(Layout); + support::ulittle32_t FpmBlock = Layout.SB->FreeBlockMapBlock; + assert(FpmBlock == 1 || FpmBlock == 2); + while (NumFpmIntervals > 0) { + FpmLayout.Blocks.push_back(FpmBlock); + FpmBlock += msf::getFpmIntervalLength(Layout); + --NumFpmIntervals; + } + FpmLayout.Length = msf::getFullFpmByteSize(Layout); +} + typedef std::pair<uint32_t, uint32_t> Interval; static Interval intersect(const Interval &I1, const Interval &I2) { return std::make_pair(std::max(I1.first, I2.first), @@ -66,6 +79,14 @@ MappedBlockStream::createDirectoryStream(const MSFLayout &Layout, return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData); } +std::unique_ptr<MappedBlockStream> +MappedBlockStream::createFpmStream(const MSFLayout &Layout, + const ReadableStream &MsfData) { + MSFStreamLayout SL; + initializeFpmStreamLayout(Layout, SL); + 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. @@ -324,6 +345,14 @@ WritableMappedBlockStream::createDirectoryStream( return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData); } +std::unique_ptr<WritableMappedBlockStream> +WritableMappedBlockStream::createFpmStream(const MSFLayout &Layout, + const WritableStream &MsfData) { + MSFStreamLayout SL; + initializeFpmStreamLayout(Layout, SL); + 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); diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp index 8520408ebd3..75840b0e776 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -122,7 +122,6 @@ Error PDBFile::parseFileHeaders() { // Initialize Free Page Map. ContainerLayout.FreePageMap.resize(SB->NumBlocks); - ArrayRef<uint8_t> FpmBytes; // The Fpm exists either at block 1 or block 2 of the MSF. However, this // allows for a maximum of getBlockSize() * 8 blocks bits in the Fpm, and // thusly an equal number of total blocks in the file. For a block size @@ -136,25 +135,22 @@ Error PDBFile::parseFileHeaders() { // at getBlockSize() intervals, so we have to be compatible. // See the function fpmPn() for more information: // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489 - - uint32_t BlocksPerSection = getBlockSize(); - uint64_t FpmBlockOffset = SB->FreeBlockMapBlock; + auto FpmStream = MappedBlockStream::createFpmStream(ContainerLayout, *Buffer); + StreamReader FpmReader(*FpmStream); + ArrayRef<uint8_t> FpmBytes; + if (auto EC = FpmReader.readBytes(FpmBytes, + msf::getFullFpmByteSize(ContainerLayout))) + return EC; uint32_t BlocksRemaining = getBlockCount(); - for (uint32_t SI = 0; BlocksRemaining > 0; ++SI) { - uint32_t FpmFileOffset = FpmBlockOffset * getBlockSize(); - - if (auto EC = Buffer->readBytes(FpmFileOffset, getBlockSize(), FpmBytes)) - return EC; - - uint32_t BlocksThisSection = std::min(BlocksRemaining, BlocksPerSection); - for (uint32_t I = 0; I < BlocksThisSection; ++I) { - uint32_t BI = I + BlocksPerSection * SI; - - if (FpmBytes[I / 8] & (1 << (I % 8))) + uint32_t BI = 0; + for (auto Byte : FpmBytes) { + uint32_t BlocksThisByte = std::min(BlocksRemaining, 8U); + for (uint32_t I = 0; I < BlocksThisByte; ++I) { + if (Byte & (1 << I)) ContainerLayout.FreePageMap[BI] = true; + --BlocksRemaining; + ++BI; } - BlocksRemaining -= BlocksThisSection; - FpmBlockOffset += BlocksPerSection; } Reader.setOffset(getBlockMapOffset()); diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp index 3018a70d4c0..b4e5ea70de1 100644 --- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp +++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp @@ -291,9 +291,8 @@ Error LLVMOutputStyle::dumpFreePageMap() { recordKnownUsedPage(PS, 0); // MSF Super Block - uint32_t BlocksPerSection = File.getBlockSize(); - uint32_t NumSections = - llvm::alignTo(File.getBlockCount(), BlocksPerSection) / BlocksPerSection; + uint32_t BlocksPerSection = msf::getFpmIntervalLength(File.getMsfLayout()); + uint32_t NumSections = msf::getNumFpmIntervals(File.getMsfLayout()); for (uint32_t I = 0; I < NumSections; ++I) { uint32_t Fpm0 = 1 + BlocksPerSection * I; // 2 Fpm blocks spaced at `getBlockSize()` block intervals |

