summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-09-14 23:00:02 +0000
committerZachary Turner <zturner@google.com>2016-09-14 23:00:02 +0000
commit620961deb9bc4c0415d56bed9b2fe20391bd2ad2 (patch)
treec313b23899ec22d2871cedecf1b65b93905cfa3b /llvm/lib/DebugInfo/PDB/Raw/TpiStreamBuilder.cpp
parent31263731da2214579540198ae96c0990b315d0ed (diff)
downloadbcm5719-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.cpp64
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();
}
OpenPOWER on IntegriCloud