View | Details | Raw Unified | Return to bug 262008 | Differences between
and this patch

Collapse All | Expand All

(-)b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__powerpc64_except.cxx (+67 lines)
Added Link Here
1
--- bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx.orig	2022-03-23 13:32:00 UTC
2
+++ bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx
3
@@ -189,10 +189,63 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
4
     return rtti;
5
 }
6
 
7
-
8
+extern "C"
9
 static void deleteException( void * pExc )
10
 {
11
     __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
12
+#if 1
13
+    // First, the libcxxabi commit
14
+    // <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
15
+    // "[libcxxabi] Align unwindHeader on a double-word boundary" towards
16
+    // LLVM 5.0 changed the size of __cxa_exception by adding
17
+    //
18
+    //   __attribute__((aligned))
19
+    //
20
+    // to the final member unwindHeader, on x86-64 effectively adding a hole of
21
+    // size 8 in front of that member (changing its offset from 88 to 96,
22
+    // sizeof(__cxa_exception) from 120 to 128, and alignof(__cxa_exception)
23
+    // from 8 to 16); the "header1" hack below to dynamically determine whether we run against a
24
+    // LLVM 5 libcxxabi is to look at the exceptionDestructor member, which must
25
+    // point to this function (the use of __cxa_exception in fillUnoException is
26
+    // unaffected, as it only accesses members towards the start of the struct,
27
+    // through a pointer known to actually point at the start).  The libcxxabi commit
28
+    // <https://github.com/llvm/llvm-project/commit/9ef1daa46edb80c47d0486148c0afc4e0d83ddcf>
29
+    // "Insert padding before the __cxa_exception header to ensure the thrown" in LLVM 6
30
+    // removes the need for this hack, so the "header1" hack can be removed again once we can be
31
+    // sure that we only run against libcxxabi from LLVM >= 6.
32
+    //
33
+    // Second, the libcxxabi commit
34
+    // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
35
+    // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility" in LLVM 10 changed
36
+    // the layout of the start of __cxa_exception to
37
+    //
38
+    //  [8 byte  void *reserve]
39
+    //   8 byte  size_t referenceCount
40
+    //
41
+    // so the "header2" hack below to dynamically determine whether we run against a LLVM >= 10
42
+    // libcxxabi is to look whether the exceptionDestructor (with its known value) has increased its
43
+    // offset by 8.  As described in the definition of __cxa_exception
44
+    // (bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx), the "header2" hack (together with the
45
+    // "#if 0" in the definition of __cxa_exception and the corresponding hack in fillUnoException)
46
+    // can be dropped once we can be sure that we only run against new libcxxabi that has the
47
+    // reserve member.
48
+    if (header->exceptionDestructor != &deleteException) {
49
+        auto const header1 = reinterpret_cast<__cxa_exception const *>(
50
+            reinterpret_cast<char const *>(header) - 8);
51
+        if (header1->exceptionDestructor == &deleteException) {
52
+            header = header1;
53
+        } else {
54
+            auto const header2 = reinterpret_cast<__cxa_exception const *>(
55
+                reinterpret_cast<char const *>(header) + 8);
56
+            if (header2->exceptionDestructor == &deleteException) {
57
+                header = header2;
58
+            } else {
59
+                assert(false);
60
+            }
61
+        }
62
+    }
63
+#endif
64
+    assert(header->exceptionDestructor == &deleteException);
65
     typelib_TypeDescription * pTD = 0;
66
     OUString unoName( toUNOname( header->exceptionType->name() ) );
67
     ::typelib_typedescription_getByName( &pTD, unoName.pData );
(-)b/editors/libreoffice/files/patch-bridges_source_cpp__uno_gcc3__linux__powerpc_except.cxx (+67 lines)
Added Link Here
1
--- bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx.orig	2022-03-23 13:32:00 UTC
2
+++ bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx
3
@@ -189,10 +189,63 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescrip
4
     return rtti;
5
 }
6
 
7
-
8
+extern "C"
9
 static void deleteException( void * pExc )
10
 {
11
     __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
12
+#if 1
13
+    // First, the libcxxabi commit
14
+    // <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
15
+    // "[libcxxabi] Align unwindHeader on a double-word boundary" towards
16
+    // LLVM 5.0 changed the size of __cxa_exception by adding
17
+    //
18
+    //   __attribute__((aligned))
19
+    //
20
+    // to the final member unwindHeader, on x86-64 effectively adding a hole of
21
+    // size 8 in front of that member (changing its offset from 88 to 96,
22
+    // sizeof(__cxa_exception) from 120 to 128, and alignof(__cxa_exception)
23
+    // from 8 to 16); the "header1" hack below to dynamically determine whether we run against a
24
+    // LLVM 5 libcxxabi is to look at the exceptionDestructor member, which must
25
+    // point to this function (the use of __cxa_exception in fillUnoException is
26
+    // unaffected, as it only accesses members towards the start of the struct,
27
+    // through a pointer known to actually point at the start).  The libcxxabi commit
28
+    // <https://github.com/llvm/llvm-project/commit/9ef1daa46edb80c47d0486148c0afc4e0d83ddcf>
29
+    // "Insert padding before the __cxa_exception header to ensure the thrown" in LLVM 6
30
+    // removes the need for this hack, so the "header1" hack can be removed again once we can be
31
+    // sure that we only run against libcxxabi from LLVM >= 6.
32
+    //
33
+    // Second, the libcxxabi commit
34
+    // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
35
+    // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility" in LLVM 10 changed
36
+    // the layout of the start of __cxa_exception to
37
+    //
38
+    //  [8 byte  void *reserve]
39
+    //   8 byte  size_t referenceCount
40
+    //
41
+    // so the "header2" hack below to dynamically determine whether we run against a LLVM >= 10
42
+    // libcxxabi is to look whether the exceptionDestructor (with its known value) has increased its
43
+    // offset by 8.  As described in the definition of __cxa_exception
44
+    // (bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx), the "header2" hack (together with the
45
+    // "#if 0" in the definition of __cxa_exception and the corresponding hack in fillUnoException)
46
+    // can be dropped once we can be sure that we only run against new libcxxabi that has the
47
+    // reserve member.
48
+    if (header->exceptionDestructor != &deleteException) {
49
+        auto const header1 = reinterpret_cast<__cxa_exception const *>(
50
+            reinterpret_cast<char const *>(header) - 8);
51
+        if (header1->exceptionDestructor == &deleteException) {
52
+            header = header1;
53
+        } else {
54
+            auto const header2 = reinterpret_cast<__cxa_exception const *>(
55
+                reinterpret_cast<char const *>(header) + 8);
56
+            if (header2->exceptionDestructor == &deleteException) {
57
+                header = header2;
58
+            } else {
59
+                assert(false);
60
+            }
61
+        }
62
+    }
63
+#endif
64
+    assert(header->exceptionDestructor == &deleteException);
65
     typelib_TypeDescription * pTD = 0;
66
     OUString unoName( toUNOname( header->exceptionType->name() ) );
67
     ::typelib_typedescription_getByName( &pTD, unoName.pData );

Return to bug 262008