Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / s390 / s390-64 / makecontext.c
blob6623744b9e4dca59f19289647ca2e103116b1624
1 /* Copyright (C) 2001-2014 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, see
17 <http://www.gnu.org/licenses/>. */
19 #include <libintl.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <ucontext.h>
25 /* This implementation can handle any ARGC value but only
26 normal integer type parameters. Parameters of type float,
27 double, complex and structure with sizes 0, 2, 4 or 8
28 won't work.
29 makecontext sets up a stack and the registers for the
30 user context. The stack looks like this:
31 size offset
32 %r15 -> +-----------------------+
33 8 | back chain (zero) | 0
34 8 | reserved | 8
35 144 | save area for (*func) | 16
36 +-----------------------+
37 n | overflow parameters | 160
38 +-----------------------+
39 The registers are set up like this:
40 %r2-%r6: parameters 1 to 5
41 %r7 : (*func) pointer
42 %r8 : uc_link from ucontext structure
43 %r9 : address of setcontext
44 %r14 : return address to uc_link trampoline
45 %r15 : stack pointer.
47 The trampoline looks like this:
48 basr %r14,%r7
49 lgr %r2,%r8
50 br %r9. */
52 void
53 __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
55 extern void __makecontext_ret (void);
56 unsigned long int *sp;
57 va_list ap;
59 sp = (unsigned long int *) (((unsigned long int) ucp->uc_stack.ss_sp
60 + ucp->uc_stack.ss_size) & -8L);
62 /* Set the return address to trampoline. */
63 ucp->uc_mcontext.gregs[14] = (long int) __makecontext_ret;
65 /* Set register parameters. */
66 va_start (ap, argc);
67 for (int i = 0; i < argc && i < 5; ++i)
68 ucp->uc_mcontext.gregs[2 + i] = va_arg (ap, long int);
70 /* The remaining arguments go to the overflow area. */
71 if (argc > 5)
73 sp -= argc - 5;
74 for (int i = 5; i < argc; ++i)
75 sp[i - 5] = va_arg (ap, long int);
77 va_end (ap);
79 /* Make room for the save area and set the backchain. */
80 sp -= 20;
81 *sp = 0;
83 /* Pass (*func) to __makecontext_ret in %r7. */
84 ucp->uc_mcontext.gregs[7] = (long int) func;
86 /* Pass ucp->uc_link to __makecontext_ret in %r8. */
87 ucp->uc_mcontext.gregs[8] = (long int) ucp->uc_link;
89 /* Pass address of setcontext in %r9. */
90 ucp->uc_mcontext.gregs[9] = (long int) &setcontext;
92 /* Set stack pointer. */
93 ucp->uc_mcontext.gregs[15] = (long int) sp;
96 weak_alias (__makecontext, makecontext)