Index: lld/trunk/COFF/Config.h =================================================================== --- lld/trunk/COFF/Config.h +++ lld/trunk/COFF/Config.h @@ -89,6 +89,7 @@ bool Force = false; bool Debug = false; bool DebugDwarf = false; + bool DebugGHashes = false; unsigned DebugTypes = static_cast(DebugType::None); llvm::SmallString<128> PDBPath; std::vector Argv; Index: lld/trunk/COFF/Driver.cpp =================================================================== --- lld/trunk/COFF/Driver.cpp +++ lld/trunk/COFF/Driver.cpp @@ -809,7 +809,8 @@ Config->Force = true; // Handle /debug - if (Args.hasArg(OPT_debug) || Args.hasArg(OPT_debug_dwarf)) { + if (Args.hasArg(OPT_debug) || Args.hasArg(OPT_debug_dwarf) || + Args.hasArg(OPT_debug_ghash)) { Config->Debug = true; if (auto *Arg = Args.getLastArg(OPT_debugtype)) Config->DebugTypes = parseDebugType(Arg->getValue()); @@ -1018,6 +1019,7 @@ Config->NxCompat = Args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); Config->TerminalServerAware = Args.hasFlag(OPT_tsaware, OPT_tsaware_no, true); Config->DebugDwarf = Args.hasArg(OPT_debug_dwarf); + Config->DebugGHashes = Args.hasArg(OPT_debug_ghash); Config->MapFile = getMapFile(Args); Index: lld/trunk/COFF/Options.td =================================================================== --- lld/trunk/COFF/Options.td +++ lld/trunk/COFF/Options.td @@ -117,6 +117,7 @@ def help_q : Flag<["/?", "-?"], "">, Alias; // LLD extensions +def debug_ghash : F<"debug:ghash">; def debug_dwarf : F<"debug:dwarf">; def export_all_symbols : F<"export-all-symbols">; def nopdb : F<"nopdb">, HelpText<"Disable PDB generation for DWARF users">; Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -17,6 +17,7 @@ #include "lld/Common/ErrorHandler.h" #include "llvm/DebugInfo/CodeView/CVDebugRecord.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" +#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/RecordName.h" @@ -72,8 +73,8 @@ class PDBLinker { public: PDBLinker(SymbolTable *Symtab) - : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc), - IDTable(Alloc) {} + : Alloc(), Symtab(Symtab), Builder(Alloc), GlobalTypeTable(Alloc), + GlobalIDTable(Alloc), TypeTable(Alloc), IDTable(Alloc) {} /// Emit the basic PDB structure: initial streams, headers, etc. void initialize(const llvm::codeview::DebugInfo &BuildId); @@ -123,6 +124,12 @@ /// Item records that will go into the PDB IPI stream. MergingTypeTableBuilder IDTable; + /// Type records that will go into the PDB TPI stream (for /DEBUG:GHASH) + GlobalTypeTableBuilder GlobalTypeTable; + + /// Item records that will go into the PDB IPI stream (for /DEBUG:GHASH) + GlobalTypeTableBuilder GlobalIDTable; + /// PDBs use a single global string table for filenames in the file checksum /// table. DebugStringTableSubsection PDBStrTab; @@ -160,6 +167,41 @@ return {}; } +// A COFF .debug$H section is currently a clang extension. This function checks +// if a .debug$H section is in a format that we expect / understand, so that we +// can ignore any sections which are coincidentally also named .debug$H but do +// not contain a format we recognize. +static bool canUseDebugH(ArrayRef DebugH) { + if (DebugH.size() < sizeof(object::debug_h_header)) + return false; + auto *Header = + reinterpret_cast(DebugH.data()); + DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); + return Header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC && + Header->Version == 0 && + Header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1) && + (DebugH.size() % 20 == 0); +} + +static Optional> getDebugH(ObjFile *File) { + SectionChunk *Sec = findByName(File->getDebugChunks(), ".debug$H"); + if (!Sec) + return llvm::None; + ArrayRef Contents = Sec->getContents(); + if (!canUseDebugH(Contents)) + return None; + return Contents; +} + +static ArrayRef +getHashesFromDebugH(ArrayRef DebugH) { + assert(canUseDebugH(DebugH)); + + DebugH = DebugH.drop_front(sizeof(object::debug_h_header)); + uint32_t Count = DebugH.size() / sizeof(GloballyHashedType); + return {reinterpret_cast(DebugH.data()), Count}; +} + static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, TypeCollection &TypeTable) { // Start the TPI or IPI stream header. @@ -207,10 +249,26 @@ // This is a /Z7 object. Fill in the temporary, caller-provided // ObjectIndexMap. - if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, - ObjectIndexMap.TPIMap, Types)) - fatal("codeview::mergeTypeAndIdRecords failed: " + - toString(std::move(Err))); + if (Config->DebugGHashes) { + ArrayRef Hashes; + std::vector OwnedHashes; + if (Optional> DebugH = getDebugH(File)) + Hashes = getHashesFromDebugH(*DebugH); + else { + OwnedHashes = GloballyHashedType::hashTypes(Types); + Hashes = OwnedHashes; + } + + if (auto Err = mergeTypeAndIdRecords(GlobalIDTable, GlobalTypeTable, + ObjectIndexMap.TPIMap, Types, Hashes)) + fatal("codeview::mergeTypeAndIdRecords failed: " + + toString(std::move(Err))); + } else { + if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, + ObjectIndexMap.TPIMap, Types)) + fatal("codeview::mergeTypeAndIdRecords failed: " + + toString(std::move(Err))); + } return ObjectIndexMap; } @@ -274,21 +332,44 @@ if (auto E = ExpectedSession.takeError()) fatal("Type server PDB was not found: " + toString(std::move(E))); - // Merge TPI first, because the IPI stream will reference type indices. auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream(); if (auto E = ExpectedTpi.takeError()) fatal("Type server does not have TPI stream: " + toString(std::move(E))); - if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap, - ExpectedTpi->typeArray())) - fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); - - // Merge IPI. auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream(); if (auto E = ExpectedIpi.takeError()) fatal("Type server does not have TPI stream: " + toString(std::move(E))); - if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap, - ExpectedIpi->typeArray())) - fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); + + if (Config->DebugGHashes) { + // PDBs do not actually store global hashes, so when merging a type server + // PDB we have to synthesize global hashes. To do this, we first synthesize + // global hashes for the TPI stream, since it is independent, then we + // synthesize hashes for the IPI stream, using the hashes for the TPI stream + // as inputs. + auto TpiHashes = GloballyHashedType::hashTypes(ExpectedTpi->typeArray()); + auto IpiHashes = + GloballyHashedType::hashIds(ExpectedIpi->typeArray(), TpiHashes); + + // Merge TPI first, because the IPI stream will reference type indices. + if (auto Err = mergeTypeRecords(GlobalTypeTable, IndexMap.TPIMap, + ExpectedTpi->typeArray(), TpiHashes)) + fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); + + // Merge IPI. + if (auto Err = + mergeIdRecords(GlobalIDTable, IndexMap.TPIMap, IndexMap.IPIMap, + ExpectedIpi->typeArray(), IpiHashes)) + fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); + } else { + // Merge TPI first, because the IPI stream will reference type indices. + if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap, + ExpectedTpi->typeArray())) + fatal("codeview::mergeTypeRecords failed: " + toString(std::move(Err))); + + // Merge IPI. + if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap, + ExpectedIpi->typeArray())) + fatal("codeview::mergeIdRecords failed: " + toString(std::move(Err))); + } return IndexMap; } @@ -658,8 +739,13 @@ File->ModuleDBI->addDebugSubsection(SS); break; case DebugSubsectionKind::Symbols: - mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, - IDTable, SS.getRecordData()); + if (Config->DebugGHashes) { + mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, + GlobalIDTable, SS.getRecordData()); + } else { + mergeSymbolRecords(Alloc, File, Builder.getGsiBuilder(), IndexMap, + IDTable, SS.getRecordData()); + } break; default: // FIXME: Process the rest of the subsections. @@ -712,11 +798,14 @@ Builder.getStringTableBuilder().setStrings(PDBStrTab); - // Construct TPI stream contents. - addTypeInfo(Builder.getTpiBuilder(), TypeTable); - - // Construct IPI stream contents. - addTypeInfo(Builder.getIpiBuilder(), IDTable); + // Construct TPI and IPI stream contents. + if (Config->DebugGHashes) { + addTypeInfo(Builder.getTpiBuilder(), GlobalTypeTable); + addTypeInfo(Builder.getIpiBuilder(), GlobalIDTable); + } else { + addTypeInfo(Builder.getTpiBuilder(), TypeTable); + addTypeInfo(Builder.getIpiBuilder(), IDTable); + } // Compute the public and global symbols. auto &GsiBuilder = Builder.getGsiBuilder(); Index: lld/trunk/test/COFF/Inputs/pdb-hashes-1.yaml =================================================================== --- lld/trunk/test/COFF/Inputs/pdb-hashes-1.yaml +++ lld/trunk/test/COFF/Inputs/pdb-hashes-1.yaml @@ -0,0 +1,540 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E55683EC188B450C8B4D088D55F4C745F8000000008B7508894DF089D18934248945ECE80000000083EC048D4DF4890C248945E8E80000000083C4185E5DC3 + Relocations: + - VirtualAddress: 38 + SymbolName: '??0Foo@NS@@QAE@H@Z' + Type: IMAGE_REL_I386_REL32 + - VirtualAddress: 55 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_REL32 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .bss + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E583EC088B4508894DFC8B4DFC8B550889118945F889C883C4085DC20400 + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F50000008400000000000000000000004100000000000000080000000000000052000000070000000400000001000000400000000000000008000000000000007F0000000600040000000000030000003E000000000000000800000000000000BD0000000400040000000000040000003D000000000000000800000000000000FA0000000300080000000000F1000000960000002A00471100000000000000000000000041000000000000000000000003100000000000000000006D61696E000D003E1174000000010061726763001200451116000000080000001700000000002A000D003E11001000000100617267760012004511160000000C0000001700000000002A000A003E1109100000000066001200451116000000F4FFFFFF1700000000002A0002004F110000F200000030000000000000000000000041000000000000000300000024000000000000000300000017000000040000003000000005000000F1000000100000000E000811091000004E533A3A466F6F00F40000003000000001000000100165C9E387F88362A8EB2B49539DD5A65500002B00000010019303CF100D518DAF59C31DA01FEF4AFC0000F30000004801000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A312E63707000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D2024657369202454302038202D205E203D2000 + Subsections: + - !Symbols + Records: + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ ] + Machine: Pentium3 + FrontendMajor: 6 + FrontendMinor: 0 + FrontendBuild: 0 + FrontendQFE: 0 + BackendMajor: 6000 + BackendMinor: 0 + BackendBuild: 0 + BackendQFE: 0 + Version: 'clang version 6.0.0 ' + - !FrameData + Frames: + - CodeSize: 65 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 8 + PrologSize: 7 + RvaStart: 0 + SavedRegsSize: 0 + - CodeSize: 64 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 8 + PrologSize: 6 + RvaStart: 1 + SavedRegsSize: 4 + - CodeSize: 62 + FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 8 + PrologSize: 4 + RvaStart: 3 + SavedRegsSize: 4 + - CodeSize: 61 + FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 8 + PrologSize: 3 + RvaStart: 4 + SavedRegsSize: 8 + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 65 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4099 + Flags: [ ] + DisplayName: main + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: argc + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 4096 + Flags: [ IsParameter ] + VarName: argv + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 4105 + Flags: [ ] + VarName: f + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 65 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' + Lines: + - Offset: 0 + LineStart: 3 + IsStatement: false + EndDelta: 0 + - Offset: 23 + LineStart: 4 + IsStatement: false + EndDelta: 0 + - Offset: 48 + LineStart: 5 + IsStatement: false + EndDelta: 0 + Columns: + - !Symbols + Records: + - Kind: S_UDT + UDTSym: + Type: 4105 + UDTName: 'NS::Foo' + - !FileChecksums + Checksums: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' + Kind: MD5 + Checksum: 65C9E387F88362A8EB2B49539DD5A655 + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' + Kind: MD5 + Checksum: 9303CF100D518DAF59C31DA01FEF4AFC + - !StringTable + Strings: + - 'D:\src\llvmbuild\clang\Debug\x86\obj1.cpp' + - 'D:\src\llvmbuild\clang\Debug\x86\obj.h' + - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = $esi $T0 8 - ^ = ' + Relocations: + - VirtualAddress: 68 + SymbolName: _main + Type: IMAGE_REL_I386_DIR32NB + - VirtualAddress: 240 + SymbolName: _main + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 244 + SymbolName: _main + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 279 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 283 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 314 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 318 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 346 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 350 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 368 + SymbolName: _main + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 372 + SymbolName: _main + Type: IMAGE_REL_I386_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 040000000A000210700400000A8000000E0001120200000074000000001000000E0008107400000000000200011000001200011600000000021000006D61696E00F3F2F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000210041000000A8000000A00011201000000740000001A0009100300000004100000051000000B00010006100000000000001A0003120D15030074000000000058001115030007100000466F6F002A0005150200000208100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E000616091000000A100000020000000E0002160410000007100000466F6F00 + Types: + - Kind: LF_POINTER + Pointer: + ReferentType: 1136 + Attrs: 32778 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 116, 4096 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 2 + ArgumentList: 4097 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 0 + FunctionType: 4098 + Name: main + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: 'NS::Foo' + UniqueName: '.?AUFoo@NS@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + - Kind: LF_POINTER + Pointer: + ReferentType: 4100 + Attrs: 32778 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 116 ] + - Kind: LF_MFUNCTION + MemberFunction: + ReturnType: 3 + ClassType: 4100 + ThisType: 4101 + CallConv: ThisCall + Options: [ None ] + ParameterCount: 1 + ArgumentList: 4102 + ThisPointerAdjustment: 0 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 0 + Name: X + - Kind: LF_ONEMETHOD + OneMethod: + Type: 4103 + Attrs: 3 + VFTableOffset: -1 + Name: Foo + - Kind: LF_STRUCTURE + Class: + MemberCount: 2 + Options: [ None, HasUniqueName ] + FieldList: 4104 + Name: 'NS::Foo' + UniqueName: '.?AUFoo@NS@@' + DerivationList: 0 + VTableShape: 0 + Size: 4 + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4105 + SourceFile: 4106 + LineNumber: 2 + - Kind: LF_MFUNC_ID + MemberFuncId: + ClassType: 4100 + FunctionType: 4103 + Name: Foo + - Name: '.debug$H' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: C5C93301000000009E56666824DC4B12E25261D4E09E6E9DA0F4EE31FDEC3D2D96287486127C66070B248ED52E421F55074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E99E616EF06A14EA74A2420F9062A1FB04917E5975E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D894CEAE81AEF8680D723D403D9A4481F0E28683A98 + GlobalHashes: + Version: 0 + HashAlgorithm: 0 + HashValues: + - 9E56666824DC4B12E25261D4E09E6E9DA0F4EE31 + - FDEC3D2D96287486127C66070B248ED52E421F55 + - 074AE5CC2D68AF9F0A3BEF23993968F7FD82CA84 + - BF0439C1A64C9070C6A6ADB0A34D21DAD0FFC3E9 + - 9E616EF06A14EA74A2420F9062A1FB04917E5975 + - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7 + - 97DD91CA4D7F1953C314442D5549419E78044E38 + - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0 + - C0A9021B711ACC4F67008974EBF441031BDD653F + - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA + - 0AF6C1846743F43D846BB19517E12E8873BBA90C + - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89 + - 4CEAE81AEF8680D723D403D9A4481F0E28683A98 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F500000064000000000000000000000020000000000000000400000000000000520000000600000004000000010000001F0000000000000004000000000000007F0000000500040000000000030000001D000000000000000400000000000000BD0000000300040000000000F10000007B000000320047110000000000000000000000002000000000000000000000000C100000000000000000004E533A3A466F6F3A3A466F6F000D003E1105100000010074686973001200451116000000FCFFFFFF0F000000000011000A003E1174000000010078001200451116000000080000000F0000000000110002004F1100F2000000200000000000000000000000200000001800000001000000140000000000000003000000 + Subsections: + - !FrameData + Frames: + - CodeSize: 32 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 6 + RvaStart: 0 + SavedRegsSize: 0 + - CodeSize: 31 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 5 + RvaStart: 1 + SavedRegsSize: 4 + - CodeSize: 29 + FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 3 + RvaStart: 3 + SavedRegsSize: 4 + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 32 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4108 + Flags: [ ] + DisplayName: 'NS::Foo::Foo' + - Kind: S_LOCAL + LocalSym: + Type: 4101 + Flags: [ IsParameter ] + VarName: this + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_LOCAL + LocalSym: + Type: 116 + Flags: [ IsParameter ] + VarName: x + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 32 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' + Lines: + - Offset: 0 + LineStart: 3 + IsStatement: false + EndDelta: 0 + Columns: + Relocations: + - VirtualAddress: 12 + SymbolName: '??0Foo@NS@@QAE@H@Z' + Type: IMAGE_REL_I386_DIR32NB + - VirtualAddress: 152 + SymbolName: '??0Foo@NS@@QAE@H@Z' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 156 + SymbolName: '??0Foo@NS@@QAE@H@Z' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 199 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 203 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 231 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 235 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 252 + SymbolName: '??0Foo@NS@@QAE@H@Z' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 256 + SymbolName: '??0Foo@NS@@QAE@H@Z' + Type: IMAGE_REL_I386_SECTION +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 65 + NumberOfRelocations: 2 + NumberOfLinenumbers: 0 + CheckSum: 4176946275 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 2 + - Name: .bss + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: .text + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 32 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 1438182552 + Number: 4 + Selection: IMAGE_COMDAT_SELECT_ANY + - Name: '??0Foo@NS@@QAE@H@Z' + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .drectve + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 5 + - Name: '.debug$S' + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 832 + NumberOfRelocations: 11 + NumberOfLinenumbers: 0 + CheckSum: 4106171226 + Number: 6 + - Name: '.debug$S' + Value: 0 + SectionNumber: 9 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 284 + NumberOfRelocations: 9 + NumberOfLinenumbers: 0 + CheckSum: 1378739251 + Number: 4 + Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE + - Name: '.debug$T' + Value: 0 + SectionNumber: 7 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 316 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3343977630 + Number: 7 + - Name: '.debug$H' + Value: 0 + SectionNumber: 8 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 268 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3965031229 + Number: 8 + - Name: '@feat.00' + Value: 1 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: _main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '?func@NS@@YAHABUFoo@1@@Z' + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: lld/trunk/test/COFF/Inputs/pdb-hashes-2-missing.yaml =================================================================== --- lld/trunk/test/COFF/Inputs/pdb-hashes-2-missing.yaml +++ lld/trunk/test/COFF/Inputs/pdb-hashes-2-missing.yaml @@ -0,0 +1,321 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E5508B45088B4D088B09C1E1018945FC89C883C4045DC3 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .bss + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 + Subsections: + - !Symbols + Records: + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ ] + Machine: Pentium3 + FrontendMajor: 6 + FrontendMinor: 0 + FrontendBuild: 0 + FrontendQFE: 0 + BackendMajor: 6000 + BackendMinor: 0 + BackendBuild: 0 + BackendQFE: 0 + Version: 'clang version 6.0.0 ' + - !FrameData + Frames: + - CodeSize: 25 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 4 + RvaStart: 0 + SavedRegsSize: 0 + - CodeSize: 24 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 3 + RvaStart: 1 + SavedRegsSize: 4 + - CodeSize: 22 + FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 1 + RvaStart: 3 + SavedRegsSize: 4 + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 25 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4109 + Flags: [ ] + DisplayName: 'NS::func' + - Kind: S_LOCAL + LocalSym: + Type: 4099 + Flags: [ IsParameter ] + VarName: f + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 25 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' + Lines: + - Offset: 0 + LineStart: 3 + IsStatement: false + EndDelta: 0 + - Offset: 7 + LineStart: 4 + IsStatement: false + EndDelta: 0 + Columns: + - !Symbols + Records: + - Kind: S_UDT + UDTSym: + Type: 4106 + UDTName: 'NS::Foo' + - !FileChecksums + Checksums: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' + Kind: MD5 + Checksum: 59DFAC75D18675AED1AD169FE316317E + - !StringTable + Strings: + - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' + - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + - '' + Relocations: + - VirtualAddress: 68 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_DIR32NB + - VirtualAddress: 208 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 212 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 248 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 252 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 268 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 272 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 + Types: + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: NS + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: 'NS::Foo' + UniqueName: '.?AUFoo@NS@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + - Kind: LF_MODIFIER + Modifier: + ModifiedType: 4097 + Modifiers: [ None, Const ] + - Kind: LF_POINTER + Pointer: + ReferentType: 4098 + Attrs: 32810 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 4099 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 1 + ArgumentList: 4100 + - Kind: LF_POINTER + Pointer: + ReferentType: 4097 + Attrs: 32778 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 116 ] + - Kind: LF_MFUNCTION + MemberFunction: + ReturnType: 3 + ClassType: 4097 + ThisType: 4102 + CallConv: ThisCall + Options: [ None ] + ParameterCount: 1 + ArgumentList: 4103 + ThisPointerAdjustment: 0 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 0 + Name: X + - Kind: LF_ONEMETHOD + OneMethod: + Type: 4104 + Attrs: 3 + VFTableOffset: -1 + Name: Foo + - Kind: LF_STRUCTURE + Class: + MemberCount: 2 + Options: [ None, HasUniqueName ] + FieldList: 4105 + Name: 'NS::Foo' + UniqueName: '.?AUFoo@NS@@' + DerivationList: 0 + VTableShape: 0 + Size: 4 + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4106 + SourceFile: 4107 + LineNumber: 2 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 4096 + FunctionType: 4101 + Name: func +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 25 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 1820185021 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 2 + - Name: .bss + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: .drectve + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 4 + - Name: '.debug$S' + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 584 + NumberOfRelocations: 7 + NumberOfLinenumbers: 0 + CheckSum: 2847177244 + Number: 5 + - Name: '.debug$T' + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 320 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2684556216 + Number: 6 + - Name: '@feat.00' + Value: 1 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '?func@NS@@YAHABUFoo@1@@Z' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: lld/trunk/test/COFF/Inputs/pdb-hashes-2.yaml =================================================================== --- lld/trunk/test/COFF/Inputs/pdb-hashes-2.yaml +++ lld/trunk/test/COFF/Inputs/pdb-hashes-2.yaml @@ -0,0 +1,355 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 5589E5508B45088B4D088B09C1E1018945FC89C883C4045DC3 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .bss + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 04000000F10000002F0000002D003C1101000000070006000000000000007017000000000000636C616E672076657273696F6E20362E302E30200000F5000000640000000000000000000000190000000000000004000000000000002B000000040000000400000001000000180000000000000004000000000000005800000003000400000000000300000016000000000000000400000000000000960000000100040000000000F1000000540000002E0047110000000000000000000000001900000000000000000000000D100000000000000000004E533A3A66756E63000A003E110310000001006600120045111600000008000000070000000000120002004F11F20000002800000000000000000000001900000000000000020000001C00000000000000030000000700000004000000F1000000100000000E0008110A1000004E533A3A466F6F00F40000001800000001000000100159DFAC75D18675AED1AD169FE316317E0000F3000000D400000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A322E63707000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2000245430202E7261536561726368203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200024543020246562702034202B203D202465697020245430205E203D2024657370202454302034202B203D2024656270202454302034202D205E203D200000 + Subsections: + - !Symbols + Records: + - Kind: S_COMPILE3 + Compile3Sym: + Flags: [ ] + Machine: Pentium3 + FrontendMajor: 6 + FrontendMinor: 0 + FrontendBuild: 0 + FrontendQFE: 0 + BackendMajor: 6000 + BackendMinor: 0 + BackendBuild: 0 + BackendQFE: 0 + Version: 'clang version 6.0.0 ' + - !FrameData + Frames: + - CodeSize: 25 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 4 + RvaStart: 0 + SavedRegsSize: 0 + - CodeSize: 24 + FrameFunc: '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 3 + RvaStart: 1 + SavedRegsSize: 4 + - CodeSize: 22 + FrameFunc: '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + LocalSize: 0 + MaxStackSize: 0 + ParamsSize: 4 + PrologSize: 1 + RvaStart: 3 + SavedRegsSize: 4 + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 25 + DbgStart: 0 + DbgEnd: 0 + FunctionType: 4109 + Flags: [ ] + DisplayName: 'NS::func' + - Kind: S_LOCAL + LocalSym: + Type: 4099 + Flags: [ IsParameter ] + VarName: f + - Kind: S_DEFRANGE_REGISTER_REL + DefRangeRegisterRelSym: + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 25 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' + Lines: + - Offset: 0 + LineStart: 3 + IsStatement: false + EndDelta: 0 + - Offset: 7 + LineStart: 4 + IsStatement: false + EndDelta: 0 + Columns: + - !Symbols + Records: + - Kind: S_UDT + UDTSym: + Type: 4106 + UDTName: 'NS::Foo' + - !FileChecksums + Checksums: + - FileName: 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' + Kind: MD5 + Checksum: 59DFAC75D18675AED1AD169FE316317E + - !StringTable + Strings: + - 'D:\src\llvmbuild\clang\Debug\x86\obj2.cpp' + - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = ' + - '$T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + - '$T0 $ebp 4 + = $eip $T0 ^ = $esp $T0 4 + = $ebp $T0 4 - ^ = ' + - '' + Relocations: + - VirtualAddress: 68 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_DIR32NB + - VirtualAddress: 208 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 212 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 248 + SymbolName: .text + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 252 + SymbolName: .text + Type: IMAGE_REL_I386_SECTION + - VirtualAddress: 268 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECREL + - VirtualAddress: 272 + SymbolName: '?func@NS@@YAHABUFoo@1@@Z' + Type: IMAGE_REL_I386_SECTION + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 040000000A000516000000004E5300F12A0005150000800200000000000000000000000000004E533A3A466F6F002E3F4155466F6F404E53404000F10A000110011000000100F2F10A000210021000002A8000000A00011201000000031000000E0008107400000000000100041000000A000210011000000A8000000A00011201000000740000001A0009100300000001100000061000000B00010007100000000000001A0003120D15030074000000000058001115030008100000466F6F002A0005150200000209100000000000000000000004004E533A3A466F6F002E3F4155466F6F404E53404000F12E00051600000000443A5C7372635C6C6C766D6275696C645C636C616E675C44656275675C7838365C6F626A2E6800F10E0006160A1000000B1000000200000012000116001000000510000066756E6300F3F2F1 + Types: + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: NS + - Kind: LF_STRUCTURE + Class: + MemberCount: 0 + Options: [ None, ForwardReference, HasUniqueName ] + FieldList: 0 + Name: 'NS::Foo' + UniqueName: '.?AUFoo@NS@@' + DerivationList: 0 + VTableShape: 0 + Size: 0 + - Kind: LF_MODIFIER + Modifier: + ModifiedType: 4097 + Modifiers: [ None, Const ] + - Kind: LF_POINTER + Pointer: + ReferentType: 4098 + Attrs: 32810 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 4099 ] + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 116 + CallConv: NearC + Options: [ None ] + ParameterCount: 1 + ArgumentList: 4100 + - Kind: LF_POINTER + Pointer: + ReferentType: 4097 + Attrs: 32778 + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 116 ] + - Kind: LF_MFUNCTION + MemberFunction: + ReturnType: 3 + ClassType: 4097 + ThisType: 4102 + CallConv: ThisCall + Options: [ None ] + ParameterCount: 1 + ArgumentList: 4103 + ThisPointerAdjustment: 0 + - Kind: LF_FIELDLIST + FieldList: + - Kind: LF_MEMBER + DataMember: + Attrs: 3 + Type: 116 + FieldOffset: 0 + Name: X + - Kind: LF_ONEMETHOD + OneMethod: + Type: 4104 + Attrs: 3 + VFTableOffset: -1 + Name: Foo + - Kind: LF_STRUCTURE + Class: + MemberCount: 2 + Options: [ None, HasUniqueName ] + FieldList: 4105 + Name: 'NS::Foo' + UniqueName: '.?AUFoo@NS@@' + DerivationList: 0 + VTableShape: 0 + Size: 4 + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'D:\src\llvmbuild\clang\Debug\x86\obj.h' + - Kind: LF_UDT_SRC_LINE + UdtSourceLine: + UDT: 4106 + SourceFile: 4107 + LineNumber: 2 + - Kind: LF_FUNC_ID + FuncId: + ParentScope: 4096 + FunctionType: 4101 + Name: func + - Name: '.debug$H' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: C5C9330100000000EC145CD76AEFE74E78880D531132B3BB8FFACEF79E616EF06A14EA74A2420F9062A1FB04917E59759949E334BA18509ED692F3C65CE242D8450EBC78B81B63AF8316DC324562EB9F0D4A0D708E8A25C263DB05943C19B84A36719E1E414DDA3EDBDF005322238D70F9058EEDC5C50EF11BC849618B51FD89E3A50EABE5E8FE3945468547C19DC681D0BFB3B797DD91CA4D7F1953C314442D5549419E78044E38A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0C0A9021B711ACC4F67008974EBF441031BDD653F6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA0AF6C1846743F43D846BB19517E12E8873BBA90CC41DD1BEAC89CBA8897AC1BA46762E2557A82D89DCBC783AF285D9DBB672F67A81E36906B2038B57 + GlobalHashes: + Version: 0 + HashAlgorithm: 0 + HashValues: + - EC145CD76AEFE74E78880D531132B3BB8FFACEF7 + - 9E616EF06A14EA74A2420F9062A1FB04917E5975 + - 9949E334BA18509ED692F3C65CE242D8450EBC78 + - B81B63AF8316DC324562EB9F0D4A0D708E8A25C2 + - 63DB05943C19B84A36719E1E414DDA3EDBDF0053 + - 22238D70F9058EEDC5C50EF11BC849618B51FD89 + - E3A50EABE5E8FE3945468547C19DC681D0BFB3B7 + - 97DD91CA4D7F1953C314442D5549419E78044E38 + - A0BF16BFFAA5EE9C0103E7DBFE9941E63379C0B0 + - C0A9021B711ACC4F67008974EBF441031BDD653F + - 6935DFF3112C6A5346EF2AC94B9B7EB56EF55CFA + - 0AF6C1846743F43D846BB19517E12E8873BBA90C + - C41DD1BEAC89CBA8897AC1BA46762E2557A82D89 + - DCBC783AF285D9DBB672F67A81E36906B2038B57 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 25 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 1820185021 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 2 + - Name: .bss + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: .drectve + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 4 + - Name: '.debug$S' + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 584 + NumberOfRelocations: 7 + NumberOfLinenumbers: 0 + CheckSum: 2847177244 + Number: 5 + - Name: '.debug$T' + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 320 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2684556216 + Number: 6 + - Name: '.debug$H' + Value: 0 + SectionNumber: 7 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 288 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2348181452 + Number: 7 + - Name: '@feat.00' + Value: 1 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '?func@NS@@YAHABUFoo@1@@Z' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: lld/trunk/test/COFF/pdb-global-hashes.test =================================================================== --- lld/trunk/test/COFF/pdb-global-hashes.test +++ lld/trunk/test/COFF/pdb-global-hashes.test @@ -0,0 +1,93 @@ +RUN: yaml2obj %p/Inputs/pdb-hashes-1.yaml > %t.1.obj +RUN: yaml2obj %p/Inputs/pdb-hashes-2.yaml > %t.2.obj +RUN: yaml2obj %p/Inputs/pdb-hashes-2-missing.yaml > %t.2.missing.obj +RUN: lld-link /debug %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.nohash.pdb +RUN: lld-link /debug:ghash %t.1.obj %t.2.obj /entry:main /nodefaultlib /PDB:%t.hash.pdb +RUN: lld-link /debug:ghash %t.1.obj %t.2.missing.obj /entry:main /nodefaultlib /PDB:%t.mixed.pdb +RUN: llvm-pdbutil dump -types -ids %t.nohash.pdb | FileCheck %s +RUN: llvm-pdbutil dump -types -ids %t.hash.pdb | FileCheck %s +RUN: llvm-pdbutil dump -types -ids %t.mixed.pdb | FileCheck %s + +; These object files were generated via the following inputs and commands: +; ---------------------------------------------- +; // obj.h +; namespace NS { +; struct Foo { +; explicit Foo(int x) : X(x) {} +; int X; +; }; +; +; int func(const Foo &f); +; } +; ---------------------------------------------- +; // obj1.cpp +; #include "obj.h" +; +; int main(int argc, char **argv) { +; NS::Foo f(argc); +; return NS::func(f); +; } +; ---------------------------------------------- +; // obj2.cpp +; #include "obj.h" +; +; int NS::func(const Foo &f) { +; return 2 * f.X; +; } +; ---------------------------------------------- +; $ clang-cl /Z7 /GS- obj1.cpp /c /o obj1.obj +; $ clang-cl /Z7 /GS- obj2.cpp /c /o obj2.obj + +CHECK: Types (TPI Stream) +CHECK-NEXT: ============================================================ +CHECK-NEXT: Showing 13 records +CHECK-NEXT: 0x1000 | LF_POINTER [size = 12] +CHECK-NEXT: referent = 0x0470 (char*), mode = pointer, opts = None, kind = ptr32 +CHECK-NEXT: 0x1001 | LF_ARGLIST [size = 16] +CHECK-NEXT: 0x0074 (int): `int` +CHECK-NEXT: 0x1000: `char**` +CHECK-NEXT: 0x1002 | LF_PROCEDURE [size = 16] +CHECK-NEXT: return type = 0x0074 (int), # args = 2, param list = 0x1001 +CHECK-NEXT: calling conv = cdecl, options = None +CHECK-NEXT: 0x1003 | LF_STRUCTURE [size = 44] `NS::Foo` +CHECK-NEXT: unique name: `.?AUFoo@NS@@` +CHECK-NEXT: vtable: , base list: , field list: +CHECK-NEXT: options: forward ref | has unique name +CHECK-NEXT: 0x1004 | LF_POINTER [size = 12] +CHECK-NEXT: referent = 0x1003, mode = pointer, opts = None, kind = ptr32 +CHECK-NEXT: 0x1005 | LF_ARGLIST [size = 12] +CHECK-NEXT: 0x0074 (int): `int` +CHECK-NEXT: 0x1006 | LF_MFUNCTION [size = 28] +CHECK-NEXT: return type = 0x0003 (void), # args = 1, param list = 0x1005 +CHECK-NEXT: class type = 0x1003, this type = 0x1004, this adjust = 0 +CHECK-NEXT: calling conv = thiscall, options = None +CHECK-NEXT: 0x1007 | LF_FIELDLIST [size = 28] +CHECK-NEXT: - LF_MEMBER [name = `X`, Type = 0x0074 (int), offset = 0, attrs = public] +CHECK-NEXT: - LF_ONEMETHOD [name = `Foo`] +CHECK-NEXT: type = 0x1006, vftable offset = -1, attrs = public +CHECK-NEXT: 0x1008 | LF_STRUCTURE [size = 44] `NS::Foo` +CHECK-NEXT: unique name: `.?AUFoo@NS@@` +CHECK-NEXT: vtable: , base list: , field list: 0x1007 +CHECK-NEXT: options: has unique name +CHECK-NEXT: 0x1009 | LF_MODIFIER [size = 12] +CHECK-NEXT: referent = 0x1003, modifiers = const +CHECK-NEXT: 0x100A | LF_POINTER [size = 12] +CHECK-NEXT: referent = 0x1009, mode = ref, opts = None, kind = ptr32 +CHECK-NEXT: 0x100B | LF_ARGLIST [size = 12] +CHECK-NEXT: 0x100A: `const NS::Foo&` +CHECK-NEXT: 0x100C | LF_PROCEDURE [size = 16] +CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = 0x100B +CHECK-NEXT: calling conv = cdecl, options = None +CHECK: Types (IPI Stream) +CHECK-NEXT: ============================================================ +CHECK-NEXT: Showing 6 records +CHECK-NEXT: 0x1000 | LF_FUNC_ID [size = 20] +CHECK-NEXT: name = main, type = 0x1002, parent scope = +CHECK-NEXT: 0x1001 | LF_STRING_ID [size = 48] ID: , String: D:\src\llvmbuild\clang\Debug\x86\obj.h +CHECK-NEXT: 0x1002 | LF_UDT_SRC_LINE [size = 16] +CHECK-NEXT: udt = 0x1008, file = 4097, line = 2 +CHECK-NEXT: 0x1003 | LF_MFUNC_ID [size = 16] +CHECK-NEXT: name = Foo, type = 0x1006, class type = 0x1003 +CHECK-NEXT: 0x1004 | LF_STRING_ID [size = 12] ID: , String: NS +CHECK-NEXT: 0x1005 | LF_FUNC_ID [size = 20] +CHECK-NEXT: name = func, type = 0x100C, parent scope = 0x1004 Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeHashing.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeHashing.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeHashing.h @@ -88,18 +88,39 @@ ArrayRef PreviousTypes, ArrayRef PreviousIds); + /// Given a sequence of bytes representing a record, compute a global hash for + /// this record. Due to the nature of global hashes incorporating the hashes + /// of referenced records, this function requires a list of types and ids + /// that RecordData might reference, indexable by TypeIndex. + static GloballyHashedType hashType(CVType Type, + ArrayRef PreviousTypes, + ArrayRef PreviousIds) { + return hashType(Type.RecordData, PreviousTypes, PreviousIds); + } + /// Given a sequence of combined type and ID records, compute global hashes /// for each of them, returning the results in a vector of hashed types. template static std::vector hashTypes(Range &&Records) { std::vector Hashes; - Hashes.reserve(std::distance(std::begin(Records), std::end(Records))); for (const auto &R : Records) Hashes.push_back(hashType(R, Hashes, Hashes)); return Hashes; } + /// Given a sequence of combined type and ID records, compute global hashes + /// for each of them, returning the results in a vector of hashed types. + template + static std::vector + hashIds(Range &&Records, ArrayRef TypeHashes) { + std::vector IdHashes; + for (const auto &R : Records) + IdHashes.push_back(hashType(R, TypeHashes, IdHashes)); + + return IdHashes; + } + static std::vector hashTypeCollection(TypeCollection &Types) { std::vector Hashes; @@ -109,6 +130,11 @@ return Hashes; } }; +static_assert(std::is_trivially_copyable::value, + "GloballyHashedType must be trivially copyable so that we can " + "reinterpret_cast arrays of hash data to arrays of " + "GloballyHashedType"); + } // namespace codeview template <> struct DenseMapInfo { Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -19,6 +19,8 @@ namespace codeview { class TypeIndex; +struct GloballyHashedType; +class GlobalTypeTableBuilder; class MergingTypeTableBuilder; /// \brief Merge one set of type records into another. This method assumes @@ -83,6 +85,22 @@ SmallVectorImpl &SourceToDest, const CVTypeArray &IdsAndTypes); +Error mergeTypeAndIdRecords(GlobalTypeTableBuilder &DestIds, + GlobalTypeTableBuilder &DestTypes, + SmallVectorImpl &SourceToDest, + const CVTypeArray &IdsAndTypes, + ArrayRef Hashes); + +Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, + SmallVectorImpl &SourceToDest, + const CVTypeArray &Types, + ArrayRef Hashes); + +Error mergeIdRecords(GlobalTypeTableBuilder &Dest, ArrayRef Types, + SmallVectorImpl &SourceToDest, + const CVTypeArray &Ids, + ArrayRef Hashes); + } // end namespace codeview } // end namespace llvm Index: llvm/trunk/include/llvm/Object/COFF.h =================================================================== --- llvm/trunk/include/llvm/Object/COFF.h +++ llvm/trunk/include/llvm/Object/COFF.h @@ -743,6 +743,12 @@ support::ulittle16_t NumberOfIDEntries; }; +struct debug_h_header { + support::ulittle32_t Magic; + support::ulittle16_t Version; + support::ulittle16_t HashAlgorithm; +}; + class COFFObjectFile : public ObjectFile { private: friend class ImportDirectoryEntryRef; Index: llvm/trunk/lib/DebugInfo/CodeView/TypeHashing.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeHashing.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeHashing.cpp @@ -54,7 +54,7 @@ reinterpret_cast(RefData.data()), Ref.Count); for (TypeIndex TI : Indices) { ArrayRef BytesToHash; - if (TI.isSimple() || TI.isNoneType()) { + if (TI.isSimple() || TI.isNoneType() || TI.toArrayIndex() >= Prev.size()) { const uint8_t *IndexBytes = reinterpret_cast(&TI); BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex)); } else { Index: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -10,6 +10,7 @@ #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" @@ -62,6 +63,7 @@ static const TypeIndex Untranslated; + // Local hashing entry points Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes, const CVTypeArray &IdsAndTypes); @@ -71,6 +73,18 @@ Error mergeTypeRecords(MergingTypeTableBuilder &Dest, const CVTypeArray &Types); + // Global hashing entry points + Error mergeTypesAndIds(GlobalTypeTableBuilder &DestIds, + GlobalTypeTableBuilder &DestTypes, + const CVTypeArray &IdsAndTypes, + ArrayRef Hashes); + Error mergeIdRecords(GlobalTypeTableBuilder &Dest, + ArrayRef TypeSourceToDest, + const CVTypeArray &Ids, + ArrayRef Hashes); + Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types, + ArrayRef Hashes); + private: Error doit(const CVTypeArray &Types); @@ -83,6 +97,14 @@ bool remapTypeIndex(TypeIndex &Idx); bool remapItemIndex(TypeIndex &Idx); + bool hasTypeStream() const { + return (UseGlobalHashes) ? (!!DestGlobalTypeStream) : (!!DestTypeStream); + } + + bool hasIdStream() const { + return (UseGlobalHashes) ? (!!DestGlobalIdStream) : (!!DestIdStream); + } + ArrayRef serializeRemapped(const RemappedType &Record); bool remapIndices(RemappedType &Record, ArrayRef Refs); @@ -100,6 +122,8 @@ Optional LastError; + bool UseGlobalHashes = false; + bool IsSecondPass = false; unsigned NumBadIndices = 0; @@ -109,6 +133,11 @@ MergingTypeTableBuilder *DestIdStream = nullptr; MergingTypeTableBuilder *DestTypeStream = nullptr; + GlobalTypeTableBuilder *DestGlobalIdStream = nullptr; + GlobalTypeTableBuilder *DestGlobalTypeStream = nullptr; + + ArrayRef GlobalHashes; + // If we're only mapping id records, this array contains the mapping for // type records. ArrayRef TypeLookup; @@ -209,7 +238,7 @@ // special mapping from OldTypeStream -> NewTypeStream which was computed // externally. Regardless, we use this special map if and only if we are // doing an id-only mapping. - if (DestTypeStream == nullptr) + if (!hasTypeStream()) return remapIndex(Idx, TypeLookup); assert(TypeLookup.empty()); @@ -217,13 +246,15 @@ } bool TypeStreamMerger::remapItemIndex(TypeIndex &Idx) { - assert(DestIdStream); + assert(hasIdStream()); return remapIndex(Idx, IndexMap); } +// Local hashing entry points Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest, const CVTypeArray &Types) { DestTypeStream = &Dest; + UseGlobalHashes = false; return doit(Types); } @@ -233,6 +264,7 @@ const CVTypeArray &Ids) { DestIdStream = &Dest; TypeLookup = TypeSourceToDest; + UseGlobalHashes = false; return doit(Ids); } @@ -242,6 +274,41 @@ const CVTypeArray &IdsAndTypes) { DestIdStream = &DestIds; DestTypeStream = &DestTypes; + UseGlobalHashes = false; + return doit(IdsAndTypes); +} + +// Global hashing entry points +Error TypeStreamMerger::mergeTypeRecords(GlobalTypeTableBuilder &Dest, + const CVTypeArray &Types, + ArrayRef Hashes) { + DestGlobalTypeStream = &Dest; + UseGlobalHashes = true; + GlobalHashes = Hashes; + + return doit(Types); +} + +Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest, + ArrayRef TypeSourceToDest, + const CVTypeArray &Ids, + ArrayRef Hashes) { + DestGlobalIdStream = &Dest; + TypeLookup = TypeSourceToDest; + UseGlobalHashes = true; + GlobalHashes = Hashes; + + return doit(Ids); +} + +Error TypeStreamMerger::mergeTypesAndIds(GlobalTypeTableBuilder &DestIds, + GlobalTypeTableBuilder &DestTypes, + const CVTypeArray &IdsAndTypes, + ArrayRef Hashes) { + DestGlobalIdStream = &DestIds; + DestGlobalTypeStream = &DestTypes; + UseGlobalHashes = true; + GlobalHashes = Hashes; return doit(IdsAndTypes); } @@ -286,18 +353,29 @@ } Error TypeStreamMerger::remapType(const CVType &Type) { - MergingTypeTableBuilder &Dest = - isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; - - RemappedType R(Type); - SmallVector Refs; - discoverTypeIndices(Type.RecordData, Refs); - bool MappedAllIndices = remapIndices(R, Refs); - ArrayRef Data = serializeRemapped(R); + auto DoSerialize = [this, Type]() -> ArrayRef { + RemappedType R(Type); + SmallVector Refs; + discoverTypeIndices(Type.RecordData, Refs); + if (!remapIndices(R, Refs)) + return {}; + return serializeRemapped(R); + }; TypeIndex DestIdx = Untranslated; - if (MappedAllIndices) - DestIdx = Dest.insertRecordBytes(Data); + if (UseGlobalHashes) { + GlobalTypeTableBuilder &Dest = + isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream; + GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()]; + DestIdx = Dest.insertRecordAs(H, DoSerialize); + } else { + MergingTypeTableBuilder &Dest = + isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream; + + auto Data = DoSerialize(); + if (!Data.empty()) + DestIdx = Dest.insertRecordBytes(Data); + } addMapping(DestIdx); ++CurIndex; @@ -350,3 +428,28 @@ TypeStreamMerger M(SourceToDest); return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes); } + +Error llvm::codeview::mergeTypeAndIdRecords( + GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes, + SmallVectorImpl &SourceToDest, const CVTypeArray &IdsAndTypes, + ArrayRef Hashes) { + TypeStreamMerger M(SourceToDest); + return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes); +} + +Error llvm::codeview::mergeTypeRecords(GlobalTypeTableBuilder &Dest, + SmallVectorImpl &SourceToDest, + const CVTypeArray &Types, + ArrayRef Hashes) { + TypeStreamMerger M(SourceToDest); + return M.mergeTypeRecords(Dest, Types, Hashes); +} + +Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest, + ArrayRef Types, + SmallVectorImpl &SourceToDest, + const CVTypeArray &Ids, + ArrayRef Hashes) { + TypeStreamMerger M(SourceToDest); + return M.mergeIdRecords(Dest, Types, Ids, Hashes); +}