summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-08-13 11:20:38 +0200
committerStephan Bergmann <sbergman@redhat.com>2020-08-13 15:55:08 +0200
commitcc5a6c6afeed1d2cf76d288133971d29ee8d893e (patch)
treefa37188299df4e189bb819643a3311de4bbadc9a /bridges
parente2c81bdf6f9f0ee3289bec7aa4ddb1f95b95382d (diff)
gcc3_linux_{aarch64,x86-64} need the __cxa_exception hack in deleteException
* gcc3_linux_aarch64 needs a hack to detect the reserve member in LLVM >= 10 libcxxabi __cxa_exception, in addition to the existing hack for LLVM 5. 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 neither of the two hacks there. (And a7d1fed24557b203acb5016a98af26f4ef24d27a "Hack to dynamically adapt to __cxa_exceptiom in LLVM 5.0 libcxxabi" had introduced a "fillUnoException" vs. "mapException" typo in the comment when it copied it from bridges/source/cpp_uno/gcc3_macosx_x86-64/except.cxx.) * Similarly, gcc3_linux_x86_64 needs both hacks when it is built against libcxxabi (and the need for the LLVM 5 hack had gone unnoticed there for now). * It is not clear to me now why gcc3_macosx_x86-64 needs the LLVM 5 hack (which I even initially developed for that platform, 7a9dd3d482deeeb3ed1d50074e56adbd3f928296 "Hack to dynamically adapt to __cxa_exceptiom in LLVM 5.0 libcxxabi") but not the LLVM >= 10 hack (although it does need the corresponding hack in fillUnoException when running against recent upstream LLVM trunk libcxxabi, f4b6f6a8ae60bdec53512728d00853b73fa18500 "Hack to dynamically adapt to __cxa_exceptiom in LLVM 11 libcxxabi". Change-Id: I8e7a5c871fbeeaf82bbd16fa03e73f10f229da93 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100656 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.cxx43
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx53
2 files changed, 88 insertions, 8 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
index 492c14898977..988502713639 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
@@ -162,8 +162,8 @@ 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
+#if !defined MACOSX && defined _LIBCPPABI_VERSION // detect libc++abi
+ // First, the libcxxabi commit
// <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
// "[libcxxabi] Align unwindHeader on a double-word boundary" towards
// LLVM 5.0 changed the size of __cxa_exception by adding
@@ -173,21 +173,48 @@ extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) {
// 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
+ // from 8 to 16); the "header1" hack below to dynamically determine whether we run against a
// LLVM 5 libcxxabi is to look at the exceptionDestructor member, which must
- // point to this function (the use of __cxa_exception in fillUnoException is
+ // point to this function (the use of __cxa_exception in mapException is
// unaffected, as it only accesses members towards the start of the struct,
// through a pointer known to actually point at the start). The libcxxabi commit
// <https://github.com/llvm/llvm-project/commit/9ef1daa46edb80c47d0486148c0afc4e0d83ddcf>
// "Insert padding before the __cxa_exception header to ensure the thrown" in LLVM 6
- // removes the need for this hack, so it can be removed again once we can be sure that we only
- // run against libcxxabi from LLVM >= 6:
+ // removes the need for this hack, so the "header1" hack can be removed again once we can be
+ // sure that we only run against libcxxabi from LLVM >= 6.
+ //
+ // Second, the libcxxabi commit
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility" in LLVM 10 changed
+ // the layout of the start of __cxa_exception to
+ //
+ // [8 byte void *reserve]
+ // 8 byte size_t referenceCount
+ //
+ // so the "header2" hack below to dynamically determine whether we run against a LLVM >= 10
+ // libcxxabi is to look whether the exceptionDestructor (with its known value) has increased its
+ // offset by 8. As described in the definition of __cxa_exception
+ // (bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx), the "header2" hack (together with the
+ // "#ifdef MACOSX" in the definition of __cxa_exception and the corresponding hack in call in
+ // bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx) can be dropped once we can be sure
+ // that we only run against new libcxxabi that has the reserve member.
if (header->exceptionDestructor != &deleteException) {
- header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
+ auto const header1 = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
reinterpret_cast<char *>(header) - 8);
- assert(header->exceptionDestructor == &deleteException);
+ if (header1->exceptionDestructor == &deleteException) {
+ header = header1;
+ } else {
+ auto const header2 = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
+ reinterpret_cast<char *>(header) + 8);
+ if (header2->exceptionDestructor == &deleteException) {
+ header = header2;
+ } else {
+ assert(false);
+ }
+ }
}
#endif
+ assert(header->exceptionDestructor == &deleteException);
OUString unoName(toUnoName(header->exceptionType->name()));
typelib_TypeDescription * td = 0;
typelib_typedescription_getByName(&td, unoName.pData);
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
index 981ddfe676f7..2a92dba37475 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
@@ -82,6 +82,59 @@ extern "C" {
static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc )
{
__cxxabiv1::__cxa_exception const * header = static_cast<__cxxabiv1::__cxa_exception const *>(pExc) - 1;
+#if defined _LIBCPPABI_VERSION // detect libc++abi
+ // First, the libcxxabi commit
+ // <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
+ // "[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); the "header1" hack below to dynamically determine whether we run against a
+ // LLVM 5 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). The libcxxabi commit
+ // <https://github.com/llvm/llvm-project/commit/9ef1daa46edb80c47d0486148c0afc4e0d83ddcf>
+ // "Insert padding before the __cxa_exception header to ensure the thrown" in LLVM 6
+ // removes the need for this hack, so the "header1" hack can be removed again once we can be
+ // sure that we only run against libcxxabi from LLVM >= 6.
+ //
+ // Second, the libcxxabi commit
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility" in LLVM 10 changed
+ // the layout of the start of __cxa_exception to
+ //
+ // [8 byte void *reserve]
+ // 8 byte size_t referenceCount
+ //
+ // so the "header2" hack below to dynamically determine whether we run against a LLVM >= 10
+ // libcxxabi is to look whether the exceptionDestructor (with its known value) has increased its
+ // offset by 8. As described in the definition of __cxa_exception
+ // (bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx), the "header2" hack (together with the
+ // "#if 0" in the definition of __cxa_exception and the corresponding hack in fillUnoException)
+ // can be dropped once we can be sure that we only run against new libcxxabi that has the
+ // reserve member.
+ if (header->exceptionDestructor != &deleteException) {
+ auto const header1 = reinterpret_cast<__cxa_exception const *>(
+ reinterpret_cast<char const *>(header) - 8);
+ if (header1->exceptionDestructor == &deleteException) {
+ header = header1;
+ } else {
+ auto const header2 = reinterpret_cast<__cxa_exception const *>(
+ reinterpret_cast<char const *>(header) + 8);
+ if (header2->exceptionDestructor == &deleteException) {
+ header = header2;
+ } else {
+ assert(false);
+ }
+ }
+ }
+#endif
+ assert(header->exceptionDestructor == &deleteException);
typelib_TypeDescription * pTD = nullptr;
OUString unoName( toUNOname( header->exceptionType->name() ) );
::typelib_typedescription_getByName( &pTD, unoName.pData );