about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386')
-rw-r--r--sysdeps/unix/sysv/linux/i386/Makefile14
-rw-r--r--sysdeps/unix/sysv/linux/i386/clone.S8
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.c (renamed from sysdeps/unix/sysv/linux/i386/sysdep.S)34
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h78
4 files changed, 49 insertions, 85 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile
index 80da5935cf..e10d133db4 100644
--- a/sysdeps/unix/sysv/linux/i386/Makefile
+++ b/sysdeps/unix/sysv/linux/i386/Makefile
@@ -27,3 +27,17 @@ endif
 ifeq ($(subdir),stdlib)
 gen-as-const-headers += ucontext_i.sym
 endif
+
+ifeq ($(subdir),csu)
+sysdep-dl-routines += sysdep
+endif
+
+ifeq ($(subdir),nptl)
+# pull in __syscall_error routine
+libpthread-routines += sysdep
+endif
+
+ifeq ($(subdir),rt)
+# pull in __syscall_error routine
+librt-routines += sysdep
+endif
diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S
index 243dbfecc9..2aafb3a4a6 100644
--- a/sysdeps/unix/sysv/linux/i386/clone.S
+++ b/sysdeps/unix/sysv/linux/i386/clone.S
@@ -47,19 +47,11 @@ ENTRY (__clone)
 	/* Sanity check arguments.  */
 	movl	$-EINVAL,%eax
 	movl	FUNC(%esp),%ecx		/* no NULL function pointers */
-#ifdef PIC
-	jecxz	SYSCALL_ERROR_LABEL
-#else
 	testl	%ecx,%ecx
 	jz	SYSCALL_ERROR_LABEL
-#endif
 	movl	STACK(%esp),%ecx	/* no NULL stack pointers */
-#ifdef PIC
-	jecxz	SYSCALL_ERROR_LABEL
-#else
 	testl	%ecx,%ecx
 	jz	SYSCALL_ERROR_LABEL
-#endif
 
 	/* Insert the argument onto the new stack.  Make sure the new
 	   thread is started with an alignment of (mod 16).  */
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.S b/sysdeps/unix/sysv/linux/i386/sysdep.c
index 4e6c262f8e..141105eeff 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.S
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2015 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
@@ -15,26 +15,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <errno.h>
 #include <sysdep.h>
 
-/* The following code is only used in the shared library when we
-   compile the reentrant version.  Otherwise each system call defines
-   each own version.  */
-
-#ifndef PIC
-
-/* The syscall stubs jump here when they detect an error.
-   The code for Linux is almost identical to the canonical Unix/i386
-   code, except that the error number in %eax is negated.  */
-
-#undef CALL_MCOUNT
-#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %eax.  */
-
-	.text
-ENTRY (__syscall_error)
-	negl %eax
-
-#define __syscall_error __syscall_error_1
-#include <sysdeps/unix/i386/sysdep.S>
-
-#endif	/* !PIC */
+/* This routine is jumped to by all the syscall handlers, to stash
+   an error number into errno.  ERROR is the negative error number
+   returned from the x86 kernel.  */
+int
+__attribute__ ((__regparm__ (1)))
+__syscall_error (int error)
+{
+  __set_errno (-error);
+  return -1;
+}
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index d76aca50d6..3cf927a24b 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -20,6 +20,7 @@
 #define _LINUX_I386_SYSDEP_H 1
 
 /* There is some commonality.  */
+#include <sysdeps/unix/sysv/linux/sysdep.h>
 #include <sysdeps/unix/i386/sysdep.h>
 /* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO.  */
 #include <dl-sysdep.h>
@@ -55,11 +56,7 @@
 
 /* We don't want the label for the error handle to be global when we define
    it here.  */
-#ifdef PIC
-# define SYSCALL_ERROR_LABEL 0f
-#else
-# define SYSCALL_ERROR_LABEL syscall_error
-#endif
+#define SYSCALL_ERROR_LABEL __syscall_error
 
 #undef	PSEUDO
 #define	PSEUDO(name, syscall_name, args)				      \
