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.h112
1 files changed, 78 insertions, 34 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index af75d4c51a..5286676fc1 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 1992,1993,1995-2000,2002,2003,2004
-   Free Software Foundation, Inc.
+/* Copyright (C) 1992,1993,1995-2000,2002-2005,2006
+   	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
 
@@ -109,27 +109,6 @@
 # define SYSCALL_ERROR_HANDLER	/* Nothing here; code in sysdep.S is used.  */
 #else
 
-# ifndef HAVE_HIDDEN
-#  define SETUP_PIC_REG(reg) \
-  call 1f;								      \
-  .subsection 1;							      \
-1:movl (%esp), %e##reg;							      \
-  ret;									      \
-  .previous
-# else
-#  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;									      \
-  .size __i686.get_pc_thunk.reg, . - __i686.get_pc_thunk.reg;		      \
-  .previous;								      \
-  call __i686.get_pc_thunk.reg
-# endif
-
 # if RTLD_PRIVATE_ERRNO
 #  define SYSCALL_ERROR_HANDLER						      \
 0:SETUP_PIC_REG(cx);							      \
@@ -154,22 +133,36 @@ __i686.get_pc_thunk.reg:						      \
   movl SYSCALL_ERROR_ERRNO@GOTNTPOFF(%ecx), %ecx;			      \
   xorl %edx, %edx;							      \
   subl %eax, %edx;							      \
-  movl %edx, %gs:0(%ecx);						      \
+  SYSCALL_ERROR_HANDLER_TLS_STORE (%edx, %ecx);				      \
   orl $-1, %eax;							      \
   jmp L(pseudo_end);
+#   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
 #   define SYSCALL_ERROR_HANDLER					      \
 0:pushl %ebx;								      \
+  cfi_adjust_cfa_offset (4);						      \
+  cfi_rel_offset (ebx, 0);						      \
   SETUP_PIC_REG (bx);							      \
   addl $_GLOBAL_OFFSET_TABLE_, %ebx;					      \
   xorl %edx, %edx;							      \
   subl %eax, %edx;							      \
   pushl %edx;								      \
+  cfi_adjust_cfa_offset (4);						      \
   PUSH_ERRNO_LOCATION_RETURN;						      \
   call BP_SYM (__errno_location)@PLT;					      \
   POP_ERRNO_LOCATION_RETURN;						      \
   popl %ecx;								      \
+  cfi_adjust_cfa_offset (-4);						      \
   popl %ebx;								      \
+  cfi_adjust_cfa_offset (-4);						      \
+  cfi_restore (ebx);							      \
   movl %ecx, (%eax);							      \
   orl $-1, %eax;							      \
   jmp L(pseudo_end);
@@ -265,9 +258,11 @@ __i686.get_pc_thunk.reg:						      \
 #define PUSHARGS_1	movl %ebx, %edx; L(SAVEBX1): PUSHARGS_0
 #define	DOARGS_1	_DOARGS_1 (4)
 #define	POPARGS_1	POPARGS_0; movl %edx, %ebx; L(RESTBX1):
-#define	_PUSHARGS_1	pushl %ebx; L(PUSHBX1): _PUSHARGS_0
+#define	_PUSHARGS_1	pushl %ebx; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (ebx, 0); L(PUSHBX1): _PUSHARGS_0
 #define _DOARGS_1(n)	movl n(%esp), %ebx; _DOARGS_0(n-4)
-#define	_POPARGS_1	_POPARGS_0; popl %ebx; L(POPBX1):
+#define	_POPARGS_1	_POPARGS_0; popl %ebx; cfi_adjust_cfa_offset (-4); \
+			cfi_restore (ebx); L(POPBX1):
 
 #define PUSHARGS_2	PUSHARGS_1
 #define	DOARGS_2	_DOARGS_2 (8)
@@ -286,23 +281,29 @@ __i686.get_pc_thunk.reg:						      \
 #define PUSHARGS_4	_PUSHARGS_4
 #define DOARGS_4	_DOARGS_4 (24)
 #define POPARGS_4	_POPARGS_4
