diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp | 309 |
1 files changed, 217 insertions, 92 deletions
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp index 383b0c50d410..8ba8b80cfec7 100644 --- a/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp +++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/PS4CPU.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "PS4CPU.h" -#include "FreeBSD.h" #include "CommonArgs.h" +#include "clang/Config/config.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -23,10 +23,18 @@ using namespace clang::driver; using namespace clang; using namespace llvm::opt; -using clang::driver::tools::AddLinkerInputs; +// Helper to paste bits of an option together and return a saved string. +static const char *makeArgString(const ArgList &Args, const char *Prefix, + const char *Base, const char *Suffix) { + // Basically "Prefix + Base + Suffix" all converted to Twine then saved. + return Args.MakeArgString(Twine(StringRef(Prefix), Base) + Suffix); +} + +void tools::PScpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args, + ArgStringList &CmdArgs) { + assert(TC.getTriple().isPS()); + auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC); -void tools::PS4cpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, false) || Args.hasFlag(options::OPT_fprofile_generate, @@ -43,14 +51,16 @@ void tools::PS4cpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args, options::OPT_fno_profile_generate, false) || Args.hasArg(options::OPT_fcreate_profile) || Args.hasArg(options::OPT_coverage))) - CmdArgs.push_back("--dependent-lib=libclang_rt.profile-x86_64.a"); + CmdArgs.push_back(makeArgString( + Args, "--dependent-lib=", PSTC.getProfileRTLibName(), "")); } -void tools::PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA, +void tools::PScpu::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain()); claimNoWarnArgs(Args); ArgStringList CmdArgs; @@ -64,40 +74,57 @@ void tools::PS4cpu::Assemble::ConstructJob(Compilation &C, const JobAction &JA, assert(Input.isFilename() && "Invalid input."); CmdArgs.push_back(Input.getFilename()); - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("orbis-as")); + std::string AsName = TC.qualifyPSCmdName("as"); + const char *Exec = Args.MakeArgString(TC.GetProgramPath(AsName.c_str())); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs, Output)); } -static void AddPS4SanitizerArgs(const ToolChain &TC, ArgStringList &CmdArgs) { - const SanitizerArgs &SanArgs = TC.getSanitizerArgs(); - if (SanArgs.needsUbsanRt()) { - CmdArgs.push_back("-lSceDbgUBSanitizer_stub_weak"); - } - if (SanArgs.needsAsanRt()) { - CmdArgs.push_back("-lSceDbgAddressSanitizer_stub_weak"); - } +void tools::PScpu::addSanitizerArgs(const ToolChain &TC, const ArgList &Args, + ArgStringList &CmdArgs) { + assert(TC.getTriple().isPS()); + auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC); + PSTC.addSanitizerArgs(Args, CmdArgs, "--dependent-lib=lib", ".a"); } -void tools::PS4cpu::addSanitizerArgs(const ToolChain &TC, - ArgStringList &CmdArgs) { - const SanitizerArgs &SanArgs = TC.getSanitizerArgs(); +void toolchains::PS4CPU::addSanitizerArgs(const ArgList &Args, + ArgStringList &CmdArgs, + const char *Prefix, + const char *Suffix) const { + auto arg = [&](const char *Name) -> const char * { + return makeArgString(Args, Prefix, Name, Suffix); + }; + const SanitizerArgs &SanArgs = getSanitizerArgs(Args); if (SanArgs.needsUbsanRt()) - CmdArgs.push_back("--dependent-lib=libSceDbgUBSanitizer_stub_weak.a"); + CmdArgs.push_back(arg("SceDbgUBSanitizer_stub_weak")); if (SanArgs.needsAsanRt()) - CmdArgs.push_back("--dependent-lib=libSceDbgAddressSanitizer_stub_weak.a"); + CmdArgs.push_back(arg("SceDbgAddressSanitizer_stub_weak")); } -void tools::PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA, - const InputInfo &Output, - const InputInfoList &Inputs, - const ArgList &Args, - const char *LinkingOutput) const { - const toolchains::FreeBSD &ToolChain = - static_cast<const toolchains::FreeBSD &>(getToolChain()); - const Driver &D = ToolChain.getDriver(); +void toolchains::PS5CPU::addSanitizerArgs(const ArgList &Args, + ArgStringList &CmdArgs, + const char *Prefix, + const char *Suffix) const { + auto arg = [&](const char *Name) -> const char * { + return makeArgString(Args, Prefix, Name, Suffix); + }; + const SanitizerArgs &SanArgs = getSanitizerArgs(Args); + if (SanArgs.needsUbsanRt()) + CmdArgs.push_back(arg("SceUBSanitizer_nosubmission_stub_weak")); + if (SanArgs.needsAsanRt()) + CmdArgs.push_back(arg("SceAddressSanitizer_nosubmission_stub_weak")); + if (SanArgs.needsTsanRt()) + CmdArgs.push_back(arg("SceThreadSanitizer_nosubmission_stub_weak")); +} + +void tools::PScpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain()); + const Driver &D = TC.getDriver(); ArgStringList CmdArgs; // Silence warning for "clang -g foo.o -o foo" @@ -117,119 +144,195 @@ void tools::PS4cpu::Link::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); if (Args.hasArg(options::OPT_shared)) - CmdArgs.push_back("--oformat=so"); + CmdArgs.push_back("--shared"); + assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); if (Output.isFilename()) { CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - } else { - assert(Output.isNothing() && "Invalid output."); } - if(!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) - AddPS4SanitizerArgs(ToolChain, CmdArgs); + const bool UseLTO = D.isUsingLTO(); + const bool UseJMC = + Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); + const bool IsPS4 = TC.getTriple().isPS4(); - Args.AddAllArgs(CmdArgs, options::OPT_L); - Args.AddAllArgs(CmdArgs, options::OPT_T_Group); - Args.AddAllArgs(CmdArgs, options::OPT_e); - Args.AddAllArgs(CmdArgs, options::OPT_s); - Args.AddAllArgs(CmdArgs, options::OPT_t); - Args.AddAllArgs(CmdArgs, options::OPT_r); + const char *PS4LTOArgs = ""; + auto AddCodeGenFlag = [&](Twine Flag) { + if (IsPS4) + PS4LTOArgs = Args.MakeArgString(Twine(PS4LTOArgs) + " " + Flag); + else + CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=") + Flag)); + }; + + if (UseLTO) { + // We default to creating the arange section, but LTO does not. Enable it + // here. + AddCodeGenFlag("-generate-arange-section"); + + // This tells LTO to perform JustMyCode instrumentation. + if (UseJMC) + AddCodeGenFlag("-enable-jmc-instrument"); + + if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) + AddCodeGenFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); + + StringRef Parallelism = getLTOParallelism(Args, D); + if (!Parallelism.empty()) { + if (IsPS4) + AddCodeGenFlag(Twine("-threads=") + Parallelism); + else + CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") + Parallelism)); + } + + if (IsPS4) { + const char *Prefix = nullptr; + if (D.getLTOMode() == LTOK_Thin) + Prefix = "-lto-thin-debug-options="; + else if (D.getLTOMode() == LTOK_Full) + Prefix = "-lto-debug-options="; + else + llvm_unreachable("new LTO mode?"); + + CmdArgs.push_back(Args.MakeArgString(Twine(Prefix) + PS4LTOArgs)); + } + } + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) + TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); + + if (D.isUsingLTO() && Args.hasArg(options::OPT_funified_lto)) { + if (D.getLTOMode() == LTOK_Thin) + CmdArgs.push_back("--lto=thin"); + else if (D.getLTOMode() == LTOK_Full) + CmdArgs.push_back("--lto=full"); + } + + Args.addAllArgs(CmdArgs, + {options::OPT_L, options::OPT_T_Group, options::OPT_s, + options::OPT_t, options::OPT_r}); if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) CmdArgs.push_back("--no-demangle"); - AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); + AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); if (Args.hasArg(options::OPT_pthread)) { 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" << getToolChain().getTriple().str(); + << "-fuse-ld" << TC.getTriple().str(); } - const char *Exec = - Args.MakeArgString(ToolChain.GetProgramPath("orbis-ld")); + std::string LdName = TC.qualifyPSCmdName(TC.getLinkerBaseName()); + const char *Exec = Args.MakeArgString(TC.GetProgramPath(LdName.c_str())); C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF8(), Exec, CmdArgs, Inputs, Output)); } -toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) +toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, StringRef Platform, + const char *EnvVar) : Generic_ELF(D, Triple, Args) { if (Args.hasArg(clang::driver::options::OPT_static)) - D.Diag(clang::diag::err_drv_unsupported_opt_for_target) << "-static" - << "PS4"; - - // Determine where to find the PS4 libraries. We use SCE_ORBIS_SDK_DIR - // if it exists; otherwise use the driver's installation path, which - // should be <SDK_DIR>/host_tools/bin. - - SmallString<512> PS4SDKDir; - if (const char *EnvValue = getenv("SCE_ORBIS_SDK_DIR")) { - if (!llvm::sys::fs::exists(EnvValue)) - getDriver().Diag(clang::diag::warn_drv_ps4_sdk_dir) << EnvValue; - PS4SDKDir = EnvValue; - } else { - PS4SDKDir = getDriver().Dir; - llvm::sys::path::append(PS4SDKDir, "/../../"); - } + D.Diag(clang::diag::err_drv_unsupported_opt_for_target) + << "-static" << Platform; - // By default, the driver won't report a warning if it can't find - // PS4's include or lib directories. This behavior could be changed if - // -Weverything or -Winvalid-or-nonexistent-directory options are passed. + // Determine where to find the PS4/PS5 libraries. // If -isysroot was passed, use that as the SDK base path. - std::string PrefixDir; + // If not, we use the EnvVar if it exists; otherwise use the driver's + // installation path, which should be <SDK_DIR>/host_tools/bin. + SmallString<80> Whence; if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { - PrefixDir = A->getValue(); - if (!llvm::sys::fs::exists(PrefixDir)) - getDriver().Diag(clang::diag::warn_missing_sysroot) << PrefixDir; - } else - PrefixDir = std::string(PS4SDKDir.str()); - - SmallString<512> PS4SDKIncludeDir(PrefixDir); - llvm::sys::path::append(PS4SDKIncludeDir, "target/include"); + SDKRootDir = A->getValue(); + if (!llvm::sys::fs::exists(SDKRootDir)) + D.Diag(clang::diag::warn_missing_sysroot) << SDKRootDir; + Whence = A->getSpelling(); + } else if (const char *EnvValue = getenv(EnvVar)) { + SDKRootDir = EnvValue; + Whence = { "environment variable '", EnvVar, "'" }; + } else { + SDKRootDir = D.Dir + "/../../"; + Whence = "compiler's location"; + } + + SmallString<512> SDKIncludeDir(SDKRootDir); + llvm::sys::path::append(SDKIncludeDir, "target/include"); if (!Args.hasArg(options::OPT_nostdinc) && !Args.hasArg(options::OPT_nostdlibinc) && !Args.hasArg(options::OPT_isysroot) && !Args.hasArg(options::OPT__sysroot_EQ) && - !llvm::sys::fs::exists(PS4SDKIncludeDir)) { - getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected) - << "PS4 system headers" << PS4SDKIncludeDir; + !llvm::sys::fs::exists(SDKIncludeDir)) { + D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) + << Twine(Platform, " system headers").str() << SDKIncludeDir << Whence; } - SmallString<512> PS4SDKLibDir(PS4SDKDir); - llvm::sys::path::append(PS4SDKLibDir, "target/lib"); + SmallString<512> SDKLibDir(SDKRootDir); + llvm::sys::path::append(SDKLibDir, "target/lib"); if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_nodefaultlibs) && !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) && !Args.hasArg(options::OPT_emit_ast) && - !llvm::sys::fs::exists(PS4SDKLibDir)) { - getDriver().Diag(clang::diag::warn_drv_unable_to_find_directory_expected) - << "PS4 system libraries" << PS4SDKLibDir; + !llvm::sys::fs::exists(SDKLibDir)) { + D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) + << Twine(Platform, " system libraries").str() << SDKLibDir << Whence; return; } - getFilePaths().push_back(std::string(PS4SDKLibDir.str())); + getFilePaths().push_back(std::string(SDKLibDir)); } -Tool *toolchains::PS4CPU::buildAssembler() const { - return new tools::PS4cpu::Assemble(*this); +void toolchains::PS4PS5Base::AddClangSystemIncludeArgs( + const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> Dir(D.ResourceDir); + llvm::sys::path::append(Dir, "include"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + addExternCSystemInclude(DriverArgs, CC1Args, + SDKRootDir + "/target/include"); + addExternCSystemInclude(DriverArgs, CC1Args, + SDKRootDir + "/target/include_common"); } -Tool *toolchains::PS4CPU::buildLinker() const { - return new tools::PS4cpu::Link(*this); +Tool *toolchains::PS4CPU::buildAssembler() const { + return new tools::PScpu::Assembler(*this); } -bool toolchains::PS4CPU::isPICDefault() const { return true; } +Tool *toolchains::PS5CPU::buildAssembler() const { + // PS5 does not support an external assembler. + getDriver().Diag(clang::diag::err_no_external_assembler); + return nullptr; +} -bool toolchains::PS4CPU::HasNativeLLVMSupport() const { return true; } +Tool *toolchains::PS4PS5Base::buildLinker() const { + return new tools::PScpu::Linker(*this); +} -SanitizerMask toolchains::PS4CPU::getSupportedSanitizers() const { +SanitizerMask toolchains::PS4PS5Base::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; Res |= SanitizerKind::PointerCompare; @@ -238,10 +341,16 @@ SanitizerMask toolchains::PS4CPU::getSupportedSanitizers() const { return Res; } -void toolchains::PS4CPU::addClangTargetOptions( +SanitizerMask toolchains::PS5CPU::getSupportedSanitizers() const { + SanitizerMask Res = PS4PS5Base::getSupportedSanitizers(); + Res |= SanitizerKind::Thread; + return Res; +} + +void toolchains::PS4PS5Base::addClangTargetOptions( const ArgList &DriverArgs, ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadingKind) const { - // PS4 does not use init arrays. + // PS4/PS5 do not use init arrays. if (DriverArgs.hasArg(options::OPT_fuse_init_array)) { Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array); getDriver().Diag(clang::diag::err_drv_unsupported_opt_for_target) @@ -250,6 +359,12 @@ void toolchains::PS4CPU::addClangTargetOptions( CC1Args.push_back("-fno-use-init-array"); + // Default to -fvisibility-global-new-delete=source for PS5. + if (getTriple().isPS5() && + !DriverArgs.hasArg(options::OPT_fvisibility_global_new_delete_EQ, + options::OPT_fvisibility_global_new_delete_hidden)) + CC1Args.push_back("-fvisibility-global-new-delete=source"); + const Arg *A = DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, options::OPT_fno_visibility_from_dllstorageclass); @@ -282,3 +397,13 @@ void toolchains::PS4CPU::addClangTargetOptions( CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default"); } } + +// PS4 toolchain. +toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : PS4PS5Base(D, Triple, Args, "PS4", "SCE_ORBIS_SDK_DIR") {} + +// PS5 toolchain. +toolchains::PS5CPU::PS5CPU(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : PS4PS5Base(D, Triple, Args, "PS5", "SCE_PROSPERO_SDK_DIR") {} |