1/* $OpenBSD: setjmp.S,v 1.13 2023/12/10 16:45:51 deraadt Exp $ */ 2 3/* 4 * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Opsycon AB nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include "SYS.h" 33#include <machine/regnum.h> 34#include <machine/setjmp.h> 35 36 .section .openbsd.randomdata,"aw",@progbits 37 .balign 8 38 .globl __jmpxor 39 .hidden __jmpxor 40__jmpxor: 41 .space 3*REGSZ # (28/gp, 29/sp, 31/ra) 42 .size __jmpxor, . - __jmpxor 43 .type __jmpxor,@object 44 .text 45 46/* 47 * setjmp, longjmp implementation for libc. this code depends 48 * on the layout of the struct sigcontext in machine/signal.h. 49 */ 50 51FRAMESZ= MKFSIZ(0,4) 52GPOFF= FRAMESZ-2*REGSZ 53 54LEAF(setjmp, FRAMESZ) 55 PTR_SUBU sp, FRAMESZ 56 SETUP_GP64(GPOFF, setjmp) 57 .set noreorder 58 59 move a2, a0 # save jmpbuf 60 li a0, 1 # how = SIG_BLOCK 61 move a1, zero # get current signal mask 62 li v0, SYS_sigprocmask 6399: syscall # mask in v0 64 PINSYSCALL(SYS_sigprocmask, 99b) 65 bne a3, zero, botch 66 REG_S v0, _JB_MASK(a2) # save sc_mask 67 68 LI v0, 0xACEDBADE # sigcontext magic number 69 REG_S v0, _JB_REGS+ZERO*REGSZ(a2) 70 REG_S s0, _JB_REGS+S0*REGSZ(a2) 71 REG_S s1, _JB_REGS+S1*REGSZ(a2) 72 REG_S s2, _JB_REGS+S2*REGSZ(a2) 73 REG_S s3, _JB_REGS+S3*REGSZ(a2) 74 REG_S s4, _JB_REGS+S4*REGSZ(a2) 75 REG_S s5, _JB_REGS+S5*REGSZ(a2) 76 REG_S s6, _JB_REGS+S6*REGSZ(a2) 77 REG_S s7, _JB_REGS+S7*REGSZ(a2) 78 REG_S s8, _JB_REGS+S8*REGSZ(a2) 79 LA t0, __jmpxor # load cookie addr 80 REG_L v0, 0(t0) # load gp cookie 81 REG_L v1, GPOFF(sp) 82 xor v0, v0, v1 83 REG_S v0, _JB_REGS+GP*REGSZ(a2) 84 REG_L v0, REGSZ(t0) # load sp cookie over gp cookie 85 PTR_ADDU v1, sp, FRAMESZ 86 xor v0, v0, v1 87 REG_S v0, _JB_REGS+SP*REGSZ(a2) 88 REG_L t0, 2*REGSZ(t0) # load ra cookie over addr 89 xor t0, ra, t0 90 REG_S t0, _JB_PC(a2) 91 cfc1 t0, $31 # overwrite ra cookie 92#if _MIPS_FPSET == 32 93 sdc1 $f20, _JB_FPREGS+((F20-F0)*REGSZ)(a2) 94 sdc1 $f21, _JB_FPREGS+((F21-F0)*REGSZ)(a2) 95 sdc1 $f22, _JB_FPREGS+((F22-F0)*REGSZ)(a2) 96 sdc1 $f23, _JB_FPREGS+((F23-F0)*REGSZ)(a2) 97 sdc1 $f24, _JB_FPREGS+((F24-F0)*REGSZ)(a2) 98 sdc1 $f25, _JB_FPREGS+((F25-F0)*REGSZ)(a2) 99 sdc1 $f26, _JB_FPREGS+((F26-F0)*REGSZ)(a2) 100 sdc1 $f27, _JB_FPREGS+((F27-F0)*REGSZ)(a2) 101 sdc1 $f28, _JB_FPREGS+((F28-F0)*REGSZ)(a2) 102 sdc1 $f29, _JB_FPREGS+((F29-F0)*REGSZ)(a2) 103 sdc1 $f30, _JB_FPREGS+((F30-F0)*REGSZ)(a2) 104 sdc1 $f31, _JB_FPREGS+((F31-F0)*REGSZ)(a2) 105#else 106 swc1 $f20, _JB_FPREGS+((F20-F0)*REGSZ)(a2) 107 swc1 $f21, _JB_FPREGS+((F21-F0)*REGSZ)(a2) 108 swc1 $f22, _JB_FPREGS+((F22-F0)*REGSZ)(a2) 109 swc1 $f23, _JB_FPREGS+((F23-F0)*REGSZ)(a2) 110 swc1 $f24, _JB_FPREGS+((F24-F0)*REGSZ)(a2) 111 swc1 $f25, _JB_FPREGS+((F25-F0)*REGSZ)(a2) 112 swc1 $f26, _JB_FPREGS+((F26-F0)*REGSZ)(a2) 113 swc1 $f27, _JB_FPREGS+((F27-F0)*REGSZ)(a2) 114 swc1 $f28, _JB_FPREGS+((F28-F0)*REGSZ)(a2) 115 swc1 $f29, _JB_FPREGS+((F29-F0)*REGSZ)(a2) 116 swc1 $f30, _JB_FPREGS+((F30-F0)*REGSZ)(a2) 117 swc1 $f31, _JB_FPREGS+((F31-F0)*REGSZ)(a2) 118#endif 119 REG_S t0, _JB_FPREGS+((FSR-F0)*REGSZ)(a2) 120 RESTORE_GP64 121 PTR_ADDU sp, FRAMESZ 122 j ra 123 move v0, zero 124END_STRONG(setjmp) 125 126LEAF(longjmp, FRAMESZ) 127 PTR_SUBU sp, FRAMESZ 128 SETUP_GP64(GPOFF, longjmp) 129 .set noreorder 130 131 move a2, a0 # save jmpbuf 132 move a4, a1 # save val 133 REG_L a1, _JB_MASK(a2) # load sc_mask 134 li a0, 3 # how = SIG_SETMASK 135 li v0, SYS_sigprocmask 13698: syscall 137 PINSYSCALL(SYS_sigprocmask, 98b) 138 bne a3, zero, botch 139 140 REG_L v0, _JB_REGS+ZERO*REGSZ(a2) 141 bne v0, 0xACEDBADE, botch # jump if error 142 LA v0, __jmpxor # load cookie addr 143 REG_L v1, 2*REGSZ(v0) # load ra cookie 144 REG_L ra, _JB_PC(a2) 145 xor ra, ra, v1 146 REG_L s0, _JB_REGS+S0*REGSZ(a2) 147 REG_L s1, _JB_REGS+S1*REGSZ(a2) 148 REG_L s2, _JB_REGS+S2*REGSZ(a2) 149 REG_L s3, _JB_REGS+S3*REGSZ(a2) 150 REG_L s4, _JB_REGS+S4*REGSZ(a2) 151 REG_L s5, _JB_REGS+S5*REGSZ(a2) 152 REG_L s6, _JB_REGS+S6*REGSZ(a2) 153 REG_L s7, _JB_REGS+S7*REGSZ(a2) 154 REG_L s8, _JB_REGS+S8*REGSZ(a2) 155 REG_L v1, 0(v0) # load gp cookie over ra cookie 156 REG_L gp, _JB_REGS+GP*REGSZ(a2) 157 xor gp, gp, v1 158 REG_L v1, REGSZ(v0) # load sp cookie over gp cookie 159 REG_L sp, _JB_REGS+SP*REGSZ(a2) 160 xor sp, sp, v1 161 REG_L v1, _JB_FPREGS+((FSR-F0)*REGSZ)(a2) # overwrite sp cookie 162 ctc1 v1, $31 163#if _MIPS_FPSET == 32 164 ldc1 $f20, _JB_FPREGS+((F20-F0)*REGSZ)(a2) 165 ldc1 $f21, _JB_FPREGS+((F21-F0)*REGSZ)(a2) 166 ldc1 $f22, _JB_FPREGS+((F22-F0)*REGSZ)(a2) 167 ldc1 $f23, _JB_FPREGS+((F23-F0)*REGSZ)(a2) 168 ldc1 $f24, _JB_FPREGS+((F24-F0)*REGSZ)(a2) 169 ldc1 $f25, _JB_FPREGS+((F25-F0)*REGSZ)(a2) 170 ldc1 $f26, _JB_FPREGS+((F26-F0)*REGSZ)(a2) 171 ldc1 $f27, _JB_FPREGS+((F27-F0)*REGSZ)(a2) 172 ldc1 $f28, _JB_FPREGS+((F28-F0)*REGSZ)(a2) 173 ldc1 $f29, _JB_FPREGS+((F29-F0)*REGSZ)(a2) 174 ldc1 $f30, _JB_FPREGS+((F30-F0)*REGSZ)(a2) 175 ldc1 $f31, _JB_FPREGS+((F31-F0)*REGSZ)(a2) 176#else 177 lwc1 $f20, _JB_FPREGS+((F20-F0)*REGSZ)(a2) 178 lwc1 $f21, _JB_FPREGS+((F21-F0)*REGSZ)(a2) 179 lwc1 $f22, _JB_FPREGS+((F22-F0)*REGSZ)(a2) 180 lwc1 $f23, _JB_FPREGS+((F23-F0)*REGSZ)(a2) 181 lwc1 $f24, _JB_FPREGS+((F24-F0)*REGSZ)(a2) 182 lwc1 $f25, _JB_FPREGS+((F25-F0)*REGSZ)(a2) 183 lwc1 $f26, _JB_FPREGS+((F26-F0)*REGSZ)(a2) 184 lwc1 $f27, _JB_FPREGS+((F27-F0)*REGSZ)(a2) 185 lwc1 $f28, _JB_FPREGS+((F28-F0)*REGSZ)(a2) 186 lwc1 $f29, _JB_FPREGS+((F29-F0)*REGSZ)(a2) 187 lwc1 $f30, _JB_FPREGS+((F30-F0)*REGSZ)(a2) 188 lwc1 $f31, _JB_FPREGS+((F31-F0)*REGSZ)(a2) 189#endif 190 beql a4, zero, 1f 191 li a4, 1 # only executed if branch taken. 1921: 193 j ra 194 move v0, a4 195 196botch: 197 jal _libc_abort 198 nop 199 RESTORE_GP64 200 PTR_ADDU sp, FRAMESZ 201END_STRONG(longjmp) 202