2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / s390 / s390-64 / makecontext.c
blobb08f1b4047f3e8db0991427212d6d360f07a18ed
1 /* Copyright (C) 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <libintl.h>
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <ucontext.h>
26 /* This implementation can handle any ARGC value but only
27 normal integer type parameters. Parameters of type float,
28 double, complex and structure with sizes 0, 2, 4 or 8
29 won't work.
30 makecontext sets up a stack and the registers for the
31 user context. The stack looks like this:
32 size offset
33 %r15 -> +-----------------------+
34 8 | back chain (zero) | 0
35 8 | reserved | 8
36 144 | save area for (*func) | 16
37 +-----------------------+
38 n | overflow parameters | 160
39 +-----------------------+
40 The registers are set up like this:
41 %r2-%r6: parameters 1 to 5
42 %r7 : (*func) pointer
43 %r8 : uc_link from ucontext structure
44 %r9 : address of setcontext
45 %r14 : return address to uc_link trampoline
46 %r15 : stack pointer.
48 The trampoline looks like this:
49 basr %r14,%r7
50 lgr %r2,%r8
51 br %r9. */
53 void
54 __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
56 extern void __makecontext_ret (void);
57 unsigned long *sp;
58 va_list ap;
59 int i;
61 sp = (unsigned long *) (((unsigned long) ucp->uc_stack.ss_sp
62 + ucp->uc_stack.ss_size) & -8L);
64 /* Set the return address to trampoline. */
65 ucp->uc_mcontext.gregs[14] = (long) __makecontext_ret;
67 /* Set register parameters. */
68 va_start (ap, argc);
69 for (i = 0; (i < argc) && (i < 5); i++)
70 ucp->uc_mcontext.gregs[2+i] = va_arg (ap, long);
72 /* The remaining arguments go to the overflow area. */
73 if (argc > 5) {
74 sp -= argc - 5;
75 for (i = 5; i < argc; i++)
76 sp[i] = va_arg(ap, long);
78 va_end (ap);
80 /* Make room for the save area and set the backchain. */
81 sp -= 20;
82 *sp = 0;
84 /* Pass (*func) to __start_context in %r7. */
85 ucp->uc_mcontext.gregs[7] = (long) func;
87 /* Pass ucp->uc_link to __start_context in %r8. */
88 ucp->uc_mcontext.gregs[8] = (long) ucp->uc_link;
90 /* Pass address of setcontext in %r9. */
91 ucp->uc_mcontext.gregs[9] = (long) &setcontext;
93 /* Set stack pointer. */
94 ucp->uc_mcontext.gregs[15] = (long) sp;
97 asm(".text\n"
98 ".type __makecontext_ret,@function\n"
99 "__makecontext_ret:\n"
100 " basr %r14,%r7\n"
101 " lgr %r2,%r8\n"
102 " br %r9\n"
103 ".size __makecontext_ret, .-__makecontext_ret");
105 weak_alias (__makecontext, makecontext)