diff --git a/Meta/build-root-filesystem.sh b/Meta/build-root-filesystem.sh index 64006129de7..bdd571f69c9 100755 --- a/Meta/build-root-filesystem.sh +++ b/Meta/build-root-filesystem.sh @@ -45,7 +45,18 @@ else chown -R 0:0 mnt/ fi SERENITY_ARCH="${SERENITY_ARCH:-i686}" -$CP "$SERENITY_SOURCE_DIR"/Toolchain/Local/"$SERENITY_ARCH"/"$SERENITY_ARCH"-pc-serenity/lib/libgcc_s.so mnt/usr/lib/ +LLVM_VERSION="${LLVM_VERSION:-12.0.1}" + +if [ "$USE_CLANG_TOOLCHAIN" = "ON" ]; then + TOOLCHAIN_DIR="$SERENITY_SOURCE_DIR"/Toolchain/Local/clang/"$SERENITY_ARCH" + mkdir -p mnt/usr/lib/clang/"$LLVM_VERSION"/lib/serenity + $CP "$TOOLCHAIN_DIR"/lib/clang/"$LLVM_VERSION"/lib/serenity/* mnt/usr/lib/clang/"$LLVM_VERSION"/lib/serenity + $CP "$TOOLCHAIN_DIR"/lib/libunwind* mnt/usr/lib + $CP "$TOOLCHAIN_DIR"/lib/libc++* mnt/usr/lib +else + $CP "$SERENITY_SOURCE_DIR"/Toolchain/Local/"$SERENITY_ARCH"/"$SERENITY_ARCH"-pc-serenity/lib/libgcc_s.so mnt/usr/lib +fi + # If umask was 027 or similar when the repo was cloned, # file permissions in Base/ are too restrictive. Restore # the permissions needed in the image. diff --git a/Toolchain/BuildClang.sh b/Toolchain/BuildClang.sh new file mode 100755 index 00000000000..27f6d3f3922 --- /dev/null +++ b/Toolchain/BuildClang.sh @@ -0,0 +1,353 @@ +#!/usr/bin/env bash +set -eo pipefail + +# === CONFIGURATION AND SETUP === + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +echo "$DIR" + +ARCH=${ARCH:-"i686"} +LLVM_ARCH= +[ "$ARCH" = "i686" ] && LLVM_ARCH="i386" || LLVM_ARCH="$ARCH" +LLVM_TARGET="$LLVM_ARCH-pc-serenity" +PREFIX="$DIR/Local/clang/$ARCH" +BUILD="$DIR/../Build/$ARCH" +SYSROOT="$BUILD/Root" + +MD5SUM="md5sum" +REALPATH="realpath" +MAKE="make" +NPROC="nproc" + +SYSTEM_NAME="$(uname -s)" + +if [ "$SYSTEM_NAME" = "OpenBSD" ]; then + MD5SUM="md5 -q" + REALPATH="readlink -f" + MAKE="gmake" + NPROC="sysctl -n hw.ncpuonline" + export CC=egcc + export CXX=eg++ + export LDFLAGS=-Wl,-z,notext +elif [ "$SYSTEM_NAME" = "FreeBSD" ]; then + MD5SUM="md5 -q" + MAKE="gmake" + NPROC="sysctl -n hw.ncpu" +fi + +if [ -z "$MAKEJOBS" ]; then + MAKEJOBS=$($NPROC) +fi + + +if [ ! -d "$BUILD" ]; then + mkdir -p "$BUILD" +fi +BUILD=$($REALPATH "$BUILD") + +dev= +while [ "$1" != "" ]; do + case $1 in + --dev ) dev=1 + ;; + esac + shift +done + +echo PREFIX is "$PREFIX" +echo SYSROOT is "$SYSROOT" + +mkdir -p "$DIR/Tarballs" + +LLVM_VERSION="12.0.1" +LLVM_MD5SUM="c28061313a4f1b7d74cd491a19f569b4" +LLVM_NAME="llvm-project-$LLVM_VERSION.src" +LLVM_PKG="$LLVM_NAME.tar.xz" +LLVM_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_PKG" + +# We need GNU binutils because we use a feature that llvm-objdump doesn't support yet. +BINUTILS_VERSION="2.37" +BINUTILS_MD5SUM="1e55743d73c100b7a0d67ffb32398cdb" +BINUTILS_NAME="binutils-$BINUTILS_VERSION" +BINUTILS_PKG="${BINUTILS_NAME}.tar.gz" +BINUTILS_BASE_URL="https://ftp.gnu.org/gnu/binutils" + +buildstep() { + NAME=$1 + shift + "$@" 2>&1 | sed $'s|^|\x1b[34m['"${NAME}"$']\x1b[39m |' +} + +# === DEPENDENCIES === +buildstep dependencies echo "Checking whether 'make' is available..." +if ! command -v ${MAKE:-make} >/dev/null; then + buildstep dependencies echo "Please make sure to install GNU Make (for the '${MAKE:-make}' tool)." + exit 1 +fi + +buildstep dependencies echo "Checking whether CMake is available..." +if ! command -v cmake >/dev/null; then + buildstep dependencies echo "Please make sure to install CMake." + exit 1 +fi + +buildstep dependencies echo "Checking whether 'patch' is available..." +if ! command -v patch >/dev/null; then + buildstep dependencies echo "Please make sure to install GNU patch." +fi + +buildstep dependencies echo "Checking whether your C compiler works..." +if ! ${CC:-cc} -o /dev/null -xc - >/dev/null <<'PROGRAM' +int main() {} +PROGRAM +then + buildstep dependencies echo "Please make sure to install a working C compiler." + exit 1 +fi + +buildstep dependencies echo "Checking whether your C++ compiler works..." +if ! ${CXX:-c++} -o /dev/null -xc - >/dev/null <<'PROGRAM' +int main() {} +PROGRAM +then + buildstep dependencies echo "Please make sure to install a working C++ compiler." + exit 1 +fi + +# === DOWNLOAD AND PATCH === + +pushd "$DIR/Tarballs" + md5="" + if [ -e "$LLVM_PKG" ]; then + md5="$($MD5SUM ${LLVM_PKG} | cut -f1 -d' ')" + echo "llvm md5='$md5'" + fi + + if [ "$md5" != "$LLVM_MD5SUM" ] ; then + rm -f "$LLVM_PKG" + curl -LO "$LLVM_URL" + else + echo "Skipped downloading LLVM" + fi + + if [ -d "$LLVM_NAME" ]; then + # Drop the previously patched extracted dir + rm -rf "${LLVM_NAME}" + # Also drop the build dir + rm -rf "$DIR/Build/clang/$ARCH" + fi + echo "Extracting LLVM..." + tar -xJf "$LLVM_PKG" + + pushd "$LLVM_NAME" + if [ "$dev" = "1" ]; then + git init > /dev/null + git add . > /dev/null + git commit -am "BASE" > /dev/null + git apply "$DIR"/Patches/llvm.patch > /dev/null + else + patch -p1 < "$DIR/Patches/llvm.patch" > /dev/null + fi + $MD5SUM "$DIR/Patches/llvm.patch" > .patch.applied + popd + + md5="" + if [ -e "$BINUTILS_PKG" ]; then + md5="$($MD5SUM $BINUTILS_PKG | cut -f1 -d' ')" + echo "bu md5='$md5'" + fi + + if [ "$md5" != "$BINUTILS_MD5SUM" ]; then + rm -f "$BINUTILS_PKG" + curl -LO "$BINUTILS_BASE_URL/$BINUTILS_PKG" + else + echo "Skipped downloading GNU binutils" + fi + + if [ -d "$BINUTILS_NAME" ]; then + rm -rf "$BINUTILS_NAME" + rm -rf "$DIR/Build/clang/$ARCH/binutils" + fi + echo "Extracting GNU binutils" + + + tar -xzf "$BINUTILS_PKG" + pushd "$BINUTILS_NAME" + if [ "$dev" = "1" ]; then + git init > /dev/null + git add . > /dev/null + git commit -am "BASE" > /dev/null + git apply "$DIR"/Patches/binutils.patch > /dev/null + else + patch -p1 < "$DIR/Patches/binutils.patch" > /dev/null + fi + $MD5SUM "$DIR/Patches/binutils.patch" > .patch.applied + popd +popd + +# === COPY SERENITYOS HEADERS === + +mkdir -p "$BUILD" +pushd "$BUILD" + mkdir -p Root/usr/include/ + SRC_ROOT=$($REALPATH "$DIR"/..) + FILES=$(find "$SRC_ROOT"/Userland/Libraries/LibC "$SRC_ROOT"/Userland/Libraries/LibM "$SRC_ROOT"/Userland/Libraries/LibPthread "$SRC_ROOT"/Userland/Libraries/LibDl -name '*.h' -print) + for header in $FILES; do + target=$(echo "$header" | sed -e "s@$SRC_ROOT/Userland/Libraries/LibC@@" -e "s@$SRC_ROOT/Userland/Libraries/LibM@@" -e "s@$SRC_ROOT/Userland/Libraries/LibPthread@@" -e "s@$SRC_ROOT/Userland/Libraries/LibDl@@") + buildstep "system_headers" install -D "$header" "Root/usr/include/$target" + done + unset SRC_ROOT +popd + +# === COMPILE AND INSTALL === + +rm -rf "$PREFIX" +mkdir -p "$PREFIX" + +mkdir -p "$DIR/Build/clang/$ARCH" + +pushd "$DIR/Build/clang/$ARCH" + + mkdir -p llvm + pushd llvm + buildstep "llvm+clang/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/llvm" \ + -G Ninja \ + -DCMAKE_BUILD_TYPE="MinSizeRel" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DLLVM_DEFAULT_TARGET_TRIPLE="$LLVM_TARGET" \ + -DLLVM_TARGETS_TO_BUILD=X86 \ + -DLLVM_ENABLE_BINDINGS=OFF \ + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \ + -DLLVM_ENABLE_PROJECTS="clang;lld" \ + -DLLVM_INCLUDE_BENCHMARKS=OFF \ + -DLLVM_INCLUDE_TESTS=OFF \ + ${dev:+"-DLLVM_CCACHE_BUILD=ON"} || exit 1 + + buildstep "llvm+clang/build" ninja -j "$MAKEJOBS" || exit 1 + buildstep "llvm+clang/install" ninja install || exit 1 + popd + + LLVM_COMPILER_FLAGS="-target $LLVM_TARGET --sysroot $SYSROOT -ftls-model=initial-exec -ffreestanding -nostdlib -nostdlib++" + + mkdir -p "compiler-rt" + pushd compiler-rt + buildstep "compiler-rt/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/compiler-rt" \ + -GNinja \ + -DCMAKE_SYSROOT="$SYSROOT" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX/lib/clang/${LLVM_VERSION}" \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_AR="$PREFIX/bin/llvm-ar" \ + -DCMAKE_C_COMPILER="$PREFIX/bin/clang" \ + -DCMAKE_C_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \ + -DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_CXX_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_ASM_COMPILER="$PREFIX/bin/clang" \ + -DCMAKE_ASM_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_ASM_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \ + -DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=OFF \ + -DCOMPILER_RT_OS_DIR="serenity" \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \ + -DCOMPILER_RT_BUILD_BUILTINS=ON \ + -DCOMPILER_RT_BUILD_CRT=ON \ + -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \ + -DCOMPILER_RT_BUILD_MEMPROF=OFF \ + -DCOMPILER_RT_BUILD_PROFILE=OFF \ + -DCOMPILER_RT_BUILD_SANITIZERS=OFF \ + -DCOMPILER_RT_BUILD_XRAY=OFF || exit 1 + + buildstep "compiler-rt/build" ninja -j "$MAKEJOBS" || exit 1 + buildstep "compiler-rt/install" ninja install || exit 1 + popd + + mkdir -p libunwind + pushd libunwind + buildstep "libunwind/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/libunwind" \ + -GNinja \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_SYSROOT="$SYSROOT" \ + -DCMAKE_C_COMPILER="$PREFIX/bin/clang" \ + -DCMAKE_C_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \ + -DCMAKE_CXX_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \ + -DLIBUNWIND_TARGET_TRIPLE="$LLVM_TARGET" \ + -DLIBUNWIND_SYSROOT="$SYSROOT" || exit 1 + + buildstep "libunwind/build" ninja -j "$MAKEJOBS" || exit 1 + buildstep "libunwind/install" ninja install || exit 1 + popd + + mkdir -p libcxxabi + pushd libcxxabi + buildstep "libcxxabi/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/libcxxabi" \ + -GNinja \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_SYSROOT="$SYSROOT" \ + -DCMAKE_C_COMPILER="$PREFIX/bin/clang" \ + -DCMAKE_C_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \ + -DCMAKE_CXX_COMPILER_TARGET="$LLVM_TARGET" \ + -DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \ + -DLIBCXXABI_STANDALONE_BUILD=ON \ + -DLIBCXXABI_ENABLE_EXCEPTIONS=ON \ + -DLIBCXXABI_STANDALONE_BUILD=ON \ + -DLIBCXXABI_ENABLE_ASSERTIONS=OFF \ + -DLIBCXXABI_BAREMETAL=ON || exit 1 + + buildstep "libcxxabi/build" ninja -j "$MAKEJOBS" || exit 1 + buildstep "libcxxabi/install" ninja install || exit 1 + popd + + mkdir -p libcxx + pushd libcxx + buildstep "libcxx/configure" cmake "$DIR/Tarballs/llvm-project-$LLVM_VERSION.src/libcxx" \ + -G Ninja \ + -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_BINARY_DIR="$PREFIX/usr" \ + -DCMAKE_SYSROOT="$SYSROOT" \ + -DCMAKE_C_COMPILER="$PREFIX/bin/clang" \ + -DCMAKE_C_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_CXX_COMPILER="$PREFIX/bin/clang++" \ + -DCMAKE_CXX_FLAGS="$LLVM_COMPILER_FLAGS" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DLLVM_CONFIG_PATH="$PREFIX/bin/llvm-config" \ + -DLLVM_BINARY_DIR="$PREFIX/usr" \ + -DLIBCXX_INSTALL_LIBRARY=ON \ + -DLIBCXX_ENABLE_LOCALIZATION=OFF \ + -DLIBCXX_ENABLE_FILESYSTEM=OFF \ + -DLIBCXX_INSTALL_HEADERS=ON \ + -DLIBCXX_ENABLE_SHARED=ON \ + -DLIBCXX_ENABLE_LOCALIZATION=OFF \ + -DLIBCXX_ENABLE_STATIC=ON \ + -DLIBCXX_CXX_ABI="libcxxabi" \ + -DLIBCXX_INCLUDE_BENCHMARKS=OFF || exit 1 + + buildstep "libcxx/build" ninja -j "$MAKEJOBS" || exit 1 + buildstep "libcxx/install" ninja install || exit 1 + buildstep "libcxx/install-headers" ninja install-cxx-headers || exit 1 + popd + + mkdir -p binutils + pushd binutils + buildstep "binutils/configure" "$DIR/Tarballs/$BINUTILS_NAME/configure" --prefix="$PREFIX/binutils" \ + --target="$ARCH-pc-serenity" \ + --disable-nls \ + --disable-gas \ + --disable-gold \ + --disable-ld \ + --disable-gprof \ + --enable-shared || exit 1 + buildstep "binutils/build" "$MAKE" -j "$MAKEJOBS" || exit 1 + buildstep "binutils/install" "$MAKE" install || exit 1 + popd +popd diff --git a/Toolchain/BuildIt.sh b/Toolchain/BuildIt.sh index f4931cb4c50..6b4eba77d48 100755 --- a/Toolchain/BuildIt.sh +++ b/Toolchain/BuildIt.sh @@ -71,6 +71,7 @@ echo SYSROOT is "$SYSROOT" mkdir -p "$DIR/Tarballs" +# Note: The version number and hash in BuildClang.sh needs to be kept in sync with this. BINUTILS_VERSION="2.37" BINUTILS_MD5SUM="1e55743d73c100b7a0d67ffb32398cdb" BINUTILS_NAME="binutils-$BINUTILS_VERSION" diff --git a/Toolchain/Patches/llvm.patch b/Toolchain/Patches/llvm.patch new file mode 100644 index 00000000000..6fc16786abe --- /dev/null +++ b/Toolchain/Patches/llvm.patch @@ -0,0 +1,933 @@ +diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp +index 90a67d03b..ad21af415 100644 +--- a/clang/lib/Basic/Targets.cpp ++++ b/clang/lib/Basic/Targets.cpp +@@ -527,6 +527,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, + return new MCUX86_32TargetInfo(Triple, Opts); + case llvm::Triple::Hurd: + return new HurdTargetInfo(Triple, Opts); ++ case llvm::Triple::Serenity: ++ return new SerenityTargetInfo(Triple, Opts); + default: + return new X86_32TargetInfo(Triple, Opts); + } +@@ -579,6 +581,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, + return new NaClTargetInfo(Triple, Opts); + case llvm::Triple::PS4: + return new PS4OSTargetInfo(Triple, Opts); ++ case llvm::Triple::Serenity: ++ return new SerenityTargetInfo(Triple, Opts); + default: + return new X86_64TargetInfo(Triple, Opts); + } +diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h +index 67fa1a537..9dd9039bb 100644 +--- a/clang/lib/Basic/Targets/OSTargets.h ++++ b/clang/lib/Basic/Targets/OSTargets.h +@@ -947,6 +947,22 @@ public: + : WebAssemblyOSTargetInfo(Triple, Opts) {} + }; + ++// 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__"); ++ Builder.defineMacro("__unix__"); ++ Builder.defineMacro("__ELF__"); ++ } ++ ++public: ++ SerenityTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) ++ : OSTargetInfo(Triple, Opts) {} ++}; ++ + } // 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 aeffcf0bb..43bec8fd7 100644 +--- a/clang/lib/Driver/CMakeLists.txt ++++ b/clang/lib/Driver/CMakeLists.txt +@@ -66,6 +66,7 @@ add_clang_library(clangDriver + ToolChains/OpenBSD.cpp + ToolChains/PS4CPU.cpp + ToolChains/RISCVToolchain.cpp ++ ToolChains/Serenity.cpp + ToolChains/Solaris.cpp + ToolChains/TCE.cpp + ToolChains/VEToolchain.cpp +diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp +index 418e1d3e8..672aadc4d 100644 +--- a/clang/lib/Driver/Driver.cpp ++++ b/clang/lib/Driver/Driver.cpp +@@ -41,6 +41,7 @@ + #include "ToolChains/PPCLinux.h" + #include "ToolChains/PS4CPU.h" + #include "ToolChains/RISCVToolchain.h" ++#include "ToolChains/Serenity.h" + #include "ToolChains/Solaris.h" + #include "ToolChains/TCE.h" + #include "ToolChains/VEToolchain.h" +@@ -5128,6 +5129,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, + 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 +index b2ddef141..48880a612 100644 +--- a/clang/lib/Driver/ToolChain.cpp ++++ b/clang/lib/Driver/ToolChain.cpp +@@ -398,6 +398,8 @@ StringRef ToolChain::getOSLibName() const { + return "sunos"; + case llvm::Triple::AIX: + return "aix"; ++ case llvm::Triple::Serenity: ++ return "serenity"; + default: + return getOS(); + } +diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp +new file mode 100644 +index 000000000..8840188eb +--- /dev/null ++++ b/clang/lib/Driver/ToolChains/Serenity.cpp +@@ -0,0 +1,220 @@ ++//===--- Serenity.cpp - SerenityOS 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 "Serenity.h" ++#include "CommonArgs.h" ++#include "InputInfo.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" ++ ++using namespace clang::driver; ++using namespace clang::driver::toolchains; ++using namespace clang; ++using namespace llvm::opt; ++ ++static bool getPIE(const ArgList &Args, const ToolChain &TC) { ++ if (Args.hasArg(options::OPT_static, options::OPT_shared, ++ options::OPT_static_pie)) ++ return false; ++ Arg *Last = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, ++ options::OPT_nopie); ++ return Last ? Last->getOption().matches(options::OPT_pie) : TC.isPIEDefault(); ++} ++ ++void tools::serenity::Linker::ConstructJob(Compilation &C, const JobAction &JA, ++ const InputInfo &Output, ++ const InputInfoList &Inputs, ++ const ArgList &Args, ++ const char *LinkingOutput) const { ++ const auto &TC = getToolChain(); ++ const auto &D = TC.getDriver(); ++ const bool IsShared = Args.hasArg(options::OPT_shared); ++ const bool IsStatic = ++ Args.hasArg(options::OPT_static) && !Args.hasArg(options::OPT_static_pie); ++ const bool IsRdynamic = Args.hasArg(options::OPT_rdynamic); ++ const bool IsStaticPIE = Args.hasArg(options::OPT_static_pie); ++ const bool IsPIE = getPIE(Args, TC); ++ ArgStringList CmdArgs; ++ ++ if (!D.SysRoot.empty()) ++ CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); ++ ++ if (IsPIE || IsStaticPIE) ++ CmdArgs.push_back("-pie"); ++ ++ if (IsShared) ++ CmdArgs.push_back("-shared"); ++ ++ if (IsStatic || IsStaticPIE) ++ CmdArgs.push_back("-static"); ++ ++ if (IsStaticPIE) { ++ CmdArgs.push_back("--no-dynamic-linker"); ++ CmdArgs.push_back("-z"); ++ CmdArgs.push_back("text"); ++ } ++ ++ if (!IsStatic && !IsStaticPIE) { ++ if (IsRdynamic) ++ CmdArgs.push_back("-export-dynamic"); ++ CmdArgs.push_back("-dynamic-linker"); ++ CmdArgs.push_back("/usr/lib/Loader.so"); ++ } ++ ++ if (!IsStatic || IsStaticPIE) ++ CmdArgs.push_back("--eh-frame-hdr"); ++ ++ if (Output.isFilename()) { ++ CmdArgs.push_back("-o"); ++ CmdArgs.push_back(Output.getFilename()); ++ } ++ ++ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { ++ CmdArgs.push_back(Args.MakeArgString( ++ TC.GetFilePath((IsShared) ? "crt0_shared.o" : "crt0.o"))); ++ CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crti.o"))); ++ ++ std::string crtbegin_path; ++ if (TC.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT) { ++ std::string crtbegin = ++ TC.getCompilerRT(Args, "crtbegin", ToolChain::FT_Object); ++ if (TC.getVFS().exists(crtbegin)) ++ crtbegin_path = crtbegin; ++ } ++ if (crtbegin_path.empty()) { ++ const char *crtbegin = (IsShared || IsPIE) ? "crtbeginS.o" : "crtbegin.o"; ++ crtbegin_path = TC.GetFilePath(crtbegin); ++ } ++ CmdArgs.push_back(Args.MakeArgString(crtbegin_path)); ++ } ++ ++ Args.AddAllArgs(CmdArgs, options::OPT_L); ++ Args.AddAllArgs(CmdArgs, options::OPT_u); ++ ++ TC.AddFilePathLibArgs(Args, CmdArgs); ++ ++ if (D.isUsingLTO()) { ++ assert(!Inputs.empty() && "Must have at least one input."); ++ addLTOOptions(TC, Args, CmdArgs, Output, Inputs[0], ++ D.getLTOMode() == LTOK_Thin); ++ } ++ ++ Args.AddAllArgs(CmdArgs, options::OPT_T_Group); ++ Args.AddAllArgs(CmdArgs, options::OPT_e); ++ Args.AddAllArgs(CmdArgs, options::OPT_s); ++ Args.AddAllArgs(CmdArgs, options::OPT_t); ++ Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag); ++ Args.AddAllArgs(CmdArgs, options::OPT_r); ++ ++ addLinkerCompressDebugSectionsOption(TC, Args, CmdArgs); ++ ++ AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); ++ ++ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { ++ AddRunTimeLibs(TC, D, CmdArgs, Args); ++ ++ // We supply our own sanitizer runtimes ++ // FIXME: What if we want to use Clang-supplied ones as well? ++ const SanitizerArgs &Sanitize = TC.getSanitizerArgs(); ++ if (Sanitize.needsUbsanRt()) ++ CmdArgs.push_back("-lubsan"); ++ } ++ ++ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { ++ if (D.CCCIsCXX()) { ++ if (TC.ShouldLinkCXXStdlib(Args)) ++ TC.AddCXXStdlibLibArgs(Args, CmdArgs); ++ CmdArgs.push_back("-lm"); ++ } ++ } ++ ++ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { ++ if (Args.hasArg(options::OPT_pthread, options::OPT_pthreads)) ++ CmdArgs.push_back("-lpthread"); ++ ++ if (!Args.hasArg(options::OPT_nolibc)) ++ CmdArgs.push_back("-lc"); ++ } ++ ++ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { ++ std::string crtend_path; ++ if (TC.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT) { ++ std::string crtend = ++ TC.getCompilerRT(Args, "crtend", ToolChain::FT_Object); ++ if (TC.getVFS().exists(crtend)) ++ crtend_path = crtend; ++ } ++ if (crtend_path.empty()) { ++ const char *crtend = (IsShared || IsPIE) ? "crtendS.o" : "crtend.o"; ++ crtend_path = TC.GetFilePath(crtend); ++ } ++ CmdArgs.push_back(Args.MakeArgString(crtend_path)); ++ ++ CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o"))); ++ } ++ ++ Args.AddAllArgs(CmdArgs, options::OPT_T); ++ ++ 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(getDriver().Dir + "/../lib"); ++ if (!getDriver().SysRoot.empty()) ++ getFilePaths().push_back(getDriver().SysRoot + "/usr/lib"); ++} ++ ++Tool *Serenity::buildLinker() const { ++ return new tools::serenity::Linker(*this); ++} ++ ++void Serenity::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ++ ArgStringList &CC1Args) const { ++ const Driver &D = getDriver(); ++ ++ if (DriverArgs.hasArg(options::OPT_nostdinc)) ++ return; ++ ++ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { ++ addSystemInclude(DriverArgs, CC1Args, D.ResourceDir + "/include"); ++ } ++ ++ if (DriverArgs.hasArg(options::OPT_nostdlibinc)) ++ return; ++ ++ if (!D.SysRoot.empty()) { ++ addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include"); ++ } ++} ++ ++void Serenity::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ++ ArgStringList &CC1Args) const { ++ if (DriverArgs.hasArg(options::OPT_nostdlibinc, options::OPT_nostdincxx)) ++ return; ++ ++ switch (GetCXXStdlibType(DriverArgs)) { ++ case ToolChain::CST_Libcxx: { ++ addSystemInclude(DriverArgs, CC1Args, ++ getDriver().SysRoot + "/usr/include/c++/v1"); ++ addSystemInclude(DriverArgs, CC1Args, ++ getDriver().Dir + "/../include/c++/v1"); ++ break; ++ } ++ default: ++ llvm_unreachable("invalid stdlib name"); ++ } ++} +diff --git a/clang/lib/Driver/ToolChains/Serenity.h b/clang/lib/Driver/ToolChains/Serenity.h +new file mode 100644 +index 000000000..a45a0c853 +--- /dev/null ++++ b/clang/lib/Driver/ToolChains/Serenity.h +@@ -0,0 +1,78 @@ ++//===--- Serenity.h - SerenityOS 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_SERENITY_H ++#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H ++ ++#include "Gnu.h" ++#include "clang/Driver/Tool.h" ++#include "clang/Driver/ToolChain.h" ++ ++namespace clang { ++namespace driver { ++namespace tools { ++/// Serenity -- Directly call GNU Binutils assembler and linker ++namespace serenity { ++ ++class LLVM_LIBRARY_VISIBILITY Linker : public Tool { ++public: ++ Linker(const ToolChain &TC) : Tool("serenity::Linker", "linker", TC) {} ++ ++ bool hasIntegratedCPP() const override { return false; } ++ bool isLinkJob() const override { return true; } ++ ++ void ConstructJob(Compilation &C, const JobAction &JA, ++ const InputInfo &Output, const InputInfoList &Inputs, ++ const llvm::opt::ArgList &TCArgs, ++ const char *LinkingOutput) const override; ++}; ++} // end namespace serenity ++} // end namespace tools ++ ++namespace toolchains { ++ ++class LLVM_LIBRARY_VISIBILITY Serenity : public 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; ++ ++ void AddClangCXXStdlibIncludeArgs( ++ const llvm::opt::ArgList &DriverArgs, ++ llvm::opt::ArgStringList &CC1Args) const override; ++ ++ RuntimeLibType GetDefaultRuntimeLibType() const override { ++ return ToolChain::RLT_CompilerRT; ++ } ++ ++ UnwindLibType GetDefaultUnwindLibType() const override { ++ return ToolChain::UNW_CompilerRT; ++ } ++ ++ CXXStdlibType GetDefaultCXXStdlibType() const override { ++ return ToolChain::CST_Libcxx; ++ } ++ const char *getDefaultLinker() const override { return "ld.lld"; } ++ ++ bool HasNativeLLVMSupport() const override { return true; } ++ bool IsIntegratedAssemblerDefault() const override { return true; } ++ ++ unsigned GetDefaultDwarfVersion() const override { return 5; } ++ ++protected: ++ Tool *buildLinker() const override; ++}; ++ ++} // end namespace toolchains ++} // end namespace driver ++} // end namespace clang ++ ++#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H +diff --git a/clang/lib/Frontend/InitHeaderSearch.cpp b/clang/lib/Frontend/InitHeaderSearch.cpp +index bc31445d6..a4a3fbc89 100644 +--- a/clang/lib/Frontend/InitHeaderSearch.cpp ++++ b/clang/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::Serenity: + break; + case llvm::Triple::Win32: + if (triple.getEnvironment() != llvm::Triple::Cygnus) +@@ -428,6 +429,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang, + case llvm::Triple::Solaris: + case llvm::Triple::WASI: + case llvm::Triple::AIX: ++ case llvm::Triple::Serenity: + return; + + case llvm::Triple::Win32: +diff --git a/libcxx/include/__config b/libcxx/include/__config +index a3838c89e..8a20731ef 100644 +--- a/libcxx/include/__config ++++ b/libcxx/include/__config +@@ -1132,6 +1132,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( + defined(__CloudABI__) || \ + defined(__sun__) || \ + defined(__MVS__) || \ ++ defined(__serenity__) || \ + (defined(__MINGW32__) && __has_include()) + # define _LIBCPP_HAS_THREAD_API_PTHREAD + # elif defined(__Fuchsia__) +diff --git a/libcxx/include/__string b/libcxx/include/__string +index d8b672e4c..638cf1698 100644 +--- a/libcxx/include/__string ++++ b/libcxx/include/__string +@@ -451,6 +451,7 @@ char_traits::find(const char_type* __s, size_t __n, const char_type& __a) + } + + ++#ifndef __serenity__ + // char_traits + + template <> +@@ -531,6 +532,7 @@ char_traits::compare(const char_type* __s1, const char_type* __s2, size + #endif + } + ++#endif + + template + _LIBCPP_INLINE_VISIBILITY +@@ -543,6 +545,7 @@ inline size_t __char_traits_length_checked(const typename _Traits::char_type* __ + #endif + } + ++#ifndef __serenity__ + inline _LIBCPP_CONSTEXPR_AFTER_CXX14 + size_t + char_traits::length(const char_type* __s) _NOEXCEPT +@@ -579,6 +582,7 @@ char_traits::find(const char_type* __s, size_t __n, const char_type& __ + return nullptr; + #endif + } ++#endif + + + #ifndef _LIBCPP_NO_HAS_CHAR8_T +diff --git a/libcxx/include/cwchar b/libcxx/include/cwchar +index 451c621f9..1e83b8e60 100644 +--- a/libcxx/include/cwchar ++++ b/libcxx/include/cwchar +@@ -112,11 +112,13 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, + + _LIBCPP_BEGIN_NAMESPACE_STD + +-using ::mbstate_t; + using ::size_t; ++using ::FILE; ++ ++#ifndef __serenity__ ++using ::mbstate_t; + using ::tm; + using ::wint_t; +-using ::FILE; + using ::fwprintf; + using ::fwscanf; + using ::swprintf; +@@ -186,6 +188,7 @@ using ::putwchar; + using ::vwprintf; + using ::wprintf; + #endif ++#endif + + _LIBCPP_END_NAMESPACE_STD + +diff --git a/libcxx/include/cwctype b/libcxx/include/cwctype +index 575fd5661..c401b6cf0 100644 +--- a/libcxx/include/cwctype ++++ b/libcxx/include/cwctype +@@ -59,6 +59,7 @@ wctrans_t wctrans(const char* property); + + _LIBCPP_BEGIN_NAMESPACE_STD + ++#ifndef __serenity__ + using ::wint_t; + using ::wctrans_t; + using ::wctype_t; +@@ -80,6 +81,7 @@ using ::towlower; + using ::towupper; + using ::towctrans; + using ::wctrans; ++#endif + + _LIBCPP_END_NAMESPACE_STD + +diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list +index 893736f57..70a0d1ccf 100644 +--- a/libcxx/include/initializer_list ++++ b/libcxx/include/initializer_list +@@ -43,7 +43,9 @@ template const E* end(initializer_list il) noexcept; // constexpr in + */ + + #include <__config> ++#ifndef KERNEL + #include ++#endif + + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) + #pragma GCC system_header +diff --git a/libcxx/include/iosfwd b/libcxx/include/iosfwd +index 0a0de99ff..790dc4023 100644 +--- a/libcxx/include/iosfwd ++++ b/libcxx/include/iosfwd +@@ -92,7 +92,11 @@ typedef fpos::state_type> wstreampos; + */ + + #include <__config> ++#if 0 + #include // for mbstate_t ++#endif ++ ++#define mbstate_t void + + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) + #pragma GCC system_header +@@ -109,7 +113,9 @@ template<> struct char_traits; + #endif + template<> struct char_traits; + template<> struct char_traits; ++#if 0 + template<> struct char_traits; ++#endif + + template class _LIBCPP_TEMPLATE_VIS allocator; + +diff --git a/libcxx/include/new b/libcxx/include/new +index 0562cef45..82f4ca8be 100644 +--- a/libcxx/include/new ++++ b/libcxx/include/new +@@ -301,6 +301,8 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s + #endif + } + ++#define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION ++ + #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) + // Low-level helpers to call the aligned allocation and deallocation functions + // on the target platform. This is used to implement libc++'s own memory +diff --git a/libcxx/include/string b/libcxx/include/string +index 687795c79..f3a216647 100644 +--- a/libcxx/include/string ++++ b/libcxx/include/string +@@ -1728,8 +1728,10 @@ _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) + _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) + #else + _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) ++#ifndef __serenity__ + _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) + #endif ++#endif + + + #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +@@ -4527,11 +4529,13 @@ inline namespace literals + return basic_string (__str, __len); + } + ++#ifndef __serenity__ + inline _LIBCPP_INLINE_VISIBILITY + basic_string operator "" s( const wchar_t *__str, size_t __len ) + { + return basic_string (__str, __len); + } ++#endif + + #ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY +diff --git a/libcxx/include/string_view b/libcxx/include/string_view +index bc0245cf2..55f9b62c4 100644 +--- a/libcxx/include/string_view ++++ b/libcxx/include/string_view +@@ -204,7 +204,9 @@ typedef basic_string_view u8string_view; + #endif + typedef basic_string_view u16string_view; + typedef basic_string_view u32string_view; ++#ifndef __serenity__ + typedef basic_string_view wstring_view; ++#endif + + template + class +@@ -214,7 +216,9 @@ class + #endif + _LIBCPP_PREFERRED_NAME(u16string_view) + _LIBCPP_PREFERRED_NAME(u32string_view) ++#ifndef __serenity__ + _LIBCPP_PREFERRED_NAME(wstring_view) ++#endif + basic_string_view { + public: + // types +@@ -836,11 +840,13 @@ inline namespace literals + return basic_string_view (__str, __len); + } + ++#ifndef __serenity__ + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + basic_string_view operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT + { + return basic_string_view (__str, __len); + } ++#endif + + #ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h +index b21a78968..ae20183ed 100644 +--- a/libcxx/include/wchar.h ++++ b/libcxx/include/wchar.h +@@ -132,6 +132,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, + #endif + + #if defined(__cplusplus) && !defined(_LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) ++#ifndef __serenity__ + extern "C++" { + inline _LIBCPP_INLINE_VISIBILITY + wchar_t* __libcpp_wcschr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcschr(__s, __c);} +@@ -178,5 +179,6 @@ size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, + size_t nwc, size_t len, mbstate_t *__restrict ps); + } // extern "C++" + #endif // __cplusplus && _LIBCPP_MSVCRT ++#endif + + #endif // _LIBCPP_WCHAR_H +diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp +index 5105594cf..ca85269db 100644 +--- a/libcxx/src/string.cpp ++++ b/libcxx/src/string.cpp +@@ -131,6 +131,7 @@ as_integer( const string& func, const string& s, size_t* idx, int base ) + return as_integer_helper( func, s, idx, base, strtoull ); + } + ++#ifndef __serenity__ + // wstring + template<> + inline +@@ -175,6 +176,7 @@ as_integer( const string& func, const wstring& s, size_t* idx, int base ) + { + return as_integer_helper( func, s, idx, base, wcstoull ); + } ++#endif + + // as_float + +@@ -226,6 +228,8 @@ as_float( const string& func, const string& s, size_t* idx ) + return as_float_helper( func, s, idx, strtold ); + } + ++ ++#ifndef __serenity__ + template<> + inline + float +@@ -249,6 +253,7 @@ as_float( const string& func, const wstring& s, size_t* idx ) + { + return as_float_helper( func, s, idx, wcstold ); + } ++#endif + + } // unnamed namespace + +@@ -258,11 +263,13 @@ stoi(const string& str, size_t* idx, int base) + return as_integer( "stoi", str, idx, base ); + } + ++#ifndef __serenity__ + int + stoi(const wstring& str, size_t* idx, int base) + { + return as_integer( "stoi", str, idx, base ); + } ++#endif + + long + stol(const string& str, size_t* idx, int base) +@@ -270,11 +277,13 @@ stol(const string& str, size_t* idx, int base) + return as_integer( "stol", str, idx, base ); + } + ++#ifndef __serenity__ + long + stol(const wstring& str, size_t* idx, int base) + { + return as_integer( "stol", str, idx, base ); + } ++#endif + + unsigned long + stoul(const string& str, size_t* idx, int base) +@@ -282,11 +291,13 @@ stoul(const string& str, size_t* idx, int base) + return as_integer( "stoul", str, idx, base ); + } + ++#ifndef __serenity__ + unsigned long + stoul(const wstring& str, size_t* idx, int base) + { + return as_integer( "stoul", str, idx, base ); + } ++#endif + + long long + stoll(const string& str, size_t* idx, int base) +@@ -294,11 +305,13 @@ stoll(const string& str, size_t* idx, int base) + return as_integer( "stoll", str, idx, base ); + } + ++#ifndef __serenity__ + long long + stoll(const wstring& str, size_t* idx, int base) + { + return as_integer( "stoll", str, idx, base ); + } ++#endif + + unsigned long long + stoull(const string& str, size_t* idx, int base) +@@ -306,11 +319,13 @@ stoull(const string& str, size_t* idx, int base) + return as_integer( "stoull", str, idx, base ); + } + ++#ifndef __serenity__ + unsigned long long + stoull(const wstring& str, size_t* idx, int base) + { + return as_integer( "stoull", str, idx, base ); + } ++#endif + + float + stof(const string& str, size_t* idx) +@@ -318,11 +333,13 @@ stof(const string& str, size_t* idx) + return as_float( "stof", str, idx ); + } + ++#ifndef __serenity__ + float + stof(const wstring& str, size_t* idx) + { + return as_float( "stof", str, idx ); + } ++#endif + + double + stod(const string& str, size_t* idx) +@@ -330,11 +347,13 @@ stod(const string& str, size_t* idx) + return as_float( "stod", str, idx ); + } + ++#ifndef __serenity__ + double + stod(const wstring& str, size_t* idx) + { + return as_float( "stod", str, idx ); + } ++#endif + + long double + stold(const string& str, size_t* idx) +@@ -342,11 +361,13 @@ stold(const string& str, size_t* idx) + return as_float( "stold", str, idx ); + } + ++#ifndef __serenity__ + long double + stold(const wstring& str, size_t* idx) + { + return as_float( "stold", str, idx ); + } ++#endif + + // to_string + +@@ -397,6 +418,7 @@ struct initial_string + } + }; + ++#ifndef __serenity__ + template <> + struct initial_string + { +@@ -408,7 +430,9 @@ struct initial_string + return s; + } + }; ++#endif + ++#ifndef __serenity__ + typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); + + inline +@@ -421,6 +445,7 @@ get_swprintf() + return static_cast(_snwprintf); + #endif + } ++#endif + + template + S i_to_string(const V v) +@@ -444,20 +469,24 @@ string to_string (unsigned val) { return i_to_string< string>(val); } + string to_string (unsigned long val) { return i_to_string< string>(val); } + string to_string (unsigned long long val) { return i_to_string< string>(val); } + ++#ifndef __serenity__ + wstring to_wstring(int val) { return i_to_string(val); } + wstring to_wstring(long val) { return i_to_string(val); } + wstring to_wstring(long long val) { return i_to_string(val); } + wstring to_wstring(unsigned val) { return i_to_string(val); } + wstring to_wstring(unsigned long val) { return i_to_string(val); } + wstring to_wstring(unsigned long long val) { return i_to_string(val); } ++#endif + + + string to_string (float val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } + string to_string (double val) { return as_string(snprintf, initial_string< string>()(), "%f", val); } + string to_string (long double val) { return as_string(snprintf, initial_string< string>()(), "%Lf", val); } + ++#ifndef __serenity__ + wstring to_wstring(float val) { return as_string(get_swprintf(), initial_string()(), L"%f", val); } + wstring to_wstring(double val) { return as_string(get_swprintf(), initial_string()(), L"%f", val); } + wstring to_wstring(long double val) { return as_string(get_swprintf(), initial_string()(), L"%Lf", val); } ++#endif + + _LIBCPP_END_NAMESPACE_STD +diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp +index 171318ff6..aa7345a19 100644 +--- a/libunwind/src/AddressSpace.hpp ++++ b/libunwind/src/AddressSpace.hpp +@@ -24,7 +24,7 @@ + #include "Registers.hpp" + + #ifndef _LIBUNWIND_USE_DLADDR +- #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) ++ #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) && !defined(__serenity__) + #define _LIBUNWIND_USE_DLADDR 1 + #else + #define _LIBUNWIND_USE_DLADDR 0 +diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h +index eed315c92..11e53b8ac 100644 +--- a/llvm/include/llvm/ADT/Triple.h ++++ b/llvm/include/llvm/ADT/Triple.h +@@ -198,7 +198,8 @@ public: + Hurd, // GNU/Hurd + WASI, // Experimental WebAssembly OS + Emscripten, +- LastOSType = Emscripten ++ Serenity, ++ LastOSType = Serenity + }; + enum EnvironmentType { + UnknownEnvironment, +@@ -626,6 +627,11 @@ public: + return getOS() == Triple::AIX; + } + ++ /// Tests whether the OS is SerenityOS ++ bool isOSSerenity() const { ++ return getOS() == Triple::Serenity; ++ } ++ + /// Tests whether the OS uses the ELF binary format. + bool isOSBinFormatELF() const { + return getObjectFormat() == Triple::ELF; +diff --git a/llvm/include/llvm/Support/SwapByteOrder.h b/llvm/include/llvm/Support/SwapByteOrder.h +index e8612ba66..f0109f4b3 100644 +--- a/llvm/include/llvm/Support/SwapByteOrder.h ++++ b/llvm/include/llvm/Support/SwapByteOrder.h +@@ -22,7 +22,7 @@ + #endif + + #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ +- defined(__Fuchsia__) || defined(__EMSCRIPTEN__) ++ defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__serenity__) + #include + #elif defined(_AIX) + #include +diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp +index 4f483c965..bdbda22c9 100644 +--- a/llvm/lib/Support/Triple.cpp ++++ b/llvm/lib/Support/Triple.cpp +@@ -215,6 +215,7 @@ StringRef Triple::getOSTypeName(OSType Kind) { + case PS4: return "ps4"; + case RTEMS: return "rtems"; + case Solaris: return "solaris"; ++ case Serenity: return "serenity"; + case TvOS: return "tvos"; + case WASI: return "wasi"; + case WatchOS: return "watchos"; +@@ -531,6 +532,7 @@ static Triple::OSType parseOS(StringRef OSName) { + .StartsWith("hurd", Triple::Hurd) + .StartsWith("wasi", Triple::WASI) + .StartsWith("emscripten", Triple::Emscripten) ++ .StartsWith("serenity", Triple::Serenity) + .Default(Triple::UnknownOS); + } +