llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libcxxabi Author: cqwrteur (trcrsired) <details> <summary>Changes</summary> 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. --- 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: - (modified) compiler-rt/lib/builtins/fp_compare_impl.inc (+1-1) - (modified) libcxx/include/__exception/exception_ptr.h (+10-11) - (modified) libcxxabi/include/cxxabi.h (+55-79) - (modified) libcxxabi/src/cxa_exception.cpp (+307-403) - (modified) libcxxabi/src/cxa_exception.h (+1-6) - (modified) libunwind/include/libunwind.h (+2) - (modified) libunwind/src/Unwind-wasm.c (+5-8) - (modified) libunwind/src/UnwindRegistersRestore.S (+2-1) - (modified) libunwind/src/UnwindRegistersSave.S (+3) - (modified) libunwind/src/assembly.h (+2) - (modified) libunwind/src/config.h (+8-7) - (modified) libunwind/src/libunwind.cpp (+2) - (modified) libunwind/src/libunwind_ext.h (+2) - (modified) libunwind/src/shadow_stack_unwind.h (+3) ``````````diff 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] `````````` </details> https://github.com/llvm/llvm-project/pull/140365 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits