summaryrefslogtreecommitdiffstats
path: root/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx')
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx33
1 files changed, 31 insertions, 2 deletions
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) {