aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2014-04-29 03:08:48 -0400
committerCarlos O'Donell <carlos@systemhalted.org>2014-04-29 04:20:39 -0400
commit5abebba403181de898bbea4ee1bcce5f088c663b (patch)
tree0c4a8eac85e1f2db87621b524bfcbdeb24c2c8f9 /sysdeps
parent4e4a58f4ee45cea6f3083af8f12d3834bb999555 (diff)
downloadglibc-5abebba403181de898bbea4ee1bcce5f088c663b.tar
glibc-5abebba403181de898bbea4ee1bcce5f088c663b.tar.gz
glibc-5abebba403181de898bbea4ee1bcce5f088c663b.tar.bz2
glibc-5abebba403181de898bbea4ee1bcce5f088c663b.zip
Relocate hppa from ports to libc.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/hppa/Makefile44
-rw-r--r--sysdeps/hppa/Versions12
-rw-r--r--sysdeps/hppa/__longjmp.c84
-rw-r--r--sysdeps/hppa/abort-instr.h6
-rw-r--r--sysdeps/hppa/add_n.S57
-rw-r--r--sysdeps/hppa/bits/endian.h7
-rw-r--r--sysdeps/hppa/bits/link.h56
-rw-r--r--sysdeps/hppa/bits/linkmap.h6
-rw-r--r--sysdeps/hppa/bits/setjmp.h60
-rw-r--r--sysdeps/hppa/bsd-_setjmp.S38
-rw-r--r--sysdeps/hppa/bsd-setjmp.S35
-rw-r--r--sysdeps/hppa/configure89
-rw-r--r--sysdeps/hppa/configure.ac66
-rw-r--r--sysdeps/hppa/crti.S79
-rw-r--r--sysdeps/hppa/crtn.S87
-rw-r--r--sysdeps/hppa/dl-fptr.c337
-rw-r--r--sysdeps/hppa/dl-fptr.h39
-rw-r--r--sysdeps/hppa/dl-irel.h47
-rw-r--r--sysdeps/hppa/dl-lookupcfg.h82
-rw-r--r--sysdeps/hppa/dl-machine.h782
-rw-r--r--sysdeps/hppa/dl-symaddr.c35
-rw-r--r--sysdeps/hppa/dl-tls.h31
-rw-r--r--sysdeps/hppa/dl-trampoline.S287
-rw-r--r--sysdeps/hppa/entry.h10
-rw-r--r--sysdeps/hppa/fpu/bits/fenv.h91
-rw-r--r--sysdeps/hppa/fpu/bits/mathdef.h38
-rw-r--r--sysdeps/hppa/fpu/fclrexcpt.c36
-rw-r--r--sysdeps/hppa/fpu/fedisblxcpt.c37
-rw-r--r--sysdeps/hppa/fpu/feenablxcpt.c37
-rw-r--r--sysdeps/hppa/fpu/fegetenv.c35
-rw-r--r--sysdeps/hppa/fpu/fegetexcept.c33
-rw-r--r--sysdeps/hppa/fpu/fegetround.c27
-rw-r--r--sysdeps/hppa/fpu/feholdexcpt.c53
-rw-r--r--sysdeps/hppa/fpu/fesetenv.c63
-rw-r--r--sysdeps/hppa/fpu/fesetround.c40
-rw-r--r--sysdeps/hppa/fpu/feupdateenv.c40
-rw-r--r--sysdeps/hppa/fpu/fgetexcptflg.c36
-rw-r--r--sysdeps/hppa/fpu/fpu_control.h66
-rw-r--r--sysdeps/hppa/fpu/fraiseexcpt.c101
-rw-r--r--sysdeps/hppa/fpu/fsetexcptflg.c37
-rw-r--r--sysdeps/hppa/fpu/ftestexcept.c34
-rw-r--r--sysdeps/hppa/fpu/libm-test-ulps717
-rw-r--r--sysdeps/hppa/frame.h27
-rw-r--r--sysdeps/hppa/gccframe.h22
-rw-r--r--sysdeps/hppa/get-rounding-mode.h35
-rw-r--r--sysdeps/hppa/hppa1.1/Implies3
-rw-r--r--sysdeps/hppa/hppa1.1/addmul_1.S103
-rw-r--r--sysdeps/hppa/hppa1.1/mul_1.S99
-rw-r--r--sysdeps/hppa/hppa1.1/s_signbit.c34
-rw-r--r--sysdeps/hppa/hppa1.1/submul_1.S112
-rw-r--r--sysdeps/hppa/hppa1.1/udiv_qrnnd.S77
-rw-r--r--sysdeps/hppa/jmpbuf-offsets.h19
-rw-r--r--sysdeps/hppa/jmpbuf-unwind.h26
-rw-r--r--sysdeps/hppa/ldsodefs.h41
-rw-r--r--sysdeps/hppa/libc-tls.c36
-rw-r--r--sysdeps/hppa/libgcc-compat.c42
-rw-r--r--sysdeps/hppa/lshift.S65
-rw-r--r--sysdeps/hppa/machine-gmon.h24
-rw-r--r--sysdeps/hppa/math_private.h27
-rw-r--r--sysdeps/hppa/memusage.h21
-rw-r--r--sysdeps/hppa/mp_clz_tab.c1
-rw-r--r--sysdeps/hppa/nptl/Makefile20
-rw-r--r--sysdeps/hppa/nptl/jmpbuf-unwind.h30
-rw-r--r--sysdeps/hppa/nptl/pthread_spin_init.c28
-rw-r--r--sysdeps/hppa/nptl/pthread_spin_lock.c23
-rw-r--r--sysdeps/hppa/nptl/pthread_spin_unlock.c28
-rw-r--r--sysdeps/hppa/nptl/pthreaddef.h39
-rw-r--r--sysdeps/hppa/nptl/shlib-versions1
-rw-r--r--sysdeps/hppa/nptl/tcb-offsets.sym19
-rw-r--r--sysdeps/hppa/nptl/tls.h171
-rw-r--r--sysdeps/hppa/nptl/tst-oddstacklimit.c26
-rw-r--r--sysdeps/hppa/preconfigure6
-rw-r--r--sysdeps/hppa/rshift.S62
-rw-r--r--sysdeps/hppa/setjmp.S72
-rw-r--r--sysdeps/hppa/shlib-versions9
-rw-r--r--sysdeps/hppa/stackinfo.h33
-rw-r--r--sysdeps/hppa/start.S143
-rw-r--r--sysdeps/hppa/sub_n.S58
-rw-r--r--sysdeps/hppa/sysdep.h76
-rw-r--r--sysdeps/hppa/tininess.h1
-rw-r--r--sysdeps/hppa/tls-macros.h114
-rw-r--r--sysdeps/hppa/tst-audit.h25
-rw-r--r--sysdeps/hppa/udiv_qrnnd.S285
-rw-r--r--sysdeps/unix/sysv/linux/hppa/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/hppa/Versions44
-rw-r--r--sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c47
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/atomic.h107
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/errno.h66
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/fcntl.h85
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/ioctls.h36
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/ipc.h62
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/mman.h112
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/msq.h84
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/sem.h91
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/shm.h106
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/sigaction.h74
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/signum.h81
-rw-r--r--sysdeps/unix/sysv/linux/hppa/bits/socket_type.h55
-rw-r--r--sysdeps/unix/sysv/linux/hppa/brk.c41
-rw-r--r--sysdeps/unix/sysv/linux/hppa/clone.S179
-rw-r--r--sysdeps/unix/sysv/linux/hppa/fcntl.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/fxstat.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/fxstatat.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/getcontext.S165
-rw-r--r--sysdeps/unix/sysv/linux/hppa/getdents64.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/getrlimit64.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/internaltypes.h78
-rw-r--r--sysdeps/unix/sysv/linux/hppa/kernel-features.h44
-rw-r--r--sysdeps/unix/sysv/linux/hppa/kernel_sigaction.h18
-rw-r--r--sysdeps/unix/sysv/linux/hppa/kernel_stat.h31
-rw-r--r--sysdeps/unix/sysv/linux/hppa/lxstat.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/makecontext.c99
-rw-r--r--sysdeps/unix/sysv/linux/hppa/mmap.c49
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h228
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/bits/semaphore.h31
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/clone.S3
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/createthread.c22
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/fork.c33
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/libc-lowlevellock.c20
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c126
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h352
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S105
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread.h1192
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthreadP.h16
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_broadcast.c41
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_destroy.c41
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_init.c42
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_signal.c41
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_timedwait.c43
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_wait.c42
-rw-r--r--sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h280
-rw-r--r--sysdeps/unix/sysv/linux/hppa/profil-counter.h24
-rw-r--r--sysdeps/unix/sysv/linux/hppa/setcontext.S157
-rw-r--r--sysdeps/unix/sysv/linux/hppa/socket.S10
-rw-r--r--sysdeps/unix/sysv/linux/hppa/swapcontext.c42
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/epoll.h143
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/eventfd.h53
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/inotify.h106
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/procfs.h118
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/signalfd.h65
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/timerfd.h59
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/ucontext.h66
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sys/user.h1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/syscall.S18
-rw-r--r--sysdeps/unix/sysv/linux/hppa/syscalls.list39
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sysdep.c77
-rw-r--r--sysdeps/unix/sysv/linux/hppa/sysdep.h497
-rw-r--r--sysdeps/unix/sysv/linux/hppa/ucontext_i.sym59
-rw-r--r--sysdeps/unix/sysv/linux/hppa/umount.c1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/xstat.c1
150 files changed, 11938 insertions, 0 deletions
diff --git a/sysdeps/hppa/Makefile b/sysdeps/hppa/Makefile
new file mode 100644
index 0000000000..8d0c08a9b0
--- /dev/null
+++ b/sysdeps/hppa/Makefile
@@ -0,0 +1,44 @@
+# Copyright (C) 2000-2014 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by David Huggins-Daines (dhd@debian.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, see
+# <http://www.gnu.org/licenses/>.
+
+# We used to need this since the build process uses ld -r. Now we use
+# ld -r --unique=.text* which does more or less the same thing, but better.
+# CFLAGS-.os += -ffunction-sections
+LDFLAGS-c_pic.os += -Wl,--unique=.text*
+
+ifeq ($(subdir),elf)
+CFLAGS-rtld.c += -mdisable-fpregs
+sysdep-dl-routines += dl-symaddr dl-fptr
+sysdep_routines += $(sysdep-dl-routines)
+sysdep-rtld-routines += $(sysdep-dl-routines)
+endif
+
+ifeq ($(subdir),csu)
+ifeq (yes,$(build-shared))
+# Compatibility
+ifeq (yes,$(have-protected))
+CPPFLAGS-libgcc-compat.c = -DHAVE_DOT_HIDDEN
+endif
+sysdep_routines += libgcc-compat
+shared-only-routines += libgcc-compat
+endif
+endif
+
+# We implement a 64-bit `long double'. The standard says we can do this.
+# This means our `long double' and `double' are identical.
+long-double-fcts = no
diff --git a/sysdeps/hppa/Versions b/sysdeps/hppa/Versions
new file mode 100644
index 0000000000..2ae3cbdf17
--- /dev/null
+++ b/sysdeps/hppa/Versions
@@ -0,0 +1,12 @@
+ld {
+ GLIBC_PRIVATE {
+ # hppa specific functions in the dynamic linker, but used by libc.so.
+ _dl_symbol_address; _dl_unmap; _dl_lookup_address;
+ _dl_function_address;
+ }
+}
+libc {
+ GLIBC_2.2 {
+ __clz_tab;
+ }
+}
diff --git a/sysdeps/hppa/__longjmp.c b/sysdeps/hppa/__longjmp.c
new file mode 100644
index 0000000000..cb1aed1c5c
--- /dev/null
+++ b/sysdeps/hppa/__longjmp.c
@@ -0,0 +1,84 @@
+/* longjmp for PA-RISC.
+ Copyright (C) 1997-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <setjmp.h>
+#include <stdlib.h>
+
+/* Jump to the position specified by ENV, causing the
+ setjmp call there to return VAL, or 1 if VAL is 0. */
+void
+__longjmp (__jmp_buf env, int val)
+{
+ /* We must use one of the non-callee saves registers
+ for env. */
+ register unsigned long r26 asm ("r26") = (unsigned long)&env[0];
+ register unsigned long r25 asm ("r25") = (unsigned long)(val == 0 ? 1 : val);
+
+#ifdef CHECK_SP
+ CHECK_SP (env[0].__jmp_buf.__sp);
+#endif
+
+ asm volatile(
+ /* Set return value. */
+ "copy %0, %%r28\n\t"
+ /* Load callee saves from r3 to r18. */
+ "ldw 0(%1), %%r3\n\t"
+ "ldw 8(%1), %%r4\n\t"
+ "ldw 12(%1), %%r5\n\t"
+ "ldw 16(%1), %%r6\n\t"
+ "ldw 20(%1), %%r7\n\t"
+ "ldw 24(%1), %%r8\n\t"
+ "ldw 28(%1), %%r9\n\t"
+ "ldw 32(%1), %%r10\n\t"
+ "ldw 36(%1), %%r11\n\t"
+ "ldw 40(%1), %%r12\n\t"
+ "ldw 44(%1), %%r13\n\t"
+ "ldw 48(%1), %%r14\n\t"
+ "ldw 52(%1), %%r15\n\t"
+ "ldw 56(%1), %%r16\n\t"
+ "ldw 60(%1), %%r17\n\t"
+ "ldw 64(%1), %%r18\n\t"
+ /* Load PIC register. */
+ "ldw 68(%1), %%r19\n\t"
+ /* Load static link register. */
+ "ldw 72(%1), %%r27\n\t"
+ /* Load stack pointer. */
+ "ldw 76(%1), %%r30\n\t"
+ /* Load return pointer. */
+ "ldw 80(%1), %%rp\n\t"
+ /* Ues a spare caller saves register. */
+ "ldo 88(%1),%%r25\n\t"
+ /* Load callee saves from fr12 to fr21. */
+ "fldds,ma 8(%%r25), %%fr12\n\t"
+ "fldds,ma 8(%%r25), %%fr13\n\t"
+ "fldds,ma 8(%%r25), %%fr14\n\t"
+ "fldds,ma 8(%%r25), %%fr15\n\t"
+ "fldds,ma 8(%%r25), %%fr16\n\t"
+ "fldds,ma 8(%%r25), %%fr17\n\t"
+ "fldds,ma 8(%%r25), %%fr18\n\t"
+ "fldds,ma 8(%%r25), %%fr19\n\t"
+ "fldds,ma 8(%%r25), %%fr20\n\t"
+ "fldds 0(%%r25), %%fr21\n\t"
+ /* Jump back to stored return address. */
+ "bv,n %%r0(%%r2)\n\t"
+ : /* No outputs. */
+ : "r" (r25), "r" (r26)
+ : /* No point in clobbers. */ );
+ /* Avoid `volatile function does return' warnings. */
+ for (;;);
+}
diff --git a/sysdeps/hppa/abort-instr.h b/sysdeps/hppa/abort-instr.h
new file mode 100644
index 0000000000..c13b0e5a4c
--- /dev/null
+++ b/sysdeps/hppa/abort-instr.h
@@ -0,0 +1,6 @@
+/* An instruction privileged instruction to crash a userspace program.
+
+ We go with iitlbp because it has a history of being used to crash
+ programs. */
+
+#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%sr0, %r0)")
diff --git a/sysdeps/hppa/add_n.S b/sysdeps/hppa/add_n.S
new file mode 100644
index 0000000000..29a169cb70
--- /dev/null
+++ b/sysdeps/hppa/add_n.S
@@ -0,0 +1,57 @@
+;! HP-PA __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+;! sum in a third limb vector.
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr gr26
+;! s1_ptr gr25
+;! s2_ptr gr24
+;! size gr23
+
+;! One might want to unroll this as for other processors, but it turns
+;! out that the data cache contention after a store makes such
+;! unrolling useless. We can't come under 5 cycles/limb anyway.
+
+ .text
+ .export __mpn_add_n
+__mpn_add_n:
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(%r25),%r21
+ ldws,ma 4(%r24),%r20
+
+ addib,= -1,%r23,L$end ;! check for (SIZE == 1)
+ add %r21,%r20,%r28 ;! add first limbs ignoring cy
+
+L$loop: ldws,ma 4(%r25),%r21
+ ldws,ma 4(%r24),%r20
+ stws,ma %r28,4(%r26)
+ addib,<> -1,%r23,L$loop
+ addc %r21,%r20,%r28
+
+L$end: stws %r28,0(%r26)
+ bv 0(%r2)
+ addc %r0,%r0,%r28
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/bits/endian.h b/sysdeps/hppa/bits/endian.h
new file mode 100644
index 0000000000..585db0c0fa
--- /dev/null
+++ b/sysdeps/hppa/bits/endian.h
@@ -0,0 +1,7 @@
+/* hppa1.1 big-endian. */
+
+#ifndef _ENDIAN_H
+# error "Never use <bits/endian.h> directly; include <endian.h> instead."
+#endif
+
+#define __BYTE_ORDER __BIG_ENDIAN
diff --git a/sysdeps/hppa/bits/link.h b/sysdeps/hppa/bits/link.h
new file mode 100644
index 0000000000..fa6e1ebe70
--- /dev/null
+++ b/sysdeps/hppa/bits/link.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+/* Registers for entry into PLT on hppa. */
+typedef struct La_hppa_regs
+{
+ uint32_t lr_reg[4];
+ double lr_fpreg[4];
+ uint32_t lr_sp;
+ uint32_t lr_ra;
+} La_hppa_regs;
+
+/* Return values for calls from PLT on hppa. */
+typedef struct La_hppa_retval
+{
+ uint32_t lrv_r28;
+ uint32_t lrv_r29;
+ double lr_fr4;
+} La_hppa_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_hppa_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_hppa_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_hppa_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_hppa_regs *__inregs,
+ La_hppa_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
diff --git a/sysdeps/hppa/bits/linkmap.h b/sysdeps/hppa/bits/linkmap.h
new file mode 100644
index 0000000000..54842b2299
--- /dev/null
+++ b/sysdeps/hppa/bits/linkmap.h
@@ -0,0 +1,6 @@
+/* Used to store the function descriptor table */
+struct link_map_machine
+ {
+ size_t fptr_table_len;
+ ElfW(Addr) *fptr_table;
+ };
diff --git a/sysdeps/hppa/bits/setjmp.h b/sysdeps/hppa/bits/setjmp.h
new file mode 100644
index 0000000000..9a404e7c1e
--- /dev/null
+++ b/sysdeps/hppa/bits/setjmp.h
@@ -0,0 +1,60 @@
+/* Copyright (C) 2000-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Define the machine-dependent type `jmp_buf'. HPPA version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
+#endif
+
+#ifndef _ASM
+/* The entire jump buffer must be 168 bytes long and laid
+ out in exactly as follows for ABI consistency.
+ * 20 x 32-bit gprs, with 8-bytes of padding, arranged so:
+ - r3 (callee saves)
+ - 4 bytes of padding.
+ - r4-r18 (callee saves)
+ - r19 (PIC register)
+ - r27 (static link register)
+ - r30 (stcack pointer)
+ - r2 (return pointer)
+ - 4 bytes of padding.
+ * 10 x 64-bit fprs in this order:
+ - fr12-fr21 (callee saves)
+ Note: We have 8 bytes of free space for future uses. */
+typedef union
+ {
+ struct __jmp_buf_internal_tag
+ {
+ int __r3;
+ int __pad0;
+ int __r4_r18[15];
+ int __r19;
+ int __r27;
+ int __sp;
+ int __rp;
+ int __pad1;
+ double __fr12_fr21[10];
+ } __jmp_buf;
+ /* Legacy definition. Ensures double alignment for fpsrs. */
+ double __align[21];
+ } __jmp_buf[1];
+#endif
+
+#endif /* bits/setjmp.h */
diff --git a/sysdeps/hppa/bsd-_setjmp.S b/sysdeps/hppa/bsd-_setjmp.S
new file mode 100644
index 0000000000..4795ceff36
--- /dev/null
+++ b/sysdeps/hppa/bsd-_setjmp.S
@@ -0,0 +1,38 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. HPPA version.
+ Copyright (C) 2001-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+ .text
+ .align 4
+ .globl _setjmp
+ .export _setjmp, code
+ .level 2.0
+ .proc
+ .callinfo
+ .import __sigsetjmp
+_setjmp:
+ b __sigsetjmp
+ ldi 0, %r25
+
+ .procend
+libc_hidden_def (_setjmp)
diff --git a/sysdeps/hppa/bsd-setjmp.S b/sysdeps/hppa/bsd-setjmp.S
new file mode 100644
index 0000000000..dd776f4e1c
--- /dev/null
+++ b/sysdeps/hppa/bsd-setjmp.S
@@ -0,0 +1,35 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. HPPA version.
+ Copyright (C) 2001-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+ We cannot do it in C because it must be a tail-call, so frame-unwinding
+ in setjmp doesn't clobber the state restored by longjmp. */
+
+ .text
+ .align 4
+ .globl setjmp
+ .export setjmp, code
+ .level 2.0
+ .proc
+ .callinfo
+ .import __sigsetjmp
+setjmp:
+ b __sigsetjmp
+ ldi 1, %r25
+
+ .procend
diff --git a/sysdeps/hppa/configure b/sysdeps/hppa/configure
new file mode 100644
index 0000000000..d78e1bcd64
--- /dev/null
+++ b/sysdeps/hppa/configure
@@ -0,0 +1,89 @@
+# This file is generated from configure.ac by Autoconf. DO NOT EDIT!
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler line separator" >&5
+$as_echo_n "checking for assembler line separator... " >&6; }
+if ${libc_cv_asm_line_sep+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.s <<EOF
+nop ; is_old_puffin
+EOF
+if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ libc_cv_asm_line_sep='!'
+else
+ if test -z "$enable_hacker_mode"; then
+ echo "*** You need a newer assembler to compile glibc"
+ rm -f conftest*
+ exit 1
+ fi
+ libc_cv_asm_line_sep=';'
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_line_sep" >&5
+$as_echo "$libc_cv_asm_line_sep" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define ASM_LINE_SEP $libc_cv_asm_line_sep
+_ACEOF
+
+
+# Check for support of thread-local storage handling in assembler and
+# linker.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for hppa TLS support" >&5
+$as_echo_n "checking for hppa TLS support... " >&6; }
+if ${libc_cv_hppa_tls+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.s <<\EOF
+; Setup tls data
+.section ".tdata","awT",@progbits
+foo: .data 32
+ .text
+; Test general dyanmic relocations
+test0:
+ addil LT'foo-$tls_gdidx$, %r19
+ ldo RT'foo-$tls_gdidx$(%r1), %r26
+ b __tls_get_addr
+ nop
+; Test local dynamic relocations
+test1:
+ addil LT'foo-$tls_ldidx$, %r19
+ b __tls_get_addr
+ ldo RT'foo-$tls_ldidx$(%r1), %r26
+ ldo RR'foo-$tls_dtpoff$(%r1), %r25
+ ; More variables can be loaded...
+; Test initial exec reloctiosn
+test2:
+ mfctl %cr27, %r26
+ addil LT'foo-$tls_ieoff$, %r19
+ ldw RT'foo-$tls_ieoff$(%r1), %r25
+ add %r26, %r25, %r24
+; Test local exec relocations
+test3:
+ mfctl %cr27, %r26
+ addil LR'foo-$tls_leoff$, %r26
+ ldo RR'foo-$tls_leoff$(%r1), %r25
+; Done all the TLS tests.
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ libc_cv_hppa_tls=yes
+else
+ libc_cv_hppa_tls=no
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_hppa_tls" >&5
+$as_echo "$libc_cv_hppa_tls" >&6; }
+if test $libc_cv_hppa_tls = no; then
+ as_fn_error $? "the assembler must support TLS" "$LINENO" 5
+fi
diff --git a/sysdeps/hppa/configure.ac b/sysdeps/hppa/configure.ac
new file mode 100644
index 0000000000..40f33603e3
--- /dev/null
+++ b/sysdeps/hppa/configure.ac
@@ -0,0 +1,66 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+
+dnl The standard hppa assembler uses `;' to start comments and `!'
+dnl as a line separator.
+AC_CACHE_CHECK(for assembler line separator,
+ libc_cv_asm_line_sep, [dnl
+cat > conftest.s <<EOF
+nop ; is_old_puffin
+EOF
+if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_asm_line_sep='!'
+else
+ if test -z "$enable_hacker_mode"; then
+ echo "*** You need a newer assembler to compile glibc"
+ rm -f conftest*
+ exit 1
+ fi
+ libc_cv_asm_line_sep=';'
+fi
+rm -f conftest*])
+AC_DEFINE_UNQUOTED(ASM_LINE_SEP, $libc_cv_asm_line_sep)
+
+# Check for support of thread-local storage handling in assembler and
+# linker.
+AC_CACHE_CHECK(for hppa TLS support, libc_cv_hppa_tls, [dnl
+cat > conftest.s <<\EOF
+; Setup tls data
+.section ".tdata","awT",@progbits
+foo: .data 32
+ .text
+; Test general dyanmic relocations
+test0:
+ addil LT'foo-$tls_gdidx$, %r19
+ ldo RT'foo-$tls_gdidx$(%r1), %r26
+ b __tls_get_addr
+ nop
+; Test local dynamic relocations
+test1:
+ addil LT'foo-$tls_ldidx$, %r19
+ b __tls_get_addr
+ ldo RT'foo-$tls_ldidx$(%r1), %r26
+ ldo RR'foo-$tls_dtpoff$(%r1), %r25
+ ; More variables can be loaded...
+; Test initial exec reloctiosn
+test2:
+ mfctl %cr27, %r26
+ addil LT'foo-$tls_ieoff$, %r19
+ ldw RT'foo-$tls_ieoff$(%r1), %r25
+ add %r26, %r25, %r24
+; Test local exec relocations
+test3:
+ mfctl %cr27, %r26
+ addil LR'foo-$tls_leoff$, %r26
+ ldo RR'foo-$tls_leoff$(%r1), %r25
+; Done all the TLS tests.
+EOF
+dnl
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ libc_cv_hppa_tls=yes
+else
+ libc_cv_hppa_tls=no
+fi
+rm -f conftest*])
+if test $libc_cv_hppa_tls = no; then
+ AC_MSG_ERROR([the assembler must support TLS])
+fi
diff --git a/sysdeps/hppa/crti.S b/sysdeps/hppa/crti.S
new file mode 100644
index 0000000000..ccb862c094
--- /dev/null
+++ b/sysdeps/hppa/crti.S
@@ -0,0 +1,79 @@
+/* Special .init and .fini section support for HPPA
+ Copyright (C) 2000-2014 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 GNU 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.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* 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. The symbols _init and _fini are
+ magic and cause the linker to emit DT_INIT and DT_FINI. */
+
+#include <libc-symbols.h>
+#include <sysdep.h>
+
+#ifndef PREINIT_FUNCTION
+# define PREINIT_FUNCTION __gmon_start__
+#endif
+
+#ifndef PREINIT_FUNCTION_WEAK
+# define PREINIT_FUNCTION_WEAK 1
+#endif
+
+/* _init prologue. */
+ .section .init, "ax", %progbits
+ .align 4
+ .globl _init
+ .type _init,@function
+_init:
+ stw %rp,-20(%sp)
+ stwm %r4,64(%sp)
+ stw %r19,-32(%sp)
+#if PREINIT_FUNCTION_WEAK
+ bl PREINIT_FUNCTION,%rp
+ copy %r19,%r4 /* delay slot */
+#else
+ bl PREINIT_FUNCTION,%rp
+ copy %r19,%r4 /* delay slot */
+#endif
+ copy %r4,%r19
+
+/* _fini prologue. */
+ .section .fini,"ax",%progbits
+ .align 4
+ .globl _fini
+ .type _fini,@function
+_fini:
+ stw %rp,-20(%sp)
+ stwm %r4,64(%sp)
+ stw %r19,-32(%sp)
+ copy %r19,%r4
diff --git a/sysdeps/hppa/crtn.S b/sysdeps/hppa/crtn.S
new file mode 100644
index 0000000000..007ccec074
--- /dev/null
+++ b/sysdeps/hppa/crtn.S
@@ -0,0 +1,87 @@
+/* Special .init and .fini section support for HPPA
+ Copyright (C) 2000-2014 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 GNU 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.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* crtn.S puts function epilogues in the .init and .fini sections
+ corresponding to the prologues in crti.S. */
+
+/* Note that we cannot have a weak undefined __gmon_start__, because
+ that would require this to be PIC, and the linker is currently not
+ able to generate a proper procedure descriptor for _init. Sad but
+ true. Anyway, HPPA is one of those horrible architectures where
+ making the comparison and indirect call is quite expensive (see the
+ comment in sysdeps/generic/initfini.c). */
+ .text
+ .align 4
+ .weak __gmon_start__
+ .type __gmon_start__,@function
+__gmon_start__:
+ .proc
+ .callinfo
+ .entry
+ bv,n %r0(%r2)
+ .exit
+ .procend
+
+/* Here is the tail end of _init. We put __gmon_start before this so
+ that the assembler creates the .PARISC.unwind section for us, ie.
+ with the right attributes. */
+ .section .init, "ax", @progbits
+ ldw -84(%sp),%rp
+ copy %r4,%r19
+ bv %r0(%rp)
+_end_init:
+ ldwm -64(%sp),%r4
+
+/* Our very own unwind info, because the assembler can't handle
+ functions split into two or more pieces. */
+ .section .PARISC.unwind
+ .extern _init
+ .word _init, _end_init
+ .byte 0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08
+
+/* Here is the tail end of _fini. */
+ .section .fini, "ax", @progbits
+ ldw -84(%sp),%rp
+ copy %r4,%r19
+ bv %r0(%rp)
+_end_fini:
+ ldwm -64(%sp),%r4
+
+ .section .PARISC.unwind
+ .extern _fini
+ .word _fini, _end_fini
+ .byte 0x08, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08
diff --git a/sysdeps/hppa/dl-fptr.c b/sysdeps/hppa/dl-fptr.c
new file mode 100644
index 0000000000..f975664dd6
--- /dev/null
+++ b/sysdeps/hppa/dl-fptr.c
@@ -0,0 +1,337 @@
+/* Manage function descriptors. Generic version.
+ Copyright (C) 1999-2014 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 <libintl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <link.h>
+#include <ldsodefs.h>
+#include <elf/dynamic-link.h>
+#include <dl-fptr.h>
+#include <dl-unmap-segments.h>
+#include <atomic.h>
+
+#ifndef ELF_MACHINE_BOOT_FPTR_TABLE_LEN
+/* ELF_MACHINE_BOOT_FPTR_TABLE_LEN should be greater than the number of
+ dynamic symbols in ld.so. */
+# define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 256
+#endif
+
+#ifndef ELF_MACHINE_LOAD_ADDRESS
+# error "ELF_MACHINE_LOAD_ADDRESS is not defined."
+#endif
+
+#ifndef COMPARE_AND_SWAP
+# define COMPARE_AND_SWAP(ptr, old, new) \
+ (catomic_compare_and_exchange_bool_acq (ptr, new, old) == 0)
+#endif
+
+ElfW(Addr) _dl_boot_fptr_table [ELF_MACHINE_BOOT_FPTR_TABLE_LEN];
+
+static struct local
+ {
+ struct fdesc_table *root;
+ struct fdesc *free_list;
+ unsigned int npages; /* # of pages to allocate */
+ /* the next to members MUST be consecutive! */
+ struct fdesc_table boot_table;
+ struct fdesc boot_fdescs[1024];
+ }
+local =
+ {
+#ifdef SHARED
+ /* Address of .boot_table is not known until runtime. */
+ .root = 0,
+#else
+ .root = &local.boot_table,
+#endif
+ .npages = 2,
+ .boot_table =
+ {
+ .len = sizeof (local.boot_fdescs) / sizeof (local.boot_fdescs[0]),
+ .first_unused = 0
+ }
+ };
+
+/* Create a new fdesc table and return a pointer to the first fdesc
+ entry. The fdesc lock must have been acquired already. */
+
+static struct fdesc_table *
+new_fdesc_table (struct local *l, size_t *size)
+{
+ size_t old_npages = l->npages;
+ size_t new_npages = old_npages + old_npages;
+ struct fdesc_table *new_table;
+
+ /* If someone has just created a new table, we return NULL to tell
+ the caller to use the new table. */
+ if (! COMPARE_AND_SWAP (&l->npages, old_npages, new_npages))
+ return (struct fdesc_table *) NULL;
+
+ *size = old_npages * GLRO(dl_pagesize);
+ new_table = __mmap (NULL, *size,
+ PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (new_table == MAP_FAILED)
+ _dl_signal_error (errno, NULL, NULL,
+ N_("cannot map pages for fdesc table"));
+
+ new_table->len
+ = (*size - sizeof (*new_table)) / sizeof (struct fdesc);
+ new_table->first_unused = 1;
+ return new_table;
+}
+
+/* Must call _dl_fptr_init before using any other function. */
+void
+_dl_fptr_init (void)
+{
+ struct local *l;
+
+ ELF_MACHINE_LOAD_ADDRESS (l, local);
+ l->root = &l->boot_table;
+}
+
+static ElfW(Addr)
+make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp)
+{
+ struct fdesc *fdesc = NULL;
+ struct fdesc_table *root;
+ unsigned int old;
+ struct local *l;
+
+ ELF_MACHINE_LOAD_ADDRESS (l, local);
+
+ retry:
+ root = l->root;
+ while (1)
+ {
+ old = root->first_unused;
+ if (old >= root->len)
+ break;
+ else if (COMPARE_AND_SWAP (&root->first_unused, old, old + 1))
+ {
+ fdesc = &root->fdesc[old];
+ goto install;
+ }
+ }
+
+ if (l->free_list)
+ {
+ /* Get it from free-list. */
+ do
+ {
+ fdesc = l->free_list;
+ if (fdesc == NULL)
+ goto retry;
+ }
+ while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->free_list,
+ (ElfW(Addr)) fdesc, fdesc->ip));
+ }
+ else
+ {
+ /* Create a new fdesc table. */
+ size_t size;
+ struct fdesc_table *new_table = new_fdesc_table (l, &size);
+
+ if (new_table == NULL)
+ goto retry;
+
+ new_table->next = root;
+ if (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->root,
+ (ElfW(Addr)) root,
+ (ElfW(Addr)) new_table))
+ {
+ /* Someone has just installed a new table. Return NULL to
+ tell the caller to use the new table. */
+ __munmap (new_table, size);
+ goto retry;
+ }
+
+ /* Note that the first entry was reserved while allocating the
+ memory for the new page. */
+ fdesc = &new_table->fdesc[0];
+ }
+
+ install:
+ fdesc->ip = ip;
+ fdesc->gp = gp;
+
+ return (ElfW(Addr)) fdesc;
+}
+
+
+static inline ElfW(Addr) * __attribute__ ((always_inline))
+make_fptr_table (struct link_map *map)
+{
+ const ElfW(Sym) *symtab
+ = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
+ const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+ ElfW(Addr) *fptr_table;
+ size_t size;
+ size_t len;
+
+ /* XXX Apparently the only way to find out the size of the dynamic
+ symbol section is to assume that the string table follows right
+ afterwards... */
+ len = ((strtab - (char *) symtab)
+ / map->l_info[DT_SYMENT]->d_un.d_val);
+ size = ((len * sizeof (fptr_table[0]) + GLRO(dl_pagesize) - 1)
+ & -GLRO(dl_pagesize));
+ /* XXX We don't support here in the moment systems without MAP_ANON.
+ There probably are none for IA-64. In case this is proven wrong
+ we will have to open /dev/null here and use the file descriptor
+ instead of the hard-coded -1. */
+ fptr_table = __mmap (NULL, size,
+ PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
+ -1, 0);
+ if (fptr_table == MAP_FAILED)
+ _dl_signal_error (errno, NULL, NULL,
+ N_("cannot map pages for fptr table"));
+
+ if (COMPARE_AND_SWAP ((ElfW(Addr) *) &map->l_mach.fptr_table,
+ (ElfW(Addr)) NULL, (ElfW(Addr)) fptr_table))
+ map->l_mach.fptr_table_len = len;
+ else
+ __munmap (fptr_table, len * sizeof (fptr_table[0]));
+
+ return map->l_mach.fptr_table;
+}
+
+
+ElfW(Addr)
+_dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym,
+ ElfW(Addr) ip)
+{
+ ElfW(Addr) *ftab = map->l_mach.fptr_table;
+ const ElfW(Sym) *symtab;
+ Elf_Symndx symidx;
+ struct local *l;
+
+ if (__builtin_expect (ftab == NULL, 0))
+ ftab = make_fptr_table (map);
+
+ symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
+ symidx = sym - symtab;
+
+ if (symidx >= map->l_mach.fptr_table_len)
+ _dl_signal_error (0, NULL, NULL,
+ N_("internal error: symidx out of range of fptr table"));
+
+ while (ftab[symidx] == 0)
+ {
+ /* GOT has already been relocated in elf_get_dynamic_info -
+ don't try to relocate it again. */
+ ElfW(Addr) fdesc
+ = make_fdesc (ip, map->l_info[DT_PLTGOT]->d_un.d_ptr);
+
+ if (__builtin_expect (COMPARE_AND_SWAP (&ftab[symidx], (ElfW(Addr)) NULL,
+ fdesc), 1))
+ {
+ /* Noone has updated the entry and the new function
+ descriptor has been installed. */
+#if 0
+ const char *strtab
+ = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+
+ ELF_MACHINE_LOAD_ADDRESS (l, local);
+ if (l->root != &l->boot_table
+ || l->boot_table.first_unused > 20)
+ _dl_debug_printf ("created fdesc symbol `%s' at %lx\n",
+ strtab + sym->st_name, ftab[symidx]);
+#endif
+ break;
+ }
+ else
+ {
+ /* We created a duplicated function descriptor. We put it on
+ free-list. */
+ struct fdesc *f = (struct fdesc *) fdesc;
+
+ ELF_MACHINE_LOAD_ADDRESS (l, local);
+
+ do
+ f->ip = (ElfW(Addr)) l->free_list;
+ while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->free_list,
+ f->ip, fdesc));
+ }
+ }
+
+ return ftab[symidx];
+}
+
+
+void
+_dl_unmap (struct link_map *map)
+{
+ ElfW(Addr) *ftab = map->l_mach.fptr_table;
+ struct fdesc *head = NULL, *tail = NULL;
+ size_t i;
+
+ _dl_unmap_segments (map);
+
+ if (ftab == NULL)
+ return;
+
+ /* String together the fdesc structures that are being freed. */
+ for (i = 0; i < map->l_mach.fptr_table_len; ++i)
+ {
+ if (ftab[i])
+ {
+ *(struct fdesc **) ftab[i] = head;
+ head = (struct fdesc *) ftab[i];
+ if (tail == NULL)
+ tail = head;
+ }
+ }
+
+ /* Prepend the new list to the free_list: */
+ if (tail)
+ do
+ tail->ip = (ElfW(Addr)) local.free_list;
+ while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &local.free_list,
+ tail->ip, (ElfW(Addr)) head));
+
+ __munmap (ftab, (map->l_mach.fptr_table_len
+ * sizeof (map->l_mach.fptr_table[0])));
+
+ map->l_mach.fptr_table = NULL;
+}
+
+
+ElfW(Addr)
+_dl_lookup_address (const void *address)
+{
+ ElfW(Addr) addr = (ElfW(Addr)) address;
+ struct fdesc_table *t;
+ unsigned long int i;
+
+ for (t = local.root; t != NULL; t = t->next)
+ {
+ i = (struct fdesc *) addr - &t->fdesc[0];
+ if (i < t->first_unused && addr == (ElfW(Addr)) &t->fdesc[i])
+ {
+ addr = t->fdesc[i].ip;
+ break;
+ }
+ }
+
+ return addr;
+}
diff --git a/sysdeps/hppa/dl-fptr.h b/sysdeps/hppa/dl-fptr.h
new file mode 100644
index 0000000000..f8ce73cf05
--- /dev/null
+++ b/sysdeps/hppa/dl-fptr.h
@@ -0,0 +1,39 @@
+/* Function descriptors. HPPA version.
+ Copyright (C) 2003-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef dl_hppa_fptr_h
+#define dl_hppa_fptr_h 1
+
+#include <sysdeps/generic/dl-fptr.h>
+
+/* Initialize function pointer code. Call before relocation processing. */
+extern void _dl_fptr_init (void);
+
+/* There are currently 33 dynamic symbols in ld.so.
+ ELF_MACHINE_BOOT_FPTR_TABLE_LEN needs to be at least that big. */
+#define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 64
+
+#define ELF_MACHINE_LOAD_ADDRESS(var, symbol) \
+ asm ( \
+" b,l 1f,%0\n" \
+" depi 0,31,2,%0\n" \
+"1: addil L'" #symbol " - ($PIC_pcrel$0 - 8),%0\n" \
+" ldo R'" #symbol " - ($PIC_pcrel$0 - 12)(%%r1),%0\n" \
+ : "=&r" (var) : : "r1");
+
+#endif /* !dl_hppa_fptr_h */
diff --git a/sysdeps/hppa/dl-irel.h b/sysdeps/hppa/dl-irel.h
new file mode 100644
index 0000000000..beefff42fe
--- /dev/null
+++ b/sysdeps/hppa/dl-irel.h
@@ -0,0 +1,47 @@
+/* Machine-dependent ELF indirect relocation inline functions.
+ HP-PARISC version.
+ Copyright (C) 2012-2014 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_IREL_H
+#define _DL_IREL_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <dl-fptr.h>
+
+#define ELF_MACHINE_IREL 1
+
+/* Implement enough to get the build going again. */
+#warning "NEED STT_GNU_IFUNC IMPLEMENTATION"
+
+static inline struct fdesc
+__attribute ((always_inline))
+elf_ifunc_invoke (uintptr_t addr)
+{
+ return ((struct fdesc) {0, 0});
+}
+
+static inline void
+__attribute ((always_inline))
+elf_irel (const Elf32_Rel *reloc)
+{
+ return;
+}
+
+#endif /* dl-irel.h */
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
new file mode 100644
index 0000000000..58dc3856c6
--- /dev/null
+++ b/sysdeps/hppa/dl-lookupcfg.h
@@ -0,0 +1,82 @@
+/* Configuration of lookup functions.
+ Copyright (C) 2000-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define ELF_FUNCTION_PTR_IS_SPECIAL
+#define DL_UNMAP_IS_SPECIAL
+
+#include <dl-fptr.h>
+
+/* Forward declaration. */
+struct link_map;
+
+void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref);
+
+#define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
+
+Elf32_Addr _dl_lookup_address (const void *address);
+
+/* Clear the bottom two bits so generic code can find the fdesc entry */
+#define DL_LOOKUP_ADDRESS(addr) \
+ (_dl_lookup_address ((void *)((unsigned long)addr & ~3)))
+
+void _dl_unmap (struct link_map *map);
+
+#define DL_UNMAP(map) _dl_unmap (map)
+
+#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \
+ attr volatile unsigned int fptr[2]; \
+ /* The test for "start & 2" below is to accommodate old binaries which \
+ violated the ELF ABI by pointing DT_INIT and DT_FINI at a function \
+ descriptor. */ \
+ if ((ElfW(Addr)) (start) & 2) \
+ addr = (ElfW(Addr)) start; \
+ else \
+ { \
+ fptr[0] = (unsigned int) (start); \
+ fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
+ /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
+ addr = (ElfW(Addr))((unsigned int)fptr | 2); \
+ } \
+
+#define DL_CALL_DT_INIT(map, start, argc, argv, env) \
+{ \
+ ElfW(Addr) addr; \
+ DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
+ init_t init = (init_t) addr; \
+ init (argc, argv, env); \
+}
+
+#define DL_CALL_DT_FINI(map, start) \
+{ \
+ ElfW(Addr) addr; \
+ DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
+ fini_t fini = (fini_t) addr; \
+ fini (); \
+}
+
+/* The type of the return value of fixup/profile_fixup */
+#define DL_FIXUP_VALUE_TYPE struct fdesc
+
+/* Construct a fixup value from the address and linkmap */
+#define DL_FIXUP_MAKE_VALUE(map, addr) \
+ ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr })
+
+/* Extract the code address from a fixup value */
+#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
+#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
+#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
new file mode 100644
index 0000000000..ba21f07d7f
--- /dev/null
+++ b/sysdeps/hppa/dl-machine.h
@@ -0,0 +1,782 @@
+/* Machine-dependent ELF dynamic relocation inline functions. PA-RISC version.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ Contributed by David Huggins-Daines <dhd@debian.org>
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef dl_machine_h
+#define dl_machine_h 1
+
+#define ELF_MACHINE_NAME "hppa"
+
+#include <sys/param.h>
+#include <assert.h>
+#include <string.h>
+#include <link.h>
+#include <errno.h>
+#include <dl-fptr.h>
+#include <abort-instr.h>
+#include <tls.h>
+
+/* These two definitions must match the definition of the stub in
+ bfd/elf32-hppa.c (see plt_stub[]).
+
+ a. Define the size of the *entire* stub we place at the end of the PLT
+ table (right up against the GOT).
+
+ b. Define the number of bytes back from the GOT to the entry point of
+ the PLT stub. You see the PLT stub must be entered in the middle
+ so it can depwi to find it's own address (long jump stub)
+
+ c. Define the size of a single PLT entry so we can jump over the
+ last entry to get the stub address */
+
+#define SIZEOF_PLT_STUB (7*4)
+#define GOT_FROM_PLT_STUB (4*4)
+#define PLT_ENTRY_SIZE (2*4)
+
+/* Initialize the function descriptor table before relocations */
+static inline void
+__hppa_init_bootstrap_fdesc_table (struct link_map *map)
+{
+ ElfW(Addr) *boot_table;
+
+ /* Careful: this will be called before got has been relocated... */
+ ELF_MACHINE_LOAD_ADDRESS(boot_table,_dl_boot_fptr_table);
+
+ map->l_mach.fptr_table_len = ELF_MACHINE_BOOT_FPTR_TABLE_LEN;
+ map->l_mach.fptr_table = boot_table;
+}
+
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
+ __hppa_init_bootstrap_fdesc_table (&bootstrap_map); \
+ _dl_fptr_init();
+
+/* Return nonzero iff ELF header is compatible with the running host. */
+static inline int
+elf_machine_matches_host (const Elf32_Ehdr *ehdr)
+{
+ return ehdr->e_machine == EM_PARISC;
+}
+
+/* Return the link-time address of _DYNAMIC. */
+static inline Elf32_Addr
+elf_machine_dynamic (void) __attribute__ ((const));
+
+static inline Elf32_Addr
+elf_machine_dynamic (void)
+{
+ Elf32_Addr dynamic;
+
+ asm ("b,l 1f,%0\n"
+" depi 0,31,2,%0\n"
+"1: addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 8),%0\n"
+" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
+ : "=r" (dynamic) : : "r1");
+
+ return dynamic;
+}
+
+/* Return the run-time load address of the shared object. */
+static inline Elf32_Addr
+elf_machine_load_address (void) __attribute__ ((const));
+
+static inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ Elf32_Addr dynamic;
+
+ asm (
+" b,l 1f,%0\n"
+" depi 0,31,2,%0\n"
+"1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%0\n"
+" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%%r1),%0\n"
+ : "=r" (dynamic) : : "r1");
+
+ return dynamic - elf_machine_dynamic ();
+}
+
+/* Fixup a PLT entry to bounce directly to the function at VALUE. */
+static inline struct fdesc __attribute__ ((always_inline))
+elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+ const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, struct fdesc value)
+{
+ volatile Elf32_Addr *rfdesc = reloc_addr;
+ /* map is the link_map for the caller, t is the link_map for the object
+ being called */
+ rfdesc[1] = value.gp;
+ /* Need to ensure that the gp is visible before the code
+ entry point is updated */
+ rfdesc[0] = value.ip;
+ return value;
+}
+
+/* Return the final value of a plt relocation. */
+static inline struct fdesc
+elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
+ struct fdesc value)
+{
+ /* We are rela only, return a function descriptor as a plt entry. */
+ return (struct fdesc) { value.ip + reloc->r_addend, value.gp };
+}
+
+/* Set up the loaded object described by L so its unrelocated PLT
+ entries will jump to the on-demand fixup code in dl-runtime.c. */
+
+static inline int
+elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
+{
+ Elf32_Addr *got = NULL;
+ Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type, r_sym;
+ const Elf32_Rela *reloc;
+ struct fdesc *fptr;
+ static union {
+ unsigned char c[8];
+ Elf32_Addr i[2];
+ } sig = {{0x00,0xc0,0xff,0xee, 0xde,0xad,0xbe,0xef}};
+
+ /* If we don't have a PLT we can just skip all this... */
+ if (__builtin_expect (l->l_info[DT_JMPREL] == NULL,0))
+ return lazy;
+
+ /* All paths use these values */
+ l_addr = l->l_addr;
+ jmprel = D_PTR(l, l_info[DT_JMPREL]);
+ end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
+
+ extern void _dl_runtime_resolve (void);
+ extern void _dl_runtime_profile (void);
+
+ /* Linking lazily */
+ if (lazy)
+ {
+ /* FIXME: Search for the got, but backwards through the relocs, technically we should
+ find it on the first try. However, assuming the relocs got out of order the
+ routine is made a bit more robust by searching them all in case of failure. */
+ for (iplt = (end_jmprel - sizeof(Elf32_Rela)); iplt >= jmprel; iplt -= sizeof (Elf32_Rela))
+ {
+
+ reloc = (const Elf32_Rela *) iplt;
+ r_type = ELF32_R_TYPE (reloc->r_info);
+ r_sym = ELF32_R_SYM (reloc->r_info);
+
+ got = (Elf32_Addr *) (reloc->r_offset + l_addr + PLT_ENTRY_SIZE + SIZEOF_PLT_STUB);
+
+ /* If we aren't an IPLT, and we aren't NONE then it's a bad reloc */
+ if (__builtin_expect (r_type != R_PARISC_IPLT, 0))
+ {
+ if (__builtin_expect (r_type != R_PARISC_NONE, 0))
+ _dl_reloc_bad_type (l, r_type, 1);
+ continue;
+ }
+
+ /* Check for the plt_stub that binutils placed here for us
+ to use with _dl_runtime_resolve */
+ if (got[-2] != sig.i[0] || got[-1] != sig.i[1])
+ {
+ got = NULL; /* Not the stub... keep looking */
+ }
+ else
+ {
+ /* Found the GOT! */
+ register Elf32_Addr ltp __asm__ ("%r19");
+
+ /* Identify this shared object. Second entry in the got. */
+ got[1] = (Elf32_Addr) l;
+
+ /* This function will be called to perform the relocation. */
+ if (__builtin_expect (!profile, 1))
+ {
+ /* If a static application called us, then _dl_runtime_resolve is not
+ a function descriptor, but the *real* address of the function... */
+ if((unsigned long) &_dl_runtime_resolve & 3)
+ {
+ got[-2] = (Elf32_Addr) ((struct fdesc *)
+ ((unsigned long) &_dl_runtime_resolve & ~3))->ip;
+ }
+ else
+ {
+ /* Static executable! */
+ got[-2] = (Elf32_Addr) &_dl_runtime_resolve;
+ }
+ }
+ else
+ {
+ if (GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), l))
+ {
+ /* This is the object we are looking for. Say that
+ we really want profiling and the timers are
+ started. */
+ GL(dl_profile_map) = l;
+ }
+
+ if((unsigned long) &_dl_runtime_profile & 3)
+ {
+ got[-2] = (Elf32_Addr) ((struct fdesc *)
+ ((unsigned long) &_dl_runtime_profile & ~3))->ip;
+ }
+ else
+ {
+ /* Static executable */
+ got[-2] = (Elf32_Addr) &_dl_runtime_profile;
+ }
+ }
+ /* Plunk in the gp of this function descriptor so we
+ can make the call to _dl_runtime_xxxxxx */
+ got[-1] = ltp;
+ break;
+ /* Done looking for the GOT, and stub is setup */
+ } /* else we found the GOT */
+ } /* for, walk the relocs backwards */
+
+ if(!got)
+ return 0; /* No lazy linking for you! */
+
+ /* Process all the relocs, now that we know the GOT... */
+ for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
+ {
+ reloc = (const Elf32_Rela *) iplt;
+ r_type = ELF32_R_TYPE (reloc->r_info);
+ r_sym = ELF32_R_SYM (reloc->r_info);
+
+ if (__builtin_expect (r_type == R_PARISC_IPLT, 1))
+ {
+ fptr = (struct fdesc *) (reloc->r_offset + l_addr);
+ if (r_sym != 0)
+ {
+ /* Relocate the pointer to the stub. */
+ fptr->ip = (Elf32_Addr) got - GOT_FROM_PLT_STUB;
+
+ /* Instead of the LTP value, we put the reloc offset
+ here. The trampoline code will load the proper
+ LTP and pass the reloc offset to the fixup
+ function. */
+ fptr->gp = iplt - jmprel;
+ } /* r_sym != 0 */
+ else
+ {
+ /* Relocate this *ABS* entry. */
+ fptr->ip = reloc->r_addend + l_addr;
+ fptr->gp = D_PTR (l, l_info[DT_PLTGOT]);
+ }
+ } /* r_type == R_PARISC_IPLT */
+ } /* for all the relocations */
+ } /* if lazy */
+ else
+ {
+ for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
+ {
+ reloc = (const Elf32_Rela *) iplt;
+ r_type = ELF32_R_TYPE (reloc->r_info);
+ r_sym = ELF32_R_SYM (reloc->r_info);
+
+ if (__builtin_expect ((r_type == R_PARISC_IPLT) && (r_sym == 0), 1))
+ {
+ fptr = (struct fdesc *) (reloc->r_offset + l_addr);
+ /* Relocate this *ABS* entry, set only the gp, the rest is set later
+ when elf_machine_rela_relative is called (WITHOUT the linkmap) */
+ fptr->gp = D_PTR (l, l_info[DT_PLTGOT]);
+ } /* r_type == R_PARISC_IPLT */
+ } /* for all the relocations */
+ }
+ return lazy;
+}
+
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER hppa_gnu_pltenter
+#define ARCH_LA_PLTEXIT hppa_gnu_pltexit
+
+/* Initial entry point code for the dynamic linker.
+ The C function `_dl_start' is the real entry point;
+ its return value is the user program's entry point. */
+
+#define RTLD_START \
+/* Set up dp for any non-PIC lib constructors that may be called. */ \
+static struct link_map * __attribute__((used)) \
+set_dp (struct link_map *map) \
+{ \
+ register Elf32_Addr dp asm ("%r27"); \
+ dp = D_PTR (map, l_info[DT_PLTGOT]); \
+ asm volatile ("" : : "r" (dp)); \
+ return map; \
+} \
+ \
+asm ( \
+" .text\n" \
+" .globl _start\n" \
+" .type _start,@function\n" \
+"_start:\n" \
+ /* The kernel does not give us an initial stack frame. */ \
+" ldo 64(%sp),%sp\n" \
+ /* Save the relevant arguments (yes, those are the correct \
+ registers, the kernel is weird) in their stack slots. */ \
+" stw %r25,-40(%sp)\n" /* argc */ \
+" stw %r24,-44(%sp)\n" /* argv */ \
+ \
+ /* We need the LTP, and we need it now. \
+ $PIC_pcrel$0 points 8 bytes past the current instruction, \
+ just like a branch reloc. This sequence gets us the \
+ runtime address of _DYNAMIC. */ \
+" bl 0f,%r19\n" \
+" depi 0,31,2,%r19\n" /* clear priviledge bits */ \
+"0: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8),%r19\n" \
+" ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%r26\n" \
+ \
+ /* The link time address is stored in the first entry of the \
+ GOT. */ \
+" addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16),%r19\n" \
+" ldw R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r20\n" \
+ \
+" sub %r26,%r20,%r20\n" /* Calculate load offset */ \
+ \
+ /* Rummage through the dynamic entries, looking for \
+ DT_PLTGOT. */ \
+" ldw,ma 8(%r26),%r19\n" \
+"1: cmpib,=,n 3,%r19,2f\n" /* tag == DT_PLTGOT? */ \
+" cmpib,<>,n 0,%r19,1b\n" \
+" ldw,ma 8(%r26),%r19\n" \
+ \
+ /* Uh oh! We didn't find one. Abort. */ \
+" iitlbp %r0,(%sr0,%r0)\n" \
+ \
+"2: ldw -4(%r26),%r19\n" /* Found it, load value. */ \
+" add %r19,%r20,%r19\n" /* And add the load offset. */ \
+ \
+ /* Our initial stack layout is rather different from everyone \
+ else's due to the unique PA-RISC ABI. As far as I know it \
+ looks like this: \
+ \
+ ----------------------------------- (this frame created above) \
+ | 32 bytes of magic | \
+ |---------------------------------| \
+ | 32 bytes argument/sp save area | \
+ |---------------------------------| ((current->mm->env_end) \
+ | N bytes of slack | + 63 & ~63) \
+ |---------------------------------| \
+ | envvar and arg strings | \
+ |---------------------------------| \
+ | ELF auxiliary info | \
+ | (up to 28 words) | \
+ |---------------------------------| \
+ | Environment variable pointers | \
+ | upwards to NULL | \
+ |---------------------------------| \
+ | Argument pointers | \
+ | upwards to NULL | \
+ |---------------------------------| \
+ | argc (1 word) | \
+ ----------------------------------- \
+ \
+ So, obviously, we can't just pass %sp to _dl_start. That's \
+ okay, argv-4 will do just fine. \
+ \
+ The pleasant part of this is that if we need to skip \
+ arguments we can just decrement argc and move argv, because \
+ the stack pointer is utterly unrelated to the location of \
+ the environment and argument vectors. */ \
+ \
+ /* This is always within range so we'll be okay. */ \
+" bl _dl_start,%rp\n" \
+" ldo -4(%r24),%r26\n" \
+ \
+" .globl _dl_start_user\n" \
+" .type _dl_start_user,@function\n" \
+"_dl_start_user:\n" \
+ /* Save the entry point in %r3. */ \
+" copy %ret0,%r3\n" \
+ \
+ /* Remember the lowest stack address. */ \
+" addil LT'__libc_stack_end,%r19\n" \
+" ldw RT'__libc_stack_end(%r1),%r20\n" \
+" stw %sp,0(%r20)\n" \
+ \
+ /* See if we were called as a command with the executable file \
+ name as an extra leading argument. */ \
+" addil LT'_dl_skip_args,%r19\n" \
+" ldw RT'_dl_skip_args(%r1),%r20\n" \
+" ldw 0(%r20),%r20\n" \
+ \
+" ldw -40(%sp),%r25\n" /* argc */ \
+" comib,= 0,%r20,.Lnofix\n" /* FIXME: Mispredicted branch */\
+" ldw -44(%sp),%r24\n" /* argv (delay slot) */ \
+ \
+" sub %r25,%r20,%r25\n" \
+" stw %r25,-40(%sp)\n" \
+" sh2add %r20,%r24,%r24\n" \
+" stw %r24,-44(%sp)\n" \
+ \
+".Lnofix:\n" \
+" addil LT'_rtld_local,%r19\n" \
+" ldw RT'_rtld_local(%r1),%r26\n" \
+" bl set_dp, %r2\n" \
+" ldw 0(%r26),%r26\n" \
+ \
+ /* Call _dl_init(_dl_loaded, argc, argv, envp). */ \
+" copy %r28,%r26\n" \
+ \
+ /* envp = argv + argc + 1 */ \
+" sh2add %r25,%r24,%r23\n" \
+" bl _dl_init_internal,%r2\n" \
+" ldo 4(%r23),%r23\n" /* delay slot */ \
+ \
+ /* Reload argc, argv to the registers start.S expects. */ \
+" ldw -40(%sp),%r25\n" \
+" ldw -44(%sp),%r24\n" \
+ \
+ /* _dl_fini is a local function in the loader, so we construct \
+ a false OPD here and pass this to the application. */ \
+ /* FIXME: Should be able to use P%, and LR RR to have the \
+ the linker construct a proper OPD. */ \
+" .section .data\n" \
+"__dl_fini_plabel:\n" \
+" .word _dl_fini\n" \
+" .word 0xdeadbeef\n" \
+" .previous\n" \
+ \
+ /* %r3 contains a function pointer, we need to mask out the \
+ lower bits and load the gp and jump address. */ \
+" depi 0,31,2,%r3\n" \
+" ldw 0(%r3),%r2\n" \
+" addil LT'__dl_fini_plabel,%r19\n" \
+" ldw RT'__dl_fini_plabel(%r1),%r23\n" \
+" stw %r19,4(%r23)\n" \
+" ldw 4(%r3),%r19\n" /* load the object's gp */ \
+" bv %r0(%r2)\n" \
+" depi 2,31,2,%r23\n" /* delay slot */ \
+);
+
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ a TLS variable, so references should not be allowed to define the value.
+ ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
+ of the main executable's symbols, as for a COPY reloc. */
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD)
+# define elf_machine_type_class(type) \
+ ((((type) == R_PARISC_IPLT \
+ || (type) == R_PARISC_EPLT \
+ || (type) == R_PARISC_TLS_DTPMOD32 \
+ || (type) == R_PARISC_TLS_DTPOFF32 \
+ || (type) == R_PARISC_TLS_TPREL32) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY))
+#else
+#define elf_machine_type_class(type) \
+ ((((type) == R_PARISC_IPLT \
+ || (type) == R_PARISC_EPLT) \
+ * ELF_RTYPE_CLASS_PLT) \
+ | (((type) == R_PARISC_COPY) * ELF_RTYPE_CLASS_COPY))
+#endif
+
+/* Used by the runtime in fixup to figure out if reloc is *really* PLT */
+#define ELF_MACHINE_JMP_SLOT R_PARISC_IPLT
+#define ELF_MACHINE_SIZEOF_JMP_SLOT PLT_ENTRY_SIZE
+
+/* We only use RELA. */
+#define ELF_MACHINE_NO_REL 1
+
+/* Return the address of the entry point. */
+#define ELF_MACHINE_START_ADDRESS(map, start) \
+({ \
+ ElfW(Addr) addr; \
+ DL_DT_FUNCTION_ADDRESS(map, start, static, addr) \
+ addr; \
+})
+
+/* We define an initialization functions. This is called very early in
+ * _dl_sysdep_start. */
+#define DL_PLATFORM_INIT dl_platform_init ()
+
+static inline void __attribute__ ((unused))
+dl_platform_init (void)
+{
+ if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
+ /* Avoid an empty string which would disturb us. */
+ GLRO(dl_platform) = NULL;
+}
+
+#endif /* !dl_machine_h */
+
+/* These are only actually used where RESOLVE_MAP is defined, anyway. */
+#ifdef RESOLVE_MAP
+
+#define reassemble_21(as21) \
+ ( (((as21) & 0x100000) >> 20) \
+ | (((as21) & 0x0ffe00) >> 8) \
+ | (((as21) & 0x000180) << 7) \
+ | (((as21) & 0x00007c) << 14) \
+ | (((as21) & 0x000003) << 12))
+
+#define reassemble_14(as14) \
+ ( (((as14) & 0x1fff) << 1) \
+ | (((as14) & 0x2000) >> 13))
+
+auto void __attribute__((always_inline))
+elf_machine_rela (struct link_map *map,
+ const Elf32_Rela *reloc,
+ const Elf32_Sym *sym,
+ const struct r_found_version *version,
+ void *const reloc_addr_arg,
+ int skip_ifunc)
+{
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ const Elf32_Sym *const refsym = sym;
+ unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
+ struct link_map *sym_map;
+ Elf32_Addr value;
+
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC && !defined SHARED
+ /* This is defined in rtld.c, but nowhere in the static libc.a; make the
+ reference weak so static programs can still link. This declaration
+ cannot be done when compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP)
+ because rtld.c contains the common defn for _dl_rtld_map, which is
+ incompatible with a weak decl in the same file. */
+ weak_extern (GL(dl_rtld_map));
+# endif
+
+ /* RESOLVE_MAP will return a null value for undefined syms, and
+ non-null for all other syms. In particular, relocs with no
+ symbol (symbol index of zero), also called *ABS* relocs, will be
+ resolved to MAP. (The first entry in a symbol table is all
+ zeros, and an all zero Elf32_Sym has a binding of STB_LOCAL.)
+ See RESOLVE_MAP definition in elf/dl-reloc.c */
+# ifdef RTLD_BOOTSTRAP
+ /* RESOLVE_MAP in rtld.c doesn't have the local sym test. */
+ sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL
+ ? RESOLVE_MAP (&sym, version, r_type) : map);
+# else
+ sym_map = RESOLVE_MAP (&sym, version, r_type);
+# endif
+
+ if (sym_map)
+ {
+ value = sym ? sym_map->l_addr + sym->st_value : 0;
+ value += reloc->r_addend;
+ }
+ else
+ value = 0;
+
+ switch (r_type)
+ {
+ case R_PARISC_DIR32:
+ /* .eh_frame can have unaligned relocs. */
+ if ((unsigned long) reloc_addr_arg & 3)
+ {
+ char *rel_addr = (char *) reloc_addr_arg;
+ rel_addr[0] = value >> 24;
+ rel_addr[1] = value >> 16;
+ rel_addr[2] = value >> 8;
+ rel_addr[3] = value;
+ return;
+ }
+ break;
+
+ case R_PARISC_DIR21L:
+ {
+ unsigned int insn = *(unsigned int *)reloc_addr;
+ value = sym_map->l_addr + sym->st_value
+ + ((reloc->r_addend + 0x1000) & -0x2000);
+ value = value >> 11;
+ insn = (insn &~ 0x1fffff) | reassemble_21 (value);
+ *(unsigned int *)reloc_addr = insn;
+ }
+ return;
+
+ case R_PARISC_DIR14R:
+ {
+ unsigned int insn = *(unsigned int *)reloc_addr;
+ value = ((sym_map->l_addr + sym->st_value) & 0x7ff)
+ + (((reloc->r_addend & 0x1fff) ^ 0x1000) - 0x1000);
+ insn = (insn &~ 0x3fff) | reassemble_14 (value);
+ *(unsigned int *)reloc_addr = insn;
+ }
+ return;
+
+ case R_PARISC_PLABEL32:
+ /* Easy rule: If there is a symbol and it is global, then we
+ need to make a dynamic function descriptor. Otherwise we
+ have the address of a PLT slot for a local symbol which we
+ know to be unique. */
+ if (sym == NULL
+ || sym_map == NULL
+ || ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
+ {
+ break;
+ }
+ /* Set bit 30 to indicate to $$dyncall that this is a PLABEL.
+ We have to do this outside of the generic function descriptor
+ code, since it doesn't know about our requirement for setting
+ protection bits */
+ value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 2);
+ break;
+
+ case R_PARISC_PLABEL21L:
+ case R_PARISC_PLABEL14R:
+ {
+ unsigned int insn = *(unsigned int *)reloc_addr;
+
+ if (__builtin_expect (sym == NULL, 0))
+ break;
+
+ value = (Elf32_Addr)((unsigned int)_dl_make_fptr (sym_map, sym, value) | 2);
+
+ if (r_type == R_PARISC_PLABEL21L)
+ {
+ value >>= 11;
+ insn = (insn &~ 0x1fffff) | reassemble_21 (value);
+ }
+ else
+ {
+ value &= 0x7ff;
+ insn = (insn &~ 0x3fff) | reassemble_14 (value);
+ }
+
+ *(unsigned int *)reloc_addr = insn;
+ }
+ return;
+
+ case R_PARISC_IPLT:
+ if (__builtin_expect (sym_map != NULL, 1))
+ {
+ elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr,
+ DL_FIXUP_MAKE_VALUE(sym_map, value));
+ }
+ else
+ {
+ /* If we get here, it's a (weak) undefined sym. */
+ elf_machine_fixup_plt (NULL, map, reloc, reloc_addr,
+ DL_FIXUP_MAKE_VALUE(map, value));
+ }
+ return;
+
+ case R_PARISC_COPY:
+ if (__builtin_expect (sym == NULL, 0))
+ /* This can happen in trace mode if an object could not be
+ found. */
+ break;
+ if (__builtin_expect (sym->st_size > refsym->st_size, 0)
+ || (__builtin_expect (sym->st_size < refsym->st_size, 0)
+ && __builtin_expect (GLRO(dl_verbose), 0)))
+ {
+ const char *strtab;
+
+ strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+ _dl_error_printf ("%s: Symbol `%s' has different size in shared object, "
+ "consider re-linking\n",
+ RTLD_PROGNAME, strtab + refsym->st_name);
+ }
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
+ return;
+
+#if defined USE_TLS && (!defined RTLD_BOOTSTRAP)
+ case R_PARISC_TLS_DTPMOD32:
+ value = sym_map->l_tls_modid;
+ break;
+
+ case R_PARISC_TLS_DTPOFF32:
+ /* During relocation all TLS symbols are defined and used.
+ Therefore the offset is already correct. */
+ if (sym != NULL)
+ *reloc_addr = sym->st_value;
+ return;
+
+ case R_PARISC_TLS_TPREL32:
+ /* The offset is negative, forward from the thread pointer */
+ if (sym != NULL)
+ {
+ CHECK_STATIC_TLS (map, sym_map);
+ value = sym_map->l_tls_offset + sym->st_value + reloc->r_addend;
+ }
+ break;
+#endif /* use TLS */
+
+ case R_PARISC_NONE: /* Alright, Wilbur. */
+ return;
+
+ default:
+ _dl_reloc_bad_type (map, r_type, 0);
+ }
+
+ *reloc_addr = value;
+}
+
+/* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with
+ ELF32_R_SYM (info) == 0 for a similar purpose. */
+auto void __attribute__((always_inline))
+elf_machine_rela_relative (Elf32_Addr l_addr,
+ const Elf32_Rela *reloc,
+ void *const reloc_addr_arg)
+{
+ unsigned long const r_type = ELF32_R_TYPE (reloc->r_info);
+ Elf32_Addr *const reloc_addr = reloc_addr_arg;
+ static char msgbuf[] = { "Unknown" };
+ struct link_map map;
+ Elf32_Addr value;
+
+ value = l_addr + reloc->r_addend;
+
+ if (ELF32_R_SYM (reloc->r_info) != 0){
+ _dl_error_printf ("%s: In elf_machine_rela_relative "
+ "ELF32_R_SYM (reloc->r_info) != 0. Aborting.",
+ RTLD_PROGNAME);
+ ABORT_INSTRUCTION; /* Crash. */
+ }
+
+ switch (r_type)
+ {
+ case R_PARISC_DIR32:
+ /* .eh_frame can have unaligned relocs. */
+ if ((unsigned long) reloc_addr_arg & 3)
+ {
+ char *rel_addr = (char *) reloc_addr_arg;
+ rel_addr[0] = value >> 24;
+ rel_addr[1] = value >> 16;
+ rel_addr[2] = value >> 8;
+ rel_addr[3] = value;
+ return;
+ }
+ break;
+
+ case R_PARISC_PLABEL32:
+ break;
+
+ case R_PARISC_IPLT: /* elf_machine_runtime_setup already set gp */
+ break;
+
+ case R_PARISC_NONE:
+ return;
+
+ default: /* Bad reloc, map unknown (really it's the current map) */
+ map.l_name = msgbuf;
+ _dl_reloc_bad_type (&map, r_type, 0);
+ return;
+ }
+
+ *reloc_addr = value;
+}
+
+auto void __attribute__((always_inline))
+elf_machine_lazy_rel (struct link_map *map,
+ Elf32_Addr l_addr, const Elf32_Rela *reloc,
+ int skip_ifunc)
+{
+ /* We don't have anything to do here. elf_machine_runtime_setup has
+ done all the relocs already. */
+}
+
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/hppa/dl-symaddr.c b/sysdeps/hppa/dl-symaddr.c
new file mode 100644
index 0000000000..7c62c9597c
--- /dev/null
+++ b/sysdeps/hppa/dl-symaddr.c
@@ -0,0 +1,35 @@
+/* Get the symbol address. HPPA version.
+ Copyright (C) 1999-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+#include <dl-machine.h>
+
+void *
+_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
+{
+ /* Find the "ip" from the "map" and symbol "ref" */
+ Elf32_Addr value = (map ? map->l_addr : 0) + ref->st_value;
+
+ /* On hppa, we have to return the pointer to function descriptor.
+ This involves an "| 2" to inform $$dyncall that this is a plabel32 */
+ if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC){
+ return (void *)((unsigned long)_dl_make_fptr (map, ref, value) | 2);
+ }
+ else
+ return (void *) value;
+}
diff --git a/sysdeps/hppa/dl-tls.h b/sysdeps/hppa/dl-tls.h
new file mode 100644
index 0000000000..71b984390b
--- /dev/null
+++ b/sysdeps/hppa/dl-tls.h
@@ -0,0 +1,31 @@
+/* Thread-local storage handling in the ELF dynamic linker. hppa version.
+ Copyright (C) 2003-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+
+/* Type used for the representation of TLS information in the GOT. */
+typedef struct
+{
+ unsigned long int ti_module;
+ unsigned long int ti_offset;
+} tls_index;
+
+
+extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed. */
+#define TLS_DTV_UNALLOCATED ((void *) -1l)
diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S
new file mode 100644
index 0000000000..969e35f421
--- /dev/null
+++ b/sysdeps/hppa/dl-trampoline.S
@@ -0,0 +1,287 @@
+/* PLT trampolines. hppa version.
+ Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* This code gets called via the .plt stub, and is used in
+ dl-runtime.c to call the `_dl_fixup' function and then redirect
+ to the address it returns. `_dl_fixup' takes two arguments, however
+ `_dl_profile_fixup' takes a number of parameters for use with
+ library auditing (LA).
+
+ WARNING: This template is also used by gcc's __cffc, and expects
+ that the "bl" for _dl_runtime_resolve exist at a particular offset.
+ Do not change this template without changing gcc, while the prefix
+ "bl" should fix everything so gcc finds the right spot, it will
+ slow down __cffc when it attempts to call fixup to resolve function
+ descriptor references. Please refer to gcc/gcc/config/pa/fptr.c
+
+ Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp. */
+
+ /* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
+ .text
+ /* THIS CODE DOES NOT EXECUTE */
+ bl _dl_fixup, %r2
+ .text
+ .global _dl_runtime_resolve
+ .type _dl_runtime_resolve,@function
+ cfi_startproc
+ .align 4
+_dl_runtime_resolve:
+ .PROC
+ .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
+ .ENTRY
+ /* SAVE_RP says we do */
+ stw %rp, -20(%sp)
+
+ /* Save static link register */
+ stw %r29,-16(%sp)
+ /* Save argument registers */
+ stw %r26,-36(%sp)
+ stw %r25,-40(%sp)
+ stw %r24,-44(%sp)
+ stw %r23,-48(%sp)
+
+ /* Build a call frame, and save structure pointer. */
+ copy %sp, %r1 /* Copy previous sp */
+ /* Save function result address (on entry) */
+ stwm %r28,128(%sp)
+ /* Fillin some frame info to follow ABI */
+ stw %r1,-4(%sp) /* Previous sp */
+ stw %r21,-32(%sp) /* PIC register value */
+
+ /* Save input floating point registers. This must be done
+ in the new frame since the previous frame doesn't have
+ enough space */
+ ldo -56(%sp),%r1
+ fstd,ma %fr4,-8(%r1)
+ fstd,ma %fr5,-8(%r1)
+ fstd,ma %fr6,-8(%r1)
+ fstd,ma %fr7,-8(%r1)
+
+ /* Set up args to fixup func, needs only two arguments */
+ ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
+ copy %r19,%r25 /* (2) reloc offset */
+
+ /* Call the real address resolver. */
+ bl _dl_fixup,%rp
+ copy %r21,%r19 /* set fixup func ltp */
+
+ /* Load up the returned func descriptor */
+ copy %r28, %r22
+ copy %r29, %r19
+
+ /* Reload arguments fp args */
+ ldo -56(%sp),%r1
+ fldd,ma -8(%r1),%fr4
+ fldd,ma -8(%r1),%fr5
+ fldd,ma -8(%r1),%fr6
+ fldd,ma -8(%r1),%fr7
+
+ /* Adjust sp, and restore function result address*/
+ ldwm -128(%sp),%r28
+
+ /* Reload static link register */
+ ldw -16(%sp),%r29
+ /* Reload general args */
+ ldw -36(%sp),%r26
+ ldw -40(%sp),%r25
+ ldw -44(%sp),%r24
+ ldw -48(%sp),%r23
+
+ /* Jump to new function, but return to previous function */
+ bv %r0(%r22)
+ ldw -20(%sp),%rp
+ .EXIT
+ .PROCEND
+ cfi_endproc
+ .size _dl_runtime_resolve, . - _dl_runtime_resolve
+
+ .text
+ .global _dl_runtime_profile
+ .type _dl_runtime_profile,@function
+ cfi_startproc
+ .align 4
+_dl_runtime_profile:
+ .PROC
+ .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3
+ .ENTRY
+
+ /* SAVE_RP says we do */
+ stw %rp, -20(%sp)
+ /* Save static link register */
+ stw %r29,-16(%sp)
+
+ /* Build a call frame, and save structure pointer. */
+ copy %sp, %r1 /* Copy previous sp */
+ /* Save function result address (on entry) */
+ stwm %r28,192(%sp)
+ /* Fillin some frame info to follow ABI */
+ stw %r1,-4(%sp) /* Previous sp */
+ stw %r21,-32(%sp) /* PIC register value */
+
+ /* Create La_hppa_retval */
+ /* -140, lrv_r28
+ -136, lrv_r29
+ -132, 4 byte pad
+ -128, lr_fr4 (8 bytes) */
+
+ /* Create save space for _dl_profile_fixup arguments
+ -120, Saved reloc offset
+ -116, Saved struct link_map
+ -112, *framesizep */
+
+ /* Create La_hppa_regs */
+ /* 32-bit registers */
+ stw %r26,-108(%sp)
+ stw %r25,-104(%sp)
+ stw %r24,-100(%sp)
+ stw %r23,-96(%sp)
+ /* -92, 4 byte pad */
+ /* 64-bit floating point registers */
+ ldo -88(%sp),%r1
+ fstd,ma %fr4,8(%r1)
+ fstd,ma %fr5,8(%r1)
+ fstd,ma %fr6,8(%r1)
+ fstd,ma %fr7,8(%r1)
+ /* 32-bit stack pointer and return register */
+ stw %sp,-56(%sp)
+ stw %r2,-52(%sp)
+
+
+ /* Set up args to fixup func, needs five arguments */
+ ldw 8+4(%r20),%r26 /* (1) got[1] == struct link_map */
+ stw %r26,-116(%sp) /* Save struct link_map */
+ copy %r19,%r25 /* (2) reloc offset */
+ stw %r25,-120(%sp) /* Save reloc offset */
+ copy %rp,%r24 /* (3) profile_fixup needs rp */
+ ldo -56(%sp),%r23 /* (4) La_hppa_regs */
+ ldo -112(%sp), %r1
+ stw %r1, -52(%sp) /* (5) long int *framesizep */
+
+ /* Call the real address resolver. */
+ bl _dl_profile_fixup,%rp
+ copy %r21,%r19 /* set fixup func ltp */
+
+ /* Load up the returned function descriptor */
+ copy %r28, %r22
+ copy %r29, %r19
+
+ /* Restore gr/fr/sp/rp */
+ ldw -108(%sp),%r26
+ ldw -104(%sp),%r25
+ ldw -100(%sp),%r24
+ ldw -96(%sp),%r23
+ /* -92, 4 byte pad, skip */
+ ldo -88(%sp),%r1
+ fldd,ma 8(%r1),%fr4
+ fldd,ma 8(%r1),%fr5
+ fldd,ma 8(%r1),%fr6
+ fldd,ma 8(%r1),%fr7
+ ldw -52(%sp),%rp
+
+ /* Reload static link register -(192+16) without adjusting stack */
+ ldw -208(%sp),%r29
+
+ /* *framesizep is >= 0 if we have to run pltexit */
+ ldw -112(%sp),%r28
+ cmpb,>>=,N %r0,%r28,L(cpe)
+
+ /* Adjust sp, and restore function result address*/
+ ldwm -192(%sp),%r28
+ /* Jump to new function, but return to previous function */
+ bv %r0(%r22)
+ ldw -20(%sp),%rp
+ /* NO RETURN */
+
+L(nf):
+ /* Call the returned function descriptor */
+ bv %r0(%r22)
+ nop
+ b,n L(cont)
+
+L(cpe):
+ /* We are going to call the resolved function, but we have a
+ stack frame in the middle. We use the value of framesize to
+ guess how much extra frame we need, and how much frame to
+ copy forward. */
+
+ /* Round to nearest multiple of 64 */
+ addi 63, %r28, %r28
+ depi 0, 27, 6, %r28
+
+ /* Calcualte start of stack copy */
+ ldo -192(%sp),%r2
+
+ /* Increate the stack by *framesizep */
+ copy %sp, %r1
+ add %sp, %r28, %sp
+ /* Save stack pointer */
+ stw %r1, -4(%sp)
+
+ /* Single byte copy of prevous stack onto newly allocated stack */
+1: ldb %r28(%r2), %r1
+ add %r28, %sp, %r26
+ stb %r1, 0(%r26)
+ addi,< -1,%r28,%r28
+ b,n 1b
+
+ /* Retore r28 and r27 and r2 already points at -192(%sp) */
+ ldw 0(%r2),%r28
+ ldw 84(%r2),%r26
+
+ /* Calculate address of L(cont) */
+ b,l L(nf),%r2
+ depwi 0,31,2,%r2
+L(cont):
+ /* Undo fake stack */
+ ldw -4(%sp),%r1
+ copy %r1, %sp
+
+ /* Arguments to _dl_call_pltexit */
+ ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */
+ ldw -120(%sp), %r25 /* (2) reloc offsets */
+ ldo -56(%sp), %r24 /* (3) *La_hppa_regs */
+ ldo -124(%sp), %r23 /* (4) *La_hppa_retval */
+
+ /* Fill *La_hppa_retval */
+ stw %r28,-140(%sp)
+ stw %r29,-136(%sp)
+ ldo -128(%sp), %r1
+ fstd %fr4,0(%r1)
+
+ /* Call _dl_call_pltexit */
+ bl _dl_call_pltexit,%rp
+ nop
+
+ /* Restore *La_hppa_retval */
+ ldw -140(%sp), %r28
+ ldw -136(%sp), %r29
+ ldo -128(%sp), %r1
+ fldd 0(%r1), %fr4
+
+ /* Unwind the stack */
+ ldo 192(%sp),%sp
+ /* Retore callers rp */
+ ldw -20(%sp),%rp
+ /* Return */
+ bv,n 0(%r2)
+ .EXIT
+ .PROCEND
+ cfi_endproc
+ .size _dl_runtime_profile, . - _dl_runtime_profile
diff --git a/sysdeps/hppa/entry.h b/sysdeps/hppa/entry.h
new file mode 100644
index 0000000000..b024db2be7
--- /dev/null
+++ b/sysdeps/hppa/entry.h
@@ -0,0 +1,10 @@
+#ifndef __ASSEMBLY__
+extern void _start (void);
+#endif
+
+/* The function's entry point is stored in the first word of the
+ function descriptor (plabel) of _start(). */
+#define ENTRY_POINT __canonicalize_funcptr_for_compare(_start)
+
+/* We have to provide a special declaration. */
+#define ENTRY_POINT_DECL(class) class void _start (void);
diff --git a/sysdeps/hppa/fpu/bits/fenv.h b/sysdeps/hppa/fpu/bits/fenv.h
new file mode 100644
index 0000000000..b675ea4c15
--- /dev/null
+++ b/sysdeps/hppa/fpu/bits/fenv.h
@@ -0,0 +1,91 @@
+/* Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FENV_H
+# error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
+#endif
+
+/* Define bits representing the exception. We use the values of the
+ appropriate enable bits in the FPU status word (which,
+ coincidentally, are the same as the flag bits, but shifted right by
+ 27 bits). */
+enum
+{
+ FE_INVALID =
+#define FE_INVALID (1<<4) /* V */
+ FE_INVALID,
+ FE_DIVBYZERO =
+#define FE_DIVBYZERO (1<<3) /* Z */
+ FE_DIVBYZERO,
+ FE_OVERFLOW =
+#define FE_OVERFLOW (1<<2) /* O */
+ FE_OVERFLOW,
+ FE_UNDERFLOW =
+#define FE_UNDERFLOW (1<<1) /* U */
+ FE_UNDERFLOW,
+ FE_INEXACT =
+#define FE_INEXACT (1<<0) /* I */
+ FE_INEXACT,
+};
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* The PA-RISC FPU supports all of the four defined rounding modes.
+ We use the values of the RM field in the floating point status
+ register for the appropriate macros. */
+enum
+ {
+ FE_TONEAREST =
+#define FE_TONEAREST (0 << 9)
+ FE_TONEAREST,
+ FE_TOWARDZERO =
+#define FE_TOWARDZERO (1 << 9)
+ FE_TOWARDZERO,
+ FE_UPWARD =
+#define FE_UPWARD (2 << 9)
+ FE_UPWARD,
+ FE_DOWNWARD =
+#define FE_DOWNWARD (3 << 9)
+ FE_DOWNWARD,
+ };
+
+/* Type representing exception flags. */
+typedef unsigned int fexcept_t;
+
+/* Type representing floating-point environment. This structure
+ corresponds to the layout of the status and exception words in the
+ register file. The exception registers are never saved/stored by
+ userspace. This structure is also not correctly aligned ever, in
+ an ABI error we left out __aligned(8) and subsequently all of our
+ fenv functions must accept unaligned input, align the input, and
+ then use assembly to store fr0. This is a performance hit, but
+ means the ABI is stable. */
+typedef struct
+{
+ unsigned int __status_word;
+ unsigned int __exception[7];
+} fenv_t;
+
+/* If the default argument is used we use this value. */
+#define FE_DFL_ENV ((const fenv_t *) -1)
+
+#ifdef __USE_GNU
+/* Floating-point environment where none of the exceptions are masked. */
+# define FE_NOMASK_ENV ((const fenv_t *) -2)
+#endif
diff --git a/sysdeps/hppa/fpu/bits/mathdef.h b/sysdeps/hppa/fpu/bits/mathdef.h
new file mode 100644
index 0000000000..d9f0c3a32b
--- /dev/null
+++ b/sysdeps/hppa/fpu/bits/mathdef.h
@@ -0,0 +1,38 @@
+/* Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#if !defined _MATH_H && !defined _COMPLEX_H
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+#endif
+
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
+/* GCC does not promote `float' values to `double'. */
+typedef float float_t; /* `float' expressions are evaluated as
+ `float'. */
+typedef double double_t; /* `double' expressions are evaluated as
+ `double'. */
+
+/* The values returned by `ilogb' for 0 and NaN respectively. */
+# define FP_ILOGB0 (-2147483647)
+# define FP_ILOGBNAN (2147483647)
+
+#endif /* ISO C99 */
+
+/* On hppa `long double' is 64-bits. */
+#undef __NO_LONG_DOUBLE_MATH
diff --git a/sysdeps/hppa/fpu/fclrexcpt.c b/sysdeps/hppa/fpu/fclrexcpt.c
new file mode 100644
index 0000000000..ee097b4522
--- /dev/null
+++ b/sysdeps/hppa/fpu/fclrexcpt.c
@@ -0,0 +1,36 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+feclearexcept (int excepts)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
+ /* Clear all the relevant bits. */
+ s.sw[0] &= ~((excepts & FE_ALL_EXCEPT) << 27);
+ __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feclearexcept)
diff --git a/sysdeps/hppa/fpu/fedisblxcpt.c b/sysdeps/hppa/fpu/fedisblxcpt.c
new file mode 100644
index 0000000000..892c78c987
--- /dev/null
+++ b/sysdeps/hppa/fpu/fedisblxcpt.c
@@ -0,0 +1,37 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+fedisableexcept (int excepts)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+ unsigned int old_exc;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
+
+ old_exc = s.sw[0] & FE_ALL_EXCEPT;
+
+ s.sw[0] &= ~(excepts & FE_ALL_EXCEPT);
+ __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+
+ return old_exc;
+}
diff --git a/sysdeps/hppa/fpu/feenablxcpt.c b/sysdeps/hppa/fpu/feenablxcpt.c
new file mode 100644
index 0000000000..b0f1d9235b
--- /dev/null
+++ b/sysdeps/hppa/fpu/feenablxcpt.c
@@ -0,0 +1,37 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+feenableexcept (int excepts)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+ unsigned int old_exc;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
+
+ old_exc = s.sw[0] & FE_ALL_EXCEPT;
+
+ s.sw[0] |= (excepts & FE_ALL_EXCEPT);
+ __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+
+ return old_exc;
+}
diff --git a/sysdeps/hppa/fpu/fegetenv.c b/sysdeps/hppa/fpu/fegetenv.c
new file mode 100644
index 0000000000..7028fe4a22
--- /dev/null
+++ b/sysdeps/hppa/fpu/fegetenv.c
@@ -0,0 +1,35 @@
+/* Store current floating-point environment.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <string.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+ unsigned long long buf[4], *bufptr = buf;
+
+ __asm__ (
+ "fstd,ma %%fr0,8(%1) \n\t"
+ "fldd -8(%1),%%fr0 \n\t"
+ : "=m" (buf), "+r" (bufptr) : : "%r0");
+ memcpy(envp, buf, sizeof (*envp));
+ return 0;
+}
+libm_hidden_def (fegetenv)
diff --git a/sysdeps/hppa/fpu/fegetexcept.c b/sysdeps/hppa/fpu/fegetexcept.c
new file mode 100644
index 0000000000..0744eea1a0
--- /dev/null
+++ b/sysdeps/hppa/fpu/fegetexcept.c
@@ -0,0 +1,33 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+ union { unsigned long long l; unsigned int sw[2] } s;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1) \n\t"
+ "fldd 0(%1),%%fr0 \n\t"
+ : "=m" (s.l) : "r" (&s.l) : "%r0");
+
+ return (s.sw[0] & FE_ALL_EXCEPT);
+}
diff --git a/sysdeps/hppa/fpu/fegetround.c b/sysdeps/hppa/fpu/fegetround.c
new file mode 100644
index 0000000000..85ae2f42fd
--- /dev/null
+++ b/sysdeps/hppa/fpu/fegetround.c
@@ -0,0 +1,27 @@
+/* Return current rounding direction.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <get-rounding-mode.h>
+
+int
+fegetround (void)
+{
+ return get_rounding_mode ();
+}
+libm_hidden_def (fegetround)
diff --git a/sysdeps/hppa/fpu/feholdexcpt.c b/sysdeps/hppa/fpu/feholdexcpt.c
new file mode 100644
index 0000000000..9995ea0802
--- /dev/null
+++ b/sysdeps/hppa/fpu/feholdexcpt.c
@@ -0,0 +1,53 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <string.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ union { unsigned long long buf[4]; fenv_t env; } clear;
+ unsigned long long *bufptr;
+
+ /* Store the environment. */
+ bufptr = clear.buf;
+ __asm__ (
+ "fstd,ma %%fr0,8(%1)\n"
+ : "=m" (clear), "+r" (bufptr) : : "%r0");
+ memcpy (envp, &clear.env, sizeof (fenv_t));
+
+ /* Clear exception queues */
+ memset (clear.env.__exception, 0, sizeof (clear.env.__exception));
+ /* And set all exceptions to non-stop. */
+ clear.env.__status_word &= ~FE_ALL_EXCEPT;
+ /* Now clear all flags */
+ clear.env.__status_word &= ~(FE_ALL_EXCEPT << 27);
+
+ /* Load the new environment. Note: fr0 must load last to enable T-bit
+ Thus we start bufptr at the end and work backwards */
+ bufptr = (unsigned long long *)((unsigned int)(clear.buf) + sizeof(unsigned int)*4);
+ __asm__ (
+ "fldd,mb -8(%0),%%fr0\n"
+ : : "r" (bufptr), "m" (clear) : "%r0");
+
+ return 0;
+}
+
+libm_hidden_def (feholdexcept)
diff --git a/sysdeps/hppa/fpu/fesetenv.c b/sysdeps/hppa/fpu/fesetenv.c
new file mode 100644
index 0000000000..c967bd505c
--- /dev/null
+++ b/sysdeps/hppa/fpu/fesetenv.c
@@ -0,0 +1,63 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+ Based on the m68k version by
+ Andreas Schwab <schwab@suse.de>
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+fesetenv (const fenv_t *envp)
+{
+ union { unsigned long long buf[4]; fenv_t env; } temp;
+ unsigned long long *bufptr;
+
+ /* Install the environment specified by ENVP. But there are a few
+ values which we do not want to come from the saved environment.
+ Therefore, we get the current environment and replace the values
+ we want to use from the environment specified by the parameter. */
+ bufptr = temp.buf;
+ __asm__ (
+ "fstd,ma %%fr0,8(%1)\n"
+ : "=m" (temp) : "r" (bufptr) : "%r0");
+
+ temp.env.__status_word &= ~(FE_ALL_EXCEPT
+ | (FE_ALL_EXCEPT << 27)
+ | FE_DOWNWARD);
+ if (envp == FE_DFL_ENV)
+ temp.env.__status_word = 0;
+ else if (envp == FE_NOMASK_ENV)
+ temp.env.__status_word |= FE_ALL_EXCEPT;
+ else
+ temp.env.__status_word |= (envp->__status_word
+ & (FE_ALL_EXCEPT
+ | FE_DOWNWARD
+ | (FE_ALL_EXCEPT << 27)));
+
+ /* Load the new environment. We use bufptr again since the
+ initial asm has modified the value of the register and here
+ we take advantage of that to load in reverse order so fr0
+ is loaded last and T-Bit is enabled. */
+ __asm__ (
+ "fldd,mb -8(%1),%%fr0\n"
+ : : "m" (temp), "r" (bufptr) : "%r0" );
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (fesetenv)
diff --git a/sysdeps/hppa/fpu/fesetround.c b/sysdeps/hppa/fpu/fesetround.c
new file mode 100644
index 0000000000..15becdb24b
--- /dev/null
+++ b/sysdeps/hppa/fpu/fesetround.c
@@ -0,0 +1,40 @@
+/* Set current rounding direction.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+fesetround (int round)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+
+ if (round & ~FE_DOWNWARD)
+ /* round is not a valid rounding mode. */
+ return 1;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
+ s.sw[0] &= ~FE_DOWNWARD;
+ s.sw[0] |= round & FE_DOWNWARD;
+ __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+
+ return 0;
+}
+
+libm_hidden_def (fesetround)
diff --git a/sysdeps/hppa/fpu/feupdateenv.c b/sysdeps/hppa/fpu/feupdateenv.c
new file mode 100644
index 0000000000..07757aebd3
--- /dev/null
+++ b/sysdeps/hppa/fpu/feupdateenv.c
@@ -0,0 +1,40 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <string.h>
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+ fenv_t temp;
+ /* Get the current exception status */
+ __asm__ ("fstd %%fr0,0(%1) \n\t"
+ "fldd 0(%1),%%fr0 \n\t"
+ : "=m" (s.l) : "r" (&s.l));
+ memcpy(&temp, envp, sizeof(fenv_t));
+ /* Currently raised exceptions not cleared */
+ temp.__status_word |= s.sw[0] & (FE_ALL_EXCEPT << 27);
+ /* Install new environment. */
+ fesetenv (&temp);
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feupdateenv)
diff --git a/sysdeps/hppa/fpu/fgetexcptflg.c b/sysdeps/hppa/fpu/fgetexcptflg.c
new file mode 100644
index 0000000000..616b717e66
--- /dev/null
+++ b/sysdeps/hppa/fpu/fgetexcptflg.c
@@ -0,0 +1,36 @@
+/* Store current representation for exceptions.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1) \n\t"
+ "fldd 0(%1),%%fr0 \n\t"
+ : "=m" (s.l) : "r" (&s.l) : "%r0");
+
+ *flagp = (s.sw[0] >> 27) & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
diff --git a/sysdeps/hppa/fpu/fpu_control.h b/sysdeps/hppa/fpu/fpu_control.h
new file mode 100644
index 0000000000..8f855207df
--- /dev/null
+++ b/sysdeps/hppa/fpu/fpu_control.h
@@ -0,0 +1,66 @@
+/* FPU control word definitions. HP-PARISC version.
+ Copyright (C) 2012-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FPU_CONTROL_H
+#define _FPU_CONTROL_H
+
+/* Masking of interrupts */
+#define _FPU_MASK_PM 0x00000001 /* Inexact (I) */
+#define _FPU_MASK_UM 0x00000002 /* Underflow (U) */
+#define _FPU_MASK_OM 0x00000004 /* Overflow (O) */
+#define _FPU_MASK_ZM 0x00000008 /* Divide by zero (Z) */
+#define _FPU_MASK_IM 0x00000010 /* Invalid operation (V) */
+
+/* Masking of rounding modes. */
+#define _FPU_HPPA_MASK_RM 0x00000600 /* Rounding mode mask */
+/* Masking of interrupt enable bits. */
+#define _FPU_HPPA_MASK_INT 0x0000001f /* Interrupt mask */
+
+/* There are no reserved bits in the PA fpsr (though some are undefined). */
+#define _FPU_RESERVED 0x00000000
+/* Default is: No traps enabled, no flags set, round to nearest. */
+#define _FPU_DEFAULT 0x00000000
+/* Default + exceptions (FE_ALL_EXCEPT) enabled. */
+#define _FPU_IEEE (_FPU_DEFAULT | _FPU_HPPA_MASK_INT)
+
+/* Type of the control word. */
+typedef unsigned int fpu_control_t;
+
+/* Macros for accessing the hardware control word. */
+#define _FPU_GETCW(cw) \
+({ \
+ union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp; \
+ /* Get the current status word. */ \
+ __asm__ ("fstd %%fr0,0(%1)\n\t" \
+ "fldd 0(%1),%%fr0\n\t" \
+ : "=m" (__fullfp.__fpreg) : "r" (&__fullfp.__fpreg) : "%r0"); \
+ cw = __fullfp.__halfreg[0]; \
+})
+
+#define _FPU_SETCW(cw) \
+({ \
+ union { __extension__ unsigned long long __fpreg; unsigned int __halfreg[2]; } __fullfp; \
+ __fullfp.__halfreg[0] = cw; \
+ __asm__ ("fldd 0(%1),%%fr0\n\t" \
+ : : "m" (__fullfp.__fpreg), "r" (&__fullfp.__fpreg) : "%r0" ); \
+})
+
+/* Default control word set at startup. */
+extern fpu_control_t __fpu_control;
+
+#endif /* _FPU_CONTROL_H */
diff --git a/sysdeps/hppa/fpu/fraiseexcpt.c b/sysdeps/hppa/fpu/fraiseexcpt.c
new file mode 100644
index 0000000000..74e93508f3
--- /dev/null
+++ b/sysdeps/hppa/fpu/fraiseexcpt.c
@@ -0,0 +1,101 @@
+/* Raise given exceptions.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+
+/* Please see section 10,
+ page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
+
+int
+feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXCEPTS. But we must raise only one
+ signal at a time. It is important that if the overflow/underflow
+ exception and the divide by zero exception are given at the same
+ time, the overflow/underflow exception follows the divide by zero
+ exception. */
+
+ /* We do these bits in assembly to be certain GCC doesn't optimize
+ away something important, and so we can force delayed traps to
+ occur. */
+
+ /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
+
+ /* First: Invalid exception. */
+ if (excepts & FE_INVALID)
+ {
+ /* One example of an invalid operation is 0 * Infinity. */
+ double d = HUGE_VAL;
+ __asm__ __volatile__ (
+ " fcpy,dbl %%fr0,%%fr22\n"
+ " fmpy,dbl %0,%%fr22,%0\n"
+ " fldd 0(%%sr0,%%sp),%0"
+ : "+f" (d) : : "%fr22" );
+ }
+
+ /* Second: Division by zero. */
+ if (excepts & FE_DIVBYZERO)
+ {
+ double d = 1.0;
+ __asm__ __volatile__ (
+ " fcpy,dbl %%fr0,%%fr22\n"
+ " fdiv,dbl %0,%%fr22,%0\n"
+ " fldd 0(%%sr0,%%sp),%0"
+ : "+f" (d) : : "%fr22" );
+ }
+
+ /* Third: Overflow. */
+ if (excepts & FE_OVERFLOW)
+ {
+ double d = DBL_MAX;
+ __asm__ __volatile__ (
+ " fadd,dbl %0,%0,%0\n"
+ " fldd 0(%%sr0,%%sp),%0"
+ : "+f" (d) );
+ }
+
+ /* Fourth: Underflow. */
+ if (excepts & FE_UNDERFLOW)
+ {
+ double d = DBL_MIN;
+ double e = 3.0;
+ __asm__ __volatile__ (
+ " fdiv,dbl %0,%1,%0\n"
+ " fldd 0(%%sr0,%%sp),%0"
+ : "+f" (d) : "f" (e) );
+ }
+
+ /* Fifth: Inexact */
+ if (excepts & FE_INEXACT)
+ {
+ double d = M_PI;
+ double e = 69.69;
+ __asm__ __volatile__ (
+ " fdiv,dbl %0,%1,%%fr22\n"
+ " fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
+ " fldd 0(%%sr0,%%sp),%%fr22"
+ : : "f" (d), "f" (e) : "%fr22" );
+ }
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def (feraiseexcept)
diff --git a/sysdeps/hppa/fpu/fsetexcptflg.c b/sysdeps/hppa/fpu/fsetexcptflg.c
new file mode 100644
index 0000000000..246b66f8a3
--- /dev/null
+++ b/sysdeps/hppa/fpu/fsetexcptflg.c
@@ -0,0 +1,37 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+#include <math.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ union { unsigned long long l; unsigned int sw[2]; } s;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1)" : "=m" (s.l) : "r" (&s.l) : "%r0");
+ /* Install new raised trap bits */
+ s.sw[0] |= (*flagp & excepts & FE_ALL_EXCEPT) << 27;
+ /* Store the new status word. */
+ __asm__ ("fldd 0(%0),%%fr0" : : "r" (&s.l), "m" (s.l) : "%r0");
+
+ /* Success. */
+ return 0;
+}
diff --git a/sysdeps/hppa/fpu/ftestexcept.c b/sysdeps/hppa/fpu/ftestexcept.c
new file mode 100644
index 0000000000..54c0e28483
--- /dev/null
+++ b/sysdeps/hppa/fpu/ftestexcept.c
@@ -0,0 +1,34 @@
+/* Test exception in current environment.
+ Copyright (C) 2000-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fenv.h>
+
+int
+fetestexcept (int excepts)
+{
+ union { unsigned long long l; unsigned int sw[2] } s;
+
+ /* Get the current status word. */
+ __asm__ ("fstd %%fr0,0(%1) \n\t"
+ "fldd 0(%1),%%fr0 \n\t"
+ : "=m" (s.l) : "r" (&s.l));
+
+ return (s.sw[0] >> 27) & excepts & FE_ALL_EXCEPT;
+}
+libm_hidden_def (fetestexcept)
diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps
new file mode 100644
index 0000000000..162edde0f6
--- /dev/null
+++ b/sysdeps/hppa/fpu/libm-test-ulps
@@ -0,0 +1,717 @@
+# Begin of automatic generation
+
+# Maximal error of functions:
+Function: "acos_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "acos_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "acos_upward":
+double: 1
+idouble: 1
+
+Function: "acosh":
+double: 1
+idouble: 1
+
+Function: "asin_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "asin_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "asin_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "asinh":
+double: 1
+float: 1
+ifloat: 1
+
+Function: "atan2":
+float: 1
+ifloat: 1
+
+Function: "atanh":
+float: 1
+ifloat: 1
+
+Function: Real part of "cacos":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Imaginary part of "cacos":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Real part of "cacosh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Imaginary part of "cacosh":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Real part of "casin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "casin":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Real part of "casinh":
+double: 5
+float: 2
+idouble: 5
+ifloat: 2
+ildouble: 5
+ldouble: 5
+
+Function: Imaginary part of "casinh":
+double: 3
+float: 1
+idouble: 3
+ifloat: 1
+ildouble: 3
+ldouble: 3
+
+Function: Real part of "catan":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "catan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "catanh":
+double: 4
+float: 1
+idouble: 4
+ifloat: 1
+ildouble: 4
+ldouble: 4
+
+Function: Imaginary part of "catanh":
+float: 1
+ifloat: 1
+
+Function: "cbrt":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ccosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "cexp":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Imaginary part of "cexp":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Real part of "clog":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "clog":
+float: 1
+ifloat: 1
+
+Function: Real part of "clog10":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Imaginary part of "clog10":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "cos":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "cos_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "cos_tonearest":
+float: 1
+ifloat: 1
+
+Function: "cos_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "cos_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "cosh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "cosh_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "cosh_tonearest":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "cosh_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "cosh_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: Real part of "cpow":
+double: 2
+float: 4
+idouble: 2
+ifloat: 4
+ildouble: 2
+ldouble: 2
+
+Function: Imaginary part of "cpow":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: Real part of "csin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "csinh":
+float: 1
+ifloat: 1
+
+Function: Imaginary part of "csinh":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "csqrt":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "csqrt":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Real part of "ctan":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ctan":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Real part of "ctan_downward":
+double: 6
+float: 5
+idouble: 6
+ifloat: 5
+
+Function: Imaginary part of "ctan_downward":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "ctan_tonearest":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: Imaginary part of "ctan_tonearest":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Real part of "ctan_towardzero":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+
+Function: Imaginary part of "ctan_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Real part of "ctan_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+
+Function: Imaginary part of "ctan_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+
+Function: Real part of "ctanh":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: Imaginary part of "ctanh":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Real part of "ctanh_downward":
+double: 4
+float: 1
+idouble: 4
+ifloat: 1
+
+Function: Imaginary part of "ctanh_downward":
+double: 6
+float: 5
+idouble: 6
+ifloat: 5
+
+Function: Real part of "ctanh_tonearest":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+
+Function: Imaginary part of "ctanh_tonearest":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Real part of "ctanh_towardzero":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+
+Function: Imaginary part of "ctanh_towardzero":
+double: 5
+float: 3
+idouble: 5
+ifloat: 3
+
+Function: Real part of "ctanh_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+
+Function: Imaginary part of "ctanh_upward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+
+Function: "erf":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "erfc":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "exp10":
+double: 6
+float: 2
+idouble: 6
+ifloat: 2
+ildouble: 6
+ldouble: 6
+
+Function: "exp10_downward":
+double: 1
+idouble: 1
+
+Function: "exp10_tonearest":
+double: 1
+idouble: 1
+
+Function: "exp10_towardzero":
+double: 1
+idouble: 1
+
+Function: "exp10_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "exp_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "exp_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "exp_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "expm1":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "expm1_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "expm1_tonearest":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "expm1_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "expm1_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "gamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "hypot":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "j0":
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 2
+ldouble: 2
+
+Function: "j1":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "jn":
+double: 4
+float: 5
+idouble: 4
+ifloat: 5
+ildouble: 4
+ldouble: 4
+
+Function: "lgamma":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log":
+float: 1
+ifloat: 1
+
+Function: "log10":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
+
+Function: "log1p":
+float: 1
+ifloat: 1
+
+Function: "pow":
+float: 1
+ifloat: 1
+
+Function: "pow10":
+double: 1
+idouble: 1
+
+Function: "pow_downward":
+float: 1
+ifloat: 1
+
+Function: "pow_tonearest":
+float: 1
+ifloat: 1
+
+Function: "pow_towardzero":
+float: 1
+ifloat: 1
+
+Function: "pow_upward":
+float: 1
+ifloat: 1
+
+Function: "sin":
+float: 1
+ifloat: 1
+
+Function: "sin_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "sin_tonearest":
+float: 1
+ifloat: 1
+
+Function: "sin_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "sin_upward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "sincos":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+Function: "sinh_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "sinh_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "sinh_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tan":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+
+Function: "tan_downward":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+
+Function: "tan_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tan_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
+Function: "tgamma":
+double: 4
+float: 3
+idouble: 4
+ifloat: 3
+ildouble: 1
+ldouble: 1
+
+Function: "y0":
+double: 2
+float: 1
+idouble: 2
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "y1":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+Function: "yn":
+double: 3
+float: 2
+idouble: 3
+ifloat: 2
+ildouble: 3
+ldouble: 3
+
+# end of automatic generation
diff --git a/sysdeps/hppa/frame.h b/sysdeps/hppa/frame.h
new file mode 100644
index 0000000000..c079fb0aff
--- /dev/null
+++ b/sysdeps/hppa/frame.h
@@ -0,0 +1,27 @@
+/* Definition of stack frame structure. HPPA version.
+ Copyright (C) 2000-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* PA stacks grow upwards. */
+#define INNER_THAN >
+
+/* FIXME: will verify this later */
+struct layout
+{
+ void *next;
+ void *return_address;
+};
diff --git a/sysdeps/hppa/gccframe.h b/sysdeps/hppa/gccframe.h
new file mode 100644
index 0000000000..b633eaf302
--- /dev/null
+++ b/sysdeps/hppa/gccframe.h
@@ -0,0 +1,22 @@
+/* Definition of object in frame unwind info. hppa version.
+ Copyright (C) 2001-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Note: For hppa64 this is 61 */
+#define DWARF_FRAME_REGISTERS 89
+
+#include <sysdeps/generic/gccframe.h>
diff --git a/sysdeps/hppa/get-rounding-mode.h b/sysdeps/hppa/get-rounding-mode.h
new file mode 100644
index 0000000000..ffcd35b3f1
--- /dev/null
+++ b/sysdeps/hppa/get-rounding-mode.h
@@ -0,0 +1,35 @@
+/* Determine floating-point rounding mode within libc. HP-PARISC version.
+ Copyright (C) 2012-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _HPPA_GET_ROUNDING_MODE_H
+#define _HPPA_GET_ROUNDING_MODE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+/* Return the floating-point rounding mode. */
+
+static inline int
+get_rounding_mode (void)
+{
+ fpu_control_t fc;
+ _FPU_GETCW (fc);
+ return fc & _FPU_HPPA_MASK_RM;
+}
+
+#endif /* get-rounding-mode.h */
diff --git a/sysdeps/hppa/hppa1.1/Implies b/sysdeps/hppa/hppa1.1/Implies
new file mode 100644
index 0000000000..780c4e2467
--- /dev/null
+++ b/sysdeps/hppa/hppa1.1/Implies
@@ -0,0 +1,3 @@
+wordsize-32
+ieee754/flt-32
+ieee754/dbl-64
diff --git a/sysdeps/hppa/hppa1.1/addmul_1.S b/sysdeps/hppa/hppa1.1/addmul_1.S
new file mode 100644
index 0000000000..666b8ca3c1
--- /dev/null
+++ b/sysdeps/hppa/hppa1.1/addmul_1.S
@@ -0,0 +1,103 @@
+;! HP-PA-1.1 __mpn_addmul_1 -- Multiply a limb vector with a limb and
+;! add the result to a second limb vector.
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr r26
+;! s1_ptr r25
+;! size r24
+;! s2_limb r23
+
+;! This runs at 11 cycles/limb on a PA7000. With the used instructions, it
+;! can not become faster due to data cache contention after a store. On the
+;! PA7100 it runs at 10 cycles/limb, and that can not be improved either,
+;! since only the xmpyu does not need the integer pipeline, so the only
+;! dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb
+;! on the PA7100.
+
+;! There are some ideas described in mul_1.s that applies to this code too.
+
+ .text
+ .export __mpn_addmul_1
+__mpn_addmul_1:
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ;! move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ;! ... into fr4
+ add %r0,%r0,%r0 ;! clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r20 ;! least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+;! Main loop
+L$loop:
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ add %r29,%r20,%r20
+ stws,ma %r20,4(%r26)
+ addc %r28,%r1,%r20
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+L$end:
+ ldw 0(%r26),%r29
+ add %r29,%r20,%r20
+ stws,ma %r20,4(%r26)
+ addc %r28,%r1,%r20
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ add %r29,%r20,%r20
+ stws,ma %r20,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+L$just_one_limb:
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ add %r29,%r1,%r20
+ stw %r20,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/hppa1.1/mul_1.S b/sysdeps/hppa/hppa1.1/mul_1.S
new file mode 100644
index 0000000000..dc1f7e2adb
--- /dev/null
+++ b/sysdeps/hppa/hppa1.1/mul_1.S
@@ -0,0 +1,99 @@
+;! HP-PA-1.1 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+;! the result in a second limb vector.
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr r26
+;! s1_ptr r25
+;! size r24
+;! s2_limb r23
+
+;! This runs at 9 cycles/limb on a PA7000. With the used instructions, it can
+;! not become faster due to data cache contention after a store. On the
+;! PA7100 it runs at 7 cycles/limb, and that can not be improved either, since
+;! only the xmpyu does not need the integer pipeline, so the only dual-issue
+;! we will get are addc+xmpyu. Unrolling would not help either CPU.
+
+;! We could use fldds to read two limbs at a time from the S1 array, and that
+;! could bring down the times to 8.5 and 6.5 cycles/limb for the PA7000 and
+;! PA7100, respectively. We don't do that since it does not seem worth the
+;! (alignment) troubles...
+
+;! At least the PA7100 is rumored to be able to deal with cache-misses
+;! without stalling instruction issue. If this is true, and the cache is
+;! actually also lockup-free, we should use a deeper software pipeline, and
+;! load from S1 very early; (The loads and stores to -12(sp) will surely be
+;! in the cache.)
+
+ .text
+ .export __mpn_mul_1
+__mpn_mul_1:
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ;! move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ;! ... into fr4
+ add %r0,%r0,%r0 ;! clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r20 ;! least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+;! Main loop
+L$loop:
+ fldws,ma 4(%r25),%fr5
+ stws,ma %r20,4(%r26)
+ addc %r28,%r1,%r20
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+L$end:
+ stws,ma %r20,4(%r26)
+ addc %r28,%r1,%r20
+ ldw -16(%r30),%r28
+ stws,ma %r20,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+L$just_one_limb:
+ xmpyu %fr4,%fr5,%fr6
+ fstds %fr6,-16(%r30)
+ ldw -16(%r30),%r28
+ ldo -64(%r30),%r30
+ bv 0(%r2)
+ fstws %fr6R,0(%r26)
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/hppa1.1/s_signbit.c b/sysdeps/hppa/hppa1.1/s_signbit.c
new file mode 100644
index 0000000000..12278ea869
--- /dev/null
+++ b/sysdeps/hppa/hppa1.1/s_signbit.c
@@ -0,0 +1,34 @@
+/* Return nonzero value if number is negative.
+ Copyright (C) 1997-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <math.h>
+
+#include <math_private.h>
+
+int
+__signbit (double x)
+{
+ int32_t hx;
+
+ GET_HIGH_WORD (hx, x);
+ return hx & 0x80000000;
+}
+#ifdef NO_LONG_DOUBLE
+strong_alias (__signbit, __signbitl)
+#endif
diff --git a/sysdeps/hppa/hppa1.1/submul_1.S b/sysdeps/hppa/hppa1.1/submul_1.S
new file mode 100644
index 0000000000..3b843e7701
--- /dev/null
+++ b/sysdeps/hppa/hppa1.1/submul_1.S
@@ -0,0 +1,112 @@
+;! HP-PA-1.1 __mpn_submul_1 -- Multiply a limb vector with a limb and
+;! subtract the result from a second limb vector.
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr r26
+;! s1_ptr r25
+;! size r24
+;! s2_limb r23
+
+;! This runs at 12 cycles/limb on a PA7000. With the used instructions, it
+;! can not become faster due to data cache contention after a store. On the
+;! PA7100 it runs at 11 cycles/limb, and that can not be improved either,
+;! since only the xmpyu does not need the integer pipeline, so the only
+;! dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb
+;! on the PA7100.
+
+;! There are some ideas described in mul_1.s that applies to this code too.
+
+;! It seems possible to make this run as fast as __mpn_addmul_1, if we use
+;! sub,>>= %r29,%r20,%r22
+;! addi 1,%r28,%r28
+;! but that requires reworking the hairy software pipeline...
+
+ .text
+ .export __mpn_submul_1
+__mpn_submul_1:
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ;! move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ;! ... into fr4
+ add %r0,%r0,%r0 ;! clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r20 ;! least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+;! Main loop
+L$loop:
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ sub %r29,%r20,%r22
+ add %r22,%r20,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r20
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+L$end:
+ ldw 0(%r26),%r29
+ sub %r29,%r20,%r22
+ add %r22,%r20,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r20
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ sub %r29,%r20,%r22
+ add %r22,%r20,%r0
+ stws,ma %r22,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+L$just_one_limb:
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ sub %r29,%r1,%r22
+ add %r22,%r1,%r0
+ stw %r22,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/hppa1.1/udiv_qrnnd.S b/sysdeps/hppa/hppa1.1/udiv_qrnnd.S
new file mode 100644
index 0000000000..6008a62945
--- /dev/null
+++ b/sysdeps/hppa/hppa1.1/udiv_qrnnd.S
@@ -0,0 +1,77 @@
+;! HP-PA __udiv_qrnnd division support, used from longlong.h.
+;! This version runs fast on PA 7000 and later.
+
+;! Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! rem_ptr gr26
+;! n1 gr25
+;! n0 gr24
+;! d gr23
+
+ .text
+L$0000:
+ .word 0x43f00000
+ .word 0x0
+ .export __udiv_qrnnd
+__udiv_qrnnd:
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+ ldo 64(%r30),%r30
+
+ stws %r25,-16(%r30) ;! n_hi
+ stws %r24,-12(%r30) ;! n_lo
+ b,l L$0,%r1
+ ldo L$0000-L$0(%r1),%r1
+L$0:
+ fldds -16(%r30),%fr5
+ stws %r23,-12(%r30)
+ comib,<= 0,%r25,L$1
+ fcnvxf,dbl,dbl %fr5,%fr5
+ fldds 0(%r1),%fr4
+ fadd,dbl %fr4,%fr5,%fr5
+L$1:
+ fcpy,sgl %fr0,%fr6L
+ fldws -12(%r30),%fr6R
+ fcnvxf,dbl,dbl %fr6,%fr4
+
+ fdiv,dbl %fr5,%fr4,%fr5
+
+ fcnvfx,dbl,dbl %fr5,%fr4
+ fstws %fr4R,-16(%r30)
+ xmpyu %fr4R,%fr6R,%fr6
+ ldws -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ ldws -12(%r30),%r21
+ ldws -16(%r30),%r20
+ sub %r24,%r21,%r22
+ subb %r25,%r20,%r1
+ comib,= 0,%r1,L$2
+ ldo -64(%r30),%r30
+
+ add %r22,%r23,%r22
+ ldo -1(%r28),%r28
+L$2:
+ bv 0(%r2)
+ stws %r22,0(%r26)
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/jmpbuf-offsets.h b/sysdeps/hppa/jmpbuf-offsets.h
new file mode 100644
index 0000000000..bed0e0636d
--- /dev/null
+++ b/sysdeps/hppa/jmpbuf-offsets.h
@@ -0,0 +1,19 @@
+/* Private macros for accessing __jmp_buf contents. HPPA version.
+ Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define JB_SP (76/4)
diff --git a/sysdeps/hppa/jmpbuf-unwind.h b/sysdeps/hppa/jmpbuf-unwind.h
new file mode 100644
index 0000000000..2a6788de6c
--- /dev/null
+++ b/sysdeps/hppa/jmpbuf-unwind.h
@@ -0,0 +1,26 @@
+/* Examine __jmp_buf for unwinding frames. HPPA version.
+ Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+
+/* Test if longjmp to JMPBUF would unwind the frame containing a local
+ variable at ADDRESS. */
+#define _JMPBUF_UNWINDS(_jmpbuf, _address, _demangle) \
+ ((void *) (_address) > \
+ (void *) _demangle ((((unsigned long *) _jmpbuf)[JB_SP])))
diff --git a/sysdeps/hppa/ldsodefs.h b/sysdeps/hppa/ldsodefs.h
new file mode 100644
index 0000000000..128f2be25a
--- /dev/null
+++ b/sysdeps/hppa/ldsodefs.h
@@ -0,0 +1,41 @@
+/* Run-time dynamic linker data structures for loaded ELF shared objects.
+ Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _HPPA_LDSODEFS_H
+#define _HPPA_LDSODEFS_H 1
+
+#include <elf.h>
+
+struct La_hppa_regs;
+struct La_hppa_retval;
+
+#define ARCH_PLTENTER_MEMBERS \
+ Elf32_Addr (*hppa_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \
+ uintptr_t *, struct La_hppa_regs *, \
+ unsigned int *, const char *name, \
+ long int *framesizep);
+
+#define ARCH_PLTEXIT_MEMBERS \
+ unsigned int (*hppa_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, \
+ uintptr_t *, \
+ const struct La_hppa_regs *, \
+ struct La_hppa_retval *, const char *);
+
+#include_next <ldsodefs.h>
+
+#endif
diff --git a/sysdeps/hppa/libc-tls.c b/sysdeps/hppa/libc-tls.c
new file mode 100644
index 0000000000..0ef01bb764
--- /dev/null
+++ b/sysdeps/hppa/libc-tls.c
@@ -0,0 +1,36 @@
+/* Thread-local storage handling in the ELF dynamic linker. hppa version.
+ Copyright (C) 2003-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <csu/libc-tls.c>
+#include <dl-tls.h>
+
+#if USE_TLS
+
+/* On hppa, linker optimizations are not required, so __tls_get_addr
+ can be called even in statically linked binaries. In this case module
+ must be always 1 and PT_TLS segment exist in the binary, otherwise it
+ would not link. */
+
+void *
+__tls_get_addr (tls_index *ti)
+{
+ dtv_t *dtv = THREAD_DTV ();
+ return (char *) dtv[1].pointer.val + ti->ti_offset;
+}
+
+#endif
diff --git a/sysdeps/hppa/libgcc-compat.c b/sysdeps/hppa/libgcc-compat.c
new file mode 100644
index 0000000000..1a54981dd2
--- /dev/null
+++ b/sysdeps/hppa/libgcc-compat.c
@@ -0,0 +1,42 @@
+/* pre-.hidden libgcc compatibility
+ Copyright (C) 2002-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Randolph Chung
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+
+#include <stdint.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_6)
+
+symbol_version (__clz_tab_internal, __clz_tab, GLIBC_2.2);
+
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+
+const UQItype __clz_tab_internal[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+
+#endif
diff --git a/sysdeps/hppa/lshift.S b/sysdeps/hppa/lshift.S
new file mode 100644
index 0000000000..f0debff415
--- /dev/null
+++ b/sysdeps/hppa/lshift.S
@@ -0,0 +1,65 @@
+;! HP-PA __mpn_lshift --
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr gr26
+;! s_ptr gr25
+;! size gr24
+;! cnt gr23
+
+ .text
+ .export __mpn_lshift
+__mpn_lshift:
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ;! compute carry out limb
+ ldws,mb -4(%r25),%r29
+ addib,= -1,%r24,L$0002
+ vshd %r22,%r29,%r20
+
+L$loop: ldws,mb -4(%r25),%r22
+ stws,mb %r20,-4(%r26)
+ addib,= -1,%r24,L$0003
+ vshd %r29,%r22,%r20
+ ldws,mb -4(%r25),%r29
+ stws,mb %r20,-4(%r26)
+ addib,<> -1,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+L$0002: stws,mb %r20,-4(%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(%r26)
+L$0003: stws,mb %r20,-4(%r26)
+L$0004: vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(%r26)
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/machine-gmon.h b/sysdeps/hppa/machine-gmon.h
new file mode 100644
index 0000000000..2f3edc2d9e
--- /dev/null
+++ b/sysdeps/hppa/machine-gmon.h
@@ -0,0 +1,24 @@
+/* Machine-specific calling sequence for `mcount' profiling function. PA-RISC
+ Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* We can call _mcount directly since gcc supplies the correct
+ * arguments */
+#define _MCOUNT_DECL(from, self) \
+ void _mcount (u_long from, u_long self)
+
+#define MCOUNT
diff --git a/sysdeps/hppa/math_private.h b/sysdeps/hppa/math_private.h
new file mode 100644
index 0000000000..f7d41417dc
--- /dev/null
+++ b/sysdeps/hppa/math_private.h
@@ -0,0 +1,27 @@
+/* Internal math stuff. HPPA version.
+ Copyright (C) 2013-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MATH_PRIVATE_H
+
+/* One of the few architectures where the meaning of the quiet/signaling bit is
+ inverse to IEEE 754-2008 (as well as common practice for IEEE 754-1985). */
+#define HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+
+#include_next <math_private.h>
+
+#endif
diff --git a/sysdeps/hppa/memusage.h b/sysdeps/hppa/memusage.h
new file mode 100644
index 0000000000..d361356d25
--- /dev/null
+++ b/sysdeps/hppa/memusage.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("%r30"); stack_ptr; })
+#define STACK_GROWS_UPWARD 1
+
+#include <sysdeps/generic/memusage.h>
diff --git a/sysdeps/hppa/mp_clz_tab.c b/sysdeps/hppa/mp_clz_tab.c
new file mode 100644
index 0000000000..52d06383c1
--- /dev/null
+++ b/sysdeps/hppa/mp_clz_tab.c
@@ -0,0 +1 @@
+/* __clz_tab not needed on hppa. */
diff --git a/sysdeps/hppa/nptl/Makefile b/sysdeps/hppa/nptl/Makefile
new file mode 100644
index 0000000000..143850e6c8
--- /dev/null
+++ b/sysdeps/hppa/nptl/Makefile
@@ -0,0 +1,20 @@
+# Copyright (C) 2005-2014 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, see
+# <http://www.gnu.org/licenses/>.
+
+ifeq ($(subdir),csu)
+gen-as-const-headers += tcb-offsets.sym
+endif
diff --git a/sysdeps/hppa/nptl/jmpbuf-unwind.h b/sysdeps/hppa/nptl/jmpbuf-unwind.h
new file mode 100644
index 0000000000..01f5870694
--- /dev/null
+++ b/sysdeps/hppa/nptl/jmpbuf-unwind.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2003-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <setjmp.h>
+#include <jmpbuf-offsets.h>
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) > (uintptr_t)(((unsigned long *) _jmpbuf)[JB_SP]) - (_adj))
+
+/* We use the normal longjmp for unwinding. */
+#define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val)
diff --git a/sysdeps/hppa/nptl/pthread_spin_init.c b/sysdeps/hppa/nptl/pthread_spin_init.c
new file mode 100644
index 0000000000..c83669eb91
--- /dev/null
+++ b/sysdeps/hppa/nptl/pthread_spin_init.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "pthreadP.h"
+
+int
+pthread_spin_init (pthread_spinlock_t *lock, int pshared)
+{
+ int tmp = 0;
+ /* This should be a memory barrier to newer compilers */
+ __asm__ __volatile__ ("stw,ma %1,0(%0)"
+ : : "r" (lock), "r" (tmp) : "memory");
+ return 0;
+}
diff --git a/sysdeps/hppa/nptl/pthread_spin_lock.c b/sysdeps/hppa/nptl/pthread_spin_lock.c
new file mode 100644
index 0000000000..b29fc7cef8
--- /dev/null
+++ b/sysdeps/hppa/nptl/pthread_spin_lock.c
@@ -0,0 +1,23 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define SPIN_LOCK_READS_BETWEEN_CMPXCHG 1000
+
+/* We can't use the normal "#include <nptl/pthread_spin_lock.c>" because
+ it will resolve to this very file. Using "sysdeps/.." as reference to the
+ top level directory does the job. */
+#include <sysdeps/../nptl/pthread_spin_lock.c>
diff --git a/sysdeps/hppa/nptl/pthread_spin_unlock.c b/sysdeps/hppa/nptl/pthread_spin_unlock.c
new file mode 100644
index 0000000000..5a8aed8e38
--- /dev/null
+++ b/sysdeps/hppa/nptl/pthread_spin_unlock.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "pthreadP.h"
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+ int tmp = 0;
+ /* This should be a memory barrier to newer compilers */
+ __asm__ __volatile__ ("stw,ma %1,0(%0)"
+ : : "r" (lock), "r" (tmp) : "memory");
+ return 0;
+}
diff --git a/sysdeps/hppa/nptl/pthreaddef.h b/sysdeps/hppa/nptl/pthreaddef.h
new file mode 100644
index 0000000000..ee8765a6f1
--- /dev/null
+++ b/sysdeps/hppa/nptl/pthreaddef.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2002-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Default stack size. */
+#define ARCH_STACK_DEFAULT_SIZE (8 * 1024 * 1024)
+
+/* Required stack pointer alignment at beginning. */
+#define STACK_ALIGN 64
+
+/* Minimal stack size after allocating thread descriptor and guard size. */
+#define MINIMAL_REST_STACK 2048
+
+/* Alignment requirement for TCB, note that this must be larger than STACK_ALIGN */
+#define TCB_ALIGNMENT STACK_ALIGN
+
+
+/* Location of current stack frame. */
+#define CURRENT_STACK_FRAME stack_pointer
+register char * stack_pointer __asm__ ("%r30");
+
+
+/* XXX Until we have a better place keep the definitions here. */
+
+#define __exit_thread_inline(val) \
+ INLINE_SYSCALL (exit, 1, (val))
diff --git a/sysdeps/hppa/nptl/shlib-versions b/sysdeps/hppa/nptl/shlib-versions
new file mode 100644
index 0000000000..adc26364b1
--- /dev/null
+++ b/sysdeps/hppa/nptl/shlib-versions
@@ -0,0 +1 @@
+hppa.*-.*-linux.* libpthread=0 GLIBC_2.2
diff --git a/sysdeps/hppa/nptl/tcb-offsets.sym b/sysdeps/hppa/nptl/tcb-offsets.sym
new file mode 100644
index 0000000000..f3cc82621a
--- /dev/null
+++ b/sysdeps/hppa/nptl/tcb-offsets.sym
@@ -0,0 +1,19 @@
+#include <sysdep.h>
+#include <tls.h>
+
+RESULT offsetof (struct pthread, result)
+TID offsetof (struct pthread, tid)
+PID offsetof (struct pthread, pid)
+CANCELHANDLING offsetof (struct pthread, cancelhandling)
+CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf)
+MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads)
+TLS_PRE_TCB_SIZE sizeof (struct pthread)
+MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
+
+-- Use a thread_offset when working with asm to make things simpler
+-- This way we get the offset of a member in the struct pthread that
+-- preceeds the thread pointer (which points to the dtv).
+#define thread_offsetof(mem) (unsigned int)(offsetof(struct pthread, mem) - sizeof(struct pthread))
+PID_THREAD_OFFSET thread_offsetof (pid)
+TID_THREAD_OFFSET thread_offsetof (tid)
+MULTIPLE_THREADS_THREAD_OFFSET thread_offsetof (header.multiple_threads)
diff --git a/sysdeps/hppa/nptl/tls.h b/sysdeps/hppa/nptl/tls.h
new file mode 100644
index 0000000000..e4dc197945
--- /dev/null
+++ b/sysdeps/hppa/nptl/tls.h
@@ -0,0 +1,171 @@
+/* Definition for thread-local data handling. NPTL/hppa version.
+ Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _TLS_H
+#define _TLS_H 1
+
+#include <dl-sysdep.h>
+
+#ifndef __ASSEMBLER__
+# include <stdbool.h>
+# include <stddef.h>
+# include <stdint.h>
+
+/* Type for the dtv. */
+typedef union dtv
+{
+ size_t counter;
+ struct
+ {
+ void *val;
+ bool is_static;
+ } pointer;
+} dtv_t;
+
+#else /* __ASSEMBLER__ */
+# include <tcb-offsets.h>
+#endif /* __ASSEMBLER__ */
+
+/* Signal that TLS support is available. */
+#define USE_TLS 1
+
+#ifndef __ASSEMBLER__
+
+/* Get system call information. */
+# include <sysdep.h>
+
+/* The TP points to the start of the thread blocks. */
+# define TLS_DTV_AT_TP 1
+# define TLS_TCB_AT_TP 0
+
+/* Get the thread descriptor definition. */
+# include <nptl/descr.h>
+
+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)
+
+/* Alignment requirements for the TCB. */
+# define TLS_TCB_ALIGN __alignof__ (struct pthread)
+
+/* This is the size we need before TCB */
+# define TLS_PRE_TCB_SIZE sizeof (struct pthread)
+
+/* 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 = (tcbhead_t *)__get_cr27(); \
+ __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) \
+ ({ __set_cr27(tcbp); NULL; })
+
+/* Return the address of the dtv for the current thread. */
+# define THREAD_DTV() \
+ ({ tcbhead_t *__tcbp = (tcbhead_t *)__get_cr27(); \
+ __tcbp->dtv; \
+ })
+
+/* Return the thread descriptor for the current thread. */
+# define THREAD_SELF \
+ ({ struct pthread *__self; \
+ __self = __get_cr27(); \
+ __self - 1; \
+ })
+
+/* Magic for libthread_db to know how to do THREAD_SELF.
+ Our thread pointer is stored in cr27. See asm/elf.h for the offset into
+ elf_gregset_t. The thread descriptor is sizeof (struct pthread) away. */
+# define DB_THREAD_SELF \
+ REGISTER (32, 32, 53 * 4, -sizeof (struct pthread))
+
+/* Access to data in the thread descriptor is easy. */
+# define THREAD_GETMEM(descr, member) \
+ descr->member
+# define THREAD_GETMEM_NC(descr, member, idx) \
+ descr->member[idx]
+# define THREAD_SETMEM(descr, member, value) \
+ descr->member = (value)
+# define THREAD_SETMEM_NC(descr, member, idx, value) \
+ descr->member[idx] = (value)
+
+static inline struct pthread *__get_cr27(void)
+{
+ long cr27;
+ asm ("mfctl %%cr27, %0" : "=r" (cr27) : );
+ return (struct pthread *) cr27;
+}
+
+/* We write to cr27, clobber r26 as the input argument, and clobber
+ r31 as the link register. */
+static inline void __set_cr27(struct pthread *cr27)
+{
+ asm ( "ble 0xe0(%%sr2, %%r0)\n\t"
+ "copy %0, %%r26"
+ : : "r" (cr27) : "r26", "r31" );
+}
+
+/* Get and set the global scope generation counter in struct pthread. */
+#define THREAD_GSCOPE_FLAG_UNUSED 0
+#define THREAD_GSCOPE_FLAG_USED 1
+#define THREAD_GSCOPE_FLAG_WAIT 2
+#define THREAD_GSCOPE_RESET_FLAG() \
+ do \
+ { int __res \
+ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \
+ THREAD_GSCOPE_FLAG_UNUSED); \
+ if (__res == THREAD_GSCOPE_FLAG_WAIT) \
+ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1, LLL_PRIVATE); \
+ } \
+ while (0)
+#define THREAD_GSCOPE_SET_FLAG() \
+ do \
+ { \
+ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \
+ atomic_write_barrier (); \
+ } \
+ while (0)
+#define THREAD_GSCOPE_WAIT() \
+ GL(dl_wait_lookup_done) ()
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* tls.h */
diff --git a/sysdeps/hppa/nptl/tst-oddstacklimit.c b/sysdeps/hppa/nptl/tst-oddstacklimit.c
new file mode 100644
index 0000000000..f65dbc8cec
--- /dev/null
+++ b/sysdeps/hppa/nptl/tst-oddstacklimit.c
@@ -0,0 +1,26 @@
+/* Test NPTL with stack limit that is not a multiple of the page size.
+ HPPA version.
+ Copyright (C) 2012-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This sets the stack resource limit to 8193kb, which is not a multiple
+ of the page size, and therefore an odd sized stack limit. We override
+ this because the default is too small to run with. */
+
+#define ODD_STACK_LIMIT (8193 * 1024)
+
+#include <sysdeps/../nptl/tst-oddstacklimit.c>
diff --git a/sysdeps/hppa/preconfigure b/sysdeps/hppa/preconfigure
new file mode 100644
index 0000000000..4d7fdcd032
--- /dev/null
+++ b/sysdeps/hppa/preconfigure
@@ -0,0 +1,6 @@
+# This fragment canonicalizes the machine names for hppa variants.
+
+case "$machine" in
+hppa*64*) base_machine=hppa machine=hppa/hppa64 ;;
+hppa*) base_machine=hppa machine=hppa/hppa1.1 ;;
+esac
diff --git a/sysdeps/hppa/rshift.S b/sysdeps/hppa/rshift.S
new file mode 100644
index 0000000000..2d3561de40
--- /dev/null
+++ b/sysdeps/hppa/rshift.S
@@ -0,0 +1,62 @@
+;! HP-PA __mpn_rshift --
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr gr26
+;! s_ptr gr25
+;! size gr24
+;! cnt gr23
+
+ .text
+ .export __mpn_rshift
+__mpn_rshift:
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$0004
+ vshd %r22,%r0,%r28 ;! compute carry out limb
+ ldws,ma 4(%r25),%r29
+ addib,= -1,%r24,L$0002
+ vshd %r29,%r22,%r20
+
+L$loop: ldws,ma 4(%r25),%r22
+ stws,ma %r20,4(%r26)
+ addib,= -1,%r24,L$0003
+ vshd %r22,%r29,%r20
+ ldws,ma 4(%r25),%r29
+ stws,ma %r20,4(%r26)
+ addib,<> -1,%r24,L$loop
+ vshd %r29,%r22,%r20
+
+L$0002: stws,ma %r20,4(%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(%r26)
+L$0003: stws,ma %r20,4(%r26)
+L$0004: vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(%r26)
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/setjmp.S b/sysdeps/hppa/setjmp.S
new file mode 100644
index 0000000000..51904af051
--- /dev/null
+++ b/sysdeps/hppa/setjmp.S
@@ -0,0 +1,72 @@
+/* setjmp for HPPA.
+ Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#define _ASM
+#define _SETJMP_H
+#include <bits/setjmp.h>
+
+
+ .text
+ .align 4
+ .import __sigjmp_save, code
+ .globl __sigsetjmp
+ .export __sigsetjmp, code
+ .proc
+ .callinfo
+__sigsetjmp:
+ stw %r3, 0(%r26)
+ /* This padding exists for unknown historical reasons. */
+ /* 4 - 4 bytes of padding. */
+ stw %r4, 8(%r26)
+ stw %r5, 12(%r26)
+ stw %r6, 16(%r26)
+ stw %r7, 20(%r26)
+ stw %r8, 24(%r26)
+ stw %r9, 28(%r26)
+ stw %r10, 32(%r26)
+ stw %r11, 36(%r26)
+ stw %r12, 40(%r26)
+ stw %r13, 44(%r26)
+ stw %r14, 48(%r26)
+ stw %r15, 52(%r26)
+ stw %r16, 56(%r26)
+ stw %r17, 60(%r26)
+ stw %r18, 64(%r26)
+ stw %r19, 68(%r26)
+ stw %r27, 72(%r26)
+ stw %r30, 76(%r26)
+
+ stw %rp, 80(%r26)
+ /* This padding exists to ensure double alignment for fprs. */
+ /* 84 - 4 bytes of padding. */
+ ldo 88(%r26),%r1
+ fstds,ma %fr12, 8(%r1) /* 88 */
+ fstds,ma %fr13, 8(%r1) /* 96 */
+ fstds,ma %fr14, 8(%r1) /* 104 */
+ fstds,ma %fr15, 8(%r1) /* 112 */
+ fstds,ma %fr16, 8(%r1) /* 120 */
+ fstds,ma %fr17, 8(%r1) /* 128 */
+ fstds,ma %fr18, 8(%r1) /* 136 */
+ fstds,ma %fr19, 8(%r1) /* 144 */
+ fstds,ma %fr20, 8(%r1) /* 152 */
+ fstds %fr21, 0(%r1) /* 160 */
+ /* Total of 168 bytes. */
+ b __sigjmp_save
+ nop
+ .procend
diff --git a/sysdeps/hppa/shlib-versions b/sysdeps/hppa/shlib-versions
new file mode 100644
index 0000000000..6b9225c925
--- /dev/null
+++ b/sysdeps/hppa/shlib-versions
@@ -0,0 +1,9 @@
+hppa.*-.*-.* libm=6 GLIBC_2.2
+
+hppa.*-.*-.* libc=6 GLIBC_2.2
+
+hppa.*-.*-.* ld=ld.so.1 GLIBC_2.2
+
+hppa-.*-.* libBrokenLocale=1 GLIBC_2.2
+
+hppa.*-.*-.* libgcc_s=4
diff --git a/sysdeps/hppa/stackinfo.h b/sysdeps/hppa/stackinfo.h
new file mode 100644
index 0000000000..5d41d85952
--- /dev/null
+++ b/sysdeps/hppa/stackinfo.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 1999-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file contains a bit of information about the stack allocation
+ of the processor. */
+
+#ifndef _STACKINFO_H
+#define _STACKINFO_H 1
+
+#include <elf.h>
+
+/* Default to an executable stack. PF_X can be overridden if PT_GNU_STACK is
+ * present, but it is presumed absent. */
+#define DEFAULT_STACK_PERMS (PF_R|PF_W|PF_X)
+
+/* On PA the stack grows up. */
+#define _STACK_GROWS_UP 1
+
+#endif /* stackinfo.h */
diff --git a/sysdeps/hppa/start.S b/sysdeps/hppa/start.S
new file mode 100644
index 0000000000..0998270afd
--- /dev/null
+++ b/sysdeps/hppa/start.S
@@ -0,0 +1,143 @@
+/* ELF startup code for HPPA.
+ Copyright (C) 2002-2014 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 GNU 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.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+ .import main, code
+ .import $global$, data
+ .import __libc_start_main, code
+ .import __libc_csu_fini, code
+ .import __libc_csu_init, code
+
+ /* Have the linker create plabel words so we get PLABEL32
+ relocs and not 21/14. The use of 21/14 relocs is only
+ supported in the latest dynamic linker. */
+ .section .rodata
+ .align 4
+.Lpmain:
+ .word P%main
+.Lp__libc_start_main:
+ .word P%__libc_start_main
+.Lp__libc_csu_fini:
+ .word P%__libc_csu_fini
+.Lp__libc_csu_init:
+ .word P%__libc_csu_init
+
+ .text
+ .align 4
+ .globl _start
+ .export _start, ENTRY
+ .type _start,@function
+_start:
+ /* At entry to the function we have:
+
+ r26 - Unused
+ r25 - argc
+ r24 - argv
+ r23 - False _dl_fini plabel address
+
+ This function is called from the lower half of RTLD_START.
+
+ The call to __libc_start_main expects:
+
+ 1. r26 - Application main
+ 2. r25 - argc
+ 3. r24 - argv
+ 4. r23 - __libc_csu_init
+ 5. sp-52 - __libc_csu_fini
+ 6. sp-56 - rtld_fini
+ 7. sp-60 - stackend */
+
+ .proc
+ .callinfo
+ /* Clear previous-sp. */
+ stw %r0, -4(%sp)
+ /* Setup the stack and frame. */
+ stw %rp, -20(%sp)
+ ldo 64(%sp), %sp
+ stw %sp, -4(%sp)
+ stw %r19, -32(%sp)
+
+ /* argc and argv should be in 25 and 24 (2nd and 3rd argument) */
+ /* void (*rtld_fini) (void) (6th argument) */
+ stw %r23, -56(%sp)
+ /* Need to setup 1, 4, 5, and 7th arguments */
+
+#if SHARED
+ /* load main (1st argument) */
+ addil LT'.Lpmain, %r19
+ ldw RT'.Lpmain(%r1), %r26
+ ldw 0(%r26),%r26
+ /* void (*init) (void) (4th argument) */
+ addil LT'.Lp__libc_csu_init, %r19
+ ldw RT'.Lp__libc_csu_init(%r1), %r23
+ ldw 0(%r23), %r23
+ /* void (*fini) (void) (5th argument) */
+ addil LT'.Lp__libc_csu_fini, %r19
+ ldw RT'.Lp__libc_csu_fini(%r1), %r22
+ ldw 0(%r22), %r22
+#else
+ /* load main (1st argument) */
+ ldil LR'.Lpmain, %r26
+ ldw RR'.Lpmain(%r26), %r26
+ /* void (*init) (void) (4th argument) */
+ ldil LR'.Lp__libc_csu_init, %r23
+ ldw RR'.Lp__libc_csu_init(%r23), %r23
+ /* void (*fini) (void) (5th argument) */
+ ldil LR'.Lp__libc_csu_fini, %r22
+ ldw RR'.Lp__libc_csu_fini(%r22), %r22
+#endif
+ /* Store 5th argument */
+ stw %r22, -52(%sp)
+ /* void *stack_end (7th argument) */
+ stw %sp, -60(%sp)
+
+ /* load global */
+ ldil L%$global$, %dp
+ ldo R%$global$(%dp), %dp
+
+ bl __libc_start_main,%r2
+ nop
+ /* die horribly if it returned (it shouldn't) */
+ iitlbp %r0,(%sr0,%r0)
+ nop
+
+ .procend
+
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/sysdeps/hppa/sub_n.S b/sysdeps/hppa/sub_n.S
new file mode 100644
index 0000000000..035c4cbbb3
--- /dev/null
+++ b/sysdeps/hppa/sub_n.S
@@ -0,0 +1,58 @@
+;! HP-PA __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+;! store difference in a third limb vector.
+
+;! Copyright (C) 1992-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! res_ptr gr26
+;! s1_ptr gr25
+;! s2_ptr gr24
+;! size gr23
+
+;! One might want to unroll this as for other processors, but it turns
+;! out that the data cache contention after a store makes such
+;! unrolling useless. We can't come under 5 cycles/limb anyway.
+
+ .text
+ .export __mpn_sub_n
+__mpn_sub_n:
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(%r25),%r21
+ ldws,ma 4(%r24),%r20
+
+ addib,= -1,%r23,L$end ;! check for (SIZE == 1)
+ sub %r21,%r20,%r28 ;! subtract first limbs ignoring cy
+
+L$loop: ldws,ma 4(%r25),%r21
+ ldws,ma 4(%r24),%r20
+ stws,ma %r28,4(%r26)
+ addib,<> -1,%r23,L$loop
+ subb %r21,%r20,%r28
+
+L$end: stws %r28,0(%r26)
+ addc %r0,%r0,%r28
+ bv 0(%r2)
+ subi 1,%r28,%r28
+
+ .exit
+ .procend
diff --git a/sysdeps/hppa/sysdep.h b/sysdeps/hppa/sysdep.h
new file mode 100644
index 0000000000..9d4b37b9c6
--- /dev/null
+++ b/sysdeps/hppa/sysdep.h
@@ -0,0 +1,76 @@
+/* Assembler macros for HP/PA.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@cygnus.com>, August 1999.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdeps/generic/sysdep.h>
+#include <sys/syscall.h>
+#include "config.h"
+
+#undef ASM_LINE_SEP
+#define ASM_LINE_SEP !
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#define ALIGNARG(log2) log2
+
+
+/* Define an entry point visible from C.
+
+ There is currently a bug in gdb which prevents us from specifying
+ incomplete stabs information. Fake some entries here which specify
+ the current source file. */
+#define ENTRY(name) \
+ .SPACE $TEXT$ ASM_LINE_SEP \
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY ASM_LINE_SEP \
+ .align ALIGNARG(4) ASM_LINE_SEP \
+ .NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY ASM_LINE_SEP \
+ .EXPORT C_SYMBOL_NAME(name),ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR ASM_LINE_SEP\
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#undef END
+#define END(name) \
+ .PROCEND
+
+/* GCC does everything for us. */
+#ifdef PROF
+#define CALL_MCOUNT
+#else
+#define CALL_MCOUNT /* Do nothing. */
+#endif
+
+#define PSEUDO(name, syscall_name, args) \
+ ENTRY (name) \
+ DO_CALL (syscall_name, args)
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+#undef JUMPTARGET
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+
+/* Local label name for asm code. */
+#ifndef L
+#define L(name) name
+#endif
+
+#endif /* __ASSEMBLER__ */
diff --git a/sysdeps/hppa/tininess.h b/sysdeps/hppa/tininess.h
new file mode 100644
index 0000000000..1db37790f8
--- /dev/null
+++ b/sysdeps/hppa/tininess.h
@@ -0,0 +1 @@
+#define TININESS_AFTER_ROUNDING 1
diff --git a/sysdeps/hppa/tls-macros.h b/sysdeps/hppa/tls-macros.h
new file mode 100644
index 0000000000..38edb1b72c
--- /dev/null
+++ b/sysdeps/hppa/tls-macros.h
@@ -0,0 +1,114 @@
+/* TLS Access Macros for HP PARISC Linux */
+
+/* HPPA Local Exec TLS access. */
+#define TLS_LE(x) \
+ ({ int * __result; \
+ unsigned long __tmp; \
+ asm ( \
+ " mfctl %%cr27, %1\n" \
+ " addil LR'" #x "-$tls_leoff$, %1\n" \
+ " ldo RR'" #x "-$tls_leoff$(%%r1), %0\n" \
+ : "=r" (__result), "=r" (__tmp) \
+ : \
+ : "r1" ); \
+ __result; \
+ })
+
+/* HPPA Initial Exec TLS access. */
+#ifdef PIC
+# define TLS_IE(x) \
+ ({ int * __result; \
+ unsigned long __tmp, __tmp2; \
+ asm ( \
+ " mfctl %%cr27, %1\n" \
+ " addil LT'" #x "-$tls_ieoff$, %%r19\n" \
+ " ldw RT'" #x "-$tls_ieoff$(%%r1), %2\n" \
+ " add %1, %2, %0\n" \
+ : "=r" (__result), "=r" (__tmp), "=r" (__tmp2) \
+ : \
+ : "r1" ); \
+ __result; \
+ })
+#else
+# define TLS_IE(x) \
+ ({ int * __result; \
+ unsigned long __tmp, __tmp2; \
+ asm ( \
+ " mfctl %%cr27, %1\n" \
+ " addil LR'" #x "-$tls_ieoff$, %%r27\n" \
+ " ldw RR'" #x "-$tls_ieoff$(%%r1), %2\n" \
+ " add %1, %2, %0\n" \
+ : "=r" (__result), "=r" (__tmp), "=r" (__tmp2) \
+ : \
+ : "r1" ); \
+ __result; \
+ })
+#endif
+
+#ifdef PIC
+/* HPPA Local Dynamic TLS access. */
+# define TLS_LD(x) \
+ ({ int * __result; \
+ asm ( \
+ " copy %%r19, %%r4\n" \
+ " addil LT'" #x "-$tls_ldidx$, %%r19\n" \
+ " bl __tls_get_addr, %%r2\n" \
+ " ldo RT'" #x "-$tls_ldidx$(%%r1), %%r26\n" \
+ " addil LR'" #x "-$tls_dtpoff$, %%r28\n" \
+ " ldo RR'" #x "-$tls_dtpoff$(%%r1), %0\n" \
+ " copy %%r4, %%r19\n" \
+ : "=r" (__result) \
+ : \
+ : "r1", "r2", "r4", "r20", "r21", "r22", "r23", "r24", \
+ "r25", "r26", "r28", "r29", "r31" ); \
+ __result; \
+ })
+#else
+# define TLS_LD(x) \
+ ({ int * __result; \
+ asm ( \
+ " addil LR'" #x "-$tls_ldidx$, %%r27\n" \
+ " bl __tls_get_addr, %%r2\n" \
+ " ldo RR'" #x "-$tls_ldidx$(%%r1), %%r26\n" \
+ " addil LR'" #x "-$tls_dtpoff$, %%r28\n" \
+ " ldo RR'" #x "-$tls_dtpoff$(%%r1), %0\n" \
+ : "=r" (__result) \
+ : \
+ : "r1", "r2", "r20", "r21", "r22", "r23", "r24", \
+ "r25", "r26", "r28", "r29", "r31" ); \
+ __result; \
+ })
+#endif
+
+/* HPPA General Dynamic TLS access. */
+#ifdef PIC
+# define TLS_GD(x) \
+ ({ int * __result; \
+ asm ( \
+ " copy %%r19, %%r4\n" \
+ " addil LT'" #x "-$tls_gdidx$, %%r19\n" \
+ " bl __tls_get_addr, %%r2\n" \
+ " ldo RT'" #x "-$tls_gdidx$(%%r1), %%r26\n" \
+ " copy %%r28, %0\n" \
+ " copy %%r4, %%r19\n" \
+ : "=r" (__result) \
+ : \
+ : "r1", "r2", "r4", "r20", "r21", "r22", "r23", "r24", \
+ "r25", "r26", "r28", "r29", "r31" ); \
+ __result; \
+ })
+#else
+# define TLS_GD(x) \
+ ({ int * __result; \
+ asm ( \
+ " addil LR'" #x "-$tls_gdidx$, %%r27\n" \
+ " bl __tls_get_addr, %%r2\n" \
+ " ldo RR'" #x "-$tls_gdidx$(%%r1), %%r26\n" \
+ " copy %%r28, %0\n" \
+ : "=r" (__result) \
+ : \
+ : "r1", "r2", "r20", "r21", "r22", "r23", "r24", \
+ "r25", "r26", "r28", "r29", "r31" ); \
+ __result; \
+ })
+#endif
diff --git a/sysdeps/hppa/tst-audit.h b/sysdeps/hppa/tst-audit.h
new file mode 100644
index 0000000000..e32699054a
--- /dev/null
+++ b/sysdeps/hppa/tst-audit.h
@@ -0,0 +1,25 @@
+/* Definitions for testing PLT entry/exit auditing. HP-PARISC version.
+
+ Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define pltenter la_hppa_gnu_pltenter
+#define pltexit la_hppa_gnu_pltexit
+#define La_regs La_hppa_regs
+#define La_retval La_hppa_retval
+#define int_retval lrv_r28
diff --git a/sysdeps/hppa/udiv_qrnnd.S b/sysdeps/hppa/udiv_qrnnd.S
new file mode 100644
index 0000000000..cf06286b02
--- /dev/null
+++ b/sysdeps/hppa/udiv_qrnnd.S
@@ -0,0 +1,285 @@
+;! HP-PA __udiv_qrnnd division support, used from longlong.h.
+;! This version runs fast on pre-PA7000 CPUs.
+
+;! Copyright (C) 1993-2014 Free Software Foundation, Inc.
+
+;! This file is part of the GNU MP Library.
+
+;! The GNU MP 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 MP 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 MP Library. If not, see
+;! <http://www.gnu.org/licenses/>.
+
+
+;! INPUT PARAMETERS
+;! rem_ptr gr26
+;! n1 gr25
+;! n0 gr24
+;! d gr23
+
+;! The code size is a bit excessive. We could merge the last two ds;addc
+;! sequences by simply moving the "bb,< Odd" instruction down. The only
+;! trouble is the FFFFFFFF code that would need some hacking.
+
+ .text
+ .export __udiv_qrnnd
+__udiv_qrnnd:
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ comb,< %r23,%r0,L$largedivisor
+ sub %r0,%r23,%r1 ;! clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r28
+ ds %r25,%r23,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r23,%r25
+ stws %r25,0(%r26)
+ bv 0(%r2)
+ addc %r28,%r28,%r28
+
+L$largedivisor:
+ extru %r24,31,1,%r20 ;! r20 = n0 & 1
+ bb,< %r23,31,L$odd
+ extru %r23,30,31,%r22 ;! r22 = d >> 1
+ shd %r25,%r24,1,%r24 ;! r24 = new n0
+ extru %r25,30,31,%r25 ;! r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r20,%r25
+ stws %r25,0(%r26)
+ bv 0(%r2)
+ addc %r24,%r24,%r28
+
+L$odd: addib,sv,n 1,%r22,L$FF.. ;! r22 = (d / 2 + 1)
+ shd %r25,%r24,1,%r24 ;! r24 = new n0
+ extru %r25,30,31,%r25 ;! r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r28
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r20,%r25
+;! We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25
+ add,nuv %r28,%r25,%r25
+ addl %r25,%r1,%r25
+ addc %r0,%r28,%r28
+ sub,<< %r25,%r23,%r0
+ addl %r25,%r1,%r25
+ stws %r25,0(%r26)
+ bv 0(%r2)
+ addc %r0,%r28,%r28
+
+;! This is just a special case of the code above.
+;! We come here when d == 0xFFFFFFFF
+L$FF..: add,uv %r25,%r24,%r24
+ sub,<< %r24,%r23,%r0
+ ldo 1(%r24),%r24
+ stws %r24,0(%r26)
+ bv 0(%r2)
+ addc %r0,%r25,%r28
+
+ .exit
+ .procend
diff --git a/sysdeps/unix/sysv/linux/hppa/Makefile b/sysdeps/unix/sysv/linux/hppa/Makefile
new file mode 100644
index 0000000000..68569013fb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/Makefile
@@ -0,0 +1,4 @@
+# Used by *context() functions
+ifeq ($(subdir),stdlib)
+gen-as-const-headers += ucontext_i.sym
+endif
diff --git a/sysdeps/unix/sysv/linux/hppa/Versions b/sysdeps/unix/sysv/linux/hppa/Versions
new file mode 100644
index 0000000000..a392feebc5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/Versions
@@ -0,0 +1,44 @@
+libc {
+ # The comment lines with "#errlist-compat" are magic; see errlist-compat.awk.
+ # When you get an error from errlist-compat.awk, you need to add a new
+ # version here. Don't do this blindly, since this means changing the ABI
+ # for all GNU/Linux configurations.
+
+ GLIBC_2.1 {
+ #errlist-compat 253
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.2 {
+ # New rlimit interface
+ getrlimit; setrlimit; getrlimit64; setrlimit64;
+ }
+ GLIBC_2.3 {
+ #errlist-compat 254
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.4 {
+ #errlist-compat 256
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.11 {
+ fallocate64;
+ }
+ GLIBC_2.12 {
+ #errlist-compat 257
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ }
+ GLIBC_2.17 {
+ #errlist-compat 260
+ _sys_errlist; sys_errlist; _sys_nerr; sys_nerr;
+ prlimit64;
+ }
+ GLIBC_2.19 {
+ fanotify_mark;
+ }
+}
+librt {
+ GLIBC_2.3 {
+ # AIO functions.
+ aio_cancel; aio_cancel64;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c b/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c
new file mode 100644
index 0000000000..8789538ded
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2009-2014 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 General Public License
+ along with GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <stdio.h>
+#include <signal.h>
+#include <sysdep.h>
+#define __longjmp ____longjmp_chk
+#define CHECK_SP(sp) \
+ do { \
+ register unsigned long this_sp asm ("r30"); \
+ /* The stack grows up, therefore frames that were created and then \
+ destroyed must all have stack values higher than ours. */ \
+ if ((unsigned long) (sp) > this_sp) \
+ { \
+ struct sigaltstack oss; \
+ INTERNAL_SYSCALL_DECL (err); \
+ int result = INTERNAL_SYSCALL (sigaltstack, err, 2, NULL, &oss);\
+ /* If we aren't using an alternate stack then we have already \
+ shown that we are jumping to a frame that doesn't exist so \
+ error out. If we are using an alternate stack we must prove \
+ that we are jumping *out* of the alternate stack. Note that \
+ the check for that is the same as that for _STACK_GROWS_UP \
+ as for _STACK_GROWS_DOWN. */ \
+ if (!INTERNAL_SYSCALL_ERROR_P (result, err) \
+ && ((oss.ss_flags & SS_ONSTACK) == 0 \
+ || ((unsigned long) oss.ss_sp + oss.ss_size \
+ - (unsigned long) (sp)) < oss.ss_size)) \
+ __fortify_fail ("longjmp causes uninitialized stack frame"); \
+ } \
+ } while (0)
+
+#include <__longjmp.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/atomic.h b/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
new file mode 100644
index 0000000000..e55e91b352
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/atomic.h
@@ -0,0 +1,107 @@
+/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 2005.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdint.h> /* Required for type definitions e.g. uint8_t. */
+#include <abort-instr.h> /* Required for ABORT_INSTRUCTIUON. */
+#include <kernel-features.h> /* Required for __ASSUME_LWS_CAS. */
+
+/* We need EFAULT, ENONSYS */
+#if !defined EFAULT && !defined ENOSYS
+#define EFAULT 14
+#define ENOSYS 251
+#endif
+
+#ifndef _BITS_ATOMIC_H
+#define _BITS_ATOMIC_H 1
+
+typedef int8_t atomic8_t;
+typedef uint8_t uatomic8_t;
+typedef int_fast8_t atomic_fast8_t;
+typedef uint_fast8_t uatomic_fast8_t;
+
+typedef int32_t atomic32_t;
+typedef uint32_t uatomic32_t;
+typedef int_fast32_t atomic_fast32_t;
+typedef uint_fast32_t uatomic_fast32_t;
+
+typedef intptr_t atomicptr_t;
+typedef uintptr_t uatomicptr_t;
+typedef intmax_t atomic_max_t;
+typedef uintmax_t uatomic_max_t;
+
+/* prev = *addr;
+ if (prev == old)
+ *addr = new;
+ return prev; */
+
+/* Use the kernel atomic light weight syscalls on hppa. */
+#define _LWS "0xb0"
+#define _LWS_CAS "0"
+/* Note r31 is the link register. */
+#define _LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
+/* String constant for -EAGAIN. */
+#define _ASM_EAGAIN "-11"
+/* String constant for -EDEADLOCK. */
+#define _ASM_EDEADLOCK "-45"
+
+#if __ASSUME_LWS_CAS
+/* The only basic operation needed is compare and exchange. */
+# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
+ ({ \
+ volatile int lws_errno; \
+ volatile int lws_ret; \
+ asm volatile( \
+ "0: \n\t" \
+ "copy %2, %%r26 \n\t" \
+ "copy %3, %%r25 \n\t" \
+ "copy %4, %%r24 \n\t" \
+ "ble " _LWS "(%%sr2, %%r0) \n\t" \
+ "ldi " _LWS_CAS ", %%r20 \n\t" \
+ "ldi " _ASM_EAGAIN ", %%r24 \n\t" \
+ "cmpb,=,n %%r24, %%r21, 0b \n\t" \
+ "nop \n\t" \
+ "ldi " _ASM_EDEADLOCK ", %%r25 \n\t" \
+ "cmpb,=,n %%r25, %%r21, 0b \n\t" \
+ "nop \n\t" \
+ "stw %%r28, %0 \n\t" \
+ "stw %%r21, %1 \n\t" \
+ : "=m" (lws_ret), "=m" (lws_errno) \
+ : "r" (mem), "r" (oldval), "r" (newval) \
+ : _LWS_CLOBBER \
+ ); \
+ \
+ if(lws_errno == -EFAULT || lws_errno == -ENOSYS) \
+ ABORT_INSTRUCTION; \
+ \
+ lws_ret; \
+ })
+
+# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
+ ({ \
+ int ret; \
+ ret = atomic_compare_and_exchange_val_acq(mem, newval, oldval); \
+ /* Return 1 if it was already acquired. */ \
+ (ret != (int)oldval); \
+ })
+#else
+# error __ASSUME_LWS_CAS is required to build glibc.
+#endif
+/* __ASSUME_LWS_CAS */
+
+#endif
+/* _BITS_ATOMIC_H */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/errno.h b/sysdeps/unix/sysv/linux/hppa/bits/errno.h
new file mode 100644
index 0000000000..ac684d23f0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/errno.h
@@ -0,0 +1,66 @@
+/* Error constants. Linux/HPPA specific version.
+ Copyright (C) 1996-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef _ERRNO_H
+
+# undef EDOM
+# undef EILSEQ
+# undef ERANGE
+# include <linux/errno.h>
+
+/* Linux also has no ECANCELED error code. Since it is not used here
+ we define it to an invalid value. */
+# ifndef ECANCELED
+# define ECANCELED ECANCELLED
+# endif
+
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 254
+# endif
+
+# ifndef ENOTRECOVERABLE
+# define ENOTRECOVERABLE 255
+# endif
+
+# ifndef ERFKILL
+# define ERFKILL 256
+# endif
+
+# ifndef EHWPOISON
+# define EHWPOISON 257
+# endif
+
+# ifndef __ASSEMBLER__
+/* Function to get address of global `errno' variable. */
+extern int *__errno_location (void) __THROW __attribute__ ((__const__));
+
+# if !defined _LIBC || defined _LIBC_REENTRANT
+/* When using threads, errno is a per-thread value. */
+# define errno (*__errno_location ())
+# endif
+# endif /* !__ASSEMBLER__ */
+#endif /* _ERRNO_H */
+
+#if !defined _ERRNO_H && defined __need_Emath
+/* This is ugly but the kernel header is not clean enough. We must
+ define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
+ defined. */
+# define EDOM 33 /* Math argument out of domain of function. */
+# define EILSEQ 47 /* Illegal byte sequence. */
+# define ERANGE 34 /* Math result not representable. */
+#endif /* !_ERRNO_H && __need_Emath */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h b/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h
new file mode 100644
index 0000000000..f596d5f100
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h
@@ -0,0 +1,85 @@
+/* O_*, F_*, FD_* bit values for Linux.
+ Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FCNTL_H
+# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
+#endif
+
+#define O_CREAT 00000400 /* not fcntl */
+#define O_EXCL 00002000 /* not fcntl */
+#define O_NOCTTY 00400000 /* not fcntl */
+#define O_APPEND 00000010
+#define O_NONBLOCK 00200004 /* HPUX has separate NDELAY & NONBLOCK */
+#define __O_DSYNC 01000000
+#define __O_RSYNC 02000000 /* HPUX only */
+#define __O_SYNC 01000000
+#define O_SYNC (__O_SYNC|__O_DSYNC)
+
+#define O_BLKSEEK 00000100 /* HPUX only */
+
+#define __O_DIRECTORY 000010000 /* Must be a directory. */
+#define __O_NOFOLLOW 000000200 /* Do not follow links. */
+#define __O_CLOEXEC 010000000 /* Set close_on_exec. */
+#define __O_NOATIME 004000000 /* Do not set atime. */
+#define __O_PATH 020000000
+#define __O_TMPFILE 040010000 /* Atomically create nameless file. */
+
+#define __O_LARGEFILE 00004000
+
+#define F_GETLK64 8 /* Get record locking info. */
+#define F_SETLK64 9 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 10 /* Set record locking info (blocking). */
+
+#define __F_GETOWN 11 /* Get owner of socket (receiver of SIGIO). */
+#define __F_SETOWN 12 /* Set owner of socket (receiver of SIGIO). */
+
+#define __F_SETSIG 13 /* Set number of signal to be sent. */
+#define __F_GETSIG 14 /* Get number of signal to be sent. */
+
+/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
+#define F_RDLCK 1 /* Read lock. */
+#define F_WRLCK 2 /* Write lock. */
+#define F_UNLCK 3 /* Remove lock. */
+
+struct flock
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+#ifndef __USE_FILE_OFFSET64
+ __off_t l_start; /* Offset where the lock begins. */
+ __off_t l_len; /* Size of the locked area; zero means until EOF. */
+#else
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+#endif
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct flock64
+ {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ __off64_t l_start; /* Offset where the lock begins. */
+ __off64_t l_len; /* Size of the locked area; zero means until EOF. */
+ __pid_t l_pid; /* Process holding the lock. */
+ };
+#endif
+
+/* Include generic Linux declarations. */
+#include <bits/fcntl-linux.h>
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ioctls.h b/sysdeps/unix/sysv/linux/hppa/bits/ioctls.h
new file mode 100644
index 0000000000..8122c103ec
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/ioctls.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IOCTL_H
+# error "Never use <bits/ioctls.h> directly; include <sys/ioctl.h> instead."
+#endif
+
+/* Use the definitions from the kernel header files. */
+#include <asm/ioctls.h>
+
+/* Oh well, this is necessary since the kernel data structure is
+ different from the user-level version. */
+#undef TCGETS
+#undef TCSETS
+#undef TCSETSW
+#undef TCSETSF
+#define TCGETS _IOR ('T', 16, char[36])
+#define TCSETS _IOW ('T', 17, char[36])
+#define TCSETSW _IOW ('T', 18, char[36])
+#define TCSETSF _IOW ('T', 19, char[36])
+
+#include <linux/sockios.h>
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/ipc.h b/sysdeps/unix/sysv/linux/hppa/bits/ipc.h
new file mode 100644
index 0000000000..89d3dd62f8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/ipc.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Mode bits for `msgget', `semget', and `shmget'. */
+#define IPC_CREAT 01000 /* Create key if key does not exist. */
+#define IPC_EXCL 02000 /* Fail if key exists. */
+#define IPC_NOWAIT 04000 /* Return error on wait. */
+
+/* Control commands for `msgctl', `semctl', and `shmctl'. */
+#define IPC_RMID 0 /* Remove identifier. */
+#define IPC_SET 1 /* Set `ipc_perm' options. */
+#define IPC_STAT 2 /* Get `ipc_perm' options. */
+#ifdef __USE_GNU
+# define IPC_INFO 3 /* See ipcs. */
+#endif
+
+/* Special key values. */
+#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+#if __WORDSIZE == 32
+ unsigned short int __pad1;
+ unsigned short int mode; /* Read/write permission. */
+ unsigned short int __pad2;
+#else
+ __mode_t mode; /* Read/write permission. */
+ unsigned short int __pad2;
+#endif
+ unsigned short int __seq; /* Sequence number. */
+ unsigned int __pad3;
+ __extension__ unsigned long long int __glibc_reserved1;
+ __extension__ unsigned long long int __glibc_reserved2;
+ };
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/mman.h b/sysdeps/unix/sysv/linux/hppa/bits/mman.h
new file mode 100644
index 0000000000..ae6683d073
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/mman.h
@@ -0,0 +1,112 @@
+/* Definitions for POSIX memory map interface. Linux/HPPA version.
+ Copyright (C) 1997-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_MMAN_H
+# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
+#endif
+
+/* These are taken from the kernel definitions. */
+
+#define PROT_READ 0x1 /* Page can be read */
+#define PROT_WRITE 0x2 /* Page can be written */
+#define PROT_EXEC 0x4 /* Page can be executed */
+#define PROT_NONE 0x0 /* Page can not be accessed */
+#define PROT_GROWSDOWN 0x01000000 /* Extend change to start of
+ growsdown vma (mprotect only). */
+#define PROT_GROWSUP 0x02000000 /* Extend change to start of
+ growsup vma (mprotect only). */
+
+#define MAP_SHARED 0x01 /* Share changes */
+#define MAP_PRIVATE 0x02 /* Changes are private */
+#ifdef __USE_MISC
+# define MAP_TYPE 0x03 /* Mask for type of mapping */
+#endif
+
+/* Other flags. */
+#define MAP_FIXED 0x04 /* Interpret addr exactly */
+#ifdef __USE_MISC
+# define MAP_FILE 0x0
+# define MAP_ANONYMOUS 0x10 /* Don't use a file */
+# define MAP_ANON MAP_ANONYMOUS
+# define MAP_VARIABLE 0
+/* When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. */
+# define MAP_HUGE_SHIFT 26
+# define MAP_HUGE_MASK 0x3f
+#endif
+
+/* These are Linux-specific. */
+#ifdef __USE_MISC
+# define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable */
+# define MAP_LOCKED 0x2000 /* Pages are locked */
+# define MAP_NORESERVE 0x4000 /* Don't check for reservations */
+# define MAP_GROWSDOWN 0x8000 /* Stack-like segment */
+# define MAP_POPULATE 0x10000 /* Populate (prefault) pagetables */
+# define MAP_NONBLOCK 0x20000 /* Do not block on IO */
+#endif
+
+/* Flags to "msync" */
+#define MS_SYNC 1 /* Synchronous memory sync */
+#define MS_ASYNC 2 /* Sync memory asynchronously */
+#define MS_INVALIDATE 4 /* Invalidate the caches */
+
+/* Flags to "mlockall" */
+#define MCL_CURRENT 1 /* Lock all current mappings */
+#define MCL_FUTURE 2 /* Lock all future mappings */
+
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
+/* Advice to "madvise" */
+#ifdef __USE_MISC
+# define MADV_NORMAL 0 /* No further special treatment */
+# define MADV_RANDOM 1 /* Expect random page references */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references */
+# define MADV_WILLNEED 3 /* Will need these pages */
+# define MADV_DONTNEED 4 /* Dont need these pages */
+# define MADV_SPACEAVAIL 5 /* Insure that resources are reserved */
+# define MADV_VPS_PURGE 6 /* Purge pages from VM page cache */
+# define MADV_VPS_INHERIT 7 /* Inherit parents page size */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
+# define MADV_MERGEABLE 65 /* KSM may merge identical pages */
+# define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */
+#endif
+
+/* The range 12-64 is reserved for page size specification. */
+#define MADV_4K_PAGES 12 /* Use 4K pages */
+#define MADV_16K_PAGES 14 /* Use 16K pages */
+#define MADV_64K_PAGES 16 /* Use 64K pages */
+#define MADV_256K_PAGES 18 /* Use 256K pages */
+#define MADV_1M_PAGES 20 /* Use 1 Megabyte pages */
+#define MADV_4M_PAGES 22 /* Use 4 Megabyte pages */
+#define MADV_16M_PAGES 24 /* Use 16 Megabyte pages */
+#define MADV_64M_PAGES 26 /* Use 64 Megabyte pages */
+
+/* The POSIX people had to invent similar names for the same things. */
+#ifdef __USE_XOPEN2K
+# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
+# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
+# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
+# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/msq.h b/sysdeps/unix/sysv/linux/hppa/bits/msq.h
new file mode 100644
index 0000000000..60db3413e4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/msq.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Define options for message queue functions. */
+#define MSG_NOERROR 010000 /* no error if message is too big */
+#ifdef __USE_GNU
+# define MSG_EXCEPT 020000 /* recv any msg except of specified type */
+# define MSG_COPY 040000 /* copy (not remove) all queue messages */
+#endif
+
+/* Types used in the structure definition. */
+typedef unsigned long int msgqnum_t;
+typedef unsigned long int msglen_t;
+
+
+/* Structure of record for one message inside the kernel.
+ The type `struct msg' is opaque. */
+struct msqid_ds
+{
+ struct ipc_perm msg_perm; /* structure describing operation permission */
+#if __WORDSIZE == 32
+ unsigned int __pad1;
+#endif
+ __time_t msg_stime; /* time of last msgsnd command */
+#if __WORDSIZE == 32
+ unsigned int __pad2;
+#endif
+ __time_t msg_rtime; /* time of last msgrcv command */
+#if __WORDSIZE == 32
+ unsigned int __pad3;
+#endif
+ __time_t msg_ctime; /* time of last change */
+ unsigned long int __msg_cbytes; /* current number of bytes on queue */
+ msgqnum_t msg_qnum; /* number of messages currently on queue */
+ msglen_t msg_qbytes; /* max number of bytes allowed on queue */
+ __pid_t msg_lspid; /* pid of last msgsnd() */
+ __pid_t msg_lrpid; /* pid of last msgrcv() */
+ unsigned long int __glibc_reserved1;
+ unsigned long int __glibc_reserved2;
+};
+
+#ifdef __USE_MISC
+
+# define msg_cbytes __msg_cbytes
+
+/* ipcs ctl commands */
+# define MSG_STAT 11
+# define MSG_INFO 12
+
+/* buffer for msgctl calls IPC_INFO, MSG_INFO */
+struct msginfo
+ {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short int msgseg;
+ };
+
+#endif /* __USE_MISC */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/sem.h b/sysdeps/unix/sysv/linux/hppa/bits/sem.h
new file mode 100644
index 0000000000..75c2605398
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/sem.h
@@ -0,0 +1,91 @@
+/* Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_SEM_H
+# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead."
+#endif
+
+#include <sys/types.h>
+#include <bits/wordsize.h>
+
+/* Flags for `semop'. */
+#define SEM_UNDO 0x1000 /* undo the operation on exit */
+
+/* Commands for `semctl'. */
+#define GETPID 11 /* get sempid */
+#define GETVAL 12 /* get semval */
+#define GETALL 13 /* get all semval's */
+#define GETNCNT 14 /* get semncnt */
+#define GETZCNT 15 /* get semzcnt */
+#define SETVAL 16 /* set semval */
+#define SETALL 17 /* set all semval's */
+
+
+/* Data structure describing a set of semaphores. */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+#if __WORDSIZE == 32
+ unsigned int __pad1;
+#endif
+ __time_t sem_otime; /* last semop() time */
+#if __WORDSIZE == 32
+ unsigned int __pad2;
+#endif
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __glibc_reserved1;
+ unsigned long int __glibc_reserved2;
+};
+
+/* The user should define a union like the following to use it for arguments
+ for `semctl'.
+
+ union semun
+ {
+ int val; <= value for SETVAL
+ struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
+ unsigned short int *array; <= array for GETALL & SETALL
+ struct seminfo *__buf; <= buffer for IPC_INFO
+ };
+
+ Previous versions of this file used to define this union but this is
+ incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
+ one must define the union or not. */
+#define _SEM_SEMUN_UNDEFINED 1
+
+#ifdef __USE_MISC
+
+/* ipcs ctl cmds */
+# define SEM_STAT 18
+# define SEM_INFO 19
+
+struct seminfo
+{
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#endif /* __USE_MISC */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/shm.h b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
new file mode 100644
index 0000000000..ec5de39fd3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/shm.h
@@ -0,0 +1,106 @@
+/* Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_SHM_H
+# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead."
+#endif
+
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* Permission flag for shmget. */
+#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */
+#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */
+
+/* Flags for `shmat'. */
+#define SHM_RDONLY 010000 /* attach read-only else read-write */
+#define SHM_RND 020000 /* round attach address to SHMLBA */
+#define SHM_REMAP 040000 /* take-over region on attach */
+
+/* Commands for `shmctl'. */
+#define SHM_LOCK 11 /* lock segment (root only) */
+#define SHM_UNLOCK 12 /* unlock segment (root only) */
+
+/* Segment low boundary address multiple. */
+#define SHMLBA 0x00400000 /* address needs to be 4 Mb aligned */
+
+/* Type to count number of attaches. */
+typedef unsigned long int shmatt_t;
+
+/* Data structure describing a shared memory segment. */
+struct shmid_ds
+ {
+ struct ipc_perm shm_perm; /* operation permission struct */
+#if __WORDSIZE == 32
+ unsigned int __pad1;
+#endif
+ __time_t shm_atime; /* time of last shmat() */
+#if __WORDSIZE == 32
+ unsigned int __pad2;
+#endif
+ __time_t shm_dtime; /* time of last shmdt() */
+#if __WORDSIZE == 32
+ unsigned int __pad3;
+#endif
+ __time_t shm_ctime; /* time of last change by shmctl() */
+#if __WORDSIZE == 32
+ unsigned int __pad4;
+#endif
+ size_t shm_segsz; /* size of segment in bytes */
+ __pid_t shm_cpid; /* pid of creator */
+ __pid_t shm_lpid; /* pid of last shmop */
+ shmatt_t shm_nattch; /* number of current attaches */
+ unsigned long int __glibc_reserved1;
+ unsigned long int __glibc_reserved2;
+ };
+
+#ifdef __USE_MISC
+
+/* ipcs ctl commands */
+# define SHM_STAT 13
+# define SHM_INFO 14
+
+/* shm_mode upper byte flags */
+# define SHM_DEST 01000 /* segment will be destroyed on last detach */
+# define SHM_LOCKED 02000 /* segment will not be swapped */
+# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */
+# define SHM_NORESERVE 010000 /* don't check for reservations */
+
+struct shminfo
+ {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __glibc_reserved1;
+ unsigned long __glibc_reserved2;
+ unsigned long __glibc_reserved3;
+ unsigned long __glibc_reserved4;
+ };
+
+struct shm_info
+ {
+ int used_ids;
+ unsigned long int shm_tot; /* total allocated shm */
+ unsigned long int shm_rss; /* total resident shm */
+ unsigned long int shm_swp; /* total swapped shm */
+ unsigned long int swap_attempts;
+ unsigned long int swap_successes;
+ };
+
+#endif /* __USE_MISC */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/sigaction.h b/sysdeps/unix/sysv/linux/hppa/bits/sigaction.h
new file mode 100644
index 0000000000..3b1638dc8e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/sigaction.h
@@ -0,0 +1,74 @@
+/* Definitions for Linux/HPPA sigaction.
+ Copyright (C) 1996-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
+#endif
+
+/* Structure describing the action to be taken when a signal arrives. */
+struct sigaction
+ {
+ /* Signal handler. */
+#ifdef __USE_POSIX199309
+ union
+ {
+ /* Used if SA_SIGINFO is not set. */
+ __sighandler_t sa_handler;
+ /* Used if SA_SIGINFO is set. */
+ void (*sa_sigaction) (int, siginfo_t *, void *);
+ }
+ __sigaction_handler;
+# define sa_handler __sigaction_handler.sa_handler
+# define sa_sigaction __sigaction_handler.sa_sigaction
+#else
+ __sighandler_t sa_handler;
+#endif
+
+ /* Special flags. */
+ unsigned long int sa_flags;
+
+ /* Additional set of signals to be blocked. */
+ __sigset_t sa_mask;
+ };
+
+/* Bits in `sa_flags'. */
+
+#define SA_NOCLDSTOP 0x00000008 /* Don't send SIGCHLD when children stop. */
+#define SA_NOCLDWAIT 0x00000080 /* Don't create zombie on child death. */
+#define SA_SIGINFO 0x00000010 /* Invoke signal-catching function with
+ three arguments instead of one. */
+#if defined __USE_UNIX98 || defined __USE_MISC
+# define SA_ONSTACK 0x00000001 /* Use signal stack by using `sa_restorer'. */
+# define SA_RESETHAND 0x00000004 /* Reset to SIG_DFL on entry to handler. */
+# define SA_NODEFER 0x00000020 /* Don't automatically block the signal
+ when its handler is being executed. */
+# define SA_RESTART 0x00000040 /* Restart syscall on signal return. */
+#endif
+#ifdef __USE_MISC
+# define SA_INTERRUPT 0x20000000 /* Historic no-op. */
+
+/* Some aliases for the SA_ constants. */
+# define SA_NOMASK SA_NODEFER
+# define SA_ONESHOT SA_RESETHAND
+# define SA_STACK SA_ONSTACK
+#endif
+
+/* Values for the HOW argument to `sigprocmask'. */
+#define SIG_BLOCK 0 /* for blocking signals */
+#define SIG_UNBLOCK 1 /* for unblocking signals */
+#define SIG_SETMASK 2 /* for setting the signal mask */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/signum.h b/sysdeps/unix/sysv/linux/hppa/bits/signum.h
new file mode 100644
index 0000000000..7f935c52a0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/signum.h
@@ -0,0 +1,81 @@
+/* Signal number definitions. Linux/HPPA version.
+ Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef _SIGNAL_H
+
+/* Fake signal functions. */
+#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
+
+#ifdef __USE_UNIX98
+# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */
+#endif
+
+
+/* Signals. */
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGABRT 6 /* Abort (ANSI). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGEMT 7
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGBUS 10 /* BUS error (4.2 BSD). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGSYS 12 /* Bad system call. */
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */
+#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGCHLD 18 /* Child status has changed (POSIX). */
+#define SIGPWR 19 /* Power failure restart (System V). */
+#define SIGVTALRM 20 /* Virtual alarm clock (4.2 BSD). */
+#define SIGPROF 21 /* Profiling alarm clock (4.2 BSD). */
+#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
+#define SIGIO 22 /* I/O now possible (4.2 BSD). */
+#define SIGWINCH 23 /* Window size change (4.3 BSD, Sun). */
+#define SIGSTOP 24 /* Stop, unblockable (POSIX). */
+#define SIGTSTP 25 /* Keyboard stop (POSIX). */
+#define SIGCONT 26 /* Continue (POSIX). */
+#define SIGTTIN 27 /* Background read from tty (POSIX). */
+#define SIGTTOU 28 /* Background write to tty (POSIX). */
+#define SIGURG 29 /* Urgent condition on socket (4.2 BSD). */
+#define SIGLOST 30 /* Operating System Has Lost (HP/UX). */
+#define SIGUNUSED 31
+#define SIGXCPU 33 /* CPU limit exceeded (4.2 BSD). */
+#define SIGXFSZ 34 /* File size limit exceeded (4.2 BSD). */
+#define SIGSTKFLT 36 /* Stack fault. */
+
+#define _NSIG 65 /* Biggest signal number + 1
+ (including real-time signals). */
+
+#define SIGRTMIN (__libc_current_sigrtmin ())
+#define SIGRTMAX (__libc_current_sigrtmax ())
+
+/* These are the hard limits of the kernel. These values should not be
+ used directly at user level. */
+#define __SIGRTMIN 37
+#define __SIGRTMAX (_NSIG - 1)
+
+#endif /* <signal.h> included. */
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/socket_type.h b/sysdeps/unix/sysv/linux/hppa/bits/socket_type.h
new file mode 100644
index 0000000000..0a404c6537
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/socket_type.h
@@ -0,0 +1,55 @@
+/* Define enum __socket_type for Linux/HP-PARISC.
+ Copyright (C) 2012-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_SOCKET_H
+# error "Never include <bits/socket_type.h> directly; use <sys/socket.h> instead."
+#endif
+
+/* Types of sockets. */
+enum __socket_type
+{
+ SOCK_STREAM = 1, /* Sequenced, reliable, connection-based
+ byte streams. */
+#define SOCK_STREAM SOCK_STREAM
+ SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams
+ of fixed maximum length. */
+#define SOCK_DGRAM SOCK_DGRAM
+ SOCK_RAW = 3, /* Raw protocol interface. */
+#define SOCK_RAW SOCK_RAW
+ SOCK_RDM = 4, /* Reliably-delivered messages. */
+#define SOCK_RDM SOCK_RDM
+ SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based,
+ datagrams of fixed maximum length. */
+#define SOCK_SEQPACKET SOCK_SEQPACKET
+ SOCK_DCCP = 6, /* Datagram Congestion Control Protocol. */
+#define SOCK_DCCP SOCK_DCCP
+ SOCK_PACKET = 10, /* Linux specific way of getting packets
+ at the dev level. For writing rarp and
+ other similar things on the user level. */
+#define SOCK_PACKET SOCK_PACKET
+
+ /* Flags to be ORed into the type parameter of socket and socketpair and
+ used for the flags parameter of paccept. */
+
+ SOCK_CLOEXEC = 010000000, /* Atomically set close-on-exec flag for the
+ new descriptor(s). */
+#define SOCK_CLOEXEC SOCK_CLOEXEC
+ SOCK_NONBLOCK = 0x40000000 /* Atomically mark descriptor(s) as
+ non-blocking. */
+#define SOCK_NONBLOCK SOCK_NONBLOCK
+};
diff --git a/sysdeps/unix/sysv/linux/hppa/brk.c b/sysdeps/unix/sysv/linux/hppa/brk.c
new file mode 100644
index 0000000000..2e0a8cfade
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/brk.c
@@ -0,0 +1,41 @@
+/* brk system call for Linux/HPPA.
+ Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep.h>
+
+/* This must be initialized data because commons can't have aliases. */
+void *__curbrk = 0;
+
+int
+__brk (void *addr)
+{
+ void *newbrk;
+
+ __curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr);
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/hppa/clone.S b/sysdeps/unix/sysv/linux/hppa/clone.S
new file mode 100644
index 0000000000..1a3c6c800d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/clone.S
@@ -0,0 +1,179 @@
+/* Copyright (C) 1996-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Huggins-Daines <dhd@debian.org>, 2000.
+ Based on the Alpha version by Richard Henderson <rth@tamu.edu>, 1996.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* clone() is even more special than fork() as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#include <asm/unistd.h>
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+/* Non-thread code calls __clone with the following parameters:
+ int clone(int (*fn)(void *arg),
+ void *child_stack,
+ int flags,
+ void *arg)
+
+ NPTL Code will call __clone with the following parameters:
+ int clone(int (*fn)(void *arg),
+ void *child_stack,
+ int flags,
+ void *arg,
+ int *parent_tidptr,
+ struct user_desc *newtls,
+ int *child_pidptr)
+
+ The code should not mangle the extra input registers.
+ Syscall expects: Input to __clone:
+ 4(r25) - function pointer (r26, arg0)
+ 0(r25) - argument (r23, arg3)
+ r26 - clone flags. (r24, arg2)
+ r25+64 - user stack pointer. (r25, arg1)
+ r24 - parent tid pointer. (stack - 52)
+ r23 - struct user_desc newtls pointer. (stack - 56)
+ r22 - child tid pointer. (stack - 60)
+ r20 - clone syscall number (constant)
+
+ Return:
+
+ On success the thread ID of the child process is returend in
+ the callers context.
+ On error return -1, and set errno to the value returned by
+ the syscall.
+ */
+
+ .text
+ENTRY(__clone)
+ /* Prologue */
+ stwm %r4, 64(%sp)
+ stw %sp, -4(%sp)
+#ifdef PIC
+ stw %r19, -32(%sp)
+#endif
+
+ /* Sanity check arguments. */
+ comib,=,n 0, %arg0, .LerrorSanity /* no NULL function pointers */
+ comib,=,n 0, %arg1, .LerrorSanity /* no NULL stack pointers */
+
+ /* Save the function pointer, arg, and flags on the new stack. */
+ stwm %r26, 64(%r25)
+ stw %r23, -60(%r25)
+ stw %r24, -56(%r25)
+ /* Clone arguments are (int flags, void * child_stack) */
+ copy %r24, %r26 /* flags are first */
+ /* User stack pointer is in the correct register already */
+
+ /* Load args from stack... */
+ ldw -116(%sp), %r24 /* Load parent_tidptr */
+ ldw -120(%sp), %r23 /* Load newtls */
+ ldw -124(%sp), %r22 /* Load child_tidptr */
+
+ /* Save the PIC register. */
+#ifdef PIC
+ copy %r19, %r4 /* parent */
+#endif
+
+ /* Do the system call */
+ ble 0x100(%sr2, %r0)
+ ldi __NR_clone, %r20
+
+ ldi -4096, %r1
+ comclr,>>= %r1, %ret0, %r0 /* Note: unsigned compare. */
+ b,n .LerrorRest
+
+ /* Restore the PIC register. */
+#ifdef PIC
+ copy %r4, %r19 /* parent */
+#endif
+
+ comib,=,n 0, %ret0, .LthreadStart
+
+ /* Successful return from the parent
+ No need to restore the PIC register,
+ since we return immediately. */
+
+ ldw -84(%sp), %rp
+ bv %r0(%rp)
+ ldwm -64(%sp), %r4
+
+.LerrorRest:
+ /* Something bad happened -- no child created */
+ bl __syscall_error, %rp
+ sub %r0, %ret0, %arg0
+ ldw -84(%sp), %rp
+ /* Return after setting errno, ret0 is set to -1 by __syscall_error. */
+ bv %r0(%rp)
+ ldwm -64(%sp), %r4
+
+.LerrorSanity:
+ /* Sanity checks failed, return -1, and set errno to EINVAL. */
+ bl __syscall_error, %rp
+ ldi EINVAL, %arg0
+ ldw -84(%sp), %rp
+ bv %r0(%rp)
+ ldwm -64(%sp), %r4
+
+.LthreadStart:
+#ifdef RESET_PID
+# define CLONE_VM_BIT 23 /* 0x00000100 */
+# define CLONE_THREAD_BIT 15 /* 0x00010000 */
+ /* Load original clone flags.
+ If CLONE_THREAD was passed, don't reset the PID/TID.
+ If CLONE_VM was passed, we need to store -1 to PID/TID.
+ If CLONE_VM and CLONE_THREAD were not set store the result
+ of getpid to PID/TID. */
+ ldw -56(%sp), %r26
+ bb,<,n %r26, CLONE_THREAD_BIT, 1f
+ bb,< %r26, CLONE_VM_BIT, 2f
+ ldi -1, %ret0
+ ble 0x100(%sr2, %r0)
+ ldi __NR_getpid, %r20
+2:
+ mfctl %cr27, %r26
+ stw %ret0, PID_THREAD_OFFSET(%r26)
+ stw %ret0, TID_THREAD_OFFSET(%r26)
+1:
+#endif
+ /* Load up the arguments. */
+ ldw -60(%sp), %arg0
+ ldw -64(%sp), %r22
+
+ /* $$dyncall fixes child's PIC register */
+
+ /* Call the user's function */
+#ifdef PIC
+ copy %r19, %r4
+#endif
+ bl $$dyncall, %r31
+ copy %r31, %rp
+#ifdef PIC
+ copy %r4, %r19
+#endif
+ /* The call to _exit needs saved r19. */
+ bl _exit, %rp
+ copy %ret0, %arg0
+
+ /* We should not return from _exit.
+ We do not restore r4, or the stack state. */
+ iitlbp %r0, (%sr0, %r0)
+
+PSEUDO_END(__clone)
+
+weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/hppa/fcntl.c b/sysdeps/unix/sysv/linux/hppa/fcntl.c
new file mode 100644
index 0000000000..ea951bc4f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/fcntl.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fcntl.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/fxstat.c b/sysdeps/unix/sysv/linux/hppa/fxstat.c
new file mode 100644
index 0000000000..4f219f0b9d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/fxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/fxstatat.c b/sysdeps/unix/sysv/linux/hppa/fxstatat.c
new file mode 100644
index 0000000000..0f8b3135d8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/fxstatat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/fxstatat.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/getcontext.S b/sysdeps/unix/sysv/linux/hppa/getcontext.S
new file mode 100644
index 0000000000..1d17d30f4f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/getcontext.S
@@ -0,0 +1,165 @@
+/* Get current user context.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Helge Deller <deller@gmx.de>, 2008.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ /* Trampoline function. Non-standard calling ABI. */
+ /* Can not use ENTRY(__getcontext_ret) here. */
+ .type __getcontext_ret, @function
+ .hidden __getcontext_ret
+__getcontext_ret:
+ .proc
+ .callinfo FRAME=0,NO_CALLS
+ /* r26-r23 contain original r3-r6, but because setcontext
+ does not reload r3-r6 (it's using them as temporaries)
+ we must save them elsewhere and swap them back in. */
+ copy %r23, %r3
+ copy %r24, %r4
+ copy %r25, %r5
+ copy %r26, %r6
+ /* r20 contains original return pointer. */
+ bv 0(%r20)
+ copy %r0, %ret0
+ .procend
+ .size __getcontext_ret, .-__getcontext_ret
+
+
+ENTRY(__getcontext)
+ /* Save the registers. */
+ stw %r0, oR0(%r26)
+ stw %r1, oR1(%r26)
+ /* stw %r2, oR2(%r26) - used for trampoline. */
+ stw %r3, oR3(%r26)
+ stw %r4, oR4(%r26)
+ stw %r5, oR5(%r26)
+ stw %r6, oR6(%r26)
+ stw %r7, oR7(%r26)
+ stw %r8, oR8(%r26)
+ stw %r9, oR9(%r26)
+ stw %r10, oR10(%r26)
+ stw %r11, oR11(%r26)
+ stw %r12, oR12(%r26)
+ stw %r13, oR13(%r26)
+ stw %r14, oR14(%r26)
+ stw %r15, oR15(%r26)
+ stw %r16, oR16(%r26)
+ stw %r17, oR17(%r26)
+ stw %r18, oR18(%r26)
+ stw %r19, oR19(%r26)
+ /* stw %r20, oR20(%r26) - used for trampoline. */
+ stw %r21, oR21(%r26)
+ stw %r22, oR22(%r26)
+ /* stw %r23, oR23(%r26) - used for trampoline. */
+ /* stw %r24, oR24(%r26) - used for trampoline. */
+ /* stw %r25, oR25(%r26) - used for trampoline. */
+ /* stw %r26, oR26(%r26) - used for trampoline. */
+ stw %r27, oR27(%r26)
+ stw %r28, oR28(%r26)
+ stw %r29, oR29(%r26)
+ stw %sp, oR30(%r26)
+ stw %r31, oR31(%r26)
+
+ stw %r0, oUC_FLAGS(%r26)
+ /* stw %r0, oUC_LINK(%r26) - Do not overwrite. */
+ stw %sp, oSS_SP(%r26)
+ stw %r0, oSS_FLAGS(%r26)
+ stw %r0, oSS_SIZE(%r26)
+
+ stw %r0, oSC_FLAGS(%r26)
+
+ stw %r0, oIASQ0(%r26)
+ stw %r0, oIASQ1(%r26)
+ stw %r0, oIAOQ0(%r26)
+ stw %r0, oIAOQ1(%r26)
+ stw %r0, oSAR(%r26) /* used as flag in swapcontext(). */
+
+
+ /* Store floating-point regs. */
+ ldo oFPREGS0(%r26),%r1
+ fstds,ma %fr0, 8(%r1)
+ fstds,ma %fr1, 8(%r1)
+ fstds,ma %fr2, 8(%r1)
+ fstds,ma %fr3, 8(%r1)
+ fstds,ma %fr4, 8(%r1)
+ fstds,ma %fr5, 8(%r1)
+ fstds,ma %fr6, 8(%r1)
+ fstds,ma %fr7, 8(%r1)
+ fstds,ma %fr8, 8(%r1)
+ fstds,ma %fr9, 8(%r1)
+ fstds,ma %fr10, 8(%r1)
+ fstds,ma %fr11, 8(%r1)
+ fstds,ma %fr12, 8(%r1)
+ fstds,ma %fr13, 8(%r1)
+ fstds,ma %fr14, 8(%r1)
+ fstds,ma %fr15, 8(%r1)
+ fstds,ma %fr16, 8(%r1)
+ fstds,ma %fr17, 8(%r1)
+ fstds,ma %fr18, 8(%r1)
+ fstds,ma %fr19, 8(%r1)
+ fstds,ma %fr20, 8(%r1)
+ fstds,ma %fr21, 8(%r1)
+ fstds,ma %fr22, 8(%r1)
+ fstds,ma %fr23, 8(%r1)
+ fstds,ma %fr24, 8(%r1)
+ fstds,ma %fr25, 8(%r1)
+ fstds,ma %fr26, 8(%r1)
+ fstds,ma %fr27, 8(%r1)
+ fstds,ma %fr28, 8(%r1)
+ fstds,ma %fr29, 8(%r1)
+ fstds,ma %fr30, 8(%r1)
+ fstds %fr31, 0(%r1)
+
+ /* Prologue */
+ stwm %r4, 64(%sp)
+#ifdef PIC
+ stw %r19, -32(%sp)
+#endif
+
+ /* Set up the trampoline registers.
+ r20, r23, r24, r25, r26 and r2 are clobbered
+ by call to getcontext() anyway. Reuse them. */
+ stw %r2, oR20(%r26)
+ stw %r3, oR23(%r26)
+ stw %r4, oR24(%r26)
+ stw %r5, oR25(%r26)
+ stw %r6, oR26(%r26)
+ ldil L%__getcontext_ret, %r1
+ ldo R%__getcontext_ret(%r1), %r1
+ stw %r1, oR2(%r26)
+
+ /* Save the current signal mask. */
+ /* sigprocmask(SIG_BLOCK, NULL, &ucp->uc_sigmask); */
+ ldo oSIGMASK(%r26), %r24
+ copy %r0, %r25
+ bl sigprocmask, %r2
+ ldi SIG_BLOCK, %r26
+
+ /* Epilogue */
+ ldw -84(%sp), %r2
+#ifdef PIC
+ ldw -96(%sp), %r19
+#endif
+ bv %r0(%r2)
+ ldwm -64(%sp), %r4
+END(__getcontext)
+
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/hppa/getdents64.c b/sysdeps/unix/sysv/linux/hppa/getdents64.c
new file mode 100644
index 0000000000..0c75fb5a06
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/getdents64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getdents64.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/getrlimit64.c b/sysdeps/unix/sysv/linux/hppa/getrlimit64.c
new file mode 100644
index 0000000000..fef018f471
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/getrlimit64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getrlimit64.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/internaltypes.h b/sysdeps/unix/sysv/linux/hppa/internaltypes.h
new file mode 100644
index 0000000000..651ce2ee45
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/internaltypes.h
@@ -0,0 +1,78 @@
+#include_next <internaltypes.h>
+#ifndef _INTERNAL_TYPES_H_HPPA_
+#define _INTERNAL_TYPES_H_HPPA_ 1
+#include <atomic.h>
+
+/* In GLIBC 2.10 HPPA switched from Linuxthreads to NPTL, and in order
+to maintain ABI compatibility with pthread_cond_t, some care had to be
+taken.
+
+The NPTL pthread_cond_t grew in size. When HPPA switched to NPTL, we
+dropped the use of ldcw, and switched to the kernel helper routine for
+compare-and-swap. This allowed HPPA to use the 4-word 16-byte aligned
+lock words, and alignment words to store the additional pthread_cond_t
+data. Once organized properly the new NPTL pthread_cond_t was 1 word
+smaller than the Linuxthreads version.
+
+However, we were faced with the case that users may have initialized the
+pthread_cond_t with PTHREAD_COND_INITIALIZER. In this case, the first
+four words were set to one, and must be cleared before any NPTL code
+used these words.
+
+We didn't want to use LDCW, because it continues to be a source of bugs
+when applications memset pthread_cond_t to all zeroes by accident. This
+works on all other architectures where lock words are unlocked at zero.
+Remember that because of the semantics of LDCW, a locked word is set to
+zero, and an unlocked word is set to 1.
+
+Instead we used atomic_compare_and_exchange_val_acq, but we couldn't use
+this on any of the pthread_cond_t words, otherwise it might interfere
+with the current operation of the structure. To solve this problem we
+used the left over word.
+
+If the stucture was initialized by a legacy Linuxthread
+PTHREAD_COND_INITIALIZER it contained a 1, and this indicates that the
+structure requires zeroing for NPTL. The first thread to come upon a
+pthread_cond_t with a 1 in the __initializer field, will
+compare-and-swap the value, placing a 2 there which will cause all other
+threads using the same pthread_cond_t to wait for the completion of the
+initialization. Lastly, we use a store (with memory barrier) to change
+__initializer from 2 to 0. Note that the store is strongly ordered, but
+we use the PA 1.1 compatible form which is ",ma" with zero offset.
+
+In the future, when the application is recompiled with NPTL
+PTHREAD_COND_INITIALIZER it will be a quick compare-and-swap, which
+fails because __initializer is zero, and the structure will be used as
+is correctly. */
+
+#define cond_compat_clear(var) \
+({ \
+ int tmp = 0; \
+ var->__data.__lock = 0; \
+ var->__data.__futex = 0; \
+ var->__data.__mutex = NULL; \
+ /* Clear __initializer last, to indicate initialization is done. */ \
+ __asm__ __volatile__ ("stw,ma %1,0(%0)" \
+ : : "r" (&var->__data.__initializer), "r" (tmp) : "memory"); \
+})
+
+#define cond_compat_check_and_clear(var) \
+({ \
+ int ret; \
+ volatile int *value = &var->__data.__initializer; \
+ if ((ret = atomic_compare_and_exchange_val_acq(value, 2, 1))) \
+ { \
+ if (ret == 1) \
+ { \
+ /* Initialize structure. */ \
+ cond_compat_clear (var); \
+ } \
+ else \
+ { \
+ /* Yield until structure is initialized. */ \
+ while (*value == 2) sched_yield (); \
+ } \
+ } \
+})
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
new file mode 100644
index 0000000000..e869c14bdd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
@@ -0,0 +1,44 @@
+/* Set flags signalling availability of kernel features based on given
+ kernel version number.
+ Copyright (C) 2006-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+
+/* There are an infinite number of PA-RISC kernel versions numbered
+ 2.4.0. But they've not really been released as such. We require
+ and expect the final version here. */
+#define __ASSUME_32BITUIDS 1
+#define __ASSUME_TRUNCATE64_SYSCALL 1
+#define __ASSUME_IPC64 1
+#define __ASSUME_ST_INO_64_BIT 1
+#define __ASSUME_GETDENTS64_SYSCALL 1
+
+/* PA-RISC 2.6.9 kernels had the first LWS CAS support */
+#define __ASSUME_LWS_CAS 1
+
+/* Support for the accept4 and recvmmsg syscalls was added in 2.6.34. */
+#if __LINUX_KERNEL_VERSION >= 0x020622
+# define __ASSUME_ACCEPT4_SYSCALL 1
+# define __ASSUME_RECVMMSG_SYSCALL 1
+#endif
+
+/* Support for the sendmmsg syscall was added in 3.1. */
+#if __LINUX_KERNEL_VERSION >= 0x030100
+# define __ASSUME_SENDMMSG_SYSCALL 1
+#endif
+
+#include_next <kernel-features.h>
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel_sigaction.h b/sysdeps/unix/sysv/linux/hppa/kernel_sigaction.h
new file mode 100644
index 0000000000..af048cbe7d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/kernel_sigaction.h
@@ -0,0 +1,18 @@
+/* We have a separate header file here because we do not support
+ SA_RESTORER on hppa. */
+
+/* This is the sigaction struction from the Linux 2.1.20 kernel. */
+/* Blah. This is bogus. We don't ever use it. */
+struct old_kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned long sa_mask;
+ unsigned long sa_flags;
+};
+
+/* This is the sigaction structure from the Linux 2.1.68 kernel. */
+
+struct kernel_sigaction {
+ __sighandler_t k_sa_handler;
+ unsigned long sa_flags;
+ sigset_t sa_mask;
+};
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel_stat.h b/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
new file mode 100644
index 0000000000..e3ea72402f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/kernel_stat.h
@@ -0,0 +1,31 @@
+/* definition of "struct stat" from the kernel */
+struct kernel_stat {
+ unsigned long st_dev; /* dev_t is 32 bits on parisc */
+ unsigned long st_ino; /* 32 bits */
+ unsigned short st_mode; /* 16 bits */
+ unsigned short st_nlink; /* 16 bits */
+ unsigned short st_reserved1; /* old st_uid */
+ unsigned short st_reserved2; /* old st_gid */
+ unsigned long st_rdev;
+ unsigned long st_size;
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+ long st_blksize;
+ long st_blocks;
+ unsigned long __glibc_reserved1; /* ACL stuff */
+ unsigned long __glibc_reserved2; /* network */
+ unsigned long __glibc_reserved3; /* network */
+ unsigned long __glibc_reserved4; /* cnodes */
+ unsigned short __glibc_reserved5; /* netsite */
+ short st_fstype;
+ unsigned long st_realdev;
+ unsigned short st_basemode;
+ unsigned short st_spareshort;
+ unsigned long st_uid;
+ unsigned long st_gid;
+ unsigned long st_spare4[3];
+};
+
+#define _HAVE_STAT_NSEC
+#define _HAVE_STAT64_NSEC
diff --git a/sysdeps/unix/sysv/linux/hppa/lxstat.c b/sysdeps/unix/sysv/linux/hppa/lxstat.c
new file mode 100644
index 0000000000..0efa0aea49
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/lxstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lxstat.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/makecontext.c b/sysdeps/unix/sysv/linux/hppa/makecontext.c
new file mode 100644
index 0000000000..c8a1599d07
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/makecontext.c
@@ -0,0 +1,99 @@
+/* Create new context.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Helge Deller <deller@gmx.de>, 2008.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libintl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysdep.h>
+#include <ucontext.h>
+
+/* POSIX only supports integer arguments. */
+
+/* Stack must be 64-byte aligned at all times. */
+#define STACK_ALIGN 64
+/* Size of frame marker in unsigned long words. */
+#define FRAME_SIZE_UL 8
+/* Size of frame marker in bytes. */
+#define FRAME_SIZE_BYTES (8 * sizeof(unsigned long))
+/* Size of X arguments in bytes. */
+#define ARGS(x) (x * sizeof(unsigned long))
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ unsigned long *sp, *osp;
+ va_list ap;
+ int i;
+
+ /* Create a 64-byte aligned frame to store args. Use ss_sp if
+ it is available, otherwise be robust and use the currently
+ saved stack pointer. */
+ if (ucp->uc_stack.ss_sp && ucp->uc_stack.ss_size)
+ osp = (unsigned long *)ucp->uc_stack.ss_sp;
+ else
+ osp = (unsigned long *)ucp->uc_mcontext.sc_gr[30];
+
+ sp = (unsigned long *)((((unsigned long) osp)
+ + FRAME_SIZE_BYTES + ARGS(argc) + STACK_ALIGN)
+ & ~(STACK_ALIGN - 1));
+
+ /* Use new frame. */
+ ucp->uc_mcontext.sc_gr[30] = ((unsigned long) sp);
+
+ /* Finish frame setup. */
+ if (ucp->uc_link)
+ {
+ /* Returning to the next context and next frame. */
+ sp[-4/sizeof(unsigned long)] = ucp->uc_link->uc_mcontext.sc_gr[30];
+ sp[-20/sizeof(unsigned long)] = ucp->uc_link->uc_mcontext.sc_gr[2];
+ }
+ else
+ {
+ /* This is the main context. No frame marker, and no return address. */
+ sp[-4/sizeof(unsigned long)] = 0x0;
+ sp[-20/sizeof(unsigned long)] = 0x0;
+ }
+
+ /* Store address to jump to. */
+ ucp->uc_mcontext.sc_gr[2] = (unsigned long) func;
+
+ /* Process arguments. */
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ {
+ if (i < 4)
+ {
+ ucp->uc_mcontext.sc_gr[26-i] = va_arg (ap, int);
+ continue;
+ }
+
+ if ((i < 8) && (sizeof(unsigned long) == 8))
+ {
+ /* 64bit: r19-r22 are arg7-arg4. */
+ ucp->uc_mcontext.sc_gr[22+4-i] = va_arg (ap, int);
+ continue;
+ }
+
+ /* All other arguments go on the stack. */
+ sp[-1 * (FRAME_SIZE_UL + 1 + i)] = va_arg (ap, int);
+ }
+ va_end (ap);
+}
+weak_alias(__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/hppa/mmap.c b/sysdeps/unix/sysv/linux/hppa/mmap.c
new file mode 100644
index 0000000000..174cd5e54f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/mmap.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 1994-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+/* Map addresses starting near ADDR and extending for LEN bytes. From
+ OFFSET into the file FD describes according to PROT and FLAGS. If ADDR
+ is nonzero, it is the desired mapping address. If the MAP_FIXED bit is
+ set in FLAGS, the mapping will be at ADDR exactly (which must be
+ page-aligned); otherwise the system chooses a convenient nearby address.
+ The return value is the actual mapping address chosen or MAP_FAILED
+ for errors (in which case `errno' is set). A successful `mmap' call
+ deallocates any previous mapping for the affected region. */
+
+#include <sysdep.h>
+
+__ptr_t
+__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+
+ __ptr_t ret;
+
+ ret = (__ptr_t) INLINE_SYSCALL (mmap, 6, addr, len, prot, flags, fd, offset);
+
+ /* check if it's really a negative number */
+ if(((unsigned long)ret & 0xfffff000) == 0xfffff000)
+ return MAP_FAILED;
+
+ return ret;
+
+}
+
+strong_alias (__mmap, mmap)
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h b/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h
new file mode 100644
index 0000000000..a79c195d9a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/bits/pthreadtypes.h
@@ -0,0 +1,228 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_PTHREADTYPES_H
+#define _BITS_PTHREADTYPES_H 1
+
+/* Linuxthread type sizes (bytes):
+ sizeof(pthread_attr_t) = 0x24 (36)
+ sizeof(pthread_barrier_t) = 0x30 (48)
+ sizeof(pthread_barrierattr_t) = 0x4 (4)
+ sizeof(pthread_cond_t) = 0x30 (48)
+ sizeof(pthread_condattr_t) = 0x4 (4)
+ sizeof(pthread_mutex_t) = 0x30 (48)
+ sizeof(pthread_mutexattr_t) = 0x4 (4)
+ sizeof(pthread_rwlock_t) = 0x40 (64)
+ sizeof(pthread_rwlockattr_t) = 0x8 (8)
+ sizeof(pthread_spinlock_t) = 0x10 (16) */
+
+#define __SIZEOF_PTHREAD_ATTR_T 36
+#define __SIZEOF_PTHREAD_BARRIER_T 48
+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4
+#define __SIZEOF_PTHREAD_COND_T 48
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+#define __SIZEOF_PTHREAD_MUTEX_T 48
+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4
+#define __SIZEOF_PTHREAD_RWLOCK_T 64
+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8
+
+/* Thread identifiers. The structure of the attribute type is not
+ exposed on purpose. */
+typedef unsigned long int pthread_t;
+
+union pthread_attr_t
+{
+ char __size[__SIZEOF_PTHREAD_ATTR_T];
+ long int __align;
+};
+#ifndef __have_pthread_attr_t
+typedef union pthread_attr_t pthread_attr_t;
+# define __have_pthread_attr_t 1
+#endif
+
+
+typedef struct __pthread_internal_slist
+{
+ struct __pthread_internal_slist *__next;
+} __pthread_slist_t;
+
+
+/* Data structures for mutex handling. The structure of the attribute
+ type is not exposed on purpose. */
+typedef union
+{
+ struct __pthread_mutex_s
+ {
+ int __lock __attribute__ ((aligned(16)));
+ unsigned int __count;
+ int __owner;
+ /* KIND must stay at this position in the structure to maintain
+ binary compatibility. */
+ int __kind;
+ /* The old 4-word 16-byte aligned lock. This is initalized
+ to all ones by the Linuxthreads PTHREAD_MUTEX_INITIALIZER.
+ Unused in NPTL. */
+ int __compat_padding[4];
+ /* In the old structure there are 4 words left due to alignment.
+ In NPTL two words are used. */
+ unsigned int __nusers;
+ __extension__ union
+ {
+ int __spins;
+ __pthread_slist_t __list;
+ };
+ /* Two more words are left before the NPTL
+ pthread_mutex_t is larger than Linuxthreads. */
+ int __reserved1;
+ int __reserved2;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_MUTEX_T];
+ long int __align;
+} pthread_mutex_t;
+
+/* Mutex __spins initializer used by PTHREAD_MUTEX_INITIALIZER. */
+#define __PTHREAD_SPINS 0
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_MUTEXATTR_T];
+ long int __align;
+} pthread_mutexattr_t;
+
+
+/* Data structure for conditional variable handling. The structure of
+ the attribute type is not exposed on purpose. However, this structure
+ is exposed via PTHREAD_COND_INITIALIZER, and because of this, the
+ Linuxthreads version sets the first four ints to one. In the NPTL
+ version we must check, in every function using pthread_cond_t,
+ for the static Linuxthreads initializer and clear the appropriate
+ words. */
+typedef union
+{
+ struct
+ {
+ /* In the old Linuxthreads pthread_cond_t, this is the
+ start of the 4-word lock structure, the next four words
+ are set all to 1 by the Linuxthreads
+ PTHREAD_COND_INITIALIZER. */
+ int __lock __attribute__ ((aligned(16)));
+ /* Tracks the initialization of this structure:
+ 0 initialized with NPTL PTHREAD_COND_INITIALIZER.
+ 1 initialized with Linuxthreads PTHREAD_COND_INITIALIZER.
+ 2 initialization in progress. */
+ int __initializer;
+ unsigned int __futex;
+ void *__mutex;
+ /* In the old Linuxthreads this would have been the start
+ of the pthread_fastlock status word. */
+ __extension__ unsigned long long int __total_seq;
+ __extension__ unsigned long long int __wakeup_seq;
+ __extension__ unsigned long long int __woken_seq;
+ unsigned int __nwaiters;
+ unsigned int __broadcast_seq;
+ /* The NPTL pthread_cond_t is exactly the same size as
+ the Linuxthreads version, there are no words to spare. */
+ } __data;
+ char __size[__SIZEOF_PTHREAD_COND_T];
+ __extension__ long long int __align;
+} pthread_cond_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ long int __align;
+} pthread_condattr_t;
+
+
+/* Keys for thread-specific data */
+typedef unsigned int pthread_key_t;
+
+
+/* Once-only execution */
+typedef int pthread_once_t;
+
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K
+/* Data structure for read-write lock variable handling. The
+ structure of the attribute type is not exposed on purpose. */
+typedef union
+{
+ struct
+ {
+ /* In the old Linuxthreads pthread_rwlock_t, this is the
+ start of the 4-word 16-byte aligned lock structure. The
+ next four words are all set to 1 by the Linuxthreads
+ PTHREAD_RWLOCK_INITIALIZER. We ignore them in NPTL. */
+ int __compat_padding[4] __attribute__ ((aligned(16)));
+ int __lock;
+ unsigned int __nr_readers;
+ unsigned int __readers_wakeup;
+ unsigned int __writer_wakeup;
+ unsigned int __nr_readers_queued;
+ unsigned int __nr_writers_queued;
+ int __writer;
+ /* An unused word, reserved for future use. It was added
+ to maintain the location of the flags from the Linuxthreads
+ layout of this structure. */
+ int __reserved1;
+ /* FLAGS must stay at this position in the structure to maintain
+ binary compatibility. */
+ unsigned char __pad2;
+ unsigned char __pad1;
+ unsigned char __shared;
+ unsigned char __flags;
+ /* The NPTL pthread_rwlock_t is 4 words smaller than the
+ Linuxthreads version. One word is in the middle of the
+ structure, the other three are at the end. */
+ int __reserved2;
+ int __reserved3;
+ int __reserved4;
+ } __data;
+ char __size[__SIZEOF_PTHREAD_RWLOCK_T];
+ long int __align;
+} pthread_rwlock_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_RWLOCKATTR_T];
+ long int __align;
+} pthread_rwlockattr_t;
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* POSIX spinlock data type. */
+typedef volatile int pthread_spinlock_t;
+
+
+/* POSIX barriers data type. The structure of the type is
+ deliberately not exposed. */
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIER_T];
+ long int __align;
+} pthread_barrier_t;
+
+typedef union
+{
+ char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
+ int __align;
+} pthread_barrierattr_t;
+#endif
+
+
+#endif /* bits/pthreadtypes.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/bits/semaphore.h b/sysdeps/unix/sysv/linux/hppa/nptl/bits/semaphore.h
new file mode 100644
index 0000000000..9d68d44e31
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/bits/semaphore.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2002-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SEMAPHORE_H
+# error "Never use <bits/semaphore.h> directly; include <semaphore.h> instead."
+#endif
+
+#define __SIZEOF_SEM_T 16
+
+/* Value returned if `sem_open' failed. */
+#define SEM_FAILED ((sem_t *) 0)
+
+typedef union
+{
+ char __size[__SIZEOF_SEM_T];
+ long int __align;
+} sem_t;
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/clone.S b/sysdeps/unix/sysv/linux/hppa/nptl/clone.S
new file mode 100644
index 0000000000..23750b3f88
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/clone.S
@@ -0,0 +1,3 @@
+#define RESET_PID
+#include <tcb-offsets.h>
+#include "../clone.S"
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/createthread.c b/sysdeps/unix/sysv/linux/hppa/nptl/createthread.c
new file mode 100644
index 0000000000..5e96513ca8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/createthread.c
@@ -0,0 +1,22 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Value passed to 'clone' for initialization of the thread register. */
+#define TLS_VALUE (pd + 1)
+
+/* Get the real implementation. */
+#include <nptl/sysdeps/pthread/createthread.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/fork.c b/sysdeps/unix/sysv/linux/hppa/nptl/fork.c
new file mode 100644
index 0000000000..3c21f5aef9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/fork.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sched.h>
+#include <signal.h>
+#include <sysdep.h>
+#include <tls.h>
+
+/* Argument 1 - Clone flags.
+ 2 - Child stack pointer.
+ 3 - Parent tid pointer.
+ 4 - New TLS area pointer.
+ 5 - Child tid pointer. */
+#define ARCH_FORK() \
+ INLINE_SYSCALL (clone, 5, \
+ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, \
+ NULL, NULL, NULL, &THREAD_SELF->tid)
+
+#include <nptl/sysdeps/unix/sysv/linux/fork.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/libc-lowlevellock.c b/sysdeps/unix/sysv/linux/hppa/nptl/libc-lowlevellock.c
new file mode 100644
index 0000000000..8f50fed615
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/libc-lowlevellock.c
@@ -0,0 +1,20 @@
+/* low level locking for pthread library. Generic futex-using version.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "lowlevellock.c"
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c
new file mode 100644
index 0000000000..0c39423d4d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c
@@ -0,0 +1,126 @@
+/* low level locking for pthread library. Generic futex-using version.
+ Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Paul Mackerras <paulus@au.ibm.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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <lowlevellock.h>
+#include <sys/time.h>
+
+void
+__lll_lock_wait (lll_lock_t *futex, int private)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2, private);
+ }
+ while (atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0);
+}
+
+void
+__lll_lock_wait_private (lll_lock_t *futex)
+{
+ do
+ {
+ int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_wait (futex, 2, LLL_PRIVATE);
+ }
+ while (atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0);
+}
+
+int
+__lll_timedlock_wait (lll_lock_t *futex, const struct timespec *abstime, int private)
+{
+ /* Reject invalid timeouts. */
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ do
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) __gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait. */
+ int oldval = atomic_compare_and_exchange_val_acq (futex, 2, 1);
+ if (oldval != 0)
+ lll_futex_timed_wait (futex, 2, &rt, private);
+ }
+ while (atomic_compare_and_exchange_bool_acq (futex, 2, 0) != 0);
+ return 0;
+}
+
+
+/* These don't get included in libc.so */
+#ifdef IS_IN_libpthread
+int
+__lll_timedwait_tid (int *tidp, const struct timespec *abstime)
+{
+ int tid;
+
+ if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+ return EINVAL;
+
+ /* Repeat until thread terminated. */
+ while ((tid = *tidp) != 0)
+ {
+ struct timeval tv;
+ struct timespec rt;
+
+ /* Get the current time. */
+ (void) __gettimeofday (&tv, NULL);
+
+ /* Compute relative timeout. */
+ rt.tv_sec = abstime->tv_sec - tv.tv_sec;
+ rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+ if (rt.tv_nsec < 0)
+ {
+ rt.tv_nsec += 1000000000;
+ --rt.tv_sec;
+ }
+
+ /* Already timed out? */
+ if (rt.tv_sec < 0)
+ return ETIMEDOUT;
+
+ /* Wait until thread terminates. */
+ if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
new file mode 100644
index 0000000000..bd16f77cf2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h
@@ -0,0 +1,352 @@
+/* Copyright (C) 2003-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _LOWLEVELLOCK_H
+#define _LOWLEVELLOCK_H 1
+
+#include <time.h>
+#include <sys/param.h>
+#include <bits/pthreadtypes.h>
+#include <sysdep.h>
+#include <atomic.h>
+#include <kernel-features.h> /* Need __ASSUME_PRIVATE_FUTEX. */
+#include <tls.h> /* Need THREAD_*, and header.*. */
+
+/* HPPA only has one atomic read and modify memory operation,
+ load and clear, so hppa uses a kernel helper routine to implement
+ compare_and_exchange. See atomic.h for the userspace calling
+ sequence. */
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1)
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_WAIT_BITSET 9
+#define FUTEX_WAKE_BITSET 10
+#define FUTEX_WAIT_REQUEUE_PI 11
+#define FUTEX_CMP_REQUEUE_PI 12
+#define FUTEX_PRIVATE_FLAG 128
+#define FUTEX_CLOCK_REALTIME 256
+
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
+/* Values for 'private' parameter of locking macros. Yes, the
+ definition seems to be backwards. But it is not. The bit will be
+ reversed before passing to the system call. */
+#define LLL_PRIVATE 0
+#define LLL_SHARED FUTEX_PRIVATE_FLAG
+
+/* Initialize locks to zero. */
+#define LLL_MUTEX_LOCK_INITIALIZER (0)
+
+#if !defined NOT_IN_libc || defined IS_IN_rtld
+/* In libc.so or ld.so all futexes are private. */
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ ((fl) | FUTEX_PRIVATE_FLAG)
+# else
+# define __lll_private_flag(fl, private) \
+ ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))
+# endif
+#else
+# ifdef __ASSUME_PRIVATE_FUTEX
+# define __lll_private_flag(fl, private) \
+ (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
+# else
+# define __lll_private_flag(fl, private) \
+ (__builtin_constant_p (private) \
+ ? ((private) == 0 \
+ ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
+ : (fl)) \
+ : ((fl) | (((private) ^ FUTEX_PRIVATE_FLAG) \
+ & THREAD_GETMEM (THREAD_SELF, header.private_futex))))
+# endif
+#endif
+
+/* Type for lock object. */
+typedef int lll_lock_t;
+
+#define lll_futex_wait(futexp, val, private) \
+ lll_futex_timed_wait (futexp, val, 0, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (timespec)); \
+ __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ __ret; \
+ })
+
+#define lll_private_futex_wait(futex, val) \
+ lll_private_futex_timed_wait (futex, val, NULL)
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+# define lll_private_futex_timed_wait(futexp, val, timespec) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, \
+ (futexp), FUTEX_WAIT | FUTEX_PRIVATE_FLAG, \
+ (val), (timespec)); \
+ __ret; \
+ })
+#else
+# define lll_private_futex_timed_wait(futexp, val, timespec) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret, __op; \
+ __op = FUTEX_WAIT | THREAD_GETMEM (THREAD_SELF, header.private_futex); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 4, \
+ (futexp), __op, (val), (timespec)); \
+ __ret; \
+ })
+#endif
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ __ret; \
+ })
+
+#define lll_robust_dead(futexv, private) \
+ do \
+ { \
+ int *__futexp = &(futexv); \
+ atomic_or (__futexp, FUTEX_OWNER_DIED); \
+ lll_futex_wake (__futexp, 1, private); \
+ } \
+ while (0)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ __ret; \
+ })
+
+/* Priority Inheritance support. */
+#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \
+ lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private)
+
+#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \
+ mutex, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 5, (futexp), \
+ __lll_private_flag (__op, private), \
+ (val), (timespec), mutex); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret; \
+ \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_trylock (int *futex, int id)
+{
+ return atomic_compare_and_exchange_val_acq (futex, id, 0) != 0;
+}
+#define lll_robust_trylock(futex, id) \
+ __lll_robust_trylock (&(futex), id)
+
+static inline int
+__attribute__ ((always_inline))
+__lll_cond_trylock (int *futex)
+{
+ return atomic_compare_and_exchange_val_acq (futex, 2, 0) != 0;
+}
+#define lll_cond_trylock(futex) __lll_cond_trylock (&(futex))
+
+static inline int
+__attribute__ ((always_inline))
+__lll_trylock (int *futex)
+{
+ return atomic_compare_and_exchange_val_acq (futex, 1, 0) != 0;
+}
+#define lll_trylock(futex) __lll_trylock (&(futex))
+
+extern void __lll_lock_wait (lll_lock_t *futex, int private) attribute_hidden;
+extern void __lll_lock_wait_private (lll_lock_t *futex) attribute_hidden;
+
+static inline void __attribute__((always_inline))
+__lll_mutex_lock(lll_lock_t *futex, int private)
+{
+ int val = atomic_compare_and_exchange_val_acq (futex, 1, 0);
+
+ if (__builtin_expect (val != 0, 0))
+ {
+ if (__builtin_constant_p (private) && private == LLL_PRIVATE)
+ __lll_lock_wait_private (futex);
+ else
+ __lll_lock_wait (futex, private);
+ }
+}
+#define lll_mutex_lock(futex, private) __lll_mutex_lock (&(futex), private)
+#define lll_lock(lock, private) lll_mutex_lock (lock, private)
+
+extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
+
+static inline int
+__attribute__ ((always_inline))
+__lll_robust_lock (int *futex, int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_lock_wait (futex, private);
+ return result;
+}
+#define lll_robust_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), id, private)
+
+#define lll_robust_cond_lock(futex, id, private) \
+ __lll_robust_lock (&(futex), (id) | FUTEX_WAITERS, private)
+
+static inline void
+__attribute__ ((always_inline))
+__lll_cond_lock (int *futex, int private)
+{
+ int val = atomic_compare_and_exchange_val_acq (futex, 2, 0);
+
+ if (__builtin_expect (val != 0, 0))
+ __lll_lock_wait (futex, private);
+}
+#define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
+
+extern int __lll_timedlock_wait (lll_lock_t *futex, const struct timespec *,
+ int private) attribute_hidden;
+extern int __lll_robust_timedlock_wait (int *futex, const struct timespec *,
+ int private) attribute_hidden;
+
+static inline int
+__attribute__ ((always_inline))
+__lll_timedlock (int *futex, const struct timespec *abstime, int private)
+{
+ int val = atomic_compare_and_exchange_val_acq (futex, 1, 0);
+ int result = 0;
+
+ if (__builtin_expect (val != 0, 0))
+ result = __lll_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_timedlock(futex, abstime, private) \
+ __lll_timedlock (&(futex), abstime, private)
+
+static inline int __attribute__ ((always_inline))
+__lll_robust_timedlock (int *futex, const struct timespec *abstime,
+ int id, int private)
+{
+ int result = 0;
+ if (atomic_compare_and_exchange_bool_acq (futex, id, 0) != 0)
+ result = __lll_robust_timedlock_wait (futex, abstime, private);
+ return result;
+}
+#define lll_robust_timedlock(futex, abstime, id, private) \
+ __lll_robust_timedlock (&(futex), abstime, id, private)
+
+#define __lll_unlock(futex, private) \
+ (void) \
+ ({ int val = atomic_exchange_rel (futex, 0); \
+ if (__builtin_expect (val > 1, 0)) \
+ lll_futex_wake (futex, 1, private); \
+ })
+#define lll_unlock(futex, private) __lll_unlock(&(futex), private)
+
+#define __lll_robust_unlock(futex,private) \
+ (void) \
+ ({ int val = atomic_exchange_rel (futex, 0); \
+ if (__builtin_expect (val & FUTEX_WAITERS, 0)) \
+ lll_futex_wake (futex, 1, private); \
+ })
+#define lll_robust_unlock(futex, private) \
+ __lll_robust_unlock(&(futex), private)
+
+#define lll_islocked(futex) \
+ (futex != 0)
+
+/* Our internal lock implementation is identical to the binary-compatible
+ mutex implementation. */
+#define LLL_LOCK_INITIALIZER (0)
+#define LLL_LOCK_INITIALIZER_CONST (0)
+#define LLL_LOCK_INITIALIZER_LOCKED (1)
+
+#define THREAD_INIT_LOCK(PD, LOCK) \
+ (PD)->LOCK = LLL_LOCK_INITIALIZER
+
+/* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
+ wakeup when the clone terminates. The memory location contains the
+ thread ID while the clone is running and is reset to zero
+ afterwards. */
+#define lll_wait_tid(tid) \
+ do \
+ { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ } \
+ while (0)
+
+extern int __lll_timedwait_tid (int *, const struct timespec *)
+ attribute_hidden;
+
+#define lll_timedwait_tid(tid, abstime) \
+ ({ \
+ int __res = 0; \
+ if ((tid) != 0) \
+ __res = __lll_timedwait_tid (&(tid), (abstime)); \
+ __res; \
+ })
+
+#endif /* lowlevellock.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S b/sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S
new file mode 100644
index 0000000000..4bf14ef949
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pt-vfork.S
@@ -0,0 +1,105 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+#include <tcb-offsets.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. */
+
+/* Load the thread register.
+ Load the saved PID value.
+ Negate the value.
+ Store the temporary PID. */
+#define SAVE_PID \
+ mfctl %cr27, %r26 ASM_LINE_SEP \
+ ldw PID_THREAD_OFFSET(%r26),%r1 ASM_LINE_SEP \
+ sub %r0,%r1,%r1 ASM_LINE_SEP \
+ stw %r1,PID_THREAD_OFFSET(%r26) ASM_LINE_SEP
+/* If we are the parent...
+ Get the thread pointer.
+ Load the saved PID.
+ Negate the value (got back original)
+ Restore the PID. */
+#define RESTORE_PID \
+ cmpb,=,n %r0,%ret0,.Lthread_start ASM_LINE_SEP \
+ mfctl %cr27, %r26 ASM_LINE_SEP \
+ ldw PID_THREAD_OFFSET(%r26),%r1 ASM_LINE_SEP \
+ sub %r0,%r1,%r1 ASM_LINE_SEP \
+ stw %r1,PID_THREAD_OFFSET(%r26) ASM_LINE_SEP \
+.Lthread_start: ASM_LINE_SEP
+
+ /* r26, r25, r24, r23 are free since vfork has no arguments */
+ENTRY(__vfork)
+ /* We must not create a frame. When the child unwinds to call
+ exec it will clobber the same frame that the parent
+ needs to unwind. */
+
+ /* Save the PIC register. */
+#ifdef PIC
+ copy %r19, %r25 /* parent */
+#endif
+
+ /* Save the process PID */
+ SAVE_PID
+
+ /* Syscall saves and restores all register states */
+ ble 0x100(%sr2,%r0)
+ ldi __NR_vfork,%r20
+
+ /* Conditionally restore the PID */
+ RESTORE_PID
+
+ /* Check for error */
+ ldi -4096,%r1
+ comclr,>>= %r1,%ret0,%r0 /* Note: unsigned compare. */
+ b,n .Lerror
+
+ /* Return, and DO NOT restore rp. The child may have called
+ functions that updated the frame's rp. This works because
+ the kernel ensures rp is preserved across the vfork
+ syscall. */
+ bv,n %r0(%rp)
+
+.Lerror:
+ /* Now we need a stack to call a function. We are assured
+ that there is no child now, so it's safe to create
+ a frame. */
+ stw %rp, -20(%sp)
+ stwm %r3, 64(%sp)
+ stw %sp, -4(%sp)
+
+ sub %r0,%ret0,%r3
+ SYSCALL_ERROR_HANDLER
+ /* Restore the PIC register (in delay slot) on error */
+#ifdef PIC
+ copy %r25, %r19 /* parent */
+#else
+ nop
+#endif
+ /* Write syscall return into errno location */
+ stw %r3, 0(%ret0)
+ ldw -84(%sp), %rp
+ bv %r0(%rp)
+ ldwm -64(%sp), %r3
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+weak_alias (__vfork, vfork)
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread.h b/sysdeps/unix/sysv/linux/hppa/nptl/pthread.h
new file mode 100644
index 0000000000..8fbc1a41e6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread.h
@@ -0,0 +1,1192 @@
+/* Copyright (C) 2002-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _PTHREAD_H
+#define _PTHREAD_H 1
+
+#include <features.h>
+#include <endian.h>
+#include <sched.h>
+#include <time.h>
+
+#include <bits/pthreadtypes.h>
+#include <bits/setjmp.h>
+#include <bits/wordsize.h>
+
+
+/* Detach state. */
+enum
+{
+ PTHREAD_CREATE_JOINABLE,
+#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
+ PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
+};
+
+
+/* Mutex types. */
+enum
+{
+ PTHREAD_MUTEX_TIMED_NP,
+ PTHREAD_MUTEX_RECURSIVE_NP,
+ PTHREAD_MUTEX_ERRORCHECK_NP,
+ PTHREAD_MUTEX_ADAPTIVE_NP
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+ ,
+ 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_TIMED_NP
+#endif
+};
+
+
+#ifdef __USE_XOPEN2K
+/* Robust mutex or not flags. */
+enum
+{
+ PTHREAD_MUTEX_STALLED,
+ PTHREAD_MUTEX_STALLED_NP = PTHREAD_MUTEX_STALLED,
+ PTHREAD_MUTEX_ROBUST,
+ PTHREAD_MUTEX_ROBUST_NP = PTHREAD_MUTEX_ROBUST
+};
+#endif
+
+
+#if defined __USE_POSIX199506 || defined __USE_UNIX98
+/* Mutex protocols. */
+enum
+{
+ PTHREAD_PRIO_NONE,
+ PTHREAD_PRIO_INHERIT,
+ PTHREAD_PRIO_PROTECT
+};
+#endif
+
+
+/* Mutex initializers. */
+#ifdef __PTHREAD_MUTEX_HAVE_PREV
+# define PTHREAD_MUTEX_INITIALIZER \
+ { { 0, 0, 0, 0, 0, 0, { 0, 0 } } }
+# ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0, 0 } } }
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0, 0 } } }
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0, 0 } } }
+# endif
+#else
+# define PTHREAD_MUTEX_INITIALIZER \
+ { { 0, 0, 0, 0, 0, { 0 } } }
+# ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0 } } }
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0 } } }
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0 } } }
+# endif
+#endif
+
+
+/* Read-write lock types. */
+#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_READER_NP
+};
+
+/* Define __PTHREAD_RWLOCK_INT_FLAGS_SHARED to 1 if pthread_rwlock_t
+ has the shared field. All 64-bit architectures have the shared field
+ in pthread_rwlock_t. */
+#ifndef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
+# if __WORDSIZE == 64
+# define __PTHREAD_RWLOCK_INT_FLAGS_SHARED 1
+# endif
+#endif
+
+/* Read-write lock initializers. */
+# define PTHREAD_RWLOCK_INITIALIZER \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+# ifdef __USE_GNU
+# ifdef __PTHREAD_RWLOCK_INT_FLAGS_SHARED
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
+# else
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
+ 0, 0, 0, 0 } }
+# else
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
+ 0 } }
+# endif
+# endif
+# endif
+#endif /* Unix98 or XOpen2K */
+
+
+/* Scheduler inheritance. */
+enum
+{
+ PTHREAD_INHERIT_SCHED,
+#define PTHREAD_INHERIT_SCHED PTHREAD_INHERIT_SCHED
+ PTHREAD_EXPLICIT_SCHED
+#define PTHREAD_EXPLICIT_SCHED PTHREAD_EXPLICIT_SCHED
+};
+
+
+/* Scope handling. */
+enum
+{
+ PTHREAD_SCOPE_SYSTEM,
+#define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM
+ PTHREAD_SCOPE_PROCESS
+#define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS
+};
+
+
+/* Process shared or private flag. */
+enum
+{
+ PTHREAD_PROCESS_PRIVATE,
+#define PTHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
+ PTHREAD_PROCESS_SHARED
+#define PTHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
+};
+
+
+
+/* Conditional variable handling. */
+#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }
+
+
+/* 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)
+
+
+/* Single execution handling. */
+#define PTHREAD_ONCE_INIT 0
+
+
+#ifdef __USE_XOPEN2K
+/* Value returned by 'pthread_barrier_wait' for one of the threads after
+ the required number of threads have called this function.
+ -1 is distinct from 0 and all errno constants */
+# define PTHREAD_BARRIER_SERIAL_THREAD -1
+#endif
+
+
+__BEGIN_DECLS
+
+/* Create a new thread, starting with execution of START-ROUTINE
+ getting passed ARG. Creation attributed come from ATTR. The new
+ handle is stored in *NEWTHREAD. */
+extern int pthread_create (pthread_t *__restrict __newthread,
+ const pthread_attr_t *__restrict __attr,
+ void *(*__start_routine) (void *),
+ void *__restrict __arg) __THROWNL __nonnull ((1, 3));
+
+/* Terminate calling thread.
+
+ The registered cleanup handlers are called via exception handling
+ so we cannot mark this function with __THROW.*/
+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.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_join (pthread_t __th, void **__thread_return);
+
+#ifdef __USE_GNU
+/* Check whether thread TH has terminated. If yes return the status of
+ the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL. */
+extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW;
+
+/* Make calling thread wait for termination of the thread TH, but only
+ until TIMEOUT. The exit status of the thread is stored in
+ *THREAD_RETURN, if THREAD_RETURN is not NULL.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
+ const struct timespec *__abstime);
+#endif
+
+/* 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;
+
+
+/* Obtain the identifier of the current thread. */
+extern pthread_t pthread_self (void) __THROW __attribute__ ((__const__));
+
+/* Compare two thread identifiers. */
+extern int pthread_equal (pthread_t __thread1, pthread_t __thread2)
+ __THROW __attribute__ ((__const__));
+
+
+/* Thread attribute handling. */
+
+/* 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 __nonnull ((1));
+
+/* Destroy thread attribute *ATTR. */
+extern int pthread_attr_destroy (pthread_attr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Get detach state attribute. */
+extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr,
+ int *__detachstate)
+ __THROW __nonnull ((1, 2));
+
+/* Set detach state attribute. */
+extern int pthread_attr_setdetachstate (pthread_attr_t *__attr,
+ int __detachstate)
+ __THROW __nonnull ((1));
+
+
+/* Get the size of the guard area created for stack overflow protection. */
+extern int pthread_attr_getguardsize (const pthread_attr_t *__attr,
+ size_t *__guardsize)
+ __THROW __nonnull ((1, 2));
+
+/* Set the size of the guard area created for stack overflow protection. */
+extern int pthread_attr_setguardsize (pthread_attr_t *__attr,
+ size_t __guardsize)
+ __THROW __nonnull ((1));
+
+
+/* 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 __nonnull ((1, 2));
+
+/* 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 __nonnull ((1, 2));
+
+/* Return in *POLICY the scheduling policy of *ATTR. */
+extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict
+ __attr, int *__restrict __policy)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling policy in *ATTR according to POLICY. */
+extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy)
+ __THROW __nonnull ((1));
+
+/* Return in *INHERIT the scheduling inheritance mode of *ATTR. */
+extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict
+ __attr, int *__restrict __inherit)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling inheritance mode in *ATTR according to INHERIT. */
+extern int pthread_attr_setinheritsched (pthread_attr_t *__attr,
+ int __inherit)
+ __THROW __nonnull ((1));
+
+
+/* Return in *SCOPE the scheduling contention scope of *ATTR. */
+extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr,
+ int *__restrict __scope)
+ __THROW __nonnull ((1, 2));
+
+/* Set scheduling contention scope in *ATTR according to SCOPE. */
+extern int pthread_attr_setscope (pthread_attr_t *__attr, int __scope)
+ __THROW __nonnull ((1));
+
+/* Return the previously set address for the stack. */
+extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict
+ __attr, void **__restrict __stackaddr)
+ __THROW __nonnull ((1, 2)) __attribute_deprecated__;
+
+/* 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 __nonnull ((1)) __attribute_deprecated__;
+
+/* Return the currently used minimal stack size. */
+extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict
+ __attr, size_t *__restrict __stacksize)
+ __THROW __nonnull ((1, 2));
+
+/* 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 __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* 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 __nonnull ((1, 2, 3));
+
+/* 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 __nonnull ((1));
+#endif
+
+#ifdef __USE_GNU
+/* Thread created with attribute ATTR will be limited to run only on
+ the processors represented in CPUSET. */
+extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
+ size_t __cpusetsize,
+ const cpu_set_t *__cpuset)
+ __THROW __nonnull ((1, 3));
+
+/* Get bit set in CPUSET representing the processors threads created with
+ ATTR can run on. */
+extern int pthread_attr_getaffinity_np (const pthread_attr_t *__attr,
+ size_t __cpusetsize,
+ cpu_set_t *__cpuset)
+ __THROW __nonnull ((1, 3));
+
+
+/* Initialize thread attribute *ATTR with attributes corresponding to the
+ already running thread TH. It shall be called on uninitialized ATTR
+ and destroyed with pthread_attr_destroy when no longer needed. */
+extern int pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr)
+ __THROW __nonnull ((2));
+#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 __nonnull ((3));
+
+/* 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 __nonnull ((2, 3));
+
+/* Set the scheduling priority for TARGET_THREAD. */
+extern int pthread_setschedprio (pthread_t __target_thread, int __prio)
+ __THROW;
+
+
+#ifdef __USE_GNU
+/* Get thread name visible in the kernel and its interfaces. */
+extern int pthread_getname_np (pthread_t __target_thread, char *__buf,
+ size_t __buflen)
+ __THROW __nonnull ((2));
+
+/* Set thread name visible in the kernel and its interfaces. */
+extern int pthread_setname_np (pthread_t __target_thread, const char *__name)
+ __THROW __nonnull ((2));
+#endif
+
+
+#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;
+
+
+/* Limit specified thread TH to run only on the processors represented
+ in CPUSET. */
+extern int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize,
+ const cpu_set_t *__cpuset)
+ __THROW __nonnull ((3));
+
+/* Get bit set in CPUSET representing the processors TH can run on. */
+extern int pthread_getaffinity_np (pthread_t __th, size_t __cpusetsize,
+ cpu_set_t *__cpuset)
+ __THROW __nonnull ((3));
+#endif
+
+
+/* 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)) __nonnull ((1, 2));
+
+
+/* Functions for handling cancellation.
+
+ Note that these functions are explicitly not marked to not throw an
+ exception in C++ code. If cancellation is implemented by unwinding
+ this is necessary to have the compiler generate the unwind information. */
+
+/* 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 __th);
+
+/* 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);
+
+
+/* Cancellation handling with integration into exception handling. */
+
+typedef struct
+{
+ struct
+ {
+ __jmp_buf __cancel_jmp_buf;
+ int __mask_was_saved;
+ } __cancel_jmp_buf[1];
+ void *__pad[4];
+} __pthread_unwind_buf_t __attribute__ ((__aligned__));
+
+/* No special attributes by default. */
+#ifndef __cleanup_fct_attribute
+# define __cleanup_fct_attribute
+#endif
+
+
+/* Structure to hold the cleanup handler information. */
+struct __pthread_cleanup_frame
+{
+ void (*__cancel_routine) (void *);
+ void *__cancel_arg;
+ int __do_it;
+ int __cancel_type;
+};
+
+#if defined __GNUC__ && defined __EXCEPTIONS
+# ifdef __cplusplus
+/* Class to handle cancellation handler invocation. */
+class __pthread_cleanup_class
+{
+ void (*__cancel_routine) (void *);
+ void *__cancel_arg;
+ int __do_it;
+ int __cancel_type;
+
+ public:
+ __pthread_cleanup_class (void (*__fct) (void *), void *__arg)
+ : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { }
+ ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); }
+ void __setdoit (int __newval) { __do_it = __newval; }
+ void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED,
+ &__cancel_type); }
+ void __restore () const { pthread_setcanceltype (__cancel_type, 0); }
+};
+
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+ when the thread is canceled 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) \
+ do { \
+ __pthread_cleanup_class __clframe (routine, arg)
+
+/* 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) \
+ __clframe.__setdoit (execute); \
+ } while (0)
+
+# ifdef __USE_GNU
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+ saves the current cancellation type and sets it to deferred
+ cancellation. */
+# define pthread_cleanup_push_defer_np(routine, arg) \
+ do { \
+ __pthread_cleanup_class __clframe (routine, arg); \
+ __clframe.__defer ()
+
+/* 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) \
+ __clframe.__restore (); \
+ __clframe.__setdoit (execute); \
+ } while (0)
+# endif
+# else
+/* Function called to call the cleanup handler. As an extern inline
+ function the compiler is free to decide inlining the change when
+ needed or fall back on the copy which must exist somewhere
+ else. */
+__extern_inline void
+__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
+{
+ if (__frame->__do_it)
+ __frame->__cancel_routine (__frame->__cancel_arg);
+}
+
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+ when the thread is canceled 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) \
+ do { \
+ struct __pthread_cleanup_frame __clframe \
+ __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
+ = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
+ .__do_it = 1 };
+
+/* 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) \
+ __clframe.__do_it = (execute); \
+ } while (0)
+
+# ifdef __USE_GNU
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+ saves the current cancellation type and sets it to deferred
+ cancellation. */
+# define pthread_cleanup_push_defer_np(routine, arg) \
+ do { \
+ struct __pthread_cleanup_frame __clframe \
+ __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
+ = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
+ .__do_it = 1 }; \
+ (void) pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, \
+ &__clframe.__cancel_type)
+
+/* 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) \
+ (void) pthread_setcanceltype (__clframe.__cancel_type, NULL); \
+ __clframe.__do_it = (execute); \
+ } while (0)
+# endif
+# endif
+#else
+/* Install a cleanup handler: ROUTINE will be called with arguments ARG
+ when the thread is canceled 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) \
+ do { \
+ __pthread_unwind_buf_t __cancel_buf; \
+ void (*__cancel_routine) (void *) = (routine); \
+ void *__cancel_arg = (arg); \
+ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
+ __cancel_buf.__cancel_jmp_buf, 0); \
+ if (__glibc_unlikely (__not_first_call)) \
+ { \
+ __cancel_routine (__cancel_arg); \
+ __pthread_unwind_next (&__cancel_buf); \
+ /* NOTREACHED */ \
+ } \
+ \
+ __pthread_register_cancel (&__cancel_buf); \
+ do {
+extern void __pthread_register_cancel (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+
+/* 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) \
+ do { } while (0);/* Empty to allow label before pthread_cleanup_pop. */\
+ } while (0); \
+ __pthread_unregister_cancel (&__cancel_buf); \
+ if (execute) \
+ __cancel_routine (__cancel_arg); \
+ } while (0)
+extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+
+# ifdef __USE_GNU
+/* Install a cleanup handler as pthread_cleanup_push does, but also
+ saves the current cancellation type and sets it to deferred
+ cancellation. */
+# define pthread_cleanup_push_defer_np(routine, arg) \
+ do { \
+ __pthread_unwind_buf_t __cancel_buf; \
+ void (*__cancel_routine) (void *) = (routine); \
+ void *__cancel_arg = (arg); \
+ int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
+ __cancel_buf.__cancel_jmp_buf, 0); \
+ if (__glibc_unlikely (__not_first_call)) \
+ { \
+ __cancel_routine (__cancel_arg); \
+ __pthread_unwind_next (&__cancel_buf); \
+ /* NOTREACHED */ \
+ } \
+ \
+ __pthread_register_cancel_defer (&__cancel_buf); \
+ do {
+extern void __pthread_register_cancel_defer (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+
+/* 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) \
+ do { } while (0);/* Empty to allow label before pthread_cleanup_pop. */\
+ } while (0); \
+ __pthread_unregister_cancel_restore (&__cancel_buf); \
+ if (execute) \
+ __cancel_routine (__cancel_arg); \
+ } while (0)
+extern void __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute;
+# endif
+
+/* Internal interface to initiate cleanup. */
+extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
+ __cleanup_fct_attribute __attribute__ ((__noreturn__))
+# ifndef SHARED
+ __attribute__ ((__weak__))
+# endif
+ ;
+#endif
+
+/* Function used in the macros. */
+struct __jmp_buf_tag;
+extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROWNL;
+
+
+/* Mutex handling. */
+
+/* Initialize a mutex. */
+extern int pthread_mutex_init (pthread_mutex_t *__mutex,
+ const pthread_mutexattr_t *__mutexattr)
+ __THROW __nonnull ((1));
+
+/* Destroy a mutex. */
+extern int pthread_mutex_destroy (pthread_mutex_t *__mutex)
+ __THROW __nonnull ((1));
+
+/* Try locking a mutex. */
+extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
+ __THROWNL __nonnull ((1));
+
+/* Lock a mutex. */
+extern int pthread_mutex_lock (pthread_mutex_t *__mutex)
+ __THROWNL __nonnull ((1));
+
+#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) __THROWNL __nonnull ((1, 2));
+#endif
+
+/* Unlock a mutex. */
+extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
+ __THROWNL __nonnull ((1));
+
+
+/* Get the priority ceiling of MUTEX. */
+extern int pthread_mutex_getprioceiling (const pthread_mutex_t *
+ __restrict __mutex,
+ int *__restrict __prioceiling)
+ __THROW __nonnull ((1, 2));
+
+/* Set the priority ceiling of MUTEX to PRIOCEILING, return old
+ priority ceiling value in *OLD_CEILING. */
+extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex,
+ int __prioceiling,
+ int *__restrict __old_ceiling)
+ __THROW __nonnull ((1, 3));
+
+
+#ifdef __USE_XOPEN2K8
+/* Declare the state protected by MUTEX as consistent. */
+extern int pthread_mutex_consistent (pthread_mutex_t *__mutex)
+ __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutex_consistent_np (pthread_mutex_t *__mutex)
+ __THROW __nonnull ((1));
+# endif
+#endif
+
+
+/* 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 __nonnull ((1));
+
+/* Destroy mutex attribute object ATTR. */
+extern int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* 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 __nonnull ((1, 2));
+
+/* Set the process-shared flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
+ int __pshared)
+ __THROW __nonnull ((1));
+
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
+/* Return in *KIND the mutex kind attribute in *ATTR. */
+extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict
+ __attr, int *__restrict __kind)
+ __THROW __nonnull ((1, 2));
+
+/* 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 __nonnull ((1));
+#endif
+
+/* Return in *PROTOCOL the mutex protocol attribute in *ATTR. */
+extern int pthread_mutexattr_getprotocol (const pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict __protocol)
+ __THROW __nonnull ((1, 2));
+
+/* Set the mutex protocol attribute in *ATTR to PROTOCOL (either
+ PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT, or PTHREAD_PRIO_PROTECT). */
+extern int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
+ int __protocol)
+ __THROW __nonnull ((1));
+
+/* Return in *PRIOCEILING the mutex prioceiling attribute in *ATTR. */
+extern int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *
+ __restrict __attr,
+ int *__restrict __prioceiling)
+ __THROW __nonnull ((1, 2));
+
+/* Set the mutex prioceiling attribute in *ATTR to PRIOCEILING. */
+extern int pthread_mutexattr_setprioceiling (pthread_mutexattr_t *__attr,
+ int __prioceiling)
+ __THROW __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Get the robustness flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr,
+ int *__robustness)
+ __THROW __nonnull ((1, 2));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr,
+ int *__robustness)
+ __THROW __nonnull ((1, 2));
+# endif
+
+/* Set the robustness flag of the mutex attribute ATTR. */
+extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr,
+ int __robustness)
+ __THROW __nonnull ((1));
+# ifdef __USE_GNU
+extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr,
+ int __robustness)
+ __THROW __nonnull ((1));
+# endif
+#endif
+
+
+#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 __nonnull ((1));
+
+/* Destroy read-write lock RWLOCK. */
+extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock)
+ __THROW __nonnull ((1));
+
+/* Acquire read lock for RWLOCK. */
+extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+/* Try to acquire read lock for RWLOCK. */
+extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+# 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) __THROWNL __nonnull ((1, 2));
+# endif
+
+/* Acquire write lock for RWLOCK. */
+extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+/* Try to acquire write lock for RWLOCK. */
+extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+# 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) __THROWNL __nonnull ((1, 2));
+# endif
+
+/* Unlock RWLOCK. */
+extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
+ __THROWNL __nonnull ((1));
+
+
+/* Functions for handling read-write lock attributes. */
+
+/* Initialize attribute object ATTR with default values. */
+extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy attribute object ATTR. */
+extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* 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 __nonnull ((1, 2));
+
+/* Set process-shared attribute of ATTR to PSHARED. */
+extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr,
+ int __pshared)
+ __THROW __nonnull ((1));
+
+/* Return current setting of reader/writer preference. */
+extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *
+ __restrict __attr,
+ int *__restrict __pref)
+ __THROW __nonnull ((1, 2));
+
+/* Set reader/write preference. */
+extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr,
+ int __pref) __THROW __nonnull ((1));
+#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 __nonnull ((1));
+
+/* Destroy condition variable COND. */
+extern int pthread_cond_destroy (pthread_cond_t *__cond)
+ __THROW __nonnull ((1));
+
+/* Wake up one thread waiting for condition variable COND. */
+extern int pthread_cond_signal (pthread_cond_t *__cond)
+ __THROWNL __nonnull ((1));
+
+/* Wake up all threads waiting for condition variables COND. */
+extern int pthread_cond_broadcast (pthread_cond_t *__cond)
+ __THROWNL __nonnull ((1));
+
+/* Wait for condition variable COND to be signaled or broadcast.
+ MUTEX is assumed to be locked before.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex)
+ __nonnull ((1, 2));
+
+/* 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).
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
+ pthread_mutex_t *__restrict __mutex,
+ const struct timespec *__restrict __abstime)
+ __nonnull ((1, 2, 3));
+
+/* Functions for handling condition variable attributes. */
+
+/* Initialize condition variable attribute ATTR. */
+extern int pthread_condattr_init (pthread_condattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy condition variable attribute ATTR. */
+extern int pthread_condattr_destroy (pthread_condattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* 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 __nonnull ((1, 2));
+
+/* Set the process-shared flag of the condition variable attribute ATTR. */
+extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
+ int __pshared) __THROW __nonnull ((1));
+
+#ifdef __USE_XOPEN2K
+/* Get the clock selected for the condition variable attribute ATTR. */
+extern int pthread_condattr_getclock (const pthread_condattr_t *
+ __restrict __attr,
+ __clockid_t *__restrict __clock_id)
+ __THROW __nonnull ((1, 2));
+
+/* Set the clock selected for the condition variable attribute ATTR. */
+extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
+ __clockid_t __clock_id)
+ __THROW __nonnull ((1));
+#endif
+
+
+#ifdef __USE_XOPEN2K
+/* Functions to handle 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 __nonnull ((1));
+
+/* Destroy the spinlock LOCK. */
+extern int pthread_spin_destroy (pthread_spinlock_t *__lock)
+ __THROW __nonnull ((1));
+
+/* Wait until spinlock LOCK is retrieved. */
+extern int pthread_spin_lock (pthread_spinlock_t *__lock)
+ __THROWNL __nonnull ((1));
+
+/* Try to lock spinlock LOCK. */
+extern int pthread_spin_trylock (pthread_spinlock_t *__lock)
+ __THROWNL __nonnull ((1));
+
+/* Release spinlock LOCK. */
+extern int pthread_spin_unlock (pthread_spinlock_t *__lock)
+ __THROWNL __nonnull ((1));
+
+
+/* Functions to handle barriers. */
+
+/* Initialize BARRIER with the attributes in ATTR. The barrier is
+ opened when COUNT waiters arrived. */
+extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier,
+ const pthread_barrierattr_t *__restrict
+ __attr, unsigned int __count)
+ __THROW __nonnull ((1));
+
+/* Destroy a previously dynamically initialized barrier BARRIER. */
+extern int pthread_barrier_destroy (pthread_barrier_t *__barrier)
+ __THROW __nonnull ((1));
+
+/* Wait on barrier BARRIER. */
+extern int pthread_barrier_wait (pthread_barrier_t *__barrier)
+ __THROWNL __nonnull ((1));
+
+
+/* Initialize barrier attribute ATTR. */
+extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Destroy previously dynamically initialized barrier attribute ATTR. */
+extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr)
+ __THROW __nonnull ((1));
+
+/* Get the process-shared flag of the barrier attribute ATTR. */
+extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *
+ __restrict __attr,
+ int *__restrict __pshared)
+ __THROW __nonnull ((1, 2));
+
+/* Set the process-shared flag of the barrier attribute ATTR. */
+extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr,
+ int __pshared)
+ __THROW __nonnull ((1));
+#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 __nonnull ((1));
+
+/* Destroy KEY. */
+extern int pthread_key_delete (pthread_key_t __key) __THROW;
+
+/* Return current value of the thread-specific data slot identified by KEY. */
+extern void *pthread_getspecific (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 ;
+
+
+#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 __nonnull ((2));
+#endif
+
+
+/* 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;
+
+
+#ifdef __USE_EXTERN_INLINES
+/* Optimizations. */
+__extern_inline int
+__NTH (pthread_equal (pthread_t __thread1, pthread_t __thread2))
+{
+ return __thread1 == __thread2;
+}
+#endif
+
+__END_DECLS
+
+#endif /* pthread.h */
+
+#ifndef _PTHREAD_H_HPPA_
+#define _PTHREAD_H_HPPA_ 1
+
+/* The pthread_cond_t initializer is compatible only with NPTL. We do not
+ want to be forwards compatible, we eventually want to drop the code
+ that has to clear the old LT initializer. */
+#undef PTHREAD_COND_INITIALIZER
+#define PTHREAD_COND_INITIALIZER { { 0, 0, 0, (void *) 0, 0, 0, 0, 0, 0 } }
+
+/* The pthread_mutex_t and pthread_rwlock_t initializers are compatible
+ only with NPTL. NPTL assumes pthread_rwlock_t is all zero. */
+#undef PTHREAD_MUTEX_INITIALIZER
+#undef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+#undef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+#undef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+/* Mutex initializers. */
+#define PTHREAD_MUTEX_INITIALIZER \
+ { { 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
+#ifdef __USE_GNU
+# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
+# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
+# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \
+ { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, { 0, 0, 0, 0 }, 0, { 0 }, 0, 0 } }
+#endif
+
+#undef PTHREAD_RWLOCK_INITIALIZER
+#undef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
+/* Read-write lock initializers. */
+#define PTHREAD_RWLOCK_INITIALIZER \
+ { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+#ifdef __USE_GNU
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
+ 0, 0, 0 } }
+#endif /* Unix98 or XOpen2K */
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthreadP.h b/sysdeps/unix/sysv/linux/hppa/nptl/pthreadP.h
new file mode 100644
index 0000000000..744b5b090b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthreadP.h
@@ -0,0 +1,16 @@
+#include_next <pthreadP.h>
+#ifndef _PTHREADP_H_HPPA_
+#define _PTHREADP_H_HPPA_ 1
+
+/* Internal cond functions. */
+extern int __pthread_cond_broadcast_internal (pthread_cond_t *cond);
+extern int __pthread_cond_destroy_internal (pthread_cond_t *cond);
+extern int __pthread_cond_init_internal (pthread_cond_t *cond,
+ const pthread_condattr_t *cond_attr);
+extern int __pthread_cond_signal_internal (pthread_cond_t *cond);
+extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime);
+extern int __pthread_cond_wait_internal (pthread_cond_t *cond,
+ pthread_mutex_t *mutex);
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_broadcast.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_broadcast.c
new file mode 100644
index 0000000000..23526c658c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_broadcast.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <pthread_cond_broadcast.c>
+#else
+# include <pthread.h>
+# include <pthreadP.h>
+# include <internaltypes.h>
+# include <shlib-compat.h>
+int
+__pthread_cond_broadcast (cond)
+ pthread_cond_t *cond;
+{
+ cond_compat_check_and_clear (cond);
+ return __pthread_cond_broadcast_internal (cond);
+}
+versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
+ GLIBC_2_3_2);
+# undef versioned_symbol
+# define versioned_symbol(lib, local, symbol, version)
+# undef __pthread_cond_broadcast
+# define __pthread_cond_broadcast __pthread_cond_broadcast_internal
+# include_next <pthread_cond_broadcast.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_destroy.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_destroy.c
new file mode 100644
index 0000000000..b90355c34d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_destroy.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <pthread_cond_destroy.c>
+#else
+# include <pthread.h>
+# include <pthreadP.h>
+# include <internaltypes.h>
+# include <shlib-compat.h>
+int
+__pthread_cond_destroy (cond)
+ pthread_cond_t *cond;
+{
+ cond_compat_check_and_clear (cond);
+ return __pthread_cond_destroy_internal (cond);
+}
+versioned_symbol (libpthread, __pthread_cond_destroy, pthread_cond_destroy,
+ GLIBC_2_3_2);
+# undef versioned_symbol
+# define versioned_symbol(lib, local, symbol, version)
+# undef __pthread_cond_destroy
+# define __pthread_cond_destroy __pthread_cond_destroy_internal
+# include_next <pthread_cond_destroy.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_init.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_init.c
new file mode 100644
index 0000000000..38a282a38a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_init.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <pthread_cond_init.c>
+#else
+# include <pthread.h>
+# include <pthreadP.h>
+# include <internaltypes.h>
+# include <shlib-compat.h>
+int
+__pthread_cond_init (cond, cond_attr)
+ pthread_cond_t *cond;
+ const pthread_condattr_t *cond_attr;
+{
+ cond_compat_clear (cond);
+ return __pthread_cond_init_internal (cond, cond_attr);
+}
+versioned_symbol (libpthread, __pthread_cond_init, pthread_cond_init,
+ GLIBC_2_3_2);
+# undef versioned_symbol
+# define versioned_symbol(lib, local, symbol, version)
+# undef __pthread_cond_init
+# define __pthread_cond_init __pthread_cond_init_internal
+# include_next <pthread_cond_init.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_signal.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_signal.c
new file mode 100644
index 0000000000..2f6e8e1b89
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_signal.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <pthread_cond_signal.c>
+#else
+# include <pthread.h>
+# include <pthreadP.h>
+# include <internaltypes.h>
+# include <shlib-compat.h>
+int
+__pthread_cond_signal (cond)
+ pthread_cond_t *cond;
+{
+ cond_compat_check_and_clear (cond);
+ return __pthread_cond_signal_internal (cond);
+}
+versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
+ GLIBC_2_3_2);
+# undef versioned_symbol
+# define versioned_symbol(lib, local, symbol, version)
+# undef __pthread_cond_signal
+# define __pthread_cond_signal __pthread_cond_signal_internal
+# include_next <pthread_cond_signal.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_timedwait.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_timedwait.c
new file mode 100644
index 0000000000..e53136bfe3
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_timedwait.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <pthread_cond_timedwait.c>
+#else
+# include <pthread.h>
+# include <pthreadP.h>
+# include <internaltypes.h>
+# include <shlib-compat.h>
+int
+__pthread_cond_timedwait (cond, mutex, abstime)
+ pthread_cond_t *cond;
+ pthread_mutex_t *mutex;
+ const struct timespec *abstime;
+{
+ cond_compat_check_and_clear (cond);
+ return __pthread_cond_timedwait_internal (cond, mutex, abstime);
+}
+versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
+ GLIBC_2_3_2);
+# undef versioned_symbol
+# define versioned_symbol(lib, local, symbol, version)
+# undef __pthread_cond_timedwait
+# define __pthread_cond_timedwait __pthread_cond_timedwait_internal
+# include_next <pthread_cond_timedwait.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_wait.c b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_wait.c
new file mode 100644
index 0000000000..c53bc98325
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/pthread_cond_wait.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Carlos O'Donell <carlos@codesourcery.com>, 2009.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef INCLUDED_SELF
+# define INCLUDED_SELF
+# include <pthread_cond_wait.c>
+#else
+# include <pthread.h>
+# include <pthreadP.h>
+# include <internaltypes.h>
+# include <shlib-compat.h>
+int
+__pthread_cond_wait (cond, mutex)
+ pthread_cond_t *cond;
+ pthread_mutex_t *mutex;
+{
+ cond_compat_check_and_clear (cond);
+ return __pthread_cond_wait_internal (cond, mutex);
+}
+versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
+ GLIBC_2_3_2);
+# undef versioned_symbol
+# define versioned_symbol(lib, local, symbol, version)
+# undef __pthread_cond_wait
+# define __pthread_cond_wait __pthread_cond_wait_internal
+# include_next <pthread_cond_wait.c>
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h b/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h
new file mode 100644
index 0000000000..6f1c9d745b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h
@@ -0,0 +1,280 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sysdeps/generic/sysdep.h>
+#include <tls.h>
+#ifndef __ASSEMBLER__
+# include <nptl/pthreadP.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+
+# ifndef NO_ERROR
+# define NO_ERROR -0x1000
+# endif
+
+/* The syscall cancellation mechanism requires userspace
+ assistance, the following code does roughly this:
+
+ do arguments (read arg5 and arg6 to registers)
+ setup frame
+
+ check if there are threads, yes jump to pseudo_cancel
+
+ unthreaded:
+ syscall
+ check syscall return (jump to pre_end)
+ set errno
+ set return to -1
+ (jump to pre_end)
+
+ pseudo_cancel:
+ cenable
+ syscall
+ cdisable
+ check syscall return (jump to pre_end)
+ set errno
+ set return to -1
+
+ pre_end
+ restore stack
+
+ It is expected that 'ret' and 'END' macros will
+ append an 'undo arguments' and 'return' to the
+ this PSEUDO macro. */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
+ ENTRY (__##syscall_name##_nocancel) \
+ DOARGS_##args ASM_LINE_SEP \
+ stwm TREG, 64(%sp) ASM_LINE_SEP \
+ .cfi_offset TREG, 0 ASM_LINE_SEP \
+ .cfi_adjust_cfa_offset 64 ASM_LINE_SEP \
+ stw %sp, -4(%sp) ASM_LINE_SEP \
+ .cfi_offset 30, -4 ASM_LINE_SEP \
+ stw %r19, -32(%sp) ASM_LINE_SEP \
+ .cfi_offset 19, -32 ASM_LINE_SEP \
+ /* Save r19 */ ASM_LINE_SEP \
+ SAVE_PIC(TREG) ASM_LINE_SEP \
+ /* Do syscall, delay loads # */ ASM_LINE_SEP \
+ ble 0x100(%sr2,%r0) ASM_LINE_SEP \
+ ldi SYS_ify (syscall_name), %r20 /* delay */ ASM_LINE_SEP \
+ ldi NO_ERROR,%r1 ASM_LINE_SEP \
+ cmpb,>>=,n %r1,%ret0,L(pre_nc_end) ASM_LINE_SEP \
+ /* Restore r19 from TREG */ ASM_LINE_SEP \
+ LOAD_PIC(TREG) /* delay */ ASM_LINE_SEP \
+ SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
+ /* Use TREG for temp storage */ ASM_LINE_SEP \
+ copy %ret0, TREG /* delay */ ASM_LINE_SEP \
+ /* OPTIMIZE: Don't reload r19 */ ASM_LINE_SEP \
+ /* do a -1*syscall_ret0 */ ASM_LINE_SEP \
+ sub %r0, TREG, TREG ASM_LINE_SEP \
+ /* Store into errno location */ ASM_LINE_SEP \
+ stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
+ /* return -1 as error */ ASM_LINE_SEP \
+ ldi -1, %ret0 ASM_LINE_SEP \
+L(pre_nc_end): ASM_LINE_SEP \
+ /* No need to LOAD_PIC */ ASM_LINE_SEP \
+ /* Undo frame */ ASM_LINE_SEP \
+ ldwm -64(%sp),TREG ASM_LINE_SEP \
+ .cfi_adjust_cfa_offset -64 ASM_LINE_SEP \
+ /* Restore rp before exit */ ASM_LINE_SEP \
+ ldw -20(%sp), %rp ASM_LINE_SEP \
+ .cfi_restore 2 ASM_LINE_SEP \
+ ret ASM_LINE_SEP \
+ END(__##syscall_name##_nocancel) ASM_LINE_SEP \
+ /**********************************************/ASM_LINE_SEP \
+ ENTRY (name) \
+ DOARGS_##args ASM_LINE_SEP \
+ stwm TREG, 64(%sp) ASM_LINE_SEP \
+ .cfi_adjust_cfa_offset 64 ASM_LINE_SEP \
+ stw %sp, -4(%sp) ASM_LINE_SEP \
+ .cfi_offset 30, -4 ASM_LINE_SEP \
+ stw %r19, -32(%sp) ASM_LINE_SEP \
+ .cfi_offset 19, -32 ASM_LINE_SEP \
+ /* Done setting up frame, continue... */ ASM_LINE_SEP \
+ SINGLE_THREAD_P ASM_LINE_SEP \
+ cmpib,<>,n 0,%ret0,L(pseudo_cancel) ASM_LINE_SEP \
+L(unthreaded): ASM_LINE_SEP \
+ /* Save r19 */ ASM_LINE_SEP \
+ SAVE_PIC(TREG) ASM_LINE_SEP \
+ /* Do syscall, delay loads # */ ASM_LINE_SEP \
+ ble 0x100(%sr2,%r0) ASM_LINE_SEP \
+ ldi SYS_ify (syscall_name), %r20 /* delay */ ASM_LINE_SEP \
+ ldi NO_ERROR,%r1 ASM_LINE_SEP \
+ cmpb,>>=,n %r1,%ret0,L(pre_end) ASM_LINE_SEP \
+ /* Restore r19 from TREG */ ASM_LINE_SEP \
+ LOAD_PIC(TREG) /* delay */ ASM_LINE_SEP \
+ SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
+ /* Use TREG for temp storage */ ASM_LINE_SEP \
+ copy %ret0, TREG /* delay */ ASM_LINE_SEP \
+ /* OPTIMIZE: Don't reload r19 */ ASM_LINE_SEP \
+ /* do a -1*syscall_ret0 */ ASM_LINE_SEP \
+ sub %r0, TREG, TREG ASM_LINE_SEP \
+ /* Store into errno location */ ASM_LINE_SEP \
+ stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
+ b L(pre_end) ASM_LINE_SEP \
+ /* return -1 as error */ ASM_LINE_SEP \
+ ldi -1, %ret0 /* delay */ ASM_LINE_SEP \
+L(pseudo_cancel): ASM_LINE_SEP \
+ PUSHARGS_##args /* Save args */ ASM_LINE_SEP \
+ /* Save r19 into TREG */ ASM_LINE_SEP \
+ CENABLE /* FUNC CALL */ ASM_LINE_SEP \
+ SAVE_PIC(TREG) /* delay */ ASM_LINE_SEP \
+ /* restore syscall args */ ASM_LINE_SEP \
+ POPARGS_##args ASM_LINE_SEP \
+ /* save mask from cenable (use stub rp slot) */ ASM_LINE_SEP \
+ stw %ret0, -24(%sp) ASM_LINE_SEP \
+ /* ... SYSCALL ... */ ASM_LINE_SEP \
+ ble 0x100(%sr2,%r0) ASM_LINE_SEP \
+ ldi SYS_ify (syscall_name), %r20 /* delay */ ASM_LINE_SEP \
+ /* ............... */ ASM_LINE_SEP \
+ LOAD_PIC(TREG) ASM_LINE_SEP \
+ /* pass mask as arg0 to cdisable */ ASM_LINE_SEP \
+ ldw -24(%sp), %r26 ASM_LINE_SEP \
+ CDISABLE ASM_LINE_SEP \
+ stw %ret0, -24(%sp) /* delay */ ASM_LINE_SEP \
+ /* Restore syscall return */ ASM_LINE_SEP \
+ ldw -24(%sp), %ret0 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,%ret0,L(pre_end) ASM_LINE_SEP \
+ LOAD_PIC(TREG) /* cond. nullify */ ASM_LINE_SEP \
+ copy %ret0, TREG /* save syscall return */ ASM_LINE_SEP \
+ SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
+ /* make syscall res value positive */ ASM_LINE_SEP \
+ sub %r0, TREG, TREG /* delay */ ASM_LINE_SEP \
+ /* No need to LOAD_PIC */ ASM_LINE_SEP \
+ /* store into errno location */ ASM_LINE_SEP \
+ stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
+ /* return -1 */ ASM_LINE_SEP \
+ ldi -1, %ret0 ASM_LINE_SEP \
+L(pre_end): ASM_LINE_SEP \
+ /* No need to LOAD_PIC */ ASM_LINE_SEP \
+ /* Undo frame */ ASM_LINE_SEP \
+ ldwm -64(%sp),TREG ASM_LINE_SEP \
+ .cfi_adjust_cfa_offset -64 ASM_LINE_SEP \
+ /* Restore rp before exit */ ASM_LINE_SEP \
+ ldw -20(%sp), %rp ASM_LINE_SEP \
+ .cfi_restore 2 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 \
+ .cfi_offset 26, -36 ASM_LINE_SEP
+# define PUSHARGS_2 PUSHARGS_1 stw %r25, -40(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 25, -40 ASM_LINE_SEP
+# define PUSHARGS_3 PUSHARGS_2 stw %r24, -44(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 24, -44 ASM_LINE_SEP
+# define PUSHARGS_4 PUSHARGS_3 stw %r23, -48(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 23, -48 ASM_LINE_SEP
+# define PUSHARGS_5 PUSHARGS_4 stw %r22, -52(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 22, -52 ASM_LINE_SEP
+# define PUSHARGS_6 PUSHARGS_5 stw %r21, -56(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 21, -56 ASM_LINE_SEP
+
+/* 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 \
+ .cfi_restore 26 ASM_LINE_SEP
+# define POPARGS_2 POPARGS_1 ldw -40(%sr0,%sp), %r25 ASM_LINE_SEP \
+ .cfi_restore 25 ASM_LINE_SEP
+# define POPARGS_3 POPARGS_2 ldw -44(%sr0,%sp), %r24 ASM_LINE_SEP \
+ .cfi_restore 24 ASM_LINE_SEP
+# define POPARGS_4 POPARGS_3 ldw -48(%sr0,%sp), %r23 ASM_LINE_SEP \
+ .cfi_restore 23 ASM_LINE_SEP
+# define POPARGS_5 POPARGS_4 ldw -52(%sr0,%sp), %r22 ASM_LINE_SEP \
+ .cfi_restore 22 ASM_LINE_SEP
+# define POPARGS_6 POPARGS_5 ldw -56(%sr0,%sp), %r21 ASM_LINE_SEP \
+ .cfi_restore 21 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
+# elif defined IS_IN_librt
+# 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
+# else
+# error Unsupported library
+# endif
+
+# ifdef IS_IN_libpthread
+# define __local_multiple_threads __pthread_multiple_threads
+# elif !defined NOT_IN_libc
+# define __local_multiple_threads __libc_multiple_threads
+# elif IS_IN_librt
+# define __local_multiple_threads __librt_multiple_threads
+# else
+# error Unsupported library
+# endif
+
+# ifndef __ASSEMBLER__
+# define SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+# else
+/* Read the value of header.multiple_threads from the thread pointer */
+# define SINGLE_THREAD_P \
+ mfctl %cr27, %ret0 ASM_LINE_SEP \
+ ldw MULTIPLE_THREADS_THREAD_OFFSET(%sr0,%ret0),%ret0 ASM_LINE_SEP
+# endif
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow. */
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+/* !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt */
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/profil-counter.h b/sysdeps/unix/sysv/linux/hppa/profil-counter.h
new file mode 100644
index 0000000000..1561672d94
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/profil-counter.h
@@ -0,0 +1,24 @@
+/* Machine-dependent SIGPROF signal handler. PA-RISC version
+ Copyright (C) 1996-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+static void
+profil_counter (int signr, siginfo_t *si, struct ucontext *uctx)
+{
+ unsigned long ip = uctx->uc_mcontext.sc_iaoq[0] & ~0x3;
+ profil_count ((void *) ip);
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/setcontext.S b/sysdeps/unix/sysv/linux/hppa/setcontext.S
new file mode 100644
index 0000000000..a90ab0f9fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/setcontext.S
@@ -0,0 +1,157 @@
+/* Install given context.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Helge Deller <deller@gmx.de>, 2008.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+
+
+ENTRY(__setcontext)
+ /* Prologue */
+ stwm %r3, 64(%sp)
+#ifdef PIC
+ stw %r19, -32(%sp)
+#endif
+
+ /* Save ucp. */
+ copy %r26, %r3
+
+.Lagain:
+ /* Set the current signal mask. */
+ /* sigprocmask(SIG_BLOCK, &ucp->uc_sigmask, NULL); */
+ copy %r0, %r24
+ ldo oSIGMASK(%r3), %r25
+ bl sigprocmask, %r2
+ ldi SIG_SETMASK, %r26
+
+ comib,<>,n 0,%ret0,.Lerror
+
+ /* Save %sp, %dp. */
+ copy %sp, %r4
+ copy %dp, %r5
+ copy %r19, %r6
+
+ /* Get the registers. */
+ ldw oR1(%r3), %r1
+ ldw oR2(%r3), %r2
+ /* ldw oR3(%r3), %r3 - used for ucp pointer. */
+ /* ldw oR4(%r3), %r4 - used for original %sp. */
+ /* ldw oR5(%r3), %r5 - used for %dp / %r27. */
+ /* ldw oR6(%r3), %r6 - used for %r19. */
+ ldw oR7(%r3), %r7
+ ldw oR8(%r3), %r8
+ ldw oR9(%r3), %r9
+ ldw oR10(%r3), %r10
+ ldw oR11(%r3), %r11
+ ldw oR12(%r3), %r12
+ ldw oR13(%r3), %r13
+ ldw oR14(%r3), %r14
+ ldw oR15(%r3), %r15
+ ldw oR16(%r3), %r16
+ ldw oR17(%r3), %r17
+ ldw oR18(%r3), %r18
+ ldw oR19(%r3), %r19
+ ldw oR20(%r3), %r20
+ ldw oR21(%r3), %r21
+ /* ldw oR22(%r3), %r22 - dyncall arg. */
+ ldw oR23(%r3), %r23
+ ldw oR24(%r3), %r24
+ ldw oR25(%r3), %r25
+ ldw oR26(%r3), %r26
+ ldw oR27(%r3), %r27
+ ldw oR28(%r3), %r28
+ ldw oR29(%r3), %r29
+ ldw oR30(%r3), %sp
+ /* ldw oR31(%r3), %r31 - dyncall scratch register */
+
+ /* Restore floating-point registers. */
+ ldo oFPREGS31(%r3), %r22
+ fldds 0(%r22), %fr31
+ fldds,mb -8(%r22), %fr30
+ fldds,mb -8(%r22), %fr29
+ fldds,mb -8(%r22), %fr28
+ fldds,mb -8(%r22), %fr27
+ fldds,mb -8(%r22), %fr26
+ fldds,mb -8(%r22), %fr25
+ fldds,mb -8(%r22), %fr24
+ fldds,mb -8(%r22), %fr23
+ fldds,mb -8(%r22), %fr22
+ fldds,mb -8(%r22), %fr21
+ fldds,mb -8(%r22), %fr20
+ fldds,mb -8(%r22), %fr19
+ fldds,mb -8(%r22), %fr18
+ fldds,mb -8(%r22), %fr17
+ fldds,mb -8(%r22), %fr16
+ fldds,mb -8(%r22), %fr15
+ fldds,mb -8(%r22), %fr14
+ fldds,mb -8(%r22), %fr13
+ fldds,mb -8(%r22), %fr12
+ fldds,mb -8(%r22), %fr11
+ fldds,mb -8(%r22), %fr10
+ fldds,mb -8(%r22), %fr9
+ fldds,mb -8(%r22), %fr8
+ fldds,mb -8(%r22), %fr7
+ fldds,mb -8(%r22), %fr6
+ fldds,mb -8(%r22), %fr5
+ fldds,mb -8(%r22), %fr4
+ fldds,mb -8(%r22), %fr3
+ fldds,mb -8(%r22), %fr2
+ fldds,mb -8(%r22), %fr1
+ fldds,mb -8(%r22), %fr0
+
+ /* Do not load oSS_SP into %sp. The value of oSS_SP indicates
+ the start of the user allocated stack, but not the sp that
+ should be used by the new context. In fact makecontext
+ will create a frame, and adjust sp as required. We do not
+ support calling getcontext and modifying ss_sp without
+ a call to makecontext to synchronize ss_sp into the machine
+ context. */
+
+ /* Call external function. */
+ copy %r2, %r22
+ bl $$dyncall, %r31
+ copy %r31, %r2
+
+ /* We return here. Get new ucp in %r3, reload %sp. */
+ ldw oUC_LINK(%r3), %r3
+ copy %r4, %sp
+ copy %r5, %dp
+ copy %r6, %r19
+
+ /* Continue until ucp == NULL. */
+ comib,<> 0,%r3,.Lagain
+ nop
+
+ /* No further context available. Exit now. */
+ bl _exit, %r2
+ ldi -1, %r26
+
+
+.Lerror:
+ /* Epilogue */
+ ldw -84(%r30), %r2
+#ifdef PIC
+ ldw -96(%r30), %r19
+#endif
+ bv %r0(%r2)
+ ldwm -64(%r30), %r3
+L(pseudo_end):
+PSEUDO_END(__setcontext)
+
+weak_alias(__setcontext, setcontext)
diff --git a/sysdeps/unix/sysv/linux/hppa/socket.S b/sysdeps/unix/sysv/linux/hppa/socket.S
new file mode 100644
index 0000000000..dfbb721a82
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/socket.S
@@ -0,0 +1,10 @@
+#include <sysdep.h>
+
+ .globl __socket
+PSEUDO(__socket, socket, 3)
+
+PSEUDO_END(__socket)
+
+#ifndef NO_WEAK_ALIAS
+weak_alias (__socket, socket)
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/swapcontext.c b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
new file mode 100644
index 0000000000..ec811868ec
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/swapcontext.c
@@ -0,0 +1,42 @@
+/* Swap to new context.
+ Copyright (C) 2008-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Helge Deller <deller@gmx.de>, 2008.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ucontext.h>
+
+extern int __getcontext (ucontext_t *ucp);
+extern int __setcontext (const ucontext_t *ucp);
+
+int
+__swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+ /* Save the current machine context to oucp. */
+ __getcontext (oucp);
+
+ /* mark sc_sar flag to skip the setcontext call on reactivation. */
+ if (oucp->uc_mcontext.sc_sar == 0) {
+ oucp->uc_mcontext.sc_sar++;
+
+ /* Restore the machine context in ucp. */
+ __setcontext (ucp);
+ }
+
+ return 0;
+}
+
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/epoll.h b/sysdeps/unix/sysv/linux/hppa/sys/epoll.h
new file mode 100644
index 0000000000..86e2ca1f6a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/epoll.h
@@ -0,0 +1,143 @@
+/* Copyright (C) 2002-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_EPOLL_H
+#define _SYS_EPOLL_H 1
+
+#include <stdint.h>
+#include <sys/types.h>
+
+/* Get __sigset_t. */
+#include <bits/sigset.h>
+
+#ifndef __sigset_t_defined
+# define __sigset_t_defined
+typedef __sigset_t sigset_t;
+#endif
+
+
+/* Flags to be passed to epoll_create1. */
+enum
+ {
+ EPOLL_CLOEXEC = 010000000
+#define EPOLL_CLOEXEC EPOLL_CLOEXEC
+ };
+
+
+enum EPOLL_EVENTS
+ {
+ EPOLLIN = 0x001,
+#define EPOLLIN EPOLLIN
+ EPOLLPRI = 0x002,
+#define EPOLLPRI EPOLLPRI
+ EPOLLOUT = 0x004,
+#define EPOLLOUT EPOLLOUT
+ EPOLLRDNORM = 0x040,
+#define EPOLLRDNORM EPOLLRDNORM
+ EPOLLRDBAND = 0x080,
+#define EPOLLRDBAND EPOLLRDBAND
+ EPOLLWRNORM = 0x100,
+#define EPOLLWRNORM EPOLLWRNORM
+ EPOLLWRBAND = 0x200,
+#define EPOLLWRBAND EPOLLWRBAND
+ EPOLLMSG = 0x400,
+#define EPOLLMSG EPOLLMSG
+ EPOLLERR = 0x008,
+#define EPOLLERR EPOLLERR
+ EPOLLHUP = 0x010,
+#define EPOLLHUP EPOLLHUP
+ EPOLLRDHUP = 0x2000,
+#define EPOLLRDHUP EPOLLRDHUP
+ EPOLLWAKEUP = 1u << 29,
+#define EPOLLWAKEUP EPOLLWAKEUP
+ EPOLLONESHOT = 1u << 30,
+#define EPOLLONESHOT EPOLLONESHOT
+ EPOLLET = 1u << 31
+#define EPOLLET EPOLLET
+ };
+
+
+/* Valid opcodes ( "op" parameter ) to issue to epoll_ctl(). */
+#define EPOLL_CTL_ADD 1 /* Add a file descriptor to the interface. */
+#define EPOLL_CTL_DEL 2 /* Remove a file descriptor from the interface. */
+#define EPOLL_CTL_MOD 3 /* Change file descriptor epoll_event structure. */
+
+
+typedef union epoll_data
+{
+ void *ptr;
+ int fd;
+ uint32_t u32;
+ uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event
+{
+ uint32_t events; /* Epoll events */
+ epoll_data_t data; /* User data variable */
+};
+
+
+__BEGIN_DECLS
+
+/* Creates an epoll instance. Returns an fd for the new instance.
+ The "size" parameter is a hint specifying the number of file
+ descriptors to be associated with the new instance. The fd
+ returned by epoll_create() should be closed with close(). */
+extern int epoll_create (int __size) __THROW;
+
+/* Same as epoll_create but with an FLAGS parameter. The unused SIZE
+ parameter has been dropped. */
+extern int epoll_create1 (int __flags) __THROW;
+
+
+/* Manipulate an epoll instance "epfd". Returns 0 in case of success,
+ -1 in case of error ( the "errno" variable will contain the
+ specific error code ) The "op" parameter is one of the EPOLL_CTL_*
+ constants defined above. The "fd" parameter is the target of the
+ operation. The "event" parameter describes which events the caller
+ is interested in and any associated user data. */
+extern int epoll_ctl (int __epfd, int __op, int __fd,
+ struct epoll_event *__event) __THROW;
+
+
+/* Wait for events on an epoll instance "epfd". Returns the number of
+ triggered events returned in "events" buffer. Or -1 in case of
+ error with the "errno" variable set to the specific error code. The
+ "events" parameter is a buffer that will contain triggered
+ events. The "maxevents" is the maximum number of events to be
+ returned ( usually size of "events" ). The "timeout" parameter
+ specifies the maximum wait time in milliseconds (-1 == infinite).
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int epoll_wait (int __epfd, struct epoll_event *__events,
+ int __maxevents, int __timeout);
+
+
+/* Same as epoll_wait, but the thread's signal mask is temporarily
+ and atomically replaced with the one provided as parameter.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int epoll_pwait (int __epfd, struct epoll_event *__events,
+ int __maxevents, int __timeout,
+ const __sigset_t *__ss);
+
+__END_DECLS
+
+#endif /* sys/epoll.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/eventfd.h b/sysdeps/unix/sysv/linux/hppa/sys/eventfd.h
new file mode 100644
index 0000000000..2d198a8f5b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/eventfd.h
@@ -0,0 +1,53 @@
+/* Copyright (C) 2007-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_EVENTFD_H
+#define _SYS_EVENTFD_H 1
+
+#include <stdint.h>
+
+
+/* Type for event counter. */
+typedef uint64_t eventfd_t;
+
+/* Flags for signalfd. */
+enum
+ {
+ EFD_SEMAPHORE = 1,
+#define EFD_SEMAPHORE EFD_SEMAPHORE
+ EFD_CLOEXEC = 010000000,
+#define EFD_CLOEXEC EFD_CLOEXEC
+ EFD_NONBLOCK = 00200004 /* HPUX has separate NDELAY & NONBLOCK */
+#define EFD_NONBLOCK EFD_NONBLOCK
+ };
+
+
+__BEGIN_DECLS
+
+/* Return file descriptor for generic event channel. Set initial
+ value to COUNT. */
+extern int eventfd (int __count, int __flags) __THROW;
+
+/* Read event counter and possibly wait for events. */
+extern int eventfd_read (int __fd, eventfd_t *__value);
+
+/* Increment event counter. */
+extern int eventfd_write (int __fd, eventfd_t __value);
+
+__END_DECLS
+
+#endif /* sys/eventfd.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/inotify.h b/sysdeps/unix/sysv/linux/hppa/sys/inotify.h
new file mode 100644
index 0000000000..ec78377781
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/inotify.h
@@ -0,0 +1,106 @@
+/* Copyright (C) 2005-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_INOTIFY_H
+#define _SYS_INOTIFY_H 1
+
+#include <stdint.h>
+
+
+/* Flags for the parameter of inotify_init1. */
+enum
+ {
+ IN_CLOEXEC = 010000000,
+#define IN_CLOEXEC IN_CLOEXEC
+ IN_NONBLOCK = 000200004 /* HPUX has separate NDELAY & NONBLOCK */
+#define IN_NONBLOCK IN_NONBLOCK
+ };
+
+
+/* Structure describing an inotify event. */
+struct inotify_event
+{
+ int wd; /* Watch descriptor. */
+ uint32_t mask; /* Watch mask. */
+ uint32_t cookie; /* Cookie to synchronize two events. */
+ uint32_t len; /* Length (including NULs) of name. */
+ char name __flexarr; /* Name. */
+};
+
+
+/* Supported events suitable for MASK parameter of INOTIFY_ADD_WATCH. */
+#define IN_ACCESS 0x00000001 /* File was accessed. */
+#define IN_MODIFY 0x00000002 /* File was modified. */
+#define IN_ATTRIB 0x00000004 /* Metadata changed. */
+#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed. */
+#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed. */
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* Close. */
+#define IN_OPEN 0x00000020 /* File was opened. */
+#define IN_MOVED_FROM 0x00000040 /* File was moved from X. */
+#define IN_MOVED_TO 0x00000080 /* File was moved to Y. */
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* Moves. */
+#define IN_CREATE 0x00000100 /* Subfile was created. */
+#define IN_DELETE 0x00000200 /* Subfile was deleted. */
+#define IN_DELETE_SELF 0x00000400 /* Self was deleted. */
+#define IN_MOVE_SELF 0x00000800 /* Self was moved. */
+
+/* Events sent by the kernel. */
+#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted. */
+#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed. */
+#define IN_IGNORED 0x00008000 /* File was ignored. */
+
+/* Helper events. */
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* Close. */
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* Moves. */
+
+/* Special flags. */
+#define IN_ONLYDIR 0x01000000 /* Only watch the path if it is a
+ directory. */
+#define IN_DONT_FOLLOW 0x02000000 /* Do not follow a sym link. */
+#define IN_EXCL_UNLINK 0x04000000 /* Exclude events on unlinked
+ objects. */
+#define IN_MASK_ADD 0x20000000 /* Add to the mask of an already
+ existing watch. */
+#define IN_ISDIR 0x40000000 /* Event occurred against dir. */
+#define IN_ONESHOT 0x80000000 /* Only send event once. */
+
+/* All events which a program can wait on. */
+#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE \
+ | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM \
+ | IN_MOVED_TO | IN_CREATE | IN_DELETE \
+ | IN_DELETE_SELF | IN_MOVE_SELF)
+
+
+__BEGIN_DECLS
+
+/* Create and initialize inotify instance. */
+extern int inotify_init (void) __THROW;
+
+/* Create and initialize inotify instance. */
+extern int inotify_init1 (int __flags) __THROW;
+
+/* Add watch of object NAME to inotify instance FD. Notify about
+ events specified by MASK. */
+extern int inotify_add_watch (int __fd, const char *__name, uint32_t __mask)
+ __THROW;
+
+/* Remove the watch specified by WD from the inotify instance FD. */
+extern int inotify_rm_watch (int __fd, int __wd) __THROW;
+
+__END_DECLS
+
+#endif /* sys/inotify.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/procfs.h b/sysdeps/unix/sysv/linux/hppa/sys/procfs.h
new file mode 100644
index 0000000000..6174471807
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/procfs.h
@@ -0,0 +1,118 @@
+/* Copyright (C) 1996-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H 1
+
+/* This is somewhat modelled after the file of the same name on SVR4
+ systems. It provides a definition of the core file format for ELF
+ used on Linux. It doesn't have anything to do with the /proc file
+ system, even though Linux has one.
+
+ Anyway, the whole purpose of this file is for GDB and GDB only.
+ Don't read too much into it. Don't use it for anything other than
+ GDB unless you know what you are doing. */
+
+#include <features.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+__BEGIN_DECLS
+
+typedef unsigned long elf_greg_t;
+#define ELF_NGREG 80 /* We only need 64 at present, but leave space
+ for expansion. */
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#define ELF_NFPREG 32
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+struct elf_siginfo
+ {
+ int si_signo; /* Signal number. */
+ int si_code; /* Extra code. */
+ int si_errno; /* Errno. */
+ };
+
+/* Definitions to generate Intel SVR4-like core files. These mostly
+ have the same names as the SVR4 types with "elf_" tacked on the
+ front to prevent clashes with Linux definitions, and the typedef
+ forms have been avoided. This is mostly like the SVR4 structure,
+ but more Linuxy, with things that Linux does not support and which
+ GDB doesn't really use excluded. */
+
+struct elf_prstatus
+ {
+ struct elf_siginfo pr_info; /* Info associated with signal. */
+ short int pr_cursig; /* Current signal. */
+ unsigned long int pr_sigpend; /* Set of pending signals. */
+ unsigned long int pr_sighold; /* Set of held signals. */
+ __pid_t pr_pid;
+ __pid_t pr_ppid;
+ __pid_t pr_pgrp;
+ __pid_t pr_sid;
+ struct timeval pr_utime; /* User time. */
+ struct timeval pr_stime; /* System time. */
+ struct timeval pr_cutime; /* Cumulative user time. */
+ struct timeval pr_cstime; /* Cumulative system time. */
+ elf_gregset_t pr_reg; /* GP registers. */
+ int pr_fpvalid; /* True if math copro being used. */
+ };
+
+
+#define ELF_PRARGSZ (80) /* Number of chars for args. */
+
+struct elf_prpsinfo
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ unsigned long int pr_flag; /* Flags. */
+ unsigned int pr_uid;
+ unsigned int pr_gid;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */
+ };
+
+
+/* The rest of this file provides the types for emulation of the
+ Solaris <proc_service.h> interfaces that should be implemented by
+ users of libthread_db. */
+
+/* Addresses. */
+typedef void *psaddr_t;
+
+/* Register sets. Linux has different names. */
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+
+/* We don't have any differences between processes and threads,
+ therefore have only one PID type. */
+typedef __pid_t lwpid_t;
+
+/* Process status and info. In the end we do provide typedefs for them. */
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+__END_DECLS
+
+#endif /* sys/procfs.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/signalfd.h b/sysdeps/unix/sysv/linux/hppa/sys/signalfd.h
new file mode 100644
index 0000000000..d6dc3a7762
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/signalfd.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 2007-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_SIGNALFD_H
+#define _SYS_SIGNALFD_H 1
+
+#define __need_sigset_t
+#include <signal.h>
+#include <stdint.h>
+
+
+struct signalfd_siginfo
+{
+ uint32_t ssi_signo;
+ int32_t ssi_errno;
+ int32_t ssi_code;
+ uint32_t ssi_pid;
+ uint32_t ssi_uid;
+ int32_t ssi_fd;
+ uint32_t ssi_tid;
+ uint32_t ssi_band;
+ uint32_t ssi_overrun;
+ uint32_t ssi_trapno;
+ int32_t ssi_status;
+ int32_t ssi_int;
+ uint64_t ssi_ptr;
+ uint64_t ssi_utime;
+ uint64_t ssi_stime;
+ uint64_t ssi_addr;
+ uint8_t __pad[48];
+};
+
+/* Flags for signalfd. */
+enum
+ {
+ SFD_CLOEXEC = 010000000,
+#define SFD_CLOEXEC SFD_CLOEXEC
+ SFD_NONBLOCK = 00200004 /* HPUX has separate NDELAY & NONBLOCK */
+#define SFD_NONBLOCK SFD_NONBLOCK
+ };
+
+__BEGIN_DECLS
+
+/* Request notification for delivery of signals in MASK to be
+ performed using descriptor FD.*/
+extern int signalfd (int __fd, const sigset_t *__mask, int __flags)
+ __THROW __nonnull ((2));
+
+__END_DECLS
+
+#endif /* sys/signalfd.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/timerfd.h b/sysdeps/unix/sysv/linux/hppa/sys/timerfd.h
new file mode 100644
index 0000000000..127e8e4386
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/timerfd.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 2008-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_TIMERFD_H
+#define _SYS_TIMERFD_H 1
+
+#include <time.h>
+
+
+/* Bits to be set in the FLAGS parameter of `timerfd_create'. */
+enum
+ {
+ TFD_CLOEXEC = 010000000,
+#define TFD_CLOEXEC TFD_CLOEXEC
+ TFD_NONBLOCK = 000200004 /* HPUX has separate NDELAY & NONBLOCK */
+#define TFD_NONBLOCK TFD_NONBLOCK
+ };
+
+
+/* Bits to be set in the FLAGS parameter of `timerfd_settime'. */
+enum
+ {
+ TFD_TIMER_ABSTIME = 1 << 0
+#define TFD_TIMER_ABSTIME TFD_TIMER_ABSTIME
+ };
+
+
+__BEGIN_DECLS
+
+/* Return file descriptor for new interval timer source. */
+extern int timerfd_create (clockid_t __clock_id, int __flags) __THROW;
+
+/* Set next expiration time of interval timer source UFD to UTMR. If
+ FLAGS has the TFD_TIMER_ABSTIME flag set the timeout value is
+ absolute. Optionally return the old expiration time in OTMR. */
+extern int timerfd_settime (int __ufd, int __flags,
+ const struct itimerspec *__utmr,
+ struct itimerspec *__otmr) __THROW;
+
+/* Return the next expiration time of UFD. */
+extern int timerfd_gettime (int __ufd, struct itimerspec *__otmr) __THROW;
+
+__END_DECLS
+
+#endif /* sys/timerfd.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h b/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h
new file mode 100644
index 0000000000..6c80433256
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h
@@ -0,0 +1,66 @@
+/* Copyright (C) 1997-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Don't rely on this, the interface is currently messed up and may need to
+ be broken to be fixed. */
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+
+/* Type for general register. */
+typedef unsigned long int greg_t;
+
+/* Number of general registers. */
+#define NGREG 80
+#define NFPREG 32
+
+/* Container for all general registers. */
+typedef struct gregset
+ {
+ greg_t g_regs[32];
+ greg_t sr_regs[8];
+ greg_t cr_regs[24];
+ greg_t g_pad[16];
+ } gregset_t;
+
+/* Container for all FPU registers. */
+typedef struct fpregset
+ {
+ double fp_dregs[32];
+ } fpregset_t;
+
+/* Context to describe whole processor state. */
+typedef struct sigcontext mcontext_t;
+
+/* Userlevel context. */
+typedef struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
+
+#endif /* sys/ucontext.h */
diff --git a/sysdeps/unix/sysv/linux/hppa/sys/user.h b/sysdeps/unix/sysv/linux/hppa/sys/user.h
new file mode 100644
index 0000000000..c871f1a03d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sys/user.h
@@ -0,0 +1 @@
+/* This file is not needed, but in practice gdb might try to include it. */
diff --git a/sysdeps/unix/sysv/linux/hppa/syscall.S b/sysdeps/unix/sysv/linux/hppa/syscall.S
new file mode 100644
index 0000000000..3efbd5a58f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/syscall.S
@@ -0,0 +1,18 @@
+/* Copyright (C) 1995-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+/* HPPA implements syscall() in 'C'; see sysdep.c. */
diff --git a/sysdeps/unix/sysv/linux/hppa/syscalls.list b/sysdeps/unix/sysv/linux/hppa/syscalls.list
new file mode 100644
index 0000000000..ae462edfe7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/syscalls.list
@@ -0,0 +1,39 @@
+# File name Caller Syscall name # args Strong name Weak names
+
+# semaphore and shm system calls
+msgctl - msgctl i:iip __msgctl msgctl
+msgget - msgget i:ii __msgget msgget
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
+shmat - shmat i:ipi __shmat shmat
+shmctl - shmctl i:iip __shmctl shmctl
+shmdt - shmdt i:s __shmdt shmdt
+shmget - shmget i:iii __shmget shmget
+semop - semop i:ipi __semop semop
+semtimedop - semtimedop i:ipip semtimedop
+semget - semget i:iii __semget semget
+semctl - semctl i:iiii __semctl semctl
+
+# proper socket implementations:
+accept - accept Ci:iBN __libc_accept __accept accept
+bind - bind i:ipi __bind bind
+connect - connect Ci:ipi __libc_connect __connect_internal __connect connect
+getpeername - getpeername i:ipp __getpeername getpeername
+getsockname - getsockname i:ipp __getsockname getsockname
+getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
+listen - listen i:ii __listen listen
+recv - recv Ci:ibni __libc_recv __recv recv
+recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
+recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
+send - send Ci:ibni __libc_send __send send
+sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
+sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
+setsockopt - setsockopt i:iiibn __setsockopt setsockopt
+shutdown - shutdown i:ii __shutdown shutdown
+socket - socket i:iii __socket socket
+socketpair - socketpair i:iiif __socketpair socketpair
+
+setrlimit - setrlimit i:ip __setrlimit setrlimit
+getrlimit - getrlimit i:ip __getrlimit getrlimit
+prlimit64 EXTRA prlimit64 i:iipp __prlimit64 prlimit64@@GLIBC_2.17
+fanotify_mark EXTRA fanotify_mark i:iiiiis __fanotify_mark fanotify_mark@@GLIBC_2.19
diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep.c b/sysdeps/unix/sysv/linux/hppa/sysdep.c
new file mode 100644
index 0000000000..af45c6906d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sysdep.c
@@ -0,0 +1,77 @@
+/* Copyright (C) 1997-2014 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdarg.h>
+#include <sysdep.h>
+#include <errno.h>
+
+extern int __syscall_error(int err_no);
+extern long int syscall (long int __sysno, ...) __THROW;
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ an error number into errno. */
+int
+__syscall_error (int err_no)
+{
+ __set_errno (err_no);
+ return -1;
+}
+
+
+/* HPPA implements syscall() in 'C'; the assembler version would
+ typically be in syscall.S. Also note that we have INLINE_SYSCALL,
+ INTERNAL_SYSCALL, and all the generated pure assembly syscall wrappers.
+ How often the function is used is unknown. */
+
+long int
+syscall (long int __sysno, ...)
+{
+ /* FIXME: Keep this matching INLINE_SYSCALL for hppa */
+ va_list args;
+ long int arg0, arg1, arg2, arg3, arg4, arg5;
+ long int __sys_res;
+
+ /* Load varargs */
+ va_start (args, __sysno);
+ arg0 = va_arg (args, long int);
+ arg1 = va_arg (args, long int);
+ arg2 = va_arg (args, long int);
+ arg3 = va_arg (args, long int);
+ arg4 = va_arg (args, long int);
+ arg5 = va_arg (args, long int);
+ va_end (args);
+
+ {
+ register unsigned long int __res asm("r28");
+ PIC_REG_DEF
+ LOAD_ARGS_6 (arg0, arg1, arg2, arg3, arg4, arg5)
+ asm volatile (SAVE_ASM_PIC
+ " ble 0x100(%%sr2, %%r0) \n"
+ " copy %1, %%r20 \n"
+ LOAD_ASM_PIC
+ : "=r" (__res)
+ : "r" (__sysno) PIC_REG_USE ASM_ARGS_6
+ : "memory", CALL_CLOB_REGS CLOB_ARGS_6);
+ __sys_res = __res;
+ }
+ if ((unsigned long int) __sys_res >= (unsigned long int) -4095)
+ {
+ __set_errno (-__sys_res);
+ __sys_res = -1;
+ }
+ return __sys_res;
+}
diff --git a/sysdeps/unix/sysv/linux/hppa/sysdep.h b/sysdeps/unix/sysv/linux/hppa/sysdep.h
new file mode 100644
index 0000000000..adbf55420b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/sysdep.h
@@ -0,0 +1,497 @@
+/* Assembler macros for PA-RISC.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper, <drepper@cygnus.com>, August 1999.
+ Linux/PA-RISC changes by Philipp Rumpf, <prumpf@tux.org>, March 2000.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <asm/unistd.h>
+#include <sysdeps/generic/sysdep.h>
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL. */
+#ifndef __ASSEMBLER__
+#include <errno.h>
+#endif
+
+#undef ASM_LINE_SEP
+#define ASM_LINE_SEP !
+
+#undef SYS_ify
+#define SYS_ify(syscall_name) (__NR_##syscall_name)
+
+/* The vfork, fork, and clone syscalls clobber r19
+ * and r21. We list r21 as either clobbered or as an
+ * input to a 6-argument syscall. We must save and
+ * restore r19 in both PIC and non-PIC cases.
+ */
+/* WARNING: TREG must be a callee saves register so
+ that it doesn't have to be restored after a call
+ to another function */
+#define TREG 4
+#define SAVE_PIC(SREG) \
+ copy %r19, SREG ASM_LINE_SEP \
+ .cfi_register 19, SREG
+#define LOAD_PIC(LREG) \
+ copy LREG , %r19 ASM_LINE_SEP \
+ .cfi_restore 19
+/* Inline assembly defines */
+#define TREG_ASM "%r4" /* Cant clobber r3, it holds framemarker */
+#define SAVE_ASM_PIC " copy %%r19, %" TREG_ASM "\n"
+#define LOAD_ASM_PIC " copy %" TREG_ASM ", %%r19\n"
+#define CLOB_TREG TREG_ASM ,
+#define PIC_REG_DEF register unsigned long __r19 asm("r19");
+#define PIC_REG_USE , "r" (__r19)
+
+#ifdef __ASSEMBLER__
+
+/* Syntactic details of assembler. */
+
+#define ALIGNARG(log2) log2
+
+/* For Linux we can use the system call table in the header file
+ /usr/include/asm/unistd.h
+ of the kernel. But these symbols do not follow the SYS_* syntax
+ so we have to redefine the `SYS_ify' macro here. */
+#undef SYS_ify
+#define SYS_ify(syscall_name) __NR_##syscall_name
+
+/* ELF-like local names start with `.L'. */
+#undef L
+#define L(name) .L##name
+
+/* Linux uses a negative return value to indicate syscall errors,
+ unlike most Unices, which use the condition codes' carry flag.
+
+ Since version 2.1 the return value of a system call might be
+ negative even if the call succeeded. E.g., the `lseek' system call
+ might return a large offset. Therefore we must not anymore test
+ for < 0, but test for a real error by making sure the value in %eax
+ is a real error number. Linus said he will make sure the no syscall
+ returns a value in -1 .. -4095 as a valid result so we can safely
+ test with -4095. */
+
+/* We don't want the label for the error handle to be global when we define
+ it here. */
+/*#ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+#else
+# define SYSCALL_ERROR_LABEL syscall_error
+#endif*/
+
+/* Argument manipulation from the stack for preparing to
+ make a syscall */
+
+#define DOARGS_0 /* nothing */
+#define DOARGS_1 /* nothing */
+#define DOARGS_2 /* nothing */
+#define DOARGS_3 /* nothing */
+#define DOARGS_4 /* nothing */
+#define DOARGS_5 ldw -52(%sp), %r22 ASM_LINE_SEP
+#define DOARGS_6 DOARGS_5 ldw -56(%sp), %r21 ASM_LINE_SEP
+
+#define UNDOARGS_0 /* nothing */
+#define UNDOARGS_1 /* nothing */
+#define UNDOARGS_2 /* nothing */
+#define UNDOARGS_3 /* nothing */
+#define UNDOARGS_4 /* nothing */
+#define UNDOARGS_5 /* nothing */
+#define UNDOARGS_6 /* nothing */
+
+/* Define an entry point visible from C.
+
+ There is currently a bug in gdb which prevents us from specifying
+ incomplete stabs information. Fake some entries here which specify
+ the current source file. */
+#define ENTRY(name) \
+ .text ASM_LINE_SEP \
+ .align ALIGNARG(4) ASM_LINE_SEP \
+ .export C_SYMBOL_NAME(name) ASM_LINE_SEP \
+ .type C_SYMBOL_NAME(name),@function ASM_LINE_SEP \
+ cfi_startproc ASM_LINE_SEP \
+ C_LABEL(name) ASM_LINE_SEP \
+ .PROC ASM_LINE_SEP \
+ .CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=3 ASM_LINE_SEP \
+ .ENTRY ASM_LINE_SEP \
+ /* SAVE_RP says we do */ ASM_LINE_SEP \
+ stw %rp, -20(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 2, -20 ASM_LINE_SEP \
+ /*FIXME: Call mcount? (carefull with stack!) */
+
+/* Some syscall wrappers do not call other functions, and
+ hence are classified as leaf, so add NO_CALLS for gdb */
+#define ENTRY_LEAF(name) \
+ .text ASM_LINE_SEP \
+ .align ALIGNARG(4) ASM_LINE_SEP \
+ .export C_SYMBOL_NAME(name) ASM_LINE_SEP \
+ .type C_SYMBOL_NAME(name),@function ASM_LINE_SEP \
+ cfi_startproc ASM_LINE_SEP \
+ C_LABEL(name) ASM_LINE_SEP \
+ .PROC ASM_LINE_SEP \
+ .CALLINFO FRAME=64,NO_CALLS,SAVE_RP,ENTRY_GR=3 ASM_LINE_SEP \
+ .ENTRY ASM_LINE_SEP \
+ /* SAVE_RP says we do */ ASM_LINE_SEP \
+ stw %rp, -20(%sr0,%sp) ASM_LINE_SEP \
+ .cfi_offset 2, -20 ASM_LINE_SEP \
+ /*FIXME: Call mcount? (carefull with stack!) */
+
+#undef END
+#define END(name) \
+ .EXIT ASM_LINE_SEP \
+ .PROCEND ASM_LINE_SEP \
+ cfi_endproc ASM_LINE_SEP \
+.size C_SYMBOL_NAME(name), .-C_SYMBOL_NAME(name) ASM_LINE_SEP
+
+/* If compiled for profiling, call `mcount' at the start
+ of each function. No, don't bother. gcc will put the
+ call in for us. */
+#define CALL_MCOUNT /* Do nothing. */
+
+/* syscall wrappers consist of
+ #include <sysdep.h>
+ PSEUDO(...)
+ ret
+ PSEUDO_END(...)
+
+ which means
+ ENTRY(name)
+ DO_CALL(...)
+ bv,n 0(2)
+*/
+
+#define PSEUDO(name, syscall_name, args) \
+ ENTRY (name) ASM_LINE_SEP \
+ /* If necc. load args from stack */ ASM_LINE_SEP \
+ DOARGS_##args ASM_LINE_SEP \
+ DO_CALL (syscall_name, args) ASM_LINE_SEP \
+ UNDOARGS_##args ASM_LINE_SEP
+
+#define ret \
+ /* Return value set by ERRNO code */ ASM_LINE_SEP \
+ bv,n 0(2) ASM_LINE_SEP
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
+
+/* We don't set the errno on the return from the syscall */
+#define PSEUDO_NOERRNO(name, syscall_name, args) \
+ ENTRY_LEAF (name) ASM_LINE_SEP \
+ DOARGS_##args ASM_LINE_SEP \
+ DO_CALL_NOERRNO (syscall_name, args) ASM_LINE_SEP \
+ UNDOARGS_##args ASM_LINE_SEP
+
+#define ret_NOERRNO ret
+
+#undef PSEUDO_END_NOERRNO
+#define PSEUDO_END_NOERRNO(name) \
+ END (name)
+
+/* This has to return the error value */
+#undef PSEUDO_ERRVAL
+#define PSEUDO_ERRVAL(name, syscall_name, args) \
+ ENTRY_LEAF (name) ASM_LINE_SEP \
+ DOARGS_##args ASM_LINE_SEP \
+ DO_CALL_ERRVAL (syscall_name, args) ASM_LINE_SEP \
+ UNDOARGS_##args ASM_LINE_SEP
+
+#define ret_ERRVAL ret
+
+#undef PSEUDO_END_ERRVAL
+#define PSEUDO_END_ERRVAL(name) \
+ END(name)
+
+#undef JUMPTARGET
+#define JUMPTARGET(name) name
+#define SYSCALL_PIC_SETUP /* Nothing. */
+
+
+/* FIXME: This comment is not true.
+ * All the syscall assembly macros rely on finding the appropriate
+ SYSCALL_ERROR_LABEL or rather HANDLER. */
+
+/* int * __errno_location(void) so you have to store your value
+ into the return address! */
+#define DEFAULT_SYSCALL_ERROR_HANDLER \
+ .import __errno_location,code ASM_LINE_SEP \
+ /* branch to errno handler */ ASM_LINE_SEP \
+ bl __errno_location,%rp ASM_LINE_SEP
+
+/* Here are the myriad of configuration options that the above can
+ work for... what we've done is provide the framework for future
+ changes if required to each section */
+
+#ifdef PIC
+# if RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER DEFAULT_SYSCALL_ERROR_HANDLER
+# else /* !RTLD_PRIVATE_ERRNO */
+# if defined _LIBC_REENTRANT
+# define SYSCALL_ERROR_HANDLER DEFAULT_SYSCALL_ERROR_HANDLER
+# else /* !_LIBC_REENTRANT */
+# define SYSCALL_ERROR_HANDLER DEFAULT_SYSCALL_ERROR_HANDLER
+# endif /* _LIBC_REENTRANT */
+# endif /* RTLD_PRIVATE_ERRNO */
+#else
+# ifndef _LIBC_REENTRANT
+# define SYSCALL_ERROR_HANDLER DEFAULT_SYSCALL_ERROR_HANDLER
+# else
+# define SYSCALL_ERROR_HANDLER DEFAULT_SYSCALL_ERROR_HANDLER
+# endif
+#endif
+
+
+/* Linux takes system call arguments in registers:
+ syscall number gr20
+ arg 1 gr26
+ arg 2 gr25
+ arg 3 gr24
+ arg 4 gr23
+ arg 5 gr22
+ arg 6 gr21
+
+ The compiler calls us by the C convention:
+ syscall number in the DO_CALL macro
+ arg 1 gr26
+ arg 2 gr25
+ arg 3 gr24
+ arg 4 gr23
+ arg 5 -52(sp)
+ arg 6 -56(sp)
+
+ gr22 and gr21 are caller-saves, so we can just load the arguments
+ there and generally be happy. */
+
+/* the cmpb...no_error code below inside DO_CALL
+ * is intended to mimic the if (__sys_res...)
+ * code inside INLINE_SYSCALL
+ */
+#define NO_ERROR -0x1000
+
+#undef DO_CALL
+#define DO_CALL(syscall_name, args) \
+ /* Create a frame */ ASM_LINE_SEP \
+ stwm TREG, 64(%sp) ASM_LINE_SEP \
+ .cfi_offset TREG, 0 ASM_LINE_SEP \
+ .cfi_adjust_cfa_offset 64 ASM_LINE_SEP \
+ stw %sp, -4(%sp) ASM_LINE_SEP \
+ .cfi_offset 30, -4 ASM_LINE_SEP \
+ stw %r19, -32(%sp) ASM_LINE_SEP \
+ .cfi_offset 19, -32 ASM_LINE_SEP \
+ /* Save r19 */ ASM_LINE_SEP \
+ SAVE_PIC(TREG) ASM_LINE_SEP \
+ /* Do syscall, delay loads # */ ASM_LINE_SEP \
+ ble 0x100(%sr2,%r0) ASM_LINE_SEP \
+ ldi SYS_ify (syscall_name), %r20 ASM_LINE_SEP \
+ ldi NO_ERROR,%r1 ASM_LINE_SEP \
+ cmpb,>>=,n %r1,%ret0,L(pre_end) ASM_LINE_SEP \
+ /* Restore r19 from TREG */ ASM_LINE_SEP \
+ LOAD_PIC(TREG) /* delay */ ASM_LINE_SEP \
+ SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
+ /* Use TREG for temp storage */ ASM_LINE_SEP \
+ copy %ret0, TREG /* delay */ ASM_LINE_SEP \
+ /* OPTIMIZE: Don't reload r19 */ ASM_LINE_SEP \
+ /* do a -1*syscall_ret0 */ ASM_LINE_SEP \
+ sub %r0, TREG, TREG ASM_LINE_SEP \
+ /* Store into errno location */ ASM_LINE_SEP \
+ stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
+ /* return -1 as error */ ASM_LINE_SEP \
+ ldo -1(%r0), %ret0 ASM_LINE_SEP \
+L(pre_end): ASM_LINE_SEP \
+ /* Restore our frame, restoring TREG */ ASM_LINE_SEP \
+ ldwm -64(%sp), TREG ASM_LINE_SEP \
+ .cfi_adjust_cfa_offset -64 ASM_LINE_SEP \
+ /* Restore return pointer */ ASM_LINE_SEP \
+ ldw -20(%sp),%rp ASM_LINE_SEP \
+ .cfi_restore 2 ASM_LINE_SEP
+
+/* We do nothing with the return, except hand it back to someone else */
+#undef DO_CALL_NOERRNO
+#define DO_CALL_NOERRNO(syscall_name, args) \
+ /* No need to store r19 */ ASM_LINE_SEP \
+ ble 0x100(%sr2,%r0) ASM_LINE_SEP \
+ ldi SYS_ify (syscall_name), %r20 ASM_LINE_SEP \
+ /* Caller will restore r19 */ ASM_LINE_SEP
+
+/* Here, we return the ERRVAL in assembly, note we don't call the
+ error handler function, but we do 'negate' the return _IF_
+ it's an error. Not sure if this is the right semantic. */
+
+#undef DO_CALL_ERRVAL
+#define DO_CALL_ERRVAL(syscall_name, args) \
+ /* No need to store r19 */ ASM_LINE_SEP \
+ ble 0x100(%sr2,%r0) ASM_LINE_SEP \
+ ldi SYS_ify (syscall_name), %r20 ASM_LINE_SEP \
+ /* Caller will restore r19 */ ASM_LINE_SEP \
+ ldi NO_ERROR,%r1 ASM_LINE_SEP \
+ cmpb,>>=,n %r1,%ret0,0f ASM_LINE_SEP \
+ sub %r0, %ret0, %ret0 ASM_LINE_SEP \
+0: ASM_LINE_SEP
+
+
+#else
+
+/* GCC has to be warned that a syscall may clobber all the ABI
+ registers listed as "caller-saves", see page 8, Table 2
+ in section 2.2.6 of the PA-RISC RUN-TIME architecture
+ document. However! r28 is the result and will conflict with
+ the clobber list so it is left out. Also the input arguments
+ registers r20 -> r26 will conflict with the list so they
+ are treated specially. Although r19 is clobbered by the syscall
+ we cannot say this because it would violate ABI, thus we say
+ TREG is clobbered and use that register to save/restore r19
+ across the syscall. */
+
+#define CALL_CLOB_REGS "%r1", "%r2", CLOB_TREG \
+ "%r20", "%r29", "%r31"
+
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+({ \
+ long __sys_res; \
+ { \
+ register unsigned long __res asm("r28"); \
+ PIC_REG_DEF \
+ LOAD_ARGS_##nr(args) \
+ /* FIXME: HACK save/load r19 around syscall */ \
+ asm volatile( \
+ SAVE_ASM_PIC \
+ " ble 0x100(%%sr2, %%r0)\n" \
+ " ldi %1, %%r20\n" \
+ LOAD_ASM_PIC \
+ : "=r" (__res) \
+ : "i" (SYS_ify(name)) PIC_REG_USE ASM_ARGS_##nr \
+ : "memory", CALL_CLOB_REGS CLOB_ARGS_##nr \
+ ); \
+ __sys_res = (long)__res; \
+ } \
+ if ( (unsigned long)__sys_res >= (unsigned long)-4095 ){ \
+ __set_errno(-__sys_res); \
+ __sys_res = -1; \
+ } \
+ __sys_res; \
+})
+
+/* INTERNAL_SYSCALL_DECL - Allows us to setup some function static
+ value to use within the context of the syscall
+ INTERNAL_SYSCALL_ERROR_P - Returns 0 if it wasn't an error, 1 otherwise
+ You are allowed to use the syscall result (val) and the DECL error
+ variable to determine what went wrong.
+ INTERLAL_SYSCALL_ERRNO - Munges the val/err pair into the error number.
+ In our case we just flip the sign. */
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err)
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((val < 0) && (val > -4095))
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+/* Similar to INLINE_SYSCALL but we don't set errno */
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+({ \
+ long __sys_res; \
+ { \
+ register unsigned long __res asm("r28"); \
+ PIC_REG_DEF \
+ LOAD_ARGS_##nr(args) \
+ /* FIXME: HACK save/load r19 around syscall */ \
+ asm volatile( \
+ SAVE_ASM_PIC \
+ " ble 0x100(%%sr2, %%r0)\n" \
+ " ldi %1, %%r20\n" \
+ LOAD_ASM_PIC \
+ : "=r" (__res) \
+ : "i" (SYS_ify(name)) PIC_REG_USE ASM_ARGS_##nr \
+ : "memory", CALL_CLOB_REGS CLOB_ARGS_##nr \
+ ); \
+ __sys_res = (long)__res; \
+ } \
+ __sys_res; \
+ })
+
+
+/* The _NCS variant allows non-constant syscall numbers. */
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+({ \
+ long __sys_res; \
+ { \
+ register unsigned long __res asm("r28"); \
+ PIC_REG_DEF \
+ LOAD_ARGS_##nr(args) \
+ /* FIXME: HACK save/load r19 around syscall */ \
+ asm volatile( \
+ SAVE_ASM_PIC \
+ " ble 0x100(%%sr2, %%r0)\n" \
+ " copy %1, %%r20\n" \
+ LOAD_ASM_PIC \
+ : "=r" (__res) \
+ : "r" (name) PIC_REG_USE ASM_ARGS_##nr \
+ : "memory", CALL_CLOB_REGS CLOB_ARGS_##nr \
+ ); \
+ __sys_res = (long)__res; \
+ } \
+ __sys_res; \
+ })
+
+
+
+#define LOAD_ARGS_0()
+#define LOAD_ARGS_1(r26) \
+ register unsigned long __r26 __asm__("r26") = (unsigned long)(r26); \
+ LOAD_ARGS_0()
+#define LOAD_ARGS_2(r26,r25) \
+ register unsigned long __r25 __asm__("r25") = (unsigned long)(r25); \
+ LOAD_ARGS_1(r26)
+#define LOAD_ARGS_3(r26,r25,r24) \
+ register unsigned long __r24 __asm__("r24") = (unsigned long)(r24); \
+ LOAD_ARGS_2(r26,r25)
+#define LOAD_ARGS_4(r26,r25,r24,r23) \
+ register unsigned long __r23 __asm__("r23") = (unsigned long)(r23); \
+ LOAD_ARGS_3(r26,r25,r24)
+#define LOAD_ARGS_5(r26,r25,r24,r23,r22) \
+ register unsigned long __r22 __asm__("r22") = (unsigned long)(r22); \
+ LOAD_ARGS_4(r26,r25,r24,r23)
+#define LOAD_ARGS_6(r26,r25,r24,r23,r22,r21) \
+ register unsigned long __r21 __asm__("r21") = (unsigned long)(r21); \
+ LOAD_ARGS_5(r26,r25,r24,r23,r22)
+
+/* Even with zero args we use r20 for the syscall number */
+#define ASM_ARGS_0
+#define ASM_ARGS_1 ASM_ARGS_0, "r" (__r26)
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (__r25)
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (__r24)
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (__r23)
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (__r22)
+#define ASM_ARGS_6 ASM_ARGS_5, "r" (__r21)
+
+/* The registers not listed as inputs but clobbered */
+#define CLOB_ARGS_6
+#define CLOB_ARGS_5 CLOB_ARGS_6, "%r21"
+#define CLOB_ARGS_4 CLOB_ARGS_5, "%r22"
+#define CLOB_ARGS_3 CLOB_ARGS_4, "%r23"
+#define CLOB_ARGS_2 CLOB_ARGS_3, "%r24"
+#define CLOB_ARGS_1 CLOB_ARGS_2, "%r25"
+#define CLOB_ARGS_0 CLOB_ARGS_1, "%r26"
+
+#endif /* __ASSEMBLER__ */
+
+/* Pointer mangling is not yet supported for HPPA. */
+#define PTR_MANGLE(var) (void) (var)
+#define PTR_DEMANGLE(var) (void) (var)
diff --git a/sysdeps/unix/sysv/linux/hppa/ucontext_i.sym b/sysdeps/unix/sysv/linux/hppa/ucontext_i.sym
new file mode 100644
index 0000000000..ee33029a07
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/ucontext_i.sym
@@ -0,0 +1,59 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_SETMASK
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+#define mreg(reg) mcontext (sc_gr[reg])
+
+oUC_FLAGS ucontext (uc_flags)
+oUC_LINK ucontext (uc_link)
+oSS_SP ucontext (uc_stack.ss_sp)
+oSS_FLAGS ucontext (uc_stack.ss_flags)
+oSS_SIZE ucontext (uc_stack.ss_size)
+oSC_FLAGS mcontext (sc_flags)
+oR0 mreg (0)
+oR1 mreg (1)
+oR2 mreg (2)
+oR3 mreg (3)
+oR4 mreg (4)
+oR5 mreg (5)
+oR6 mreg (6)
+oR7 mreg (7)
+oR8 mreg (8)
+oR9 mreg (9)
+oR10 mreg (10)
+oR11 mreg (11)
+oR12 mreg (12)
+oR13 mreg (13)
+oR14 mreg (14)
+oR15 mreg (15)
+oR16 mreg (16)
+oR17 mreg (17)
+oR18 mreg (18)
+oR19 mreg (19)
+oR20 mreg (20)
+oR21 mreg (21)
+oR22 mreg (22)
+oR23 mreg (23)
+oR24 mreg (24)
+oR25 mreg (25)
+oR26 mreg (26)
+oR27 mreg (27)
+oR28 mreg (28)
+oR29 mreg (29)
+oR30 mreg (30)
+oR31 mreg (31)
+oFPREGS0 mcontext (sc_fr[0])
+oFPREGS31 mcontext (sc_fr[31])
+oIASQ0 mcontext (sc_iasq[0])
+oIASQ1 mcontext (sc_iasq[1])
+oIAOQ0 mcontext (sc_iaoq[0])
+oIAOQ1 mcontext (sc_iaoq[1])
+oSAR mcontext (sc_sar)
+oSIGMASK ucontext (uc_sigmask)
diff --git a/sysdeps/unix/sysv/linux/hppa/umount.c b/sysdeps/unix/sysv/linux/hppa/umount.c
new file mode 100644
index 0000000000..208fbec994
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/umount.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/mips/mips64/umount.c>
diff --git a/sysdeps/unix/sysv/linux/hppa/xstat.c b/sysdeps/unix/sysv/linux/hppa/xstat.c
new file mode 100644
index 0000000000..e9869f5508
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/xstat.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/xstat.c>