git: bd9f0cee99a8 - 2022Q2 - editors/libreoffice: make robust against __cxa_exception ABI changes

From: Tijl Coosemans <tijl_at_FreeBSD.org>
Date: Wed, 27 Apr 2022 17:04:53 UTC
The branch 2022Q2 has been updated by tijl:

URL: https://cgit.FreeBSD.org/ports/commit/?id=bd9f0cee99a8822c19b155fd7c05bdfb5bce3c9d

commit bd9f0cee99a8822c19b155fd7c05bdfb5bce3c9d
Author:     Tijl Coosemans <tijl@FreeBSD.org>
AuthorDate: 2022-04-27 16:51:19 +0000
Commit:     Tijl Coosemans <tijl@FreeBSD.org>
CommitDate: 2022-04-27 17:01:40 +0000

    editors/libreoffice: make robust against __cxa_exception ABI changes
    
    Patch libreoffice to replace __cxa_get_globals()->caughtExceptions,
    which is a pointer to the start of a struct __cxa_exception, with
    __cxa_current_primary_exception(), which is a pointer to the end.  This
    allows struct __cxa_exception to be extended at the start as was
    recently done in FreeBSD main and stable/13 on 64-bit architectures.
    
    Recently on FreeBSD main and stable/13 __attribute__((__aligned__)) was
    added to struct _Unwind_Exception which changes its size on 32-bit
    architectures, and that of __cxa_exception as well.  Patch libreoffice
    to detect this so packages built on 13.0 still work on 13.1.
    
    Change the LIB_DEPENDS on libunwind to a BUILD_DEPENDS because we only
    need unwind.h (for FreeBSD 13.0 and older where that header is hidden
    in /usr/include/c++/v1).
    
    PR:             263596
    Approved by:    office (fluffy)
    
    (cherry picked from commit 35a5054819f15db65cd25a661887805550aedbc7)
---
 editors/libreoffice/Makefile                       | 12 +---
 ...es_source_cpp__uno_gcc3__linux__aarch64_abi.cxx | 11 ----
 ...ource_cpp__uno_gcc3__linux__aarch64_uno2cpp.cxx | 25 ++++++++
 ...s_source_cpp__uno_gcc3__linux__intel_except.cxx | 60 ++++++++++++++++--
 ..._source_cpp__uno_gcc3__linux__x86-64_except.cxx | 46 +++++++++++---
 ...es-source-cpp_uno-gcc3_linux_powerpc-except.cxx | 74 ++++++++++++++--------
 ...-source-cpp_uno-gcc3_linux_powerpc64-except.cxx | 52 ++++++++-------
 7 files changed, 197 insertions(+), 83 deletions(-)

diff --git a/editors/libreoffice/Makefile b/editors/libreoffice/Makefile
index 5d3b98c34cd8..9d04de9426bf 100644
--- a/editors/libreoffice/Makefile
+++ b/editors/libreoffice/Makefile
@@ -1,4 +1,4 @@
-PORTREVISION=	1
+PORTREVISION=	2
 
 .include "${.CURDIR}/Makefile.common"
 
@@ -19,6 +19,7 @@ BUILD_DEPENDS=	p5-Archive-Zip>=0:archivers/p5-Archive-Zip \
 		dmake:devel/dmake \
 		gperf>=3.1:devel/gperf \
 		${LOCALBASE}/include/libcuckoo/cuckoohash_map.hh:devel/libcuckoo \
+		libunwind>=20211201_1:devel/libunwind \
 		mdds>=2.0:devel/mdds \
 		ucpp:devel/ucpp \
 		${LOCALBASE}/include/sane/sane.h:graphics/sane-backends \
@@ -85,14 +86,7 @@ LIB_DEPENDS=	libapr-1.so:devel/apr1 \
 		libZXing.so:textproc/zxing-cpp \
 		libfontconfig.so:x11-fonts/fontconfig \
 		libxcb-icccm.so:x11/xcb-util-wm \
-		libserf-1.so:www/serf \
-		${LIB_DEPENDS_${ARCH}}
-LIB_DEPENDS_aarch64=	libunwind.so:devel/libunwind
-LIB_DEPENDS_amd64=	libunwind.so:devel/libunwind
-LIB_DEPENDS_armv7=	libunwind.so:devel/libunwind
-LIB_DEPENDS_i386=	libunwind.so:devel/libunwind
-LIB_DEPENDS_powerpc64=	libunwind.so:devel/libunwind
-LIB_DEPENDS_powerpc64le=	libunwind.so:devel/libunwind
+		libserf-1.so:www/serf
 
 RUN_DEPENDS=	xdg-open:devel/xdg-utils \
 		${LOCALBASE}/share/fonts/Caladea/Caladea-Bold.ttf:x11-fonts/crosextrafonts-caladea-ttf \
