Make PDBFile store an msf::Layout.
Previously it was storing all the fields of an msf::Layout as separate members. This is a trivial cleanup to make it store an msf::Layout directly. This makes the code more readable since it becomes clear which fields of PDBFile are actually the msf specific layout information in a sea of other bookkeeping fields. llvm-svn: 276460
This commit is contained in:
parent
e109dc63f9
commit
e4a4f33daf
|
@ -49,7 +49,8 @@ struct SuperBlock {
|
|||
};
|
||||
|
||||
struct Layout {
|
||||
SuperBlock *SB;
|
||||
Layout() : SB(nullptr) {}
|
||||
const SuperBlock *SB;
|
||||
ArrayRef<support::ulittle32_t> DirectoryBlocks;
|
||||
ArrayRef<support::ulittle32_t> StreamSizes;
|
||||
std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
|
||||
|
|
|
@ -67,9 +67,11 @@ public:
|
|||
Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
|
||||
ArrayRef<uint8_t> Data) const override;
|
||||
|
||||
ArrayRef<support::ulittle32_t> getStreamSizes() const { return StreamSizes; }
|
||||
ArrayRef<support::ulittle32_t> getStreamSizes() const {
|
||||
return MsfLayout.StreamSizes;
|
||||
}
|
||||
ArrayRef<ArrayRef<support::ulittle32_t>> getStreamMap() const {
|
||||
return StreamMap;
|
||||
return MsfLayout.StreamMap;
|
||||
}
|
||||
|
||||
ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
|
||||
|
@ -88,15 +90,11 @@ public:
|
|||
Error commit();
|
||||
|
||||
private:
|
||||
Error setSuperBlock(const msf::SuperBlock *Block);
|
||||
|
||||
BumpPtrAllocator &Allocator;
|
||||
|
||||
std::unique_ptr<msf::StreamInterface> Buffer;
|
||||
const msf::SuperBlock *SB;
|
||||
ArrayRef<support::ulittle32_t> StreamSizes;
|
||||
ArrayRef<support::ulittle32_t> DirectoryBlocks;
|
||||
std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
|
||||
|
||||
msf::Layout MsfLayout;
|
||||
|
||||
std::unique_ptr<InfoStream> Info;
|
||||
std::unique_ptr<DbiStream> Dbi;
|
||||
|
|
|
@ -219,17 +219,18 @@ uint32_t MsfBuilder::computeDirectoryByteSize() const {
|
|||
}
|
||||
|
||||
Expected<Layout> MsfBuilder::build() {
|
||||
SuperBlock *SB = Allocator.Allocate<SuperBlock>();
|
||||
Layout L;
|
||||
L.SB = Allocator.Allocate<SuperBlock>();
|
||||
std::memcpy(L.SB->MagicBytes, Magic, sizeof(Magic));
|
||||
L.SB->BlockMapAddr = BlockMapAddr;
|
||||
L.SB->BlockSize = BlockSize;
|
||||
L.SB->NumDirectoryBytes = computeDirectoryByteSize();
|
||||
L.SB->FreeBlockMapBlock = FreePageMap;
|
||||
L.SB->Unknown1 = Unknown1;
|
||||
L.SB = SB;
|
||||
|
||||
uint32_t NumDirectoryBlocks =
|
||||
bytesToBlocks(L.SB->NumDirectoryBytes, BlockSize);
|
||||
std::memcpy(SB->MagicBytes, Magic, sizeof(Magic));
|
||||
SB->BlockMapAddr = BlockMapAddr;
|
||||
SB->BlockSize = BlockSize;
|
||||
SB->NumDirectoryBytes = computeDirectoryByteSize();
|
||||
SB->FreeBlockMapBlock = FreePageMap;
|
||||
SB->Unknown1 = Unknown1;
|
||||
|
||||
uint32_t NumDirectoryBlocks = bytesToBlocks(SB->NumDirectoryBytes, BlockSize);
|
||||
if (NumDirectoryBlocks > DirectoryBlocks.size()) {
|
||||
// Our hint wasn't enough to satisfy the entire directory. Allocate
|
||||
// remaining pages.
|
||||
|
@ -251,7 +252,7 @@ Expected<Layout> MsfBuilder::build() {
|
|||
// Don't set the number of blocks in the file until after allocating Blocks
|
||||
// for the directory, since the allocation might cause the file to need to
|
||||
// grow.
|
||||
L.SB->NumBlocks = FreeBlocks.size();
|
||||
SB->NumBlocks = FreeBlocks.size();
|
||||
|
||||
ulittle32_t *DirBlocks = Allocator.Allocate<ulittle32_t>(NumDirectoryBlocks);
|
||||
std::uninitialized_copy_n(DirectoryBlocks.begin(), NumDirectoryBlocks,
|
||||
|
|
|
@ -38,39 +38,46 @@ typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
|
|||
|
||||
PDBFile::PDBFile(std::unique_ptr<StreamInterface> PdbFileBuffer,
|
||||
BumpPtrAllocator &Allocator)
|
||||
: Allocator(Allocator), Buffer(std::move(PdbFileBuffer)), SB(nullptr) {}
|
||||
: Allocator(Allocator), Buffer(std::move(PdbFileBuffer)) {}
|
||||
|
||||
PDBFile::~PDBFile() {}
|
||||
|
||||
uint32_t PDBFile::getBlockSize() const { return SB->BlockSize; }
|
||||
uint32_t PDBFile::getBlockSize() const { return MsfLayout.SB->BlockSize; }
|
||||
|
||||
uint32_t PDBFile::getFreeBlockMapBlock() const { return SB->FreeBlockMapBlock; }
|
||||
uint32_t PDBFile::getFreeBlockMapBlock() const {
|
||||
return MsfLayout.SB->FreeBlockMapBlock;
|
||||
}
|
||||
|
||||
uint32_t PDBFile::getBlockCount() const { return SB->NumBlocks; }
|
||||
uint32_t PDBFile::getBlockCount() const { return MsfLayout.SB->NumBlocks; }
|
||||
|
||||
uint32_t PDBFile::getNumDirectoryBytes() const { return SB->NumDirectoryBytes; }
|
||||
uint32_t PDBFile::getNumDirectoryBytes() const {
|
||||
return MsfLayout.SB->NumDirectoryBytes;
|
||||
}
|
||||
|
||||
uint32_t PDBFile::getBlockMapIndex() const { return SB->BlockMapAddr; }
|
||||
uint32_t PDBFile::getBlockMapIndex() const {
|
||||
return MsfLayout.SB->BlockMapAddr;
|
||||
}
|
||||
|
||||
uint32_t PDBFile::getUnknown1() const { return SB->Unknown1; }
|
||||
uint32_t PDBFile::getUnknown1() const { return MsfLayout.SB->Unknown1; }
|
||||
|
||||
uint32_t PDBFile::getNumDirectoryBlocks() const {
|
||||
return msf::bytesToBlocks(SB->NumDirectoryBytes, SB->BlockSize);
|
||||
return msf::bytesToBlocks(MsfLayout.SB->NumDirectoryBytes,
|
||||
MsfLayout.SB->BlockSize);
|
||||
}
|
||||
|
||||
uint64_t PDBFile::getBlockMapOffset() const {
|
||||
return (uint64_t)SB->BlockMapAddr * SB->BlockSize;
|
||||
return (uint64_t)MsfLayout.SB->BlockMapAddr * MsfLayout.SB->BlockSize;
|
||||
}
|
||||
|
||||
uint32_t PDBFile::getNumStreams() const { return StreamSizes.size(); }
|
||||
uint32_t PDBFile::getNumStreams() const { return MsfLayout.StreamSizes.size(); }
|
||||
|
||||
uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
|
||||
return StreamSizes[StreamIndex];
|
||||
return MsfLayout.StreamSizes[StreamIndex];
|
||||
}
|
||||
|
||||
ArrayRef<support::ulittle32_t>
|
||||
PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
|
||||
return StreamMap[StreamIndex];
|
||||
return MsfLayout.StreamMap[StreamIndex];
|
||||
}
|
||||
|
||||
uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }
|
||||
|
@ -104,24 +111,31 @@ Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
|
|||
Error PDBFile::parseFileHeaders() {
|
||||
StreamReader Reader(*Buffer);
|
||||
|
||||
const msf::SuperBlock *SB = nullptr;
|
||||
if (auto EC = Reader.readObject(SB)) {
|
||||
consumeError(std::move(EC));
|
||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"Does not contain superblock");
|
||||
}
|
||||
|
||||
if (auto EC = setSuperBlock(SB))
|
||||
if (auto EC = msf::validateSuperBlock(*SB))
|
||||
return EC;
|
||||
|
||||
if (Buffer->getLength() % SB->BlockSize != 0)
|
||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"File size is not a multiple of block size");
|
||||
MsfLayout.SB = SB;
|
||||
|
||||
Reader.setOffset(getBlockMapOffset());
|
||||
if (auto EC = Reader.readArray(DirectoryBlocks, getNumDirectoryBlocks()))
|
||||
if (auto EC =
|
||||
Reader.readArray(MsfLayout.DirectoryBlocks, getNumDirectoryBlocks()))
|
||||
return EC;
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error PDBFile::parseStreamData() {
|
||||
assert(SB);
|
||||
assert(MsfLayout.SB);
|
||||
if (DirectoryStream)
|
||||
return Error::success();
|
||||
|
||||
|
@ -133,21 +147,22 @@ Error PDBFile::parseStreamData() {
|
|||
// subclass of IPDBStreamData which only accesses the fields that have already
|
||||
// been parsed, we can avoid this and reuse MappedBlockStream.
|
||||
auto DS = MappedBlockStream::createDirectoryStream(
|
||||
SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
|
||||
MsfLayout.SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
|
||||
if (!DS)
|
||||
return DS.takeError();
|
||||
StreamReader Reader(**DS);
|
||||
if (auto EC = Reader.readInteger(NumStreams))
|
||||
return EC;
|
||||
|
||||
if (auto EC = Reader.readArray(StreamSizes, NumStreams))
|
||||
if (auto EC = Reader.readArray(MsfLayout.StreamSizes, NumStreams))
|
||||
return EC;
|
||||
for (uint32_t I = 0; I < NumStreams; ++I) {
|
||||
uint32_t StreamSize = getStreamByteSize(I);
|
||||
// FIXME: What does StreamSize ~0U mean?
|
||||
uint64_t NumExpectedStreamBlocks =
|
||||
StreamSize == UINT32_MAX ? 0 : msf::bytesToBlocks(StreamSize,
|
||||
SB->BlockSize);
|
||||
StreamSize == UINT32_MAX
|
||||
? 0
|
||||
: msf::bytesToBlocks(StreamSize, MsfLayout.SB->BlockSize);
|
||||
|
||||
// For convenience, we store the block array contiguously. This is because
|
||||
// if someone calls setStreamMap(), it is more convenient to be able to call
|
||||
|
@ -159,12 +174,12 @@ Error PDBFile::parseStreamData() {
|
|||
if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
|
||||
return EC;
|
||||
for (uint32_t Block : Blocks) {
|
||||
uint64_t BlockEndOffset = (uint64_t)(Block + 1) * SB->BlockSize;
|
||||
uint64_t BlockEndOffset = (uint64_t)(Block + 1) * MsfLayout.SB->BlockSize;
|
||||
if (BlockEndOffset > getFileSize())
|
||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"Stream block map is corrupt.");
|
||||
}
|
||||
StreamMap.push_back(Blocks);
|
||||
MsfLayout.StreamMap.push_back(Blocks);
|
||||
}
|
||||
|
||||
// We should have read exactly SB->NumDirectoryBytes bytes.
|
||||
|
@ -174,7 +189,7 @@ Error PDBFile::parseStreamData() {
|
|||
}
|
||||
|
||||
llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
|
||||
return DirectoryBlocks;
|
||||
return MsfLayout.DirectoryBlocks;
|
||||
}
|
||||
|
||||
Expected<InfoStream &> PDBFile::getPDBInfoStream() {
|
||||
|
@ -297,29 +312,17 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
|
|||
return *StringTable;
|
||||
}
|
||||
|
||||
Error PDBFile::setSuperBlock(const msf::SuperBlock *Block) {
|
||||
if (auto EC = msf::validateSuperBlock(*Block))
|
||||
return EC;
|
||||
|
||||
if (Buffer->getLength() % SB->BlockSize != 0)
|
||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"File size is not a multiple of block size");
|
||||
|
||||
SB = Block;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error PDBFile::commit() {
|
||||
StreamWriter Writer(*Buffer);
|
||||
|
||||
if (auto EC = Writer.writeObject(*SB))
|
||||
if (auto EC = Writer.writeObject(*MsfLayout.SB))
|
||||
return EC;
|
||||
Writer.setOffset(getBlockMapOffset());
|
||||
if (auto EC = Writer.writeArray(DirectoryBlocks))
|
||||
if (auto EC = Writer.writeArray(MsfLayout.DirectoryBlocks))
|
||||
return EC;
|
||||
|
||||
auto DS = MappedBlockStream::createDirectoryStream(
|
||||
SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
|
||||
MsfLayout.SB->NumDirectoryBytes, getDirectoryBlockArray(), *this);
|
||||
if (!DS)
|
||||
return DS.takeError();
|
||||
auto DirStream = std::move(*DS);
|
||||
|
@ -327,10 +330,10 @@ Error PDBFile::commit() {
|
|||
if (auto EC = DW.writeInteger(this->getNumStreams()))
|
||||
return EC;
|
||||
|
||||
if (auto EC = DW.writeArray(StreamSizes))
|
||||
if (auto EC = DW.writeArray(MsfLayout.StreamSizes))
|
||||
return EC;
|
||||
|
||||
for (const auto &Blocks : StreamMap) {
|
||||
for (const auto &Blocks : MsfLayout.StreamMap) {
|
||||
if (auto EC = DW.writeArray(Blocks))
|
||||
return EC;
|
||||
}
|
||||
|
|
|
@ -76,11 +76,7 @@ PDBFileBuilder::build(std::unique_ptr<msf::StreamInterface> PdbFileBuffer) {
|
|||
return ExpectedLayout.takeError();
|
||||
|
||||
auto File = llvm::make_unique<PDBFile>(std::move(PdbFileBuffer), Allocator);
|
||||
const msf::Layout &L = *ExpectedLayout;
|
||||
File->StreamMap = L.StreamMap;
|
||||
File->StreamSizes = L.StreamSizes;
|
||||
File->DirectoryBlocks = L.DirectoryBlocks;
|
||||
File->SB = L.SB;
|
||||
File->MsfLayout = *ExpectedLayout;
|
||||
|
||||
if (Info) {
|
||||
auto ExpectedInfo = Info->build(*File);
|
||||
|
|
Loading…
Reference in New Issue