1 /* Create new context for ARC.
2 Copyright (C) 2020-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
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/>. */
18
19 #include <sysdep.h>
20 #include <stdarg.h>
21 #include <stdint.h>
22 #include <sys/ucontext.h>
23
24 void
__makecontext(ucontext_t * ucp,void (* func)(void),int argc,...)25 __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
26 {
27 extern void __startcontext (void) attribute_hidden;
28 unsigned long int sp, *r;
29 va_list vl;
30 int i, reg_args, stack_args;
31
32 sp = ((unsigned long int) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size) & ~7;
33
34 ucp->uc_mcontext.__sp = sp;
35 ucp->uc_mcontext.__fp = 0;
36
37 /* __startcontext is sort of trampoline to invoke @func
38 From setcontext pov, the resume address is __startcontext,
39 set it up in BLINK place holder. */
40
41 ucp->uc_mcontext.__blink = (unsigned long int) &__startcontext;
42
43 /* __startcontext passed 2 types of args
44 - args to @func setup in canonical r0-r7
45 - @func and next function in r14,r15. */
46
47 ucp->uc_mcontext.__r14 = (unsigned long int) func;
48 ucp->uc_mcontext.__r15 = (unsigned long int) ucp->uc_link;
49
50 r = &ucp->uc_mcontext.__r0;
51
52 va_start (vl, argc);
53
54 reg_args = argc > 8 ? 8 : argc;
55 for (i = 0; i < reg_args; i++)
56 *r-- = va_arg (vl, unsigned long int);
57
58 stack_args = argc - reg_args;
59
60 if (__glibc_unlikely (stack_args > 0))
61 {
62 sp -= stack_args * sizeof (unsigned long int);
63 ucp->uc_mcontext.__sp = sp;
64 r = (unsigned long int *) sp;
65
66 for (i = 0; i < stack_args; i++)
67 *r++ = va_arg (vl, unsigned long int);
68 }
69
70 va_end (vl);
71 }
72
73 weak_alias (__makecontext, makecontext)
74