diff --git a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__aarch64_abi.cxx b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__aarch64_abi.cxx
deleted file mode 100644
index dc8af45ecfea..000000000000
--- a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__aarch64_abi.cxx
+++ /dev/null
@@ -1,11 +0,0 @@
---- bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx.orig	2022-01-26 14:35:29 UTC
-+++ bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
-@@ -147,7 +147,7 @@ extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException
- extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) {
-     __cxxabiv1::__cxa_exception * header =
-         static_cast<__cxxabiv1::__cxa_exception *>(exception) - 1;
--#if !defined MACOSX && defined _LIBCPPABI_VERSION // detect libc++abi
-+#if 1
-     // First, the libcxxabi commit
-     // <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
-     // "[libcxxabi] Align unwindHeader on a double-word boundary" towards
diff --git a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__aarch64_uno2cpp.cxx b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__aarch64_uno2cpp.cxx
new file mode 100644
index 000000000000..7a05a7f4e1a3
--- /dev/null
+++ b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__aarch64_uno2cpp.cxx
@@ -0,0 +1,25 @@
+--- bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx.orig	2022-03-23 13:32:00 UTC
++++ bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
+@@ -304,8 +304,10 @@ 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;
++        __cxxabiv1::__cxa_exception * header =
++            reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++                 __cxxabiv1::__cxa_current_primary_exception());
++        __cxxabiv1::__cxa_decrement_exception_refcount(header);
+ #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
+@@ -335,8 +337,7 @@ void call(
+         }
+ #endif
+         abi_aarch64::mapException(
+-            header,
+-            __cxxabiv1::__cxa_current_exception_type(), *exception,
++            header - 1, header[-1].exceptionType, *exception,
+             proxy->getBridge()->getCpp2Uno());
+         for (sal_Int32 i = 0; i != count; ++i) {
+             if (cppArgs[i] != nullptr) {
diff --git a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__intel_except.cxx b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__intel_except.cxx
index 7f7b6d805a22..439b9ea3adf4 100644
--- a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__intel_except.cxx
+++ b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__intel_except.cxx
@@ -1,14 +1,60 @@
-Fix uno bridge exception handling on i386.  This matches the amd64
-implementation and fixes a segfault in code that uses uno exceptions.
-
---- bridges/source/cpp_uno/gcc3_linux_intel/except.cxx.orig	2020-11-22 14:05:28 UTC
+--- bridges/source/cpp_uno/gcc3_linux_intel/except.cxx.orig	2022-03-23 13:32:00 UTC
 +++ bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
-@@ -202,7 +202,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
+@@ -202,9 +202,15 @@ static void _GLIBCXX_CDTOR_CALLABI deleteException( vo
  extern "C" {
  static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc )
  {
 -    __cxa_exception const * header = static_cast<__cxa_exception const *>(pExc) - 1;
-+    __cxxabiv1::__cxa_exception const * header = (static_cast<__cxxabiv1::__cxa_exception const *>(pExc) - 1);
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(pExc);
++    if (header[-1].exceptionDestructor != &deleteException) {
++        header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++            reinterpret_cast<char *>(header) - 12);
++    }
++    assert(header[-1].exceptionDestructor == &deleteException);
      typelib_TypeDescription * pTD = nullptr;
-     OUString unoName( toUNOname( header->exceptionType->name() ) );
+-    OUString unoName( toUNOname( header->exceptionType->name() ) );
++    OUString unoName( toUNOname( header[-1].exceptionType->name() ) );
      ::typelib_typedescription_getByName( &pTD, unoName.pData );
+     assert(pTD && "### unknown exception type! leaving out destruction => leaking!!!");
+     if (pTD)
+@@ -262,8 +268,19 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+ 
+ void fillUnoException(uno_Any * pUnoExc, uno_Mapping * pCpp2Uno)
+ {
+-    __cxa_exception * header = reinterpret_cast<CPPU_CURRENT_NAMESPACE::__cxa_eh_globals*>(
+-                 __cxxabiv1::__cxa_get_globals())->caughtExceptions;
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++             __cxxabiv1::__cxa_current_primary_exception());
++    if (header) {
++        __cxxabiv1::__cxa_decrement_exception_refcount(header);
++        if (header[-1].exceptionDestructor != &deleteException) {
++            header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++                reinterpret_cast<char *>(header) - 12);
++            if (header[-1].exceptionDestructor != &deleteException) {
++                header = nullptr;
++            }
++        }
++    }
+     if (! header)
+     {
+         RuntimeException aRE( "no exception header!" );
+@@ -273,7 +290,7 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+         return;
+     }
+ 
+-    std::type_info *exceptionType = __cxxabiv1::__cxa_current_exception_type();
++    std::type_info *exceptionType = header[-1].exceptionType;
+ 
+     typelib_TypeDescription * pExcTypeDescr = nullptr;
+     OUString unoName( toUNOname( exceptionType->name() ) );
+@@ -292,7 +309,7 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+     else
+     {
+         // construct uno exception any
+-        uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
++        uno_any_constructAndConvert( pUnoExc, header[-1].adjustedPtr, pExcTypeDescr, pCpp2Uno );
+         typelib_typedescription_release( pExcTypeDescr );
+     }
+ }
diff --git a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__x86-64_except.cxx b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__x86-64_except.cxx
index 4553e0303b2a..28737d352e42 100644
--- a/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__x86-64_except.cxx
+++ b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__x86-64_except.cxx
@@ -1,11 +1,39 @@
---- bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx.orig	2022-01-26 14:35:29 UTC
+--- bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx.orig	2022-03-23 13:32:00 UTC
 +++ bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
-@@ -82,7 +82,7 @@ static void _GLIBCXX_CDTOR_CALLABI deleteException( vo
- static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc )
+@@ -193,7 +193,9 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+ 
+ void fillUnoException(uno_Any * pUnoExc, uno_Mapping * pCpp2Uno)
  {
-     __cxxabiv1::__cxa_exception const * header = static_cast<__cxxabiv1::__cxa_exception const *>(pExc) - 1;
--#if defined _LIBCPPABI_VERSION // detect libc++abi
-+#if 1
-     // First, the libcxxabi commit
-     // <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
-     // "[libcxxabi] Align unwindHeader on a double-word boundary" towards
+-    __cxxabiv1::__cxa_exception * header = __cxxabiv1::__cxa_get_globals()->caughtExceptions;
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++             __cxxabiv1::__cxa_current_primary_exception());
+     if (! header)
+     {
+         RuntimeException aRE( "no exception header!" );
+@@ -202,6 +204,7 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+         SAL_WARN("bridges", aRE.Message);
+         return;
+     }
++    __cxxabiv1::__cxa_decrement_exception_refcount(header);
+ 
+ #if defined _LIBCPPABI_VERSION // detect libc++abi
+     // Very bad HACK to find out whether we run against a libcxxabi that has a new
+@@ -231,7 +234,7 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+     }
+ #endif
+ 
+-    std::type_info *exceptionType = __cxxabiv1::__cxa_current_exception_type();
++    std::type_info *exceptionType = header[-1].exceptionType;
+ 
+     typelib_TypeDescription * pExcTypeDescr = nullptr;
+     OUString unoName( toUNOname( exceptionType->name() ) );
+@@ -250,7 +253,7 @@ void fillUnoException(uno_Any * pUnoExc, uno_Mapping *
+     else
+     {
+         // construct uno exception any
+-        uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
++        uno_any_constructAndConvert( pUnoExc, header[-1].adjustedPtr, pExcTypeDescr, pCpp2Uno );
+         typelib_typedescription_release( pExcTypeDescr );
+     }
+ }
diff --git a/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc-except.cxx b/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc-except.cxx
index dbc6e134f1e1..c656588cb0a5 100644
--- a/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc-except.cxx
+++ b/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc-except.cxx
@@ -1,14 +1,14 @@
---- bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx.orig	2019-12-05 13:59:23.000000000 -0600
-+++ bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx	2020-09-14 11:24:58.489149000 -0500
-@@ -24,6 +24,7 @@
- #include <cxxabi.h>
+--- bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx.orig	2022-03-23 13:32:00 UTC
++++ bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx
+@@ -25,6 +25,7 @@
+ 
  #include <rtl/strbuf.hxx>
  #include <rtl/ustrbuf.hxx>
 +#include <sal/log.hxx>
  #include <osl/mutex.hxx>
  
  #include <com/sun/star/uno/genfunc.hxx>
