|
Lines 136-143
Link Here
|
| 136 |
extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) { |
136 |
extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) { |
| 137 |
__cxxabiv1::__cxa_exception * header = |
137 |
__cxxabiv1::__cxa_exception * header = |
| 138 |
static_cast<__cxxabiv1::__cxa_exception *>(exception) - 1; |
138 |
static_cast<__cxxabiv1::__cxa_exception *>(exception) - 1; |
| 139 |
#if defined _LIBCPPABI_VERSION // detect libc++abi |
139 |
#if !defined MACOSX && defined _LIBCPPABI_VERSION // detect libc++abi |
| 140 |
// The libcxxabi commit |
140 |
// First, the libcxxabi commit |
| 141 |
// <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175> |
141 |
// <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175> |
| 142 |
// "[libcxxabi] Align unwindHeader on a double-word boundary" towards |
142 |
// "[libcxxabi] Align unwindHeader on a double-word boundary" towards |
| 143 |
// LLVM 5.0 changed the size of __cxa_exception by adding |
143 |
// LLVM 5.0 changed the size of __cxa_exception by adding |
|
Lines 147-163
Link Here
|
| 147 |
// to the final member unwindHeader, on x86-64 effectively adding a hole of |
147 |
// to the final member unwindHeader, on x86-64 effectively adding a hole of |
| 148 |
// size 8 in front of that member (changing its offset from 88 to 96, |
148 |
// size 8 in front of that member (changing its offset from 88 to 96, |
| 149 |
// sizeof(__cxa_exception) from 120 to 128, and alignof(__cxa_exception) |
149 |
// sizeof(__cxa_exception) from 120 to 128, and alignof(__cxa_exception) |
| 150 |
// from 8 to 16); a hack to dynamically determine whether we run against a |
150 |
// from 8 to 16); the "header1" hack below to dynamically determine whether we run against a |
| 151 |
// new libcxxabi is to look at the exceptionDestructor member, which must |
151 |
// LLVM 5 libcxxabi is to look at the exceptionDestructor member, which must |
| 152 |
// point to this function (the use of __cxa_exception in fillUnoException is |
152 |
// point to this function (the use of __cxa_exception in mapException is |
| 153 |
// unaffected, as it only accesses members towards the start of the struct, |
153 |
// unaffected, as it only accesses members towards the start of the struct, |
| 154 |
// through a pointer known to actually point at the start): |
154 |
// through a pointer known to actually point at the start). The libcxxabi commit |
|
|
155 |
// <https://github.com/llvm/llvm-project/commit/9ef1daa46edb80c47d0486148c0afc4e0d83ddcf> |
| 156 |
// "Insert padding before the __cxa_exception header to ensure the thrown" in LLVM 6 |
| 157 |
// removes the need for this hack, so the "header1" hack can be removed again once we can be |
| 158 |
// sure that we only run against libcxxabi from LLVM >= 6. |
| 159 |
// |
| 160 |
// Second, the libcxxabi commit |
| 161 |
// <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77> |
| 162 |
// "[libcxxabi] Insert padding in __cxa_exception struct for compatibility" in LLVM 10 changed |
| 163 |
// the layout of the start of __cxa_exception to |
| 164 |
// |
| 165 |
// [8 byte void *reserve] |
| 166 |
// 8 byte size_t referenceCount |
| 167 |
// |
| 168 |
// so the "header2" hack below to dynamically determine whether we run against a LLVM >= 10 |
| 169 |
// libcxxabi is to look whether the exceptionDestructor (with its known value) has increased its |
| 170 |
// offset by 8. As described in the definition of __cxa_exception |
| 171 |
// (bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx), the "header2" hack (together with the |
| 172 |
// "#ifdef MACOSX" in the definition of __cxa_exception and the corresponding hack in call in |
| 173 |
// bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx) can be dropped once we can be sure |
| 174 |
// that we only run against new libcxxabi that has the reserve member. |
| 155 |
if (header->exceptionDestructor != &deleteException) { |
175 |
if (header->exceptionDestructor != &deleteException) { |
| 156 |
header = reinterpret_cast<__cxxabiv1::__cxa_exception *>( |
176 |
auto const header1 = reinterpret_cast<__cxxabiv1::__cxa_exception *>( |
| 157 |
reinterpret_cast<char *>(header) - 8); |
177 |
reinterpret_cast<char *>(header) - 8); |
| 158 |
assert(header->exceptionDestructor == &deleteException); |
178 |
if (header1->exceptionDestructor == &deleteException) { |
|
|
179 |
header = header1; |
| 180 |
} else { |
| 181 |
auto const header2 = reinterpret_cast<__cxxabiv1::__cxa_exception *>( |
| 182 |
reinterpret_cast<char *>(header) + 8); |
| 183 |
if (header2->exceptionDestructor == &deleteException) { |
| 184 |
header = header2; |
| 185 |
} else { |
| 186 |
assert(false); |
| 187 |
} |
| 188 |
} |
| 159 |
} |
189 |
} |
| 160 |
#endif |
190 |
#endif |
|
|
191 |
assert(header->exceptionDestructor == &deleteException); |
| 161 |
OUString unoName(toUnoName(header->exceptionType->name())); |
192 |
OUString unoName(toUnoName(header->exceptionType->name())); |
| 162 |
typelib_TypeDescription * td = 0; |
193 |
typelib_TypeDescription * td = 0; |
| 163 |
typelib_typedescription_getByName(&td, unoName.pData); |
194 |
typelib_typedescription_getByName(&td, unoName.pData); |