dceb6815f40cd6fc6e6bbda5b675a6f38c3c8943
[kopensolaris-gnu/glibc.git] / sysdeps / unix / i386 / sysdep.S
1 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 2000, 2002
2         Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <sysdep.h>
21 #define _ERRNO_H
22 #include <bits/errno.h>
23 #include <bp-asm.h>
24 #include <bp-sym.h>
25
26 #ifdef IS_IN_rtld
27 # include <dl-sysdep.h>         /* Defines RTLD_PRIVATE_ERRNO.  */
28 #endif
29
30 .globl C_SYMBOL_NAME(errno)
31 .globl syscall_error
32
33 #undef syscall_error
34 #ifdef NO_UNDERSCORES
35 __syscall_error:
36 #else
37 syscall_error:
38 #endif
39 #if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN
40         /* We translate the system's EWOULDBLOCK error into EAGAIN.
41            The GNU C library always defines EWOULDBLOCK==EAGAIN.
42            EWOULDBLOCK_sys is the original number.  */
43         cmpl $EWOULDBLOCK_sys, %eax /* Is it the old EWOULDBLOCK?  */
44         jne notb                /* Branch if not.  */
45         movl $EAGAIN, %eax      /* Yes; translate it to EAGAIN.  */
46 notb:
47 #endif
48 #ifndef PIC
49 # if USE___THREAD
50         movl %eax, %gs:C_SYMBOL_NAME(errno@NTPOFF)
51 # elif !defined _LIBC_REENTRANT
52         movl %eax, C_SYMBOL_NAME(errno)
53 # else
54         pushl %eax
55         PUSH_ERRNO_LOCATION_RETURN
56         call BP_SYM (__errno_location)
57         POP_ERRNO_LOCATION_RETURN
58         popl %ecx
59         movl %ecx, (%eax)
60 # endif
61 #else
62         /* The caller has pushed %ebx and then set it up to
63            point to the GOT before calling us through the PLT.  */
64 # if USE___THREAD
65         movl C_SYMBOL_NAME(errno@GOTNTPOFF)(%ebx), %ecx
66
67         /* Pop %ebx value saved before jumping here.  */
68         popl %ebx
69         movl %eax, %gs:0(%ecx)
70 # elif RTLD_PRIVATE_ERRNO
71         movl %eax, C_SYMBOL_NAME(errno@GOTOFF)(%ebx)
72
73         /* Pop %ebx value saved before jumping here.  */
74         popl %ebx
75 # elif !defined _LIBC_REENTRANT
76         movl C_SYMBOL_NAME(errno@GOT)(%ebx), %ecx
77
78         /* Pop %ebx value saved before jumping here.  */
79         popl %ebx
80         movl %eax, (%ecx)
81 # else
82         pushl %eax
83         PUSH_ERRNO_LOCATION_RETURN
84         call C_SYMBOL_NAME (BP_SYM (__errno_location)@PLT)
85         POP_ERRNO_LOCATION_RETURN
86         popl %ecx
87         /* Pop %ebx value saved before jumping here.  */
88         popl %ebx
89         movl %ecx, (%eax)
90 # endif
91 #endif
92         movl $-1, %eax
93         ret
94
95 #undef  __syscall_error
96 END (__syscall_error)