(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / unix / sysv / linux / i386 / makecontext.S
blobec49b74b9ac546cfca00917d630ee150b3771297
1 /* Create new context.
2    Copyright (C) 2001,02 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, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #include <sysdep.h>
23 #include "ucontext_i.h"
26 ENTRY(__makecontext)
27         movl    4(%esp), %eax
29         /* Load the address of the function we are supposed to run.  */
30         movl    8(%esp), %ecx
32         /* Compute the address of the stack.  The information comes from
33            to us_stack element.  */
34         movl    oSS_SP(%eax), %edx
35         movl    %ecx, oEIP(%eax)
36         addl    oSS_SIZE(%eax), %edx
38         /* Put the next context on the new stack (from the uc_link
39            element).  */
40         movl    oLINK(%eax), %ecx
41         movl    %ecx, -4(%edx)
43         /* Remember the number of parameters for the exit handler since
44            it has to remove them.  We store the number in the EBX register
45            which the function we will call must preserve.  */
46         movl    12(%esp), %ecx
47         movl    %ecx, oEBX(%eax)
49         /* Make room on the new stack for the parameters.  */
50         negl    %ecx
51         leal    -8(%edx,%ecx,4), %edx
52         negl    %ecx
53         /* Store the future stack pointer.  */
54         movl    %edx, oESP(%eax)
56         /* Copy all the parameters.  */
57         jecxz   2f
58 1:      movl    12(%esp,%ecx,4), %eax
59         movl    %eax, (%edx,%ecx,4)
60         decl    %ecx
61         jnz     1b
64         /* If the function we call returns we must continue with the
65            context which is given in the uc_link element.  To do this
66            set the return address for the function the user provides
67            to a little bit of helper code which does the magic (see
68            below).  */
69 #ifdef PIC
70         call    1f
71 1:      popl    %ecx
72         addl    $L(exitcode)-1b, %ecx
73         movl    %ecx, (%edx)
74 #else
75         movl    $L(exitcode), (%edx)
76 #endif
77         /* 'makecontext' returns no value.  */
78         ret
80         /* This is the helper code which gets called if a function which
81            is registered with 'makecontext' returns.  In this case we
82            have to install the context listed in the uc_link element of
83            the context 'makecontext' manipulated at the time of the
84            'makecontext' call.  If the pointer is NULL the process must
85            terminate.  */
86 L(exitcode):
87         /* This removes the parameters passed to the function given to
88            'makecontext' from the stack.  EBX contains the number of
89            parameters (see above).  */
90         leal    (%esp,%ebx,4), %esp
92 #ifdef  PIC
93         call    1f
94 1:      popl    %ebx
95         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
96 #endif
97         popl    %eax                    /* This is the next context.  */
98         testl   %eax, %eax
99         je      2f                      /* If it is zero exit.  */
101         pushl   %eax
102         call    JUMPTARGET(__setcontext)
103         /* If this returns (which can happen if the syscall fails) we'll
104            exit the program with the return error value (-1).  */
106 2:      pushl   %eax
107         call    HIDDEN_JUMPTARGET(exit)
108         /* The 'exit' call should never return.  In case it does cause
109            the process to terminate.  */
110         hlt
111 END(__makecontext)
113 weak_alias(__makecontext, makecontext)