Browse Source

Toolchain: Update LLVM to 18.1.3

Apart from bumping the toolchain Clang's and port's version, this commit
completely overhauls the way LLVM toolchain is built.

First, it gets rid of a complicated two-stage process of first compiling
clang and compiler-rt builtins and then building libunwind, libc++abi,
and libc++ -- it is possible to create a complete cross-compilation
toolchain in a single CMake invocation with a modern LLVM. Moreover, the
old method was inherently unsupported and subtly broken.

Next, it utilizes full potential of the Stubs "framework". Now we are
even able to compile Clang with -Wl,-z,defs which makes one of the
patches obsolete and the whole installation less error-prone. Note that
it comes at a cost of complicating the bootstrap process on a completely
novel architecture but this hopefully won't happen often.

Lastly, it fixes handling of the -no*lib* family of flags in the
Serenity LLVM driver and correctly uses -nostartfiles in conjunction
with stubs to make necessary CMake configure-time checks succeed.
Dan Klishch 1 year ago
parent
commit
fa1eef8bbe
39 changed files with 1257 additions and 1231 deletions
  1. 1 1
      CMakeLists.txt
  2. 1 1
      Ports/AvailablePorts.md
  3. 3 3
      Ports/llvm/package.sh
  4. 5 31
      Toolchain/BuildClang.sh
  5. 26 2
      Toolchain/CMake/LLVMConfig.cmake
  6. 0 74
      Toolchain/CMake/LLVMRuntimesConfig.cmake
  7. 0 78
      Toolchain/Patches/llvm/0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch
  8. 754 0
      Toolchain/Patches/llvm/0001-clang-Add-support-for-SerenityOS.patch
  9. 0 56
      Toolchain/Patches/llvm/0002-Triple-Add-triple-for-SerenityOS.patch
  10. 134 0
      Toolchain/Patches/llvm/0002-llvm-Add-support-for-building-LLVM-on-SerenityOS.patch
  11. 0 596
      Toolchain/Patches/llvm/0003-Driver-Add-support-for-SerenityOS.patch
  12. 46 0
      Toolchain/Patches/llvm/0003-tools-Support-building-shared-libLLVM-and-libClang-f.patch
  13. 0 32
      Toolchain/Patches/llvm/0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch
  14. 110 0
      Toolchain/Patches/llvm/0004-compiler-rt-Enable-profile-instrumentation-for-Seren.patch
  15. 32 29
      Toolchain/Patches/llvm/0005-libcxx-Add-support-for-SerenityOS.patch
  16. 89 0
      Toolchain/Patches/llvm/0006-clang-Add-fvisibility-inlines-hidden-function-templa.patch
  17. 0 22
      Toolchain/Patches/llvm/0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch
  18. 0 25
      Toolchain/Patches/llvm/0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch
  19. 0 51
      Toolchain/Patches/llvm/0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch
  20. 0 71
      Toolchain/Patches/llvm/0009-compiler-rt-llvm-Enable-profile-instrumentation-for-.patch
  21. 0 23
      Toolchain/Patches/llvm/0010-Add-SerenityOS-to-config.guess.patch
  22. 0 38
      Toolchain/Patches/llvm/0011-llvm-Prevent-the-use-of-POSIX-shm-on-SerenityOS.patch
  23. 0 24
      Toolchain/Patches/llvm/0012-cmake-Increase-the-default-stack-size-when-running-o.patch
  24. 25 63
      Toolchain/Patches/llvm/ReadMe.md
  25. 25 11
      Toolchain/Stubs/README.md
  26. BIN
      Toolchain/Stubs/aarch64/empty.so
  27. 1 0
      Toolchain/Stubs/aarch64/libc++.so
  28. BIN
      Toolchain/Stubs/aarch64/libc.so
  29. 1 0
      Toolchain/Stubs/aarch64/libunwind.so
  30. BIN
      Toolchain/Stubs/i686clang/libc.so
  31. BIN
      Toolchain/Stubs/riscv64/empty.so
  32. 1 0
      Toolchain/Stubs/riscv64/libc++.so
  33. BIN
      Toolchain/Stubs/riscv64/libc.so
  34. 1 0
      Toolchain/Stubs/riscv64/libunwind.so
  35. BIN
      Toolchain/Stubs/x86_64/empty.so
  36. 1 0
      Toolchain/Stubs/x86_64/libc++.so
  37. BIN
      Toolchain/Stubs/x86_64/libc.so
  38. 1 0
      Toolchain/Stubs/x86_64/libunwind.so
  39. BIN
      Toolchain/Stubs/x86_64clang/libc.so

+ 1 - 1
CMakeLists.txt

@@ -18,7 +18,7 @@ endif()
 
 
 # Check for toolchain mismatch, user might need to rebuild toolchain
 # Check for toolchain mismatch, user might need to rebuild toolchain
 set(GCC_VERSION "13.2.0")
 set(GCC_VERSION "13.2.0")
-set(LLVM_VERSION "16.0.6")
+set(LLVM_VERSION "18.1.3")
 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     set(EXPECTED_COMPILER_VERSION "${GCC_VERSION}")
     set(EXPECTED_COMPILER_VERSION "${GCC_VERSION}")
 else()
 else()

+ 1 - 1
Ports/AvailablePorts.md

@@ -189,7 +189,7 @@ This list is also available at [ports.serenityos.net](https://ports.serenityos.n
 | [`libzip`](libzip/)                                 | libzip                                                          | 1.10.1                    | https://libzip.org/                                                            |
 | [`libzip`](libzip/)                                 | libzip                                                          | 1.10.1                    | https://libzip.org/                                                            |
 | [`links`](links/)                                   | Links web browser                                               | 2.29                      | http://links.twibright.com/                                                    |
 | [`links`](links/)                                   | Links web browser                                               | 2.29                      | http://links.twibright.com/                                                    |
 | [`lite-xl`](lite-xl/)                               | Lite-XL                                                         | 2.1.3                     | https://lite-xl.com/                                                           |
 | [`lite-xl`](lite-xl/)                               | Lite-XL                                                         | 2.1.3                     | https://lite-xl.com/                                                           |
-| [`llvm`](llvm/)                                     | LLVM                                                            | 16.0.6                    | https://llvm.org/                                                              |
+| [`llvm`](llvm/)                                     | LLVM                                                            | 18.1.3                    | https://llvm.org/                                                              |
 | [`lowdown`](lowdown/)                               | lowdown                                                         | 1.0.2                     | https://kristaps.bsd.lv/lowdown/                                               |
 | [`lowdown`](lowdown/)                               | lowdown                                                         | 1.0.2                     | https://kristaps.bsd.lv/lowdown/                                               |
 | [`lrzip`](lrzip/)                                   | lrzip                                                           | 0.651                     | https://github.com/ckolivas/lrzip                                              |
 | [`lrzip`](lrzip/)                                   | lrzip                                                           | 0.651                     | https://github.com/ckolivas/lrzip                                              |
 | [`lua`](lua/)                                       | Lua                                                             | 5.4.6                     | https://www.lua.org/                                                           |
 | [`lua`](lua/)                                       | Lua                                                             | 5.4.6                     | https://www.lua.org/                                                           |

+ 3 - 3
Ports/llvm/package.sh

@@ -1,13 +1,13 @@
 #!/usr/bin/env -S bash ../.port_include.sh
 #!/usr/bin/env -S bash ../.port_include.sh
 port='llvm'
 port='llvm'
 useconfigure='true'
 useconfigure='true'
-version='16.0.6'
+version='18.1.3'
 workdir="llvm-project-${version}.src"
 workdir="llvm-project-${version}.src"
 configopts=(
 configopts=(
     "-DCMAKE_TOOLCHAIN_FILE=${SERENITY_BUILD_DIR}/CMakeToolchain.txt"
     "-DCMAKE_TOOLCHAIN_FILE=${SERENITY_BUILD_DIR}/CMakeToolchain.txt"
 )
 )
 files=(
 files=(
-    "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-project-${version}.src.tar.xz#ce5e71081d17ce9e86d7cbcfa28c4b04b9300f8fb7e78422b1feb6bc52c3028e"
+    "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-project-${version}.src.tar.xz#2929f62d69dec0379e529eb632c40e15191e36f3bd58c2cb2df0413a0dc48651"
 )
 )
 depends=(
 depends=(
     "ncurses"
     "ncurses"
@@ -54,7 +54,7 @@ configure() {
         -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
         -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
         -DLLVM_OCAML_INSTALL_PATH="${SERENITY_INSTALL_ROOT}/usr/local/ocaml" \
         -DLLVM_OCAML_INSTALL_PATH="${SERENITY_INSTALL_ROOT}/usr/local/ocaml" \
         -DLLVM_PTHREAD_LIB=pthread \
         -DLLVM_PTHREAD_LIB=pthread \
-        -DLLVM_TARGETS_TO_BUILD=X86
+        -DLLVM_TARGETS_TO_BUILD="X86;AArch64;RISCV"
 }
 }
 
 
 build() {
 build() {

+ 5 - 31
Toolchain/BuildClang.sh

@@ -68,8 +68,8 @@ echo PREFIX is "$PREFIX"
 
 
 mkdir -p "$DIR/Tarballs"
 mkdir -p "$DIR/Tarballs"
 
 
-LLVM_VERSION="16.0.6"
-LLVM_MD5SUM="dc13938a604f70379d3b38d09031de98"
+LLVM_VERSION="18.1.3"
+LLVM_MD5SUM="4f2cbf1e35f9c9377c6c89e67364c3fd"
 LLVM_NAME="llvm-project-$LLVM_VERSION.src"
 LLVM_NAME="llvm-project-$LLVM_VERSION.src"
 LLVM_PKG="$LLVM_NAME.tar.xz"
 LLVM_PKG="$LLVM_NAME.tar.xz"
 LLVM_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_PKG"
 LLVM_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_PKG"
@@ -269,18 +269,6 @@ for arch in $ARCHS; do
 done
 done
 unset SRC_ROOT
 unset SRC_ROOT
 
 
-# === COPY LIBRARY STUBS ===
-
-for arch in $USERLAND_ARCHS; do
-    pushd "$BUILD/${arch}clang"
-        mkdir -p Root/usr/lib/
-        for lib in "$DIR/Stubs/${arch}clang/"*".so"; do
-            lib_name=$(basename "$lib")
-            [ ! -f "Root/usr/lib/${lib_name}" ] && cp "$lib" "Root/usr/lib/${lib_name}"
-        done
-    popd
-done
-
 # === COMPILE AND INSTALL ===
 # === COMPILE AND INSTALL ===
 
 
 rm -rf "$PREFIX"
 rm -rf "$PREFIX"
@@ -296,6 +284,9 @@ pushd "$DIR/Build/clang"
             -DSERENITY_x86_64-pc-serenity_SYSROOT="$BUILD/x86_64clang/Root" \
             -DSERENITY_x86_64-pc-serenity_SYSROOT="$BUILD/x86_64clang/Root" \
             -DSERENITY_aarch64-pc-serenity_SYSROOT="$BUILD/aarch64clang/Root" \
             -DSERENITY_aarch64-pc-serenity_SYSROOT="$BUILD/aarch64clang/Root" \
             -DSERENITY_riscv64-pc-serenity_SYSROOT="$BUILD/riscv64clang/Root" \
             -DSERENITY_riscv64-pc-serenity_SYSROOT="$BUILD/riscv64clang/Root" \
+            -DSERENITY_x86_64-pc-serenity_STUBS="$DIR/Stubs/x86_64" \
+            -DSERENITY_aarch64-pc-serenity_STUBS="$DIR/Stubs/aarch64" \
+            -DSERENITY_riscv64-pc-serenity_STUBS="$DIR/Stubs/riscv64" \
             -DCMAKE_INSTALL_PREFIX="$PREFIX" \
             -DCMAKE_INSTALL_PREFIX="$PREFIX" \
             -DSERENITY_MODULE_PATH="$DIR/CMake" \
             -DSERENITY_MODULE_PATH="$DIR/CMake" \
             -C "$DIR/CMake/LLVMConfig.cmake" \
             -C "$DIR/CMake/LLVMConfig.cmake" \
@@ -308,23 +299,6 @@ pushd "$DIR/Build/clang"
         buildstep_ninja "llvm/build" ninja -j "$MAKEJOBS"
         buildstep_ninja "llvm/build" ninja -j "$MAKEJOBS"
         buildstep_ninja "llvm/install" ninja install/strip
         buildstep_ninja "llvm/install" ninja install/strip
     popd
     popd
-
-    for arch in $ARCHS; do
-        mkdir -p runtimes/"$arch"
-        pushd runtimes/"$arch"
-            buildstep "runtimes/$arch/configure" cmake "$DIR/Tarballs/$LLVM_NAME/runtimes" \
-                -G Ninja \
-                -DSERENITY_TOOLCHAIN_ARCH="$arch" \
-                -DSERENITY_TOOLCHAIN_ROOT="$PREFIX" \
-                -DSERENITY_BUILD_DIR="$BUILD/${arch}clang/" \
-                -DSERENITY_MODULE_PATH="$DIR/CMake" \
-                -DCMAKE_INSTALL_PREFIX="$PREFIX" \
-                -C "$DIR/CMake/LLVMRuntimesConfig.cmake"
-
-            buildstep_ninja "runtimes/$arch/build" ninja -j "$MAKEJOBS"
-            buildstep_ninja "runtimes/$arch/install" ninja install
-        popd
-    done
 popd
 popd
 
 
 pushd "$DIR/Local/clang/bin/"
 pushd "$DIR/Local/clang/bin/"

+ 26 - 2
Toolchain/CMake/LLVMConfig.cmake

@@ -1,5 +1,10 @@
 # This file specifies the options used for building the Clang compiler, LLD linker and the compiler builtins library
 # This file specifies the options used for building the Clang compiler, LLD linker and the compiler builtins library
 
 
+if (CMAKE_VERSION VERSION_EQUAL "3.29.0" OR CMAKE_VERSION VERSION_EQUAL "3.29.1")
+    message(FATAL_ERROR "CMake versions 3.29.0 and 3.29.1 are known to not install LLVM correctly. "
+                        "Please either downgrade CMake or update it to 3.29.2+.")
+endif()
+
 # Note: We force the cmake module path for all dependent projects to include our custom directory
 # Note: We force the cmake module path for all dependent projects to include our custom directory
 # That has the Platform/SerenityOS.cmake definition
 # That has the Platform/SerenityOS.cmake definition
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SERENITY_MODULE_PATH}" CACHE STRING "Modules for CMake")
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SERENITY_MODULE_PATH}" CACHE STRING "Modules for CMake")
@@ -9,7 +14,7 @@ set(CMAKE_BUILD_TYPE Release CACHE STRING "")
 set(LLVM_TARGETS_TO_BUILD "X86;AArch64;RISCV" CACHE STRING "")
 set(LLVM_TARGETS_TO_BUILD "X86;AArch64;RISCV" CACHE STRING "")
 
 
 set(LLVM_ENABLE_PROJECTS "llvm;clang;lld;clang-tools-extra" CACHE STRING "")
 set(LLVM_ENABLE_PROJECTS "llvm;clang;lld;clang-tools-extra" CACHE STRING "")
-set(LLVM_ENABLE_RUNTIMES "compiler-rt" CACHE STRING "")
+set(LLVM_ENABLE_RUNTIMES "compiler-rt;libunwind;libcxxabi;libcxx" CACHE STRING "")
 
 
 set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "")
 set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "")
 set(LLVM_ENABLE_BINDINGS OFF CACHE BOOL "")
 set(LLVM_ENABLE_BINDINGS OFF CACHE BOOL "")
