1/* Copyright (C) 2009-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#define ENV(base,reg) [%base + (reg * 4)] 22#define ST_FLUSH_WINDOWS 3 23 24.section .rodata.str1.1,"aMS",@progbits,1 25 .type longjmp_msg,@object 26longjmp_msg: 27 .string "longjmp causes uninitialized stack frame" 28 .size longjmp_msg, .-longjmp_msg 29 30 .text 31ENTRY (____longjmp_chk) 32 ld ENV(o0,JB_SP), %g5 33#ifdef PTR_DEMANGLE 34 PTR_DEMANGLE (%g5, %g5, %g4) 35#endif 36 37 cmp %sp, %g5 38 bleu .Lok_norestore 39 nop 40 41 save %sp, -80, %sp 42 cfi_remember_state 43 cfi_def_cfa_register(%fp) 44 cfi_window_save 45 cfi_register(%o7, %i7) 46 47 clr %o0 48 add %sp, 64, %o1 49 LOADSYSCALL(sigaltstack) 50 ta 0x10 51 bcs .Lok 52 ld [%sp + 64 + 4], %o2 53 andcc %o2, 0x1, %g0 54 be .Lfail 55 ld [%sp + 64 + 0], %o0 56 57 ld [%sp + 64 + 8], %o1 58 add %o0, %o1, %o0 59 sub %o0, %g5, %o0 60 cmp %o0, %o1 61 bgeu .Lok 62 nop 63 64.Lfail: 65#ifndef PIC 66 sethi %hi(longjmp_msg), %o0 67 or %o0, %lo(longjmp_msg), %o0 68#else 69 SETUP_PIC_REG(l7) 70 sethi %gdop_hix22(longjmp_msg), %o0 71 xor %o0, %gdop_lox10(longjmp_msg), %o0 72 ld [%l7 + %o0], %o0, %gdop(longjmp_msg) 73#endif 74 call HIDDEN_JUMPTARGET(__fortify_fail) 75 nop 76 77.Lok: 78 restore 79 cfi_restore_state 80 81.Lok_norestore: 82 ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */ 83#ifdef PTR_DEMANGLE 84 PTR_DEMANGLE2 (%g3, %g3, %g4) 85#endif 86 87 mov %o0, %g1 /* ENV in %g1 */ 88 orcc %o1, %g0, %g2 /* VAL in %g2 */ 89 be,a 0f /* Branch if zero; else skip delay slot. */ 90 mov 1, %g2 /* Delay slot only hit if zero: VAL = 1. */ 910: 92 93 save %sp, -96, %sp 94 /* 95 * Do a "flush register windows trap". The trap handler in the 96 * kernel writes all the register windows to their stack slots, and 97 * marks them all as invalid (needing to be sucked up from the 98 * stack when used). This ensures that all information needed to 99 * unwind to these callers is in memory, not in the register 100 * windows. 101 */ 102 ta ST_FLUSH_WINDOWS 103#ifdef PTR_DEMANGLE 104 ld ENV(g1,JB_PC), %g1 /* Set return PC. */ 105 PTR_DEMANGLE2 (%i7, %g1, %g4) 106#else 107 ld ENV(g1,JB_PC), %i7 /* Set return PC. */ 108#endif 109 mov %g5, %fp 110 jmp %i7 + 8 111 restore %g2, 0, %o0 /* Restore values from above register frame. */ 112 113END(____longjmp_chk) 114