diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/dl-sysdep.h glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/dl-sysdep.h --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/dl-sysdep.h 1970-01-01 09:00:00.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/dl-sysdep.h 2005-04-22 03:18:42.753839334 +0900 @@ -0,0 +1,61 @@ +/* System-specific settings for dynamic linker code. AMD64 version. + Copyright (C) 2002, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_SYSDEP_H +#define _DL_SYSDEP_H 1 + +/* This macro must be defined to either 0 or 1. + + If 1, then an errno global variable hidden in ld.so will work right with + all the errno-using libc code compiled for ld.so, and there is never a + need to share the errno location with libc. This is appropriate only if + 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. */ + +#ifdef IS_IN_rtld +# define RTLD_PRIVATE_ERRNO 1 +#else +# define RTLD_PRIVATE_ERRNO 0 +#endif + +/* Traditionally system calls have been made using int $0x80. A + second method was introduced which, if possible, will use the + sysenter/syscall instructions. To signal the presence and where to + find the code the kernel passes an AT_SYSINFO value in the + auxiliary vector to the application. */ +#define NEED_DL_SYSINFO 1 +#define USE_DL_SYSINFO 1 + +#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__ +extern void _dl_sysinfo_syscall (void) attribute_hidden; +# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_syscall +# define DL_SYSINFO_IMPLEMENTATION \ + asm (".text\n\t" \ + ".type _dl_sysinfo_syscall,@function\n\t" \ + ".hidden _dl_sysinfo_syscall\n" \ + CFI_STARTPROC "\n" \ + "_dl_sysinfo_syscall:\n\t" \ + "syscall;\n\t" \ + "ret;\n\t" \ + CFI_ENDPROC "\n" \ + ".size _dl_sysinfo_syscall,.-_dl_sysinfo_syscall\n\t" \ + ".previous"); +#endif + +#endif /* dl-sysdep.h */ diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h 2004-07-06 02:29:20.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h 2005-04-22 03:18:42.753839334 +0900 @@ -51,7 +51,7 @@ int __ignore; \ register __typeof (val) _val asm ("edx") = (val); \ __asm __volatile ("xorq %%r10, %%r10\n\t" \ - "syscall" \ + STR_ENTER_KERNEL \ : "=a" (__ignore) \ : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \ "d" (_val) \ @@ -63,7 +63,7 @@ do { \ int __ignore; \ register __typeof (nr) _nr asm ("edx") = (nr); \ - __asm __volatile ("syscall" \ + __asm __volatile (STR_ENTER_KERNEL \ : "=a" (__ignore) \ : "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE), \ "d" (_nr) \ @@ -294,7 +294,7 @@ if (_tid != 0) \ __asm __volatile ("xorq %%r10, %%r10\n\t" \ "1:\tmovq %2, %%rax\n\t" \ - "syscall\n\t" \ + STR_ENTER_KERNEL "\n\t" \ "cmpl $0, (%%rdi)\n\t" \ "jne 1b" \ : "=&a" (__ignore) \ diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S 2004-10-02 06:23:14.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S 2005-04-22 03:18:42.754839047 +0900 @@ -54,7 +54,7 @@ jne 2f 1: movq $SYS_futex, %rax - syscall + ENTER_KERNEL 2: movl %edx, %eax xchgl %eax, (%rdi) /* NB: lock is implied */ @@ -129,7 +129,7 @@ xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */ movq %r12, %rdi movq $SYS_futex, %rax - syscall + ENTER_KERNEL movq %rax, %rcx 8: /* NB: %edx == 2 */ @@ -198,7 +198,7 @@ movq $FUTEX_WAKE, %rsi movl $1, %edx /* Wake one thread. */ movq $SYS_futex, %rax - syscall + ENTER_KERNEL popq %rdx popq %rsi @@ -251,7 +251,7 @@ xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */ movq %r12, %rdi movq $SYS_futex, %rax - syscall + ENTER_KERNEL cmpl $0, (%rdi) jne 1f diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S 2004-02-19 11:46:29.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S 2005-04-22 03:18:42.754839047 +0900 @@ -66,7 +66,7 @@ 7: xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */ xorq %r10, %r10 8: movq $SYS_futex, %rax - syscall + ENTER_KERNEL /* Don't return on spurious wakeups. The syscall does not change any register except %eax so there is no need to reload any of @@ -112,7 +112,7 @@ movl $0x7fffffff, %edx movq $FUTEX_WAKE, %rsi movq $SYS_futex, %rax - syscall + ENTER_KERNEL /* Increment LEFT. If this brings the count back to the initial count unlock the object. */ diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S 2004-06-04 01:02:38.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S 2005-04-22 03:18:42.754839047 +0900 @@ -85,7 +85,7 @@ movq $SYS_futex, %rax movl $1, %edx movq $0x7fffffff, %r10 - syscall + ENTER_KERNEL /* For any kind of error, which mainly is EAGAIN, we try again with WAKE. The general test also covers running on old @@ -131,7 +131,7 @@ movq $0x7fffffff, %rdx movq $FUTEX_WAKE, %rsi movq $SYS_futex, %rax - syscall + ENTER_KERNEL jmp 10b .size __pthread_cond_broadcast, .-__pthread_cond_broadcast versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast, diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S 2004-06-04 01:02:51.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S 2005-04-22 03:18:42.754839047 +0900 @@ -69,7 +69,7 @@ movq $FUTEX_WAKE, %rsi movq $SYS_futex, %rax movq $1, %rdx - syscall + ENTER_KERNEL /* Unlock. */ 4: LOCK diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S 2004-09-03 03:53:10.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S 2005-04-22 03:18:42.754839047 +0900 @@ -142,7 +142,7 @@ kernel. */ leaq 24(%rsp), %rsi movq $__NR_clock_gettime, %rax - syscall + ENTER_KERNEL # ifndef __ASSUME_POSIX_TIMERS cmpq $-ENOSYS, %rax je 19f @@ -199,7 +199,7 @@ movq %r12, %rdx addq $cond_futex, %rdi movq $SYS_futex, %rax - syscall + ENTER_KERNEL movq %rax, %r14 movl (%rsp), %edi @@ -259,7 +259,7 @@ movq $SYS_futex, %rax movq $FUTEX_WAKE, %rsi movl $1, %edx - syscall + ENTER_KERNEL subq $cond_nwaiters, %rdi 25: LOCK diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S 2004-09-03 03:52:37.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S 2005-04-22 03:18:42.754839047 +0900 @@ -85,7 +85,7 @@ movq $SYS_futex, %rax movq $FUTEX_WAKE, %rsi movl $1, %edx - syscall + ENTER_KERNEL subq $cond_nwaiters, %rdi movq $1, %r12 @@ -108,7 +108,7 @@ movq $FUTEX_WAKE, %rsi movl $0x7fffffff, %edx movq $SYS_futex, %rax - syscall + ENTER_KERNEL 5: movq 16(%r8), %rdi callq __pthread_mutex_cond_lock @@ -217,7 +217,7 @@ addq $cond_futex-cond_lock, %rdi movq $SYS_futex, %rax movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */ - syscall + ENTER_KERNEL movl (%rsp), %edi callq __pthread_disable_asynccancel @@ -265,7 +265,7 @@ movq $SYS_futex, %rax movq $FUTEX_WAKE, %rsi movl $1, %edx - syscall + ENTER_KERNEL subq $cond_nwaiters, %rdi 17: LOCK diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S 2003-07-02 02:01:44.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S 2005-04-22 03:19:12.364331105 +0900 @@ -17,6 +17,8 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include + #ifndef UP # define LOCK lock #else @@ -76,7 +78,7 @@ /* Somebody else got here first. Wait. */ movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */ movq $SYS_futex, %rax - syscall + ENTER_KERNEL jmp 6b /* Preserve the pointer to the control variable. */ @@ -99,7 +101,7 @@ movl $0x7fffffff, %edx movl $FUTEX_WAKE, %esi movq $SYS_futex, %rax - syscall + ENTER_KERNEL 4: addq $8, %rsp .Ladd: @@ -126,7 +128,7 @@ movl $0x7fffffff, %edx movq $FUTEX_WAKE, %rsi movq $SYS_futex, %rax - syscall + ENTER_KERNEL movq %r8, %rdi .LcallUR: diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S 2003-09-22 13:40:52.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S 2005-04-22 03:18:42.754839047 +0900 @@ -76,7 +76,7 @@ 11: addq $READERS_WAKEUP, %rdi movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */ movq $SYS_futex, %rax - syscall + ENTER_KERNEL subq $READERS_WAKEUP, %rdi diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S 2004-07-05 08:11:34.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S 2005-04-22 03:18:42.755838759 +0900 @@ -117,7 +117,7 @@ movl %r14d, %edx leaq READERS_WAKEUP(%r12), %rdi movq $SYS_futex, %rax - syscall + ENTER_KERNEL movq %rax, %rdx 17: diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S 2003-09-22 13:40:52.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S 2005-04-22 03:18:42.755838759 +0900 @@ -113,7 +113,7 @@ movl %r14d, %edx leaq WRITERS_WAKEUP(%r12), %rdi movq $SYS_futex, %rax - syscall + ENTER_KERNEL movq %rax, %rdx 17: diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S 2004-02-19 04:58:58.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S 2005-04-22 03:18:42.755838759 +0900 @@ -80,7 +80,7 @@ 8: movq $SYS_futex, %rax movq %r10, %rdi - syscall + ENTER_KERNEL xorq %rax, %rax retq diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S 2003-09-22 13:40:52.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S 2005-04-22 03:18:42.755838759 +0900 @@ -74,7 +74,7 @@ 11: addq $WRITERS_WAKEUP, %rdi movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */ movq $SYS_futex, %rax - syscall + ENTER_KERNEL subq $WRITERS_WAKEUP, %rdi diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S 2003-03-13 10:48:34.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S 2005-04-22 03:18:42.755838759 +0900 @@ -44,7 +44,7 @@ movq $SYS_futex, %rax movq $FUTEX_WAKE, %rsi incl %edx - syscall + ENTER_KERNEL testq %rax, %rax js 1f diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S 2003-07-09 06:07:37.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S 2005-04-22 03:18:42.755838759 +0900 @@ -110,7 +110,7 @@ xorq %rsi, %rsi movq $SYS_futex, %rax xorl %edx, %edx - syscall + ENTER_KERNEL movq %rax, %r14 movl 16(%rsp), %edi diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S 2003-07-09 06:07:19.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S 2005-04-22 03:18:42.755838759 +0900 @@ -81,7 +81,7 @@ movq %r13, %rdi movq %r10, %rsi movq %r10, %rdx - syscall + ENTER_KERNEL movq %rax, %r12 movl %r8d, %edi diff -urN glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h --- glibc-2.3.5.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h 2004-07-06 13:25:43.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h 2005-04-22 03:18:42.755838759 +0900 @@ -49,7 +49,7 @@ /* The return value from CENABLE is argument for CDISABLE. */ \ movq %rax, (%rsp); \ movq $SYS_ify (syscall_name), %rax; \ - syscall; \ + ENTER_KERNEL; \ movq (%rsp), %rdi; \ /* Save %rax since it's the error code from the syscall. */ \ movq %rax, 8(%rsp); \ diff -urN glibc-2.3.5.orig/nptl/sysdeps/x86_64/pthreaddef.h glibc-2.3.5/nptl/sysdeps/x86_64/pthreaddef.h --- glibc-2.3.5.orig/nptl/sysdeps/x86_64/pthreaddef.h 2003-05-09 16:28:50.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/x86_64/pthreaddef.h 2005-04-22 03:18:42.755838759 +0900 @@ -51,4 +51,4 @@ /* While there is no such syscall. */ #define __exit_thread_inline(val) \ - asm volatile ("syscall" :: "a" (__NR_exit), "D" (val)) + asm volatile (STR_ENTER_KERNEL :: "a" (__NR_exit), "D" (val)) diff -urN glibc-2.3.5.orig/nptl/sysdeps/x86_64/tcb-offsets.sym glibc-2.3.5/nptl/sysdeps/x86_64/tcb-offsets.sym --- glibc-2.3.5.orig/nptl/sysdeps/x86_64/tcb-offsets.sym 2004-03-09 15:26:54.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/x86_64/tcb-offsets.sym 2005-04-22 03:18:42.756838472 +0900 @@ -10,3 +10,4 @@ CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) +SYSINFO_OFFSET offsetof (tcbhead_t, sysinfo) diff -urN glibc-2.3.5.orig/nptl/sysdeps/x86_64/tls.h glibc-2.3.5/nptl/sysdeps/x86_64/tls.h --- glibc-2.3.5.orig/nptl/sysdeps/x86_64/tls.h 2003-09-09 16:00:21.000000000 +0900 +++ glibc-2.3.5/nptl/sysdeps/x86_64/tls.h 2005-04-22 03:18:42.756838472 +0900 @@ -20,6 +20,7 @@ #ifndef _TLS_H #define _TLS_H 1 +#include #include /* For ARCH_SET_FS. */ #ifndef __ASSEMBLER__ # include @@ -42,6 +43,7 @@ dtv_t *dtv; void *self; /* Pointer to the thread descriptor. */ int multiple_threads; + uintptr_t sysinfo; } tcbhead_t; #else /* __ASSEMBLER__ */ @@ -108,6 +110,8 @@ # define GET_DTV(descr) \ (((tcbhead_t *) (descr))->dtv) +#define THREAD_SELF_SYSINFO THREAD_GETMEM (THREAD_SELF, header.sysinfo) +#define THREAD_SYSINFO(pd) ((pd)->header.sysinfo) /* Macros to load from and store into segment registers. */ # define TLS_GET_FS() \ @@ -122,6 +126,30 @@ We have to make the syscall for both uses of the macro since the address might be (and probably is) different. */ +#if defined NEED_DL_SYSINFO +# define TLS_INIT_TP(thrdescr, secondcall) \ + ({ void *_thrdescr = (thrdescr); \ + tcbhead_t *_head = _thrdescr; \ + int _result; \ + \ + _head->tcb = _thrdescr; \ + /* For now the thread descriptor is at the same address. */ \ + _head->self = _thrdescr; \ + \ + _head->sysinfo = GLRO(dl_sysinfo); \ + \ + /* It is a simple syscall to set the %fs value for the thread. */ \ + asm volatile ("callq *%4" \ + : "=a" (_result) \ + : "0" ((unsigned long int) __NR_arch_prctl), \ + "D" ((unsigned long int) ARCH_SET_FS), \ + "S" (_thrdescr), \ + "m" (_head->sysinfo) \ + : "memory", "cc", "r11", "cx"); \ + \ + _result ? "cannot set %fs base address for thread-local storage" : 0; \ + }) +#else # define TLS_INIT_TP(thrdescr, secondcall) \ ({ void *_thrdescr = (thrdescr); \ tcbhead_t *_head = _thrdescr; \ @@ -141,7 +169,7 @@ \ _result ? "cannot set %fs base address for thread-local storage" : 0; \ }) - +#endif /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/clone.S glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/clone.S --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/clone.S 2004-12-05 16:49:19.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/clone.S 2005-04-22 03:18:42.756838472 +0900 @@ -62,12 +62,23 @@ jz SYSCALL_ERROR_LABEL /* Insert the argument onto the new stack. */ +#ifdef X86_64_USE_VSYSCALL + subq $24,%rsi + movq %rcx,16(%rsi) +#else subq $16,%rsi movq %rcx,8(%rsi) +#endif /* Save the function pointer. It will be popped off in the child in the ebx frobbing below. */ +#ifdef X86_64_USE_VSYSCALL + movq %rdi,8(%rsi) + leaq L(enter_kernel_end)(%rip),%r10 + movq %r10,0(%rsi) +#else movq %rdi,0(%rsi) +#endif /* Do the system call. */ movq %rdx, %rdi @@ -79,8 +90,8 @@ /* End FDE now, because in the child the unwind info will be wrong. */ cfi_endproc; - syscall - + ENTER_KERNEL +L(enter_kernel_end): testq %rax,%rax jl SYSCALL_ERROR_LABEL jz L(thread_start) @@ -100,7 +111,7 @@ movl $-1, %eax jne 2f movq $SYS_ify(getpid), %rax - syscall + ENTER_KERNEL 2: movl %eax, %fs:PID movl %eax, %fs:TID 1: diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/getcontext.S glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/getcontext.S --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/getcontext.S 2002-08-31 17:05:51.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/getcontext.S 2005-04-22 03:18:42.756838472 +0900 @@ -71,7 +71,7 @@ movq $SIG_BLOCK, %rdi movq $_NSIG8,%r10 movq $__NR_rt_sigprocmask, %rax - syscall + ENTER_KERNEL cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/setcontext.S glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/setcontext.S --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/setcontext.S 2004-01-22 17:17:42.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/setcontext.S 2005-04-22 03:18:42.756838472 +0900 @@ -44,7 +44,7 @@ movq $SIG_SETMASK, %rdi movq $_NSIG8,%r10 movq $__NR_rt_sigprocmask, %rax - syscall + ENTER_KERNEL popq %rdi /* Reload %rdi, adjust stack. */ cfi_adjust_cfa_offset(-8) cmpq $-4095, %rax /* Check %rax for error. */ diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/sigaction.c glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/sigaction.c --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/sigaction.c 2003-09-03 12:21:28.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/sigaction.c 2005-04-22 03:18:42.756838472 +0900 @@ -85,6 +85,17 @@ weak_alias (__libc_sigaction, sigaction) #endif +#ifdef X86_64_USE_VSYSCALL +# ifdef SHARED +/* XXX : SYSINFO_OFFSET is hard-coded here! */ +# define ENTER_KERNEL_NO_RETURN "jmp *%fs:0x20" +# else +# define ENTER_KERNEL_NO_RETURN "jmp *_dl_sysinfo" +# endif +#else +# define ENTER_KERNEL_NO_RETURN "syscall" +#endif + /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to recognize them as signal trampolines, and make backtraces through @@ -101,7 +112,7 @@ CFI_STARTPROC "\n" \ "__" #name ":\n" \ " movq $" #syscall ", %rax\n" \ - " syscall\n" \ + ENTER_KERNEL_NO_RETURN "\n" \ CFI_ENDPROC "\n" \ ); /* The return code for realtime-signals. */ diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/swapcontext.S glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/swapcontext.S --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/swapcontext.S 2002-08-31 17:05:51.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/swapcontext.S 2005-04-22 03:18:42.756838472 +0900 @@ -76,7 +76,7 @@ movq $SIG_SETMASK, %rdi movq $_NSIG8,%r10 movq $__NR_rt_sigprocmask, %rax - syscall + ENTER_KERNEL cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/syscall.S glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/syscall.S --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/syscall.S 2003-12-12 20:02:04.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/syscall.S 2005-04-22 03:18:42.756838472 +0900 @@ -35,7 +35,7 @@ movq %r8, %r10 movq %r9, %r8 movq 8(%rsp),%r9 /* arg6 is on the stack. */ - syscall /* Do the system call. */ + ENTER_KERNEL /* Do the system call. */ cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ L(pseudo_end): diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/sysdep.h glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/sysdep.h --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/sysdep.h 2004-10-05 05:59:36.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/sysdep.h 2005-04-22 03:18:42.757838185 +0900 @@ -36,6 +36,13 @@ #undef SYS_ify #define SYS_ify(syscall_name) __NR_##syscall_name +#if defined USE_DL_SYSINFO \ + && (!defined NOT_IN_libc || defined IS_IN_libpthread) +# define X86_64_USE_VSYSCALL 1 +#else +# undef X86_64_USE_VSYSCALL +#endif + /* This is a kludge to make syscalls.list find these under the names pread and pwrite, since some kernel headers define those names and some define the *64 names for the same system calls. */ @@ -168,6 +175,20 @@ jmp L(pseudo_end); #endif /* PIC */ + +/* The original calling convention for system calls on Linux/x86-64 is + to use syscall. */ +#ifdef X86_64_USE_VSYSCALL +# ifdef SHARED +# define ENTER_KERNEL call *%fs:SYSINFO_OFFSET +# else +# define ENTER_KERNEL call *_dl_sysinfo +# endif +#else +# define ENTER_KERNEL syscall +#endif + + /* The Linux/x86-64 kernel expects the system call parameters in registers according to the following table: @@ -209,7 +230,7 @@ #define DO_CALL(syscall_name, args) \ DOARGS_##args \ movq $SYS_ify (syscall_name), %rax; \ - syscall; + ENTER_KERNEL; #define DOARGS_0 /* nothing */ #define DOARGS_1 /* nothing */ @@ -220,6 +241,18 @@ #define DOARGS_6 DOARGS_5 #else /* !__ASSEMBLER__ */ + +#ifdef X86_64_USE_VSYSCALL +# ifdef SHARED +/* XXX : SYSINFO_OFFSET is hard-coded here! */ +# define STR_ENTER_KERNEL "call *%%fs:0x20" +# else +# define STR_ENTER_KERNEL "call *_dl_sysinfo" +# endif +#else +# define STR_ENTER_KERNEL "syscall" +#endif + /* Define a macro which expands inline into the wrapper code for a system call. */ #undef INLINE_SYSCALL @@ -236,16 +269,44 @@ #undef INTERNAL_SYSCALL_DECL #define INTERNAL_SYSCALL_DECL(err) do { } while (0) +#ifdef X86_64_USE_VSYSCALL +# ifdef SHARED #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ ({ \ unsigned long resultvar; \ LOAD_ARGS_##nr (args) \ LOAD_REGS_##nr \ asm volatile ( \ + "call *%%fs:%P2\n\t" \ + : "=a" (resultvar) \ + : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ + (long) resultvar; }) +# else +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + unsigned long resultvar; \ + LOAD_ARGS_##nr (args) \ + LOAD_REGS_##nr \ + asm volatile ( \ + "call *_dl_sysinfo\n\t" \ + : "=a" (resultvar) \ + : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ + ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ + (long) resultvar; }) +# endif +#else +# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + unsigned long resultvar; \ + LOAD_ARGS_##nr (args) \ + LOAD_REGS_##nr \ + asm volatile ( \ "syscall\n\t" \ : "=a" (resultvar) \ : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ (long) resultvar; }) +#endif #undef INTERNAL_SYSCALL #define INTERNAL_SYSCALL(name, err, nr, args...) \ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) diff -urN glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/vfork.S glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/vfork.S --- glibc-2.3.5.orig/sysdeps/unix/sysv/linux/x86_64/vfork.S 2004-03-09 15:29:00.000000000 +0900 +++ glibc-2.3.5/sysdeps/unix/sysv/linux/x86_64/vfork.S 2005-04-22 03:18:42.757838185 +0900 @@ -38,7 +38,7 @@ /* Stuff the syscall number in RAX and enter into the kernel. */ movl $SYS_ify (vfork), %eax - syscall + ENTER_KERNEL /* Push back the return PC. */ pushq %rdi