summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp')
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp64
1 files changed, 46 insertions, 18 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 27b9dad02ac..375c35b1114 100644
--- a/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -45,7 +45,17 @@ void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
Optional<uint32_t> Hash) {
- TypeRecordBytes += Record.size();
+ // If we just crossed an 8KB threshold, add a type index offset.
+ size_t NewSize = TypeRecordBytes + Record.size();
+ constexpr size_t EightKB = 8 * 1024;
+ if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecords.empty()) {
+ TypeIndexOffsets.push_back(
+ {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
+ TypeRecords.size()),
+ ulittle32_t(TypeRecordBytes)});
+ }
+ TypeRecordBytes = NewSize;
+
TypeRecords.push_back(Record);
if (Hash)
TypeHashes.push_back(*Hash);
@@ -58,7 +68,6 @@ Error TpiStreamBuilder::finalize() {
TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
uint32_t Count = TypeRecords.size();
- uint32_t HashBufferSize = calculateHashBufferSize();
H->Version = *VerHeader;
H->HeaderSize = sizeof(TpiStreamHeader);
@@ -75,11 +84,15 @@ Error TpiStreamBuilder::finalize() {
// 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->HashValueBuffer.Length = calculateHashBufferSize();
+
+ // We never write any adjustments into our PDBs, so this is usually some
+ // offset with zero length.
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;
+ H->IndexOffsetBuffer.Length = calculateIndexOffsetSize();
Header = H;
return Error::success();
@@ -90,34 +103,42 @@ uint32_t TpiStreamBuilder::calculateSerializedLength() {
}
uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
- assert(TypeHashes.size() == TypeHashes.size() &&
+ assert((TypeRecords.size() == TypeHashes.size() || TypeHashes.empty()) &&
"either all or no type records should have hashes");
return TypeHashes.size() * sizeof(ulittle32_t);
}
+uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const {
+ return TypeIndexOffsets.size() * sizeof(TypeIndexOffset);
+}
+
Error TpiStreamBuilder::finalizeMsfLayout() {
uint32_t Length = calculateSerializedLength();
if (auto EC = Msf.setStreamSize(Idx, Length))
return EC;
- uint32_t HashBufferSize = calculateHashBufferSize();
+ uint32_t HashStreamSize =
+ calculateHashBufferSize() + calculateIndexOffsetSize();
- if (HashBufferSize == 0)
+ if (HashStreamSize == 0)
return Error::success();
- auto ExpectedIndex = Msf.addStream(HashBufferSize);
+ auto ExpectedIndex = Msf.addStream(HashStreamSize);
if (!ExpectedIndex)
return ExpectedIndex.takeError();
HashStreamIndex = *ExpectedIndex;
- ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeHashes.size());
- MutableArrayRef<ulittle32_t> HashBuffer(H, TypeHashes.size());
- for (uint32_t I = 0; I < TypeHashes.size(); ++I) {
- HashBuffer[I] = TypeHashes[I] % MinTpiHashBuckets;
+ if (!TypeHashes.empty()) {
+ ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeHashes.size());
+ MutableArrayRef<ulittle32_t> HashBuffer(H, TypeHashes.size());
+ for (uint32_t I = 0; I < TypeHashes.size(); ++I) {
+ HashBuffer[I] = TypeHashes[I] % MinTpiHashBuckets;
+ }
+ ArrayRef<uint8_t> Bytes(
+ reinterpret_cast<const uint8_t *>(HashBuffer.data()),
+ calculateHashBufferSize());
+ HashValueStream =
+ llvm::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
}
- ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(HashBuffer.data()),
- HashBufferSize);
- HashValueStream =
- llvm::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
return Error::success();
}
@@ -141,8 +162,15 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
auto HVS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
HashStreamIndex);
BinaryStreamWriter HW(*HVS);
- if (auto EC = HW.writeStreamRef(*HashValueStream))
- return EC;
+ if (HashValueStream) {
+ if (auto EC = HW.writeStreamRef(*HashValueStream))
+ return EC;
+ }
+
+ for (auto &IndexOffset : TypeIndexOffsets) {
+ if (auto EC = HW.writeObject(IndexOffset))
+ return EC;
+ }
}
return Error::success();
OpenPOWER on IntegriCloud