-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[libunwind][libcxx][libcxxabi] Fix Exception Handling build for wasm #140365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The wasm unwind build appears to be dysfunctional, likely because the author has only supplied a customized LLVM build on request, rather than a fully functional patch. This patch fixes the build Apply formatting patch proposed by github bot use "" to prevent CMAKE_SYSTEM_PROCESSOR not defined [libunwind] logAPI functions should also be built [libcxxabi] Fix function signatures for wasm wasm does not define the function signatures correctly for cxxabi Fix them Fix formatting issues for libcxxabi's wasm eh change Merge remote-tracking branch 'parent/main' into wasmlibunwindfix remove unwanted changes in unwind-wasm.c Make Unwind-wasm.c compile correctly without workaround in CMakeLists.txt using __wasm__ macro to guard against all wasm eh build fix UnwindLevel.c's formatting issue ISO C requires a translation unit to contain at least one declaration [-Werror,-Wempty-translation-unit] compiler-rt does not define CMP_RESULT correct on wasm64 Fixed Merge code
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-libcxx @llvm/pr-subscribers-libcxxabi Author: cqwrteur (trcrsired) ChangesThe wasm unwind build appears to be dysfunctional, likely because the author has only supplied a customized LLVM build on request, rather than a fully functional patch. Patch is 63.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140365.diff 14 Files Affected:
diff --git a/compiler-rt/lib/builtins/fp_compare_impl.inc b/compiler-rt/lib/builtins/fp_compare_impl.inc
index f883338c471d3..fa1629fc1a07a 100644
--- a/compiler-rt/lib/builtins/fp_compare_impl.inc
+++ b/compiler-rt/lib/builtins/fp_compare_impl.inc
@@ -12,7 +12,7 @@
// functions. We need to ensure that the return value is sign-extended in the
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
// returns true for finite 128-bit floating-point numbers).
-#if defined(__aarch64__) || defined(__arm64ec__)
+#if defined(__aarch64__) || defined(__arm64ec__) || defined(__wasm__)
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
typedef int CMP_RESULT;
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index b1fe9a1299ec7..6b1e9f09c95d2 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -28,22 +28,21 @@
namespace __cxxabiv1 {
+# if defined(__wasm__)
+typedef void* (*__libcpp_exception_destructor_func)(void*);
+# elif defined(_WIN32)
+typedef void(__thiscall* __libcpp_exception_destructor_func)(void*);
+# else
+typedef void (*__libcpp_exception_destructor_func)(void*);
+# endif
+
extern "C" {
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw();
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();
struct __cxa_exception;
-_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(
- void*,
- std::type_info*,
-# if defined(_WIN32)
- void(__thiscall*)(void*)) throw();
-# elif defined(__wasm__)
- // In Wasm, a destructor returns its argument
- void* (*)(void*)) throw();
-# else
- void (*)(void*)) throw();
-# endif
+_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception*
+__cxa_init_primary_exception(void*, std::type_info*, __libcpp_exception_destructor_func) throw();
}
} // namespace __cxxabiv1
diff --git a/libcxxabi/include/cxxabi.h b/libcxxabi/include/cxxabi.h
index 9ea93680f62e0..cf0cc40ff42b9 100644
--- a/libcxxabi/include/cxxabi.h
+++ b/libcxxabi/include/cxxabi.h
@@ -20,49 +20,41 @@
#include <__cxxabi_config.h>
#define _LIBCPPABI_VERSION 15000
-#define _LIBCXXABI_NORETURN __attribute__((noreturn))
+#define _LIBCXXABI_NORETURN __attribute__((noreturn))
#define _LIBCXXABI_ALWAYS_COLD __attribute__((cold))
#ifdef __cplusplus
namespace std {
-#if defined(_WIN32)
+# if defined(_WIN32)
class _LIBCXXABI_TYPE_VIS type_info; // forward declaration
-#else
+# else
class type_info; // forward declaration
-#endif
-}
-
+# endif
+} // namespace std
// runtime routines use C calling conventions, but are in __cxxabiv1 namespace
namespace __cxxabiv1 {
struct __cxa_exception;
+# if defined(__wasm__)
+typedef void* (*__libcxxabi_exception_destructor_func)(void*);
+# else
+typedef void(_LIBCXXABI_DTOR_FUNC* __libcxxabi_exception_destructor_func)(void*);
+# endif
-extern "C" {
+extern "C" {
// 2.4.2 Allocating the Exception Object
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_free_exception(void *thrown_exception) _LIBCXXABI_NOEXCEPT;
+extern _LIBCXXABI_FUNC_VIS void* __cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
+extern _LIBCXXABI_FUNC_VIS void __cxa_free_exception(void* thrown_exception) _LIBCXXABI_NOEXCEPT;
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
-extern _LIBCXXABI_FUNC_VIS __cxa_exception*
-#ifdef __wasm__
-// In Wasm, a destructor returns its argument
-__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
-#else
-__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
-#endif
+extern _LIBCXXABI_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(void* object, std::type_info* tinfo,
+ __libcxxabi_exception_destructor_func) _LIBCXXABI_NOEXCEPT;
// 2.4.3 Throwing the Exception Object
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
-__cxa_throw(void *thrown_exception, std::type_info *tinfo,
-#ifdef __wasm__
- void *(_LIBCXXABI_DTOR_FUNC *dest)(void *));
-#else
- void (_LIBCXXABI_DTOR_FUNC *dest)(void *));
-#endif
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw(void* thrown_exception, std::type_info* tinfo,
+ __libcxxabi_exception_destructor_func);
// 2.5.3 Exception Handlers
extern _LIBCXXABI_FUNC_VIS void *
@@ -74,8 +66,8 @@ extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
extern _LIBCXXABI_FUNC_VIS bool
__cxa_begin_cleanup(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup();
-#endif
-extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
+# endif
+extern _LIBCXXABI_FUNC_VIS std::type_info* __cxa_current_exception_type();
// GNU extension
// Calls `terminate` with the current exception being caught. This function is used by GCC when a `noexcept` function
@@ -88,8 +80,7 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow();
// 2.6 Auxiliary Runtime APIs
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_cast(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_typeid(void);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
-__cxa_throw_bad_array_new_length(void);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw_bad_array_new_length(void);
// 3.2.6 Pure Virtual Function API
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
@@ -98,63 +89,49 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
// 3.3.2 One-time Construction API
-#if defined(_LIBCXXABI_GUARD_ABI_ARM)
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t *);
-#else
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t *);
-#endif
+# if defined(_LIBCXXABI_GUARD_ABI_ARM)
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t*);
+# else
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t*);
+# endif
// 3.3.3 Array Construction and Destruction API
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size,
- void (*constructor)(void *), void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size,
+ void (*constructor)(void*), void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size,
- void (*constructor)(void *), void (*destructor)(void *),
- void *(*alloc)(size_t), void (*dealloc)(void *));
+extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size,
+ void (*constructor)(void*), void (*destructor)(void*),
+ void* (*alloc)(size_t), void (*dealloc)(void*));
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size,
- void (*constructor)(void *), void (*destructor)(void *),
- void *(*alloc)(size_t), void (*dealloc)(void *, size_t));
+extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size,
+ void (*constructor)(void*), void (*destructor)(void*),
+ void* (*alloc)(size_t), void (*dealloc)(void*, size_t));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_ctor(void *array_address, size_t element_count, size_t element_size,
- void (*constructor)(void *), void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_ctor(void* array_address, size_t element_count, size_t element_size,
+ void (*constructor)(void*), void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void *array_address,
- size_t element_count,
- size_t element_size,
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void* array_address, size_t element_count, size_t element_size,
+ void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void *array_address,
- size_t element_count,
- size_t element_size,
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void* array_address, size_t element_count, size_t element_size,
+ void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void *array_address,
- size_t element_size,
- size_t padding_size,
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void* array_address, size_t element_size, size_t padding_size,
+ void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_delete2(void *array_address, size_t element_size, size_t padding_size,
- void (*destructor)(void *), void (*dealloc)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete2(void* array_address, size_t element_size, size_t padding_size,
+ void (*destructor)(void*), void (*dealloc)(void*));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_delete3(void *__array_address, size_t element_size,
- size_t padding_size, void (*destructor)(void *),
- void (*dealloc)(void *, size_t));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete3(void* __array_address, size_t element_size, size_t padding_size,
+ void (*destructor)(void*), void (*dealloc)(void*, size_t));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
- size_t element_size, void (*constructor)(void *, void *),
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count,
+ size_t element_size, void (*constructor)(void*, void*),
+ void (*destructor)(void*));
// 3.3.5.3 Runtime API
// These functions are part of the C++ ABI, but they are not defined in libc++abi:
@@ -162,9 +139,8 @@ __cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
// void __cxa_finalize(void *);
// 3.4 Demangler API
-extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
- char *output_buffer,
- size_t *length, int *status);
+extern _LIBCXXABI_FUNC_VIS char* __cxa_demangle(const char* mangled_name, char* output_buffer, size_t* length,
+ int* status);
// Apple additions to support C++ 0x exception_ptr class
// These are primitives to wrap a smart pointer around an exception object
@@ -180,7 +156,7 @@ __cxa_decrement_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _LIBCXXABI_NOEXCEPT;
-#if defined(__linux__) || defined(__Fuchsia__)
+# if defined(__linux__) || defined(__Fuchsia__)
// Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *,
diff --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp
index 92901a83bfd03..7eae8bbccf092 100644
--- a/libcxxabi/src/cxa_exception.cpp
+++ b/libcxxabi/src/cxa_exception.cpp
@@ -12,15 +12,15 @@
#include "cxxabi.h"
-#include <exception> // for std::terminate
-#include <string.h> // for memset
+#include <exception> // for std::terminate
+#include <string.h> // for memset
#include "cxa_exception.h"
#include "cxa_handlers.h"
#include "fallback_malloc.h"
#include "include/atomic_support.h" // from libc++
#if __has_feature(address_sanitizer)
-#include <sanitizer/asan_interface.h>
+# include <sanitizer/asan_interface.h>
#endif
// +---------------------------+-----------------------------+---------------+
@@ -37,89 +37,67 @@
namespace __cxxabiv1 {
// Utility routines
-static
-inline
-__cxa_exception*
-cxa_exception_from_thrown_object(void* thrown_object)
-{
- return static_cast<__cxa_exception*>(thrown_object) - 1;
+static inline __cxa_exception* cxa_exception_from_thrown_object(void* thrown_object) {
+ return static_cast<__cxa_exception*>(thrown_object) - 1;
}
// Note: This is never called when exception_header is masquerading as a
// __cxa_dependent_exception.
-static
-inline
-void*
-thrown_object_from_cxa_exception(__cxa_exception* exception_header)
-{
- return static_cast<void*>(exception_header + 1);
+static inline void* thrown_object_from_cxa_exception(__cxa_exception* exception_header) {
+ return static_cast<void*>(exception_header + 1);
}
// Get the exception object from the unwind pointer.
// Relies on the structure layout, where the unwind pointer is right in
// front of the user's exception object
-static
-inline
-__cxa_exception*
-cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception)
-{
- return cxa_exception_from_thrown_object(unwind_exception + 1 );
+static inline __cxa_exception* cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception) {
+ return cxa_exception_from_thrown_object(unwind_exception + 1);
}
// Round s up to next multiple of a.
-static inline
-size_t aligned_allocation_size(size_t s, size_t a) {
- return (s + a - 1) & ~(a - 1);
-}
+static inline size_t aligned_allocation_size(size_t s, size_t a) { return (s + a - 1) & ~(a - 1); }
-static inline
-size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
- return aligned_allocation_size(size + sizeof (__cxa_exception),
- alignof(__cxa_exception));
+static inline size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
+ return aligned_allocation_size(size + sizeof(__cxa_exception), alignof(__cxa_exception));
}
void __setExceptionClass(_Unwind_Exception* unwind_exception, uint64_t newValue) {
- ::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
+ ::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
}
-
static void setOurExceptionClass(_Unwind_Exception* unwind_exception) {
- __setExceptionClass(unwind_exception, kOurExceptionClass);
+ __setExceptionClass(unwind_exception, kOurExceptionClass);
}
static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {
- __setExceptionClass(unwind_exception, kOurDependentExceptionClass);
+ __setExceptionClass(unwind_exception, kOurDependentExceptionClass);
}
// Is it one of ours?
uint64_t __getExceptionClass(const _Unwind_Exception* unwind_exception) {
- // On x86 and some ARM unwinders, unwind_exception->exception_class is
- // a uint64_t. On other ARM unwinders, it is a char[8].
- // See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
- // So we just copy it into a uint64_t to be sure.
- uint64_t exClass;
- ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
- return exClass;
+ // On x86 and some ARM unwinders, unwind_exception->exception_class is
+ // a uint64_t. On other ARM unwinders, it is a char[8].
+ // See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
+ // So we just copy it into a uint64_t to be sure.
+ uint64_t exClass;
+ ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
+ return exClass;
}
bool __isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
- return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
- (kOurExceptionClass & get_vendor_and_language);
+ return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
+ (kOurExceptionClass & get_vendor_and_language);
}
static bool isDependentException(_Unwind_Exception* unwind_exception) {
- return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
+ return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
}
// This does not need to be atomic
-static inline int incrementHandlerCount(__cxa_exception *exception) {
- return ++exception->handlerCount;
-}
+static inline int incrementHandlerCount(__cxa_exception* exception) { return ++exception->handlerCount; }
// This does not need to be atomic
-static inline int decrementHandlerCount(__cxa_exception *exception) {
- return --exception->handlerCount;
-}
+static inline int decrementHandlerCount(__cxa_exception* exception) { return --exception->handlerCount; }
/*
If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
@@ -128,28 +106,25 @@ static inline int decrementHandlerCount(__cxa_exception *exception) {
This is never called for a __cxa_dependent_exception.
*/
-static
-void
-exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)
-{
- __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);
- if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
- std::__terminate(exception_header->terminateHandler);
- // Just in case there exists a dependent exception that is pointing to this,
- // check the reference count and only destroy this if that count goes to zero.
- __cxa_decrement_exception_refcount(unwind_exception + 1);
+static void exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception) {
+ __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);
+ if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
+ std::__terminate(exception_header->terminateHandler);
+ // Just in case there exists a dependent exception that is pointing to this,
+ // check the reference count and only destroy this if that count goes to zero.
+ __cxa_decrement_exception_refcount(unwind_exception + 1);
}
static _LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) {
-// Section 2.5.3 says:
-// * For purposes of this ABI, several...
[truncated]
|
@llvm/pr-subscribers-libunwind Author: cqwrteur (trcrsired) ChangesThe wasm unwind build appears to be dysfunctional, likely because the author has only supplied a customized LLVM build on request, rather than a fully functional patch. Patch is 63.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140365.diff 14 Files Affected:
diff --git a/compiler-rt/lib/builtins/fp_compare_impl.inc b/compiler-rt/lib/builtins/fp_compare_impl.inc
index f883338c471d3..fa1629fc1a07a 100644
--- a/compiler-rt/lib/builtins/fp_compare_impl.inc
+++ b/compiler-rt/lib/builtins/fp_compare_impl.inc
@@ -12,7 +12,7 @@
// functions. We need to ensure that the return value is sign-extended in the
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
// returns true for finite 128-bit floating-point numbers).
-#if defined(__aarch64__) || defined(__arm64ec__)
+#if defined(__aarch64__) || defined(__arm64ec__) || defined(__wasm__)
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
typedef int CMP_RESULT;
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index b1fe9a1299ec7..6b1e9f09c95d2 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -28,22 +28,21 @@
namespace __cxxabiv1 {
+# if defined(__wasm__)
+typedef void* (*__libcpp_exception_destructor_func)(void*);
+# elif defined(_WIN32)
+typedef void(__thiscall* __libcpp_exception_destructor_func)(void*);
+# else
+typedef void (*__libcpp_exception_destructor_func)(void*);
+# endif
+
extern "C" {
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw();
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();
struct __cxa_exception;
-_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(
- void*,
- std::type_info*,
-# if defined(_WIN32)
- void(__thiscall*)(void*)) throw();
-# elif defined(__wasm__)
- // In Wasm, a destructor returns its argument
- void* (*)(void*)) throw();
-# else
- void (*)(void*)) throw();
-# endif
+_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception*
+__cxa_init_primary_exception(void*, std::type_info*, __libcpp_exception_destructor_func) throw();
}
} // namespace __cxxabiv1
diff --git a/libcxxabi/include/cxxabi.h b/libcxxabi/include/cxxabi.h
index 9ea93680f62e0..cf0cc40ff42b9 100644
--- a/libcxxabi/include/cxxabi.h
+++ b/libcxxabi/include/cxxabi.h
@@ -20,49 +20,41 @@
#include <__cxxabi_config.h>
#define _LIBCPPABI_VERSION 15000
-#define _LIBCXXABI_NORETURN __attribute__((noreturn))
+#define _LIBCXXABI_NORETURN __attribute__((noreturn))
#define _LIBCXXABI_ALWAYS_COLD __attribute__((cold))
#ifdef __cplusplus
namespace std {
-#if defined(_WIN32)
+# if defined(_WIN32)
class _LIBCXXABI_TYPE_VIS type_info; // forward declaration
-#else
+# else
class type_info; // forward declaration
-#endif
-}
-
+# endif
+} // namespace std
// runtime routines use C calling conventions, but are in __cxxabiv1 namespace
namespace __cxxabiv1 {
struct __cxa_exception;
+# if defined(__wasm__)
+typedef void* (*__libcxxabi_exception_destructor_func)(void*);
+# else
+typedef void(_LIBCXXABI_DTOR_FUNC* __libcxxabi_exception_destructor_func)(void*);
+# endif
-extern "C" {
+extern "C" {
// 2.4.2 Allocating the Exception Object
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_free_exception(void *thrown_exception) _LIBCXXABI_NOEXCEPT;
+extern _LIBCXXABI_FUNC_VIS void* __cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
+extern _LIBCXXABI_FUNC_VIS void __cxa_free_exception(void* thrown_exception) _LIBCXXABI_NOEXCEPT;
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
-extern _LIBCXXABI_FUNC_VIS __cxa_exception*
-#ifdef __wasm__
-// In Wasm, a destructor returns its argument
-__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
-#else
-__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
-#endif
+extern _LIBCXXABI_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(void* object, std::type_info* tinfo,
+ __libcxxabi_exception_destructor_func) _LIBCXXABI_NOEXCEPT;
// 2.4.3 Throwing the Exception Object
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
-__cxa_throw(void *thrown_exception, std::type_info *tinfo,
-#ifdef __wasm__
- void *(_LIBCXXABI_DTOR_FUNC *dest)(void *));
-#else
- void (_LIBCXXABI_DTOR_FUNC *dest)(void *));
-#endif
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw(void* thrown_exception, std::type_info* tinfo,
+ __libcxxabi_exception_destructor_func);
// 2.5.3 Exception Handlers
extern _LIBCXXABI_FUNC_VIS void *
@@ -74,8 +66,8 @@ extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
extern _LIBCXXABI_FUNC_VIS bool
__cxa_begin_cleanup(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup();
-#endif
-extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
+# endif
+extern _LIBCXXABI_FUNC_VIS std::type_info* __cxa_current_exception_type();
// GNU extension
// Calls `terminate` with the current exception being caught. This function is used by GCC when a `noexcept` function
@@ -88,8 +80,7 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow();
// 2.6 Auxiliary Runtime APIs
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_cast(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_typeid(void);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
-__cxa_throw_bad_array_new_length(void);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw_bad_array_new_length(void);
// 3.2.6 Pure Virtual Function API
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
@@ -98,63 +89,49 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);
// 3.3.2 One-time Construction API
-#if defined(_LIBCXXABI_GUARD_ABI_ARM)
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t *);
-#else
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t *);
-extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t *);
-#endif
+# if defined(_LIBCXXABI_GUARD_ABI_ARM)
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t*);
+# else
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t*);
+extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t*);
+# endif
// 3.3.3 Array Construction and Destruction API
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size,
- void (*constructor)(void *), void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size,
+ void (*constructor)(void*), void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size,
- void (*constructor)(void *), void (*destructor)(void *),
- void *(*alloc)(size_t), void (*dealloc)(void *));
+extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size,
+ void (*constructor)(void*), void (*destructor)(void*),
+ void* (*alloc)(size_t), void (*dealloc)(void*));
-extern _LIBCXXABI_FUNC_VIS void *
-__cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size,
- void (*constructor)(void *), void (*destructor)(void *),
- void *(*alloc)(size_t), void (*dealloc)(void *, size_t));
+extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size,
+ void (*constructor)(void*), void (*destructor)(void*),
+ void* (*alloc)(size_t), void (*dealloc)(void*, size_t));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_ctor(void *array_address, size_t element_count, size_t element_size,
- void (*constructor)(void *), void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_ctor(void* array_address, size_t element_count, size_t element_size,
+ void (*constructor)(void*), void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void *array_address,
- size_t element_count,
- size_t element_size,
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void* array_address, size_t element_count, size_t element_size,
+ void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void *array_address,
- size_t element_count,
- size_t element_size,
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void* array_address, size_t element_count, size_t element_size,
+ void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void *array_address,
- size_t element_size,
- size_t padding_size,
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void* array_address, size_t element_size, size_t padding_size,
+ void (*destructor)(void*));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_delete2(void *array_address, size_t element_size, size_t padding_size,
- void (*destructor)(void *), void (*dealloc)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete2(void* array_address, size_t element_size, size_t padding_size,
+ void (*destructor)(void*), void (*dealloc)(void*));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_delete3(void *__array_address, size_t element_size,
- size_t padding_size, void (*destructor)(void *),
- void (*dealloc)(void *, size_t));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete3(void* __array_address, size_t element_size, size_t padding_size,
+ void (*destructor)(void*), void (*dealloc)(void*, size_t));
-extern _LIBCXXABI_FUNC_VIS void
-__cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
- size_t element_size, void (*constructor)(void *, void *),
- void (*destructor)(void *));
+extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count,
+ size_t element_size, void (*constructor)(void*, void*),
+ void (*destructor)(void*));
// 3.3.5.3 Runtime API
// These functions are part of the C++ ABI, but they are not defined in libc++abi:
@@ -162,9 +139,8 @@ __cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
// void __cxa_finalize(void *);
// 3.4 Demangler API
-extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
- char *output_buffer,
- size_t *length, int *status);
+extern _LIBCXXABI_FUNC_VIS char* __cxa_demangle(const char* mangled_name, char* output_buffer, size_t* length,
+ int* status);
// Apple additions to support C++ 0x exception_ptr class
// These are primitives to wrap a smart pointer around an exception object
@@ -180,7 +156,7 @@ __cxa_decrement_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _LIBCXXABI_NOEXCEPT;
-#if defined(__linux__) || defined(__Fuchsia__)
+# if defined(__linux__) || defined(__Fuchsia__)
// Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *,
diff --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp
index 92901a83bfd03..7eae8bbccf092 100644
--- a/libcxxabi/src/cxa_exception.cpp
+++ b/libcxxabi/src/cxa_exception.cpp
@@ -12,15 +12,15 @@
#include "cxxabi.h"
-#include <exception> // for std::terminate
-#include <string.h> // for memset
+#include <exception> // for std::terminate
+#include <string.h> // for memset
#include "cxa_exception.h"
#include "cxa_handlers.h"
#include "fallback_malloc.h"
#include "include/atomic_support.h" // from libc++
#if __has_feature(address_sanitizer)
-#include <sanitizer/asan_interface.h>
+# include <sanitizer/asan_interface.h>
#endif
// +---------------------------+-----------------------------+---------------+
@@ -37,89 +37,67 @@
namespace __cxxabiv1 {
// Utility routines
-static
-inline
-__cxa_exception*
-cxa_exception_from_thrown_object(void* thrown_object)
-{
- return static_cast<__cxa_exception*>(thrown_object) - 1;
+static inline __cxa_exception* cxa_exception_from_thrown_object(void* thrown_object) {
+ return static_cast<__cxa_exception*>(thrown_object) - 1;
}
// Note: This is never called when exception_header is masquerading as a
// __cxa_dependent_exception.
-static
-inline
-void*
-thrown_object_from_cxa_exception(__cxa_exception* exception_header)
-{
- return static_cast<void*>(exception_header + 1);
+static inline void* thrown_object_from_cxa_exception(__cxa_exception* exception_header) {
+ return static_cast<void*>(exception_header + 1);
}
// Get the exception object from the unwind pointer.
// Relies on the structure layout, where the unwind pointer is right in
// front of the user's exception object
-static
-inline
-__cxa_exception*
-cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception)
-{
- return cxa_exception_from_thrown_object(unwind_exception + 1 );
+static inline __cxa_exception* cxa_exception_from_exception_unwind_exception(_Unwind_Exception* unwind_exception) {
+ return cxa_exception_from_thrown_object(unwind_exception + 1);
}
// Round s up to next multiple of a.
-static inline
-size_t aligned_allocation_size(size_t s, size_t a) {
- return (s + a - 1) & ~(a - 1);
-}
+static inline size_t aligned_allocation_size(size_t s, size_t a) { return (s + a - 1) & ~(a - 1); }
-static inline
-size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
- return aligned_allocation_size(size + sizeof (__cxa_exception),
- alignof(__cxa_exception));
+static inline size_t cxa_exception_size_from_exception_thrown_size(size_t size) {
+ return aligned_allocation_size(size + sizeof(__cxa_exception), alignof(__cxa_exception));
}
void __setExceptionClass(_Unwind_Exception* unwind_exception, uint64_t newValue) {
- ::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
+ ::memcpy(&unwind_exception->exception_class, &newValue, sizeof(newValue));
}
-
static void setOurExceptionClass(_Unwind_Exception* unwind_exception) {
- __setExceptionClass(unwind_exception, kOurExceptionClass);
+ __setExceptionClass(unwind_exception, kOurExceptionClass);
}
static void setDependentExceptionClass(_Unwind_Exception* unwind_exception) {
- __setExceptionClass(unwind_exception, kOurDependentExceptionClass);
+ __setExceptionClass(unwind_exception, kOurDependentExceptionClass);
}
// Is it one of ours?
uint64_t __getExceptionClass(const _Unwind_Exception* unwind_exception) {
- // On x86 and some ARM unwinders, unwind_exception->exception_class is
- // a uint64_t. On other ARM unwinders, it is a char[8].
- // See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
- // So we just copy it into a uint64_t to be sure.
- uint64_t exClass;
- ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
- return exClass;
+ // On x86 and some ARM unwinders, unwind_exception->exception_class is
+ // a uint64_t. On other ARM unwinders, it is a char[8].
+ // See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
+ // So we just copy it into a uint64_t to be sure.
+ uint64_t exClass;
+ ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass));
+ return exClass;
}
bool __isOurExceptionClass(const _Unwind_Exception* unwind_exception) {
- return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
- (kOurExceptionClass & get_vendor_and_language);
+ return (__getExceptionClass(unwind_exception) & get_vendor_and_language) ==
+ (kOurExceptionClass & get_vendor_and_language);
}
static bool isDependentException(_Unwind_Exception* unwind_exception) {
- return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
+ return (__getExceptionClass(unwind_exception) & 0xFF) == 0x01;
}
// This does not need to be atomic
-static inline int incrementHandlerCount(__cxa_exception *exception) {
- return ++exception->handlerCount;
-}
+static inline int incrementHandlerCount(__cxa_exception* exception) { return ++exception->handlerCount; }
// This does not need to be atomic
-static inline int decrementHandlerCount(__cxa_exception *exception) {
- return --exception->handlerCount;
-}
+static inline int decrementHandlerCount(__cxa_exception* exception) { return --exception->handlerCount; }
/*
If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
@@ -128,28 +106,25 @@ static inline int decrementHandlerCount(__cxa_exception *exception) {
This is never called for a __cxa_dependent_exception.
*/
-static
-void
-exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception)
-{
- __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);
- if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
- std::__terminate(exception_header->terminateHandler);
- // Just in case there exists a dependent exception that is pointing to this,
- // check the reference count and only destroy this if that count goes to zero.
- __cxa_decrement_exception_refcount(unwind_exception + 1);
+static void exception_cleanup_func(_Unwind_Reason_Code reason, _Unwind_Exception* unwind_exception) {
+ __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception);
+ if (_URC_FOREIGN_EXCEPTION_CAUGHT != reason)
+ std::__terminate(exception_header->terminateHandler);
+ // Just in case there exists a dependent exception that is pointing to this,
+ // check the reference count and only destroy this if that count goes to zero.
+ __cxa_decrement_exception_refcount(unwind_exception + 1);
}
static _LIBCXXABI_NORETURN void failed_throw(__cxa_exception* exception_header) {
-// Section 2.5.3 says:
-// * For purposes of this ABI, several...
[truncated]
|
The wasm unwind build appears to be dysfunctional, likely because the author has only supplied a customized LLVM build on request, rather than a fully functional patch.