diff options
Diffstat (limited to 'libc/sysdeps/unix/sysv/linux/ia64')
-rw-r--r-- | libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S | 48 | ||||
-rw-r--r-- | libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S | 10 |
2 files changed, 57 insertions, 1 deletions
diff --git a/libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S b/libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S new file mode 100644 index 000000000..e097c2288 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/ia64/____longjmp_chk.S @@ -0,0 +1,48 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser 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. */ + + .section .rodata.str1.8,"aMS",@progbits,1 + .align 8 +.LC0: + .string "longjmp causes uninitialized stack frame" + + .section .sdata,"aws",@progbits + .align 8 + .type longjmp_msg,@object +longjmp_msg: + data8 .LC0 + .size longjmp_msg, .-longjmp_msg + +#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL __GI___fortify_fail +#else +# define CALL_FAIL __fortify_fail +#endif + +#define CHECK_RSP(reg) \ + cmp.ltu p0, p8 = reg, r12; \ +(p8) br.cond.dpnt .Lok;; \ + addl r28 = @ltoffx(longjmp_msg#), r1;; \ + ld8.mov r28 = [r28], longjmp_msg#;; \ + ld8 out0 = [r28]; \ + br.call.sptk.many b0 = CALL_FAIL#;; \ +.Lok: + +#include "__longjmp.S" diff --git a/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S b/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S index aa18fadf9..2e7490438 100644 --- a/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S +++ b/libc/sysdeps/unix/sysv/linux/ia64/__longjmp.S @@ -42,7 +42,11 @@ /* __longjmp(__jmp_buf buf, int val) */ LEAF(__longjmp) +#ifdef CHECK_RSP + alloc r8=ar.pfs,2,1,1,0 +#else alloc r8=ar.pfs,2,1,0,0 +#endif mov r27=ar.rsc add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr ;; @@ -70,14 +74,18 @@ LEAF(__longjmp) add r3=8,in0 // r3 <- &jmpbuf.r1 shl r9=r25,r17 ;; + ld8.fill.nta r28=[r2],16 // r28 <- jmpbuf.sp or r25=r8,r9 ;; mov r26=ar.rnat mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12) ;; - ld8.fill.nta sp=[r2],16 // r12 (sp) +#ifdef CHECK_RSP + CHECK_RSP (r28) +#endif ld8.fill.nta gp=[r3],16 // r1 (gp) dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp) + mov sp=r28 // r12 (sp) ;; ld8.nta r16=[r2],16 // caller's unat ld8.nta r17=[r3],16 // fpsr |