diff options
author | Ulrich Drepper <drepper@redhat.com> | 2002-09-29 18:12:30 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2002-09-29 18:12:30 +0000 |
commit | 3ae5121b7ff54f043c0288c29a76fa28a8ff7c3d (patch) | |
tree | dd1dfbb3f2029bd0e4efd56f6669130cc6121c60 /linuxthreads/sysdeps | |
parent | f2672dddd1604f2eeb58f655bf0c81c0ef08f9d2 (diff) | |
download | glibc-3ae5121b7ff54f043c0288c29a76fa28a8ff7c3d.tar.gz glibc-3ae5121b7ff54f043c0288c29a76fa28a8ff7c3d.tar.xz glibc-3ae5121b7ff54f043c0288c29a76fa28a8ff7c3d.zip |
(DO_SET_THREAD_AREA): Don't use INLINE_SYSCALL for set_thread_area syscall.
Diffstat (limited to 'linuxthreads/sysdeps')
-rw-r--r-- | linuxthreads/sysdeps/i386/useldt.h | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/linuxthreads/sysdeps/i386/useldt.h b/linuxthreads/sysdeps/i386/useldt.h index 31893b4013..16aee9989f 100644 --- a/linuxthreads/sysdeps/i386/useldt.h +++ b/linuxthreads/sysdeps/i386/useldt.h @@ -22,7 +22,6 @@ #ifndef __ASSEMBLER__ #include <stddef.h> /* For offsetof. */ #include <stdlib.h> /* For abort(). */ -#include <sysdep.h> /* For INLINE_SYSCALL. */ /* We don't want to include the kernel header. So duplicate the @@ -75,17 +74,25 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); asm ("movw %w0, %%gs" : : "q" (nr * 8 + 7)); \ }) +#ifdef __PIC__ +# define USETLS_EBX_ARG "r" +# define USETLS_LOAD_EBX "xchgl %3, %%ebx\n\t" +#else +# define USETLS_EBX_ARG "b" +# define USETLS_LOAD_EBX +#endif + /* When using the new set_thread_area call, we don't need to change %gs because we inherited the value set up in the main thread by TLS setup. We need to extract that value and set up the same segment in this thread. */ -# if USE_TLS -# define DO_SET_THREAD_AREA_REUSE(nr) 1 -# else +#if USE_TLS +# define DO_SET_THREAD_AREA_REUSE(nr) 1 +#else /* Without TLS, we do the initialization of the main thread, where NR == 0. */ -# define DO_SET_THREAD_AREA_REUSE(nr) (!__builtin_constant_p (nr) || (nr)) -# endif -# define DO_SET_THREAD_AREA(descr, nr) \ +# define DO_SET_THREAD_AREA_REUSE(nr) (!__builtin_constant_p (nr) || (nr)) +#endif +#define DO_SET_THREAD_AREA(descr, nr) \ ({ \ int __gs; \ if (DO_SET_THREAD_AREA_REUSE (nr)) \ @@ -95,8 +102,15 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); { (__gs & 0xffff) >> 3, \ (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \ 1, 0, 0, 1, 0, 1, 0 }; \ - if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry), \ - 0) == 0) \ + \ + int __result; \ + __asm (USETLS_LOAD_EBX \ + "movl %2, %%eax\n\t" \ + "int $0x80\n\t" \ + USETLS_LOAD_EBX \ + : "&a" (__result) \ + : USETLS_EBX_ARG (&ldt_entry), "i" (__NR_set_thread_area)); \ + if (__result == 0) \ asm ("movw %w0, %%gs" :: "q" (__gs)); \ else \ __gs = -1; \ @@ -107,8 +121,14 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); { -1, \ (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \ 1, 0, 0, 1, 0, 1, 0 }; \ - if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry), \ - 0) == 0) \ + int __result; \ + __asm (USETLS_LOAD_EBX \ + "movl %2, %%eax\n\t" \ + "int $0x80\n\t" \ + USETLS_LOAD_EBX \ + : "&a" (__result) \ + : USETLS_EBX_ARG (&ldt_entry), "i" (__NR_set_thread_area)); \ + if (__result == 0) \ { \ __gs = (ldt_entry.entry_number << 3) + 3; \ asm ("movw %w0, %%gs" : : "q" (__gs)); \ |