aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h25
1 files changed, 18 insertions, 7 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 1bf20bd718..b00c976351 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -37,16 +37,25 @@ Cambridge, MA 02139, USA. */
#ifdef ASSEMBLER
-/* Linux uses a negative return value to indicate syscall errors, unlike
- most Unices, which use the condition codes' carry flag. */
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. For now (as of 2.1.1) 122 is the largest
+ defined error number. Given a bit room for development, Linus
+ chose in <asm/unistd.h> to use the values -125 to -1 for error
+ values. We follow him here. */
#undef PSEUDO
#define PSEUDO(name, syscall_name, args) \
.text; \
SYSCALL_ERROR_HANDLER \
ENTRY (name) \
DO_CALL (args, syscall_name); \
- testl %eax, %eax; \
- jl syscall_error;
+ cmpl $-125, %eax; \
+ jae syscall_error;
#ifndef PIC
#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
@@ -70,9 +79,10 @@ syscall_error: \
popl %ebx; \
movl %ecx, (%eax); \
movl $-1, %eax; \
- ret;
+ ret; \
+ .size syscall_error,.-syscall-error;
/* A quick note: it is assumed that the call to `__errno_location' does
- not modify the parameter value! */
+ not modify the stack! */
#else
#define SYSCALL_ERROR_HANDLER \
.type syscall_error,@function; \
@@ -85,7 +95,8 @@ syscall_error: \
movl errno@GOT(%ecx), %ecx; \
movl %edx, (%ecx); \
movl $-1, %eax; \
- ret;
+ ret; \
+ .size syscall_error,.-syscall-error;
#endif /* _LIBC_REENTRANT */
#endif /* PIC */