1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28/* 29 * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 1. Redistributions of source code must retain the above copyright 35 * notice, this list of conditions and the following disclaimer. 36 * 2. Redistributions in binary form must reproduce the above copyright 37 * notice, this list of conditions and the following disclaimer in the 38 * documentation and/or other materials provided with the distribution. 39 * 3. Neither the name of Opsycon AB nor the names of its contributors 40 * may be used to endorse or promote products derived from this software 41 * without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 * SUCH DAMAGE. 54 * 55 */ 56/*- 57 * Copyright (c) 1991, 1993, 1995, 58 * The Regents of the University of California. All rights reserved. 59 * 60 * This code is derived from software contributed to Berkeley by 61 * Havard Eidnes. 62 * 63 * Redistribution and use in source and binary forms, with or without 64 * modification, are permitted provided that the following conditions 65 * are met: 66 * 1. Redistributions of source code must retain the above copyright 67 * notice, this list of conditions and the following disclaimer. 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in the 70 * documentation and/or other materials provided with the distribution. 71 * 3. Neither the name of the University nor the names of its contributors 72 * may be used to endorse or promote products derived from this software 73 * without specific prior written permission. 74 * 75 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 76 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 77 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 78 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 79 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 80 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 81 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 82 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 83 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 84 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 85 * SUCH DAMAGE. 86 */ 87/* 88 * Copyright (c) 1992, 1993 89 * The Regents of the University of California. All rights reserved. 90 * 91 * This code is derived from software contributed to Berkeley by 92 * Ralph Campbell. 93 * 94 * Redistribution and use in source and binary forms, with or without 95 * modification, are permitted provided that the following conditions 96 * are met: 97 * 1. Redistributions of source code must retain the above copyright 98 * notice, this list of conditions and the following disclaimer. 99 * 2. Redistributions in binary form must reproduce the above copyright 100 * notice, this list of conditions and the following disclaimer in the 101 * documentation and/or other materials provided with the distribution. 102 * 3. Neither the name of the University nor the names of its contributors 103 * may be used to endorse or promote products derived from this software 104 * without specific prior written permission. 105 * 106 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 107 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 108 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 109 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 110 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 111 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 112 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 113 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 114 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 115 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 116 * SUCH DAMAGE. 117 * 118 * @(#)signal.h 8.1 (Berkeley) 6/10/93 119 */ 120 121#include <private/bionic_asm.h> 122 123/* jmpbuf is declared to users as an array of longs, which is only 124 * 4-byte aligned in 32-bit builds. The Mips jmpbuf begins with a 125 * dynamically-sized 0- or 4-byte unused filler so that double-prec FP regs 126 * are saved to 8-byte-aligned mem cells. 127 * All the following jmpbuf offsets are from the rounded-DOWN base addr. 128 */ 129 130/* Fields of same size on all MIPS abis: */ 131/* field: byte offset: size: */ 132/* dynam filler (0*4) 0-4 bytes of rounddown filler, DON'T TOUCH!! 133 often overlays user storage!! */ 134#define SC_FPSR_OFFSET (1*4) /* 4 bytes, floating point control/status reg */ 135/* following fields are 8-byte aligned */ 136#define SC_FLAG_OFFSET (2*4) /* 8 bytes, cookie and savesigs flag, first actual field */ 137#define SC_MASK_OFFSET (4*4) /* 16 bytes, mips32/mips64 version of sigset_t */ 138#define SC_CKSUM_OFFSET (8*4) /* 8 bytes, used for checksum */ 139 140/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */ 141#define SC_REGS_OFFSET (10*4) /* SC_REGS_BYTES */ 142#define SC_REGS_SAVED 12 /*regs*/ /* ra,s0-s8,gp,sp */ 143#define SC_REGS_BYTES (SC_REGS_SAVED*REGSZ) 144#define SC_REGS SC_REGS_OFFSET 145 146/* Double floating pt registers are 8-bytes on all abis, 147 * but the number of saved fp regs varies for o32/n32 versus n64 abis: 148 */ 149 150#ifdef __LP64__ 151#define SC_FPREGS_SAVED 8 /* all fp regs f24,f25,f26,f27,f28,f29,f30,f31 */ 152#else 153#define SC_FPREGS_SAVED 6 /* even fp regs f20,f22,f24,f26,f28,f30 */ 154#endif 155 156#define SC_FPREGS_OFFSET (SC_REGS_OFFSET + SC_REGS_BYTES) /* SC_FPREGS_BYTES */ 157#define SC_FPREGS_BYTES (SC_FPREGS_SAVED*REGSZ_FP) 158#define SC_FPREGS SC_FPREGS_OFFSET 159 160#define SC_TOTAL_BYTES (SC_FPREGS_OFFSET + SC_FPREGS_BYTES) 161#define SC_TOTAL_LONGS (SC_TOTAL_BYTES/REGSZ) 162 163#define USE_CHECKSUM 1 164 165.macro m_mangle_reg_and_store reg, cookie, temp, offset 166 xor \temp, \reg, \cookie 167 REG_S \temp, \offset 168.endm 169 170.macro m_unmangle_reg_and_load reg, cookie, temp, offset 171 REG_L \temp, \offset 172 xor \reg, \temp, \cookie 173.endm 174 175.macro m_calculate_checksum dst, src, scratch 176 REG_L \dst, REGSZ(\src) 177#ifdef __LP64__ 178 /* 64 bit: checksum offset is 4 (actual _JBLEN is 25) */ 179 .irp i,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 180#else 181 /* 32 bit: checksum offset is 8 (actual _JBLEN is 34) */ 182 .irp i,2,3,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33 183#endif 184 REG_L \scratch, \i*REGSZ(\src) 185 xor \dst, \dst, \scratch 186 .endr 187.endm 188 189/* 190 * 191 * GPOFF and FRAMESIZE must be the same for all setjmp/longjmp routines 192 * 193 */ 194 195FRAMESZ= MKFSIZ(2,6) 196A1OFF= FRAMESZ-4*REGSZ 197A0OFF= FRAMESZ-3*REGSZ 198GPOFF= FRAMESZ-2*REGSZ 199RAOFF= FRAMESZ-1*REGSZ 200 201NON_LEAF(sigsetjmp, FRAMESZ, $ra) 202__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(sigsetjmp) 203 .mask 0x80000000, RAOFF 204 PTR_SUBU $sp, FRAMESZ # allocate stack frame 205 SETUP_GP64(GPOFF, sigsetjmp) 206 SAVE_GP(GPOFF) 207 .set reorder 208 209setjmp_common: 210#ifndef __LP64__ 211 li $t0, ~7 212 and $a0, $t0 # round jmpbuf addr DOWN to 8-byte boundary 213#endif 214 REG_S $ra, RAOFF($sp) # spill state 215 REG_S $a0, A0OFF($sp) 216 217 # get the cookie and store it along with the signal flag. 218 move $a0, $a1 219 jal __bionic_setjmp_cookie_get 220 REG_L $a0, A0OFF($sp) 221 222 REG_S $v0, SC_FLAG_OFFSET($a0) # save cookie and savesigs flag 223 andi $t0, $v0, 1 # extract savesigs flag 224 225 beqz $t0, 1f # do saving of signal mask? 226 227 # call sigprocmask(int how ignored, sigset_t* null, sigset_t* SC_MASK(a0)): 228 LA $a2, SC_MASK_OFFSET($a0) # gets current signal mask 229 li $a0, 0 # how; ignored when new mask is null 230 li $a1, 0 # null new mask 231 jal sigprocmask # get current signal mask 232 REG_L $a0, A0OFF($sp) 2331: 234 REG_L $gp, GPOFF($sp) # restore spills 235 REG_L $ra, RAOFF($sp) 236 REG_L $t0, SC_FLAG_OFFSET($a0) # move cookie to temp reg 237 238 # callee-saved long-sized regs: 239 PTR_ADDU $v1, $sp, FRAMESZ # save orig sp 240 241 # m_mangle_reg_and_store reg, cookie, temp, offset 242 m_mangle_reg_and_store $ra, $t0, $t1, SC_REGS+0*REGSZ($a0) 243 m_mangle_reg_and_store $s0, $t0, $t2, SC_REGS+1*REGSZ($a0) 244 m_mangle_reg_and_store $s1, $t0, $t3, SC_REGS+2*REGSZ($a0) 245 m_mangle_reg_and_store $s2, $t0, $t1, SC_REGS+3*REGSZ($a0) 246 m_mangle_reg_and_store $s3, $t0, $t2, SC_REGS+4*REGSZ($a0) 247 m_mangle_reg_and_store $s4, $t0, $t3, SC_REGS+5*REGSZ($a0) 248 m_mangle_reg_and_store $s5, $t0, $t1, SC_REGS+6*REGSZ($a0) 249 m_mangle_reg_and_store $s6, $t0, $t2, SC_REGS+7*REGSZ($a0) 250 m_mangle_reg_and_store $s7, $t0, $t3, SC_REGS+8*REGSZ($a0) 251 m_mangle_reg_and_store $s8, $t0, $t1, SC_REGS+9*REGSZ($a0) 252 m_mangle_reg_and_store $gp, $t0, $t2, SC_REGS+10*REGSZ($a0) 253 m_mangle_reg_and_store $v1, $t0, $t3, SC_REGS+11*REGSZ($a0) 254 255 cfc1 $v0, $31 256 257#ifdef __LP64__ 258 # callee-saved fp regs on mips n64 ABI are $f24..$f31 259 s.d $f24, SC_FPREGS+0*REGSZ_FP($a0) 260 s.d $f25, SC_FPREGS+1*REGSZ_FP($a0) 261 s.d $f26, SC_FPREGS+2*REGSZ_FP($a0) 262 s.d $f27, SC_FPREGS+3*REGSZ_FP($a0) 263 s.d $f28, SC_FPREGS+4*REGSZ_FP($a0) 264 s.d $f29, SC_FPREGS+5*REGSZ_FP($a0) 265 s.d $f30, SC_FPREGS+6*REGSZ_FP($a0) 266 s.d $f31, SC_FPREGS+7*REGSZ_FP($a0) 267#else 268 # callee-saved fp regs on mips o32 ABI are 269 # the even-numbered double fp regs $f20,$f22,...$f30 270 s.d $f20, SC_FPREGS+0*REGSZ_FP($a0) 271 s.d $f22, SC_FPREGS+1*REGSZ_FP($a0) 272 s.d $f24, SC_FPREGS+2*REGSZ_FP($a0) 273 s.d $f26, SC_FPREGS+3*REGSZ_FP($a0) 274 s.d $f28, SC_FPREGS+4*REGSZ_FP($a0) 275 s.d $f30, SC_FPREGS+5*REGSZ_FP($a0) 276#endif 277 sw $v0, SC_FPSR_OFFSET($a0) 278#if USE_CHECKSUM 279 m_calculate_checksum $t0, $a0, $t1 280 REG_S $t0, SC_CKSUM_OFFSET($a0) 281#endif 282 move $v0, $zero 283 RESTORE_GP64 284 PTR_ADDU $sp, FRAMESZ 285 j $ra 286END(sigsetjmp) 287 288 289# Alternate entry points: 290 291NON_LEAF(setjmp, FRAMESZ, $ra) 292__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(setjmp) 293 .mask 0x80000000, RAOFF 294 PTR_SUBU $sp, FRAMESZ 295 SETUP_GP64(GPOFF, setjmp) # can't share sigsetjmp's gp code 296 SAVE_GP(GPOFF) 297 .set reorder 298 299 li $a1, 1 # save/restore signals state 300 b setjmp_common # tail call 301END(setjmp) 302 303 304NON_LEAF(_setjmp, FRAMESZ, $ra) 305__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_setjmp) 306 .mask 0x80000000, RAOFF 307 PTR_SUBU $sp, FRAMESZ 308 SETUP_GP64(GPOFF, _setjmp) # can't share sigsetjmp's gp code 309 SAVE_GP(GPOFF) 310 .set reorder 311 312 li $a1, 0 # don't save/restore signals 313 b setjmp_common # tail call 314END(_setjmp) 315 316 317NON_LEAF(siglongjmp, FRAMESZ, $ra) 318__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(siglongjmp) 319 .mask 0x80000000, RAOFF 320 PTR_SUBU $sp, FRAMESZ 321 SETUP_GP64(GPOFF, siglongjmp) 322 SAVE_GP(GPOFF) 323 .set reorder 324 325#ifndef __LP64__ 326 li $t0, ~7 327 and $a0, $t0 # round jmpbuf addr DOWN to 8-byte boundary 328#endif 329 330 move $s1, $a1 # temp spill 331 move $s0, $a0 332 333#if USE_CHECKSUM 334 m_calculate_checksum $t0, $s0, $s2 335 REG_L $s2, SC_CKSUM_OFFSET($s0) 336 beq $t0, $s2, 0f 337 nop 338 jal __bionic_setjmp_checksum_mismatch 339 nop 3400: 341#endif 342 343 # extract savesigs flag 344 REG_L $s2, SC_FLAG_OFFSET($s0) 345 andi $t0, $s2, 1 346 beqz $t0, 1f # restore signal mask? 347 348 # call sigprocmask(int how SIG_SETMASK, sigset_t* SC_MASK(a0), sigset_t* null): 349 LA $a1, SC_MASK_OFFSET($s0) # signals being restored 350 li $a0, 3 # mips SIG_SETMASK 351 li $a2, 0 # null 352 jal sigprocmask # restore signal mask 3531: 354 move $t0, $s2 # get cookie to temp reg 355 move $a1, $s1 356 move $a0, $s0 357 358 # callee-saved long-sized regs: 359 360 # m_unmangle_reg_and_load reg, cookie, temp, offset 361 # don't restore gp yet, old value is needed for cookie_check call 362 m_unmangle_reg_and_load $ra, $t0, $t1, SC_REGS+0*REGSZ($a0) 363 m_unmangle_reg_and_load $s0, $t0, $t2, SC_REGS+1*REGSZ($a0) 364 m_unmangle_reg_and_load $s1, $t0, $t3, SC_REGS+2*REGSZ($a0) 365 m_unmangle_reg_and_load $s2, $t0, $t1, SC_REGS+3*REGSZ($a0) 366 m_unmangle_reg_and_load $s3, $t0, $t2, SC_REGS+4*REGSZ($a0) 367 m_unmangle_reg_and_load $s4, $t0, $t3, SC_REGS+5*REGSZ($a0) 368 m_unmangle_reg_and_load $s5, $t0, $t1, SC_REGS+6*REGSZ($a0) 369 m_unmangle_reg_and_load $s6, $t0, $t2, SC_REGS+7*REGSZ($a0) 370 m_unmangle_reg_and_load $s7, $t0, $t3, SC_REGS+8*REGSZ($a0) 371 m_unmangle_reg_and_load $s8, $t0, $t1, SC_REGS+9*REGSZ($a0) 372 m_unmangle_reg_and_load $v1, $t0, $t2, SC_REGS+10*REGSZ($a0) 373 m_unmangle_reg_and_load $sp, $t0, $t3, SC_REGS+11*REGSZ($a0) 374 375 lw $v0, SC_FPSR_OFFSET($a0) 376 ctc1 $v0, $31 # restore old fr mode before fp values 377#ifdef __LP64__ 378 # callee-saved fp regs on mips n64 ABI are $f24..$f31 379 l.d $f24, SC_FPREGS+0*REGSZ_FP($a0) 380 l.d $f25, SC_FPREGS+1*REGSZ_FP($a0) 381 l.d $f26, SC_FPREGS+2*REGSZ_FP($a0) 382 l.d $f27, SC_FPREGS+3*REGSZ_FP($a0) 383 l.d $f28, SC_FPREGS+4*REGSZ_FP($a0) 384 l.d $f29, SC_FPREGS+5*REGSZ_FP($a0) 385 l.d $f30, SC_FPREGS+6*REGSZ_FP($a0) 386 l.d $f31, SC_FPREGS+7*REGSZ_FP($a0) 387#else 388 # callee-saved fp regs on mips o32 ABI are 389 # the even-numbered double fp regs $f20,$f22,...$f30 390 l.d $f20, SC_FPREGS+0*REGSZ_FP($a0) 391 l.d $f22, SC_FPREGS+1*REGSZ_FP($a0) 392 l.d $f24, SC_FPREGS+2*REGSZ_FP($a0) 393 l.d $f26, SC_FPREGS+3*REGSZ_FP($a0) 394 l.d $f28, SC_FPREGS+4*REGSZ_FP($a0) 395 l.d $f30, SC_FPREGS+5*REGSZ_FP($a0) 396#endif 397 398 # check cookie 399 PTR_SUBU $sp, FRAMESZ 400 REG_S $v1, GPOFF($sp) 401 REG_S $ra, RAOFF($sp) 402 REG_S $a1, A1OFF($sp) 403 move $a0, $t0 404 jal __bionic_setjmp_cookie_check 405 REG_L $gp, GPOFF($sp) 406 REG_L $ra, RAOFF($sp) 407 REG_L $a1, A1OFF($sp) 408 PTR_ADDU $sp, FRAMESZ 409 410 sltiu $t0, $a1, 1 # never return 0! 411 xor $v0, $a1, $t0 412 j $ra # return to setjmp call site 413END(siglongjmp) 414 415ALIAS_SYMBOL(longjmp, siglongjmp) 416__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(longjmp) 417ALIAS_SYMBOL(_longjmp, siglongjmp) 418__BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(_longjmp) 419