-@@ -136,7 +137,7 @@
+@@ -136,7 +137,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
          buf.append( 'E' );
  
          OString symName( buf.makeStringAndClear() );
@@ -17,7 +17,7 @@
  
          if (rtti)
          {
-@@ -161,9 +162,9 @@
+@@ -161,9 +162,9 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
                  {
                      // ensure availability of base
                      type_info * base_rtti = getRTTI(
@@ -29,18 +29,26 @@
                  }
                  else
                  {
-@@ -192,8 +193,8 @@
+@@ -192,9 +193,15 @@ static void deleteException( void * pExc )
  
  static void deleteException( void * pExc )
  {
 -    __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
 -    typelib_TypeDescription * pTD = 0;
-+    __cxxabiv1::__cxa_exception const * header = static_cast<__cxxabiv1::__cxa_exception const *>(pExc) - 1;
+-    OUString unoName( toUNOname( header->exceptionType->name() ) );
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(pExc);
++    if (header[-1].exceptionDestructor != &deleteException) {
++        header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++            reinterpret_cast<char *>(header) - 12);
++    }
++    assert(header[-1].exceptionDestructor == &deleteException);
 +    typelib_TypeDescription * pTD = nullptr;
-     OUString unoName( toUNOname( header->exceptionType->name() ) );
++    OUString unoName( toUNOname( header[-1].exceptionType->name() ) );
      ::typelib_typedescription_getByName( &pTD, unoName.pData );
      assert(pTD && "### unknown exception type! leaving out destruction => leaking!!!");
-@@ -216,39 +217,57 @@
+     if (pTD)
+@@ -218,39 +225,68 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * 
      if (! pTypeDescr)
          terminate();
  
@@ -69,44 +77,60 @@
 +    __cxxabiv1::__cxa_throw( pCppExc, rtti, deleteException );
  }
  
- void fillUnoException(uno_Any * pExc, uno_Mapping * pCpp2Uno)
+-void fillUnoException(uno_Any * pExc, uno_Mapping * pCpp2Uno)
++void fillUnoException(uno_Any * pUnoExc, uno_Mapping * pCpp2Uno)
  {
 -    __cxa_exception * header = __cxa_get_globals()->caughtExceptions;
-+    __cxxabiv1::__cxa_exception * header = 
-+                 __cxxabiv1::__cxa_get_globals()->caughtExceptions;
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++             __cxxabiv1::__cxa_current_primary_exception());
++    if (header) {
++        __cxxabiv1::__cxa_decrement_exception_refcount(header);
++        if (header[-1].exceptionDestructor != &deleteException) {
++            header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++                reinterpret_cast<char *>(header) - 12);
++            if (header[-1].exceptionDestructor != &deleteException) {
++                header = nullptr;
++            }
++        }
++    }
      if (! header)
-         terminate();
+-        terminate();
++    {
++        RuntimeException aRE( "no exception header!" );
++        Type const & rType = cppu::UnoType<decltype(aRE)>::get();
++        uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
++        SAL_WARN("bridges", aRE.Message);
++        return;
++    }
  
 -    std::type_info *exceptionType = __cxa_current_exception_type();
-+    std::type_info *exceptionType = __cxxabiv1::__cxa_current_exception_type();
++    std::type_info *exceptionType = header[-1].exceptionType;
  
 -    typelib_TypeDescription * pExcTypeDescr = 0;
 +    typelib_TypeDescription * pExcTypeDescr = nullptr;
      OUString unoName( toUNOname( exceptionType->name() ) );
 -    ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
 -    if (! pExcTypeDescr)
+-        terminate();
+-
+-    // construct uno exception any
+-    ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+-    ::typelib_typedescription_release( pExcTypeDescr );
 +    typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
 +    if (pExcTypeDescr == nullptr)
 +    {
 +        RuntimeException aRE( "exception type not found: " + unoName );
 +        Type const & rType = cppu::UnoType<decltype(aRE)>::get();
-+        uno_type_any_constructAndConvert( pExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
++        uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
 +        SAL_WARN("bridges", aRE.Message);
 +    }
 +    else
 +    {
 +        // construct uno exception any
-+        uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
++        uno_any_constructAndConvert( pUnoExc, header[-1].adjustedPtr, pExcTypeDescr, pCpp2Uno );
 +        typelib_typedescription_release( pExcTypeDescr );
 +    }
-+    if (nullptr == pExcTypeDescr)
-         terminate();
- 
-     // construct uno exception any
--    ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
--    ::typelib_typedescription_release( pExcTypeDescr );
-+    uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
-+    typelib_typedescription_release( pExcTypeDescr );
  }
  
  }
