Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,10 @@ jobs:
matrix:
include:
- name: default
- name: exceptions
defines: -DWASI_SDK_EXCEPTIONS=ON
# TODO: re-enable this once LLVM 24 is released as wasi-sdk now relies
# on patches that only LLVM 24 has.
# - name: exceptions
# defines: -DWASI_SDK_EXCEPTIONS=ON
- name: static
defines: -DWASI_SDK_BUILD_SHARED=OFF
steps:
Expand Down
13 changes: 7 additions & 6 deletions cmake/wasi-sdk-sysroot.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,10 @@ function(define_libcxx_sub sysroot target target_suffix extra_target_flags extra
set(exnsuffix "")

if (exceptions)
# TODO: lots of builds fail with shared libraries and `-fPIC`. Looks like
# things are maybe changing in llvm/llvm-project#159143 but otherwise I'm at
# least not really sure what the state of shared libraries and exceptions
# are. For now shared libraries are disabled and supporting them is left for
# a future endeavor.
set(pic OFF)
# Building with `-fPIC` requires fixes in LLVM 23-and-later.
if(CMAKE_C_COMPILER_VERSION VERSION_LESS 23.0.0)
set(pic OFF)
endif()
set(runtimes "libunwind;${runtimes}")
list(APPEND extra_flags -fwasm-exceptions -mllvm -wasm-use-legacy-eh=false)
if (WASI_SDK_EXCEPTIONS STREQUAL "DUAL")
Expand Down Expand Up @@ -399,6 +397,9 @@ function(define_libcxx_sub sysroot target target_suffix extra_target_flags extra
COMMAND
${CMAKE_COMMAND} -E chdir .. bash -c
"git apply ${CMAKE_SOURCE_DIR}/src/llvm-undo-part-of-194317.patch || git apply ${CMAKE_SOURCE_DIR}/src/llvm-undo-part-of-194317.patch -R --check"
COMMAND
${CMAKE_COMMAND} -E chdir .. bash -c
"git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-209282.patch || git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-209282.patch -R --check"
)
add_dependencies(libcxx-${target} libcxx-${target}${target_suffix}-build)
endfunction()
Expand Down
8 changes: 7 additions & 1 deletion cmake/wasi-sdk-toolchain.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,12 @@ ExternalProject_Add(llvm-build
COMMAND
${CMAKE_COMMAND} -E chdir .. bash -c
"git apply ${CMAKE_SOURCE_DIR}/src/llvm-prs-208263-208332-208597.patch || git apply ${CMAKE_SOURCE_DIR}/src/llvm-prs-208263-208332-208597.patch -R --check"
COMMAND
${CMAKE_COMMAND} -E chdir .. bash -c
"git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-209282.patch || git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-209282.patch -R --check"
COMMAND
${CMAKE_COMMAND} -E chdir .. bash -c
"git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-215413.patch || git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-215413.patch -R --check"
)

add_custom_target(build ALL DEPENDS llvm-build)
Expand All @@ -275,7 +281,7 @@ install(DIRECTORY ${wasi_tmp_install}/bin ${wasi_tmp_install}/lib ${wasi_tmp_ins
# Build logic for `wasm-component-ld` installed from Rust code.
set(wasm_component_ld_root ${CMAKE_CURRENT_BINARY_DIR}/wasm-component-ld)
set(wasm_component_ld ${wasm_component_ld_root}/bin/wasm-component-ld${CMAKE_EXECUTABLE_SUFFIX})
set(wasm_component_ld_version 0.5.27)
set(wasm_component_ld_version 0.5.29)
if(RUST_TARGET)
set(rust_target_flag --target=${RUST_TARGET})
endif()
Expand Down
300 changes: 300 additions & 0 deletions src/llvm-pr-209282.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 99dfaa80be42..b0fb3b4d85d1 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -265,8 +265,14 @@ const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {

static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM,
const EHPersonality &Personality) {
- return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
- Personality.PersonalityFn,
+ llvm::FunctionType *FTy;
+
+ if (Personality.isWasmPersonality()) {
+ FTy = llvm::FunctionType::get(CGM.Int32Ty, {CGM.VoidPtrTy}, false);
+ } else {
+ FTy = llvm::FunctionType::get(CGM.Int32Ty, true);
+ }
+ return CGM.CreateRuntimeFunction(FTy, Personality.PersonalityFn,
llvm::AttributeList(), /*Local=*/true);
}

diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp
index c5050e46c0e8..3fdcd8a0c134 100644
--- a/libcxxabi/src/cxa_personality.cpp
+++ b/libcxxabi/src/cxa_personality.cpp
@@ -1011,9 +1011,7 @@ static inline void get_landing_pad(__cxa_catch_temp_type &dest,
#endif
}

-#ifdef __WASM_EXCEPTIONS__
-_Unwind_Reason_Code __gxx_personality_wasm0
-#elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+#if (defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)) || defined(__WASM_EXCEPTIONS__)
static _Unwind_Reason_Code __gxx_personality_imp
#else
_LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
@@ -1114,6 +1112,20 @@ __gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
}
#endif

+#ifdef __WASM_EXCEPTIONS__
+extern "C" _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code __gxx_wasm_personality_v0(void* exception_ptr) {
+ struct _Unwind_Exception* exception_object = (struct _Unwind_Exception*)exception_ptr;
+
+ // Reset the selector.
+ __wasm_lpad_context.selector = 0;
+
+ // Call personality function. Wasm does not have two-phase unwinding, so we
+ // only do the search phase.
+ return __gxx_personality_imp(1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
+ (struct _Unwind_Context*)&__wasm_lpad_context);
+}
+#endif
+
#else

extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*);
diff --git a/libunwind/include/unwind.h b/libunwind/include/unwind.h
index b1775d3a3dec..93a9d92f327d 100644
--- a/libunwind/include/unwind.h
+++ b/libunwind/include/unwind.h
@@ -61,6 +61,10 @@ typedef struct _Unwind_Context _Unwind_Context; // opaque
#include <unwind_itanium.h>
#endif

+#if defined(__WASM_EXCEPTIONS__)
+#include <unwind_wasm.h>
+#endif
+
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
(int version,
_Unwind_Action actions,
diff --git a/libunwind/include/unwind_wasm.h b/libunwind/include/unwind_wasm.h
new file mode 100644
index 000000000000..7bf3f30562bd
--- /dev/null
+++ b/libunwind/include/unwind_wasm.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 __WASM_UNWIND_H__
+#define __WASM_UNWIND_H__
+
+#include <threads.h>
+
+struct _Unwind_LandingPadContext {
+ // Input information to personality function
+ uintptr_t lpad_index; // landing pad index
+ uintptr_t lsda; // LSDA address
+
+ // Output information computed by personality function
+ uintptr_t selector; // selector value
+};
+
+// Communication channel between compiler-generated user code and personality
+// function
+extern thread_local struct _Unwind_LandingPadContext __wasm_lpad_context;
+
+#endif // __WASM_UNWIND_H__
diff --git a/libunwind/src/Unwind-wasm.c b/libunwind/src/Unwind-wasm.c
index 2e949d005b8f..963019ea0efc 100644
--- a/libunwind/src/Unwind-wasm.c
+++ b/libunwind/src/Unwind-wasm.c
@@ -19,46 +19,8 @@
#include "unwind.h"
#include <threads.h>

-_Unwind_Reason_Code __gxx_personality_wasm0(int version, _Unwind_Action actions,
- uint64_t exceptionClass,
- _Unwind_Exception *unwind_exception,
- _Unwind_Context *context);
-
-struct _Unwind_LandingPadContext {
- // Input information to personality function
- uintptr_t lpad_index; // landing pad index
- uintptr_t lsda; // LSDA address
-
- // Output information computed by personality function
- uintptr_t selector; // selector value
-};
-
-// Communication channel between compiler-generated user code and personality
-// function
-thread_local struct _Unwind_LandingPadContext __wasm_lpad_context;
-
-/// Calls to this function are in landing pads in compiler-generated user code.
-/// In other EH schemes, stack unwinding is done by libunwind library, which
-/// calls the personality function for each frame it lands. On the other hand,
-/// WebAssembly stack unwinding process is performed by a VM, and the
-/// personality function cannot be called from there. So the compiler inserts a
-/// call to this function in landing pads in the user code, which in turn calls
-/// the personality function.
-_Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
- struct _Unwind_Exception *exception_object =
- (struct _Unwind_Exception *)exception_ptr;
- _LIBUNWIND_TRACE_API("_Unwind_CallPersonality(exception_object=%p)",
- (void *)exception_object);
-
- // Reset the selector.
- __wasm_lpad_context.selector = 0;
-
- // Call personality function. Wasm does not have two-phase unwinding, so we
- // only do the search phase.
- return __gxx_personality_wasm0(
- 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
- (struct _Unwind_Context *)&__wasm_lpad_context);
-}
+_LIBUNWIND_EXPORT thread_local struct _Unwind_LandingPadContext
+ __wasm_lpad_context;

/// Called by __cxa_throw.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index d5f38b9674cd..68fe561bb606 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -1681,9 +1681,6 @@ defset list<RuntimeLibcallImpl> SjLjExceptionHandlingLibcalls = {
def _Unwind_SjLj_Unregister : RuntimeLibcallImpl<UNWIND_UNREGISTER>;
}

