diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -332,6 +332,10 @@ /// coverage pass should actually not be instrumented. std::vector SanitizeCoverageBlacklistFiles; + /// Executable and command-line used to create a given CompilerInvocation. + const char *Argv0 = nullptr; + ArrayRef CommandLineArgs; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -155,7 +155,8 @@ /// \param [out] Res - The resulting invocation. static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef CommandLineArgs, - DiagnosticsEngine &Diags); + DiagnosticsEngine &Diags, + const char *Argv0 = nullptr); /// Get the directory where the compiler headers /// reside, relative to the compiler binary (found by the passed in diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -536,6 +536,8 @@ Entry.Group == frontend::IncludeDirGroup::System)) Options.MCOptions.IASSearchPaths.push_back( Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path); + Options.MCOptions.Argv0 = CodeGenOpts.Argv0; + Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs; } static Optional getGCOVOptions(const CodeGenOptions &CodeGenOpts) { if (CodeGenOpts.DisableGCov) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3615,7 +3615,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ArrayRef CommandLineArgs, - DiagnosticsEngine &Diags) { + DiagnosticsEngine &Diags, + const char *Argv0) { bool Success = true; // Parse the arguments. @@ -3735,6 +3736,11 @@ Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false; Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored); } + + // Store the command-line for using in CodeView backend. + Res.getCodeGenOpts().Argv0 = Argv0; + Res.getCodeGenOpts().CommandLineArgs = CommandLineArgs; + return Success; } diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp --- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -93,7 +93,7 @@ if (CC1Args) *CC1Args = {CCArgs.begin(), CCArgs.end()}; auto CI = std::make_unique(); - if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags) && + if (!CompilerInvocation::CreateFromArgs(*CI, CCArgs, *Diags, Args[0]) && !ShouldRecoverOnErorrs) return nullptr; return CI; diff --git a/clang/test/CodeGen/debug-info-codeview-buildinfo.c b/clang/test/CodeGen/debug-info-codeview-buildinfo.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/debug-info-codeview-buildinfo.c @@ -0,0 +1,24 @@ +// RUN: %clang_cl /c /Z7 %s /Fo%t.obj +// RUN: llvm-pdbutil dump --types %t.obj | FileCheck %s +// RUN: %clang_cl /c /Z7 %s /Fo%t.obj -fdebug-compilation-dir . +// RUN: llvm-pdbutil dump --types %t.obj | FileCheck %s --check-prefix RELATIVE + +int main() { return 42; } + +// CHECK: Types (.debug$T) +// CHECK: ============================================================ +// CHECK: 0x[[PWD:.+]] | LF_STRING_ID [size = {{.+}}] ID: , String: [[PWDVAL:.+]] +// CHECK: 0x[[FILEPATH:.+]] | LF_STRING_ID [size = {{.+}}] ID: , String: [[FILEPATHVAL:.+[\\/]debug-info-codeview-buildinfo.c]] +// CHECK: 0x[[TOOL:.+]] | LF_STRING_ID [size = {{.+}}] ID: , String: [[TOOLVAL:.+[\\/]clang.*]] +// CHECK: 0x[[CMDLINE:.+]] | LF_STRING_ID [size = {{.+}}] ID: , String: -cc1 +// CHECK: 0x{{.+}} | LF_BUILDINFO [size = {{.+}}] +// CHECK: 0x[[PWD]]: `[[PWDVAL]]` +// CHECK: 0x[[TOOL]]: `[[TOOLVAL]]` +// CHECK: 0x[[FILEPATH]]: `[[FILEPATHVAL]]` +// CHECK: : `` +// CHECK: 0x[[CMDLINE]]: `-cc1 + +// RELATIVE: Types (.debug$T) +// RELATIVE: ============================================================ +// RELATIVE: 0x{{.+}} | LF_BUILDINFO [size = {{.+}}] +// RELATIVE: 0x{{.+}}: `.` diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -181,7 +181,7 @@ return 0; } -int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { +int cc1_main(ArrayRef Argv, void *MainAddr) { ensureSufficientStack(); std::unique_ptr Clang(new CompilerInstance()); @@ -203,12 +203,11 @@ IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); - bool Success = - CompilerInvocation::CreateFromArgs(Clang->getInvocation(), Argv, Diags); - + bool Success = CompilerInvocation::CreateFromArgs( + Clang->getInvocation(), Argv.slice(1), Diags, Argv[0]); if (Clang->getFrontendOpts().TimeTrace) { llvm::timeTraceProfilerInitialize( - Clang->getFrontendOpts().TimeTraceGranularity, Argv0); + Clang->getFrontendOpts().TimeTraceGranularity, Argv[0]); } // --print-supported-cpus takes priority over the actual compilation. if (Clang->getFrontendOpts().PrintSupportedCPUs) @@ -218,7 +217,7 @@ if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && Clang->getHeaderSearchOpts().ResourceDir.empty()) Clang->getHeaderSearchOpts().ResourceDir = - CompilerInvocation::GetResourcesPath(Argv0, MainAddr); + CompilerInvocation::GetResourcesPath(Argv[0], MainAddr); // Create the actual diagnostics engine. Clang->createDiagnostics(); diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -203,8 +203,7 @@ } } -extern int cc1_main(ArrayRef Argv, const char *Argv0, - void *MainAddr); +extern int cc1_main(ArrayRef Argv, void *MainAddr); extern int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr); extern int cc1gen_reproducer_main(ArrayRef Argv, @@ -327,7 +326,7 @@ StringRef Tool = ArgV[1]; void *GetExecutablePathVP = (void *)(intptr_t)GetExecutablePath; if (Tool == "-cc1") - return cc1_main(makeArrayRef(ArgV).slice(2), ArgV[0], GetExecutablePathVP); + return cc1_main(makeArrayRef(ArgV), GetExecutablePathVP); if (Tool == "-cc1as") return cc1as_main(makeArrayRef(ArgV).slice(2), ArgV[0], GetExecutablePathVP); diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -250,6 +250,55 @@ }); } +// LF_BUILDINFO records might contain relative paths, and we want to make them +// absolute. We do this remapping only after the type records were merged, +// because the full types graph isn't known during merging. In addition, we plan +// to multi-thread the type merging, and the change below needs to be done +// atomically, single-threaded. + +// A complication could arise when a LF_STRING_ID record already exists with the +// same content as the new absolutized path. In that case, we simply redirect +// LF_BUILDINFO's CurrentDirectory index to reference the existing LF_STRING_ID +// record. + +static void remapBuildInfo(TypeCollection &idTable) { + SimpleTypeSerializer S; + idTable.ForEachRecord([&](TypeIndex ti, const CVType &type) { + if (type.kind() != LF_BUILDINFO) + return; + BuildInfoRecord bi; + cantFail(TypeDeserializer::deserializeAs(const_cast(type), bi)); + + TypeIndex pwdTI = bi.getArgs()[BuildInfoRecord::CurrentDirectory]; + CVType curDir = idTable.getType(pwdTI); + + StringIdRecord pwd; + cantFail(TypeDeserializer::deserializeAs(curDir, pwd)); + + SmallString<128> remappedPWD(pwd.getString()); + pdbMakeAbsolute(remappedPWD); + + if (remappedPWD == pwd.getString()) + return; // The path is already absolute. + + pwd.String = remappedPWD; + ArrayRef data = S.serialize(pwd); + + // Replace the previous LF_STRING_ID record + if (!idTable.replaceType(pwdTI, CVType(data), /*Stabilize=*/true)) { + + // This new record is already there. We don't want duplicates, so + // re-serialize the BuildInfoRecord instead. + bi.ArgIndices[BuildInfoRecord::CurrentDirectory] = pwdTI; + + data = S.serialize(bi); + bool r = idTable.replaceType(ti, CVType(data), /*Stabilize=*/true); + assert(r && "Didn't expect two build records pointing to the same OBJ!"); + (void)r; + } + }); +} + static bool remapTypeIndex(TypeIndex &ti, ArrayRef typeIndexMap) { if (ti.isSimple()) return true; @@ -988,6 +1037,9 @@ builder.getStringTableBuilder().setStrings(pdbStrTab); t1.stop(); + // Remap the contents of the LF_BUILDINFO record. + remapBuildInfo(tMerger.getIDTable()); + // Construct TPI and IPI stream contents. ScopedTimer t2(tpiStreamLayoutTimer); addTypeInfo(builder.getTpiBuilder(), tMerger.getTypeTable()); diff --git a/lld/test/COFF/Inputs/pdb_lines_1_relative.yaml b/lld/test/COFF/Inputs/pdb_lines_1_relative.yaml --- a/lld/test/COFF/Inputs/pdb_lines_1_relative.yaml +++ b/lld/test/COFF/Inputs/pdb_lines_1_relative.yaml @@ -19,6 +19,7 @@ Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] Alignment: 4 SectionData: '' + SizeOfRawData: 0 - Name: .xdata Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] Alignment: 4 @@ -38,7 +39,7 @@ - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 4 - SectionData: 04000000F10000002F0000002D003C1100000000D0000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F1000000300000002A0047110000000000000000000000001B000000000000000000000002100000000000000000006D61696E0002004F11F20000003000000000000000000000001B00000000000000030000002400000000000000020000000C000000030000001100000004000000F400000030000000010000001001EA6429BCE282CCF3F0E3CD93B216EB410000110000001001061EB73ABB642532857A4F1D9CBAC3230000F30000001C000000002E5C7064625F6C696E65735F312E63002E5C666F6F2E6800000000 + SectionData: 04000000F10000008400000082003C1100000000D0000B00000000000000F82A000000000000636C616E672076657273696F6E2031312E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A6563742E6769742036373830626534633633653538323436366133356437363434633335653039626138356434663637290000F1000000500000002A0047110000000000000000000000001B000000000000000000000002100000000000000000006D61696E001E0012102800000000000000000000000000000000000000000000400100000002004F11F20000003000000000000000000000001B00000000000000030000002400000000000000020000000C000000030000001100000004000000F4000000300000000100000010019A64DD4298487888B1D99F825D520C5E0000110000001001A9D05E6DC184DE20A57797E24F8B0E970000F30000001C000000002E5C7064625F6C696E65735F312E63002E5C666F6F2E6800000000F10000000800000006004C1109100000 Subsections: - !Symbols Records: @@ -46,15 +47,15 @@ Compile3Sym: Flags: [ ] Machine: X64 - FrontendMajor: 7 + FrontendMajor: 11 FrontendMinor: 0 FrontendBuild: 0 FrontendQFE: 0 - BackendMajor: 7000 + BackendMajor: 11000 BackendMinor: 0 BackendBuild: 0 BackendQFE: 0 - Version: 'clang version 7.0.0 ' + Version: 'clang version 11.0.0 (https://github.com/llvm/llvm-project.git 6780be4c63e582466a35d7644c35e09ba85d4f67)' - !Symbols Records: - Kind: S_GPROC32_ID @@ -65,8 +66,17 @@ FunctionType: 4098 Flags: [ ] DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 40 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ ] - Kind: S_PROC_ID_END - ScopeEndSym: + ScopeEndSym: {} - !Lines CodeSize: 27 Flags: [ ] @@ -87,15 +97,15 @@ LineStart: 4 IsStatement: false EndDelta: 0 - Columns: + Columns: [] - !FileChecksums Checksums: - FileName: '.\pdb_lines_1.c' Kind: MD5 - Checksum: EA6429BCE282CCF3F0E3CD93B216EB41 + Checksum: 9A64DD4298487888B1D99F825D520C5E - FileName: '.\foo.h' Kind: MD5 - Checksum: 061EB73ABB642532857A4F1D9CBAC323 + Checksum: A9D05E6DC184DE20A57797E24F8B0E97 - !StringTable Strings: - '.\pdb_lines_1.c' @@ -103,23 +113,28 @@ - '' - '' - '' + - !Symbols + Records: + - Kind: S_BUILDINFO + BuildInfoSym: + BuildId: 4105 Relocations: - - VirtualAddress: 100 + - VirtualAddress: 184 SymbolName: main Type: IMAGE_REL_AMD64_SECREL - - VirtualAddress: 104 + - VirtualAddress: 188 SymbolName: main Type: IMAGE_REL_AMD64_SECTION - - VirtualAddress: 124 + - VirtualAddress: 240 SymbolName: main Type: IMAGE_REL_AMD64_SECREL - - VirtualAddress: 128 + - VirtualAddress: 244 SymbolName: main Type: IMAGE_REL_AMD64_SECTION - Name: '.debug$T' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 4 - SectionData: 0400000006000112000000000E0008107400000000000000001000001200011600000000011000006D61696E00F3F2F10E0008100300000000000000001000000E0001160000000003100000666F6F00 + SectionData: 0400000006000112000000000E0008107400000000000000001000001200011600000000011000006D61696E00F3F2F10E0008100300000000000000001000000E0001160000000003100000666F6F000A000516000000002E00F2F116000516000000007064625F6C696E65735F312E6300F2F13A00051600000000443A5C6C6C766D2D70726F6A6563745C6275696C646E696E6A614465624D5356435C62696E5C636C616E672D636C2E65786500F186060516000000002D636331202D747269706C65207838365F36342D70632D77696E646F77732D6D73766331392E32362E3238383036202D656D69742D6F626A202D6D72656C61782D616C6C202D6D696E6372656D656E74616C2D6C696E6B65722D636F6D70617469626C65202D64697361626C652D66726565202D6D61696E2D66696C652D6E616D65202D6D72656C6F636174696F6E2D6D6F64656C20706963202D7069632D6C6576656C2032202D6D7468726561642D6D6F64656C20706F736978202D6D6672616D652D706F696E7465723D6E6F6E65202D72656C617865642D616C696173696E67202D666D6174682D6572726E6F202D666E6F2D726F756E64696E672D6D617468202D6D636F6E7374727563746F722D616C6961736573202D6D756E77696E642D7461626C6573202D7461726765742D637075207838362D3634202D6D6C6C766D202D7838362D61736D2D73796E7461783D696E74656C202D445F4D54202D666C746F2D7669736962696C6974792D7075626C69632D737464202D2D646570656E64656E742D6C69623D6C6962636D74202D2D646570656E64656E742D6C69623D6F6C646E616D6573202D737461636B2D70726F746563746F722032202D666D732D766F6C6174696C65202D66646961676E6F73746963732D666F726D6174206D737663202D67636F646576696577202D64656275672D696E666F2D6B696E643D6C696D69746564202D7265736F757263652D6469722022443A5C6C6C766D2D70726F6A6563745C6275696C646E696E6A614465624D5356435C6C69625C636C616E675C31312E302E3022202D696E7465726E616C2D6973797374656D2022443A5C6C6C766D2D70726F6A6563745C6275696C646E696E6A614465624D5356435C6C69625C636C616E675C31312E302E305C696E636C75646522202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C4D6963726F736F66742056697375616C2053747564696F5C323031395C50726F66657373696F6E616C5C56435C546F6F6C735C4D5356435C31342E32362E32383830315C41544C4D46435C696E636C75646522202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C4D6963726F736F66742056697375616C2053747564696F5C323031395C50726F66657373696F6E616C5C56435C546F6F6C735C4D5356435C31342E32362E32383830315C696E636C75646522202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C4E4554465853444B5C342E385C696E636C7564655C756D22202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C7563727422202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C73686172656422202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C756D22202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C77696E727422202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C63707077696E727422202D6664656275672D636F6D70696C6174696F6E2D646972202E202D666572726F722D6C696D6974203139202D666D6573736167652D6C656E6774683D313230202D666E6F2D7573652D6378612D617465786974202D666D732D657874656E73696F6E73202D666D732D636F6D7061746962696C697479202D666D732D636F6D7061746962696C6974792D76657273696F6E3D31392E32362E3238383036202D6664656C617965642D74656D706C6174652D70617273696E67202D66636F6C6F722D646961676E6F7374696373202D6661646472736967202D6F207064625F6C696E65735F312E6F626A202D78206300F2F11A00031605000510000007100000061000000000000008100000F2F1 Types: - Kind: LF_ARGLIST ArgList: @@ -148,6 +163,25 @@ ParentScope: 0 FunctionType: 4099 Name: foo + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: . + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: pdb_lines_1.c + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'D:\llvm-project\buildninjaDebMSVC\bin\clang-cl.exe' + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: '-cc1 -triple x86_64-pc-windows-msvc19.26.28806 -emit-obj -mrelax-all -mincremental-linker-compatible -disable-free -main-file-name -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -mllvm -x86-asm-syntax=intel -D_MT -flto-visibility-public-std --dependent-lib=libcmt --dependent-lib=oldnames -stack-protector 2 -fms-volatile -fdiagnostics-format msvc -gcodeview -debug-info-kind=limited -resource-dir "D:\llvm-project\buildninjaDebMSVC\lib\clang\11.0.0" -internal-isystem "D:\llvm-project\buildninjaDebMSVC\lib\clang\11.0.0\include" -internal-isystem "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.26.28801\ATLMFC\include" -internal-isystem "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.26.28801\include" -internal-isystem "C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt" -fdebug-compilation-dir . -ferror-limit 19 -fmessage-length=120 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.26.28806 -fdelayed-template-parsing -fcolor-diagnostics -faddrsig -o pdb_lines_1.obj -x c' + - Kind: LF_BUILDINFO + BuildInfo: + ArgIndices: [ 4101, 4103, 4102, 0, 4104 ] - Name: .pdata Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] Alignment: 4 @@ -160,8 +194,12 @@ SymbolName: main Type: IMAGE_REL_AMD64_ADDR32NB - VirtualAddress: 8 - SymbolName: .xdata + SymbolTableIndex: 6 Type: IMAGE_REL_AMD64_ADDR32NB + - Name: .llvm_addrsig + Characteristics: [ IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 0A1D - Name: .xdata Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] Alignment: 4 @@ -169,7 +207,7 @@ - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 4 - SectionData: 04000000F10000002F000000290047110000000000000000000000000F00000000000000000000000410000000000000000000666F6F0002004F1100F20000003000000000000000000000000F000000180000000300000024000000000000000200000004000000030000000900000004000000 + SectionData: 04000000F1000000500000002A0047110000000000000000000000000F00000000000000000000000410000000000000000000666F6F00001E0012102800000000000000000000000000000000000000000000400100000002004F11F20000003000000000000000000000000F000000180000000300000024000000000000000200000004000000030000000900000004000000 Subsections: - !Symbols Records: @@ -181,8 +219,17 @@ FunctionType: 4100 Flags: [ ] DisplayName: foo + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 40 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ ] - Kind: S_PROC_ID_END - ScopeEndSym: + ScopeEndSym: {} - !Lines CodeSize: 15 Flags: [ ] @@ -203,7 +250,7 @@ LineStart: 4 IsStatement: false EndDelta: 0 - Columns: + Columns: [] Relocations: - VirtualAddress: 44 SymbolName: foo @@ -211,10 +258,10 @@ - VirtualAddress: 48 SymbolName: foo Type: IMAGE_REL_AMD64_SECTION - - VirtualAddress: 68 + - VirtualAddress: 100 SymbolName: foo Type: IMAGE_REL_AMD64_SECREL - - VirtualAddress: 72 + - VirtualAddress: 104 SymbolName: foo Type: IMAGE_REL_AMD64_SECTION - Name: .pdata @@ -229,7 +276,7 @@ SymbolName: foo Type: IMAGE_REL_AMD64_ADDR32NB - VirtualAddress: 8 - SymbolName: .xdata + SymbolTableIndex: 11 Type: IMAGE_REL_AMD64_ADDR32NB symbols: - Name: .text @@ -301,7 +348,7 @@ StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: .xdata Value: 0 - SectionNumber: 10 + SectionNumber: 11 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC @@ -331,22 +378,22 @@ ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: - Length: 264 + Length: 396 NumberOfRelocations: 4 NumberOfLinenumbers: 0 - CheckSum: 2204933783 + CheckSum: 692696726 Number: 7 - Name: '.debug$S' Value: 0 - SectionNumber: 11 + SectionNumber: 12 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: - Length: 116 + Length: 148 NumberOfRelocations: 4 NumberOfLinenumbers: 0 - CheckSum: 2691661839 + CheckSum: 1236081121 Number: 5 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE - Name: '.debug$T' @@ -356,10 +403,10 @@ ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: - Length: 80 + Length: 1876 NumberOfRelocations: 0 NumberOfLinenumbers: 0 - CheckSum: 3541780432 + CheckSum: 2406155785 Number: 8 - Name: .pdata Value: 0 @@ -375,7 +422,7 @@ Number: 9 - Name: .pdata Value: 0 - SectionNumber: 12 + SectionNumber: 13 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC @@ -386,6 +433,24 @@ CheckSum: 3642757804 Number: 5 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE + - Name: .llvm_addrsig + Value: 0 + SectionNumber: 10 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 2 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2582217811 + Number: 10 + - Name: '@feat.00' + Value: 0 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC - Name: main Value: 0 SectionNumber: 1 @@ -398,4 +463,11 @@ SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .file + Value: 0 + SectionNumber: -2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_FILE + File: pdb_lines_1.c ... diff --git a/lld/test/COFF/Inputs/pdb_lines_2_relative.yaml b/lld/test/COFF/Inputs/pdb_lines_2_relative.yaml --- a/lld/test/COFF/Inputs/pdb_lines_2_relative.yaml +++ b/lld/test/COFF/Inputs/pdb_lines_2_relative.yaml @@ -15,6 +15,7 @@ Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] Alignment: 4 SectionData: '' + SizeOfRawData: 0 - Name: .drectve Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] Alignment: 1 @@ -22,7 +23,7 @@ - Name: '.debug$S' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 4 - SectionData: 04000000F10000002F0000002D003C1100000000D0000700000000000000581B000000000000636C616E672076657273696F6E20372E302E30200000F10000002F0000002900471100000000000000000000000001000000000000000000000002100000000000000000006261720002004F1100F2000000200000000000000000000000010000000000000001000000140000000000000002000000F400000018000000010000001001DF91CB3A2B8D917486574BB50CAC4CC70000F300000014000000002E5C7064625F6C696E65735F322E6300000000 + SectionData: 04000000F10000008400000082003C1100000000D0000B00000000000000F82A000000000000636C616E672076657273696F6E2031312E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A6563742E6769742036373830626534633633653538323436366133356437363434633335653039626138356434663637290000F1000000500000002A004711000000000000000000000000010000000000000000000000021000000000000000000062617200001E0012100000000000000000000000000000000000000000000000000000000002004F11F2000000200000000000000000000000010000000000000001000000140000000000000002000000F4000000180000000100000010014CC58B73BFD5AB52F87CFB3C604BB2880000F300000014000000002E5C7064625F6C696E65735F322E6300000000F10000000800000006004C1107100000 Subsections: - !Symbols Records: @@ -30,15 +31,15 @@ Compile3Sym: Flags: [ ] Machine: X64 - FrontendMajor: 7 + FrontendMajor: 11 FrontendMinor: 0 FrontendBuild: 0 FrontendQFE: 0 - BackendMajor: 7000 + BackendMajor: 11000 BackendMinor: 0 BackendBuild: 0 BackendQFE: 0 - Version: 'clang version 7.0.0 ' + Version: 'clang version 11.0.0 (https://github.com/llvm/llvm-project.git 6780be4c63e582466a35d7644c35e09ba85d4f67)' - !Symbols Records: - Kind: S_GPROC32_ID @@ -49,8 +50,17 @@ FunctionType: 4098 Flags: [ ] DisplayName: bar + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 0 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ ] - Kind: S_PROC_ID_END - ScopeEndSym: + ScopeEndSym: {} - !Lines CodeSize: 1 Flags: [ ] @@ -63,35 +73,40 @@ LineStart: 2 IsStatement: false EndDelta: 0 - Columns: + Columns: [] - !FileChecksums Checksums: - FileName: '.\pdb_lines_2.c' Kind: MD5 - Checksum: DF91CB3A2B8D917486574BB50CAC4CC7 + Checksum: 4CC58B73BFD5AB52F87CFB3C604BB288 - !StringTable Strings: - '.\pdb_lines_2.c' - '' - '' - '' + - !Symbols + Records: + - Kind: S_BUILDINFO + BuildInfoSym: + BuildId: 4103 Relocations: - - VirtualAddress: 100 + - VirtualAddress: 184 SymbolName: bar Type: IMAGE_REL_AMD64_SECREL - - VirtualAddress: 104 + - VirtualAddress: 188 SymbolName: bar Type: IMAGE_REL_AMD64_SECTION - - VirtualAddress: 124 + - VirtualAddress: 240 SymbolName: bar Type: IMAGE_REL_AMD64_SECREL - - VirtualAddress: 128 + - VirtualAddress: 244 SymbolName: bar Type: IMAGE_REL_AMD64_SECTION - Name: '.debug$T' Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] Alignment: 4 - SectionData: 0400000006000112000000000E0008100300000000000000001000000E000116000000000110000062617200 + SectionData: 0400000006000112000000000E0008100300000000000000001000000E0001160000000001100000626172000A000516000000002E00F2F116000516000000007064625F6C696E65735F322E6300F2F13A00051600000000443A5C6C6C766D2D70726F6A6563745C6275696C646E696E6A614465624D5356435C62696E5C636C616E672D636C2E65786500F186060516000000002D636331202D747269706C65207838365F36342D70632D77696E646F77732D6D73766331392E32362E3238383036202D656D69742D6F626A202D6D72656C61782D616C6C202D6D696E6372656D656E74616C2D6C696E6B65722D636F6D70617469626C65202D64697361626C652D66726565202D6D61696E2D66696C652D6E616D65202D6D72656C6F636174696F6E2D6D6F64656C20706963202D7069632D6C6576656C2032202D6D7468726561642D6D6F64656C20706F736978202D6D6672616D652D706F696E7465723D6E6F6E65202D72656C617865642D616C696173696E67202D666D6174682D6572726E6F202D666E6F2D726F756E64696E672D6D617468202D6D636F6E7374727563746F722D616C6961736573202D6D756E77696E642D7461626C6573202D7461726765742D637075207838362D3634202D6D6C6C766D202D7838362D61736D2D73796E7461783D696E74656C202D445F4D54202D666C746F2D7669736962696C6974792D7075626C69632D737464202D2D646570656E64656E742D6C69623D6C6962636D74202D2D646570656E64656E742D6C69623D6F6C646E616D6573202D737461636B2D70726F746563746F722032202D666D732D766F6C6174696C65202D66646961676E6F73746963732D666F726D6174206D737663202D67636F646576696577202D64656275672D696E666F2D6B696E643D6C696D69746564202D7265736F757263652D6469722022443A5C6C6C766D2D70726F6A6563745C6275696C646E696E6A614465624D5356435C6C69625C636C616E675C31312E302E3022202D696E7465726E616C2D6973797374656D2022443A5C6C6C766D2D70726F6A6563745C6275696C646E696E6A614465624D5356435C6C69625C636C616E675C31312E302E305C696E636C75646522202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C4D6963726F736F66742056697375616C2053747564696F5C323031395C50726F66657373696F6E616C5C56435C546F6F6C735C4D5356435C31342E32362E32383830315C41544C4D46435C696E636C75646522202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C4D6963726F736F66742056697375616C2053747564696F5C323031395C50726F66657373696F6E616C5C56435C546F6F6C735C4D5356435C31342E32362E32383830315C696E636C75646522202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C4E4554465853444B5C342E385C696E636C7564655C756D22202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C7563727422202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C73686172656422202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C756D22202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C77696E727422202D696E7465726E616C2D6973797374656D2022433A5C50726F6772616D2046696C65732028783836295C57696E646F7773204B6974735C31305C696E636C7564655C31302E302E31383336322E305C63707077696E727422202D6664656275672D636F6D70696C6174696F6E2D646972202E202D666572726F722D6C696D6974203139202D666D6573736167652D6C656E6774683D313230202D666E6F2D7573652D6378612D617465786974202D666D732D657874656E73696F6E73202D666D732D636F6D7061746962696C697479202D666D732D636F6D7061746962696C6974792D76657273696F6E3D31392E32362E3238383036202D6664656C617965642D74656D706C6174652D70617273696E67202D66636F6C6F722D646961676E6F7374696373202D6661646472736967202D6F207064625F6C696E65735F322E6F626A202D78206300F2F11A00031605000310000005100000041000000000000006100000F2F1 Types: - Kind: LF_ARGLIST ArgList: @@ -108,6 +123,29 @@ ParentScope: 0 FunctionType: 4097 Name: bar + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: . + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: pdb_lines_2.c + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: 'D:\llvm-project\buildninjaDebMSVC\bin\clang-cl.exe' + - Kind: LF_STRING_ID + StringId: + Id: 0 + String: '-cc1 -triple x86_64-pc-windows-msvc19.26.28806 -emit-obj -mrelax-all -mincremental-linker-compatible -disable-free -main-file-name -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -mllvm -x86-asm-syntax=intel -D_MT -flto-visibility-public-std --dependent-lib=libcmt --dependent-lib=oldnames -stack-protector 2 -fms-volatile -fdiagnostics-format msvc -gcodeview -debug-info-kind=limited -resource-dir "D:\llvm-project\buildninjaDebMSVC\lib\clang\11.0.0" -internal-isystem "D:\llvm-project\buildninjaDebMSVC\lib\clang\11.0.0\include" -internal-isystem "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.26.28801\ATLMFC\include" -internal-isystem "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.26.28801\include" -internal-isystem "C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt" -internal-isystem "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt" -fdebug-compilation-dir . -ferror-limit 19 -fmessage-length=120 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.26.28806 -fdelayed-template-parsing -fcolor-diagnostics -faddrsig -o pdb_lines_2.obj -x c' + - Kind: LF_BUILDINFO + BuildInfo: + ArgIndices: [ 4099, 4101, 4100, 0, 4102 ] + - Name: .llvm_addrsig + Characteristics: [ IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: '' symbols: - Name: .text Value: 0 @@ -164,10 +202,10 @@ ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: - Length: 216 + Length: 348 NumberOfRelocations: 4 NumberOfLinenumbers: 0 - CheckSum: 2383431754 + CheckSum: 3457657876 Number: 5 - Name: '.debug$T' Value: 0 @@ -176,15 +214,40 @@ ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_STATIC SectionDefinition: - Length: 44 + Length: 1840 NumberOfRelocations: 0 NumberOfLinenumbers: 0 - CheckSum: 179171995 + CheckSum: 1127805914 Number: 6 + - Name: .llvm_addrsig + Value: 0 + SectionNumber: 7 + 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: 7 + - Name: '@feat.00' + Value: 0 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC - Name: bar Value: 0 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .file + Value: 0 + SectionNumber: -2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_FILE + File: pdb_lines_2.c ... diff --git a/lld/test/COFF/pdb-relative-source-lines.test b/lld/test/COFF/pdb-relative-source-lines.test --- a/lld/test/COFF/pdb-relative-source-lines.test +++ b/lld/test/COFF/pdb-relative-source-lines.test @@ -15,7 +15,7 @@ void bar(void) { } -$ clang-cl -Xclang -fdebug-compilation-dir -Xclang . -c -Z7 pdb_lines*.c +$ clang-cl -fdebug-compilation-dir . -c -Z7 pdb_lines*.c /pdbsourcepath: only sets the directory that relative paths are considered relative to, so this test needs to pass relative paths to lld-link for: @@ -33,9 +33,9 @@ RUN: yaml2obj %S/Inputs/pdb_lines_1_relative.yaml -o %t/pdb_lines_1_relative.obj RUN: yaml2obj %S/Inputs/pdb_lines_2_relative.yaml -o %t/pdb_lines_2_relative.obj RUN: ./lld-link -debug "-pdbsourcepath:c:\src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj -RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck %s +RUN: llvm-pdbutil pdb2yaml -ipi-stream -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck %s RUN: ./lld-link -debug "-pdbsourcepath:/usr/src" -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj -RUN: llvm-pdbutil pdb2yaml -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck --check-prefix=POSIX %s +RUN: llvm-pdbutil pdb2yaml -ipi-stream -modules -module-files -module-syms -subsections=lines,fc %t/out.pdb | FileCheck --check-prefix=POSIX %s CHECK-LABEL: - Module: 'c:\src\pdb_lines_1_relative.obj' CHECK-NEXT: ObjFile: 'c:\src\pdb_lines_1_relative.obj' @@ -70,7 +70,20 @@ CHECK-NEXT: - cmd CHECK-NEXT: - '-debug -pdbsourcepath:c:\src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj' - +CHECK-LABEL: IpiStream: +CHECK: - Kind: LF_STRING_ID +CHECK-NEXT: StringId: +CHECK-NEXT: Id: 0 +CHECK-NEXT: String: 'c:\src' +CHECK-NEXT: - Kind: LF_STRING_ID +CHECK-NEXT: StringId: +CHECK-NEXT: Id: 0 +CHECK-NEXT: String: pdb_lines_1.c +CHECK-NEXT: - Kind: LF_STRING_ID +CHECK-NEXT: StringId: +CHECK-NEXT: Id: 0 +CHECK-NEXT: String: 'D:\llvm-project\buildninjaDebMSVC\bin\clang-cl.exe' + POSIX-LABEL: - Module: '/usr/src/pdb_lines_1_relative.obj' POSIX-NEXT: ObjFile: '/usr/src/pdb_lines_1_relative.obj' POSIX: SourceFiles: @@ -103,3 +116,17 @@ POSIX-NEXT: - '/usr/src/out.pdb' POSIX-NEXT: - cmd POSIX-NEXT: - '-debug -pdbsourcepath:/usr/src -entry:main -nodefaultlib -out:out.exe -pdb:out.pdb pdb_lines_1_relative.obj pdb_lines_2_relative.obj' + +POSIX-LABEL: IpiStream: +POSIX: - Kind: LF_STRING_ID +POSIX-NEXT: StringId: +POSIX-NEXT: Id: 0 +POSIX-NEXT: String: '/usr/src' +POSIX-NEXT: - Kind: LF_STRING_ID +POSIX-NEXT: StringId: +POSIX-NEXT: Id: 0 +POSIX-NEXT: String: pdb_lines_1.c +POSIX-NEXT: - Kind: LF_STRING_ID +POSIX-NEXT: StringId: +POSIX-NEXT: Id: 0 +POSIX-NEXT: String: 'D:\llvm-project\buildninjaDebMSVC\bin\clang-cl.exe' diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h --- a/llvm/include/llvm/ADT/StringExtras.h +++ b/llvm/include/llvm/ADT/StringExtras.h @@ -48,6 +48,13 @@ return Result; } +inline std::vector toStringRefArray(ArrayRef Strings) { + std::vector Result; + for (auto Str : Strings) + Result.push_back(Str); + return Result; +} + /// Construct a string ref from a boolean. inline StringRef toStringRef(bool B) { return StringRef(B ? "true" : "false"); } diff --git a/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h --- a/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h +++ b/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h @@ -38,7 +38,7 @@ explicit AppendingTypeTableBuilder(BumpPtrAllocator &Storage); ~AppendingTypeTableBuilder(); - // TypeTableCollection overrides + // TypeCollection overrides Optional getFirst() override; Optional getNext(TypeIndex Prev) override; CVType getType(TypeIndex Index) override; @@ -46,6 +46,7 @@ bool contains(TypeIndex Index) override; uint32_t size() override; uint32_t capacity() override; + bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override; // public interface void reset(); diff --git a/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h --- a/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h +++ b/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h @@ -50,7 +50,7 @@ explicit GlobalTypeTableBuilder(BumpPtrAllocator &Storage); ~GlobalTypeTableBuilder(); - // TypeTableCollection overrides + // TypeCollection overrides Optional getFirst() override; Optional getNext(TypeIndex Prev) override; CVType getType(TypeIndex Index) override; @@ -58,6 +58,7 @@ bool contains(TypeIndex Index) override; uint32_t size() override; uint32_t capacity() override; + bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override; // public interface void reset(); diff --git a/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h --- a/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h +++ b/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h @@ -79,6 +79,7 @@ uint32_t capacity() override; Optional getFirst() override; Optional getNext(TypeIndex Prev) override; + bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override; private: Error ensureTypeExists(TypeIndex Index); diff --git a/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h b/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h --- a/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h +++ b/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h @@ -47,7 +47,7 @@ explicit MergingTypeTableBuilder(BumpPtrAllocator &Storage); ~MergingTypeTableBuilder(); - // TypeTableCollection overrides + // TypeCollection overrides Optional getFirst() override; Optional getNext(TypeIndex Prev) override; CVType getType(TypeIndex Index) override; @@ -55,6 +55,7 @@ bool contains(TypeIndex Index) override; uint32_t size() override; uint32_t capacity() override; + bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override; // public interface void reset(); diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h b/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h --- a/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h @@ -30,6 +30,7 @@ virtual bool contains(TypeIndex Index) = 0; virtual uint32_t size() = 0; virtual uint32_t capacity() = 0; + virtual bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) = 0; template void ForEachRecord(TFunc Func) { Optional Next = getFirst(); diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h b/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h --- a/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h @@ -29,6 +29,7 @@ bool contains(TypeIndex Index) override; uint32_t size() override; uint32_t capacity() override; + bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override; private: BumpPtrAllocator Allocator; diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -9,6 +9,7 @@ #ifndef LLVM_MC_MCTARGETOPTIONS_H #define LLVM_MC_MCTARGETOPTIONS_H +#include "llvm/ADT/ArrayRef.h" #include #include @@ -59,6 +60,9 @@ std::string AssemblyLanguage; std::string SplitDwarfFile; + const char *Argv0 = nullptr; + ArrayRef CommandLineArgs; + /// Additional paths to search for `.include` directives when using the /// integrated assembler. std::vector IASSearchPaths; diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -77,6 +77,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -831,6 +832,24 @@ return TypeTable.writeLeafType(SIR); } +static std::string flattenCommandLine(ArrayRef Args, + StringRef MainFilename) { + std::vector Vec = toStringRefArray(Args); + // The command-line shall not contain the file to compile. + erase_if(Vec, [&](StringRef Arg) { + return Arg.data() == nullptr || Arg == MainFilename; + }); +#if defined(_WIN32) + std::string FlatCmdLine = + llvm::sys::flattenWindowsCommandLine(makeArrayRef(Vec)); +#else + std::string FlatCmdLine = llvm::join(Vec, " "); +#endif + // Trim whitespaces at the end + FlatCmdLine.erase(FlatCmdLine.find_last_not_of(' ') + 1); + return FlatCmdLine; +} + void CodeViewDebug::emitBuildInfo() { // First, make LF_BUILDINFO. It's a sequence of strings with various bits of // build info. The known prefix is: @@ -851,8 +870,15 @@ getStringIdTypeIdx(TypeTable, MainSourceFile->getDirectory()); BuildInfoArgs[BuildInfoRecord::SourceFile] = getStringIdTypeIdx(TypeTable, MainSourceFile->getFilename()); - // FIXME: Path to compiler and command line. PDB is intentionally blank unless - // we implement /Zi type servers. + if (!StringRef(Asm->TM.Options.MCOptions.Argv0).empty() && + !Asm->TM.Options.MCOptions.CommandLineArgs.empty()) { + BuildInfoArgs[BuildInfoRecord::BuildTool] = + getStringIdTypeIdx(TypeTable, Asm->TM.Options.MCOptions.Argv0); + BuildInfoArgs[BuildInfoRecord::CommandLine] = getStringIdTypeIdx( + TypeTable, flattenCommandLine(Asm->TM.Options.MCOptions.CommandLineArgs, + MainSourceFile->getFilename())); + } + // FIXME: PDB is intentionally blank unless we implement /Zi type servers. BuildInfoRecord BIR(BuildInfoArgs); TypeIndex BuildInfoIndex = TypeTable.writeLeafType(BIR); diff --git a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp --- a/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp @@ -74,12 +74,17 @@ void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); } +static ArrayRef stabilize(BumpPtrAllocator &RecordStorage, + ArrayRef Record) { + uint8_t *Stable = RecordStorage.Allocate(Record.size()); + memcpy(Stable, Record.data(), Record.size()); + return ArrayRef(Stable, Record.size()); +} + TypeIndex AppendingTypeTableBuilder::insertRecordBytes(ArrayRef &Record) { TypeIndex NewTI = nextTypeIndex(); - uint8_t *Stable = RecordStorage.Allocate(Record.size()); - memcpy(Stable, Record.data(), Record.size()); - Record = ArrayRef(Stable, Record.size()); + Record = stabilize(RecordStorage, Record); SeenRecords.push_back(Record); return NewTI; } @@ -93,3 +98,15 @@ 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 Record = Data.data(); + if (Stabilize) + Record = stabilize(RecordStorage, Record); + SeenRecords[Index.toArrayIndex()] = Record; + return true; +} diff --git a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp --- a/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp @@ -84,6 +84,13 @@ SeenRecords.clear(); } +static inline ArrayRef stabilize(BumpPtrAllocator &Alloc, + ArrayRef Data) { + uint8_t *Stable = Alloc.Allocate(Data.size()); + memcpy(Stable, Data.data(), Data.size()); + return makeArrayRef(Stable, Data.size()); +} + TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef Record) { GloballyHashedType GHT = GloballyHashedType::hashType(Record, SeenHashes, SeenHashes); @@ -104,3 +111,30 @@ 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 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 --- a/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ b/llvm/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -277,3 +277,8 @@ ++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 --- a/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp +++ b/llvm/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp @@ -123,3 +123,30 @@ 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 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/TypeTableCollection.cpp b/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp --- a/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeTableCollection.cpp @@ -58,3 +58,8 @@ 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"); +}