@@ -100,55 +97,7 @@
 
 #define ret_ERRVAL ret
 
-#ifndef PIC
-# define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
-#else
-
-# if RTLD_PRIVATE_ERRNO
-#  define SYSCALL_ERROR_HANDLER						      \
-0:SETUP_PIC_REG(cx);							      \
-  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \
-  negl %eax;								      \
-  movl %eax, rtld_errno@GOTOFF(%ecx);					      \
-  orl $-1, %eax;							      \
-  ret;
-
-# elif defined _LIBC_REENTRANT
-
-#  if IS_IN (libc)
-#   define SYSCALL_ERROR_ERRNO __libc_errno
-#  else
-#   define SYSCALL_ERROR_ERRNO errno
-#  endif
-#  define SYSCALL_ERROR_HANDLER					      \
-0:SETUP_PIC_REG (cx);							      \
-  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \
-  movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx;			      \
-  negl %eax;								      \
-  SYSCALL_ERROR_HANDLER_TLS_STORE (%eax, %ecx);				      \
-  orl $-1, %eax;							      \
-  ret;
-#  ifndef NO_TLS_DIRECT_SEG_REFS
-#   define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)		      \
-  movl src, %gs:(destoff)
-#  else
-#   define SYSCALL_ERROR_HANDLER_TLS_STORE(src, destoff)		      \
-  addl %gs:0, destoff;							      \
-  movl src, (destoff)
-#  endif
-# else
-/* Store (- %eax) into errno through the GOT.  */
-#  define SYSCALL_ERROR_HANDLER						      \
-0:SETUP_PIC_REG(cx);							      \
-  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \
-  negl %eax;								      \
-  movl errno@GOT(%ecx), %ecx;						      \
-  movl %eax, (%ecx);							      \
-  orl $-1, %eax;							      \
-  ret;
-# endif	/* _LIBC_REENTRANT */
-#endif	/* PIC */
-
+#define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.c is used.  */
 
 /* The original calling convention for system calls on Linux/i386 is
    to use int $0x80.  */
@@ -275,6 +224,9 @@
 
 #else	/* !__ASSEMBLER__ */
 
+extern int __syscall_error (int)
+  attribute_hidden __attribute__ ((__regparm__ (1)));
+
 /* We need some help from the assembler to generate optimal code.  We
    define some macros here which later will be used.  */
 asm (".L__X'%ebx = 1\n\t"
@@ -318,7 +270,15 @@ struct libc_do_syscall_args
 /* Define a macro which expands inline into the wrapper code for a system
    call.  */
 #undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) \
+#if IS_IN (libc)
+# define INLINE_SYSCALL(name, nr, args...) \
+  ({									      \
+    unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);	      \
+    __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, ))		      \
+    ? __syscall_error (-INTERNAL_SYSCALL_ERRNO (resultvar, ))		      \
+    : (int) resultvar; })
+#else
+# define INLINE_SYSCALL(name, nr, args...) \
   ({									      \
     unsigned int resultvar = INTERNAL_SYSCALL (name, , nr, args);	      \
     if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (resultvar, )))	      \
@@ -327,6 +287,14 @@ struct libc_do_syscall_args
 	resultvar = 0xffffffff;						      \
       }									      \
     (int) resultvar; })
+#endif
+
+/* Set error number and return -1.  Return the internal function,
+   __syscall_error, which sets errno from the negative error number
+   and returns -1, to avoid PIC.  */
+#undef INLINE_SYSCALL_ERROR_RETURN_VALUE
+#define INLINE_SYSCALL_ERROR_RETURN_VALUE(resultvar) \
+  __syscall_error (-(resultvar))
 
 /* List of system calls which are supported as vsyscalls.  */
 # define HAVE_CLOCK_GETTIME_VSYSCALL    1