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
 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")
     set(EXPECTED_COMPILER_VERSION "${GCC_VERSION}")
 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/                                                            |
 | [`links`](links/)                                   | Links web browser                                               | 2.29                      | http://links.twibright.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/                                               |
 | [`lrzip`](lrzip/)                                   | lrzip                                                           | 0.651                     | https://github.com/ckolivas/lrzip                                              |
 | [`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
 port='llvm'
 useconfigure='true'
-version='16.0.6'
+version='18.1.3'
 workdir="llvm-project-${version}.src"
 configopts=(
     "-DCMAKE_TOOLCHAIN_FILE=${SERENITY_BUILD_DIR}/CMakeToolchain.txt"
 )
 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=(
     "ncurses"
@@ -54,7 +54,7 @@ configure() {
         -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
         -DLLVM_OCAML_INSTALL_PATH="${SERENITY_INSTALL_ROOT}/usr/local/ocaml" \
         -DLLVM_PTHREAD_LIB=pthread \
-        -DLLVM_TARGETS_TO_BUILD=X86
+        -DLLVM_TARGETS_TO_BUILD="X86;AArch64;RISCV"
 }
 
 build() {

+ 5 - 31
Toolchain/BuildClang.sh

@@ -68,8 +68,8 @@ echo PREFIX is "$PREFIX"
 
 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_PKG="$LLVM_NAME.tar.xz"
 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
 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 ===
 
 rm -rf "$PREFIX"
@@ -296,6 +284,9 @@ pushd "$DIR/Build/clang"
             -DSERENITY_x86_64-pc-serenity_SYSROOT="$BUILD/x86_64clang/Root" \
             -DSERENITY_aarch64-pc-serenity_SYSROOT="$BUILD/aarch64clang/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" \
             -DSERENITY_MODULE_PATH="$DIR/CMake" \
             -C "$DIR/CMake/LLVMConfig.cmake" \
@@ -308,23 +299,6 @@ pushd "$DIR/Build/clang"
         buildstep_ninja "llvm/build" ninja -j "$MAKEJOBS"
         buildstep_ninja "llvm/install" ninja install/strip
     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
 
 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
 
+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
 # That has the Platform/SerenityOS.cmake definition
 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_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_BINDINGS OFF CACHE BOOL "")
@@ -24,13 +29,13 @@ set(LLVM_INSTALL_BINUTILS_SYMLINKS 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)
     list(APPEND targets "${target}")
 
     set(RUNTIMES_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "")
     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.
+    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_CXX_FLAGS ${compiler_flags} CACHE STRING "")
     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}_CMAKE_SYSTEM_NAME SerenityOS 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()
 
 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: Daniel Bertalan <dani@danielbertalan.dev>
 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
 LibC, namely:
@@ -24,23 +24,23 @@ LibC, namely:
  create mode 100644 libcxx/include/__support/serenity/xlocale.h
 
 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
 +++ b/libcxx/include/CMakeLists.txt
-@@ -549,6 +549,7 @@ set(files
+@@ -675,6 +675,7 @@ set(files
    __support/musl/xlocale.h
    __support/newlib/xlocale.h
    __support/openbsd/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
-index 108153883..e4434809c 100644
+index 8b2eaf69d170..53a09f46eaf7 100644
 --- a/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(_AIX) ||                                                                                               \
 -        defined(__EMSCRIPTEN__)
@@ -49,7 +49,7 @@ index 108153883..e4434809c 100644
  // clang-format on
  #      define _LIBCPP_HAS_THREAD_API_PTHREAD
  #    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
  
  #  if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) ||                        \
@@ -59,21 +59,21 @@ index 108153883..e4434809c 100644
  #  endif
  
 diff --git a/libcxx/include/__locale b/libcxx/include/__locale
-index e0ffa0ca0..33e994abe 100644
+index 3ba7ac18b0b3..9a68dade7fef 100644
 --- a/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)
- # include <__support/musl/xlocale.h>
+ #  include <__support/musl/xlocale.h>
 +#elif defined(__serenity__)
-+# include <__support/serenity/xlocale.h>
++#  include <__support/serenity/xlocale.h>
  #endif
  
  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 diff --git a/libcxx/include/__support/serenity/xlocale.h b/libcxx/include/__support/serenity/xlocale.h
 new file mode 100644
-index 000000000..0f939d2f6
+index 000000000000..67c85bf641e2
 --- /dev/null
 +++ b/libcxx/include/__support/serenity/xlocale.h
 @@ -0,0 +1,24 @@
@@ -90,22 +90,22 @@ index 000000000..0f939d2f6
 +
 +#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
 diff --git a/libcxx/include/locale b/libcxx/include/locale
-index 874866f69..55632f101 100644
+index 9e97eb9f3395..4bcdc13c1967 100644
 --- a/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__))
  // 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>
  #  endif
 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
 +++ b/libcxx/src/include/config_elast.h
 @@ -35,6 +35,8 @@
- #define _LIBCPP_ELAST 4095
+ #  define _LIBCPP_ELAST 4095
  #elif defined(__APPLE__)
  // No _LIBCPP_ELAST needed on Apple
 +#elif defined(__serenity__)
 +// No _LIBCPP_ELAST needed on SerenityOS
- #elif defined(__sun__)
- #define _LIBCPP_ELAST ESTALE
  #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
 
-## `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
 
@@ -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
 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
 
@@ -71,30 +34,29 @@ 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.
 
-## `0009-compiler-rt-llvm-Enable-profile-instrumentation-for-.patch`
+## `0004-compiler-rt-Enable-profile-instrumentation-for-Seren.patch`
 
 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.
-
-## `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
 
-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?
 
-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
-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