summaryrefslogtreecommitdiff
path: root/coregrind/m_trampoline.S
diff options
context:
space:
mode:
Diffstat (limited to 'coregrind/m_trampoline.S')
-rw-r--r--coregrind/m_trampoline.S34
1 files changed, 34 insertions, 0 deletions
diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S
index 07d76898..0fdcf9e8 100644
--- a/coregrind/m_trampoline.S
+++ b/coregrind/m_trampoline.S
@@ -1214,6 +1214,39 @@ VG_(trampoline_stuff_end):
.fill 2048, 2, 0x0b0f /* `ud2` */
+/*---------------- s390x-linux ----------------*/
+#else
+#if defined(VGP_s390x_linux)
+
+ /* a leading page of unexecutable code */
+ .fill 2048, 2, 0x0000
+
+.global VG_(trampoline_stuff_start)
+VG_(trampoline_stuff_start):
+
+.global VG_(s390x_linux_SUBST_FOR_sigreturn)
+VG_(s390x_linux_SUBST_FOR_sigreturn):
+ svc __NR_sigreturn
+ .short 0
+
+.global VG_(s390x_linux_SUBST_FOR_rt_sigreturn)
+VG_(s390x_linux_SUBST_FOR_rt_sigreturn):
+ /* Old gcc unwinding code checks for a sig(_rt)_return svc and then
+ for ra = cfa to decide if it is a sig_rt_frame or not. Since we
+ set ra to this trampoline, but the cfa is still in the stack,
+ the unwinder thinks, that this is a non-rt frame and causes a
+ crash in the gcc unwinder - which is used by the thread library
+ and others. Therefore we add a lr 1,1 nop, to let the gcc
+ unwinder bail out gracefully. This might also affect unwinding
+ across the signal frame - tough luck. fixs390 */
+ lr 1,1
+ svc __NR_rt_sigreturn
+ .short 0
+
+.globl VG_(trampoline_stuff_end)
+VG_(trampoline_stuff_end):
+ .fill 2048, 2, 0x0000
+
/*---------------- unknown ----------------*/
#else
# error Unknown platform
@@ -1226,6 +1259,7 @@ VG_(trampoline_stuff_end):
#endif
#endif
#endif
+#endif
#if defined(VGO_linux)
/* Let the linker know we don't need an executable stack */