Index: llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h +++ llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h @@ -71,6 +71,9 @@ template TypeIndex insertRecordAs(GloballyHashedType Hash, size_t RecordSize, CreateFunc Create) { + assert(RecordSize < UINT32_MAX && "Record too big"); + assert(RecordSize % 4 == 0 && "Record is not aligned to 4 bytes!"); + auto Result = HashedRecords.try_emplace(Hash, nextTypeIndex()); if (LLVM_UNLIKELY(Result.second /*inserted*/ || Index: llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -360,16 +360,18 @@ [this, Type](MutableArrayRef Storage) -> ArrayRef { 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 Result = DoSerialize(RemapStorage); if (!Result.empty()) DestIdx = Dest.insertRecordBytes(Result); @@ -386,9 +388,14 @@ ArrayRef TypeStreamMerger::remapIndices(const CVType &OriginalType, MutableArrayRef Storage) { + unsigned Align = OriginalType.RecordData.size() & 3; + unsigned AlignedSize = alignTo(OriginalType.RecordData.size(), 4); + assert(Storage.size() == AlignedSize && + "The target buffer size must be aligned on a 4-byte boundary!"); + SmallVector 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,13 @@ return {}; } } + + if (Align > 0) { + DestContent = Storage.data() + OriginalType.RecordData.size(); + for (; Align < 4; ++Align) { + DestContent[Align] = LF_PAD0 + Align; + } + } return Storage; } Index: llvm/test/tools/llvm-readobj/COFF/codeview-merging-alignement.yaml =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/COFF/codeview-merging-alignement.yaml @@ -0,0 +1,56 @@ +# RUN: yaml2obj %s -o=%t.obj +# RUN: llvm-readobj --codeview-merged-types %t.obj | FileCheck %s +# RUN: llvm-readobj --codeview-merged-types %t.obj --codeview-ghash | FileCheck %s +# CHECK: MergedTypeStream [ +# CHECK: Procedure (0x1000) { +# CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +# CHECK: ReturnType: void (0x3) +# CHECK: CallingConvention: NearC (0x0) +# CHECK: FunctionOptions [ (0x0) +# CHECK: ] +# CHECK: NumParameters: 0 +# CHECK: ArgListType: 0x0 +# CHECK: } +# CHECK: ArgList (0x1001) { +# CHECK: TypeLeafKind: LF_ARGLIST (0x1201) +# CHECK: NumArgs: 0 +# CHECK: Arguments [ +# CHECK: ] +# CHECK: } + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + # It is important to keep the 'SectionData' since the .OBJ is reconstructed from it, + # and that triggers an alignement bug in the output .PDB. + SectionData: '040000001000081003000000000000000000000000000600011200000000' + Types: + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 3 + CallConv: NearC + Options: [ None ] + ParameterCount: 0 + ArgumentList: 0 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ ] +symbols: + - Name: '.debug$T' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 30 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 +...