1/* Copyright (C) 2009-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 <sigaltstack-offsets.h> 19 20 .section .rodata.str1.8,"aMS",@progbits,1 21 .align 8 22.LC0: 23 .string "longjmp causes uninitialized stack frame" 24 25 .section .sdata,"aws",@progbits 26 .align 8 27 .type longjmp_msg,@object 28longjmp_msg: 29 data8 .LC0 30 .size longjmp_msg, .-longjmp_msg 31 32#define __longjmp ____longjmp_chk 33 34/* We use 32 bytes (rather than sizeof(stack_t)) so that we keep the stack 35 properly aligned. But we still want a sanity check to make sure 32 is 36 actually enough. */ 37#define STACK_SPACE ((sizeSS + 31) & -32) 38 39/* Check the stack pointer held in the jumpbuf. Make sure it's in either the 40 current stack (r12) or in the signal stack. */ 41#define CHECK_RSP \ 42 ld8 loc0 = [in0]; \ 43 ;; \ 44 /* First see if target stack is within current one. */ \ 45 cmp.ltu p0, p8 = loc0, r12; \ 46(p8) br.cond.dptk.many .Lok; \ 47 \ 48 /* Check if it's an alternative signal stack. */ \ 49 mov out0 = r0; \ 50 add out1 = -STACK_SPACE, r12; \ 51 ;; \ 52 mov r12 = out1; \ 53 DO_CALL_VIA_BREAK (SYS_ify (sigaltstack)); \ 54 ;; \ 55 /* If the syscall failed, then assume it's OK. */ \ 56 cmp.eq p8, p0 = -1, r10; \ 57(p8) br.cond.spnt .Lok; \ 58 /* Move stack_t into regs. */ \ 59 add r14 = oSS_FLAGS, r12; /* ss_flags */ \ 60 add r15 = oSS_SIZE, r12; /* ss_size */ \ 61 ld8 r16 = [r12]; /* ss_sp */ \ 62 ;; \ 63 ld4 r17 = [r14]; /* ss_flags */ \ 64 ld8 r18 = [r15]; /* ss_size */ \ 65 ;; \ 66 sub r19 = r16, r18; /* sp - size */ \ 67 /* See if we're currently on the altstack. */ \ 68 tbit.nz p0, p8 = r17, 0; /* SS_ONSTACK */ \ 69(p8) br.cond.spnt .Lfail; \ 70 /* Verify target is within alternative stack. */ \ 71 cmp.gtu p7, p0 = loc0, r16; \ 72(p7) br.cond.spnt .Lfail; \ 73 ;; \ 74 cmp.ltu p0, p8 = loc0, r19; \ 75(p8) br.cond.sptk.many .Lok; \ 76 ;; \ 77 \ 78 /* Still here? Abort! */ \ 79.Lfail: \ 80 add r12 = STACK_SPACE, r12; \ 81 addl loc0 = @ltoffx(longjmp_msg#), r1;; \ 82 ld8.mov loc0 = [loc0], longjmp_msg#;; \ 83 ld8 out0 = [loc0]; \ 84 br.call.sptk.many b0 = HIDDEN_JUMPTARGET(__fortify_fail)#;; \ 85.Lok: \ 86 add r12 = STACK_SPACE, r12; 87 88#include "__longjmp.S" 89