aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--elf/rtld.c2
-rw-r--r--nptl/ChangeLog7
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/createthread.c5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h6
-rw-r--r--sysdeps/generic/dl-sysdep.h6
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h75
7 files changed, 95 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index e006997..64f1b81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
2002-12-19 Roland McGrath <roland@redhat.com>
* iconvdata/ibm856.h: Convert GCC extension initializer syntax to C99.
diff --git a/elf/rtld.c b/elf/rtld.c
index 9b08b96..d510018 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -37,6 +37,7 @@
#include <unsecvars.h>
#include <dl-cache.h>
#include <dl-procinfo.h>
+#include <tls.h>
#include <assert.h>
@@ -328,6 +329,7 @@ _dl_start (void *arg)
to it. When we have something like GOTOFF relocs, we can use a plain
reference to find the runtime address. Without that, we have to rely
on the `l_addr' value, which is not the value we want when prelinked. */
+ dtv_t initdtv[3];
ElfW(Ehdr) *ehdr
# ifdef DONT_USE_BOOTSTRAP_MAP
= (ElfW(Ehdr) *) &_begin;
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 86fd4ed..c71c44b 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,12 @@
2002-12-19 Ulrich Drepper <drepper@redhat.com>
+ * allocatestack.c (allocate_stack) [NEED_DL_SYSINFO]: Set sysinfo
+ in new TCB.
+ * sysdeps/unix/sysv/linux/i386/createthread.c (create_thread): Check
+ that sysinfo is properly initialized.
+ * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Define RTLD_PRIVATE_ERRNO
+ to 1 only for ld.so.
+
* sysdeps/unix/sysv/linux/i386/dl-sysdep.h: Define
RTLD_CORRECT_DYNAMIC_WEAK.
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/createthread.c b/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
index be2ca82..def1633 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
+++ b/nptl/sysdeps/unix/sysv/linux/i386/createthread.c
@@ -108,6 +108,11 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
}
}
+#ifdef NEED_DL_SYSINFO
+ assert (THREAD_GETMEM (THREAD_SELF, header.data.sysinfo)
+ == pd->header.data.sysinfo);
+#endif
+
/* We rely heavily on various flags the CLONE function understands:
CLONE_VM, CLONE_FS, CLONE_FILES
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h
index 8f541c5..f0d4ac7 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h
@@ -28,7 +28,11 @@
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
/* This configuration has in libc.so cancellable functions and other
functions which have to behave differently if the application uses
diff --git a/sysdeps/generic/dl-sysdep.h b/sysdeps/generic/dl-sysdep.h
index b39103c..98bd5db 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 5275eba..6478af7 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