https://github.com/LucasChollet updated https://github.com/llvm/llvm-project/pull/187941
>From 7fddbc845aaae37c7d43430bce4f7d1f4d558d4f Mon Sep 17 00:00:00 2001 From: Lucas Chollet <[email protected]> Date: Sat, 7 Mar 2026 09:36:08 +0100 Subject: [PATCH 1/2] [clang] Add support for SerenityOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for the $arch-unknown-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: Daniel Bertalan <[email protected]> Co-authored-by: kleines Filmröllchen <[email protected]> Co-authored-by: Andrew Kaster <[email protected]> Co-authored-by: Dan Klishch <[email protected]> --- clang/lib/Basic/Targets.cpp | 10 + clang/lib/Basic/Targets/OSTargets.h | 17 ++ clang/lib/Driver/CMakeLists.txt | 1 + clang/lib/Driver/Driver.cpp | 4 + clang/lib/Driver/ToolChain.cpp | 5 +- clang/lib/Driver/ToolChains/Serenity.cpp | 206 ++++++++++++++ clang/lib/Driver/ToolChains/Serenity.h | 90 +++++++ clang/lib/Lex/InitHeaderSearch.cpp | 1 + .../clang_rt.crtbegin.o | 0 .../clang_rt.crtend.o | 0 .../clang_rt.crtbegin.o | 0 .../clang_rt.crtend.o | 0 .../clang_rt.crtbegin.o | 0 .../x86_64-unknown-serenity/clang_rt.crtend.o | 0 .../serenity_tree/usr/include/c++/v1/.keep | 0 .../Inputs/serenity_tree/usr/lib/crt0.o | 0 .../Inputs/serenity_tree/usr/local/.keep | 0 clang/test/Driver/pic.c | 8 + clang/test/Driver/save-stats.c | 2 + clang/test/Driver/serenity.cpp | 254 ++++++++++++++++++ 20 files changed, 597 insertions(+), 1 deletion(-) create mode 100644 clang/lib/Driver/ToolChains/Serenity.cpp create mode 100644 clang/lib/Driver/ToolChains/Serenity.h create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-serenity/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-serenity/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/riscv64-unknown-serenity/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/riscv64-unknown-serenity/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-serenity/clang_rt.crtbegin.o create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-serenity/clang_rt.crtend.o create mode 100644 clang/test/Driver/Inputs/serenity_tree/usr/include/c++/v1/.keep create mode 100644 clang/test/Driver/Inputs/serenity_tree/usr/lib/crt0.o create mode 100644 clang/test/Driver/Inputs/serenity_tree/usr/local/.keep create mode 100644 clang/test/Driver/serenity.cpp diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index dc6ef6ed8f3f8..b24794d26c7c3 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -177,6 +177,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Hurd: return std::make_unique<HurdTargetInfo<AArch64leTargetInfo>>(Triple, Opts); + case llvm::Triple::Serenity: + return std::make_unique<SerenityTargetInfo<AArch64leTargetInfo>>(Triple, + Opts); case llvm::Triple::Win32: switch (Triple.getEnvironment()) { case llvm::Triple::GNU: @@ -477,6 +480,10 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, Opts); case llvm::Triple::Hurd: return std::make_unique<HurdTargetInfo<RISCV64TargetInfo>>(Triple, Opts); + + case llvm::Triple::Serenity: + return std::make_unique<SerenityTargetInfo<RISCV64TargetInfo>>(Triple, + Opts); default: return std::make_unique<RISCV64TargetInfo>(Triple, Opts); } @@ -664,6 +671,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Managarm: return std::make_unique<ManagarmTargetInfo<X86_64TargetInfo>>(Triple, Opts); + case llvm::Triple::Serenity: + return std::make_unique<SerenityTargetInfo<X86_64TargetInfo>>(Triple, + Opts); default: return std::make_unique<X86_64TargetInfo>(Triple, Opts); } diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 16337d56f82c3..9e2916eace079 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -1104,6 +1104,23 @@ class LLVM_LIBRARY_VISIBILITY QURTTargetInfo : public OSTargetInfo<Target> { using OSTargetInfo<Target>::OSTargetInfo; }; +// 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); + } + +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 e3eff21986181..ff8557e8ced97 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -81,6 +81,7 @@ add_clang_library(clangDriver ToolChains/OHOS.cpp ToolChains/OpenBSD.cpp ToolChains/PS4CPU.cpp + ToolChains/Serenity.cpp ToolChains/Solaris.cpp ToolChains/SPIRV.cpp ToolChains/SPIRVOpenMP.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index c559855ac91f5..a57a0e2676052 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -46,6 +46,7 @@ #include "ToolChains/SPIRV.h" #include "ToolChains/SPIRVOpenMP.h" #include "ToolChains/SYCL.h" +#include "ToolChains/Serenity.h" #include "ToolChains/Solaris.h" #include "ToolChains/TCE.h" #include "ToolChains/UEFI.h" @@ -7012,6 +7013,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Managarm: TC = std::make_unique<toolchains::Managarm>(*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 94913837f5339..6c99b4ca837e9 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -724,6 +724,8 @@ StringRef ToolChain::getOSLibName() const { return "sunos"; case llvm::Triple::AIX: return "aix"; + case llvm::Triple::Serenity: + return "serenity"; default: return getOS(); } @@ -1365,7 +1367,8 @@ ToolChain::UnwindLibType ToolChain::GetUnwindLibType( else if (LibName == "platform" || LibName == "") { ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args); if (RtLibType == ToolChain::RLT_CompilerRT) { - if (getTriple().isAndroid() || getTriple().isOSAIX()) + if (getTriple().isAndroid() || getTriple().isOSAIX() || + getTriple().isOSSerenity()) unwindLibType = ToolChain::UNW_CompilerRT; else unwindLibType = ToolChain::UNW_None; diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp new file mode 100644 index 0000000000000..a61f2f81d1f66 --- /dev/null +++ b/clang/lib/Driver/ToolChains/Serenity.cpp @@ -0,0 +1,206 @@ +//===---- 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 "clang/Config/config.h" +#include "clang/Driver/CommonArgs.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/SanitizerArgs.h" +#include "clang/Options/Options.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; + +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 = cast<Generic_ELF const&>(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 IsStaticPIE = Args.hasArg(options::OPT_static_pie); + ArgStringList CmdArgs; + + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + + if (IsShared) + CmdArgs.push_back("-shared"); + + if (IsStaticPIE) { + CmdArgs.push_back("-static"); + CmdArgs.push_back("-pie"); + CmdArgs.push_back("--no-dynamic-linker"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("text"); + } else if (IsStatic) { + CmdArgs.push_back("-static"); + } else if (!Args.hasArg(options::OPT_r)) { + if (Args.hasArg(options::OPT_rdynamic)) + CmdArgs.push_back("-export-dynamic"); + if (!IsShared) { + Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, + options::OPT_nopie); + bool IsPIE = A ? A->getOption().matches(options::OPT_pie) : + TC.isPIEDefault(Args); + if (IsPIE) + CmdArgs.push_back("-pie"); + CmdArgs.push_back("-dynamic-linker"); + CmdArgs.push_back(Args.MakeArgString(TC.getDynamicLinker(Args))); + } + } + + CmdArgs.push_back("--eh-frame-hdr"); + + assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } + + CmdArgs.push_back("-z"); + CmdArgs.push_back("pack-relative-relocs"); + + bool HasNoStdLib = Args.hasArg(options::OPT_nostdlib, options::OPT_r); + bool HasNoStdLibXX = Args.hasArg(options::OPT_nostdlibxx); + bool HasNoLibC = Args.hasArg(options::OPT_nolibc); + bool HasNoStartFiles = Args.hasArg(options::OPT_nostartfiles); + bool HasNoDefaultLibs = Args.hasArg(options::OPT_nodefaultlibs); + + bool ShouldLinkStartFiles = !HasNoStartFiles && !HasNoStdLib; + bool ShouldLinkCompilerRuntime = !HasNoDefaultLibs && !HasNoStdLib; + bool ShouldLinkLibC = !HasNoLibC && !HasNoStdLib && !HasNoDefaultLibs; + bool ShouldLinkLibCXX = + D.CCCIsCXX() && !HasNoStdLibXX && !HasNoStdLib && !HasNoDefaultLibs; + + if (ShouldLinkStartFiles) { + if (!IsShared) + CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crt0.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()) + crtbegin_path = TC.GetFilePath("crtbeginS.o"); + CmdArgs.push_back(Args.MakeArgString(crtbegin_path)); + } + + Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u}); + + TC.AddFilePathLibArgs(Args, CmdArgs); + + if (D.isUsingLTO()) + addLTOOptions(TC, Args, CmdArgs, Output, Inputs, + D.getLTOMode() == LTOK_Thin); + + Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s, + options::OPT_t, options::OPT_r}); + + addLinkerCompressDebugSectionsOption(TC, Args, CmdArgs); + + AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); + + if (ShouldLinkCompilerRuntime) { + AddRunTimeLibs(TC, D, CmdArgs, Args); + + // We supply our own sanitizer runtimes that output errors to the + // Kernel debug log as well as stderr. + // FIXME: Properly port clang/gcc sanitizers and use those instead. + const SanitizerArgs &Sanitize = TC.getSanitizerArgs(Args); + if (Sanitize.needsUbsanRt()) + CmdArgs.push_back("-lubsan"); + } + + if (ShouldLinkLibCXX) { + 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"); + } + + // FIXME: This is currently required to building Ports, but we should take + // care of that in the Port's build system rather than here. + CmdArgs.push_back("-L=/usr/local/lib"); + + // Silence warnings when linking C code with a C++ '-stdlib' argument. + Args.ClaimAllArgs(options::OPT_stdlib_EQ); + + if (ShouldLinkLibC) + CmdArgs.push_back("-lc"); + + if (ShouldLinkStartFiles) { + 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()) + crtend_path = TC.GetFilePath("crtendS.o"); + CmdArgs.push_back(Args.MakeArgString(crtend_path)); + } + + const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); + C.addCommand(std::make_unique<Command>(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); +} + +SanitizerMask Serenity::getSupportedSanitizers() const { + return ToolChain::getSupportedSanitizers() | SanitizerKind::KernelAddress; +} + +Serenity::Serenity(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + getFilePaths().push_back(concat(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, concat(D.ResourceDir, "/include")); + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // FIXME: See FIXME about "/usr/local/lib" in Linker::ConstructJob. + addSystemInclude(DriverArgs, CC1Args, + concat(D.SysRoot, "/usr/local/include")); + + addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot, "/usr/include")); +} diff --git a/clang/lib/Driver/ToolChains/Serenity.h b/clang/lib/Driver/ToolChains/Serenity.h new file mode 100644 index 0000000000000..dcf94f016dc6a --- /dev/null +++ b/clang/lib/Driver/ToolChains/Serenity.h @@ -0,0 +1,90 @@ +//===---- 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 "Gnu.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 final : 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 final : public Generic_ELF { +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; + + RuntimeLibType GetDefaultRuntimeLibType() const override { + return ToolChain::RLT_CompilerRT; + } + + CXXStdlibType GetDefaultCXXStdlibType() const override { + return ToolChain::CST_Libcxx; + } + + const char *getDefaultLinker() const override { return "ld.lld"; } + + std::string getDynamicLinker(const llvm::opt::ArgList &) const override { + return "/usr/lib/Loader.so"; + } + + bool HasNativeLLVMSupport() const override { return true; } + + bool isPICDefault() const override { return true; } + bool isPIEDefault(const llvm::opt::ArgList &) const override { return true; } + bool isPICDefaultForced() const override { return false; } + + SanitizerMask getSupportedSanitizers() const override; + + bool IsMathErrnoDefault() const override { return false; } + + UnwindTableLevel + getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override { + return UnwindTableLevel::Asynchronous; + } + + LangOptions::StackProtectorMode + GetDefaultStackProtectorLevel(bool KernelOrKext) const override { + return LangOptions::SSPStrong; + } + +protected: + Tool *buildLinker() const override; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp index 3b0e0704ff8c4..e894086b66e76 100644 --- a/clang/lib/Lex/InitHeaderSearch.cpp +++ b/clang/lib/Lex/InitHeaderSearch.cpp @@ -227,6 +227,7 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths( case llvm::Triple::PS4: case llvm::Triple::PS5: case llvm::Triple::RTEMS: + case llvm::Triple::Serenity: case llvm::Triple::Solaris: case llvm::Triple::UEFI: case llvm::Triple::WASI: diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-serenity/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-serenity/clang_rt.crtbegin.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-serenity/clang_rt.crtend.o b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-serenity/clang_rt.crtend.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/riscv64-unknown-serenity/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/riscv64-unknown-serenity/clang_rt.crtbegin.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/riscv64-unknown-serenity/clang_rt.crtend.o b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/riscv64-unknown-serenity/clang_rt.crtend.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-serenity/clang_rt.crtbegin.o b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-serenity/clang_rt.crtbegin.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-serenity/clang_rt.crtend.o b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-serenity/clang_rt.crtend.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/serenity_tree/usr/include/c++/v1/.keep b/clang/test/Driver/Inputs/serenity_tree/usr/include/c++/v1/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/serenity_tree/usr/lib/crt0.o b/clang/test/Driver/Inputs/serenity_tree/usr/lib/crt0.o new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/serenity_tree/usr/local/.keep b/clang/test/Driver/Inputs/serenity_tree/usr/local/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c index f5d0745422790..7a63e79742f85 100644 --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -329,3 +329,11 @@ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 // RUN: %clang -c %s --target=i586-pc-haiku -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 + +// Serenity has PIC and PIE by default +// RUN: %clang -c %s --target=x86_64-unkown-serenity -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s --target=aarch64-unkown-serenity -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s --target=riscv64-unkown-serenity -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 diff --git a/clang/test/Driver/save-stats.c b/clang/test/Driver/save-stats.c index ad7867a991686..4821a2f175c32 100644 --- a/clang/test/Driver/save-stats.c +++ b/clang/test/Driver/save-stats.c @@ -30,6 +30,8 @@ // RUN: %clang --target=x86_64-unknown-fuchsia -save-stats -flto -o obj/dir/save-stats.exe -Wl,-plugin-opt=-dummy %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO // RUN: %clang --target=x86_64-unknown-haiku -save-stats -flto -o obj/dir/save-stats.exe %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO // RUN: %clang --target=x86_64-unknown-haiku -save-stats -flto -o obj/dir/save-stats.exe -Wl,-plugin-opt=-dummy %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO +// RUN: %clang --target=x86_64-unknown-serenity -save-stats -flto -o obj/dir/save-stats.exe %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO +// RUN: %clang --target=x86_64-unknown-serenity -save-stats -flto -o obj/dir/save-stats.exe -Wl,-plugin-opt=-dummy %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO // RUN: %clang --target=avr -save-stats -flto -o obj/dir/save-stats.exe %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO // RUN: %clang --target=avr -save-stats -flto -o obj/dir/save-stats.exe -Wl,-plugin-opt=-dummy %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO // CHECK-LTO: "-stats-file=save-stats.stats" diff --git a/clang/test/Driver/serenity.cpp b/clang/test/Driver/serenity.cpp new file mode 100644 index 0000000000000..c748dc0473011 --- /dev/null +++ b/clang/test/Driver/serenity.cpp @@ -0,0 +1,254 @@ +// UNSUPPORTED: system-windows + +/// Check default header and linker paths for each supported triple +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: 2>&1 | FileCheck %s --check-prefix=PATHS + +// RUN: %clang -### %s --target=aarch64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: 2>&1 | FileCheck %s --check-prefix=PATHS + +// RUN: %clang -### %s --target=riscv64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: 2>&1 | FileCheck %s --check-prefix=PATHS + +// PATHS: "-resource-dir" "[[RESOURCE:[^"]+]]" +// PATHS-SAME: "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/include/c++/v1" +// PATHS-SAME: "-internal-isystem" "[[RESOURCE]]/include" +// PATHS-SAME: "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// PATHS-SAME: "-internal-isystem" "[[SYSROOT]]/usr/include" +// PATHS: "-L[[SYSROOT]]/usr/lib" +// PATHS-SAME: "-L=/usr/local/lib" + +/// Check include paths with -nostdinc +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -fsyntax-only -nostdinc 2>&1 | FileCheck %s --check-prefix=PATH_NOSTDINC +// PATH_NOSTDINC: "-nostdsysteminc" "-nobuiltininc" +// PATH_NOSTDINC-NOT: /include + +/// Check include paths with -nobuiltininc +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -fsyntax-only -nobuiltininc 2>&1 | FileCheck %s --check-prefix=PATH_NOBUILTIN +// PATH_NOBUILTIN: "-nobuiltininc" +// PATH_NOBUILTIN-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]" +// PATH_NOBUILTIN-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// PATH_NOBUILTIN-SAME: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// PATH_NOBUILTIN-NOT: "-internal-isystem" "[[RESOURCE]]/include" +// PATH_NOBUILTIN-SAME: "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// PATH_NOBUILTIN-SAME: "-internal-isystem" "[[SYSROOT]]/usr/include" + +/// Check include paths with -nostdlibinc +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -fsyntax-only -nostdlibinc 2>&1 | FileCheck %s --check-prefix=PATH_NOSTDLIBINC +// PATH_NOSTDLIBINC: "-nostdsysteminc" +// PATH_NOSTDLIBINC-SAME: "-resource-dir" "[[RESOURCE:[^"]+]]" +// PATH_NOSTDLIBINC-SAME: "-isysroot" "[[SYSROOT:[^"]+]]" +// PATH_NOSTDLIBINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// PATH_NOSTDLIBINC-SAME: "-internal-isystem" "[[RESOURCE]]/include" +// PATH_NOSTDLIBINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include" +// PATH_NOSTDLIBINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include" + +/// Check default linker args for each supported triple +// RUN: %clang -### %s --target=x86_64-unknown-serenity -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir 2>&1 | FileCheck %s --check-prefix=SERENITY_X86_64,DEFAULT_LINKER +// SERENITY_X86_64: "-cc1" "-triple" "[[TRIPLE:x86_64-unknown-serenity]]" + +// RUN: %clang -### %s --target=aarch64-unknown-serenity -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir 2>&1 | FileCheck %s --check-prefix=SERENITY_AARCH64,DEFAULT_LINKER +// SERENITY_AARCH64: "-cc1" "-triple" "[[TRIPLE:aarch64-unknown-serenity]]" + +// RUN: %clang -### %s --target=riscv64-unknown-serenity -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir 2>&1 | FileCheck %s --check-prefix=SERENITY_RISCV64,DEFAULT_LINKER +// SERENITY_RISCV64: "-cc1" "-triple" "[[TRIPLE:riscv64-unknown-serenity]]" + +// DEFAULT_LINKER: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// DEFAULT_LINKER-SAME: "-pie" +// DEFAULT_LINKER-SAME: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// DEFAULT_LINKER-SAME: "-o" "a.out" +// DEFAULT_LINKER-SAME: "-z" "pack-relative-relocs" +// DEFAULT_LINKER-SAME: "crt0.o" +// DEFAULT_LINKER-SAME: "[[RESOURCE:[^"]+]]/lib/[[TRIPLE]]/clang_rt.crtbegin.o" +// DEFAULT_LINKER-SAME: "[[RESOURCE]]/lib/[[TRIPLE]]/libclang_rt.builtins.a" +// DEFAULT_LINKER-SAME: "-lc" "[[RESOURCE]]/lib/[[TRIPLE]]/clang_rt.crtend.o" + +/// Check if the sysroot is passed to the linker +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=TestSysroot \ +// RUN: -static-pie 2>&1 | FileCheck %s --check-prefix=LINKER_SYSROOT +// LINKER_SYSROOT: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// LINKER_SYSROOT-SAME: "--sysroot=TestSysroot" + +/// -static-pie suppresses -dynamic-linker +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot= -resource-dir= \ +// RUN: -static-pie 2>&1 | FileCheck %s --check-prefix=STATIC_PIE +// STATIC_PIE: "-static" "-pie" +// STATIC_PIE-NOT: "-dynamic-linker" +// STATIC_PIE-SAME: "--no-dynamic-linker" "-z" "text" +// STATIC_PIE-SAME: "--eh-frame-hdr" +// STATIC_PIE-SAME: "-z" "pack-relative-relocs" +// STATIC_PIE-SAME: "crt0.o" "crtbeginS.o" +// STATIC_PIE-SAME: "-lc" "crtendS.o" + +/// -shared forces use of shared crt files +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot= -resource-dir= \ +// RUN: -shared 2>&1 | FileCheck %s --check-prefix=SHARED +// SHARED: "-shared" +// SHARED-SAME: "--eh-frame-hdr" +// SHARED-SAME: "-z" "pack-relative-relocs" +// SHARED-NOT: "crt0.o" +// SHARED-SAME: "crtbeginS.o" +// SHARED-SAME: "-lc" "crtendS.o" + +/// -static forces use of static crt files +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot= -resource-dir= \ +// RUN: -static 2>&1 | FileCheck %s --check-prefix=STATIC +// STATIC: "-static" +// STATIC-SAME: "--eh-frame-hdr" +// STATIC-SAME: "-z" "pack-relative-relocs" +// STATIC-SAME: "crt0.o" "crtbeginS.o" +// STATIC-SAME: "-lc" "crtendS.o" + +/// -rdynamic passes -export-dynamic +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot= -resource-dir= \ +// RUN: -rdynamic 2>&1 | FileCheck %s --check-prefix=RDYNAMIC,RDYNAMIC_SHARED +// RDYNAMIC: "-export-dynamic" "-pie" + +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot= -resource-dir= \ +// RUN: -no-pie -rdynamic 2>&1 | FileCheck %s --check-prefix=RDYNAMIC_NOPIE,RDYNAMIC_SHARED +// RDYNAMIC_NOPIE: "-export-dynamic" +// RDYNAMIC_NOPIE-NOT: "-pie" + +// RDYNAMIC_SHARED-SAME: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// RDYNAMIC_SHARED-SAME: "-o" "a.out" +// RDYNAMIC_SHARED-SAME: "-z" "pack-relative-relocs" +// RDYNAMIC_SHARED-SAME: "crt0.o" "crtbeginS.o" +// RDYNAMIC_SHARED-SAME: "-lc" "crtendS.o" + +/// -nostdlib suppresses default -l and crt*.o +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_tree/usr/local/bin -resource-dir= \ +// RUN: -nostdlib --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=NOSTDLIB +// NOSTDLIB: "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/include/c++/v1" +// NOSTDLIB-NOT: crt{{[^./]+}}.o +// NOSTDLIB: "-L +// NOSTDLIB-SAME: {{^}}[[SYSROOT]]/usr/lib" +// NOSTDLIB-NOT: "-l +// NOSTDLIB-NOT: libclang_rt.builtins-x86_64.a +// NOSTDLIB-NOT: crt{{[^./]+}}.o + +// -nostartfiles suppresses crt*.o, but not default -l +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_tree/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -nostartfiles --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=NOSTARTFILES +// NOSTARTFILES: "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/include/c++/v1" +// NOSTARTFILES-SAME: {{^}} +// NOSTARTFILES-NOT: crt{{[^./]+}}.o +// NOSTARTFILES: "-L +// NOSTARTFILES-SAME: {{^}}[[SYSROOT]]/usr/lib" +// NOSTARTFILES: lib/x86_64-unknown-serenity/libclang_rt.builtins.a" +// NOSTARTFILES: "-lc" +// NOSTARTFILES-NOT: crt{{[^./]+}}.o + +/// -r suppresses -dynamic-linker, default -l, and crt*.o like -nostdlib. +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_tree/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -r --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=RELOCATABLE +// RELOCATABLE-NOT: "-dynamic-linker" +// RELOCATABLE: "-internal-isystem" +// RELOCATABLE-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/include/c++/v1" +// RELOCATABLE-NOT: crt{{[^./]+}}.o +// RELOCATABLE: "-L +// RELOCATABLE-SAME: {{^}}[[SYSROOT]]/usr/lib" +// RELOCATABLE-NOT: "-l +// RELOCATABLE-NOT: crt{{[^./]+}}.o +// RELOCATABLE-NOT: libclang_rt.builtins-x86_64.a + +/// -nolibc suppresses -lc but not other default -l +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_tree/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -nolibc --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=NOLIBC +// NOLIBC: "-internal-isystem" +// NOLIBC-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/include/c++/v1" +// NOLIBC: "[[SYSROOT:[^"]+]]/usr/lib/crt0.o" "crtbeginS.o" +// NOLIBC: "-L +// NOLIBC-SAME: {{^}}[[SYSROOT]]/usr/lib" +// NOLIBC-NOT: "-lc" +// NOLIBC: "[[RESOURCE:[^"]+]]/lib/x86_64-unknown-serenity/libclang_rt.builtins.a" +// NOLIBC: "crtendS.o" + +/// -fsanitize=undefined redirects to Serenity-custom UBSAN runtime +// RUN: %clang -### %s --target=x86_64-unknown-serenity --sysroot=%S/Inputs/serenity_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_tree/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -fsanitize=undefined --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=UBSAN +// UBSAN-NOT: "libclang_rt.ubsan{{[^./]+}}.a" +// UBSAN-NOT: "libclang_rt.ubsan{{[^./]+}}.so" +// UBSAN: "-lubsan" + +/// C++ stdlib behavior +// RUN: %clangxx -### %s --target=x86_64-unknown-serenity --sysroot="" -resource-dir= \ +// RUN: 2>&1 | FileCheck %s --check-prefix=DEFAULT_LIBCXX +// DEFAULT_LIBCXX: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// DEFAULT_LIBCXX: "-z" "pack-relative-relocs" +// DEFAULT_LIBCXX: "crt0.o" "crtbeginS.o" +// DEFAULT_LIBCXX: "--push-state" +// DEFAULT_LIBCXX: "--as-needed" +// DEFAULT_LIBCXX: "-lc++" +// DEFAULT_LIBCXX: "--pop-state" +// DEFAULT_LIBCXX: "-lc" "crtendS.o" + +// RUN: %clangxx -### %s --target=x86_64-unknown-serenity --sysroot="" -resource-dir= \ +// RUN: -static 2>&1 | FileCheck %s --check-prefix=STATIC_LIBCXX +// STATIC_LIBCXX: "-z" "pack-relative-relocs" +// STATIC_LIBCXX: "crt0.o" "crtbeginS.o" +// STATIC_LIBCXX: "--push-state" +// STATIC_LIBCXX: "--as-needed" +// STATIC_LIBCXX: "-lc++" +// STATIC_LIBCXX: "--pop-state" +// STATIC_LIBCXX: "-lc" "crtendS.o" + +// RUN: %clangxx -### %s --target=x86_64-unknown-serenity --sysroot="" -resource-dir= \ +// RUN: -static-libstdc++ 2>&1 | FileCheck %s --check-prefix=STATIC_LIBSTDCXX +// STATIC_LIBSTDCXX: "-z" "pack-relative-relocs" +// STATIC_LIBSTDCXX: "crt0.o" "crtbeginS.o" +// STATIC_LIBSTDCXX: "--push-state" +// STATIC_LIBSTDCXX: "--as-needed" +// STATIC_LIBSTDCXX: "-Bstatic" +// STATIC_LIBSTDCXX: "-lc++" +// STATIC_LIBSTDCXX: "-Bdynamic" +// STATIC_LIBSTDCXX: "--pop-state" +// STATIC_LIBSTDCXX: "-lc" "crtendS.o" + +// RUN: %clangxx -### %s --target=x86_64-unknown-serenity --sysroot="" -resource-dir= \ +// RUN: -nostdlib++ 2>&1 | FileCheck %s --check-prefix=NO_LIBCXX +// NO_LIBCXX: "-z" "pack-relative-relocs" +// NO_LIBCXX: "crt0.o" "crtbeginS.o" +// NO_LIBCXX-SAME: "--as-needed" +// NO_LIBCXX-SAME: "-lunwind" +// NO_LIBCXX-NOT: "-lc++" +// NO_LIBCXX-SAME: "-lc" "crtendS.o" + +/// Check that unwind tables are enabled +// RUN: %clang --target=x86_64-unknown-serenity -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=UNWIND-TABLES %s +// RUN: %clang --target=aarch64-unknown-serenity -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=UNWIND-TABLES %s +// RUN: %clang --target=riscv64-unknown-serenity -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=UNWIND-TABLES %s +// UNWIND-TABLES: "-funwind-tables=2" + +/// Check that parameters are forwarded to the linker + +// RUN: %clang --target=x86_64-unknown-serenity -### %s -L/foo -u bar -T script.ld -s -t -r 2>&1 \ +// RUN: | FileCheck %s --check-prefix=LINK +// LINK: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// LINK-SAME: "-L/foo" +// LINK-SAME: "-u" "bar" +// LINK-SAME: "-T" "script.ld" +// LINK-SAME: "-s" +// LINK-SAME: "-t" +// LINK-SAME: "-r" + +// RUN: %clang --target=x86_64-unknown-serenity -### %s -Wl,--compress-debug-sections=zlib 2>&1 \ +// RUN: | FileCheck %s --check-prefix=COMPRESS +// COMPRESS: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// COMPRESS: "--compress-debug-sections=zlib" >From 0301cdddae1663ea8092195b9db9e2500f962000 Mon Sep 17 00:00:00 2001 From: Lucas Chollet <[email protected]> Date: Sun, 22 Mar 2026 17:23:46 +0100 Subject: [PATCH 2/2] fix ci failures It surprisingly compiles just fine with GCC. --- clang/lib/Driver/ToolChains/Serenity.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp index a61f2f81d1f66..c6dbba39b1b39 100644 --- a/clang/lib/Driver/ToolChains/Serenity.cpp +++ b/clang/lib/Driver/ToolChains/Serenity.cpp @@ -27,7 +27,7 @@ void tools::serenity::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const auto &TC = cast<Generic_ELF const&>(getToolChain()); + const auto &TC = cast<Generic_ELF>(getToolChain()); const auto &D = TC.getDriver(); const bool IsShared = Args.hasArg(options::OPT_shared); const bool IsStatic = @@ -55,8 +55,8 @@ void tools::serenity::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (!IsShared) { Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, options::OPT_nopie); - bool IsPIE = A ? A->getOption().matches(options::OPT_pie) : - TC.isPIEDefault(Args); + bool IsPIE = + A ? A->getOption().matches(options::OPT_pie) : TC.isPIEDefault(Args); if (IsPIE) CmdArgs.push_back("-pie"); CmdArgs.push_back("-dynamic-linker"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
