diff options
| author | Zachary Turner <zturner@google.com> | 2016-09-14 23:00:02 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2016-09-14 23:00:02 +0000 |
| commit | 620961deb9bc4c0415d56bed9b2fe20391bd2ad2 (patch) | |
| tree | c313b23899ec22d2871cedecf1b65b93905cfa3b /llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp | |
| parent | 31263731da2214579540198ae96c0990b315d0ed (diff) | |
| download | bcm5719-llvm-620961deb9bc4c0415d56bed9b2fe20391bd2ad2.tar.gz bcm5719-llvm-620961deb9bc4c0415d56bed9b2fe20391bd2ad2.zip | |
[pdb] Write TPI hash values to the TPI stream.
This completes being able to write all the interesting
values of a PDB TPI stream.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D24370
llvm-svn: 281555
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp')
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp index 5591df5993e..ee9e89bbe59 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp @@ -2,6 +2,7 @@ #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/MSF/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" @@ -14,8 +15,8 @@ using namespace llvm::msf; using namespace llvm::pdb; using namespace llvm::support; -TpiStreamBuilder::TpiStreamBuilder(BumpPtrAllocator &Allocator) - : Allocator(Allocator), Header(nullptr) {} +TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf) + : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr) {} TpiStreamBuilder::~TpiStreamBuilder() {} @@ -35,6 +36,7 @@ Error TpiStreamBuilder::finalize() { TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>(); uint32_t Count = TypeRecords.size(); + uint32_t HashBufferSize = calculateHashBufferSize(); H->Version = *VerHeader; H->HeaderSize = sizeof(TpiStreamHeader); @@ -42,13 +44,19 @@ Error TpiStreamBuilder::finalize() { H->TypeIndexEnd = H->TypeIndexBegin + Count; H->TypeRecordBytes = TypeRecordStream.getLength(); - H->HashStreamIndex = kInvalidStreamIndex; + H->HashStreamIndex = HashStreamIndex; H->HashAuxStreamIndex = kInvalidStreamIndex; H->HashKeySize = sizeof(ulittle32_t); H->NumHashBuckets = MinTpiHashBuckets; - H->HashValueBuffer.Length = 0; + // Recall that hash values go into a completely different stream identified by + // the `HashStreamIndex` field of the `TpiStreamHeader`. Therefore, the data + // begins at offset 0 of this independent stream. + H->HashValueBuffer.Off = 0; + H->HashValueBuffer.Length = HashBufferSize; + H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length; H->HashAdjBuffer.Length = 0; + H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length; H->IndexOffsetBuffer.Length = 0; Header = H; @@ -56,7 +64,39 @@ Error TpiStreamBuilder::finalize() { } uint32_t TpiStreamBuilder::calculateSerializedLength() const { - return sizeof(TpiStreamHeader) + TypeRecordStream.getLength(); + return sizeof(TpiStreamHeader) + TypeRecordStream.getLength() + + calculateHashBufferSize(); +} + +uint32_t TpiStreamBuilder::calculateHashBufferSize() const { + if (TypeRecords.empty() || !TypeRecords[0].Hash.hasValue()) + return 0; + return TypeRecords.size() * sizeof(ulittle32_t); +} + +Error TpiStreamBuilder::finalizeMsfLayout() { + uint32_t Length = calculateSerializedLength(); + if (auto EC = Msf.setStreamSize(StreamTPI, Length)) + return EC; + + uint32_t HashBufferSize = calculateHashBufferSize(); + + if (HashBufferSize == 0) + return Error::success(); + + auto ExpectedIndex = Msf.addStream(HashBufferSize); + if (!ExpectedIndex) + return ExpectedIndex.takeError(); + HashStreamIndex = *ExpectedIndex; + ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeRecords.size()); + MutableArrayRef<ulittle32_t> HashBuffer(H, TypeRecords.size()); + for (uint32_t I = 0; I < TypeRecords.size(); ++I) { + HashBuffer[I] = *TypeRecords[I].Hash % MinTpiHashBuckets; + } + ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(HashBuffer.data()), + HashBufferSize); + HashValueStream = llvm::make_unique<ByteStream>(Bytes); + return Error::success(); } Expected<std::unique_ptr<TpiStream>> @@ -72,6 +112,12 @@ TpiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) { auto Tpi = llvm::make_unique<TpiStream>(File, std::move(StreamData)); Tpi->Header = Header; Tpi->TypeRecords = VarStreamArray<codeview::CVType>(TypeRecordStream); + if (HashValueStream) { + Tpi->HashStream = std::move(HashValueStream); + StreamReader HSR(*Tpi->HashStream); + if (auto EC = HSR.readArray(Tpi->HashValues, TypeRecords.size())) + return std::move(EC); + } return std::move(Tpi); } @@ -91,5 +137,13 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout, if (auto EC = Writer.writeArray(RecordArray)) return EC; + if (HashStreamIndex != kInvalidStreamIndex) { + auto HVS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer, + HashStreamIndex); + StreamWriter HW(*HVS); + if (auto EC = HW.writeStreamRef(*HashValueStream)) + return EC; + } + return Error::success(); } |

