diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp index df43da93d7755..485ce1a64eb83 100644 --- a/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -183,6 +183,7 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString(Twine("-lto-debug-options=") + LTOArgs)); + // Sanitizer runtimes must be supplied before all other objects and libs. if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); @@ -358,9 +359,6 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (StringRef Jobs = getLTOParallelism(Args, D); !Jobs.empty()) AddLTOFlag(Twine("jobs=") + Jobs); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) - TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); - TC.AddFilePathLibArgs(Args, CmdArgs); Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, options::OPT_s, options::OPT_t}); @@ -368,17 +366,63 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) CmdArgs.push_back("--no-demangle"); - AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); + // Sanitizer runtimes must be supplied before all other objects and libs. + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) + TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); - if (Args.hasArg(options::OPT_pthread)) { - CmdArgs.push_back("-lpthread"); + const bool AddStartFiles = + !Relocatable && + !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib); + + auto AddCRTObject = [&](const char *Name) { + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(Name))); + }; + + if (AddStartFiles) { + if (!Shared) + AddCRTObject("crt1.o"); + AddCRTObject("crti.o"); + AddCRTObject(Shared ? "crtbeginS.o" + : Static ? "crtbeginT.o" + : "crtbegin.o"); } - if (UseJMC) { - CmdArgs.push_back("--push-state"); - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back("-lSceJmc_nosubmission"); - CmdArgs.push_back("--pop-state"); + AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); + + if (!Relocatable && + !Args.hasArg(options::OPT_nodefaultlibs, options::OPT_nostdlib)) { + + if (UseJMC) { + CmdArgs.push_back("--push-state"); + CmdArgs.push_back("--whole-archive"); + CmdArgs.push_back("-lSceJmc_nosubmission"); + CmdArgs.push_back("--pop-state"); + } + + if (Args.hasArg(options::OPT_pthread)) + CmdArgs.push_back("-lpthread"); + + if (Static) { + if (!Args.hasArg(options::OPT_nostdlibxx)) + CmdArgs.push_back("-lstdc++"); + if (!Args.hasArg(options::OPT_nolibc)) { + CmdArgs.push_back("-lm"); + CmdArgs.push_back("-lc"); + } + + CmdArgs.push_back("-lcompiler_rt"); + CmdArgs.push_back("-lkernel"); + } else { + // The C and C++ libraries are combined. + if (!Args.hasArg(options::OPT_nolibc, options::OPT_nostdlibxx)) + CmdArgs.push_back("-lc_stub_weak"); + + CmdArgs.push_back("-lkernel_stub_weak"); + } + } + if (AddStartFiles) { + AddCRTObject(Shared ? "crtendS.o" : "crtend.o"); + AddCRTObject("crtn.o"); } if (Args.hasArg(options::OPT_fuse_ld_EQ)) { diff --git a/clang/test/Driver/ps5-linker.c b/clang/test/Driver/ps5-linker.c index 95267942edc17..ffbea090e057e 100644 --- a/clang/test/Driver/ps5-linker.c +++ b/clang/test/Driver/ps5-linker.c @@ -97,6 +97,60 @@ // Check the default library name. // CHECK-JMC: "--push-state" "--whole-archive" "-lSceJmc_nosubmission" "--pop-state" +// Test that CRT objects and libraries are supplied to the linker and can be +// omitted with -noxxx options. These switches have some interaction with +// sanitizer RT libraries. That's checked in fsanitize.c + +// RUN: %clang --target=x86_64-sie-ps5 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN-CRT,CHECK-DYNAMIC-LIBC,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -shared -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-SHARED-CRT,CHECK-DYNAMIC-LIBC,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -static -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-CRT,CHECK-STATIC-LIBCPP,CHECK-STATIC-LIBC,CHECK-STATIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -r -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-NO-LIBS %s + +// RUN: %clang --target=x86_64-sie-ps5 %s -pthread -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-PTHREAD %s + +// RUN: %clang --target=x86_64-sie-ps5 %s -nostartfiles -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-DYNAMIC-LIBC,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nostartfiles -shared -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-DYNAMIC-LIBC,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nostartfiles -static -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-STATIC-LIBCPP,CHECK-STATIC-LIBC,CHECK-STATIC-CORE-LIBS %s + +// RUN: %clang --target=x86_64-sie-ps5 %s -nodefaultlibs -pthread -fjmc -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN-CRT,CHECK-NO-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nodefaultlibs -pthread -fjmc -shared -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-SHARED-CRT,CHECK-NO-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nodefaultlibs -pthread -fjmc -static -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-CRT,CHECK-NO-LIBS %s + +// RUN: %clang --target=x86_64-sie-ps5 %s -nostdlib -pthread -fjmc -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-NO-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nostdlib -pthread -fjmc -shared -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-NO-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nostdlib -pthread -fjmc -static -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NO-CRT,CHECK-NO-LIBS %s + +// RUN: %clang --target=x86_64-sie-ps5 %s -nolibc -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN-CRT,CHECK-NO-LIBC,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nolibc -shared -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-SHARED-CRT,CHECK-NO-LIBC,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nolibc -static -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-CRT,CHECK-STATIC-LIBCPP,CHECK-NO-LIBC,CHECK-STATIC-CORE-LIBS %s + +// RUN: %clang --target=x86_64-sie-ps5 %s -nostdlib++ -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN-CRT,CHECK-NO-LIBCPP,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nostdlib++ -shared -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-SHARED-CRT,CHECK-NO-LIBCPP,CHECK-DYNAMIC-CORE-LIBS %s +// RUN: %clang --target=x86_64-sie-ps5 %s -nostdlib++ -static -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-CRT,CHECK-NO-LIBCPP,CHECK-STATIC-LIBC,CHECK-STATIC-CORE-LIBS %s + +// CHECK-LD: {{ld(\.exe)?}}" +// CHECK-MAIN-CRT-SAME: "crt1.o" "crti.o" "crtbegin.o" +// CHECK-SHARED-CRT-SAME: "crti.o" "crtbeginS.o" +// CHECK-STATIC-CRT-SAME: "crt1.o" "crti.o" "crtbeginT.o" + +// CHECK-NO-LIBC-NOT: "-lc{{(_stub_weak)?}}" +// CHECK-NO-LIBCPP-NOT: "-l{{c_stub_weak|stdc\+\+}}" + +// CHECK-DYNAMIC-LIBC-SAME: "-lc_stub_weak" +// CHECK-DYNAMIC-CORE-LIBS-SAME: "-lkernel_stub_weak" +// CHECK-STATIC-LIBCPP-SAME: "-lstdc++" +// CHECK-STATIC-LIBC-SAME: "-lm" "-lc" +// CHECK-STATIC-CORE-LIBS-SAME: "-lcompiler_rt" "-lkernel" + +// CHECK-PTHREAD-SAME: "-lpthread" + +// CHECK-MAIN-CRT-SAME: "crtend.o" "crtn.o" +// CHECK-SHARED-CRT-SAME: "crtendS.o" "crtn.o" +// CHECK-STATIC-CRT-SAME: "crtend.o" "crtn.o" + +// CHECK-NO-CRT-NOT: "crt{{[^"]*}}.o" +// CHECK-NO-LIBS-NOT: "-l{{[^"]*}}" + // Test the driver's control over the -fcrash-diagnostics-dir behavior with linker flags. // RUN: %clang --target=x86_64-sie-ps5 -fcrash-diagnostics-dir=mydumps %s -### 2>&1 | FileCheck --check-prefixes=CHECK-DIAG %s @@ -122,7 +176,8 @@ // CHECK-LDOT-SAME: "-L." // Test that /target/lib is added to library search paths, if it -// exists and no --sysroot is specified. +// exists and no --sysroot is specified. Also confirm that CRT objects are +// found there. // RUN: rm -rf %t.dir && mkdir %t.dir // RUN: env SCE_PROSPERO_SDK_DIR=%t.dir %clang --target=x64_64-sie-ps5 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-NO-TARGETLIB %s @@ -132,7 +187,9 @@ // CHECK-NO-TARGETLIB-NOT: "-L{{.*[/\\]}}target/lib" // RUN: mkdir -p %t.dir/target/lib +// RUN: touch %t.dir/target/lib/crti.o // RUN: env SCE_PROSPERO_SDK_DIR=%t.dir %clang --target=x64_64-sie-ps5 %s -### 2>&1 | FileCheck --check-prefixes=CHECK-TARGETLIB %s // CHECK-TARGETLIB: {{ld(\.exe)?}}" // CHECK-TARGETLIB-SAME: "-L{{.*[/\\]}}target/lib" +// CHECK-TARGETLIB-SAME: "{{.*[/\\]}}target{{/|\\\\}}lib{{/|\\\\}}crti.o"