]>
Commit | Line | Data |
---|---|---|
4ee87ecc | 1 | /* Create new context. |
b168057a | 2 | Copyright (C) 2001-2015 Free Software Foundation, Inc. |
4ee87ecc UD |
3 | This file is part of the GNU C Library. |
4 | Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. | |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
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. | |
4ee87ecc UD |
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 | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
4ee87ecc | 15 | |
41bdb6e2 | 16 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
4ee87ecc UD |
19 | |
20 | #include <sysdep.h> | |
21 | ||
22 | #include "ucontext_i.h" | |
23 | ||
24 | ||
25 | ENTRY(__makecontext) | |
26 | movl 4(%esp), %eax | |
27 | ||
28 | /* Load the address of the function we are supposed to run. */ | |
29 | movl 8(%esp), %ecx | |
30 | ||
31 | /* Compute the address of the stack. The information comes from | |
32 | to us_stack element. */ | |
33 | movl oSS_SP(%eax), %edx | |
34 | movl %ecx, oEIP(%eax) | |
35 | addl oSS_SIZE(%eax), %edx | |
36 | ||
4ee87ecc UD |
37 | /* Remember the number of parameters for the exit handler since |
38 | it has to remove them. We store the number in the EBX register | |
39 | which the function we will call must preserve. */ | |
40 | movl 12(%esp), %ecx | |
41 | movl %ecx, oEBX(%eax) | |
42 | ||
148e12ed UD |
43 | /* Make room on the new stack for the parameters. |
44 | Room for the arguments, return address (== L(exitcode)) and | |
45 | oLINK pointer is needed. One of the pointer sizes is subtracted | |
46 | after aligning the stack. */ | |
4ee87ecc | 47 | negl %ecx |
148e12ed | 48 | leal -4(%edx,%ecx,4), %edx |
4ee87ecc | 49 | negl %ecx |
51bd20d9 UD |
50 | |
51 | /* Align the stack. */ | |
51bd20d9 UD |
52 | andl $0xfffffff0, %edx |
53 | subl $4, %edx | |
54 | ||
4ee87ecc UD |
55 | /* Store the future stack pointer. */ |
56 | movl %edx, oESP(%eax) | |
57 | ||
51bd20d9 UD |
58 | /* Put the next context on the new stack (from the uc_link |
59 | element). */ | |
60 | movl oLINK(%eax), %eax | |
61 | movl %eax, 4(%edx,%ecx,4) | |
62 | ||
4ee87ecc UD |
63 | /* Copy all the parameters. */ |
64 | jecxz 2f | |
65 | 1: movl 12(%esp,%ecx,4), %eax | |
66 | movl %eax, (%edx,%ecx,4) | |
67 | decl %ecx | |
68 | jnz 1b | |
69 | 2: | |
70 | ||
71 | /* If the function we call returns we must continue with the | |
72 | context which is given in the uc_link element. To do this | |
73 | set the return address for the function the user provides | |
74 | to a little bit of helper code which does the magic (see | |
75 | below). */ | |
76 | #ifdef PIC | |
77 | call 1f | |
fee732e5 | 78 | cfi_adjust_cfa_offset (4) |
4ee87ecc | 79 | 1: popl %ecx |
fee732e5 | 80 | cfi_adjust_cfa_offset (-4) |
4ee87ecc UD |
81 | addl $L(exitcode)-1b, %ecx |
82 | movl %ecx, (%edx) | |
83 | #else | |
84 | movl $L(exitcode), (%edx) | |
85 | #endif | |
86 | /* 'makecontext' returns no value. */ | |
87 | ret | |
88 | ||
89 | /* This is the helper code which gets called if a function which | |
90 | is registered with 'makecontext' returns. In this case we | |
91 | have to install the context listed in the uc_link element of | |
92 | the context 'makecontext' manipulated at the time of the | |
93 | 'makecontext' call. If the pointer is NULL the process must | |
94 | terminate. */ | |
fee732e5 | 95 | cfi_endproc |
4ee87ecc UD |
96 | L(exitcode): |
97 | /* This removes the parameters passed to the function given to | |
98 | 'makecontext' from the stack. EBX contains the number of | |
99 | parameters (see above). */ | |
100 | leal (%esp,%ebx,4), %esp | |
101 | ||
102 | #ifdef PIC | |
103 | call 1f | |
104 | 1: popl %ebx | |
105 | addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx | |
106 | #endif | |
9b6bf8a3 | 107 | cmpl $0, (%esp) /* Check the next context. */ |
4ee87ecc UD |
108 | je 2f /* If it is zero exit. */ |
109 | ||
4ee87ecc UD |
110 | call JUMPTARGET(__setcontext) |
111 | /* If this returns (which can happen if the syscall fails) we'll | |
112 | exit the program with the return error value (-1). */ | |
113 | ||
9b6bf8a3 UD |
114 | movl %eax, (%esp) |
115 | 2: call HIDDEN_JUMPTARGET(exit) | |
4ee87ecc UD |
116 | /* The 'exit' call should never return. In case it does cause |
117 | the process to terminate. */ | |
118 | hlt | |
fee732e5 | 119 | cfi_startproc |
4ee87ecc UD |
120 | END(__makecontext) |
121 | ||
1ab18a5b | 122 | weak_alias (__makecontext, makecontext) |