@@ -24,13 +29,13 @@ set(LLVM_INSTALL_BINUTILS_SYMLINKS OFF CACHE BOOL "")
 
 
 set(CLANG_ENABLE_CLANGD OFF CACHE BOOL "")
 set(CLANG_ENABLE_CLANGD OFF CACHE BOOL "")
 
 
-set(compiler_flags "-nostdlib -nostdlib++")
 foreach(target x86_64-pc-serenity;aarch64-pc-serenity;riscv64-pc-serenity)
 foreach(target x86_64-pc-serenity;aarch64-pc-serenity;riscv64-pc-serenity)
     list(APPEND targets "${target}")
     list(APPEND targets "${target}")
 
 
     set(RUNTIMES_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "")
     set(RUNTIMES_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "")
     set(RUNTIMES_${target}_CMAKE_SYSROOT ${SERENITY_${target}_SYSROOT} CACHE PATH "")
     set(RUNTIMES_${target}_CMAKE_SYSROOT ${SERENITY_${target}_SYSROOT} CACHE PATH "")
     # Prevent configure checks from trying to link to the not-yet-built startup files & libunwind.
     # Prevent configure checks from trying to link to the not-yet-built startup files & libunwind.
+    set(compiler_flags "-Wno-unused-command-line-argument -nostartfiles -L${SERENITY_${target}_STUBS}")
     set(RUNTIMES_${target}_CMAKE_C_FLAGS ${compiler_flags} CACHE STRING "")
     set(RUNTIMES_${target}_CMAKE_C_FLAGS ${compiler_flags} CACHE STRING "")
     set(RUNTIMES_${target}_CMAKE_CXX_FLAGS ${compiler_flags} CACHE STRING "")
     set(RUNTIMES_${target}_CMAKE_CXX_FLAGS ${compiler_flags} CACHE STRING "")
     set(RUNTIMES_${target}_COMPILER_RT_BUILD_CRT ON CACHE BOOL "")
     set(RUNTIMES_${target}_COMPILER_RT_BUILD_CRT ON CACHE BOOL "")
@@ -51,6 +56,25 @@ foreach(target x86_64-pc-serenity;aarch64-pc-serenity;riscv64-pc-serenity)
     set(BUILTINS_${target}_COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN OFF CACHE BOOL "")
     set(BUILTINS_${target}_COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN OFF CACHE BOOL "")
     set(BUILTINS_${target}_CMAKE_SYSTEM_NAME SerenityOS CACHE STRING "")
     set(BUILTINS_${target}_CMAKE_SYSTEM_NAME SerenityOS CACHE STRING "")
     set(BUILTINS_${target}_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CACHE STRING "")
     set(BUILTINS_${target}_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CACHE STRING "")
+
+    set(RUNTIMES_${target}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
+
+    set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "")
+
+    # Hardcode autodetection results for libm, libdl, and libpthread.
+    # This keeps us from accidentially detecting those libraries as being present
+    # if we build the toolchain with a populated sysroot (which features the
+    # compability linker scripts).
+    # TODO: Figure out if we can always build against the Stubs directory instead.
+    set(RUNTIMES_${target}_LIBCXXABI_HAS_DL_LIB OFF CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBCXXABI_HAS_PTHREAD_LIB OFF CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBCXX_HAS_M_LIB OFF CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBCXX_HAS_PTHREAD_LIB OFF CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBUNWIND_HAS_DL_LIB OFF CACHE BOOL "")
+    set(RUNTIMES_${target}_LIBUNWIND_HAS_PTHREAD_LIB OFF CACHE BOOL "")
 endforeach()
 endforeach()
 
 
 set(LLVM_TOOLCHAIN_TOOLS
 set(LLVM_TOOLCHAIN_TOOLS

+ 0 - 74
Toolchain/CMake/LLVMRuntimesConfig.cmake

@@ -1,74 +0,0 @@
-# This file specifies the options used for building the various LLVM runtime libraries
-
-# Note: We force the cmake module path for all dependent projects to include our custom directory
-# That has the Platform/SerenityOS.cmake definition
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SERENITY_MODULE_PATH}" CACHE STRING "Modules for CMake")
-
-set(CMAKE_BUILD_TYPE Release CACHE STRING "")
-
-set(LLVM_ENABLE_RUNTIMES "libcxx;libcxxabi;libunwind" CACHE STRING "")
-
-set(CMAKE_SYSTEM_NAME SerenityOS CACHE STRING "")
-set(target_triple ${SERENITY_TOOLCHAIN_ARCH}-pc-serenity)
-
-IF(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Darwin")
-    set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "")
-ENDIF()
-
-set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "")
-set(LLVM_ENABLE_BINDINGS OFF CACHE BOOL "")
-set(LLVM_INCLUDE_BENCHMARKS OFF CACHE BOOL "")
-set(LLVM_BUILD_UTILS OFF CACHE BOOL "")
-set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
-set(LLVM_BUILD_LLVM_DYLIB ON CACHE BOOL "")
-set(LLVM_LINK_LLVM_DYLIB ON CACHE BOOL "")
-set(LLVM_INSTALL_UTILS OFF CACHE BOOL "")
-set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
-set(LLVM_INSTALL_BINUTILS_SYMLINKS OFF CACHE BOOL "")
-set(LLVM_DEFAULT_TARGET_TRIPLE ${target_triple} CACHE STRING "")
-set(LLVM_BINARY_DIR "${SERENITY_TOOLCHAIN_ROOT}" CACHE PATH "")
-
-set(CMAKE_SYSROOT "${SERENITY_BUILD_DIR}/Root" CACHE PATH "")
-set(compiler_flags "-nostdlib -nostdlib++")
-
-set(CMAKE_C_COMPILER "${SERENITY_TOOLCHAIN_ROOT}/bin/clang" CACHE PATH "")
-set(CMAKE_C_COMPILER_WORKS ON CACHE BOOL "")
-set(CMAKE_CXX_COMPILER "${SERENITY_TOOLCHAIN_ROOT}/bin/clang++" CACHE PATH "")
-set(CMAKE_CXX_COMPILER_WORKS ON CACHE BOOL "")
-set(CMAKE_ASM_COMPILER "${SERENITY_TOOLCHAIN_ROOT}/bin/clang" CACHE PATH "")
-set(CMAKE_ASM_COMPILER_WORKS ON CACHE BOOL "")
-set(CMAKE_LINKER "${SERENITY_TOOLCHAIN_ROOT}/bin/ld.lld" CACHE PATH "")
-
-set(CMAKE_ADDR2LINE "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-addr2line" CACHE PATH "")
-set(CMAKE_AR "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-ar" CACHE PATH "")
-set(CMAKE_NM "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-nm" CACHE PATH "")
-set(CMAKE_OBJCOPY "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-objcopy" CACHE PATH "")
-set(CMAKE_OBJDUMP "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-objdump" CACHE PATH "")
-set(CMAKE_RANLIB "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-ranlib" CACHE PATH "")
-set(CMAKE_READELF "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-readelf" CACHE PATH "")
-set(CMAKE_STRIP "${SERENITY_TOOLCHAIN_ROOT}/bin/llvm-strip" CACHE PATH "")
-
-set(CMAKE_C_COMPILER_TARGET ${target_triple} CACHE STRING "")
-set(CMAKE_CXX_COMPILER_TARGET ${target_triple} CACHE STRING "")
-set(CMAKE_ASM_COMPILER_TARGET ${target_triple} CACHE STRING "")
-
-set(CMAKE_C_FLAGS ${compiler_flags} CACHE STRING "")
-set(CMAKE_CXX_FLAGS ${compiler_flags} CACHE STRING "")
-
-set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
-set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
-set(LIBCXX_INCLUDE_BENCHMARKS OFF CACHE BOOL "")
-set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
-set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
-
-# Hardcode autodetection results for libm, libdl, and libpthread.
-# This keeps us from accidentially detecting those libraries as being present
-# if we build the toolchain with a populated sysroot (which features the
-# compability linker scripts).
-# TODO: Figure out if we can always build against the Stubs directory instead.
-set(LIBCXXABI_HAS_DL_LIB OFF CACHE BOOL "")
-set(LIBCXXABI_HAS_PTHREAD_LIB OFF CACHE BOOL "")
-set(LIBCXX_HAS_M_LIB OFF CACHE BOOL "")
-set(LIBCXX_HAS_PTHREAD_LIB OFF CACHE BOOL "")
-set(LIBUNWIND_HAS_DL_LIB OFF CACHE BOOL "")
-set(LIBUNWIND_HAS_PTHREAD_LIB OFF CACHE BOOL "")

