summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rwxr-xr-xMeta/build-root-filesystem.sh2
-rw-r--r--Ports/AvailablePorts.md2
-rwxr-xr-xPorts/llvm/package.sh64
l---------Ports/llvm/patches1
-rw-r--r--Ports/llvm/patches/ReadMe.md45
-rw-r--r--Ports/llvm/patches/insert-ifdef-serenity.patch113
l---------Ports/llvm/patches/llvm-backport-objcopy-update-section.patch1
-rw-r--r--Ports/llvm/patches/remove-version-script.patch35
l---------Ports/llvm/patches/toolchain.patch1
-rwxr-xr-xToolchain/BuildClang.sh76
-rw-r--r--Toolchain/CMake/LLVMConfig.cmake4
-rw-r--r--Toolchain/Patches/llvm-backport-objcopy-update-section.patch440
-rw-r--r--Toolchain/Patches/llvm/0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch81
-rw-r--r--Toolchain/Patches/llvm/0002-Triple-Add-triple-for-SerenityOS.patch59
-rw-r--r--Toolchain/Patches/llvm/0003-Driver-Add-support-for-SerenityOS.patch (renamed from Toolchain/Patches/llvm.patch)369
-rw-r--r--Toolchain/Patches/llvm/0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch36
-rw-r--r--Toolchain/Patches/llvm/0005-libc-Add-support-for-SerenityOS.patch153
-rw-r--r--Toolchain/Patches/llvm/0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch25
-rw-r--r--Toolchain/Patches/llvm/0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch28
-rw-r--r--Toolchain/Patches/llvm/0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch54
-rw-r--r--Toolchain/Patches/llvm/ReadMe.md78
22 files changed, 663 insertions, 1006 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 867c516896..4f8e6694fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@ endif()
# Check for toolchain mismatch, user might need to rebuild toolchain
set(GCC_VERSION "11.2.0")
-set(LLVM_VERSION "13.0.0")
+set(LLVM_VERSION "14.0.1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(EXPECTED_COMPILER_VERSION "${GCC_VERSION}")
else()
diff --git a/Meta/build-root-filesystem.sh b/Meta/build-root-filesystem.sh
index 01ae733145..0e44c59b32 100755
--- a/Meta/build-root-filesystem.sh
+++ b/Meta/build-root-filesystem.sh
@@ -42,7 +42,7 @@ else
fi
SERENITY_ARCH="${SERENITY_ARCH:-i686}"
-LLVM_VERSION="${LLVM_VERSION:-13.0.0}"
+LLVM_VERSION="${LLVM_VERSION:-14.0.1}"
if [ "$SERENITY_TOOLCHAIN" = "Clang" ]; then
TOOLCHAIN_DIR="$SERENITY_SOURCE_DIR"/Toolchain/Local/clang/
diff --git a/Ports/AvailablePorts.md b/Ports/AvailablePorts.md
index 921801249b..2589863c67 100644
--- a/Ports/AvailablePorts.md
+++ b/Ports/AvailablePorts.md
@@ -121,7 +121,7 @@ Please make sure to keep this list up to date when adding and updating ports. :^
| [`libyaml`](libyaml/) | libyaml | 0.2.5 | https://pyyaml.org/wiki/LibYAML |
| [`libzip`](libzip/) | libzip | 1.7.3 | https://libzip.org/ |
| [`links`](links/) | Links web browser | 2.25 | http://links.twibright.com/ |
-| [`llvm`](llvm/) | LLVM | 13.0.0 | https://llvm.org/ |
+| [`llvm`](llvm/) | LLVM | 14.0.1 | https://llvm.org/ |
| [`lua`](lua/) | Lua | 5.3.6 | https://www.lua.org/ |
| [`luajit`](luajit/) | LuaJIT | 2.1.0-beta3 | https://luajit.org/luajit.html |
| [`luarocks`](luarocks/) | LuaRocks | 3.8.0 | https://luarocks.org/ |
diff --git a/Ports/llvm/package.sh b/Ports/llvm/package.sh
index 298a828c42..6f7e8e768a 100755
--- a/Ports/llvm/package.sh
+++ b/Ports/llvm/package.sh
@@ -1,54 +1,52 @@
#!/usr/bin/env -S bash ../.port_include.sh
port=llvm
useconfigure=true
-version=13.0.0
-workdir=llvm-project-llvmorg-${version}
+version=14.0.1
+workdir=llvm-project-${version}.src
configopts=("-DCMAKE_TOOLCHAIN_FILE=${SERENITY_BUILD_DIR}/CMakeToolchain.txt")
-files="https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-${version}.zip llvm.zip 333a4e053fb543d9efb8dc68126d9e7a948ecb246985f2804a0ecbc5ccdb9d08"
+files="https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-project-${version}.src.tar.xz llvm-project-${version}.src.tar.xz 1a3c2e57916c5a70153aaf0a0e6f1230d6368b9e0f4d04dcb9e039a31b1cd4e6"
auth_type=sha256
depends=("ncurses" "zlib")
-pre_patch() {
+configure() {
+ # The cross compilers will be picked up from the CMake toolchain file.
+ # CC/CXX must point to the host compiler to let it build host tools (tblgen).
host_env
- mkdir -p llvm-host
- cmake ${workdir}/llvm \
- -B llvm-host \
- -DLLVM_ENABLE_PROJECTS=clang
- make -C llvm-host -j $(nproc) llvm-tblgen clang-tblgen
- target_env
-}
-configure() {
if [ "$SERENITY_TOOLCHAIN" = "Clang" ]; then
stdlib=""
unwindlib=""
+ exclude_atomic_builtin="OFF"
else
stdlib="libstdc++"
unwindlib="libgcc"
+ # Atomic builtins can't be cross-compiled with GCC. Use the libatomic port
+ # if the program you're building has references to symbols like __atomic_load.
+ exclude_atomic_builtin="ON"
fi
+
mkdir -p llvm-build
cmake ${workdir}/llvm \
- -G Ninja \
- -B llvm-build "${configopts[@]}" \
- -DCMAKE_BUILD_TYPE=MinSizeRel \
- -DCMAKE_FIND_ROOT_PATH="$SERENITY_BUILD_DIR"/Root \
- -DCLANG_DEFAULT_CXX_STDLIB=$stdlib \
- -DCLANG_DEFAULT_UNWINDLIB=$unwindlib \
- -DCLANG_TABLEGEN=$(pwd)/llvm-host/bin/clang-tblgen \
- -DCOMPILER_RT_BUILD_CRT=ON \
- -DCOMPILER_RT_BUILD_ORC=OFF \
- -DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=OFF \
- -DCOMPILER_RT_OS_DIR=serenity \
- -DHAVE_LIBRT=OFF \
- -DLLVM_DEFAULT_TARGET_TRIPLE=$SERENITY_ARCH-pc-serenity \
- -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt" \
- -DLLVM_HAVE_LIBXAR=OFF \
- -DLLVM_INCLUDE_BENCHMARKS=OFF \
- -DLLVM_INCLUDE_TESTS=OFF \
- -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
- -DLLVM_PTHREAD_LIB=pthread \
- -DLLVM_TABLEGEN=$(pwd)/llvm-host/bin/llvm-tblgen \
- -DLLVM_TARGETS_TO_BUILD=X86
+ -G Ninja \
+ -B llvm-build "${configopts[@]}" \
+ -DCMAKE_BUILD_TYPE=MinSizeRel \
+ -DCMAKE_FIND_ROOT_PATH="$SERENITY_BUILD_DIR"/Root \
+ -DCROSS_TOOLCHAIN_FLAGS_NATIVE="-DCMAKE_C_COMPILER=$CC;-DCMAKE_CXX_COMPILER=$CXX" \
+ -DCLANG_DEFAULT_CXX_STDLIB=$stdlib \
+ -DCLANG_DEFAULT_UNWINDLIB=$unwindlib \
+ -DCOMPILER_RT_BUILD_CRT=ON \
+ -DCOMPILER_RT_BUILD_ORC=OFF \
+ -DCOMPILER_RT_EXCLUDE_ATOMIC_BUILTIN=$exclude_atomic_builtin \
+ -DCOMPILER_RT_OS_DIR=serenity \
+ -DHAVE_LIBRT=OFF \
+ -DLLVM_DEFAULT_TARGET_TRIPLE=$SERENITY_ARCH-pc-serenity \
+ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt" \
+ -DLLVM_HAVE_LIBXAR=OFF \
+ -DLLVM_INCLUDE_BENCHMARKS=OFF \
+ -DLLVM_INCLUDE_TESTS=OFF \
+ -DLLVM_INSTALL_TOOLCHAIN_ONLY=ON \
+ -DLLVM_PTHREAD_LIB=pthread \
+ -DLLVM_TARGETS_TO_BUILD=X86
}
build() {
diff --git a/Ports/llvm/patches b/Ports/llvm/patches
new file mode 120000
index 0000000000..12796d33b8
--- /dev/null
+++ b/Ports/llvm/patches
@@ -0,0 +1 @@
+../../Toolchain/Patches/llvm \ No newline at end of file
diff --git a/Ports/llvm/patches/ReadMe.md b/Ports/llvm/patches/ReadMe.md
deleted file mode 100644
index 815e5a3336..0000000000
--- a/Ports/llvm/patches/ReadMe.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Patches for LLVM on SerenityOS
-
-## `insert-ifdef-serenity.patch`
-
-This patch adds several defines in order to omit things not supported by SerenityOS.
-
-### Status
-- [ ] Local?
-- [ ] Should be merged to upstream?
-- [X] Resolves issue(s) with our side of things
-- [x] Hack
-
-## `remove-version-script.patch`
-
-Instructs the linker to not build LLVM shared libraries (`libclang.so`, `libLTO.so`, etc.) with
-symbol versioning, which our dynamic linker does not support.
-
-### Status
-- [ ] Local?
-- [x] Should be merged to upstream?
-- [X] Resolves issue(s) with our side of things
-- [ ] Hack
-
-## `toolchain.patch`
-
-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 building position-independent executables by default.
-
-### Status
-- [ ] Local?
-- [x] Should be merged to upstream?
-- [ ] Resolves issue(s) with our side of things
-- [ ] Hack
-
-## `llvm-backport-objcopy-update-section.patch`
-
-Backports support for `llvm-objcopy --update-section` used by our toolchain from reviews.llvm.org/D112116.
-
-### Status
-- [ ] Local?
-- [ ] Should be merged to upstream?
-- [ ] Resolves issues(s) with our side of things
-- [ ] Hack
-
diff --git a/Ports/llvm/patches/insert-ifdef-serenity.patch b/Ports/llvm/patches/insert-ifdef-serenity.patch
deleted file mode 100644
index e1b16686d7..0000000000
--- a/Ports/llvm/patches/insert-ifdef-serenity.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
-index c37b3a546..e51badb34 100644
---- a/llvm/lib/Support/Unix/Path.inc
-+++ b/llvm/lib/Support/Unix/Path.inc
-@@ -109,7 +109,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
-@@ -531,7 +531,7 @@ static bool is_local_impl(struct STATVFS &Vfs) {
-
- // vmount entry not found; "remote" is the conservative answer.
- return false;
--#elif defined(__MVS__)
-+#elif defined(__MVS__) || defined(__serenity__)
- // The file system can have an arbitrary structure on z/OS; must go with the
- // conservative answer.
- return false;
-diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
-index be59bb023..ff8931308 100644
---- a/llvm/lib/Support/Unix/Program.inc
-+++ b/llvm/lib/Support/Unix/Program.inc
-@@ -335,7 +335,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);
-@@ -344,7 +344,7 @@ static pid_t (wait4)(pid_t pid, int *status, int options, struct rusage *usage);
- } // namespace sys
- } // namespace llvm
-
--#ifdef _AIX
-+#if defined(_AIX) || defined(__serenity__)
- #ifndef _ALL_SOURCE
- extern "C" pid_t (wait4)(pid_t pid, int *status, int options,
- struct rusage *usage);
-@@ -357,7 +357,7 @@ pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
-
- // AIX wait4 does not work well with WNOHANG.
- if (!(options & WNOHANG))
-- return ::wait4(pid, status, options, usage);
-+ return ::waitpid(pid, status, options);
-
- // For WNOHANG, we use waitid (which supports WNOWAIT) until the child process
- // has terminated.
-@@ -374,7 +374,7 @@ pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
- // The child has already terminated, so a blocking wait on it is okay in the
- // absence of indiscriminate `wait` calls from the current process (which
- // would cause the call here to fail with ECHILD).
-- return ::wait4(pid, status, options & ~WNOHANG, usage);
-+ return ::waitpid(pid, status, options & ~WNOHANG);
- }
- #endif
-
-@@ -534,10 +534,10 @@ llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
-
- bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program,
- ArrayRef<StringRef> Args) {
-- static long ArgMax = sysconf(_SC_ARG_MAX);
-+ static long ArgMax = 4096;
- // POSIX requires that _POSIX_ARG_MAX is 4096, which is the lowest possible
- // value for ARG_MAX on a POSIX compliant system.
-- static long ArgMin = _POSIX_ARG_MAX;
-+ static long ArgMin = 4096;
-
- // This the same baseline used by xargs.
- long EffectiveArgMax = 128 * 1024;
-diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
-index 7f197a50c..03bf029db 100644
---- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
-+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
-@@ -50,7 +50,7 @@ void printErrorAndExit(Twine ErrMsg) {
- }
-
- int openListener(std::string Host, std::string PortStr) {
--#ifndef LLVM_ON_UNIX
-+#if !defined(LLVM_ON_UNIX) || defined(__serenity__)
- // FIXME: Add TCP support for Windows.
- printErrorAndExit("listen option not supported");
- return 0;
-diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
-index 8bd384ec7..a28e938ec 100644
---- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
-+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
-@@ -770,7 +770,7 @@ static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) {
-
- Expected<std::unique_ptr<ExecutorProcessControl>>
- LLVMJITLinkRemoteExecutorProcessControl::ConnectToExecutor() {
--#ifndef LLVM_ON_UNIX
-+#if !defined(LLVM_ON_UNIX) || defined(__serenity__)
- // FIXME: Add TCP support for Windows.
- return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +
- " not supported on non-unix platforms",
-diff -ruN llvm-orig/llvm-project-llvmorg-12.0.0/llvm/include/llvm/Support/SwapByteOrder.h llvm-project-llvmorg-12.0.0/llvm/include/llvm/Support/SwapByteOrder.h
---- llvm-orig/llvm-project-llvmorg-12.0.0/llvm/include/llvm/Support/SwapByteOrder.h 2021-04-06 19:38:18.000000000 +0300
-+++ llvm-project-llvmorg-12.0.0/llvm/include/llvm/Support/SwapByteOrder.h 2021-06-09 16:00:20.111549941 +0300
-@@ -22,7 +22,7 @@
- #endif
-
- #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/Ports/llvm/patches/llvm-backport-objcopy-update-section.patch b/Ports/llvm/patches/llvm-backport-objcopy-update-section.patch
deleted file mode 120000
index bba9bce43a..0000000000
--- a/Ports/llvm/patches/llvm-backport-objcopy-update-section.patch
+++ /dev/null
@@ -1 +0,0 @@
-../../../Toolchain/Patches/llvm-backport-objcopy-update-section.patch \ No newline at end of file
diff --git a/Ports/llvm/patches/remove-version-script.patch b/Ports/llvm/patches/remove-version-script.patch
deleted file mode 100644
index 99954ee959..0000000000
--- a/Ports/llvm/patches/remove-version-script.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-diff --git a/clang/tools/libclang/CMakeLists.txt b/clang/tools/libclang/CMakeLists.txt
-index bf88dca0a..dfac32b16 100644
---- a/clang/tools/libclang/CMakeLists.txt
-+++ b/clang/tools/libclang/CMakeLists.txt
-@@ -80,7 +80,7 @@ if(MSVC)
- set(LLVM_EXPORTED_SYMBOL_FILE)
- endif()
-
--if (UNIX AND NOT APPLE)
-+if (UNIX AND NOT APPLE AND NOT 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 76b9a25cb..808838926 100644
---- a/llvm/tools/llvm-shlib/CMakeLists.txt
-+++ b/llvm/tools/llvm-shlib/CMakeLists.txt
-@@ -33,7 +33,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
- add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${INSTALL_WITH_TOOLCHAIN} ${SOURCES})
-
- list(REMOVE_DUPLICATES LIB_NAMES)
-- if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR (HAIKU)
-+ if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR (HAIKU) OR (SERENITYOS)
- OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
- OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU")
- OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
-@@ -46,7 +46,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()
diff --git a/Ports/llvm/patches/toolchain.patch b/Ports/llvm/patches/toolchain.patch
deleted file mode 120000
index 20ae89f0f3..0000000000
--- a/Ports/llvm/patches/toolchain.patch
+++ /dev/null
@@ -1 +0,0 @@
-../../../Toolchain/Patches/llvm.patch \ No newline at end of file
diff --git a/Toolchain/BuildClang.sh b/Toolchain/BuildClang.sh
index da940b9f43..77c0163486 100755
--- a/Toolchain/BuildClang.sh
+++ b/Toolchain/BuildClang.sh
@@ -70,8 +70,8 @@ echo PREFIX is "$PREFIX"
mkdir -p "$DIR/Tarballs"
-LLVM_VERSION="13.0.0"
-LLVM_MD5SUM="bfc5191cbe87954952d25c6884596ccb"
+LLVM_VERSION="14.0.1"
+LLVM_MD5SUM="47a50c31659488a6ae562475b41d2c32"
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"
@@ -142,6 +142,25 @@ else
buildstep dependencies echo "LLD not found. Using the default linker."
fi
+buildstep setup echo "Determining if LLVM should be built with -march=native..."
+if [ "$ci" = "1" ]; then
+ # The toolchain cache is shared among all runners, which might have different CPUs.
+ buildstep setup echo "On a CI runner. Using the default compiler settings."
+elif [ -z "${CFLAGS+x}" ] && [ -z "${CXXFLAGS+x}" ]; then
+ if ${CXX:-c++} -o /dev/null -march=native -xc - >/dev/null 2>/dev/null << 'PROGRAM'
+int main() {}
+PROGRAM
+ then
+ export CFLAGS="-march=native"
+ export CXXFLAGS="-march=native"
+ buildstep setup echo "Using -march=native for compiling LLVM."
+ else
+ buildstep setup echo "-march=native is not supported by the compiler. Using the default settings."
+ fi
+else
+ buildstep setup echo "Using user-provided CFLAGS/CXXFLAGS."
+fi
+
# === CHECK CACHE AND REUSE ===
pushd "$DIR"
@@ -195,28 +214,35 @@ pushd "$DIR/Tarballs"
echo "Skipped downloading LLVM"
fi
- if [ -d "$LLVM_NAME" ]; then
- # Drop the previously patched extracted dir
- rm -rf "${LLVM_NAME}"
- # Also drop the build dir
+ patch_md5="$($MD5SUM "$DIR"/Patches/llvm/*.patch)"
+
+ if [ ! -d "$LLVM_NAME" ] || [ "$(cat $LLVM_NAME/.patch.applied)" != "$patch_md5" ]; then
+ if [ -d "$LLVM_NAME" ]; then
+ # Drop the previously patched extracted dir
+ rm -rf "${LLVM_NAME}"
+ fi
+
rm -rf "$DIR/Build/clang"
+
+ echo "Extracting LLVM..."
+ tar -xJf "$LLVM_PKG"
+
+ pushd "$LLVM_NAME"
+ if [ "$dev" = "1" ]; then
+ git init > /dev/null
+ git add . > /dev/null
+ git commit -am "BASE" > /dev/null
+ git am "$DIR"/Patches/llvm/*.patch > /dev/null
+ else
+ for patch in "$DIR"/Patches/llvm/*.patch; do
+ patch -p1 < "$patch" > /dev/null
+ done
+ fi
+ echo "$patch_md5" > .patch.applied
+ popd
+ else
+ echo "Using existing LLVM source directory"
fi
- echo "Extracting LLVM..."
- tar -xJf "$LLVM_PKG"
-
- pushd "$LLVM_NAME"
- if [ "$dev" = "1" ]; then
- git init > /dev/null
- git add . > /dev/null
- git commit -am "BASE" > /dev/null
- git am "$DIR"/Patches/llvm-backport-objcopy-update-section.patch > /dev/null
- git apply "$DIR"/Patches/llvm.patch > /dev/null
- else
- patch -p1 < "$DIR/Patches/llvm.patch" > /dev/null
- patch -p1 < "$DIR/Patches/llvm-backport-objcopy-update-section.patch" > /dev/null
- fi
- $MD5SUM "$DIR/Patches/llvm.patch" "$DIR/Patches/llvm-backport-objcopy-update-section.patch" > .patch.applied
- popd
popd
# === COPY HEADERS ===
@@ -273,7 +299,7 @@ pushd "$DIR/Build/clang"
${ci:+"-DLLVM_CCACHE_MAXSIZE=$LLVM_CCACHE_MAXSIZE"}
buildstep_ninja "llvm/build" ninja -j "$MAKEJOBS"
- buildstep "llvm/install" ninja install/strip
+ buildstep_ninja "llvm/install" ninja install/strip
popd
for arch in $ARCHS; do
@@ -288,8 +314,8 @@ pushd "$DIR/Build/clang"
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-C "$DIR/CMake/LLVMRuntimesConfig.cmake"
- buildstep "runtimes/$arch/build" ninja -j "$MAKEJOBS"
- buildstep "runtimes/$arch/install" ninja install
+ buildstep_ninja "runtimes/$arch/build" ninja -j "$MAKEJOBS"
+ buildstep_ninja "runtimes/$arch/install" ninja install
popd
done
popd
diff --git a/Toolchain/CMake/LLVMConfig.cmake b/Toolchain/CMake/LLVMConfig.cmake
index 133b7b479c..e408bd3f03 100644
--- a/Toolchain/CMake/LLVMConfig.cmake
+++ b/Toolchain/CMake/LLVMConfig.cmake
@@ -30,6 +30,7 @@ foreach(target i686-pc-serenity;x86_64-pc-serenity;aarch64-pc-serenity)
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(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 "")
@@ -44,6 +45,9 @@ foreach(target i686-pc-serenity;x86_64-pc-serenity;aarch64-pc-serenity)
set(BUILTINS_${target}_CMAKE_BUILD_TYPE Release CACHE STRING "")
set(BUILTINS_${target}_CMAKE_SYSROOT ${SERENITY_${target}_SYSROOT} CACHE PATH "")
+ # Explicitly set these so that host CFLAGS/CXXFLAGS don't get passed to the cross compiler.
+ set(BUILTINS_${target}_CMAKE_C_FLAGS "" CACHE STRING "")
+ set(BUILTINS_${target}_CMAKE_CXX_FLAGS "" CACHE STRING "")
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 "")
diff --git a/Toolchain/Patches/llvm-backport-objcopy-update-section.patch b/Toolchain/Patches/llvm-backport-objcopy-update-section.patch
deleted file mode 100644
index 8b0f3aa38d..0000000000
--- a/Toolchain/Patches/llvm-backport-objcopy-update-section.patch
+++ /dev/null
@@ -1,440 +0,0 @@
-From 140a4569a033b133fc2dc1787ae83d505e03b982 Mon Sep 17 00:00:00 2001
-From: Leonard Chan <leonardchan@google.com>
-Date: Wed, 20 Oct 2021 13:03:49 -0700
-Subject: [PATCH] Add --update-section
-
-This is another attempt at D59351 which attempted to add --update-section, but
-with some heuristics for adjusting segment/section offsets/sizes in the event
-the data copied into the section is larger than the original size of the section.
-We are opting to not support this case. GNU's objcopy was able to do this because
-the linker and objcopy are tightly coupled enough that segment reformatting was
-simpler. This is not the case with llvm-objcopy and lld where they like to be separated.
-
-This will attempt to copy data into the section without changing any other
-properties of the parent segment (if the section is part of one).
-
-Differential Revision: https://reviews.llvm.org/D112116
----
- .../llvm-objcopy/ELF/update-section.test | 176 ++++++++++++++++++
- llvm/tools/llvm-objcopy/CommonConfig.h | 1 +
- llvm/tools/llvm-objcopy/ConfigManager.cpp | 11 ++
- llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 48 +++--
- llvm/tools/llvm-objcopy/ELF/Object.cpp | 42 +++++
- llvm/tools/llvm-objcopy/ELF/Object.h | 14 ++
- llvm/tools/llvm-objcopy/ObjcopyOpts.td | 4 +
- 7 files changed, 281 insertions(+), 15 deletions(-)
- create mode 100644 llvm/test/tools/llvm-objcopy/ELF/update-section.test
-
-diff --git a/llvm/test/tools/llvm-objcopy/ELF/update-section.test b/llvm/test/tools/llvm-objcopy/ELF/update-section.test
-new file mode 100644
-index 000000000..644225557
---- /dev/null
-+++ b/llvm/test/tools/llvm-objcopy/ELF/update-section.test
-@@ -0,0 +1,176 @@
-+# RUN: yaml2obj %s -o %t
-+
-+# RUN: echo -n 11112222 > %t.same
-+# RUN: echo -n 00000000 > %t.zeros
-+# RUN: echo -n 11 > %t.short
-+# RUN: echo -n 11113333 > %t.updated
-+# RUN: echo -n 111122223 > %t.larger
-+
-+## Update the segment section with a regular chunk of data the same size as the section.
-+# RUN: llvm-objcopy --update-section=.in_segment=%t.same %t %t.same.o
-+# RUN: llvm-readobj --section-headers --section-data --program-headers %t.same.o | \
-+# RUN: FileCheck %s --check-prefix=NORMAL
-+
-+## Show that if we overwrite a given section (.in_segment) with new data, then rewrite it
-+## back (from the second `--update-section`), then it should be the exact same as the
-+## original file.
-+# RUN: llvm-objcopy %t %t.copy.o
-+# RUN: llvm-objcopy --update-section=.in_segment=%t.same --update-section=.in_segment=%t.zeros %t %t.original.o
-+# RUN: cmp %t.copy.o %t.original.o
-+
-+## Update segment section with a smaller chunk of data. This will also update the
-+## section size to the length of the new data written. This does not affect the offset
-+## of any subsequent sections in the same segment as this.
-+# RUN: llvm-objcopy --update-section=.in_segment=%t.short %t %t.short.o
-+# RUN: llvm-readobj --section-headers --section-data --program-headers %t.short.o | \
-+# RUN: FileCheck %s --check-prefix=SHORT
-+
-+## Ensure the data that was in a shortened section within a segment is still retained.
-+## For cases where there are gaps in segments not covered by sections, the existing
-+## contents are preserved.
-+# RUN: od -t x1 -j 0x78 -N 16 %t.short.o | FileCheck %s --check-prefix=PRESERVED
-+
-+## Add a new section via --add-section, then update it.
-+# RUN: llvm-objcopy --add-section=.added=%t.zeros --update-section=.added=%t.updated \
-+# RUN: %t %t.updated.o
-+# RUN: llvm-readobj --section-headers --section-data --program-headers %t.updated.o | \
-+# RUN: FileCheck %s --check-prefix=ADD-UPDATE
-+
-+## Adding should always be first regardless of flag order.
-+# RUN: llvm-objcopy --update-section=.added=%t.updated --add-section=.added=%t.updated \
-+# RUN: %t %t.updated.o
-+# RUN: llvm-readobj --section-headers --section-data --program-headers %t.updated.o | \
-+# RUN: FileCheck %s --check-prefix=ADD-UPDATE
-+
-+## We can't update sections which don't exist.
-+# RUN: not llvm-objcopy --update-section=.nosection=%t.same %t %t-err1 2>&1 | \
-+# RUN: FileCheck %s --check-prefix=ERR-NO-SECTION
-+
-+## We can't update certain types of sections.
-+# RUN: not llvm-objcopy --update-section=.nobits_type=%t.same %t %t-err2 2>&1 | \
-+# RUN: FileCheck %s --check-prefix=ERR-NOBITS-TYPE
-+# RUN: not llvm-objcopy --update-section=.null_type=%t.same %t %t-err2 2>&1 | \
-+# RUN: FileCheck %s --check-prefix=ERR-NULL-TYPE
-+
-+## Fail on trying to insert data larger than the existing section.
-+# RUN: not llvm-objcopy --update-section=.in_segment=%t.larger %t %t-err3 2>&1 | \
-+# RUN: FileCheck %s --check-prefix=ERR-LARGER
-+
-+## But we can insert larger data if the section is NOT part of a segment.
-+# RUN: llvm-objcopy --update-section=.not_in_segment=%t.larger %t %t.larger.o
-+# RUN: llvm-readobj --section-headers --section-data --program-headers %t.larger.o | \
-+# RUN: FileCheck %s --check-prefix=LONG
-+
-+## We should still fail on inserting larger data, even if it is superceded by a
-+## valid --update-section flag.
-+# RUN: not llvm-objcopy --update-section=.in_segment=%t.larger --update-section=.in_segment=%t.same %t %t-err3 2>&1 | \
-+# RUN: FileCheck %s --check-prefix=ERR-LARGER
-+
-+## Test option parsing failures.
-+# RUN: not llvm-objcopy --update-section %t %t.out 2>&1 | FileCheck %s --check-prefix=MISSING-EQ
-+# RUN: not llvm-objcopy --update-section=.in_segment= %t %t.out 2>&1 | FileCheck %s --check-prefix=MISSING-FILE
-+
-+!ELF
-+FileHeader:
-+ Class: ELFCLASS64
-+ Data: ELFDATA2LSB
-+ Type: ET_EXEC
-+ Machine: EM_X86_64
-+Sections:
-+ - Name: .in_segment
-+ Type: SHT_PROGBITS
-+ Content: "3030303030303030"
-+ - Name: .unmodified_in_segment
-+ Type: SHT_PROGBITS
-+ Content: "3130303030303030"
-+ - Name: .nobits_type
-+ Type: SHT_NOBITS
-+ - Name: .not_in_segment
-+ Type: SHT_PROGBITS
-+ - Name: .null_type
-+ Type: SHT_NULL
-+ProgramHeaders:
-+ - Type: PT_LOAD
-+ VAddr: 0x1000
-+ FirstSec: .in_segment
-+## The unmodified section is for ensuring that it remains untouched (ie. its
-+## offset is the same) even when the section before it is shrunk.
-+ LastSec: .unmodified_in_segment
-+
-+# NORMAL: Name: .in_segment
-+# NORMAL: Offset:
-+# NORMAL-SAME: {{ }}0x78{{$}}
-+# NORMAL: Size:
-+# NORMAL-SAME: {{ }}8{{$}}
-+# NORMAL: SectionData (
-+# NORMAL-NEXT: |11112222|
-+# NORMAL-NEXT: )
-+# NORMAL: Name: .unmodified_in_segment
-+# NORMAL: Offset:
-+# NORMAL-SAME: {{ }}0x80{{$}}
-+# NORMAL: Size:
-+# NORMAL-SAME: {{ }}8{{$}}
-+# NORMAL: SectionData (
-+# NORMAL-NEXT: |10000000|
-+# NORMAL-NEXT: )
-+# NORMAL: ProgramHeaders [
-+# NORMAL-NEXT: ProgramHeader {
-+# NORMAL-NEXT: Type: PT_LOAD (0x1)
-+# NORMAL: FileSize:
-+# NORMAL-SAME: {{ }}16{{$}}
-+# NORMAL: MemSize:
-+# NORMAL-SAME: {{ }}16{{$}}
-+# NORMAL: }
-+# NORMAL-NEXT: ]
-+
-+# SHORT: Name: .in_segment
-+# SHORT: Offset:
-+# SHORT-SAME: {{ }}0x78{{$}}
-+# SHORT: Size:
-+# SHORT-SAME: {{ }}2{{$}}
-+# SHORT: SectionData (
-+# SHORT-NEXT: |11|
-+# SHORT-NEXT: )
-+# SHORT: Name: .unmodified_in_segment
-+# SHORT: Offset:
-+# SHORT-SAME: {{ }}0x80{{$}}
-+# SHORT: Size:
-+# SHORT-SAME: {{ }}8{{$}}
-+# SHORT: SectionData (
-+# SHORT-NEXT: |10000000|
-+# SHORT-NEXT: )
-+# SHORT: ProgramHeaders [
-+# SHORT-NEXT: ProgramHeader {
-+# SHORT-NEXT: Type: PT_LOAD (0x1)
-+# SHORT: FileSize:
-+# SHORT-SAME: {{ }}16{{$}}
-+# SHORT: MemSize:
-+# SHORT-SAME: {{ }}16{{$}}
-+# SHORT: }
-+# SHORT-NEXT: ]
-+
-+## The first 8 bytes are the modified section. The last 8 bytes are the
-+## unmodified section.
-+# PRESERVED: 31 31 30 30 30 30 30 30 31 30 30 30 30 30 30 30
-+
-+# LONG: Name: .not_in_segment
-+# LONG: Size:
-+# LONG-SAME: {{ }}9{{$}}
-+# LONG: SectionData (
-+# LONG-NEXT: |111122223|
-+# LONT-NEXT: )
-+
-+# ADD-UPDATE: Name: .added
-+# ADD-UPDATE: Size:
-+# ADD-UPDATE-SAME: {{ }}8{{$}}
-+# ADD-UPDATE: SectionData (
-+# ADD-UPDATE-NEXT: |11113333|
-+# ADD-UPDATE: )
-+
-+# ERR-NO-SECTION: error: {{.*}}section '.nosection' not found
-+# ERR-NOBITS-TYPE: error: {{.*}}section '.nobits_type' can't be updated because it does not have contents
-+# ERR-NULL-TYPE: error: {{.*}}section '.null_type' can't be updated because it does not have contents
-+# ERR-LARGER: error: {{.*}}cannot fit data of size 9 into section '.in_segment' with size 8 that is part of a segment
-+
-+# MISSING-EQ: error: bad format for --update-section: missing '='
-+# MISSING-FILE: error: bad format for --update-section: missing file name
-diff --git a/llvm/tools/llvm-objcopy/CommonConfig.h b/llvm/tools/llvm-objcopy/CommonConfig.h
-index 131ce5c59..b7a7a5ec7 100644
---- a/llvm/tools/llvm-objcopy/CommonConfig.h
-+++ b/llvm/tools/llvm-objcopy/CommonConfig.h
-@@ -210,6 +210,7 @@ struct CommonConfig {
- // Repeated options
- std::vector<StringRef> AddSection;
- std::vector<StringRef> DumpSection;
-+ std::vector<StringRef> UpdateSection;
- std::vector<StringRef> RPathToAdd;
- std::vector<StringRef> RPathToPrepend;
- DenseMap<StringRef, StringRef> RPathsToUpdate;
-diff --git a/llvm/tools/llvm-objcopy/ConfigManager.cpp b/llvm/tools/llvm-objcopy/ConfigManager.cpp
-index 9f7d06b99..2840f90cb 100644
---- a/llvm/tools/llvm-objcopy/ConfigManager.cpp
-+++ b/llvm/tools/llvm-objcopy/ConfigManager.cpp
-@@ -887,6 +887,17 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
- "bad format for --add-section: missing file name");
- Config.AddSection.push_back(ArgValue);
- }
-+ for (auto Arg : InputArgs.filtered(OBJCOPY_update_section)) {
-+ StringRef ArgValue(Arg->getValue());
-+ if (!ArgValue.contains('='))
-+ return createStringError(errc::invalid_argument,
-+ "bad format for --update-section: missing '='");
-+ if (ArgValue.split("=").second.empty())
-+ return createStringError(
-+ errc::invalid_argument,
-+ "bad format for --update-section: missing file name");
-+ Config.UpdateSection.push_back(ArgValue);
-+ }
- for (auto *Arg : InputArgs.filtered(OBJCOPY_dump_section)) {
- StringRef Value(Arg->getValue());
- if (Value.split('=').second.empty())
-diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
-index 986eeca62..b9c6abdc1 100644
---- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
-+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
-@@ -554,6 +554,22 @@ static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo,
- Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0);
- }
-
-+static Error
-+handleUserSection(StringRef Flag,
-+ function_ref<Error(StringRef, ArrayRef<uint8_t>)> F) {
-+ std::pair<StringRef, StringRef> SecPair = Flag.split("=");
-+ StringRef SecName = SecPair.first;
-+ StringRef File = SecPair.second;
-+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(File);
-+ if (!BufOrErr)
-+ return createFileError(File, errorCodeToError(BufOrErr.getError()));
-+ std::unique_ptr<MemoryBuffer> Buf = std::move(*BufOrErr);
-+ ArrayRef<uint8_t> Data(
-+ reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
-+ Buf->getBufferSize());
-+ return F(SecName, Data);
-+}
-+
- // This function handles the high level operations of GNU objcopy including
- // handling command line options. It's important to outline certain properties
- // we expect to hold of the command line operations. Any operation that "keeps"
-@@ -664,21 +680,23 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
- Sec.Type = SHT_NOBITS;
-
- for (const auto &Flag : Config.AddSection) {
-- std::pair<StringRef, StringRef> SecPair = Flag.split("=");
-- StringRef SecName = SecPair.first;
-- StringRef File = SecPair.second;
-- ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
-- MemoryBuffer::getFile(File);
-- if (!BufOrErr)
-- return createFileError(File, errorCodeToError(BufOrErr.getError()));
-- std::unique_ptr<MemoryBuffer> Buf = std::move(*BufOrErr);
-- ArrayRef<uint8_t> Data(
-- reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
-- Buf->getBufferSize());
-- OwnedDataSection &NewSection =
-- Obj.addSection<OwnedDataSection>(SecName, Data);
-- if (SecName.startswith(".note") && SecName != ".note.GNU-stack")
-- NewSection.Type = SHT_NOTE;
-+ auto AddSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
-+ OwnedDataSection &NewSection =
-+ Obj.addSection<OwnedDataSection>(Name, Data);
-+ if (Name.startswith(".note") && Name != ".note.GNU-stack")
-+ NewSection.Type = SHT_NOTE;
-+ return Error::success();
-+ };
-+ if (Error E = handleUserSection(Flag, AddSection))
-+ return E;
-+ }
-+
-+ for (StringRef Flag : Config.UpdateSection) {
-+ auto UpdateSection = [&](StringRef Name, ArrayRef<uint8_t> Data) {
-+ return Obj.updateSection(Name, Data);
-+ };
-+ if (Error E = handleUserSection(Flag, UpdateSection))
-+ return E;
- }
-
- if (!Config.AddGnuDebugLink.empty())
-diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
-index ba91d08e5..c8a27f7a6 100644
---- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
-+++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
-@@ -2093,6 +2093,17 @@ template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() {
- Size);
- }
-
-+ for (auto it : Obj.getUpdatedSections()) {
-+ SectionBase *Sec = it.first;
-+ ArrayRef<uint8_t> Data = it.second;
-+
-+ auto *Parent = Sec->ParentSegment;
-+ assert(Parent && "This section should've been part of a segment.");
-+ uint64_t Offset =
-+ Sec->OriginalOffset - Parent->OriginalOffset + Parent->Offset;
-+ llvm::copy(Data, Buf->getBufferStart() + Offset);
-+ }
-+
- // Iterate over removed sections and overwrite their old data with zeroes.
- for (auto &Sec : Obj.removedSections()) {
- Segment *Parent = Sec.ParentSegment;
-@@ -2110,6 +2121,37 @@ ELFWriter<ELFT>::ELFWriter(Object &Obj, raw_ostream &Buf, bool WSH,
- : Writer(Obj, Buf), WriteSectionHeaders(WSH && Obj.HadShdrs),
- OnlyKeepDebug(OnlyKeepDebug) {}
-
-+Error Object::updateSection(StringRef Name, ArrayRef<uint8_t> Data) {
-+ auto It = llvm::find_if(Sections,
-+ [&](const SecPtr &Sec) { return Sec->Name == Name; });
-+ if (It == Sections.end())
-+ return createStringError(errc::invalid_argument, "section '%s' not found",
-+ Name.str().c_str());
-+
-+ auto *OldSec = It->get();
-+ if (!OldSec->hasContents())
-+ return createStringError(
-+ errc::invalid_argument,
-+ "section '%s' can't be updated because it does not have contents",
-+ Name.str().c_str());
-+
-+ if (Data.size() > OldSec->Size && OldSec->ParentSegment)
-+ return createStringError(errc::invalid_argument,
-+ "cannot fit data of size %zu into section '%s' "
-+ "with size %zu that is part of a segment",
-+ Data.size(), Name.str().c_str(), OldSec->Size);
-+
-+ if (!OldSec->ParentSegment) {
-+ *It = std::make_unique<OwnedDataSection>(*OldSec, Data);
-+ } else {
-+ // The segment writer will be in charge of updating these contents.
-+ OldSec->Size = Data.size();
-+ UpdatedSections[OldSec] = Data;
-+ }
-+
-+ return Error::success();
-+}
-+
- Error Object::removeSections(
- bool AllowBrokenLinks, std::function<bool(const SectionBase &)> ToRemove) {
-
-diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
-index 6fd26afa3..060a92159 100644
---- a/llvm/tools/llvm-objcopy/ELF/Object.h
-+++ b/llvm/tools/llvm-objcopy/ELF/Object.h
-@@ -429,6 +429,7 @@ public:
- virtual void markSymbols();
- virtual void
- replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &);
-+ virtual bool hasContents() const { return false; }
- // Notify the section that it is subject to removal.
- virtual void onRemove();
- };
-@@ -493,6 +494,9 @@ public:
- function_ref<bool(const SectionBase *)> ToRemove) override;
- Error initialize(SectionTableRef SecTable) override;
- void finalize() override;
-+ bool hasContents() const override {
-+ return Type != ELF::SHT_NOBITS && Type != ELF::SHT_NULL;
-+ }
- };
-
- class OwnedDataSection : public SectionBase {
-@@ -518,9 +522,15 @@ public:
- OriginalOffset = SecOff;
- }
-
-+ OwnedDataSection(SectionBase &S, ArrayRef<uint8_t> Data)
-+ : SectionBase(S), Data(std::begin(Data), std::end(Data)) {
-+ Size = Data.size();
-+ }
-+
- void appendHexData(StringRef HexData);
- Error accept(SectionVisitor &Sec) const override;
- Error accept(MutableSectionVisitor &Visitor) override;
-+ bool hasContents() const override { return true; }
- };
-
- class CompressedSection : public SectionBase {
-@@ -1016,6 +1026,7 @@ private:
- std::vector<SecPtr> Sections;
- std::vector<SegPtr> Segments;
- std::vector<SecPtr> RemovedSections;
-+ DenseMap<SectionBase *, std::vector<uint8_t>> UpdatedSections;
-
- static bool sectionIsAlloc(const SectionBase &Sec) {
- return Sec.Flags & ELF::SHF_ALLOC;
-@@ -1066,6 +1077,9 @@ public:
- return make_filter_range(make_pointee_range(Sections), sectionIsAlloc);
- }
-
-+ const auto &getUpdatedSections() const { return UpdatedSections; }
-+ Error updateSection(StringRef Name, ArrayRef<uint8_t> Data);
-+
- SectionBase *findSection(StringRef Name) {
- auto SecIt =
- find_if(Sections, [&](const SecPtr &Sec) { return Sec->Name == Name; });
-diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
-index 63abbe4c2..ccd7ff292 100644
---- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
-+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
-@@ -214,3 +214,7 @@ defm add_symbol
- "compatibility: debug, constructor, warning, indirect, synthetic, "
- "unique-object, before.">,
- MetaVarName<"name=[section:]value[,flags]">;
-+
-+defm update_section
-+ : Eq<"update-section", "Add section <name> with contents from a file <file>.">,
-+ MetaVarName<"name=file">;
---
-2.34.1
-
diff --git a/Toolchain/Patches/llvm/0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch b/Toolchain/Patches/llvm/0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch
new file mode 100644
index 0000000000..50d571ab7d
--- /dev/null
+++ b/Toolchain/Patches/llvm/0001-Support-Add-support-for-building-LLVM-on-SerenityOS.patch
@@ -0,0 +1,81 @@
+From 9ff3d5362c71dfa9b6aba1dd65a33bb6d8971164 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 09:54:22 +0200
+Subject: [PATCH 1/8] [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 e8612ba66..f0109f4b3 100644
+--- a/llvm/include/llvm/Support/SwapByteOrder.h
++++ b/llvm/include/llvm/Support/SwapByteOrder.h
+@@ -22,7 +22,7 @@
+ #endif
+
+ #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
+- defined(__Fuchsia__) || defined(__EMSCRIPTEN__)
++ defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__serenity__)
+ #include <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 788460d65..566628935 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
+@@ -512,6 +512,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
+ StringRef fstype(Vfs.f_basetype);
+diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
+index 089342030..3ffe064e5 100644
+--- a/llvm/lib/Support/Unix/Program.inc
++++ b/llvm/lib/Support/Unix/Program.inc
+@@ -336,7 +336,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);
+@@ -379,6 +379,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, unsigned SecondsToWait,
+ bool WaitUntilTerminates, std::string *ErrMsg,
+ Optional<ProcessStatistics> *ProcStat) {
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/0002-Triple-Add-triple-for-SerenityOS.patch b/Toolchain/Patches/llvm/0002-Triple-Add-triple-for-SerenityOS.patch
new file mode 100644
index 0000000000..25275c7d5f
--- /dev/null
+++ b/Toolchain/Patches/llvm/0002-Triple-Add-triple-for-SerenityOS.patch
@@ -0,0 +1,59 @@
+From 0cf66d1dbcd3b7c0e2ddd65177066955c41352b7 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 09:51:24 +0200
+Subject: [PATCH 2/8] [Triple] Add triple for SerenityOS
+
+---
+ llvm/include/llvm/ADT/Triple.h | 8 +++++++-
+ llvm/lib/Support/Triple.cpp | 2 ++
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
+index 42277c013..b0378dd3a 100644
+--- a/llvm/include/llvm/ADT/Triple.h
++++ b/llvm/include/llvm/ADT/Triple.h
+@@ -205,7 +205,8 @@ public:
+ Hurd, // GNU/Hurd
+ WASI, // Experimental WebAssembly OS
+ Emscripten,
+- LastOSType = Emscripten
++ Serenity,
++ LastOSType = Serenity
+ };
+ enum EnvironmentType {
+ UnknownEnvironment,
+@@ -612,6 +613,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/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
+index a9afcc9db..aef8c7549 100644
+--- a/llvm/lib/Support/Triple.cpp
++++ b/llvm/lib/Support/Triple.cpp
+@@ -224,6 +224,7 @@ StringRef Triple::getOSTypeName(OSType Kind) {
+ case PS4: return "ps4";
+ case RTEMS: return "rtems";
+ case Solaris: return "solaris";
++ case Serenity: return "serenity";
+ case TvOS: return "tvos";
+ case WASI: return "wasi";
+ case WatchOS: return "watchos";
+@@ -548,6 +549,7 @@ static Triple::OSType parseOS(StringRef OSName) {
+ .StartsWith("hurd", Triple::Hurd)
+ .StartsWith("wasi", Triple::WASI)
+ .StartsWith("emscripten", Triple::Emscripten)
++ .StartsWith("serenity", Triple::Serenity)
+ .Default(Triple::UnknownOS);
+ }
+
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm.patch b/Toolchain/Patches/llvm/0003-Driver-Add-support-for-SerenityOS.patch
index 5382be4e04..36cebcc697 100644
--- a/Toolchain/Patches/llvm.patch
+++ b/Toolchain/Patches/llvm/0003-Driver-Add-support-for-SerenityOS.patch
@@ -1,5 +1,27 @@
+From 70cbf6e9ed46f0d39f43ac4a43b9bd2cc10da6c3 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 10:09:50 +0200
+Subject: [PATCH 3/8] [Driver] Add support for SerenityOS
+
+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.
+---
+ clang/lib/Basic/Targets.cpp | 6 +
+ 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/Arch/X86.cpp | 1 +
+ clang/lib/Driver/ToolChains/Serenity.cpp | 340 +++++++++++++++++++++++
+ clang/lib/Driver/ToolChains/Serenity.h | 99 +++++++
+ 8 files changed, 471 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 ba91d0439..42265d547 100644
+index 994a491cd..066c8140b 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -149,6 +149,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
@@ -30,10 +52,10 @@ index ba91d0439..42265d547 100644
return new X86_64TargetInfo(Triple, Opts);
}
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
-index 3fe39ed64..51e7a6cca 100644
+index 3c1830d5f..b0bae0535 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
-@@ -966,6 +966,24 @@ public:
+@@ -977,6 +977,24 @@ public:
}
};
@@ -59,30 +81,30 @@ index 3fe39ed64..51e7a6cca 100644
} // 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 08be9f011..69038ff00 100644
+index 78e8fd185..3b70257a9 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
-@@ -67,6 +67,7 @@ add_clang_library(clangDriver
+@@ -70,6 +70,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
- ToolChains/VEToolchain.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
-index 94a7553e2..c6b3210f6 100644
+index 3bfddeefc..a75e0ee14 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
-@@ -41,6 +41,7 @@
+@@ -43,6 +43,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"
- #include "ToolChains/VEToolchain.h"
-@@ -5299,6 +5300,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
+@@ -5564,6 +5565,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
case llvm::Triple::Fuchsia:
TC = std::make_unique<toolchains::Fuchsia>(*this, Target, Args);
break;
@@ -93,10 +115,10 @@ index 94a7553e2..c6b3210f6 100644
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 6c1b88141..c77ff78be 100644
+index d657d21bf..eea53e6ac 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
-@@ -404,6 +404,8 @@ StringRef ToolChain::getOSLibName() const {
+@@ -413,6 +413,8 @@ StringRef ToolChain::getOSLibName() const {
return "sunos";
case llvm::Triple::AIX:
return "aix";
@@ -106,10 +128,10 @@ index 6c1b88141..c77ff78be 100644
return getOS();
}
diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp
-index 12749c7ec..91f744a26 100644
+index bfa008f96..b7f1780fd 100644
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
-@@ -100,6 +100,7 @@ std::string x86::getX86TargetCPU(const ArgList &Args,
+@@ -107,6 +107,7 @@ std::string x86::getX86TargetCPU(const Driver &D, const ArgList &Args,
case llvm::Triple::OpenBSD:
return "i586";
case llvm::Triple::FreeBSD:
@@ -117,31 +139,12 @@ index 12749c7ec..91f744a26 100644
return "i686";
default:
// Fallback to p4.
-diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
-index 58ae08a38..8e9a3fee6 100644
---- a/clang/lib/Driver/ToolChains/Clang.cpp
-+++ b/clang/lib/Driver/ToolChains/Clang.cpp
-@@ -5695,7 +5695,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
- 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_fno_operator_names,
- options::OPT_foperator_names, false))
diff --git a/clang/lib/Driver/ToolChains/Serenity.cpp b/clang/lib/Driver/ToolChains/Serenity.cpp
new file mode 100644
-index 000000000..4d653d86f
+index 000000000..955422438
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Serenity.cpp
-@@ -0,0 +1,327 @@
+@@ -0,0 +1,340 @@
+//===---- Serenity.cpp - SerenityOS ToolChain Implementation ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -173,7 +176,7 @@ index 000000000..4d653d86f
+ return false;
+ Arg *Last = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
+ options::OPT_nopie);
-+ return Last ? Last->getOption().matches(options::OPT_pie) : TC.isPIEDefault();
++ return Last ? Last->getOption().matches(options::OPT_pie) : true;
+}
+
+void tools::serenity::Linker::ConstructJob(Compilation &C, const JobAction &JA,
@@ -224,6 +227,19 @@ index 000000000..4d653d86f
+ 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")));
@@ -270,7 +286,7 @@ index 000000000..4d653d86f
+
+ // We supply our own sanitizer runtimes
+ // FIXME: What if we want to use Clang-supplied ones as well?
-+ const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
++ const SanitizerArgs &Sanitize = TC.getSanitizerArgs(Args);
+ if (Sanitize.needsUbsanRt())
+ CmdArgs.push_back("-lubsan");
+ }
@@ -316,7 +332,6 @@ index 000000000..4d653d86f
+
+ Args.AddAllArgs(CmdArgs, options::OPT_T);
+
-+ const char *Exec = Args.MakeArgString(TC.GetLinkerPath());
+ C.addCommand(std::make_unique<Command>(JA, *this,
+ ResponseFileSupport::AtFileCurCP(),
+ Exec, CmdArgs, Inputs, Output));
@@ -328,6 +343,7 @@ index 000000000..4d653d86f
+ 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");
+}
+
@@ -471,7 +487,7 @@ index 000000000..4d653d86f
+}
diff --git a/clang/lib/Driver/ToolChains/Serenity.h b/clang/lib/Driver/ToolChains/Serenity.h
new file mode 100644
-index 000000000..50b0dbe62
+index 000000000..d414f8366
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Serenity.h
@@ -0,0 +1,99 @@
@@ -547,7 +563,7 @@ index 000000000..50b0dbe62
+ bool IsIntegratedAssemblerDefault() const override { return true; }
+
+ bool isPICDefault() const override { return true; }
-+ bool isPIEDefault() const override { return true; }
++ bool isPIEDefault(const llvm::opt::ArgList&) const override { return false; }
+ bool isPICDefaultForced() const override { return false; }
+
+ bool IsMathErrnoDefault() const override { return false; }
@@ -574,273 +590,6 @@ index 000000000..50b0dbe62
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SERENITY_H
-diff --git a/clang/lib/Frontend/InitHeaderSearch.cpp b/clang/lib/Frontend/InitHeaderSearch.cpp
-index ba9f96384..4aecfeee2 100644
---- a/clang/lib/Frontend/InitHeaderSearch.cpp
-+++ b/clang/lib/Frontend/InitHeaderSearch.cpp
-@@ -233,6 +233,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
- case llvm::Triple::PS4:
- case llvm::Triple::ELFIAMCU:
- case llvm::Triple::Fuchsia:
-+ case llvm::Triple::Serenity:
- break;
- case llvm::Triple::Win32:
- if (triple.getEnvironment() != llvm::Triple::Cygnus)
-@@ -432,6 +433,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
- case llvm::Triple::Solaris:
- case llvm::Triple::WASI:
- case llvm::Triple::AIX:
-+ case llvm::Triple::Serenity:
- return;
-
- case llvm::Triple::Win32:
-diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
-index 39b9120f0..1a49ac3e5 100644
---- a/compiler-rt/cmake/config-ix.cmake
-+++ b/compiler-rt/cmake/config-ix.cmake
-@@ -684,7 +684,7 @@ endif()
-
- # TODO: Add builtins support.
-
--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)
-diff --git a/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake b/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake
-index ad2820b32..deaa2c380 100644
---- a/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake
-+++ b/libcxx/cmake/Modules/HandleOutOfTreeLLVM.cmake
-@@ -14,6 +14,8 @@ set(LLVM_INCLUDE_DIR ${LLVM_PATH}/include CACHE PATH "Path to llvm/include")
- set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree")
- set(LLVM_MAIN_SRC_DIR ${LLVM_PATH})
- set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules")
-+set(LLVM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-+set(LLVM_LIBRARY_OUTPUT_INTDIR "${CMAKE_CURRENT_BINARY_DIR}/lib")
-
- if (EXISTS "${LLVM_CMAKE_PATH}")
- list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
-diff --git a/libcxx/include/__config b/libcxx/include/__config
-index 97e33f315..179bd2a67 100644
---- a/libcxx/include/__config
-+++ b/libcxx/include/__config
-@@ -1148,6 +1148,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
- defined(__sun__) || \
- defined(__MVS__) || \
- defined(_AIX) || \
-+ defined(__serenity__) || \
- (defined(__MINGW32__) && __has_include(<pthread.h>))
- # define _LIBCPP_HAS_THREAD_API_PTHREAD
- # elif defined(__Fuchsia__)
-diff --git a/libcxx/include/__locale b/libcxx/include/__locale
-index ad742997d..c75dcb458 100644
---- a/libcxx/include/__locale
-+++ b/libcxx/include/__locale
-@@ -31,7 +31,7 @@
- #elif defined(__sun__)
- # include <xlocale.h>
- # include <__support/solaris/xlocale.h>
--#elif defined(_NEWLIB_VERSION)
-+#elif defined(_NEWLIB_VERSION) || defined(__serenity__)
- # include <__support/newlib/xlocale.h>
- #elif defined(__OpenBSD__)
- # include <__support/openbsd/xlocale.h>
-@@ -490,7 +490,7 @@ public:
- static const mask xdigit = _ISXDIGIT;
- static const mask blank = _ISBLANK;
- static const mask __regex_word = 0x80;
--#elif defined(_NEWLIB_VERSION)
-+#elif defined(_NEWLIB_VERSION) || defined(__serenity__)
- // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
- typedef char mask;
- static const mask space = _S;
-diff --git a/libcxx/include/__support/newlib/xlocale.h b/libcxx/include/__support/newlib/xlocale.h
-index b75f9263a..f5ffb9003 100644
---- a/libcxx/include/__support/newlib/xlocale.h
-+++ b/libcxx/include/__support/newlib/xlocale.h
-@@ -9,7 +9,7 @@
- #ifndef _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H
- #define _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H
-
--#if defined(_NEWLIB_VERSION)
-+#if defined(_NEWLIB_VERSION) || defined(__serenity__)
-
- #include <cstdlib>
- #include <clocale>
-@@ -22,6 +22,6 @@
- #include <__support/xlocale/__strtonum_fallback.h>
- #endif
-
--#endif // _NEWLIB_VERSION
-+#endif // _NEWLIB_VERSION || __serenity__
-
- #endif
-diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
-index ea1f23467..45631ac2f 100644
---- a/libcxx/include/initializer_list
-+++ b/libcxx/include/initializer_list
-@@ -43,7 +43,9 @@ template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in
- */
-
- #include <__config>
-+#if !defined(__serenity__) || !defined(KERNEL)
- #include <cstddef>
-+#endif
-
- #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
- #pragma GCC system_header
-diff --git a/libcxx/include/locale b/libcxx/include/locale
-index 8e584005d..f29f3453e 100644
---- a/libcxx/include/locale
-+++ b/libcxx/include/locale
-@@ -206,7 +206,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.
--# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION)
-+# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__serenity__)
- # define _LIBCPP_HAS_CATOPEN 1
- # include <nl_types.h>
- # endif
-diff --git a/libcxx/include/new b/libcxx/include/new
-index aefc08c16..7ee71d16b 100644
---- a/libcxx/include/new
-+++ b/libcxx/include/new
-@@ -310,7 +310,7 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
- // Returns the allocated memory, or `nullptr` on failure.
- inline _LIBCPP_INLINE_VISIBILITY
- void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
--#if defined(_LIBCPP_MSVCRT_LIKE)
-+#if defined(_LIBCPP_MSVCRT_LIKE) || (defined(__serenity__) && !defined(KERNEL))
- return ::_aligned_malloc(__size, __alignment);
- #else
- void* __result = nullptr;
-@@ -322,7 +322,7 @@ void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
-
- inline _LIBCPP_INLINE_VISIBILITY
- void __libcpp_aligned_free(void* __ptr) {
--#if defined(_LIBCPP_MSVCRT_LIKE)
-+#if defined(_LIBCPP_MSVCRT_LIKE) || (defined(__serenity__) && !defined(KERNEL))
- ::_aligned_free(__ptr);
- #else
- ::free(__ptr);
-diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h
-index 7880c733f..87b25cf42 100644
---- a/libcxx/src/include/config_elast.h
-+++ b/libcxx/src/include/config_elast.h
-@@ -33,6 +33,8 @@
- #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__)
-diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
-index d5ab8fb3b..5039c1987 100644
---- a/libcxx/src/locale.cpp
-+++ b/libcxx/src/locale.cpp
-@@ -1145,6 +1145,8 @@ ctype<char>::classic_table() noexcept
- return __pctype_func();
- #elif defined(__EMSCRIPTEN__)
- return *__ctype_b_loc();
-+#elif defined(__serenity__)
-+ return _ctype_;
- #elif defined(_NEWLIB_VERSION)
- // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
- return _ctype_ + 1;
-diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
-index 0c3419390..7673b9183 100644
---- a/llvm/cmake/modules/HandleLLVMOptions.cmake
-+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
-@@ -228,7 +228,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|SunOS|OS390" OR
-+if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|FreeBSD|OpenBSD|DragonFly|AIX|SunOS|OS390|SerenityOS" OR
- WIN32 OR CYGWIN) AND
- NOT LLVM_USE_SANITIZER)
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
-diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
-index 76f351405..b81556c55 100644
---- a/llvm/include/llvm/ADT/Triple.h
-+++ b/llvm/include/llvm/ADT/Triple.h
-@@ -199,7 +199,8 @@ public:
- Hurd, // GNU/Hurd
- WASI, // Experimental WebAssembly OS
- Emscripten,
-- LastOSType = Emscripten
-+ Serenity,
-+ LastOSType = Serenity
- };
- enum EnvironmentType {
- UnknownEnvironment,
-@@ -628,6 +629,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/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
-index 883115463..22b39d8f5 100644
---- a/llvm/lib/Support/Triple.cpp
-+++ b/llvm/lib/Support/Triple.cpp
-@@ -218,6 +218,7 @@ StringRef Triple::getOSTypeName(OSType Kind) {
- case PS4: return "ps4";
- case RTEMS: return "rtems";
- case Solaris: return "solaris";
-+ case Serenity: return "serenity";
- case TvOS: return "tvos";
- case WASI: return "wasi";
- case WatchOS: return "watchos";
-@@ -538,6 +539,7 @@ static Triple::OSType parseOS(StringRef OSName) {
- .StartsWith("hurd", Triple::Hurd)
- .StartsWith("wasi", Triple::WASI)
- .StartsWith("emscripten", Triple::Emscripten)
-+ .StartsWith("serenity", Triple::Serenity)
- .Default(Triple::UnknownOS);
- }
-
-diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt
-index 1ffce323d..552521192 100644
---- a/runtimes/CMakeLists.txt
-+++ b/runtimes/CMakeLists.txt
-@@ -58,17 +58,28 @@ if(compiler_rt_path)
- endif()
- endif()
-
-+# If building standalone by pointing CMake at this runtimes directory,
-+# LLVM_BINARY_DIR isn't set, find_package(LLVM) will fail and these
-+# intermediate paths are unset.
-+if (LLVM_BINARY_DIR STREQUAL "")
-+ set(LLVM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-+endif()
-+if (NOT LLVM_FOUND)
-+ set(LLVM_TOOLS_BINARY_DIR ${LLVM_BINARY_DIR}/bin)
-+ set(LLVM_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib)
-+endif()
-+
- # Setting these variables will allow the sub-build to put their outputs into
- # the library and bin directories of the top-level build.
- set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_LIBRARY_DIR})
- set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_TOOLS_BINARY_DIR})
-
- # This variable makes sure that e.g. llvm-lit is found.
--set(LLVM_MAIN_SRC_DIR ${LLVM_BUILD_MAIN_SRC_DIR})
-+set(LLVM_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)
- set(LLVM_CMAKE_PATH ${LLVM_MAIN_SRC_DIR}/cmake/modules)
-
- # This variable is used by individual runtimes to locate LLVM files.
--set(LLVM_PATH ${LLVM_BUILD_MAIN_SRC_DIR})
-+set(LLVM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../llvm)
-
- if(APPLE)
- set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "")
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch b/Toolchain/Patches/llvm/0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch
new file mode 100644
index 0000000000..11eb6e6937
--- /dev/null
+++ b/Toolchain/Patches/llvm/0004-Driver-Default-to-ftls-model-initial-exec-on-Serenit.patch
@@ -0,0 +1,36 @@
+From 50e7b15efa5f7e2ff57e998879fee28fff4a5305 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 10:12:54 +0200
+Subject: [PATCH 4/8] [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 f2f18e901..39d6c18fe 100644
+--- a/clang/lib/Driver/ToolChains/Clang.cpp
++++ b/clang/lib/Driver/ToolChains/Clang.cpp
+@@ -5872,7 +5872,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))
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/0005-libc-Add-support-for-SerenityOS.patch b/Toolchain/Patches/llvm/0005-libc-Add-support-for-SerenityOS.patch
new file mode 100644
index 0000000000..3407153388
--- /dev/null
+++ b/Toolchain/Patches/llvm/0005-libc-Add-support-for-SerenityOS.patch
@@ -0,0 +1,153 @@
+From fae5030852da34db641d636ad4c599e56b92ccdf Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 10:17:13 +0200
+Subject: [PATCH 5/8] [libc++] 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.
+* Aligned memory allocation is provided by the MSVCRT-like
+ `_aligned_{malloc,free}` functions.
+
+Adds a hack for a header not found error when including
+`<initializer_list>` inside the SerenityOS kernel.
+
+Makes libc++ use its builtin character type table instead of the one
+provided by LibC as it is incomplete.
+---
+ libcxx/include/__config | 6 ++++--
+ libcxx/include/__locale | 2 +-
+ libcxx/include/__support/newlib/xlocale.h | 4 ++--
+ libcxx/include/initializer_list | 2 ++
+ libcxx/include/locale | 2 +-
+ libcxx/include/new | 4 ++--
+ libcxx/src/include/config_elast.h | 2 ++
+ 7 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/libcxx/include/__config b/libcxx/include/__config
+index 458d0c1b8..69f627294 100644
+--- a/libcxx/include/__config
++++ b/libcxx/include/__config
+@@ -1146,7 +1146,8 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
+ defined(__APPLE__) || \
+ defined(__sun__) || \
+ defined(__MVS__) || \
+- defined(_AIX)
++ defined(_AIX) || \
++ defined(__serenity__)
+ # define _LIBCPP_HAS_THREAD_API_PTHREAD
+ # elif defined(__Fuchsia__)
+ // TODO(44575): Switch to C11 thread API when possible.
+@@ -1225,7 +1226,8 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
+
+ #if defined(__BIONIC__) || defined(__NuttX__) || \
+ defined(__Fuchsia__) || defined(__wasi__) || \
+- defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__)
++ defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) || \
++ defined(__serenity__)
+ #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
+ #endif
+
+diff --git a/libcxx/include/__locale b/libcxx/include/__locale
+index 51f35eece..4bc91ecb5 100644
+--- a/libcxx/include/__locale
++++ b/libcxx/include/__locale
+@@ -30,7 +30,7 @@
+ #elif defined(__sun__)
+ # include <xlocale.h>
+ # include <__support/solaris/xlocale.h>
+-#elif defined(_NEWLIB_VERSION)
++#elif defined(_NEWLIB_VERSION) || defined(__serenity__)
+ # include <__support/newlib/xlocale.h>
+ #elif defined(__OpenBSD__)
+ # include <__support/openbsd/xlocale.h>
+diff --git a/libcxx/include/__support/newlib/xlocale.h b/libcxx/include/__support/newlib/xlocale.h
+index b75f9263a..f5ffb9003 100644
+--- a/libcxx/include/__support/newlib/xlocale.h
++++ b/libcxx/include/__support/newlib/xlocale.h
+@@ -9,7 +9,7 @@
+ #ifndef _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H
+ #define _LIBCPP_SUPPORT_NEWLIB_XLOCALE_H
+
+-#if defined(_NEWLIB_VERSION)
++#if defined(_NEWLIB_VERSION) || defined(__serenity__)
+
+ #include <cstdlib>
+ #include <clocale>
+@@ -22,6 +22,6 @@
+ #include <__support/xlocale/__strtonum_fallback.h>
+ #endif
+
+-#endif // _NEWLIB_VERSION
++#endif // _NEWLIB_VERSION || __serenity__
+
+ #endif
+diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
+index fefaf8cf8..c388bc246 100644
+--- a/libcxx/include/initializer_list
++++ b/libcxx/include/initializer_list
+@@ -43,7 +43,9 @@ template<class E> const E* end(initializer_list<E> il) noexcept; // constexpr in
+ */
+
+ #include <__config>
++#if !defined(__serenity__) || !defined(KERNEL)
+ #include <cstddef>
++#endif
+
+ #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+ #pragma GCC system_header
+diff --git a/libcxx/include/locale b/libcxx/include/locale
+index 7c2d2361f..229ca7258 100644
+--- a/libcxx/include/locale
++++ b/libcxx/include/locale
+@@ -206,7 +206,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.
+-# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION)
++# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) && !defined(__serenity__)
+ # define _LIBCPP_HAS_CATOPEN 1
+ # include <nl_types.h>
+ # endif
+diff --git a/libcxx/include/new b/libcxx/include/new
+index be0d972f4..d212bae46 100644
+--- a/libcxx/include/new
++++ b/libcxx/include/new
+@@ -320,7 +320,7 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
+ // Returns the allocated memory, or `nullptr` on failure.
+ inline _LIBCPP_INLINE_VISIBILITY
+ void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
+-#if defined(_LIBCPP_MSVCRT_LIKE)
++#if defined(_LIBCPP_MSVCRT_LIKE) || (defined(__serenity__) && !defined(KERNEL))
+ return ::_aligned_malloc(__size, __alignment);
+ #else
+ void* __result = nullptr;
+@@ -332,7 +332,7 @@ void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
+
+ inline _LIBCPP_INLINE_VISIBILITY
+ void __libcpp_aligned_free(void* __ptr) {
+-#if defined(_LIBCPP_MSVCRT_LIKE)
++#if defined(_LIBCPP_MSVCRT_LIKE) || (defined(__serenity__) && !defined(KERNEL))
+ ::_aligned_free(__ptr);
+ #else
+ ::free(__ptr);
+diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h
+index 0ed53a3b2..7fffd937e 100644
+--- a/libcxx/src/include/config_elast.h
++++ b/libcxx/src/include/config_elast.h
+@@ -33,6 +33,8 @@
+ #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__)
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch b/Toolchain/Patches/llvm/0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch
new file mode 100644
index 0000000000..25a01acc94
--- /dev/null
+++ b/Toolchain/Patches/llvm/0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch
@@ -0,0 +1,25 @@
+From 1cf9ec98aa817c13b94b42e4df80804a6757aa8a Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 10:20:46 +0200
+Subject: [PATCH 6/8] [compiler-rt] Build crtbegin.o/crtend.o for SerenityOS
+
+---
+ compiler-rt/cmake/config-ix.cmake | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
+index fc62d5ecc..7a47b7f71 100644
+--- a/compiler-rt/cmake/config-ix.cmake
++++ b/compiler-rt/cmake/config-ix.cmake
+@@ -696,7 +696,7 @@ endif()
+
+ # TODO: Add builtins support.
+
+-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)
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch b/Toolchain/Patches/llvm/0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch
new file mode 100644
index 0000000000..6f85426ba4
--- /dev/null
+++ b/Toolchain/Patches/llvm/0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch
@@ -0,0 +1,28 @@
+From ac91fd973bdf23b24645336a470d5dfb31811aa6 Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Thu, 14 Apr 2022 10:21:19 +0200
+Subject: [PATCH 7/8] [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 fcaa8f20b..c27209146 100644
+--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
++++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
+@@ -227,7 +227,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|SunOS|OS390" OR
++if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|FreeBSD|OpenBSD|DragonFly|AIX|SunOS|OS390|SerenityOS" OR
+ WIN32 OR CYGWIN) AND
+ NOT LLVM_USE_SANITIZER)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch b/Toolchain/Patches/llvm/0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch
new file mode 100644
index 0000000000..abb9c098e4
--- /dev/null
+++ b/Toolchain/Patches/llvm/0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch
@@ -0,0 +1,54 @@
+From eb1dbc59eaebdefd9735b738ca30478ce1788dca Mon Sep 17 00:00:00 2001
+From: Daniel Bertalan <dani@danielbertalan.dev>
+Date: Mon, 18 Apr 2022 22:32:29 +0200
+Subject: [PATCH 8/8] [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 4e0647971..2e4aeeab3 100644
+--- a/clang/tools/libclang/CMakeLists.txt
++++ b/clang/tools/libclang/CMakeLists.txt
+@@ -80,7 +80,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 8e2b78f1b..909018753 100644
+--- a/llvm/tools/llvm-shlib/CMakeLists.txt
++++ b/llvm/tools/llvm-shlib/CMakeLists.txt
+@@ -39,6 +39,7 @@ if(LLVM_BUILD_LLVM_DYLIB)
+ OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
+ OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
+ OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
++ 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
+@@ -46,7 +47,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()
+--
+2.35.3
+
diff --git a/Toolchain/Patches/llvm/ReadMe.md b/Toolchain/Patches/llvm/ReadMe.md
new file mode 100644
index 0000000000..7ebf072a6f
--- /dev/null
+++ b/Toolchain/Patches/llvm/ReadMe.md
@@ -0,0 +1,78 @@
+# 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`
+
+Add support for SerenityOS
+
+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.
+
+## `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.
+
+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.
+* Aligned memory allocation is provided by the MSVCRT-like
+ `_aligned_{malloc,free}` functions.
+
+Adds a hack for a header not found error when including
+`<initializer_list>` inside the SerenityOS kernel.
+
+Makes libc++ use its builtin character type table instead of the one
+provided by LibC as it is incomplete.
+
+## `0006-compiler-rt-Build-crtbegin.o-crtend.o-for-SerenityOS.patch`
+
+Build crtbegin.o/crtend.o for SerenityOS
+
+
+## `0007-cmake-Allow-undefined-symbols-on-SerenityOS.patch`
+
+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.
+
+## `0008-cmake-Support-building-shared-libLLVM-and-libClang-f.patch`
+
+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.
+