-#define _PUSHARGS_4	pushl %esi; L(PUSHSI1): _PUSHARGS_3
+#define _PUSHARGS_4	pushl %esi; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (esi, 0); L(PUSHSI1): _PUSHARGS_3
 #define _DOARGS_4(n)	movl n(%esp), %esi; _DOARGS_3 (n-4)
-#define _POPARGS_4	_POPARGS_3; popl %esi; L(POPSI1):
+#define _POPARGS_4	_POPARGS_3; popl %esi; cfi_adjust_cfa_offset (-4); \
+			cfi_restore (esi); L(POPSI1):
 
 #define PUSHARGS_5	_PUSHARGS_5
 #define DOARGS_5	_DOARGS_5 (32)
 #define POPARGS_5	_POPARGS_5
-#define _PUSHARGS_5	pushl %edi; L(PUSHDI1): _PUSHARGS_4
+#define _PUSHARGS_5	pushl %edi; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (edi, 0); L(PUSHDI1): _PUSHARGS_4
 #define _DOARGS_5(n)	movl n(%esp), %edi; _DOARGS_4 (n-4)
-#define _POPARGS_5	_POPARGS_4; popl %edi; L(POPDI1):
+#define _POPARGS_5	_POPARGS_4; popl %edi; cfi_adjust_cfa_offset (-4); \
+			cfi_restore (edi); L(POPDI1):
 
 #define PUSHARGS_6	_PUSHARGS_6
-#define DOARGS_6	_DOARGS_6 (36)
+#define DOARGS_6	_DOARGS_6 (40)
 #define POPARGS_6	_POPARGS_6
-#define _PUSHARGS_6	pushl %ebp; L(PUSHBP1): _PUSHARGS_5
+#define _PUSHARGS_6	pushl %ebp; cfi_adjust_cfa_offset (4); \
+			cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
 #define _DOARGS_6(n)	movl n(%esp), %ebp; _DOARGS_5 (n-4)
-#define _POPARGS_6	_POPARGS_5; popl %ebp; L(POPBP1):
+#define _POPARGS_6	_POPARGS_5; popl %ebp; cfi_adjust_cfa_offset (-4); \
+			cfi_restore (ebp); L(POPBP1):
 
 #else	/* !__ASSEMBLER__ */
 
@@ -446,7 +447,7 @@ asm (".L__X'%ebx = 1\n\t"
 
 #define LOADARGS_0
 #ifdef __PIC__
-# if defined I386_USE_SYSENTER
+# if defined I386_USE_SYSENTER && defined SHARED
 #  define LOADARGS_1 \
     "bpushl .L__X'%k3, %k3\n\t"
 #  define LOADARGS_5 \
@@ -532,6 +533,49 @@ asm (".L__X'%ebx = 1\n\t"
 # define EXTRAVAR_5
 #endif
 
+/* Consistency check for position-independent code.  */
+#ifdef __PIC__
+# define check_consistency()						      \
+  ({ int __res;								      \
+     __asm__ __volatile__						      \
+       ("call __i686.get_pc_thunk.cx;"					      \
+	"addl $_GLOBAL_OFFSET_TABLE_, %%ecx;"				      \
+	"subl %%ebx, %%ecx;"						      \
+	"je 1f;"							      \
+	"ud2;"								      \
+	"1:\n"								      \
+	".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"							      \
+	: "=c" (__res));						      \
+     __res; })
+#endif
+
 #endif	/* __ASSEMBLER__ */
 
+
+/* Pointer mangling support.  */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+   earlier than the descriptor is initialized.  Using a global variable
+   is too complicated here since we have no PC-relative addressing mode.  */
+#else
+# ifdef __ASSEMBLER__
+#  define PTR_MANGLE(reg)	xorl %gs:POINTER_GUARD, reg
+#  define PTR_DEMANGLE(reg)	PTR_MANGLE (reg)
+# else
+#  define PTR_MANGLE(var)	asm ("xorl %%gs:%c2, %0"		      \
+				     : "=r" (var)			      \
+				     : "0" (var),			      \
+				       "i" (offsetof (tcbhead_t,	      \
+						      pointer_guard)))
+#  define PTR_DEMANGLE(var)	PTR_MANGLE (var)
+# endif
+#endif
+
 #endif /* linux/i386/sysdep.h */