about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2012-11-19 00:28:30 -0500
committerCarlos O'Donell <carlos@systemhalted.org>2012-11-19 00:28:30 -0500
commit320194d5b958156a9ad21e8c4e07e8033b405ccd (patch)
treeda19acdb612dc723b93a792f83edfff42c92b2d0
parent05b227bdaea9a5f1faf08dad31221d8736f3659d (diff)
downloadglibc-320194d5b958156a9ad21e8c4e07e8033b405ccd.tar.gz
glibc-320194d5b958156a9ad21e8c4e07e8033b405ccd.tar.xz
glibc-320194d5b958156a9ad21e8c4e07e8033b405ccd.zip
hppa: Implement __longjmp_chk.
Implement longjmp and the chk variant in C.
-rw-r--r--ports/ChangeLog.hppa8
-rw-r--r--ports/sysdeps/hppa/__longjmp.S71
-rw-r--r--ports/sysdeps/hppa/__longjmp.c83
-rw-r--r--ports/sysdeps/hppa/bits/setjmp.h39
-rw-r--r--ports/sysdeps/hppa/setjmp.S8
5 files changed, 129 insertions, 80 deletions
diff --git a/ports/ChangeLog.hppa b/ports/ChangeLog.hppa
index 201dd01def..71b5e178fc 100644
--- a/ports/ChangeLog.hppa
+++ b/ports/ChangeLog.hppa
@@ -1,3 +1,11 @@
+2012-11-18  Carlos O'Donell  <carlos@systemhalted.org>
+
+	* ports/sysdeps/hppa/__longjmp.S: Removed.
+	* ports/sysdeps/hppa/__longjmp.c: New file.
+	* ports/sysdeps/unix/sysv/linux/hppa/____longjmp_chk.c: New file.
+	* ports/sysdeps/hppa/bits/setjmp.h: Use union for __jmp_buf.
+	* ports/sysdeps/hppa/setjmp.S: Comment byte offsets and padding.
+
 2012-11-05  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #14805]
diff --git a/ports/sysdeps/hppa/__longjmp.S b/ports/sysdeps/hppa/__longjmp.S
deleted file mode 100644
index 4ef219e414..0000000000
--- a/ports/sysdeps/hppa/__longjmp.S
+++ /dev/null
@@ -1,71 +0,0 @@
-/* longjmp for PA-RISC.
-   Copyright (C) 1997, 1998 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 _SETJMP_H
-#define _ASM
-#include <bits/setjmp.h>
-
-/* __longjmp(jmpbuf, val) */
-
-	.text
-	.align 4
-	.globl __longjmp
-	.export __longjmp, code
-	.proc
-	.callinfo
-__longjmp:	
-	/* set return value */
-	copy	%r25, %r28
-	
-	ldw	0(%r26), %r3
-	ldw	8(%r26), %r4
-	ldw	12(%r26), %r5
-	ldw	16(%r26), %r6
-	ldw	20(%r26), %r7
-	ldw	24(%r26), %r8
-	ldw	28(%r26), %r9
-	ldw	32(%r26), %r10
-	ldw	36(%r26), %r11
-	ldw	40(%r26), %r12
-	ldw	44(%r26), %r13
-	ldw	48(%r26), %r14
-	ldw	52(%r26), %r15
-	ldw	56(%r26), %r16
-	ldw	60(%r26), %r17
-	ldw	64(%r26), %r18
-	ldw	68(%r26), %r19
-	ldw	72(%r26), %r27
-	ldw	76(%r26), %r30
-	
-	ldw	80(%r26), %rp
-
-	ldo	88(%r26),%r20
-	fldds,ma 8(%r20), %fr12
-	fldds,ma 8(%r20), %fr13
-	fldds,ma 8(%r20), %fr14
-	fldds,ma 8(%r20), %fr15
-	fldds,ma 8(%r20), %fr16
-	fldds,ma 8(%r20), %fr17
-	fldds,ma 8(%r20), %fr18
-	fldds,ma 8(%r20), %fr19
-	fldds,ma 8(%r20), %fr20
-	fldds	 0(%r20), %fr21
-
-	bv,n	%r0(%r2)
-	.procend
diff --git a/ports/sysdeps/hppa/__longjmp.c b/ports/sysdeps/hppa/__longjmp.c
new file mode 100644
index 0000000000..8ad51055f2
--- /dev/null
+++ b/ports/sysdeps/hppa/__longjmp.c
@@ -0,0 +1,83 @@
+/* longjmp for PA-RISC.
+   Copyright (C) 1997-2012 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];
+
+#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),%%r20\n\t"
+	/* Load callee saves from fr12 to fr21.  */
+	"fldds,ma 8(%%r20), %%fr12\n\t"
+	"fldds,ma 8(%%r20), %%fr13\n\t"
+	"fldds,ma 8(%%r20), %%fr14\n\t"
+	"fldds,ma 8(%%r20), %%fr15\n\t"
+	"fldds,ma 8(%%r20), %%fr16\n\t"
+	"fldds,ma 8(%%r20), %%fr17\n\t"
+	"fldds,ma 8(%%r20), %%fr18\n\t"
+	"fldds,ma 8(%%r20), %%fr19\n\t"
+	"fldds,ma 8(%%r20), %%fr20\n\t"
+	"fldds	 0(%%r20), %%fr21\n\t"
+	/* Jump back to stored return address.  */
+	"bv,n	%%r0(%%r2)\n\t"
+	: /* No outputs.  */
+	: "r" (val == 0 ? 1 : val), "r" (r26)
+	: /* No point in clobbers.  */ );
+  /* Avoid `volatile function does return' warnings.  */
+  for (;;);
+}
diff --git a/ports/sysdeps/hppa/bits/setjmp.h b/ports/sysdeps/hppa/bits/setjmp.h
index 19a0cfe621..7283cc16f3 100644
--- a/ports/sysdeps/hppa/bits/setjmp.h
+++ b/ports/sysdeps/hppa/bits/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2012 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
@@ -23,13 +23,38 @@
 # error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
 #endif
 
-/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
-   We use an array of 'double' instead, to make writing the assembler
-   easier, and to ensure proper alignment. Naturally, user code should
-   not depend on either representation. */
-
 #ifndef	_ASM
-typedef double __jmp_buf[21];
+/* 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/ports/sysdeps/hppa/setjmp.S b/ports/sysdeps/hppa/setjmp.S
index 146e4d1943..0f05fd9951 100644
--- a/ports/sysdeps/hppa/setjmp.S
+++ b/ports/sysdeps/hppa/setjmp.S
@@ -1,5 +1,5 @@
 /* setjmp for HPPA.
-   Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,8 @@
 	.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)
@@ -51,7 +53,8 @@ __sigsetjmp:
 	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 */
@@ -63,6 +66,7 @@ __sigsetjmp:
 	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