aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-15 12:42:24 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-16 06:36:27 +0200
commit0c6743749f8bab4bbace3f3c3d1172d1ca959f7c (patch)
tree39f3abafd4249b171181bf2b44b81e600633c514 /src
parent4e45120a7b593cfafccb5cd7b7c7645afffc37c4 (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')
-rw-r--r--src/qml/jsruntime/qv4engine_cxxabi.cpp33
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