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 ); |