about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c')
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c b/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
index b08f1b4047..cdff9a4f21 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
@@ -37,6 +37,8 @@
                +-----------------------+
              n | overflow parameters   | 160
                +-----------------------+
+             8 | trampoline            | 160+n
+               +-----------------------+
    The registers are set up like this:
      %r2-%r6: parameters 1 to 5
      %r7    : (*func) pointer
@@ -53,16 +55,17 @@
 void
 __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
 {
-  extern void __makecontext_ret (void);
   unsigned long *sp;
   va_list ap;
   int i;
 
-  sp = (unsigned long *) (((unsigned long) ucp->uc_stack.ss_sp
-			   + ucp->uc_stack.ss_size) & -8L);
+  sp = (long *) (((long) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & -8L);
+
+  /* Setup the trampoline.  */
+  *--sp = 0x0de7b904002807f9;
 
   /* Set the return address to trampoline.  */
-  ucp->uc_mcontext.gregs[14] = (long) __makecontext_ret;
+  ucp->uc_mcontext.gregs[14] = (long) sp;
 
   /* Set register parameters.  */
   va_start (ap, argc);
@@ -94,12 +97,4 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
   ucp->uc_mcontext.gregs[15] = (long) sp;
 }
 
-asm(".text\n"
-    ".type __makecontext_ret,@function\n"
-    "__makecontext_ret:\n"
-    "      basr  %r14,%r7\n"
-    "      lgr   %r2,%r8\n"
-    "      br    %r9\n"
-    ".size __makecontext_ret, .-__makecontext_ret");
-
 weak_alias (__makecontext, makecontext)