mirror of
https://github.com/RGBCube/serenity
synced 2025-06-17 20:12:09 +00:00

This is essentially a no-op since we have our replacement linker script, but if we can skip over that entirely, why not?
589 lines
21 KiB
Diff
589 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
|
|
|
|
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.
|
|
---
|
|
clang/lib/Basic/Targets.cpp | 6 +
|
|
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/Arch/X86.cpp | 1 +
|
|
clang/lib/Driver/ToolChains/Serenity.cpp | 340 +++++++++++++++++++++++
|
|
clang/lib/Driver/ToolChains/Serenity.h | 99 +++++++
|
|
8 files changed, 471 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 994a491cd..066c8140b 100644
|
|
--- a/clang/lib/Basic/Targets.cpp
|
|
+++ b/clang/lib/Basic/Targets.cpp
|
|
@@ -149,6 +149,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:
|
|
@@ -538,6 +540,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);
|
|
}
|
|
@@ -590,6 +594,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
|
|
return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts);
|
|
case llvm::Triple::PS4:
|
|
return new PS4OSTargetInfo<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 3c1830d5f..b0bae0535 100644
|
|
--- a/clang/lib/Basic/Targets/OSTargets.h
|
|
+++ b/clang/lib/Basic/Targets/OSTargets.h
|
|
@@ -977,6 +977,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 78e8fd185..3b70257a9 100644
|
|
--- a/clang/lib/Driver/CMakeLists.txt
|
|
+++ b/clang/lib/Driver/CMakeLists.txt
|
|
@@ -70,6 +70,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 3bfddeefc..a75e0ee14 100644
|
|
--- a/clang/lib/Driver/Driver.cpp
|
|
+++ b/clang/lib/Driver/Driver.cpp
|
|
@@ -43,6 +43,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"
|
|
@@ -5564,6 +5565,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 d657d21bf..eea53e6ac 100644
|
|
--- a/clang/lib/Driver/ToolChain.cpp
|
|
+++ b/clang/lib/Driver/ToolChain.cpp
|
|
@@ -413,6 +413,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/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp
|
|
index bfa008f96..b7f1780fd 100644
|
|
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
|
|
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
|
|
@@ -107,6 +107,7 @@ std::string x86::getX86TargetCPU(const Driver &D, const ArgList &Args,
|
|
case llvm::Triple::OpenBSD:
|
|
return "i586";
|
|
case llvm::Triple::FreeBSD:
|
|
+ case llvm::Triple::Serenity:
|
|
return "i686";
|
|
default:
|
|
// Fallback to p4.
|
|
diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp
|
|
new file mode 100644
|
|
index 000000000..955422438
|
|
--- /dev/null
|
|
+++ b/clang/lib/Driver/ToolChains/Serenity.cpp
|
|
@@ -0,0 +1,337 @@
|
|
+//===---- 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("-lm");
|
|
+ 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..d414f8366
|
|
--- /dev/null
|
|
+++ b/clang/lib/Driver/ToolChains/Serenity.h
|
|
@@ -0,0 +1,99 @@
|
|
+//===---- 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; }
|
|
+
|
|
+ bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ 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
|