diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 966cb907b7e2..5bcd5093be7d 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -2709,6 +2709,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 noprofilelib : Flag<["-"], "noprofilelib">; def noseglinkedit : Flag<["-"], "noseglinkedit">; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 965f273892bd..7a22f90d3652 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -142,6 +142,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: @@ -186,6 +188,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo(Triple, Opts); + case llvm::Triple::Genode: + return new GenodeTargetInfo(Triple, Opts); case llvm::Triple::NetBSD: return new NetBSDTargetInfo(Triple, Opts); case llvm::Triple::OpenBSD: @@ -485,6 +489,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 GenodeI386TargetInfo(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo(Triple, Opts); case llvm::Triple::Minix: @@ -544,6 +550,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/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp index 25c02cb888c1..8b9a622865cd 100644 --- a/lib/Basic/Targets/AArch64.cpp +++ b/lib/Basic/Targets/AArch64.cpp @@ -43,7 +43,7 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), ABI("aapcs") { - if (getTriple().isOSOpenBSD()) { + if (getTriple().isOSOpenBSD() || getTriple().isOSGenode()) { Int64Type = SignedLongLong; IntMaxType = SignedLongLong; } else { diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp index 21cfe0107bbb..b02ef0aa0f2f 100644 --- a/lib/Basic/Targets/ARM.cpp +++ b/lib/Basic/Targets/ARM.cpp @@ -238,18 +238,19 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, HW_FP(0) { bool IsOpenBSD = Triple.isOSOpenBSD(); bool IsNetBSD = Triple.isOSNetBSD(); + bool IsGenode = Triple.isOSGenode(); // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like // environment where size_t is `unsigned long` rather than `unsigned int` PtrDiffType = IntPtrType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || - IsNetBSD) + IsNetBSD || IsGenode) ? SignedLong : SignedInt; SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || - IsNetBSD) + IsNetBSD || IsGenode) ? UnsignedLong : UnsignedInt; diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h index 2a9e4f91d478..e453358027f0 100644 --- a/lib/Basic/Targets/OSTargets.h +++ b/lib/Basic/Targets/OSTargets.h @@ -296,7 +296,7 @@ protected: Builder.defineMacro("__HAIKU__"); Builder.defineMacro("__ELF__"); DefineStd(Builder, "unix", Opts); - if (this->HasFloat128) + if (this->HasFloat128) Builder.defineMacro("__FLOAT128__"); } @@ -820,6 +820,40 @@ 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__"); + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__ELF__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); + } + +public: + GenodeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) { + this->IntMaxType = TargetInfo::SignedLongLong; + this->Int64Type = TargetInfo::SignedLongLong; + this->SizeType = TargetInfo::UnsignedLong; + this->TLSSupported = false; + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } + + } +}; + // WebAssembly target template class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo diff --git a/lib/Basic/Targets/X86.h b/lib/Basic/Targets/X86.h index 72a01d2514c2..ae7b01b0d9a7 100644 --- a/lib/Basic/Targets/X86.h +++ b/lib/Basic/Targets/X86.h @@ -447,6 +447,18 @@ public: } }; +class LLVM_LIBRARY_VISIBILITY GenodeI386TargetInfo + : public GenodeTargetInfo { +public: + GenodeI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : GenodeTargetInfo(Triple, Opts) { + SizeType = UnsignedLong; + IntPtrType = SignedLong; + PtrDiffType = SignedLong; + } +}; + + class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo : public DarwinTargetInfo { public: diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 9463ca5c109d..5ae757f99e2f 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangDriver ToolChains/Flang.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 ece8222dcf24..4ca793af6c81 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" @@ -4951,6 +4952,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Solaris: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::Genode: + TC = std::make_unique(*this, Target, Args); + break; case llvm::Triple::AMDHSA: TC = std::make_unique(*this, Target, Args); break; diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp index dd4545d6c48f..22ec56518046 100644 --- a/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -373,7 +373,7 @@ fp16_fml_fallthrough: options::OPT_munaligned_access)) { if (A->getOption().matches(options::OPT_mno_unaligned_access)) Features.push_back("+strict-align"); - } else if (Triple.isOSOpenBSD()) + } else if (Triple.isOSOpenBSD() || Triple.isOSGenode()) Features.push_back("+strict-align"); if (Args.hasArg(options::OPT_ffixed_x1)) diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp index afe896b4a65b..f93dd30beb98 100644 --- a/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/lib/Driver/ToolChains/Arch/ARM.cpp @@ -587,7 +587,7 @@ fp16_fml_fallthrough: if (VersionNum < 6 || Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m) Features.push_back("+strict-align"); - } else if (Triple.isOSLinux() || Triple.isOSNaCl()) { + } else if (Triple.isOSLinux() || Triple.isOSNaCl() || Triple.isOSGenode()) { if (VersionNum < 7) Features.push_back("+strict-align"); } else diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index af4bcf951e6c..c96b192c7e09 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -538,7 +538,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, break; } - if (Triple.isOSNetBSD()) { + if (Triple.isOSNetBSD() || Triple.isOSGenode()) { return !areOptimizationsEnabled(Args); } diff --git a/lib/Driver/ToolChains/Genode.cpp b/lib/Driver/ToolChains/Genode.cpp new file mode 100644 index 000000000000..37151999b7bf --- /dev/null +++ b/lib/Driver/ToolChains/Genode.cpp @@ -0,0 +1,191 @@ +//===--- Genode.h - Genode ToolChain Implementations ------------*- 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 "Genode.h" +#include "CommonArgs.h" +#include "InputInfo.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +void genode::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + ArgStringList CmdArgs; + + const auto &TC = static_cast(getToolChain()); + const auto &D = TC.getDriver(); + + 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 (TC.getArch()) { + 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); + TC.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(TC, Inputs, Args, CmdArgs, JA); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_noposix)) { + AddRunTimeLibs(TC, D, CmdArgs, Args); + + CmdArgs.push_back("-lc"); + if (!Args.hasArg(options::OPT_shared)) { + CmdArgs.push_back("-lposix"); + } + } + + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::None(), + Args.MakeArgString(TC.GetLinkerPath()), + CmdArgs, Inputs)); +} + +Genode::Genode(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + + std::vector GenodeExtraTriples; + switch (Triple.getArch()) { + case llvm::Triple::arm: + GenodeExtraTriples.push_back("arm-none-eabi"); + break; + case llvm::Triple::aarch64: + GenodeExtraTriples.push_back("aarch64-none-elf"); + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + GenodeExtraTriples.push_back("x86_64-pc-elf"); + break; + case llvm::Triple::riscv64: + GenodeExtraTriples.push_back("riscv64-unknown-elf"); + break; + default: + break; + } + + GCCInstallation.init(Triple, Args, GenodeExtraTriples); + + const std::string MultiarchTriple = getMultiarchTriple(D, Triple, /*SysRoot*/ ""); + if (GCCInstallation.isValid() && + (Triple.getArch() == llvm::Triple::x86_64 || + Triple.getArch() == llvm::Triple::x86)) { + + path_list MultilibPaths; + Generic_GCC::AddMultilibPaths(D, /*SysRoot*/ "", "lib", + MultiarchTriple, MultilibPaths); + + auto Suffix = GCCInstallation.getMultilib().gccSuffix(); + for (auto path: MultilibPaths) + addPathIfExists(D, path + Suffix, getFilePaths()); + } else { + Generic_GCC::AddMultilibPaths(D, /*SysRoot*/ "", "lib", + MultiarchTriple, getFilePaths()); + } + + ToolChain::path_list &PPaths = getProgramPaths(); + + Generic_GCC::PushPPaths(PPaths); + +#ifdef ENABLE_LINKER_BUILD_ID + ExtraOpts.push_back("--build-id"); +#endif +} + +void +Genode::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + // Try generic GCC detection first. + if (Generic_GCC::addGCCLibStdCxxIncludePaths(DriverArgs, CC1Args)) + return; + + if (!GCCInstallation.isValid()) + return; + + StringRef LibDir = GCCInstallation.getParentLibPath(); + StringRef TripleStr = GCCInstallation.getTriple().str(); + const Multilib &Multilib = GCCInstallation.getMultilib(); + const GCCVersion &Version = GCCInstallation.getVersion(); + + const std::string IncludePath = { + LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, + }; + + addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr, + /*GCCMultiarchTriple*/ "", + /*TargetMultiarchTriple*/ "", + Multilib.includeSuffix(), DriverArgs, CC1Args); +} + +void Genode::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + for (const auto &Opt : ExtraOpts) + CmdArgs.push_back(Opt.c_str()); +} + +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 000000000000..27e51ca45d9e --- /dev/null +++ b/lib/Driver/ToolChains/Genode.h @@ -0,0 +1,69 @@ +//===--- Genode.h - Genode ToolChain Implementations ------------*- 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_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 { +namespace genode { +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("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 &Inputs, + const llvm::opt::ArgList &TCArgs, + 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 IsMathErrnoDefault() const override { return false; } + bool HasNativeLLVMSupport() const override { return true; } + bool isPICDefault() const override { return false; } + bool isPIEDefault() const override { return false; } + bool isPICDefaultForced() const override { return false; } + bool IsIntegratedAssemblerDefault() const override { return true; } + + void + addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const final; + + bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override { + return true; + } + + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; + + std::vector ExtraOpts; + +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 bc31445d6d08..364942eff068 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -229,6 +229,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) @@ -338,6 +339,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 000000000000..e69de29bb2d1 diff --git a/test/Driver/genode.cpp b/test/Driver/genode.cpp new file mode 100644 index 000000000000..e69de29bb2d1