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