diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index d02d9744d..b57a7cb05 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2452,6 +2452,7 @@ def nolibc : Flag<["-"], "nolibc">; def nomultidefs : Flag<["-"], "nomultidefs">; def nopie : Flag<["-"], "nopie">; def no_pie : Flag<["-"], "no-pie">, Alias; +def noposix : Flag<["-"], "noposix">; def noprebind : Flag<["-"], "noprebind">; def noseglinkedit : Flag<["-"], "noseglinkedit">; def nostartfiles : Flag<["-"], "nostartfiles">; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 3c139d724..89d6df3f5 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -147,6 +147,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new FreeBSDTargetInfo(Triple, Opts); case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); + case llvm::Triple::Genode: + return new GenodeTargetInfo(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::NetBSD: @@ -171,6 +173,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new FreeBSDTargetInfo(Triple, Opts); case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); + case llvm::Triple::Genode: + return new GenodeTargetInfo(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::NetBSD: @@ -528,6 +532,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new FreeBSDTargetInfo(Triple, Opts); case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); + case llvm::Triple::Genode: + return new GenodeTargetInfo(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo(Triple, Opts); case llvm::Triple::Solaris: diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h index 09867d82c..f67151a13 100644 --- a/lib/Basic/Targets/OSTargets.h +++ b/lib/Basic/Targets/OSTargets.h @@ -760,6 +760,26 @@ public: } }; +// Genode Target +template +class LLVM_LIBRARY_VISIBILITY GenodeTargetInfo : public OSTargetInfo { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + Builder.defineMacro("__GENODE__"); + Builder.defineMacro("__ELF__"); + // Required by the libc++ locale support. + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + } + +public: + GenodeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) { + this->MCountName = "__mcount"; + } +}; + // WebAssembly target template class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 4793a1f90..4691b898e 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -44,6 +44,7 @@ add_clang_library(clangDriver ToolChains/DragonFly.cpp ToolChains/FreeBSD.cpp ToolChains/Fuchsia.cpp + ToolChains/Genode.cpp ToolChains/Gnu.cpp ToolChains/Haiku.cpp ToolChains/HIP.cpp diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index a784e218f..881b78abc 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -22,6 +22,7 @@ #include "ToolChains/DragonFly.h" #include "ToolChains/FreeBSD.h" #include "ToolChains/Fuchsia.h" +#include "ToolChains/Genode.h" #include "ToolChains/Gnu.h" #include "ToolChains/HIP.h" #include "ToolChains/Haiku.h" @@ -4570,6 +4571,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Solaris: TC = llvm::make_unique(*this, Target, Args); break; + case llvm::Triple::Genode: + TC = llvm::make_unique(*this, Target, Args); + break; case llvm::Triple::AMDHSA: TC = llvm::make_unique(*this, Target, Args); break; diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 1a46073aa..72b6f7389 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -693,7 +693,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, ImplicitCfiRuntime = TC.getTriple().isAndroid(); if (AllAddedKinds & Address) { - NeedPIE |= TC.getTriple().isOSFuchsia(); + NeedPIE |= TC.getTriple().isOSFuchsia() | TC.getTriple().isOSGenode(); if (Arg *A = Args.getLastArg(options::OPT_fsanitize_address_field_padding)) { StringRef S = A->getValue(); diff --git a/lib/Driver/ToolChains/Genode.cpp b/lib/Driver/ToolChains/Genode.cpp new file mode 100644 index 000000000..488863cb4 --- /dev/null +++ b/lib/Driver/ToolChains/Genode.cpp @@ -0,0 +1,147 @@ +//===--- Genode.cpp - Genode ToolChain Implementations ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#include "Genode.h" +#include "InputInfo.h" +#include "CommonArgs.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang::driver::tools; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +void genode::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const llvm::opt::ArgList &Args, + const char *LinkingOutput) const { + const toolchains::Genode &ToolChain = + static_cast(getToolChain()); + const Driver &D = ToolChain.getDriver(); + const llvm::Triple::ArchType Arch = ToolChain.getArch(); + ArgStringList CmdArgs; + + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + + // Explicitly set the linker emulation for platforms that might not + // be the default emulation for the linker. + switch (Arch) { + case llvm::Triple::x86: + CmdArgs.push_back("-melf_i386"); + break; + case llvm::Triple::x86_64: + CmdArgs.push_back("-melf_x86_64"); + break; + case llvm::Triple::riscv32: + CmdArgs.push_back("-melf32lriscv"); + break; + case llvm::Triple::riscv64: + CmdArgs.push_back("-melf64lriscv"); + break; + default: + break; + } + + CmdArgs.push_back("--eh-frame-hdr"); + CmdArgs.push_back("--gc-sections"); + CmdArgs.push_back("-zmax-page-size=0x1000"); + + CmdArgs.push_back("-Ttext=0x01000000"); + + Args.AddAllArgs(CmdArgs, options::OPT_L); + ToolChain.AddFilePathLibArgs(Args, CmdArgs); + 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); + + if (Args.hasArg(options::OPT_static)) { + CmdArgs.push_back("-Bstatic"); + } else { + if (Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back(Args.MakeArgString("-shared")); + CmdArgs.push_back(Args.MakeArgString("-T" + D.SysRoot + "/ld/genode_rel.ld")); + } else { + CmdArgs.push_back(Args.MakeArgString("-T" + D.SysRoot + "/ld/genode_dyn.ld")); + CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + D.SysRoot + "/ld/genode_dyn.dl")); + CmdArgs.push_back("--dynamic-linker=ld.lib.so"); + } + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + CmdArgs.push_back("-l:ld.lib.so"); + } + } + + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } else { + assert(Output.isNothing() && "Invalid output."); + } + + AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); + + AddRunTimeLibs(ToolChain, D, CmdArgs, Args); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_noposix)) { + CmdArgs.push_back("-lc"); + if (!Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-lposix"); + } + } + + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); + C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); +} + +Genode::Genode(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : Generic_ELF(D, Triple, Args) { + SmallString<128> P(getDriver().Dir); + llvm::sys::path::append(P, "..", getTriple().str(), "lib"); + getFilePaths().push_back(P.str()); +} + +void Genode::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + SmallString<128> P(getDriver().Dir); + llvm::sys::path::append(P, "..", getTriple().str(), "include/c++/v1"); + addSystemInclude(DriverArgs, CC1Args, P.str()); +} + +bool Genode::isPIEDefault() const { + switch (getTriple().getArch()) { + case llvm::Triple::aarch64: + case llvm::Triple::x86_64: + return true; + default: + return false; + } +} + +SanitizerMask Genode::getSupportedSanitizers() const { + return Generic_ELF::getSupportedSanitizers(); +} + +SanitizerMask Genode::getDefaultSanitizers() const { + return Generic_ELF::getDefaultSanitizers(); +} + +Tool *Genode::buildLinker() const { + return new tools::genode::Linker(*this); +} diff --git a/lib/Driver/ToolChains/Genode.h b/lib/Driver/ToolChains/Genode.h new file mode 100644 index 000000000..144f4f99a --- /dev/null +++ b/lib/Driver/ToolChains/Genode.h @@ -0,0 +1,69 @@ +//===----- Genode.h - Genode ToolChain Implementations ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GENODE_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GENODE_H + +#include "Gnu.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace tools { + +//// genode -- Directly call GNU Binutils linker +namespace genode { +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("genode::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 &Inputss, + const llvm::opt::ArgList &Args, + const char *LinkingOutput) const override; +}; +} // end namespace genode +} // end namespace tools + +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY Genode : public Generic_ELF { +public: + Genode(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + bool HasNativeLLVMSupport() const override { return true; } + + bool IsMathErrnoDefault() const override { return true; } + + CXXStdlibType + GetCXXStdlibType(const llvm::opt::ArgList &Args) const override { + return ToolChain::CST_Libcxx; + } + void addLibCxxIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + + bool isPIEDefault() const override; + SanitizerMask getSupportedSanitizers() const override; + SanitizerMask getDefaultSanitizers() const override; + +protected: + Tool *buildLinker() const override; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GENODE_H diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 67842b5dc..26a2c65fe 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -221,6 +221,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, case llvm::Triple::PS4: case llvm::Triple::ELFIAMCU: case llvm::Triple::Fuchsia: + case llvm::Triple::Genode: break; case llvm::Triple::Win32: if (triple.getEnvironment() != llvm::Triple::Cygnus) @@ -329,6 +330,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, case llvm::Triple::NaCl: case llvm::Triple::ELFIAMCU: case llvm::Triple::Fuchsia: + case llvm::Triple::Genode: break; case llvm::Triple::PS4: { // gets prepended later in AddPath(). diff --git a/test/Driver/genode.c b/test/Driver/genode.c new file mode 100644 index 000000000..e69de29bb diff --git a/test/Driver/genode.cpp b/test/Driver/genode.cpp new file mode 100644 index 000000000..e69de29bb