about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h72
1 files changed, 33 insertions, 39 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 730c4dfdf9..a6f18ec6f1 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -24,6 +24,7 @@
 #include <sysdeps/unix/i386/sysdep.h>
 #include <bp-sym.h>
 #include <bp-asm.h>
+#include <tls.h>
 
 /* For Linux we can use the system call table in the header file
 	/usr/include/asm/unistd.h
@@ -72,34 +73,47 @@
   END (name)
 
 #ifndef PIC
-#define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
+# define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
 #else
-/* Store (- %eax) into errno through the GOT.  */
-#ifdef _LIBC_REENTRANT
 
 # ifndef HAVE_HIDDEN
-#  define SETUP_PIC_REG \
+#  define SETUP_PIC_REG(reg) \
   call 1f;								      \
   .subsection 1;							      \
-1:movl (%esp), %ebx;							      \
+1:movl (%esp), %e##reg;							      \
   ret;									      \
   .previous
 # else
-#  define SETUP_PIC_REG \
-  .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits;	      \
-  .globl __i686.get_pc_thunk.bx;					      \
-  .hidden __i686.get_pc_thunk.bx;					      \
-  .type __i686.get_pc_thunk.bx,@function;				      \
-__i686.get_pc_thunk.bx:							      \
-  movl (%esp), %ebx;							      \
+#  define SETUP_PIC_REG(reg) \
+  .section .gnu.linkonce.t.__i686.get_pc_thunk.reg,"ax",@progbits;	      \
+  .globl __i686.get_pc_thunk.reg;					      \
+  .hidden __i686.get_pc_thunk.reg;					      \
+  .type __i686.get_pc_thunk.reg,@function;				      \
+__i686.get_pc_thunk.reg:						      \
+  movl (%esp), %e##reg;							      \
   ret;									      \
   .previous;								      \
-  call __i686.get_pc_thunk.bx
+  call __i686.get_pc_thunk.reg
 # endif
 
-#define SYSCALL_ERROR_HANDLER						      \
+/* Store (- %eax) into errno through the GOT.  */
+# ifdef _LIBC_REENTRANT
+
+#  if USE_TLS && HAVE___THREAD
+#   define SYSCALL_ERROR_HANDLER					      \
+0:SETUP_PIC_REG (cx);							      \
+  addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \
+  xorl %edx, %edx;							      \
+  subl %eax, %edx;							      \
+  movl %gs:0, %eax;							      \
+  subl errno@gottpoff(%ecx), %eax;					      \
+  movl %edx, (%eax);							      \
+  orl $-1, %eax;							      \
+  jmp L(pseudo_end);
+#  else
+#   define SYSCALL_ERROR_HANDLER					      \
 0:pushl %ebx;								      \
-  SETUP_PIC_REG;							      \
+  SETUP_PIC_REG (bx);							      \
   addl $_GLOBAL_OFFSET_TABLE_, %ebx;					      \
   xorl %edx, %edx;							      \
   subl %eax, %edx;							      \
@@ -114,30 +128,10 @@ __i686.get_pc_thunk.bx:							      \
   jmp L(pseudo_end);
 /* A quick note: it is assumed that the call to `__errno_location' does
    not modify the stack!  */
-#else
-
-# ifndef HAVE_HIDDEN
-#  define SETUP_PIC_REG \
-  call 1f;								      \
-  .subsection 1;							      \
-1:movl (%esp), %ecx;							      \
-  ret;									      \
-  .previous
+#  endif
 # else
-#  define SETUP_PIC_REG \
-  .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits;	      \
-  .globl __i686.get_pc_thunk.cx;					      \
-  .hidden __i686.get_pc_thunk.cx;					      \
-  .type __i686.get_pc_thunk.cx,@function;				      \
-__i686.get_pc_thunk.cx:							      \
-  movl (%esp), %ecx;							      \
-  ret;									      \
-  .previous;								      \
-  call __i686.get_pc_thunk.cx
-# endif
-
-#define SYSCALL_ERROR_HANDLER						      \
-0:define SETUP_PIC_REG;							      \
+#  define SYSCALL_ERROR_HANDLER						      \
+0:define SETUP_PIC_REG(cx);						      \
   addl $_GLOBAL_OFFSET_TABLE_, %ecx;					      \
   xorl %edx, %edx;							      \
   subl %eax, %edx;							      \
@@ -145,7 +139,7 @@ __i686.get_pc_thunk.cx:							      \
   movl %edx, (%ecx);							      \
   orl $-1, %eax;							      \
   jmp L(pseudo_end);
-#endif	/* _LIBC_REENTRANT */
+# endif	/* _LIBC_REENTRANT */
 #endif	/* PIC */
 
 /* Linux takes system call arguments in registers: