1/* Copyright (C) 1992-2022 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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 <https://www.gnu.org/licenses/>. */
17
18#include <sysdep.h>
19#include <jmpbuf-offsets.h>
20
21
22 .section .rodata.str1.1,"aMS",@progbits,1
23 .type longjmp_msg,@object
24longjmp_msg:
25 .string "longjmp causes uninitialized stack frame"
26 .size longjmp_msg, .-longjmp_msg
27
28
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
37
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
47
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
54
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
68
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
109
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)
124
125 /* Without working sigaltstack we cannot perform the test. */
126 bne a3, $Lok
127
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
133
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
142
143 cfi_endproc
144 .size ____longjmp_chk, .-____longjmp_chk
145

source code of glibc/sysdeps/unix/sysv/linux/alpha/____longjmp_chk.S