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 82 83.Lsetjmp_magic: 84 .word _JB_MAGIC_SETJMP 85 86 87ENTRY(longjmp) 88 ldr r2, .Lsetjmp_magic 89 ldr r3, [r0, #(_JB_MAGIC * 4)] 90 teq r2, r3 91 bne botch 92 93 /* Fetch signal mask */ 94 ldr r2, [r0, #(_JB_SIGMASK * 4)] 95 96 /* Set signal mask */ 97 stmfd sp!, {r0, r1, r14} 98 sub sp, sp, #4 /* align the stack */ 99 100 mov r0, r2 101 bl PIC_SYM(_C_LABEL(sigsetmask), PLT) 102 103 add sp, sp, #4 /* unalign the stack */ 104 ldmfd sp!, {r0, r1, r14} 105 106#ifdef __ARM_HAVE_VFP 107 /* Restore floating-point registers */ 108 add r2, r0, #(_JB_FLOAT_BASE * 4) 109 vldmia r2, {d8-d15} 110 /* Restore floating-point state */ 111 ldr r2, [r0, #(_JB_FLOAT_STATE * 4)] 112 fmxr fpscr, r2 113#endif /* __ARM_HAVE_VFP */ 114 115 /* Restore core registers */ 116 add r2, r0, #(_JB_CORE_BASE * 4) 117 ldmia r2, {r4-r14} 118 119 /* Validate sp and r14 */ 120 teq sp, #0 121 teqne r14, #0 122 beq botch 123 124 /* Set return value */ 125 126 mov r0, r1 127 teq r0, #0x00000000 128 moveq r0, #0x00000001 129 bx lr 130#ifdef __ARM_26__ 131 mov r15, r14 132#else 133 mov r15, r14 134#endif 135 136 /* validation failed, die die die. */ 137botch: 138 bl PIC_SYM(_C_LABEL(longjmperror), PLT) 139 bl PIC_SYM(_C_LABEL(abort), PLT) 140 b . - 8 /* Cannot get here */ 141