Reland - [CodeView] Emit S_OBJNAME record

Reland integrates build fixes & further review suggestions.

Thanks to @zturner for the initial S_OBJNAME patch!

Differential Revision: https://reviews.llvm.org/D43002
This commit is contained in:
Alexandre Ganea 2021-12-21 18:59:47 -05:00
parent 5bb5142e80
commit a282ea4898
25 changed files with 255 additions and 68 deletions

View File

@ -227,6 +227,9 @@ public:
/// 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;

View File

@ -204,6 +204,10 @@ public:
/// from the parent process will be used.
virtual void setEnvironment(llvm::ArrayRef<const char *> 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; }

View File

@ -3802,6 +3802,11 @@ def o : JoinedOrSeparate<["-"], "o">, Flags<[NoXarchOption, RenderAsInput,
CC1Option, CC1AsOption, FC1Option, FlangOption]>,
HelpText<"Write output to <file>">, MetaVarName<"<file>">,
MarshallingInfoString<FrontendOpts<"OutputFile">>;
def object_file_name_EQ : Joined<["-"], "object-file-name=">, Flags<[CC1Option, CC1AsOption, CoreOption]>,
HelpText<"Set the output <file> for debug infos">, MetaVarName<"<file>">,
MarshallingInfoString<CodeGenOpts<"ObjectFilenameForDebug">>;
def object_file_name : Separate<["-"], "object-file-name">, Flags<[CC1Option, CC1AsOption, CoreOption]>,
Alias<object_file_name_EQ>;
def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>,

View File

@ -646,6 +646,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
Options.MCOptions.Argv0 = CodeGenOpts.Argv0;
Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs;
Options.DebugStrictDwarf = CodeGenOpts.DebugStrictDwarf;
Options.ObjectFilenameForDebug = CodeGenOpts.ObjectFilenameForDebug;
return true;
}
@ -1583,7 +1584,8 @@ static void runThinLTOBackend(
return;
auto AddStream = [&](size_t Task) {
return std::make_unique<CachedFileStream>(std::move(OS));
return std::make_unique<CachedFileStream>(std::move(OS),
CGOpts.ObjectFilenameForDebug);
};
lto::Config Conf;
if (CGOpts.SaveTempsFilePrefix != "") {

View File

@ -625,8 +625,9 @@ getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
}
/// 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 @@ static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs,
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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
// 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 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
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());

View File

@ -126,6 +126,7 @@ if( NOT CLANG_BUILT_STANDALONE )
llvm-nm
llvm-objcopy
llvm-objdump
llvm-pdbutil
llvm-profdata
llvm-rc
llvm-readelf

View File

@ -0,0 +1,41 @@
// REQUIRES: x86-registered-target
// RUN: rm -rf %t && mkdir %t && cd %t
// RUN: cp %s debug-info-objname.cpp
/// No output file provided, input file is relative, we emit an absolute path (MSVC behavior).
// RUN: %clang_cl --target=x86_64-windows-msvc /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 --target=x86_64-windows-msvc /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 --target=x86_64-windows-msvc /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 --target=x86_64-windows-msvc /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 --target=x86_64-windows-msvc /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 --target=x86_64-windows-msvc /c /Z7 -nostdinc -fdebug-compilation-dir=. /FA debug-info-objname.cpp
// RUN: FileCheck --input-file=debug-info-objname.asm --check-prefix=ASM %s
/// Same thing for -save-temps
// RUN: %clang_cl --target=x86_64-windows-msvc /c /Z7 -nostdinc -fdebug-compilation-dir=. /clang:-save-temps debug-info-objname.cpp
// RUN: FileCheck --input-file=debug-info-objname.asm --check-prefix=ASM %s
int main() {
return 1;
}
// ABSOLUTE: S_OBJNAME [size = [[#]]] sig=0, `{{.+}}debug-info-objname.obj`
// RELATIVE: S_OBJNAME [size = [[#]]] sig=0, `debug-info-objname.obj`
// ASM: Record kind: S_OBJNAME
// ASM-NEXT: .long 0
// ASM-NEXT: .asciz "debug-info-objname.obj"

View File

@ -62,6 +62,7 @@ public:
std::string ABIName;
std::string AssemblyLanguage;
std::string SplitDwarfFile;
std::string COFFOutputFilename;
const char *Argv0 = nullptr;
ArrayRef<std::string> CommandLineArgs;

View File

@ -27,8 +27,11 @@ class MemoryBuffer;
/// that can be done by deriving from this class and overriding the destructor.
class CachedFileStream {
public:
CachedFileStream(std::unique_ptr<raw_pwrite_stream> OS) : OS(std::move(OS)) {}
CachedFileStream(std::unique_ptr<raw_pwrite_stream> OS,
std::string OSPath = "")
: OS(std::move(OS)), ObjectPathName(OSPath) {}
std::unique_ptr<raw_pwrite_stream> OS;
std::string ObjectPathName;
virtual ~CachedFileStream() = default;
};

View File

@ -29,9 +29,10 @@ class ToolOutputFile {
/// 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 @@ public:
/// 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

View File

@ -418,6 +418,11 @@ namespace llvm {
/// 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

View File

@ -649,6 +649,7 @@ void CodeViewDebug::endModule() {
switchToDebugSectionForSymbol(nullptr);
MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
emitObjName();
emitCompilerInformation();
endCVSubsection(CompilerInfo);
@ -784,6 +785,29 @@ void CodeViewDebug::emitTypeGlobalHashes() {
}
}
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];

View File

@ -302,6 +302,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitTypeGlobalHashes();
void emitObjName();
void emitCompilerInformation();
void emitBuildInfo();

View File

@ -412,6 +412,8 @@ static void codegen(const Config &Conf, TargetMachine *TM,
if (Error Err = StreamOrErr.takeError())
report_fatal_error(std::move(Err));
std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
TM->Options.ObjectFilenameForDebug = Stream->ObjectPathName;
legacy::PassManager CodeGenPasses;
CodeGenPasses.add(
createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex));

View File

@ -79,14 +79,13 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
struct CacheStream : CachedFileStream {
AddBufferFn AddBuffer;
sys::fs::TempFile TempFile;
std::string EntryPath;
unsigned Task;
CacheStream(std::unique_ptr<raw_pwrite_stream> 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 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
// Open the file first to avoid racing with a cache pruner.
ErrorOr<std::unique_ptr<MemoryBuffer>> 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 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
// 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 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
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));

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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: ]

View File

@ -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 @@ attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-ma
; 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)

View File

@ -42,10 +42,10 @@ entry:
; 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: ]

View File

@ -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 @@ attributes #0 = { nounwind sspstrong "correctly-rounded-divide-sqrt-fp-math"="fa
; 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}

View File

@ -605,6 +605,9 @@ static int compileModule(char **argv, LLVMContext &Context) {
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<ToolOutputFile> DwoOut;
if (!SplitDwarfOutputFile.empty()) {
std::error_code EC;

View File

@ -378,7 +378,7 @@ static int run(int argc, char **argv) {
std::error_code EC;
auto S = std::make_unique<raw_fd_ostream>(Path, EC, sys::fs::OF_None);
check(EC, Path);
return std::make_unique<CachedFileStream>(std::move(S));
return std::make_unique<CachedFileStream>(std::move(S), Path);
};
auto AddBuffer = [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {