1/* $OpenBSD: setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */ 2/* $NetBSD: setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */ 3 4/* 5 * Copyright (c) 1997 Mark Brinicombe 6 * Copyright (c) 2010 Android Open Source Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Mark Brinicombe 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#include <machine/asm.h> 38#include <machine/setjmp.h> 39#include <machine/cpu-features.h> 40 41/* 42 * C library -- setjmp, longjmp 43 * 44 * longjmp(a,v) 45 * will generate a "return(v)" from the last call to 46 * setjmp(a) 47 * by restoring registers from the stack. 48 * The previous signal state is restored. 49 */ 50 51ENTRY(setjmp) 52 /* Block all signals and retrieve the old signal mask */ 53 stmfd sp!, {r0, r14} 54 mov r0, #0x00000000 55 56 bl PIC_SYM(_C_LABEL(sigblock), PLT) 57 mov r1, r0 58 59 ldmfd sp!, {r0, r14} 60 61 /* Store signal mask */ 62 str r1, [r0, #(_JB_SIGMASK * 4)] 63 64 ldr r1, .Lsetjmp_magic 65 str r1, [r0, #(_JB_MAGIC * 4)] 66 67 /* Store core registers */ 68 add r1, r0, #(_JB_CORE_BASE * 4) 69 stmia r1, {r4-r14} 70 71#ifdef __ARM_HAVE_VFP 72 /* Store floating-point registers */ 73 add r1, r0, #(_JB_FLOAT_BASE * 4) 74 vstmia r1, {d8-d15} 75 /* Store floating-point state */ 76 fmrx r1, fpscr 77 str r1, [r0, #(_JB_FLOAT_STATE * 4)] 78#endif /* __ARM_HAVE_VFP */ 79 80 mov r0, #0x00000000 81 bx lr 82END(setjmp) 83 84.Lsetjmp_magic: 85 .word _JB_MAGIC_SETJMP 86 87 88ENTRY(longjmp) 89 ldr r2, .Lsetjmp_magic 90 ldr r3, [r0, #(_JB_MAGIC * 4)] 91 teq r2, r3 92 bne botch 93 94 /* Fetch signal mask */ 95 ldr r2, [r0, #(_JB_SIGMASK * 4)] 96 97 /* Set signal mask */ 98 stmfd sp!, {r0, r1, r14} 99 sub sp, sp, #4 /* align the stack */ 100 101 mov r0, r2 102 bl PIC_SYM(_C_LABEL(sigsetmask), PLT) 103 104 add sp, sp, #4 /* unalign the stack */ 105 ldmfd sp!, {r0, r1, r14} 106 107#ifdef __ARM_HAVE_VFP 108 /* Restore floating-point registers */ 109 add r2, r0, #(_JB_FLOAT_BASE * 4) 110 vldmia r2, {d8-d15} 111 /* Restore floating-point state */ 112 ldr r2, [r0, #(_JB_FLOAT_STATE * 4)] 113 fmxr fpscr, r2 114#endif /* __ARM_HAVE_VFP */ 115 116 /* Restore core registers */ 117 add r2, r0, #(_JB_CORE_BASE * 4) 118 ldmia r2, {r4-r14} 119 120 /* Validate sp and r14 */ 121 teq sp, #0 122 teqne r14, #0 123 beq botch 124 125 /* Set return value */ 126 127 mov r0, r1 128 teq r0, #0x00000000 129 moveq r0, #0x00000001 130 bx lr 131#ifdef __ARM_26__ 132 mov r15, r14 133#else 134 mov r15, r14 135#endif 136 137 /* validation failed, die die die. */ 138botch: 139 bl PIC_SYM(_C_LABEL(longjmperror), PLT) 140 bl PIC_SYM(_C_LABEL(abort), PLT) 141 b . - 8 /* Cannot get here */ 142END(longjmp) 143