1/* Copyright (C) 1992-2021 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