2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / i386 / posix_fadvise64.S
blob092a3bfb97e9ab90e0664b694b03015123ad03af
1 /* Copyright (C) 1995-2000,2002,2003,2004,2005,2006
2         Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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.  */
20 #include <sysdep.h>
21 #include <bp-sym.h>
22 #include <bp-asm.h>
24 #include <kernel-features.h>
26 #define EINVAL  22
27 #define ENOSYS  38
28 #define EOVERFLOW 75
30 #define SVRSP   16              /* saved register space */
31 #define PARMS   LINKAGE+SVRSP   /* space for 4 saved regs */
32 #define FD      PARMS
33 #define OFFLO   FD+4
34 #define OFFHI   OFFLO+4
35 #define LENLO   OFFHI+4
36 #define LENHI   LENLO+4
37 #define FLAGS   LENHI+4
39         .text
40 ENTRY (BP_SYM (__posix_fadvise64_l64))
42 #ifdef __NR_fadvise64_64
44         /* Save registers.  */
45         pushl   %ebp
46         cfi_adjust_cfa_offset (4)
47         pushl   %ebx
48         cfi_adjust_cfa_offset (4)
49         pushl   %esi
50         cfi_adjust_cfa_offset (4)
51         pushl   %edi
52         cfi_adjust_cfa_offset (4)
54         movl    FD(%esp), %ebx
55         cfi_rel_offset (ebx, 8)
56         movl    OFFLO(%esp), %ecx
57         movl    OFFHI(%esp), %edx
58         movl    LENLO(%esp), %esi
59         cfi_rel_offset (esi, 4)
60         movl    LENHI(%esp), %edi
61         cfi_rel_offset (edi, 0)
62         movl    FLAGS(%esp), %ebp
63         cfi_rel_offset (ebp, 12)
65         movl    $SYS_ify(fadvise64_64), %eax
66         ENTER_KERNEL
68         /* Restore registers.  */
69         popl    %edi
70         cfi_adjust_cfa_offset (-4)
71         cfi_restore (edi)
72         popl    %esi
73         cfi_adjust_cfa_offset (-4)
74         cfi_restore (esi)
75         popl    %ebx
76         cfi_adjust_cfa_offset (-4)
77         cfi_restore (ebx)
78         popl    %ebp
79         cfi_adjust_cfa_offset (-4)
80         cfi_restore (ebp)
82 #ifndef __ASSUME_FADVISE64_64_SYSCALL
83         cmpl    $-ENOSYS, %eax
84         je      1f
85 #endif
87         /* The function returns zero, or the error number.  So all we
88            have to do is negate the value passed back from the kernel.  */
89         /* If 0 > %eax > -4096 there was an error.  */
90         negl    %eax
92         /* Successful; return the syscall's value.  */
93         ret
94 #endif
96 #if defined __NR_fadvise64 \
97     && (!defined __ASSUME_FADVISE64_64_SYSCALL || !defined __NR_fadvise64_64)
98 1:      /* Save registers.  */
99         pushl   %ebx
100         cfi_adjust_cfa_offset (4)
101         pushl   %esi
102         cfi_adjust_cfa_offset (4)
103         pushl   %edi
104         cfi_adjust_cfa_offset (4)
106         /* Overflow check.  */
107         cmpl    $0, LENHI(%esp)
108         movl    $-EOVERFLOW, %eax
109         jne     L(overflow)
111         movl    FD(%esp), %ebx
112         cfi_rel_offset (ebx, 8)
113         movl    OFFLO(%esp), %ecx
114         movl    OFFHI(%esp), %edx
115         movl    LENLO(%esp), %esi
116         cfi_rel_offset (esi, 4)
117         movl    FLAGS(%esp), %edi
118         cfi_rel_offset (edi, 0)
120         movl    $SYS_ify(fadvise64), %eax
121         ENTER_KERNEL
123         /* Restore registers.  */
124 L(overflow):
125         popl    %edi
126         cfi_adjust_cfa_offset (-4)
127         cfi_restore (edi)
128         popl    %esi
129         cfi_adjust_cfa_offset (-4)
130         cfi_restore (esi)
131         popl    %ebx
132         cfi_adjust_cfa_offset (-4)
133         cfi_restore (ebx)
135         /* If 0 > %eax > -4096 there was an error.  */
136         negl    %eax
138         /* Successful; return the syscall's value.  */
139         ret
140 #else
141         movl    $ENOSYS, %eax
142         ret
143 #endif
145 END (BP_SYM (__posix_fadvise64_l64))
147 #ifdef __NR_fadvise64
148         .section        .text.compat, "ax"
149 ENTRY (__posix_fadvise64_l32)
150         DO_CALL (fadvise64, 5)
151         negl %eax
152         ret
153 PSEUDO_END_ERRVAL (__posix_fadvise64_l32)
154 #else
155 ENTRY (BP_SYM (__posix_fadvise64_l32))
156         movl    $ENOSYS, %eax
157         ret
158 END (BP_SYM (__posix_fadvise64_l32))
159 #endif
161 default_symbol_version (__posix_fadvise64_l64, posix_fadvise64, GLIBC_2.3.3)
162 symbol_version (__posix_fadvise64_l32, posix_fadvise64, GLIBC_2.2)