brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.7 KiB · 5b5b560 Raw
654 lines · cpp
1//===--- PS4CPU.cpp - PS4CPU ToolChain Implementations ----------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "PS4CPU.h"10#include "clang/Config/config.h"11#include "clang/Driver/CommonArgs.h"12#include "clang/Driver/Compilation.h"13#include "clang/Driver/Driver.h"14#include "clang/Driver/SanitizerArgs.h"15#include "clang/Options/Options.h"16#include "llvm/Option/ArgList.h"17#include "llvm/Support/FileSystem.h"18#include "llvm/Support/Path.h"19#include <cstdlib> // ::getenv20 21using namespace clang::driver;22using namespace clang;23using namespace llvm::opt;24 25// Helper to paste bits of an option together and return a saved string.26static const char *makeArgString(const ArgList &Args, const char *Prefix,27                                 const char *Base, const char *Suffix) {28  // Basically "Prefix + Base + Suffix" all converted to Twine then saved.29  return Args.MakeArgString(Twine(StringRef(Prefix), Base) + Suffix);30}31 32void tools::PScpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args,33                                    ArgStringList &CmdArgs) {34  assert(TC.getTriple().isPS());35  auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC);36 37  if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,38                    false) ||39       Args.hasFlag(options::OPT_fprofile_generate,40                    options::OPT_fno_profile_generate, false) ||41       Args.hasFlag(options::OPT_fprofile_generate_EQ,42                    options::OPT_fno_profile_generate, false) ||43       Args.hasFlag(options::OPT_fprofile_instr_generate,44                    options::OPT_fno_profile_instr_generate, false) ||45       Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,46                    options::OPT_fno_profile_instr_generate, false) ||47       Args.hasFlag(options::OPT_fcs_profile_generate,48                    options::OPT_fno_profile_generate, false) ||49       Args.hasFlag(options::OPT_fcs_profile_generate_EQ,50                    options::OPT_fno_profile_generate, false) ||51       Args.hasArg(options::OPT_fcreate_profile) ||52       Args.hasArg(options::OPT_coverage)))53    CmdArgs.push_back(makeArgString(54        Args, "--dependent-lib=", PSTC.getProfileRTLibName(), ""));55}56 57void tools::PScpu::Assembler::ConstructJob(Compilation &C, const JobAction &JA,58                                           const InputInfo &Output,59                                           const InputInfoList &Inputs,60                                           const ArgList &Args,61                                           const char *LinkingOutput) const {62  auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain());63  claimNoWarnArgs(Args);64  ArgStringList CmdArgs;65 66  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);67 68  CmdArgs.push_back("-o");69  CmdArgs.push_back(Output.getFilename());70 71  assert(Inputs.size() == 1 && "Unexpected number of inputs.");72  const InputInfo &Input = Inputs[0];73  assert(Input.isFilename() && "Invalid input.");74  CmdArgs.push_back(Input.getFilename());75 76  std::string AsName = TC.qualifyPSCmdName("as");77  const char *Exec = Args.MakeArgString(TC.GetProgramPath(AsName.c_str()));78  C.addCommand(std::make_unique<Command>(JA, *this,79                                         ResponseFileSupport::AtFileUTF8(),80                                         Exec, CmdArgs, Inputs, Output));81}82 83void tools::PScpu::addSanitizerArgs(const ToolChain &TC, const ArgList &Args,84                                    ArgStringList &CmdArgs) {85  assert(TC.getTriple().isPS());86  auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC);87  PSTC.addSanitizerArgs(Args, CmdArgs, "--dependent-lib=lib", ".a");88}89 90void toolchains::PS4CPU::addSanitizerArgs(const ArgList &Args,91                                          ArgStringList &CmdArgs,92                                          const char *Prefix,93                                          const char *Suffix) const {94  auto arg = [&](const char *Name) -> const char * {95    return makeArgString(Args, Prefix, Name, Suffix);96  };97  const SanitizerArgs &SanArgs = getSanitizerArgs(Args);98  if (SanArgs.needsUbsanRt())99    CmdArgs.push_back(arg("SceDbgUBSanitizer_stub_weak"));100  if (SanArgs.needsAsanRt())101    CmdArgs.push_back(arg("SceDbgAddressSanitizer_stub_weak"));102}103 104void toolchains::PS5CPU::addSanitizerArgs(const ArgList &Args,105                                          ArgStringList &CmdArgs,106                                          const char *Prefix,107                                          const char *Suffix) const {108  auto arg = [&](const char *Name) -> const char * {109    return makeArgString(Args, Prefix, Name, Suffix);110  };111  const SanitizerArgs &SanArgs = getSanitizerArgs(Args);112  if (SanArgs.needsUbsanRt())113    CmdArgs.push_back(arg("SceUBSanitizer_nosubmission_stub_weak"));114  if (SanArgs.needsAsanRt())115    CmdArgs.push_back(arg("SceAddressSanitizer_nosubmission_stub_weak"));116  if (SanArgs.needsTsanRt())117    CmdArgs.push_back(arg("SceThreadSanitizer_nosubmission_stub_weak"));118}119 120void tools::PS4cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,121                                         const InputInfo &Output,122                                         const InputInfoList &Inputs,123                                         const ArgList &Args,124                                         const char *LinkingOutput) const {125  auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain());126  const Driver &D = TC.getDriver();127  ArgStringList CmdArgs;128 129  // Silence warning for "clang -g foo.o -o foo"130  Args.ClaimAllArgs(options::OPT_g_Group);131  // and "clang -emit-llvm foo.o -o foo"132  Args.ClaimAllArgs(options::OPT_emit_llvm);133  // and for "clang -w foo.o -o foo". Other warning options are already134  // handled somewhere else.135  Args.ClaimAllArgs(options::OPT_w);136 137  CmdArgs.push_back(138      Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));139 140  if (Args.hasArg(options::OPT_pie))141    CmdArgs.push_back("-pie");142 143  if (Args.hasArg(options::OPT_static))144    CmdArgs.push_back("-static");145  if (Args.hasArg(options::OPT_rdynamic))146    CmdArgs.push_back("-export-dynamic");147  if (Args.hasArg(options::OPT_shared))148    CmdArgs.push_back("--shared");149 150  assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");151  if (Output.isFilename()) {152    CmdArgs.push_back("-o");153    CmdArgs.push_back(Output.getFilename());154  }155 156  const bool UseJMC =157      Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false);158 159  const char *LTOArgs = "";160  auto AddLTOFlag = [&](Twine Flag) {161    LTOArgs = Args.MakeArgString(Twine(LTOArgs) + " " + Flag);162  };163 164  // If the linker sees bitcode objects it will perform LTO. We can't tell165  // whether or not that will be the case at this point. So, unconditionally166  // pass LTO options to ensure proper codegen, metadata production, etc if167  // LTO indeed occurs.168  if (Args.hasFlag(options::OPT_funified_lto, options::OPT_fno_unified_lto,169                   true))170    CmdArgs.push_back(D.getLTOMode() == LTOK_Thin ? "--lto=thin"171                                                  : "--lto=full");172  if (UseJMC)173    AddLTOFlag("-enable-jmc-instrument");174 175  if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir))176    AddLTOFlag(Twine("-crash-diagnostics-dir=") + A->getValue());177 178  if (StringRef Threads = getLTOParallelism(Args, D); !Threads.empty())179    AddLTOFlag(Twine("-threads=") + Threads);180 181  if (*LTOArgs)182    CmdArgs.push_back(183        Args.MakeArgString(Twine("-lto-debug-options=") + LTOArgs));184 185  // Sanitizer runtimes must be supplied before all other objects and libs.186  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))187    TC.addSanitizerArgs(Args, CmdArgs, "-l", "");188 189  // Other drivers typically add library search paths (`-L`) here via190  // TC.AddFilePathLibArgs(). We don't do that on PS4 as the PS4 linker191  // searches those locations by default.192  Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,193                            options::OPT_s, options::OPT_t});194 195  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))196    CmdArgs.push_back("--no-demangle");197 198  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);199 200  if (Args.hasArg(options::OPT_pthread)) {201    CmdArgs.push_back("-lpthread");202  }203 204  if (UseJMC) {205    CmdArgs.push_back("--whole-archive");206    CmdArgs.push_back("-lSceDbgJmc");207    CmdArgs.push_back("--no-whole-archive");208  }209 210  if (Args.hasArg(options::OPT_fuse_ld_EQ)) {211    D.Diag(diag::err_drv_unsupported_opt_for_target)212        << "-fuse-ld" << TC.getTriple().str();213  }214 215  std::string LdName = TC.qualifyPSCmdName(TC.getLinkerBaseName());216  const char *Exec = Args.MakeArgString(TC.GetProgramPath(LdName.c_str()));217 218  C.addCommand(std::make_unique<Command>(JA, *this,219                                         ResponseFileSupport::AtFileUTF8(),220                                         Exec, CmdArgs, Inputs, Output));221}222 223void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,224                                         const InputInfo &Output,225                                         const InputInfoList &Inputs,226                                         const ArgList &Args,227                                         const char *LinkingOutput) const {228  auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain());229  const Driver &D = TC.getDriver();230  ArgStringList CmdArgs;231 232  const bool Relocatable = Args.hasArg(options::OPT_r);233  const bool Shared = Args.hasArg(options::OPT_shared);234  const bool Static = Args.hasArg(options::OPT_static);235 236  // Silence warning for "clang -g foo.o -o foo"237  Args.ClaimAllArgs(options::OPT_g_Group);238  // and "clang -emit-llvm foo.o -o foo"239  Args.ClaimAllArgs(options::OPT_emit_llvm);240  // and for "clang -w foo.o -o foo". Other warning options are already241  // handled somewhere else.242  Args.ClaimAllArgs(options::OPT_w);243 244  CmdArgs.push_back("-m");245  CmdArgs.push_back("elf_x86_64_fbsd");246 247  CmdArgs.push_back(248      Args.MakeArgString("--sysroot=" + TC.getSDKLibraryRootDir()));249 250  // Default to PIE for non-static executables.251  const bool PIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie,252                                !Relocatable && !Shared && !Static);253  if (PIE)254    CmdArgs.push_back("-pie");255 256  if (!Relocatable) {257    CmdArgs.push_back("--eh-frame-hdr");258    CmdArgs.push_back("--hash-style=sysv");259 260    // Add a build-id by default to allow the PlayStation symbol server to261    // index the symbols. `uuid` is the cheapest fool-proof method.262    // (The non-determinism and alternative methods are noted in the downstream263    // PlayStation docs).264    // Static executables are only used for a handful of specialized components,265    // where the extra section is not wanted.266    if (!Static)267      CmdArgs.push_back("--build-id=uuid");268 269    // All references are expected to be resolved at static link time for both270    // executables and dynamic libraries. This has been the default linking271    // behaviour for numerous PlayStation generations.272    CmdArgs.push_back("--unresolved-symbols=report-all");273 274    // Lazy binding of PLTs is not supported on PlayStation. They are placed in275    // the RelRo segment.276    CmdArgs.push_back("-z");277    CmdArgs.push_back("now");278 279    // Don't export linker-generated __start/stop... section bookends.280    CmdArgs.push_back("-z");281    CmdArgs.push_back("start-stop-visibility=hidden");282 283    // DT_DEBUG is not supported on PlayStation.284    CmdArgs.push_back("-z");285    CmdArgs.push_back("rodynamic");286 287    CmdArgs.push_back("-z");288    CmdArgs.push_back("common-page-size=0x4000");289 290    CmdArgs.push_back("-z");291    CmdArgs.push_back("max-page-size=0x4000");292 293    // Patch relocated regions of DWARF whose targets are eliminated at link294    // time with specific tombstones, such that they're recognisable by the295    // PlayStation debugger.296    CmdArgs.push_back("-z");297    CmdArgs.push_back("dead-reloc-in-nonalloc=.debug_*=0xffffffffffffffff");298    CmdArgs.push_back("-z");299    CmdArgs.push_back(300        "dead-reloc-in-nonalloc=.debug_ranges=0xfffffffffffffffe");301    CmdArgs.push_back("-z");302    CmdArgs.push_back("dead-reloc-in-nonalloc=.debug_loc=0xfffffffffffffffe");303 304    // The PlayStation loader expects linked objects to be laid out in a305    // particular way. This is achieved by linker scripts that are supplied306    // with the SDK. The scripts are inside <sdkroot>/target/lib, which is307    // added as a search path elsewhere.308    // "PRX" has long stood for "PlayStation Relocatable eXecutable".309    if (!Args.hasArgNoClaim(options::OPT_T)) {310      CmdArgs.push_back("--default-script");311      CmdArgs.push_back(Static   ? "static.script"312                        : Shared ? "prx.script"313                                 : "main.script");314    }315  }316 317  if (Static)318    CmdArgs.push_back("-static");319  if (Args.hasArg(options::OPT_rdynamic))320    CmdArgs.push_back("-export-dynamic");321  if (Shared)322    CmdArgs.push_back("--shared");323 324  // Provide a base address for non-PIE executables. This includes cases where325  // -static is supplied without -pie.326  if (!Relocatable && !Shared && !PIE)327    CmdArgs.push_back("--image-base=0x400000");328 329  assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");330  if (Output.isFilename()) {331    CmdArgs.push_back("-o");332    CmdArgs.push_back(Output.getFilename());333  }334 335  const bool UseJMC =336      Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false);337 338  auto AddLTOFlag = [&](Twine Flag) {339    CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=") + Flag));340  };341 342  // If the linker sees bitcode objects it will perform LTO. We can't tell343  // whether or not that will be the case at this point. So, unconditionally344  // pass LTO options to ensure proper codegen, metadata production, etc if345  // LTO indeed occurs.346 347  tools::addDTLTOOptions(TC, Args, CmdArgs);348 349  if (Args.hasFlag(options::OPT_funified_lto, options::OPT_fno_unified_lto,350                   true))351    CmdArgs.push_back(D.getLTOMode() == LTOK_Thin ? "--lto=thin"352                                                  : "--lto=full");353 354  AddLTOFlag("-emit-jump-table-sizes-section");355 356  if (UseJMC)357    AddLTOFlag("-enable-jmc-instrument");358 359  if (Args.hasFlag(options::OPT_fstack_size_section,360                   options::OPT_fno_stack_size_section, false))361    AddLTOFlag("-stack-size-section");362 363  if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir))364    AddLTOFlag(Twine("-crash-diagnostics-dir=") + A->getValue());365 366  if (StringRef Jobs = getLTOParallelism(Args, D); !Jobs.empty())367    AddLTOFlag(Twine("jobs=") + Jobs);368 369  Args.AddAllArgs(CmdArgs, options::OPT_L);370  TC.AddFilePathLibArgs(Args, CmdArgs);371  Args.addAllArgs(CmdArgs,372                  {options::OPT_T_Group, options::OPT_s, options::OPT_t});373 374  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))375    CmdArgs.push_back("--no-demangle");376 377  // Sanitizer runtimes must be supplied before all other objects and libs.378  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))379    TC.addSanitizerArgs(Args, CmdArgs, "-l", "");380 381  const bool AddStartFiles =382      !Relocatable &&383      !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib);384 385  auto AddCRTObject = [&](StringRef Name) {386    // CRT objects can be found on user supplied library paths. This is387    // an entrenched expectation on PlayStation.388    CmdArgs.push_back(Args.MakeArgString("-l:" + Name));389  };390 391  if (AddStartFiles) {392    if (!Shared)393      AddCRTObject("crt1.o");394    AddCRTObject("crti.o");395    AddCRTObject(Shared   ? "crtbeginS.o"396                 : Static ? "crtbeginT.o"397                          : "crtbegin.o");398  }399 400  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);401 402  if (!Relocatable &&403      !Args.hasArg(options::OPT_nodefaultlibs, options::OPT_nostdlib)) {404 405    if (UseJMC) {406      CmdArgs.push_back("--push-state");407      CmdArgs.push_back("--whole-archive");408      CmdArgs.push_back("-lSceJmc_nosubmission");409      CmdArgs.push_back("--pop-state");410    }411 412    if (Args.hasArg(options::OPT_pthread))413      CmdArgs.push_back("-lpthread");414 415    if (Static) {416      if (!Args.hasArg(options::OPT_nostdlibxx))417        CmdArgs.push_back("-lstdc++");418      if (!Args.hasArg(options::OPT_nolibc)) {419        CmdArgs.push_back("-lm");420        CmdArgs.push_back("-lc");421      }422 423      CmdArgs.push_back("-lcompiler_rt");424      CmdArgs.push_back("-lkernel");425    } else {426      // The C and C++ libraries are combined.427      if (!Args.hasArg(options::OPT_nolibc, options::OPT_nostdlibxx))428        CmdArgs.push_back("-lc_stub_weak");429 430      CmdArgs.push_back("-lkernel_stub_weak");431    }432  }433  if (AddStartFiles) {434    AddCRTObject(Shared ? "crtendS.o" : "crtend.o");435    AddCRTObject("crtn.o");436  }437 438  if (Args.hasArg(options::OPT_fuse_ld_EQ)) {439    D.Diag(diag::err_drv_unsupported_opt_for_target)440        << "-fuse-ld" << TC.getTriple().str();441  }442 443  std::string LdName = TC.qualifyPSCmdName(TC.getLinkerBaseName());444  const char *Exec = Args.MakeArgString(TC.GetProgramPath(LdName.c_str()));445 446  C.addCommand(std::make_unique<Command>(JA, *this,447                                         ResponseFileSupport::AtFileUTF8(),448                                         Exec, CmdArgs, Inputs, Output));449}450 451toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple,452                                   const ArgList &Args, StringRef Platform,453                                   const char *EnvVar)454    : Generic_ELF(D, Triple, Args) {455  // Determine the baseline SDK directory from the environment, else456  // the driver's location, which should be <SDK_DIR>/host_tools/bin.457  SmallString<128> SDKRootDir;458  SmallString<80> Whence;459  if (const char *EnvValue = getenv(EnvVar)) {460    SDKRootDir = EnvValue;461    Whence = {"environment variable '", EnvVar, "'"};462  } else {463    SDKRootDir = D.Dir + "/../../";464    Whence = "compiler's location";465  }466 467  // Allow --sysroot= to override the root directory for header and library468  // search, and -isysroot to override header search. If both are specified,469  // -isysroot overrides --sysroot for header search.470  auto OverrideRoot = [&](const options::ID &Opt, std::string &Root,471                          StringRef Default) {472    if (const Arg *A = Args.getLastArg(Opt)) {473      Root = A->getValue();474      if (!llvm::sys::fs::exists(Root))475        D.Diag(clang::diag::warn_missing_sysroot) << Root;476      return true;477    }478    Root = Default.str();479    return false;480  };481 482  bool CustomSysroot =483      OverrideRoot(options::OPT__sysroot_EQ, SDKLibraryRootDir, SDKRootDir);484  bool CustomISysroot =485      OverrideRoot(options::OPT_isysroot, SDKHeaderRootDir, SDKLibraryRootDir);486 487  // Emit warnings if parts of the SDK are missing, unless the user has taken488  // control of header or library search. If we're not linking, don't check489  // for missing libraries.490  auto CheckSDKPartExists = [&](StringRef Dir, StringRef Desc) {491    // In ThinLTO code generation mode SDK files are not required.492    if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ))493      return true;494    if (llvm::sys::fs::exists(Dir))495      return true;496    D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected)497        << (Twine(Platform) + " " + Desc).str() << Dir << Whence;498    return false;499  };500 501  bool Linking = !Args.hasArg(options::OPT_E, options::OPT_c, options::OPT_S,502                              options::OPT_emit_ast);503  if (Linking) {504    SmallString<128> Dir(SDKLibraryRootDir);505    llvm::sys::path::append(Dir, "target/lib");506    if (CheckSDKPartExists(Dir, "system libraries"))507      getFilePaths().push_back(std::string(Dir));508  }509  if (!CustomSysroot && !CustomISysroot &&510      !Args.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc)) {511    SmallString<128> Dir(SDKHeaderRootDir);512    llvm::sys::path::append(Dir, "target/include");513    CheckSDKPartExists(Dir, "system headers");514  }515 516  getFilePaths().push_back(".");517}518 519void toolchains::PS4PS5Base::AddClangSystemIncludeArgs(520    const ArgList &DriverArgs, ArgStringList &CC1Args) const {521  const Driver &D = getDriver();522 523  if (DriverArgs.hasArg(options::OPT_nostdinc))524    return;525 526  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {527    SmallString<128> Dir(D.ResourceDir);528    llvm::sys::path::append(Dir, "include");529    addSystemInclude(DriverArgs, CC1Args, Dir.str());530  }531 532  if (DriverArgs.hasArg(options::OPT_nostdlibinc))533    return;534 535  addExternCSystemInclude(DriverArgs, CC1Args,536                          SDKHeaderRootDir + "/target/include");537  addExternCSystemInclude(DriverArgs, CC1Args,538                          SDKHeaderRootDir + "/target/include_common");539}540 541Tool *toolchains::PS4CPU::buildAssembler() const {542  return new tools::PScpu::Assembler(*this);543}544 545Tool *toolchains::PS4CPU::buildLinker() const {546  return new tools::PS4cpu::Linker(*this);547}548 549Tool *toolchains::PS5CPU::buildAssembler() const {550  // PS5 does not support an external assembler.551  getDriver().Diag(clang::diag::err_no_external_assembler);552  return nullptr;553}554 555Tool *toolchains::PS5CPU::buildLinker() const {556  return new tools::PS5cpu::Linker(*this);557}558 559SanitizerMask toolchains::PS4PS5Base::getSupportedSanitizers() const {560  SanitizerMask Res = ToolChain::getSupportedSanitizers();561  Res |= SanitizerKind::Address;562  Res |= SanitizerKind::PointerCompare;563  Res |= SanitizerKind::PointerSubtract;564  Res |= SanitizerKind::Vptr;565  return Res;566}567 568SanitizerMask toolchains::PS5CPU::getSupportedSanitizers() const {569  SanitizerMask Res = PS4PS5Base::getSupportedSanitizers();570  Res |= SanitizerKind::Thread;571  return Res;572}573 574void toolchains::PS4PS5Base::addClangTargetOptions(575    const ArgList &DriverArgs, ArgStringList &CC1Args,576    Action::OffloadKind DeviceOffloadingKind) const {577  // PS4/PS5 do not use init arrays.578  if (DriverArgs.hasArg(options::OPT_fuse_init_array)) {579    Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array);580    getDriver().Diag(clang::diag::err_drv_unsupported_opt_for_target)581        << A->getAsString(DriverArgs) << getTriple().str();582  }583 584  CC1Args.push_back("-fno-use-init-array");585 586  // Default to `hidden` visibility for PS5.587  if (getTriple().isPS5() &&588      !DriverArgs.hasArg(options::OPT_fvisibility_EQ,589                         options::OPT_fvisibility_ms_compat))590    CC1Args.push_back("-fvisibility=hidden");591 592  // Default to -fvisibility-global-new-delete=source for PS5.593  if (getTriple().isPS5() &&594      !DriverArgs.hasArg(options::OPT_fvisibility_global_new_delete_EQ,595                         options::OPT_fvisibility_global_new_delete_hidden))596    CC1Args.push_back("-fvisibility-global-new-delete=source");597 598  const Arg *A =599      DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass,600                            options::OPT_fno_visibility_from_dllstorageclass);601  if (!A ||602      A->getOption().matches(options::OPT_fvisibility_from_dllstorageclass)) {603    CC1Args.push_back("-fvisibility-from-dllstorageclass");604 605    if (DriverArgs.hasArg(options::OPT_fvisibility_dllexport_EQ))606      DriverArgs.AddLastArg(CC1Args, options::OPT_fvisibility_dllexport_EQ);607    else608      CC1Args.push_back("-fvisibility-dllexport=protected");609 610    // For PS4 we override the visibilty of globals definitions without611    // dllimport or  dllexport annotations.612    if (DriverArgs.hasArg(options::OPT_fvisibility_nodllstorageclass_EQ))613      DriverArgs.AddLastArg(CC1Args,614                            options::OPT_fvisibility_nodllstorageclass_EQ);615    else if (getTriple().isPS4())616      CC1Args.push_back("-fvisibility-nodllstorageclass=hidden");617    else618      CC1Args.push_back("-fvisibility-nodllstorageclass=keep");619 620    if (DriverArgs.hasArg(options::OPT_fvisibility_externs_dllimport_EQ))621      DriverArgs.AddLastArg(CC1Args,622                            options::OPT_fvisibility_externs_dllimport_EQ);623    else624      CC1Args.push_back("-fvisibility-externs-dllimport=default");625 626    // For PS4 we override the visibilty of external globals without627    // dllimport or  dllexport annotations.628    if (DriverArgs.hasArg(629            options::OPT_fvisibility_externs_nodllstorageclass_EQ))630      DriverArgs.AddLastArg(631          CC1Args, options::OPT_fvisibility_externs_nodllstorageclass_EQ);632    else if (getTriple().isPS4())633      CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default");634    else635      CC1Args.push_back("-fvisibility-externs-nodllstorageclass=keep");636  }637 638  // Enable jump table sizes section for PS5.639  if (getTriple().isPS5()) {640    CC1Args.push_back("-mllvm");641    CC1Args.push_back("-emit-jump-table-sizes-section");642  }643}644 645// PS4 toolchain.646toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple,647                           const llvm::opt::ArgList &Args)648    : PS4PS5Base(D, Triple, Args, "PS4", "SCE_ORBIS_SDK_DIR") {}649 650// PS5 toolchain.651toolchains::PS5CPU::PS5CPU(const Driver &D, const llvm::Triple &Triple,652                           const llvm::opt::ArgList &Args)653    : PS4PS5Base(D, Triple, Args, "PS5", "SCE_PROSPERO_SDK_DIR") {}654