1/* Copyright (C) 1992-2024 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 <pointer_guard.h>
20#include <jmpbuf-offsets.h>
21
22
23 .section .rodata.str1.1,"aMS",@progbits,1
24 .type longjmp_msg,@object
25longjmp_msg:
26 .string "longjmp causes uninitialized stack frame"
27 .size longjmp_msg, .-longjmp_msg
28
29
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
38
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
48
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
55
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
69
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
110
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)
125
126 /* Without working sigaltstack we cannot perform the test. */
127 bne a3, $Lok
128
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
134
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
143
144 cfi_endproc
145 .size ____longjmp_chk, .-____longjmp_chk
146

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