Maintain stack alignment in ____longjmp_chk on x86_64
[glibc.git] / sysdeps / unix / sysv / linux / i386 / accept4.S
blob1d05eff7f7c3df1b60e879c64661b0a238b2acd3
1 /* Copyright (C) 1995-1998,2002,2003,2005, 2008 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
19 #include <sysdep-cancel.h>
20 #include <socketcall.h>
21 #include <tls.h>
22 #include <kernel-features.h>
24 #define EINVAL  22
25 #define ENOSYS  38
27 #ifdef __ASSUME_ACCEPT4
28 # define errlabel SYSCALL_ERROR_LABEL
29 #else
30 # define errlabel .Lerr
31         .data
32 have_accept4:
33         .long   0
34 #endif
36         .text
37 /* The socket-oriented system calls are handled unusally in Linux/i386.
38    They are all gated through the single `socketcall' system call number.
39    `socketcall' takes two arguments: the first is the subcode, specifying
40    which socket function is being called; and the second is a pointer to
41    the arguments to the specific function.  */
43 .globl __libc_accept4
44 ENTRY (__libc_accept4)
45 #ifdef CENABLE
46         SINGLE_THREAD_P
47         jne 1f
48 #endif
50         /* Save registers.  */
51         movl %ebx, %edx
52         cfi_register (3, 2)
54         movl $SYS_ify(socketcall), %eax /* System call number in %eax.  */
56         movl $SOCKOP_accept4, %ebx      /* Subcode is first arg to syscall.  */
57         lea 4(%esp), %ecx               /* Address of args is 2nd arg.  */
59         /* Do the system call trap.  */
60         ENTER_KERNEL
62         /* Restore registers.  */
63         movl %edx, %ebx
64         cfi_restore (3)
66         /* %eax is < 0 if there was an error.  */
67         cmpl $-125, %eax
68         jae errlabel
70         /* Successful; return the syscall's value.  */
71 L(pseudo_end):
72         ret
75 #ifdef CENABLE
76         /* We need one more register.  */
77 1:      pushl %esi
78         cfi_adjust_cfa_offset(4)
80         /* Enable asynchronous cancellation.  */
81         CENABLE
82         movl %eax, %esi
83         cfi_offset(6, -8)               /* %esi */
85         /* Save registers.  */
86         movl %ebx, %edx
87         cfi_register (3, 2)
89         movl $SYS_ify(socketcall), %eax /* System call number in %eax.  */
91         movl $SOCKOP_accept4, %ebx      /* Subcode is first arg to syscall.  */
92         lea 8(%esp), %ecx               /* Address of args is 2nd arg.  */
94         /* Do the system call trap.  */
95         ENTER_KERNEL
97         /* Restore registers.  */
98         movl %edx, %ebx
99         cfi_restore (3)
101         /* Restore the cancellation.  */
102         xchgl %esi, %eax
103         CDISABLE
105         /* Restore registers.  */
106         movl %esi, %eax
107         popl %esi
108         cfi_restore (6)
109         cfi_adjust_cfa_offset(-4)
111         /* %eax is < 0 if there was an error.  */
112         cmpl $-125, %eax
113         jae errlabel
115         /* Successful; return the syscall's value.  */
116         ret
117 #endif
119 #ifndef __ASSUME_ACCEPT4
120         /* The kernel returns -EINVAL for unknown socket operations.
121            We need to convert that error to an ENOSYS error.  */
122 .Lerr:  cmpl $-EINVAL, %eax
123         jne SYSCALL_ERROR_LABEL
125         /* Save registers.  */
126         pushl %ebx
127         cfi_adjust_cfa_offset(4)
128         cfi_offset(ebx, -8)
130 # ifdef PIC
131         SETUP_PIC_REG (dx)
132         addl $_GLOBAL_OFFSET_TABLE_, %edx
133         movl have_accept4@GOTOFF(%edx), %eax
134 # else
135         movl have_accept4, %eax
136 # endif
137         testl %eax, %eax
138         jne 1f
140         /* Try another call, this time with the FLAGS parameter
141            cleared and an invalid file descriptor.  This call will not
142            cause any harm and it will return immediately.  */
143         movl $-1, 8(%esp)
144         movl $0, 20(%esp)
146         movl $SYS_ify(socketcall), %eax /* System call number in %eax.  */
148         movl $SOCKOP_accept4, %ebx      /* Subcode is first arg to syscall.  */
149         lea 8(%esp), %ecx               /* Address of args is 2nd arg.  */
151         /* Do the system call trap.  */
152         ENTER_KERNEL
154         cmpl $-EINVAL, %eax
155         movl $-1, %eax
156         je 3f
157         movl $1, %eax
159 # ifdef PIC
160         movl %eax, have_accept4@GOTOFF(%edx)
161 # else
162         movl %eax, have_accept4
163 # endif
165         testl %eax, %eax
167 1:      movl $-EINVAL, %eax
168         jns 2f
169         movl $-ENOSYS, %eax
171         /* Restore registers.  */
172 2:      popl %ebx
173         cfi_restore (ebx)
175         jmp SYSCALL_ERROR_LABEL
176 #endif
177 PSEUDO_END (__libc_accept4)
179 weak_alias (__libc_accept4, accept4)