]>
Commit | Line | Data |
---|---|---|
ba1e2fe6 | 1 | /* Create new context. |
a334319f | 2 | Copyright (C) 2002, 2004 Free Software Foundation, Inc. |
ba1e2fe6 AJ |
3 | This file is part of the GNU C Library. |
4 | Contributed by Andreas Jaeger <aj@suse.de>, 2002. | |
5 | ||
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. | |
10 | ||
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. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public | |
17 | License along with the GNU C Library; if not, write to the Free | |
18 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
19 | 02111-1307 USA. */ | |
20 | ||
21 | #include <sysdep.h> | |
22 | #include <stdarg.h> | |
23 | #include <ucontext.h> | |
24 | ||
25 | #include "ucontext_i.h" | |
26 | ||
27 | /* This implementation can handle any ARGC value but only | |
28 | normal integer parameters. | |
29 | makecontext sets up a stack and the registers for the | |
30 | user context. The stack looks like this: | |
31 | +-----------------------+ | |
32 | | next context | | |
33 | +-----------------------+ | |
34 | | parameter 7-n | | |
35 | +-----------------------+ | |
36 | | trampoline address | | |
37 | %rsp -> +-----------------------+ | |
38 | ||
39 | The registers are set up like this: | |
40 | %rdi,%rsi,%rdx,%rcx,%r8,%r9: parameter 1 to 6 | |
41 | %rbx : address of next context | |
42 | %rsp : stack pointer. | |
43 | */ | |
44 | ||
45 | /* XXX: This implementation currently only handles integer arguments. | |
46 | To handle long int and pointer arguments the va_arg arguments needs | |
47 | to be changed to long and also the stdlib/tst-setcontext.c file needs | |
48 | to be changed to pass long arguments to makecontext. */ | |
49 | ||
50 | ||
51 | void | |
52 | __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) | |
53 | { | |
54 | extern void __start_context (void); | |
a334319f | 55 | unsigned long *sp, idx_uc_link; |
ba1e2fe6 AJ |
56 | va_list ap; |
57 | int i; | |
58 | ||
59 | /* Generate room on stack for parameter if needed and uc_link. */ | |
a334319f | 60 | sp = (long *) ((long) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); |
c2df18a9 | 61 | sp -= (argc > 6 ? argc - 6 : 0) + 1; |
9f19140a | 62 | /* Align stack and make space for trampoline address. */ |
a334319f | 63 | sp = (long *) ((((long) sp) & -16L) - 8); |
ba1e2fe6 | 64 | |
c2df18a9 | 65 | idx_uc_link = (argc > 6 ? argc - 6 : 0) + 1; |
ba1e2fe6 AJ |
66 | |
67 | /* Setup context ucp. */ | |
68 | /* Address to jump to. */ | |
a334319f | 69 | ucp->uc_mcontext.gregs[REG_RIP] = (long) func; |
ba1e2fe6 | 70 | /* Setup rbx.*/ |
a334319f UD |
71 | ucp->uc_mcontext.gregs[REG_RBX] = (long) &sp[idx_uc_link]; |
72 | ucp->uc_mcontext.gregs[REG_RSP] = (long) sp; | |
ba1e2fe6 AJ |
73 | |
74 | /* Setup stack. */ | |
a334319f UD |
75 | sp[0] = (long) &__start_context; |
76 | sp[idx_uc_link] = (long) ucp->uc_link; | |
ba1e2fe6 AJ |
77 | |
78 | va_start (ap, argc); | |
79 | /* Handle arguments. */ | |
80 | for (i = 0; i < argc; ++i) | |
81 | switch (i) | |
82 | { | |
83 | case 0: | |
84 | ucp->uc_mcontext.gregs [REG_RDI] = va_arg (ap, int); | |
85 | break; | |
86 | case 1: | |
87 | ucp->uc_mcontext.gregs [REG_RSI] = va_arg (ap, int); | |
88 | break; | |
89 | case 2: | |
90 | ucp->uc_mcontext.gregs [REG_RDX] = va_arg (ap, int); | |
91 | break; | |
92 | case 3: | |
93 | ucp->uc_mcontext.gregs [REG_RCX] = va_arg (ap, int); | |
94 | break; | |
95 | case 4: | |
96 | ucp->uc_mcontext.gregs [REG_R8] = va_arg (ap, int); | |
97 | break; | |
98 | case 5: | |
99 | ucp->uc_mcontext.gregs [REG_R9] = va_arg (ap, int); | |
100 | break; | |
101 | default: | |
102 | /* Put value on stack. */ | |
c2df18a9 | 103 | sp[(i - 5)] = va_arg (ap, int); |
ba1e2fe6 AJ |
104 | break; |
105 | } | |
106 | va_end (ap); | |
107 | ||
108 | } | |
109 | ||
110 | ||
a334319f | 111 | weak_alias(__makecontext, makecontext) |