-// Only used on wasm?
-def _Unwind_CallPersonality : RuntimeLibcallImpl<UNWIND_CALL_PERSONALITY>;
-
// Used on OpenBSD
def __stack_smash_handler : RuntimeLibcallImpl<STACK_SMASH_HANDLER>;

@@ -3399,7 +3396,6 @@ def WasmSystemLibrary
(add DefaultRuntimeLibcallImpls, Int128RTLibcalls,
CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls,
exp10f, exp10,
- _Unwind_CallPersonality,
emscripten_return_address,
LibcallImpls<(add __small_printf,
__small_sprintf,
diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp
index b83bcf67716f..e4da22274e69 100644
--- a/llvm/lib/CodeGen/WasmEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp
@@ -28,7 +28,7 @@
// wasm.landingpad.index(index);
// __wasm_lpad_context.lpad_index = index;
// __wasm_lpad_context.lsda = wasm.lsda();
-// _Unwind_CallPersonality(exn);
+// personality_fn(exn);
// selector = __wasm_lpad_context.selector;
// ...
//
@@ -39,9 +39,9 @@
// transfered to WebAssembly 'catch' instruction.
//
// Unwinding the stack is not done by libunwind but the VM, so the personality
-// function in libcxxabi cannot be called from libunwind during the unwinding
-// process. So after a catch instruction, we insert a call to a wrapper function
-// in libunwind that in turn calls the real personality function.
+// function (e.g. in libcxxabi) cannot be called from libunwind during the
+// unwinding process. So after a catch instruction, we insert a direct call to
+// the personality instead.
//
// In Itanium EH, if the personality function decides there is no matching catch
// clause in a call frame and no cleanup action to perform, the unwinder doesn't
@@ -49,7 +49,7 @@
// every call frame with a catch intruction, after which the personality
// function is called from the compiler-generated user code here.
//
-// In libunwind, we have this struct that serves as a communincation channel
+// In libunwind, we have this struct that serves as a communication channel
// between the compiler-generated user code and the personality function in
// libcxxabi.
//
@@ -60,20 +60,8 @@
// };
// struct _Unwind_LandingPadContext __wasm_lpad_context = ...;
//
-// And this wrapper in libunwind calls the personality function.
-//
-// _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
-// struct _Unwind_Exception *exception_obj =
-// (struct _Unwind_Exception *)exception_ptr;
-// _Unwind_Reason_Code ret = __gxx_personality_v0(
-// 1, _UA_CLEANUP_PHASE, exception_obj->exception_class, exception_obj,
-// (struct _Unwind_Context *)__wasm_lpad_context);
-// return ret;
-// }
-//
// We pass a landing pad index, and the address of LSDA for the current function
-// to the wrapper function _Unwind_CallPersonality in libunwind, and we retrieve
-// the selector after it returns.
+// to the personality function, and we retrieve the selector after it returns.
//
//===----------------------------------------------------------------------===//

@@ -111,8 +99,7 @@ class WasmEHPrepareImpl {
Function *GetExnF = nullptr; // wasm.get.exception() intrinsic
Function *CatchF = nullptr; // wasm.catch() intrinsic
Function *GetSelectorF = nullptr; // wasm.get.ehselector() intrinsic
- FunctionCallee CallPersonalityF =
- nullptr; // _Unwind_CallPersonality() wrapper
+ FunctionCallee PersonalityF = nullptr;

bool prepareThrows(Function &F);
bool prepareEHPads(Function &F);
@@ -235,11 +222,14 @@ bool WasmEHPrepareImpl::prepareEHPads(Function &F) {
if (CatchPads.empty() && CleanupPads.empty())
return false;

- if (!F.hasPersonalityFn() ||
- !isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
+ if (!F.hasPersonalityFn())
+ return false;
+
+ auto Personality = classifyEHPersonality(F.getPersonalityFn());
+
+ if (!isScopedEHPersonality(Personality)) {
report_fatal_error("Function '" + F.getName() +
- "' does not have a correct Wasm personality function "
- "'__gxx_wasm_personality_v0'");
+ "' does not have a supported Wasm personality function");
}
assert(F.hasPersonalityFn() && "Personality function not found");

@@ -274,15 +264,12 @@ bool WasmEHPrepareImpl::prepareEHPads(Function &F) {
// instruction selection.
CatchF = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::wasm_catch);

- // FIXME: Verify this is really supported for current module.
- StringRef UnwindCallPersonalityName =
- RTLIB::RuntimeLibcallsInfo::getLibcallImplName(
- RTLIB::impl__Unwind_CallPersonality);
+ auto *PersPrototype =
+ FunctionType::get(IRB.getInt32Ty(), {IRB.getPtrTy()}, false);
+ PersonalityF =
+ M.getOrInsertFunction(getEHPersonalityName(Personality), PersPrototype);

- // _Unwind_CallPersonality() wrapper function, which calls the personality
- CallPersonalityF = M.getOrInsertFunction(UnwindCallPersonalityName,
- IRB.getInt32Ty(), IRB.getPtrTy());
- if (Function *F = dyn_cast<Function>(CallPersonalityF.getCallee()))
+ if (Function *F = dyn_cast<Function>(PersonalityF.getCallee()))
F->setDoesNotThrow();

unsigned Index = 0;
@@ -367,9 +354,9 @@ void WasmEHPrepareImpl::prepareEHPad(BasicBlock *BB, bool NeedPersonality,
// Pseudocode: __wasm_lpad_context.lsda = wasm.lsda();
IRB.CreateStore(IRB.CreateCall(LSDAF), LSDAField);

- // Pseudocode: _Unwind_CallPersonality(exn);
- CallInst *PersCI = IRB.CreateCall(CallPersonalityF, CatchCI,
- OperandBundleDef("funclet", CPI));
+ // Pseudocode: personality_fn(exn);
+ CallInst *PersCI =
+ IRB.CreateCall(PersonalityF, CatchCI, OperandBundleDef("funclet", CPI));
PersCI->setDoesNotThrow();

// Pseudocode: int selector = __wasm_lpad_context.selector;
14 changes: 14 additions & 0 deletions src/llvm-pr-215413.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 740e8878c6e03..da5a5d6092c1e 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -1004,6 +1004,9 @@ static void createSyntheticSymbols() {
ctx.sym.getTLSBase =
createUndefinedFunction("__wasm_get_tls_base", &getTLSBaseSignature);
ctx.sym.getTLSBase->markLive();
+ ctx.arg.exportedSymbols.insert(ctx.sym.tlsSize->getName());
+ ctx.arg.exportedSymbols.insert(ctx.sym.tlsAlign->getName());
+ ctx.arg.exportedSymbols.insert(ctx.sym.initTLS->getName());
}
}
}
2 changes: 1 addition & 1 deletion src/wasi-libc
Submodule wasi-libc updated 67 files
+1 −1 .github/workflows/main.yml
+12 −1 CMakeLists.txt
+1 −0 cmake/ba-download.cmake
+2 −1 cmake/scripts/run-check-symbols.cmake
+20 −1 cmake/wasm-component-ld.cmake
+1 −1 cmake/wasm-tools.cmake
+0 −1 expected/wasm32-wasip1-threads/include-all.c
+0 −2 expected/wasm32-wasip1-threads/predefined-macros.txt
+0 −2 expected/wasm32-wasip1-threads/undefined-symbols.txt
+0 −1 expected/wasm32-wasip1/include-all.c
+0 −2 expected/wasm32-wasip1/predefined-macros.txt
+1 −0 expected/wasm32-wasip2/defined-symbols.txt
+0 −1 expected/wasm32-wasip2/include-all.c
+0 −2 expected/wasm32-wasip2/predefined-macros.txt
+1 −0 expected/wasm32-wasip2/undefined-symbols.txt
+2 −1 expected/wasm32-wasip3-coop/defined-symbols.txt
+0 −1 expected/wasm32-wasip3-coop/include-all.c
+2 −4 expected/wasm32-wasip3-coop/predefined-macros.txt
+2 −2 expected/wasm32-wasip3-coop/undefined-symbols.txt
+1 −0 expected/wasm32-wasip3/defined-symbols.txt
+0 −1 expected/wasm32-wasip3/include-all.c
+2 −4 expected/wasm32-wasip3/predefined-macros.txt
+1 −1 libc-bottom-half/CMakeLists.txt
+3 −0 libc-bottom-half/cloudlibc/src/libc/errno/errno.c
+1 −4 libc-bottom-half/cloudlibc/src/libc/stdlib/_Exit.c
+5 −5 libc-bottom-half/cloudlibc/src/libc/unistd/pread.c
+2 −10 libc-bottom-half/crt/crt1-command.c
+1 −10 libc-bottom-half/crt/crt1-reactor.c
+49 −0 libc-bottom-half/crt/wasip3_symbol_references.h
+0 −15 libc-bottom-half/headers/public/__errno.h
+88 −105 libc-bottom-half/headers/public/wasi/__generated_wasip2.h
+19 −7 libc-bottom-half/sources/__cabi_realloc_wrapper.S
+5 −0 libc-bottom-half/sources/__errno_location.c
+0 −73 libc-bottom-half/sources/__libcall_thread_context.S
+6 −6 libc-bottom-half/sources/__wasm_init_task.S
+0 −1 libc-bottom-half/sources/isatty.c
+7 −0 libc-bottom-half/sources/netdb.c
+167 −160 libc-bottom-half/sources/wasip2.c
+ libc-bottom-half/sources/wasip2_component_type.o
+23 −0 libc-bottom-half/sources/wasip3_tls.c
+48 −0 libc-top-half/headers/private/wasi/wasip3_tls.h
+10 −2 libc-top-half/musl/include/errno.h
+2 −1 libc-top-half/musl/include/netdb.h
+0 −39 libc-top-half/musl/src/env/__init_tls.c
+142 −28 libc-top-half/musl/src/thread/coop-threads/pthread_create.c
+134 −7 test/CMakeLists.txt
+5 −0 test/entrypoint.wit
+28 −0 test/src/external_entrypoint_pthread_tls.c
+216 −0 test/src/multi_tls.c
+47 −0 test/src/pread.c
+32 −0 test/src/shared/tls_a.c
+16 −0 test/src/shared/tls_a.h
+22 −0 test/src/shared/tls_b.c
+18 −0 test/src/shared/tls_b.h
+9 −0 test/src/shared/tls_none.c
+8 −0 test/src/shared/tls_none.h
+0 −159 wasi/p2/wit/deps/wasi-cli-0.2.0/package.wit
+233 −0 wasi/p2/wit/deps/wasi-cli-0.2.12/package.wit
+0 −90 wasi/p2/wit/deps/wasi-clocks-0.2.0/package.wit
+162 −0 wasi/p2/wit/deps/wasi-clocks-0.2.12/package.wit
+77 −23 wasi/p2/wit/deps/wasi-filesystem-0.2.12/package.wit
+231 −69 wasi/p2/wit/deps/wasi-http-0.2.12/package.wit
+62 −55 wasi/p2/wit/deps/wasi-io-0.2.12/package.wit
+13 −1 wasi/p2/wit/deps/wasi-random-0.2.12/package.wit
+143 −27 wasi/p2/wit/deps/wasi-sockets-0.2.12/package.wit
+7 −7 wasi/p2/wit/wasi-libc.wit
+21 −21 wasi/p2/wkg.lock
Loading
Loading