diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -166,6 +166,9 @@ case llvm::Triple::OpenBSD: return std::make_unique>(Triple, Opts); + case llvm::Triple::Serenity: + return std::make_unique>(Triple, + Opts); case llvm::Triple::Win32: switch (Triple.getEnvironment()) { case llvm::Triple::GNU: @@ -463,6 +466,9 @@ return std::make_unique>(Triple, Opts); } + case llvm::Triple::Serenity: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } @@ -586,6 +592,9 @@ return std::make_unique(Triple, Opts); case llvm::Triple::Hurd: return std::make_unique>(Triple, Opts); + case llvm::Triple::Serenity: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } @@ -644,6 +653,9 @@ return std::make_unique>(Triple, Opts); case llvm::Triple::PS5: return std::make_unique>(Triple, Opts); + case llvm::Triple::Serenity: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -982,6 +982,23 @@ } }; +// SerenityOS target +template +class LLVM_LIBRARY_VISIBILITY SerenityTargetInfo : public OSTargetInfo { +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(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 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -75,6 +75,7 @@ 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 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -43,6 +43,7 @@ #include "ToolChains/PS4CPU.h" #include "ToolChains/RISCVToolchain.h" #include "ToolChains/SPIRV.h" +#include "ToolChains/Serenity.h" #include "ToolChains/Solaris.h" #include "ToolChains/TCE.h" #include "ToolChains/VEToolchain.h" @@ -6246,6 +6247,9 @@ case llvm::Triple::Fuchsia: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::Serenity: + TC = std::make_unique(*this, Target, Args); + break; case llvm::Triple::Solaris: TC = std::make_unique(*this, Target, Args); break; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -589,6 +589,8 @@ 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.h b/clang/lib/Driver/ToolChains/Serenity.h new file mode 100644 --- /dev/null +++ b/clang/lib/Driver/ToolChains/Serenity.h @@ -0,0 +1,84 @@ +//===---- 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"; } + + 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; } + + 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/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp new file mode 100644 --- /dev/null +++ b/clang/lib/Driver/ToolChains/Serenity.cpp @@ -0,0 +1,211 @@ +//===---- 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/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/VirtualFileSystem.h" +#include + +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); + 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"); + } + + 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"); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_r)) { + 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, options::OPT_u}); + + TC.AddFilePathLibArgs(Args, CmdArgs); + + if (D.isUsingLTO()) { + assert(!Inputs.empty() && "Must have at least one input."); + // Find the first filename InputInfo object. + auto const* Input = llvm::find_if( + Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); }); + if (Input == Inputs.end()) + // For a very rare case, all of the inputs to the linker are + // InputArg. If that happens, just use the first InputInfo. + Input = Inputs.begin(); + + addLTOOptions(TC, Args, CmdArgs, Output, *Input, + 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 (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, + options::OPT_r)) { + 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 (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"); + } + + // Silence warnings when linking C code with a C++ '-stdlib' argument. + Args.ClaimAllArgs(options::OPT_stdlib_EQ); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, + options::OPT_r)) { + if (!Args.hasArg(options::OPT_nolibc)) + CmdArgs.push_back("-lc"); + } + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, + options::OPT_r)) { + 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"))); + } + + const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); + C.addCommand(std::make_unique(JA, *this, + ResponseFileSupport::AtFileCurCP(), + Exec, CmdArgs, Inputs, Output)); +} + +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; + + addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot, "/usr/include")); +} diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp --- a/clang/lib/Lex/InitHeaderSearch.cpp +++ b/clang/lib/Lex/InitHeaderSearch.cpp @@ -304,6 +304,7 @@ case llvm::Triple::PS4: case llvm::Triple::PS5: case llvm::Triple::RTEMS: + case llvm::Triple::Serenity: case llvm::Triple::Solaris: case llvm::Triple::WASI: case llvm::Triple::ZOS: diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/include/c++/v1/.keep b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/include/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/include/x86_64-pc-serenity/c++/v1/.keep b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/include/x86_64-pc-serenity/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crt0.o b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crt0.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crt0_shared.o b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crt0_shared.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crti.o b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crti.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crtn.o b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crtn.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/local/.keep b/clang/test/Driver/Inputs/serenity_x86_64_tree/usr/local/.keep new file mode 100644 diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -330,3 +330,9 @@ // 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-pc-serenity -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s --target=aarch64-pc-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 --- a/clang/test/Driver/save-stats.c +++ b/clang/test/Driver/save-stats.c @@ -28,6 +28,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=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 +// RUN: %clang --target=x86_64-pc-serenity -save-stats -flto -o obj/dir/save-stats.exe %s -### 2>&1 | FileCheck %s -check-prefix=CHECK-LTO +// RUN: %clang --target=x86_64-pc-serenity -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" // CHECK-LTO: "-o" "obj/dir{{/|\\\\}}save-stats.exe" // CHECK-LTO: "-plugin-opt=stats-file=save-stats.stats" diff --git a/clang/test/Driver/serenity.cpp b/clang/test/Driver/serenity.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/serenity.cpp @@ -0,0 +1,196 @@ +// UNSUPPORTED: system-windows + +/// Check default header and linker paths +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot=%S/Inputs/serenity_x86_64_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_x86_64/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: 2>&1 | FileCheck %s --check-prefix=PATHS_X86_64 +// PATHS_X86_64: "-resource-dir" "[[RESOURCE:[^"]+]]" +// PATHS_X86_64: "-internal-isystem" +// PATHS_X86_64-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/include/x86_64-pc-serenity/c++/v1" +// PATHS_X86_64-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/include/c++/v1" +// PATHS_X86_64-SAME: {{^}} "-internal-isystem" "[[RESOURCE]]/include" +// PATHS_X86_64-SAME: {{^}} "-internal-isystem" "[[SYSROOT:[^"]+]]/usr/include" +// PATHS_X86_64: "-L +// PATHS_X86_64-SAME: {{^}}[[SYSROOT]]/usr/lib" + +/// Check default linker args for each supported triple +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot= 2>&1 | FileCheck %s --check-prefix=SERENITY_X86_64 +// SERENITY_X86_64: "-cc1" "-triple" "x86_64-pc-serenity" +// SERENITY_X86_64: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// SERENITY_X86_64: "-pie" +// SERENITY_X86_64: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// SERENITY_X86_64: "-o" "a.out" +// SERENITY_X86_64: "-z" "pack-relative-relocs" +// SERENITY_X86_64: "crt0.o" "crti.o" "crtbeginS.o" +// SERENITY_X86_64: "-lc" "crtendS.o" "crtn.o" + +// RUN: %clang -### %s --target=aarch64-pc-serenity --sysroot= 2>&1 | FileCheck %s --check-prefix=SERENITY_AARCH64 +// SERENITY_AARCH64: "-cc1" "-triple" "aarch64-pc-serenity" +// SERENITY_AARCH64: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// SERENITY_AARCH64: "-pie" +// SERENITY_AARCH64: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// SERENITY_AARCH64: "-o" "a.out" +// SERENITY_AARCH64: "-z" "pack-relative-relocs" +// SERENITY_AARCH64: "crt0.o" "crti.o" "crtbeginS.o" +// SERENITY_AARCH64: "-lc" "crtendS.o" "crtn.o" + +// RUN: %clang -### %s --target=riscv64-pc-serenity --sysroot= 2>&1 | FileCheck %s --check-prefix=SERENITY_RISCV64 +// SERENITY_RISCV64: "-cc1" "-triple" "riscv64-pc-serenity" +// SERENITY_RISCV64: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld" +// SERENITY_RISCV64: "-pie" +// SERENITY_RISCV64: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// SERENITY_RISCV64: "-o" "a.out" +// SERENITY_RISCV64: "-z" "pack-relative-relocs" +// SERENITY_RISCV64: "crt0.o" "crti.o" "crtbeginS.o" +// SERENITY_RISCV64: "-lc" "crtendS.o" "crtn.o" + +/// -static-pie suppresses -dynamic-linker +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot= \ +// -static-pie 2>&1 | FileCheck %s --check-prefix=STATIC_PIE +// STATIC_PIE: "-pie" "-static" +// STATIC_PIE-NOT: "-dynamic-linker" +// STATIC_PIE: "--no-dynamic-linker" "-z" "text" +// STATIC_PIE: "--eh-frame-hdr" "-z" "pack-relative-relocs" +// STATIC_PIE: "crt0.o" "crti.o" "crtbeginS.o" +// STATIC_PIE: "-lc" "crtendS.o" "crtn.o" + +/// -shared forces use of shared crt files +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot= \ +// -shared 2>&1 | FileCheck %s --check-prefix=SHARED +// SHARED: "-shared" +// SHARED: "--eh-frame-hdr" "-z" "pack-relative-relocs" +// SHARED: "crt0_shared.o" "crti.o" "crtbeginS.o" +// SHARED: "-lc" "crtendS.o" "crtn.o" + +/// -static forces use of static crt files +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot= \ +// -static 2>&1 | FileCheck %s --check-prefix=STATIC +// STATIC: "-static" +// STATIC: "--eh-frame-hdr" "-z" "pack-relative-relocs" +// STATIC: "crt0.o" "crti.o" "crtbegin.o" +// STATIC: "-lc" "crtend.o" "crtn.o" + +/// -rdynamic passes -export-dynamic +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot= \ +// -rdynamic 2>&1 | FileCheck %s --check-prefix=RDYNAMIC +// RDYNAMIC: "-pie" "-export-dynamic" +// RDYNAMIC: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// RDYNAMIC: "-o" "a.out" +// RDYNAMIC: "-z" "pack-relative-relocs" +// RDYNAMIC: "crt0.o" "crti.o" "crtbeginS.o" +// RDYNAMIC: "-lc" "crtendS.o" "crtn.o" + +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot= \ +// -no-pie -rdynamic 2>&1 | FileCheck %s --check-prefix=RDYNAMIC_NOPIE +// RDYNAMIC_NOPIE-NOT: "-pie" +// RDYNAMIC_NOPIE: "-export-dynamic" +// RDYNAMIC_NOPIE: "-dynamic-linker" "/usr/lib/Loader.so" "--eh-frame-hdr" +// RDYNAMIC_NOPIE: "-o" "a.out" +// RDYNAMIC_NOPIE: "-z" "pack-relative-relocs" +// RDYNAMIC_NOPIE: "crt0.o" "crti.o" "crtbeginS.o" +// RDYNAMIC_NOPIE: "-lc" "crtendS.o" "crtn.o" + +/// -nostdlib suppresses default -l and crt*.o +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot=%S/Inputs/serenity_x86_64_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_x86_64_tree/usr/local/bin -resource-dir=%S/Inputs/resource_dir \ +// RUN: -nostdlib --rtlib=compiler-rt 2>&1 | FileCheck %s --check-prefix=NOSTDLIB +// NOSTDLIB: "-internal-isystem" +// NOSTDLIB-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/include/x86_64-pc-serenity/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-pc-serenity --sysroot=%S/Inputs/serenity_x86_64_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_x86_64_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" +// NOSTARTFILES-SAME: {{^}} "[[SYSROOT:[^"]+]]/usr/include/x86_64-pc-serenity/c++/v1" +// NOSTARTFILES-NOT: crt{{[^./]+}}.o +// NOSTARTFILES: "-L +// NOSTARTFILES-SAME: {{^}}[[SYSROOT]]/usr/lib" +// NOSTARTFILES: "[[RESOURCE:[^"]+]]/lib/serenity/libclang_rt.builtins-x86_64.a" +// NOSTARTFILES: "-lc" +// NOSTARTFILES-NOT: crt{{[^./]+}}.o + +/// -r suppresses -dynamic-linker, default -l, and crt*.o like -nostdlib. +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot=%S/Inputs/serenity_x86_64_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_x86_64_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/x86_64-pc-serenity/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-pc-serenity --sysroot=%S/Inputs/serenity_x86_64_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_x86_64_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/x86_64-pc-serenity/c++/v1" +// NOLIBC: "[[SYSROOT:[^"]+]]/usr/lib/crt0.o" "[[SYSROOT:[^"]+]]/usr/lib/crti.o" "crtbeginS.o" +// NOLIBC: "-L +// NOLIBC-SAME: {{^}}[[SYSROOT]]/usr/lib" +// NOLIBC-NOT: "-lc" +// NOLIBC: "[[RESOURCE:[^"]+]]/lib/serenity/libclang_rt.builtins-x86_64.a" +// NOLIBC: "crtendS.o" "[[SYSROOT:[^"]+]]/usr/lib/crtn.o" + +/// -fsanitize=undefined redirects to Serenity-custom UBSAN runtime +// RUN: %clang -### %s --target=x86_64-pc-serenity --sysroot=%S/Inputs/serenity_x86_64_tree \ +// RUN: -ccc-install-dir %S/Inputs/serenity_x86_64_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-pc-serenity --sysroot="" \ +// 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" "crti.o" "crtbeginS.o" +// DEFAULT_LIBCXX: "--push-state" +// DEFAULT_LIBCXX: "--as-needed" +// DEFAULT_LIBCXX: "-lc++" +// DEFAULT_LIBCXX: "--pop-state" +// DEFAULT_LIBCXX: "-lc" "crtendS.o" "crtn.o" + +// RUN: %clangxx -### %s --target=x86_64-pc-serenity --sysroot="" \ +// RUN: -static 2>&1 | FileCheck %s --check-prefix=STATIC_LIBCXX +// STATIC_LIBCXX: "-z" "pack-relative-relocs" +// STATIC_LIBCXX: "crt0.o" "crti.o" "crtbegin.o" +// STATIC_LIBCXX: "--push-state" +// STATIC_LIBCXX: "--as-needed" +// STATIC_LIBCXX: "-lc++" +// STATIC_LIBCXX: "--pop-state" +// STATIC_LIBCXX: "-lc" "crtend.o" "crtn.o" + +// RUN: %clangxx -### %s --target=x86_64-pc-serenity --sysroot="" \ +// RUN: -static-libstdc++ 2>&1 | FileCheck %s --check-prefix=STATIC_LIBSTDCXX +// STATIC_LIBSTDCXX: "-z" "pack-relative-relocs" +// STATIC_LIBSTDCXX: "crt0.o" "crti.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" "crtn.o" + +// RUN: %clangxx -### %s --target=x86_64-pc-serenity --sysroot="" \ +// RUN: -nostdlib++ 2>&1 | FileCheck %s --check-prefix=NO_LIBCXX +// NO_LIBCXX: "-z" "pack-relative-relocs" +// NO_LIBCXX: "crt0.o" "crti.o" "crtbeginS.o" +// NO_LIBCXX-NOT: "--push-state" +// NO_LIBCXX-NOT: "--as-needed" +// NO_LIBCXX-NOT: "-lc++" +// NO_LIBCXX-NOT: "--pop-state" +// NO_LIBCXX: "-lc" "crtendS.o" "crtn.o"