summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/misc/sysvipc/msgq.c2
-rw-r--r--libc/sysdeps/linux/x86_64/Makefile.arch12
-rw-r--r--libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h2
-rw-r--r--libc/sysdeps/linux/x86_64/vfork.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c6
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile17
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch73
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h30
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S116
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S11
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S22
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S22
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h35
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S306
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S4
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S4
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c14
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S2
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S1
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h63
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h259
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_create.c28
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_delete.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_getoverr.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_gettime.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_settime.c27
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S16
-rw-r--r--libpthread/nptl/sysdeps/x86_64/Makefile9
-rw-r--r--libpthread/nptl/sysdeps/x86_64/Makefile.arch52
-rw-r--r--libpthread/nptl/sysdeps/x86_64/pthreaddef.h17
-rw-r--r--libpthread/nptl/sysdeps/x86_64/sysdep.h114
-rw-r--r--libpthread/nptl/sysdeps/x86_64/tls.h165
48 files changed, 1245 insertions, 318 deletions
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index e20e3ca64..27eb1ff92 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -65,7 +65,7 @@ static inline ssize_t do_msgrcv (int msqid, void *msgp, size_t msgsz,
return __syscall_ipc(IPCOP_msgrcv ,msqid ,msgsz ,msgflg ,&temp, 0);
#endif
}
-int msgrcv (int msqid, void *msgp, size_t msgsz,
+ssize_t msgrcv (int msqid, void *msgp, size_t msgsz,
long int msgtyp, int msgflg)
{
if (SINGLE_THREAD_P)
diff --git a/libc/sysdeps/linux/x86_64/Makefile.arch b/libc/sysdeps/linux/x86_64/Makefile.arch
index 044f97f95..de7ce7285 100644
--- a/libc/sysdeps/linux/x86_64/Makefile.arch
+++ b/libc/sysdeps/linux/x86_64/Makefile.arch
@@ -5,7 +5,15 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := brk.c sigaction.c __syscall_error.c mmap.c
+CSRC := brk.c __syscall_error.c mmap.c
+
+ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+CSRC += sigaction.c
+endif
SSRC := \
- __longjmp.S vfork.S setjmp.S syscall.S bsd-setjmp.S bsd-_setjmp.S clone.S
+ __longjmp.S setjmp.S syscall.S bsd-setjmp.S bsd-_setjmp.S
+
+ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+SSRC += vfork.S clone.S
+endif
diff --git a/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h b/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h
index 748e544bb..1d966aee4 100644
--- a/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/x86_64/bits/uClibc_arch_features.h
@@ -36,7 +36,7 @@
#undef __UCLIBC_HAVE_ASM_GLOBAL_DOT_NAME__
/* define if target supports CFI pseudo ops */
-#undef __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
+#define __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__
/* define if target supports IEEE signed zero floats */
#define __UCLIBC_HAVE_SIGNED_ZERO__
diff --git a/libc/sysdeps/linux/x86_64/vfork.S b/libc/sysdeps/linux/x86_64/vfork.S
index 2dadbbfe0..97c9c5b67 100644
--- a/libc/sysdeps/linux/x86_64/vfork.S
+++ b/libc/sysdeps/linux/x86_64/vfork.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2004, 2008 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
@@ -31,7 +31,7 @@
.text
.global __vfork
.hidden __vfork
-.type __vfork,%function
+.type __vfork,%function
__vfork:
@@ -39,6 +39,10 @@ __vfork:
is preserved by the syscall and that we're allowed to destroy. */
popq %rdi
+#ifdef SAVE_PID
+ SAVE_PID
+#endif
+
/* Stuff the syscall number in RAX and enter into the kernel. */
movl $__NR_vfork, %eax
syscall
@@ -46,6 +50,10 @@ __vfork:
/* Push back the return PC. */
pushq %rdi
+#ifdef RESTORE_PID
+ RESTORE_PID
+#endif
+
cmpl $-4095, %eax
jae __syscall_error /* Branch forward if it failed. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
index 01b2cdd8a..fce368f5a 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.in
@@ -63,8 +63,9 @@ X86_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
libpthread_CSRC := $(filter-out $(X86_PTHREAD_SPECIFIC),$(libpthread_CSRC))
endif
-
ifeq ($(TARGET_ARCH),x86_64)
+X86_PTHREAD_SPECIFIC := sem_post.c sem_wait.c sem_timedwait.c sem_trywait.c
+libpthread_CSRC := $(filter-out $(X86_PTHREAD_SPECIFIC),$(libpthread_CSRC))
librt_CSRC := mq_notify.c
endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
index 5f9380814..155d3645f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_getcpuclockid.c
@@ -33,9 +33,9 @@ int __libc_missing_posix_timers attribute_hidden;
#endif
int
-pthread_getcpuclockid (threadid, clockid)
- pthread_t threadid;
- clockid_t *clockid;
+pthread_getcpuclockid (
+ pthread_t threadid,
+ clockid_t *clockid)
{
struct pthread *pd = (struct pthread *) threadid;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
index b32ce29ef..43a6fad84 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -1,4 +1,13 @@
-ifeq ($(subdir),nptl)
-CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions \
- -fno-asynchronous-unwind-tables $(fno-unit-at-a-time)
-endif
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../../../../../../
+top_builddir=../../../../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch
new file mode 100644
index 000000000..e50539a36
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile.arch
@@ -0,0 +1,73 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+LINUX_ARCH_DIR:=$(top_srcdir)libpthread/nptl/sysdeps/unix/sysv/linux/x86_64
+LINUX_ARCH_OUT:=$(top_builddir)libpthread/nptl/sysdeps/unix/sysv/linux/x86_64
+
+
+libpthread_SSRC = pt-vfork.S clone.S pthread_once.S
+libpthread_CSRC = pthread_spin_init.c
+
+libc_a_CSRC = fork.c
+libc_a_SSRC = clone.S vfork.S
+
+libpthread_SSRC += lowlevellock.S pthread_barrier_wait.S pthread_cond_signal.S pthread_cond_broadcast.S \
+ sem_post.S sem_timedwait.S \
+ sem_trywait.S sem_wait.S pthread_rwlock_rdlock.S pthread_rwlock_wrlock.S \
+ pthread_rwlock_timedrdlock.S pthread_rwlock_timedwrlock.S pthread_rwlock_unlock.S \
+ pthread_cond_timedwait.S pthread_cond_wait.S
+
+libc_a_SSRC += libc-lowlevellock.S
+
+
+CFLAGS-OMIT-fork.c = -DNOT_IN_libc=1 -DIS_IN_libpthread=1
+
+ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
+CFLAGS-fork.c = -D__USE_STDIO_FUTEXES__
+endif
+
+ASFLAGS-pt-vfork.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-lowlevellock.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+ASFLAGS-pthread_once.S = -DNOT_IN_libc=1 -DIS_IN_libpthread=1 -D_LIBC_REENTRANT -DUSE___THREAD
+
+
+ASFLAGS-clone.S = -D_LIBC_REENTRANT
+ASFLAGS-vfork.S = -D_LIBC_REENTRANT
+ASFLAGS-libc-lowlevellock.S = -D_LIBC_REENTRANT
+
+ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
+#Needed to use the correct SYSCALL_ERROR_HANDLER
+ASFLAGS-clone.S += -DUSE___THREAD
+ASFLAGS-vfork.S += -DUSE___THREAD
+endif
+
+CFLAGS += $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+LINUX_ARCH_OBJ:=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libpthread_SSRC))
+LINUX_ARCH_OBJ+=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(LINUX_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(LINUX_ARCH_OBJ)
+endif
+libpthread-so-y += $(LINUX_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y+=$(LINUX_ARCH_OBJS)
+
+LIBC_LINUX_ARCH_OBJ:=$(patsubst %.c,$(LINUX_ARCH_OUT)/%.o,$(libc_a_CSRC))
+LIBC_LINUX_ARCH_OBJ+=$(patsubst %.S,$(LINUX_ARCH_OUT)/%.o,$(libc_a_SSRC))
+
+libc-static-y+=$(LIBC_LINUX_ARCH_OBJ)
+libc-shared-y+=$(LIBC_LINUX_ARCH_OBJ:.o=.oS)
+
+libc-nomulti-y+=$(LIBC_LINUX_ARCH_OBJ)
+
+objclean-y+=nptl_linux_arch_clean
+
+nptl_linux_arch_clean:
+ $(do_rm) $(addprefix $(LINUX_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
index 51fdab0fb..7a09c8119 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -75,7 +75,7 @@ typedef struct __pthread_internal_slist
type is not exposed on purpose. */
typedef union
{
- struct
+ struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
@@ -86,10 +86,18 @@ typedef union
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
-#if __WORDSIZE != 64
+#if __WORDSIZE == 64
+ int __spins;
+ __pthread_list_t __list;
+# define __PTHREAD_MUTEX_HAVE_PREV 1
+#else
unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
#endif
- int __spins;
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
@@ -151,9 +159,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
@@ -169,7 +177,10 @@ typedef union
unsigned int __nr_writers_queued;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
int __writer;
} __data;
# endif
@@ -206,4 +217,9 @@ typedef union
#endif
+#if __WORDSIZE == 32
+/* Extra attributes for the cleanup functions. */
+# define __cleanup_fct_attribute __attribute__ ((__regparm__ (1)))
+#endif
+
#endif /* bits/pthreadtypes.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
new file mode 100644
index 000000000..680696200
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S
@@ -0,0 +1,116 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ 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. */
+
+#include <sysdep.h>
+#include <tcb-offsets.h>
+#include <kernel-features.h>
+#include "lowlevellock.h"
+
+#ifdef IS_IN_libpthread
+# ifdef SHARED
+# define __pthread_unwind __GI___pthread_unwind
+# endif
+#else
+# ifndef SHARED
+ .weak __pthread_unwind
+# endif
+#endif
+
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
+ movl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+#endif
+
+/* It is crucial that the functions in this file don't modify registers
+ other than %rax and %r11. The syscall wrapper code depends on this
+ because it doesn't explicitly save the other registers which hold
+ relevant values. */
+ .text
+
+ .hidden __pthread_enable_asynccancel
+ENTRY(__pthread_enable_asynccancel)
+ movl %fs:CANCELHANDLING, %eax
+2: movl %eax, %r11d
+ orl $TCB_CANCELTYPE_BITMASK, %r11d
+ cmpl %eax, %r11d
+ je 1f
+
+ lock
+ cmpxchgl %r11d, %fs:CANCELHANDLING
+ jnz 2b
+
+ andl $(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d
+ cmpl $(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d
+ je 3f
+
+1: ret
+
+3: movq $TCB_PTHREAD_CANCELED, %fs:RESULT
+ lock
+ orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING
+ movq %fs:CLEANUP_JMP_BUF, %rdi
+#ifdef SHARED
+ call __pthread_unwind@PLT
+#else
+ call __pthread_unwind
+#endif
+ hlt
+END(__pthread_enable_asynccancel)
+
+
+ .hidden __pthread_disable_asynccancel
+ENTRY(__pthread_disable_asynccancel)
+ testl $TCB_CANCELTYPE_BITMASK, %edi
+ jnz 1f
+
+ movl %fs:CANCELHANDLING, %eax
+2: movl %eax, %r11d
+ andl $~TCB_CANCELTYPE_BITMASK, %r11d
+ lock
+ cmpxchgl %r11d, %fs:CANCELHANDLING
+ jnz 2b
+
+ movl %r11d, %eax
+3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax
+ cmpl $TCB_CANCELING_BITMASK, %eax
+ je 4f
+1: ret
+
+ /* Performance doesn't matter in this loop. We will
+ delay until the thread is canceled. And we will unlikely
+ enter the loop twice. */
+4: movq %fs:0, %rdi
+ movl $__NR_futex, %eax
+ xorq %r10, %r10
+ addq $CANCELHANDLING, %rdi
+ LOAD_PRIVATE_FUTEX_WAIT (%esi)
+ syscall
+ movl %fs:CANCELHANDLING, %eax
+ jmp 3b
+END(__pthread_disable_asynccancel)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
index dfa6adb3e..675a997e9 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -1,2 +1,9 @@
-#define RESET_PID
-#include <sysdeps/unix/sysv/linux/x86_64/clone.S>
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <clone.S>
+#else
+# define RESET_PID
+# include_next <clone.S>
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
new file mode 100644
index 000000000..110058850
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ 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. */
+
+#define __pthread_enable_asynccancel __libc_enable_asynccancel
+#define __pthread_disable_asynccancel __libc_disable_asynccancel
+#include "cancellation.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
index 3621efa4f..ce8ad27aa 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -17,14 +17,4 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-/* In libc.so we do not unconditionally use the lock prefix. Only if
- the application is using threads. */
-#ifndef UP
-# define LOCK \
- cmpl $0, __libc_multiple_threads(%rip); \
- je 0f; \
- lock; \
-0:
-#endif
-
#include "lowlevellock.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
new file mode 100644
index 000000000..ce4192b5d
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S
@@ -0,0 +1,22 @@
+/* Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
+
+ 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. */
+
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include "cancellation.S"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index 3a49e25dd..1e461ad41 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -30,7 +30,6 @@
# endif
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 35cd868d0..c9f30e962 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -23,6 +23,8 @@
#include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h>
+#include <atomic.h>
+#include <sysdep.h>
#ifndef LOCK_INSTR
# ifdef UP
@@ -32,7 +34,6 @@
# endif
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
@@ -43,14 +44,14 @@
#define LLL_MUTEX_LOCK_INITIALIZER_WAITERS (2)
/* Delay in spinlock loop. */
-#define BUSY_WAIT_NOP asm ("rep; nop")
+#define BUSY_WAIT_NOP __asm__ ("rep; nop")
#define lll_futex_wait(futex, val) \
do { \
int __ignore; \
- register __typeof (val) _val asm ("edx") = (val); \
- __asm __volatile ("xorq %%r10, %%r10\n\t" \
+ register __typeof (val) _val __asm__ ("edx") = (val); \
+ __asm__ __volatile ("xorq %%r10, %%r10\n\t" \
"syscall" \
: "=a" (__ignore) \
: "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAIT), \
@@ -62,8 +63,8 @@
#define lll_futex_wake(futex, nr) \
do { \
int __ignore; \
- register __typeof (nr) _nr asm ("edx") = (nr); \
- __asm __volatile ("syscall" \
+ register __typeof (nr) _nr __asm__ ("edx") = (nr); \
+ __asm__ __volatile ("syscall" \
: "=a" (__ignore) \
: "0" (SYS_futex), "D" (futex), "S" (FUTEX_WAKE), \
"d" (_nr) \
@@ -88,7 +89,7 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
to be nonzero. */
#define lll_mutex_trylock(futex) \
({ int ret; \
- __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
: "=a" (ret), "=m" (futex) \
: "r" (LLL_MUTEX_LOCK_INITIALIZER_LOCKED), "m" (futex),\
"0" (LLL_MUTEX_LOCK_INITIALIZER) \
@@ -98,7 +99,7 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
#define lll_mutex_cond_trylock(futex) \
({ int ret; \
- __asm __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %1" \
: "=a" (ret), "=m" (futex) \
: "r" (LLL_MUTEX_LOCK_INITIALIZER_WAITERS), \
"m" (futex), "0" (LLL_MUTEX_LOCK_INITIALIZER) \
@@ -108,7 +109,7 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
#define lll_mutex_lock(futex) \
(void) ({ int ignore1, ignore2, ignore3; \
- __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t" \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t" \
"jnz 1f\n\t" \
".subsection 1\n" \
"1:\tleaq %2, %%rdi\n\t" \
@@ -126,7 +127,7 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
#define lll_mutex_cond_lock(futex) \
(void) ({ int ignore1, ignore2, ignore3; \
- __asm __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t" \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %0, %2\n\t" \
"jnz 1f\n\t" \
".subsection 1\n" \
"1:\tleaq %2, %%rdi\n\t" \
@@ -144,7 +145,7 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
#define lll_mutex_timedlock(futex, timeout) \
({ int _result, ignore1, ignore2, ignore3; \
- __asm __volatile (LOCK_INSTR "cmpxchgl %2, %4\n\t" \
+ __asm__ __volatile (LOCK_INSTR "cmpxchgl %2, %4\n\t" \
"jnz 1f\n\t" \
".subsection 1\n" \
"1:\tleaq %4, %%rdi\n\t" \
@@ -164,7 +165,7 @@ extern int __lll_mutex_unlock_wait (int *__futex) attribute_hidden;
#define lll_mutex_unlock(futex) \
(void) ({ int ignore; \
- __asm __volatile (LOCK_INSTR "decl %0\n\t" \
+ __asm__ __volatile (LOCK_INSTR "decl %0\n\t" \
"jne 1f\n\t" \
".subsection 1\n" \
"1:\tleaq %0, %%rdi\n\t" \
@@ -218,7 +219,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
# define lll_trylock(futex) \
({ unsigned char ret; \
- __asm __volatile ("cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
+ __asm__ __volatile ("cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
"je 0f\n\t" \
"lock; cmpxchgl %2, %1\n\t" \
"jmp 1f\n" \
@@ -233,7 +234,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
# define lll_lock(futex) \
(void) ({ int ignore1, ignore2, ignore3; \
- __asm __volatile ("cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
+ __asm__ __volatile ("cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
"je 0f\n\t" \
"lock; cmpxchgl %0, %2\n\t" \
"jnz 1f\n\t" \
@@ -256,7 +257,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
# define lll_unlock(futex) \
(void) ({ int ignore; \
- __asm __volatile ("cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
+ __asm__ __volatile ("cmpl $0, __libc_multiple_threads(%%rip)\n\t" \
"je 0f\n\t" \
"lock; decl %0\n\t" \
"jne 1f\n\t" \
@@ -290,9 +291,9 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
#define lll_wait_tid(tid) \
do { \
int __ignore; \
- register __typeof (tid) _tid asm ("edx") = (tid); \
+ register __typeof (tid) _tid __asm__ ("edx") = (tid); \
if (_tid != 0) \
- __asm __volatile ("xorq %%r10, %%r10\n\t" \
+ __asm__ __volatile ("xorq %%r10, %%r10\n\t" \
"1:\tmovq %2, %%rax\n\t" \
"syscall\n\t" \
"cmpl $0, (%%rdi)\n\t" \
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
new file mode 100644
index 000000000..02db0a4f9
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S
@@ -0,0 +1,306 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ 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. */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevellock.h>
+#include <lowlevelrobustlock.h>
+#include <kernel-features.h>
+
+ .text
+
+#define FUTEX_WAITERS 0x80000000
+#define FUTEX_OWNER_DIED 0x40000000
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg
+#else
+# if FUTEX_WAIT == 0
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg
+# else
+# define LOAD_FUTEX_WAIT(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT, reg
+# endif
+# define LOAD_FUTEX_WAIT_ABS(reg) \
+ xorl $FUTEX_PRIVATE_FLAG, reg ; \
+ andl %fs:PRIVATE_FUTEX, reg ; \
+ orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg
+#endif
+
+/* For the calculation see asm/vsyscall.h. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
+
+
+ .globl __lll_robust_lock_wait
+ .type __lll_robust_lock_wait,@function
+ .hidden __lll_robust_lock_wait
+ .align 16
+__lll_robust_lock_wait:
+ cfi_startproc
+ pushq %r10
+ cfi_adjust_cfa_offset(8)
+ pushq %rdx
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r10, -16)
+ cfi_offset(%rdx, -24)
+
+ xorq %r10, %r10 /* No timeout. */
+ LOAD_FUTEX_WAIT (%esi)
+
+4: movl %eax, %edx
+ orl $FUTEX_WAITERS, %edx
+
+ testl $FUTEX_OWNER_DIED, %eax
+ jnz 3f
+
+ cmpl %edx, %eax
+ je 1f
+
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 2f
+
+1: movl $SYS_futex, %eax
+ syscall
+
+ movl (%rdi), %eax
+
+2: testl %eax, %eax
+ jne 4b
+
+ movl %fs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 4b
+ /* NB: %rax == 0 */
+
+3: popq %rdx
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%rdx)
+ popq %r10
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r10)
+ retq
+ cfi_endproc
+ .size __lll_robust_lock_wait,.-__lll_robust_lock_wait
+
+
+ .globl __lll_robust_timedlock_wait
+ .type __lll_robust_timedlock_wait,@function
+ .hidden __lll_robust_timedlock_wait
+ .align 16
+__lll_robust_timedlock_wait:
+ cfi_startproc
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef PIC
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+# endif
+
+ pushq %r9
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r9, 0)
+ movq %rdx, %r10
+ movl $0xffffffff, %r9d
+ LOAD_FUTEX_WAIT_ABS (%esi)
+
+1: testl $FUTEX_OWNER_DIED, %eax
+ jnz 3f
+
+ movl %eax, %edx
+ orl $FUTEX_WAITERS, %edx
+
+ cmpl %eax, %edx
+ je 5f
+
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ movq $0, %rcx /* Must use mov to avoid changing cc. */
+ jnz 6f
+
+5: movl $SYS_futex, %eax
+ syscall
+ movl %eax, %ecx
+
+ movl (%rdi), %eax
+
+6: testl %eax, %eax
+ jne 2f
+
+ movl %fs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%rdi)
+ jnz 2f
+
+3: popq %r9
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+ retq
+
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r9, 0)
+ /* Check whether the time expired. */
+2: cmpl $-ETIMEDOUT, %ecx
+ je 4f
+ cmpl $-EINVAL, %ecx
+ jne 1b
+
+4: movl %ecx, %eax
+ negl %eax
+ jmp 3b
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+
+
+# ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+.Lreltmo:
+ /* Check for a valid timeout value. */
+ cmpq $1000000000, 8(%rdx)
+ jae 3f
+
+ pushq %r8
+ cfi_adjust_cfa_offset(8)
+ pushq %r9
+ cfi_adjust_cfa_offset(8)
+ pushq %r12
+ cfi_adjust_cfa_offset(8)
+ pushq %r13
+ cfi_adjust_cfa_offset(8)
+ cfi_offset(%r8, -16)
+ cfi_offset(%r9, -24)
+ cfi_offset(%r12, -32)
+ cfi_offset(%r13, -40)
+ pushq %rsi
+ cfi_adjust_cfa_offset(8)
+
+ /* Stack frame for the timespec and timeval structs. */
+ subq $32, %rsp
+ cfi_adjust_cfa_offset(32)
+
+ movq %rdi, %r12
+ movq %rdx, %r13
+
+1: movq %rax, 16(%rsp)
+
+ /* Get current time. */
+ movq %rsp, %rdi
+ xorl %esi, %esi
+ movq $VSYSCALL_ADDR_vgettimeofday, %rax
+ /* This is a regular function call, all caller-save registers
+ might be clobbered. */
+ callq *%rax
+
+ /* Compute relative timeout. */
+ movq 8(%rsp), %rax
+ movl $1000, %edi
+ mul %rdi /* Milli seconds to nano seconds. */
+ movq (%r13), %rdi
+ movq 8(%r13), %rsi
+ subq (%rsp), %rdi
+ subq %rax, %rsi
+ jns 4f
+ addq $1000000000, %rsi
+ decq %rdi
+4: testq %rdi, %rdi
+ js 8f /* Time is already up. */
+
+ /* Futex call. */
+ movq %rdi, (%rsp) /* Store relative timeout. */
+ movq %rsi, 8(%rsp)
+
+ movq 16(%rsp), %rdx
+ movl %edx, %eax
+ orl $FUTEX_WAITERS, %edx
+
+ testl $FUTEX_OWNER_DIED, %eax
+ jnz 6f
+
+ cmpl %eax, %edx
+ je 2f
+
+ LOCK
+ cmpxchgl %edx, (%r12)
+ movq $0, %rcx /* Must use mov to avoid changing cc. */
+ jnz 5f
+
+2: movq %rsp, %r10
+ movl 32(%rsp), %esi
+ LOAD_FUTEX_WAIT (%esi)
+ movq %r12, %rdi
+ movl $SYS_futex, %eax
+ syscall
+ movq %rax, %rcx
+
+ movl (%r12), %eax
+
+5: testl %eax, %eax
+ jne 7f
+
+ movl %fs:TID, %edx
+ orl $FUTEX_WAITERS, %edx
+ LOCK
+ cmpxchgl %edx, (%r12)
+ jnz 7f
+
+6: addq $40, %rsp
+ cfi_adjust_cfa_offset(-40)
+ popq %r13
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
+ popq %r12
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
+ popq %r9
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r9)
+ popq %r8
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r8)
+ retq
+
+3: movl $EINVAL, %eax
+ retq
+
+ cfi_adjust_cfa_offset(72)
+ cfi_offset(%r8, -16)
+ cfi_offset(%r9, -24)
+ cfi_offset(%r12, -32)
+ cfi_offset(%r13, -40)
+ /* Check whether the time expired. */
+7: cmpl $-ETIMEDOUT, %ecx
+ jne 1b
+
+8: movl $ETIMEDOUT, %eax
+ jmp 6b
+#endif
+ cfi_endproc
+ .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S
index 653b6b12f..c20ef73e7 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pt-vfork.S
@@ -16,8 +16,6 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#include <tcb-offsets.h>
-
#define SAVE_PID \
movl %fs:PID, %esi; \
movl %esi, %edx; \
@@ -30,4 +28,4 @@
movl %esi, %fs:PID; \
1:
-#include <../../../../../../sysdeps/unix/sysv/linux/x86_64/vfork.S>
+#include <../../../../../../../libc/sysdeps/linux/x86_64/vfork.S>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
index fa8125dd8..f6e15a2d7 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
@@ -20,7 +20,6 @@
#include <sysdep.h>
#include <lowlevelbarrier.h>
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
index 8b3833392..8f878b17e 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <lowlevelcond.h>
#include <bits/kernel-features.h>
@@ -28,7 +27,6 @@
# define LOCK lock
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_REQUEUE 3
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
index bc5843564..11a9e397e 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <lowlevelcond.h>
#include <bits/kernel-features.h>
@@ -28,7 +27,6 @@
# define LOCK lock
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_REQUEUE 3
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index ad3ae1e76..f4fb61f70 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <lowlevelcond.h>
#include <pthread-errnos.h>
@@ -28,7 +27,6 @@
# define LOCK lock
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
@@ -382,7 +380,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.section .eh_frame,"a",@progbits
.LSTARTFRAME:
- .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
.LSTARTCIE:
.long 0 # CIE ID.
.byte 1 # Version number.
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index b837d466b..7c1c0e29c 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -18,9 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <lowlevelcond.h>
-#include <tcb-offsets.h>
#ifdef UP
# define LOCK
@@ -28,7 +26,6 @@
# define LOCK lock
#endif
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
@@ -357,7 +354,7 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
.section .eh_frame,"a",@progbits
.LSTARTFRAME:
- .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
+ .long .LENDCIE-.LSTARTCIE # Length of the CIE.
.LSTARTCIE:
.long 0 # CIE ID.
.byte 1 # Version number.
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
index 6bf8d095b..3fb89e419 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S
@@ -23,7 +23,7 @@
# define LOCK
#endif
-#define SYS_futex 202
+#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
.comm __fork_generation, 4, 4
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
index 5e9d8fb1d..524da36f6 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S
@@ -22,7 +22,6 @@
#include <pthread-errnos.h>
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
index b44660418..29696e7da 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
@@ -22,7 +22,6 @@
#include <pthread-errnos.h>
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
index 525e5b6b9..b6b91f908 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
@@ -22,7 +22,6 @@
#include <pthread-errnos.h>
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
index 3a6b9f0ba..a0f75226a 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S
@@ -21,7 +21,6 @@
#include <lowlevelrwlock.h>
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
index 0e82f890a..c675c769e 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S
@@ -22,7 +22,6 @@
#include <pthread-errnos.h>
-#define SYS_futex 202
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c
new file mode 100644
index 000000000..640d3044f
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c
@@ -0,0 +1,14 @@
+#include <tls.h>
+
+#define RESET_VGETCPU_CACHE() \
+ do { \
+ asm volatile ("movl %0, %%fs:%P1\n\t" \
+ "movl %0, %%fs:%P2" \
+ : \
+ : "ir" (0), "i" (offsetof (struct pthread, \
+ header.vgetcpu_cache[0])), \
+ "i" (offsetof (struct pthread, \
+ header.vgetcpu_cache[1]))); \
+ } while (0)
+
+#include "../pthread_setaffinity.c"
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c
index dc811787e..483de8cac 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_spin_init.c
@@ -1 +1 @@
-#include <nptl/sysdeps/x86_64/pthread_spin_init.c>
+#include <sysdeps/x86_64/pthread_spin_init.c>
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
index 7f608a597..5c8a858ad 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <pthread-errnos.h>
#ifndef UP
@@ -27,7 +26,6 @@
# define
#endif
-#define SYS_futex 202
#define FUTEX_WAKE 1
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
index c44d3f5e7..e5fbf8eb2 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <pthread-errnos.h>
#ifndef UP
@@ -27,8 +26,6 @@
# define
#endif
-#define SYS_futex 202
-
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
index 31271bb94..d16ab3ce5 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <pthread-errnos.h>
#ifndef UP
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
index 63ecd063a..32c24e83d 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include <sysdep.h>
-#include <shlib-compat.h>
#include <pthread-errnos.h>
#ifndef UP
@@ -27,8 +26,6 @@
# define
#endif
-#define SYS_futex 202
-
.text
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
index 97debaba9..1c93952d4 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
@@ -20,11 +20,15 @@
#include <sysdep.h>
#include <tls.h>
#ifndef __ASSEMBLER__
-# include <nptl/pthreadP.h>
+# include <pthreadP.h>
#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+/* The code to disable cancellation depends on the fact that the called
+ functions are special. They don't modify registers other than %rax
+ and %r11 if they return. Therefore we don't have to preserve other
+ registers around these calls. */
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
@@ -40,60 +44,23 @@
ret; \
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
L(pseudo_cancel): \
- /* Save registers that might get destroyed. */ \
- SAVESTK_##args \
- PUSHARGS_##args \
+ /* We always have to align the stack before calling a function. */ \
+ subq $8, %rsp; cfi_adjust_cfa_offset (8); \
CENABLE \
- /* Restore registers. */ \
- POPARGS_##args \
/* The return value from CENABLE is argument for CDISABLE. */ \
movq %rax, (%rsp); \
- movl $SYS_ify (syscall_name), %eax; \
- syscall; \
+ DO_CALL (syscall_name, args); \
movq (%rsp), %rdi; \
/* Save %rax since it's the error code from the syscall. */ \
- movq %rax, 8(%rsp); \
+ movq %rax, %rdx; \
CDISABLE \
- movq 8(%rsp), %rax; \
- RESTSTK_##args \
+ movq %rdx, %rax; \
+ addq $8,%rsp; cfi_adjust_cfa_offset (-8); \
cmpq $-4095, %rax; \
jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
-# define PUSHARGS_0 /* Nothing. */
-# define PUSHARGS_1 PUSHARGS_0 movq %rdi, 8(%rsp);
-# define PUSHARGS_2 PUSHARGS_1 movq %rsi, 16(%rsp);
-# define PUSHARGS_3 PUSHARGS_2 movq %rdx, 24(%rsp);
-# define PUSHARGS_4 PUSHARGS_3 movq %rcx, 32(%rsp);
-# define PUSHARGS_5 PUSHARGS_4 movq %r8, 40(%rsp);
-# define PUSHARGS_6 PUSHARGS_5 movq %r9, 48(%rsp);
-
-# define POPARGS_0 /* Nothing. */
-# define POPARGS_1 POPARGS_0 movq 8(%rsp), %rdi;
-# define POPARGS_2 POPARGS_1 movq 16(%rsp), %rsi;
-# define POPARGS_3 POPARGS_2 movq 24(%rsp), %rdx;
-# define POPARGS_4 POPARGS_3 movq 32(%rsp), %r10;
-# define POPARGS_5 POPARGS_4 movq 40(%rsp), %r8;
-# define POPARGS_6 POPARGS_5 movq 48(%rsp), %r9;
-
-/* We always have to align the stack before calling a function. */
-# define SAVESTK_0 subq $24, %rsp; cfi_adjust_cfa_offset (24);
-# define SAVESTK_1 SAVESTK_0
-# define SAVESTK_2 SAVESTK_1
-# define SAVESTK_3 subq $40, %rsp; cfi_adjust_cfa_offset (40);
-# define SAVESTK_4 SAVESTK_3
-# define SAVESTK_5 subq $56, %rsp; cfi_adjust_cfa_offset (56);
-# define SAVESTK_6 SAVESTK_5
-
-# define RESTSTK_0 addq $24,%rsp; cfi_adjust_cfa_offset (-24);
-# define RESTSTK_1 RESTSTK_0
-# define RESTSTK_2 RESTSTK_1
-# define RESTSTK_3 addq $40, %rsp; cfi_adjust_cfa_offset (-40);
-# define RESTSTK_4 RESTSTK_3
-# define RESTSTK_5 addq $56, %rsp; cfi_adjust_cfa_offset (-56);
-# define RESTSTK_6 RESTSTK_5
-
# ifdef IS_IN_libpthread
# define CENABLE call __pthread_enable_asynccancel;
# define CDISABLE call __pthread_disable_asynccancel;
@@ -136,3 +103,9 @@ extern int __local_multiple_threads attribute_hidden;
# define NO_CANCELLATION 1
#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h
new file mode 100644
index 000000000..b13a14f6a
--- /dev/null
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -0,0 +1,259 @@
+/* Copyright (C) 2001-2005, 2007 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 _LINUX_X86_64_SYSDEP_H
+#define _LINUX_X86_64_SYSDEP_H 1
+
+/* There is some commonality. */
+#include <sys/syscall.h>
+#include <sysdeps/i386/sysdep.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
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+/* 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. */
+#if !defined __NR_pread && defined __NR_pread64
+# define __NR_pread __NR_pread64
+#endif
+#if !defined __NR_pwrite && defined __NR_pwrite64
+# define __NR_pwrite __NR_pwrite64
+#endif
+
+/* This is to help the old kernel headers where __NR_semtimedop is not
+ available. */
+#ifndef __NR_semtimedop
+# define __NR_semtimedop 220
+#endif
+
+
+#ifdef __ASSEMBLER__
+
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. Linus said he will make sure the no syscall
+ returns a value in -1 .. -4095 as a valid result so we can savely
+ test with -4095. */
+
+/* We don't want the label for the error handle to be global when we define
+ it here. */
+# ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+# else
+# define SYSCALL_ERROR_LABEL syscall_error
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ cmpq $-4095, %rax; \
+ jae SYSCALL_ERROR_LABEL; \
+ L(pseudo_end):
+
+# undef PSEUDO_END
+# define PSEUDO_END(name) \
+ SYSCALL_ERROR_HANDLER \
+ END (name)
+
+# undef PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+# define ret_NOERRNO ret
+
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args) \
+ .text; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ negq %rax
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
+ END (name)
+
+# define ret_ERRVAL ret
+
+# ifndef PIC
+# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
+# elif defined(RTLD_PRIVATE_ERRNO)
+# define SYSCALL_ERROR_HANDLER \
+0: \
+ leaq rtld_errno(%rip), %rcx; \
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ movl %edx, (%rcx); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+# elif USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_HANDLER \
+0: \
+ movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ movl %edx, %fs:(%rcx); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+# elif defined _LIBC_REENTRANT
+/* Store (- %rax) into errno through the GOT.
+ Note that errno occupies only 4 bytes. */
+# define SYSCALL_ERROR_HANDLER \
+0: \
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ pushq %rdx; \
+ cfi_adjust_cfa_offset(8); \
+ call __errno_location@PLT; \
+ popq %rdx; \
+ cfi_adjust_cfa_offset(-8); \
+ movl %edx, (%rax); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+
+/* A quick note: it is assumed that the call to `__errno_location' does
+ not modify the stack! */
+# else /* Not _LIBC_REENTRANT. */
+# define SYSCALL_ERROR_HANDLER \
+0:movq errno@GOTPCREL(%RIP), %rcx; \
+ xorl %edx, %edx; \
+ subq %rax, %rdx; \
+ movl %edx, (%rcx); \
+ orq $-1, %rax; \
+ jmp L(pseudo_end);
+# endif /* PIC */
+
+/* The Linux/x86-64 kernel expects the system call parameters in
+ registers according to the following table:
+
+ syscall number rax
+ arg 1 rdi
+ arg 2 rsi
+ arg 3 rdx
+ arg 4 r10
+ arg 5 r8
+ arg 6 r9
+
+ The Linux kernel uses and destroys internally these registers:
+ return address from
+ syscall rcx
+ eflags from syscall r11
+
+ Normal function call, including calls to the system call stub
+ functions in the libc, get the first six parameters passed in
+ registers and the seventh parameter and later on the stack. The
+ register use is as follows:
+
+ system call number in the DO_CALL macro
+ arg 1 rdi
+ arg 2 rsi
+ arg 3 rdx
+ arg 4 rcx
+ arg 5 r8
+ arg 6 r9
+
+ We have to take care that the stack is aligned to 16 bytes. When
+ called the stack is not aligned since the return address has just
+ been pushed.
+
+
+ Syscalls of more than 6 arguments are not supported. */
+
+# undef DO_CALL
+# define DO_CALL(syscall_name, args) \
+ DOARGS_##args \
+ movl $SYS_ify (syscall_name), %eax; \
+ syscall;
+
+# define DOARGS_0 /* nothing */
+# define DOARGS_1 /* nothing */
+# define DOARGS_2 /* nothing */
+# define DOARGS_3 /* nothing */
+# define DOARGS_4 movq %rcx, %r10;
+# define DOARGS_5 DOARGS_4
+# define DOARGS_6 DOARGS_5
+
+#endif /* __ASSEMBLER__ */
+
+
+/* Pointer mangling support. */
+#if defined NOT_IN_libc && defined IS_IN_rtld
+/* We cannot use the thread descriptor because in ld.so we use setjmp
+ earlier than the descriptor is initialized. */
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg) xorq __pointer_chk_guard_local(%rip), reg; \
+ rolq $17, reg
+# define PTR_DEMANGLE(reg) rorq $17, reg; \
+ xorq __pointer_chk_guard_local(%rip), reg
+# else
+# define PTR_MANGLE(reg) asm ("xorq __pointer_chk_guard_local(%%rip), %0\n" \
+ "rolq $17, %0" \
+ : "=r" (reg) : "0" (reg))
+# define PTR_DEMANGLE(reg) asm ("rorq $17, %0\n" \
+ "xorq __pointer_chk_guard_local(%%rip), %0" \
+ : "=r" (reg) : "0" (reg))
+# endif
+#else
+# ifdef __ASSEMBLER__
+# define PTR_MANGLE(reg) xorq %fs:POINTER_GUARD, reg; \
+ rolq $17, reg
+# define PTR_DEMANGLE(reg) rorq $17, reg; \
+ xorq %fs:POINTER_GUARD, reg
+# else
+# define PTR_MANGLE(var) asm ("xorq %%fs:%c2, %0\n" \
+ "rolq $17, %0" \
+ : "=r" (var) \
+ : "0" (var), \
+ "i" (offsetof (tcbhead_t, \
+ pointer_guard)))
+# define PTR_DEMANGLE(var) asm ("rorq $17, %0\n" \
+ "xorq %%fs:%c2, %0" \
+ : "=r" (var) \
+ : "0" (var), \
+ "i" (offsetof (tcbhead_t, \
+ pointer_guard)))
+# endif
+#endif
+
+#endif /* linux/x86_64/sysdep.h */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_create.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_create.c
deleted file mode 100644
index a07b1afe5..000000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_create.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
- 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; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "compat-timer.h"
-#include <atomic.h>
-
-
-#define timer_create_alias __timer_create_new
-#include "../timer_create.c"
-
-#undef timer_create
-weak_alias(__timer_create_new, timer_create)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_delete.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_delete.c
deleted file mode 100644
index 8456dc31a..000000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_delete.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
- 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; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "compat-timer.h"
-
-
-#define timer_delete_alias __timer_delete_new
-#include "../timer_delete.c"
-
-#undef timer_delete
-weak_alias(__timer_delete_new, timer_delete)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_getoverr.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_getoverr.c
deleted file mode 100644
index 86a2df696..000000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_getoverr.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
- 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; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "compat-timer.h"
-
-
-#define timer_getoverrun_alias __timer_getoverrun_new
-#include "../timer_getoverr.c"
-
-#undef timer_getoverrun
-weak_alias(__timer_getoverrun_new, timer_getoverrun)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_gettime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_gettime.c
deleted file mode 100644
index 6b260e453..000000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_gettime.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
- 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; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "compat-timer.h"
-
-
-#define timer_gettime_alias __timer_gettime_new
-#include "../timer_gettime.c"
-
-#undef timer_gettime
-weak_alias(__timer_gettime_new, timer_gettime)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_settime.c
deleted file mode 100644
index 0ec178246..000000000
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/timer_settime.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
-
- 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; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
-#include "compat-timer.h"
-
-
-#define timer_settime_alias __timer_settime_new
-#include "../timer_settime.c"
-
-#undef timer_settime
-weak_alias(__timer_settime_new, timer_settime)
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
index f68d40439..9a9912ca8 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -16,9 +16,16 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#include <tcb-offsets.h>
+/* We want an #include_next, but we are the main source file.
+ So, #include ourselves and in that incarnation we can use #include_next. */
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <vfork.S>
+#else
-#define SAVE_PID \
+# include <tcb-offsets.h>
+
+# define SAVE_PID \
movl %fs:PID, %esi; \
movl $0x80000000, %ecx; \
movl %esi, %edx; \
@@ -26,10 +33,11 @@
cmove %ecx, %edx; \
movl %edx, %fs:PID
-#define RESTORE_PID \
+# define RESTORE_PID \
testq %rax, %rax; \
je 1f; \
movl %esi, %fs:PID; \
1:
-#include <sysdeps/unix/sysv/linux/x86_64/vfork.S>
+# include_next <vfork.S>
+#endif
diff --git a/libpthread/nptl/sysdeps/x86_64/Makefile b/libpthread/nptl/sysdeps/x86_64/Makefile
index 6e24a26cd..2f0d88f30 100644
--- a/libpthread/nptl/sysdeps/x86_64/Makefile
+++ b/libpthread/nptl/sysdeps/x86_64/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+# 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
@@ -21,8 +21,7 @@ gen-as-const-headers += tcb-offsets.sym
endif
ifeq ($(subdir),nptl)
-# P4s have problems with 4M aliasing. We disturb the allocation of stacks
-# just enough so the subsequent allocations do not use stack address
-# (mod 4M) == 0.
-CFLAGS-pthread_create.c += -DMULTI_PAGE_ALIASING=65536
+CFLAGS-pthread_create.c += -mpreferred-stack-boundary=4
+CFLAGS-tst-align.c += -mpreferred-stack-boundary=4
+CFLAGS-tst-align2.c += -mpreferred-stack-boundary=4
endif
diff --git a/libpthread/nptl/sysdeps/x86_64/Makefile.arch b/libpthread/nptl/sysdeps/x86_64/Makefile.arch
new file mode 100644
index 000000000..b99a0da0e
--- /dev/null
+++ b/libpthread/nptl/sysdeps/x86_64/Makefile.arch
@@ -0,0 +1,52 @@
+# Makefile for uClibc NPTL
+#
+# Copyright (C) 2005 Steven J. Hill <sjhill@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+libpthread_CSRC = pthread_spin_lock.c
+libpthread_SSRC = pthread_spin_trylock.S
+
+CFLAGS-pthread_spin_lock.c += -D_GNU_SOURCE
+
+CFLAGS-x86_64 = $(SSP_ALL_CFLAGS)
+#CFLAGS:=$(CFLAGS:-O1=-O2)
+
+PTHREAD_ARCH_DIR := $(top_srcdir)libpthread/nptl/sysdeps/x86_64
+PTHREAD_ARCH_OUT := $(top_builddir)libpthread/nptl/sysdeps/x86_64
+PTHREAD_ARCH_OBJ := $(patsubst %.S,$(PTHREAD_ARCH_OUT)/%.o,$(libpthread_SSRC))
+PTHREAD_ARCH_OBJ += $(patsubst %.c,$(PTHREAD_ARCH_OUT)/%.o,$(libpthread_CSRC))
+
+ifeq ($(DOPIC),y)
+libpthread-a-y += $(PTHREAD_ARCH_OBJ:.o=.os)
+else
+libpthread-a-y += $(PTHREAD_ARCH_OBJ)
+endif
+libpthread-so-y += $(PTHREAD_ARCH_OBJ:.o=.oS)
+
+libpthread-nomulti-y += $(PTHREAD_ARCH_OBJ)
+
+objclean-y += nptl_arch_clean
+headers-y += $(PTHREAD_ARCH_OUT)/tcb-offsets.h
+headers_clean-y += nptl_arch_headers_clean
+
+#
+# Create 'tcb-offsets.h' header file.
+#
+CFLAGS-tcb-offsets.c = -S
+
+$(PTHREAD_ARCH_OUT)/tcb-offsets.c: $(PTHREAD_ARCH_DIR)/tcb-offsets.sym
+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@
+
+$(PTHREAD_ARCH_OUT)/tcb-offsets.s: $(PTHREAD_ARCH_OUT)/tcb-offsets.c
+ $(compile.c)
+
+$(PTHREAD_ARCH_OUT)/tcb-offsets.h: $(PTHREAD_ARCH_OUT)/tcb-offsets.s
+ @sed -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@
+
+nptl_arch_headers_clean:
+ $(do_rm) $(addprefix $(PTHREAD_ARCH_OUT)/tcb-offsets., c s h)
+
+nptl_arch_clean:
+ $(do_rm) $(addprefix $(PTHREAD_ARCH_OUT)/*., o os oS)
diff --git a/libpthread/nptl/sysdeps/x86_64/pthreaddef.h b/libpthread/nptl/sysdeps/x86_64/pthreaddef.h
index 27896a445..b33c18638 100644
--- a/libpthread/nptl/sysdeps/x86_64/pthreaddef.h
+++ b/libpthread/nptl/sysdeps/x86_64/pthreaddef.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -33,22 +33,11 @@
/* Location of current stack frame. The frame pointer is not usable. */
#define CURRENT_STACK_FRAME \
- ({ char *frame; asm ("movq %%rsp, %0" : "=r" (frame)); frame; })
-
-
-/* We prefer to have the stack allocated in the low 4GB since this
- allows faster context switches. */
-#define ARCH_MAP_FLAGS MAP_32BIT
-
-/* If it is not possible to allocate memory there retry without that
- flag. */
-#define ARCH_RETRY_MMAP(size) \
- mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, \
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
+ ({ char *frame; __asm__ ("movq %%rsp, %0" : "=r" (frame)); frame; })
/* XXX Until we have a better place keep the definitions here. */
/* While there is no such syscall. */
#define __exit_thread_inline(val) \
- asm volatile ("syscall" :: "a" (__NR_exit), "D" (val))
+ __asm__ volatile ("syscall" :: "a" (__NR_exit), "D" (val))
diff --git a/libpthread/nptl/sysdeps/x86_64/sysdep.h b/libpthread/nptl/sysdeps/x86_64/sysdep.h
new file mode 100644
index 000000000..122270f91
--- /dev/null
+++ b/libpthread/nptl/sysdeps/x86_64/sysdep.h
@@ -0,0 +1,114 @@
+/* Assembler macros for x86-64.
+ Copyright (C) 2001, 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. */
+
+#include <sysdeps/generic/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#ifdef HAVE_ELF
+
+/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */
+#define ALIGNARG(log2) 1<<log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
+
+/* In ELF C symbols are asm symbols. */
+#undef NO_UNDERSCORES
+#define NO_UNDERSCORES
+
+#else
+
+#define ALIGNARG(log2) log2
+#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */
+#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */
+
+#endif
+
+
+/* Define an entry point visible from C. */
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(4); \
+ C_LABEL(name) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(name)
+
+/* If compiled for profiling, call `mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a normal frame pointer being on the stack
+ to locate our caller, so push one just for its benefit. */
+#define CALL_MCOUNT \
+ pushq %rbp; \
+ cfi_adjust_cfa_offset(8); \
+ movq %rsp, %rbp; \
+ cfi_def_cfa_register(%rbp); \
+ call JUMPTARGET(mcount); \
+ popq %rbp; \
+ cfi_def_cfa(rsp,8);
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#ifdef NO_UNDERSCORES
+/* Since C identifiers are not normally prefixed with an underscore
+ on this system, the asm identifier `syscall_error' intrudes on the
+ C name space. Make sure we use an innocuous name. */
+#define syscall_error __syscall_error
+#define mcount _mcount
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+lose: \
+ jmp JUMPTARGET(syscall_error) \
+ .globl syscall_error; \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args); \
+ jb lose
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#ifdef PIC
+#define JUMPTARGET(name) name##@PLT
+#else
+#define JUMPTARGET(name) name
+#endif
+
+/* Local label name for asm code. */
+#ifndef L
+# ifdef HAVE_ELF
+/* ELF-like local names start with `.L'. */
+# define L(name) .L##name
+# else
+# define L(name) name
+# endif
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/libpthread/nptl/sysdeps/x86_64/tls.h b/libpthread/nptl/sysdeps/x86_64/tls.h
index 516827b8e..7b40e3d57 100644
--- a/libpthread/nptl/sysdeps/x86_64/tls.h
+++ b/libpthread/nptl/sysdeps/x86_64/tls.h
@@ -1,5 +1,5 @@
/* Definition for thread-local data handling. nptl/x86_64 version.
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002-2007, 2008, 2009 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
@@ -20,12 +20,15 @@
#ifndef _TLS_H
#define _TLS_H 1
-#include <asm/prctl.h> /* For ARCH_SET_FS. */
#ifndef __ASSEMBLER__
+# include <asm/prctl.h> /* For ARCH_SET_FS. */
# include <stdbool.h>
# include <stddef.h>
# include <stdint.h>
# include <stdlib.h>
+# include <sysdep.h>
+# include <bits/wordsize.h>
+# include <xmmintrin.h>
/* Type for the dtv. */
@@ -42,13 +45,33 @@ typedef union dtv
typedef struct
{
- void *tcb; /* Pointer to the TCB. Not necessary the
+ void *tcb; /* Pointer to the TCB. Not necessarily the
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
+ int gscope_flag;
uintptr_t sysinfo;
uintptr_t stack_guard;
+ uintptr_t pointer_guard;
+ unsigned long int vgetcpu_cache[2];
+# ifndef __ASSUME_PRIVATE_FUTEX
+ int private_futex;
+# else
+ int __unused1;
+# endif
+# if __WORDSIZE == 64
+ int rtld_must_xmm_save;
+# endif
+ /* Reservation of some values for the TM ABI. */
+ void *__private_tm[5];
+# if __WORDSIZE == 64
+ long int __unused2;
+ /* Have space for the post-AVX register size. */
+ __m128 rtld_savespace_sse[8][4];
+
+ void *__padding[8];
+# endif
} tcbhead_t;
#else /* __ASSEMBLER__ */
@@ -57,9 +80,9 @@ typedef struct
/* We require TLS support in the tools. */
-#ifndef HAVE_TLS_SUPPORT
-# error "TLS support is required."
-#endif
+#define HAVE_TLS_SUPPORT 1
+#define HAVE___THREAD 1
+#define HAVE_TLS_MODEL_ATTRIBUTE 1
/* Signal that TLS support is available. */
#define USE_TLS 1
@@ -74,7 +97,7 @@ typedef struct
/* Get the thread descriptor definition. */
-# include <nptl/descr.h>
+# include <descr.h>
#ifndef LOCK_PREFIX
# ifdef UP
@@ -96,7 +119,12 @@ typedef struct
# define TLS_TCB_SIZE sizeof (struct pthread)
/* Alignment requirements for the TCB. */
-# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+//# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+// Normally the above would be correct But we have to store post-AVX
+// vector registers in the TCB and we want the storage to be aligned.
+// unfortunately there isn't yet a type for these values and hence no
+// 32-byte alignment requirement. Make this explicit, for now.
+# define TLS_TCB_ALIGN 32
/* The TCB can have any size and the memory following the address the
thread pointer points to is unspecified. Allocate the TCB there. */
@@ -120,9 +148,9 @@ typedef struct
/* Macros to load from and store into segment registers. */
# define TLS_GET_FS() \
- ({ int __seg; __asm ("movl %%fs, %0" : "=q" (__seg)); __seg; })
+ ({ int __seg; __asm__ ("movl %%fs, %0" : "=q" (__seg)); __seg; })
# define TLS_SET_FS(val) \
- __asm ("movl %0, %%fs" :: "q" (val))
+ __asm__ ("movl %0, %%fs" :: "q" (val))
/* Code to initially initialize the thread pointer. This might need
@@ -141,7 +169,7 @@ typedef struct
_head->self = _thrdescr; \
\
/* It is a simple syscall to set the %fs value for the thread. */ \
- asm volatile ("syscall" \
+ __asm__ volatile ("syscall" \
: "=a" (_result) \
: "0" ((unsigned long int) __NR_arch_prctl), \
"D" ((unsigned long int) ARCH_SET_FS), \
@@ -162,11 +190,11 @@ typedef struct
The contained asm must *not* be marked volatile since otherwise
assignments like
- pthread_descr self = thread_self();
+ pthread_descr self = thread_self();
do not get optimized away. */
# define THREAD_SELF \
({ struct pthread *__self; \
- asm ("movq %%fs:%c1,%q0" : "=r" (__self) \
+ __asm__ ("movq %%fs:%c1,%q0" : "=r" (__self) \
: "i" (offsetof (struct pthread, header.self))); \
__self;})
@@ -178,11 +206,11 @@ typedef struct
# define THREAD_GETMEM(descr, member) \
({ __typeof (descr->member) __value; \
if (sizeof (__value) == 1) \
- asm volatile ("movb %%fs:%P2,%b0" \
+ __asm__ volatile ("movb %%fs:%P2,%b0" \
: "=q" (__value) \
: "0" (0), "i" (offsetof (struct pthread, member))); \
else if (sizeof (__value) == 4) \
- asm volatile ("movl %%fs:%P1,%0" \
+ __asm__ volatile ("movl %%fs:%P1,%0" \
: "=r" (__value) \
: "i" (offsetof (struct pthread, member))); \
else \
@@ -192,7 +220,7 @@ typedef struct
4 or 8. */ \
abort (); \
\
- asm volatile ("movq %%fs:%P1,%q0" \
+ __asm__ volatile ("movq %%fs:%P1,%q0" \
: "=r" (__value) \
: "i" (offsetof (struct pthread, member))); \
} \
@@ -203,12 +231,12 @@ typedef struct
# define THREAD_GETMEM_NC(descr, member, idx) \
({ __typeof (descr->member[0]) __value; \
if (sizeof (__value) == 1) \
- asm volatile ("movb %%fs:%P2(%q3),%b0" \
+ __asm__ volatile ("movb %%fs:%P2(%q3),%b0" \
: "=q" (__value) \
: "0" (0), "i" (offsetof (struct pthread, member[0])), \
"r" (idx)); \
else if (sizeof (__value) == 4) \
- asm volatile ("movl %%fs:%P1(,%q2,4),%0" \
+ __asm__ volatile ("movl %%fs:%P1(,%q2,4),%0" \
: "=r" (__value) \
: "i" (offsetof (struct pthread, member[0])), "r" (idx));\
else \
@@ -218,7 +246,7 @@ typedef struct
4 or 8. */ \
abort (); \
\
- asm volatile ("movq %%fs:%P1(,%q2,8),%q0" \
+ __asm__ volatile ("movq %%fs:%P1(,%q2,8),%q0" \
: "=r" (__value) \
: "i" (offsetof (struct pthread, member[0])), \
"r" (idx)); \
@@ -238,11 +266,11 @@ typedef struct
/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
# define THREAD_SETMEM(descr, member, value) \
({ if (sizeof (descr->member) == 1) \
- asm volatile ("movb %b0,%%fs:%P1" : \
+ __asm__ volatile ("movb %b0,%%fs:%P1" : \
: "iq" (value), \
"i" (offsetof (struct pthread, member))); \
else if (sizeof (descr->member) == 4) \
- asm volatile ("movl %0,%%fs:%P1" : \
+ __asm__ volatile ("movl %0,%%fs:%P1" : \
: IMM_MODE (value), \
"i" (offsetof (struct pthread, member))); \
else \
@@ -252,7 +280,7 @@ typedef struct
4 or 8. */ \
abort (); \
\
- asm volatile ("movq %q0,%%fs:%P1" : \
+ __asm__ volatile ("movq %q0,%%fs:%P1" : \
: IMM_MODE ((unsigned long int) value), \
"i" (offsetof (struct pthread, member))); \
}})
@@ -261,12 +289,12 @@ typedef struct
/* Set member of the thread descriptor directly. */
# define THREAD_SETMEM_NC(descr, member, idx, value) \
({ if (sizeof (descr->member[0]) == 1) \
- asm volatile ("movb %b0,%%fs:%P1(%q2)" : \
+ __asm__ volatile ("movb %b0,%%fs:%P1(%q2)" : \
: "iq" (value), \
"i" (offsetof (struct pthread, member[0])), \
"r" (idx)); \
else if (sizeof (descr->member[0]) == 4) \
- asm volatile ("movl %0,%%fs:%P1(,%q2,4)" : \
+ __asm__ volatile ("movl %0,%%fs:%P1(,%q2,4)" : \
: IMM_MODE (value), \
"i" (offsetof (struct pthread, member[0])), \
"r" (idx)); \
@@ -277,7 +305,7 @@ typedef struct
4 or 8. */ \
abort (); \
\
- asm volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \
+ __asm__ volatile ("movq %q0,%%fs:%P1(,%q2,8)" : \
: IMM_MODE ((unsigned long int) value), \
"i" (offsetof (struct pthread, member[0])), \
"r" (idx)); \
@@ -285,11 +313,11 @@ typedef struct
/* Atomic compare and exchange on TLS, returning old value. */
-#define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
+# define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
({ __typeof (descr->member) __ret; \
__typeof (oldval) __old = (oldval); \
if (sizeof (descr->member) == 4) \
- asm volatile (LOCK_PREFIX "cmpxchgl %2, %%fs:%P3" \
+ __asm__ volatile (LOCK_PREFIX "cmpxchgl %2, %%fs:%P3" \
: "=a" (__ret) \
: "0" (__old), "r" (newval), \
"i" (offsetof (struct pthread, member))); \
@@ -299,10 +327,21 @@ typedef struct
__ret; })
+/* Atomic logical and. */
+# define THREAD_ATOMIC_AND(descr, member, val) \
+ (void) ({ if (sizeof ((descr)->member) == 4) \
+ __asm__ volatile (LOCK_PREFIX "andl %1, %%fs:%P0" \
+ :: "i" (offsetof (struct pthread, member)), \
+ "ir" (val)); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); })
+
+
/* Atomic set bit. */
-#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
(void) ({ if (sizeof ((descr)->member) == 4) \
- asm volatile (LOCK_PREFIX "orl %1, %%fs:%P0" \
+ __asm__ volatile (LOCK_PREFIX "orl %1, %%fs:%P0" \
:: "i" (offsetof (struct pthread, member)), \
"ir" (1 << (bit))); \
else \
@@ -310,9 +349,9 @@ typedef struct
abort (); })
-#define CALL_THREAD_FCT(descr) \
+# define CALL_THREAD_FCT(descr) \
({ void *__res; \
- asm volatile ("movq %%fs:%P2, %%rdi\n\t" \
+ __asm__ volatile ("movq %%fs:%P2, %%rdi\n\t" \
"callq *%%fs:%P1" \
: "=a" (__res) \
: "i" (offsetof (struct pthread, start_routine)), \
@@ -329,6 +368,70 @@ typedef struct
((descr)->header.stack_guard \
= THREAD_GETMEM (THREAD_SELF, header.stack_guard))
+
+/* Set the pointer guard field in the TCB head. */
+# define THREAD_SET_POINTER_GUARD(value) \
+ THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value)
+# define THREAD_COPY_POINTER_GUARD(descr) \
+ ((descr)->header.pointer_guard \
+ = THREAD_GETMEM (THREAD_SELF, header.pointer_guard))
+
+
+/* Get and set the global scope generation counter in the TCB head. */
+# define THREAD_GSCOPE_FLAG_UNUSED 0
+# define THREAD_GSCOPE_FLAG_USED 1
+# define THREAD_GSCOPE_FLAG_WAIT 2
+# define THREAD_GSCOPE_RESET_FLAG() \
+ do \
+ { int __res; \
+ __asm__ volatile ("xchgl %0, %%fs:%P1" \
+ : "=r" (__res) \
+ : "i" (offsetof (struct pthread, header.gscope_flag)), \
+ "0" (THREAD_GSCOPE_FLAG_UNUSED)); \
+ if (__res == THREAD_GSCOPE_FLAG_WAIT) \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
+ } \
+ while (0)
+# define THREAD_GSCOPE_SET_FLAG() \
+ THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED)
+# define THREAD_GSCOPE_WAIT() \
+ GL(dl_wait_lookup_done) ()
+
+
+# ifdef SHARED
+/* Defined in dl-trampoline.S. */
+extern void _dl_x86_64_save_sse (void);
+extern void _dl_x86_64_restore_sse (void);
+
+# define RTLD_CHECK_FOREIGN_CALL \
+ (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) != 0)
+
+/* NB: Don't use the xchg operation because that would imply a lock
+ prefix which is expensive and unnecessary. The cache line is also
+ not contested at all. */
+# define RTLD_ENABLE_FOREIGN_CALL \
+ int old_rtld_must_xmm_save = THREAD_GETMEM (THREAD_SELF, \
+ header.rtld_must_xmm_save); \
+ THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 1)
+
+# define RTLD_PREPARE_FOREIGN_CALL \
+ do if (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save)) \
+ { \
+ _dl_x86_64_save_sse (); \
+ THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 0); \
+ } \
+ while (0)
+
+# define RTLD_FINALIZE_FOREIGN_CALL \
+ do { \
+ if (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) == 0) \
+ _dl_x86_64_restore_sse (); \
+ THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, \
+ old_rtld_must_xmm_save); \
+ } while (0)
+# endif
+
+
#endif /* __ASSEMBLER__ */
#endif /* tls.h */