+ 0 - 78
Toolchain/Patches/llvm/0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch

@@ -1,78 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Thu, 14 Apr 2022 09:54:22 +0200
-Subject: [PATCH] [Support] Add support for building LLVM on SerenityOS
-
-Adds SerenityOS `#ifdef`s for platform-specific code.
-
-We stub out wait4, as SerenityOS doesn't support querying a child
-process's resource usage information.
----
- llvm/include/llvm/Support/SwapByteOrder.h | 2 +-
- llvm/lib/Support/Unix/Path.inc            | 5 ++++-
- llvm/lib/Support/Unix/Program.inc         | 9 ++++++++-
- 3 files changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/llvm/include/llvm/Support/SwapByteOrder.h b/llvm/include/llvm/Support/SwapByteOrder.h
-index 9dd08665b..8915f92e8 100644
---- a/llvm/include/llvm/Support/SwapByteOrder.h
-+++ b/llvm/include/llvm/Support/SwapByteOrder.h
-@@ -20,7 +20,7 @@
- #include <type_traits>
- 
- #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) ||            \
--    defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
-+    defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__serenity__)
- #include <endian.h>
- #elif defined(_AIX)
- #include <sys/machine.h>
-diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
-index 3efcad4f2..4f83d0e76 100644
---- a/llvm/lib/Support/Unix/Path.inc
-+++ b/llvm/lib/Support/Unix/Path.inc
-@@ -112,7 +112,7 @@ typedef uint_t uint;
- #endif
- 
- #if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) ||       \
--    defined(__MVS__)
-+    defined(__MVS__) || defined(__serenity__)
- #define STATVFS_F_FLAG(vfs) (vfs).f_flag
- #else
- #define STATVFS_F_FLAG(vfs) (vfs).f_flags
-@@ -506,6 +506,9 @@ static bool is_local_impl(struct STATVFS &Vfs) {
- #elif defined(__HAIKU__)
-   // Haiku doesn't expose this information.
-   return false;
-+#elif defined(__serenity__)
-+  // Serenity doesn't yet support remote filesystem mounts.
-+  return false;
- #elif defined(__sun)
-   // statvfs::f_basetype contains a null-terminated FSType name of the mounted
-   // target
-diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
-index 897e22711..23965a1a1 100644
---- a/llvm/lib/Support/Unix/Program.inc
-+++ b/llvm/lib/Support/Unix/Program.inc
-@@ -340,7 +340,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
- namespace llvm {
- namespace sys {
- 
--#ifndef _AIX
-+#if !defined(_AIX) && !defined(__serenity__)
- using ::wait4;
- #else
- static pid_t(wait4)(pid_t pid, int *status, int options, struct rusage *usage);
-@@ -383,6 +383,13 @@ pid_t(llvm::sys::wait4)(pid_t pid, int *status, int options,
- }
- #endif
- 
-+#ifdef __serenity__
-+pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
-+                         struct rusage*) {
-+  return ::waitpid(pid, status, options);
-+}
-+#endif
-+
- ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
-                             std::optional<unsigned> SecondsToWait,
-                             std::string *ErrMsg,

+ 754 - 0
Toolchain/Patches/llvm/0001-clang-Add-support-for-SerenityOS.patch

@@ -0,0 +1,754 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 10:09:50 +0200
+Subject: [PATCH] [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-pc-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: kleines Filmröllchen <filmroellchen@serenityos.org>
+Co-authored-by: Andrew Kaster <akaster@serenityos.org>
+Co-authored-by: Daniel Bertalan <dani@danielbertalan.dev>
+Co-authored-by: Dan Klishch <danilklishch@gmail.com>
+---
+ clang/lib/Basic/Targets.cpp                   |  12 +
+ 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      | 216 ++++++++++++++++++
+ clang/lib/Driver/ToolChains/Serenity.h        |  84 +++++++
+ clang/lib/Lex/InitHeaderSearch.cpp            |   1 +
+ .../usr/include/c++/v1/.keep                  |   0
+ .../include/x86_64-pc-serenity/c++/v1/.keep   |   0
+ .../serenity_x86_64_tree/usr/lib/crt0.o       |   0
+ .../usr/lib/crt0_shared.o                     |   0
+ .../serenity_x86_64_tree/usr/lib/crti.o       |   0
+ .../serenity_x86_64_tree/usr/lib/crtn.o       |   0
+ .../serenity_x86_64_tree/usr/local/.keep      |   0
+ clang/test/Driver/pic.c                       |   6 +
+ clang/test/Driver/save-stats.c                |   2 +
+ clang/test/Driver/serenity.cpp                | 196 ++++++++++++++++
+ 18 files changed, 543 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/serenity_x86_64_tree/usr/include/c++/v1/.keep
+ create mode 100644 clang/test/Driver/Inputs/serenity_x86_64_tree/usr/include/x86_64-pc-serenity/c++/v1/.keep
+ create mode 100644 clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crt0.o
+ create mode 100644 clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crt0_shared.o
+ create mode 100644 clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crti.o
+ create mode 100644 clang/test/Driver/Inputs/serenity_x86_64_tree/usr/lib/crtn.o
+ create mode 100644 clang/test/Driver/Inputs/serenity_x86_64_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 e3283510c6aa..8cf3fc4fb346 100644
+--- a/clang/lib/Basic/Targets.cpp
++++ b/clang/lib/Basic/Targets.cpp
+@@ -166,6 +166,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
+     case llvm::Triple::OpenBSD:
+       return std::make_unique<OpenBSDTargetInfo<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:
+@@ -463,6 +466,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
+         return std::make_unique<OHOSTargetInfo<RISCV64TargetInfo>>(Triple,
+                                                                    Opts);
+       }
++    case llvm::Triple::Serenity:
++      return std::make_unique<SerenityTargetInfo<RISCV64TargetInfo>>(Triple,
++                                                                     Opts);
+     default:
+       return std::make_unique<RISCV64TargetInfo>(Triple, Opts);
+     }
+@@ -586,6 +592,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
+       return std::make_unique<MCUX86_32TargetInfo>(Triple, Opts);
+     case llvm::Triple::Hurd:
+       return std::make_unique<HurdTargetInfo<X86_32TargetInfo>>(Triple, Opts);
++    case llvm::Triple::Serenity:
++      return std::make_unique<SerenityTargetInfo<X86_32TargetInfo>>(Triple,
++                                                                    Opts);
+     default:
+       return std::make_unique<X86_32TargetInfo>(Triple, Opts);
+     }
+@@ -646,6 +655,9 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
+       return std::make_unique<PS5OSTargetInfo<X86_64TargetInfo>>(Triple, Opts);
+     case llvm::Triple::Hurd:
+       return std::make_unique<HurdTargetInfo<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 4366c1149e40..3528e16d8690 100644
+--- a/clang/lib/Basic/Targets/OSTargets.h
++++ b/clang/lib/Basic/Targets/OSTargets.h
+@@ -1000,6 +1000,23 @@ public:
+   }
+ };
+ 
++// 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 58427e3f83c4..e8a081bbf728 100644
+--- a/clang/lib/Driver/CMakeLists.txt
++++ b/clang/lib/Driver/CMakeLists.txt
+@@ -75,6 +75,7 @@ add_clang_library(clangDriver
+   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
+index 93cddf742d52..8a821456ce28 100644
+--- 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"
+@@ -6272,6 +6273,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
+     case llvm::Triple::Fuchsia:
+       TC = std::make_unique<toolchains::Fuchsia>(*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 388030592b48..02a706da75a4 100644
+--- a/clang/lib/Driver/ToolChain.cpp
++++ b/clang/lib/Driver/ToolChain.cpp
+@@ -589,6 +589,8 @@ StringRef ToolChain::getOSLibName() const {
+     return "sunos";
+   case llvm::Triple::AIX:
+     return "aix";
++  case llvm::Triple::Serenity:
++    return "serenity";
+   default:
+     return getOS();
+   }
+@@ -1081,7 +1083,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 000000000000..2167758100bc
+--- /dev/null
++++ b/clang/lib/Driver/ToolChains/Serenity.cpp
+@@ -0,0 +1,216 @@
++//===---- 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 <string>
++
++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");
++
++  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) {
++    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 (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");
++  }
++
++  // 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()) {
++      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<Command>(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/Driver/ToolChains/Serenity.h b/clang/lib/Driver/ToolChains/Serenity.h
+new file mode 100644
+index 000000000000..2a1f685cb662
+--- /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/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp
+index 2218db15013d..36a6cd6425dd 100644
+--- a/clang/lib/Lex/InitHeaderSearch.cpp
++++ b/clang/lib/Lex/InitHeaderSearch.cpp
+@@ -304,6 +304,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::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
+index 000000000000..e69de29bb2d1
+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
+index 000000000000..e69de29bb2d1
+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
+index 000000000000..e69de29bb2d1
+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
+index 000000000000..e69de29bb2d1
+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
+index 000000000000..e69de29bb2d1
+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
+index 000000000000..e69de29bb2d1
+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
+index 000000000000..e69de29bb2d1
+diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c
+index aeddead6dbf8..57ef930b7848 100644
+--- 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
+index ad7867a99168..94d93dc23920 100644
+--- a/clang/test/Driver/save-stats.c
++++ b/clang/test/Driver/save-stats.c
+@@ -32,6 +32,8 @@
+ // 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=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
+index 000000000000..48de4c0eb6ec
+--- /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"
+-- 
+2.44.0
+

+ 0 - 56
Toolchain/Patches/llvm/0002-Triple-Add-triple-for-SerenityOS.patch

@@ -1,56 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Thu, 14 Apr 2022 09:51:24 +0200
-Subject: [PATCH] [Triple] Add triple for SerenityOS
-
----
- llvm/include/llvm/TargetParser/Triple.h | 8 +++++++-
- llvm/lib/TargetParser/Triple.cpp        | 2 ++
- 2 files changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
-index 59513fa2f..951d69010 100644
---- a/llvm/include/llvm/TargetParser/Triple.h
-+++ b/llvm/include/llvm/TargetParser/Triple.h
-@@ -223,7 +223,8 @@ public:
-     WASI,       // Experimental WebAssembly OS
-     Emscripten,
-     ShaderModel, // DirectX ShaderModel
--    LastOSType = ShaderModel
-+    Serenity,
-+    LastOSType = Serenity
-   };
-   enum EnvironmentType {
-     UnknownEnvironment,
-@@ -670,6 +671,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/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
-index a68035989..1ee9ea3b1 100644
---- a/llvm/lib/TargetParser/Triple.cpp
-+++ b/llvm/lib/TargetParser/Triple.cpp
-@@ -237,6 +237,7 @@ StringRef Triple::getOSTypeName(OSType Kind) {
-   case PS5: return "ps5";
-   case RTEMS: return "rtems";
-   case Solaris: return "solaris";
-+  case Serenity: return "serenity";
-   case TvOS: return "tvos";
-   case WASI: return "wasi";
-   case WatchOS: return "watchos";
-@@ -596,6 +597,7 @@ static Triple::OSType parseOS(StringRef OSName) {
-     .StartsWith("wasi", Triple::WASI)
-     .StartsWith("emscripten", Triple::Emscripten)
-     .StartsWith("shadermodel", Triple::ShaderModel)
-+    .StartsWith("serenity", Triple::Serenity)
-     .Default(Triple::UnknownOS);
- }
- 

+ 134 - 0
Toolchain/Patches/llvm/0002-llvm-Add-support-for-building-LLVM-on-SerenityOS.patch

@@ -0,0 +1,134 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 09:54:22 +0200
+Subject: [PATCH] [llvm] Add support for building LLVM on SerenityOS
+
+Adds SerenityOS `#ifdef`s for platform-specific code.
+
+We stub out wait4, as SerenityOS doesn't support querying a child
+process's resource usage information.
+
+POSIX shm is not supported by SerenityOS yet, so disable it in Orc.
+
+Serenity gives each thread a default of 1MiB of stack. Increase the
+default stack size for llvm applications when running on SerenityOS.
+
+Co-Authored-By: sin-ack <sin-ack@users.noreply.github.com>
+Co-Authored-By: Tim Schumacher <timschumi@gmx.de>
+---
+ llvm/cmake/modules/HandleLLVMOptions.cmake               | 3 +++
+ llvm/include/llvm/ADT/bit.h                              | 2 +-
+ llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp            | 3 ++-
+ .../TargetProcess/ExecutorSharedMemoryMapperService.cpp  | 3 ++-
+ llvm/lib/Support/Unix/Path.inc                           | 5 ++++-
+ llvm/lib/Support/Unix/Program.inc                        | 9 ++++++++-
+ 6 files changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
+index 0699a8586fcc..29d0d46fdcb4 100644
+--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
++++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
+@@ -503,6 +503,9 @@ elseif(MINGW OR CYGWIN)
+   if (NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+     append("-Wa,-mbig-obj" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+   endif()
++elseif(SERENITYOS)
++  # SerenityOS sets a very low default stack size value, so increase it to 4MB manually.
++  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,stack-size=4194304")
+ endif()
+ 
+ option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)
+diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h
+index c42b5e686bdc..ad4ad534f40c 100644
+--- a/llvm/include/llvm/ADT/bit.h
++++ b/llvm/include/llvm/ADT/bit.h
+@@ -29,7 +29,7 @@
+ 
+ #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) ||            \
+     defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) ||  \
+-    defined(__OpenBSD__) || defined(__DragonFly__)
++    defined(__OpenBSD__) || defined(__DragonFly__) || defined(__serenity__)
+ #include <endian.h>
+ #elif defined(_AIX)
+ #include <sys/machine.h>
+diff --git a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
+index 9cfe547c84c3..f43a317064f5 100644
+--- a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
++++ b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
+@@ -215,7 +215,8 @@ SharedMemoryMapper::Create(ExecutorProcessControl &EPC, SymbolAddrs SAs) {
+ 
+ void SharedMemoryMapper::reserve(size_t NumBytes,
+                                  OnReservedFunction OnReserved) {
+-#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
++#if (defined(LLVM_ON_UNIX) && !(defined(__ANDROID__) || defined(__serenity__))) \
++    || defined(_WIN32)
+ 
+   EPC.callSPSWrapperAsync<
+       rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>(
+diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
+index e8b0e240ac1f..fcc7bfe1c1cc 100644
+--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
++++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
+@@ -47,7 +47,8 @@ static DWORD getWindowsProtectionFlags(MemProt MP) {
+ 
+ Expected<std::pair<ExecutorAddr, std::string>>
+ ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
+-#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
++#if (defined(LLVM_ON_UNIX) && !(defined(__ANDROID__) || defined(__serenity__))) \
++    || defined(_WIN32)
+ 
+ #if defined(LLVM_ON_UNIX)
+ 
+diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
+index 9f89d63bb0fd..5035b1b05f4d 100644
+--- a/llvm/lib/Support/Unix/Path.inc
++++ b/llvm/lib/Support/Unix/Path.inc
+@@ -112,7 +112,7 @@ typedef uint_t uint;
+ #endif
+ 
+ #if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) ||       \
+-    defined(__MVS__)
++    defined(__MVS__) || defined(__serenity__)
+ #define STATVFS_F_FLAG(vfs) (vfs).f_flag
+ #else
+ #define STATVFS_F_FLAG(vfs) (vfs).f_flags
+@@ -511,6 +511,9 @@ static bool is_local_impl(struct STATVFS &Vfs) {
+ #elif defined(__HAIKU__)
+   // Haiku doesn't expose this information.
+   return false;
++#elif defined(__serenity__)
++  // Serenity doesn't yet support remote filesystem mounts.
++  return false;
+ #elif defined(__sun)
+   // statvfs::f_basetype contains a null-terminated FSType name of the mounted
+   // target
+diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
+index 5d9757bcc51b..18295dc2229c 100644
+--- a/llvm/lib/Support/Unix/Program.inc
++++ b/llvm/lib/Support/Unix/Program.inc
+@@ -342,7 +342,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
+ namespace llvm {
+ namespace sys {
+ 
+-#if defined(_AIX)
++#if defined(_AIX) || defined(__serenity__)
+ static pid_t(wait4)(pid_t pid, int *status, int options, struct rusage *usage);
+ #elif !defined(__Fuchsia__)
+ using ::wait4;
+@@ -385,6 +385,13 @@ pid_t(llvm::sys::wait4)(pid_t pid, int *status, int options,
+ }
+ #endif
+ 
++#ifdef __serenity__
++pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
++                         struct rusage*) {
++  return ::waitpid(pid, status, options);
++}
++#endif
++
+ ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
+                             std::optional<unsigned> SecondsToWait,
+                             std::string *ErrMsg,
+-- 
+2.44.0
+

+ 0 - 596
Toolchain/Patches/llvm/0003-Driver-Add-support-for-SerenityOS.patch

@@ -1,596 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Thu, 14 Apr 2022 10:09:50 +0200
-Subject: [PATCH] [Driver] Add support for SerenityOS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Adds support for the `$arch-pc-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: kleines Filmröllchen <filmroellchen@serenityos.org>
----
- clang/lib/Basic/Targets.cpp              |   8 +
- clang/lib/Basic/Targets/OSTargets.h      |  18 ++
- clang/lib/Driver/CMakeLists.txt          |   1 +
- clang/lib/Driver/Driver.cpp              |   4 +
- clang/lib/Driver/ToolChain.cpp           |   2 +
- clang/lib/Driver/ToolChains/Serenity.cpp | 336 +++++++++++++++++++++++
- clang/lib/Driver/ToolChains/Serenity.h   | 100 +++++++
- 7 files changed, 469 insertions(+)
- create mode 100644 clang/lib/Driver/ToolChains/Serenity.cpp
- create mode 100644 clang/lib/Driver/ToolChains/Serenity.h
-
-diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
-index 8400774db..f82618dc8 100644
---- a/clang/lib/Basic/Targets.cpp
-+++ b/clang/lib/Basic/Targets.cpp
-@@ -153,6 +153,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
-       return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
-     case llvm::Triple::OpenBSD:
-       return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
-+    case llvm::Triple::Serenity:
-+      return new SerenityTargetInfo<AArch64leTargetInfo>(Triple, Opts);
-     case llvm::Triple::Win32:
-       switch (Triple.getEnvironment()) {
-       case llvm::Triple::GNU:
-@@ -424,6 +426,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
-       return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts);
-     case llvm::Triple::Linux:
-       return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
-+    case llvm::Triple::Serenity:
-+      return new SerenityTargetInfo<RISCV64TargetInfo>(Triple, Opts);
-     default:
-       return new RISCV64TargetInfo(Triple, Opts);
-     }
-@@ -542,6 +546,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
-       return new MCUX86_32TargetInfo(Triple, Opts);
-     case llvm::Triple::Hurd:
-       return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts);
-+    case llvm::Triple::Serenity:
-+      return new SerenityTargetInfo<X86_32TargetInfo>(Triple, Opts);
-     default:
-       return new X86_32TargetInfo(Triple, Opts);
-     }
-@@ -596,6 +602,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
-       return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
-     case llvm::Triple::PS5:
-       return new PS5OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
-+    case llvm::Triple::Serenity:
-+      return new SerenityTargetInfo<X86_64TargetInfo>(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 fd372cb12..27a3f9797 100644
---- a/clang/lib/Basic/Targets/OSTargets.h
-+++ b/clang/lib/Basic/Targets/OSTargets.h
-@@ -1005,6 +1005,24 @@ public:
-   }
- };
- 
-+// 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);
-+    Builder.defineMacro("__ELF__");
-+  }
-+
-+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 ba56a9323..4d0ffe88c 100644
---- a/clang/lib/Driver/CMakeLists.txt
-+++ b/clang/lib/Driver/CMakeLists.txt
-@@ -78,6 +78,7 @@ add_clang_library(clangDriver
-   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
-index a268f2fa8..df54be3de 100644
---- a/clang/lib/Driver/Driver.cpp
-+++ b/clang/lib/Driver/Driver.cpp
-@@ -45,6 +45,7 @@
- #include "ToolChains/PPCLinux.h"
- #include "ToolChains/PS4CPU.h"
- #include "ToolChains/RISCVToolchain.h"
-+#include "ToolChains/Serenity.h"
- #include "ToolChains/SPIRV.h"
- #include "ToolChains/Solaris.h"
- #include "ToolChains/TCE.h"
-@@ -6041,6 +6042,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
-     case llvm::Triple::Fuchsia:
-       TC = std::make_unique<toolchains::Fuchsia>(*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 bc70205a6..3d5c856ab 100644
---- a/clang/lib/Driver/ToolChain.cpp
-+++ b/clang/lib/Driver/ToolChain.cpp
-@@ -482,6 +482,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..4fdf45a19
---- /dev/null
-+++ b/clang/lib/Driver/ToolChains/Serenity.cpp
-@@ -0,0 +1,340 @@
-+//===---- 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/DriverDiagnostic.h"
-+#include "clang/Driver/Options.h"
-+#include "clang/Driver/SanitizerArgs.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;
-+
-+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) : 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");
-+  }
-+
-+  if (!IsStatic || IsStaticPIE)
-+    CmdArgs.push_back("--eh-frame-hdr");
-+
-+  if (Output.isFilename()) {
-+    CmdArgs.push_back("-o");
-+    CmdArgs.push_back(Output.getFilename());
-+  }
-+
-+  const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
-+  auto linkerIs = [Exec](const char* name) {
-+    return llvm::sys::path::filename(Exec).equals_insensitive(name) ||
-+           llvm::sys::path::stem(Exec).equals_insensitive(name);
-+  };
-+
-+  if (linkerIs("ld.lld") || linkerIs("ld.mold")) {
-+    CmdArgs.push_back("--pack-dyn-relocs=relr");
-+  } else {
-+    CmdArgs.push_back("-z");
-+    CmdArgs.push_back("pack-relative-relocs");
-+  }
-+
-+  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(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");
-+  }
-+
-+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-+    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);
-+
-+  C.addCommand(std::make_unique<Command>(JA, *this,
-+                                         ResponseFileSupport::AtFileCurCP(),
-+                                         Exec, CmdArgs, Inputs, Output));
-+}
-+
-+Serenity::Serenity(const Driver &D, const llvm::Triple &Triple,
-+                   const ArgList &Args)
-+    : ToolChain(D, Triple, Args) {
-+  getProgramPaths().push_back(getDriver().getInstalledDir());
-+  if (getDriver().getInstalledDir() != getDriver().Dir)
-+    getProgramPaths().push_back(getDriver().Dir);
-+  getFilePaths().push_back(getDriver().SysRoot + "/usr/local/lib");
-+  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;
-+
-+  addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include");
-+  addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
-+}
-+
-+static std::string getLibStdCXXVersion(const Driver &D, StringRef IncludePath) {
-+  SmallString<128> Path(IncludePath);
-+  llvm::sys::path::append(Path, "c++");
-+
-+  std::error_code EC;
-+  std::tuple<int, int, int> Newest{0, 0, 0};
-+  std::string Result;
-+
-+  for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE;
-+       !EC && LI != LE; LI = LI.increment(EC)) {
-+    StringRef VersionText = llvm::sys::path::filename(LI->path());
-+
-+    // This is libc++
-+    if (VersionText[0] == 'v')
-+      continue;
-+
-+    llvm::SmallVector<StringRef, 3> Parts;
-+    VersionText.split(Parts, '.');
-+
-+    // SerenityOS always builds GCC with <major>.<minor>.<patch> versions
-+    if (Parts.size() < 3)
-+      continue;
-+
-+    std::tuple<int, int, int> Current;
-+    if (!llvm::to_integer(Parts[0], std::get<0>(Current)))
-+      continue;
-+    if (!llvm::to_integer(Parts[1], std::get<1>(Current)))
-+      continue;
-+    if (!llvm::to_integer(Parts[2], std::get<2>(Current)))
-+      continue;
-+
-+    if (Current > Newest) {
-+      Newest = Current;
-+      Result = VersionText.str();
-+    }
-+  }
-+  return Result;
-+}
-+
-+void Serenity::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
-+                                            ArgStringList &CC1Args) const {
-+  if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx,
-+                        options::OPT_nostdlibinc))
-+    return;
-+
-+  const auto StdLib = GetCXXStdlibType(DriverArgs);
-+
-+  const Driver &D = getDriver();
-+  std::string SysRoot = computeSysRoot();
-+  std::string Target = getTripleString();
-+
-+  auto AddIncludePath = [&](std::string Path) {
-+    std::string Version = StdLib == CXXStdlibType::CST_Libstdcxx
-+                              ? getLibStdCXXVersion(D, Path)
-+                              : detectLibcxxVersion(Path);
-+    if (Version.empty())
-+      return false;
-+
-+    std::string TargetDir;
-+    if (StdLib == CXXStdlibType::CST_Libstdcxx) {
-+      TargetDir = Path + "/c++/" + Version + "/" + Target;
-+    } else {
-+      TargetDir = Path + "/" + Target + "/c++/" + Version;
-+    }
-+
-+    if (D.getVFS().exists(TargetDir))
-+      addSystemInclude(DriverArgs, CC1Args, TargetDir);
-+
-+    addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version);
-+    return true;
-+  };
-+
-+  if (AddIncludePath(getDriver().Dir + "/../include"))
-+    return;
-+  if (AddIncludePath(SysRoot + "/usr/local/include"))
-+    return;
-+  if (AddIncludePath(SysRoot + "/usr/include"))
-+    return;
-+}
-+
-+void Serenity::addClangTargetOptions(
-+    const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
-+    Action::OffloadKind DeviceOffloadKind) const {
-+  if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
-+                          options::OPT_fno_use_init_array, true))
-+    CC1Args.push_back("-fno-use-init-array");
-+}
-+
-+ToolChain::UnwindLibType
-+Serenity::GetUnwindLibType(const llvm::opt::ArgList &Args) const {
-+
-+  const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
-+  StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
-+
-+  if (LibName == "none") {
-+    return ToolChain::UNW_None;
-+  } else if (LibName == "platform" || LibName == "") {
-+    ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
-+    if (RtLibType == ToolChain::RLT_CompilerRT) {
-+      return ToolChain::UNW_CompilerRT;
-+    } else if (RtLibType == ToolChain::RLT_Libgcc)
-+      return ToolChain::UNW_Libgcc;
-+  } else if (LibName == "libunwind") {
-+    if (GetRuntimeLibType(Args) == RLT_Libgcc)
-+      getDriver().Diag(diag::err_drv_incompatible_unwindlib);
-+    return ToolChain::UNW_CompilerRT;
-+  } else if (LibName == "libgcc") {
-+    return ToolChain::UNW_Libgcc;
-+  }
-+
-+  if (A)
-+    getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
-+        << A->getAsString(Args);
-+
-+  return ToolChain::UNW_None;
-+}
-+
-+SanitizerMask Serenity::getSupportedSanitizers() const {
-+  return ToolChain::getSupportedSanitizers() | SanitizerKind::KernelAddress;
-+}
-diff --git a/clang/lib/Driver/ToolChains/Serenity.h b/clang/lib/Driver/ToolChains/Serenity.h
-new file mode 100644
-index 000000000..feb31a0d6
---- /dev/null
-+++ b/clang/lib/Driver/ToolChains/Serenity.h
-@@ -0,0 +1,102 @@
-+//===---- 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 "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 : 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 ToolChain {
-+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;
-+  }
-+
-+  CXXStdlibType GetDefaultCXXStdlibType() const override {
-+    return ToolChain::CST_Libcxx;
-+  }
-+
-+  UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override;
-+
-+  void
-+  addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-+                        llvm::opt::ArgStringList &CC1Args,
-+                        Action::OffloadKind DeviceOffloadKind) const override;
-+
-+  const char *getDefaultLinker() const override { return "ld.lld"; }
-+
-+  bool HasNativeLLVMSupport() const override { return true; }
-+
-+  bool IsIntegratedAssemblerDefault() const override { return true; }
-+
-+  bool isPICDefault() const override { return true; }
-+  bool isPIEDefault(const llvm::opt::ArgList&) const override { return false; }
-+  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;
-+  }
-+
-+  bool useRelaxRelocations() const override { return true; }
-+
-+  LangOptions::StackProtectorMode
-+  GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
-+    return LangOptions::SSPStrong;
-+  }
-+
-+  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

+ 46 - 0
Toolchain/Patches/llvm/0003-tools-Support-building-shared-libLLVM-and-libClang-f.patch

@@ -0,0 +1,46 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Mon, 18 Apr 2022 22:32:29 +0200
+Subject: [PATCH] [tools] Support building shared libLLVM and libClang for
+ SerenityOS
+
+This patch tells CMake that the --whole-archive linker option should be
+used for specifying the archives whose members will constitute these
+shared libraries.
+
+Symbol versioning is disabled, as the SerenityOS loader doesn't support
+it, and the ELF sections that store version data would just waste space.
+---
+ llvm/cmake/modules/HandleLLVMOptions.cmake | 2 +-
+ llvm/tools/llvm-shlib/CMakeLists.txt       | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
+index 29d0d46fdcb4..df8d63902dfd 100644
+--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
++++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
+@@ -181,7 +181,7 @@ if(WIN32)
+ elseif(FUCHSIA OR UNIX)
+   set(LLVM_ON_WIN32 0)
+   set(LLVM_ON_UNIX 1)
+-  if(APPLE OR ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
++  if(APPLE OR SERENITYOS OR ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+     set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
+   else()
+     set(LLVM_HAVE_LINK_VERSION_SCRIPT 1)
+diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt
+index b20ac318e768..d3df0de2f694 100644
+--- a/llvm/tools/llvm-shlib/CMakeLists.txt
++++ b/llvm/tools/llvm-shlib/CMakeLists.txt
+@@ -51,7 +51,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
+ 
+     # GNU ld doesn't resolve symbols in the version script.
+     set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive)
+-    if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW)
++    if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW AND NOT SERENITYOS)
+       # Solaris ld does not accept global: *; so there is no way to version *all* global symbols
+       set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES})
+     endif()
+-- 
+2.44.0
+

+ 0 - 32
Toolchain/Patches/llvm/0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch

@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Thu, 14 Apr 2022 10:12:54 +0200
-Subject: [PATCH] [Driver] Default to -ftls-model=initial-exec on SerenityOS
-
-This is a hack to make Clang use the initial-exec TLS model instead of
-the default local-exec when building code for Serenity.
-
-This patch should be removed when we implement proper TLS support.
----
- clang/lib/Driver/ToolChains/Clang.cpp | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
-index 77554aa2c..84eebee36 100644
---- a/clang/lib/Driver/ToolChains/Clang.cpp
-+++ b/clang/lib/Driver/ToolChains/Clang.cpp
-@@ -6100,7 +6100,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
-   Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var,
-                            options::OPT_fno_visibility_inlines_hidden_static_local_var);
-   Args.AddLastArg(CmdArgs, options::OPT_fvisibility_global_new_delete_hidden);
--  Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
-+  if (Triple.isOSSerenity()) {
-+    StringRef tls_model =
-+        Args.getLastArgValue(options::OPT_ftlsmodel_EQ, "initial-exec");
-+    CmdArgs.push_back(Args.MakeArgString("-ftls-model=" + tls_model));
-+  } else {
-+    Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
-+  }
- 
-   if (Args.hasFlag(options::OPT_fnew_infallible,
-                    options::OPT_fno_new_infallible, false))

+ 110 - 0
Toolchain/Patches/llvm/0004-compiler-rt-Enable-profile-instrumentation-for-Seren.patch

@@ -0,0 +1,110 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Andrew Kaster <akaster@serenityos.org>
+Date: Fri, 4 Mar 2022 15:13:42 -0700
+Subject: [PATCH] [compiler-rt] Enable profile instrumentation for SerenityOS
+
+Treat SerenityOS the same as other *NIX platforms that behave close
+enough to linux to use the pre-canned InstrProfiling implementation.
+---
+ clang/lib/Driver/ToolChains/Serenity.cpp      |  3 +++
+ clang/test/Driver/instrprof-ld.c              | 20 +++++++++++++++++++
+ compiler-rt/cmake/config-ix.cmake             |  2 +-
+ .../lib/profile/InstrProfilingPlatformLinux.c |  2 +-
+ .../lib/profile/InstrProfilingPlatformOther.c |  3 ++-
+ 5 files changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp
+index 2167758100bc..c132e5c41185 100644
+--- a/clang/lib/Driver/ToolChains/Serenity.cpp
++++ b/clang/lib/Driver/ToolChains/Serenity.cpp
+@@ -183,6 +183,9 @@ void tools::serenity::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+     CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtn.o")));
+   }
+ 
++  if (ShouldLinkCompilerRuntime)
++    TC.addProfileRTLibs(Args, CmdArgs);
++
+   const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
+   C.addCommand(std::make_unique<Command>(JA, *this,
+                                          ResponseFileSupport::AtFileCurCP(),
+diff --git a/clang/test/Driver/instrprof-ld.c b/clang/test/Driver/instrprof-ld.c
+index 9a58cd3a0be7..d37de48b9d83 100644
+--- a/clang/test/Driver/instrprof-ld.c
++++ b/clang/test/Driver/instrprof-ld.c
+@@ -54,6 +54,15 @@
+ // CHECK-OPENBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+ // CHECK-OPENBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}openbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
+ 
++// RUN: %clang -### %s 2>&1 \
++// RUN:     --target=x86_64-pc-serenity -fprofile-instr-generate -fuse-ld=ld \
++// RUN:     -resource-dir=%S/Inputs/resource_dir \
++// RUN:     --sysroot=%S/Inputs/serenity_x86_64_tree \
++// RUN:   | FileCheck --check-prefix=CHECK-SERENITY-X86-64 %s
++
++// CHECK-SERENITY-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
++// CHECK-SERENITY-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}serenity{{/|\\\\}}libclang_rt.profile-x86_64.a"
++
+ // RUN: %clang -### %s 2>&1 \
+ // RUN:     -shared \
+ // RUN:     --target=i386-unknown-linux -fprofile-instr-generate -fuse-ld=ld \
+@@ -104,6 +113,17 @@
+ // CHECK-OPENBSD-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+ // CHECK-OPENBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}openbsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
+ 
++// RUN: %clang -### %s 2>&1 \
++// RUN:     -shared \
++// RUN:     --target=x86_64-pc-serenity -fprofile-instr-generate -fuse-ld=ld \
++// RUN:     -resource-dir=%S/Inputs/resource_dir \
++// RUN:     --sysroot=%S/Inputs/serenity_x86_64_tree \
++// RUN:   | FileCheck --check-prefix=CHECK-SERENITY-X86-64-SHARED %s
++
++// CHECK-SERENITY-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
++// CHECK-SERENITY-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}serenity{{/|\\\\}}libclang_rt.profile-x86_64.a"
++
++
+ // RUN: %clang -### %s 2>&1 \
+ // RUN:     --target=x86_64-apple-darwin14 -fprofile-instr-generate -fuse-ld=ld \
+ // RUN:     -resource-dir=%S/Inputs/resource_dir \
+diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
+index 2ca18ebb4ad4..e9e00e6fec5c 100644
+--- a/compiler-rt/cmake/config-ix.cmake
++++ b/compiler-rt/cmake/config-ix.cmake
+@@ -795,7 +795,7 @@ else()
+ endif()
+ 
+ if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
+-    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
++    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|SerenityOS")
+   set(COMPILER_RT_HAS_PROFILE TRUE)
+ else()
+   set(COMPILER_RT_HAS_PROFILE FALSE)
+diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+index 19266ab6c6fb..ee7200730f86 100644
+--- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
++++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+@@ -8,7 +8,7 @@
+ 
+ #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
+     (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
+-    defined(_AIX)
++    defined(_AIX) || defined(__serenity__)
+ 
+ #if !defined(_AIX)
+ #include <elf.h>
+diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
+index 5319ca813b43..40ff14b75e7c 100644
+--- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
++++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
+@@ -8,7 +8,8 @@
+ 
+ #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) &&     \
+     !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) &&       \
+-    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
++    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) &&              \
++    !defined(__serenity__)
+ 
+ #include <stdlib.h>
+ #include <stdio.h>
+-- 
+2.44.0
+

+ 32 - 29
Toolchain/Patches/llvm/0005-libc-Add-support-for-SerenityOS.patch → Toolchain/Patches/llvm/0005-libcxx-Add-support-for-SerenityOS.patch

@@ -1,7 +1,7 @@
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Daniel Bertalan <dani@danielbertalan.dev>
 From: Daniel Bertalan <dani@danielbertalan.dev>
 Date: Thu, 14 Apr 2022 10:17:13 +0200
 Date: Thu, 14 Apr 2022 10:17:13 +0200
-Subject: [PATCH] [libc++] Add support for SerenityOS
+Subject: [PATCH] [libcxx] Add support for SerenityOS
 
 
 This commit teaches libc++ about what features are available in our
 This commit teaches libc++ about what features are available in our
 LibC, namely:
 LibC, namely:
@@ -24,23 +24,23 @@ LibC, namely:
  create mode 100644 libcxx/include/__support/serenity/xlocale.h
  create mode 100644 libcxx/include/__support/serenity/xlocale.h
 
 
 diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
 diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
-index a12aa1de1..075ebbe81 100644
+index ed721d467e94..5641e32b1343 100644
 --- a/libcxx/include/CMakeLists.txt
 --- a/libcxx/include/CMakeLists.txt
 +++ b/libcxx/include/CMakeLists.txt
 +++ b/libcxx/include/CMakeLists.txt
-@@ -549,6 +549,7 @@ set(files
+@@ -675,6 +675,7 @@ set(files
    __support/musl/xlocale.h
    __support/musl/xlocale.h
    __support/newlib/xlocale.h
    __support/newlib/xlocale.h
    __support/openbsd/xlocale.h
    __support/openbsd/xlocale.h
 +  __support/serenity/xlocale.h
 +  __support/serenity/xlocale.h
-   __support/solaris/floatingpoint.h
-   __support/solaris/wchar.h
-   __support/solaris/xlocale.h
+   __support/win32/locale_win32.h
+   __support/xlocale/__nop_locale_mgmt.h
+   __support/xlocale/__posix_l_fallback.h
 diff --git a/libcxx/include/__config b/libcxx/include/__config
 diff --git a/libcxx/include/__config b/libcxx/include/__config
-index 108153883..e4434809c 100644
+index 8b2eaf69d170..53a09f46eaf7 100644
 --- a/libcxx/include/__config
 --- a/libcxx/include/__config
 +++ b/libcxx/include/__config
 +++ b/libcxx/include/__config
-@@ -930,7 +930,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
-         defined(__sun__) ||                                                                                            \
+@@ -1103,7 +1103,8 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
+         defined(__APPLE__) ||                                                                                          \
          defined(__MVS__) ||                                                                                            \
          defined(__MVS__) ||                                                                                            \
          defined(_AIX) ||                                                                                               \
          defined(_AIX) ||                                                                                               \
 -        defined(__EMSCRIPTEN__)
 -        defined(__EMSCRIPTEN__)
@@ -49,7 +49,7 @@ index 108153883..e4434809c 100644
  // clang-format on
  // clang-format on
  #      define _LIBCPP_HAS_THREAD_API_PTHREAD
  #      define _LIBCPP_HAS_THREAD_API_PTHREAD
  #    elif defined(__Fuchsia__)
  #    elif defined(__Fuchsia__)
-@@ -1008,7 +1009,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
+@@ -1176,7 +1177,7 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
  #  endif
  #  endif
  
  
  #  if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) ||                        \
  #  if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) ||                        \
@@ -59,21 +59,21 @@ index 108153883..e4434809c 100644
  #  endif
  #  endif
  
  
 diff --git a/libcxx/include/__locale b/libcxx/include/__locale
 diff --git a/libcxx/include/__locale b/libcxx/include/__locale
-index e0ffa0ca0..33e994abe 100644
+index 3ba7ac18b0b3..9a68dade7fef 100644
 --- a/libcxx/include/__locale
 --- a/libcxx/include/__locale
 +++ b/libcxx/include/__locale
 +++ b/libcxx/include/__locale
-@@ -44,6 +44,8 @@
- # include <__support/musl/xlocale.h>
+@@ -51,6 +51,8 @@
+ #  include <__support/musl/xlocale.h>
  #elif defined(_LIBCPP_HAS_MUSL_LIBC)
  #elif defined(_LIBCPP_HAS_MUSL_LIBC)
- # include <__support/musl/xlocale.h>
+ #  include <__support/musl/xlocale.h>
 +#elif defined(__serenity__)
 +#elif defined(__serenity__)
-+# include <__support/serenity/xlocale.h>
++#  include <__support/serenity/xlocale.h>
  #endif
  #endif
  
  
  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 diff --git a/libcxx/include/__support/serenity/xlocale.h b/libcxx/include/__support/serenity/xlocale.h
 diff --git a/libcxx/include/__support/serenity/xlocale.h b/libcxx/include/__support/serenity/xlocale.h
 new file mode 100644
 new file mode 100644
-index 000000000..0f939d2f6
+index 000000000000..67c85bf641e2
 --- /dev/null
 --- /dev/null
 +++ b/libcxx/include/__support/serenity/xlocale.h
 +++ b/libcxx/include/__support/serenity/xlocale.h
 @@ -0,0 +1,24 @@
 @@ -0,0 +1,24 @@
@@ -90,22 +90,22 @@ index 000000000..0f939d2f6
 +
 +
 +#if defined(__serenity__)
 +#if defined(__serenity__)
 +
 +
-+#include <cstdlib>
-+#include <clocale>
-+#include <cwctype>
-+#include <ctype.h>
-+#include <__support/xlocale/__nop_locale_mgmt.h>
-+#include <__support/xlocale/__posix_l_fallback.h>
-+#include <__support/xlocale/__strtonum_fallback.h>
++#  include <__support/xlocale/__nop_locale_mgmt.h>
++#  include <__support/xlocale/__posix_l_fallback.h>
++#  include <__support/xlocale/__strtonum_fallback.h>
++#  include <clocale>
++#  include <cstdlib>
++#  include <ctype.h>
++#  include <cwctype>
 +
 +
 +#endif // __serenity__
 +#endif // __serenity__
 +
 +
 +#endif
 +#endif
 diff --git a/libcxx/include/locale b/libcxx/include/locale
 diff --git a/libcxx/include/locale b/libcxx/include/locale
-index 874866f69..55632f101 100644
+index 9e97eb9f3395..4bcdc13c1967 100644
 --- a/libcxx/include/locale
 --- a/libcxx/include/locale
 +++ b/libcxx/include/locale
 +++ b/libcxx/include/locale
-@@ -216,7 +216,7 @@ template <class charT> class messages_byname;
+@@ -217,7 +217,7 @@ template <class charT> class messages_byname;
  
  
  #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
  // Most unix variants have catopen.  These are the specific ones that don't.
  // Most unix variants have catopen.  These are the specific ones that don't.
@@ -115,15 +115,18 @@ index 874866f69..55632f101 100644
  #    include <nl_types.h>
  #    include <nl_types.h>
  #  endif
  #  endif
 diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h
 diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h
-index bef26ec50..fbb2899b1 100644
+index 899e124ad261..11d930bc8a3c 100644
 --- a/libcxx/src/include/config_elast.h
 --- a/libcxx/src/include/config_elast.h
 +++ b/libcxx/src/include/config_elast.h
 +++ b/libcxx/src/include/config_elast.h
 @@ -35,6 +35,8 @@
 @@ -35,6 +35,8 @@
- #define _LIBCPP_ELAST 4095
+ #  define _LIBCPP_ELAST 4095
  #elif defined(__APPLE__)
  #elif defined(__APPLE__)
  // No _LIBCPP_ELAST needed on Apple
  // No _LIBCPP_ELAST needed on Apple
 +#elif defined(__serenity__)
 +#elif defined(__serenity__)
 +// No _LIBCPP_ELAST needed on SerenityOS
 +// No _LIBCPP_ELAST needed on SerenityOS
- #elif defined(__sun__)
- #define _LIBCPP_ELAST ESTALE
  #elif defined(__MVS__)
  #elif defined(__MVS__)
+ #  define _LIBCPP_ELAST 1160
+ #elif defined(_LIBCPP_MSVCRT_LIKE)
+-- 
+2.44.0
+

+ 89 - 0
Toolchain/Patches/llvm/0006-clang-Add-fvisibility-inlines-hidden-function-templa.patch

@@ -0,0 +1,89 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Fri, 8 Sep 2023 00:42:17 +0200
+Subject: [PATCH] [clang] Add -fvisibility-inlines-hidden-function-templates
+
+---
+ clang/include/clang/Basic/LangOptions.def |  3 +++
+ clang/include/clang/Driver/Options.td     |  6 ++++++
+ clang/lib/AST/Decl.cpp                    | 18 ++++++++++++------
+ clang/lib/Driver/ToolChains/Clang.cpp     |  2 ++
+ 4 files changed, 23 insertions(+), 6 deletions(-)
+
+diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
+index 4942dcaa086e..677ad6273e3a 100644
+--- a/clang/include/clang/Basic/LangOptions.def
++++ b/clang/include/clang/Basic/LangOptions.def
+@@ -310,6 +310,9 @@ BENIGN_LANGOPT(IgnoreXCOFFVisibility, 1, 0, "All the visibility attributes that
+ BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0,
+                "hidden visibility for static local variables in inline C++ "
+                "methods when -fvisibility-inlines hidden is enabled")
++BENIGN_LANGOPT(VisibilityInlinesHiddenFunctionTemplate, 1, 0,
++               "hidden visibility for implicitly instantiated C++ function "
++               "templates when -fvisibility-inlines-hidden is enabled")
+ ENUM_LANGOPT(GlobalAllocationFunctionVisibility, VisibilityForcedKinds, 3, VisibilityForcedKinds::ForceDefault,
+              "How to apply visibility to global operator new and delete declarations")
+ LANGOPT(NewInfallible , 1, 0, "Treats throwing global C++ operator new as always returning valid memory (annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.")
+diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
+index 175bedbfb4d0..7cc661956e3a 100644
+--- a/clang/include/clang/Driver/Options.td
++++ b/clang/include/clang/Driver/Options.td
+@@ -3918,6 +3918,12 @@ defm visibility_inlines_hidden_static_local_var : BoolFOption<"visibility-inline
+   NegFlag<SetFalse, [], [ClangOption], "Disables -fvisibility-inlines-hidden-static-local-var"
+          " (this is the default on non-darwin targets)">, BothFlags<
+                  [], [ClangOption, CC1Option]>>;
++defm visibility_inlines_hidden_function_template : BoolFOption<"visibility-inlines-hidden-function-template",
++  LangOpts<"VisibilityInlinesHiddenFunctionTemplate">, DefaultFalse,
++  PosFlag<SetTrue, [], [ClangOption, CC1Option],
++          "When -fvisibility-inlines-hidden is enabled, all template functions will be given"
++          " hidden visibility by default, even if they are not declared ``inline``">,
++  NegFlag<SetFalse>>;
+ def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>,
+   HelpText<"Give global types 'default' visibility and global functions and "
+            "variables 'hidden' visibility by default">;
+diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
+index 1ee33fd7576d..b8cb7e5a494b 100644
+--- a/clang/lib/AST/Decl.cpp
++++ b/clang/lib/AST/Decl.cpp
+@@ -562,13 +562,19 @@ static bool useInlineVisibilityHidden(const NamedDecl *D) {
+     TSK = MSI->getTemplateSpecializationKind();
+   }
+ 
++  if (TSK == TSK_ExplicitInstantiationDeclaration ||
++      TSK == TSK_ExplicitInstantiationDefinition)
++    return false;
++
+   const FunctionDecl *Def = nullptr;
+-  // InlineVisibilityHidden only applies to definitions, and
+-  // isInlined() only gives meaningful answers on definitions
+-  // anyway.
+-  return TSK != TSK_ExplicitInstantiationDeclaration &&
+-    TSK != TSK_ExplicitInstantiationDefinition &&
+-    FD->hasBody(Def) && Def->isInlined() && !Def->hasAttr<GNUInlineAttr>();
++  if (!FD->hasBody(Def))
++    return false;
++
++  if (Def->hasAttr<GNUInlineAttr>())
++    return false;
++
++  return Def->isInlined() || (TSK == TSK_ImplicitInstantiation &&
++                              Opts.VisibilityInlinesHiddenFunctionTemplate);
+ }
+ 
+ template <typename T> static bool isFirstInExternCContext(T *D) {
+diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
+index aa344b3465ab..a9e2a4012fd1 100644
+--- a/clang/lib/Driver/ToolChains/Clang.cpp
++++ b/clang/lib/Driver/ToolChains/Clang.cpp
+@@ -6350,6 +6350,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
+ 
+   Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_static_local_var,
+                            options::OPT_fno_visibility_inlines_hidden_static_local_var);
++  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden_function_template,
++                           options::OPT_fno_visibility_inlines_hidden_function_template);
+ 
+   // -fvisibility-global-new-delete-hidden is a deprecated spelling of
+   // -fvisibility-global-new-delete=force-hidden.
+-- 
+2.44.0
+

+ 0 - 22
Toolchain/Patches/llvm/0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch

@@ -1,22 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Thu, 14 Apr 2022 10:20:46 +0200
-Subject: [PATCH] [compiler-rt] Build crtbegin.o/crtend.o for SerenityOS
-
----
- compiler-rt/cmake/crt-config-ix.cmake | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake
-index 066a0edbc..62c2f050f 100644
---- a/compiler-rt/cmake/crt-config-ix.cmake
-+++ b/compiler-rt/cmake/crt-config-ix.cmake
-@@ -44,7 +44,7 @@ if(NOT APPLE)
-   message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}")
- endif()
- 
--if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER)
-+if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER)
-   set(COMPILER_RT_HAS_CRT TRUE)
- else()
-   set(COMPILER_RT_HAS_CRT FALSE)

+ 0 - 25
Toolchain/Patches/llvm/0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch

@@ -1,25 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Thu, 14 Apr 2022 10:21:19 +0200
-Subject: [PATCH] [cmake] Allow undefined symbols on SerenityOS
-
-Allow undefined symbols in LLVM libraries, which is needed because only
-stubs are available for SerenityOS libraries when libc++ and libunwind
-are built.
----
- llvm/cmake/modules/HandleLLVMOptions.cmake | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
-index 6119ecdce..59d2c7539 100644
---- a/llvm/cmake/modules/HandleLLVMOptions.cmake
-+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
-@@ -226,7 +226,7 @@ endif()
- 
- # Pass -Wl,-z,defs. This makes sure all symbols are defined. Otherwise a DSO
- # build might work on ELF but fail on MachO/COFF.
--if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|FreeBSD|OpenBSD|DragonFly|AIX|OS390" OR
-+if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|FreeBSD|OpenBSD|DragonFly|AIX|OS390|SerenityOS" OR
-         WIN32 OR CYGWIN) AND
-    NOT LLVM_USE_SANITIZER)
-   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")

+ 0 - 51
Toolchain/Patches/llvm/0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch

@@ -1,51 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Daniel Bertalan <dani@danielbertalan.dev>
-Date: Mon, 18 Apr 2022 22:32:29 +0200
-Subject: [PATCH] [cmake] Support building shared libLLVM and libClang for
- SerenityOS
-
-This patch tells CMake that the --whole-archive linker option should be
-used for specifying the archives whose members will constitute these
-shared libraries.
-
-Symbol versioning is disabled, as the SerenityOS loader doesn't support
-it, and the ELF sections that store version data would just waste space.
----
- clang/tools/libclang/CMakeLists.txt  | 2 +-
- llvm/tools/llvm-shlib/CMakeLists.txt | 3 ++-
- 2 files changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt
-index 4f23065a2..f180d2229 100644
---- a/clang/tools/libclang/CMakeLists.txt
-+++ b/clang/tools/libclang/CMakeLists.txt
-@@ -97,7 +97,7 @@ if(MSVC)
-   set(LLVM_EXPORTED_SYMBOL_FILE)
- endif()
- 
--if (UNIX AND NOT APPLE)
-+if (UNIX AND NOT APPLE AND (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "SerenityOS"))
-   set(LLVM_EXPORTED_SYMBOL_FILE)
-   set(USE_VERSION_SCRIPT ${LLVM_HAVE_LINK_VERSION_SCRIPT})
- endif()
-diff --git a/llvm/tools/llvm-shlib/CMakeLists.txt b/llvm/tools/llvm-shlib/CMakeLists.txt
-index 90e290435..f72ca9646 100644
---- a/llvm/tools/llvm-shlib/CMakeLists.txt
-+++ b/llvm/tools/llvm-shlib/CMakeLists.txt
-@@ -40,6 +40,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
-      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
-      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
-      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
-+     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "SerenityOS")
-      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")) # FIXME: It should be "GNU ld for elf"
-     configure_file(
-     ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in
-@@ -47,7 +48,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
- 
-     # GNU ld doesn't resolve symbols in the version script.
-     set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive)
--    if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW)
-+    if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW AND (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "SerenityOS"))
-       # Solaris ld does not accept global: *; so there is no way to version *all* global symbols
-       set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES})
-     endif()

+ 0 - 71
Toolchain/Patches/llvm/0009-compiler-rt-llvm-Enable-profile-instrumentation-for-.patch

@@ -1,71 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Andrew Kaster <akaster@serenityos.org>
-Date: Fri, 4 Mar 2022 15:13:42 -0700
-Subject: [PATCH] [compiler-rt/llvm] Enable profile instrumentation for
- SerenityOS
-
-Treat SerenityOS the same as other *NIX platforms that behave close
-enough to linux to use the pre-canned InstrProfiling implementation.
-
-Curiously, enabling profiling for the SerenityOS target changes the ELF
-OS ABI for userspace binaries to 3, or GNU/Linux.
----
- compiler-rt/cmake/config-ix.cmake                      | 2 +-
- compiler-rt/lib/profile/InstrProfilingPlatformLinux.c  | 2 +-
- compiler-rt/lib/profile/InstrProfilingPlatformOther.c  | 2 +-
- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | 3 ++-
- 4 files changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
-index 5f51befc1..6a7e45549 100644
---- a/compiler-rt/cmake/config-ix.cmake
-+++ b/compiler-rt/cmake/config-ix.cmake
-@@ -774,7 +774,7 @@ else()
- endif()
- 
- if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
--    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
-+    OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|SerenityOS")
-   set(COMPILER_RT_HAS_PROFILE TRUE)
- else()
-   set(COMPILER_RT_HAS_PROFILE FALSE)
-diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
-index adf4132c6..1ed5bd295 100644
---- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
-+++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
-@@ -8,7 +8,7 @@
- 
- #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
-     (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
--    defined(_AIX)
-+    defined(_AIX) || defined(__serenity__)
- 
- #if !defined(_AIX)
- #include <elf.h>
-diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
-index c7b6e842c..00fdf9ee6 100644
---- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
-+++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
-@@ -8,7 +8,7 @@
- 
- #if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) &&     \
-     !defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) &&       \
--    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
-+    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && !defined(__serenity__)
- 
- #include <stdlib.h>
- #include <stdio.h>
-diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
-index c04092062..e148cff6f 100644
---- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
-+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
-@@ -829,7 +829,8 @@ static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) {
-     return false;
-   // Use linker script magic to get data/cnts/name start/end.
-   if (TT.isOSAIX() || TT.isOSLinux() || TT.isOSFreeBSD() || TT.isOSNetBSD() ||
--      TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS() || TT.isOSWindows())
-+      TT.isOSSolaris() || TT.isOSFuchsia() || TT.isPS() || TT.isOSWindows() ||
-+      TT.isOSSerenity())
-     return false;
- 
-   return true;

+ 0 - 23
Toolchain/Patches/llvm/0010-Add-SerenityOS-to-config.guess.patch

@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tim Schumacher <timschumi@gmx.de>
-Date: Wed, 10 Nov 2021 03:29:21 +0100
-Subject: [PATCH] Add SerenityOS to config.guess
-
----
- llvm/cmake/config.guess | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/llvm/cmake/config.guess b/llvm/cmake/config.guess
-index 71abbf939..f48962367 100644
---- a/llvm/cmake/config.guess
-+++ b/llvm/cmake/config.guess
-@@ -816,6 +816,9 @@ EOF
-     i*:PW*:*)
- 	echo ${UNAME_MACHINE}-pc-pw32
- 	exit ;;
-+    *:SerenityOS:*:*)
-+	echo ${UNAME_MACHINE}-pc-serenity
-+	exit ;;
-     *:Interix*:*)
- 	case ${UNAME_MACHINE} in
- 	    x86)

+ 0 - 38
Toolchain/Patches/llvm/0011-llvm-Prevent-the-use-of-POSIX-shm-on-SerenityOS.patch

@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: sin-ack <sin-ack@users.noreply.github.com>
-Date: Sat, 1 Oct 2022 20:05:52 +0000
-Subject: [PATCH] [llvm] Prevent the use of POSIX shm on SerenityOS
-
-POSIX shm is not supported by SerenityOS yet, so this causes a
-compilation error.
----
- llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp                   | 2 +-
- .../Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp     | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
-index b457c7297..5e2907f0c 100644
---- a/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
-+++ b/llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp
-@@ -215,7 +215,7 @@ SharedMemoryMapper::Create(ExecutorProcessControl &EPC, SymbolAddrs SAs) {
- 
- void SharedMemoryMapper::reserve(size_t NumBytes,
-                                  OnReservedFunction OnReserved) {
--#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
-+#if (defined(LLVM_ON_UNIX) && !(defined(__ANDROID__) || defined(__serenity__))) || defined(_WIN32)
- 
-   EPC.callSPSWrapperAsync<
-       rt::SPSExecutorSharedMemoryMapperServiceReserveSignature>(
-diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
-index 147f915f6..ca773e1ca 100644
---- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
-+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/ExecutorSharedMemoryMapperService.cpp
-@@ -47,7 +47,7 @@ static DWORD getWindowsProtectionFlags(MemProt MP) {
- 
- Expected<std::pair<ExecutorAddr, std::string>>
- ExecutorSharedMemoryMapperService::reserve(uint64_t Size) {
--#if (defined(LLVM_ON_UNIX) && !defined(__ANDROID__)) || defined(_WIN32)
-+#if (defined(LLVM_ON_UNIX) && !(defined(__ANDROID__) || defined(__serenity__))) || defined(_WIN32)
- 
- #if defined(LLVM_ON_UNIX)
- 

+ 0 - 24
Toolchain/Patches/llvm/0012-cmake-Increase-the-default-stack-size-when-running-o.patch

@@ -1,24 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Tim Schumacher <timschumi@gmx.de>
-Date: Mon, 10 Apr 2023 12:17:32 +0200
-Subject: [PATCH] cmake: Increase the default stack size when running on
- SerenityOS
-
----
- llvm/cmake/modules/HandleLLVMOptions.cmake | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
-index 59d2c7539..7c3b1ff6d 100644
---- a/llvm/cmake/modules/HandleLLVMOptions.cmake
-+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
-@@ -455,6 +455,9 @@ elseif(MINGW) # FIXME: Also cygwin?
-   if (NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-     append("-Wa,-mbig-obj" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
-   endif()
-+elseif(SERENITYOS)
-+  # SerenityOS sets a very low default stack size value, so increase it to 4MB manually.
-+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,stack-size=4194304")
- endif()
- 
- option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON)

+ 25 - 63
Toolchain/Patches/llvm/ReadMe.md

@@ -1,20 +1,6 @@
 # Patches for llvm on SerenityOS
 # Patches for llvm on SerenityOS
 
 
-## `0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch`
-
-Add support for building LLVM on SerenityOS
-
-Adds SerenityOS `#ifdef`s for platform-specific code.
-
-We stub out wait4, as SerenityOS doesn't support querying a child
-process's resource usage information.
-
-## `0002-Triple-Add-triple-for-SerenityOS.patch`
-
-Add triple for SerenityOS
-
-
-## `0003-Driver-Add-support-for-SerenityOS.patch`
+## `0001-clang-Add-support-for-SerenityOS.patch`
 
 
 Add support for SerenityOS
 Add support for SerenityOS
 
 
@@ -23,44 +9,21 @@ This makes the compiler look for libraries and headers in the right
 places, and enables some security mitigations like stack-smashing
 places, and enables some security mitigations like stack-smashing
 protection and position-independent code by default.
 protection and position-independent code by default.
 
 
-## `0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch`
-
-Default to -ftls-model=initial-exec on SerenityOS
-
-This is a hack to make Clang use the initial-exec TLS model instead of
-the default local-exec when building code for Serenity.
+## `0002-llvm-Add-support-for-building-LLVM-on-SerenityOS.patch`
 
 
-This patch should be removed when we implement proper TLS support.
-
-## `0005-libc-Add-support-for-SerenityOS.patch`
-
-Add support for SerenityOS
-
-This commit teaches libc++ about what features are available in our
-LibC, namely:
-* We do not have locale support, so no-op shims should be used in place
-  of the C locale API.
-* The number of errno constants defined by us is given by the value of
-  the `ELAST` macro.
-* Multithreading is implemented though the pthread library.
-* Use libc++'s builtin character type table instead of the one provided
-  by LibC as there's a lot of extra porting work to convince the rest of
-  locale.cpp to use our character type table properly.
-
-## `0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch`
-
-Build crtbegin.o/crtend.o for SerenityOS
+Add support for building LLVM on SerenityOS
 
 
+Adds SerenityOS `#ifdef`s for platform-specific code.
 
 
-## `0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch`
+We stub out wait4, as SerenityOS doesn't support querying a child
+process's resource usage information.
 
 
-Allow undefined symbols on SerenityOS
+POSIX shm is not supported by SerenityOS yet, so disable it in Orc.
 
 
-Allow undefined symbols in LLVM libraries, which is needed because only
-stubs are available for SerenityOS libraries when libc++ and libunwind
-are built.
+Serenity gives each thread a default of 1MiB of stack. Increase the
+default stack size for llvm applications when running on SerenityOS.
 
 
-## `0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch`
+## `0003-tools-Support-building-shared-libLLVM-and-libClang-f.patch`
 
 
 Support building shared libLLVM and libClang for SerenityOS
 Support building shared libLLVM and libClang for SerenityOS
 
 
@@ -71,30 +34,29 @@ shared libraries.
 Symbol versioning is disabled, as the SerenityOS loader doesn't support
 Symbol versioning is disabled, as the SerenityOS loader doesn't support
 it, and the ELF sections that store version data would just waste space.
 it, and the ELF sections that store version data would just waste space.
 
 
-## `0009-compiler-rt-llvm-Enable-profile-instrumentation-for-.patch`
+## `0004-compiler-rt-Enable-profile-instrumentation-for-Seren.patch`
 
 
 Enable profile instrumentation for SerenityOS
 Enable profile instrumentation for SerenityOS
 
 
 Treat SerenityOS the same as other *NIX platforms that behave close
 Treat SerenityOS the same as other *NIX platforms that behave close
 enough to linux to use the pre-canned InstrProfiling implementation.
 enough to linux to use the pre-canned InstrProfiling implementation.
 
 
-Curiously, enabling profiling for the SerenityOS target changes the ELF
-OS ABI for userspace binaries to 3, or GNU/Linux.
-
-## `0010-Add-SerenityOS-to-config.guess.patch`
-
-Add SerenityOS to config.guess
-
-
-## `0011-llvm-Prevent-the-use-of-POSIX-shm-on-SerenityOS.patch`
+## `0005-libcxx-Add-support-for-SerenityOS.patch`
 
 
-Prevent the use of POSIX shm on SerenityOS
-
-POSIX shm is not supported by SerenityOS yet, so this causes a
-compilation error.
+Add support for SerenityOS
 
 
-## `0012-cmake-Increase-the-default-stack-size-when-running-o.patch`
+This commit teaches libc++ about what features are available in our
+LibC, namely:
+* We do not have locale support, so no-op shims should be used in place
+  of the C locale API.
+* The number of errno constants defined by us is given by the value of
+  the `ELAST` macro.
+* Multithreading is implemented though the pthread library.
+* Use libc++'s builtin character type table instead of the one provided
+  by LibC as there's a lot of extra porting work to convince the rest of
+  locale.cpp to use our character type table properly.
 
 
-cmake: Increase the default stack size when running on SerenityOS
+## `0006-clang-Add-fvisibility-inlines-hidden-function-templa.patch`
 
 
+Add -fvisibility-inlines-hidden-function-templates
 
 

+ 25 - 11
Toolchain/Stubs/README.md

@@ -1,21 +1,35 @@
 # Library stubs
 # Library stubs
 
 
-This directory contains stubs for SerenityOS libraries (LibC, LibM, LibDl, LibPthread)
-that are referenced from the LLVM runtime libraries. These are needed by the linker
-in order to add the required `DT_NEEDED` entries.
+This directory contains stubs for SerenityOS's LibC that are referenced from the LLVM runtime
+libraries. These are needed by the linker in order to add the required `DT_NEEDED` entries and to
+not emit errors regarding undefiend libc symbols. Additionally, it provides fake empty libunwind.so
+and libc++.so for CMake configuration checks to succeed when bootstrapping the OS.
 
 
 ## Do these need to be updated?
 ## Do these need to be updated?
 
 
-Generally, no. LLVM does not use the header files to decide which functionality it can
-use. After adding a new function to a header, you don't have to worry about LLVM
-toolchain builds failing because the symbol is not present in the stubs.
+Most likely no but it depends. Either way, if you are reading this, you are probably qualified
+enough to figure out if a failing LLVM toolchain configuration or build is caused by an out-of-date
+LibC stub.
 
 
-## How to generate these?
+## How to generate LibC stub?
 
 
-First, you need to have a working SerenityOS installation that's been built by the
-Clang toolchain. Then, using the `llvm-ifs` tool, these libraries need to be converted
-into a stripped-down stub form. To do that, run the following command:
+First, you need to compile the LLVM toolchain and the SerenityOS's LibC. This will be a bit awkward
+(see discussion at https://github.com/SerenityOS/serenity/pull/23960) until (unless) we solve the
+dependency cycle between LibC and libunwind. Then, using the `llvm-ifs` tool,
+`Userland/Libraries/LibC/libc.so` can be converted into a stripped-down stub form. To do that, run
+the following command:
 
 
 ```sh
 ```sh
-Toolchain/Local/clang/bin/llvm-ifs --output-format=ELF --output=<path-to-stub> <path-to-original>
+Toolchain/Local/clang/bin/llvm-ifs --output-elf=<path-to-stub> <path-to-original>
+```
+
+## How to generate `empty.so`?
+
+Simple, my friend:
+
+```sh
+touch empty.cpp
+Toolchain/Local/clang/bin/clang++ --target={arch}-pc-serenity -nostdlib -shared empty.cpp -o empty.so
+# And optionally,
+Toolchain/Local/clang/bin/llvm-strip empty.so
 ```
 ```

BIN
Toolchain/Stubs/aarch64/empty.so


+ 1 - 0
Toolchain/Stubs/aarch64/libc++.so

@@ -0,0 +1 @@
+empty.so

BIN
Toolchain/Stubs/aarch64/libc.so


+ 1 - 0
Toolchain/Stubs/aarch64/libunwind.so

@@ -0,0 +1 @@
+empty.so

BIN
Toolchain/Stubs/i686clang/libc.so


BIN
Toolchain/Stubs/riscv64/empty.so


+ 1 - 0
Toolchain/Stubs/riscv64/libc++.so

@@ -0,0 +1 @@
+empty.so

BIN
Toolchain/Stubs/riscv64/libc.so


+ 1 - 0
Toolchain/Stubs/riscv64/libunwind.so

@@ -0,0 +1 @@
+empty.so

BIN
Toolchain/Stubs/x86_64/empty.so


+ 1 - 0
Toolchain/Stubs/x86_64/libc++.so

@@ -0,0 +1 @@
+empty.so

BIN
Toolchain/Stubs/x86_64/libc.so


+ 1 - 0
Toolchain/Stubs/x86_64/libunwind.so

@@ -0,0 +1 @@
+empty.so

BIN
Toolchain/Stubs/x86_64clang/libc.so