mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[msf] Make FPM reader use MappedBlockStream.
MappedBlockSTream can work with any sequence of block data where the ordering is specified by a list of block numbers. So rather than manually stitch them together in the case of the FPM, reuse this functionality so that we can treat the FPM as if it were contiguous. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D23066 llvm-svn: 277609
This commit is contained in:
parent
02cd526c3c
commit
16b9ab7f45
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
@ -49,6 +48,9 @@ public:
|
||||
createIndexedStream(const MSFLayout &Layout, const ReadableStream &MsfData,
|
||||
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);
|
||||
|
||||
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user