10b57cec5SDimitry Andric //===--- PS4CPU.cpp - PS4CPU ToolChain Implementations ----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "PS4CPU.h" 100b57cec5SDimitry Andric #include "CommonArgs.h" 110b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 120b57cec5SDimitry Andric #include "clang/Driver/Driver.h" 130b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 140b57cec5SDimitry Andric #include "clang/Driver/Options.h" 150b57cec5SDimitry Andric #include "clang/Driver/SanitizerArgs.h" 160b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 170b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 180b57cec5SDimitry Andric #include "llvm/Support/Path.h" 190b57cec5SDimitry Andric #include <cstdlib> // ::getenv 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace clang::driver; 220b57cec5SDimitry Andric using namespace clang; 230b57cec5SDimitry Andric using namespace llvm::opt; 240b57cec5SDimitry Andric 2581ad6265SDimitry Andric // Helper to paste bits of an option together and return a saved string. 2681ad6265SDimitry Andric static const char *makeArgString(const ArgList &Args, const char *Prefix, 2781ad6265SDimitry Andric const char *Base, const char *Suffix) { 2881ad6265SDimitry Andric // Basically "Prefix + Base + Suffix" all converted to Twine then saved. 2981ad6265SDimitry Andric return Args.MakeArgString(Twine(StringRef(Prefix), Base) + Suffix); 3081ad6265SDimitry Andric } 3181ad6265SDimitry Andric 3281ad6265SDimitry Andric void tools::PScpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args, 330b57cec5SDimitry Andric ArgStringList &CmdArgs) { 3481ad6265SDimitry Andric assert(TC.getTriple().isPS()); 3581ad6265SDimitry Andric auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC); 3681ad6265SDimitry Andric 370b57cec5SDimitry Andric if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, 380b57cec5SDimitry Andric false) || 390b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_generate, 405ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 410b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_generate_EQ, 425ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 430b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_instr_generate, 440b57cec5SDimitry Andric options::OPT_fno_profile_instr_generate, false) || 450b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_instr_generate_EQ, 460b57cec5SDimitry Andric options::OPT_fno_profile_instr_generate, false) || 475ffd83dbSDimitry Andric Args.hasFlag(options::OPT_fcs_profile_generate, 485ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 495ffd83dbSDimitry Andric Args.hasFlag(options::OPT_fcs_profile_generate_EQ, 505ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 510b57cec5SDimitry Andric Args.hasArg(options::OPT_fcreate_profile) || 520b57cec5SDimitry Andric Args.hasArg(options::OPT_coverage))) 5381ad6265SDimitry Andric CmdArgs.push_back(makeArgString( 5481ad6265SDimitry Andric Args, "--dependent-lib=", PSTC.getProfileRTLibName(), "")); 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 5781ad6265SDimitry Andric void tools::PScpu::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 580b57cec5SDimitry Andric const InputInfo &Output, 590b57cec5SDimitry Andric const InputInfoList &Inputs, 600b57cec5SDimitry Andric const ArgList &Args, 610b57cec5SDimitry Andric const char *LinkingOutput) const { 6281ad6265SDimitry Andric auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain()); 630b57cec5SDimitry Andric claimNoWarnArgs(Args); 640b57cec5SDimitry Andric ArgStringList CmdArgs; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric CmdArgs.push_back("-o"); 690b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric assert(Inputs.size() == 1 && "Unexpected number of inputs."); 720b57cec5SDimitry Andric const InputInfo &Input = Inputs[0]; 730b57cec5SDimitry Andric assert(Input.isFilename() && "Invalid input."); 740b57cec5SDimitry Andric CmdArgs.push_back(Input.getFilename()); 750b57cec5SDimitry Andric 7681ad6265SDimitry Andric std::string AsName = TC.qualifyPSCmdName("as"); 7781ad6265SDimitry Andric const char *Exec = Args.MakeArgString(TC.GetProgramPath(AsName.c_str())); 78e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 79e8d8bef9SDimitry Andric ResponseFileSupport::AtFileUTF8(), 80e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 8381ad6265SDimitry Andric void tools::PScpu::addSanitizerArgs(const ToolChain &TC, const ArgList &Args, 84349cc55cSDimitry Andric ArgStringList &CmdArgs) { 8581ad6265SDimitry Andric assert(TC.getTriple().isPS()); 8681ad6265SDimitry Andric auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC); 8781ad6265SDimitry Andric PSTC.addSanitizerArgs(Args, CmdArgs, "--dependent-lib=lib", ".a"); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 9081ad6265SDimitry Andric void toolchains::PS4CPU::addSanitizerArgs(const ArgList &Args, 9181ad6265SDimitry Andric ArgStringList &CmdArgs, 9281ad6265SDimitry Andric const char *Prefix, 9381ad6265SDimitry Andric const char *Suffix) const { 9481ad6265SDimitry Andric auto arg = [&](const char *Name) -> const char * { 9581ad6265SDimitry Andric return makeArgString(Args, Prefix, Name, Suffix); 9681ad6265SDimitry Andric }; 9781ad6265SDimitry Andric const SanitizerArgs &SanArgs = getSanitizerArgs(Args); 980b57cec5SDimitry Andric if (SanArgs.needsUbsanRt()) 9981ad6265SDimitry Andric CmdArgs.push_back(arg("SceDbgUBSanitizer_stub_weak")); 1000b57cec5SDimitry Andric if (SanArgs.needsAsanRt()) 10181ad6265SDimitry Andric CmdArgs.push_back(arg("SceDbgAddressSanitizer_stub_weak")); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 10481ad6265SDimitry Andric void toolchains::PS5CPU::addSanitizerArgs(const ArgList &Args, 10581ad6265SDimitry Andric ArgStringList &CmdArgs, 10681ad6265SDimitry Andric const char *Prefix, 10781ad6265SDimitry Andric const char *Suffix) const { 10881ad6265SDimitry Andric auto arg = [&](const char *Name) -> const char * { 10981ad6265SDimitry Andric return makeArgString(Args, Prefix, Name, Suffix); 11081ad6265SDimitry Andric }; 11181ad6265SDimitry Andric const SanitizerArgs &SanArgs = getSanitizerArgs(Args); 11281ad6265SDimitry Andric if (SanArgs.needsUbsanRt()) 11381ad6265SDimitry Andric CmdArgs.push_back(arg("SceUBSanitizer_nosubmission_stub_weak")); 11481ad6265SDimitry Andric if (SanArgs.needsAsanRt()) 11581ad6265SDimitry Andric CmdArgs.push_back(arg("SceAddressSanitizer_nosubmission_stub_weak")); 11681ad6265SDimitry Andric if (SanArgs.needsTsanRt()) 11781ad6265SDimitry Andric CmdArgs.push_back(arg("SceThreadSanitizer_nosubmission_stub_weak")); 11881ad6265SDimitry Andric } 11981ad6265SDimitry Andric 12081ad6265SDimitry Andric void tools::PScpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, 1215ffd83dbSDimitry Andric const InputInfo &Output, 1220b57cec5SDimitry Andric const InputInfoList &Inputs, 1230b57cec5SDimitry Andric const ArgList &Args, 1245ffd83dbSDimitry Andric const char *LinkingOutput) const { 12581ad6265SDimitry Andric auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain()); 12681ad6265SDimitry Andric const Driver &D = TC.getDriver(); 1270b57cec5SDimitry Andric ArgStringList CmdArgs; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // Silence warning for "clang -g foo.o -o foo" 1300b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_g_Group); 1310b57cec5SDimitry Andric // and "clang -emit-llvm foo.o -o foo" 1320b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_emit_llvm); 1330b57cec5SDimitry Andric // and for "clang -w foo.o -o foo". Other warning options are already 1340b57cec5SDimitry Andric // handled somewhere else. 1350b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_w); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric if (!D.SysRoot.empty()) 1380b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pie)) 1410b57cec5SDimitry Andric CmdArgs.push_back("-pie"); 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric if (Args.hasArg(options::OPT_rdynamic)) 1440b57cec5SDimitry Andric CmdArgs.push_back("-export-dynamic"); 1450b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared)) 14681ad6265SDimitry Andric CmdArgs.push_back("--shared"); 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric if (Output.isFilename()) { 1490b57cec5SDimitry Andric CmdArgs.push_back("-o"); 1500b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 1510b57cec5SDimitry Andric } else { 1520b57cec5SDimitry Andric assert(Output.isNothing() && "Invalid output."); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 155*bdd1243dSDimitry Andric const bool UseLTO = D.isUsingLTO(); 156*bdd1243dSDimitry Andric const bool UseJMC = 157*bdd1243dSDimitry Andric Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); 158*bdd1243dSDimitry Andric const bool IsPS4 = TC.getTriple().isPS4(); 159*bdd1243dSDimitry Andric const bool IsPS5 = TC.getTriple().isPS5(); 160*bdd1243dSDimitry Andric assert(IsPS4 || IsPS5); 161*bdd1243dSDimitry Andric 162*bdd1243dSDimitry Andric auto AddCodeGenFlag = [&](Twine Flag) { 163*bdd1243dSDimitry Andric const char *Prefix = nullptr; 164*bdd1243dSDimitry Andric if (IsPS4 && D.getLTOMode() == LTOK_Thin) 165*bdd1243dSDimitry Andric Prefix = "-lto-thin-debug-options="; 166*bdd1243dSDimitry Andric else if (IsPS4 && D.getLTOMode() == LTOK_Full) 167*bdd1243dSDimitry Andric Prefix = "-lto-debug-options="; 168*bdd1243dSDimitry Andric else if (IsPS5) 169*bdd1243dSDimitry Andric Prefix = "-plugin-opt="; 170*bdd1243dSDimitry Andric else 171*bdd1243dSDimitry Andric llvm_unreachable("new LTO mode?"); 172*bdd1243dSDimitry Andric 173*bdd1243dSDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine(Prefix) + Flag)); 174*bdd1243dSDimitry Andric }; 175*bdd1243dSDimitry Andric 176*bdd1243dSDimitry Andric if (UseLTO) { 177*bdd1243dSDimitry Andric // We default to creating the arange section, but LTO does not. Enable it 178*bdd1243dSDimitry Andric // here. 179*bdd1243dSDimitry Andric AddCodeGenFlag("-generate-arange-section"); 180*bdd1243dSDimitry Andric 181*bdd1243dSDimitry Andric // This tells LTO to perform JustMyCode instrumentation. 182*bdd1243dSDimitry Andric if (UseJMC) 183*bdd1243dSDimitry Andric AddCodeGenFlag("-enable-jmc-instrument"); 184*bdd1243dSDimitry Andric 185*bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) 186*bdd1243dSDimitry Andric AddCodeGenFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); 187*bdd1243dSDimitry Andric } 188*bdd1243dSDimitry Andric 1890b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 19081ad6265SDimitry Andric TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_L); 1930b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 1940b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_e); 1950b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_s); 1960b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_t); 1970b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_r); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 2000b57cec5SDimitry Andric CmdArgs.push_back("--no-demangle"); 2010b57cec5SDimitry Andric 20281ad6265SDimitry Andric AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pthread)) { 2050b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 208*bdd1243dSDimitry Andric if (UseJMC) { 209*bdd1243dSDimitry Andric CmdArgs.push_back("--whole-archive"); 210*bdd1243dSDimitry Andric if (IsPS4) 211*bdd1243dSDimitry Andric CmdArgs.push_back("-lSceDbgJmc"); 212*bdd1243dSDimitry Andric else 213*bdd1243dSDimitry Andric CmdArgs.push_back("-lSceJmc_nosubmission"); 214*bdd1243dSDimitry Andric CmdArgs.push_back("--no-whole-archive"); 215*bdd1243dSDimitry Andric } 216*bdd1243dSDimitry Andric 2175ffd83dbSDimitry Andric if (Args.hasArg(options::OPT_fuse_ld_EQ)) { 2185ffd83dbSDimitry Andric D.Diag(diag::err_drv_unsupported_opt_for_target) 21981ad6265SDimitry Andric << "-fuse-ld" << TC.getTriple().str(); 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric 22281ad6265SDimitry Andric std::string LdName = TC.qualifyPSCmdName(TC.getLinkerBaseName()); 22381ad6265SDimitry Andric const char *Exec = Args.MakeArgString(TC.GetProgramPath(LdName.c_str())); 2240b57cec5SDimitry Andric 225e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 226e8d8bef9SDimitry Andric ResponseFileSupport::AtFileUTF8(), 227e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric 23081ad6265SDimitry Andric toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple, 23181ad6265SDimitry Andric const ArgList &Args, StringRef Platform, 23281ad6265SDimitry Andric const char *EnvVar) 2330b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 2340b57cec5SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_static)) 23581ad6265SDimitry Andric D.Diag(clang::diag::err_drv_unsupported_opt_for_target) 23681ad6265SDimitry Andric << "-static" << Platform; 2370b57cec5SDimitry Andric 23881ad6265SDimitry Andric // Determine where to find the PS4/PS5 libraries. We use the EnvVar 2390b57cec5SDimitry Andric // if it exists; otherwise use the driver's installation path, which 2400b57cec5SDimitry Andric // should be <SDK_DIR>/host_tools/bin. 2410b57cec5SDimitry Andric 24281ad6265SDimitry Andric SmallString<512> SDKDir; 24381ad6265SDimitry Andric if (const char *EnvValue = getenv(EnvVar)) { 2440b57cec5SDimitry Andric if (!llvm::sys::fs::exists(EnvValue)) 24581ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_ps_sdk_dir) << EnvVar << EnvValue; 24681ad6265SDimitry Andric SDKDir = EnvValue; 2470b57cec5SDimitry Andric } else { 24881ad6265SDimitry Andric SDKDir = D.Dir; 24981ad6265SDimitry Andric llvm::sys::path::append(SDKDir, "/../../"); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 25281ad6265SDimitry Andric // By default, the driver won't report a warning if it can't find the 25381ad6265SDimitry Andric // SDK include or lib directories. This behavior could be changed if 2540b57cec5SDimitry Andric // -Weverything or -Winvalid-or-nonexistent-directory options are passed. 2550b57cec5SDimitry Andric // If -isysroot was passed, use that as the SDK base path. 2560b57cec5SDimitry Andric std::string PrefixDir; 2570b57cec5SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 2580b57cec5SDimitry Andric PrefixDir = A->getValue(); 2590b57cec5SDimitry Andric if (!llvm::sys::fs::exists(PrefixDir)) 26081ad6265SDimitry Andric D.Diag(clang::diag::warn_missing_sysroot) << PrefixDir; 2610b57cec5SDimitry Andric } else 26281ad6265SDimitry Andric PrefixDir = std::string(SDKDir.str()); 2630b57cec5SDimitry Andric 26481ad6265SDimitry Andric SmallString<512> SDKIncludeDir(PrefixDir); 26581ad6265SDimitry Andric llvm::sys::path::append(SDKIncludeDir, "target/include"); 2660b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdinc) && 2670b57cec5SDimitry Andric !Args.hasArg(options::OPT_nostdlibinc) && 2680b57cec5SDimitry Andric !Args.hasArg(options::OPT_isysroot) && 2690b57cec5SDimitry Andric !Args.hasArg(options::OPT__sysroot_EQ) && 27081ad6265SDimitry Andric !llvm::sys::fs::exists(SDKIncludeDir)) { 27181ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) 27281ad6265SDimitry Andric << Twine(Platform, " system headers").str() << SDKIncludeDir; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric 27581ad6265SDimitry Andric SmallString<512> SDKLibDir(SDKDir); 27681ad6265SDimitry Andric llvm::sys::path::append(SDKLibDir, "target/lib"); 2770b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && 2780b57cec5SDimitry Andric !Args.hasArg(options::OPT_nodefaultlibs) && 2790b57cec5SDimitry Andric !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) && 2800b57cec5SDimitry Andric !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) && 2810b57cec5SDimitry Andric !Args.hasArg(options::OPT_emit_ast) && 28281ad6265SDimitry Andric !llvm::sys::fs::exists(SDKLibDir)) { 28381ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) 28481ad6265SDimitry Andric << Twine(Platform, " system libraries").str() << SDKLibDir; 2850b57cec5SDimitry Andric return; 2860b57cec5SDimitry Andric } 28781ad6265SDimitry Andric getFilePaths().push_back(std::string(SDKLibDir.str())); 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric Tool *toolchains::PS4CPU::buildAssembler() const { 29181ad6265SDimitry Andric return new tools::PScpu::Assembler(*this); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 29481ad6265SDimitry Andric Tool *toolchains::PS5CPU::buildAssembler() const { 29581ad6265SDimitry Andric // PS5 does not support an external assembler. 29681ad6265SDimitry Andric getDriver().Diag(clang::diag::err_no_external_assembler); 29781ad6265SDimitry Andric return nullptr; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 30081ad6265SDimitry Andric Tool *toolchains::PS4PS5Base::buildLinker() const { 30181ad6265SDimitry Andric return new tools::PScpu::Linker(*this); 30281ad6265SDimitry Andric } 3030b57cec5SDimitry Andric 30481ad6265SDimitry Andric SanitizerMask toolchains::PS4PS5Base::getSupportedSanitizers() const { 3050b57cec5SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 3060b57cec5SDimitry Andric Res |= SanitizerKind::Address; 3070b57cec5SDimitry Andric Res |= SanitizerKind::PointerCompare; 3080b57cec5SDimitry Andric Res |= SanitizerKind::PointerSubtract; 3090b57cec5SDimitry Andric Res |= SanitizerKind::Vptr; 3100b57cec5SDimitry Andric return Res; 3110b57cec5SDimitry Andric } 3125ffd83dbSDimitry Andric 31381ad6265SDimitry Andric SanitizerMask toolchains::PS5CPU::getSupportedSanitizers() const { 31481ad6265SDimitry Andric SanitizerMask Res = PS4PS5Base::getSupportedSanitizers(); 31581ad6265SDimitry Andric Res |= SanitizerKind::Thread; 31681ad6265SDimitry Andric return Res; 31781ad6265SDimitry Andric } 31881ad6265SDimitry Andric 31981ad6265SDimitry Andric void toolchains::PS4PS5Base::addClangTargetOptions( 320e8d8bef9SDimitry Andric const ArgList &DriverArgs, ArgStringList &CC1Args, 3215ffd83dbSDimitry Andric Action::OffloadKind DeviceOffloadingKind) const { 32281ad6265SDimitry Andric // PS4/PS5 do not use init arrays. 3235ffd83dbSDimitry Andric if (DriverArgs.hasArg(options::OPT_fuse_init_array)) { 3245ffd83dbSDimitry Andric Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array); 3255ffd83dbSDimitry Andric getDriver().Diag(clang::diag::err_drv_unsupported_opt_for_target) 3265ffd83dbSDimitry Andric << A->getAsString(DriverArgs) << getTriple().str(); 3275ffd83dbSDimitry Andric } 3285ffd83dbSDimitry Andric 3295ffd83dbSDimitry Andric CC1Args.push_back("-fno-use-init-array"); 330e8d8bef9SDimitry Andric 331e8d8bef9SDimitry Andric const Arg *A = 332e8d8bef9SDimitry Andric DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, 333e8d8bef9SDimitry Andric options::OPT_fno_visibility_from_dllstorageclass); 334e8d8bef9SDimitry Andric if (!A || 335e8d8bef9SDimitry Andric A->getOption().matches(options::OPT_fvisibility_from_dllstorageclass)) { 336e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-from-dllstorageclass"); 337e8d8bef9SDimitry Andric 338e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_dllexport_EQ)) 339e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, options::OPT_fvisibility_dllexport_EQ); 340e8d8bef9SDimitry Andric else 341e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-dllexport=protected"); 342e8d8bef9SDimitry Andric 343e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_nodllstorageclass_EQ)) 344e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, 345e8d8bef9SDimitry Andric options::OPT_fvisibility_nodllstorageclass_EQ); 346e8d8bef9SDimitry Andric else 347e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-nodllstorageclass=hidden"); 348e8d8bef9SDimitry Andric 349e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_externs_dllimport_EQ)) 350e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, 351e8d8bef9SDimitry Andric options::OPT_fvisibility_externs_dllimport_EQ); 352e8d8bef9SDimitry Andric else 353e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-externs-dllimport=default"); 354e8d8bef9SDimitry Andric 355e8d8bef9SDimitry Andric if (DriverArgs.hasArg( 356e8d8bef9SDimitry Andric options::OPT_fvisibility_externs_nodllstorageclass_EQ)) 357e8d8bef9SDimitry Andric DriverArgs.AddLastArg( 358e8d8bef9SDimitry Andric CC1Args, options::OPT_fvisibility_externs_nodllstorageclass_EQ); 359e8d8bef9SDimitry Andric else 360e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default"); 361e8d8bef9SDimitry Andric } 3625ffd83dbSDimitry Andric } 36381ad6265SDimitry Andric 36481ad6265SDimitry Andric // PS4 toolchain. 36581ad6265SDimitry Andric toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, 36681ad6265SDimitry Andric const llvm::opt::ArgList &Args) 36781ad6265SDimitry Andric : PS4PS5Base(D, Triple, Args, "PS4", "SCE_ORBIS_SDK_DIR") {} 36881ad6265SDimitry Andric 36981ad6265SDimitry Andric // PS5 toolchain. 37081ad6265SDimitry Andric toolchains::PS5CPU::PS5CPU(const Driver &D, const llvm::Triple &Triple, 37181ad6265SDimitry Andric const llvm::opt::ArgList &Args) 37281ad6265SDimitry Andric : PS4PS5Base(D, Triple, Args, "PS5", "SCE_PROSPERO_SDK_DIR") {} 373