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 @@ -227,6 +227,9 @@ /// Output filename for the split debug info, not used in the skeleton CU. std::string SplitDwarfOutput; + /// Output filename used in the COFF debug information. + std::string ObjectFilenameForDebug; + /// The name of the relocation model to use. llvm::Reloc::Model RelocationModel; diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h --- a/clang/include/clang/Driver/Job.h +++ b/clang/include/clang/Driver/Job.h @@ -204,6 +204,10 @@ /// from the parent process will be used. virtual void setEnvironment(llvm::ArrayRef NewEnvironment); + void replaceArguments(llvm::opt::ArgStringList List) { + Arguments = std::move(List); + } + const char *getExecutable() const { return Executable; } const llvm::opt::ArgStringList &getArguments() const { return Arguments; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3802,6 +3802,11 @@ CC1Option, CC1AsOption, FC1Option, FlangOption]>, HelpText<"Write output to ">, MetaVarName<"">, MarshallingInfoString>; +def object_file_name_EQ : Joined<["-"], "object-file-name=">, Flags<[CC1Option, CC1AsOption, CoreOption]>, + HelpText<"Set the output for debug infos">, MetaVarName<"">, + MarshallingInfoString>; +def object_file_name : Separate<["-"], "object-file-name">, Flags<[CC1Option, CC1AsOption, CoreOption]>, + Alias; def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">; def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group, Flags<[CC1Option]>, 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 @@ -646,6 +646,7 @@ Options.MCOptions.Argv0 = CodeGenOpts.Argv0; Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs; Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf; + Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug; return true; } @@ -1583,7 +1584,8 @@ return; auto AddStream = [&](size_t Task) { - return std::make_unique(std::move(OS)); + return std::make_unique(std::move(OS), + CGOpts.ObjectFilenameForDebug); }; lto::Config Conf; if (CGOpts.SaveTempsFilePrefix != "") { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -625,8 +625,9 @@ } /// Add a CC1 option to specify the debug compilation directory. -static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs, - const llvm::vfs::FileSystem &VFS) { +static const char *addDebugCompDirArg(const ArgList &Args, + ArgStringList &CmdArgs, + const llvm::vfs::FileSystem &VFS) { if (Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ, options::OPT_fdebug_compilation_dir_EQ)) { if (A->getOption().matches(options::OPT_ffile_compilation_dir_EQ)) @@ -638,6 +639,31 @@ VFS.getCurrentWorkingDirectory()) { CmdArgs.push_back(Args.MakeArgString("-fdebug-compilation-dir=" + *CWD)); } + StringRef Path(CmdArgs.back()); + return Path.substr(Path.find('=') + 1).data(); +} + +static void addDebugObjectName(const ArgList &Args, ArgStringList &CmdArgs, + const char *DebugCompilationDir, + const char *OutputFileName) { + // No need to generate a value for -object-file-name if it was provided. + for (auto *Arg : Args.filtered(options::OPT_Xclang)) + if (StringRef(Arg->getValue()).startswith("-object-file-name")) + return; + + if (Args.hasArg(options::OPT_object_file_name_EQ)) + return; + + SmallString<128> ObjFileNameForDebug(OutputFileName); + if (ObjFileNameForDebug != "-" && + !llvm::sys::path::is_absolute(ObjFileNameForDebug) && + (!DebugCompilationDir || + llvm::sys::path::is_absolute(DebugCompilationDir))) { + // Make the path absolute in the debug infos like MSVC does. + llvm::sys::fs::make_absolute(ObjFileNameForDebug); + } + CmdArgs.push_back( + Args.MakeArgString(Twine("-object-file-name=") + ObjFileNameForDebug)); } /// Add a CC1 and CC1AS option to specify the debug file path prefix map. @@ -5649,7 +5675,8 @@ CmdArgs.push_back("-fno-autolink"); // Add in -fdebug-compilation-dir if necessary. - addDebugCompDirArg(Args, CmdArgs, D.getVFS()); + const char *DebugCompilationDir = + addDebugCompDirArg(Args, CmdArgs, D.getVFS()); addDebugPrefixMapArg(D, Args, CmdArgs); @@ -7021,6 +7048,11 @@ CmdArgs.push_back(Args.MakeArgString(Str)); } + // Add the output path to the object file for CodeView debug infos. + if (EmitCodeView && Output.isFilename()) + addDebugObjectName(Args, CmdArgs, DebugCompilationDir, + Output.getFilename()); + // Add the "-o out -x type src.c" flags last. This is done primarily to make // the -cc1 command easier to edit when reproducing compiler crashes. if (Output.getType() == types::TY_Dependencies) { @@ -7638,11 +7670,14 @@ Args.AddAllArgs(CmdArgs, options::OPT_I_Group); // Determine the original source input. - const Action *SourceAction = &JA; - while (SourceAction->getKind() != Action::InputClass) { - assert(!SourceAction->getInputs().empty() && "unexpected root action!"); - SourceAction = SourceAction->getInputs()[0]; - } + auto FindSource = [](const Action *S) -> const Action * { + while (S->getKind() != Action::InputClass) { + assert(!S->getInputs().empty() && "unexpected root action!"); + S = S->getInputs()[0]; + } + return S; + }; + const Action *SourceAction = FindSource(&JA); // Forward -g and handle debug info related flags, assuming we are dealing // with an actual assembly file. @@ -7661,6 +7696,10 @@ codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo; + // Add the -fdebug-compilation-dir flag if needed. + const char *DebugCompilationDir = + addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS()); + if (SourceAction->getType() == types::TY_Asm || SourceAction->getType() == types::TY_PP_Asm) { // You might think that it would be ok to set DebugInfoKind outside of @@ -7669,8 +7708,6 @@ // and it's not clear whether that test is just overly restrictive. DebugInfoKind = (WantDebug ? codegenoptions::DebugInfoConstructor : codegenoptions::NoDebugInfo); - // Add the -fdebug-compilation-dir flag if needed. - addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS()); addDebugPrefixMapArg(getToolChain().getDriver(), Args, CmdArgs); @@ -7781,6 +7818,29 @@ Args.AddAllArgs(CmdArgs, options::OPT_mllvm); + if (DebugInfoKind > codegenoptions::NoDebugInfo && Output.isFilename()) + addDebugObjectName(Args, CmdArgs, DebugCompilationDir, + Output.getFilename()); + + // Fixup any previous commands that use -object-file-name because when we + // generated them, the final .obj name wasn't yet known. + for (Command &J : C.getJobs()) { + if (SourceAction != FindSource(&J.getSource())) + continue; + auto &JArgs = J.getArguments(); + for (unsigned I = 0; I < JArgs.size(); ++I) { + if (StringRef(JArgs[I]).startswith("-object-file-name=") && + Output.isFilename()) { + ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I); + addDebugObjectName(Args, NewArgs, DebugCompilationDir, + Output.getFilename()); + NewArgs.append(JArgs.begin() + I + 1, JArgs.end()); + J.replaceArguments(NewArgs); + break; + } + } + } + assert(Output.isFilename() && "Unexpected lipo output."); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -126,6 +126,7 @@ llvm-nm llvm-objcopy llvm-objdump + llvm-pdbutil llvm-profdata llvm-rc llvm-readelf diff --git a/clang/test/CodeGenCXX/debug-info-objname.cpp b/clang/test/CodeGenCXX/debug-info-objname.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-objname.cpp @@ -0,0 +1,40 @@ +// RUN: cp %s %T/debug-info-objname.cpp +// RUN: cd %T + +// No output file provided, input file is relative, we emit an absolute path (MSVC behavior). +// RUN: %clang_cl /c /Z7 -nostdinc debug-info-objname.cpp +// RUN: llvm-pdbutil dump -all debug-info-objname.obj | FileCheck %s --check-prefix=ABSOLUTE + +// No output file provided, input file is absolute, we emit an absolute path (MSVC behavior). +// RUN: %clang_cl /c /Z7 -nostdinc -- %T/debug-info-objname.cpp +// RUN: llvm-pdbutil dump -all debug-info-objname.obj | FileCheck %s --check-prefix=ABSOLUTE + +// The output file is provided as an absolute path, we emit an absolute path. +// RUN: %clang_cl /c /Z7 -nostdinc /Fo%T/debug-info-objname.obj -- %T/debug-info-objname.cpp +// RUN: llvm-pdbutil dump -all debug-info-objname.obj | FileCheck %s --check-prefix=ABSOLUTE + +// The output file is provided as relative path, -working-dir is provided, we emit an absolute path. +// RUN: %clang_cl /c /Z7 -nostdinc -working-dir=%T debug-info-objname.cpp +// RUN: llvm-pdbutil dump -all debug-info-objname.obj | FileCheck %s --check-prefix=ABSOLUTE + +// The input file name is relative and we specify -fdebug-compilation-dir, we emit a relative path. +// RUN: %clang_cl /c /Z7 -nostdinc -fdebug-compilation-dir=. debug-info-objname.cpp +// RUN: llvm-pdbutil dump -all debug-info-objname.obj | FileCheck %s --check-prefix=RELATIVE + +// Ensure /FA emits an .asm file which contains the path to the final .obj, not the .asm +// RUN: %clang_cl /c /Z7 -nostdinc -fdebug-compilation-dir=. /FA debug-info-objname.cpp +// RUN: cat debug-info-objname.asm | FileCheck %s --check-prefix=ASM + +// Same thing for -save-temps +// RUN: %clang_cl /c /Z7 -nostdinc -fdebug-compilation-dir=. /clang:-save-temps debug-info-objname.cpp +// RUN: cat debug-info-objname.asm | FileCheck %s --check-prefix=ASM + +int main() { + return 1; +} + +// ABSOLUTE: S_OBJNAME [size = {{[0-9]+}}] sig=0, `{{.+}}debug-info-objname.obj` +// RELATIVE: S_OBJNAME [size = {{[0-9]+}}] sig=0, `debug-info-objname.obj` +// ASM: Record kind: S_OBJNAME +// ASM-NEXT: .long 0 +// ASM-NEXT: .asciz "debug-info-objname.obj" 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 @@ -62,6 +62,7 @@ std::string ABIName; std::string AssemblyLanguage; std::string SplitDwarfFile; + std::string COFFOutputFilename; const char *Argv0 = nullptr; ArrayRef CommandLineArgs; diff --git a/llvm/include/llvm/Support/Caching.h b/llvm/include/llvm/Support/Caching.h --- a/llvm/include/llvm/Support/Caching.h +++ b/llvm/include/llvm/Support/Caching.h @@ -27,8 +27,11 @@ /// that can be done by deriving from this class and overriding the destructor. class CachedFileStream { public: - CachedFileStream(std::unique_ptr OS) : OS(std::move(OS)) {} + CachedFileStream(std::unique_ptr OS, + std::string OSPath = "") + : OS(std::move(OS)), ObjectPathName(OSPath) {} std::unique_ptr OS; + std::string ObjectPathName; virtual ~CachedFileStream() = default; }; diff --git a/llvm/include/llvm/Support/ToolOutputFile.h b/llvm/include/llvm/Support/ToolOutputFile.h --- a/llvm/include/llvm/Support/ToolOutputFile.h +++ b/llvm/include/llvm/Support/ToolOutputFile.h @@ -29,9 +29,10 @@ /// raw_fd_ostream is destructed. It installs cleanups in its constructor and /// uninstalls them in its destructor. class CleanupInstaller { + public: /// The name of the file. std::string Filename; - public: + /// The flag which indicates whether we should not delete the file. bool Keep; @@ -64,6 +65,8 @@ /// Indicate that the tool's job wrt this output file has been successful and /// the file should not be deleted. void keep() { Installer.Keep = true; } + + const std::string &outputFilename() { return Installer.Filename; } }; } // end llvm namespace diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -418,6 +418,11 @@ /// Machine level options. MCTargetOptions MCOptions; + + /// Stores the filename/path of the final .o/.obj file, to be written in the + /// debug information. This is used for emitting the CodeView S_OBJNAME + /// record. + std::string ObjectFilenameForDebug; }; } // End llvm namespace diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -302,6 +302,8 @@ void emitTypeGlobalHashes(); + void emitObjName(); + void emitCompilerInformation(); void emitBuildInfo(); 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 @@ -649,6 +649,7 @@ switchToDebugSectionForSymbol(nullptr); MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols); + emitObjName(); emitCompilerInformation(); endCVSubsection(CompilerInfo); @@ -784,6 +785,29 @@ } } +void CodeViewDebug::emitObjName() { + MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_OBJNAME); + + StringRef PathRef(Asm->TM.Options.ObjectFilenameForDebug); + llvm::SmallString<256> PathStore(PathRef); + + if (PathRef.empty() || PathRef == "-") { + // Don't emit the filename if we're writing to stdout or to /dev/null. + PathRef = {}; + } else { + llvm::sys::path::remove_dots(PathStore, /*remove_dot_dot=*/true); + PathRef = PathStore; + } + + OS.AddComment("Signature"); + OS.emitIntValue(0, 4); + + OS.AddComment("Object name"); + emitNullTerminatedSymbolName(OS, PathRef); + + endSymbolRecord(CompilerEnd); +} + namespace { struct Version { int Part[4]; diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -412,6 +412,8 @@ if (Error Err = StreamOrErr.takeError()) report_fatal_error(std::move(Err)); std::unique_ptr &Stream = *StreamOrErr; + TM->Options.ObjectFilenameForDebug = Stream->ObjectPathName; + legacy::PassManager CodeGenPasses; CodeGenPasses.add( createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex)); diff --git a/llvm/lib/Support/Caching.cpp b/llvm/lib/Support/Caching.cpp --- a/llvm/lib/Support/Caching.cpp +++ b/llvm/lib/Support/Caching.cpp @@ -79,14 +79,13 @@ struct CacheStream : CachedFileStream { AddBufferFn AddBuffer; sys::fs::TempFile TempFile; - std::string EntryPath; unsigned Task; CacheStream(std::unique_ptr OS, AddBufferFn AddBuffer, sys::fs::TempFile TempFile, std::string EntryPath, unsigned Task) - : CachedFileStream(std::move(OS)), AddBuffer(std::move(AddBuffer)), - TempFile(std::move(TempFile)), EntryPath(std::move(EntryPath)), + : CachedFileStream(std::move(OS), std::move(EntryPath)), + AddBuffer(std::move(AddBuffer)), TempFile(std::move(TempFile)), Task(Task) {} ~CacheStream() { @@ -99,7 +98,7 @@ // Open the file first to avoid racing with a cache pruner. ErrorOr> MBOrErr = MemoryBuffer::getOpenFile( - sys::fs::convertFDToNativeFile(TempFile.FD), EntryPath, + sys::fs::convertFDToNativeFile(TempFile.FD), ObjectPathName, /*FileSize=*/-1, /*RequiresNullTerminator=*/false); if (!MBOrErr) report_fatal_error(Twine("Failed to open new cache file ") + @@ -115,14 +114,14 @@ // AddBuffer a copy of the bytes we wrote in that case. We do this // instead of just using the existing file, because the pruner might // delete the file before we get a chance to use it. - Error E = TempFile.keep(EntryPath); + Error E = TempFile.keep(ObjectPathName); E = handleErrors(std::move(E), [&](const ECError &E) -> Error { std::error_code EC = E.convertToErrorCode(); if (EC != errc::permission_denied) return errorCodeToError(EC); auto MBCopy = MemoryBuffer::getMemBufferCopy((*MBOrErr)->getBuffer(), - EntryPath); + ObjectPathName); MBOrErr = std::move(MBCopy); // FIXME: should we consume the discard error? @@ -133,7 +132,7 @@ if (E) report_fatal_error(Twine("Failed to rename temporary file ") + - TempFile.TmpName + " to " + EntryPath + ": " + + TempFile.TmpName + " to " + ObjectPathName + ": " + toString(std::move(E)) + "\n"); AddBuffer(Task, std::move(*MBOrErr)); diff --git a/llvm/test/DebugInfo/COFF/globals.ll b/llvm/test/DebugInfo/COFF/globals.ll --- a/llvm/test/DebugInfo/COFF/globals.ll +++ b/llvm/test/DebugInfo/COFF/globals.ll @@ -1,7 +1,9 @@ ; RUN: llc < %s | FileCheck %s --check-prefix=ASM ; RUN: llc < %s -filetype=obj | llvm-readobj - --codeview | FileCheck %s --check-prefix=OBJ ; RUN: llc < %s | llvm-mc -filetype=obj --triple=x86_64-windows | llvm-readobj - --codeview | FileCheck %s --check-prefix=OBJ -; RUN: llc < %s -filetype=obj | obj2yaml | FileCheck %s --check-prefix=YAML +; RUN: llc < %s -filetype=obj | obj2yaml | FileCheck %s --check-prefixes=YAML,YAML-STDOUT +; RUN: llc < %s -filetype=obj -o %t +; RUN: obj2yaml < %t | FileCheck %s --check-prefixes=YAML,YAML-FILE ; C++ source to regenerate: ; $ cat a.cpp @@ -246,6 +248,11 @@ ; YAML: Subsections: ; YAML: - !Symbols ; YAML: Records: +; YAML: - Kind: S_OBJNAME +; YAML: ObjNameSym: +; YAML: Signature: 0 +; YAML-STDOUT: ObjectName: '' +; YAML-FILE: ObjectName: '{{.*}}' ; YAML: - Kind: S_COMPILE3 ; YAML: Compile3Sym: diff --git a/llvm/test/DebugInfo/COFF/multifunction.ll b/llvm/test/DebugInfo/COFF/multifunction.ll --- a/llvm/test/DebugInfo/COFF/multifunction.ll +++ b/llvm/test/DebugInfo/COFF/multifunction.ll @@ -498,18 +498,18 @@ ; OBJ64: Characteristics [ (0x42300040) ; OBJ64: ] ; OBJ64: Relocations [ -; OBJ64-NEXT: 0x64 IMAGE_REL_AMD64_SECREL x -; OBJ64-NEXT: 0x68 IMAGE_REL_AMD64_SECTION x -; OBJ64-NEXT: 0x9C IMAGE_REL_AMD64_SECREL x -; OBJ64-NEXT: 0xA0 IMAGE_REL_AMD64_SECTION x -; OBJ64-NEXT: 0x100 IMAGE_REL_AMD64_SECREL y -; OBJ64-NEXT: 0x104 IMAGE_REL_AMD64_SECTION y -; OBJ64-NEXT: 0x138 IMAGE_REL_AMD64_SECREL y -; OBJ64-NEXT: 0x13C IMAGE_REL_AMD64_SECTION y -; OBJ64-NEXT: 0x19C IMAGE_REL_AMD64_SECREL f -; OBJ64-NEXT: 0x1A0 IMAGE_REL_AMD64_SECTION f -; OBJ64-NEXT: 0x1D4 IMAGE_REL_AMD64_SECREL f -; OBJ64-NEXT: 0x1D8 IMAGE_REL_AMD64_SECTION f +; OBJ64-NEXT: 0x70 IMAGE_REL_AMD64_SECREL x +; OBJ64-NEXT: 0x74 IMAGE_REL_AMD64_SECTION x +; OBJ64-NEXT: 0xA8 IMAGE_REL_AMD64_SECREL x +; OBJ64-NEXT: 0xAC IMAGE_REL_AMD64_SECTION x +; OBJ64-NEXT: 0x10C IMAGE_REL_AMD64_SECREL y +; OBJ64-NEXT: 0x110 IMAGE_REL_AMD64_SECTION y +; OBJ64-NEXT: 0x144 IMAGE_REL_AMD64_SECREL y +; OBJ64-NEXT: 0x148 IMAGE_REL_AMD64_SECTION y +; OBJ64-NEXT: 0x1A8 IMAGE_REL_AMD64_SECREL f +; OBJ64-NEXT: 0x1AC IMAGE_REL_AMD64_SECTION f +; OBJ64-NEXT: 0x1E0 IMAGE_REL_AMD64_SECREL f +; OBJ64-NEXT: 0x1E4 IMAGE_REL_AMD64_SECTION f ; OBJ64-NEXT: ] ; OBJ64: Subsection [ ; OBJ64-NEXT: SubSectionType: Symbols (0xF1) diff --git a/llvm/test/DebugInfo/COFF/pr28747.ll b/llvm/test/DebugInfo/COFF/pr28747.ll --- a/llvm/test/DebugInfo/COFF/pr28747.ll +++ b/llvm/test/DebugInfo/COFF/pr28747.ll @@ -5,8 +5,10 @@ ; CHECK-NEXT: .long 241 ; CHECK-NEXT: .long [[SUBSEC_END:.*]]-[[SUBSEC_START:.*]] # Subsection size ; CHECK-NEXT: [[SUBSEC_START]]: -; CHECK-NEXT: .short [[C1_END:.*]]-[[C1_START:.*]] # Record length -; CHECK: [[C1_END]]: +; CHECK-NEXT: .short [[OBJNAME_END:.*]]-[[OBJNAME_START:.*]] # Record length +; CHECK: [[OBJNAME_END]]: +; CHECK-NEXT: .short [[COMPILE3_END:.*]]-[[COMPILE3_START:.*]] # Record length +; CHECK: [[COMPILE3_END]]: ; CHECK-NEXT: [[SUBSEC_END]]: ; CHECK-NEXT: .p2align 2 ; CHECK-NEXT: .cv_filechecksums diff --git a/llvm/test/DebugInfo/COFF/simple.ll b/llvm/test/DebugInfo/COFF/simple.ll --- a/llvm/test/DebugInfo/COFF/simple.ll +++ b/llvm/test/DebugInfo/COFF/simple.ll @@ -36,8 +36,10 @@ ; X86-NEXT: .long [[COMPILE_END:.*]]-[[COMPILE_START:.*]] # ; Compiler information record ; X86-NEXT: [[COMPILE_START]]: -; X86-NEXT: .short [[C1_END:.*]]-[[C1_START:.*]] # -; X86: [[C1_END]]: +; X86-NEXT: .short [[OBJNAME_END:.*]]-[[OBJNAME_START:.*]] # +; X86: [[OBJNAME_END]]: +; X86-NEXT: .short [[COMPILE3_END:.*]]-[[COMPILE3_START:.*]] # +; X86: [[COMPILE3_END]]: ; X86-NEXT: [[COMPILE_END]]: ; X86-NEXT: .p2align 2 ; X86-NEXT: .cv_fpo_data _f @@ -88,11 +90,11 @@ ; OBJ32: Characteristics [ (0x42300040) ; OBJ32: ] ; OBJ32: Relocations [ -; OBJ32-NEXT: 0x44 IMAGE_REL_I386_DIR32NB _f -; OBJ32-NEXT: 0x90 IMAGE_REL_I386_SECREL _f -; OBJ32-NEXT: 0x94 IMAGE_REL_I386_SECTION _f -; OBJ32-NEXT: 0xC8 IMAGE_REL_I386_SECREL _f -; OBJ32-NEXT: 0xCC IMAGE_REL_I386_SECTION _f +; OBJ32-NEXT: 0x50 IMAGE_REL_I386_DIR32NB _f +; OBJ32-NEXT: 0x9C IMAGE_REL_I386_SECREL _f +; OBJ32-NEXT: 0xA0 IMAGE_REL_I386_SECTION _f +; OBJ32-NEXT: 0xD4 IMAGE_REL_I386_SECREL _f +; OBJ32-NEXT: 0xD8 IMAGE_REL_I386_SECTION _f ; OBJ32-NEXT: ] ; OBJ32: Subsection [ ; OBJ32-NEXT: SubSectionType: Symbols (0xF1) @@ -165,8 +167,10 @@ ; X64-NEXT: .long [[COMPILE_END:.*]]-[[COMPILE_START:.*]] # ; Compiler information record ; X64-NEXT: [[COMPILE_START]]: -; X64-NEXT: .short [[C1_END:.*]]-[[C1_START:.*]] # -; X64: [[C1_END]]: +; X64-NEXT: .short [[OBJNAME_END:.*]]-[[OBJNAME_START:.*]] # +; X64: [[OBJNAME_END]]: +; X64-NEXT: .short [[COMPILE3_END:.*]]-[[COMPILE3_START:.*]] # +; X64: [[COMPILE3_END]]: ; X64-NEXT: [[COMPILE_END]]: ; X64-NEXT: .p2align 2 ; X64-NEXT: .long 241 # Symbol subsection for f @@ -216,10 +220,10 @@ ; OBJ64: Characteristics [ (0x42300040) ; OBJ64: ] ; OBJ64: Relocations [ -; OBJ64-NEXT: 0x64 IMAGE_REL_AMD64_SECREL f -; OBJ64-NEXT: 0x68 IMAGE_REL_AMD64_SECTION f -; OBJ64-NEXT: 0x9C IMAGE_REL_AMD64_SECREL f -; OBJ64-NEXT: 0xA0 IMAGE_REL_AMD64_SECTION f +; OBJ64-NEXT: 0x70 IMAGE_REL_AMD64_SECREL f +; OBJ64-NEXT: 0x74 IMAGE_REL_AMD64_SECTION f +; OBJ64-NEXT: 0xA8 IMAGE_REL_AMD64_SECREL f +; OBJ64-NEXT: 0xAC IMAGE_REL_AMD64_SECTION f ; OBJ64-NEXT: ] ; OBJ64: Subsection [ ; OBJ64-NEXT: SubSectionType: Symbols (0xF1) diff --git a/llvm/test/DebugInfo/COFF/vframe-fpo.ll b/llvm/test/DebugInfo/COFF/vframe-fpo.ll --- a/llvm/test/DebugInfo/COFF/vframe-fpo.ll +++ b/llvm/test/DebugInfo/COFF/vframe-fpo.ll @@ -65,7 +65,9 @@ ; CODEVIEW-NEXT: Subsection [ ; CODEVIEW-NEXT: SubSectionType: Symbols (0xF1) ; CODEVIEW-NEXT: SubSectionSize: -; CODEVIEW-NEXT: Compile3Sym { +; CODEVIEW-NEXT: ObjNameSym { +; CODEVIEW-NEXT: Kind: S_OBJNAME (0x1101) +; CODEVIEW: Compile3Sym { ; CODEVIEW-NEXT: Kind: S_COMPILE3 (0x113C) ; CODEVIEW: } ; CODEVIEW: ] diff --git a/llvm/test/MC/AArch64/coff-debug.ll b/llvm/test/MC/AArch64/coff-debug.ll --- a/llvm/test/MC/AArch64/coff-debug.ll +++ b/llvm/test/MC/AArch64/coff-debug.ll @@ -1,5 +1,7 @@ ; RUN: llc -mtriple=aarch64-windows -filetype=obj -o - %s | \ -; RUN: llvm-readobj --codeview - | FileCheck %s +; RUN: llvm-readobj --codeview - | FileCheck %s --check-prefixes=CHECK,CHECK-STDOUT +; RUN: llc -mtriple=aarch64-windows -filetype=obj -o %t.o %s +; RUN: llvm-readobj --codeview %t.o | FileCheck %s --check-prefixes=CHECK,CHECK-FILE ; ModuleID = 'a.c' source_filename = "a.c" @@ -66,6 +68,12 @@ ; CHECK: Magic: 0x4 ; CHECK: Subsection [ ; CHECK: SubSectionType: Symbols (0xF1) +; CHECK: ObjNameSym { +; CHECK: Kind: S_OBJNAME (0x1101) +; CHECK: Signature: 0x0 +; CHECK-STDOUT: ObjectName: {{$}} +; CHECK-FILE: ObjectName: {{.*}}.o +; CHECK: } ; CHECK: Compile3Sym { ; CHECK: Kind: S_COMPILE3 (0x113C) ; CHECK: Language: C (0x0) diff --git a/llvm/test/MC/ARM/coff-debugging-secrel.ll b/llvm/test/MC/ARM/coff-debugging-secrel.ll --- a/llvm/test/MC/ARM/coff-debugging-secrel.ll +++ b/llvm/test/MC/ARM/coff-debugging-secrel.ll @@ -42,10 +42,10 @@ ; CHECK-MSVC: Relocations [ ; CHECK-MSVC: Section {{.*}} .debug$S { -; CHECK-MSVC: 0x64 IMAGE_REL_ARM_SECREL function -; CHECK-MSVC: 0x68 IMAGE_REL_ARM_SECTION function -; CHECK-MSVC: 0xA0 IMAGE_REL_ARM_SECREL function -; CHECK-MSVC: 0xA4 IMAGE_REL_ARM_SECTION function +; CHECK-MSVC: 0x70 IMAGE_REL_ARM_SECREL function +; CHECK-MSVC: 0x74 IMAGE_REL_ARM_SECTION function +; CHECK-MSVC: 0xAC IMAGE_REL_ARM_SECREL function +; CHECK-MSVC: 0xB0 IMAGE_REL_ARM_SECTION function ; CHECK-MSVC: } ; CHECK-MSVC: ] diff --git a/llvm/test/MC/COFF/cv-compiler-info.ll b/llvm/test/MC/COFF/cv-compiler-info.ll --- a/llvm/test/MC/COFF/cv-compiler-info.ll +++ b/llvm/test/MC/COFF/cv-compiler-info.ll @@ -1,4 +1,6 @@ -; RUN: llc -mtriple i686-pc-windows-msvc < %s | FileCheck %s +; RUN: llc -mtriple i686-pc-windows-msvc < %s | FileCheck %s --check-prefixes=CHECK,STDOUT +; RUN: llc -mtriple i686-pc-windows-msvc < %s -o %t +; RUN: FileCheck %s --input-file=%t --check-prefixes=CHECK,FILE ; ModuleID = 'D:\src\scopes\foo.cpp' source_filename = "D:\5Csrc\5Cscopes\5Cfoo.cpp" target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" @@ -20,19 +22,23 @@ ; One .debug$S section should contain an S_COMPILE3 record that identifies the ; source language and the version of the compiler based on the DICompileUnit. ; CHECK: .section .debug$S,"dr" +; CHECK: .short 4353 # Record kind: S_OBJNAME +; CHECK-NEXT: .long 0 # Signature +; STDOUT-NEXT: .byte 0 # Object name +; FILE-NEXT: .asciz "{{.*}}{{\\\\|/}}cv-compiler-info.ll.tmp" # Object name ; CHECK: .short 4412 # Record kind: S_COMPILE3 -; CHECK: .long 1 # Flags and language -; CHECK: .short 7 # CPUType -; CHECK: .short 4 # Frontend version -; CHECK: .short 0 -; CHECK: .short 0 -; CHECK: .short 0 -; CHECK: .short [[BACKEND_VERSION:[0-9]+]] # Backend version -; CHECK: .short 0 -; CHECK: .short 0 -; CHECK: .short 0 -; CHECK: .asciz "clang version 4.0.0 " # Null-terminated compiler version string -; CHECK-NOT: .short 4412 # Record kind: S_COMPILE3 +; CHECK-NEXT: .long 1 # Flags and language +; CHECK-NEXT: .short 7 # CPUType +; CHECK-NEXT: .short 4 # Frontend version +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short [[BACKEND_VERSION:[0-9]+]] # Backend version +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .asciz "clang version 4.0.0 " # Null-terminated compiler version string +; CHECK-NOT: .short 4412 # Record kind: S_COMPILE3 !1 = !DIFile(filename: "D:\5Csrc\5Cscopes\5Cfoo.cpp", directory: "D:\5Csrc\5Cscopes\5Cclang") !2 = !{} !7 = !{i32 2, !"CodeView", i32 1} diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -605,6 +605,9 @@ GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]); if (!Out) return 1; + // Ensure the filename is passed down to CodeViewDebug. + Target->Options.ObjectFilenameForDebug = Out->outputFilename(); + std::unique_ptr DwoOut; if (!SplitDwarfOutputFile.empty()) { std::error_code EC; diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -378,7 +378,7 @@ std::error_code EC; auto S = std::make_unique(Path, EC, sys::fs::OF_None); check(EC, Path); - return std::make_unique(std::move(S)); + return std::make_unique(std::move(S), Path); }; auto AddBuffer = [&](size_t Task, std::unique_ptr MB) {