about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-12-19 23:05:13 +0000
committerUlrich Drepper <drepper@redhat.com>2002-12-19 23:05:13 +0000
commit5f5843e30dda46ffc443c492959e206530837c98 (patch)
tree7bc5ac8db51b676ae724d006fec887e2fdb11c75 /sysdeps
parent13880b3014cddd3700e4186a3e07aa6146863b02 (diff)
downloadglibc-5f5843e30dda46ffc443c492959e206530837c98.tar.gz
glibc-5f5843e30dda46ffc443c492959e206530837c98.tar.xz
glibc-5f5843e30dda46ffc443c492959e206530837c98.zip
Update.
2002-12-19  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/i386/sysdep.h: Add support to use AT_SYSINFO
	information for system calls.

	* sysdeps/generic/dl-sysdep.h: Define RTLD_PRIVATE_ERRNO to 1 only
	for ld.so.

	* elf/rtld.c (_dl_start) [USE___THREAD]: Define initdtv.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/dl-sysdep.h6
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h75
2 files changed, 66 insertions, 15 deletions
diff --git a/sysdeps/generic/dl-sysdep.h b/sysdeps/generic/dl-sysdep.h
index b39103cbc2..98bd5dbe84 100644
--- a/sysdeps/generic/dl-sysdep.h
+++ b/sysdeps/generic/dl-sysdep.h
@@ -25,4 +25,8 @@
    all the libc functions that ld.so uses are called without PLT and always
    get the versions linked into ld.so rather than the libc ones.  */
 
-#define RTLD_PRIVATE_ERRNO 1
+#ifdef IS_IN_rtld
+# define RTLD_PRIVATE_ERRNO 1
+#else
+# define RTLD_PRIVATE_ERRNO 0
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 5275ebaf57..6478af7f63 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -24,14 +24,11 @@
 #include <sysdeps/unix/i386/sysdep.h>
 #include <bp-sym.h>
 #include <bp-asm.h>
+/* Defines RTLD_PRIVATE_ERRNO and NEED_DL_SYSINFO.  */
+#include <dl-sysdep.h>
 #include <tls.h>
 
 
-#ifdef IS_IN_rtld
-# include <dl-sysdep.h>		/* Defines RTLD_PRIVATE_ERRNO.  */
-#endif
-
-
 /* For Linux we can use the system call table in the header file
 	/usr/include/asm/unistd.h
    of the kernel.  But these symbols do not follow the SYS_* syntax
@@ -39,6 +36,12 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)	__NR_##syscall_name
 
+#if defined NEED_DL_SYSINFO && !defined IS_IN_rtld
+# define I386_USE_SYSENTER	1
+#else
+# undef I386_USE_SYSENTER
+#endif
+
 #ifdef __ASSEMBLER__
 
 /* Linux uses a negative return value to indicate syscall errors,
@@ -162,7 +165,15 @@ __i686.get_pc_thunk.reg:						      \
 
 /* The original calling convention for system calls on Linux/i386 is
    to use int $0x80.  */
-#define ENTER_KERNEL int $0x80
+#ifdef I386_USE_SYSENTER
+# ifdef SHARED
+#  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
+# else
+#  define ENTER_KERNEL call *_dl_sysinfo
+# endif
+#else
+# define ENTER_KERNEL int $0x80
+#endif
 
 /* Linux takes system call arguments in registers:
 
@@ -260,10 +271,6 @@ __i686.get_pc_thunk.reg:						      \
 
 #else	/* !__ASSEMBLER__ */
 
-/* The original calling convention for system calls on Linux/i386 is
-   to use int $0x80.  */
-#define ENTER_KERNEL "int $0x80"
-
 /* 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,17 +325,46 @@ asm (".L__X'%ebx = 1\n\t"
    normally.  It will never touch errno.  This returns just what the kernel
    gave back.  */
 #undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, nr, args...) \
+#ifdef I386_USE_SYSENTER
+# ifdef SHARED
+#  define INTERNAL_SYSCALL(name, nr, args...) \
+  ({									      \
+    unsigned int resultvar;						      \
+    asm volatile (							      \
+    LOADARGS_##nr							      \
+    "movl %1, %%eax\n\t"						      \
+    "call *%%gs:%P2\n\t"						      \
+    RESTOREARGS_##nr							      \
+    : "=a" (resultvar)							      \
+    : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo))		      \
+      ASMFMT_##nr(args) : "memory", "cc");				      \
+    (int) resultvar; })
+# else
+#  define INTERNAL_SYSCALL(name, nr, args...) \
   ({									      \
     unsigned int resultvar;						      \
     asm volatile (							      \
     LOADARGS_##nr							      \
     "movl %1, %%eax\n\t"						      \
-    ENTER_KERNEL "\n\t"						      \
+    "call *_dl_sysinfo\n\t"						      \
     RESTOREARGS_##nr							      \
     : "=a" (resultvar)							      \
     : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");		      \
     (int) resultvar; })
+# endif
+#else
+# define INTERNAL_SYSCALL(name, nr, args...) \
+  ({									      \
+    unsigned int resultvar;						      \
+    asm volatile (							      \
+    LOADARGS_##nr							      \
+    "movl %1, %%eax\n\t"						      \
+    "int $0x80\n\t"						      \
+    RESTOREARGS_##nr							      \
+    : "=a" (resultvar)							      \
+    : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");		      \
+    (int) resultvar; })
+#endif
 
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val)	((unsigned int) (val) >= 0xfffff001u)
@@ -337,17 +373,28 @@ asm (".L__X'%ebx = 1\n\t"
 #define INTERNAL_SYSCALL_ERRNO(val)	(-(val))
 
 #define LOADARGS_0
-#define LOADARGS_1 \
+#if defined I386_USE_SYSENTER && defined SHARED
+# define LOADARGS_1 \
+    "bpushl .L__X'%k3, %k3\n\t"						      \
+    "bmovl .L__X'%k3, %k3\n\t"
+#else
+# define LOADARGS_1 \
     "bpushl .L__X'%k2, %k2\n\t"						      \
     "bmovl .L__X'%k2, %k2\n\t"
+#endif
 #define LOADARGS_2	LOADARGS_1
 #define LOADARGS_3	LOADARGS_1
 #define LOADARGS_4	LOADARGS_1
 #define LOADARGS_5	LOADARGS_1
 
 #define RESTOREARGS_0
-#define RESTOREARGS_1 \
+#if defined I386_USE_SYSENTER && defined SHARED
+# define RESTOREARGS_1 \
+    "bpopl .L__X'%k3, %k3\n\t"
+#else
+# define RESTOREARGS_1 \
     "bpopl .L__X'%k2, %k2\n\t"
+#endif
 #define RESTOREARGS_2	RESTOREARGS_1
 #define RESTOREARGS_3	RESTOREARGS_1
 #define RESTOREARGS_4	RESTOREARGS_1