Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / alpha / ____longjmp_chk.S
blob8cabe31cf106ef63100836440449a61ee3f29d20
1 /* Copyright (C) 1992-2015 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library.  If not, see
16    <http://www.gnu.org/licenses/>.  */
18 #include <sysdep.h>
19 #include <jmpbuf-offsets.h>
22         .section .rodata.str1.1,"aMS",@progbits,1
23         .type   longjmp_msg,@object
24 longjmp_msg:
25         .string "longjmp causes uninitialized stack frame"
26         .size   longjmp_msg, .-longjmp_msg
29 /* Jump to the position specified by ENV, causing the
30    setjmp call there to return VAL, or 1 if VAL is 0.
31    void __longjmp (__jmp_buf env, int val).  */
32         .text
33         .align  4
34         .globl  ____longjmp_chk
35         .type   ____longjmp_chk, @function
36         .usepv  ____longjmp_chk, std
38         cfi_startproc
39 ____longjmp_chk:
40         ldgp    gp, 0(pv)
41 #ifdef PROF
42         .set noat
43         lda     AT, _mcount
44         jsr     AT, (AT), _mcount
45         .set at
46 #endif
48         ldq     s2, JB_PC*8(a0)
49         mov     a0, s0
50         ldq     fp, JB_FP*8(a0)
51         mov     a1, s1
52         ldq     s3, JB_SP*8(a0)
53         cmoveq  s1, 1, s1
55 #ifdef PTR_DEMANGLE
56         PTR_DEMANGLE(s2, t1)
57         PTR_DEMANGLE2(s3, t1)
58         PTR_DEMANGLE2(fp, t1)
59 #endif
60         /* ??? While this is a proper test for detecting a longjmp to an
61            invalid frame within any given stack, the main thread stack is
62            located *below* almost everything in the address space.  Which
63            means that the test at Lfail vs the signal stack will almost
64            certainly never pass.  We ought bounds check top and bottom of
65            the current thread's stack.  */
66         cmpule  s3, sp, t1
67         bne     t1, $Lfail
69         .align  4
70 $Lok:
71         mov     s0, a0
72         mov     s1, v0
73         mov     s3, t0
74         mov     s2, ra
75         cfi_remember_state
76         cfi_def_cfa(a0, 0)
77         cfi_register(sp, t0)
78         cfi_offset(s0, JB_S0*8)
79         cfi_offset(s1, JB_S1*8)
80         cfi_offset(s2, JB_S2*8)
81         cfi_offset(s3, JB_S3*8)
82         cfi_offset(s4, JB_S4*8)
83         cfi_offset(s5, JB_S5*8)
84         cfi_offset(s3, JB_S3*8)
85         cfi_offset($f2, JB_F2*8)
86         cfi_offset($f3, JB_F3*8)
87         cfi_offset($f4, JB_F4*8)
88         cfi_offset($f5, JB_F5*8)
89         cfi_offset($f6, JB_F6*8)
90         cfi_offset($f7, JB_F7*8)
91         cfi_offset($f8, JB_F8*8)
92         cfi_offset($f9, JB_F9*8)
93         ldq     s0, JB_S0*8(a0)
94         ldq     s1, JB_S1*8(a0)
95         ldq     s2, JB_S2*8(a0)
96         ldq     s3, JB_S3*8(a0)
97         ldq     s4, JB_S4*8(a0)
98         ldq     s5, JB_S5*8(a0)
99         ldt     $f2, JB_F2*8(a0)
100         ldt     $f3, JB_F3*8(a0)
101         ldt     $f4, JB_F4*8(a0)
102         ldt     $f5, JB_F5*8(a0)
103         ldt     $f6, JB_F6*8(a0)
104         ldt     $f7, JB_F7*8(a0)
105         ldt     $f8, JB_F8*8(a0)
106         ldt     $f9, JB_F9*8(a0)
107         mov     t0, sp
108         ret
110         .align  4
111 $Lfail:
112         cfi_restore_state
113         lda     v0, __NR_sigaltstack
114         lda     a0, 0
115         lda     a1, -32(sp)
116         lda     sp, -32(sp)
117         cfi_adjust_cfa_offset(32)
118         callsys
119         ldq     t0, 0(sp)       /* ss_sp */
120         ldl     t1, 8(sp)       /* ss_flags */
121         ldq     t2, 16(sp)      /* ss_size */
122         lda     sp, 32(sp)
123         cfi_adjust_cfa_offset(-32)
125         /* Without working sigaltstack we cannot perform the test.  */
126         bne     a3, $Lok
128         addq    t0, t2, t0      /* t0 = ss_sp + ss_size */
129         subq    t0, s3, t0      /* t0 = (ss_sp + ss_size) - new_sp */
130         cmpule  t2, t0, t0      /* t0 = (t0 >= ss_size) */
131         and     t0, t1, t0      /* t0 = (t0 >= ss_size) & (ss_flags & SS_ONSTACK) */
132         bne     t0, $Lok
134         ldah    a0, longjmp_msg(gp)     !gprelhigh
135         lda     a0, longjmp_msg(a0)     !gprellow
136 #ifdef PIC
137         jsr     ra, HIDDEN_JUMPTARGET(__fortify_fail)
138 #else
139         bsr     ra, HIDDEN_JUMPTARGET(__fortify_fail)   !samegp
140 #endif
141         bugchk
143         cfi_endproc
144         .size   ____longjmp_chk, .-____longjmp_chk