summaryrefslogtreecommitdiff
path: root/dyngen-exec.h
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-25 00:36:06 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-25 00:36:06 +0000
commit9b7b85d26006af61b69dbabe2354d73a8c67cc6c (patch)
treee4322a41fe45763778ff10a01b163724e5304f75 /dyngen-exec.h
parent8bba5c81b1febeb20cdd60f1c18eb0e695cad6d6 (diff)
Fix off-by-one unwinding error.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4570 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'dyngen-exec.h')
-rw-r--r--dyngen-exec.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 52cb779de..f51d36328 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -287,4 +287,16 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
#error unsupported CPU
#endif
+/* The return address may point to the start of the next instruction.
+ Subtracting one gets us the call instruction itself. */
+#if defined(__s390__)
+# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1))
+#elif defined(__arm__)
+/* Thumb return addresses have the low bit set, so we need to subtract two.
+ This is still safe in ARM mode because instructions are 4 bytes. */
+# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2))
+#else
+# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1))
+#endif
+
#endif /* !defined(__DYNGEN_EXEC_H__) */