From 1ec6f5ddf0919dcf10d242014582e986c0de9e10 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 21 Aug 2023 16:19:29 -0700 Subject: [PATCH 1/2] Update libunwind to llvm 16.0.6 Drive-by update of libcxx version number to 160006 to make all library versions consistent at 16.0.6. 16.0.4->16.0.6 doesn't have any other changes in other libraries. --- libcxx/include/__config | 2 +- libunwind/include/unwind_itanium.h | 2 +- libunwind/src/Unwind-wasm.c | 110 +++++++++++++++++++++++++++++ libunwind/src/config.h | 1 + 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 libunwind/src/Unwind-wasm.c diff --git a/libcxx/include/__config b/libcxx/include/__config index 663774b0da38a..e2d5ccdada1ac 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -38,7 +38,7 @@ // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM. // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is // defined to XXYYZZ. -# define _LIBCPP_VERSION 160004 +# define _LIBCPP_VERSION 160006 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) diff --git a/libunwind/include/unwind_itanium.h b/libunwind/include/unwind_itanium.h index d94a6183be290..4a15eb2a36e43 100644 --- a/libunwind/include/unwind_itanium.h +++ b/libunwind/include/unwind_itanium.h @@ -24,7 +24,7 @@ struct _Unwind_Exception { _Unwind_Exception *exc); #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) uintptr_t private_[6]; -#else +#elif !defined(__USING_WASM_EXCEPTIONS__) // XXX EMSCRIPTEN uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use #endif diff --git a/libunwind/src/Unwind-wasm.c b/libunwind/src/Unwind-wasm.c new file mode 100644 index 0000000000000..daa7d093d72af --- /dev/null +++ b/libunwind/src/Unwind-wasm.c @@ -0,0 +1,110 @@ +#include "config.h" +#include "unwind.h" +#include +#include + +#ifdef __USING_WASM_EXCEPTIONS__ + +_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 is 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 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 cleanup phase. + _Unwind_Reason_Code ret = __gxx_personality_wasm0( + 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, + (struct _Unwind_Context *)&__wasm_lpad_context); + return ret; +} + +/// Called by __cxa_throw. +_LIBUNWIND_EXPORT _Unwind_Reason_Code +_Unwind_RaiseException(_Unwind_Exception *exception_object) { + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(exception_object=%p)", + (void *)exception_object); + __builtin_wasm_throw(0, exception_object); +} + +/// Called by __cxa_end_catch. +_LIBUNWIND_EXPORT void +_Unwind_DeleteException(_Unwind_Exception *exception_object) { + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", + (void *)(exception_object)); + if (exception_object->exception_cleanup != NULL) + (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, + exception_object); +} + +/// Called by personality handler to alter register values. +_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, + uintptr_t value) { + _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, index=%d, value=%lu)", + (void *)context, index, value); + // We only use this function to set __wasm_lpad_context.selector field, which + // is index 1 in the personality function. + if (index != 1) + return; + ((struct _Unwind_LandingPadContext *)context)->selector = value; +} + +/// Called by personality handler to get instruction pointer. +_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { + // The result will be used as an 1-based index after decrementing 1, so we + // increment 2 here + uintptr_t result = + ((struct _Unwind_LandingPadContext *)context)->lpad_index + 2; + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => %lu", (void *)context, + result); + return result; +} + +/// Not used in wasm. +_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, + uintptr_t value) {} + +/// Called by personality handler to get LSDA for current frame. +_LIBUNWIND_EXPORT uintptr_t +_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { + uintptr_t result = ((struct _Unwind_LandingPadContext *)context)->lsda; + _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) => 0x%lx", + (void *)context, result); + return result; +} + +/// Not used in wasm. +_LIBUNWIND_EXPORT uintptr_t +_Unwind_GetRegionStart(struct _Unwind_Context *context) { + return 0; +} + +#endif diff --git a/libunwind/src/config.h b/libunwind/src/config.h index 4bbac951624f9..bc7af06ff0888 100644 --- a/libunwind/src/config.h +++ b/libunwind/src/config.h @@ -98,6 +98,7 @@ SYMBOL_NAME(name))) \ extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; #endif +#elif defined(__EMSCRIPTEN__) // XXX EMSCRIPTEN #else #error Unsupported target #endif From 569fac8a663d37b0724ba96a2e6152e00820b135 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 21 Aug 2023 16:31:54 -0700 Subject: [PATCH 2/2] Remove "XXX EMSCRIPTEN" --- libunwind/include/unwind_itanium.h | 2 +- libunwind/src/config.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libunwind/include/unwind_itanium.h b/libunwind/include/unwind_itanium.h index 4a15eb2a36e43..ffa46ed9fdc1b 100644 --- a/libunwind/include/unwind_itanium.h +++ b/libunwind/include/unwind_itanium.h @@ -24,7 +24,7 @@ struct _Unwind_Exception { _Unwind_Exception *exc); #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) uintptr_t private_[6]; -#elif !defined(__USING_WASM_EXCEPTIONS__) // XXX EMSCRIPTEN +#elif !defined(__USING_WASM_EXCEPTIONS__) uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use #endif diff --git a/libunwind/src/config.h b/libunwind/src/config.h index bc7af06ff0888..c7584edc34438 100644 --- a/libunwind/src/config.h +++ b/libunwind/src/config.h @@ -98,7 +98,7 @@ SYMBOL_NAME(name))) \ extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; #endif -#elif defined(__EMSCRIPTEN__) // XXX EMSCRIPTEN +#elif defined(__EMSCRIPTEN__) #else #error Unsupported target #endif