summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2005-07-06 22:40:33 +0000
committerMike Frysinger <vapier@gentoo.org>2005-07-06 22:40:33 +0000
commit76d80593426f5f77a51dcf694786576a37f3b208 (patch)
tree9e70c2ade4627510fe6173ae614683efc28de466 /libc
parentd1de87b09ddd8f096d0191ffb0a694acea13d84b (diff)
Peter S. Mazinger writes: use the __syscall_error.c trick to handle setting errno
Diffstat (limited to 'libc')
-rw-r--r--libc/sysdeps/linux/i386/Makefile2
-rw-r--r--libc/sysdeps/linux/i386/__syscall_error.c29
-rw-r--r--libc/sysdeps/linux/i386/mmap64.S30
-rw-r--r--libc/sysdeps/linux/i386/syscall.S55
-rw-r--r--libc/sysdeps/linux/i386/vfork.S23
5 files changed, 55 insertions, 84 deletions
diff --git a/libc/sysdeps/linux/i386/Makefile b/libc/sysdeps/linux/i386/Makefile
index e29707f0e..fc13e6f45 100644
--- a/libc/sysdeps/linux/i386/Makefile
+++ b/libc/sysdeps/linux/i386/Makefile
@@ -28,7 +28,7 @@ SSRC=__longjmp.S vfork.S clone.S setjmp.S bsd-setjmp.S \
bsd-_setjmp.S syscall.S mmap64.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
-CSRC=brk.c sigaction.c
+CSRC=brk.c sigaction.c __syscall_error.c
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(SOBJS) $(COBJS)
diff --git a/libc/sysdeps/linux/i386/__syscall_error.c b/libc/sysdeps/linux/i386/__syscall_error.c
new file mode 100644
index 000000000..de65a1f39
--- /dev/null
+++ b/libc/sysdeps/linux/i386/__syscall_error.c
@@ -0,0 +1,29 @@
+/* Wrapper for setting errno.
+ Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <features.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ * an error number into errno. */
+int attribute_hidden __syscall_error(int err_no)
+{
+ __set_errno(err_no);
+ return -1;
+}
diff --git a/libc/sysdeps/linux/i386/mmap64.S b/libc/sysdeps/linux/i386/mmap64.S
index 42d1bb69e..dde3b9ae1 100644
--- a/libc/sysdeps/linux/i386/mmap64.S
+++ b/libc/sysdeps/linux/i386/mmap64.S
@@ -65,6 +65,7 @@ mmap64:
movl FD(%esp), %edi
movl $__NR_mmap2, %eax /* System call number in %eax. */
+ /* Do the system call trap. */
int $0x80
/* Restore registers. */
@@ -75,7 +76,8 @@ mmap64:
/* If 0 > %eax > -4096 there was an error. */
cmpl $-4095,%eax
- jae __syscall_error
+ ja __error
+ /* Successful; return the syscall's value. */
ret
/* This means the offset value is too large. */
@@ -85,27 +87,11 @@ L_einval:
popl %ebx
popl %ebp
movl $-EINVAL, %eax
- jmp __syscall_error
-
-
-__syscall_error:
- negl %eax
- pushl %eax
-#ifdef __PIC__
- call .Lthere
-.Lthere:
- popl %ebx
- addl $_GLOBAL_OFFSET_TABLE_+[.- .Lthere ], %ebx
- call __errno_location@PLT
-#else
- call __errno_location
-#endif
- popl %ecx
- movl %ecx, (%eax)
- xorl %eax, %eax
- decl %eax
+ jmp __error
+
+__error:
+ call __syscall_error
-.Lsize:
-.size mmap64,.Lsize-mmap64
+.size mmap64,.-mmap64
#endif
diff --git a/libc/sysdeps/linux/i386/syscall.S b/libc/sysdeps/linux/i386/syscall.S
index b65950fb5..7c49625b2 100644
--- a/libc/sysdeps/linux/i386/syscall.S
+++ b/libc/sysdeps/linux/i386/syscall.S
@@ -20,8 +20,6 @@
* and things will just work.
*/
-#include <features.h>
-
.text
.global syscall
.type syscall,%function
@@ -30,49 +28,22 @@ syscall:
pushl %edi
pushl %esi
pushl %ebx
- movl 36(%esp),%edi; /* Load the 5 syscall argument registers */
- movl 32(%esp),%esi;
- movl 28(%esp),%edx;
- movl 24(%esp),%ecx;
- movl 20(%esp),%ebx;
+ movl 36(%esp),%edi /* Load the 5 syscall argument registers */
+ movl 32(%esp),%esi
+ movl 28(%esp),%edx
+ movl 24(%esp),%ecx
+ movl 20(%esp),%ebx
movl 16(%esp),%eax /* Load syscall number into %eax. */
-#APP
int $0x80
-#NO_APP
- cmpl $-4095,%eax
- jbe .Ldone
-
-#ifdef __PIC__
- call Lhere
-Lhere:
- popl %ebx
- addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere],%ebx
- negl %eax
- movl %eax,%ecx
-#ifdef __UCLIBC_HAS_THREADS__
- call __errno_location@PLT
-#else
- movl errno@GOT(%ebx),%eax
-#endif /* __UCLIBC_HAS_THREADS__ */
- movl %ecx,(%eax)
-#else
- negl %eax
-#ifdef __UCLIBC_HAS_THREADS__
- movl %eax,%ecx
- call __errno_location
- movl %ecx,(%eax)
-#else
- movl %eax,errno
-#endif /* __UCLIBC_HAS_THREADS__ */
-
-#endif /* __PIC__ */
- movl $-1,%eax
- .p2align 4,,7
-.Ldone:
popl %ebx
popl %esi
popl %edi
- ret
-.Lsize:
-.size syscall,.Lsize-syscall
+ cmpl $-4095,%eax
+ jae __error
+ ret /* Return to caller. */
+
+__error:
+ call __syscall_error
+
+.size syscall,.-syscall
diff --git a/libc/sysdeps/linux/i386/vfork.S b/libc/sysdeps/linux/i386/vfork.S
index d9b8ab7ca..00a2954d5 100644
--- a/libc/sysdeps/linux/i386/vfork.S
+++ b/libc/sysdeps/linux/i386/vfork.S
@@ -25,28 +25,13 @@ __vfork:
int $0x80
pushl %ecx
cmpl $-4095,%eax
- jae __syscall_error
+ jae __error
ret
-__syscall_error:
- negl %eax
- pushl %eax
-#ifdef __PIC__
- call .Lthere
-.Lthere:
- popl %ebx
- addl $_GLOBAL_OFFSET_TABLE_+[.- .Lthere ], %ebx
- call __errno_location@PLT
-#else
- call __errno_location
-#endif
- popl %ecx
- movl %ecx, (%eax)
- xorl %eax, %eax
- decl %eax
+__error:
+ call __syscall_error
-.Lsize:
-.size __vfork,.Lsize-__vfork
+.size __vfork,.-__vfork
.weak vfork ; vfork = __vfork