summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/MSF/MSFCommon.h13
-rw-r--r--llvm/include/llvm/DebugInfo/MSF/MSFStreamLayout.h4
-rw-r--r--llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h7
-rw-r--r--llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp29
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp30
-rw-r--r--llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp5
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
OpenPOWER on IntegriCloud