1 /* Copyright (C) 2001-2023 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
24 /* This implementation can handle any ARGC value but only
25 normal integer type parameters. Parameters of type float,
26 double, complex and structure with sizes 0, 2, 4 or 8
28 makecontext sets up a stack and the registers for the
29 user context. The stack looks like this:
31 %r15 -> +-----------------------+
32 4 | back chain (zero) | 0
34 88 | save area for (*func) | 8
35 +-----------------------+
36 n | overflow parameters | 96
37 +-----------------------+
38 The registers are set up like this:
39 %r2-%r6: parameters 1 to 5
41 %r8 : uc_link from ucontext structure
42 %r9 : address of setcontext
43 %r14 : return address to uc_link trampoline
46 The trampoline looks like this:
52 __makecontext (ucontext_t
*ucp
, void (*func
) (void), int argc
, ...)
54 extern void __makecontext_ret (void);
55 unsigned long int *sp
;
58 sp
= (unsigned long int *) (((unsigned long int) ucp
->uc_stack
.ss_sp
59 + ucp
->uc_stack
.ss_size
) & -8L);
61 /* Set the return address to trampoline. */
62 ucp
->uc_mcontext
.gregs
[14] = (long int) __makecontext_ret
;
64 /* Set register parameters. */
66 for (int i
= 0; i
< argc
&& i
< 5; ++i
)
67 ucp
->uc_mcontext
.gregs
[2 + i
] = va_arg (ap
, long int);
69 /* The remaining arguments go to the overflow area. */
73 for (int i
= 5; i
< argc
; ++i
)
74 sp
[i
- 5] = va_arg (ap
, long int);
78 /* Make room for the save area and set the backchain. */
82 /* Pass (*func) to __makecontext_ret in %r7. */
83 ucp
->uc_mcontext
.gregs
[7] = (long int) func
;
85 /* Pass ucp->uc_link to __makecontext_ret in %r8. */
86 ucp
->uc_mcontext
.gregs
[8] = (long int) ucp
->uc_link
;
88 /* Pass address of setcontext in %r9. */
89 ucp
->uc_mcontext
.gregs
[9] = (long int) &setcontext
;
91 /* Set stack pointer. */
92 ucp
->uc_mcontext
.gregs
[15] = (long int) sp
;
95 weak_alias (__makecontext
, makecontext
)