diff --git a/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc64-except.cxx b/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc64-except.cxx
index 3d9108a73ece..b64d358e5742 100644
--- a/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc64-except.cxx
+++ b/editors/libreoffice/files/powerpc64/patch-bridges-source-cpp_uno-gcc3_linux_powerpc64-except.cxx
@@ -1,5 +1,5 @@
---- bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx.orig	2019-12-05 13:59:23.000000000 -0600
-+++ bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx	2020-09-14 11:24:58.489149000 -0500
+--- bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx.orig	2022-03-23 13:32:00 UTC
++++ bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx
 @@ -24,6 +24,7 @@
  #include <cxxabi.h>
  #include <rtl/strbuf.hxx>
@@ -8,7 +8,7 @@
  #include <osl/mutex.hxx>
  
  #include <com/sun/star/uno/genfunc.hxx>
-@@ -136,7 +137,7 @@
+@@ -136,7 +137,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
          buf.append( 'E' );
  
          OString symName( buf.makeStringAndClear() );
@@ -17,7 +17,7 @@
  
          if (rtti)
          {
-@@ -161,9 +162,9 @@
+@@ -161,9 +162,9 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
                  {
                      // ensure availability of base
                      type_info * base_rtti = getRTTI(
@@ -29,18 +29,19 @@
                  }
                  else
                  {
-@@ -192,8 +193,8 @@
+@@ -192,8 +193,9 @@ static void deleteException( void * pExc )
  
  static void deleteException( void * pExc )
  {
 -    __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
 -    typelib_TypeDescription * pTD = 0;
-+    __cxxabiv1::__cxa_exception const * header = static_cast<__cxxabiv1::__cxa_exception const *>(pExc) - 1;
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(pExc) - 1;
 +    typelib_TypeDescription * pTD = nullptr;
      OUString unoName( toUNOname( header->exceptionType->name() ) );
      ::typelib_typedescription_getByName( &pTD, unoName.pData );
      assert(pTD && "### unknown exception type! leaving out destruction => leaking!!!");
-@@ -216,39 +217,57 @@
+@@ -216,39 +218,59 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * 
      if (! pTypeDescr)
          terminate();
  
@@ -69,44 +70,51 @@
 +    __cxxabiv1::__cxa_throw( pCppExc, rtti, deleteException );
  }
  
- void fillUnoException(uno_Any * pExc, uno_Mapping * pCpp2Uno)
+-void fillUnoException(uno_Any * pExc, uno_Mapping * pCpp2Uno)
++void fillUnoException(uno_Any * pUnoExc, uno_Mapping * pCpp2Uno)
  {
 -    __cxa_exception * header = __cxa_get_globals()->caughtExceptions;
-+    __cxxabiv1::__cxa_exception * header = 
-+                 __cxxabiv1::__cxa_get_globals()->caughtExceptions;
++    __cxxabiv1::__cxa_exception * header =
++        reinterpret_cast<__cxxabiv1::__cxa_exception *>(
++             __cxxabiv1::__cxa_current_primary_exception());
      if (! header)
-         terminate();
+-        terminate();
++    {
++        RuntimeException aRE( "no exception header!" );
++        Type const & rType = cppu::UnoType<decltype(aRE)>::get();
++        uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
++        SAL_WARN("bridges", aRE.Message);
++        return;
++    }
++    __cxxabiv1::__cxa_decrement_exception_refcount(header);
  
 -    std::type_info *exceptionType = __cxa_current_exception_type();
-+    std::type_info *exceptionType = __cxxabiv1::__cxa_current_exception_type();
++    std::type_info *exceptionType = header[-1].exceptionType;
  
 -    typelib_TypeDescription * pExcTypeDescr = 0;
 +    typelib_TypeDescription * pExcTypeDescr = nullptr;
      OUString unoName( toUNOname( exceptionType->name() ) );
 -    ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
 -    if (! pExcTypeDescr)
+-        terminate();
+-
+-    // construct uno exception any
+-    ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+-    ::typelib_typedescription_release( pExcTypeDescr );
 +    typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
 +    if (pExcTypeDescr == nullptr)
 +    {
 +        RuntimeException aRE( "exception type not found: " + unoName );
 +        Type const & rType = cppu::UnoType<decltype(aRE)>::get();
-+        uno_type_any_constructAndConvert( pExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
++        uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
 +        SAL_WARN("bridges", aRE.Message);
 +    }
 +    else
 +    {
 +        // construct uno exception any
-+        uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
++        uno_any_constructAndConvert( pUnoExc, header[-1].adjustedPtr, pExcTypeDescr, pCpp2Uno );
 +        typelib_typedescription_release( pExcTypeDescr );
 +    }
-+    if (nullptr == pExcTypeDescr)
-         terminate();
- 
-     // construct uno exception any
--    ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
--    ::typelib_typedescription_release( pExcTypeDescr );
-+    uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
-+    typelib_typedescription_release( pExcTypeDescr );
  }
  
  }