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