summaryrefslogtreecommitdiffstats
path: root/bridges
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-08-13 09:38:27 +0200
committerStephan Bergmann <sbergman@redhat.com>2020-08-13 13:25:47 +0200
commite6450f1115b8c1f80d6b442cce8b4ee24bcddd02 (patch)
tree6c9c682e6dad629e83981f5ffac7fcd09494835f /bridges
parentSifr: icons for Manage Changes (diff)
downloadcore-e6450f1115b8c1f80d6b442cce8b4ee24bcddd02.tar.gz
core-e6450f1115b8c1f80d6b442cce8b4ee24bcddd02.zip
gcc3_linux_aarch64 also needs the hack to dynamically adapt to __cxa_exception
...in LLVM 10 libcxxabi, same as f4b6f6a8ae60bdec53512728d00853b73fa18500 "Hack to dynamically adapt to __cxa_exceptiom in LLVM 11 libcxxabi" for gcc3_macosx_x86-64 and 986bd28388df745dd969e7be7c3bda36b2b2cb0e "ofz#24641 libc++abi __cxa_exception has grown another member" for gcc3_linux_x86-64. (Note that 91c8a3f3e7d3c178952d7e78e24cd0d6ba2b165a "The __cxa_exception::reserve member has been backported to LLVM 10 libcxxabi" found out that this is already relevant for LLVM 10, contrary to the mentioned commits' subject lines.) On macOS arm64 (which shares the bridges/source/cpp_uno/gcc3_linux_aarch64/ code) we know that we always target a >= LLVM 10 libcxxabi, so we do not need the hack there. Change-Id: I49e3d5b06b0b427ee3edeb10281025e4b9f2615f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100644 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'bridges')
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx33
2 files changed, 42 insertions, 2 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
index 008d4723e295..4a677be0219f 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
@@ -72,6 +72,17 @@ struct __cxa_exception {
#if defined _LIBCPPABI_VERSION // detect libc++abi
#if defined __LP64__ || LIBCXXABI_ARM_EHABI
#ifdef MACOSX // on arm64
+ // This is a new field added with LLVM 10
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility". For non-MACOSX,
+ // the HACK in call (bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx) tries to find out at
+ // runtime whether a __cxa_exception has this member. Once we can be sure that we only run
+ // against new libcxxabi that has this member, we can drop the "#ifdef MACOSX" here and drop the
+ // hack in call.
+
+ // Now _Unwind_Exception is marked with __attribute__((aligned)),
+ // which implies __cxa_exception is also aligned. Insert padding
+ // in the beginning of the struct, rather than before unwindHeader.
void *reserve;
#endif
std::size_t referenceCount;
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
index d1928942eb06..760a7b38551d 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
@@ -187,9 +187,38 @@ void call(
"C++ code threw unknown exception");
}
} catch (css::uno::Exception &) {
+ __cxxabiv1::__cxa_exception * header = reinterpret_cast<__cxxabiv1::__cxa_eh_globals *>(
+ __cxxabiv1::__cxa_get_globals())->caughtExceptions;
+#if !defined MACOSX && defined _LIBCPPABI_VERSION // detect libc++abi
+ // Very bad HACK to find out whether we run against a libcxxabi that has a new
+ // __cxa_exception::reserved member at the start, introduced with LLVM 10
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility". The layout of
+ // the start of __cxa_exception is
+ //
+ // [8 byte void *reserve]
+ // 8 byte size_t referenceCount
+ //
+ // where the (bad, hacky) assumption is that reserve (if present) is null
+ // (__cxa_allocate_exception in at least LLVM 11 zero-fills the object, and nothing actively
+ // sets reserve) while referenceCount is non-null (__cxa_throw sets it to 1, and
+ // __cxa_decrement_exception_refcount destroys the exception as soon as it drops to 0; for a
+ // __cxa_dependent_exception, the referenceCount member is rather
+ //
+ // 8 byte void* primaryException
+ //
+ // but which also will always be set to a non-null value in
+ // __cxa_rethrow_primary_exception). As described in the definition of __cxa_exception
+ // (bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx), this hack (together with the
+ // "#ifdef MACOSX" there) can be dropped once we can be sure that we only run against new
+ // libcxxabi that has the reserve member:
+ if (*reinterpret_cast<void **>(header) == nullptr) {
+ header = reinterpret_cast<__cxxabiv1::__cxa_exception*>(
+ reinterpret_cast<void **>(header) + 1);
+ }
+#endif
abi_aarch64::mapException(
- reinterpret_cast<__cxxabiv1::__cxa_eh_globals *>(
- __cxxabiv1::__cxa_get_globals())->caughtExceptions,
+ header,
__cxxabiv1::__cxa_current_exception_type(), *exception,
proxy->getBridge()->getCpp2Uno());
for (sal_Int32 i = 0; i != count; ++i) {