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#include <machine/setjmp.h> 123 124/* jmpbuf is declared to users as an array of longs, which is only 125 * 4-byte aligned in 32-bit builds. The Mips jmpbuf begins with a 126 * dynamically-sized 0- or 4-byte unused filler so that double-prec FP regs 127 * are saved to 8-byte-aligned mem cells. 128 * All the following jmpbuf offsets are from the rounded-DOWN base addr. 129 */ 130 131/* Fields of same size on all MIPS abis: */ 132/* field: byte offset: size: */ 133/* dynam filler (0*4) 0-4 bytes of rounddown filler, DON'T TOUCH!! 134 often overlays user storage!! */ 135#define SC_FPSR_OFFSET (1*4) /* 4 bytes, floating point control/status reg */ 136/* following fields are 8-byte aligned */ 137#define SC_FLAG_OFFSET (2*4) /* 8 bytes, cookie and savesigs flag, first actual field */ 138#define SC_MASK_OFFSET (4*4) /* 16 bytes, mips32/mips64 version of sigset_t */ 139#define SC_CKSUM_OFFSET (8*4) /* 8 bytes, used for checksum */ 140 141/* Registers that are 4-byte on mips32 o32, and 8-byte on mips64 n64 abi */ 142#define SC_REGS_OFFSET (10*4) /* SC_REGS_BYTES */ 143#define SC_REGS_SAVED 12 /*regs*/ /* ra,s0-s8,gp,sp */ 144#define SC_REGS_BYTES (SC_REGS_SAVED*REGSZ) 145#define SC_REGS SC_REGS_OFFSET 146 147/* Double floating pt registers are 8-bytes on all abis, 148 * but the number of saved fp regs varies for o32/n32 versus n64 abis: 149 */ 150 151#ifdef __LP64__ 152#define SC_FPREGS_SAVED 8 /* all fp regs f24,f25,f26,f27,f28,f29,f30,f31 */ 153#else 154#define SC_FPREGS_SAVED 6 /* even fp regs f20,f22,f24,f26,f28,f30 */ 155#endif 156 157#define SC_FPREGS_OFFSET (SC_REGS_OFFSET + SC_REGS_BYTES) /* SC_FPREGS_BYTES */ 158#define SC_FPREGS_BYTES (SC_FPREGS_SAVED*REGSZ_FP) 159#define SC_FPREGS SC_FPREGS_OFFSET 160 161#define SC_TOTAL_BYTES (SC_FPREGS_OFFSET + SC_FPREGS_BYTES) 162#define SC_TOTAL_LONGS (SC_TOTAL_BYTES/REGSZ) 163 164#if SC_TOTAL_LONGS > _JBLEN 165#error _JBLEN is too small 166#endif 167 168#define USE_CHECKSUM 1 169 170.macro m_mangle_reg_and_store reg, cookie, temp, offset 171 xor \temp, \reg, \cookie 172 REG_S \temp, \offset 173.endm 174 175.macro m_unmangle_reg_and_load reg, cookie, temp, offset 176 REG_L \temp, \offset 177 xor \reg, \temp, \cookie 178.endm 179 180.macro m_calculate_checksum dst, src, scratch 181 REG_L \dst, REGSZ(\src) 182#ifdef __LP64__ 183 /* 64 bit: checksum offset is 4 (actual _JBLEN is 25) */ 184 .irp i,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 185#else 186 /* 32 bit: checksum offset is 8 (actual _JBLEN is 34) */ 187 .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 188#endif 189 REG_L \scratch, \i*REGSZ(\src) 190 xor \dst, \dst, \scratch 191 .endr 192.endm 193 194/* 195 * 196 * GPOFF and FRAMESIZE must be the same for all setjmp/longjmp routines 197 * 198 */ 199 200FRAMESZ= MKFSIZ(2,6) 201A1OFF= FRAMESZ-4*REGSZ 202A0OFF= FRAMESZ-3*REGSZ 203GPOFF= FRAMESZ-2*REGSZ 204RAOFF= FRAMESZ-1*REGSZ 205 206NON_LEAF(sigsetjmp, FRAMESZ, ra) 207 .mask 0x80000000, RAOFF 208 PTR_SUBU sp, FRAMESZ # allocate stack frame 209 SETUP_GP64(GPOFF, sigsetjmp) 210 SAVE_GP(GPOFF) 211 .set reorder 212 213setjmp_common: 214#ifndef __LP64__ 215 li t0, ~7 216 and a0, t0 # round jmpbuf addr DOWN to 8-byte boundary 217#endif 218 REG_S ra, RAOFF(sp) # spill state 219 REG_S a0, A0OFF(sp) 220 221 # get the cookie and store it along with the signal flag. 222 move a0, a1 223 jal __bionic_setjmp_cookie_get 224 REG_L a0, A0OFF(sp) 225 226 REG_S v0, SC_FLAG_OFFSET(a0) # save cookie and savesigs flag 227 andi t0, v0, 1 # extract savesigs flag 228 229 beqz t0, 1f # do saving of signal mask? 230 231 # call sigprocmask(int how ignored, sigset_t* null, sigset_t* SC_MASK(a0)): 232 LA a2, SC_MASK_OFFSET(a0) # gets current signal mask 233 li a0, 0 # how; ignored when new mask is null 234 li a1, 0 # null new mask 235 jal sigprocmask # get current signal mask 236 REG_L a0, A0OFF(sp) 2371: 238 REG_L gp, GPOFF(sp) # restore spills 239 REG_L ra, RAOFF(sp) 240 REG_L t0, SC_FLAG_OFFSET(a0) # move cookie to temp reg 241 242 # callee-saved long-sized regs: 243 PTR_ADDU v1, sp, FRAMESZ # save orig sp 244 245 # m_mangle_reg_and_store reg, cookie, temp, offset 246 m_mangle_reg_and_store ra, t0, t1, SC_REGS+0*REGSZ(a0) 247 m_mangle_reg_and_store s0, t0, t2, SC_REGS+1*REGSZ(a0) 248 m_mangle_reg_and_store s1, t0, t3, SC_REGS+2*REGSZ(a0) 249 m_mangle_reg_and_store s2, t0, t1, SC_REGS+3*REGSZ(a0) 250 m_mangle_reg_and_store s3, t0, t2, SC_REGS+4*REGSZ(a0) 251 m_mangle_reg_and_store s4, t0, t3, SC_REGS+5*REGSZ(a0) 252 m_mangle_reg_and_store s5, t0, t1, SC_REGS+6*REGSZ(a0) 253 m_mangle_reg_and_store s6, t0, t2, SC_REGS+7*REGSZ(a0) 254 m_mangle_reg_and_store s7, t0, t3, SC_REGS+8*REGSZ(a0) 255 m_mangle_reg_and_store s8, t0, t1, SC_REGS+9*REGSZ(a0) 256 m_mangle_reg_and_store gp, t0, t2, SC_REGS+10*REGSZ(a0) 257 m_mangle_reg_and_store v1, t0, t3, SC_REGS+11*REGSZ(a0) 258 259 cfc1 v0, $31 260 261#ifdef __LP64__ 262 # callee-saved fp regs on mips n64 ABI are $f24..$f31 263 s.d $f24, SC_FPREGS+0*REGSZ_FP(a0) 264 s.d $f25, SC_FPREGS+1*REGSZ_FP(a0) 265 s.d $f26, SC_FPREGS+2*REGSZ_FP(a0) 266 s.d $f27, SC_FPREGS+3*REGSZ_FP(a0) 267 s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) 268 s.d $f29, SC_FPREGS+5*REGSZ_FP(a0) 269 s.d $f30, SC_FPREGS+6*REGSZ_FP(a0) 270 s.d $f31, SC_FPREGS+7*REGSZ_FP(a0) 271#else 272 # callee-saved fp regs on mips o32 ABI are 273 # the even-numbered double fp regs $f20,$f22,...$f30 274 s.d $f20, SC_FPREGS+0*REGSZ_FP(a0) 275 s.d $f22, SC_FPREGS+1*REGSZ_FP(a0) 276 s.d $f24, SC_FPREGS+2*REGSZ_FP(a0) 277 s.d $f26, SC_FPREGS+3*REGSZ_FP(a0) 278 s.d $f28, SC_FPREGS+4*REGSZ_FP(a0) 279 s.d $f30, SC_FPREGS+5*REGSZ_FP(a0) 280#endif 281 sw v0, SC_FPSR_OFFSET(a0) 282#if USE_CHECKSUM 283 m_calculate_checksum t0, a0, t1 284 REG_S t0, SC_CKSUM_OFFSET(a0) 285#endif 286 move v0, zero 287 RESTORE_GP64 288 PTR_ADDU sp, FRAMESZ 289 j ra 290END(sigsetjmp) 291 292 293# Alternate entry points: 294 295NON_LEAF(setjmp, FRAMESZ, ra) 296 .mask 0x80000000, RAOFF 297 PTR_SUBU sp, FRAMESZ 298 SETUP_GP64(GPOFF, setjmp) # can't share sigsetjmp's gp code 299 SAVE_GP(GPOFF) 300 .set reorder 301 302 li a1, 1 # save/restore signals state 303 b setjmp_common # tail call 304END(setjmp) 305 306 307NON_LEAF(_setjmp, FRAMESZ, ra) 308 .mask 0x80000000, RAOFF 309 PTR_SUBU sp, FRAMESZ 310 SETUP_GP64(GPOFF, _setjmp) # can't share sigsetjmp's gp code 311 SAVE_GP(GPOFF) 312 .set reorder 313 314 li a1, 0 # don't save/restore signals 315 b setjmp_common # tail call 316END(_setjmp) 317 318 319NON_LEAF(siglongjmp, FRAMESZ, ra) 320 .mask 0x80000000, RAOFF 321 PTR_SUBU sp, FRAMESZ 322 SETUP_GP64(GPOFF, siglongjmp) 323 SAVE_GP(GPOFF) 324 .set reorder 325 326#ifndef __LP64__ 327 li t0, ~7 328 and a0, t0 # round jmpbuf addr DOWN to 8-byte boundary 329#endif 330 331 move s1, a1 # temp spill 332 move s0, a0 333 334#if USE_CHECKSUM 335 m_calculate_checksum t0, s0, s2 336 REG_L s2, SC_CKSUM_OFFSET(s0) 337 beq t0, s2, 0f 338 nop 339 jal __bionic_setjmp_checksum_mismatch 340 nop 3410: 342#endif 343 344 # extract savesigs flag 345 REG_L s2, SC_FLAG_OFFSET(s0) 346 andi t0, s2, 1 347 beqz t0, 1f # restore signal mask? 348 349 # call sigprocmask(int how SIG_SETMASK, sigset_t* SC_MASK(a0), sigset_t* null): 350 LA a1, SC_MASK_OFFSET(s0) # signals being restored 351 li a0, 3 # mips SIG_SETMASK 352 li a2, 0 # null 353 jal sigprocmask # restore signal mask 3541: 355 move t0, s2 # get cookie to temp reg 356 move a1, s1 357 move a0, s0 358 359 # callee-saved long-sized regs: 360 361 # m_unmangle_reg_and_load reg, cookie, temp, offset 362 # don't restore gp yet, old value is needed for cookie_check call 363 m_unmangle_reg_and_load ra, t0, t1, SC_REGS+0*REGSZ(a0) 364 m_unmangle_reg_and_load s0, t0, t2, SC_REGS+1*REGSZ(a0) 365 m_unmangle_reg_and_load s1, t0, t3, SC_REGS+2*REGSZ(a0) 366 m_unmangle_reg_and_load s2, t0, t1, SC_REGS+3*REGSZ(a0) 367 m_unmangle_reg_and_load s3, t0, t2, SC_REGS+4*REGSZ(a0) 368 m_unmangle_reg_and_load s4, t0, t3, SC_REGS+5*REGSZ(a0) 369 m_unmangle_reg_and_load s5, t0, t1, SC_REGS+6*REGSZ(a0) 370 m_unmangle_reg_and_load s6, t0, t2, SC_REGS+7*REGSZ(a0) 371 m_unmangle_reg_and_load s7, t0, t3, SC_REGS+8*REGSZ(a0) 372 m_unmangle_reg_and_load s8, t0, t1, SC_REGS+9*REGSZ(a0) 373 m_unmangle_reg_and_load v1, t0, t2, SC_REGS+10*REGSZ(a0) 374 m_unmangle_reg_and_load sp, t0, t3, SC_REGS+11*REGSZ(a0) 375 376 lw v0, SC_FPSR_OFFSET(a0) 377 ctc1 v0, $31 # restore old fr mode before fp values 378#ifdef __LP64__ 379 # callee-saved fp regs on mips n64 ABI are $f24..$f31 380 l.d $f24, SC_FPREGS+0*REGSZ_FP(a0) 381 l.d $f25, SC_FPREGS+1*REGSZ_FP(a0) 382 l.d $f26, SC_FPREGS+2*REGSZ_FP(a0) 383 l.d $f27, SC_FPREGS+3*REGSZ_FP(a0) 384 l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) 385 l.d $f29, SC_FPREGS+5*REGSZ_FP(a0) 386 l.d $f30, SC_FPREGS+6*REGSZ_FP(a0) 387 l.d $f31, SC_FPREGS+7*REGSZ_FP(a0) 388#else 389 # callee-saved fp regs on mips o32 ABI are 390 # the even-numbered double fp regs $f20,$f22,...$f30 391 l.d $f20, SC_FPREGS+0*REGSZ_FP(a0) 392 l.d $f22, SC_FPREGS+1*REGSZ_FP(a0) 393 l.d $f24, SC_FPREGS+2*REGSZ_FP(a0) 394 l.d $f26, SC_FPREGS+3*REGSZ_FP(a0) 395 l.d $f28, SC_FPREGS+4*REGSZ_FP(a0) 396 l.d $f30, SC_FPREGS+5*REGSZ_FP(a0) 397#endif 398 399 # check cookie 400 PTR_SUBU sp, FRAMESZ 401 REG_S v1, GPOFF(sp) 402 REG_S ra, RAOFF(sp) 403 REG_S a1, A1OFF(sp) 404 move a0, t0 405 jal __bionic_setjmp_cookie_check 406 REG_L gp, GPOFF(sp) 407 REG_L ra, RAOFF(sp) 408 REG_L a1, A1OFF(sp) 409 PTR_ADDU sp, FRAMESZ 410 411 sltiu t0, a1, 1 # never return 0! 412 xor v0, a1, t0 413 j ra # return to setjmp call site 414END(siglongjmp) 415 416ALIAS_SYMBOL(longjmp, siglongjmp) 417ALIAS_SYMBOL(_longjmp, siglongjmp) 418