diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp --- a/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -152,6 +152,26 @@ assert(Output.isNothing() && "Invalid output."); } + const bool UseLTO = D.isUsingLTO(); + const bool UseJMC = + Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); + const bool IsPS4 = TC.getTriple().isPS4(); + const bool IsPS5 = TC.getTriple().isPS5(); + assert(IsPS4 || IsPS5); + + // This tells LTO to perform JustMyCode instrumentation. + if (UseLTO && UseJMC) { + if (IsPS4 && D.getLTOMode() == LTOK_Thin) { + CmdArgs.push_back("-lto-thin-debug-options=-enable-jmc-instrument"); + } else if (IsPS4 && D.getLTOMode() == LTOK_Full) { + CmdArgs.push_back("-lto-debug-options=-enable-jmc-instrument"); + } else if (IsPS5) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-enable-jmc-instrument"); + } else + llvm_unreachable("new LTO mode?"); + } + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); @@ -171,6 +191,15 @@ CmdArgs.push_back("-lpthread"); } + if (UseJMC) { + CmdArgs.push_back("--whole-archive"); + if (IsPS4) + CmdArgs.push_back("-lSceDbgJmc"); + else + CmdArgs.push_back("-lSceJmc_nosubmission"); + CmdArgs.push_back("--no-whole-archive"); + } + if (Args.hasArg(options::OPT_fuse_ld_EQ)) { D.Diag(diag::err_drv_unsupported_opt_for_target) << "-fuse-ld" << TC.getTriple().str(); diff --git a/clang/test/Driver/ps4-ps5-linker-jmc.c b/clang/test/Driver/ps4-ps5-linker-jmc.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/ps4-ps5-linker-jmc.c @@ -0,0 +1,20 @@ +// Test the driver's control over the JustMyCode behavior with linker flags. + +// RUN: %clang --target=x86_64-scei-ps4 -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-PS4,CHECK-PS4-LIB %s +// RUN: %clang --target=x86_64-scei-ps4 -flto=thin -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-PS4-THIN-LTO,CHECK-PS4-LIB %s +// RUN: %clang --target=x86_64-scei-ps4 -flto=full -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-PS4-FULL-LTO,CHECK-PS4-LIB %s +// RUN: %clang --target=x86_64-scei-ps5 -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-PS5,CHECK-PS5-LIB %s +// RUN: %clang --target=x86_64-scei-ps5 -flto -fjmc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-PS5-LTO,CHECK-PS5-LIB %s + +// CHECK-PS4-NOT: "-enable-jmc-instrument" + +// CHECK-PS4-THIN-LTO: "-lto-thin-debug-options=-enable-jmc-instrument" +// CHECK-PS4-FULL-LTO: "-lto-debug-options=-enable-jmc-instrument" + +// CHECK-PS5-NOT: "-enable-jmc-instrument" + +// CHECK-PS5-LTO: "-mllvm" "-enable-jmc-instrument" + +// Check the default library name. +// CHECK-PS4-LIB: "--whole-archive" "-lSceDbgJmc" "--no-whole-archive" +// CHECK-PS5-LIB: "--whole-archive" "-lSceJmc_nosubmission" "--no-whole-archive"