From 189d498f5c0c633f8cd87b3f1b6d57020371a952 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Tue, 17 Dec 2019 23:33:28 +0100 Subject: [PATCH] tdf#128671: Rely on unwind.h, declare what's missing from cxxabi.h ...for gcc3_linux_aarch64, similar to what 128deeae81a6f802bfb79b8f0fa8c4b10729f7db "cxxabi.h is not specific to GCC" et al did for gcc3_linux_x86-64 Change-Id: Iee9980842c0e5f6f49642407339a67e865f8be9c Reviewed-on: https://gerrit.libreoffice.org/85344 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- .../source/cpp_uno/gcc3_linux_aarch64/abi.cxx | 7 +- .../source/cpp_uno/gcc3_linux_aarch64/abi.hxx | 117 +++++++++++++----- .../cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx | 4 +- 3 files changed, 92 insertions(+), 36 deletions(-) diff --git bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx index 938011a09a2e..892bf6e81963 100644 --- bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx +++ bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx @@ -24,7 +24,6 @@ #include #include -#include #include #include @@ -135,8 +134,8 @@ std::type_info * getRtti(typelib_TypeDescription const & type) { } extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) { - abi_aarch64::__cxa_exception * header = - static_cast(exception) - 1; + __cxxabiv1::__cxa_exception * header = + static_cast<__cxxabiv1::__cxa_exception *>(exception) - 1; OUString unoName(toUnoName(header->exceptionType->name())); typelib_TypeDescription * td = 0; typelib_typedescription_getByName(&td, unoName.pData); @@ -224,7 +223,7 @@ StructKind getStructKind(typelib_CompoundTypeDescription const * type) { namespace abi_aarch64 { void mapException( - __cxa_exception * exception, std::type_info const * type, uno_Any * any, uno_Mapping * mapping) + __cxxabiv1::__cxa_exception * exception, std::type_info const * type, uno_Any * any, uno_Mapping * mapping) { assert(exception != 0); assert(type != nullptr); diff --git bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx index 50c5f1f21a37..e3dc9b5872a7 100644 --- bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx +++ bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx @@ -22,55 +22,114 @@ #include +#include #include #include +#include +#ifndef _GLIBCXX_CDTOR_CALLABI // new in GCC 4.7 cxxabi.h +#define _GLIBCXX_CDTOR_CALLABI +#endif +#include + +#include #include #include #include -namespace abi_aarch64 { - -// Following declarations from libstdc++-v3/libsupc++/unwind-cxx.h and -// lib/gcc/*-*-*/*/include/unwind.h: - -struct _Unwind_Exception -{ - unsigned exception_class __attribute__((__mode__(__DI__))); - void * exception_cleanup; - unsigned private_1 __attribute__((__mode__(__word__))); - unsigned private_2 __attribute__((__mode__(__word__))); -} __attribute__((__aligned__)); +#if !HAVE_CXXABI_H_CLASS_TYPE_INFO +// , +// libstdc++-v3/libsupc++/cxxabi.h: +namespace __cxxabiv1 { +class __class_type_info: public std::type_info { +public: + explicit __class_type_info(char const * n): type_info(n) {} + ~__class_type_info() override; +}; +} +#endif -struct __cxa_exception -{ - std::type_info *exceptionType; - void (*exceptionDestructor)(void *); +#if !HAVE_CXXABI_H_SI_CLASS_TYPE_INFO +// , +// libstdc++-v3/libsupc++/cxxabi.h: +namespace __cxxabiv1 { +class __si_class_type_info: public __class_type_info { +public: + __class_type_info const * __base_type; + explicit __si_class_type_info( + char const * n, __class_type_info const *base): + __class_type_info(n), __base_type(base) {} + ~__si_class_type_info() override; +}; +} +#endif +#if !HAVE_CXXABI_H_CXA_EXCEPTION +// , +// libcxxabi/src/cxa_exception.hpp: +namespace __cxxabiv1 { +struct __cxa_exception { +#if defined _LIBCPPABI_VERSION // detect libc++abi +#if defined __LP64__ || LIBCXXABI_ARM_EHABI + std::size_t referenceCount; +#endif +#endif + std::type_info * exceptionType; + void (* exceptionDestructor)(void *); void (*unexpectedHandler)(); // std::unexpected_handler dropped from C++17 std::terminate_handler terminateHandler; - - __cxa_exception *nextException; - + __cxa_exception * nextException; int handlerCount; - int handlerSwitchValue; - const unsigned char *actionRecord; - const unsigned char *languageSpecificData; - void *catchTemp; - void *adjustedPtr; - + char const * actionRecord; + char const * languageSpecificData; + void * catchTemp; + void * adjustedPtr; _Unwind_Exception unwindHeader; }; +} +#endif -struct __cxa_eh_globals -{ - __cxa_exception *caughtExceptions; +#if !HAVE_CXXABI_H_CXA_EH_GLOBALS +// : +namespace __cxxabiv1 { +struct __cxa_eh_globals { + __cxa_exception * caughtExceptions; unsigned int uncaughtExceptions; }; +} +#endif + +#if !HAVE_CXXABI_H_CXA_GET_GLOBALS +namespace __cxxabiv1 { +extern "C" __cxa_eh_globals * __cxa_get_globals() throw(); +} +#endif + +#if !HAVE_CXXABI_H_CXA_CURRENT_EXCEPTION_TYPE +namespace __cxxabiv1 { +extern "C" std::type_info *__cxa_current_exception_type() throw(); +} +#endif + +#if !HAVE_CXXABI_H_CXA_ALLOCATE_EXCEPTION +namespace __cxxabiv1 { +extern "C" void * __cxa_allocate_exception(std::size_t thrown_size) throw(); +} +#endif + +#if !HAVE_CXXABI_H_CXA_THROW +namespace __cxxabiv1 { +extern "C" void __cxa_throw( + void * thrown_exception, void * tinfo, void (* dest)(void *)) + __attribute__((noreturn)); +} +#endif + +namespace abi_aarch64 { void mapException( - __cxa_exception * exception, std::type_info const * type, uno_Any * any, uno_Mapping * mapping); + __cxxabiv1::__cxa_exception * exception, std::type_info const * type, uno_Any * any, uno_Mapping * mapping); void raiseException(uno_Any * any, uno_Mapping * mapping); diff --git bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx index f03d848521cc..0847dfc76db5 100644 --- bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx +++ bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx @@ -24,8 +24,6 @@ #include #include -#include - #include #include #include @@ -190,7 +188,7 @@ void call( } } catch (css::uno::Exception &) { abi_aarch64::mapException( - reinterpret_cast( + reinterpret_cast<__cxxabiv1::__cxa_eh_globals *>( __cxxabiv1::__cxa_get_globals())->caughtExceptions, __cxxabiv1::__cxa_current_exception_type(), *exception, proxy->getBridge()->getCpp2Uno()); From a7d1fed24557b203acb5016a98af26f4ef24d27a Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Tue, 11 Feb 2020 15:46:45 +0100 Subject: [PATCH] Hack to dynamically adapt to __cxa_exceptiom in LLVM 5.0 libcxxabi ...for Linux aarch64, similar to 7a9dd3d482deeeb3ed1d50074e56adbd3f928296 "Hack to dynamically adapt to __cxa_exceptiom in LLVM 5.0 libcxxabi" for macOS x86-64. But unlike on macOS (which is known to always use libcxxabi), be careful to only execute the hack in builds targeting libcxxabi. Change-Id: I5417fde425d2d6bac9400592193a9fe5d2bfe175 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88458 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- .../source/cpp_uno/gcc3_linux_aarch64/abi.cxx | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx index 892bf6e81963..611442a31e31 100644 --- bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx +++ bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx @@ -136,6 +136,28 @@ std::type_info * getRtti(typelib_TypeDescription const & type) { extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) { __cxxabiv1::__cxa_exception * header = static_cast<__cxxabiv1::__cxa_exception *>(exception) - 1; +#if defined _LIBCPPABI_VERSION // detect libc++abi + // The libcxxabi commit + // + // "[libcxxabi] Align unwindHeader on a double-word boundary" towards + // LLVM 5.0 changed the size of __cxa_exception by adding + // + // __attribute__((aligned)) + // + // to the final member unwindHeader, on x86-64 effectively adding a hole of + // size 8 in front of that member (changing its offset from 88 to 96, + // sizeof(__cxa_exception) from 120 to 128, and alignof(__cxa_exception) + // from 8 to 16); a hack to dynamically determine whether we run against a + // new libcxxabi is to look at the exceptionDestructor member, which must + // point to this function (the use of __cxa_exception in fillUnoException is + // unaffected, as it only accesses members towards the start of the struct, + // through a pointer known to actually point at the start): + if (header->exceptionDestructor != &deleteException) { + header = reinterpret_cast<__cxa_exception const *>( + reinterpret_cast(header) - 8); + assert(header->exceptionDestructor == &deleteException); + } +#endif OUString unoName(toUnoName(header->exceptionType->name())); typelib_TypeDescription * td = 0; typelib_typedescription_getByName(&td, unoName.pData);