diff options
author | Carlos O'Donell <carlos@systemhalted.org> | 2012-11-19 00:28:30 -0500 |
---|---|---|
committer | Carlos O'Donell <carlos@systemhalted.org> | 2012-11-19 00:28:30 -0500 |
commit | 320194d5b958156a9ad21e8c4e07e8033b405ccd (patch) | |
tree | da19acdb612dc723b93a792f83edfff42c92b2d0 /ports/sysdeps/hppa | |
parent | 05b227bdaea9a5f1faf08dad31221d8736f3659d (diff) | |
download | glibc-320194d5b958156a9ad21e8c4e07e8033b405ccd.tar.gz |
hppa: Implement __longjmp_chk.
Implement longjmp and the chk variant in C.
Diffstat (limited to 'ports/sysdeps/hppa')
-rw-r--r-- | ports/sysdeps/hppa/__longjmp.S | 71 | ||||
-rw-r--r-- | ports/sysdeps/hppa/__longjmp.c | 83 | ||||
-rw-r--r-- | ports/sysdeps/hppa/bits/setjmp.h | 39 | ||||
-rw-r--r-- | ports/sysdeps/hppa/setjmp.S | 8 |
4 files changed, 121 insertions, 80 deletions
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 |