aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp62
1 files changed, 46 insertions, 16 deletions
diff --git a/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 51a1f0a544e3..5f4f497690b6 100644
--- a/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -25,6 +25,7 @@
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstdint>
+#include <numeric>
using namespace llvm;
using namespace llvm::msf;
@@ -41,39 +42,68 @@ void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
VerHeader = Version;
}
+void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {
+ // If we just crossed an 8KB threshold, add a type index offset.
+ for (uint16_t Size : Sizes) {
+ size_t NewSize = TypeRecordBytes + Size;
+ constexpr size_t EightKB = 8 * 1024;
+ if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecordCount == 0) {
+ TypeIndexOffsets.push_back(
+ {codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex +
+ TypeRecordCount),
+ ulittle32_t(TypeRecordBytes)});
+ }
+ ++TypeRecordCount;
+ TypeRecordBytes = NewSize;
+ }
+}
+
void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
Optional<uint32_t> Hash) {
- // If we just crossed an 8KB threshold, add a type index offset.
assert(((Record.size() & 3) == 0) &&
"The type record's size is not a multiple of 4 bytes which will "
"cause misalignment in the output TPI stream!");
- 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;
+ assert(Record.size() <= codeview::MaxRecordLength);
+ uint16_t OneSize = (uint16_t)Record.size();
+ updateTypeIndexOffsets(makeArrayRef(&OneSize, 1));
- TypeRecords.push_back(Record);
+ TypeRecBuffers.push_back(Record);
+ // FIXME: Require it.
if (Hash)
TypeHashes.push_back(*Hash);
}
+void TpiStreamBuilder::addTypeRecords(ArrayRef<uint8_t> Types,
+ ArrayRef<uint16_t> Sizes,
+ ArrayRef<uint32_t> Hashes) {
+ // Ignore empty type buffers. There should be no hashes or sizes in this case.
+ if (Types.empty()) {
+ assert(Sizes.empty() && Hashes.empty());
+ return;
+ }
+
+ assert(((Types.size() & 3) == 0) &&
+ "The type record's size is not a multiple of 4 bytes which will "
+ "cause misalignment in the output TPI stream!");
+ assert(Sizes.size() == Hashes.size() && "sizes and hashes should be in sync");
+ assert(std::accumulate(Sizes.begin(), Sizes.end(), 0U) == Types.size() &&
+ "sizes of type records should sum to the size of the types");
+ updateTypeIndexOffsets(Sizes);
+
+ TypeRecBuffers.push_back(Types);
+ llvm::append_range(TypeHashes, Hashes);
+}
+
Error TpiStreamBuilder::finalize() {
if (Header)
return Error::success();
TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
- uint32_t Count = TypeRecords.size();
-
H->Version = VerHeader;
H->HeaderSize = sizeof(TpiStreamHeader);
H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
- H->TypeIndexEnd = H->TypeIndexBegin + Count;
+ H->TypeIndexEnd = H->TypeIndexBegin + TypeRecordCount;
H->TypeRecordBytes = TypeRecordBytes;
H->HashStreamIndex = HashStreamIndex;
@@ -104,7 +134,7 @@ uint32_t TpiStreamBuilder::calculateSerializedLength() {
}
uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
- assert((TypeRecords.size() == TypeHashes.size() || TypeHashes.empty()) &&
+ assert((TypeRecordCount == TypeHashes.size() || TypeHashes.empty()) &&
"either all or no type records should have hashes");
return TypeHashes.size() * sizeof(ulittle32_t);
}
@@ -155,7 +185,7 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
if (auto EC = Writer.writeObject(*Header))
return EC;
- for (auto Rec : TypeRecords) {
+ for (auto Rec : TypeRecBuffers) {
assert(!Rec.empty() && "Attempting to write an empty type record shifts "
"all offsets in the TPI stream!");
assert(((Rec.size() & 3) == 0) &&