Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / i386 / makecontext.S
blob8364fb98ee8ac88e333fd420b14f6f5e919d9bf3
1 /* Create new context.
2    Copyright (C) 2001-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
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    <http://www.gnu.org/licenses/>.  */
20 #include <sysdep.h>
22 #include "ucontext_i.h"
25 ENTRY(__makecontext)
26         movl    4(%esp), %eax
28         /* Load the address of the function we are supposed to run.  */
29         movl    8(%esp), %ecx
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
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)
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.  */
47         negl    %ecx
48         leal    -4(%edx,%ecx,4), %edx
49         negl    %ecx
51         /* Align the stack.  */
52         andl    $0xfffffff0, %edx
53         subl    $4, %edx
55         /* Store the future stack pointer.  */
56         movl    %edx, oESP(%eax)
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)
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
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
78         cfi_adjust_cfa_offset (4)
79 1:      popl    %ecx
80         cfi_adjust_cfa_offset (-4)
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
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.  */
95         cfi_endproc
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
102 #ifdef  PIC
103         call    1f
104 1:      popl    %ebx
105         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
106 #endif
107         cmpl    $0, (%esp)              /* Check the next context.  */
108         je      2f                      /* If it is zero exit.  */
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).  */
114         movl    %eax, (%esp)
115 2:      call    HIDDEN_JUMPTARGET(exit)
116         /* The 'exit' call should never return.  In case it does cause
117            the process to terminate.  */
118         hlt
119         cfi_startproc
120 END(__makecontext)
122 weak_alias (__makecontext, makecontext)