about summary refs log tree commit diff
path: root/linuxthreads/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/sysdeps')
-rw-r--r--linuxthreads/sysdeps/alpha/elf/pt-initfini.c90
-rw-r--r--linuxthreads/sysdeps/alpha/pspinlock.c110
-rw-r--r--linuxthreads/sysdeps/alpha/pt-machine.h128
-rw-r--r--linuxthreads/sysdeps/alpha/tls.h129
-rw-r--r--linuxthreads/sysdeps/arm/pspinlock.c82
-rw-r--r--linuxthreads/sysdeps/arm/pt-machine.h55
-rw-r--r--linuxthreads/sysdeps/cris/pspinlock.c72
-rw-r--r--linuxthreads/sysdeps/cris/pt-machine.h58
-rw-r--r--linuxthreads/sysdeps/hppa/pspinlock.c81
-rw-r--r--linuxthreads/sysdeps/hppa/pt-machine.h62
-rw-r--r--linuxthreads/sysdeps/i386/Makefile23
-rw-r--r--linuxthreads/sysdeps/i386/i586/Versions5
-rw-r--r--linuxthreads/sysdeps/i386/i686/Versions5
-rw-r--r--linuxthreads/sysdeps/i386/i686/pt-machine.h79
-rw-r--r--linuxthreads/sysdeps/i386/pspinlock.c103
-rw-r--r--linuxthreads/sysdeps/i386/pt-machine.h108
-rw-r--r--linuxthreads/sysdeps/i386/tcb-offsets.sym7
-rw-r--r--linuxthreads/sysdeps/i386/tls.h225
-rw-r--r--linuxthreads/sysdeps/i386/useldt.h314
-rw-r--r--linuxthreads/sysdeps/ia64/Makefile3
-rw-r--r--linuxthreads/sysdeps/ia64/Versions5
-rw-r--r--linuxthreads/sysdeps/ia64/pspinlock.c79
-rw-r--r--linuxthreads/sysdeps/ia64/pt-machine.h133
-rw-r--r--linuxthreads/sysdeps/ia64/tcb-offsets.sym9
-rw-r--r--linuxthreads/sysdeps/ia64/tls.h141
-rw-r--r--linuxthreads/sysdeps/m68k/Makefile7
-rw-r--r--linuxthreads/sysdeps/m68k/pspinlock.c82
-rw-r--r--linuxthreads/sysdeps/m68k/pt-machine.h69
-rw-r--r--linuxthreads/sysdeps/mips/pspinlock.c98
-rw-r--r--linuxthreads/sysdeps/mips/pt-machine.h92
-rw-r--r--linuxthreads/sysdeps/powerpc/Makefile7
-rw-r--r--linuxthreads/sysdeps/powerpc/powerpc32/pspinlock.c70
-rw-r--r--linuxthreads/sysdeps/powerpc/powerpc32/pt-machine.h120
-rw-r--r--linuxthreads/sysdeps/powerpc/powerpc64/pspinlock.c70
-rw-r--r--linuxthreads/sysdeps/powerpc/powerpc64/pt-machine.h185
-rw-r--r--linuxthreads/sysdeps/powerpc/tcb-offsets.sym19
-rw-r--r--linuxthreads/sysdeps/powerpc/tls.h160
-rw-r--r--linuxthreads/sysdeps/pthread/Makefile14
-rw-r--r--linuxthreads/sysdeps/pthread/Subdirs1
-rw-r--r--linuxthreads/sysdeps/pthread/bits/initspin.h28
-rw-r--r--linuxthreads/sysdeps/pthread/bits/libc-lock.h413
-rw-r--r--linuxthreads/sysdeps/pthread/bits/libc-tsd.h59
-rw-r--r--linuxthreads/sysdeps/pthread/bits/pthreadtypes.h152
-rw-r--r--linuxthreads/sysdeps/pthread/bits/typesizes.h66
-rw-r--r--linuxthreads/sysdeps/pthread/errno-loc.c46
-rw-r--r--linuxthreads/sysdeps/pthread/flockfile.c33
-rw-r--r--linuxthreads/sysdeps/pthread/ftrylockfile.c33
-rw-r--r--linuxthreads/sysdeps/pthread/funlockfile.c33
-rw-r--r--linuxthreads/sysdeps/pthread/getcpuclockid.c49
-rw-r--r--linuxthreads/sysdeps/pthread/herrno-loc.c43
-rw-r--r--linuxthreads/sysdeps/pthread/list.h114
-rw-r--r--linuxthreads/sysdeps/pthread/malloc-machine.h67
-rw-r--r--linuxthreads/sysdeps/pthread/posix-timer.h204
-rw-r--r--linuxthreads/sysdeps/pthread/pt-initfini.c124
-rw-r--r--linuxthreads/sysdeps/pthread/pthread-functions.h96
-rw-r--r--linuxthreads/sysdeps/pthread/pthread.h686
-rw-r--r--linuxthreads/sysdeps/pthread/ptlongjmp.c39
-rw-r--r--linuxthreads/sysdeps/pthread/res-state.c47
-rw-r--r--linuxthreads/sysdeps/pthread/semaphore.h1
-rw-r--r--linuxthreads/sysdeps/pthread/sigaction.c55
-rw-r--r--linuxthreads/sysdeps/pthread/tcb-offsets.h1
-rw-r--r--linuxthreads/sysdeps/pthread/timer_create.c170
-rw-r--r--linuxthreads/sysdeps/pthread/timer_delete.c70
-rw-r--r--linuxthreads/sysdeps/pthread/timer_getoverr.c45
-rw-r--r--linuxthreads/sysdeps/pthread/timer_gettime.c77
-rw-r--r--linuxthreads/sysdeps/pthread/timer_routines.c573
-rw-r--r--linuxthreads/sysdeps/pthread/timer_settime.c137
-rw-r--r--linuxthreads/sysdeps/pthread/tst-timer.c114
-rw-r--r--linuxthreads/sysdeps/s390/Makefile6
-rw-r--r--linuxthreads/sysdeps/s390/pspinlock.c91
-rw-r--r--linuxthreads/sysdeps/s390/s390-32/pt-machine.h120
-rw-r--r--linuxthreads/sysdeps/s390/s390-64/pt-machine.h125
-rw-r--r--linuxthreads/sysdeps/s390/tcb-offsets.sym4
-rw-r--r--linuxthreads/sysdeps/s390/tls.h140
-rw-r--r--linuxthreads/sysdeps/sh/Makefile3
-rw-r--r--linuxthreads/sysdeps/sh/pspinlock.c80
-rw-r--r--linuxthreads/sysdeps/sh/pt-machine.h81
-rw-r--r--linuxthreads/sysdeps/sh/tcb-offsets.sym10
-rw-r--r--linuxthreads/sysdeps/sh/tls.h148
-rw-r--r--linuxthreads/sysdeps/sparc/Makefile3
-rw-r--r--linuxthreads/sysdeps/sparc/sparc32/pspinlock.c88
-rw-r--r--linuxthreads/sysdeps/sparc/sparc32/pt-machine.h83
-rw-r--r--linuxthreads/sysdeps/sparc/sparc32/sparcv9/Versions5
-rw-r--r--linuxthreads/sysdeps/sparc/sparc32/sparcv9/pspinlock.c94
-rw-r--r--linuxthreads/sysdeps/sparc/sparc64/Versions5
-rw-r--r--linuxthreads/sysdeps/sparc/sparc64/pspinlock.c93
-rw-r--r--linuxthreads/sysdeps/sparc/sparc64/pt-machine.h105
-rw-r--r--linuxthreads/sysdeps/sparc/tcb-offsets.sym4
-rw-r--r--linuxthreads/sysdeps/sparc/tls.h110
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/Implies1
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/Makefile3
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/Versions5
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/allocalim.h26
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c87
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile3
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions6
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c33
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h92
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h66
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S28
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h146
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S70
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h145
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S80
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h92
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h181
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h38
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/execve.c73
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/fork.c43
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/fork.h60
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c33
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h27
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h73
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c109
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h189
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h64
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h179
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S95
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile3
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions6
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h92
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h49
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h25
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c140
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c33
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h144
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S54
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c34
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h129
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S84
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile3
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h144
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h143
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c287
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile2
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions5
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h131
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S78
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h127
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S91
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c70
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c56
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/raise.c36
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c88
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h72
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c154
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h137
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S69
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c137
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c1
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h116
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S54
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c143
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h24
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h227
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S77
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sigwait.c88
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/smp.h48
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions6
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c33
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h92
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h66
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h34
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h102
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S65
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile5
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c1
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h101
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S64
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c49
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile4
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c1
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h132
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S62
-rw-r--r--linuxthreads/sysdeps/x86_64/Makefile3
-rw-r--r--linuxthreads/sysdeps/x86_64/Versions5
-rw-r--r--linuxthreads/sysdeps/x86_64/pspinlock.c97
-rw-r--r--linuxthreads/sysdeps/x86_64/pt-machine.h225
-rw-r--r--linuxthreads/sysdeps/x86_64/tcb-offsets.sym4
-rw-r--r--linuxthreads/sysdeps/x86_64/tls.h129
180 files changed, 14801 insertions, 0 deletions
diff --git a/linuxthreads/sysdeps/alpha/elf/pt-initfini.c b/linuxthreads/sysdeps/alpha/elf/pt-initfini.c
new file mode 100644
index 0000000000..ee25582101
--- /dev/null
+++ b/linuxthreads/sysdeps/alpha/elf/pt-initfini.c
@@ -0,0 +1,90 @@
+/* Special .init and .fini section support for Alpha.  Linuxthreads 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.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the .init and .fini
+   sections and defines global symbols for those addresses, so they can be
+   called as functions.
+
+   * crtn.s puts the corresponding function epilogues in the .init and .fini
+   sections.
+
+   This differs from what would be generated by the generic code in that
+   we save and restore the GP within the function.  In order for linker
+   relaxation to work, the value in the GP register on exit from a function
+   must be valid for the function entry point.  Normally, a function is
+   contained within one object file and this is not an issue, provided
+   that the function reloads the gp after making any function calls.
+   However, _init and _fini are constructed from pieces of many object
+   files, all of which may have different GP values.  So we must reload
+   the GP value from crti.o in crtn.o.  */
+
+__asm__ ("						\n\
+#include \"defs.h\"					\n\
+							\n\
+/*@HEADER_ENDS*/					\n\
+							\n\
+/*@_init_PROLOG_BEGINS*/				\n\
+	.section .init, \"ax\", @progbits		\n\
+	.globl	_init					\n\
+	.type	_init,@function				\n\
+	.usepv	_init,std				\n\
+_init:							\n\
+	ldgp	$29, 0($27)				\n\
+	subq	$30, 16, $30				\n\
+	stq	$26, 0($30)				\n\
+	stq	$29, 8($30)				\n\
+	jsr	$26, __pthread_initialize_minimal	\n\
+	ldq	$29, 8($30)				\n\
+	.align 3					\n\
+/*@_init_PROLOG_ENDS*/					\n\
+							\n\
+/*@_init_EPILOG_BEGINS*/				\n\
+	.section .init, \"ax\", @progbits		\n\
+	ldq	$26, 0($30)				\n\
+	ldq	$29, 8($30)				\n\
+	addq	$30, 16, $30				\n\
+	ret						\n\
+/*@_init_EPILOG_ENDS*/					\n\
+							\n\
+/*@_fini_PROLOG_BEGINS*/				\n\
+	.section .fini, \"ax\", @progbits		\n\
+	.globl	_fini					\n\
+	.type	_fini,@function				\n\
+	.usepv	_fini,std				\n\
+_fini:							\n\
+	ldgp	$29, 0($27)				\n\
+	subq	$30, 16, $30				\n\
+	stq	$26, 0($30)				\n\
+	stq	$29, 8($30)				\n\
+	.align 3					\n\
+/*@_fini_PROLOG_ENDS*/					\n\
+							\n\
+/*@_fini_EPILOG_BEGINS*/				\n\
+	.section .fini, \"ax\", @progbits		\n\
+	ldq	$26, 0($30)				\n\
+	ldq	$29, 8($30)				\n\
+	addq	$30, 16, $30				\n\
+	ret						\n\
+/*@_fini_EPILOG_ENDS*/					\n\
+							\n\
+/*@TRAILER_BEGINS*/					\n\
+");
diff --git a/linuxthreads/sysdeps/alpha/pspinlock.c b/linuxthreads/sysdeps/alpha/pspinlock.c
new file mode 100644
index 0000000000..79b7836293
--- /dev/null
+++ b/linuxthreads/sysdeps/alpha/pspinlock.c
@@ -0,0 +1,110 @@
+/* POSIX spinlock implementation.  Alpha version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+
+/* This implementation is similar to the one used in the Linux kernel.
+   But the kernel is byte instructions for the memory access.  This is
+   faster but unusable here.  The problem is that only 128
+   threads/processes could use the spinlock at the same time.  If (by
+   a design error in the program) a thread/process would hold the
+   spinlock for a time long enough to accumulate 128 waiting
+   processes, the next one will find a positive value in the spinlock
+   and assume it is unlocked.  We cannot accept that.  */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  unsigned int tmp;
+  asm volatile
+    ("1:	ldl_l	%0,%1\n"
+     "		blbs	%0,2f\n"
+     "		or	%0,1,%0\n"
+     "		stl_c	%0,%1\n"
+     "		beq	%0,2f\n"
+     "		mb\n"
+     ".subsection 2\n"
+     "2:	ldl	%0,%1\n"
+     "		blbs	%0,2b\n"
+     "		br	1b\n"
+     ".previous"
+     : "=r" (tmp), "=m" (lock)
+     : "m" (lock));
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  unsigned long int oldval;
+  unsigned long int temp;
+
+  asm volatile
+    ("1:	ldl_l	%0,%1\n"
+     "		and	%0,%3,%2\n"
+     "		bne	%2,2f\n"
+     "		xor	%0,%3,%0\n"
+     "		stl_c	%0,%1\n"
+     "		beq	%0,3f\n"
+     "		mb\n"
+     "2:\n"
+     ".subsection 2\n"
+     "3:	br	1b\n"
+     ".previous"
+     : "=&r" (temp), "=m" (*lock), "=&r" (oldval)
+     : "Ir" (1UL), "m" (*lock));
+
+  return oldval == 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile ("mb");
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/alpha/pt-machine.h b/linuxthreads/sysdeps/alpha/pt-machine.h
new file mode 100644
index 0000000000..853ac6f04a
--- /dev/null
+++ b/linuxthreads/sysdeps/alpha/pt-machine.h
@@ -0,0 +1,128 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   Alpha version.
+   Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+#ifdef __linux__
+# include <asm/pal.h>
+#else
+# include <machine/pal.h>
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char *stack_pointer __asm__("$30");
+
+
+/* Memory barrier; default is to do nothing */
+#define MEMORY_BARRIER() __asm__ __volatile__("mb" : : : "memory")
+/* Write barrier.  */
+#define WRITE_MEMORY_BARRIER() __asm__ __volatile__("wmb" : : : "memory")
+
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  long int ret, temp;
+
+  __asm__ __volatile__(
+	"/* Inline spinlock test & set */\n"
+	"1:\t"
+	"ldl_l %0,%3\n\t"
+	"bne %0,2f\n\t"
+	"or $31,1,%1\n\t"
+	"stl_c %1,%2\n\t"
+	"beq %1,1b\n"
+	"2:\tmb\n"
+	"/* End spinlock test & set */"
+	: "=&r"(ret), "=&r"(temp), "=m"(*spinlock)
+	: "m"(*spinlock)
+        : "memory");
+
+  return ret;
+}
+
+
+/* Begin allocating thread stacks at this address.  Default is to allocate
+   them just below the initial program stack.  */
+#define THREAD_STACK_START_ADDRESS  0x40000000000
+
+
+/* Return the thread descriptor for the current thread.  */
+#define THREAD_SELF \
+({									      \
+  register pthread_descr __self __asm__("$0");				      \
+  __asm__ ("call_pal %1" : "=r"(__self) : "i"(PAL_rduniq));		      \
+  __self;								      \
+})
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr) \
+{									      \
+  register pthread_descr __self __asm__("$16") = (descr);		      \
+  __asm__ __volatile__ ("call_pal %1" : : "r"(__self), "i"(PAL_wruniq));      \
+}
+
+
+/* Compare-and-swap for semaphores. */
+
+#define HAS_COMPARE_AND_SWAP
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  long int ret;
+
+  __asm__ __volatile__ (
+	"/* Inline compare & swap */\n"
+	"1:\t"
+	"ldq_l %0,%4\n\t"
+	"cmpeq %0,%2,%0\n\t"
+	"beq %0,2f\n\t"
+	"mov %3,%0\n\t"
+	"stq_c %0,%1\n\t"
+	"beq %0,1b\n\t"
+	"2:\tmb\n"
+	"/* End compare & swap */"
+	: "=&r"(ret), "=m"(*p)
+	: "r"(oldval), "r"(newval), "m"(*p)
+        : "memory");
+
+  return ret;
+}
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     32*1024*1024
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/alpha/tls.h b/linuxthreads/sysdeps/alpha/tls.h
new file mode 100644
index 0000000000..261d333eb4
--- /dev/null
+++ b/linuxthreads/sysdeps/alpha/tls.h
@@ -0,0 +1,129 @@
+/* Definitions for thread-local data handling.  linuxthreads/Alpha 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+
+typedef struct
+{
+  dtv_t *dtv;
+
+  /* Reserved for the thread implementation.  Unused in LinuxThreads.  */
+  void *private;
+} tcbhead_t;
+#endif
+
+
+#ifdef HAVE_TLS_SUPPORT
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+/* Get system call information.  */
+#  include <sysdep.h>
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN	__alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE		sizeof (tcbhead_t)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN		__alignof__ (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+#  define TLS_PRE_TCB_SIZE	sizeof (struct _pthread_descr_struct)
+
+/* The DTV is allocated at the TP; the TCB is placed elsewhere.  */
+#  define TLS_DTV_AT_TP 1
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(TCBP, DTVP) \
+  (((tcbhead_t *) (TCBP))->dtv = (DTVP) + 1)
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(DTV) \
+  (((tcbhead_t *)__builtin_thread_pointer ())->dtv = (DTV))
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(TCBP) \
+  (((tcbhead_t *) (TCBP))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(TCBP, SECONDCALL) \
+  (__builtin_set_thread_pointer (TCBP), 0)
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  (((tcbhead_t *)__builtin_thread_pointer ())->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+#  undef THREAD_SELF
+#  define THREAD_SELF \
+  ((pthread_descr)__builtin_thread_pointer () - 1)
+
+#  undef INIT_THREAD_SELF
+#  define INIT_THREAD_SELF(DESCR, NR) \
+  __builtin_set_thread_pointer ((struct _pthread_descr_struct *)(DESCR) + 1)
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+/* ??? Generic bits of LinuxThreads may call these macros with
+   DESCR set to NULL.  We are expected to be able to reference
+   the "current" value.
+
+   In our case, we'd really prefer to use DESCR, since lots of
+   PAL_code calls would be expensive.  We can only trust that
+   the compiler does its job and unifies the multiple
+   __builtin_thread_pointer instances.  */
+
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+
+# endif	/* HAVE_TLS_SUPPORT */
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/arm/pspinlock.c b/linuxthreads/sysdeps/arm/pspinlock.c
new file mode 100644
index 0000000000..665e270b69
--- /dev/null
+++ b/linuxthreads/sysdeps/arm/pspinlock.c
@@ -0,0 +1,82 @@
+/* POSIX spinlock implementation.  Arm version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  do
+    asm volatile ("swp %0, %1, [%2]"
+		  : "=r" (val)
+		  : "0" (1), "r" (lock)
+		  : "memory");
+  while (val != 0);
+
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  asm volatile ("swp %0, %1, [%2]"
+		: "=r" (val)
+		: "0" (1), "r" (lock)
+		: "memory");
+
+  return val ? EBUSY : 0;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/arm/pt-machine.h b/linuxthreads/sysdeps/arm/pt-machine.h
new file mode 100644
index 0000000000..a4c2f314cb
--- /dev/null
+++ b/linuxthreads/sysdeps/arm/pt-machine.h
@@ -0,0 +1,55 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   ARM version.
+   Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* This will not work on ARM1 or ARM2 because SWP is lacking on those
+   machines.  Unfortunately we have no way to detect this at compile
+   time; let's hope nobody tries to use one.  */
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  register unsigned int ret;
+
+  __asm__ __volatile__("swp %0, %1, [%2]"
+		       : "=r"(ret)
+		       : "0"(1), "r"(spinlock));
+
+  return ret;
+}
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("sp");
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/cris/pspinlock.c b/linuxthreads/sysdeps/cris/pspinlock.c
new file mode 100644
index 0000000000..402e838c00
--- /dev/null
+++ b/linuxthreads/sysdeps/cris/pspinlock.c
@@ -0,0 +1,72 @@
+/* POSIX spinlock implementation.  CRIS version.
+   Copyright (C) 2000, 2001 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+/* FIXME: These are just dummies.  I don't know why or if they're needed;
+   configury should default to these definitions.  We just follow the
+   crowd here.  */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  while (testandset (lock) != 0)
+    ;
+
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return testandset (lock) != 0 ? EBUSY : 0;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/cris/pt-machine.h b/linuxthreads/sysdeps/cris/pt-machine.h
new file mode 100644
index 0000000000..431da7101d
--- /dev/null
+++ b/linuxthreads/sysdeps/cris/pt-machine.h
@@ -0,0 +1,58 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   CRIS version.
+   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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+PT_EI long int
+testandset (int *spinlock)
+{
+  register unsigned long int ret;
+
+  /* Note the use of a dummy output of *spinlock to expose the write.  The
+     memory barrier is to stop *other* writes being moved past this code.  */
+  __asm__ __volatile__("clearf\n"
+		       "0:\n\t"
+		       "movu.b [%2],%0\n\t"
+		       "ax\n\t"
+		       "move.b %3,[%2]\n\t"
+		       "bwf 0b\n\t"
+		       "clearf"
+		       : "=&r" (ret), "=m" (*spinlock)
+		       : "r" (spinlock), "r" ((int) 1)
+		       : "memory");
+  return ret;
+}
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.
+   I don't trust register variables, so let's do this the safe way.  */
+#define CURRENT_STACK_FRAME \
+ ({ char *sp; __asm__ ("move.d $sp,%0" : "=rm" (sp)); sp; })
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/hppa/pspinlock.c b/linuxthreads/sysdeps/hppa/pspinlock.c
new file mode 100644
index 0000000000..7f481fa4b6
--- /dev/null
+++ b/linuxthreads/sysdeps/hppa/pspinlock.c
@@ -0,0 +1,81 @@
+/* POSIX spinlock implementation.  hppa version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  do
+    asm volatile ("ldcw %1,%0"
+		  : "=r" (val), "=m" (*lock)
+		  : "m" (*lock));
+  while (!val);
+
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  asm volatile ("ldcw %1,%0"
+		: "=r" (val), "=m" (*lock)
+		: "m" (*lock));
+
+  return val ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  *lock = 1;
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 1;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/hppa/pt-machine.h b/linuxthreads/sysdeps/hppa/pt-machine.h
new file mode 100644
index 0000000000..abc25c4ca4
--- /dev/null
+++ b/linuxthreads/sysdeps/hppa/pt-machine.h
@@ -0,0 +1,62 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   hppa version.
+   Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#include <bits/initspin.h>
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("%r30");
+
+
+/* The hppa only has one atomic read and modify memory operation,
+   load and clear, so hppa spinlocks must use zero to signify that
+   someone is holding the lock.  */
+
+#define xstr(s) str(s)
+#define str(s) #s
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  int ret;
+
+  __asm__ __volatile__(
+       "ldcw 0(%2),%0"
+       : "=r"(ret), "=m"(*spinlock)
+       : "r"(spinlock));
+
+  return ret == 0;
+}
+#undef str
+#undef xstr
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/i386/Makefile b/linuxthreads/sysdeps/i386/Makefile
new file mode 100644
index 0000000000..418fa5c6ef
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/Makefile
@@ -0,0 +1,23 @@
+ifeq ($(subdir),linuxthreads)
+# On i686 we must avoid generating the trampoline functions generated
+# to get the GOT pointer.
+CFLAGS-pt-initfini.s += -march=i386 -mcpu=i386
+
+# Most files must not be compiled without frame pointer since we need
+# the frame base address which is stored in %ebp unless the frame pointer
+# is optimized out.
+CFLAGS-cancel.c += -fno-omit-frame-pointer -mpreferred-stack-boundary=4
+CFLAGS-condvar.c += -fno-omit-frame-pointer
+CFLAGS-join.c += -fno-omit-frame-pointer
+CFLAGS-manager.c += -fno-omit-frame-pointer -mpreferred-stack-boundary=4
+CFLAGS-oldsemaphore.c += -fno-omit-frame-pointer
+CFLAGS-pthread.c += -fno-omit-frame-pointer -mpreferred-stack-boundary=4
+CFLAGS-ptlongjmp.c += -fno-omit-frame-pointer
+CFLAGS-semaphore.c += -fno-omit-frame-pointer
+CFLAGS-sighandler.c += -fno-omit-frame-pointer -mpreferred-stack-boundary=4
+CFLAGS-tst-align.c += -mpreferred-stack-boundary=4
+endif
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/i386/i586/Versions b/linuxthreads/sysdeps/i386/i586/Versions
new file mode 100644
index 0000000000..32da57080d
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/i586/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_PRIVATE {
+    __pthread_clock_gettime; __pthread_clock_settime;
+  }
+}
diff --git a/linuxthreads/sysdeps/i386/i686/Versions b/linuxthreads/sysdeps/i386/i686/Versions
new file mode 100644
index 0000000000..32da57080d
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/i686/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_PRIVATE {
+    __pthread_clock_gettime; __pthread_clock_settime;
+  }
+}
diff --git a/linuxthreads/sysdeps/i386/i686/pt-machine.h b/linuxthreads/sysdeps/i386/i686/pt-machine.h
new file mode 100644
index 0000000000..1c75bf9807
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/i686/pt-machine.h
@@ -0,0 +1,79 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   i686 version.
+   Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H	1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+#include "kernel-features.h"
+
+#ifndef __ASSEMBLER__
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  __builtin_frame_address (0)
+
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  long int ret;
+
+  __asm__ __volatile__ (
+	"xchgl %0, %1"
+	: "=r" (ret), "=m" (*spinlock)
+	: "0" (1), "m" (*spinlock)
+	: "memory");
+
+  return ret;
+}
+
+
+/* Compare-and-swap for semaphores.  It's always available on i686.  */
+#define HAS_COMPARE_AND_SWAP
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  char ret;
+  long int readval;
+
+  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+			: "=q" (ret), "=m" (*p), "=a" (readval)
+			: "r" (newval), "m" (*p), "a" (oldval)
+			: "memory");
+  return ret;
+}
+#endif
+
+#if __ASSUME_LDT_WORKS > 0
+#include "../useldt.h"
+#endif
+
+/* The P4 and above really want some help to prevent overheating.  */
+#define BUSY_WAIT_NOP	__asm__ ("rep; nop")
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/i386/pspinlock.c b/linuxthreads/sysdeps/i386/pspinlock.c
new file mode 100644
index 0000000000..6a70093957
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/pspinlock.c
@@ -0,0 +1,103 @@
+/* POSIX spinlock implementation.  x86 version.
+   Copyright (C) 2000, 2002 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+#include "kernel-features.h"
+
+
+/* This implementation is similar to the one used in the Linux kernel.
+   But the kernel is byte instructions for the memory access.  This is
+   faster but unusable here.  The problem is that only 128
+   threads/processes could use the spinlock at the same time.  If (by
+   a design error in the program) a thread/process would hold the
+   spinlock for a time long enough to accumulate 128 waiting
+   processes, the next one will find a positive value in the spinlock
+   and assume it is unlocked.  We cannot accept that.  */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("\n"
+     "1:\n\t"
+     "lock; decl %0\n\t"
+     "js 2f\n\t"
+     ".section .text.spinlock,\"ax\"\n"
+     "2:\n\t"
+     "cmpl $0,%0\n\t"
+     "rep; nop\n\t"
+     "jle 2b\n\t"
+     "jmp 1b\n\t"
+     ".previous"
+     : "=m" (*lock));
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int oldval;
+
+  asm volatile
+    ("xchgl %0,%1"
+     : "=r" (oldval), "=m" (*lock)
+     : "0" (0));
+  return oldval > 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("movl $1,%0"
+     : "=m" (*lock));
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 1;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
+
+#ifndef __ASSUME_SET_THREAD_AREA_SYSCALL
+int __have_no_set_thread_area;
+#endif
diff --git a/linuxthreads/sysdeps/i386/pt-machine.h b/linuxthreads/sysdeps/i386/pt-machine.h
new file mode 100644
index 0000000000..0df096d152
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/pt-machine.h
@@ -0,0 +1,108 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   i386 version.
+   Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H	1
+
+#ifndef __ASSEMBLER__
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  __builtin_frame_address (0)
+
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  long int ret;
+
+  __asm__ __volatile__(
+       "xchgl %0, %1"
+       : "=r"(ret), "=m"(*spinlock)
+       : "0"(1), "m"(*spinlock)
+       : "memory");
+
+  return ret;
+}
+
+
+/* Compare-and-swap for semaphores.
+   Available on the 486 and above, but not on the 386.
+   We test dynamically whether it's available or not. */
+
+#define HAS_COMPARE_AND_SWAP
+#define TEST_FOR_COMPARE_AND_SWAP
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  char ret;
+  long int readval;
+
+  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+			: "=q" (ret), "=m" (*p), "=a" (readval)
+			: "r" (newval), "m" (*p), "a" (oldval)
+			: "memory");
+  return ret;
+}
+
+
+PT_EI int
+get_eflags (void)
+{
+  int res;
+  __asm__ __volatile__ ("pushfl; popl %0" : "=r" (res) : );
+  return res;
+}
+
+
+PT_EI void
+set_eflags (int newflags)
+{
+  __asm__ __volatile__ ("pushl %0; popfl" : : "r" (newflags) : "cc");
+}
+
+
+PT_EI int
+compare_and_swap_is_available (void)
+{
+  int oldflags = get_eflags ();
+  int changed;
+  /* Flip AC bit in EFLAGS.  */
+  set_eflags (oldflags ^ 0x40000);
+  /* See if bit changed.  */
+  changed = (get_eflags () ^ oldflags) & 0x40000;
+  /* Restore EFLAGS.  */
+  set_eflags (oldflags);
+  /* If the AC flag did not change, it's a 386 and it lacks cmpxchg.
+     Otherwise, it's a 486 or above and it has cmpxchg.  */
+  return changed != 0;
+}
+#endif /* __ASSEMBLER__ */
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/i386/tcb-offsets.sym b/linuxthreads/sysdeps/i386/tcb-offsets.sym
new file mode 100644
index 0000000000..69a5018d88
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/tcb-offsets.sym
@@ -0,0 +1,7 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
+#ifdef NEED_DL_SYSINFO
+SYSINFO_OFFSET			offsetof (tcbhead_t, sysinfo)
+#endif
diff --git a/linuxthreads/sysdeps/i386/tls.h b/linuxthreads/sysdeps/i386/tls.h
new file mode 100644
index 0000000000..5306d082bb
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/tls.h
@@ -0,0 +1,225 @@
+/* Definition for thread-local data handling.  linuxthreads/i386 version.
+   Copyright (C) 2002, 2003, 2004 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 _TLS_H
+#define _TLS_H
+
+# include <dl-sysdep.h>
+# include <pt-machine.h>
+
+#ifndef __ASSEMBLER__
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+
+typedef struct
+{
+  void *tcb;		/* Pointer to the TCB.  Not necessary the
+			   thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;		/* Pointer to the thread descriptor.  */
+  int multiple_threads;
+#ifdef NEED_DL_SYSINFO
+  uintptr_t sysinfo;
+#endif
+} tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif
+
+/* We can support TLS only if the floating-stack support is available.
+   However, we want to compile in the support and test at runtime whether
+   the running kernel can support it or not.  To avoid bothering with the
+   TLS support code at all, use configure --without-tls.
+
+   We need USE_TLS to be consistently defined, for ldsodefs.h conditionals.
+   But some of the code below can cause problems in building libpthread
+   (e.g. useldt.h will defined FLOATING_STACKS when it shouldn't).  */
+
+#if defined HAVE_TLS_SUPPORT \
+    && (defined FLOATING_STACKS || !defined IS_IN_libpthread)
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+/* Get system call information.  */
+#  include <sysdep.h>
+
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+#  define TLS_TCB_AT_TP	1
+
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(descr, dtvp) \
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(dtv) \
+  ({ struct _pthread_descr_struct *__descr;				      \
+     THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); })
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+#  ifdef __PIC__
+#   define TLS_EBX_ARG "r"
+#   define TLS_LOAD_EBX "xchgl %3, %%ebx\n\t"
+#  else
+#   define TLS_EBX_ARG "b"
+#   define TLS_LOAD_EBX
+#  endif
+
+#  if !defined IS_IN_linuxthreads && !defined DO_MODIFY_LDT
+#   include "useldt.h"		/* For the structure.  */
+#  endif
+#  if __ASSUME_LDT_WORKS > 0
+#   define TLS_DO_MODIFY_LDT_KERNEL_CHECK(doit) (doit) /* Nothing to check.  */
+#  else
+#   define TLS_DO_MODIFY_LDT_KERNEL_CHECK(doit)				      \
+  (__builtin_expect (GLRO(dl_osversion) < 131939, 0)			      \
+   ? "kernel too old for thread-local storage support\n"			      \
+   : (doit))
+#  endif
+
+#  define TLS_DO_MODIFY_LDT(descr, nr)					      \
+TLS_DO_MODIFY_LDT_KERNEL_CHECK(						      \
+({									      \
+  struct modify_ldt_ldt_s ldt_entry =					      \
+    { nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */,	      \
+      1, 0, 0, 1, 0, 1, 0 };						      \
+  int result;								      \
+  asm volatile (TLS_LOAD_EBX						      \
+		"int $0x80\n\t"						      \
+		TLS_LOAD_EBX						      \
+		: "=a" (result)						      \
+		: "0" (__NR_modify_ldt),				      \
+		/* The extra argument with the "m" constraint is necessary    \
+		   to let the compiler know that we are accessing LDT_ENTRY   \
+		   here.  */						      \
+		"m" (ldt_entry), TLS_EBX_ARG (1), "c" (&ldt_entry),	      \
+		"d" (sizeof (ldt_entry)));				      \
+  __builtin_expect (result, 0) == 0					      \
+  ? ({ asm ("movw %w0, %%gs" : : "q" ((nr) * 8 + 7)); NULL; })		      \
+  : "cannot set up LDT for thread-local storage\n";			      \
+}))
+
+#  define TLS_DO_SET_THREAD_AREA(descr, secondcall)			      \
+({									      \
+  struct modify_ldt_ldt_s ldt_entry =					      \
+    { -1, (unsigned long int) (descr), 0xfffff /* 4GB in pages */,	      \
+      1, 0, 0, 1, 0, 1, 0 };						      \
+  int result;								      \
+  if (secondcall)							      \
+    ldt_entry.entry_number = ({ int _gs;				      \
+				asm ("movw %%gs, %w0" : "=q" (_gs));	      \
+				(_gs & 0xffff) >> 3; });		      \
+  asm volatile (TLS_LOAD_EBX						      \
+		"int $0x80\n\t"						      \
+		TLS_LOAD_EBX						      \
+		: "=a" (result), "=m" (ldt_entry.entry_number)		      \
+		: "0" (__NR_set_thread_area),				      \
+		/* The extra argument with the "m" constraint is necessary    \
+		   to let the compiler know that we are accessing LDT_ENTRY   \
+		   here.  */						      \
+		TLS_EBX_ARG (&ldt_entry), "m" (ldt_entry));		      \
+  if (__builtin_expect (result, 0) == 0)				      \
+    asm ("movw %w0, %%gs" : : "q" (ldt_entry.entry_number * 8 + 3));	      \
+  result;								      \
+})
+
+#  ifdef __ASSUME_SET_THREAD_AREA_SYSCALL
+#   define TLS_SETUP_GS_SEGMENT(descr, secondcall)			      \
+  (TLS_DO_SET_THREAD_AREA (descr, secondcall)				      \
+   ? "set_thread_area failed when setting up thread-local storage\n" : NULL)
+#  elif defined __NR_set_thread_area
+#   define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
+  (TLS_DO_SET_THREAD_AREA (descr, secondcall)				      \
+   ? TLS_DO_MODIFY_LDT (descr, 0) : NULL)
+#  else
+#   define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
+  TLS_DO_MODIFY_LDT ((descr), 0)
+#  endif
+
+#if defined NEED_DL_SYSINFO
+# define INIT_SYSINFO \
+  head->sysinfo = GLRO(dl_sysinfo)
+#else
+# define INIT_SYSINFO
+#endif
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.
+
+   The value of this macro is null if successful, or an error string.  */
+#  define TLS_INIT_TP(descr, secondcall)				      \
+  ({									      \
+    void *_descr = (descr);						      \
+    tcbhead_t *head = _descr;						      \
+									      \
+    head->tcb = _descr;							      \
+    /* For now the thread descriptor is at the same address.  */	      \
+    head->self = _descr;						      \
+									      \
+    INIT_SYSINFO;							      \
+    TLS_SETUP_GS_SEGMENT (_descr, secondcall);				      \
+  })
+
+/* Indicate that dynamic linker shouldn't try to initialize TLS even
+   when no PT_TLS segments are found in the program and libraries
+   it is linked against.  */
+#  define TLS_INIT_TP_EXPENSIVE 1
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  ({ struct _pthread_descr_struct *__descr;				      \
+     THREAD_GETMEM (__descr, p_header.data.dtvp); })
+
+# endif	/* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/i386/useldt.h b/linuxthreads/sysdeps/i386/useldt.h
new file mode 100644
index 0000000000..4ac82f1ab0
--- /dev/null
+++ b/linuxthreads/sysdeps/i386/useldt.h
@@ -0,0 +1,314 @@
+/* Special definitions for ix86 machine using segment register based
+   thread descriptor.
+   Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>.
+
+   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.	*/
+
+#ifndef __ASSEMBLER__
+#include <stddef.h>	/* For offsetof.  */
+#include <stdlib.h>	/* For abort().	 */
+#include <sysdep.h>
+
+
+/* We don't want to include the kernel header.	So duplicate the
+   information.	 */
+
+/* Structure passed on `modify_ldt' call.  */
+struct modify_ldt_ldt_s
+{
+  unsigned int entry_number;
+  unsigned long int base_addr;
+  unsigned int limit;
+  unsigned int seg_32bit:1;
+  unsigned int contents:2;
+  unsigned int read_exec_only:1;
+  unsigned int limit_in_pages:1;
+  unsigned int seg_not_present:1;
+  unsigned int useable:1;
+  unsigned int empty:25;
+};
+
+/* System call to set LDT entry.  */
+extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
+
+
+/* Return the thread descriptor for the current thread.
+
+   The contained asm must *not* be marked volatile since otherwise
+   assignments like
+	pthread_descr self = thread_self();
+   do not get optimized away.  */
+#define THREAD_SELF \
+({									      \
+  register pthread_descr __self;					      \
+  __asm__ ("movl %%gs:%c1,%0" : "=r" (__self)				      \
+	   : "i" (offsetof (struct _pthread_descr_struct,		      \
+			    p_header.data.self)));			      \
+  __self;								      \
+})
+
+
+/* Initialize the thread-unique value.	Two possible ways to do it.  */
+
+#define DO_MODIFY_LDT(descr, nr)					      \
+({									      \
+  struct modify_ldt_ldt_s ldt_entry =					      \
+    { nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */,	      \
+      1, 0, 0, 1, 0, 1, 0 };						      \
+  if (__modify_ldt (1, &ldt_entry, sizeof (ldt_entry)) != 0)		      \
+    abort ();								      \
+  asm ("movw %w0, %%gs" : : "q" (nr * 8 + 7));				      \
+})
+
+#ifdef __PIC__
+# define USETLS_EBX_ARG "r"
+# define USETLS_LOAD_EBX "xchgl %1, %%ebx\n\t"
+#else
+# define USETLS_EBX_ARG "b"
+# define USETLS_LOAD_EBX
+#endif
+
+/* When using the new set_thread_area call, we don't need to change %gs
+   because we inherited the value set up in the main thread by TLS setup.
+   We need to extract that value and set up the same segment in this
+   thread.  */
+#if USE_TLS
+# define DO_SET_THREAD_AREA_REUSE(nr)	1
+#else
+/* Without TLS, we do the initialization of the main thread, where NR == 0.  */
+# define DO_SET_THREAD_AREA_REUSE(nr)	(!__builtin_constant_p (nr) || (nr))
+#endif
+#define DO_SET_THREAD_AREA(descr, nr) \
+({									      \
+  int __gs;								      \
+  if (DO_SET_THREAD_AREA_REUSE (nr))					      \
+    {									      \
+      asm ("movw %%gs, %w0" : "=q" (__gs));				      \
+      struct modify_ldt_ldt_s ldt_entry =				      \
+	{ (__gs & 0xffff) >> 3,						      \
+	  (unsigned long int) (descr), 0xfffff /* 4GB in pages */,	      \
+	  1, 0, 0, 1, 0, 1, 0 };					      \
+									      \
+      int __result;							      \
+      __asm (USETLS_LOAD_EBX						      \
+	     "movl %2, %%eax\n\t"					      \
+	     "int $0x80\n\t"						      \
+	     USETLS_LOAD_EBX						      \
+	     : "=&a" (__result)						      \
+	     : USETLS_EBX_ARG (&ldt_entry), "i" (__NR_set_thread_area),	      \
+	       "m" (ldt_entry)						      \
+	     : "memory");						      \
+      if (__result == 0)						      \
+	asm ("movw %w0, %%gs" :: "q" (__gs));				      \
+      else								      \
+	__gs = -1;							      \
+    }									      \
+  else									      \
+    {									      \
+      struct modify_ldt_ldt_s ldt_entry =				      \
+	{ -1,								      \
+	  (unsigned long int) (descr), 0xfffff /* 4GB in pages */,	      \
+	  1, 0, 0, 1, 0, 1, 0 };					      \
+      int __result;							      \
+      __asm (USETLS_LOAD_EBX						      \
+	     "movl %2, %%eax\n\t"					      \
+	     "int $0x80\n\t"						      \
+	     USETLS_LOAD_EBX						      \
+	     : "=&a" (__result)						      \
+	     : USETLS_EBX_ARG (&ldt_entry), "i" (__NR_set_thread_area),	      \
+	       "m" (ldt_entry)						      \
+	     : "memory");						      \
+      if (__result == 0)						      \
+	{								      \
+	  __gs = (ldt_entry.entry_number << 3) + 3;			      \
+	  asm ("movw %w0, %%gs" : : "q" (__gs));			      \
+	}								      \
+      else								      \
+	__gs = -1;							      \
+    }									      \
+  __gs;									      \
+})
+
+#if defined __ASSUME_SET_THREAD_AREA_SYSCALL
+# define INIT_THREAD_SELF(descr, nr)	DO_SET_THREAD_AREA (descr, nr)
+#elif defined __NR_set_thread_area
+# define INIT_THREAD_SELF(descr, nr)					      \
+({									      \
+  if (__builtin_expect (__have_no_set_thread_area, 0)			      \
+      || (DO_SET_THREAD_AREA (descr, DO_SET_THREAD_AREA_REUSE (nr)) == -1     \
+	  && (__have_no_set_thread_area = 1)))				      \
+    DO_MODIFY_LDT (descr, nr);						      \
+})
+/* Defined in pspinlock.c.  */
+extern int __have_no_set_thread_area;
+#else
+# define INIT_THREAD_SELF(descr, nr)	DO_MODIFY_LDT (descr, nr)
+#endif
+
+/* Free resources associated with thread descriptor.  */
+#ifdef __ASSUME_SET_THREAD_AREA_SYSCALL
+#define FREE_THREAD(descr, nr) do { } while (0)
+#elif defined __NR_set_thread_area
+#define FREE_THREAD(descr, nr) \
+{									      \
+  int __gs;								      \
+  __asm__ __volatile__ ("movw %%gs, %w0" : "=q" (__gs));		      \
+  if (__builtin_expect (__gs & 4, 0))					      \
+    {									      \
+      struct modify_ldt_ldt_s ldt_entry =				      \
+	{ nr, 0, 0, 0, 0, 1, 0, 1, 0, 0 };				      \
+      __modify_ldt (1, &ldt_entry, sizeof (ldt_entry));			      \
+    }									      \
+}
+#else
+#define FREE_THREAD(descr, nr) \
+{									      \
+  struct modify_ldt_ldt_s ldt_entry =					      \
+    { nr, 0, 0, 0, 0, 1, 0, 1, 0, 0 };					      \
+  __modify_ldt (1, &ldt_entry, sizeof (ldt_entry));			      \
+}
+#endif
+
+/* Read member of the thread descriptor directly.  */
+#define THREAD_GETMEM(descr, member) \
+({									      \
+  __typeof__ (descr->member) __value;					      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %%gs:%P2,%b0"				      \
+			  : "=q" (__value)				      \
+			  : "0" (0),					      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %%gs:%P1,%0"				      \
+			  : "=r" (__value)				      \
+			  : "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movl %%gs:%P1,%%eax\n\t"			      \
+			    "movl %%gs:%P2,%%edx"			      \
+			    : "=A" (__value)				      \
+			    : "i" (offsetof (struct _pthread_descr_struct,    \
+					     member)),			      \
+			      "i" (offsetof (struct _pthread_descr_struct,    \
+					     member) + 4));		      \
+    }									      \
+  __value;								      \
+})
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+#define THREAD_GETMEM_NC(descr, member) \
+({									      \
+  __typeof__ (descr->member) __value;					      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %%gs:(%2),%b0"				      \
+			  : "=q" (__value)				      \
+			  : "0" (0),					      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %%gs:(%1),%0"				      \
+			  : "=r" (__value)				      \
+			  : "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movl %%gs:(%1),%%eax\n\t"			      \
+			    "movl %%gs:4(%1),%%edx"			      \
+			    : "=&A" (__value)				      \
+			    : "r" (offsetof (struct _pthread_descr_struct,    \
+					     member)));			      \
+    }									      \
+  __value;								      \
+})
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+#define THREAD_SETMEM(descr, member, value) \
+({									      \
+  __typeof__ (descr->member) __value = (value);				      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %0,%%gs:%P1" :				      \
+			  : "q" (__value),				      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %0,%%gs:%P1" :				      \
+			  : "r" (__value),				      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movl %%eax,%%gs:%P1\n\n"			      \
+			    "movl %%edx,%%gs:%P2" :			      \
+			    : "A" (__value),				      \
+			      "i" (offsetof (struct _pthread_descr_struct,    \
+					     member)),			      \
+			      "i" (offsetof (struct _pthread_descr_struct,    \
+					     member) + 4));		      \
+    }									      \
+})
+
+/* Set member of the thread descriptor directly.  */
+#define THREAD_SETMEM_NC(descr, member, value) \
+({									      \
+  __typeof__ (descr->member) __value = (value);				      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %0,%%gs:(%1)" :				      \
+			  : "q" (__value),				      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %0,%%gs:(%1)" :				      \
+			  : "r" (__value),				      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movl %%eax,%%gs:(%1)\n\t"			      \
+			    "movl %%edx,%%gs:4(%1)" :			      \
+			    : "A" (__value),				      \
+			      "r" (offsetof (struct _pthread_descr_struct,    \
+					     member)));			      \
+    }									      \
+})
+#endif
+
+#if __ASSUME_LDT_WORKS > 0
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS	1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE	8*1024*1024
+#endif
diff --git a/linuxthreads/sysdeps/ia64/Makefile b/linuxthreads/sysdeps/ia64/Makefile
new file mode 100644
index 0000000000..81bddf688c
--- /dev/null
+++ b/linuxthreads/sysdeps/ia64/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/ia64/Versions b/linuxthreads/sysdeps/ia64/Versions
new file mode 100644
index 0000000000..32da57080d
--- /dev/null
+++ b/linuxthreads/sysdeps/ia64/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_PRIVATE {
+    __pthread_clock_gettime; __pthread_clock_settime;
+  }
+}
diff --git a/linuxthreads/sysdeps/ia64/pspinlock.c b/linuxthreads/sysdeps/ia64/pspinlock.c
new file mode 100644
index 0000000000..14c7f3a181
--- /dev/null
+++ b/linuxthreads/sysdeps/ia64/pspinlock.c
@@ -0,0 +1,79 @@
+/* POSIX spinlock implementation.  ia64 version.
+   Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jes Sorensen <jes@linuxcare.com>
+
+   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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+#include <ia64intrin.h>
+
+/* This implementation is inspired by the implementation used in the
+   Linux kernel. */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  int *p = (int *) lock;
+  
+  while (__builtin_expect (__sync_val_compare_and_swap_si (p, 0, 1), 0))
+    {
+      /* Spin without using the atomic instruction.  */
+      do
+        __asm __volatile ("" : : : "memory");
+      while (*p);
+    }
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return __sync_val_compare_and_swap_si ((int *) lock, 0, 1) == 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/ia64/pt-machine.h b/linuxthreads/sysdeps/ia64/pt-machine.h
new file mode 100644
index 0000000000..6c5dfe93bb
--- /dev/null
+++ b/linuxthreads/sysdeps/ia64/pt-machine.h
@@ -0,0 +1,133 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   IA-64 version.
+   Copyright (C) 1999, 2000, 2002, 2003, 2004 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#include <ia64intrin.h>
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Make sure gcc doesn't try to be clever and move things around on
+   us. We need to use _exactly_ the address the user gave us, not some
+   alias that contains the same information.  */
+#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
+
+#ifndef ELF_MACHINE_NAME
+
+#define NEED_SEPARATE_REGISTER_STACK
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     32*1024*1024
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.
+   r12 (sp) is the stack pointer. */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char *stack_pointer __asm__ ("sp");
+
+
+/* Register r13 (tp) is reserved by the ABI as "thread pointer". */
+struct _pthread_descr_struct;
+register struct _pthread_descr_struct *__thread_self __asm__("r13");
+
+/* Return the thread descriptor for the current thread.  */
+#define THREAD_SELF  __thread_self
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr))
+
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+
+
+/* Memory barrier */
+#define MEMORY_BARRIER() __sync_synchronize ()
+
+
+#define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  long int readval;
+
+  __asm__ __volatile__
+       ("mov ar.ccv=%4;;\n\t"
+	"cmpxchg8.acq %0=%1,%2,ar.ccv"
+	: "=r" (readval), "=m" (__atomic_fool_gcc (p))
+	: "r"(newval), "m" (__atomic_fool_gcc (p)), "r" (oldval)
+	: "memory");
+  return readval == oldval;
+}
+
+PT_EI int
+__compare_and_swap_with_release_semantics (long int *p,
+					   long int oldval,
+					   long int newval)
+{
+  long int readval;
+
+  __asm__ __volatile__
+       ("mov ar.ccv=%4;;\n\t"
+	"cmpxchg8.rel %0=%1,%2,ar.ccv"
+	: "=r" (readval), "=m" (__atomic_fool_gcc (p))
+	: "r"(newval), "m" (__atomic_fool_gcc (p)), "r" (oldval)
+	: "memory");
+  return readval == oldval;
+}
+
+#endif /* ELF_MACHINE_NAME */
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  long int ret;
+
+  __asm__ __volatile__(
+       "xchg4 %0=%1,%2"
+       : "=r"(ret), "=m"(__atomic_fool_gcc (spinlock))
+       : "r"(1), "m"(__atomic_fool_gcc (spinlock))
+       : "memory");
+
+  return ret;
+}
+
+/* Indicate that we are looping.  */
+#define BUSY_WAIT_NOP	__asm__ ("hint @pause")
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/ia64/tcb-offsets.sym b/linuxthreads/sysdeps/ia64/tcb-offsets.sym
new file mode 100644
index 0000000000..f7793f7665
--- /dev/null
+++ b/linuxthreads/sysdeps/ia64/tcb-offsets.sym
@@ -0,0 +1,9 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+#ifdef USE_TLS
+MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads) - sizeof (struct _pthread_descr_struct)
+#else
+MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+#endif
diff --git a/linuxthreads/sysdeps/ia64/tls.h b/linuxthreads/sysdeps/ia64/tls.h
new file mode 100644
index 0000000000..3ec2eda783
--- /dev/null
+++ b/linuxthreads/sysdeps/ia64/tls.h
@@ -0,0 +1,141 @@
+/* Definitions for thread-local data handling.  linuxthreads/IA-64 version.
+   Copyright (C) 2002, 2003, 2004 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <dl-sysdep.h>
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+#ifdef HAVE_TLS_SUPPORT
+
+/* Signal that TLS support is available.  */
+# define USE_TLS        1
+
+# ifndef __ASSEMBLER__
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+#  define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+
+/* The DTV is allocated at the TP; the TCB is placed elsewhere.  */
+#  define TLS_DTV_AT_TP 1
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(DTV) \
+  (((tcbhead_t *)__thread_self)->dtv = (DTV))
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))->dtv)
+
+#if defined NEED_DL_SYSINFO
+# define INIT_SYSINFO \
+  (((tcbhead_t *) __thread_self)->private = (void *) GLRO(dl_sysinfo))
+#else
+# define INIT_SYSINFO 0
+#endif
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+#  define TLS_INIT_TP(tcbp, secondcall) \
+  (__thread_self = (__typeof (__thread_self)) (tcbp), INIT_SYSINFO, NULL)
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  (((tcbhead_t *)__thread_self)->dtv)
+
+/* Return the thread descriptor for the current thread.  */
+#  undef THREAD_SELF
+#  define THREAD_SELF (__thread_self - 1)
+
+#  undef INIT_THREAD_SELF
+#  define INIT_THREAD_SELF(descr, nr) \
+  (__thread_self = (struct _pthread_descr_struct *)(descr) + 1)
+
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+# endif
+
+#else
+
+# ifndef __ASSEMBLER__
+
+typedef struct
+{
+  void *tcb;
+  dtv_t *dtv;
+  void *self;
+  int multiple_threads;
+} tcbhead_t;
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+#  define NONTLS_INIT_TP \
+  do { 									\
+    static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };	\
+    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;		\
+  } while (0)
+
+#endif
+
+#endif /* USE_TLS */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/m68k/Makefile b/linuxthreads/sysdeps/m68k/Makefile
new file mode 100644
index 0000000000..1cd27d44ca
--- /dev/null
+++ b/linuxthreads/sysdeps/m68k/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(subdir), linuxthreads)
+object-suffixes-left := $(libpthread-nonshared)
+define o-iterator-doit
+$(objpfx)$o.os: pic-ccflag = -fPIC
+endef
+include $(o-iterator)
+endif
diff --git a/linuxthreads/sysdeps/m68k/pspinlock.c b/linuxthreads/sysdeps/m68k/pspinlock.c
new file mode 100644
index 0000000000..30b9b9e8b9
--- /dev/null
+++ b/linuxthreads/sysdeps/m68k/pspinlock.c
@@ -0,0 +1,82 @@
+/* POSIX spinlock implementation.  M68k version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  do
+    asm volatile ("tas %1; sne %0"
+		  : "=dm" (val), "=m" (*lock)
+		  : "m" (*lock)
+		  : "cc");
+  while (val);
+
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  asm volatile ("tas %1; sne %0"
+		: "=dm" (val), "=m" (*lock)
+		: "m" (*lock)
+		: "cc");
+
+  return val ? EBUSY : 0;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/m68k/pt-machine.h b/linuxthreads/sysdeps/m68k/pt-machine.h
new file mode 100644
index 0000000000..ad524d6d2e
--- /dev/null
+++ b/linuxthreads/sysdeps/m68k/pt-machine.h
@@ -0,0 +1,69 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   m68k version.
+   Copyright (C) 1996, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  char ret;
+
+  __asm__ __volatile__("tas %1; sne %0"
+       : "=dm"(ret), "=m"(*spinlock)
+       : "m"(*spinlock)
+       : "cc");
+
+  return ret;
+}
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("%sp");
+
+
+/* Compare-and-swap for semaphores. */
+
+#define HAS_COMPARE_AND_SWAP
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  char ret;
+  long int readval;
+
+  __asm__ __volatile__ ("casl %2, %3, %1; seq %0"
+			: "=dm" (ret), "=m" (*p), "=d" (readval)
+			: "d" (newval), "m" (*p), "2" (oldval));
+
+  return ret;
+}
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/mips/pspinlock.c b/linuxthreads/sysdeps/mips/pspinlock.c
new file mode 100644
index 0000000000..350aa7553c
--- /dev/null
+++ b/linuxthreads/sysdeps/mips/pspinlock.c
@@ -0,0 +1,98 @@
+/* POSIX spinlock implementation.  MIPS version.
+   Copyright (C) 2000, 2002, 2003, 2004 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; 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 <errno.h>
+#include <pthread.h>
+#include <sgidefs.h>
+#include <sys/tas.h>
+#include "internals.h"
+
+#include <sgidefs.h>
+
+/* This implementation is similar to the one used in the Linux kernel.  */
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  unsigned int tmp1, tmp2;
+
+  asm volatile
+    ("\t\t\t# spin_lock\n"
+     "1:\n\t"
+     ".set	push\n\t"
+#if _MIPS_SIM == _ABIO32
+     ".set	mips2\n\t"
+#endif
+     "ll	%1,%3\n\t"
+     "li	%2,1\n\t"
+     "bnez	%1,1b\n\t"
+     "sc	%2,%0\n\t"
+     ".set	pop\n\t"
+     "beqz	%2,1b"
+     : "=m" (*lock), "=&r" (tmp1), "=&r" (tmp2)
+     : "m" (*lock)
+     : "memory");
+
+  return 0;
+}
+
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  /* To be done.  */
+  return 0;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("\t\t\t# spin_unlock\n\t"
+     "sw	$0,%0"
+     : "=m" (*lock)
+     :
+     : "memory");
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/mips/pt-machine.h b/linuxthreads/sysdeps/mips/pt-machine.h
new file mode 100644
index 0000000000..96f7a7f8c6
--- /dev/null
+++ b/linuxthreads/sysdeps/mips/pt-machine.h
@@ -0,0 +1,92 @@
+/* Machine-dependent pthreads configuration and inline functions.
+
+   Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ralf Baechle <ralf@gnu.org>.
+   Based on the Alpha version by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#include <sgidefs.h>
+#include <sys/tas.h>
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+
+/* Spinlock implementation; required.  */
+
+PT_EI long int
+testandset (int *spinlock)
+{
+  return _test_and_set (spinlock, 1);
+}
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("$29");
+
+
+/* Compare-and-swap for semaphores. */
+
+#define HAS_COMPARE_AND_SWAP
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  long int ret, temp;
+
+  __asm__ __volatile__
+    ("/* Inline compare & swap */\n"
+     "1:\n\t"
+     ".set	push\n\t"
+#if _MIPS_SIM == _ABIO32
+     ".set	mips2\n\t"
+#endif
+#if _MIPS_SIM == _ABI64
+     "lld	%1,%5\n\t"
+#else
+     "ll	%1,%5\n\t"
+#endif
+     "move	%0,$0\n\t"
+     "bne	%1,%3,2f\n\t"
+     "move	%0,%4\n\t"
+#if _MIPS_SIM == _ABI64
+     "scd	%0,%2\n\t"
+#else
+     "sc	%0,%2\n\t"
+#endif
+     ".set	pop\n\t"
+     "beqz	%0,1b\n"
+     "2:\n\t"
+     "/* End compare & swap */"
+     : "=&r" (ret), "=&r" (temp), "=m" (*p)
+     : "r" (oldval), "r" (newval), "m" (*p)
+     : "memory");
+
+  return ret;
+}
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/powerpc/Makefile b/linuxthreads/sysdeps/powerpc/Makefile
new file mode 100644
index 0000000000..33e4aceb5b
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(subdir):$(elf),linuxthreads:yes)
+# See CFLAGS-initfini.s above; this is the same code.
+CFLAGS-pt-initfini.s = -g0 -fpic -O1
+endif
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/powerpc/powerpc32/pspinlock.c b/linuxthreads/sysdeps/powerpc/powerpc32/pspinlock.c
new file mode 100644
index 0000000000..15fd545c14
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/powerpc32/pspinlock.c
@@ -0,0 +1,70 @@
+/* POSIX spinlock implementation.  PowerPC version.
+   Copyright (C) 2000, 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  while (! __compare_and_swap ((long int *)lock, 0, 1))
+    ;
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return __compare_and_swap ((long int *)lock, 0, 1) ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  MEMORY_BARRIER ();
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/powerpc/powerpc32/pt-machine.h b/linuxthreads/sysdeps/powerpc/powerpc32/pt-machine.h
new file mode 100644
index 0000000000..8363d16d08
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/powerpc32/pt-machine.h
@@ -0,0 +1,120 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   powerpc version.
+   Copyright (C) 1996, 1997, 1998, 2000, 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; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* These routines are from Appendix G of the 'PowerPC 601 RISC Microprocessor
+   User's Manual', by IBM and Motorola.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* For multiprocessor systems, we want to ensure all memory accesses
+   are completed before we reset a lock.  On other systems, we still
+   need to make sure that the compiler has flushed everything to memory.  */
+#define MEMORY_BARRIER() __asm__ __volatile__ ("sync" : : : "memory")
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     8*1024*1024
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("r1");
+
+/* Register r2 (tp) is reserved by the ABI as "thread pointer". */
+struct _pthread_descr_struct;
+register struct _pthread_descr_struct *__thread_self __asm__("r2");
+
+/* Return the thread descriptor for the current thread.  */
+#define THREAD_SELF  __thread_self
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr))
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) (descr), THREAD_SELF->member = (value))
+
+/* Compare-and-swap for semaphores. */
+/* note that test-and-set(x) is the same as !compare-and-swap(x, 0, 1) */
+
+#define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
+#define IMPLEMENT_TAS_WITH_CAS
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  int ret;
+
+  __asm__ __volatile__ (
+	   "0:    lwarx %0,0,%1 ;"
+	   "      xor. %0,%3,%0;"
+	   "      bne 1f;"
+	   "      stwcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r"(newval), "r"(oldval)
+	: "cr0", "memory");
+  /* This version of __compare_and_swap is to be used when acquiring
+     a lock, so we don't need to worry about whether other memory
+     operations have completed, but we do need to be sure that any loads
+     after this point really occur after we have acquired the lock.  */
+  __asm__ __volatile__ ("isync" : : : "memory");
+  return ret == 0;
+}
+
+PT_EI int
+__compare_and_swap_with_release_semantics (long int *p,
+					   long int oldval, long int newval)
+{
+  int ret;
+
+  MEMORY_BARRIER ();
+  __asm__ __volatile__ (
+	   "0:    lwarx %0,0,%1 ;"
+	   "      xor. %0,%3,%0;"
+	   "      bne 1f;"
+	   "      stwcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r"(newval), "r"(oldval)
+	: "cr0", "memory");
+  return ret == 0;
+}
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/powerpc/powerpc64/pspinlock.c b/linuxthreads/sysdeps/powerpc/powerpc64/pspinlock.c
new file mode 100644
index 0000000000..19161c6e10
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/powerpc64/pspinlock.c
@@ -0,0 +1,70 @@
+/* POSIX spinlock implementation.  PowerPC version.
+   Copyright (C) 2000, 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  while (! __compare_and_swap32 ((int *)lock, 0, 1))
+    ;
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  return __compare_and_swap32 ((int *)lock, 0, 1) ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  MEMORY_BARRIER ();
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/powerpc/powerpc64/pt-machine.h b/linuxthreads/sysdeps/powerpc/powerpc64/pt-machine.h
new file mode 100644
index 0000000000..562e69fa18
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/powerpc64/pt-machine.h
@@ -0,0 +1,185 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   powerpc 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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.  */
+
+/* These routines are from Appendix G of the 'PowerPC 601 RISC Microprocessor
+   User's Manual', by IBM and Motorola.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+extern int __compare_and_swap32 (int *p, int oldval, int newval);
+
+/* For multiprocessor systems, we want to ensure all memory accesses
+   are completed before we reset a lock.  On other systems, we still
+   need to make sure that the compiler has flushed everything to memory.  */
+#define MEMORY_BARRIER() __asm__ __volatile__ ("lwsync" : : : "memory")
+#define READ_MEMORY_BARRIER() __asm__ __volatile__ ("lwsync" : : : "memory")
+#define WRITE_MEMORY_BARRIER() __asm__ __volatile__ ("eieio" : : : "memory")
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     16*1024*1024
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("r1");
+
+/* Register r13 (tp) is reserved by the ABI as "thread pointer". */
+struct _pthread_descr_struct;
+register struct _pthread_descr_struct *__thread_self __asm__("r13");
+
+/* Return the thread descriptor for the current thread.  */
+#define THREAD_SELF  __thread_self
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr))
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) (descr), THREAD_SELF->member = (value))
+
+/* Compare-and-swap for semaphores. */
+/* note that test-and-set(x) is the same as !compare-and-swap(x, 0, 1) */
+
+#define HAS_COMPARE_AND_SWAP
+#define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  long int ret;
+
+  __asm__ __volatile__ (
+	   "0:    ldarx %0,0,%1 ;"
+	   "      xor. %0,%3,%0;"
+	   "      bne 1f;"
+	   "      stdcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r"(newval), "r"(oldval)
+	: "cr0", "memory");
+  /* This version of __compare_and_swap is to be used when acquiring
+     a lock, so we don't need to worry about whether other memory
+     operations have completed, but we do need to be sure that any loads
+     after this point really occur after we have acquired the lock.  */
+  __asm__ __volatile__ ("isync" : : : "memory");
+  return (int)(ret == 0);
+}
+
+PT_EI int
+__compare_and_swap_with_release_semantics (long int *p,
+					   long int oldval, long int newval)
+{
+  long int ret;
+
+  MEMORY_BARRIER ();
+  __asm__ __volatile__ (
+	   "0:    ldarx %0,0,%1 ;"
+	   "      xor. %0,%3,%0;"
+	   "      bne 1f;"
+	   "      stdcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r"(newval), "r"(oldval)
+	: "cr0", "memory");
+  return (int)(ret == 0);
+}
+
+PT_EI int
+__compare_and_swap32 (int *p, int oldval, int newval)
+{
+  int ret;
+
+  __asm__ __volatile__ (
+	   "0:    lwarx %0,0,%1 ;"
+	   "      xor. %0,%3,%0;"
+	   "      bne 1f;"
+	   "      stwcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r"(newval), "r"(oldval)
+	: "cr0", "memory");
+  /* This version of __compare_and_swap is to be used when acquiring
+     a lock, so we don't need to worry about whether other memory
+     operations have completed, but we do need to be sure that any loads
+     after this point really occur after we have acquired the lock.  */
+  __asm__ __volatile__ ("isync" : : : "memory");
+  return (int)(ret == 0);
+}
+
+PT_EI int
+__compare_and_swap32_with_release_semantics (long int *p,
+					   long int oldval, long int newval)
+{
+  long int ret;
+
+  MEMORY_BARRIER ();
+  __asm__ __volatile__ (
+	   "0:    lwarx %0,0,%1 ;"
+	   "      xor. %0,%3,%0;"
+	   "      bne 1f;"
+	   "      stwcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r"(newval), "r"(oldval)
+	: "cr0", "memory");
+  return (int)(ret == 0);
+}
+
+PT_EI long int
+testandset (int *p)
+{
+  long int ret, val = 1;
+
+  MEMORY_BARRIER ();
+  __asm__ __volatile__ (
+	   "0:    lwarx %0,0,%1 ;"
+	   "      cmpwi  0,%0,0;"
+	   "      bne 1f;"
+	   "      stwcx. %2,0,%1;"
+	   "      bne- 0b;"
+	   "1:    "
+	: "=&r"(ret)
+	: "r"(p), "r" (val)
+	: "cr0", "memory");
+  MEMORY_BARRIER ();
+  return ret != 0;
+}
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/powerpc/tcb-offsets.sym b/linuxthreads/sysdeps/powerpc/tcb-offsets.sym
new file mode 100644
index 0000000000..b526b62336
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/tcb-offsets.sym
@@ -0,0 +1,19 @@
+#include <sysdep.h>
+#include <tls.h>
+
+-- This line separates the #include lines from conditionals.
+
+# ifdef USE_TLS
+
+-- Abuse tls.h macros to derive offsets relative to the thread register.
+#  undef __thread_register
+#  define __thread_register	((void *) 0)
+#  define thread_offsetof(mem)	((void *) &THREAD_SELF->p_##mem - (void *) 0)
+
+# else
+
+#  define thread_offsetof(mem)	offsetof (tcbhead_t, mem)
+
+# endif
+
+MULTIPLE_THREADS_OFFSET		thread_offsetof (multiple_threads)
diff --git a/linuxthreads/sysdeps/powerpc/tls.h b/linuxthreads/sysdeps/powerpc/tls.h
new file mode 100644
index 0000000000..f6eb48b434
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/tls.h
@@ -0,0 +1,160 @@
+/* Definitions for thread-local data handling.  linuxthreads/PPC version.
+   Copyright (C) 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+#ifdef HAVE_TLS_SUPPORT
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+
+/* This layout is actually wholly private and not affected by the ABI.
+   Nor does it overlap the pthread data structure, so we need nothing
+   extra here at all.  */
+typedef struct
+{
+  dtv_t *dtv;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE	0
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN	__alignof__ (struct _pthread_descr_struct)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE		0
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN		__alignof__ (struct _pthread_descr_struct)
+
+/* This is the size we need before TCB.  */
+#  define TLS_PRE_TCB_SIZE \
+  (sizeof (struct _pthread_descr_struct)				      \
+   + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
+
+/* The following assumes that TP (R2 or R13) is points to the end of the
+   TCB + 0x7000 (per the ABI).  This implies that TCB address is
+   TP - 0x7000.  As we define TLS_DTV_AT_TP we can
+   assume that the pthread_descr is allocated immediately ahead of the
+   TCB.  This implies that the pthread_descr address is
+   TP - (TLS_PRE_TCB_SIZE + 0x7000).  */
+#define TLS_TCB_OFFSET		0x7000
+
+/* The DTV is allocated at the TP; the TCB is placed elsewhere.  */
+/* This is not really true for powerpc64.  We are following alpha
+   where the DTV pointer is first doubleword in the TCB.  */
+#  define TLS_DTV_AT_TP 1
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(TCBP, DTVP) \
+  (((tcbhead_t *) (TCBP))[-1].dtv = (DTVP) + 1)
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(TCBP)	(((tcbhead_t *) (TCBP))[-1].dtv)
+
+/* We still need this define so that tcb-offsets.sym can override it and
+   use THREAD_SELF to generate MULTIPLE_THREADS_OFFSET.  */
+#  define __thread_register ((void *) __thread_self)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.
+   
+   The global register variable is declared in pt-machine.h with the 
+   wrong type, so we need some extra casts to get the desired result.  
+   This avoids a lvalue cast that gcc-3.4 does not like.  */
+# define TLS_INIT_TP(TCBP, SECONDCALL) \
+    (__thread_self = (struct _pthread_descr_struct *) \
+	((void *) (TCBP) + TLS_TCB_OFFSET), NULL)
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+     (((tcbhead_t *) ((void *) __thread_self - TLS_TCB_OFFSET))[-1].dtv)
+
+/* Return the thread descriptor for the current thread.  */
+#  undef THREAD_SELF
+#  define THREAD_SELF \
+    ((pthread_descr) (__thread_register \
+		      - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
+
+#  undef INIT_THREAD_SELF
+#  define INIT_THREAD_SELF(DESCR, NR) \
+     (__thread_self = (struct _pthread_descr_struct *)((void *) (DESCR) \
+		           + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE))
+
+/* Make sure we have the p_multiple_threads member in the thread structure.
+   See below.  */
+#  define TLS_MULTIPLE_THREADS_IN_TCB 1
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+/* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
+   different value to mean unset l_tls_offset.  */
+#  define NO_TLS_OFFSET	-1
+
+# endif /* __ASSEMBLER__ */
+
+#elif !defined __ASSEMBLER__
+
+/* This overlaps the start of the pthread_descr.  System calls
+   and such use this to find the multiple_threads flag and need
+   to use the same offset relative to the thread register in both
+   single-threaded and multi-threaded code.  */
+typedef struct
+{
+  void *tcb;			/* Never used.  */
+  dtv_t *dtv;			/* Never used.  */
+  void *self;			/* Used only if multithreaded, and rarely.  */
+  int multiple_threads;		/* Only this member is really used.  */
+} tcbhead_t;
+
+#define NONTLS_INIT_TP							\
+  do {									\
+    static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };	\
+    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;		\
+  } while (0)
+
+#endif /* HAVE_TLS_SUPPORT */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/pthread/Makefile b/linuxthreads/sysdeps/pthread/Makefile
new file mode 100644
index 0000000000..f73f40e9d9
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/Makefile
@@ -0,0 +1,14 @@
+ifeq ($(subdir),rt)
+librt-sysdep_routines += timer_routines
+CPPFLAGS += -DBROKEN_THREAD_SIGNALS
+
+ifeq (yes,$(build-shared))
+$(objpfx)tst-timer: $(objpfx)librt.so $(shared-thread-library)
+else
+$(objpfx)tst-timer: $(objpfx)librt.a $(static-thread-library)
+endif
+endif
+
+ifeq ($(subdir),posix)
+CFLAGS-confstr.c += -DLIBPTHREAD_VERSION="\"$(shell sed 's/\(.*\) by .*/\1/' ../linuxthreads/Banner)\""
+endif
diff --git a/linuxthreads/sysdeps/pthread/Subdirs b/linuxthreads/sysdeps/pthread/Subdirs
new file mode 100644
index 0000000000..2c56497842
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/Subdirs
@@ -0,0 +1 @@
+linuxthreads_db
diff --git a/linuxthreads/sysdeps/pthread/bits/initspin.h b/linuxthreads/sysdeps/pthread/bits/initspin.h
new file mode 100644
index 0000000000..a19ec077e8
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/bits/initspin.h
@@ -0,0 +1,28 @@
+/* Generic definitions for spinlock initializers.
+   Copyright (C) 2000, 2001 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Initial value of a spinlock.  Most platforms should use zero,
+   unless they only implement a "test and clear" operation instead of
+   the usual "test and set". */
+#define __LT_SPINLOCK_INIT 0
+
+/* Macros for lock initializers, using the above definition. */
+#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }
+#define __ALT_LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }
+#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_INIT }
diff --git a/linuxthreads/sysdeps/pthread/bits/libc-lock.h b/linuxthreads/sysdeps/pthread/bits/libc-lock.h
new file mode 100644
index 0000000000..7e22166862
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/bits/libc-lock.h
@@ -0,0 +1,413 @@
+/* libc-internal interface for mutex locks.  LinuxThreads version.
+   Copyright (C) 1996,1997,1998,1999,2000,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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _BITS_LIBC_LOCK_H
+#define _BITS_LIBC_LOCK_H 1
+
+#include <pthread.h>
+
+#if defined _LIBC && !defined NOT_IN_libc
+#include <linuxthreads/internals.h>
+#endif
+
+/* Mutex type.  */
+#if defined(_LIBC) || defined(_IO_MTSAFE_IO)
+typedef pthread_mutex_t __libc_lock_t;
+typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t;
+# ifdef __USE_UNIX98
+typedef pthread_rwlock_t __libc_rwlock_t;
+# else
+typedef struct __libc_rwlock_opaque__ __libc_rwlock_t;
+# endif
+typedef __libc_lock_recursive_t __rtld_lock_recursive_t;
+#else
+typedef struct __libc_lock_opaque__ __libc_lock_t;
+typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
+typedef struct __libc_rwlock_opaque__ __libc_rwlock_t;
+#endif
+
+/* Type for key to thread-specific data.  */
+typedef pthread_key_t __libc_key_t;
+
+/* Define a lock variable NAME with storage class CLASS.  The lock must be
+   initialized with __libc_lock_init before it can be used (or define it
+   with __libc_lock_define_initialized, below).  Use `extern' for CLASS to
+   declare a lock defined in another module.  In public structure
+   definitions you must use a pointer to the lock structure (i.e., NAME
+   begins with a `*'), because its storage size will not be known outside
+   of libc.  */
+#define __libc_lock_define(CLASS,NAME) \
+  CLASS __libc_lock_t NAME;
+#define __libc_rwlock_define(CLASS,NAME) \
+  CLASS __libc_rwlock_t NAME;
+#define __libc_lock_define_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME;
+#define __rtld_lock_define_recursive(CLASS,NAME) \
+  CLASS __rtld_lock_recursive_t NAME;
+
+/* Define an initialized lock variable NAME with storage class CLASS.
+
+   For the C library we take a deeper look at the initializer.  For
+   this implementation all fields are initialized to zero.  Therefore
+   we don't initialize the variable which allows putting it into the
+   BSS section.  (Except on PA-RISC and other odd architectures, where
+   initialized locks must be set to one due to the lack of normal
+   atomic operations.) */
+
+#if __LT_SPINLOCK_INIT == 0
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME;
+#else
+#  define __libc_lock_define_initialized(CLASS,NAME) \
+  CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+#define __libc_rwlock_define_initialized(CLASS,NAME) \
+  CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER;
+
+/* Define an initialized recursive lock variable NAME with storage
+   class CLASS.  */
+#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+#define _LIBC_LOCK_RECURSIVE_INITIALIZER \
+  {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
+
+#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __rtld_lock_recursive_t NAME = _RTLD_LOCK_RECURSIVE_INITIALIZER;
+#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
+  {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
+
+#if defined _LIBC && defined IS_IN_libpthread
+# define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS
+#else
+# if defined __PIC__ || (defined _LIBC && defined SHARED)
+#  define __libc_maybe_call(FUNC, ARGS, ELSE) \
+  (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
+                    _fn != NULL ? (*_fn) ARGS : ELSE; }))
+# else
+#  define __libc_maybe_call(FUNC, ARGS, ELSE) \
+  (FUNC != NULL ? FUNC ARGS : ELSE)
+# endif
+#endif
+#if defined _LIBC && !defined NOT_IN_libc && defined SHARED
+# define __libc_maybe_call2(FUNC, ARGS, ELSE) \
+  ({__builtin_expect (__libc_pthread_functions.ptr_##FUNC != NULL, 0) \
+    ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })
+#else
+# define __libc_maybe_call2(FUNC, ARGS, ELSE) __libc_maybe_call (__##FUNC, ARGS, ELSE)
+#endif
+
+/* Initialize the named lock variable, leaving it in a consistent, unlocked
+   state.  */
+#if defined _LIBC && !defined NOT_IN_libc && defined SHARED
+#define __libc_lock_init(NAME) \
+  ({									      \
+    (NAME).__m_count = 0;						      \
+    (NAME).__m_owner = NULL;						      \
+    (NAME).__m_kind = PTHREAD_MUTEX_TIMED_NP;				      \
+    (NAME).__m_lock.__status = 0;					      \
+    (NAME).__m_lock.__spinlock = __LT_SPINLOCK_INIT;			      \
+    0; })
+#else
+#define __libc_lock_init(NAME) \
+  (__libc_maybe_call2 (pthread_mutex_init, (&(NAME), NULL), 0))
+#endif
+#define __libc_rwlock_init(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0));
+
+/* Same as last but this time we initialize a recursive mutex.  */
+#if defined _LIBC && !defined NOT_IN_libc && defined SHARED
+#define __libc_lock_init_recursive(NAME) \
+  ({									      \
+    (NAME).mutex.__m_count = 0;						      \
+    (NAME).mutex.__m_owner = NULL;					      \
+    (NAME).mutex.__m_kind = PTHREAD_MUTEX_RECURSIVE_NP;			      \
+    (NAME).mutex.__m_lock.__status = 0;					      \
+    (NAME).mutex.__m_lock.__spinlock = __LT_SPINLOCK_INIT;		      \
+    0; })
+#else
+#define __libc_lock_init_recursive(NAME) \
+  do {									      \
+    if (__pthread_mutex_init != NULL)					      \
+      {									      \
+	pthread_mutexattr_t __attr;					      \
+	__pthread_mutexattr_init (&__attr);				      \
+	__pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \
+	__pthread_mutex_init (&(NAME).mutex, &__attr);			      \
+	__pthread_mutexattr_destroy (&__attr);				      \
+      }									      \
+  } while (0);
+#endif
+#define __rtld_lock_init_recursive(NAME) \
+  __libc_lock_init_recursive (NAME)
+
+/* Finalize the named lock variable, which must be locked.  It cannot be
+   used again until __libc_lock_init is called again on it.  This must be
+   called on a lock variable before the containing storage is reused.  */
+#define __libc_lock_fini(NAME) \
+  (__libc_maybe_call2 (pthread_mutex_destroy, (&(NAME)), 0));
+#define __libc_rwlock_fini(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_destroy, (&(NAME)), 0));
+
+/* Finalize recursive named lock.  */
+#define __libc_lock_fini_recursive(NAME) __libc_lock_fini ((NAME).mutex)
+#define __rtld_lock_fini_recursive(NAME) __libc_lock_fini_recursive (NAME)
+
+/* Lock the named lock variable.  */
+#define __libc_lock_lock(NAME) \
+  (__libc_maybe_call2 (pthread_mutex_lock, (&(NAME)), 0));
+#define __libc_rwlock_rdlock(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_rdlock, (&(NAME)), 0));
+#define __libc_rwlock_wrlock(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_wrlock, (&(NAME)), 0));
+
+/* Lock the recursive named lock variable.  */
+#define __libc_lock_lock_recursive(NAME) __libc_lock_lock ((NAME).mutex)
+
+/* Try to lock the named lock variable.  */
+#define __libc_lock_trylock(NAME) \
+  (__libc_maybe_call2 (pthread_mutex_trylock, (&(NAME)), 0))
+#define __libc_rwlock_tryrdlock(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_tryrdlock, (&(NAME)), 0))
+#define __libc_rwlock_trywrlock(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_trywrlock, (&(NAME)), 0))
+
+/* Try to lock the recursive named lock variable.  */
+#define __libc_lock_trylock_recursive(NAME) __libc_lock_trylock ((NAME).mutex)
+#define __rtld_lock_trylock_recursive(NAME) \
+  __libc_lock_trylock_recursive (NAME)
+
+/* Unlock the named lock variable.  */
+#define __libc_lock_unlock(NAME) \
+  (__libc_maybe_call2 (pthread_mutex_unlock, (&(NAME)), 0));
+#define __libc_rwlock_unlock(NAME) \
+  (__libc_maybe_call (__pthread_rwlock_unlock, (&(NAME)), 0));
+
+/* Unlock the recursive named lock variable.  */
+#define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock ((NAME).mutex)
+
+#if defined _LIBC && defined SHARED
+# define __rtld_lock_default_lock_recursive(lock) \
+  ++((pthread_mutex_t *)(lock))->__m_count;
+
+# define __rtld_lock_default_unlock_recursive(lock) \
+  --((pthread_mutex_t *)(lock))->__m_count;
+
+# define __rtld_lock_lock_recursive(NAME) \
+  GL(dl_rtld_lock_recursive) (&(NAME).mutex)
+
+# define __rtld_lock_unlock_recursive(NAME) \
+  GL(dl_rtld_unlock_recursive) (&(NAME).mutex)
+#else
+#define __rtld_lock_lock_recursive(NAME) __libc_lock_lock_recursive (NAME)
+#define __rtld_lock_unlock_recursive(NAME) __libc_lock_unlock_recursive (NAME)
+#endif
+
+/* Define once control variable.  */
+#if PTHREAD_ONCE_INIT == 0
+/* Special case for static variables where we can avoid the initialization
+   if it is zero.  */
+# define __libc_once_define(CLASS, NAME) \
+  CLASS pthread_once_t NAME
+#else
+# define __libc_once_define(CLASS, NAME) \
+  CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
+#endif
+
+/* Call handler iff the first call.  */
+#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
+  do {									      \
+    if (__pthread_once != NULL)						      \
+      __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION));		      \
+    else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) {			      \
+      INIT_FUNCTION ();							      \
+      (ONCE_CONTROL) = 2;						      \
+    }									      \
+  } while (0)
+
+
+/* Start critical region with cleanup.  */
+#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
+  { struct _pthread_cleanup_buffer _buffer;				      \
+    int _avail = (DOIT) && _pthread_cleanup_push_defer != NULL;		      \
+    if (_avail) {							      \
+      _pthread_cleanup_push_defer (&_buffer, (FCT), (ARG));		      \
+    }
+
+/* End critical region with cleanup.  */
+#define __libc_cleanup_region_end(DOIT) \
+    if (_avail) {							      \
+      _pthread_cleanup_pop_restore (&_buffer, (DOIT));			      \
+    }									      \
+  }
+
+/* Sometimes we have to exit the block in the middle.  */
+#define __libc_cleanup_end(DOIT) \
+    if (_avail) {							      \
+      _pthread_cleanup_pop_restore (&_buffer, (DOIT));			      \
+    }
+
+#define __libc_cleanup_push(fct, arg) \
+    { struct _pthread_cleanup_buffer _buffer; 				      \
+    __libc_maybe_call (_pthread_cleanup_push, (&_buffer, (fct), (arg)), 0)
+
+#define __libc_cleanup_pop(execute) \
+    __libc_maybe_call (_pthread_cleanup_pop, (&_buffer, execute), 0);	      \
+    }
+
+/* Create thread-specific key.  */
+#define __libc_key_create(KEY, DESTRUCTOR) \
+  (__libc_maybe_call (__pthread_key_create, (KEY, DESTRUCTOR), 1))
+
+/* Get thread-specific data.  */
+#define __libc_getspecific(KEY) \
+  (__libc_maybe_call (__pthread_getspecific, (KEY), NULL))
+
+/* Set thread-specific data.  */
+#define __libc_setspecific(KEY, VALUE) \
+  (__libc_maybe_call (__pthread_setspecific, (KEY, VALUE), 0))
+
+
+/* Register handlers to execute before and after `fork'.  */
+#define __libc_atfork(PREPARE, PARENT, CHILD) \
+  (__libc_maybe_call (__pthread_atfork, (PREPARE, PARENT, CHILD), 0))
+
+/* Functions that are used by this file and are internal to the GNU C
+   library.  */
+
+extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
+				 __const pthread_mutexattr_t *__mutex_attr);
+
+extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+
+extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr);
+
+extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr,
+					int __kind);
+
+#ifdef __USE_UNIX98
+extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock,
+				  __const pthread_rwlockattr_t *__attr);
+
+extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);
+
+extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);
+#endif
+
+extern int __pthread_key_create (pthread_key_t *__key,
+				 void (*__destr_function) (void *));
+
+extern int __pthread_setspecific (pthread_key_t __key,
+				  __const void *__pointer);
+
+extern void *__pthread_getspecific (pthread_key_t __key);
+
+extern int __pthread_once (pthread_once_t *__once_control,
+			   void (*__init_routine) (void));
+
+extern int __pthread_atfork (void (*__prepare) (void),
+			     void (*__parent) (void),
+			     void (*__child) (void));
+
+
+
+/* Make the pthread functions weak so that we can elide them from
+   single-threaded processes.  */
+#ifndef __NO_WEAK_PTHREAD_ALIASES
+# ifdef weak_extern
+#  if _LIBC
+#   include <bp-sym.h>
+#  else
+#   define BP_SYM (sym) sym
+#  endif
+weak_extern (BP_SYM (__pthread_mutex_init))
+weak_extern (BP_SYM (__pthread_mutex_destroy))
+weak_extern (BP_SYM (__pthread_mutex_lock))
+weak_extern (BP_SYM (__pthread_mutex_trylock))
+weak_extern (BP_SYM (__pthread_mutex_unlock))
+weak_extern (BP_SYM (__pthread_mutexattr_init))
+weak_extern (BP_SYM (__pthread_mutexattr_destroy))
+weak_extern (BP_SYM (__pthread_mutexattr_settype))
+weak_extern (BP_SYM (__pthread_rwlock_init))
+weak_extern (BP_SYM (__pthread_rwlock_destroy))
+weak_extern (BP_SYM (__pthread_rwlock_rdlock))
+weak_extern (BP_SYM (__pthread_rwlock_tryrdlock))
+weak_extern (BP_SYM (__pthread_rwlock_wrlock))
+weak_extern (BP_SYM (__pthread_rwlock_trywrlock))
+weak_extern (BP_SYM (__pthread_rwlock_unlock))
+weak_extern (BP_SYM (__pthread_key_create))
+weak_extern (BP_SYM (__pthread_setspecific))
+weak_extern (BP_SYM (__pthread_getspecific))
+weak_extern (BP_SYM (__pthread_once))
+weak_extern (__pthread_initialize)
+weak_extern (__pthread_atfork)
+weak_extern (BP_SYM (_pthread_cleanup_push))
+weak_extern (BP_SYM (_pthread_cleanup_pop))
+weak_extern (BP_SYM (_pthread_cleanup_push_defer))
+weak_extern (BP_SYM (_pthread_cleanup_pop_restore))
+# else
+#  pragma weak __pthread_mutex_init
+#  pragma weak __pthread_mutex_destroy
+#  pragma weak __pthread_mutex_lock
+#  pragma weak __pthread_mutex_trylock
+#  pragma weak __pthread_mutex_unlock
+#  pragma weak __pthread_mutexattr_init
+#  pragma weak __pthread_mutexattr_destroy
+#  pragma weak __pthread_mutexattr_settype
+#  pragma weak __pthread_rwlock_destroy
+#  pragma weak __pthread_rwlock_rdlock
+#  pragma weak __pthread_rwlock_tryrdlock
+#  pragma weak __pthread_rwlock_wrlock
+#  pragma weak __pthread_rwlock_trywrlock
+#  pragma weak __pthread_rwlock_unlock
+#  pragma weak __pthread_key_create
+#  pragma weak __pthread_setspecific
+#  pragma weak __pthread_getspecific
+#  pragma weak __pthread_once
+#  pragma weak __pthread_initialize
+#  pragma weak __pthread_atfork
+#  pragma weak _pthread_cleanup_push_defer
+#  pragma weak _pthread_cleanup_pop_restore
+#  pragma weak _pthread_cleanup_push
+#  pragma weak _pthread_cleanup_pop
+# endif
+#endif
+
+/* We need portable names for some functions.  E.g., when they are
+   used as argument to __libc_cleanup_region_start.  */
+#define __libc_mutex_unlock __pthread_mutex_unlock
+
+#endif	/* bits/libc-lock.h */
diff --git a/linuxthreads/sysdeps/pthread/bits/libc-tsd.h b/linuxthreads/sysdeps/pthread/bits/libc-tsd.h
new file mode 100644
index 0000000000..fa6eb4be28
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/bits/libc-tsd.h
@@ -0,0 +1,59 @@
+/* libc-internal interface for thread-specific data.  LinuxThreads version.
+   Copyright (C) 1997-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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _BITS_LIBC_TSD_H
+#define _BITS_LIBC_TSD_H 1
+
+#include <linuxthreads/descr.h>
+#include <tls.h>
+
+#if USE_TLS && HAVE___THREAD
+
+/* When __thread works, the generic definition is what we want.  */
+# include <sysdeps/generic/bits/libc-tsd.h>
+
+#else
+
+# include <bits/libc-lock.h>
+
+# ifndef SHARED
+extern void ** __pthread_internal_tsd_address (int);
+extern void *__pthread_internal_tsd_get (int);
+extern int __pthread_internal_tsd_set (int, const void *);
+
+weak_extern (__pthread_internal_tsd_address)
+weak_extern (__pthread_internal_tsd_get)
+weak_extern (__pthread_internal_tsd_set)
+# endif
+
+#define __libc_tsd_define(CLASS, KEY)	CLASS void *__libc_tsd_##KEY##_data;
+#define __libc_tsd_address(KEY) \
+  __libc_maybe_call2 (pthread_internal_tsd_address,			\
+		      (_LIBC_TSD_KEY_##KEY), &__libc_tsd_##KEY##_data)
+#define __libc_tsd_get(KEY) \
+  __libc_maybe_call2 (pthread_internal_tsd_get,				\
+		      (_LIBC_TSD_KEY_##KEY), __libc_tsd_##KEY##_data)
+#define __libc_tsd_set(KEY, VALUE) \
+  __libc_maybe_call2 (pthread_internal_tsd_set,				\
+		      (_LIBC_TSD_KEY_##KEY, (VALUE)),			\
+		       (__libc_tsd_##KEY##_data = (VALUE), 0))
+
+#endif
+
+#endif	/* bits/libc-tsd.h */
diff --git a/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h b/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
new file mode 100644
index 0000000000..d1daef07aa
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
@@ -0,0 +1,152 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix        */
+/* threads for Linux.                                                   */
+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
+/*                                                                      */
+/* This program is free software; you can redistribute it and/or        */
+/* modify it under the terms of the GNU Library General Public License  */
+/* as published by the Free Software Foundation; either version 2       */
+/* of the License, or (at your option) any later version.               */
+/*                                                                      */
+/* This program 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 Library General Public License for more details.                 */
+
+#if !defined _BITS_TYPES_H && !defined _PTHREAD_H
+# error "Never include <bits/pthreadtypes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H	1
+
+#define __need_schedparam
+#include <bits/sched.h>
+
+/* Fast locks (not abstract because mutexes and conditions aren't abstract). */
+struct _pthread_fastlock
+{
+  long int __status;   /* "Free" or "taken" or head of waiting list */
+  int __spinlock;      /* Used by compare_and_swap emulation. Also,
+			  adaptive SMP lock stores spin count here. */
+};
+
+#ifndef _PTHREAD_DESCR_DEFINED
+/* Thread descriptors */
+typedef struct _pthread_descr_struct *_pthread_descr;
+# define _PTHREAD_DESCR_DEFINED
+#endif
+
+
+/* Attributes for threads.  */
+typedef struct __pthread_attr_s
+{
+  int __detachstate;
+  int __schedpolicy;
+  struct __sched_param __schedparam;
+  int __inheritsched;
+  int __scope;
+  size_t __guardsize;
+  int __stackaddr_set;
+  void *__stackaddr;
+  size_t __stacksize;
+} pthread_attr_t;
+
+
+/* Conditions (not abstract because of PTHREAD_COND_INITIALIZER */
+
+#ifdef __GLIBC_HAVE_LONG_LONG
+__extension__ typedef long long __pthread_cond_align_t;
+#else
+typedef long __pthread_cond_align_t;
+#endif
+
+typedef struct
+{
+  struct _pthread_fastlock __c_lock; /* Protect against concurrent access */
+  _pthread_descr __c_waiting;        /* Threads waiting on this condition */
+  char __padding[48 - sizeof (struct _pthread_fastlock)
+		 - sizeof (_pthread_descr) - sizeof (__pthread_cond_align_t)];
+  __pthread_cond_align_t __align;
+} pthread_cond_t;
+
+
+/* Attribute for conditionally variables.  */
+typedef struct
+{
+  int __dummy;
+} pthread_condattr_t;
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER).  */
+/* (The layout is unnatural to maintain binary compatibility
+    with earlier releases of LinuxThreads.) */
+typedef struct
+{
+  int __m_reserved;               /* Reserved for future use */
+  int __m_count;                  /* Depth of recursive locking */
+  _pthread_descr __m_owner;       /* Owner thread (if recursive or errcheck) */
+  int __m_kind;                   /* Mutex kind: fast, recursive or errcheck */
+  struct _pthread_fastlock __m_lock; /* Underlying fast lock */
+} pthread_mutex_t;
+
+
+/* Attribute for mutex.  */
+typedef struct
+{
+  int __mutexkind;
+} pthread_mutexattr_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Read-write locks.  */
+typedef struct _pthread_rwlock_t
+{
+  struct _pthread_fastlock __rw_lock; /* Lock to guarantee mutual exclusion */
+  int __rw_readers;                   /* Number of readers */
+  _pthread_descr __rw_writer;         /* Identity of writer, or NULL if none */
+  _pthread_descr __rw_read_waiting;   /* Threads waiting for reading */
+  _pthread_descr __rw_write_waiting;  /* Threads waiting for writing */
+  int __rw_kind;                      /* Reader/Writer preference selection */
+  int __rw_pshared;                   /* Shared between processes or not */
+} pthread_rwlock_t;
+
+
+/* Attribute for read-write locks.  */
+typedef struct
+{
+  int __lockkind;
+  int __pshared;
+} pthread_rwlockattr_t;
+#endif
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type.  */
+typedef volatile int pthread_spinlock_t;
+
+/* POSIX barrier. */
+typedef struct {
+  struct _pthread_fastlock __ba_lock; /* Lock to guarantee mutual exclusion */
+  int __ba_required;                  /* Threads needed for completion */
+  int __ba_present;                   /* Threads waiting */
+  _pthread_descr __ba_waiting;        /* Queue of waiting threads */
+} pthread_barrier_t;
+
+/* barrier attribute */
+typedef struct {
+  int __pshared;
+} pthread_barrierattr_t;
+
+#endif
+
+
+/* Thread identifiers */
+typedef unsigned long int pthread_t;
+
+#endif	/* bits/pthreadtypes.h */
diff --git a/linuxthreads/sysdeps/pthread/bits/typesizes.h b/linuxthreads/sysdeps/pthread/bits/typesizes.h
new file mode 100644
index 0000000000..45264ac9cf
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t.  Generic 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 _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef	_BITS_TYPESIZES_H
+#define	_BITS_TYPESIZES_H	1
+
+/* See <bits/types.h> for the meaning of these macros.  This file exists so
+   that <bits/types.h> need not vary across different GNU platforms.  */
+
+#define __DEV_T_TYPE		__UQUAD_TYPE
+#define __UID_T_TYPE		__U32_TYPE
+#define __GID_T_TYPE		__U32_TYPE
+#define __INO_T_TYPE		__ULONGWORD_TYPE
+#define __INO64_T_TYPE		__UQUAD_TYPE
+#define __MODE_T_TYPE		__U32_TYPE
+#define __NLINK_T_TYPE		__UWORD_TYPE
+#define __OFF_T_TYPE		__SLONGWORD_TYPE
+#define __OFF64_T_TYPE		__SQUAD_TYPE
+#define __PID_T_TYPE		__S32_TYPE
+#define __RLIM_T_TYPE		__ULONGWORD_TYPE
+#define __RLIM64_T_TYPE		__UQUAD_TYPE
+#define	__BLKCNT_T_TYPE		__SLONGWORD_TYPE
+#define	__BLKCNT64_T_TYPE	__SQUAD_TYPE
+#define	__FSBLKCNT_T_TYPE	__ULONGWORD_TYPE
+#define	__FSBLKCNT64_T_TYPE	__UQUAD_TYPE
+#define	__FSFILCNT_T_TYPE	__ULONGWORD_TYPE
+#define	__FSFILCNT64_T_TYPE	__UQUAD_TYPE
+#define	__ID_T_TYPE		__U32_TYPE
+#define __CLOCK_T_TYPE		__SLONGWORD_TYPE
+#define __TIME_T_TYPE		__SLONGWORD_TYPE
+#define __USECONDS_T_TYPE	__U32_TYPE
+#define __SUSECONDS_T_TYPE	__SLONGWORD_TYPE
+#define __DADDR_T_TYPE		__S32_TYPE
+#define __SWBLK_T_TYPE		__SLONGWORD_TYPE
+#define __KEY_T_TYPE		__S32_TYPE
+#define __CLOCKID_T_TYPE	__S32_TYPE
+#define __TIMER_T_TYPE		__S32_TYPE
+#define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE
+#define __FSID_T_TYPE		struct { int __val[2]; }
+#define __SSIZE_T_TYPE		__SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'.  */
+#define	__FD_SETSIZE		1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/linuxthreads/sysdeps/pthread/errno-loc.c b/linuxthreads/sysdeps/pthread/errno-loc.c
new file mode 100644
index 0000000000..0a8f0f9076
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/errno-loc.c
@@ -0,0 +1,46 @@
+/* MT support function to get address of `errno' variable, linuxthreads
+   version.
+   Copyright (C) 1996, 1998, 2002, 2003, 2004 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 <errno.h>
+#include <tls.h>
+#include <linuxthreads/internals.h>
+#include <sysdep-cancel.h>
+
+#if ! USE___THREAD && !RTLD_PRIVATE_ERRNO
+#undef errno
+extern int errno;
+#endif
+
+int *
+#if ! USE___THREAD
+weak_const_function
+#endif
+__errno_location (void)
+{
+#if ! USE___THREAD && !defined NOT_IN_libc
+  if (! SINGLE_THREAD_P)
+    {
+      pthread_descr self = thread_self();
+      return LIBC_THREAD_GETMEM (self, p_errnop);
+    }
+#endif
+  return &errno;
+}
+libc_hidden_def (__errno_location)
diff --git a/linuxthreads/sysdeps/pthread/flockfile.c b/linuxthreads/sysdeps/pthread/flockfile.c
new file mode 100644
index 0000000000..918cb84f61
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/flockfile.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 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 <pthread.h>
+#include <stdio.h>
+#include <libio.h>
+#include <bits/stdio-lock.h>
+
+
+void
+__flockfile (stream)
+     FILE *stream;
+{
+  _IO_lock_lock (*stream->_lock);
+}
+strong_alias (__flockfile, _IO_flockfile)
+weak_alias (__flockfile, flockfile)
diff --git a/linuxthreads/sysdeps/pthread/ftrylockfile.c b/linuxthreads/sysdeps/pthread/ftrylockfile.c
new file mode 100644
index 0000000000..21c1ea01ed
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/ftrylockfile.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 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 <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <bits/stdio-lock.h>
+
+
+int
+__ftrylockfile (stream)
+     FILE *stream;
+{
+  return _IO_lock_trylock (*stream->_lock);
+}
+strong_alias (__ftrylockfile, _IO_ftrylockfile)
+weak_alias (__ftrylockfile, ftrylockfile)
diff --git a/linuxthreads/sysdeps/pthread/funlockfile.c b/linuxthreads/sysdeps/pthread/funlockfile.c
new file mode 100644
index 0000000000..f941fc9851
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/funlockfile.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 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 <pthread.h>
+#include <stdio.h>
+#include <libio.h>
+#include <bits/stdio-lock.h>
+
+
+void
+__funlockfile (stream)
+     FILE *stream;
+{
+  _IO_lock_unlock (*stream->_lock);
+}
+strong_alias (__funlockfile, _IO_funlockfile)
+weak_alias (__funlockfile, funlockfile)
diff --git a/linuxthreads/sysdeps/pthread/getcpuclockid.c b/linuxthreads/sysdeps/pthread/getcpuclockid.c
new file mode 100644
index 0000000000..032caeb081
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/getcpuclockid.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2000, 2001, 2004 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; 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 <errno.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
+#include <internals.h>
+
+int
+pthread_getcpuclockid (pthread_t thread_id, clockid_t *clock_id)
+{
+#ifdef CLOCK_THREAD_CPUTIME_ID
+  /* We need to store the thread ID in the CLOCKID variable together
+     with a number identifying the clock.  We reserve the low 3 bits
+     for the clock ID and the rest for the thread ID.  This is
+     problematic if the thread ID is too large.  But 29 bits should be
+     fine.
+
+     If some day more clock IDs are needed the ID part can be
+     enlarged.  The IDs are entirely internal.  */
+  if (2 * PTHREAD_THREADS_MAX
+      >= 1 << (8 * sizeof (*clock_id) - CLOCK_IDFIELD_SIZE))
+    return ERANGE;
+
+  /* Store the number.  */
+  *clock_id = CLOCK_THREAD_CPUTIME_ID | (thread_id << CLOCK_IDFIELD_SIZE);
+
+  return 0;
+#else
+  /* We don't have a timer for that.  */
+  return ENOENT;
+#endif
+}
diff --git a/linuxthreads/sysdeps/pthread/herrno-loc.c b/linuxthreads/sysdeps/pthread/herrno-loc.c
new file mode 100644
index 0000000000..fbc5576166
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/herrno-loc.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1996, 97, 98, 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 <netdb.h>
+#include <tls.h>
+#include <linuxthreads/internals.h>
+#include <sysdep-cancel.h>
+
+#if ! USE___THREAD
+# undef h_errno
+extern int h_errno;
+#endif
+
+/* When threaded, h_errno may be a per-thread variable.  */
+int *
+weak_const_function
+__h_errno_location (void)
+{
+#if ! USE___THREAD
+  if (! SINGLE_THREAD_P)
+    {
+      pthread_descr self = thread_self();
+      return LIBC_THREAD_GETMEM (self, p_h_errnop);
+    }
+#endif
+  return &h_errno;
+}
+libc_hidden_def (__h_errno_location)
diff --git a/linuxthreads/sysdeps/pthread/list.h b/linuxthreads/sysdeps/pthread/list.h
new file mode 100644
index 0000000000..43186a2d51
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/list.h
@@ -0,0 +1,114 @@
+/* Copyright (C) 2002 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.  */
+
+#ifndef _LIST_H
+#define _LIST_H	1
+
+/* The definitions of this file are adopted from those which can be
+   found in the Linux kernel headers to enable people familiar with
+   the latter find their way in these sources as well.  */
+
+
+/* Basic type for the double-link list.  */
+typedef struct list_head
+{
+  struct list_head *next;
+  struct list_head *prev;
+} list_t;
+
+
+/* Define a variable with the head and tail of the list.  */
+#define LIST_HEAD(name) \
+  list_t name = { &(name), &(name) }
+
+/* Initialize a new list head.  */
+#define INIT_LIST_HEAD(ptr) \
+  (ptr)->next = (ptr)->prev = (ptr)
+
+
+/* Add new element at the head of the list.  */
+static inline void
+list_add (list_t *newp, list_t *head)
+{
+  head->next->prev = newp;
+  newp->next = head->next;
+  newp->prev = head;
+  head->next = newp;
+}
+
+
+/* Add new element at the tail of the list.  */
+static inline void
+list_add_tail (list_t *newp, list_t *head)
+{
+  head->prev->next = newp;
+  newp->next = head;
+  newp->prev = head->prev;
+  head->prev = newp;
+}
+
+
+/* Remove element from list.  */
+static inline void
+list_del (list_t *elem)
+{
+  elem->next->prev = elem->prev;
+  elem->prev->next = elem->next;
+}
+
+
+/* Join two lists.  */
+static inline void
+list_splice (list_t *add, list_t *head)
+{
+  /* Do nothing if the list which gets added is empty.  */
+  if (add != add->next)
+    {
+      add->next->prev = head;
+      add->prev->next = head->next;
+      head->next->prev = add->prev;
+      head->next = add->next;
+    }
+}
+
+
+/* Get typed element from list at a given position.  */
+#define list_entry(ptr, type, member) \
+  ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member)))
+
+
+
+/* Iterate forward over the elements of the list.  */
+#define list_for_each(pos, head) \
+  for (pos = (head)->next; pos != (head); pos = pos->next)
+
+
+/* Iterate forward over the elements of the list.  */
+#define list_for_each_prev(pos, head) \
+  for (pos = (head)->prev; pos != (head); pos = pos->prev)
+
+
+/* Iterate backwards over the elements list.  The list elements can be
+   removed from the list while doing this.  */
+#define list_for_each_prev_safe(pos, p, head) \
+  for (pos = (head)->prev, p = pos->prev; \
+       pos != (head); \
+       pos = p, p = pos->prev)
+
+#endif	/* list.h */
diff --git a/linuxthreads/sysdeps/pthread/malloc-machine.h b/linuxthreads/sysdeps/pthread/malloc-machine.h
new file mode 100644
index 0000000000..5191f8c779
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/malloc-machine.h
@@ -0,0 +1,67 @@
+/* Basic platform-independent macro definitions for mutexes,
+   thread-specific data and parameters for malloc.
+   Copyright (C) 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 _MALLOC_MACHINE_H
+#define _MALLOC_MACHINE_H
+
+#undef thread_atfork_static
+
+#include <atomic.h>
+#include <bits/libc-lock.h>
+
+__libc_lock_define (typedef, mutex_t)
+
+#define mutex_init(m)		\
+  __libc_maybe_call2 (pthread_mutex_init, (m, NULL), (*(int *)(m) = 0))
+#define mutex_lock(m)		\
+  __libc_maybe_call2 (pthread_mutex_lock, (m), ((*(int *)(m) = 1), 0))
+#define mutex_trylock(m)	\
+  __libc_maybe_call2 (pthread_mutex_trylock, (m), \
+		      (*(int *)(m) ? 1 : ((*(int *)(m) = 1), 0)))
+#define mutex_unlock(m)		\
+  __libc_maybe_call2 (pthread_mutex_unlock, (m), (*(int *)(m) = 0))
+
+/* This is defined by newer gcc version unique for each module.  */
+extern void *__dso_handle __attribute__ ((__weak__));
+
+#include <fork.h>
+
+#ifdef SHARED
+# define thread_atfork(prepare, parent, child) \
+   __register_atfork (prepare, parent, child, __dso_handle)
+#else
+# define thread_atfork(prepare, parent, child) \
+   __register_atfork (prepare, parent, child,				      \
+		      &__dso_handle == NULL ? NULL : __dso_handle)
+#endif
+
+/* thread specific data for glibc */
+
+#include <bits/libc-tsd.h>
+
+typedef int tsd_key_t[1];	/* no key data structure, libc magic does it */
+__libc_tsd_define (static, MALLOC)	/* declaration/common definition */
+#define tsd_key_create(key, destr)	((void) (key))
+#define tsd_setspecific(key, data)	__libc_tsd_set (MALLOC, (data))
+#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (MALLOC))
+
+#include <sysdeps/generic/malloc-machine.h>
+
+#endif /* !defined(_MALLOC_MACHINE_H) */
diff --git a/linuxthreads/sysdeps/pthread/posix-timer.h b/linuxthreads/sysdeps/pthread/posix-timer.h
new file mode 100644
index 0000000000..1b0a2b65e4
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/posix-timer.h
@@ -0,0 +1,204 @@
+/* Definitions for POSIX timer implementation on top of LinuxThreads.
+   Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <limits.h>
+#include <signal.h>
+
+/* Double linked list.  */
+struct list_links
+{
+  struct list_links *next;
+  struct list_links *prev;
+};
+
+
+/* Forward declaration.  */
+struct timer_node;
+
+
+/* Definitions for an internal thread of the POSIX timer implementation.  */
+struct thread_node
+{
+  struct list_links links;
+  pthread_attr_t attr;
+  pthread_t id;
+  unsigned int exists;
+  struct list_links timer_queue;
+  pthread_cond_t cond;
+  struct timer_node *current_timer;
+  pthread_t captured;
+  clockid_t clock_id;
+};
+
+
+/* Internal representation of a timer.  */
+struct timer_node
+{
+  struct list_links links;
+  struct sigevent event;
+  clockid_t clock;
+  struct itimerspec value;
+  struct timespec expirytime;
+  pthread_attr_t attr;
+  unsigned int abstime;
+  unsigned int armed;
+  enum {
+    TIMER_FREE, TIMER_INUSE, TIMER_DELETED
+  } inuse;
+  struct thread_node *thread;
+  pid_t creator_pid;
+  int refcount;
+  int overrun_count;
+};
+
+
+/* Static array with the structures for all the timers.  */
+extern struct timer_node __timer_array[TIMER_MAX];
+
+/* Global lock to protect operation on the lists.  */
+extern pthread_mutex_t __timer_mutex;
+
+/* Variable to protext initialization.  */
+extern pthread_once_t __timer_init_once_control;
+
+/* Nonzero if initialization of timer implementation failed.  */
+extern int __timer_init_failed;
+
+/* Nodes for the threads used to deliver signals.  */
+/* A distinct thread is used for each clock type.  */
+
+extern struct thread_node __timer_signal_thread_rclk;
+
+
+/* Return pointer to timer structure corresponding to ID.  */
+static inline struct timer_node *
+timer_id2ptr (timer_t timerid)
+{
+  if (timerid >= 0 && timerid < TIMER_MAX)
+    return &__timer_array[timerid];
+
+  return NULL;
+}
+
+/* Return ID of TIMER.  */
+static inline int
+timer_ptr2id (struct timer_node *timer)
+{
+  return timer - __timer_array;
+}
+
+/* Check whether timer is valid; global mutex must be held. */
+static inline int
+timer_valid (struct timer_node *timer)
+{
+  return timer && timer->inuse == TIMER_INUSE;
+}
+
+/* Timer refcount functions; need global mutex. */
+extern void __timer_dealloc (struct timer_node *timer);
+
+static inline void
+timer_addref (struct timer_node *timer)
+{
+  timer->refcount++;
+}
+
+static inline void
+timer_delref (struct timer_node *timer)
+{
+  if (--timer->refcount == 0)
+    __timer_dealloc (timer);
+}
+
+/* Timespec helper routines.  */
+static inline int
+timespec_compare (const struct timespec *left, const struct timespec *right)
+{
+  if (left->tv_sec < right->tv_sec)
+    return -1;
+  if (left->tv_sec > right->tv_sec)
+    return 1;
+
+  if (left->tv_nsec < right->tv_nsec)
+    return -1;
+  if (left->tv_nsec > right->tv_nsec)
+    return 1;
+
+  return 0;
+}
+
+static inline void
+timespec_add (struct timespec *sum, const struct timespec *left,
+	      const struct timespec *right)
+{
+  sum->tv_sec = left->tv_sec + right->tv_sec;
+  sum->tv_nsec = left->tv_nsec + right->tv_nsec;
+
+  if (sum->tv_nsec >= 1000000000)
+    {
+      ++sum->tv_sec;
+      sum->tv_nsec -= 1000000000;
+    }
+}
+
+static inline void
+timespec_sub (struct timespec *diff, const struct timespec *left,
+	      const struct timespec *right)
+{
+  diff->tv_sec = left->tv_sec - right->tv_sec;
+  diff->tv_nsec = left->tv_nsec - right->tv_nsec;
+
+  if (diff->tv_nsec < 0)
+    {
+      --diff->tv_sec;
+      diff->tv_nsec += 1000000000;
+    }
+}
+
+
+/* We need one of the list functions in the other modules.  */
+static inline void
+list_unlink_ip (struct list_links *list)
+{
+  struct list_links *lnext = list->next, *lprev = list->prev;
+
+  lnext->prev = lprev;
+  lprev->next = lnext;
+
+  /* The suffix ip means idempotent; list_unlink_ip can be called
+   * two or more times on the same node.
+   */
+
+  list->next = list;
+  list->prev = list;
+}
+
+
+/* Functions in the helper file.  */
+extern void __timer_mutex_cancel_handler (void *arg);
+extern void __timer_init_once (void);
+extern struct timer_node *__timer_alloc (void);
+extern int __timer_thread_start (struct thread_node *thread);
+extern struct thread_node *__timer_thread_find_matching (const pthread_attr_t *desired_attr, clockid_t);
+extern struct thread_node *__timer_thread_alloc (const pthread_attr_t *desired_attr, clockid_t);
+extern void __timer_thread_dealloc (struct thread_node *thread);
+extern int __timer_thread_queue_timer (struct thread_node *thread,
+				       struct timer_node *insert);
+extern void __timer_thread_wakeup (struct thread_node *thread);
diff --git a/linuxthreads/sysdeps/pthread/pt-initfini.c b/linuxthreads/sysdeps/pthread/pt-initfini.c
new file mode 100644
index 0000000000..1ccac2f6ef
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/pt-initfini.c
@@ -0,0 +1,124 @@
+/* Special .init and .fini section support.  Linuxthread version.
+   Copyright (C) 1995, 1996, 1997, 2000, 2001 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+#include <stdlib.h>
+
+/* We use embedded asm for .section unconditionally, as this makes it
+   easier to insert the necessary directives into crtn.S. */
+#define SECTION(x) asm (".section " x )
+
+/* Embed an #include to pull in the alignment and .end directives. */
+asm ("\n#include \"defs.h\"");
+
+/* The initial common code ends here. */
+asm ("\n/*@HEADER_ENDS*/");
+
+/* To determine whether we need .end and .align: */
+asm ("\n/*@TESTS_BEGIN*/");
+extern void dummy (void (*foo) (void));
+void
+dummy (void (*foo) (void))
+{
+  if (foo)
+    (*foo) ();
+}
+asm ("\n/*@TESTS_END*/");
+
+/* The beginning of _init:  */
+asm ("\n/*@_init_PROLOG_BEGINS*/");
+
+static void
+call_initialize_minimal (void)
+{
+  extern void __pthread_initialize_minimal (void);
+
+  __pthread_initialize_minimal ();
+}
+
+SECTION (".init");
+extern void _init (void);
+void
+_init (void)
+{
+  /* The very first thing we must do is to set up the registers.  */
+  call_initialize_minimal ();
+
+  asm ("ALIGN");
+  asm("END_INIT");
+  /* Now the epilog. */
+  asm ("\n/*@_init_PROLOG_ENDS*/");
+  asm ("\n/*@_init_EPILOG_BEGINS*/");
+  SECTION(".init");
+}
+asm ("END_INIT");
+
+/* End of the _init epilog, beginning of the _fini prolog. */
+asm ("\n/*@_init_EPILOG_ENDS*/");
+asm ("\n/*@_fini_PROLOG_BEGINS*/");
+
+SECTION (".fini");
+extern void _fini (void);
+void
+_fini (void)
+{
+
+  /* End of the _fini prolog. */
+  asm ("ALIGN");
+  asm ("END_FINI");
+  asm ("\n/*@_fini_PROLOG_ENDS*/");
+
+  {
+    /* Let GCC know that _fini is not a leaf function by having a dummy
+       function call here.  We arrange for this call to be omitted from
+       either crt file.  */
+    extern void i_am_not_a_leaf (void);
+    i_am_not_a_leaf ();
+  }
+
+  /* Beginning of the _fini epilog. */
+  asm ("\n/*@_fini_EPILOG_BEGINS*/");
+  SECTION (".fini");
+}
+asm ("END_FINI");
+
+/* End of the _fini epilog.  Any further generated assembly (e.g. .ident)
+   is shared between both crt files. */
+asm ("\n/*@_fini_EPILOG_ENDS*/");
+asm ("\n/*@TRAILER_BEGINS*/");
+
+/* End of file. */
diff --git a/linuxthreads/sysdeps/pthread/pthread-functions.h b/linuxthreads/sysdeps/pthread/pthread-functions.h
new file mode 100644
index 0000000000..43a328ae9c
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/pthread-functions.h
@@ -0,0 +1,96 @@
+/* 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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _PTHREAD_FUNCTIONS_H
+#define _PTHREAD_FUNCTIONS_H	1
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <linuxthreads/descr.h>
+
+struct fork_block;
+
+/* Data type shared with libc.  The libc uses it to pass on calls to
+   the thread functions.  Wine pokes directly into this structure,
+   so if possible avoid breaking it and append new hooks to the end.  */
+struct pthread_functions
+{
+  pid_t (*ptr_pthread_fork) (struct fork_block *);
+  int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
+  int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *);
+  int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *);
+  int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
+  int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
+  int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
+					 struct sched_param *);
+  int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
+					 const struct sched_param *);
+  int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
+  int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
+  int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
+  int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
+  int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
+  int (*ptr___pthread_cond_broadcast) (pthread_cond_t *);
+  int (*ptr___pthread_cond_destroy) (pthread_cond_t *);
+  int (*ptr___pthread_cond_init) (pthread_cond_t *,
+				  const pthread_condattr_t *);
+  int (*ptr___pthread_cond_signal) (pthread_cond_t *);
+  int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
+  int (*ptr_pthread_equal) (pthread_t, pthread_t);
+  void (*ptr___pthread_exit) (void *);
+  int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
+  int (*ptr_pthread_setschedparam) (pthread_t, int,
+				    const struct sched_param *);
+  int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
+  int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
+				 const pthread_mutexattr_t *);
+  int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
+  int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *);
+  int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
+  pthread_t (*ptr_pthread_self) (void);
+  int (*ptr_pthread_setcancelstate) (int, int *);
+  int (*ptr_pthread_setcanceltype) (int, int *);
+  void (*ptr_pthread_do_exit) (void *retval, char *currentframe);
+  void (*ptr_pthread_cleanup_upto) (__jmp_buf target,
+				    char *targetframe);
+  pthread_descr (*ptr_pthread_thread_self) (void);
+  int (*ptr_pthread_internal_tsd_set) (int key, const void *pointer);
+  void * (*ptr_pthread_internal_tsd_get) (int key);
+  void ** __attribute__ ((__const__))
+    (*ptr_pthread_internal_tsd_address) (int key);
+  int (*ptr_pthread_sigaction) (int sig, const struct sigaction * act,
+				struct sigaction *oact);
+  int (*ptr_pthread_sigwait) (const sigset_t *set, int *sig);
+  int (*ptr_pthread_raise) (int sig);
+  int (*ptr___pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
+				       const struct timespec *);
+  void (*ptr__pthread_cleanup_push) (struct _pthread_cleanup_buffer * buffer,
+				     void (*routine)(void *), void * arg);
+
+  void (*ptr__pthread_cleanup_pop) (struct _pthread_cleanup_buffer * buffer,
+				    int execute);
+};
+
+/* Variable in libc.so.  */
+extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+
+#endif	/* pthread-functions.h */
diff --git a/linuxthreads/sysdeps/pthread/pthread.h b/linuxthreads/sysdeps/pthread/pthread.h
new file mode 100644
index 0000000000..86c7ff7391
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/pthread.h
@@ -0,0 +1,686 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix        */
+/* threads for Linux.                                                   */
+/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
+/*                                                                      */
+/* This program is free software; you can redistribute it and/or        */
+/* modify it under the terms of the GNU Library General Public License  */
+/* as published by the Free Software Foundation; either version 2       */
+/* of the License, or (at your option) any later version.               */
+/*                                                                      */
+/* This program 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 Library General Public License for more details.                 */
+
+#ifndef _PTHREAD_H
+#define _PTHREAD_H	1
+
+#include <features.h>
+
+#include <sched.h>
+#include <time.h>
+
+#define __need_sigset_t
+#include <signal.h>
+#include <bits/pthreadtypes.h>
+#include <bits/initspin.h>
+
+
+__BEGIN_DECLS
+
+/* Initializers.  */
+
+#define PTHREAD_MUTEX_INITIALIZER \
+  {0, 0, 0, PTHREAD_MUTEX_TIMED_NP, __LOCK_INITIALIZER}
+#ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+  {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __LOCK_INITIALIZER}
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+  {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __LOCK_INITIALIZER}
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+  {0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __LOCK_INITIALIZER}
+#endif
+
+#define PTHREAD_COND_INITIALIZER {__LOCK_INITIALIZER, 0, "", 0}
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+# define PTHREAD_RWLOCK_INITIALIZER \
+  { __LOCK_INITIALIZER, 0, NULL, NULL, NULL,				      \
+    PTHREAD_RWLOCK_DEFAULT_NP, PTHREAD_PROCESS_PRIVATE }
+#endif
+#ifdef __USE_GNU
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+  { __LOCK_INITIALIZER, 0, NULL, NULL, NULL,				      \
+    PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, PTHREAD_PROCESS_PRIVATE }
+#endif
+
+/* Values for attributes.  */
+
+enum
+{
+  PTHREAD_CREATE_JOINABLE,
+#define PTHREAD_CREATE_JOINABLE	PTHREAD_CREATE_JOINABLE
+  PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED	PTHREAD_CREATE_DETACHED
+};
+
+enum
+{
+  PTHREAD_INHERIT_SCHED,
+#define PTHREAD_INHERIT_SCHED	PTHREAD_INHERIT_SCHED
+  PTHREAD_EXPLICIT_SCHED
+#define PTHREAD_EXPLICIT_SCHED	PTHREAD_EXPLICIT_SCHED
+};
+
+enum
+{
+  PTHREAD_SCOPE_SYSTEM,
+#define PTHREAD_SCOPE_SYSTEM	PTHREAD_SCOPE_SYSTEM
+  PTHREAD_SCOPE_PROCESS
+#define PTHREAD_SCOPE_PROCESS	PTHREAD_SCOPE_PROCESS
+};
+
+enum
+{
+  PTHREAD_MUTEX_TIMED_NP,
+  PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_ADAPTIVE_NP
+#ifdef __USE_UNIX98
+  ,
+  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
+  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+#endif
+#ifdef __USE_GNU
+  /* For compatibility.  */
+  , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_ADAPTIVE_NP
+#endif
+};
+
+enum
+{
+  PTHREAD_PROCESS_PRIVATE,
+#define PTHREAD_PROCESS_PRIVATE	PTHREAD_PROCESS_PRIVATE
+  PTHREAD_PROCESS_SHARED
+#define PTHREAD_PROCESS_SHARED	PTHREAD_PROCESS_SHARED
+};
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+enum
+{
+  PTHREAD_RWLOCK_PREFER_READER_NP,
+  PTHREAD_RWLOCK_PREFER_WRITER_NP,
+  PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
+  PTHREAD_RWLOCK_DEFAULT_NP = PTHREAD_RWLOCK_PREFER_WRITER_NP
+};
+#endif	/* Unix98 */
+
+#define PTHREAD_ONCE_INIT 0
+
+/* Special constants */
+
+#ifdef __USE_XOPEN2K
+/* -1 is distinct from 0 and all errno constants */
+# define PTHREAD_BARRIER_SERIAL_THREAD -1
+#endif
+
+/* Cleanup buffers */
+
+struct _pthread_cleanup_buffer
+{
+  void (*__routine) (void *);		  /* Function to call.  */
+  void *__arg;				  /* Its argument.  */
+  int __canceltype;			  /* Saved cancellation type. */
+  struct _pthread_cleanup_buffer *__prev; /* Chaining of cleanup functions.  */
+};
+
+/* Cancellation */
+
+enum
+{
+  PTHREAD_CANCEL_ENABLE,
+#define PTHREAD_CANCEL_ENABLE	PTHREAD_CANCEL_ENABLE
+  PTHREAD_CANCEL_DISABLE
+#define PTHREAD_CANCEL_DISABLE	PTHREAD_CANCEL_DISABLE
+};
+enum
+{
+  PTHREAD_CANCEL_DEFERRED,
+#define PTHREAD_CANCEL_DEFERRED	PTHREAD_CANCEL_DEFERRED
+  PTHREAD_CANCEL_ASYNCHRONOUS
+#define PTHREAD_CANCEL_ASYNCHRONOUS	PTHREAD_CANCEL_ASYNCHRONOUS
+};
+#define PTHREAD_CANCELED ((void *) -1)
+
+
+/* Function for handling threads.  */
+
+/* Create a thread with given attributes ATTR (or default attributes
+   if ATTR is NULL), and call function START_ROUTINE with given
+   arguments ARG.  */
+extern int pthread_create (pthread_t *__restrict __threadp,
+			   __const pthread_attr_t *__restrict __attr,
+			   void *(*__start_routine) (void *),
+			   void *__restrict __arg) __THROW;
+
+/* Obtain the identifier of the current thread.  */
+extern pthread_t pthread_self (void) __THROW;
+
+/* Compare two thread identifiers.  */
+extern int pthread_equal (pthread_t __thread1, pthread_t __thread2) __THROW;
+
+/* Terminate calling thread.  */
+extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));
+
+/* Make calling thread wait for termination of the thread TH.  The
+   exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
+   is not NULL.  */
+extern int pthread_join (pthread_t __th, void **__thread_return);
+
+/* Indicate that the thread TH is never to be joined with PTHREAD_JOIN.
+   The resources of TH will therefore be freed immediately when it
+   terminates, instead of waiting for another thread to perform PTHREAD_JOIN
+   on it.  */
+extern int pthread_detach (pthread_t __th) __THROW;
+
+
+/* Functions for handling attributes.  */
+
+/* Initialize thread attribute *ATTR with default attributes
+   (detachstate is PTHREAD_JOINABLE, scheduling policy is SCHED_OTHER,
+    no user-provided stack).  */
+extern int pthread_attr_init (pthread_attr_t *__attr) __THROW;
+
+/* Destroy thread attribute *ATTR.  */
+extern int pthread_attr_destroy (pthread_attr_t *__attr) __THROW;
+
+/* Set the `detachstate' attribute in *ATTR according to DETACHSTATE.  */
+extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
+					int __detachstate) __THROW;
+
+/* Return in *DETACHSTATE the `detachstate' attribute in *ATTR.  */
+extern int pthread_attr_getdetachstate (__const pthread_attr_t *__attr,
+					int *__detachstate) __THROW;
+
+/* Set scheduling parameters (priority, etc) in *ATTR according to PARAM.  */
+extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr,
+				       __const struct sched_param *__restrict
+				       __param) __THROW;
+
+/* Return in *PARAM the scheduling parameters of *ATTR.  */
+extern int pthread_attr_getschedparam (__const pthread_attr_t *__restrict
+				       __attr,
+				       struct sched_param *__restrict __param)
+     __THROW;
+
+/* Set scheduling policy in *ATTR according to POLICY.  */
+extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
+     __THROW;
+
+/* Return in *POLICY the scheduling policy of *ATTR.  */
+extern int pthread_attr_getschedpolicy (__const pthread_attr_t *__restrict
+					__attr, int *__restrict __policy)
+     __THROW;
+
+/* Set scheduling inheritance mode in *ATTR according to INHERIT.  */
+extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
+					 int __inherit) __THROW;
+
+/* Return in *INHERIT the scheduling inheritance mode of *ATTR.  */
+extern int pthread_attr_getinheritsched (__const pthread_attr_t *__restrict
+					 __attr, int *__restrict __inherit)
+     __THROW;
+
+/* Set scheduling contention scope in *ATTR according to SCOPE.  */
+extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
+     __THROW;
+
+/* Return in *SCOPE the scheduling contention scope of *ATTR.  */
+extern int pthread_attr_getscope (__const pthread_attr_t *__restrict __attr,
+				  int *__restrict __scope) __THROW;
+
+#ifdef __USE_UNIX98
+/* Set the size of the guard area at the bottom of the thread.  */
+extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
+				      size_t __guardsize) __THROW;
+
+/* Get the size of the guard area at the bottom of the thread.  */
+extern int pthread_attr_getguardsize (__const pthread_attr_t *__restrict
+				      __attr, size_t *__restrict __guardsize)
+     __THROW;
+#endif
+
+/* Set the starting address of the stack of the thread to be created.
+   Depending on whether the stack grows up or down the value must either
+   be higher or lower than all the address in the memory block.  The
+   minimal size of the block must be PTHREAD_STACK_MIN.  */
+extern int pthread_attr_setstackaddr (pthread_attr_t *__attr,
+				      void *__stackaddr) __THROW;
+
+/* Return the previously set address for the stack.  */
+extern int pthread_attr_getstackaddr (__const pthread_attr_t *__restrict
+				      __attr, void **__restrict __stackaddr)
+     __THROW;
+
+#ifdef __USE_XOPEN2K
+/* The following two interfaces are intended to replace the last two.  They
+   require setting the address as well as the size since only setting the
+   address will make the implementation on some architectures impossible.  */
+extern int pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
+				  size_t __stacksize) __THROW;
+
+/* Return the previously set address for the stack.  */
+extern int pthread_attr_getstack (__const pthread_attr_t *__restrict __attr,
+				  void **__restrict __stackaddr,
+				  size_t *__restrict __stacksize) __THROW;
+#endif
+
+/* Add information about the minimum stack size needed for the thread
+   to be started.  This size must never be less than PTHREAD_STACK_MIN
+   and must also not exceed the system limits.  */
+extern int pthread_attr_setstacksize (pthread_attr_t *__attr,
+				      size_t __stacksize) __THROW;
+
+/* Return the currently used minimal stack size.  */
+extern int pthread_attr_getstacksize (__const pthread_attr_t *__restrict
+				      __attr, size_t *__restrict __stacksize)
+     __THROW;
+
+#ifdef __USE_GNU
+/* Initialize thread attribute *ATTR with attributes corresponding to the
+   already running thread TH.  It shall be called on unitialized ATTR
+   and destroyed with pthread_attr_destroy when no longer needed.  */
+extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) __THROW;
+#endif
+
+/* Functions for scheduling control.  */
+
+/* Set the scheduling parameters for TARGET_THREAD according to POLICY
+   and *PARAM.  */
+extern int pthread_setschedparam (pthread_t __target_thread, int __policy,
+				  __const struct sched_param *__param)
+     __THROW;
+
+/* Return in *POLICY and *PARAM the scheduling parameters for TARGET_THREAD.  */
+extern int pthread_getschedparam (pthread_t __target_thread,
+				  int *__restrict __policy,
+				  struct sched_param *__restrict __param)
+     __THROW;
+
+#ifdef __USE_UNIX98
+/* Determine level of concurrency.  */
+extern int pthread_getconcurrency (void) __THROW;
+
+/* Set new concurrency level to LEVEL.  */
+extern int pthread_setconcurrency (int __level) __THROW;
+#endif
+
+#ifdef __USE_GNU
+/* Yield the processor to another thread or process.
+   This function is similar to the POSIX `sched_yield' function but
+   might be differently implemented in the case of a m-on-n thread
+   implementation.  */
+extern int pthread_yield (void) __THROW;
+#endif
+
+/* Functions for mutex handling.  */
+
+/* Initialize MUTEX using attributes in *MUTEX_ATTR, or use the
+   default values if later is NULL.  */
+extern int pthread_mutex_init (pthread_mutex_t *__restrict __mutex,
+			       __const pthread_mutexattr_t *__restrict
+			       __mutex_attr) __THROW;
+
+/* Destroy MUTEX.  */
+extern int pthread_mutex_destroy (pthread_mutex_t *__mutex) __THROW;
+
+/* Try to lock MUTEX.  */
+extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) __THROW;
+
+/* Wait until lock for MUTEX becomes available and lock it.  */
+extern int pthread_mutex_lock (pthread_mutex_t *__mutex) __THROW;
+
+#ifdef __USE_XOPEN2K
+/* Wait until lock becomes available, or specified time passes. */
+extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
+				    __const struct timespec *__restrict
+				    __abstime) __THROW;
+#endif
+
+/* Unlock MUTEX.  */
+extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) __THROW;
+
+
+/* Functions for handling mutex attributes.  */
+
+/* Initialize mutex attribute object ATTR with default attributes
+   (kind is PTHREAD_MUTEX_TIMED_NP).  */
+extern int pthread_mutexattr_init (pthread_mutexattr_t *__attr) __THROW;
+
+/* Destroy mutex attribute object ATTR.  */
+extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr) __THROW;
+
+/* Get the process-shared flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_getpshared (__const pthread_mutexattr_t *
+					 __restrict __attr,
+					 int *__restrict __pshared) __THROW;
+
+/* Set the process-shared flag of the mutex attribute ATTR.  */
+extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
+					 int __pshared) __THROW;
+
+#ifdef __USE_UNIX98
+/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
+   PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
+   PTHREAD_MUTEX_DEFAULT).  */
+extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
+     __THROW;
+
+/* Return in *KIND the mutex kind attribute in *ATTR.  */
+extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
+				      __attr, int *__restrict __kind) __THROW;
+#endif
+
+
+/* Functions for handling conditional variables.  */
+
+/* Initialize condition variable COND using attributes ATTR, or use
+   the default values if later is NULL.  */
+extern int pthread_cond_init (pthread_cond_t *__restrict __cond,
+			      __const pthread_condattr_t *__restrict
+			      __cond_attr) __THROW;
+
+/* Destroy condition variable COND.  */
+extern int pthread_cond_destroy (pthread_cond_t *__cond) __THROW;
+
+/* Wake up one thread waiting for condition variable COND.  */
+extern int pthread_cond_signal (pthread_cond_t *__cond) __THROW;
+
+/* Wake up all threads waiting for condition variables COND.  */
+extern int pthread_cond_broadcast (pthread_cond_t *__cond) __THROW;
+
+/* Wait for condition variable COND to be signaled or broadcast.
+   MUTEX is assumed to be locked before.  */
+extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
+			      pthread_mutex_t *__restrict __mutex);
+
+/* Wait for condition variable COND to be signaled or broadcast until
+   ABSTIME.  MUTEX is assumed to be locked before.  ABSTIME is an
+   absolute time specification; zero is the beginning of the epoch
+   (00:00:00 GMT, January 1, 1970).  */
+extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
+				   pthread_mutex_t *__restrict __mutex,
+				   __const struct timespec *__restrict
+				   __abstime);
+
+/* Functions for handling condition variable attributes.  */
+
+/* Initialize condition variable attribute ATTR.  */
+extern int pthread_condattr_init (pthread_condattr_t *__attr) __THROW;
+
+/* Destroy condition variable attribute ATTR.  */
+extern int pthread_condattr_destroy (pthread_condattr_t *__attr) __THROW;
+
+/* Get the process-shared flag of the condition variable attribute ATTR.  */
+extern int pthread_condattr_getpshared (__const pthread_condattr_t *
+					__restrict __attr,
+					int *__restrict __pshared) __THROW;
+
+/* Set the process-shared flag of the condition variable attribute ATTR.  */
+extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
+					int __pshared) __THROW;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Functions for handling read-write locks.  */
+
+/* Initialize read-write lock RWLOCK using attributes ATTR, or use
+   the default values if later is NULL.  */
+extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
+				__const pthread_rwlockattr_t *__restrict
+				__attr) __THROW;
+
+/* Destroy read-write lock RWLOCK.  */
+extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock) __THROW;
+
+/* Acquire read lock for RWLOCK.  */
+extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) __THROW;
+
+/* Try to acquire read lock for RWLOCK.  */
+extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) __THROW;
+
+# ifdef __USE_XOPEN2K
+/* Try to acquire read lock for RWLOCK or return after specfied time.  */
+extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
+				       __const struct timespec *__restrict
+				       __abstime) __THROW;
+# endif
+
+/* Acquire write lock for RWLOCK.  */
+extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) __THROW;
+
+/* Try to acquire write lock for RWLOCK.  */
+extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) __THROW;
+
+# ifdef __USE_XOPEN2K
+/* Try to acquire write lock for RWLOCK or return after specfied time.  */
+extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
+				       __const struct timespec *__restrict
+				       __abstime) __THROW;
+# endif
+
+/* Unlock RWLOCK.  */
+extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) __THROW;
+
+
+/* Functions for handling read-write lock attributes.  */
+
+/* Initialize attribute object ATTR with default values.  */
+extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr) __THROW;
+
+/* Destroy attribute object ATTR.  */
+extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr) __THROW;
+
+/* Return current setting of process-shared attribute of ATTR in PSHARED.  */
+extern int pthread_rwlockattr_getpshared (__const pthread_rwlockattr_t *
+					  __restrict __attr,
+					  int *__restrict __pshared) __THROW;
+
+/* Set process-shared attribute of ATTR to PSHARED.  */
+extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
+					  int __pshared) __THROW;
+
+/* Return current setting of reader/writer preference.  */
+extern int pthread_rwlockattr_getkind_np (__const pthread_rwlockattr_t *__attr,
+					  int *__pref) __THROW;
+
+/* Set reader/write preference.  */
+extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
+					  int __pref) __THROW;
+#endif
+
+#ifdef __USE_XOPEN2K
+/* The IEEE Std. 1003.1j-2000 introduces functions to implement
+   spinlocks.  */
+
+/* Initialize the spinlock LOCK.  If PSHARED is nonzero the spinlock can
+   be shared between different processes.  */
+extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared)
+     __THROW;
+
+/* Destroy the spinlock LOCK.  */
+extern int pthread_spin_destroy (pthread_spinlock_t *__lock) __THROW;
+
+/* Wait until spinlock LOCK is retrieved.  */
+extern int pthread_spin_lock (pthread_spinlock_t *__lock) __THROW;
+
+/* Try to lock spinlock LOCK.  */
+extern int pthread_spin_trylock (pthread_spinlock_t *__lock) __THROW;
+
+/* Release spinlock LOCK.  */
+extern int pthread_spin_unlock (pthread_spinlock_t *__lock) __THROW;
+
+
+/* Barriers are a also a new feature in 1003.1j-2000. */
+
+extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
+				 __const pthread_barrierattr_t *__restrict
+				 __attr, unsigned int __count) __THROW;
+
+extern int pthread_barrier_destroy (pthread_barrier_t *__barrier) __THROW;
+
+extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr) __THROW;
+
+extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr) __THROW;
+
+extern int pthread_barrierattr_getpshared (__const pthread_barrierattr_t *
+					   __restrict __attr,
+					   int *__restrict __pshared) __THROW;
+
+extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
+					   int __pshared) __THROW;
+
+extern int pthread_barrier_wait (pthread_barrier_t *__barrier) __THROW;
+#endif
+
+
+/* Functions for handling thread-specific data.  */
+
+/* Create a key value identifying a location in the thread-specific
+   data area.  Each thread maintains a distinct thread-specific data
+   area.  DESTR_FUNCTION, if non-NULL, is called with the value
+   associated to that key when the key is destroyed.
+   DESTR_FUNCTION is not called if the value associated is NULL when
+   the key is destroyed.  */
+extern int pthread_key_create (pthread_key_t *__key,
+			       void (*__destr_function) (void *)) __THROW;
+
+/* Destroy KEY.  */
+extern int pthread_key_delete (pthread_key_t __key) __THROW;
+
+/* Store POINTER in the thread-specific data slot identified by KEY. */
+extern int pthread_setspecific (pthread_key_t __key,
+				__const void *__pointer) __THROW;
+
+/* Return current value of the thread-specific data slot identified by KEY.  */
+extern void *pthread_getspecific (pthread_key_t __key) __THROW;
+
+
+/* Functions for handling initialization.  */
+
+/* Guarantee that the initialization function INIT_ROUTINE will be called
+   only once, even if pthread_once is executed several times with the
+   same ONCE_CONTROL argument. ONCE_CONTROL must point to a static or
+   extern variable initialized to PTHREAD_ONCE_INIT.
+
+   The initialization functions might throw exception which is why
+   this function is not marked with __THROW.  */
+extern int pthread_once (pthread_once_t *__once_control,
+			 void (*__init_routine) (void));
+
+
+/* Functions for handling cancellation.  */
+
+/* Set cancelability state of current thread to STATE, returning old
+   state in *OLDSTATE if OLDSTATE is not NULL.  */
+extern int pthread_setcancelstate (int __state, int *__oldstate);
+
+/* Set cancellation state of current thread to TYPE, returning the old
+   type in *OLDTYPE if OLDTYPE is not NULL.  */
+extern int pthread_setcanceltype (int __type, int *__oldtype);
+
+/* Cancel THREAD immediately or at the next possibility.  */
+extern int pthread_cancel (pthread_t __cancelthread);
+
+/* Test for pending cancellation for the current thread and terminate
+   the thread as per pthread_exit(PTHREAD_CANCELED) if it has been
+   cancelled.  */
+extern void pthread_testcancel (void);
+
+
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+   when the thread is cancelled or calls pthread_exit.  ROUTINE will also
+   be called with arguments ARG when the matching pthread_cleanup_pop
+   is executed with non-zero EXECUTE argument.
+   pthread_cleanup_push and pthread_cleanup_pop are macros and must always
+   be used in matching pairs at the same nesting level of braces. */
+
+#define pthread_cleanup_push(routine,arg) \
+  { struct _pthread_cleanup_buffer _buffer;				      \
+    _pthread_cleanup_push (&_buffer, (routine), (arg));
+
+extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
+				   void (*__routine) (void *),
+				   void *__arg) __THROW;
+
+/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
+   If EXECUTE is non-zero, the handler function is called. */
+
+#define pthread_cleanup_pop(execute) \
+    _pthread_cleanup_pop (&_buffer, (execute)); }
+
+extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
+				  int __execute) __THROW;
+
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+   saves the current cancellation type and set it to deferred cancellation.  */
+
+#ifdef __USE_GNU
+# define pthread_cleanup_push_defer_np(routine,arg) \
+  { struct _pthread_cleanup_buffer _buffer;				      \
+    _pthread_cleanup_push_defer (&_buffer, (routine), (arg));
+
+extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *__buffer,
+					 void (*__routine) (void *),
+					 void *__arg) __THROW;
+
+/* Remove a cleanup handler as pthread_cleanup_pop does, but also
+   restores the cancellation type that was in effect when the matching
+   pthread_cleanup_push_defer was called.  */
+
+# define pthread_cleanup_pop_restore_np(execute) \
+  _pthread_cleanup_pop_restore (&_buffer, (execute)); }
+
+extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *__buffer,
+					  int __execute) __THROW;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* Get ID of CPU-time clock for thread THREAD_ID.  */
+extern int pthread_getcpuclockid (pthread_t __thread_id,
+				  __clockid_t *__clock_id) __THROW;
+#endif
+
+
+/* Functions for handling signals.  */
+#include <bits/sigthread.h>
+
+
+/* Functions for handling process creation and process execution.  */
+
+/* Install handlers to be called when a new process is created with FORK.
+   The PREPARE handler is called in the parent process just before performing
+   FORK. The PARENT handler is called in the parent process just after FORK.
+   The CHILD handler is called in the child process.  Each of the three
+   handlers can be NULL, meaning that no handler needs to be called at that
+   point.
+   PTHREAD_ATFORK can be called several times, in which case the PREPARE
+   handlers are called in LIFO order (last added with PTHREAD_ATFORK,
+   first called before FORK), and the PARENT and CHILD handlers are called
+   in FIFO (first added, first called).  */
+
+extern int pthread_atfork (void (*__prepare) (void),
+			   void (*__parent) (void),
+			   void (*__child) (void)) __THROW;
+
+/* Terminate all threads in the program except the calling process.
+   Should be called just before invoking one of the exec*() functions.  */
+
+extern void pthread_kill_other_threads_np (void) __THROW;
+
+__END_DECLS
+
+#endif	/* pthread.h */
diff --git a/linuxthreads/sysdeps/pthread/ptlongjmp.c b/linuxthreads/sysdeps/pthread/ptlongjmp.c
new file mode 100644
index 0000000000..a2a56b8d9c
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/ptlongjmp.c
@@ -0,0 +1,39 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix        */
+/* threads for Linux.                                                   */
+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr)              */
+/*                                                                      */
+/* This program is free software; you can redistribute it and/or        */
+/* modify it under the terms of the GNU Library General Public License  */
+/* as published by the Free Software Foundation; either version 2       */
+/* of the License, or (at your option) any later version.               */
+/*                                                                      */
+/* This program 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 Library General Public License for more details.                 */
+
+/* Redefine siglongjmp and longjmp so that they interact correctly
+   with cleanup handlers */
+
+#include <setjmp.h>
+#include "pthread.h"
+#include "internals.h"
+
+/* These functions are not declared anywhere since they shouldn't be
+   used at another place but here.  */
+extern void __libc_siglongjmp (sigjmp_buf env, int val)
+     __attribute__ ((noreturn));
+extern void __libc_longjmp (sigjmp_buf env, int val)
+     __attribute__ ((noreturn));
+
+#ifdef SHARED
+void siglongjmp (sigjmp_buf env, int val)
+{
+  __libc_siglongjmp (env, val);
+}
+
+void longjmp (jmp_buf env, int val)
+{
+  __libc_longjmp (env, val);
+}
+#endif
diff --git a/linuxthreads/sysdeps/pthread/res-state.c b/linuxthreads/sysdeps/pthread/res-state.c
new file mode 100644
index 0000000000..016e20b4ef
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/res-state.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1996, 97, 98, 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 <resolv.h>
+#include <tls.h>
+#include <linuxthreads/internals.h>
+#include <sysdep-cancel.h>
+
+#if ! USE___THREAD
+# undef _res
+extern struct __res_state _res;
+#endif
+
+/* When threaded, _res may be a per-thread variable.  */
+struct __res_state *
+#if ! USE___THREAD
+weak_const_function
+#endif
+__res_state (void)
+{
+#if ! USE___THREAD
+  if (! SINGLE_THREAD_P)
+    {
+      pthread_descr self = thread_self();
+      return LIBC_THREAD_GETMEM (self, p_resp);
+    }
+  return &_res;
+#else
+  return __resp;
+#endif
+}
+libc_hidden_def (__res_state)
diff --git a/linuxthreads/sysdeps/pthread/semaphore.h b/linuxthreads/sysdeps/pthread/semaphore.h
new file mode 100644
index 0000000000..8793768a8e
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/semaphore.h
@@ -0,0 +1 @@
+#include <linuxthreads/semaphore.h>
diff --git a/linuxthreads/sysdeps/pthread/sigaction.c b/linuxthreads/sysdeps/pthread/sigaction.c
new file mode 100644
index 0000000000..f4e20790d9
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/sigaction.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* This is tricky.  GCC doesn't like #include_next in the primary
+   source file and even if it did, the first #include_next is this
+   exact file anyway.  */
+#ifndef LIBC_SIGACTION
+
+# include <bits/libc-lock.h>
+
+# define LIBC_SIGACTION	1
+
+# include <linuxthreads/sysdeps/pthread/sigaction.c>
+
+# ifndef NOT_IN_libc
+#  ifndef SHARED
+weak_extern (__pthread_sigaction)
+#  endif
+
+int
+__sigaction (sig, act, oact)
+     int sig;
+     const struct sigaction *act;
+     struct sigaction *oact;
+{
+  return __libc_maybe_call2 (pthread_sigaction, (sig, act, oact),
+			     __libc_sigaction (sig, act, oact));
+}
+# else
+weak_alias (__libc_sigaction, __sigaction)
+# endif
+libc_hidden_weak (__sigaction)
+weak_alias (__sigaction, sigaction)
+
+#else
+
+# include_next <sigaction.c>
+
+#endif /* LIBC_SIGACTION */
diff --git a/linuxthreads/sysdeps/pthread/tcb-offsets.h b/linuxthreads/sysdeps/pthread/tcb-offsets.h
new file mode 100644
index 0000000000..3fe13702ea
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/tcb-offsets.h
@@ -0,0 +1 @@
+/* This is overridden by generated tcb-offsets.h on arches which need it.  */
diff --git a/linuxthreads/sysdeps/pthread/timer_create.c b/linuxthreads/sysdeps/pthread/timer_create.c
new file mode 100644
index 0000000000..7f7e886c83
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/timer_create.c
@@ -0,0 +1,170 @@
+/* Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "posix-timer.h"
+
+
+/* Create new per-process timer using CLOCK.  */
+int
+timer_create (clock_id, evp, timerid)
+     clockid_t clock_id;
+     struct sigevent *evp;
+     timer_t *timerid;
+{
+  int retval = -1;
+  struct timer_node *newtimer = NULL;
+  struct thread_node *thread = NULL;
+
+  if (0
+#ifdef _POSIX_CPUTIME
+      || clock_id == CLOCK_PROCESS_CPUTIME_ID
+#endif
+#ifdef _POSIX_THREAD_CPUTIME
+      || clock_id == CLOCK_THREAD_CPUTIME_ID
+#endif
+      )
+    {
+      /* We don't allow timers for CPU clocks.  At least not in the
+	 moment.  */
+      __set_errno (ENOTSUP);
+      return -1;
+    }
+
+  if (clock_id != CLOCK_REALTIME)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  pthread_once (&__timer_init_once_control, __timer_init_once);
+
+  if (__timer_init_failed)
+    {
+      __set_errno (ENOMEM);
+      return -1;
+    }
+
+  pthread_mutex_lock (&__timer_mutex);
+
+  newtimer = __timer_alloc ();
+  if (__builtin_expect (newtimer == NULL, 0))
+    {
+      __set_errno (EAGAIN);
+      goto unlock_bail;
+    }
+
+  if (evp != NULL)
+    newtimer->event = *evp;
+  else
+    {
+      newtimer->event.sigev_notify = SIGEV_SIGNAL;
+      newtimer->event.sigev_signo = SIGALRM;
+      newtimer->event.sigev_value.sival_int = timer_ptr2id (newtimer);
+      newtimer->event.sigev_notify_function = 0;
+    }
+
+  newtimer->event.sigev_notify_attributes = &newtimer->attr;
+  newtimer->creator_pid = getpid ();
+
+  switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL))
+    {
+    case SIGEV_NONE:
+    case SIGEV_SIGNAL:
+      /* We have a global thread for delivering timed signals.
+	 If it is not running, try to start it up.  */
+      thread = &__timer_signal_thread_rclk;
+      if (! thread->exists)
+	{
+	  if (__builtin_expect (__timer_thread_start (thread),
+				1) < 0)
+	    {
+	      __set_errno (EAGAIN);
+	      goto unlock_bail;
+            }
+        }
+      break;
+
+    case SIGEV_THREAD:
+      /* Copy over thread attributes or set up default ones.  */
+      if (evp->sigev_notify_attributes)
+	newtimer->attr = *(pthread_attr_t *) evp->sigev_notify_attributes;
+      else
+	pthread_attr_init (&newtimer->attr);
+
+      /* Ensure thread attributes call for deatched thread.  */
+      pthread_attr_setdetachstate (&newtimer->attr, PTHREAD_CREATE_DETACHED);
+
+      /* Try to find existing thread having the right attributes.  */
+      thread = __timer_thread_find_matching (&newtimer->attr, clock_id);
+
+      /* If no existing thread has these attributes, try to allocate one.  */
+      if (thread == NULL)
+	thread = __timer_thread_alloc (&newtimer->attr, clock_id);
+
+      /* Out of luck; no threads are available.  */
+      if (__builtin_expect (thread == NULL, 0))
+	{
+	  __set_errno (EAGAIN);
+	  goto unlock_bail;
+	}
+
+      /* If the thread is not running already, try to start it.  */
+      if (! thread->exists
+	  && __builtin_expect (! __timer_thread_start (thread), 0))
+	{
+	  __set_errno (EAGAIN);
+	  goto unlock_bail;
+	}
+      break;
+
+    default:
+      __set_errno (EINVAL);
+      goto unlock_bail;
+    }
+
+  newtimer->clock = clock_id;
+  newtimer->abstime = 0;
+  newtimer->armed = 0;
+  newtimer->thread = thread;
+
+  *timerid = timer_ptr2id (newtimer);
+  retval = 0;
+
+  if (__builtin_expect (retval, 0) == -1)
+    {
+    unlock_bail:
+      if (thread != NULL)
+	__timer_thread_dealloc (thread);
+      if (newtimer != NULL)
+	{
+	  timer_delref (newtimer);
+	  __timer_dealloc (newtimer);
+	}
+    }
+
+  pthread_mutex_unlock (&__timer_mutex);
+
+  return retval;
+}
diff --git a/linuxthreads/sysdeps/pthread/timer_delete.c b/linuxthreads/sysdeps/pthread/timer_delete.c
new file mode 100644
index 0000000000..48ba1f2726
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/timer_delete.c
@@ -0,0 +1,70 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include "posix-timer.h"
+
+
+/* Delete timer TIMERID.  */
+int
+timer_delete (timerid)
+     timer_t timerid;
+{
+  struct timer_node *timer;
+  int retval = -1;
+
+  pthread_mutex_lock (&__timer_mutex);
+
+  timer = timer_id2ptr (timerid);
+  if (! timer_valid (timer))
+    /* Invalid timer ID or the timer is not in use.  */
+    __set_errno (EINVAL);
+  else
+    {
+      if (timer->armed && timer->thread != NULL)
+	{
+	  struct thread_node *thread = timer->thread;
+	  assert (thread != NULL);
+
+	  /* If thread is cancelled while waiting for handler to terminate,
+	     the mutex is unlocked and timer_delete is aborted.  */
+	  pthread_cleanup_push (__timer_mutex_cancel_handler, &__timer_mutex);
+
+	  /* If timer is currently being serviced, wait for it to finish.  */
+	  while (thread->current_timer == timer)
+	    pthread_cond_wait (&thread->cond, &__timer_mutex);
+
+	  pthread_cleanup_pop (0);
+        }
+
+      /* Remove timer from whatever queue it may be on and deallocate it.  */
+      timer->inuse = TIMER_DELETED;
+      list_unlink_ip (&timer->links);
+      timer_delref (timer);
+      retval = 0;
+    }
+
+  pthread_mutex_unlock (&__timer_mutex);
+
+  return retval;
+}
diff --git a/linuxthreads/sysdeps/pthread/timer_getoverr.c b/linuxthreads/sysdeps/pthread/timer_getoverr.c
new file mode 100644
index 0000000000..f3e22215b2
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/timer_getoverr.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include "posix-timer.h"
+
+
+/* Get expiration overrun for timer TIMERID.  */
+int
+timer_getoverrun (timerid)
+     timer_t timerid;
+{
+  struct timer_node *timer;
+  int retval = -1;
+
+  pthread_mutex_lock (&__timer_mutex);
+
+  if (! timer_valid (timer = timer_id2ptr (timerid)))
+    __set_errno (EINVAL);
+  else
+    retval = timer->overrun_count;
+
+  pthread_mutex_unlock (&__timer_mutex);
+
+  return retval;
+}
diff --git a/linuxthreads/sysdeps/pthread/timer_gettime.c b/linuxthreads/sysdeps/pthread/timer_gettime.c
new file mode 100644
index 0000000000..723a61632f
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/timer_gettime.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include "posix-timer.h"
+
+
+/* Get current value of timer TIMERID and store it in VLAUE.  */
+int
+timer_gettime (timerid, value)
+     timer_t timerid;
+     struct itimerspec *value;
+{
+  struct timer_node *timer;
+  struct timespec now, expiry;
+  int retval = -1, armed = 0, valid;
+  clock_t clock = 0;
+
+  pthread_mutex_lock (&__timer_mutex);
+
+  timer = timer_id2ptr (timerid);
+  valid = timer_valid (timer);
+
+  if (valid) {
+    armed = timer->armed;
+    expiry = timer->expirytime;
+    clock = timer->clock;
+    value->it_interval = timer->value.it_interval;
+  }
+
+  pthread_mutex_unlock (&__timer_mutex);
+
+  if (valid)
+    {
+      if (armed)
+	{
+	  clock_gettime (clock, &now);
+	  if (timespec_compare (&now, &expiry) < 0)
+	    timespec_sub (&value->it_value, &expiry, &now);
+	  else
+	    {
+	      value->it_value.tv_sec = 0;
+	      value->it_value.tv_nsec = 0;
+	    }
+	}
+      else
+	{
+	  value->it_value.tv_sec = 0;
+	  value->it_value.tv_nsec = 0;
+	}
+
+      retval = 0;
+    }
+  else
+    __set_errno (EINVAL);
+
+  return retval;
+}
diff --git a/linuxthreads/sysdeps/pthread/timer_routines.c b/linuxthreads/sysdeps/pthread/timer_routines.c
new file mode 100644
index 0000000000..3877b86fbb
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/timer_routines.c
@@ -0,0 +1,573 @@
+/* Helper code for POSIX timer implementation on LinuxThreads.
+   Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "posix-timer.h"
+
+
+/* Number of threads used.  */
+#define THREAD_MAXNODES	16
+
+/* Array containing the descriptors for the used threads.  */
+static struct thread_node thread_array[THREAD_MAXNODES];
+
+/* Static array with the structures for all the timers.  */
+struct timer_node __timer_array[TIMER_MAX];
+
+/* Global lock to protect operation on the lists.  */
+pthread_mutex_t __timer_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Variable to protext initialization.  */
+pthread_once_t __timer_init_once_control = PTHREAD_ONCE_INIT;
+
+/* Nonzero if initialization of timer implementation failed.  */
+int __timer_init_failed;
+
+/* Node for the thread used to deliver signals.  */
+struct thread_node __timer_signal_thread_rclk;
+
+/* Lists to keep free and used timers and threads.  */
+struct list_links timer_free_list;
+struct list_links thread_free_list;
+struct list_links thread_active_list;
+
+
+#ifdef __NR_rt_sigqueueinfo
+extern int __syscall_rt_sigqueueinfo (int, int, siginfo_t *);
+#endif
+
+
+/* List handling functions.  */
+static inline void
+list_init (struct list_links *list)
+{
+  list->next = list->prev = list;
+}
+
+static inline void
+list_append (struct list_links *list, struct list_links *newp)
+{
+  newp->prev = list->prev;
+  newp->next = list;
+  list->prev->next = newp;
+  list->prev = newp;
+}
+
+static inline void
+list_insbefore (struct list_links *list, struct list_links *newp)
+{
+  list_append (list, newp);
+}
+
+/*
+ * Like list_unlink_ip, except that calling it on a node that
+ * is already unlinked is disastrous rather than a noop.
+ */
+
+static inline void
+list_unlink (struct list_links *list)
+{
+  struct list_links *lnext = list->next, *lprev = list->prev;
+
+  lnext->prev = lprev;
+  lprev->next = lnext;
+}
+
+static inline struct list_links *
+list_first (struct list_links *list)
+{
+  return list->next;
+}
+
+static inline struct list_links *
+list_null (struct list_links *list)
+{
+  return list;
+}
+
+static inline struct list_links *
+list_next (struct list_links *list)
+{
+  return list->next;
+}
+
+static inline int
+list_isempty (struct list_links *list)
+{
+  return list->next == list;
+}
+
+
+/* Functions build on top of the list functions.  */
+static inline struct thread_node *
+thread_links2ptr (struct list_links *list)
+{
+  return (struct thread_node *) ((char *) list
+				 - offsetof (struct thread_node, links));
+}
+
+static inline struct timer_node *
+timer_links2ptr (struct list_links *list)
+{
+  return (struct timer_node *) ((char *) list
+				- offsetof (struct timer_node, links));
+}
+
+
+/* Initialize a newly allocated thread structure.  */
+static void
+thread_init (struct thread_node *thread, const pthread_attr_t *attr, clockid_t clock_id)
+{
+  if (attr != NULL)
+    thread->attr = *attr;
+  else
+    {
+      pthread_attr_init (&thread->attr);
+      pthread_attr_setdetachstate (&thread->attr, PTHREAD_CREATE_DETACHED);
+    }
+
+  thread->exists = 0;
+  list_init (&thread->timer_queue);
+  pthread_cond_init (&thread->cond, 0);
+  thread->current_timer = 0;
+  thread->captured = pthread_self ();
+  thread->clock_id = clock_id;
+}
+
+
+/* Initialize the global lists, and acquire global resources.  Error
+   reporting is done by storing a non-zero value to the global variable
+   timer_init_failed.  */
+static void
+init_module (void)
+{
+  int i;
+
+  list_init (&timer_free_list);
+  list_init (&thread_free_list);
+  list_init (&thread_active_list);
+
+  for (i = 0; i < TIMER_MAX; ++i)
+    {
+      list_append (&timer_free_list, &__timer_array[i].links);
+      __timer_array[i].inuse = TIMER_FREE;
+    }
+
+  for (i = 0; i < THREAD_MAXNODES; ++i)
+    list_append (&thread_free_list, &thread_array[i].links);
+
+  thread_init (&__timer_signal_thread_rclk, 0, CLOCK_REALTIME);
+}
+
+
+/* This is a handler executed in a child process after a fork()
+   occurs.  It reinitializes the module, resetting all of the data
+   structures to their initial state.  The mutex is initialized in
+   case it was locked in the parent process.  */
+static void
+reinit_after_fork (void)
+{
+  init_module ();
+  pthread_mutex_init (&__timer_mutex, 0);
+}
+
+
+/* Called once form pthread_once in timer_init. This initializes the
+   module and ensures that reinit_after_fork will be executed in any
+   child process.  */
+void
+__timer_init_once (void)
+{
+  init_module ();
+  pthread_atfork (0, 0, reinit_after_fork);
+}
+
+
+/* Deinitialize a thread that is about to be deallocated.  */
+static void
+thread_deinit (struct thread_node *thread)
+{
+  assert (list_isempty (&thread->timer_queue));
+  pthread_cond_destroy (&thread->cond);
+}
+
+
+/* Allocate a thread structure from the global free list.  Global
+   mutex lock must be held by caller.  The thread is moved to
+   the active list. */
+struct thread_node *
+__timer_thread_alloc (const pthread_attr_t *desired_attr, clockid_t clock_id)
+{
+  struct list_links *node = list_first (&thread_free_list);
+
+  if (node != list_null (&thread_free_list))
+    {
+      struct thread_node *thread = thread_links2ptr (node);
+      list_unlink (node);
+      thread_init (thread, desired_attr, clock_id);
+      list_append (&thread_active_list, node);
+      return thread;
+    }
+
+  return 0;
+}
+
+
+/* Return a thread structure to the global free list.  Global lock
+   must be held by caller.  */
+void
+__timer_thread_dealloc (struct thread_node *thread)
+{
+  thread_deinit (thread);
+  list_unlink (&thread->links);
+  list_append (&thread_free_list, &thread->links);
+}
+
+
+/* Each of our threads which terminates executes this cleanup
+   handler. We never terminate threads ourselves; if a thread gets here
+   it means that the evil application has killed it.  If the thread has
+   timers, these require servicing and so we must hire a replacement
+   thread right away.  We must also unblock another thread that may
+   have been waiting for this thread to finish servicing a timer (see
+   timer_delete()).  */
+
+static void
+thread_cleanup (void *val)
+{
+  if (val != NULL)
+    {
+      struct thread_node *thread = val;
+
+      /* How did the signal thread get killed?  */
+      assert (thread != &__timer_signal_thread_rclk);
+
+      pthread_mutex_lock (&__timer_mutex);
+
+      thread->exists = 0;
+
+      /* We are no longer processing a timer event.  */
+      thread->current_timer = 0;
+
+      if (list_isempty (&thread->timer_queue))
+	  __timer_thread_dealloc (thread);
+      else
+	(void) __timer_thread_start (thread);
+
+      pthread_mutex_unlock (&__timer_mutex);
+
+      /* Unblock potentially blocked timer_delete().  */
+      pthread_cond_broadcast (&thread->cond);
+    }
+}
+
+
+/* Handle a timer which is supposed to go off now.  */
+static void
+thread_expire_timer (struct thread_node *self, struct timer_node *timer)
+{
+  self->current_timer = timer; /* Lets timer_delete know timer is running. */
+
+  pthread_mutex_unlock (&__timer_mutex);
+
+  switch (__builtin_expect (timer->event.sigev_notify, SIGEV_SIGNAL))
+    {
+    case SIGEV_NONE:
+      break;
+
+    case SIGEV_SIGNAL:
+#ifdef __NR_rt_sigqueueinfo
+      {
+	siginfo_t info;
+
+	/* First, clear the siginfo_t structure, so that we don't pass our
+	   stack content to other tasks.  */
+	memset (&info, 0, sizeof (siginfo_t));
+	/* We must pass the information about the data in a siginfo_t
+           value.  */
+	info.si_signo = timer->event.sigev_signo;
+	info.si_code = SI_TIMER;
+	info.si_pid = timer->creator_pid;
+	info.si_uid = getuid ();
+	info.si_value = timer->event.sigev_value;
+
+	INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, info.si_signo, &info);
+      }
+#else
+      if (pthread_kill (self->captured, timer->event.sigev_signo) != 0)
+	{
+	  if (pthread_kill (self->id, timer->event.sigev_signo) != 0)
+	    abort ();
+        }
+#endif
+      break;
+
+    case SIGEV_THREAD:
+      timer->event.sigev_notify_function (timer->event.sigev_value);
+      break;
+
+    default:
+      assert (! "unknown event");
+      break;
+    }
+
+  pthread_mutex_lock (&__timer_mutex);
+
+  self->current_timer = 0;
+
+  pthread_cond_broadcast (&self->cond);
+}
+
+
+/* Thread function; executed by each timer thread. The job of this
+   function is to wait on the thread's timer queue and expire the
+   timers in chronological order as close to their scheduled time as
+   possible.  */
+static void
+__attribute__ ((noreturn))
+thread_func (void *arg)
+{
+  struct thread_node *self = arg;
+
+  /* Register cleanup handler, in case rogue application terminates
+     this thread.  (This cannot happen to __timer_signal_thread, which
+     doesn't invoke application callbacks). */
+
+  pthread_cleanup_push (thread_cleanup, self);
+
+  pthread_mutex_lock (&__timer_mutex);
+
+  while (1)
+    {
+      struct list_links *first;
+      struct timer_node *timer = NULL;
+
+      /* While the timer queue is not empty, inspect the first node.  */
+      first = list_first (&self->timer_queue);
+      if (first != list_null (&self->timer_queue))
+	{
+	  struct timespec now;
+
+	  timer = timer_links2ptr (first);
+
+	  /* This assumes that the elements of the list of one thread
+	     are all for the same clock.  */
+	  clock_gettime (timer->clock, &now);
+
+	  while (1)
+	    {
+	      /* If the timer is due or overdue, remove it from the queue.
+		 If it's a periodic timer, re-compute its new time and
+		 requeue it.  Either way, perform the timer expiry. */
+	      if (timespec_compare (&now, &timer->expirytime) < 0)
+		break;
+
+	      list_unlink_ip (first);
+
+	      if (__builtin_expect (timer->value.it_interval.tv_sec, 0) != 0
+		  || timer->value.it_interval.tv_nsec != 0)
+		{
+		  timer->overrun_count = 0;
+		  timespec_add (&timer->expirytime, &timer->expirytime,
+				&timer->value.it_interval);
+		  while (timespec_compare (&timer->expirytime, &now) < 0)
+		    {
+		      timespec_add (&timer->expirytime, &timer->expirytime,
+				    &timer->value.it_interval);
+		      if (timer->overrun_count < DELAYTIMER_MAX)
+			++timer->overrun_count;
+		    }
+		  __timer_thread_queue_timer (self, timer);
+		}
+
+	      thread_expire_timer (self, timer);
+
+	      first = list_first (&self->timer_queue);
+	      if (first == list_null (&self->timer_queue))
+		break;
+
+	      timer = timer_links2ptr (first);
+	    }
+	}
+
+      /* If the queue is not empty, wait until the expiry time of the
+	 first node.  Otherwise wait indefinitely.  Insertions at the
+	 head of the queue must wake up the thread by broadcasting
+	 this condition variable.  */
+      if (timer != NULL)
+	pthread_cond_timedwait (&self->cond, &__timer_mutex,
+				&timer->expirytime);
+      else
+	pthread_cond_wait (&self->cond, &__timer_mutex);
+    }
+  /* This macro will never be executed since the while loop loops
+     forever - but we have to add it for proper nesting.  */
+  pthread_cleanup_pop (1);
+}
+
+
+/* Enqueue a timer in wakeup order in the thread's timer queue.
+   Returns 1 if the timer was inserted at the head of the queue,
+   causing the queue's next wakeup time to change. */
+
+int
+__timer_thread_queue_timer (struct thread_node *thread,
+			    struct timer_node *insert)
+{
+  struct list_links *iter;
+  int athead = 1;
+
+  for (iter = list_first (&thread->timer_queue);
+       iter != list_null (&thread->timer_queue);
+        iter = list_next (iter))
+    {
+      struct timer_node *timer = timer_links2ptr (iter);
+
+      if (timespec_compare (&insert->expirytime, &timer->expirytime) < 0)
+	  break;
+      athead = 0;
+    }
+
+  list_insbefore (iter, &insert->links);
+  return athead;
+}
+
+
+/* Start a thread and associate it with the given thread node.  Global
+   lock must be held by caller.  */
+int
+__timer_thread_start (struct thread_node *thread)
+{
+  int retval = 1;
+
+  assert (!thread->exists);
+  thread->exists = 1;
+
+  if (pthread_create (&thread->id, &thread->attr,
+		      (void *(*) (void *)) thread_func, thread) != 0)
+    {
+      thread->exists = 0;
+      retval = -1;
+    }
+
+  return retval;
+}
+
+
+void
+__timer_thread_wakeup (struct thread_node *thread)
+{
+  pthread_cond_broadcast (&thread->cond);
+}
+
+
+/* Compare two pthread_attr_t thread attributes for exact equality.
+   Returns 1 if they are equal, otherwise zero if they are not equal or
+   contain illegal values.  This version is LinuxThreads-specific for
+   performance reason.  One could use the access functions to get the
+   values of all the fields of the attribute structure.  */
+static int
+thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right)
+{
+  return (left->__detachstate == right->__detachstate
+	  && left->__schedpolicy == right->__schedpolicy
+	  && left->__guardsize == right->__guardsize
+	  && (left->__schedparam.sched_priority
+	      == right->__schedparam.sched_priority)
+	  && left->__inheritsched == right->__inheritsched
+	  && left->__scope == right->__scope
+	  && left->__stacksize == right->__stacksize
+	  && left->__stackaddr_set == right->__stackaddr_set
+	  && (left->__stackaddr_set
+	      || left->__stackaddr == right->__stackaddr));
+}
+
+
+/* Search the list of active threads and find one which has matching
+   attributes.  Global mutex lock must be held by caller.  */
+struct thread_node *
+__timer_thread_find_matching (const pthread_attr_t *desired_attr,
+			      clockid_t desired_clock_id)
+{
+  struct list_links *iter = list_first (&thread_active_list);
+
+  while (iter != list_null (&thread_active_list))
+    {
+      struct thread_node *candidate = thread_links2ptr (iter);
+
+      if (thread_attr_compare (desired_attr, &candidate->attr)
+	  && desired_clock_id == candidate->clock_id)
+	return candidate;
+
+      iter = list_next (iter);
+    }
+
+  return NULL;
+}
+
+
+/* Grab a free timer structure from the global free list.  The global
+   lock must be held by the caller.  */
+struct timer_node *
+__timer_alloc (void)
+{
+  struct list_links *node = list_first (&timer_free_list);
+
+  if (node != list_null (&timer_free_list))
+    {
+      struct timer_node *timer = timer_links2ptr (node);
+      list_unlink_ip (node);
+      timer->inuse = TIMER_INUSE;
+      timer->refcount = 1;
+      return timer;
+    }
+
+  return NULL;
+}
+
+
+/* Return a timer structure to the global free list.  The global lock
+   must be held by the caller.  */
+void
+__timer_dealloc (struct timer_node *timer)
+{
+  assert (timer->refcount == 0);
+  timer->thread = NULL;	/* Break association between timer and thread.  */
+  timer->inuse = TIMER_FREE;
+  list_append (&timer_free_list, &timer->links);
+}
+
+
+/* Thread cancellation handler which unlocks a mutex.  */
+void
+__timer_mutex_cancel_handler (void *arg)
+{
+  pthread_mutex_unlock (arg);
+}
diff --git a/linuxthreads/sysdeps/pthread/timer_settime.c b/linuxthreads/sysdeps/pthread/timer_settime.c
new file mode 100644
index 0000000000..592b5271ba
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/timer_settime.c
@@ -0,0 +1,137 @@
+/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include "posix-timer.h"
+
+
+/* Set timer TIMERID to VALUE, returning old value in OVLAUE.  */
+int
+timer_settime (timerid, flags, value, ovalue)
+     timer_t timerid;
+     int flags;
+     const struct itimerspec *value;
+     struct itimerspec *ovalue;
+{
+  struct timer_node *timer;
+  struct thread_node *thread = NULL;
+  struct timespec now;
+  int have_now = 0, need_wakeup = 0;
+  int retval = -1;
+
+  timer = timer_id2ptr (timerid);
+  if (timer == NULL)
+    {
+      __set_errno (EINVAL);
+      goto bail;
+    }
+
+  if (value->it_interval.tv_nsec < 0
+      || value->it_interval.tv_nsec >= 1000000000
+      || value->it_value.tv_nsec < 0
+      || value->it_value.tv_nsec >= 1000000000)
+    {
+      __set_errno (EINVAL);
+      goto bail;
+    }
+
+  /* Will need to know current time since this is a relative timer;
+     might as well make the system call outside of the lock now! */
+
+  if ((flags & TIMER_ABSTIME) == 0)
+    {
+      clock_gettime (timer->clock, &now);
+      have_now = 1;
+    }
+
+  pthread_mutex_lock (&__timer_mutex);
+  timer_addref (timer);
+
+  /* One final check of timer validity; this one is possible only
+     until we have the mutex, because it accesses the inuse flag. */
+
+  if (! timer_valid(timer))
+    {
+      __set_errno (EINVAL);
+      goto unlock_bail;
+    }
+
+  if (ovalue != NULL)
+    {
+      ovalue->it_interval = timer->value.it_interval;
+
+      if (timer->armed)
+	{
+	  if (! have_now)
+	    {
+	      pthread_mutex_unlock (&__timer_mutex);
+	      clock_gettime (timer->clock, &now);
+	      have_now = 1;
+	      pthread_mutex_lock (&__timer_mutex);
+	      timer_addref (timer);
+	    }
+
+	  timespec_sub (&ovalue->it_value, &timer->expirytime, &now);
+	}
+      else
+	{
+	  ovalue->it_value.tv_sec = 0;
+	  ovalue->it_value.tv_nsec = 0;
+	}
+    }
+
+  timer->value = *value;
+
+  list_unlink_ip (&timer->links);
+  timer->armed = 0;
+
+  thread = timer->thread;
+
+  /* A value of { 0, 0 } causes the timer to be stopped. */
+  if (value->it_value.tv_sec != 0
+      || __builtin_expect (value->it_value.tv_nsec != 0, 1))
+    {
+      if ((flags & TIMER_ABSTIME) != 0)
+	/* The user specified the expiration time.  */
+	timer->expirytime = value->it_value;
+      else
+	timespec_add (&timer->expirytime, &now, &value->it_value);
+
+      /* Only need to wake up the thread if timer is inserted
+	 at the head of the queue. */
+      if (thread != NULL)
+	need_wakeup = __timer_thread_queue_timer (thread, timer);
+      timer->armed = 1;
+    }
+
+  retval = 0;
+
+unlock_bail:
+  timer_delref (timer);
+  pthread_mutex_unlock (&__timer_mutex);
+
+bail:
+  if (thread != NULL && need_wakeup)
+    __timer_thread_wakeup (thread);
+
+  return retval;
+}
diff --git a/linuxthreads/sysdeps/pthread/tst-timer.c b/linuxthreads/sysdeps/pthread/tst-timer.c
new file mode 100644
index 0000000000..7417bcd5f0
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/tst-timer.c
@@ -0,0 +1,114 @@
+/* Tests for POSIX timer implementation.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kaz Kylheku <kaz@ashi.footprints.net>.
+
+   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 <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+
+static void
+notify_func (union sigval sigval)
+{
+  puts ("notify_func");
+}
+
+
+static void
+signal_func (int sig)
+{
+  static const char text[] = "signal_func\n";
+  signal (sig, signal_func);
+  write (STDOUT_FILENO, text, sizeof text - 1);
+}
+
+static void
+intr_sleep (int sec)
+{
+  struct timespec ts;
+
+  ts.tv_sec = sec;
+  ts.tv_nsec = 0;
+
+  while (nanosleep (&ts, &ts) == -1 && errno == EINTR)
+    ;
+}
+
+#define ZSIGALRM 14
+
+
+int
+main (void)
+{
+  struct timespec ts;
+  timer_t timer_sig, timer_thr1, timer_thr2;
+  int retval;
+  struct sigevent sigev1 =
+  {
+    .sigev_notify = SIGEV_SIGNAL,
+    .sigev_signo = ZSIGALRM
+  };
+  struct sigevent sigev2;
+  struct itimerspec itimer1 = { { 0, 200000000 }, { 0, 200000000 } };
+  struct itimerspec itimer2 = { { 0, 100000000 }, { 0, 500000000 } };
+  struct itimerspec itimer3 = { { 0, 150000000 }, { 0, 300000000 } };
+  struct itimerspec old;
+
+  retval = clock_gettime (CLOCK_REALTIME, &ts);
+
+  sigev2.sigev_notify = SIGEV_THREAD;
+  sigev2.sigev_notify_function = notify_func;
+  sigev2.sigev_notify_attributes = NULL;
+
+  setvbuf (stdout, 0, _IOLBF, 0);
+
+  printf ("clock_gettime returned %d, timespec = { %ld, %ld }\n",
+	  retval, ts.tv_sec, ts.tv_nsec);
+
+  retval = clock_getres (CLOCK_REALTIME, &ts);
+
+  printf ("clock_getres returned %d, timespec = { %ld, %ld }\n",
+	  retval, ts.tv_sec, ts.tv_nsec);
+
+  timer_create (CLOCK_REALTIME, &sigev1, &timer_sig);
+  timer_create (CLOCK_REALTIME, &sigev2, &timer_thr1);
+  timer_create (CLOCK_REALTIME, &sigev2, &timer_thr2);
+
+  timer_settime (timer_thr1, 0, &itimer2, &old);
+  timer_settime (timer_thr2, 0, &itimer3, &old);
+
+  signal (ZSIGALRM, signal_func);
+
+  timer_settime (timer_sig, 0, &itimer1, &old);
+
+  timer_delete (-1);
+
+  intr_sleep (3);
+
+  timer_delete (timer_sig);
+  timer_delete (timer_thr1);
+
+  intr_sleep (3);
+
+  timer_delete (timer_thr2);
+
+  return 0;
+}
diff --git a/linuxthreads/sysdeps/s390/Makefile b/linuxthreads/sysdeps/s390/Makefile
new file mode 100644
index 0000000000..2885c968b3
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/Makefile
@@ -0,0 +1,6 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
+ifeq ($(subdir),linuxthreads)
+libpthread-routines += ptw-sysdep
+endif
diff --git a/linuxthreads/sysdeps/s390/pspinlock.c b/linuxthreads/sysdeps/s390/pspinlock.c
new file mode 100644
index 0000000000..f963f35371
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/pspinlock.c
@@ -0,0 +1,91 @@
+/* POSIX spinlock implementation.  S/390 version.
+   Copyright (C) 2000, 2004 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+   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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+/* This implementation is similar to the one used in the Linux kernel.
+   But the kernel is byte instructions for the memory access.  This is
+   faster but unusable here.  The problem is that only 128
+   threads/processes could use the spinlock at the same time.  If (by
+   a design error in the program) a thread/process would hold the
+   spinlock for a time long enough to accumulate 128 waiting
+   processes, the next one will find a positive value in the spinlock
+   and assume it is unlocked.  We cannot accept that.  */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  asm volatile("    basr  1,0\n"
+	       "0:  slr   0,0\n"
+	       "    cs    0,1,%1\n"
+	       "    jl    0b\n"
+	       : "=m" (*lock)
+	       : "m" (*lock) : "0", "1", "cc" );
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int oldval;
+
+  asm volatile("    slr   %1,%1\n"
+	       "    basr  1,0\n"
+	       "0:  cs    %1,1,%0"
+	       : "=m" (*lock), "=&d" (oldval)
+	       : "m" (*lock) : "1", "cc" );
+  return oldval == 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile("    xc 0(4,%0),0(%0)\n"
+	       "    bcr 15,0"
+	       : : "a" (lock) : "memory" );
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/s390/s390-32/pt-machine.h b/linuxthreads/sysdeps/s390/s390-32/pt-machine.h
new file mode 100644
index 0000000000..398332965f
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/s390-32/pt-machine.h
@@ -0,0 +1,120 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   S390 version.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+   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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* For multiprocessor systems, we want to ensure all memory accesses
+   are completed before we reset a lock.  On other systems, we still
+   need to make sure that the compiler has flushed everything to memory.  */
+#define MEMORY_BARRIER() __asm__ __volatile__ ("bcr 15,0" : : : "memory")
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  int ret;
+
+  __asm__ __volatile__(
+       "    la    1,%1\n"
+       "    lhi   0,1\n"
+       "    l     %0,%1\n"
+       "0:  cs    %0,0,0(1)\n"
+       "    jl    0b"
+       : "=&d" (ret), "+m" (*spinlock)
+       : : "0", "1", "cc");
+
+  return ret;
+}
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("15");
+
+#ifdef USE_TLS
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF ((pthread_descr) __builtin_thread_pointer ())
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr) __builtin_set_thread_pointer (descr)
+#else
+/* Return the thread descriptor for the current thread.
+   S/390 registers uses access register 0 as "thread register".  */
+#define THREAD_SELF  ({                                                       \
+  register pthread_descr __self;                                              \
+  __asm__ ("ear %0,%%a0" : "=d" (__self) );                                   \
+  __self;                                                                     \
+})
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  ({                                       \
+  __asm__ ("sar %%a0,%0" : : "d" (descr) );                                   \
+})
+#endif
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     8*1024*1024
+
+/* Compare-and-swap for semaphores. */
+
+#define HAS_COMPARE_AND_SWAP
+
+PT_EI int
+__compare_and_swap(long int *p, long int oldval, long int newval)
+{
+        int retval;
+
+        __asm__ __volatile__(
+                "  la   1,%1\n"
+                "  lr   0,%2\n"
+                "  cs   0,%3,0(1)\n"
+                "  ipm  %0\n"
+                "  srl  %0,28\n"
+                "0:"
+                : "=&d" (retval), "+m" (*p)
+                : "d" (oldval) , "d" (newval)
+                : "cc", "0", "1" );
+        return retval == 0;
+}
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/s390/s390-64/pt-machine.h b/linuxthreads/sysdeps/s390/s390-64/pt-machine.h
new file mode 100644
index 0000000000..49f8ae2b9a
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/s390-64/pt-machine.h
@@ -0,0 +1,125 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   64 bit S/390 version.
+   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+   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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* For multiprocessor systems, we want to ensure all memory accesses
+   are completed before we reset a lock.  On other systems, we still
+   need to make sure that the compiler has flushed everything to memory.  */
+#define MEMORY_BARRIER() __asm__ __volatile__ ("bcr 15,0" : : : "memory")
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  int ret;
+
+  __asm__ __volatile__(
+       "    la    1,%1\n"
+       "    lhi   0,1\n"
+       "    l     %0,%1\n"
+       "0:  cs    %0,0,0(1)\n"
+       "    jl    0b"
+       : "=&d" (ret), "+m" (*spinlock)
+       : : "0", "1", "cc");
+
+  return ret;
+}
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("15");
+
+#ifdef USE_TLS
+/* Return the thread descriptor for the current thread.  */
+# define THREAD_SELF ((pthread_descr) __builtin_thread_pointer ())
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr) __builtin_set_thread_pointer (descr)
+#else
+/* Return the thread descriptor for the current thread.
+   64 bit S/390 uses access register 0 and 1 as "thread register".  */
+#define THREAD_SELF  ({                                                       \
+  register pthread_descr __self;                                              \
+  __asm__ ("   ear  %0,%%a0\n"                                                \
+           "   sllg %0,%0,32\n"                                               \
+           "   ear  %0,%%a1\n"                                                \
+           : "=d" (__self) );                                                 \
+  __self;                                                                     \
+})
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  ({                                       \
+  __asm__ ("   sar  %%a1,%0\n"                                                \
+           "   srlg 0,%0,32\n"                                                \
+           "   sar  %%a0,0\n"                                                 \
+           : : "d" (descr) : "0" );                                           \
+})
+#endif
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     8*1024*1024
+
+/* Compare-and-swap for semaphores. */
+
+#define HAS_COMPARE_AND_SWAP
+
+PT_EI int
+__compare_and_swap(long int *p, long int oldval, long int newval)
+{
+        int retval;
+
+        __asm__ __volatile__(
+                "  lgr  0,%2\n"
+                "  csg  0,%3,%1\n"
+                "  ipm  %0\n"
+                "  srl  %0,28\n"
+                "0:"
+                : "=&d" (retval), "+m" (*p)
+                : "d" (oldval) , "d" (newval)
+                : "cc", "0");
+        return retval == 0;
+}
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/s390/tcb-offsets.sym b/linuxthreads/sysdeps/s390/tcb-offsets.sym
new file mode 100644
index 0000000000..aee6be2570
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/tcb-offsets.sym
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
diff --git a/linuxthreads/sysdeps/s390/tls.h b/linuxthreads/sysdeps/s390/tls.h
new file mode 100644
index 0000000000..41a83a72fb
--- /dev/null
+++ b/linuxthreads/sysdeps/s390/tls.h
@@ -0,0 +1,140 @@
+/* Definitions for thread-local data handling.  linuxthreads/s390 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;		/* Pointer to the TCB.  Not necessary the
+			   thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;		/* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+/* TLS is always supported if the tools support it.  There are no
+   kernel dependencies.  To avoid bothering with the TLS support code
+   at all, use configure --without-tls.
+
+   We need USE_TLS to be consistently defined, for ldsodefs.h
+   conditionals.  */
+
+#ifdef HAVE_TLS_SUPPORT
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+/* Get system call information.  */
+#  include <sysdep.h>
+
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+#  define TLS_TCB_AT_TP	1
+
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(descr, dtvp) \
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(dtv) \
+  (((tcbhead_t *) __builtin_thread_pointer ())->dtv = (dtv))
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.
+
+   The value of this macro is null if successful, or an error string.  */
+#  define TLS_INIT_TP(descr, secondcall)				      \
+  ({									      \
+    void *_descr = (descr);						      \
+    tcbhead_t *head = _descr;						      \
+									      \
+    head->tcb = _descr;							      \
+    /* For now the thread descriptor is at the same address.  */	      \
+    head->self = _descr;						      \
+									      \
+    __builtin_set_thread_pointer (_descr);				      \
+    NULL;								      \
+  })
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  (((tcbhead_t *) __builtin_thread_pointer ())->dtv)
+
+# endif /* __ASSEMBLER__ */
+
+#else	/* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
+
+# ifndef __ASSEMBLER__
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+#  define NONTLS_INIT_TP \
+  do { 								\
+    static const tcbhead_t nontls_init_tp			\
+      = { .multiple_threads = 0 };				\
+    INIT_THREAD_SELF (&nontls_init_tp, 0);			\
+  } while (0)
+
+# endif /* __ASSEMBLER__ */
+
+#endif	/* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/sh/Makefile b/linuxthreads/sysdeps/sh/Makefile
new file mode 100644
index 0000000000..81bddf688c
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/sh/pspinlock.c b/linuxthreads/sysdeps/sh/pspinlock.c
new file mode 100644
index 0000000000..2dec849d3c
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/pspinlock.c
@@ -0,0 +1,80 @@
+/* POSIX spinlock implementation.  SH version.
+   Copyright (C) 2000, 2001 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  do
+    asm volatile ("tas.b @%1; movt %0"
+		  : "=r" (val)
+		  : "r" (lock)
+		  : "memory");
+  while (val == 0);
+
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  unsigned int val;
+
+  asm volatile ("tas.b @%1; movt %0"
+		: "=r" (val)
+		: "r" (lock)
+		: "memory");
+  return val ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  return *lock = 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/sh/pt-machine.h b/linuxthreads/sysdeps/sh/pt-machine.h
new file mode 100644
index 0000000000..02545e6b45
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/pt-machine.h
@@ -0,0 +1,81 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   SuperH version.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Niibe Yutaka <gniibe@m17n.org>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef __ASSEMBLER__
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  int ret;
+
+  __asm__ __volatile__(
+       "tas.b	@%1\n\t"
+       "movt	%0"
+       : "=r" (ret)
+       : "r" (spinlock)
+       : "memory", "cc");
+
+  return (ret == 0);
+}
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     32*1024*1024
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("r15");
+
+/* Return the thread descriptor for the current thread.  */
+struct _pthread_descr_struct;
+#define THREAD_SELF \
+  ({ struct _pthread_descr_struct *self; \
+      __asm__("stc gbr,%0" : "=r" (self)); self;})
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr) \
+  ({ __asm__ __volatile__("ldc %0,gbr" : : "r" (descr));})
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#endif /* __ASSEMBLER__ */
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/sh/tcb-offsets.sym b/linuxthreads/sysdeps/sh/tcb-offsets.sym
new file mode 100644
index 0000000000..328eb05738
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/tcb-offsets.sym
@@ -0,0 +1,10 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+#ifdef USE_TLS
+MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads)
+TLS_PRE_TCB_SIZE	sizeof (struct _pthread_descr_struct)
+#else
+MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
+#endif
diff --git a/linuxthreads/sysdeps/sh/tls.h b/linuxthreads/sysdeps/sh/tls.h
new file mode 100644
index 0000000000..17a247c6b6
--- /dev/null
+++ b/linuxthreads/sysdeps/sh/tls.h
@@ -0,0 +1,148 @@
+/* Definition for thread-local data handling.  linuxthreads/SH 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 _TLS_H
+#define _TLS_H
+
+# include <dl-sysdep.h>
+# include <pt-machine.h>
+
+#ifndef __ASSEMBLER__
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+
+/* We can support TLS only if the floating-stack support is available.  */
+#if defined HAVE_TLS_SUPPORT \
+    && (defined FLOATING_STACKS || !defined IS_IN_libpthread)
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+
+typedef struct
+{
+  dtv_t *dtv;
+  void *private;
+} tcbhead_t;
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE sizeof (tcbhead_t)
+
+/* This is the size we need before TCB.  */
+#  define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+
+/* The TLS blocks start right after the TCB.  */
+#  define TLS_DTV_AT_TP	1
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(tcbp, dtvp) \
+  ((tcbhead_t *) (tcbp))->dtv = dtvp + 1
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(dtv) \
+  ({ tcbhead_t *__tcbp;							      \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
+     __tcbp->dtv = (dtv);})
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(tcbp) \
+  (((tcbhead_t *) (tcbp))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+#  define TLS_INIT_TP(tcbp, secondcall) \
+  ({ __asm __volatile ("ldc %0,gbr" : : "r" (tcbp)); 0; })
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  ({ tcbhead_t *__tcbp;							      \
+     __asm __volatile ("stc gbr,%0" : "=r" (__tcbp));			      \
+     __tcbp->dtv;})
+
+/* Return the thread descriptor for the current thread.  */
+#  undef THREAD_SELF
+#  define THREAD_SELF \
+  ({ struct _pthread_descr_struct *__self;				      \
+     __asm ("stc gbr,%0" : "=r" (__self));				      \
+     __self - 1;})
+
+#  undef INIT_THREAD_SELF
+#  define INIT_THREAD_SELF(descr, nr) \
+  ({ struct _pthread_descr_struct *__self = (void *) descr;		      \
+     __asm __volatile ("ldc %0,gbr" : : "r" (__self + 1));		      \
+     0; })
+
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+
+/* Get the thread descriptor definition.  This must be after the
+   the definition of THREAD_SELF for TLS.  */
+#  include <linuxthreads/descr.h>
+
+# endif /* __ASSEMBLER__ */
+
+#else
+
+# ifndef __ASSEMBLER__
+
+typedef struct
+{
+  void *tcb;
+  dtv_t *dtv;
+  void *self;
+  int multiple_threads;
+} tcbhead_t;
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+#  define NONTLS_INIT_TP \
+  do { 									\
+    static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };	\
+    __asm __volatile ("ldc %0,gbr" : : "r" (&nontls_init_tp));	        \
+  } while (0)
+
+# endif /* __ASSEMBLER__ */
+
+#endif	/* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/sparc/Makefile b/linuxthreads/sysdeps/sparc/Makefile
new file mode 100644
index 0000000000..81bddf688c
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/sparc/sparc32/pspinlock.c b/linuxthreads/sysdeps/sparc/sparc32/pspinlock.c
new file mode 100644
index 0000000000..a67dbf901e
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc32/pspinlock.c
@@ -0,0 +1,88 @@
+/* POSIX spinlock implementation.  SPARC32 version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+/* This implementation is similar to the one used in the Linux kernel.  */
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("1: ldstub [%0], %%g2\n"
+     "   orcc   %%g2, 0x0, %%g0\n"
+     "   bne,a  2f\n"
+     "   ldub   [%0], %%g2\n"
+     ".subsection 2\n"
+     "2: orcc   %%g2, 0x0, %%g0\n"
+     "   bne,a  2b\n"
+     "   ldub   [%0], %%g2\n"
+     "   b,a    1b\n"
+     ".previous"
+     : /* no outputs */
+     : "r" (lock)
+     : "g2", "memory", "cc");
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int result;
+  asm volatile
+    ("ldstub [%1], %0"
+     : "=r" (result)
+     : "r" (lock)
+     : "memory");
+  return result == 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h b/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h
new file mode 100644
index 0000000000..322a52051f
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc32/pt-machine.h
@@ -0,0 +1,83 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   sparc version.
+   Copyright (C) 1996-1998, 2000-2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  int ret;
+
+  __asm__ __volatile__("ldstub %1,%0"
+	: "=r"(ret), "=m"(*spinlock)
+	: "m"(*spinlock));
+
+  return ret;
+}
+
+
+/* Memory barrier; default is to do nothing */
+#define MEMORY_BARRIER() __asm__ __volatile__("stbar" : : : "memory")
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  (stack_pointer + (2 * 64))
+register char *stack_pointer __asm__("%sp");
+
+
+/* Registers %g6 and %g7 are reserved by the ABI for "system use".
+   %g7 is specified in the TLS ABI as thread pointer -- we do the same.  */
+struct _pthread_descr_struct;
+register struct _pthread_descr_struct *__thread_self __asm__("%g7");
+
+/* Return the thread descriptor for the current thread.  */
+#define THREAD_SELF  __thread_self
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr))
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     8*1024*1024
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/sparc/sparc32/sparcv9/Versions b/linuxthreads/sysdeps/sparc/sparc32/sparcv9/Versions
new file mode 100644
index 0000000000..32da57080d
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc32/sparcv9/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_PRIVATE {
+    __pthread_clock_gettime; __pthread_clock_settime;
+  }
+}
diff --git a/linuxthreads/sysdeps/sparc/sparc32/sparcv9/pspinlock.c b/linuxthreads/sysdeps/sparc/sparc32/sparcv9/pspinlock.c
new file mode 100644
index 0000000000..04f588bed5
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc32/sparcv9/pspinlock.c
@@ -0,0 +1,94 @@
+/* POSIX spinlock implementation.  SPARC v9 version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+
+/* This implementation is similar to the one used in the Linux kernel.  */
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("1: ldstub  [%0], %%g2\n"
+     "   brnz,pn %%g2, 2f\n"
+     "    membar #StoreLoad | #StoreStore\n"
+     ".subsection 2\n"
+     "2: ldub    [%0], %%g2\n"
+     "   brnz,pt %%g2, 2b\n"
+     "    membar #LoadLoad\n"
+     "   b,a,pt  %%xcc, 1b\n"
+     ".previous"
+     : /* no outputs */
+     : "r" (lock)
+     : "g2", "memory");
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int result;
+  asm volatile
+    ("ldstub [%1], %0\n"
+     "membar #StoreLoad | #StoreStore"
+     : "=r" (result)
+     : "r" (lock)
+     : "memory");
+  return result == 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("membar #StoreStore | #LoadStore\n"
+     "stb    %%g0, [%0]"
+     :
+     : "r" (lock)
+     : "memory");
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/sparc/sparc64/Versions b/linuxthreads/sysdeps/sparc/sparc64/Versions
new file mode 100644
index 0000000000..32da57080d
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc64/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_PRIVATE {
+    __pthread_clock_gettime; __pthread_clock_settime;
+  }
+}
diff --git a/linuxthreads/sysdeps/sparc/sparc64/pspinlock.c b/linuxthreads/sysdeps/sparc/sparc64/pspinlock.c
new file mode 100644
index 0000000000..92b84f5108
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc64/pspinlock.c
@@ -0,0 +1,93 @@
+/* POSIX spinlock implementation.  SPARC64 version.
+   Copyright (C) 2000 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; 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+/* This implementation is similar to the one used in the Linux kernel.  */
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("1: ldstub  [%0], %%g5\n"
+     "   brnz,pn %%g5, 2f\n"
+     "    membar #StoreLoad | #StoreStore\n"
+     ".subsection 2\n"
+     "2: ldub    [%0], %%g5\n"
+     "   brnz,pt %%g5, 2b\n"
+     "    membar #LoadLoad\n"
+     "   b,a,pt  %%xcc, 1b\n"
+     ".previous"
+     : /* no outputs */
+     : "r" (lock)
+     : "g5", "memory");
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int result;
+  asm volatile
+    ("ldstub [%1], %0\n"
+     "membar #StoreLoad | #StoreStore"
+     : "=r" (result)
+     : "r" (lock)
+     : "memory");
+  return result == 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("membar #StoreStore | #LoadStore\n"
+     "stb    %%g0, [%0]"
+     :
+     : "r" (lock)
+     : "memory");
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 0;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h b/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h
new file mode 100644
index 0000000000..f65c13be1b
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/sparc64/pt-machine.h
@@ -0,0 +1,105 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   Sparc v9 version.
+   Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson <rth@tamu.edu>.
+
+   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.  */
+
+#ifndef _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef PT_EI
+# define PT_EI extern inline __attribute__ ((always_inline))
+#endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  int ret;
+
+  __asm__ __volatile__("ldstub %1,%0"
+	: "=r" (ret), "=m" (*spinlock) : "m" (*spinlock));
+
+  return ret;
+}
+
+
+/* Memory barrier; default is to do nothing */
+#define MEMORY_BARRIER() \
+     __asm__ __volatile__("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore" : : : "memory")
+/* Read barrier.  */
+#define READ_MEMORY_BARRIER() \
+     __asm__ __volatile__("membar #LoadLoad | #LoadStore" : : : "memory")
+/* Write barrier.  */
+#define WRITE_MEMORY_BARRIER() \
+     __asm__ __volatile__("membar #StoreLoad | #StoreStore" : : : "memory")
+
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#define CURRENT_STACK_FRAME  (stack_pointer + (2 * 128))
+register char *stack_pointer __asm__ ("%sp");
+
+
+/* Registers %g6 and %g7 are reserved by the ABI for "system use".  The
+   TLS ABI specifies %g7 as the thread pointer.  */
+struct _pthread_descr_struct;
+register struct _pthread_descr_struct *__thread_self __asm__ ("%g7");
+
+/* Return the thread descriptor for the current thread.  */
+#define THREAD_SELF  __thread_self
+
+/* Initialize the thread-unique value.  */
+#define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr))
+
+
+/* Compare-and-swap for semaphores. */
+
+#define HAS_COMPARE_AND_SWAP
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  long int readval;
+
+  __asm__ __volatile__ ("casx	[%4], %2, %0"
+			: "=r"(readval), "=m"(*p)
+			: "r"(oldval), "m"(*p), "r"(p), "0"(newval));
+  MEMORY_BARRIER();
+  return readval == oldval;
+}
+
+/* Access to data in the thread descriptor is easy.  */
+#define THREAD_GETMEM(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_GETMEM_NC(descr, member) \
+  ((void) sizeof (descr), THREAD_SELF->member)
+#define THREAD_SETMEM(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+#define THREAD_SETMEM_NC(descr, member, value) \
+  ((void) sizeof (descr), THREAD_SELF->member = (value))
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS 1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE     32*1024*1024
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/sparc/tcb-offsets.sym b/linuxthreads/sysdeps/sparc/tcb-offsets.sym
new file mode 100644
index 0000000000..aee6be2570
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/tcb-offsets.sym
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
diff --git a/linuxthreads/sysdeps/sparc/tls.h b/linuxthreads/sysdeps/sparc/tls.h
new file mode 100644
index 0000000000..6b1966fe1c
--- /dev/null
+++ b/linuxthreads/sysdeps/sparc/tls.h
@@ -0,0 +1,110 @@
+/* Definitions for thread-local data handling.  linuxthreads/sparc 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+typedef struct
+{
+  void *tcb;		/* Pointer to the TCB.  Not necessary the
+			   thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;		/* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+#ifdef HAVE_TLS_SUPPORT
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+/* Get system call information.  */
+#  include <sysdep.h>
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+#  define TLS_TCB_AT_TP	1
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(descr, dtvp) \
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(DTV) \
+  (((tcbhead_t *) __thread_self)->dtv = (DTV))
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+/* Code to initially initialize the thread pointer.  */
+# define TLS_INIT_TP(descr, secondcall) \
+  (__thread_self = (__typeof (__thread_self)) (descr), NULL)
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  (((tcbhead_t *) __thread_self)->dtv)
+
+# endif
+
+#else
+
+# define NONTLS_INIT_TP \
+  do {									      \
+    static const tcbhead_t nontls_init_tp				      \
+      = { .multiple_threads = 0 };					      \
+    __thread_self = (__typeof (__thread_self)) &nontls_init_tp;		      \
+  } while (0)
+
+#endif /* USE_TLS */
+
+#endif	/* tls.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/Implies b/linuxthreads/sysdeps/unix/sysv/linux/Implies
new file mode 100644
index 0000000000..f1b3e8939c
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/Implies
@@ -0,0 +1 @@
+pthread
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/Makefile
new file mode 100644
index 0000000000..38c6cbc1af
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),linuxthreads)
+sysdep_routines += register-atfork unregister-atfork
+endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/Versions b/linuxthreads/sysdeps/unix/sysv/linux/Versions
new file mode 100644
index 0000000000..6cd3dbe372
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/Versions
@@ -0,0 +1,5 @@
+libc {
+  GLIBC_2.3.2 {
+    __register_atfork;
+  }
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h b/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h
new file mode 100644
index 0000000000..f62f7d6e9f
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h
@@ -0,0 +1,26 @@
+/* Determine whether block of given size can be allocated on the stack or not.
+   Copyright (C) 2002 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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 <limits.h>
+
+extern inline int __libc_use_alloca (size_t size)
+{
+  return (__builtin_expect (size <= PTHREAD_STACK_MIN / 4, 1)
+	  || __libc_alloca_cutoff (size));
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c b/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c
new file mode 100644
index 0000000000..af1581a4c3
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c
@@ -0,0 +1,87 @@
+/* Handle real-time signal allocation.
+   Copyright (C) 1997,98,99,2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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 <signal.h>
+
+/* Sanity check.  */
+#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3
+# error "This must not happen"
+#endif
+
+static int current_rtmin;
+static int current_rtmax;
+
+static int initialized;
+
+#include <testrtsig.h>
+
+static void
+init (void)
+{
+  if (!kernel_has_rtsig ())
+    {
+      current_rtmin = -1;
+      current_rtmax = -1;
+    }
+  else
+    {
+      current_rtmin = __SIGRTMIN + 3;
+      current_rtmax = __SIGRTMAX;
+    }
+  initialized = 1;
+}
+
+/* Return number of available real-time signal with highest priority.  */
+int
+__libc_current_sigrtmin (void)
+{
+  if (!initialized)
+    init ();
+  return current_rtmin;
+}
+strong_alias (__libc_current_sigrtmin, __libc_current_sigrtmin_private);
+libc_hidden_def (__libc_current_sigrtmin)
+
+/* Return number of available real-time signal with lowest priority.  */
+int
+__libc_current_sigrtmax (void)
+{
+  if (!initialized)
+    init ();
+  return current_rtmax;
+}
+strong_alias (__libc_current_sigrtmax, __libc_current_sigrtmax_private);
+libc_hidden_def (__libc_current_sigrtmax)
+
+/* Allocate real-time signal with highest/lowest available
+   priority.  Please note that we don't use a lock since we assume
+   this function to be called at program start.  */
+int
+__libc_allocate_rtsig (int high)
+{
+  if (!initialized)
+    init ();
+  if (current_rtmin == -1 || current_rtmin > current_rtmax)
+    /* We don't have anymore signal available.  */
+    return -1;
+
+  return high ? current_rtmin++ : current_rtmax--;
+}
+strong_alias (__libc_allocate_rtsig, __libc_allocate_rtsig_private);
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile
new file mode 100644
index 0000000000..e03aee99fc
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),linuxthreads)
+libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask
+endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions
new file mode 100644
index 0000000000..d102772482
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/Versions
@@ -0,0 +1,6 @@
+libpthread {
+  GLIBC_2.3.3 {
+    # Changed PTHREAD_STACK_MIN.
+    pthread_attr_setstack; pthread_attr_setstacksize;
+  }
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c b/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c
new file mode 100644
index 0000000000..0d6da82919
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/aio_cancel.c
@@ -0,0 +1,33 @@
+#include <shlib-compat.h>
+
+#define aio_cancel64 XXX
+#include <aio.h>
+#undef aio_cancel64
+#include <errno.h>
+
+extern __typeof (aio_cancel) __new_aio_cancel;
+extern __typeof (aio_cancel) __old_aio_cancel;
+
+#define aio_cancel	__new_aio_cancel
+
+#include <sysdeps/pthread/aio_cancel.c>
+
+#undef aio_cancel
+strong_alias (__new_aio_cancel, __new_aio_cancel64);
+versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3);
+versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3);
+
+#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3)
+
+#undef ECANCELED
+#define aio_cancel	__old_aio_cancel
+#define ECANCELED	125
+
+#include <sysdeps/pthread/aio_cancel.c>
+
+#undef aio_cancel
+strong_alias (__old_aio_cancel, __old_aio_cancel64);
+compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1);
+compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1);
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
new file mode 100644
index 0000000000..96893c59da
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/local_lim.h
@@ -0,0 +1,92 @@
+/* Minimum guaranteed maximum values for system limits.  Linux/Alpha version.
+   Copyright (C) 1993-1998,2000,2002,2003,2004 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+   and defines LINK_MAX although filesystems have different maxima.  A
+   similar thing is true for OPEN_MAX: the limit can be changed at
+   runtime and therefore the macro must not be defined.  Remove this
+   after including the header if necessary.  */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information.  */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN?  */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX?  */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX?  */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* The number of data keys per process.  */
+#define _POSIX_THREAD_KEYS_MAX	128
+/* This is the value this implementation supports.  */
+#define PTHREAD_KEYS_MAX	1024
+
+/* Controlling the iterations of destructors for thread-specific data.  */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4
+/* Number of iterations this implementation does.  */
+#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process.  */
+#define _POSIX_THREAD_THREADS_MAX	64
+/* This is the value this implementation supports.  */
+#define PTHREAD_THREADS_MAX	16384
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+   priority level.  */
+#define AIO_PRIO_DELTA_MAX	20
+
+/* Minimum size for a thread.  We are free to choose a reasonable value.  */
+#define PTHREAD_STACK_MIN	24576
+
+/* Maximum number of POSIX timers available.  */
+#define TIMER_MAX	256
+
+/* Maximum number of timer expiration overruns.  */
+#define DELAYTIMER_MAX	2147483647
+
+/* Maximum tty name length.  */
+#define TTY_NAME_MAX		32
+
+/* Maximum login name length.  This is arbitrary.  */
+#define LOGIN_NAME_MAX		256
+
+/* Maximum host name length.  */
+#define HOST_NAME_MAX		64
+
+/* Maximum message queue priority level.  */
+#define MQ_PRIO_MAX		32768
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
new file mode 100644
index 0000000000..a2724885e2
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t.  Linux/Alpha 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 _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef	_BITS_TYPESIZES_H
+#define	_BITS_TYPESIZES_H	1
+
+/* See <bits/types.h> for the meaning of these macros.  This file exists so
+   that <bits/types.h> need not vary across different GNU platforms.  */
+
+#define __DEV_T_TYPE		__U64_TYPE
+#define __UID_T_TYPE		__U32_TYPE
+#define __GID_T_TYPE		__U32_TYPE
+#define __INO_T_TYPE		__U32_TYPE
+#define __INO64_T_TYPE		__U64_TYPE
+#define __MODE_T_TYPE		__U32_TYPE
+#define __NLINK_T_TYPE		__U32_TYPE
+#define __OFF_T_TYPE		__SLONGWORD_TYPE
+#define __OFF64_T_TYPE		__S64_TYPE
+#define __PID_T_TYPE		__S32_TYPE
+#define __RLIM_T_TYPE		__ULONGWORD_TYPE
+#define __RLIM64_T_TYPE		__U64_TYPE
+#define	__BLKCNT_T_TYPE		__U32_TYPE
+#define	__BLKCNT64_T_TYPE	__U64_TYPE
+#define	__FSBLKCNT_T_TYPE	__S32_TYPE
+#define	__FSBLKCNT64_T_TYPE	__S64_TYPE
+#define	__FSFILCNT_T_TYPE	__U32_TYPE
+#define	__FSFILCNT64_T_TYPE	__U64_TYPE
+#define	__ID_T_TYPE		__U32_TYPE
+#define __CLOCK_T_TYPE		__SLONGWORD_TYPE
+#define __TIME_T_TYPE		__SLONGWORD_TYPE
+#define __USECONDS_T_TYPE	__U32_TYPE
+#define __SUSECONDS_T_TYPE	__S64_TYPE
+#define __DADDR_T_TYPE		__S32_TYPE
+#define __SWBLK_T_TYPE		__SLONGWORD_TYPE
+#define __KEY_T_TYPE		__S32_TYPE
+#define __CLOCKID_T_TYPE	__S32_TYPE
+#define __TIMER_T_TYPE		__S32_TYPE
+#define __BLKSIZE_T_TYPE	__U32_TYPE
+#define __FSID_T_TYPE		struct { int __val[2]; }
+#define __SSIZE_T_TYPE		__SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'.  */
+#define	__FD_SETSIZE		1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S b/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S
new file mode 100644
index 0000000000..91e5c86782
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/pt-sigsuspend.S
@@ -0,0 +1,28 @@
+/* Internal sigsuspend system call for LinuxThreads.  Alpha version.
+   Copyright (C) 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 <sysdep.h>
+
+#undef PSEUDO_PREPARE_ARGS
+#define PSEUDO_PREPARE_ARGS	ldq	a0, 0(a0);
+
+	.hidden __pthread_sigsuspend
+PSEUDO_NOERRNO(__pthread_sigsuspend, sigsuspend, 1)
+	ret
+PSEUDO_END_NOERRNO(__pthread_sigsuspend)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
new file mode 100644
index 0000000000..9ea779e0d5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
@@ -0,0 +1,146 @@
+/* Copyright (C) 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 <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# ifdef PROF
+#  define PSEUDO_PROF				\
+	.set noat;				\
+	lda	AT, _mcount;			\
+	jsr	AT, (AT), _mcount;		\
+	.set at
+# else
+#  define PSEUDO_PROF
+# endif
+
+/* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
+   besides "ret".  */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)			\
+	.globl name;						\
+	.align 4;						\
+	.type name, @function;					\
+	.usepv name, std;					\
+	cfi_startproc;						\
+__LABEL(name)							\
+	ldgp	gp, 0(pv);					\
+	PSEUDO_PROF;						\
+	PSEUDO_PREPARE_ARGS					\
+	SINGLE_THREAD_P(t0);					\
+	bne	t0, $pseudo_cancel;				\
+	lda	v0, SYS_ify(syscall_name);			\
+	call_pal PAL_callsys;					\
+	bne	a3, SYSCALL_ERROR_LABEL;			\
+__LABEL($pseudo_ret)						\
+	.subsection 2;						\
+__LABEL($pseudo_cancel)						\
+	subq	sp, 64, sp;					\
+	cfi_def_cfa_offset(64);					\
+	stq	ra, 0(sp);					\
+	cfi_offset(ra, -64);					\
+	SAVE_ARGS_##args;					\
+	CENABLE;						\
+	LOAD_ARGS_##args;					\
+	lda	v0, SYS_ify(syscall_name);			\
+	call_pal PAL_callsys;					\
+	stq	v0, 8(sp);					\
+	bne	a3, $multi_error;				\
+	CDISABLE;						\
+	ldq	ra, 0(sp);					\
+	ldq	v0, 8(sp);					\
+	addq	sp, 64, sp;					\
+	cfi_remember_state;					\
+	cfi_restore(ra);					\
+	cfi_def_cfa_offset(0);					\
+	ret;							\
+	cfi_restore_state;					\
+__LABEL($multi_error)						\
+	CDISABLE;						\
+	ldq	ra, 0(sp);					\
+	ldq	v0, 8(sp);					\
+	addq	sp, 64, sp;					\
+	cfi_restore(ra);					\
+	cfi_def_cfa_offset(0);					\
+__LABEL($syscall_error)						\
+	SYSCALL_ERROR_HANDLER;					\
+	.previous
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym)					\
+	.subsection 2;						\
+	cfi_endproc;						\
+	.size sym, .-sym
+
+# define SAVE_ARGS_0	/* Nothing.  */
+# define SAVE_ARGS_1	SAVE_ARGS_0; stq a0, 8(sp)
+# define SAVE_ARGS_2	SAVE_ARGS_1; stq a1, 16(sp)
+# define SAVE_ARGS_3	SAVE_ARGS_2; stq a2, 24(sp)
+# define SAVE_ARGS_4	SAVE_ARGS_3; stq a3, 32(sp)
+# define SAVE_ARGS_5	SAVE_ARGS_4; stq a4, 40(sp)
+# define SAVE_ARGS_6	SAVE_ARGS_5; stq a5, 48(sp)
+
+# define LOAD_ARGS_0	/* Nothing.  */
+# define LOAD_ARGS_1	LOAD_ARGS_0; ldq a0, 8(sp)
+# define LOAD_ARGS_2	LOAD_ARGS_1; ldq a1, 16(sp)
+# define LOAD_ARGS_3	LOAD_ARGS_2; ldq a2, 24(sp)
+# define LOAD_ARGS_4	LOAD_ARGS_3; ldq a3, 32(sp)
+# define LOAD_ARGS_5	LOAD_ARGS_4; ldq a4, 40(sp)
+# define LOAD_ARGS_6	LOAD_ARGS_5; ldq a5, 48(sp)
+
+# ifdef IS_IN_libpthread
+#  define __local_enable_asynccancel	__pthread_enable_asynccancel
+#  define __local_disable_asynccancel	__pthread_disable_asynccancel
+#  define __local_multiple_threads	__pthread_multiple_threads
+# else
+#  define __local_enable_asynccancel	__libc_enable_asynccancel
+#  define __local_disable_asynccancel	__libc_disable_asynccancel
+#  define __local_multiple_threads	__libc_multiple_threads
+# endif
+
+# ifdef PIC
+#  define CENABLE	bsr ra, __local_enable_asynccancel !samegp
+#  define CDISABLE	bsr ra, __local_disable_asynccancel !samegp
+# else
+#  define CENABLE	jsr ra, __local_enable_asynccancel; ldgp ra, 0(gp)
+#  define CDISABLE	jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp)
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P \
+  __builtin_expect (__local_multiple_threads == 0, 1)
+# elif defined(PIC)
+#  define SINGLE_THREAD_P(reg)  ldl reg, __local_multiple_threads(gp) !gprel
+# else
+#  define SINGLE_THREAD_P(reg)					\
+	ldah	reg, __local_multiple_threads(gp) !gprelhigh;	\
+	ldl	reg, __local_multiple_threads(reg) !gprellow
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S
new file mode 100644
index 0000000000..cfaae10606
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/alpha/vfork.S
@@ -0,0 +1,70 @@
+/* Copyright (C) 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 <sysdep-cancel.h>
+
+        .align 4
+	.globl	__vfork
+	.type	__vfork, @function
+	.usepv	__vfork, std
+	cfi_startproc
+__vfork:
+	ldgp	gp, 0(pv)
+	PSEUDO_PROF
+
+#ifdef SHARED
+	ldq	t0, __libc_pthread_functions(gp) !gprel
+	bne	t0, HIDDEN_JUMPTARGET (__fork) !samegp
+#else
+	.weak	pthread_create
+	ldq	t0, pthread_create(gp) !literal
+	bne	t0, $do_fork
+#endif
+
+	lda	v0, SYS_ify(vfork)
+	call_pal PAL_callsys
+	bne	a3, SYSCALL_ERROR_LABEL
+	ret
+
+#ifndef SHARED
+	/* Can't tail-call due to possible mismatch between GP in
+	   fork and vfork object files.  */
+$do_fork:
+	subq	sp, 16, sp
+	cfi_adjust_cfa_offset(16)
+	stq	ra, 0(sp)
+	cfi_offset(ra, -16)
+	jsr	ra, HIDDEN_JUMPTARGET (__fork)
+	ldgp	gp, 0(ra)
+	ldq	ra, 0(sp)
+	addq	sp, 16, sp
+	cfi_restore(ra)
+	cfi_adjust_cfa_offset(-16)
+	ret
+
+$syscall_error:
+	SYSCALL_ERROR_HANDLER
+#endif
+
+	cfi_endproc
+	.size __vfork, .-__vfork
+
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
new file mode 100644
index 0000000000..019bd54913
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/sysdep-cancel.h
@@ -0,0 +1,145 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Phil Blundell <pb@nexus.co.uk>, 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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+/* We push lr onto the stack, so we have to use ldmib instead of ldmia
+   to find the saved arguments.  */
+# ifdef PIC
+#  undef DOARGS_5
+#  undef DOARGS_6
+#  undef DOARGS_7
+#  define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8];
+#  define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5};
+#  define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6};
+# endif
+
+# undef PSEUDO_RET
+# define PSEUDO_RET						        \
+    ldrcc pc, [sp], $4;						        \
+    ldr	lr, [sp], $4;							\
+    b PLTJMP(SYSCALL_ERROR)
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  .section ".text";							\
+    PSEUDO_PROLOGUE;							\
+  ENTRY (name);								\
+    SINGLE_THREAD_P_INT;						\
+    bne .Lpseudo_cancel;						\
+    DO_CALL (syscall_name, args);					\
+    cmn r0, $4096;							\
+    PSEUDO_RET_MOV;							\
+  .Lpseudo_cancel:							\
+    MAYBE_SAVE_LR;							\
+    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+    CENABLE;								\
+    mov ip, r0;		/* put mask in safe place.  */			\
+    UNDOCARGS_##args;	/* restore syscall args.  */			\
+    swi SYS_ify (syscall_name);	/* do the call.  */			\
+    str r0, [sp, $-4]!; /* save syscall return value.  */		\
+    mov r0, ip;		/* get mask back.  */				\
+    CDISABLE;								\
+    ldr r0, [sp], $4;	/* retrieve return value.  */			\
+    UNDOC2ARGS_##args;	/* fix register damage.  */			\
+    cmn r0, $4096;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+# define UNDOC2ARGS_0
+
+# define DOCARGS_1	str r0, [sp, #-4]!;
+# define UNDOCARGS_1	ldr r0, [sp], #4;
+# define UNDOC2ARGS_1
+
+# define DOCARGS_2	str r1, [sp, #-4]!; str r0, [sp, #-4]!;
+# define UNDOCARGS_2	ldr r0, [sp], #4; ldr r1, [sp], #4;
+# define UNDOC2ARGS_2
+
+# define DOCARGS_3	str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!;
+# define UNDOCARGS_3	ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4
+# define UNDOC2ARGS_3
+
+# define DOCARGS_4	stmfd sp!, {r0-r3}
+# define UNDOCARGS_4	ldmfd sp!, {r0-r3}
+# define UNDOC2ARGS_4
+
+# define DOCARGS_5	stmfd sp!, {r0-r3}
+# define UNDOCARGS_5	ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]
+# define UNDOC2ARGS_5   ldr r4, [sp], #20
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	bl PLTJMP(__pthread_enable_asynccancel)
+#  define CDISABLE	bl PLTJMP(__pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# else
+#  define CENABLE	bl PLTJMP(__libc_enable_asynccancel)
+#  define CDISABLE	bl PLTJMP(__libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P_INT						\
+  ldr ip, =__local_multiple_threads;					\
+  ldr ip, [ip];								\
+  teq ip, #0;
+#   define SINGLE_THREAD_P SINGLE_THREAD_P_INT
+#   define MAYBE_SAVE_LR						\
+  str lr, [sp, $-4]!;
+#   define PSEUDO_RET_MOV						\
+  RETINSTR(cc, lr);							\
+  b PLTJMP(SYSCALL_ERROR)
+#   define PSEUDO_PROLOGUE
+#  else
+#   define SINGLE_THREAD_P_PIC(reg)					\
+  ldr ip, 1b;								\
+  ldr reg, 2b;								\
+3:									\
+  add ip, pc, ip;							\
+  ldr ip, [ip, reg];							\
+  teq ip, #0;
+#   define SINGLE_THREAD_P_INT						\
+  str lr, [sp, $-4]!;							\
+  SINGLE_THREAD_P_PIC(lr)
+#   define SINGLE_THREAD_P						\
+  SINGLE_THREAD_P_INT;							\
+  ldr lr, [sp], $4
+#   define PSEUDO_PROLOGUE						\
+  1:  .word _GLOBAL_OFFSET_TABLE_ - 3f - 8;				\
+  2:  .word __local_multiple_threads(GOTOFF);
+#   define MAYBE_SAVE_LR	/* lr already saved */
+#   define PSEUDO_RET_MOV PSEUDO_RET
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
new file mode 100644
index 0000000000..2708c701eb
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S
@@ -0,0 +1,80 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Philip Blundell <philb@gnu.org>.
+
+   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-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+	PSEUDO_PROLOGUE
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+
+#ifdef SHARED
+	ldr	ip, 1f
+	ldr	r0, 2f
+3:	add	ip, pc, ip
+	ldr	r0, [ip, r0]
+#else
+	ldr	r0, 1f
+#endif
+	movs	r0, r0
+	bne	HIDDEN_JUMPTARGET (__fork)
+		
+	swi	__NR_vfork
+	cmn	a1, #4096
+	RETINSTR(cc, lr)
+
+#ifndef __ASSUME_VFORK_SYSCALL
+	/* Check if vfork syscall is known at all.  */
+	cmn	a1, #ENOSYS
+	bne	PLTJMP(C_SYMBOL_NAME(__syscall_error))
+#endif
+
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+	/* If we don't have vfork, fork is close enough.  */
+	swi	__NR_fork
+	cmn	a1, #4096
+	RETINSTR(cc, lr)
+#elif !defined __NR_vfork
+# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
+#endif
+    	b	PLTJMP(C_SYMBOL_NAME(__syscall_error))
+
+#ifdef SHARED
+1:	.word	_GLOBAL_OFFSET_TABLE_ - 3b - 8
+2:	.word	__libc_pthread_functions(GOTOFF)
+#else
+	.weak	pthread_create
+1:	.word	pthread_create
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h
new file mode 100644
index 0000000000..ed6c3c589b
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/bits/local_lim.h
@@ -0,0 +1,92 @@
+/* Minimum guaranteed maximum values for system limits.  Linux version.
+   Copyright (C) 1993-1998,2000,2002,2003,2004 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+   and defines LINK_MAX although filesystems have different maxima.  A
+   similar thing is true for OPEN_MAX: the limit can be changed at
+   runtime and therefore the macro must not be defined.  Remove this
+   after including the header if necessary.  */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information.  */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN?  */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX?  */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX?  */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* The number of data keys per process.  */
+#define _POSIX_THREAD_KEYS_MAX	128
+/* This is the value this implementation supports.  */
+#define PTHREAD_KEYS_MAX	1024
+
+/* Controlling the iterations of destructors for thread-specific data.  */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4
+/* Number of iterations this implementation does.  */
+#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process.  */
+#define _POSIX_THREAD_THREADS_MAX	64
+/* This is the value this implementation supports.  */
+#define PTHREAD_THREADS_MAX	16384
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+   priority level.  */
+#define AIO_PRIO_DELTA_MAX	20
+
+/* Minimum size for a thread.  We are free to choose a reasonable value.  */
+#define PTHREAD_STACK_MIN	16384
+
+/* Maximum number of POSIX timers available.  */
+#define TIMER_MAX	256
+
+/* Maximum number of timer expiration overruns.  */
+#define DELAYTIMER_MAX	2147483647
+
+/* Maximum tty name length.  */
+#define TTY_NAME_MAX		32
+
+/* Maximum login name length.  This is arbitrary.  */
+#define LOGIN_NAME_MAX		256
+
+/* Maximum host name length.  */
+#define HOST_NAME_MAX		64
+
+/* Maximum message queue priority level.  */
+#define MQ_PRIO_MAX		32768
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h b/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h
new file mode 100644
index 0000000000..71b7e74649
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/bits/posix_opt.h
@@ -0,0 +1,181 @@
+/* Define POSIX options for Linux.
+   Copyright (C) 1996-2001, 2002, 2003, 2004 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef	_POSIX_OPT_H
+#define	_POSIX_OPT_H	1
+
+/* Job control is supported.  */
+#define	_POSIX_JOB_CONTROL	1
+
+/* Processes have a saved set-user-ID and a saved set-group-ID.  */
+#define	_POSIX_SAVED_IDS	1
+
+/* Priority scheduling is supported.  */
+#define	_POSIX_PRIORITY_SCHEDULING	200112L
+
+/* Synchronizing file data is supported.  */
+#define	_POSIX_SYNCHRONIZED_IO	200112L
+
+/* The fsync function is present.  */
+#define	_POSIX_FSYNC	200112L
+
+/* Mapping of files to memory is supported.  */
+#define	_POSIX_MAPPED_FILES	200112L
+
+/* Locking of all memory is supported.  */
+#define	_POSIX_MEMLOCK	200112L
+
+/* Locking of ranges of memory is supported.  */
+#define	_POSIX_MEMLOCK_RANGE	200112L
+
+/* Setting of memory protections is supported.  */
+#define	_POSIX_MEMORY_PROTECTION	200112L
+
+/* Only root can change owner of file.  */
+#define	_POSIX_CHOWN_RESTRICTED	1
+
+/* `c_cc' member of 'struct termios' structure can be disabled by
+   using the value _POSIX_VDISABLE.  */
+#define	_POSIX_VDISABLE	'\0'
+
+/* Filenames are not silently truncated.  */
+#define	_POSIX_NO_TRUNC	1
+
+/* X/Open realtime support is available.  */
+#define _XOPEN_REALTIME	1
+
+/* X/Open realtime thread support is available.  */
+#define _XOPEN_REALTIME_THREADS	1
+
+/* XPG4.2 shared memory is supported.  */
+#define	_XOPEN_SHM	1
+
+/* Tell we have POSIX threads.  */
+#define _POSIX_THREADS	200112L
+
+/* We have the reentrant functions described in POSIX.  */
+#define _POSIX_REENTRANT_FUNCTIONS      1
+#define _POSIX_THREAD_SAFE_FUNCTIONS	200112L
+
+/* We provide priority scheduling for threads.  */
+#define	_POSIX_THREAD_PRIORITY_SCHEDULING	200112L
+
+/* We support user-defined stack sizes.  */
+#define _POSIX_THREAD_ATTR_STACKSIZE	200112L
+
+/* We support user-defined stacks.  */
+#define _POSIX_THREAD_ATTR_STACKADDR	200112L
+
+/* We support POSIX.1b semaphores, but only the non-shared form for now.  */
+#define _POSIX_SEMAPHORES	200112L
+
+/* Real-time signals are supported.  */
+#define _POSIX_REALTIME_SIGNALS	200112L
+
+/* We support asynchronous I/O.  */
+#define _POSIX_ASYNCHRONOUS_IO	200112L
+#define _POSIX_ASYNC_IO		1
+/* Alternative name for Unix98.  */
+#define _LFS_ASYNCHRONOUS_IO	1
+/* Support for prioritization is also available.  */
+#define _POSIX_PRIORITIZED_IO	200112L
+
+/* The LFS support in asynchronous I/O is also available.  */
+#define _LFS64_ASYNCHRONOUS_IO	1
+
+/* The rest of the LFS is also available.  */
+#define _LFS_LARGEFILE		1
+#define _LFS64_LARGEFILE	1
+#define _LFS64_STDIO		1
+
+/* POSIX shared memory objects are implemented.  */
+#define _POSIX_SHARED_MEMORY_OBJECTS	200112L
+
+/* CPU-time clocks support needs to be checked at runtime.  */
+#define _POSIX_CPUTIME	0
+
+/* Clock support in threads must be also checked at runtime.  */
+#define _POSIX_THREAD_CPUTIME	0
+
+/* GNU libc provides regular expression handling.  */
+#define _POSIX_REGEXP	1
+
+/* Reader/Writer locks are available.  */
+#define _POSIX_READER_WRITER_LOCKS	200112L
+
+/* We have a POSIX shell.  */
+#define _POSIX_SHELL	1
+
+/* We support the Timeouts option.  */
+#define _POSIX_TIMEOUTS	200112L
+
+/* We support spinlocks.  */
+#define _POSIX_SPIN_LOCKS	200112L
+
+/* The `spawn' function family is supported.  */
+#define _POSIX_SPAWN	200112L
+
+/* We have POSIX timers.  */
+#define _POSIX_TIMERS	200112L
+
+/* The barrier functions are available.  */
+#define _POSIX_BARRIERS	200112L
+
+/* POSIX message queues are available.  */
+#define	_POSIX_MESSAGE_PASSING	200112L
+
+/* Thread process-shared synchronization is not supported.  */
+#define _POSIX_THREAD_PROCESS_SHARED	-1
+
+/* The monotonic clock might be available.  */
+#define _POSIX_MONOTONIC_CLOCK	0
+
+/* The clock selection interfaces are not available.  */
+#define _POSIX_CLOCK_SELECTION	-1
+
+/* Advisory information interfaces are available.  */
+#define _POSIX_ADVISORY_INFO	200112L
+
+/* IPv6 support is available.  */
+#define _POSIX_IPV6	200112L
+
+/* Raw socket support is available.  */
+#define _POSIX_RAW_SOCKETS	200112L
+
+/* We have at least one terminal.  */
+#define _POSIX2_CHAR_TERM	200112L
+
+/* Neither process nor thread sporadic server interfaces is available.  */
+#define _POSIX_SPORADIC_SERVER	-1
+#define _POSIX_THREAD_SPORADIC_SERVER	-1
+
+/* trace.h is not available.  */
+#define _POSIX_TRACE	-1
+#define _POSIX_TRACE_EVENT_FILTER	-1
+#define _POSIX_TRACE_INHERIT	-1
+#define _POSIX_TRACE_LOG	-1
+
+/* Typed memory objects are not available.  */
+#define _POSIX_TYPED_MEMORY_OBJECTS	-1
+
+/* No support for priority inheritance or protection.  */
+#define _POSIX_THREAD_PRIO_INHERIT	-1
+#define _POSIX_THREAD_PRIO_PROTECT	-1
+
+#endif /* posix_opt.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h b/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h
new file mode 100644
index 0000000000..960bde18a9
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h
@@ -0,0 +1,38 @@
+/* Signal handling function for threaded programs.
+   Copyright (C) 1998, 1999, 2000, 2002 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _BITS_SIGTHREAD_H
+#define _BITS_SIGTHREAD_H	1
+
+#if !defined _SIGNAL_H && !defined _PTHREAD_H
+# error "Never include this file directly.  Use <pthread.h> instead"
+#endif
+
+/* Functions for handling signals. */
+
+/* Modify the signal mask for the calling thread.  The arguments have
+   the same meaning as for sigprocmask(2). */
+extern int pthread_sigmask (int __how,
+			    __const __sigset_t *__restrict __newmask,
+			    __sigset_t *__restrict __oldmask)__THROW;
+
+/* Send signal SIGNO to the given thread. */
+extern int pthread_kill (pthread_t __threadid, int __signo) __THROW;
+
+#endif	/* bits/sigthread.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/execve.c b/linuxthreads/sysdeps/unix/sysv/linux/execve.c
new file mode 100644
index 0000000000..9fa912b90d
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/execve.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 1999, 2000, 2002 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 <errno.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <alloca.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+extern int __syscall_execve (const char *__unbounded file,
+			     char *__unbounded const *__unbounded argv,
+			     char *__unbounded const *__unbounded envp);
+extern void __pthread_kill_other_threads_np (void);
+weak_extern (__pthread_kill_other_threads_np)
+
+
+int
+__execve (file, argv, envp)
+     const char *file;
+     char *const argv[];
+     char *const envp[];
+{
+  /* If this is a threaded application kill all other threads.  */
+  if (__pthread_kill_other_threads_np)
+    __pthread_kill_other_threads_np ();
+#if __BOUNDED_POINTERS__
+  {
+    char *const *v;
+    int i;
+    char *__unbounded *__unbounded ubp_argv;
+    char *__unbounded *__unbounded ubp_envp;
+    char *__unbounded *__unbounded ubp_v;
+
+    for (v = argv; *v; v++)
+      ;
+    i = v - argv + 1;
+    ubp_argv = (char *__unbounded *__unbounded) alloca (sizeof (*ubp_argv) * i);
+    for (v = argv, ubp_v = ubp_argv; --i; v++, ubp_v++)
+      *ubp_v = CHECK_STRING (*v);
+    *ubp_v = 0;
+
+    for (v = envp; *v; v++)
+      ;
+    i = v - envp + 1;
+    ubp_envp = (char *__unbounded *__unbounded) alloca (sizeof (*ubp_envp) * i);
+    for (v = envp, ubp_v = ubp_envp; --i; v++, ubp_v++)
+      *ubp_v = CHECK_STRING (*v);
+    *ubp_v = 0;
+
+    return INLINE_SYSCALL (execve, 3, CHECK_STRING (file), ubp_argv, ubp_envp);
+  }
+#else
+  return INLINE_SYSCALL (execve, 3, file, argv, envp);
+#endif
+}
+weak_alias (__execve, execve)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/fork.c b/linuxthreads/sysdeps/unix/sysv/linux/fork.c
new file mode 100644
index 0000000000..00eb787093
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/fork.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <errno.h>
+#include <fork.h>
+#include <bits/libc-lock.h>
+
+#ifndef SHARED
+weak_extern (__pthread_fork);
+#endif
+
+struct fork_block __fork_block =
+{
+  .lock = PTHREAD_MUTEX_INITIALIZER,
+  .prepare_list = { &__fork_block.prepare_list, &__fork_block.prepare_list },
+  .parent_list = { &__fork_block.parent_list, &__fork_block.parent_list },
+  .child_list = { &__fork_block.child_list, &__fork_block.child_list }
+};
+
+pid_t
+__libc_fork (void)
+{
+  return __libc_maybe_call2 (pthread_fork, (&__fork_block), ARCH_FORK ());
+}
+weak_alias (__libc_fork, __fork)
+libc_hidden_def (__fork)
+weak_alias (__libc_fork, fork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/fork.h b/linuxthreads/sysdeps/unix/sysv/linux/fork.h
new file mode 100644
index 0000000000..76708e3e39
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/fork.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2002 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 <list.h>
+#include <bits/libc-lock.h>
+#include <sysdep.h>
+
+struct fork_block
+{
+  /* Lock to protect handling of fork handlers.  */
+  __libc_lock_define (, lock);
+
+  /* Lists of registered fork handlers.  */
+  list_t prepare_list;
+  list_t parent_list;
+  list_t child_list;
+};
+
+extern struct fork_block __fork_block attribute_hidden;
+
+/* Elements of the fork handler lists.  */
+struct fork_handler
+{
+  list_t list;
+  void (*handler) (void);
+  void *dso_handle;
+};
+
+
+/* Function to call to unregister fork handlers.  */
+extern void __unregister_atfork (void *dso_handle) attribute_hidden;
+#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
+
+
+/* C library side function to register new fork handlers.  */
+extern int __register_atfork (void (*__prepare) (void),
+			      void (*__parent) (void),
+			      void (*__child) (void),
+			      void *dso_handle);
+libc_hidden_proto (__register_atfork)
+
+#ifndef ARCH_FORK
+# define ARCH_FORK() INLINE_SYSCALL (fork, 0)
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c b/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c
new file mode 100644
index 0000000000..0d6da82919
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/aio_cancel.c
@@ -0,0 +1,33 @@
+#include <shlib-compat.h>
+
+#define aio_cancel64 XXX
+#include <aio.h>
+#undef aio_cancel64
+#include <errno.h>
+
+extern __typeof (aio_cancel) __new_aio_cancel;
+extern __typeof (aio_cancel) __old_aio_cancel;
+
+#define aio_cancel	__new_aio_cancel
+
+#include <sysdeps/pthread/aio_cancel.c>
+
+#undef aio_cancel
+strong_alias (__new_aio_cancel, __new_aio_cancel64);
+versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3);
+versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3);
+
+#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3)
+
+#undef ECANCELED
+#define aio_cancel	__old_aio_cancel
+#define ECANCELED	125
+
+#include <sysdeps/pthread/aio_cancel.c>
+
+#undef aio_cancel
+strong_alias (__old_aio_cancel, __old_aio_cancel64);
+compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1);
+compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1);
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h
new file mode 100644
index 0000000000..9b13400286
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h
@@ -0,0 +1,27 @@
+/* PA-RISC specific definitions for spinlock initializers.
+   Copyright (C) 2000, 2001 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Initial value of a spinlock.  PA-RISC only implements atomic load
+   and clear so this must be non-zero. */
+#define __LT_SPINLOCK_INIT 1
+
+/* Macros for lock initializers, using the above definition. */
+#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }
+#define __ALT_LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT }
+#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_INIT }
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h
new file mode 100644
index 0000000000..817cf59222
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/malloc-machine.h
@@ -0,0 +1,73 @@
+/* HP-PARISC macro definitions for mutexes, thread-specific data 
+   and parameters for malloc.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _MALLOC_MACHINE_H
+#define _MALLOC_MACHINE_H
+
+#undef thread_atfork_static
+
+#include <atomic.h>
+#include <bits/libc-lock.h>
+
+__libc_lock_define (typedef, mutex_t)
+
+/* Since our lock structure does not tolerate being initialized to zero, we must
+   modify the standard function calls made by malloc */
+#  define mutex_init(m)		\
+	__libc_maybe_call (__pthread_mutex_init, (m, NULL), \
+		(((m)->__m_lock.__spinlock = __LT_SPINLOCK_INIT),(*(int *)(m))) )
+#  define mutex_lock(m)		\
+	__libc_maybe_call (__pthread_mutex_lock, (m), \
+			(__load_and_clear(&((m)->__m_lock.__spinlock)), 0))
+#  define mutex_trylock(m)	\
+	__libc_maybe_call (__pthread_mutex_trylock, (m), \
+			(*(int *)(m) ? 1 : (__load_and_clear(&((m)->__m_lock.__spinlock)), 0)))
+#  define mutex_unlock(m)	\
+	__libc_maybe_call (__pthread_mutex_unlock, (m), \
+			(((m)->__m_lock.__spinlock = __LT_SPINLOCK_INIT), (*(int *)(m))) )
+	
+/* This is defined by newer gcc version unique for each module.  */
+extern void *__dso_handle __attribute__ ((__weak__));
+
+#include <fork.h>
+
+#ifdef SHARED
+# define thread_atfork(prepare, parent, child) \
+   __register_atfork (prepare, parent, child, __dso_handle)
+#else
+# define thread_atfork(prepare, parent, child) \
+   __register_atfork (prepare, parent, child,				      \
+		      &__dso_handle == NULL ? NULL : __dso_handle)
+#endif
+
+/* thread specific data for glibc */
+
+#include <bits/libc-tsd.h>
+
+typedef int tsd_key_t[1];	/* no key data structure, libc magic does it */
+__libc_tsd_define (static, MALLOC)	/* declaration/common definition */
+#define tsd_key_create(key, destr)	((void) (key))
+#define tsd_setspecific(key, data)	__libc_tsd_set (MALLOC, (data))
+#define tsd_getspecific(key, vptr)	((vptr) = __libc_tsd_get (MALLOC))
+
+#include <sysdeps/generic/malloc-machine.h>
+
+#endif /* !defined(_MALLOC_MACHINE_H) */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c
new file mode 100644
index 0000000000..27f850cf8f
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/pt-initfini.c
@@ -0,0 +1,109 @@
+/* Special .init and .fini section support for HPPA.  Linuxthreads version.
+   Copyright (C) 2001, 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+/* If we use the standard C version, the linkage table pointer won't
+   be properly preserved due to the splitting up of function prologues
+   and epilogues.  Therefore we write these in assembly to make sure
+   they do the right thing.  */
+
+__asm__ (
+"#include \"defs.h\"\n"
+"\n"
+"/*@HEADER_ENDS*/\n"
+"\n"
+"/*@_init_PROLOG_BEGINS*/\n"
+"	.section .init\n"
+"	.align 4\n"
+"	.globl _init\n"
+"	.type _init,@function\n"
+"_init:\n"
+"	stw	%rp,-20(%sp)\n"
+"	stwm	%r4,64(%sp)\n"
+"	stw	%r19,-32(%sp)\n"
+"	bl	__pthread_initialize_minimal,%rp\n"
+"	copy	%r19,%r4	/* delay slot */\n"
+"	copy	%r4,%r19\n"
+"/*@_init_PROLOG_ENDS*/\n"
+"\n"
+"/*@_init_EPILOG_BEGINS*/\n"
+"/* Here is the tail end of _init.  */\n"
+"	.section .init\n"
+"	ldw	-84(%sp),%rp\n"
+"	copy	%r4,%r19\n"
+"	bv	%r0(%rp)\n"
+"_end_init:\n"
+"	ldwm	-64(%sp),%r4\n"
+"\n"
+"/* Our very own unwind info, because the assembler can't handle\n"
+"   functions split into two or more pieces.  */\n"
+"	.section .PARISC.unwind,\"a\",@progbits\n"
+"	.extern _init\n"
+"	.word	_init, _end_init\n"
+"	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08\n"
+"\n"
+"/*@_init_EPILOG_ENDS*/\n"
+"\n"
+"/*@_fini_PROLOG_BEGINS*/\n"
+"	.section .fini\n"
+"	.align 4\n"
+"	.globl _fini\n"
+"	.type _fini,@function\n"
+"_fini:\n"
+"	stw	%rp,-20(%sp)\n"
+"	stwm	%r4,64(%sp)\n"
+"	stw	%r19,-32(%sp)\n"
+"	copy	%r19,%r4\n"
+"/*@_fini_PROLOG_ENDS*/\n"
+"\n"
+"/*@_fini_EPILOG_BEGINS*/\n"
+"	.section .fini\n"
+"	ldw	-84(%sp),%rp\n"
+"	copy	%r4,%r19\n"
+"	bv	%r0(%rp)\n"
+"_end_fini:\n"
+"	ldwm	-64(%sp),%r4\n"
+"\n"
+"	.section .PARISC.unwind,\"a\",@progbits\n"
+"	.extern _fini\n"
+"	.word	_fini, _end_fini\n"
+"	.byte	0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08\n"
+"\n"
+"/*@_fini_EPILOG_ENDS*/\n"
+"\n"
+"/*@TRAILER_BEGINS*/\n"
+);
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h
new file mode 100644
index 0000000000..134977e074
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h
@@ -0,0 +1,189 @@
+/* cancellable system calls for Linux/HPPA.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# ifndef NO_ERROR
+#  define NO_ERROR -0x1000
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  ENTRY (name)								\
+    SINGLE_THREAD_P					ASM_LINE_SEP	\
+    cmpib,<> 0,%ret0,Lpseudo_cancel			ASM_LINE_SEP	\
+    nop							ASM_LINE_SEP	\
+    DO_CALL(syscall_name, args)				ASM_LINE_SEP	\
+    /* DONE! */						ASM_LINE_SEP	\
+    bv 0(2)						ASM_LINE_SEP	\
+    nop							ASM_LINE_SEP	\
+  Lpseudo_cancel:					ASM_LINE_SEP	\
+    /* store return ptr */				ASM_LINE_SEP	\
+    stw %rp, -20(%sr0,%sp)				ASM_LINE_SEP	\
+    /* save syscall args */				ASM_LINE_SEP	\
+    PUSHARGS_##args /* MACRO */				ASM_LINE_SEP	\
+    STW_PIC						ASM_LINE_SEP	\
+    CENABLE /* FUNC CALL */				ASM_LINE_SEP	\
+    ldo 64(%sp), %sp					ASM_LINE_SEP	\
+    ldo -64(%sp), %sp					ASM_LINE_SEP	\
+    LDW_PIC						ASM_LINE_SEP	\
+    /* restore syscall args */				ASM_LINE_SEP	\
+    POPARGS_##args					ASM_LINE_SEP	\
+    /* save r4 in arg0 stack slot */			ASM_LINE_SEP	\
+    stw %r4, -36(%sr0,%sp)				ASM_LINE_SEP	\
+    /* save mask from cenable */			ASM_LINE_SEP	\
+    copy %ret0, %r4					ASM_LINE_SEP	\
+    ble 0x100(%sr2,%r0)					ASM_LINE_SEP    \
+    ldi SYS_ify (syscall_name), %r20			ASM_LINE_SEP	\
+    LDW_PIC						ASM_LINE_SEP	\
+    /* pass mask as arg0 to cdisable */			ASM_LINE_SEP	\
+    copy %r4, %r26					ASM_LINE_SEP	\
+    copy %ret0, %r4					ASM_LINE_SEP	\
+    CDISABLE						ASM_LINE_SEP	\
+    ldo 64(%sp), %sp					ASM_LINE_SEP	\
+    ldo -64(%sp), %sp					ASM_LINE_SEP	\
+    LDW_PIC						ASM_LINE_SEP	\
+    /* compare error */					ASM_LINE_SEP	\
+    ldi NO_ERROR,%r1					ASM_LINE_SEP	\
+    /* branch if no error */				ASM_LINE_SEP	\
+    cmpb,>>=,n %r1,%r4,Lpre_end				ASM_LINE_SEP	\
+    nop							ASM_LINE_SEP	\
+    SYSCALL_ERROR_HANDLER				ASM_LINE_SEP	\
+    ldo 64(%sp), %sp					ASM_LINE_SEP	\
+    ldo -64(%sp), %sp					ASM_LINE_SEP	\
+    /* No need to LDW_PIC */				ASM_LINE_SEP	\
+    /* make syscall res value positive */		ASM_LINE_SEP	\
+    sub %r0, %r4, %r4					ASM_LINE_SEP	\
+    /* store into errno location */			ASM_LINE_SEP	\
+    stw %r4, 0(%sr0,%ret0)				ASM_LINE_SEP	\
+    /* return -1 */					ASM_LINE_SEP	\
+    ldo -1(%r0), %ret0					ASM_LINE_SEP	\
+  Lpre_end:						ASM_LINE_SEP	\
+    ldw -20(%sr0,%sp), %rp             			ASM_LINE_SEP	\
+    /* No need to LDW_PIC */				ASM_LINE_SEP	\
+    ldw -36(%sr0,%sp), %r4				ASM_LINE_SEP
+
+/* Save arguments into our frame */
+# define PUSHARGS_0	/* nothing to do */
+# define PUSHARGS_1	PUSHARGS_0 stw %r26, -36(%sr0,%sp)	ASM_LINE_SEP
+# define PUSHARGS_2	PUSHARGS_1 stw %r25, -40(%sr0,%sp)	ASM_LINE_SEP
+# define PUSHARGS_3	PUSHARGS_2 stw %r24, -44(%sr0,%sp)	ASM_LINE_SEP
+# define PUSHARGS_4	PUSHARGS_3 stw %r23, -48(%sr0,%sp)	ASM_LINE_SEP
+# define PUSHARGS_5	PUSHARGS_4 /* Args are on the stack... */
+# define PUSHARGS_6	PUSHARGS_5
+
+/* Bring them back from the stack */
+# define POPARGS_0	/* nothing to do */
+# define POPARGS_1	POPARGS_0 ldw -36(%sr0,%sp), %r26	ASM_LINE_SEP
+# define POPARGS_2	POPARGS_1 ldw -40(%sr0,%sp), %r25	ASM_LINE_SEP
+# define POPARGS_3	POPARGS_2 ldw -44(%sr0,%sp), %r24	ASM_LINE_SEP
+# define POPARGS_4	POPARGS_3 ldw -48(%sr0,%sp), %r23	ASM_LINE_SEP
+# define POPARGS_5	POPARGS_4 ldw -52(%sr0,%sp), %r22	ASM_LINE_SEP
+# define POPARGS_6	POPARGS_5 ldw -54(%sr0,%sp), %r21	ASM_LINE_SEP
+
+# ifdef IS_IN_libpthread
+#  ifdef PIC
+#   define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
+			bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
+#   define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
+			bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
+#  else
+#   define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
+			bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
+#   define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
+			bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
+#  endif
+# elif !defined NOT_IN_libc
+#  ifdef PIC
+#   define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
+			bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
+#   define CDISABLE	.import __libc_disable_asynccancel,code ASM_LINE_SEP \
+			bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
+#  else
+#   define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
+			bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
+#   define CDISABLE	.import __libc_disable_asynccancel,code ASM_LINE_SEP \
+			bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
+#  endif
+# else
+#  ifdef PIC
+#   define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
+			bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
+#   define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
+			bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
+#  else
+#   define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
+			bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
+#   define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
+			bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
+#  endif
+# endif
+
+/* p_header.multiple_threads is +12 from the pthread_descr struct start,
+   We could have called __get_cr27() but we really want less overhead */
+# define MULTIPLE_THREADS_OFFSET 0xC
+
+/* cr27 has been initialized to 0x0 by kernel */
+# define NO_THREAD_CR27 0x0
+
+# ifdef IS_IN_libpthread
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define __local_multiple_threads __libc_multiple_threads
+# else
+#  define __local_multiple_threads __librt_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+ extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+/* This ALT version requires newer kernel support */
+#  define SINGLE_THREAD_P_MFCTL						\
+	mfctl %cr27, %ret0					ASM_LINE_SEP	\
+	cmpib,= NO_THREAD_CR27,%ret0,Lstp			ASM_LINE_SEP	\
+	nop							ASM_LINE_SEP	\
+	ldw MULTIPLE_THREADS_OFFSET(%sr0,%ret0),%ret0		ASM_LINE_SEP	\
+ Lstp:								ASM_LINE_SEP
+#  ifdef PIC
+/* Slower version uses GOT to get value of __local_multiple_threads */
+#   define SINGLE_THREAD_P							\
+	addil LT%__local_multiple_threads, %r19			ASM_LINE_SEP	\
+	ldw RT%__local_multiple_threads(%sr0,%r1), %ret0	ASM_LINE_SEP	\
+	ldw 0(%sr0,%ret0), %ret0 				ASM_LINE_SEP
+#  else
+  /* Slow non-pic version using DP */
+#   define SINGLE_THREAD_P								\
+	addil LR%__local_multiple_threads-$global$,%r27  		ASM_LINE_SEP	\
+	ldw RR%__local_multiple_threads-$global$(%sr0,%r1),%ret0	ASM_LINE_SEP
+#  endif
+# endif
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
+/* !defined NOT_IN_libc || defined IS_IN_libpthread */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h
new file mode 100644
index 0000000000..5355310ccd
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/dl-sysdep.h
@@ -0,0 +1,64 @@
+/* System-specific settings for dynamic linker code.  IA-32 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.
+   sysenter/syscall is not useful on i386 through i586, but the dynamic
+   linker and dl code in libc.a has to be able to load i686 compiled
+   libraries.  */
+#define NEED_DL_SYSINFO	1
+#undef USE_DL_SYSINFO
+
+#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
+extern void _dl_sysinfo_int80 (void) attribute_hidden;
+# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80
+# define DL_SYSINFO_IMPLEMENTATION \
+  asm (".text\n\t"							      \
+       ".type _dl_sysinfo_int80,@function\n\t"				      \
+       ".hidden _dl_sysinfo_int80\n"					      \
+       CFI_STARTPROC "\n"						      \
+       "_dl_sysinfo_int80:\n\t"						      \
+       "int $0x80;\n\t"							      \
+       "ret;\n\t"							      \
+       CFI_ENDPROC "\n"							      \
+       ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80\n\t"		      \
+       ".previous");
+#endif
+
+#endif	/* dl-sysdep.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
new file mode 100644
index 0000000000..7865f7165e
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -0,0 +1,179 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <tls.h>
+#include <pt-machine.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .text;								      \
+  ENTRY (name)								      \
+    SINGLE_THREAD_P;							      \
+    jne L(pseudo_cancel);						      \
+    DO_CALL (syscall_name, args);					      \
+    cmpl $-4095, %eax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+    ret;								      \
+  L(pseudo_cancel):							      \
+    CENABLE								      \
+    SAVE_OLDTYPE_##args							      \
+    PUSHCARGS_##args							      \
+    DOCARGS_##args							      \
+    movl $SYS_ify (syscall_name), %eax;					      \
+    int $0x80								      \
+    POPCARGS_##args;							      \
+    POPSTATE_##args							      \
+    cmpl $-4095, %eax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+  L(pseudo_end):
+
+# define SAVE_OLDTYPE_0	movl %eax, %ecx;
+# define SAVE_OLDTYPE_1	SAVE_OLDTYPE_0
+# define SAVE_OLDTYPE_2	pushl %eax;
+# define SAVE_OLDTYPE_3	SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_4	SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_5	SAVE_OLDTYPE_2
+
+# define PUSHCARGS_0	/* No arguments to push.  */
+# define DOCARGS_0	/* No arguments to frob.  */
+# define POPCARGS_0	/* No arguments to pop.  */
+# define _PUSHCARGS_0	/* No arguments to push.  */
+# define _POPCARGS_0	/* No arguments to pop.  */
+
+# define PUSHCARGS_1	movl %ebx, %edx; PUSHCARGS_0
+# define DOCARGS_1	_DOARGS_1 (4)
+# define POPCARGS_1	POPCARGS_0; movl %edx, %ebx
+# define _PUSHCARGS_1	pushl %ebx; L(PUSHBX2): _PUSHCARGS_0
+# define _POPCARGS_1	_POPCARGS_0; popl %ebx; L(POPBX2):
+
+# define PUSHCARGS_2	PUSHCARGS_1
+# define DOCARGS_2	_DOARGS_2 (12)
+# define POPCARGS_2	POPCARGS_1
+# define _PUSHCARGS_2	_PUSHCARGS_1
+# define _POPCARGS_2	_POPCARGS_1
+
+# define PUSHCARGS_3	_PUSHCARGS_2
+# define DOCARGS_3	_DOARGS_3 (20)
+# define POPCARGS_3	_POPCARGS_3
+# define _PUSHCARGS_3	_PUSHCARGS_2
+# define _POPCARGS_3	_POPCARGS_2
+
+# define PUSHCARGS_4	_PUSHCARGS_4
+# define DOCARGS_4	_DOARGS_4 (28)
+# define POPCARGS_4	_POPCARGS_4
+# define _PUSHCARGS_4	pushl %esi; L(PUSHSI2): _PUSHCARGS_3
+# define _POPCARGS_4	_POPCARGS_3; popl %esi; L(POPSI2):
+
+# define PUSHCARGS_5	_PUSHCARGS_5
+# define DOCARGS_5	_DOARGS_5 (36)
+# define POPCARGS_5	_POPCARGS_5
+# define _PUSHCARGS_5	pushl %edi; L(PUSHDI2): _PUSHCARGS_4
+# define _POPCARGS_5	_POPCARGS_4; popl %edi; L(POPDI2):
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel;
+#  define CDISABLE	call __pthread_disable_asynccancel
+# elif defined IS_IN_librt
+#  ifdef PIC
+#   define CENABLE	pushl %ebx; \
+			call __i686.get_pc_thunk.bx; \
+			addl     $_GLOBAL_OFFSET_TABLE_, %ebx; \
+			call __librt_enable_asynccancel@PLT; \
+			popl %ebx;
+#   define CDISABLE	pushl %ebx; \
+			call __i686.get_pc_thunk.bx; \
+			addl     $_GLOBAL_OFFSET_TABLE_, %ebx; \
+			call __librt_disable_asynccancel@PLT; \
+			popl %ebx;
+#  else
+#   define CENABLE	call __librt_enable_asynccancel;
+#   define CDISABLE	call __librt_disable_asynccancel
+#  endif
+# else
+#  define CENABLE	call __libc_enable_asynccancel;
+#  define CDISABLE	call __libc_disable_asynccancel
+# endif
+# define POPSTATE_0	pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax;
+# define POPSTATE_1	POPSTATE_0
+# define POPSTATE_2	xchgl (%esp), %eax; CDISABLE; popl %eax;
+# define POPSTATE_3	POPSTATE_2
+# define POPSTATE_4	POPSTATE_2
+# define POPSTATE_5	POPSTATE_2
+
+#if !defined NOT_IN_libc
+# define __local_multiple_threads __libc_multiple_threads
+#elif defined IS_IN_libpthread
+# define __local_multiple_threads __pthread_multiple_threads
+#else
+# define __local_multiple_threads __librt_multiple_threads
+#endif
+
+# ifndef __ASSEMBLER__
+#  if defined FLOATING_STACKS && USE___THREAD && defined PIC
+#   define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+#  else
+extern int __local_multiple_threads
+#   if !defined NOT_IN_libc || defined IS_IN_libpthread
+  attribute_hidden;
+#   else
+  ;
+#   endif
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  endif
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P cmpl $0, __local_multiple_threads
+#  elif defined FLOATING_STACKS && USE___THREAD
+#   define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
+#  else
+#   if !defined NOT_IN_libc || defined IS_IN_libpthread
+#    define __SINGLE_THREAD_CMP cmpl $0, __local_multiple_threads@GOTOFF(%ecx)
+#   else
+#    define __SINGLE_THREAD_CMP \
+  movl __local_multiple_threads@GOT(%ecx), %ecx;\
+  cmpl $0, (%ecx)
+#   endif
+#   if !defined HAVE_HIDDEN || !USE___THREAD
+#    define SINGLE_THREAD_P \
+  SETUP_PIC_REG (cx);				\
+  addl $_GLOBAL_OFFSET_TABLE_, %ecx;		\
+  __SINGLE_THREAD_CMP
+#   else
+#    define SINGLE_THREAD_P \
+  call __i686.get_pc_thunk.cx;			\
+  addl $_GLOBAL_OFFSET_TABLE_, %ecx;		\
+  __SINGLE_THREAD_CMP
+#   endif
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S
new file mode 100644
index 0000000000..c7a120d239
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -0,0 +1,95 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Schwab <schwab@gnu.org>.
+
+   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-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+
+# ifdef SHARED
+#  if !defined HAVE_HIDDEN || !USE___THREAD
+	SETUP_PIC_REG (cx)
+#  else
+	call	__i686.get_pc_thunk.cx
+#  endif
+	addl	$_GLOBAL_OFFSET_TABLE_, %ecx
+	cmpl	$0, __libc_pthread_functions@GOTOFF(%ecx)
+# else
+	.weak	pthread_create
+	movl	$pthread_create, %eax
+	testl	%eax, %eax
+# endif
+	jne	HIDDEN_JUMPTARGET (__fork)
+
+	/* Pop the return PC value into ECX.  */
+	popl	%ecx
+
+	/* Stuff the syscall number in EAX and enter into the kernel.  */
+	movl	$SYS_ify (vfork), %eax
+	int	$0x80
+
+	/* Jump to the return PC.  Don't jump directly since this
+	   disturbs the branch target cache.  Instead push the return
+	   address back on the stack.  */
+	pushl	%ecx
+
+	cmpl	$-4095, %eax
+	/* Branch forward if it failed.  */
+# ifdef __ASSUME_VFORK_SYSCALL
+	jae	SYSCALL_ERROR_LABEL
+.Lpseudo_end:
+# else
+	jae	.Lerror
+# endif
+
+	ret
+
+# ifndef __ASSUME_VFORK_SYSCALL
+.Lerror:
+	/* Check if vfork syscall is known at all.  */
+	cmpl	$-ENOSYS, %eax
+	jne	SYSCALL_ERROR_LABEL
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+	/* If we don't have vfork, fork is close enough.  */
+
+	movl	$SYS_ify (fork), %eax
+	int	$0x80
+	cmpl	$-4095, %eax
+	jae	SYSCALL_ERROR_LABEL
+.Lpseudo_end:
+	ret
+#elif !defined __NR_vfork
+# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined"
+#endif
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile
new file mode 100644
index 0000000000..e03aee99fc
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),linuxthreads)
+libpthread-routines += ptw-sysdep ptw-sigblock ptw-sigprocmask
+endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions
new file mode 100644
index 0000000000..d102772482
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/Versions
@@ -0,0 +1,6 @@
+libpthread {
+  GLIBC_2.3.3 {
+    # Changed PTHREAD_STACK_MIN.
+    pthread_attr_setstack; pthread_attr_setstacksize;
+  }
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
new file mode 100644
index 0000000000..629b1f89c1
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/bits/local_lim.h
@@ -0,0 +1,92 @@
+/* Minimum guaranteed maximum values for system limits.  Linux/Alpha version.
+   Copyright (C) 1993-1998,2000,2002,2003,2004 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+   and defines LINK_MAX although filesystems have different maxima.  A
+   similar thing is true for OPEN_MAX: the limit can be changed at
+   runtime and therefore the macro must not be defined.  Remove this
+   after including the header if necessary.  */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information.  */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN?  */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX?  */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX?  */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* The number of data keys per process.  */
+#define _POSIX_THREAD_KEYS_MAX	128
+/* This is the value this implementation supports.  */
+#define PTHREAD_KEYS_MAX	1024
+
+/* Controlling the iterations of destructors for thread-specific data.  */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4
+/* Number of iterations this implementation does.  */
+#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process.  */
+#define _POSIX_THREAD_THREADS_MAX	64
+/* This is the value this implementation supports.  */
+#define PTHREAD_THREADS_MAX	16384
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+   priority level.  */
+#define AIO_PRIO_DELTA_MAX	20
+
+/* Minimum size for a thread.  We are free to choose a reasonable value.  */
+#define PTHREAD_STACK_MIN	196608
+
+/* Maximum number of POSIX timers available.  */
+#define TIMER_MAX	256
+
+/* Maximum number of timer expiration overruns.  */
+#define DELAYTIMER_MAX	2147483647
+
+/* Maximum tty name length.  */
+#define TTY_NAME_MAX		32
+
+/* Maximum login name length.  This is arbitrary.  */
+#define LOGIN_NAME_MAX		256
+
+/* Maximum host name length.  */
+#define HOST_NAME_MAX		64
+
+/* Maximum message queue priority level.  */
+#define MQ_PRIO_MAX		32768
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
new file mode 100644
index 0000000000..27d5fdfbf5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h
@@ -0,0 +1,49 @@
+/* System-specific settings for dynamic linker code.  IA-64 version.
+   Copyright (C) 2003, 2004 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
+
+#define NEED_DL_SYSINFO	1
+#undef USE_DL_SYSINFO
+
+#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__
+/* Don't declare this as a function---we want it's entry-point, not
+   it's function descriptor... */
+extern int _dl_sysinfo_break attribute_hidden;
+# define DL_SYSINFO_DEFAULT ((uintptr_t) &_dl_sysinfo_break)
+# define DL_SYSINFO_IMPLEMENTATION		\
+  asm (".text\n\t"				\
+       ".hidden _dl_sysinfo_break\n\t"		\
+       ".proc _dl_sysinfo_break\n\t"		\
+       "_dl_sysinfo_break:\n\t"			\
+       ".prologue\n\t"				\
+       ".altrp b6\n\t"				\
+       ".body\n\t"				\
+       "break 0x100000;\n\t"			\
+       "br.ret.sptk.many b6;\n\t"		\
+       ".endp _dl_sysinfo_break"		\
+       ".previous");
+#endif
+
+/* _dl_argv cannot be attribute_relro, because _dl_start_user
+   might write into it after _dl_start returns.  */
+#define DL_ARGV_NOT_RELRO 1
+
+#endif	/* dl-sysdep.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h
new file mode 100644
index 0000000000..30a0cc1918
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h
@@ -0,0 +1,25 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <signal.h>
+#include <sysdep.h>
+
+#define ARCH_FORK() INLINE_SYSCALL (clone, 2, SIGCHLD, 0)
+
+#include_next <fork.h>
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
new file mode 100644
index 0000000000..85fd33f4a8
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-initfini.c
@@ -0,0 +1,140 @@
+/* Special .init and .fini section support for ia64. LinuxThreads version.
+   Copyright (C) 2000, 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+#include <stddef.h>
+
+#ifdef HAVE_INITFINI_ARRAY
+
+# define INIT_NEW_WAY \
+    ".xdata8 \".init_array\", @fptr(__pthread_initialize_minimal)\n"
+# define INIT_OLD_WAY ""
+#else
+# define INIT_NEW_WAY ""
+# define INIT_OLD_WAY \
+	"\n\
+	st8 [r12] = gp, -16\n\
+	br.call.sptk.many b0 = __pthread_initialize_minimal# ;;\n\
+	;;\n\
+	adds r12 = 16, r12\n\
+	;;\n\
+	ld8 gp = [r12]\n\
+	;;\n"
+#endif
+
+__asm__ ("\n\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n"
+	INIT_NEW_WAY
+	".section .init\n\
+	.align 16\n\
+	.global _init#\n\
+	.proc _init#\n\
+_init:\n\
+	.prologue\n\
+	.save ar.pfs, r34\n\
+	alloc r34 = ar.pfs, 0, 3, 0, 0\n\
+	.vframe r32\n\
+	mov r32 = r12\n\
+	.save rp, r33\n\
+	mov r33 = b0\n\
+	.body\n\
+	adds r12 = -16, r12\n\
+	;;\n"
+	INIT_OLD_WAY
+	".endp _init#\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+	.section .init\n\
+	.proc _init#\n\
+	.prologue\n\
+	.save ar.pfs, r34\n\
+	.vframe r32\n\
+	.save rp, r33\n\
+	.body\n\
+	mov r12 = r32\n\
+	mov ar.pfs = r34\n\
+	mov b0 = r33\n\
+	br.ret.sptk.many b0\n\
+	.endp _init#\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+	.section .fini\n\
+	.align 16\n\
+	.global _fini#\n\
+	.proc _fini#\n\
+_fini:\n\
+	.prologue\n\
+	.save ar.pfs, r34\n\
+	alloc r34 = ar.pfs, 0, 3, 0, 0\n\
+	.vframe r32\n\
+	mov r32 = r12\n\
+	.save rp, r33\n\
+	mov r33 = b0\n\
+	.body\n\
+	adds r12 = -16, r12\n\
+	;;\n\
+	.endp _fini#\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+	.section .fini\n\
+	.proc _fini#\n\
+	.prologue\n\
+	.save ar.pfs, r34\n\
+	.vframe r32\n\
+	.save rp, r33\n\
+	.body\n\
+	mov r12 = r32\n\
+	mov ar.pfs = r34\n\
+	mov b0 = r33\n\
+	br.ret.sptk.many b0\n\
+	.endp _fini#\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+	.weak	__gmon_start__#\n\
+");
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c
new file mode 100644
index 0000000000..0b96e3d5bd
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/pt-sigsuspend.c
@@ -0,0 +1,33 @@
+/* Internal sigsuspend system call for LinuxThreads.  IA64 version.
+   Copyright (C) 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 <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <linuxthreads/internals.h>
+
+void
+__pthread_sigsuspend (const sigset_t *set)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL (rt_sigsuspend, err, 2, set, _NSIG / 8);
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
new file mode 100644
index 0000000000..dd9637d2b5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
@@ -0,0 +1,144 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# ifdef IS_IN_librt
+#  define PSEUDO_NLOCAL		6
+#  define PSEUDO_SAVE_GP	mov loc5 = gp
+#  define PSEUDO_RESTORE_GP	mov gp = loc5
+#  define PSEUDO_SAVE_GP_1
+#  define PSEUDO_RESTORE_GP_1	mov gp = loc5
+# else
+#  define PSEUDO_NLOCAL		5
+#  define PSEUDO_SAVE_GP
+#  define PSEUDO_RESTORE_GP
+#  define PSEUDO_SAVE_GP_1	mov loc4 = gp;;
+#  define PSEUDO_RESTORE_GP_1	mov gp = loc4
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+.text;									      \
+ENTRY (name)								      \
+     adds r14 = MULTIPLE_THREADS_OFFSET, r13;;				      \
+     ld4 r14 = [r14];							      \
+     mov r15 = SYS_ify(syscall_name);;					      \
+     cmp4.ne p6, p7 = 0, r14;						      \
+(p6) br.cond.spnt .Lpseudo_cancel;;					      \
+     break __BREAK_SYSCALL;;						      \
+     cmp.eq p6,p0=-1,r10;						      \
+(p6) br.cond.spnt.few __syscall_error;					      \
+     ret;;								      \
+     .endp name;							      \
+     .proc __GC_##name;							      \
+     .globl __GC_##name;						      \
+     .hidden __GC_##name;						      \
+__GC_##name:								      \
+.Lpseudo_cancel:							      \
+     .prologue;								      \
+     .regstk args, PSEUDO_NLOCAL, args, 0;				      \
+     .save ar.pfs, loc0;						      \
+     alloc loc0 = ar.pfs, args, PSEUDO_NLOCAL, args, 0;			      \
+     .save rp, loc1;							      \
+     mov loc1 = rp;							      \
+     PSEUDO_SAVE_GP;;							      \
+     .body;								      \
+     CENABLE;;								      \
+     PSEUDO_RESTORE_GP;							      \
+     mov loc2 = r8;							      \
+     COPY_ARGS_##args							      \
+     mov r15 = SYS_ify(syscall_name);					      \
+     break __BREAK_SYSCALL;;						      \
+     mov loc3 = r8;							      \
+     mov loc4 = r10;							      \
+     mov out0 = loc2;							      \
+     CDISABLE;;								      \
+     PSEUDO_RESTORE_GP;							      \
+     cmp.eq p6,p0=-1,loc4;						      \
+(p6) br.cond.spnt.few __syscall_error_##args;				      \
+     mov r8 = loc3;							      \
+     mov rp = loc1;							      \
+     mov ar.pfs = loc0;							      \
+.Lpseudo_end:								      \
+     ret;								      \
+     .endp __GC_##name;							      \
+.section .gnu.linkonce.t.__syscall_error_##args, "ax";			      \
+     .align 32;								      \
+     .proc __syscall_error_##args;					      \
+     .global __syscall_error_##args;					      \
+     .hidden __syscall_error_##args;					      \
+     .size __syscall_error_##args, 64;					      \
+__syscall_error_##args:							      \
+     .prologue;								      \
+     .regstk args, PSEUDO_NLOCAL, args, 0;				      \
+     .save ar.pfs, loc0;						      \
+     .save rp, loc1;							      \
+     .body;								      \
+     PSEUDO_SAVE_GP_1;							      \
+     br.call.sptk.many b0 = __errno_location;;				      \
+     st4 [r8] = loc3;							      \
+     PSEUDO_RESTORE_GP_1;						      \
+     mov rp = loc1;							      \
+     mov r8 = -1;							      \
+     mov ar.pfs = loc0
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) .endp
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	br.call.sptk.many b0 = __pthread_enable_asynccancel
+#  define CDISABLE	br.call.sptk.many b0 = __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+#  define CENABLE	br.call.sptk.many b0 = __libc_enable_asynccancel
+#  define CDISABLE	br.call.sptk.many b0 = __libc_disable_asynccancel
+# else
+#  define CENABLE	br.call.sptk.many b0 = __librt_enable_asynccancel
+#  define CDISABLE	br.call.sptk.many b0 = __librt_disable_asynccancel
+# endif
+
+#define COPY_ARGS_0	/* Nothing */
+#define COPY_ARGS_1	COPY_ARGS_0 mov out0 = in0;
+#define COPY_ARGS_2	COPY_ARGS_1 mov out1 = in1;
+#define COPY_ARGS_3	COPY_ARGS_2 mov out2 = in2;
+#define COPY_ARGS_4	COPY_ARGS_3 mov out3 = in3;
+#define COPY_ARGS_5	COPY_ARGS_4 mov out4 = in4;
+#define COPY_ARGS_6	COPY_ARGS_5 mov out5 = in5;
+#define COPY_ARGS_7	COPY_ARGS_6 mov out6 = in6;
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P \
+  adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S
new file mode 100644
index 0000000000..54acedad4c
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/vfork.S
@@ -0,0 +1,54 @@
+/* Copyright (C) 2000, 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 <sysdep-cancel.h>
+#define _SIGNAL_H
+#include <bits/signum.h>
+
+/* The following are defined in linux/sched.h, which unfortunately	*/
+/* is not safe for inclusion in an assembly file.			*/
+#define CLONE_VM        0x00000100      /* set if VM shared between processes */
+#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
+
+/* pid_t vfork(void); */
+/* Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0)	*/
+
+ENTRY(__vfork)
+#ifdef SHARED
+	addl r14 = @gprel(__libc_pthread_functions#), gp;;
+#else
+	.weak	pthread_create
+	addl r14 = @ltoff(@fptr(pthread_create#)), gp;;
+#endif
+	ld8 r14 = [r14];;
+	cmp.ne p6, p7 = 0, r14
+(p6)	br.cond.spnt.few HIDDEN_JUMPTARGET (__fork);;
+	alloc r2=ar.pfs,0,0,2,0
+	mov out0=CLONE_VM+CLONE_VFORK+SIGCHLD
+	mov out1=0		/* Standard sp value.			*/
+	;;
+	DO_CALL (SYS_ify (clone))
+	cmp.eq p6,p0=-1,r10
+	;;
+(p6)	br.cond.spnt.few __syscall_error
+	ret
+PSEUDO_END(__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c b/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c
new file mode 100644
index 0000000000..4b90315707
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c
@@ -0,0 +1,34 @@
+/* _longjmp_unwind -- Clean up stack frames unwound by longjmp.
+   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.  */
+
+#include <setjmp.h>
+#include <stddef.h>
+#include <bits/libc-lock.h>
+
+#ifndef SHARED
+weak_extern (__pthread_cleanup_upto);
+#endif
+
+void
+_longjmp_unwind (jmp_buf env, int val)
+{
+  __libc_maybe_call2 (pthread_cleanup_upto,
+		      (env->__jmpbuf, __builtin_frame_address (0)),
+		      (void) 0);
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h
new file mode 100644
index 0000000000..bb798e40d6
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h
@@ -0,0 +1,129 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Schwab <schwab@suse.de>, 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>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .text;								      \
+  ENTRY (name)								      \
+    SINGLE_THREAD_P;							      \
+    jne .Lpseudo_cancel;						      \
+    DO_CALL (syscall_name, args);					      \
+    cmp.l &-4095, %d0;							      \
+    jcc SYSCALL_ERROR_LABEL;						      \
+    rts;								      \
+  .Lpseudo_cancel:							      \
+    CENABLE;								      \
+    DOCARGS_##args							      \
+    move.l %d0, -(%sp);							      \
+    move.l &SYS_ify (syscall_name), %d0;				      \
+    trap &0;								      \
+    move.l %d0, %d2;							      \
+    CDISABLE;								      \
+    addq.l &4, %sp;							      \
+    move.l %d2, %d0;							      \
+    UNDOCARGS_##args							      \
+    cmp.l &-4095, %d0;							      \
+    jcc SYSCALL_ERROR_LABEL
+
+# define DOCARGS_0	move.l %d2, -(%sp);
+# define _DOCARGS_0(n)
+# define UNDOCARGS_0	move.l (%sp)+, %d2;
+
+# define DOCARGS_1	_DOCARGS_1 (4); DOCARGS_0
+# define _DOCARGS_1(n)	move.l n(%sp), %d1; _DOARGS_0 (n)
+# define UNDOCARGS_1	UNDOCARGS_0
+
+# define DOCARGS_2	_DOCARGS_2 (8)
+# define _DOCARGS_2(n)	move.l %d2, -(%sp); move.l n+4(%sp), %d2;	\
+			_DOCARGS_1 (n)
+# define UNDOCARGS_2	UNDOCARGS_1
+
+# define DOCARGS_3	_DOCARGS_3 (12)
+# define _DOCARGS_3(n)	move.l %d3, -(%sp); move.l n+4(%sp), %d3;	\
+  	 		_DOCARGS_2 (n)
+# define UNDOCARGS_3	UNDOCARGS_2; move.l (%sp)+, %d3;
+
+# define DOCARGS_4	_DOCARGS_4 (16)
+# define _DOCARGS_4(n)	move.l %d4, -(%sp); move.l n+4(%sp), %d4;	\
+			_DOCARGS_3 (n)
+# define UNDOCARGS_4	UNDOCARGS_3; move.l (%sp)+, %d4;
+
+# define DOCARGS_5	_DOCARGS_5 (20)
+# define _DOCARGS_5(n)	move.l %d5, -(%sp); move.l n+4(%sp), %d5;	\
+			_DOCARGS_4 (n)
+# define UNDOCARGS_5	UNDOCARGS_4; move.l (%sp)+, %d5;
+
+# ifdef IS_IN_libpthread
+#  ifdef PIC
+#   define CENABLE	jbsr __pthread_enable_asynccancel@PLTPC
+#   define CDISABLE	jbsr __pthread_disable_asynccancel@PLTPC
+#  else
+#   define CENABLE	jbsr __pthread_enable_asynccancel
+#   define CDISABLE	jbsr __pthread_disable_asynccancel
+#  endif
+# elif !defined NOT_IN_libc
+#  ifdef PIC
+#   define CENABLE	jbsr __libc_enable_asynccancel@PLTPC
+#   define CDISABLE	jbsr __libc_disable_asynccancel@PLTPC
+#  else
+#   define CENABLE	jbsr __libc_enable_asynccancel
+#   define CDISABLE	jbsr __libc_disable_asynccancel
+#  endif
+# else
+#  ifdef PIC
+#   define CENABLE	jbsr __librt_enable_asynccancel@PLTPC
+#   define CDISABLE	jbsr __librt_disable_asynccancel@PLTPC
+#  else
+#   define CENABLE	jbsr __librt_enable_asynccancel
+#   define CDISABLE	jbsr __librt_disable_asynccancel
+#  endif
+# endif
+
+# if !defined NOT_IN_libc
+#  define __local_multiple_threads __libc_multiple_threads
+# elif defined IS_IN_libpthread
+#  define __local_multiple_threads __pthread_multiple_threads
+# else
+#  define __local_multiple_threads __librt_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P tst.l __local_multiple_threads
+#  else
+#   define SINGLE_THREAD_P tst.l (__local_multiple_threads, %pc)
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S
new file mode 100644
index 0000000000..49b8a3c0ac
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/m68k/vfork.S
@@ -0,0 +1,84 @@
+/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Schwab <schwab@gnu.org>.
+
+   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-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+
+#ifdef SHARED
+	tstl	(__libc_pthread_functions@GOTPC, %pc)
+#else
+	.weak	pthread_create
+	movel	#pthread_create, %d0
+#endif
+	jbne	HIDDEN_JUMPTARGET (__fork)
+
+#ifdef __NR_vfork
+
+	/* Pop the return PC value into A0.  */
+	movel	%sp@+, %a0
+
+	/* Stuff the syscall number in D0 and trap into the kernel.  */
+	movel	#SYS_ify (vfork), %d0
+	trap	#0
+	tstl	%d0
+	jmi	.Lerror		/* Branch forward if it failed.  */
+
+	/* Jump to the return PC.  */
+	jmp	%a0@
+
+.Lerror:
+	/* Push back the return PC.  */
+	movel	%a0,%sp@-
+
+# ifdef __ASSUME_VFORK_SYSCALL
+#  ifndef PIC
+	jbra	SYSCALL_ERROR_LABEL
+#  endif
+# else
+	/* Check if vfork syscall is known at all.  */
+	movel	#-ENOSYS,%d1
+	cmpl	%d0,%d1
+	jne	SYSCALL_ERROR_LABEL
+
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+	/* If we don't have vfork, fork is close enough.  */
+
+	movel	#SYS_ify (fork), %d0
+	trap	#0
+	tstl	%d0
+	jmi	SYSCALL_ERROR_LABEL
+	rts
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile
new file mode 100644
index 0000000000..56eeecc789
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/mips/Makefile
@@ -0,0 +1,3 @@
+# pull in __syscall_error routine
+libpthread-routines += sysdep
+
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
new file mode 100644
index 0000000000..fc51774252
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h
@@ -0,0 +1,144 @@
+/* system call stubs with cancellation handling.  Linux/MIPS version.
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Demetriou of Broadcom Corporation,
+   based on work by Guido Guenther <agx@sigxcpu.org>.
+
+   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>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+#include <sys/asm.h>
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+#ifdef __PIC__
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .align 2;								      \
+  99:									      \
+  PTR_LA t9,__syscall_error;					 	      \
+  /* manual cpreturn.  */						      \
+  REG_L gp, STKOFF_GP(sp);						      \
+  RESTORESTK ;								      \
+  jr t9;								      \
+  ENTRY (name)								      \
+    SAVESTK ;								      \
+    .cpsetup t9, STKOFF_GP, name ;					      \
+    .set reorder;							      \
+    SINGLE_THREAD_P(t0);						      \
+    bne zero, t0, L(pseudo_cancel);					      \
+    .set noreorder;							      \
+    li v0, SYS_ify(syscall_name);					      \
+    syscall;								      \
+    .set reorder;							      \
+    bne a3, zero, SYSCALL_ERROR_LABEL;			       		      \
+    /* manual cpreturn.  */						      \
+    REG_L gp, STKOFF_GP(sp);						      \
+    RESTORESTK ;							      \
+    ret;								      \
+  L(pseudo_cancel):							      \
+    REG_S ra, STKOFF_RA(sp);						      \
+    PUSHARGS_##args;			/* save syscall args */	      	      \
+    CENABLE;								      \
+    REG_S v0, STKOFF_SVMSK(sp);		/* save mask */			      \
+    POPARGS_##args;			/* restore syscall args */	      \
+    .set noreorder;							      \
+    li v0, SYS_ify (syscall_name);				      	      \
+    syscall;								      \
+    .set reorder;							      \
+    REG_S v0, STKOFF_SC_V0(sp);		/* save syscall result */             \
+    REG_S a3, STKOFF_SC_ERR(sp);	/* save syscall error flag */	      \
+    REG_L a0, STKOFF_SVMSK(sp);		/* pass mask as arg1 */		      \
+    CDISABLE;								      \
+    REG_L a3, STKOFF_SC_ERR(sp);	/* restore syscall error flag */      \
+    REG_L ra, STKOFF_RA(sp);		/* restore return address */	      \
+    REG_L v0, STKOFF_SC_V0(sp);		/* restore syscall result */          \
+    bne a3, zero, SYSCALL_ERROR_LABEL;					      \
+    /* manual cpreturn.  */						      \
+    REG_L gp, STKOFF_GP(sp);						      \
+    RESTORESTK ;							      \
+  L(pseudo_end):
+#endif
+
+# define PUSHARGS_0	/* nothing to do */
+# define PUSHARGS_1	PUSHARGS_0 REG_S a0, STKOFF_A0(sp);
+# define PUSHARGS_2	PUSHARGS_1 REG_S a1, STKOFF_A1(sp);
+# define PUSHARGS_3	PUSHARGS_2 REG_S a2, STKOFF_A2(sp);
+# define PUSHARGS_4	PUSHARGS_3 REG_S a3, STKOFF_A3(sp);
+# define PUSHARGS_5	PUSHARGS_4 REG_S a4, STKOFF_A4(sp);
+# define PUSHARGS_6	PUSHARGS_5 REG_S a5, STKOFF_A5(sp);
+
+# define POPARGS_0	/* nothing to do */
+# define POPARGS_1	POPARGS_0 REG_L a0, STKOFF_A0(sp);
+# define POPARGS_2	POPARGS_1 REG_L a1, STKOFF_A1(sp);
+# define POPARGS_3	POPARGS_2 REG_L a2, STKOFF_A2(sp);
+# define POPARGS_4	POPARGS_3 REG_L a3, STKOFF_A3(sp);
+# define POPARGS_5	POPARGS_4 REG_L a4, STKOFF_A4(sp);
+# define POPARGS_6	POPARGS_5 REG_L a5, STKOFF_A5(sp);
+
+/* Save an even number of slots.  Should be 0 if an even number of slots
+   are used below, or SZREG if an odd number are used.  */
+# define STK_PAD	SZREG
+
+/* Place values that we are more likely to use later in this sequence, i.e.
+   closer to the SP at function entry.  If you do that, the are more
+   likely to already be in your d-cache.  */
+# define STKOFF_A5	(STK_PAD)
+# define STKOFF_A4	(STKOFF_A5 + SZREG)
+# define STKOFF_A3	(STKOFF_A4 + SZREG)
+# define STKOFF_A2	(STKOFF_A3 + SZREG)	/* MT and more args.  */
+# define STKOFF_A1	(STKOFF_A2 + SZREG)	/* MT and 2 args.  */
+# define STKOFF_A0	(STKOFF_A1 + SZREG)	/* MT and 1 arg.  */
+# define STKOFF_RA	(STKOFF_A0 + SZREG)	/* Used if MT.  */
+# define STKOFF_SC_V0	(STKOFF_RA + SZREG)	/* Used if MT.  */
+# define STKOFF_SC_ERR	(STKOFF_SC_V0 + SZREG)	/* Used if MT.  */
+# define STKOFF_SVMSK	(STKOFF_SC_ERR + SZREG)	/* Used if MT.  */
+# define STKOFF_GP	(STKOFF_SVMSK + SZREG)	/* Always used.  */
+
+# define STKSPACE	(STKOFF_GP + SZREG)
+# define SAVESTK 	PTR_SUBU sp, STKSPACE
+# define RESTORESTK 	PTR_ADDU sp, STKSPACE
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	PTR_LA t9, __pthread_enable_asynccancel; jalr t9;
+#  define CDISABLE	PTR_LA t9, __pthread_disable_asynccancel; jalr t9;
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE	PTR_LA t9, __librt_enable_asynccancel; jalr t9;
+#  define CDISABLE	PTR_LA t9, __librt_disable_asynccancel; jalr t9;
+#  define __local_multiple_threads __librt_multiple_threads
+# else
+#  define CENABLE	PTR_LA t9, __libc_enable_asynccancel; jalr t9;
+#  define CDISABLE	PTR_LA t9, __libc_disable_asynccancel; jalr t9;
+#  define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads
+#endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h
new file mode 100644
index 0000000000..1fff782397
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/mips/sysdep-cancel.h
@@ -0,0 +1,143 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Guido Guenther <agx@sigxcpu.org>, 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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+#ifdef __PIC__
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .align 2;								      \
+  99: la t9,__syscall_error;						      \
+  jr t9;								      \
+  ENTRY (name)								      \
+    .set noreorder;							      \
+    .cpload t9;								      \
+    .set reorder;							      \
+    SINGLE_THREAD_P(t0);						      \
+    bne zero, t0, L(pseudo_cancel);					      \
+    .set noreorder;							      \
+    li v0, SYS_ify(syscall_name);					      \
+    syscall;								      \
+    .set reorder;							      \
+    bne a3, zero, SYSCALL_ERROR_LABEL;			       		      \
+    ret;								      \
+  L(pseudo_cancel):							      \
+    SAVESTK_##args;						              \
+    sw ra, 28(sp);							      \
+    sw gp, 32(sp);							      \
+    PUSHARGS_##args;			/* save syscall args */	      	      \
+    CENABLE;								      \
+    lw gp, 32(sp);							      \
+    sw v0, 44(sp);			/* save mask */			      \
+    POPARGS_##args;			/* restore syscall args */	      \
+    .set noreorder;							      \
+    li v0, SYS_ify (syscall_name);				      	      \
+    syscall;								      \
+    .set reorder;							      \
+    sw v0, 36(sp);			/* save syscall result */             \
+    sw a3, 40(sp);			/* save syscall error flag */	      \
+    lw a0, 44(sp);			/* pass mask as arg1 */		      \
+    CDISABLE;								      \
+    lw gp, 32(sp);							      \
+    lw v0, 36(sp);			/* restore syscall result */          \
+    lw a3, 40(sp);			/* restore syscall error flag */      \
+    lw ra, 28(sp);			/* restore return address */	      \
+    RESTORESTK;							              \
+    bne a3, zero, SYSCALL_ERROR_LABEL;					      \
+  L(pseudo_end):
+#endif
+
+# define PUSHARGS_0	/* nothing to do */
+# define PUSHARGS_1	PUSHARGS_0 sw a0, 0(sp);
+# define PUSHARGS_2	PUSHARGS_1 sw a1, 4(sp);
+# define PUSHARGS_3	PUSHARGS_2 sw a2, 8(sp);
+# define PUSHARGS_4	PUSHARGS_3 sw a3, 12(sp);
+# define PUSHARGS_5	PUSHARGS_4 /* handeld by SAVESTK_## */
+# define PUSHARGS_6	PUSHARGS_5
+# define PUSHARGS_7	PUSHARGS_6
+
+# define POPARGS_0	/* nothing to do */
+# define POPARGS_1	POPARGS_0 lw a0, 0(sp);
+# define POPARGS_2	POPARGS_1 lw a1, 4(sp);
+# define POPARGS_3	POPARGS_2 lw a2, 8(sp);
+# define POPARGS_4	POPARGS_3 lw a3, 12(sp);
+# define POPARGS_5	POPARGS_4 /* args already in new stackframe */
+# define POPARGS_6	POPARGS_5
+# define POPARGS_7	POPARGS_6
+
+
+# define STKSPACE	48
+# define SAVESTK_0 	subu sp, STKSPACE
+# define SAVESTK_1      SAVESTK_0
+# define SAVESTK_2      SAVESTK_1
+# define SAVESTK_3      SAVESTK_2
+# define SAVESTK_4      SAVESTK_3
+# define SAVESTK_5      lw t0, 16(sp);		\
+			subu sp, STKSPACE;	\
+			sw t0, 16(sp)
+
+# define SAVESTK_6      lw t0, 16(sp);		\
+			lw t1, 20(sp);		\
+			subu sp, STKSPACE;	\
+			sw t0, 16(sp);		\
+			sw t1, 20(sp)
+
+# define SAVESTK_7      lw t0, 16(sp);		\
+			lw t1, 20(sp);		\
+			lw t2, 24(sp);		\
+			subu sp, STKSPACE;	\
+			sw t0, 16(sp);		\
+			sw t1, 20(sp);		\
+			sw t2, 24(sp)
+
+# define RESTORESTK 	addu sp, STKSPACE
+
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	la t9, __pthread_enable_asynccancel; jalr t9;
+#  define CDISABLE	la t9, __pthread_disable_asynccancel; jalr t9;
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif defined IS_IN_librt
+#  define CENABLE	la t9, __librt_enable_asynccancel; jalr t9;
+#  define CDISABLE	la t9, __librt_disable_asynccancel; jalr t9;
+#  define __local_multiple_threads __librt_multiple_threads
+# else
+#  define CENABLE	la t9, __libc_enable_asynccancel; jalr t9;
+#  define CDISABLE	la t9, __libc_disable_asynccancel; jalr t9;
+#  define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  define SINGLE_THREAD_P(reg) lw reg, __local_multiple_threads
+#endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c b/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c
new file mode 100644
index 0000000000..e9c2b6e79a
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/mq_notify.c
@@ -0,0 +1,287 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contribute by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   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 <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysdep.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <not-cancel.h>
+
+
+#ifdef __NR_mq_notify
+
+/* Defined in the kernel headers: */
+#define NOTIFY_COOKIE_LEN	32	/* Length of the cookie used.  */
+#define NOTIFY_WOKENUP		1	/* Code for notifcation.  */
+#define NOTIFY_REMOVED		2	/* Code for closed message queue
+					   of de-notifcation.  */
+
+
+/* Data structure for the queued notification requests.  */
+union notify_data
+{
+  struct
+  {
+    void (*fct) (union sigval);	/* The function to run.  */
+    union sigval param;		/* The parameter to pass.  */
+    pthread_attr_t *attr;	/* Attributes to create the thread with.  */
+    /* NB: on 64-bit machines the struct as a size of 24 bytes.  Which means
+       byte 31 can still be used for returning the status.  */
+  };
+  char raw[NOTIFY_COOKIE_LEN];
+};
+
+
+/* Keep track of the initialization.  */
+static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+
+/* The netlink socket.  */
+static int netlink_socket = -1;
+
+
+/* Barrier used to make sure data passed to the new thread is not
+   resused by the parent.  */
+static pthread_barrier_t notify_barrier;
+
+
+/* Modify the signal mask.  We move this into a separate function so
+   that the stack space needed for sigset_t is not deducted from what
+   the thread can use.  */
+static int
+__attribute__ ((noinline))
+change_sigmask (int how, sigset_t *oss)
+{
+  sigset_t ss;
+  sigfillset (&ss);
+  return pthread_sigmask (how, &ss, oss);
+}
+
+
+/* The function used for the notification.  */
+static void *
+notification_function (void *arg)
+{
+  /* Copy the function and parameter so that the parent thread can go
+     on with its life.  */
+  volatile union notify_data *data = (volatile union notify_data *) arg;
+  void (*fct) (union sigval) = data->fct;
+  union sigval param = data->param;
+
+  /* Let the parent go.  */
+  (void) pthread_barrier_wait (&notify_barrier);
+
+  /* Make the thread detached.  */
+  (void) pthread_detach (pthread_self ());
+
+  /* The parent thread has all signals blocked.  This is probably a
+     bit surprising for this thread.  So we unblock all of them.  */
+  (void) change_sigmask (SIG_UNBLOCK, NULL);
+
+  /* Now run the user code.  */
+  fct (param);
+
+  /* And we are done.  */
+  return NULL;
+}
+
+
+/* Helper thread.  */
+static void *
+helper_thread (void *arg)
+{
+  while (1)
+    {
+      union notify_data data;
+
+      ssize_t n = recv (netlink_socket, &data, sizeof (data),
+			MSG_NOSIGNAL | MSG_WAITALL);
+      if (n < NOTIFY_COOKIE_LEN)
+	continue;
+
+      if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_WOKENUP)
+	{
+	  /* Just create the thread as instructed.  There is no way to
+	     report a problem with creating a thread.  */
+	  pthread_t th;
+	  if (__builtin_expect (pthread_create (&th, data.attr,
+						notification_function, &data)
+				== 0, 0))
+	    /* Since we passed a pointer to DATA to the new thread we have
+	       to wait until it is done with it.  */
+	    (void) pthread_barrier_wait (&notify_barrier);
+	}
+      else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
+	/* The only state we keep is the copy of the thread attributes.  */
+	free (data.attr);
+    }
+  return NULL;
+}
+
+
+static void
+reset_once (void)
+{
+  once = PTHREAD_ONCE_INIT;
+}
+
+
+static void
+init_mq_netlink (void)
+{
+  /* This code might be called a second time after fork().  The file
+     descriptor is inherited from the parent.  */
+  if (netlink_socket == -1)
+    {
+      /* Just a normal netlink socket, not bound.  */
+      netlink_socket = socket (AF_NETLINK, SOCK_RAW, 0);
+      /* No need to do more if we have no socket.  */
+      if (netlink_socket == -1)
+	return;
+
+      /* Make sure the descriptor is closed on exec.  */
+      if (fcntl (netlink_socket, F_SETFD, FD_CLOEXEC) != 0)
+	goto errout;
+    }
+
+  int err = 1;
+
+  /* Initialize the barrier.  */
+  if (__builtin_expect (pthread_barrier_init (&notify_barrier, NULL, 2) == 0,
+			0))
+    {
+      /* Create the helper thread.  */
+      pthread_attr_t attr;
+      (void) pthread_attr_init (&attr);
+      (void) pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+      /* We do not need much stack space, the bare minimum will be enough.  */
+      (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+      /* Temporarily block all signals so that the newly created
+	 thread inherits the mask.  */
+      sigset_t oss;
+      int have_no_oss = change_sigmask (SIG_BLOCK, &oss);
+
+      pthread_t th;
+      err = pthread_create (&th, &attr, helper_thread, NULL);
+
+      /* Reset the signal mask.  */
+      if (!have_no_oss)
+	pthread_sigmask (SIG_SETMASK, &oss, NULL);
+
+      (void) pthread_attr_destroy (&attr);
+
+      if (err == 0)
+	{
+	  static int added_atfork;
+
+	  if (added_atfork == 0
+	      && pthread_atfork (NULL, NULL, reset_once) != 0)
+	    {
+	      /* The child thread will call recv() which is a
+		 cancellation point.  */
+	      (void) pthread_cancel (th);
+	      err = 1;
+	    }
+	  else
+	    added_atfork = 1;
+	}
+    }
+
+  if (err != 0)
+    {
+    errout:
+      close_not_cancel_no_status (netlink_socket);
+      netlink_socket = -1;
+    }
+}
+
+
+/* Register notification upon message arrival to an empty message queue
+   MQDES.  */
+int
+mq_notify (mqd_t mqdes, const struct sigevent *notification)
+{
+  /* Make sure the type is correctly defined.  */
+  assert (sizeof (union notify_data) == NOTIFY_COOKIE_LEN);
+
+  /* Special treatment needed for SIGEV_THREAD.  */
+  if (notification == NULL || notification->sigev_notify != SIGEV_THREAD)
+    return INLINE_SYSCALL (mq_notify, 2, mqdes, notification);
+
+  /* The kernel cannot directly start threads.  This will have to be
+     done at userlevel.  Since we cannot start threads from signal
+     handlers we have to create a dedicated thread which waits for
+     notifications for arriving messages and creates threads in
+     response.  */
+
+  /* Initialize only once.  */
+  pthread_once (&once, init_mq_netlink);
+
+  /* If we cannot create the netlink socket we cannot provide
+     SIGEV_THREAD support.  */
+  if (__builtin_expect (netlink_socket == -1, 0))
+    {
+      __set_errno (ENOSYS);
+      return -1;
+    }
+
+  /* Create the cookie.  It will hold almost all the state.  */
+  union notify_data data;
+  memset (&data, '\0', sizeof (data));
+  data.fct = notification->sigev_notify_function;
+  data.param = notification->sigev_value;
+
+  if (notification->sigev_notify_attributes != NULL)
+    {
+      /* The thread attribute has to be allocated separately.  */
+      data.attr = (pthread_attr_t *) malloc (sizeof (pthread_attr_t));
+      if (data.attr == NULL)
+	return -1;
+
+      memcpy (data.attr, notification->sigev_notify_attributes,
+	      sizeof (pthread_attr_t));
+    }
+
+  /* Construct the new request.  */
+  struct sigevent se;
+  se.sigev_notify = SIGEV_THREAD;
+  se.sigev_signo = netlink_socket;
+  se.sigev_value.sival_ptr = &data;
+
+  /* Tell the kernel.  */
+  int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se);
+
+  /* If it failed, free the allocated memory.  */
+  if (__builtin_expect (retval != 0, 0))
+    free (data.attr);
+
+  return retval;
+}
+
+#else
+# include <sysdeps/generic/mq_notify.c>
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile
new file mode 100644
index 0000000000..e98c9bd866
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -0,0 +1,2 @@
+# pull in __syscall_error routine
+libpthread-routines += sysdep
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions
new file mode 100644
index 0000000000..326307c30c
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_2.3.4 {
+    longjmp;  siglongjmp;
+  }
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
new file mode 100644
index 0000000000..0ee10c1c3a
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -0,0 +1,131 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  .section ".text";							\
+  ENTRY (name)								\
+    SINGLE_THREAD_P;							\
+    bne- .Lpseudo_cancel;						\
+    DO_CALL (SYS_ify (syscall_name));					\
+    PSEUDO_RET;								\
+  .Lpseudo_cancel:							\
+    stwu 1,-48(1);							\
+    mflr 9;								\
+    stw 9,52(1);							\
+    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+    CENABLE;								\
+    stw 3,16(1);	/* store CENABLE return value (MASK).  */	\
+    UNDOCARGS_##args;	/* restore syscall args.  */			\
+    DO_CALL (SYS_ify (syscall_name));					\
+    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
+    stw 3,8(1);								\
+    stw 0,12(1);							\
+    lwz 3,16(1);	/* pass MASK to CDISABLE.  */			\
+    CDISABLE;								\
+    lwz 4,52(1);							\
+    lwz 0,12(1);	/* restore CR/R3. */				\
+    lwz 3,8(1);								\
+    mtlr 4;								\
+    mtcr 0;								\
+    addi 1,1,48;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1	stw 3,20(1); DOCARGS_0
+# define UNDOCARGS_1	lwz 3,20(1); UNDOCARGS_0
+
+# define DOCARGS_2	stw 4,24(1); DOCARGS_1
+# define UNDOCARGS_2	lwz 4,24(1); UNDOCARGS_1
+
+# define DOCARGS_3	stw 5,28(1); DOCARGS_2
+# define UNDOCARGS_3	lwz 5,28(1); UNDOCARGS_2
+
+# define DOCARGS_4	stw 6,32(1); DOCARGS_3
+# define UNDOCARGS_4	lwz 6,32(1); UNDOCARGS_3
+
+# define DOCARGS_5	stw 7,36(1); DOCARGS_4
+# define UNDOCARGS_5	lwz 7,36(1); UNDOCARGS_4
+
+# define DOCARGS_6	stw 8,40(1); DOCARGS_5
+# define UNDOCARGS_6	lwz 8,40(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel)
+# elif !defined NOT_IN_libc
+#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel)
+# else
+#  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel)
+# endif
+
+# ifdef HAVE_TLS_SUPPORT
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P						\
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+#  else
+#   define SINGLE_THREAD_P						\
+  lwz 10,MULTIPLE_THREADS_OFFSET(2);					\
+  cmpwi 10,0
+#  endif
+# else
+#  if !defined NOT_IN_libc
+#   define __local_multiple_threads __libc_multiple_threads
+#  else
+#   define __local_multiple_threads __librt_multiple_threads
+#  endif
+#  ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  else
+#   if !defined PIC
+#    define SINGLE_THREAD_P						\
+  lis 10,__local_multiple_threads@ha;					\
+  lwz 10,__local_multiple_threads@l(10);				\
+  cmpwi 10,0
+#   else
+#    define SINGLE_THREAD_P						\
+  mflr 9;								\
+  bl _GLOBAL_OFFSET_TABLE_@local-4;					\
+  mflr 10;								\
+  mtlr 9;								\
+  lwz 10,__local_multiple_threads@got(10);				\
+  lwz 10,0(10);								\
+  cmpwi 10,0
+#   endif
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
new file mode 100644
index 0000000000..ee6254a950
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/vfork.S
@@ -0,0 +1,78 @@
+/* Copyright (C) 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 <sysdep-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+# ifdef SHARED
+	mflr	9
+	bl	_GLOBAL_OFFSET_TABLE_@local-4
+	mflr	10
+	mtlr	9
+	lwz	10,__libc_pthread_functions@got(10)
+	lwz	10,0(10)
+# else
+	.weak	pthread_create
+	lis	10,pthread_create@ha
+	la	10,pthread_create@l(10)
+# endif
+
+	cmpwi	10,0
+	bne-	.Lhidden_fork
+
+	DO_CALL (SYS_ify (vfork));
+
+# ifdef __ASSUME_VFORK_SYSCALL
+	PSEUDO_RET
+# else
+	bnslr+
+	/* Check if vfork syscall is known at all.  */
+	cmpwi	r3,ENOSYS
+	bne-	.Lsyscall_error
+
+# endif
+
+.Lhidden_fork:
+	b	HIDDEN_JUMPTARGET(__fork)
+
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+	/* If we don't have vfork, fork is close enough.  */
+
+	DO_CALL (SYS_ify (fork));
+	bnslr+
+
+.Lsyscall_error:
+	b	JUMPTARGET(__syscall_error)
+#endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
new file mode 100644
index 0000000000..0c74676766
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  .section ".text";							\
+  ENTRY (name)								\
+    SINGLE_THREAD_P;							\
+    bne- .Lpseudo_cancel;						\
+    DO_CALL (SYS_ify (syscall_name));					\
+    PSEUDO_RET;								\
+  .Lpseudo_cancel:							\
+    stdu 1,-128(1);							\
+    mflr 9;								\
+    std  9,128+16(1);							\
+    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+    CENABLE;								\
+    std  3,72(1);	/* store CENABLE return value (MASK).  */	\
+    UNDOCARGS_##args;	/* restore syscall args.  */			\
+    DO_CALL (SYS_ify (syscall_name));					\
+    mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
+    std  3,64(1);								\
+    std  0,8(1);							\
+    ld   3,72(1);	/* pass MASK to CDISABLE.  */			\
+    CDISABLE;								\
+    ld   9,128+16(1);							\
+    ld   0,8(1);	/* restore CR/R3. */				\
+    ld   3,64(1);								\
+    mtlr 9;								\
+    mtcr 0;								\
+    addi 1,1,128;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+
+# define DOCARGS_1	std 3,80(1); DOCARGS_0
+# define UNDOCARGS_1	ld 3,80(1); UNDOCARGS_0
+
+# define DOCARGS_2	std 4,88(1); DOCARGS_1
+# define UNDOCARGS_2	ld 4,88(1); UNDOCARGS_1
+
+# define DOCARGS_3	std 5,96(1); DOCARGS_2
+# define UNDOCARGS_3	ld 5,96(1); UNDOCARGS_2
+
+# define DOCARGS_4	std 6,104(1); DOCARGS_3
+# define UNDOCARGS_4	ld 6,104(1); UNDOCARGS_3
+
+# define DOCARGS_5	std 7,112(1); DOCARGS_4
+# define UNDOCARGS_5	ld 7,112(1); UNDOCARGS_4
+
+# define DOCARGS_6	std 8,120(1); DOCARGS_5
+# define UNDOCARGS_6	ld 8,120(1); UNDOCARGS_5
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	bl JUMPTARGET(__pthread_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE	bl JUMPTARGET(__libc_enable_asynccancel)
+#  define CDISABLE	bl JUMPTARGET(__libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# else
+#  define CENABLE	bl JUMPTARGET(__librt_enable_asynccancel); nop
+#  define CDISABLE	bl JUMPTARGET(__librt_disable_asynccancel); nop
+#  define __local_multiple_threads __librt_multiple_threads
+# endif
+
+# ifdef HAVE_TLS_SUPPORT
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P						\
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+#  else
+#   define SINGLE_THREAD_P						\
+  lwz 10,MULTIPLE_THREADS_OFFSET(13);					\
+  cmpwi 10,0
+#  endif
+# else /* !HAVE_TLS_SUPPORT */
+#  ifndef __ASSEMBLER__
+extern int __local_multiple_threads
+#   if !defined NOT_IN_libc || defined IS_IN_libpthread
+  attribute_hidden;
+#   else
+  ;
+#   endif
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  else
+#   define SINGLE_THREAD_P						\
+	.section	".toc","aw";					\
+.LC__local_multiple_threads:;						\
+	.tc __local_multiple_threads[TC],__local_multiple_threads;	\
+  .previous;								\
+  ld    10,.LC__local_multiple_threads@toc(2);				\
+  lwz   10,0(10);							\
+  cmpwi 10,0
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
new file mode 100644
index 0000000000..b408e31b7b
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/vfork.S
@@ -0,0 +1,91 @@
+/* Copyright (C) 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 <sysdep-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <kernel-features.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+#ifdef SHARED
+	.section	".toc","aw"
+.LC0:
+	.tc __libc_pthread_functions[TC],__libc_pthread_functions
+	.section	".text"
+	.align 2
+#endif
+
+ENTRY (__vfork)
+
+#ifdef __NR_vfork
+
+# ifdef SHARED
+  ld  10,.LC0@toc(2)
+  ld  10,0(10)
+  cmpwi  10,0
+  bne-  HIDDEN_JUMPTARGET(__fork)
+# else
+  .weak  pthread_create
+	lis  10,pthread_create@highest
+	ori  10,10,pthread_create@higher
+  sldi 10,10,32
+  oris 10,10,pthread_create@h
+  ori  10,10,pthread_create@l
+  cmpwi  10,0
+  bne-  .Lhidden_fork
+# endif
+
+	DO_CALL (SYS_ify (vfork));
+
+# ifdef __ASSUME_VFORK_SYSCALL
+  PSEUDO_RET
+# else
+  bnslr+
+  /* Check if vfork syscall is known at all.  */
+  cmpdi	r3,ENOSYS
+# ifdef SHARED
+  bne	JUMPTARGET(__syscall_error)
+# else
+  bne-  .Lsyscall_error
+# endif
+
+# endif
+#endif
+
+#ifndef __ASSUME_VFORK_SYSCALL
+	/* If we don't have vfork, fork is close enough.  */
+
+	DO_CALL (SYS_ify (fork));
+	PSEUDO_RET
+#endif
+
+# ifndef SHARED
+.Lhidden_fork:
+	b	HIDDEN_JUMPTARGET(__fork)
+.Lsyscall_error:
+	b	JUMPTARGET(__syscall_error)
+# endif
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c
new file mode 100644
index 0000000000..177256c7fb
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/ptlongjmp.c
@@ -0,0 +1,70 @@
+/* Linuxthreads - a simple clone()-based implementation of Posix        */
+/* threads for Linux.                                                   */
+/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr)              */
+/*                                                                      */
+/* This program is free software; you can redistribute it and/or        */
+/* modify it under the terms of the GNU Library General Public License  */
+/* as published by the Free Software Foundation; either version 2       */
+/* of the License, or (at your option) any later version.               */
+/*                                                                      */
+/* This program 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 Library General Public License for more details.                 */
+
+/* Redefine siglongjmp and longjmp so that they interact correctly
+   with cleanup handlers */
+/* Derived from linuxthreads/ptlongjmp.c & added AltiVec/VMX versioning. */
+#include "pthread.h"
+#include <setjmp.h>
+#include <bits/wordsize.h>
+#include <shlib-compat.h>
+#if defined SHARED
+# if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3_4)
+
+/* These functions are not declared anywhere since they shouldn't be
+   used at another place but here.  */
+extern void __novmx__libc_siglongjmp (sigjmp_buf env, int val)
+     __attribute__ ((noreturn));
+extern void __novmx__libc_longjmp (sigjmp_buf env, int val)
+     __attribute__ ((noreturn));
+
+
+void __novmx_siglongjmp (sigjmp_buf env, int val)
+{
+  __novmx__libc_siglongjmp (env, val);
+}
+
+void __novmx_longjmp (jmp_buf env, int val)
+{
+  __novmx__libc_longjmp (env, val);
+}
+
+#  if __WORDSIZE == 64
+symbol_version (__novmx_longjmp,longjmp,GLIBC_2.3);
+symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.3);
+#  else
+symbol_version (__novmx_longjmp,longjmp,GLIBC_2.0);
+symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.0);
+#  endif
+# endif  /* SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3_4) ) */
+
+/* These functions are not declared anywhere since they shouldn't be
+   used at another place but here.  */
+extern void __vmx__libc_siglongjmp (sigjmp_buf env, int val)
+     __attribute__ ((noreturn));
+extern void __vmx__libc_longjmp (sigjmp_buf env, int val)
+     __attribute__ ((noreturn));
+
+void __vmx_siglongjmp (sigjmp_buf env, int val)
+{
+  __vmx__libc_siglongjmp (env, val);
+}
+
+void __vmx_longjmp (jmp_buf env, int val)
+{
+  __vmx__libc_longjmp (env, val);
+}
+default_symbol_version (__vmx_longjmp,longjmp,GLIBC_2.3.4);
+default_symbol_version (__vmx_siglongjmp,siglongjmp,GLIBC_2.3.4);
+#endif /* SHARED */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c
new file mode 100644
index 0000000000..5528c55ca5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/pt-sigsuspend.c
@@ -0,0 +1,56 @@
+/* Internal sigsuspend system call for LinuxThreads.  Generic Linux version.
+   Copyright (C) 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 <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+#include <linuxthreads/internals.h>
+
+#include "kernel-features.h"
+
+void
+__pthread_sigsuspend (const sigset_t *set)
+{
+  INTERNAL_SYSCALL_DECL (err);
+#if !__ASSUME_REALTIME_SIGNALS
+  static int __pthread_missing_rt_sigs;
+
+# ifdef __NR_rt_sigsuspend
+  /* First try the RT signals.  */
+  if (!__pthread_missing_rt_sigs)
+    {
+      /* XXX The size argument hopefully will have to be changed to the
+	 real size of the user-level sigset_t.  */
+      int r;
+      r = INTERNAL_SYSCALL (rt_sigsuspend, err, 2, set, _NSIG / 8);
+      if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS)
+	return;
+
+      __pthread_missing_rt_sigs = 1;
+    }
+# endif
+
+  INTERNAL_SYSCALL (sigsuspend, err, 3, 0, 0, set->__val[0]);
+#else
+  INTERNAL_SYSCALL (rt_sigsuspend, err, 2, set, _NSIG / 8);
+#endif
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/raise.c b/linuxthreads/sysdeps/unix/sysv/linux/raise.c
new file mode 100644
index 0000000000..9dad2b2697
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/raise.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1996, 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 <signal.h>
+#include <unistd.h>
+#include <bits/libc-lock.h>
+
+#ifndef SHARED
+weak_extern (__pthread_raise)
+#endif
+
+/* Raise the signal SIG.  */
+int
+raise (sig)
+     int sig;
+{
+  return __libc_maybe_call2 (pthread_raise, (sig),
+			     __kill (__getpid (), sig));
+}
+libc_hidden_def (raise)
+weak_alias (raise, gsignal)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c b/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c
new file mode 100644
index 0000000000..e4490e73e9
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 2002 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 <errno.h>
+#include <stdlib.h>
+#include "fork.h"
+
+
+int
+__register_atfork (prepare, parent, child, dso_handle)
+     void (*prepare) (void);
+     void (*parent) (void);
+     void (*child) (void);
+     void *dso_handle;
+{
+  struct fork_handler *new_prepare = NULL;
+  struct fork_handler *new_parent = NULL;
+  struct fork_handler *new_child = NULL;
+
+  if (prepare != NULL)
+    {
+      new_prepare = (struct fork_handler *) malloc (sizeof (*new_prepare));
+      if (new_prepare == NULL)
+	goto out1;
+
+      new_prepare->handler = prepare;
+      new_prepare->dso_handle = dso_handle;
+    }
+
+  if (parent != NULL)
+    {
+      new_parent = (struct fork_handler *) malloc (sizeof (*new_parent));
+      if (new_parent == NULL)
+	goto out2;
+
+      new_parent->handler = parent;
+      new_parent->dso_handle = dso_handle;
+    }
+
+  if (child != NULL)
+    {
+      new_child = (struct fork_handler *) malloc (sizeof (*new_child));
+      if (new_child == NULL)
+	{
+	  free (new_parent);
+	out2:
+	  free (new_prepare);
+	out1:
+	  return errno;
+	}
+
+      new_child->handler = child;
+      new_child->dso_handle = dso_handle;
+    }
+
+  /* Get the lock to not conflict with running forks.  */
+  __libc_lock_lock (__fork_block.lock);
+
+  /* Now that we have all the handlers allocate enqueue them.  */
+  if (new_prepare != NULL)
+    list_add_tail (&new_prepare->list, &__fork_block.prepare_list);
+  if (new_parent != NULL)
+    list_add_tail (&new_parent->list, &__fork_block.parent_list);
+  if (new_child != NULL)
+    list_add_tail (&new_child->list, &__fork_block.child_list);
+
+  /* Release the lock.  */
+  __libc_lock_unlock (__fork_block.lock);
+
+  return 0;
+}
+libc_hidden_def (__register_atfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
new file mode 100644
index 0000000000..bee7639f06
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
@@ -0,0 +1,72 @@
+/* bits/typesizes.h -- underlying types for *_t.  Linux/s390 version.
+   Copyright (C) 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 _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef	_BITS_TYPESIZES_H
+#define	_BITS_TYPESIZES_H	1
+
+/* See <bits/types.h> for the meaning of these macros.  This file exists so
+   that <bits/types.h> need not vary across different GNU platforms.  */
+
+#define __DEV_T_TYPE		__UQUAD_TYPE
+#define __UID_T_TYPE		__U32_TYPE
+#define __GID_T_TYPE		__U32_TYPE
+#define __INO_T_TYPE		__ULONGWORD_TYPE
+#define __INO64_T_TYPE		__UQUAD_TYPE
+#define __MODE_T_TYPE		__U32_TYPE
+#define __NLINK_T_TYPE		__UWORD_TYPE
+#define __OFF_T_TYPE		__SLONGWORD_TYPE
+#define __OFF64_T_TYPE		__SQUAD_TYPE
+#define __PID_T_TYPE		__S32_TYPE
+#define __RLIM_T_TYPE		__ULONGWORD_TYPE
+#define __RLIM64_T_TYPE		__UQUAD_TYPE
+#define	__BLKCNT_T_TYPE		__SLONGWORD_TYPE
+#define	__BLKCNT64_T_TYPE	__SQUAD_TYPE
+#define	__FSBLKCNT_T_TYPE	__ULONGWORD_TYPE
+#define	__FSBLKCNT64_T_TYPE	__UQUAD_TYPE
+#define	__FSFILCNT_T_TYPE	__ULONGWORD_TYPE
+#define	__FSFILCNT64_T_TYPE	__UQUAD_TYPE
+#define	__ID_T_TYPE		__U32_TYPE
+#define __CLOCK_T_TYPE		__SLONGWORD_TYPE
+#define __TIME_T_TYPE		__SLONGWORD_TYPE
+#define __USECONDS_T_TYPE	__U32_TYPE
+#define __SUSECONDS_T_TYPE	__SLONGWORD_TYPE
+#define __DADDR_T_TYPE		__S32_TYPE
+#define __SWBLK_T_TYPE		__SLONGWORD_TYPE
+#define __KEY_T_TYPE		__S32_TYPE
+#define __CLOCKID_T_TYPE	__S32_TYPE
+#define __TIMER_T_TYPE		__S32_TYPE
+#define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE
+#define __FSID_T_TYPE		struct { int __val[2]; }
+#if defined __GNUC__ && __GNUC__ <= 2
+/* Compatibility with g++ 2.95.x.  */
+#define __SSIZE_T_TYPE		__SWORD_TYPE
+#else
+/* size_t is unsigned long int on s390 -m31.  */
+#define __SSIZE_T_TYPE		__SLONGWORD_TYPE
+#endif
+
+/* Number of descriptors that can fit in an `fd_set'.  */
+#define	__FD_SETSIZE		1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c
new file mode 100644
index 0000000000..b7d901c4c6
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/pt-initfini.c
@@ -0,0 +1,154 @@
+/* Special .init and .fini section support for S/390.
+   Copyright (C) 2000, 2001 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+__asm__ ("\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+\n\
+	.section .init\n\
+#NO_APP\n\
+	.align 4\n\
+.globl _init\n\
+	.type	 _init,@function\n\
+_init:\n\
+#	leaf function           0\n\
+#	automatics              0\n\
+#	outgoing args           0\n\
+#	need frame pointer      0\n\
+#	call alloca             0\n\
+#	has varargs             0\n\
+#	incoming args (stack)   0\n\
+#	function length         36\n\
+	STM	6,15,24(15)\n\
+	BRAS	13,.LTN1_0\n\
+.LT1_0:\n\
+.LC13:\n\
+	.long	__pthread_initialize_minimal@PLT-.LT1_0\n\
+.LC14:\n\
+	.long	__gmon_start__@GOT\n\
+.LC15:\n\
+	.long	_GLOBAL_OFFSET_TABLE_-.LT1_0\n\
+.LTN1_0:\n\
+	LR	1,15\n\
+	AHI	15,-96\n\
+	ST	1,0(15)\n\
+	L	12,.LC15-.LT1_0(13)\n\
+	AR	12,13\n\
+	L     1,.LC13-.LT1_0(13)\n\
+	LA    1,0(1,13)\n\
+	BASR  14,1\n\
+	L     1,.LC14-.LT1_0(13)\n\
+	L     1,0(1,12)\n\
+	LTR   1,1\n\
+	JE    .L22\n\
+	BASR  14,1\n\
+.L22:\n\
+#APP\n\
+	.align 4,0x07\n\
+	END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+	.align 4\n\
+	.section .init\n\
+#NO_APP\n\
+	.align 4\n\
+	L	4,152(15)\n\
+	LM	6,15,120(15)\n\
+	BR	4\n\
+#APP\n\
+	END_INIT\n\
+\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+	.section .fini\n\
+#NO_APP\n\
+	.align 4\n\
+.globl _fini\n\
+	.type	 _fini,@function\n\
+_fini:\n\
+#	leaf function           0\n\
+#	automatics              0\n\
+#	outgoing args           0\n\
+#	need frame pointer      0\n\
+#	call alloca             0\n\
+#	has varargs             0\n\
+#	incoming args (stack)   0\n\
+#	function length         30\n\
+	STM	6,15,24(15)\n\
+	BRAS	13,.LTN2_0\n\
+.LT2_0:\n\
+.LC17:\n\
+	.long	_GLOBAL_OFFSET_TABLE_-.LT2_0\n\
+.LTN2_0:\n\
+	LR	1,15\n\
+	AHI	15,-96\n\
+	ST	1,0(15)\n\
+	L	12,.LC17-.LT2_0(13)\n\
+	AR	12,13\n\
+#APP\n\
+	.align 4,0x07\n\
+	END_FINI\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+	.align 4\n\
+	.section .fini\n\
+#NO_APP\n\
+	.align 4\n\
+	L	4,152(15)\n\
+	LM	6,15,120(15)\n\
+	BR	4\n\
+#APP\n\
+	END_FINI\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\
+");
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
new file mode 100644
index 0000000000..06f7aed7dc
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h
@@ -0,0 +1,137 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+#  define PSEUDO_CANCEL(name, syscall_name, args)			      \
+L(pseudo_cancel):							      \
+	STM_##args							      \
+	stm	%r12,%r15,48(%r15);					      \
+	lr	%r14,%r15;						      \
+	ahi	%r15,-96;						      \
+	st	%r14,0(%r15);						      \
+	basr    %r13,0;							      \
+0:	l	%r1,1f-0b(%r13);					      \
+	bas	%r14,0(%r1,%r13);					      \
+	lr	%r0,%r2;						      \
+	LM_##args							      \
+	DO_CALL(syscall_name, args);					      \
+	l	%r1,2f-0b(%r13);					      \
+	lr	%r12,%r2;						      \
+	lr	%r2,%r0;						      \
+	bas	%r14,0(%r1,%r13);					      \
+	lr	%r2,%r12;						      \
+	lm	%r12,%r15,48+96(%r15);					      \
+	j	L(pseudo_check);					      \
+1:	.long	CENABLE-0b;						      \
+2:	.long	CDISABLE-0b;
+
+# else /* !libc.so && !libpthread.so */
+
+#  define PSEUDO_CANCEL(name, syscall_name, args)			      \
+L(pseudo_cancel):							      \
+	STM_##args							      \
+	stm	%r11,%r15,44(%r15);					      \
+	lr	%r14,%r15;						      \
+	ahi	%r15,-96;						      \
+	st	%r14,0(%r15);						      \
+	basr    %r13,0;							      \
+0:	l	%r12,3f-0b(%r13);					      \
+	l	%r1,1f-0b(%r13);					      \
+	la	%r12,0(%r12,%r13);					      \
+	bas	%r14,0(%r1,%r13);					      \
+	lr	%r0,%r2;						      \
+	LM_##args							      \
+	DO_CALL(syscall_name, args);					      \
+	l	%r1,2f-0b(%r13);					      \
+	lr	%r11,%r2;						      \
+	lr	%r2,%r0;						      \
+	bas	%r14,0(%r1,%r13);					      \
+	lr	%r2,%r11;						      \
+	lm	%r11,%r15,44+96(%r15);					      \
+	j	L(pseudo_check);					      \
+1:	.long	CENABLE@PLT-0b;						      \
+2:	.long	CDISABLE@PLT-0b;					      \
+3:	.long	_GLOBAL_OFFSET_TABLE_-0b;
+
+# endif
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+	.text;								      \
+PSEUDO_CANCEL(name, syscall_name, args)					      \
+ENTRY(name)								      \
+	SINGLE_THREAD_P(%r1)						      \
+	jne	L(pseudo_cancel);					      \
+	DO_CALL(syscall_name, args);					      \
+L(pseudo_check):							      \
+	lhi	%r4,-4095;						      \
+	clr	%r2,%r4;						      \
+	jnl	SYSCALL_ERROR_LABEL;					      \
+L(pseudo_end):
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	__pthread_enable_asynccancel
+#  define CDISABLE	__pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+#  define CENABLE	__libc_enable_asynccancel
+#  define CDISABLE	__libc_disable_asynccancel
+# else
+#  define CENABLE	__librt_enable_asynccancel
+#  define CDISABLE	__librt_disable_asynccancel
+# endif
+
+#define STM_0		/* Nothing */
+#define STM_1		st %r2,8(%r15);
+#define STM_2		stm %r2,%r3,8(%r15);
+#define STM_3		stm %r2,%r4,8(%r15);
+#define STM_4		stm %r2,%r5,8(%r15);
+#define STM_5		stm %r2,%r5,8(%r15);
+
+#define LM_0		/* Nothing */
+#define LM_1		l %r2,8+96(%r15);
+#define LM_2		lm %r2,%r3,8+96(%r15);
+#define LM_3		lm %r2,%r4,8+96(%r15);
+#define LM_4		lm %r2,%r5,8+96(%r15);
+#define LM_5		lm %r2,%r5,8+96(%r15);
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P(reg) \
+	ear	reg,%a0;						      \
+	icm	reg,15,MULTIPLE_THREADS_OFFSET(reg);
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S
new file mode 100644
index 0000000000..6dfeca86d4
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-32/vfork.S
@@ -0,0 +1,69 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+   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-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+	basr	%r1,0
+0:
+#ifdef SHARED
+	al	%r1,4f-0b(%r1)
+	l	%r1,0(%r1)
+	ltr	%r1,%r1
+#else
+	icm	%r1,15,4f-0b(%r1)
+#endif
+	jne	1f
+
+	/* Do vfork system call.  */
+	svc	SYS_ify (vfork)
+
+	/* Check for error.  */
+	lhi	%r4,-4095
+	clr	%r2,%r4
+	jnl	SYSCALL_ERROR_LABEL
+
+	/* Normal return.  */
+	br	%r14
+1:
+	basr	%r1,0
+2:
+	al	%r1,3f-2b(%r1)
+	br	%r1
+3:
+	.long	HIDDEN_JUMPTARGET(__fork)-2b
+4:
+#ifdef SHARED
+	.long	__libc_pthread_functions-0b
+#else
+	.weak	pthread_create
+	.long	pthread_create
+#endif
+PSEUDO_END(__vfork)
+
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c
new file mode 100644
index 0000000000..540443e6a3
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-initfini.c
@@ -0,0 +1,137 @@
+/* Special .init and .fini section support for 64 bit S/390.
+   Copyright (C) 2001 Free Software Foundation, Inc.
+   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
+   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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+__asm__ ("\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+\n\
+	.section .init\n\
+#NO_APP\n\
+	.align 4\n\
+.globl _init\n\
+	.type	 _init,@function\n\
+_init:\n\
+#	leaf function           0\n\
+#	automatics              0\n\
+#	outgoing args           0\n\
+#	need frame pointer      0\n\
+#	call alloca             0\n\
+#	has varargs             0\n\
+#	incoming args (stack)   0\n\
+#	function length         36\n\
+	STMG	6,15,48(15)\n\
+	LGR	1,15\n\
+	AGHI	15,-160\n\
+	STG	1,0(15)\n\
+	LARL	12,_GLOBAL_OFFSET_TABLE_\n\
+	BRASL	14,__pthread_initialize_minimal@PLT\n\
+	LARL	1,__gmon_start__@GOTENT\n\
+	LG	1,0(1)\n\
+	LTGR	1,1\n\
+	JE	.L22\n\
+	BASR	14,1\n\
+.L22:\n\
+#APP\n\
+	.align 4,0x07\n\
+	END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+	.align 4\n\
+	.section .init\n\
+#NO_APP\n\
+	.align 4\n\
+	LG	4,272(15)\n\
+	LMG	6,15,208(15)\n\
+	BR	4\n\
+#APP\n\
+	END_INIT\n\
+\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+	.section .fini\n\
+#NO_APP\n\
+	.align 4\n\
+.globl _fini\n\
+	.type	 _fini,@function\n\
+_fini:\n\
+#	leaf function           0\n\
+#	automatics              0\n\
+#	outgoing args           0\n\
+#	need frame pointer      0\n\
+#	call alloca             0\n\
+#	has varargs             0\n\
+#	incoming args (stack)   0\n\
+#	function length         30\n\
+	STMG	6,15,48(15)\n\
+	LGR	1,15\n\
+	AGHI	15,-160\n\
+	STG	1,0(15)\n\
+	LARL	12,_GLOBAL_OFFSET_TABLE_\n\
+#APP\n\
+	.align 4,0x07\n\
+	END_FINI\n\
+\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+	.align 4\n\
+	.section .fini\n\
+#NO_APP\n\
+	.align 4\n\
+	LG	4,272(15)\n\
+	LMG	6,15,208(15)\n\
+	BR	4\n\
+#APP\n\
+	END_FINI\n\
+\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+	");
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c
new file mode 100644
index 0000000000..d57283ad23
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/pt-sigsuspend.c
@@ -0,0 +1 @@
+#include "../../ia64/pt-sigsuspend.c"
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
new file mode 100644
index 0000000000..f71ef3f689
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h
@@ -0,0 +1,116 @@
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+	.text;								      \
+L(pseudo_cancel):							      \
+	STM_##args							      \
+	stmg	%r13,%r15,104(%r15);					      \
+	lgr	%r14,%r15;						      \
+	aghi	%r15,-160;						      \
+	stg	%r14,0(%r15);						      \
+	brasl	%r14,CENABLE;						      \
+	lgr	%r0,%r2;						      \
+	LM_##args							      \
+	DO_CALL(syscall_name, args);					      \
+	lgr	%r13,%r2;						      \
+	lgr	%r2,%r0;						      \
+	brasl	%r14,CDISABLE;						      \
+	lgr	%r2,%r13;						      \
+	lmg	%r13,%r15,104+160(%r15);				      \
+	j	L(pseudo_check);					      \
+ENTRY(name)								      \
+	SINGLE_THREAD_P							      \
+	jne	L(pseudo_cancel);					      \
+	DO_CALL(syscall_name, args);					      \
+L(pseudo_check):							      \
+	lghi	%r4,-4095;						      \
+	clgr	%r2,%r4;						      \
+	jgnl	SYSCALL_ERROR_LABEL;					      \
+L(pseudo_end):
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	__pthread_enable_asynccancel
+#  define CDISABLE	__pthread_disable_asynccancel
+#  define __local_multiple_threads	__pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE	__libc_enable_asynccancel
+#  define CDISABLE	__libc_disable_asynccancel
+#  define __local_multiple_threads	__libc_multiple_threads
+# else
+#  define CENABLE	__librt_enable_asynccancel@PLT
+#  define CDISABLE	__librt_disable_asynccancel@PLT
+# endif
+
+#define STM_0		/* Nothing */
+#define STM_1		stg %r2,16(%r15);
+#define STM_2		stmg %r2,%r3,16(%r15);
+#define STM_3		stmg %r2,%r4,16(%r15);
+#define STM_4		stmg %r2,%r5,16(%r15);
+#define STM_5		stmg %r2,%r5,16(%r15);
+
+#define LM_0		/* Nothing */
+#define LM_1		lg %r2,16+160(%r15);
+#define LM_2		lmg %r2,%r3,16+160(%r15);
+#define LM_3		lmg %r2,%r4,16+160(%r15);
+#define LM_4		lmg %r2,%r5,16+160(%r15);
+#define LM_5		lmg %r2,%r5,16+160(%r15);
+
+# if !defined NOT_IN_libc || defined IS_IN_libpthread
+#  ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P \
+  __builtin_expect (__local_multiple_threads == 0, 1)
+#  else
+#   define SINGLE_THREAD_P \
+	larl	%r1,__local_multiple_threads;				      \
+	icm	%r0,15,0(%r1);
+#  endif
+
+# else
+
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+#  else
+#   define SINGLE_THREAD_P \
+	ear	%r1,%a0;						      \
+	sllg	%r1,%r1,32;						      \
+	ear	%r1,%a1;						      \
+	icm	%r1,15,MULTIPLE_THREADS_OFFSET(%r1);
+#  endif
+
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S
new file mode 100644
index 0000000000..199f0017ff
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/s390/s390-64/vfork.S
@@ -0,0 +1,54 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+   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-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+#ifdef SHARED
+	larl	%r1,__libc_pthread_functions
+	lg	%r1,0(%r1)
+#else
+	.weak	pthread_create
+	larl	%r1,pthread_create
+#endif
+	ltgr	%r1,%r1
+	jgne	HIDDEN_JUMPTARGET(__fork)
+
+	/* Do vfork system call.  */
+	svc	SYS_ify (vfork)
+
+	/* Check for error.  */
+	lghi	%r4,-4095
+	clgr	%r2,%r4
+	jgnl	SYSCALL_ERROR_LABEL
+
+	/* Normal return.  */
+	br	%r14
+PSEUDO_END(__vfork)
+
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c
new file mode 100644
index 0000000000..1cdb98f0f7
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/pt-initfini.c
@@ -0,0 +1,143 @@
+/* Special .init and .fini section support for SH. Linuxthread version.
+   Copyright (C) 2000, 2001, 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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   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, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This file is compiled into assembly code which is then munged by a sed
+   script into two files: crti.s and crtn.s.
+
+   * crti.s puts a function prologue at the beginning of the
+   .init and .fini sections and defines global symbols for
+   those addresses, so they can be called as functions.
+
+   * crtn.s puts the corresponding function epilogues
+   in the .init and .fini sections. */
+
+__asm__ ("\n\
+\n\
+#include \"defs.h\"\n\
+\n\
+/*@HEADER_ENDS*/\n\
+\n\
+/*@TESTS_BEGIN*/\n\
+\n\
+/*@TESTS_END*/\n\
+\n\
+/*@_init_PROLOG_BEGINS*/\n\
+	.section .init\n\
+	.align 5\n\
+	.global	_init\n\
+	.type	_init,@function\n\
+_init:\n\
+	mov.l	r12,@-r15\n\
+	mov.l	r14,@-r15\n\
+	sts.l	pr,@-r15\n\
+	mova	.L22,r0\n\
+	mov.l	.L22,r12\n\
+	add	r0,r12\n\
+	mova	.L24,r0\n\
+	mov.l	.L24,r1\n\
+	add	r0,r1\n\
+	jsr	@r1\n\
+	 nop\n\
+	mova	.L23,r0\n\
+	mov.l	.L23,r1\n\
+	add	r0,r1\n\
+	jsr	@r1\n\
+	 mov	r15,r14\n\
+	bra	1f\n\
+	 nop\n\
+	.align 2\n\
+.L22:\n\
+	.long	_GLOBAL_OFFSET_TABLE_\n\
+.L23:\n\
+	.long	__gmon_start__@PLT\n\
+.L24:\n\
+	.long	__pthread_initialize_minimal@PLT\n\
+1:\n\
+	ALIGN\n\
+	END_INIT\n\
+\n\
+/*@_init_PROLOG_ENDS*/\n\
+\n\
+/*@_init_EPILOG_BEGINS*/\n\
+	.section .init\n\
+	mov	r14,r15\n\
+	lds.l	@r15+,pr\n\
+	mov.l	@r15+,r14\n\
+	rts	\n\
+	mov.l	@r15+,r12\n\
+	END_INIT\n\
+	.section .text\n\
+	.align 5\n\
+	.weak	__gmon_start__\n\
+	.type	__gmon_start__,@function\n\
+__gmon_start__:\n\
+	mov.l	r14,@-r15\n\
+	mov	r15,r14\n\
+	mov	r14,r15\n\
+	rts	\n\
+	mov.l	@r15+,r14\n\
+	\n\
+/*@_init_EPILOG_ENDS*/\n\
+\n\
+/*@_fini_PROLOG_BEGINS*/\n\
+	.section .fini\n\
+	.align 5\n\
+	.global	_fini\n\
+	.type	_fini,@function\n\
+_fini:\n\
+	mov.l	r12,@-r15\n\
+	mov.l	r14,@-r15\n\
+	sts.l	pr,@-r15\n\
+	mova	.L27,r0\n\
+	mov.l	.L27,r12\n\
+	add	r0,r12\n\
+	mov	r15,r14\n\
+	ALIGN\n\
+	END_FINI\n\
+	bra	1f\n\
+	 nop\n\
+	.align	2\n\
+.L27:\n\
+	.long	_GLOBAL_OFFSET_TABLE_\n\
+1:\n\
+/*@_fini_PROLOG_ENDS*/\n\
+\n\
+/*@_fini_EPILOG_BEGINS*/\n\
+	.section .fini\n\
+	mov	r14,r15\n\
+	lds.l	@r15+,pr\n\
+	mov.l	@r15+,r14\n\
+	rts	\n\
+	mov.l	@r15+,r12\n\
+\n\
+	END_FINI\n\
+	\n\
+/*@_fini_EPILOG_ENDS*/\n\
+\n\
+/*@TRAILER_BEGINS*/\n\
+");
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h
new file mode 100644
index 0000000000..2c0cbe99ac
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h
@@ -0,0 +1,24 @@
+/* Determine whether the host has multiple processors.  SH version.
+   Copyright (C) 2002 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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.  */
+
+static inline int
+is_smp_system (void)
+{
+  return 0;
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
new file mode 100644
index 0000000000..03c6fedbfe
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -0,0 +1,227 @@
+/* Copyright (C) 2003, 2004 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 <sysdep.h>
+#include <tls.h>
+#include <pt-machine.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# define _IMM12 #-12
+# define _IMM16 #-16
+# define _IMP16 #16
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+  .text; \
+  ENTRY (name); \
+    SINGLE_THREAD_P; \
+    bf .Lpseudo_cancel; \
+    DO_CALL (syscall_name, args); \
+    mov r0,r1; \
+    mov _IMM12,r2; \
+    shad r2,r1; \
+    not r1,r1; \
+    tst r1,r1; \
+    bt .Lsyscall_error; \
+    bra .Lpseudo_end; \
+     nop; \
+ .Lpseudo_cancel: \
+    sts.l pr,@-r15; \
+    add _IMM16,r15; \
+    SAVE_ARGS_##args; \
+    CENABLE; \
+    LOAD_ARGS_##args; \
+    add _IMP16,r15; \
+    lds.l @r15+,pr; \
+    DO_CALL(syscall_name, args); \
+    SYSCALL_INST_PAD; \
+    sts.l pr,@-r15; \
+    mov.l r0,@-r15; \
+    CDISABLE; \
+    mov.l @r15+,r0; \
+    lds.l @r15+,pr; \
+    mov r0,r1; \
+    mov _IMM12,r2; \
+    shad r2,r1; \
+    not r1,r1; \
+    tst r1,r1; \
+    bf .Lpseudo_end; \
+ .Lsyscall_error: \
+    SYSCALL_ERROR_HANDLER; \
+ .Lpseudo_end:
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) \
+  END (sym)
+
+# define SAVE_ARGS_0	/* Nothing.  */
+# define SAVE_ARGS_1	SAVE_ARGS_0; mov.l r4,@(0,r15)
+# define SAVE_ARGS_2	SAVE_ARGS_1; mov.l r5,@(4,r15)
+# define SAVE_ARGS_3	SAVE_ARGS_2; mov.l r6,@(8,r15)
+# define SAVE_ARGS_4	SAVE_ARGS_3; mov.l r7,@(12,r15)
+# define SAVE_ARGS_5	SAVE_ARGS_4
+# define SAVE_ARGS_6	SAVE_ARGS_5
+
+# define LOAD_ARGS_0	/* Nothing.  */
+# define LOAD_ARGS_1	LOAD_ARGS_0; mov.l @(0,r15),r4
+# define LOAD_ARGS_2	LOAD_ARGS_1; mov.l @(4,r15),r5
+# define LOAD_ARGS_3	LOAD_ARGS_2; mov.l @(8,r15),r6
+# define LOAD_ARGS_4	LOAD_ARGS_3; mov.l @(12,r15),r7
+# define LOAD_ARGS_5	LOAD_ARGS_4
+# define LOAD_ARGS_6	LOAD_ARGS_5
+
+# ifdef IS_IN_libpthread
+#  define __local_enable_asynccancel	__pthread_enable_asynccancel
+#  define __local_disable_asynccancel	__pthread_disable_asynccancel
+#  define __local_multiple_threads	__pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define __local_enable_asynccancel	__libc_enable_asynccancel
+#  define __local_disable_asynccancel	__libc_disable_asynccancel
+#  define __local_multiple_threads	__libc_multiple_threads
+# else
+#  define __local_enable_asynccancel	__librt_enable_asynccancel
+#  define __local_disable_asynccancel	__librt_disable_asynccancel
+#  define __local_multiple_threads	__librt_multiple_threads
+# endif
+
+# if defined IS_IN_librt && defined PIC
+#  define CENABLE \
+	mov.l r12,@-r15; \
+	mov.l 1f,r12; \
+	mova 1f,r0; \
+	add r0,r12; \
+	mov.l 2f,r0; \
+	bsrf r0; \
+	 nop; \
+     0: bra 3f; \
+	 mov r0,r2; \
+	.align 2; \
+     1: .long _GLOBAL_OFFSET_TABLE_; \
+     2: .long __local_enable_asynccancel@PLT - (0b-.); \
+     3: mov.l @r15+,r12
+
+#  define CDISABLE \
+	mov.l r12,@-r15; \
+	mov.l 1f,r12; \
+	mova 1f,r0; \
+	add r0,r12; \
+	mov.l 2f,r0; \
+	bsrf r0; \
+	 mov r2,r4; \
+     0: bra 3f; \
+	 nop; \
+	.align 2; \
+     1: .long _GLOBAL_OFFSET_TABLE_; \
+     2: .long __local_disable_asynccancel@PLT - (0b-.); \
+     3: mov.l @r15+,r12
+# else
+#  define CENABLE \
+	mov.l 1f,r0; \
+	bsrf r0; \
+	 nop; \
+     0: bra 2f; \
+	 mov r0,r2; \
+	.align 2; \
+     1: .long __local_enable_asynccancel - 0b; \
+     2:
+
+#  define CDISABLE \
+	mov.l 1f,r0; \
+	bsrf r0; \
+	 mov r2,r4; \
+     0: bra 2f; \
+	 nop; \
+	.align 2; \
+     1: .long __local_disable_asynccancel - 0b; \
+     2:
+# endif
+
+# ifndef __ASSEMBLER__
+#  if defined FLOATING_STACKS && USE___THREAD && defined PIC
+#   define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+#  else
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  endif
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P \
+	mov.l 1f,r0; \
+	mov.l @r0,r0; \
+	bra 2f; \
+	 tst r0,r0; \
+	.align 2; \
+     1: .long __local_multiple_threads; \
+     2:
+#  elif defined FLOATING_STACKS && USE___THREAD
+#   define SINGLE_THREAD_P \
+	stc gbr,r0; \
+	mov.w 0f,r1; \
+	sub r1,r0; \
+	mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
+	bra 1f; \
+	 tst r0,r0; \
+     0: .word TLS_PRE_TCB_SIZE; \
+     1:
+
+#  else
+#   if !defined NOT_IN_libc || defined IS_IN_libpthread
+#    define SINGLE_THREAD_P \
+	mov r12,r2; \
+	mov.l 0f,r12; \
+	mova 0f,r0; \
+	add r0,r12; \
+	mov.l 1f,r0; \
+	mov.l @(r0,r12),r0; \
+	mov r2,r12; \
+	bra 2f; \
+	 tst r0,r0; \
+	.align 2; \
+     0: .long _GLOBAL_OFFSET_TABLE_; \
+     1: .long __local_multiple_threads@GOTOFF; \
+     2:
+#   else
+#    define SINGLE_THREAD_P \
+	mov r12,r2; \
+	mov.l 0f,r12; \
+	mova 0f,r0; \
+	add r0,r12; \
+	mov.l 1f,r0; \
+	mov.l @(r0,r12),r0; \
+	mov.l @r0,r0; \
+	mov r2,r12; \
+	bra 2f; \
+	 tst r0,r0; \
+	.align 2; \
+     0: .long _GLOBAL_OFFSET_TABLE_; \
+     1: .long __local_multiple_threads@GOT; \
+     2:
+#   endif
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
new file mode 100644
index 0000000000..f230c01226
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/vfork.S
@@ -0,0 +1,77 @@
+/* Copyright (C) 2003, 2004 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 <sysdep-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+#ifdef SHARED
+	mov.l	.Lgot, r1
+	mova	.Lgot, r0
+	add	r0, r1
+	mov.l	.Lpthread_func, r0
+	mov.l	@(r0,r1), r0
+#else
+	mov.l	.Lpthread_create, r0
+#endif
+	tst	r0, r0
+	bf	.Lhidden_fork
+
+	mov.w	.L1, r3
+	trapa	#0x10
+	mov     r0, r1
+	mov	#-12, r2
+	shad	r2, r1
+	not	r1, r1			// r1=0 means r0 = -1 to -4095
+	tst	r1, r1			// i.e. error in linux
+	bf	.Lpseudo_end
+	SYSCALL_ERROR_HANDLER
+.Lpseudo_end:
+	rts
+	 nop
+.L1:	.word	__NR_vfork
+	.align	2
+#ifdef SHARED
+.Lgot:
+	.long	_GLOBAL_OFFSET_TABLE_
+.Lpthread_func:
+	.long	__libc_pthread_functions@GOTOFF
+#else
+.Lpthread_create:
+	.weak	pthread_create
+	.long	pthread_create
+#endif
+
+.Lhidden_fork:	
+	mov.l	.L2, r1
+	braf	r1
+	 nop
+1:
+	.align 2
+.L2:	.long	HIDDEN_JUMPTARGET(__fork)-1b
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c b/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c
new file mode 100644
index 0000000000..fdec09455a
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sigwait.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 1997, 1998, 2000, 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 <errno.h>
+#include <signal.h>
+#define __need_NULL
+#include <stddef.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+#include <bits/libc-lock.h>
+
+extern int __syscall_rt_sigtimedwait (const sigset_t *__unbounded, siginfo_t *__unbounded,
+				      const struct timespec *__unbounded, size_t);
+
+
+/* Return any pending signal or wait for one for the given time.  */
+static inline int
+do_sigwait (const sigset_t *set, int *sig)
+{
+  int ret;
+
+  /* XXX The size argument hopefully will have to be changed to the
+     real size of the user-level sigset_t.  */
+#ifdef INTERNAL_SYSCALL
+  INTERNAL_SYSCALL_DECL (err);
+  ret = INTERNAL_SYSCALL (rt_sigtimedwait, err, 4, CHECK_SIGSET (set),
+			  NULL, NULL, _NSIG / 8);
+  if (! INTERNAL_SYSCALL_ERROR_P (ret, err))
+    {
+      *sig = ret;
+      ret = 0;
+    }
+  else
+    ret = INTERNAL_SYSCALL_ERRNO (ret, err);
+#else
+  ret = INLINE_SYSCALL (rt_sigtimedwait, 4, CHECK_SIGSET (set),
+			NULL, NULL, _NSIG / 8);
+  if (ret != -1)
+    {
+      *sig = ret;
+      ret = 0;
+    }
+  else
+    ret = errno;
+#endif
+
+  return ret;
+}
+
+#ifndef SHARED
+weak_extern (__pthread_sigwait)
+#endif
+
+int
+__sigwait (set, sig)
+     const sigset_t *set;
+     int *sig;
+{
+#ifndef NOT_IN_libc
+  return __libc_maybe_call2 (pthread_sigwait, (set, sig),
+			     do_sigwait (set, sig));
+#else
+  return do_sigwait (set, sig);
+#endif
+}
+libc_hidden_def (__sigwait)
+weak_alias (__sigwait, sigwait)
+strong_alias (__sigwait, __libc_sigwait)
+
+/* Cancellation is handled in __pthread_sigwait.  */
+LIBC_CANCEL_HANDLED ();
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/smp.h b/linuxthreads/sysdeps/unix/sysv/linux/smp.h
new file mode 100644
index 0000000000..81289294b4
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/smp.h
@@ -0,0 +1,48 @@
+/* Determine whether the host has multiple processors.  Linux version.
+   Copyright (C) 1996, 2002 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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 <sys/sysctl.h>
+
+/* Test whether the machine has more than one processor.  This is not the
+   best test but good enough.  More complicated tests would require `malloc'
+   which is not available at that time.  */
+static inline int
+is_smp_system (void)
+{
+  static const int sysctl_args[] = { CTL_KERN, KERN_VERSION };
+  char buf[512];
+  size_t reslen = sizeof (buf);
+
+  /* Try reading the number using `sysctl' first.  */
+  if (__sysctl ((int *) sysctl_args,
+		sizeof (sysctl_args) / sizeof (sysctl_args[0]),
+		buf, &reslen, NULL, 0) < 0)
+    {
+      /* This was not successful.  Now try reading the /proc filesystem.  */
+      int fd = __open ("/proc/sys/kernel/version", O_RDONLY);
+      if (__builtin_expect (fd, 0) == -1
+	  || (reslen = __read (fd, buf, sizeof (buf))) <= 0)
+	/* This also didn't work.  We give up and say it's a UP machine.  */
+	buf[0] = '\0';
+
+      __close (fd);
+    }
+
+  return strstr (buf, "SMP") != NULL;
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions b/linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions
new file mode 100644
index 0000000000..d102772482
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/Versions
@@ -0,0 +1,6 @@
+libpthread {
+  GLIBC_2.3.3 {
+    # Changed PTHREAD_STACK_MIN.
+    pthread_attr_setstack; pthread_attr_setstacksize;
+  }
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c b/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c
new file mode 100644
index 0000000000..0d6da82919
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/aio_cancel.c
@@ -0,0 +1,33 @@
+#include <shlib-compat.h>
+
+#define aio_cancel64 XXX
+#include <aio.h>
+#undef aio_cancel64
+#include <errno.h>
+
+extern __typeof (aio_cancel) __new_aio_cancel;
+extern __typeof (aio_cancel) __old_aio_cancel;
+
+#define aio_cancel	__new_aio_cancel
+
+#include <sysdeps/pthread/aio_cancel.c>
+
+#undef aio_cancel
+strong_alias (__new_aio_cancel, __new_aio_cancel64);
+versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3);
+versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3);
+
+#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3)
+
+#undef ECANCELED
+#define aio_cancel	__old_aio_cancel
+#define ECANCELED	125
+
+#include <sysdeps/pthread/aio_cancel.c>
+
+#undef aio_cancel
+strong_alias (__old_aio_cancel, __old_aio_cancel64);
+compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1);
+compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1);
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
new file mode 100644
index 0000000000..27ffa668f4
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/local_lim.h
@@ -0,0 +1,92 @@
+/* Minimum guaranteed maximum values for system limits.  Linux/SPARC version.
+   Copyright (C) 1993-1998,2000,2002,2003,2004 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; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* The kernel header pollutes the namespace with the NR_OPEN symbol
+   and defines LINK_MAX although filesystems have different maxima.  A
+   similar thing is true for OPEN_MAX: the limit can be changed at
+   runtime and therefore the macro must not be defined.  Remove this
+   after including the header if necessary.  */
+#ifndef NR_OPEN
+# define __undef_NR_OPEN
+#endif
+#ifndef LINK_MAX
+# define __undef_LINK_MAX
+#endif
+#ifndef OPEN_MAX
+# define __undef_OPEN_MAX
+#endif
+
+/* The kernel sources contain a file with all the needed information.  */
+#include <linux/limits.h>
+
+/* Have to remove NR_OPEN?  */
+#ifdef __undef_NR_OPEN
+# undef NR_OPEN
+# undef __undef_NR_OPEN
+#endif
+/* Have to remove LINK_MAX?  */
+#ifdef __undef_LINK_MAX
+# undef LINK_MAX
+# undef __undef_LINK_MAX
+#endif
+/* Have to remove OPEN_MAX?  */
+#ifdef __undef_OPEN_MAX
+# undef OPEN_MAX
+# undef __undef_OPEN_MAX
+#endif
+
+/* The number of data keys per process.  */
+#define _POSIX_THREAD_KEYS_MAX	128
+/* This is the value this implementation supports.  */
+#define PTHREAD_KEYS_MAX	1024
+
+/* Controlling the iterations of destructors for thread-specific data.  */
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS	4
+/* Number of iterations this implementation does.  */
+#define PTHREAD_DESTRUCTOR_ITERATIONS	_POSIX_THREAD_DESTRUCTOR_ITERATIONS
+
+/* The number of threads per process.  */
+#define _POSIX_THREAD_THREADS_MAX	64
+/* This is the value this implementation supports.  */
+#define PTHREAD_THREADS_MAX	16384
+
+/* Maximum amount by which a process can descrease its asynchronous I/O
+   priority level.  */
+#define AIO_PRIO_DELTA_MAX	20
+
+/* Minimum size for a thread.  We are free to choose a reasonable value.  */
+#define PTHREAD_STACK_MIN	24576
+
+/* Maximum number of POSIX timers available.  */
+#define TIMER_MAX	256
+
+/* Maximum number of timer expiration overruns.  */
+#define DELAYTIMER_MAX	2147483647
+
+/* Maximum tty name length.  */
+#define TTY_NAME_MAX		32
+
+/* Maximum login name length.  This is arbitrary.  */
+#define LOGIN_NAME_MAX		256
+
+/* Maximum host name length.  */
+#define HOST_NAME_MAX		64
+
+/* Maximum message queue priority level.  */
+#define MQ_PRIO_MAX		32768
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
new file mode 100644
index 0000000000..7e4253789c
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
@@ -0,0 +1,66 @@
+/* bits/typesizes.h -- underlying types for *_t.  Linux/SPARC 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 _BITS_TYPES_H
+# error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
+#endif
+
+#ifndef	_BITS_TYPESIZES_H
+#define	_BITS_TYPESIZES_H	1
+
+/* See <bits/types.h> for the meaning of these macros.  This file exists so
+   that <bits/types.h> need not vary across different GNU platforms.  */
+
+#define __DEV_T_TYPE		__UQUAD_TYPE
+#define __UID_T_TYPE		__U32_TYPE
+#define __GID_T_TYPE		__U32_TYPE
+#define __INO_T_TYPE		__ULONGWORD_TYPE
+#define __INO64_T_TYPE		__UQUAD_TYPE
+#define __MODE_T_TYPE		__U32_TYPE
+#define __NLINK_T_TYPE		__U32_TYPE
+#define __OFF_T_TYPE		__SLONGWORD_TYPE
+#define __OFF64_T_TYPE		__SQUAD_TYPE
+#define __PID_T_TYPE		__S32_TYPE
+#define __RLIM_T_TYPE		__ULONGWORD_TYPE
+#define __RLIM64_T_TYPE		__UQUAD_TYPE
+#define	__BLKCNT_T_TYPE		__SLONGWORD_TYPE
+#define	__BLKCNT64_T_TYPE	__SQUAD_TYPE
+#define	__FSBLKCNT_T_TYPE	__ULONGWORD_TYPE
+#define	__FSBLKCNT64_T_TYPE	__UQUAD_TYPE
+#define	__FSFILCNT_T_TYPE	__ULONGWORD_TYPE
+#define	__FSFILCNT64_T_TYPE	__UQUAD_TYPE
+#define	__ID_T_TYPE		__U32_TYPE
+#define __CLOCK_T_TYPE		__SLONGWORD_TYPE
+#define __TIME_T_TYPE		__SLONGWORD_TYPE
+#define __USECONDS_T_TYPE	__U32_TYPE
+#define __SUSECONDS_T_TYPE	__S32_TYPE
+#define __DADDR_T_TYPE		__S32_TYPE
+#define __SWBLK_T_TYPE		__SLONGWORD_TYPE
+#define __KEY_T_TYPE		__S32_TYPE
+#define __CLOCKID_T_TYPE	__S32_TYPE
+#define __TIMER_T_TYPE		__S32_TYPE
+#define __BLKSIZE_T_TYPE	__SLONGWORD_TYPE
+#define __FSID_T_TYPE		struct { int __val[2]; }
+#define __SSIZE_T_TYPE		__SWORD_TYPE
+
+/* Number of descriptors that can fit in an `fd_set'.  */
+#define	__FD_SETSIZE		1024
+
+
+#endif /* bits/typesizes.h */
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h
new file mode 100644
index 0000000000..793cb1d5f9
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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>
+
+#define ARCH_FORK() \
+({									\
+  register long __o0 __asm__ ("o0");					\
+  register long __o1 __asm__ ("o1");					\
+  register long __g1 __asm__ ("g1") = __NR_fork;			\
+  __asm __volatile (__SYSCALL_STRING					\
+		    : "=r" (__g1), "=r" (__o0), "=r" (__o1)		\
+		    : "0" (__g1)					\
+		    : __SYSCALL_CLOBBERS);				\
+  __o0 == -1 ? __o0 : (__o0 & (__o1 - 1));				\
+})
+
+#include_next <fork.h>
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
new file mode 100644
index 0000000000..dd3f52a989
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+	.text;								      \
+ENTRY(name)								      \
+	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;			      \
+	cmp %g1, 0;							      \
+	bne 1f;								      \
+	 mov SYS_ify(syscall_name), %g1;				      \
+	ta 0x10;							      \
+	bcs __syscall_error_handler;					      \
+	 nop;								      \
+	.subsection 2;							      \
+1:	save %sp, -96, %sp;						      \
+	CENABLE;							      \
+	 nop;								      \
+	mov %o0, %l0;							      \
+	COPY_ARGS_##args						      \
+	mov SYS_ify(syscall_name), %g1;					      \
+	ta 0x10;							      \
+	bcs __syscall_error_handler2;					      \
+	 mov %o0, %l1;							      \
+	CDISABLE;							      \
+	 mov %l0, %o0;							      \
+	jmpl %i7 + 8, %g0;						      \
+	 restore %g0, %l1, %o0;						      \
+	.previous;							      \
+	SYSCALL_ERROR_HANDLER						      \
+	SYSCALL_ERROR_HANDLER2
+
+#define SYSCALL_ERROR_HANDLER2						      \
+SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \
+	.global __errno_location;					      \
+        .type   __errno_location,@function;				      \
+	CDISABLE;							      \
+	 mov	%l0, %o0;						      \
+	call	__errno_location;					      \
+	 nop;								      \
+	st	%l1, [%o0];						      \
+	jmpl	%i7 + 8, %g0;						      \
+	 restore %g0, -1, %o0;						      \
+	.previous;
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel
+#  define CDISABLE	call __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+#  define CENABLE	call __libc_enable_asynccancel
+#  define CDISABLE	call __libc_disable_asynccancel
+# else
+#  define CENABLE	call __librt_enable_asynccancel
+#  define CDISABLE	call __librt_disable_asynccancel
+# endif
+
+#define COPY_ARGS_0	/* Nothing */
+#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0;
+#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1;
+#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2;
+#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3;
+#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4;
+#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5;
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
new file mode 100644
index 0000000000..132da67a14
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S
@@ -0,0 +1,65 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep-cancel.h>
+
+	.text
+#ifdef SHARED
+.LLGETPC0:
+	retl
+	 add	%o7, %o0, %o0
+#endif
+ENTRY(__vfork)
+#ifdef SHARED
+	mov	%o7, %o1
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %o0
+	call	.LLGETPC0
+	 add	%o0, %lo(_GLOBAL_OFFSET_TABLE_+4), %o0
+	sethi	%hi(__libc_pthread_functions), %o2
+	mov	%o1, %o7
+	or	%o2, %lo(__libc_pthread_functions), %o2
+	ld	[%o0 + %o2], %o2
+	ld	[%o2], %o2
+	cmp	%o2, 0
+#else
+	.weak	pthread_create
+	sethi	%hi(pthread_create), %o0
+	orcc	%o0, %lo(pthread_create), %o0
+#endif
+#if defined SHARED && !defined BROKEN_SPARC_WDISP22
+	bne	HIDDEN_JUMPTARGET(__fork)
+#else
+	bne	1f
+#endif
+	 mov	__NR_vfork, %g1
+	ta	0x10
+	bcs	__syscall_error_handler
+	 nop
+	sub	%o1, 1, %o1
+	retl
+	 and	%o0, %o1, %o0
+#if !defined SHARED || defined BROKEN_SPARC_WDISP22
+1:	mov	%o7, %g1
+	call	HIDDEN_JUMPTARGET(__fork)
+	 mov	%g1, %o7
+#endif
+	SYSCALL_ERROR_HANDLER
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
new file mode 100644
index 0000000000..90203051ae
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
@@ -0,0 +1,5 @@
+# glibc makefile fragment for linuxthreads on sparc/sparc64.
+
+ifeq ($(subdir),linuxthreads)
+libpthread-routines += ptw-sigprocmask
+endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c
new file mode 100644
index 0000000000..d57283ad23
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/pt-sigsuspend.c
@@ -0,0 +1 @@
+#include "../../ia64/pt-sigsuspend.c"
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
new file mode 100644
index 0000000000..80834292e5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
@@ -0,0 +1,101 @@
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <tls.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+	.text;								      \
+ENTRY(name)								      \
+	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;			      \
+	brnz,pn %g1, 1f;						      \
+	 mov SYS_ify(syscall_name), %g1;				      \
+	ta 0x6d;							      \
+	bcs,pn %xcc, __syscall_error_handler;				      \
+	 nop;								      \
+	.subsection 2;							      \
+1:	save %sp, -192, %sp;						      \
+	CENABLE;							      \
+	 nop;								      \
+	mov %o0, %l0;							      \
+	COPY_ARGS_##args						      \
+	mov SYS_ify(syscall_name), %g1;					      \
+	ta 0x6d;							      \
+	bcs,pn %xcc, __syscall_error_handler2;				      \
+	 mov %o0, %l1;							      \
+	CDISABLE;							      \
+	 mov %l0, %o0;							      \
+	jmpl %i7 + 8, %g0;						      \
+	 restore %g0, %l1, %o0;						      \
+	.previous;							      \
+	SYSCALL_ERROR_HANDLER						      \
+	SYSCALL_ERROR_HANDLER2
+
+#define SYSCALL_ERROR_HANDLER2						      \
+SYSCALL_ERROR_HANDLER_ENTRY(__syscall_error_handler2)			      \
+	.global __errno_location;					      \
+        .type   __errno_location,@function;				      \
+	CDISABLE;							      \
+	 mov	%l0, %o0;						      \
+	call	__errno_location;					      \
+	 nop;								      \
+	st	%l1, [%o0];						      \
+	jmpl	%i7 + 8, %g0;						      \
+	 restore %g0, -1, %o0;						      \
+	.previous;
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel
+#  define CDISABLE	call __pthread_disable_asynccancel
+# elif !defined NOT_IN_libc
+#  define CENABLE	call __libc_enable_asynccancel
+#  define CDISABLE	call __libc_disable_asynccancel
+# else
+#  define CENABLE	call __librt_enable_asynccancel
+#  define CDISABLE	call __librt_disable_asynccancel
+# endif
+
+#define COPY_ARGS_0	/* Nothing */
+#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0;
+#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1;
+#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2;
+#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3;
+#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4;
+#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5;
+
+# ifndef __ASSEMBLER__
+#  define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+# else
+#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
new file mode 100644
index 0000000000..8a6d2771e8
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S
@@ -0,0 +1,64 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep-cancel.h>
+
+#ifdef SHARED
+.LLGETPC0:
+	retl
+	 add	%o7, %o0, %o0
+#endif
+ENTRY(__vfork)
+#ifdef SHARED
+	mov	%o7, %o1
+	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %o0
+	call	.LLGETPC0
+	 add	%o0, %lo(_GLOBAL_OFFSET_TABLE_+4), %o0
+	sethi	%hi(__libc_pthread_functions), %o2
+	mov	%o1, %o7
+	or	%o2, %lo(__libc_pthread_functions), %o2
+	ldx	[%o0 + %o2], %o2
+	ldx	[%o2], %o0
+#else
+	.weak	pthread_create
+	sethi	%hi(pthread_create), %o0
+	or	%o0, %lo(pthread_create), %o0
+#endif
+#if defined SHARED && !defined BROKEN_SPARC_WDISP22
+	cmp	%o0, 0
+	bne	HIDDEN_JUMPTARGET(__fork)
+#else
+	brnz,pn	%o0, 1f
+#endif
+	 mov	__NR_vfork, %g1
+	ta	0x6d
+	bcs,pn	%xcc, __syscall_error_handler
+	 nop
+	sub	%o1, 1, %o1
+	retl
+	 and	%o0, %o1, %o0
+#if !defined SHARED || defined BROKEN_SPARC_WDISP22
+1:	mov	%o7, %g1
+	call	HIDDEN_JUMPTARGET(__fork)
+	 mov	%g1, %o7
+#endif
+	SYSCALL_ERROR_HANDLER
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c b/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c
new file mode 100644
index 0000000000..dad273fdf5
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2002 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 <errno.h>
+#include <stdlib.h>
+#include "fork.h"
+
+
+void
+__unregister_atfork (dso_handle)
+     void *dso_handle;
+{
+  /* Get the lock to not conflict with running forks.  */
+  __libc_lock_lock (__fork_block.lock);
+
+  list_t *runp;
+  list_t *prevp;
+
+  list_for_each_prev_safe (runp, prevp, &__fork_block.prepare_list)
+    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
+      list_del (runp);
+
+  list_for_each_prev_safe (runp, prevp, &__fork_block.parent_list)
+    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
+      list_del (runp);
+
+  list_for_each_prev_safe (runp, prevp, &__fork_block.child_list)
+    if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
+      list_del (runp);
+
+  /* Release the lock.  */
+  __libc_lock_unlock (__fork_block.lock);
+}
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile
new file mode 100644
index 0000000000..b5e5d5d480
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),linuxthreads)
+CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions \
+		       -fno-asynchronous-unwind-tables $(fno-unit-at-a-time)
+endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c
new file mode 100644
index 0000000000..3a0c2afc0f
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/pt-sigsuspend.c
@@ -0,0 +1 @@
+#include "../ia64/pt-sigsuspend.c"
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
new file mode 100644
index 0000000000..742dbeb0de
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
@@ -0,0 +1,132 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@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 <tls.h>
+#include <pt-machine.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .text;								      \
+  ENTRY (name)								      \
+    SINGLE_THREAD_P;							      \
+    jne L(pseudo_cancel);						      \
+    DO_CALL (syscall_name, args);					      \
+    cmpq $-4095, %rax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+    ret;								      \
+  L(pseudo_cancel):							      \
+    /* Save registers that might get destroyed.  */			      \
+    SAVESTK_##args							      \
+    PUSHARGS_##args							      \
+    CENABLE								      \
+    /* Restore registers.  */						      \
+    POPARGS_##args							      \
+    /* The return value from CENABLE is argument for CDISABLE.  */	      \
+    movq %rax, (%rsp);							      \
+    movq $SYS_ify (syscall_name), %rax;					      \
+    syscall;								      \
+    movq (%rsp), %rdi;							      \
+    /* Save %rax since it's the error code from the syscall.  */	      \
+    movq %rax, 8(%rsp);							      \
+    CDISABLE								      \
+    movq 8(%rsp), %rax;							      \
+    RESTSTK_##args							      \
+    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;
+#  define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+#  define CENABLE	call __libc_enable_asynccancel;
+#  define CDISABLE	call __libc_disable_asynccancel;
+#  define __local_multiple_threads __libc_multiple_threads
+# else
+#  define CENABLE	call __librt_enable_asynccancel@plt;
+#  define CDISABLE	call __librt_disable_asynccancel@plt;
+# endif
+
+# if defined IS_IN_libpthread || !defined NOT_IN_libc
+#  ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P \
+  __builtin_expect (__local_multiple_threads == 0, 1)
+#  else
+#   define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
+#  endif
+
+# else
+
+#  ifndef __ASSEMBLER__
+#   define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+				   p_header.data.multiple_threads) == 0, 1)
+#  else
+#   define SINGLE_THREAD_P cmpl $0, %fs:MULTIPLE_THREADS_OFFSET
+#  endif
+
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S
new file mode 100644
index 0000000000..25d1d3f96a
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -0,0 +1,62 @@
+/* Copyright (C) 2001, 2002, 2003, 2004 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 <sysdep-cancel.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+/* Clone the calling process, but without copying the whole address space.
+   The calling process is suspended until the new process exits or is
+   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
+   and the process ID of the new process to the old process.  */
+
+ENTRY (__vfork)
+
+#ifdef SHARED
+	cmpq	$0, __libc_pthread_functions(%rip)
+#else
+	.weak	pthread_create
+	movq	$pthread_create, %rax
+	testq	%rax, %rax
+#endif
+	jne	HIDDEN_JUMPTARGET (__fork)
+
+	/* Pop the return PC value into RDI.  We need a register that
+	   is preserved by the syscall and that we're allowed to destroy. */
+	popq	%rdi
+	cfi_adjust_cfa_offset(-8)
+
+	/* Stuff the syscall number in RAX and enter into the kernel.  */
+	movl	$SYS_ify (vfork), %eax
+	syscall
+
+	/* Push back the return PC.  */
+	pushq	%rdi
+	cfi_adjust_cfa_offset(8)
+
+	cmpl	$-4095, %eax
+	jae SYSCALL_ERROR_LABEL		/* Branch forward if it failed.  */
+
+	/* Normal return.  */
+.Lpseudo_end:
+	ret
+
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)
diff --git a/linuxthreads/sysdeps/x86_64/Makefile b/linuxthreads/sysdeps/x86_64/Makefile
new file mode 100644
index 0000000000..81bddf688c
--- /dev/null
+++ b/linuxthreads/sysdeps/x86_64/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/linuxthreads/sysdeps/x86_64/Versions b/linuxthreads/sysdeps/x86_64/Versions
new file mode 100644
index 0000000000..32da57080d
--- /dev/null
+++ b/linuxthreads/sysdeps/x86_64/Versions
@@ -0,0 +1,5 @@
+libpthread {
+  GLIBC_PRIVATE {
+    __pthread_clock_gettime; __pthread_clock_settime;
+  }
+}
diff --git a/linuxthreads/sysdeps/x86_64/pspinlock.c b/linuxthreads/sysdeps/x86_64/pspinlock.c
new file mode 100644
index 0000000000..e1b2a66841
--- /dev/null
+++ b/linuxthreads/sysdeps/x86_64/pspinlock.c
@@ -0,0 +1,97 @@
+/* POSIX spinlock implementation.  x86-64 version.
+   Copyright (C) 2001 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 <errno.h>
+#include <pthread.h>
+#include "internals.h"
+
+/* This implementation is similar to the one used in the Linux kernel.
+   But the kernel is byte instructions for the memory access.  This is
+   faster but unusable here.  The problem is that only 128
+   threads/processes could use the spinlock at the same time.  If (by
+   a design error in the program) a thread/process would hold the
+   spinlock for a time long enough to accumulate 128 waiting
+   processes, the next one will find a positive value in the spinlock
+   and assume it is unlocked.  We cannot accept that.  */
+
+int
+__pthread_spin_lock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("\n"
+     "1:\n\t"
+     "lock; decl %0\n\t"
+     "js 2f\n\t"
+     ".section .text.spinlock,\"ax\"\n"
+     "2:\n\t"
+     "cmpl $0,%0\n\t"
+     "rep; nop\n\t"
+     "jle 2b\n\t"
+     "jmp 1b\n\t"
+     ".previous"
+     : "=m" (*lock));
+  return 0;
+}
+weak_alias (__pthread_spin_lock, pthread_spin_lock)
+
+
+int
+__pthread_spin_trylock (pthread_spinlock_t *lock)
+{
+  int oldval;
+
+  asm volatile
+    ("xchgl %0,%1"
+     : "=r" (oldval), "=m" (*lock)
+     : "0" (0));
+  return oldval > 0 ? 0 : EBUSY;
+}
+weak_alias (__pthread_spin_trylock, pthread_spin_trylock)
+
+
+int
+__pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  asm volatile
+    ("movl $1,%0"
+     : "=m" (*lock));
+  return 0;
+}
+weak_alias (__pthread_spin_unlock, pthread_spin_unlock)
+
+
+int
+__pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+  /* We can ignore the `pshared' parameter.  Since we are busy-waiting
+     all processes which can access the memory location `lock' points
+     to can use the spinlock.  */
+  *lock = 1;
+  return 0;
+}
+weak_alias (__pthread_spin_init, pthread_spin_init)
+
+
+int
+__pthread_spin_destroy (pthread_spinlock_t *lock)
+{
+  /* Nothing to do.  */
+  return 0;
+}
+weak_alias (__pthread_spin_destroy, pthread_spin_destroy)
diff --git a/linuxthreads/sysdeps/x86_64/pt-machine.h b/linuxthreads/sysdeps/x86_64/pt-machine.h
new file mode 100644
index 0000000000..df187a7c03
--- /dev/null
+++ b/linuxthreads/sysdeps/x86_64/pt-machine.h
@@ -0,0 +1,225 @@
+/* Machine-dependent pthreads configuration and inline functions.
+   x86-64 version.
+   Copyright (C) 2001, 2002, 2003, 2004 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 _PT_MACHINE_H
+#define _PT_MACHINE_H   1
+
+#ifndef __ASSEMBLER__
+# include <stddef.h>	/* For offsetof.  */
+# include <stdlib.h>	/* For abort().  */
+# include <asm/prctl.h>
+
+
+# ifndef PT_EI
+#  define PT_EI extern inline __attribute__ ((always_inline))
+# endif
+
+extern long int testandset (int *spinlock);
+extern int __compare_and_swap (long int *p, long int oldval, long int newval);
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+# define CURRENT_STACK_FRAME  stack_pointer
+register char * stack_pointer __asm__ ("%rsp") __attribute_used__;
+
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  long int ret;
+
+  __asm__ __volatile__ (
+	"xchgl %k0, %1"
+	: "=r"(ret), "=m"(*spinlock)
+	: "0"(1), "m"(*spinlock)
+	: "memory");
+
+  return ret;
+}
+
+
+/* Compare-and-swap for semaphores.  */
+# define HAS_COMPARE_AND_SWAP
+
+PT_EI int
+__compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  char ret;
+  long int readval;
+
+  __asm__ __volatile__ ("lock; cmpxchgq %3, %1; sete %0"
+			: "=q" (ret), "=m" (*p), "=a" (readval)
+			: "r" (newval), "m" (*p), "a" (oldval)
+			: "memory");
+  return ret;
+}
+
+/* Return the thread descriptor for the current thread.
+
+   The contained asm must *not* be marked volatile since otherwise
+   assignments like
+	pthread_descr self = thread_self();
+   do not get optimized away.  */
+# define THREAD_SELF \
+({									      \
+  register pthread_descr __self;					      \
+  __asm__ ("movq %%fs:%c1,%0" : "=r" (__self)				      \
+	   : "i" (offsetof (struct _pthread_descr_struct,		      \
+			    p_header.data.self)));			      \
+  __self;								      \
+})
+
+/* Prototype for the system call.  */
+extern int __arch_prctl (int __code, unsigned long __addr);
+
+/* Initialize the thread-unique value.  */
+# define INIT_THREAD_SELF(descr, nr) \
+{									      \
+  if (__arch_prctl (ARCH_SET_FS, (unsigned long)descr) != 0)		      \
+    abort ();								      \
+}
+
+/* Read member of the thread descriptor directly.  */
+# define THREAD_GETMEM(descr, member) \
+({									      \
+  __typeof__ (descr->member) __value;					      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %%fs:%P2,%b0"				      \
+			  : "=q" (__value)				      \
+			  : "0" (0),					      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %%fs:%P2,%k0"				      \
+			  : "=r" (__value)				      \
+			  : "0" (0),					      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movq %%fs:%P1,%0"				      \
+			    : "=r" (__value)				      \
+			    : "i" (offsetof (struct _pthread_descr_struct,    \
+					     member)));			      \
+    }									      \
+  __value;								      \
+})
+
+/* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
+# define THREAD_GETMEM_NC(descr, member) \
+({									      \
+  __typeof__ (descr->member) __value;					      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %%fs:(%2),%b0"				      \
+			  : "=q" (__value)				      \
+			  : "0" (0),					      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %%fs:(%2),%k0"				      \
+			  : "=r" (__value)				      \
+			  : "0" (0),					      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movq %%fs:(%1),%0"				      \
+			    : "=r" (__value)				      \
+			    : "r" (offsetof (struct _pthread_descr_struct,    \
+					     member)));			      \
+    }									      \
+  __value;								      \
+})
+
+/* Set member of the thread descriptor directly.  */
+# define THREAD_SETMEM(descr, member, value) \
+({									      \
+  __typeof__ (descr->member) __value = (value);				      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %0,%%fs:%P1" :				      \
+			  : "q" (__value),				      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %k0,%%fs:%P1" :				      \
+			  : "r" (__value),				      \
+			    "i" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movq %0,%%fs:%P1" :			      \
+			    : "r" (__value),				      \
+			      "i" (offsetof (struct _pthread_descr_struct,    \
+					     member)));			      \
+    }									      \
+})
+
+/* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
+# define THREAD_SETMEM_NC(descr, member, value) \
+({									      \
+  __typeof__ (descr->member) __value = (value);				      \
+  if (sizeof (__value) == 1)						      \
+    __asm__ __volatile__ ("movb %0,%%fs:(%1)" :				      \
+			  : "q" (__value),				      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else if (sizeof (__value) == 4)					      \
+    __asm__ __volatile__ ("movl %k0,%%fs:(%1)" :			      \
+			  : "r" (__value),				      \
+			    "r" (offsetof (struct _pthread_descr_struct,      \
+					   member)));			      \
+  else									      \
+    {									      \
+      if (sizeof (__value) != 8)					      \
+	/* There should not be any value with a size other than 1, 4 or 8.  */\
+	abort ();							      \
+									      \
+      __asm__ __volatile__ ("movq %0,%%fs:(%1)"	:			      \
+			    : "r" (__value),				      \
+			      "r" (offsetof (struct _pthread_descr_struct,    \
+					     member)));			      \
+    }									      \
+})
+
+#endif /* !__ASSEMBLER__ */
+
+/* We want the OS to assign stack addresses.  */
+#define FLOATING_STACKS	1
+
+/* Maximum size of the stack if the rlimit is unlimited.  */
+#define ARCH_STACK_MAX_SIZE	32*1024*1024
+
+/* The ia32e really want some help to prevent overheating.  */
+#define BUSY_WAIT_NOP	__asm__ ("rep; nop")
+
+#endif /* pt-machine.h */
diff --git a/linuxthreads/sysdeps/x86_64/tcb-offsets.sym b/linuxthreads/sysdeps/x86_64/tcb-offsets.sym
new file mode 100644
index 0000000000..aee6be2570
--- /dev/null
+++ b/linuxthreads/sysdeps/x86_64/tcb-offsets.sym
@@ -0,0 +1,4 @@
+#include <sysdep.h>
+#include <tls.h>
+
+MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
diff --git a/linuxthreads/sysdeps/x86_64/tls.h b/linuxthreads/sysdeps/x86_64/tls.h
new file mode 100644
index 0000000000..63feebdb2c
--- /dev/null
+++ b/linuxthreads/sysdeps/x86_64/tls.h
@@ -0,0 +1,129 @@
+/* Definitions for thread-local data handling.  linuxthreads/x86-64 version.
+   Copyright (C) 2002 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 _TLS_H
+#define _TLS_H
+
+#ifndef __ASSEMBLER__
+
+# include <pt-machine.h>
+# include <stddef.h>
+
+/* Type for the dtv.  */
+typedef union dtv
+{
+  size_t counter;
+  void *pointer;
+} dtv_t;
+
+
+typedef struct
+{
+  void *tcb;		/* Pointer to the TCB.  Not necessary the
+			   thread descriptor used by libpthread.  */
+  dtv_t *dtv;
+  void *self;		/* Pointer to the thread descriptor.  */
+  int multiple_threads;
+} tcbhead_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif
+
+
+#ifdef HAVE_TLS_SUPPORT
+
+/* Signal that TLS support is available.  */
+# define USE_TLS	1
+
+# ifndef __ASSEMBLER__
+/* Get system call information.  */
+#  include <sysdep.h>
+
+/* Get the thread descriptor definition.  */
+#  include <linuxthreads/descr.h>
+
+/* This is the size of the initial TCB.  */
+#  define TLS_INIT_TCB_SIZE sizeof (tcbhead_t)
+
+/* Alignment requirements for the initial TCB.  */
+#  define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t)
+
+/* This is the size of the TCB.  */
+#  define TLS_TCB_SIZE sizeof (struct _pthread_descr_struct)
+
+/* Alignment requirements for the TCB.  */
+#  define TLS_TCB_ALIGN __alignof__ (struct _pthread_descr_struct)
+
+/* The TCB can have any size and the memory following the address the
+   thread pointer points to is unspecified.  Allocate the TCB there.  */
+#  define TLS_TCB_AT_TP	1
+
+
+/* Install the dtv pointer.  The pointer passed is to the element with
+   index -1 which contain the length.  */
+#  define INSTALL_DTV(descr, dtvp) \
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
+
+/* Install new dtv for current thread.  */
+#  define INSTALL_NEW_DTV(dtv) \
+  ({ struct _pthread_descr_struct *__descr;				      \
+     THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); })
+
+/* Return dtv of given thread descriptor.  */
+#  define GET_DTV(descr) \
+  (((tcbhead_t *) (descr))->dtv)
+
+/* Code to initially initialize the thread pointer.  This might need
+   special attention since 'errno' is not yet available and if the
+   operation can cause a failure 'errno' must not be touched.  */
+# define TLS_INIT_TP(descr, secondcall)					      \
+  ({									      \
+    void *_descr = (descr);						      \
+    tcbhead_t *head = _descr;						      \
+    long int _result;							      \
+									      \
+    head->tcb = _descr;							      \
+    /* For now the thread descriptor is at the same address.  */	      \
+    head->self = _descr;						      \
+									      \
+    asm volatile ("syscall"						      \
+		  : "=a" (_result)					      \
+		  : "0" ((unsigned long int) __NR_arch_prctl),		      \
+		    "D" ((unsigned long int) ARCH_SET_FS),		      \
+		    "S" (_descr)					      \
+		  : "memory", "cc", "r11", "cx");			      \
+									      \
+    _result ? "cannot set %fs base address for thread-local storage" : 0;     \
+  })
+
+/* Indicate that dynamic linker shouldn't try to initialize TLS even
+   when no PT_TLS segments are found in the program and libraries
+   it is linked against.  */
+#  define TLS_INIT_TP_EXPENSIVE 1
+
+/* Return the address of the dtv for the current thread.  */
+#  define THREAD_DTV() \
+  ({ struct _pthread_descr_struct *__descr;				      \
+     THREAD_GETMEM (__descr, p_header.data.dtvp); })
+
+# endif	/* HAVE_TLS_SUPPORT */
+#endif /* __ASSEMBLER__ */
+
+#endif	/* tls.h */