2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library. If not, see
18 <https://www.gnu.org/licenses/>. */
22 #include <sys/ucontext.h>
27 __makecontext (ucontext_t
*ucp
, void (*func
) (void), int argc
, long int a0
,
28 long int a1
, long int a2
, long int a3
, long int a4
, ...)
30 extern void __start_context (void) attribute_hidden
;
31 unsigned long int *sp
;
33 _Static_assert(LARCH_REG_NARGS
== 8,
34 "__makecontext assumes 8 argument registers");
36 /* Set up the stack. */
37 sp
= (unsigned long int *)
38 (((uintptr_t) ucp
->uc_stack
.ss_sp
+ ucp
->uc_stack
.ss_size
) & ALMASK
);
40 /* Set up the register context.
41 ra = s0 = 0, terminating the stack for backtracing purposes.
42 s1 = the function we must call.
43 s2 = the subsequent context to run. */
44 ucp
->uc_mcontext
.__gregs
[LARCH_REG_RA
] = (uintptr_t) 0;
45 ucp
->uc_mcontext
.__gregs
[LARCH_REG_S0
] = (uintptr_t) 0;
46 ucp
->uc_mcontext
.__gregs
[LARCH_REG_S1
] = (uintptr_t) func
;
47 ucp
->uc_mcontext
.__gregs
[LARCH_REG_S2
] = (uintptr_t) ucp
->uc_link
;
48 ucp
->uc_mcontext
.__gregs
[LARCH_REG_SP
] = (uintptr_t) sp
;
49 ucp
->uc_mcontext
.__pc
= (uintptr_t) &__start_context
;
51 /* Put args in a0-a7, then put any remaining args on the stack. */
52 ucp
->uc_mcontext
.__gregs
[LARCH_REG_A0
+ 0] = (uintptr_t) a0
;
53 ucp
->uc_mcontext
.__gregs
[LARCH_REG_A0
+ 1] = (uintptr_t) a1
;
54 ucp
->uc_mcontext
.__gregs
[LARCH_REG_A0
+ 2] = (uintptr_t) a2
;
55 ucp
->uc_mcontext
.__gregs
[LARCH_REG_A0
+ 3] = (uintptr_t) a3
;
56 ucp
->uc_mcontext
.__gregs
[LARCH_REG_A0
+ 4] = (uintptr_t) a4
;
58 if (__glibc_unlikely (argc
> 5))
63 long int reg_args
= argc
< LARCH_REG_NARGS
? argc
: LARCH_REG_NARGS
;
64 for (long int i
= 5; i
< reg_args
; i
++)
65 ucp
->uc_mcontext
.__gregs
[LARCH_REG_A0
+ i
] = va_arg (vl
, unsigned long int);
67 long int stack_args
= argc
- reg_args
;
70 sp
= (unsigned long int *)
71 (((uintptr_t) sp
- stack_args
* sizeof (long int)) & ALMASK
);
72 ucp
->uc_mcontext
.__gregs
[LARCH_REG_SP
] = (uintptr_t) sp
;
73 for (long int i
= 0; i
< stack_args
; i
++)
74 sp
[i
] = va_arg (vl
, unsigned long int);
81 weak_alias (__makecontext
, makecontext
)