From 5f5843e30dda46ffc443c492959e206530837c98 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 19 Dec 2002 23:05:13 +0000 Subject: [PATCH] Update. 2002-12-19 Ulrich Drepper * 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. --- ChangeLog | 10 ++++ elf/rtld.c | 2 + nptl/ChangeLog | 7 +++ nptl/sysdeps/unix/sysv/linux/i386/createthread.c | 5 ++ nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h | 6 +- sysdeps/generic/dl-sysdep.h | 6 +- sysdeps/unix/sysv/linux/i386/sysdep.h | 75 +++++++++++++++++++----- 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 + + * 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 * 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 #include #include +#include #include @@ -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 + * 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 #include #include +/* Defines RTLD_PRIVATE_ERRNO and NEED_DL_SYSINFO. */ +#include #include -#ifdef IS_IN_rtld -# include /* 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 -- 2.7.4