diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /llvm/lib/DebugInfo/CodeView | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
11 files changed, 176 insertions, 59 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp index 86a6f9eebfa2..4d8b15530b9e 100644 --- a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp @@ -74,12 +74,17 @@ ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const { void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); } +static ArrayRef<uint8_t> stabilize(BumpPtrAllocator &RecordStorage, + ArrayRef<uint8_t> Record) { + uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size()); + memcpy(Stable, Record.data(), Record.size()); + return ArrayRef<uint8_t>(Stable, Record.size()); +} + TypeIndex AppendingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) { TypeIndex NewTI = nextTypeIndex(); - uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size()); - memcpy(Stable, Record.data(), Record.size()); - Record = ArrayRef<uint8_t>(Stable, Record.size()); + Record = stabilize(RecordStorage, Record); SeenRecords.push_back(Record); return NewTI; } @@ -93,3 +98,15 @@ AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { TI = insertRecordBytes(C.RecordData); return TI; } + +bool AppendingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data, + bool Stabilize) { + assert(Index.toArrayIndex() < SeenRecords.size() && + "This function cannot be used to insert records!"); + + ArrayRef<uint8_t> Record = Data.data(); + if (Stabilize) + Record = stabilize(RecordStorage, Record); + SeenRecords[Index.toArrayIndex()] = Record; + return true; +} diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp index 36a384baa13d..49761b9dce88 100644 --- a/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp +++ b/llvm/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp @@ -46,7 +46,7 @@ Error CodeViewRecordIO::endRecord() { while (PaddingBytes > 0) { char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes); StringRef BytesSR = StringRef(&Pad, sizeof(Pad)); - Streamer->EmitBytes(BytesSR); + Streamer->emitBytes(BytesSR); --PaddingBytes; } resetStreamedLen(); @@ -101,7 +101,7 @@ Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes, const Twine &Comment) { if (isStreaming()) { emitComment(Comment); - Streamer->EmitBinaryData(toStringRef(Bytes)); + Streamer->emitBinaryData(toStringRef(Bytes)); incrStreamedLen(Bytes.size()); } else if (isWriting()) { if (auto EC = Writer->writeBytes(Bytes)) @@ -131,7 +131,7 @@ Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) { emitComment(Comment + ": " + TypeNameStr); else emitComment(Comment); - Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex())); + Streamer->emitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex())); incrStreamedLen(sizeof(TypeInd.getIndex())); } else if (isWriting()) { if (auto EC = Writer->writeInteger(TypeInd.getIndex())) @@ -205,7 +205,7 @@ Error CodeViewRecordIO::mapStringZ(StringRef &Value, const Twine &Comment) { if (isStreaming()) { auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1); emitComment(Comment); - Streamer->EmitBytes(NullTerminatedString); + Streamer->emitBytes(NullTerminatedString); incrStreamedLen(NullTerminatedString.size()); } else if (isWriting()) { // Truncate if we attempt to write too much. @@ -226,7 +226,7 @@ Error CodeViewRecordIO::mapGuid(GUID &Guid, const Twine &Comment) { StringRef GuidSR = StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize); emitComment(Comment); - Streamer->EmitBytes(GuidSR); + Streamer->emitBytes(GuidSR); incrStreamedLen(GuidSize); return Error::success(); } @@ -275,24 +275,24 @@ void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value, const Twine &Comment) { assert(Value < 0 && "Encoded integer is not signed!"); if (Value >= std::numeric_limits<int8_t>::min()) { - Streamer->EmitIntValue(LF_CHAR, 2); + Streamer->emitIntValue(LF_CHAR, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 1); + Streamer->emitIntValue(Value, 1); incrStreamedLen(3); } else if (Value >= std::numeric_limits<int16_t>::min()) { - Streamer->EmitIntValue(LF_SHORT, 2); + Streamer->emitIntValue(LF_SHORT, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 2); + Streamer->emitIntValue(Value, 2); incrStreamedLen(4); } else if (Value >= std::numeric_limits<int32_t>::min()) { - Streamer->EmitIntValue(LF_LONG, 2); + Streamer->emitIntValue(LF_LONG, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 4); + Streamer->emitIntValue(Value, 4); incrStreamedLen(6); } else { - Streamer->EmitIntValue(LF_QUADWORD, 2); + Streamer->emitIntValue(LF_QUADWORD, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 4); + Streamer->emitIntValue(Value, 4); incrStreamedLen(6); } } @@ -301,22 +301,22 @@ void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value, const Twine &Comment) { if (Value < LF_NUMERIC) { emitComment(Comment); - Streamer->EmitIntValue(Value, 2); + Streamer->emitIntValue(Value, 2); incrStreamedLen(2); } else if (Value <= std::numeric_limits<uint16_t>::max()) { - Streamer->EmitIntValue(LF_USHORT, 2); + Streamer->emitIntValue(LF_USHORT, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 2); + Streamer->emitIntValue(Value, 2); incrStreamedLen(4); } else if (Value <= std::numeric_limits<uint32_t>::max()) { - Streamer->EmitIntValue(LF_ULONG, 2); + Streamer->emitIntValue(LF_ULONG, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 4); + Streamer->emitIntValue(Value, 4); incrStreamedLen(6); } else { - Streamer->EmitIntValue(LF_UQUADWORD, 2); + Streamer->emitIntValue(LF_UQUADWORD, 2); emitComment(Comment); - Streamer->EmitIntValue(Value, 8); + Streamer->emitIntValue(Value, 8); incrStreamedLen(6); } } diff --git a/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp b/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp index 0f704f286ee9..3c8a30101450 100644 --- a/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp +++ b/llvm/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp @@ -23,13 +23,11 @@ using namespace llvm::codeview; DebugSubsectionRecord::DebugSubsectionRecord() = default; DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind, - BinaryStreamRef Data, - CodeViewContainer Container) - : Container(Container), Kind(Kind), Data(Data) {} + BinaryStreamRef Data) + : Kind(Kind), Data(Data) {} Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream, - DebugSubsectionRecord &Info, - CodeViewContainer Container) { + DebugSubsectionRecord &Info) { const DebugSubsectionHeader *Header; BinaryStreamReader Reader(Stream); if (auto EC = Reader.readObject(Header)) @@ -39,7 +37,6 @@ Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream, static_cast<DebugSubsectionKind>(uint32_t(Header->Kind)); if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) return EC; - Info.Container = Container; Info.Kind = Kind; return Error::success(); } @@ -53,14 +50,14 @@ DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; } BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; } DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder( - std::shared_ptr<DebugSubsection> Subsection, CodeViewContainer Container) - : Subsection(std::move(Subsection)), Container(Container) {} + std::shared_ptr<DebugSubsection> Subsection) + : Subsection(std::move(Subsection)) {} DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder( - const DebugSubsectionRecord &Contents, CodeViewContainer Container) - : Contents(Contents), Container(Container) {} + const DebugSubsectionRecord &Contents) + : Contents(Contents) {} -uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() { +uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() const { uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize() : Contents.getRecordData().getLength(); // The length of the entire subsection is always padded to 4 bytes, @@ -68,7 +65,8 @@ uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() { return sizeof(DebugSubsectionHeader) + alignTo(DataSize, 4); } -Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const { +Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer, + CodeViewContainer Container) const { assert(Writer.getOffset() % alignOf(Container) == 0 && "Debug Subsection not properly aligned"); diff --git a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp index a7ad1d045f04..7cd9ca7498f5 100644 --- a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp @@ -84,6 +84,13 @@ void GlobalTypeTableBuilder::reset() { SeenRecords.clear(); } +static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc, + ArrayRef<uint8_t> Data) { + uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size()); + memcpy(Stable, Data.data(), Data.size()); + return makeArrayRef(Stable, Data.size()); +} + TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> Record) { GloballyHashedType GHT = GloballyHashedType::hashType(Record, SeenHashes, SeenHashes); @@ -104,3 +111,30 @@ GlobalTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { TI = insertRecordBytes(C.RecordData); return TI; } + +bool GlobalTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data, + bool Stabilize) { + assert(Index.toArrayIndex() < SeenRecords.size() && + "This function cannot be used to insert records!"); + + ArrayRef<uint8_t> Record = Data.data(); + assert(Record.size() < UINT32_MAX && "Record too big"); + assert(Record.size() % 4 == 0 && + "The type record size is not a multiple of 4 bytes which will cause " + "misalignment in the output TPI stream!"); + + GloballyHashedType Hash = + GloballyHashedType::hashType(Record, SeenHashes, SeenHashes); + auto Result = HashedRecords.try_emplace(Hash, Index.toArrayIndex()); + if (!Result.second) { + Index = Result.first->second; + return false; // The record is already there, at a different location + } + + if (Stabilize) + Record = stabilize(RecordStorage, Record); + + SeenRecords[Index.toArrayIndex()] = Record; + SeenHashes[Index.toArrayIndex()] = Hash; + return true; +} diff --git a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp index dc1253b7a39f..06b20ba33eec 100644 --- a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -277,3 +277,8 @@ void LazyRandomTypeCollection::visitRange(TypeIndex Begin, uint32_t BeginOffset, ++RI; } } + +bool LazyRandomTypeCollection::replaceType(TypeIndex &Index, CVType Data, + bool Stabilize) { + llvm_unreachable("Method cannot be called"); +} diff --git a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp index 4d7cd468f3ee..13ce3ae82c26 100644 --- a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp @@ -90,7 +90,9 @@ static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc, TypeIndex MergingTypeTableBuilder::insertRecordAs(hash_code Hash, ArrayRef<uint8_t> &Record) { assert(Record.size() < UINT32_MAX && "Record too big"); - assert(Record.size() % 4 == 0 && "Record is not aligned to 4 bytes!"); + assert(Record.size() % 4 == 0 && + "The type record size is not a multiple of 4 bytes which will cause " + "misalignment in the output TPI stream!"); LocallyHashedType WeakHash{Hash, Record}; auto Result = HashedRecords.try_emplace(WeakHash, nextTypeIndex()); @@ -121,3 +123,30 @@ MergingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) { TI = insertRecordBytes(C.RecordData); return TI; } + +bool MergingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data, + bool Stabilize) { + assert(Index.toArrayIndex() < SeenRecords.size() && + "This function cannot be used to insert records!"); + + ArrayRef<uint8_t> Record = Data.data(); + assert(Record.size() < UINT32_MAX && "Record too big"); + assert(Record.size() % 4 == 0 && + "The type record size is not a multiple of 4 bytes which will cause " + "misalignment in the output TPI stream!"); + + LocallyHashedType WeakHash{hash_value(Record), Record}; + auto Result = HashedRecords.try_emplace(WeakHash, Index.toArrayIndex()); + if (!Result.second) { + Index = Result.first->second; + return false; // The record is already there, at a different location + } + + if (Stabilize) { + Record = stabilize(RecordStorage, Record); + Result.first->first.RecordData = Record; + } + + SeenRecords[Index.toArrayIndex()] = Record; + return true; +} diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/llvm/lib/DebugInfo/CodeView/RecordName.cpp index cfaad1581159..47b5498181b7 100644 --- a/llvm/lib/DebugInfo/CodeView/RecordName.cpp +++ b/llvm/lib/DebugInfo/CodeView/RecordName.cpp @@ -253,7 +253,7 @@ std::string llvm::codeview::computeTypeName(TypeCollection &Types, consumeError(std::move(EC)); return "<unknown UDT>"; } - return Computer.name(); + return std::string(Computer.name()); } static int getSymbolNameOffset(CVSymbol Sym) { diff --git a/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp b/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp index 654c40a7470d..ac3b30175956 100644 --- a/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp +++ b/llvm/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp @@ -1,4 +1,15 @@ +//===- SimpleTypeSerializer.cpp -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" +#include "llvm/Support/BinaryStreamWriter.h" using namespace llvm; using namespace llvm::codeview; diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp index 1aded589e565..bb71c86a0609 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp @@ -99,12 +99,12 @@ static std::string getMemberAttributes(CodeViewRecordIO &IO, MethodOptions Options) { if (!IO.isStreaming()) return ""; - std::string AccessSpecifier = - getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())); + std::string AccessSpecifier = std::string( + getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames()))); std::string MemberAttrs(AccessSpecifier); if (Kind != MethodKind::Vanilla) { - std::string MethodKind = - getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())); + std::string MethodKind = std::string( + getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames()))); MemberAttrs += ", " + MethodKind; } if (Options != MethodOptions::None) { @@ -201,8 +201,8 @@ Error TypeRecordMapping::visitTypeBegin(CVType &CVR) { if (IO.isStreaming()) { auto RecordKind = CVR.kind(); uint16_t RecordLen = CVR.length() - 2; - std::string RecordKindName = - getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)); + std::string RecordKindName = std::string( + getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames))); error(IO.mapInteger(RecordLen, "Record length")); error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName)); } @@ -241,7 +241,7 @@ Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) { MemberKind = Record.Kind; if (IO.isStreaming()) { - std::string MemberKindName = getLeafTypeName(Record.Kind); + std::string MemberKindName = std::string(getLeafTypeName(Record.Kind)); MemberKindName += " ( " + (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames))) @@ -277,8 +277,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) { Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ProcedureRecord &Record) { - std::string CallingConvName = getEnumName( - IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())); + std::string CallingConvName = std::string(getEnumName( + IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()))); std::string FuncOptionNames = getFlagNames(IO, static_cast<uint16_t>(Record.Options), makeArrayRef(getFunctionOptionEnum())); @@ -293,8 +293,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, Error TypeRecordMapping::visitKnownRecord(CVType &CVR, MemberFunctionRecord &Record) { - std::string CallingConvName = getEnumName( - IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())); + std::string CallingConvName = std::string(getEnumName( + IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()))); std::string FuncOptionNames = getFlagNames(IO, static_cast<uint16_t>(Record.Options), makeArrayRef(getFunctionOptionEnum())); @@ -337,12 +337,13 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) { SmallString<128> Attr("Attrs: "); if (IO.isStreaming()) { - std::string PtrType = getEnumName(IO, unsigned(Record.getPointerKind()), - makeArrayRef(getPtrKindNames())); + std::string PtrType = + std::string(getEnumName(IO, unsigned(Record.getPointerKind()), + makeArrayRef(getPtrKindNames()))); Attr += "[ Type: " + PtrType; - std::string PtrMode = getEnumName(IO, unsigned(Record.getMode()), - makeArrayRef(getPtrModeNames())); + std::string PtrMode = std::string(getEnumName( + IO, unsigned(Record.getMode()), makeArrayRef(getPtrModeNames()))); Attr += ", Mode: " + PtrMode; auto PtrSizeOf = Record.getSize(); @@ -374,8 +375,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) { MemberPointerInfo &M = *Record.MemberInfo; error(IO.mapInteger(M.ContainingType, "ClassType")); - std::string PtrMemberGetRepresentation = getEnumName( - IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())); + std::string PtrMemberGetRepresentation = std::string(getEnumName( + IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames()))); error(IO.mapEnum(M.Representation, "Representation: " + PtrMemberGetRepresentation)); } @@ -581,8 +582,8 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) { - std::string ModeName = - getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())); + std::string ModeName = std::string( + getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum()))); error(IO.mapEnum(Record.Mode, "Mode: " + ModeName)); return Error::success(); } diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index f9fca74a2199..8c4b640bcd19 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -360,16 +360,18 @@ Error TypeStreamMerger::remapType(const CVType &Type) { [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> { return remapIndices(Type, Storage); }; + unsigned AlignedSize = alignTo(Type.RecordData.size(), 4); + if (LLVM_LIKELY(UseGlobalHashes)) { GlobalTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream; GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()]; - DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize); + DestIdx = Dest.insertRecordAs(H, AlignedSize, DoSerialize); } else { MergingTypeTableBuilder &Dest = isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; - RemapStorage.resize(Type.RecordData.size()); + RemapStorage.resize(AlignedSize); ArrayRef<uint8_t> Result = DoSerialize(RemapStorage); if (!Result.empty()) DestIdx = Dest.insertRecordBytes(Result); @@ -386,9 +388,14 @@ Error TypeStreamMerger::remapType(const CVType &Type) { ArrayRef<uint8_t> TypeStreamMerger::remapIndices(const CVType &OriginalType, MutableArrayRef<uint8_t> Storage) { + unsigned Align = OriginalType.RecordData.size() & 3; + assert(Storage.size() == alignTo(OriginalType.RecordData.size(), 4) && + "The storage buffer size is not a multiple of 4 bytes which will " + "cause misalignment in the output TPI stream!"); + SmallVector<TiReference, 4> Refs; discoverTypeIndices(OriginalType.RecordData, Refs); - if (Refs.empty()) + if (Refs.empty() && Align == 0) return OriginalType.RecordData; ::memcpy(Storage.data(), OriginalType.RecordData.data(), @@ -408,6 +415,16 @@ TypeStreamMerger::remapIndices(const CVType &OriginalType, return {}; } } + + if (Align > 0) { + RecordPrefix *StorageHeader = + reinterpret_cast<RecordPrefix *>(Storage.data()); + StorageHeader->RecordLen += 4 - Align; + + DestContent = Storage.data() + OriginalType.RecordData.size(); + for (; Align < 4; ++Align) + *DestContent++ = LF_PAD4 - Align; + } return Storage; } diff --git a/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp b/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp index e13068b5b1eb..e517e8846d69 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp @@ -58,3 +58,8 @@ bool TypeTableCollection::contains(TypeIndex Index) { uint32_t TypeTableCollection::size() { return Records.size(); } uint32_t TypeTableCollection::capacity() { return Records.size(); } + +bool TypeTableCollection::replaceType(TypeIndex &Index, CVType Data, + bool Stabilize) { + llvm_unreachable("Method cannot be called"); +} |