diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-15 12:42:24 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-16 06:36:27 +0200 |
commit | 0c6743749f8bab4bbace3f3c3d1172d1ca959f7c (patch) | |
tree | 39f3abafd4249b171181bf2b44b81e600633c514 /src/qml | |
parent | 4e45120a7b593cfafccb5cd7b7c7645afffc37c4 (diff) |
Fix cleanup handlers on Android when exceptions are thrown
When an exception is thrown and we traverse a frame that requires only cleanup
(i.e. call QV4::Scope::~Scope), control is first transferred to the generated
cleanup code. Afterwards the unwinding is resumed (on ARM) by calling
__cxa_end_cleanup, which resides in libsupc++ (libgnustl_shared).
__cxa_end_cleanup first calls __gnu_end_cleanup and then resumes the process of
stack unwinding by calling _Unwind_Resume (per specification). Given the
linking situation on Android, this will end up calling _Unwind_Resume inside
libgnustl_shared, which sidesteps our statically linked copy of the unwind
code in QtQml (libgcc.a). Therefore any further unwinding through JIT generated
frames will fail.
This patch introduces the same EABI symbol exported in libQt5Qml, which will
direct control to the correct JIT aware unwinder.
This relies on https://codereview.qt-project.org/#change,68206 in order to
ensure that libsupc++.a is gone from all link lines (not needed) and that
gnustl_shared is after libQt5Qml.
Task-Number: QTBUG-33892
Change-Id: I6ed691db3ceb287475a70b7af8cf3cd7b4ddfdd6
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsruntime/qv4engine_cxxabi.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4engine_cxxabi.cpp b/src/qml/jsruntime/qv4engine_cxxabi.cpp index 02a6b9bdde..dfe1db8fe3 100644 --- a/src/qml/jsruntime/qv4engine_cxxabi.cpp +++ b/src/qml/jsruntime/qv4engine_cxxabi.cpp @@ -136,4 +136,37 @@ void ExecutionEngine::rethrowInternal() QT_END_NAMESPACE +/* + * We override these EABI defined symbols on Android, where we must statically link in the unwinder from libgcc.a + * and thus also ensure that compiler generated cleanup code / landing pads end up calling these stubs, that + * ultimately return control to our copy of the unwinder. The symbols are also exported from gnustl_shared, which + * comes later in the link line. + */ +#if defined(__ANDROID__) && defined(__ARM_EABI_UNWINDER__) +#pragma GCC visibility push(default) +#ifdef __thumb__ +asm (" .pushsection .text.__cxa_end_cleanup\n" +" .global __cxa_end_cleanup\n" +" .type __cxa_end_cleanup, \"function\"\n" +" .thumb_func\n" +"__cxa_end_cleanup:\n" +" push\t{r1, r2, r3, r4}\n" +" bl\t__gnu_end_cleanup\n" +" pop\t{r1, r2, r3, r4}\n" +" bl\t_Unwind_Resume @ Never returns\n" +" .popsection\n"); +#else +asm (" .pushsection .text.__cxa_end_cleanup\n" +" .global __cxa_end_cleanup\n" +" .type __cxa_end_cleanup, \"function\"\n" +"__cxa_end_cleanup:\n" +" stmfd\tsp!, {r1, r2, r3, r4}\n" +" bl\t__gnu_end_cleanup\n" +" ldmfd\tsp!, {r1, r2, r3, r4}\n" +" bl\t_Unwind_Resume @ Never returns\n" +" .popsection\n"); +#endif +#pragma GCC visibility pop +#endif + #endif |