ladybird/Toolchain/Patches/llvm/0003-Driver-Add-support-for-SerenityOS.patch
2023-08-11 13:35:17 +02:00

591 lines
21 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Bertalan <dani@danielbertalan.dev>
Date: Thu, 14 Apr 2022 10:09:50 +0200
Subject: [PATCH] [Driver] Add support for SerenityOS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds support for the `$arch-pc-serenity` target to the Clang front end.
This makes the compiler look for libraries and headers in the right
places, and enables some security mitigations like stack-smashing
protection and position-independent code by default.
Co-authored-by: kleines Filmröllchen <filmroellchen@serenityos.org>
---
clang/lib/Basic/Targets.cpp | 8 +
clang/lib/Basic/Targets/OSTargets.h | 18 ++
clang/lib/Driver/CMakeLists.txt | 1 +
clang/lib/Driver/Driver.cpp | 4 +
clang/lib/Driver/ToolChain.cpp | 2 +
clang/lib/Driver/ToolChains/Serenity.cpp | 336 +++++++++++++++++++++++
clang/lib/Driver/ToolChains/Serenity.h | 100 +++++++
7 files changed, 469 insertions(+)
create mode 100644 clang/lib/Driver/ToolChains/Serenity.cpp
create mode 100644 clang/lib/Driver/ToolChains/Serenity.h
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 8400774db..f82618dc8 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -153,6 +153,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
case llvm::Triple::OpenBSD:
return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+ case llvm::Triple::Serenity:
+ return new SerenityTargetInfo<AArch64leTargetInfo>(Triple, Opts);
case llvm::Triple::Win32:
switch (Triple.getEnvironment()) {
case llvm::Triple::GNU:
@@ -424,6 +426,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts);
case llvm::Triple::Linux:
return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+ case llvm::Triple::Serenity:
+ return new SerenityTargetInfo<RISCV64TargetInfo>(Triple, Opts);
default:
return new RISCV64TargetInfo(Triple, Opts);
}
@@ -542,6 +546,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new MCUX86_32TargetInfo(Triple, Opts);
case llvm::Triple::Hurd:
return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ case llvm::Triple::Serenity:
+ return new SerenityTargetInfo<X86_32TargetInfo>(Triple, Opts);
default:
return new X86_32TargetInfo(Triple, Opts);
}
@@ -596,6 +602,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
case llvm::Triple::PS5:
return new PS5OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ case llvm::Triple::Serenity:
+ return new SerenityTargetInfo<X86_64TargetInfo>(Triple, Opts);
default:
return new X86_64TargetInfo(Triple, Opts);
}
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index fd372cb12..27a3f9797 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -1005,6 +1005,24 @@ public:
}
};
+// SerenityOS target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY SerenityTargetInfo : public OSTargetInfo<Target> {
+protected:
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const override {
+ Builder.defineMacro("__serenity__");
+ DefineStd(Builder, "unix", Opts);
+ Builder.defineMacro("__ELF__");
+ }
+
+public:
+ SerenityTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : OSTargetInfo<Target>(Triple, Opts) {
+ this->WIntType = TargetInfo::UnsignedInt;
+ }
+};
+
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index ba56a9323..4d0ffe88c 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -78,6 +78,7 @@ add_clang_library(clangDriver
ToolChains/OpenBSD.cpp
ToolChains/PS4CPU.cpp
ToolChains/RISCVToolchain.cpp
+ ToolChains/Serenity.cpp
ToolChains/Solaris.cpp
ToolChains/SPIRV.cpp
ToolChains/TCE.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a268f2fa8..df54be3de 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -45,6 +45,7 @@
#include "ToolChains/PPCLinux.h"
#include "ToolChains/PS4CPU.h"
#include "ToolChains/RISCVToolchain.h"
+#include "ToolChains/Serenity.h"
#include "ToolChains/SPIRV.h"
#include "ToolChains/Solaris.h"
#include "ToolChains/TCE.h"
@@ -6041,6 +6042,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
case llvm::Triple::Fuchsia:
TC = std::make_unique<toolchains::Fuchsia>(*this, Target, Args);
break;
+ case llvm::Triple::Serenity:
+ TC = std::make_unique<toolchains::Serenity>(*this, Target, Args);
+ break;
case llvm::Triple::Solaris:
TC = std::make_unique<toolchains::Solaris>(*this, Target, Args);
break;
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index bc70205a6..3d5c856ab 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -482,6 +482,8 @@ StringRef ToolChain::getOSLibName() const {
return "sunos";
case llvm::Triple::AIX:
return "aix";
+ case llvm::Triple::Serenity:
+ return "serenity";
default:
return getOS();
}
diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp
new file mode 100644
index 000000000..4fdf45a19
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Serenity.cpp
@@ -0,0 +1,336 @@
+//===---- Serenity.cpp - SerenityOS ToolChain Implementation ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Serenity.h"
+#include "CommonArgs.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/VirtualFileSystem.h"
+#include <string>
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+static bool getPIE(const ArgList &Args, const ToolChain &TC) {
+ if (Args.hasArg(options::OPT_static, options::OPT_shared,
+ options::OPT_static_pie))
+ return false;
+ Arg *Last = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
+ options::OPT_nopie);
+ return Last ? Last->getOption().matches(options::OPT_pie) : true;
+}
+
+void tools::serenity::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const auto &TC = getToolChain();
+ const auto &D = TC.getDriver();
+ const bool IsShared = Args.hasArg(options::OPT_shared);
+ const bool IsStatic =
+ Args.hasArg(options::OPT_static) && !Args.hasArg(options::OPT_static_pie);
+ const bool IsRdynamic = Args.hasArg(options::OPT_rdynamic);
+ const bool IsStaticPIE = Args.hasArg(options::OPT_static_pie);
+ const bool IsPIE = getPIE(Args, TC);
+ ArgStringList CmdArgs;
+
+ if (!D.SysRoot.empty())
+ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+ if (IsPIE || IsStaticPIE)
+ CmdArgs.push_back("-pie");
+
+ if (IsShared)
+ CmdArgs.push_back("-shared");
+
+ if (IsStatic || IsStaticPIE)
+ CmdArgs.push_back("-static");
+
+ if (IsStaticPIE) {
+ CmdArgs.push_back("--no-dynamic-linker");
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("text");
+ }
+
+ if (!IsStatic && !IsStaticPIE) {
+ if (IsRdynamic)
+ CmdArgs.push_back("-export-dynamic");
+ CmdArgs.push_back("-dynamic-linker");
+ CmdArgs.push_back("/usr/lib/Loader.so");
+ }
+
+ if (!IsStatic || IsStaticPIE)
+ CmdArgs.push_back("--eh-frame-hdr");
+
+ if (Output.isFilename()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ }
+
+ const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
+ auto linkerIs = [Exec](const char* name) {
+ return llvm::sys::path::filename(Exec).equals_insensitive(name) ||
+ llvm::sys::path::stem(Exec).equals_insensitive(name);
+ };
+
+ if (linkerIs("ld.lld") || linkerIs("ld.mold")) {
+ CmdArgs.push_back("--pack-dyn-relocs=relr");
+ } else {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("pack-relative-relocs");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+ CmdArgs.push_back(Args.MakeArgString(
+ TC.GetFilePath((IsShared) ? "crt0_shared.o" : "crt0.o")));
+ CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crti.o")));
+
+ std::string crtbegin_path;
+ if (TC.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT) {
+ std::string crtbegin =
+ TC.getCompilerRT(Args, "crtbegin", ToolChain::FT_Object);
+ if (TC.getVFS().exists(crtbegin))
+ crtbegin_path = crtbegin;
+ }
+ if (crtbegin_path.empty()) {
+ const char *crtbegin = (IsShared || IsPIE) ? "crtbeginS.o" : "crtbegin.o";
+ crtbegin_path = TC.GetFilePath(crtbegin);
+ }
+ CmdArgs.push_back(Args.MakeArgString(crtbegin_path));
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+ Args.AddAllArgs(CmdArgs, options::OPT_u);
+
+ TC.AddFilePathLibArgs(Args, CmdArgs);
+
+ if (D.isUsingLTO()) {
+ assert(!Inputs.empty() && "Must have at least one input.");
+ addLTOOptions(TC, Args, CmdArgs, Output, Inputs[0],
+ D.getLTOMode() == LTOK_Thin);
+ }
+
+ 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_Z_Flag);
+ Args.AddAllArgs(CmdArgs, options::OPT_r);
+
+ addLinkerCompressDebugSectionsOption(TC, Args, CmdArgs);
+
+ AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+ AddRunTimeLibs(TC, D, CmdArgs, Args);
+
+ // We supply our own sanitizer runtimes
+ // FIXME: What if we want to use Clang-supplied ones as well?
+ const SanitizerArgs &Sanitize = TC.getSanitizerArgs(Args);
+ if (Sanitize.needsUbsanRt())
+ CmdArgs.push_back("-lubsan");
+ }
+
+ if (D.CCCIsCXX() && TC.ShouldLinkCXXStdlib(Args)) {
+ bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+ !Args.hasArg(options::OPT_static);
+ CmdArgs.push_back("--push-state");
+ CmdArgs.push_back("--as-needed");
+ if (OnlyLibstdcxxStatic)
+ CmdArgs.push_back("-Bstatic");
+ TC.AddCXXStdlibLibArgs(Args, CmdArgs);
+ if (OnlyLibstdcxxStatic)
+ CmdArgs.push_back("-Bdynamic");
+ CmdArgs.push_back("--pop-state");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+ if (!Args.hasArg(options::OPT_nolibc))
+ CmdArgs.push_back("-lc");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
+ std::string crtend_path;
+ if (TC.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT) {
+ std::string crtend =
+ TC.getCompilerRT(Args, "crtend", ToolChain::FT_Object);
+ if (TC.getVFS().exists(crtend))
+ crtend_path = crtend;
+ }
+ if (crtend_path.empty()) {
+ const char *crtend = (IsShared || IsPIE) ? "crtendS.o" : "crtend.o";
+ crtend_path = TC.GetFilePath(crtend);
+ }
+ CmdArgs.push_back(Args.MakeArgString(crtend_path));
+
+ CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o")));
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_T);
+
+ C.addCommand(std::make_unique<Command>(JA, *this,
+ ResponseFileSupport::AtFileCurCP(),
+ Exec, CmdArgs, Inputs, Output));
+}
+
+Serenity::Serenity(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : ToolChain(D, Triple, Args) {
+ getProgramPaths().push_back(getDriver().getInstalledDir());
+ if (getDriver().getInstalledDir() != getDriver().Dir)
+ getProgramPaths().push_back(getDriver().Dir);
+ getFilePaths().push_back(getDriver().SysRoot + "/usr/local/lib");
+ getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
+}
+
+Tool *Serenity::buildLinker() const {
+ return new tools::serenity::Linker(*this);
+}
+
+void Serenity::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ addSystemInclude(DriverArgs, CC1Args, D.ResourceDir + "/include");
+ }
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include");
+ addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
+}
+
+static std::string getLibStdCXXVersion(const Driver &D, StringRef IncludePath) {
+ SmallString<128> Path(IncludePath);
+ llvm::sys::path::append(Path, "c++");
+
+ std::error_code EC;
+ std::tuple<int, int, int> Newest{0, 0, 0};
+ std::string Result;
+
+ for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+ StringRef VersionText = llvm::sys::path::filename(LI->path());
+
+ // This is libc++
+ if (VersionText[0] == 'v')
+ continue;
+
+ llvm::SmallVector<StringRef, 3> Parts;
+ VersionText.split(Parts, '.');
+
+ // SerenityOS always builds GCC with <major>.<minor>.<patch> versions
+ if (Parts.size() < 3)
+ continue;
+
+ std::tuple<int, int, int> Current;
+ if (!llvm::to_integer(Parts[0], std::get<0>(Current)))
+ continue;
+ if (!llvm::to_integer(Parts[1], std::get<1>(Current)))
+ continue;
+ if (!llvm::to_integer(Parts[2], std::get<2>(Current)))
+ continue;
+
+ if (Current > Newest) {
+ Newest = Current;
+ Result = VersionText.str();
+ }
+ }
+ return Result;
+}
+
+void Serenity::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,
+ options::OPT_nostdlibinc))
+ return;
+
+ const auto StdLib = GetCXXStdlibType(DriverArgs);
+
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string Target = getTripleString();
+
+ auto AddIncludePath = [&](std::string Path) {
+ std::string Version = StdLib == CXXStdlibType::CST_Libstdcxx
+ ? getLibStdCXXVersion(D, Path)
+ : detectLibcxxVersion(Path);
+ if (Version.empty())
+ return false;
+
+ std::string TargetDir;
+ if (StdLib == CXXStdlibType::CST_Libstdcxx) {
+ TargetDir = Path + "/c++/" + Version + "/" + Target;
+ } else {
+ TargetDir = Path + "/" + Target + "/c++/" + Version;
+ }
+
+ if (D.getVFS().exists(TargetDir))
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version);
+ return true;
+ };
+
+ if (AddIncludePath(getDriver().Dir + "/../include"))
+ return;
+ if (AddIncludePath(SysRoot + "/usr/local/include"))
+ return;
+ if (AddIncludePath(SysRoot + "/usr/include"))
+ return;
+}
+
+void Serenity::addClangTargetOptions(
+ const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const {
+ if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
+ options::OPT_fno_use_init_array, true))
+ CC1Args.push_back("-fno-use-init-array");
+}
+
+ToolChain::UnwindLibType
+Serenity::GetUnwindLibType(const llvm::opt::ArgList &Args) const {
+
+ const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
+ StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
+
+ if (LibName == "none") {
+ return ToolChain::UNW_None;
+ } else if (LibName == "platform" || LibName == "") {
+ ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
+ if (RtLibType == ToolChain::RLT_CompilerRT) {
+ return ToolChain::UNW_CompilerRT;
+ } else if (RtLibType == ToolChain::RLT_Libgcc)
+ return ToolChain::UNW_Libgcc;
+ } else if (LibName == "libunwind") {
+ if (GetRuntimeLibType(Args) == RLT_Libgcc)
+ getDriver().Diag(diag::err_drv_incompatible_unwindlib);
+ return ToolChain::UNW_CompilerRT;
+ } else if (LibName == "libgcc") {
+ return ToolChain::UNW_Libgcc;
+ }
+
+ if (A)
+ getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
+ << A->getAsString(Args);
+
+ return ToolChain::UNW_None;
+}
diff --git a/clang/lib/Driver/ToolChains/Serenity.h b/clang/lib/Driver/ToolChains/Serenity.h
new file mode 100644
index 000000000..feb31a0d6
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Serenity.h
@@ -0,0 +1,100 @@
+//===---- Serenity.h - SerenityOS ToolChain Implementation ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace serenity {
+
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+ Linker(const ToolChain &TC) : Tool("serenity::Linker", "linker", TC) {}
+
+ bool hasIntegratedCPP() const override { return false; }
+ bool isLinkJob() const override { return true; }
+
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
+} // end namespace serenity
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY Serenity : public ToolChain {
+public:
+ Serenity(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
+
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ void AddClangCXXStdlibIncludeArgs(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ RuntimeLibType GetDefaultRuntimeLibType() const override {
+ return ToolChain::RLT_CompilerRT;
+ }
+
+ CXXStdlibType GetDefaultCXXStdlibType() const override {
+ return ToolChain::CST_Libcxx;
+ }
+
+ UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override;
+
+ void
+ addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const override;
+
+ const char *getDefaultLinker() const override { return "ld.lld"; }
+
+ bool HasNativeLLVMSupport() const override { return true; }
+
+ bool IsIntegratedAssemblerDefault() const override { return true; }
+
+ bool isPICDefault() const override { return true; }
+ bool isPIEDefault(const llvm::opt::ArgList&) const override { return false; }
+ bool isPICDefaultForced() const override { return false; }
+
+ bool IsMathErrnoDefault() const override { return false; }
+
+ UnwindTableLevel
+ getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override {
+ return UnwindTableLevel::Asynchronous;
+ }
+
+ bool useRelaxRelocations() const override { return true; }
+
+ LangOptions::StackProtectorMode
+ GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+ return LangOptions::SSPStrong;
+ }
+
+ unsigned GetDefaultDwarfVersion() const override { return 5; }
+
+protected:
+ Tool *buildLinker() const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H