]>
git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/riscv/makecontext.c
1 /* Create new context. RISC-V version.
2 Copyright (C) 2001-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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 <https://www.gnu.org/licenses/>. */
21 #include <sys/ucontext.h>
26 __makecontext (ucontext_t
*ucp
, void (*func
) (void), int argc
,
27 long int a0
, long int a1
, long int a2
, long int a3
, long int a4
,
30 extern void __start_context (void) attribute_hidden
;
33 _Static_assert (REG_NARGS
== 8, "__makecontext assumes 8 argument registers");
35 /* Set up the stack. */
36 sp
= ((long int) ucp
->uc_stack
.ss_sp
+ ucp
->uc_stack
.ss_size
) & ALMASK
;
38 /* Set up the register context.
39 ra = s0 = 0, terminating the stack for backtracing purposes.
40 s1 = the function we must call.
41 s2 = the subsequent context to run. */
42 ucp
->uc_mcontext
.__gregs
[REG_RA
] = 0;
43 ucp
->uc_mcontext
.__gregs
[REG_S0
] = 0;
44 ucp
->uc_mcontext
.__gregs
[REG_S1
] = (long int) func
;
45 ucp
->uc_mcontext
.__gregs
[REG_S2
] = (long int) ucp
->uc_link
;
46 ucp
->uc_mcontext
.__gregs
[REG_SP
] = sp
;
47 ucp
->uc_mcontext
.__gregs
[REG_PC
] = (long int) &__start_context
;
49 /* Put args in a0-a7, then put any remaining args on the stack. */
50 ucp
->uc_mcontext
.__gregs
[REG_A0
+ 0] = a0
;
51 ucp
->uc_mcontext
.__gregs
[REG_A0
+ 1] = a1
;
52 ucp
->uc_mcontext
.__gregs
[REG_A0
+ 2] = a2
;
53 ucp
->uc_mcontext
.__gregs
[REG_A0
+ 3] = a3
;
54 ucp
->uc_mcontext
.__gregs
[REG_A0
+ 4] = a4
;
56 if (__glibc_unlikely (argc
> 5))
61 long reg_args
= argc
< REG_NARGS
? argc
: REG_NARGS
;
62 for (i
= 5; i
< reg_args
; i
++)
63 ucp
->uc_mcontext
.__gregs
[REG_A0
+ i
] = va_arg (vl
, long);
65 long int stack_args
= argc
- reg_args
;
68 sp
= (sp
- stack_args
* sizeof (long int)) & ALMASK
;
69 ucp
->uc_mcontext
.__gregs
[REG_SP
] = sp
;
70 for (i
= 0; i
< stack_args
; i
++)
71 ((long int *) sp
)[i
] = va_arg (vl
, long int);
78 weak_alias (__makecontext
, makecontext
)