2 * Copyright (c) 1997 Mark Brinicombe
3 * Copyright (c) 2010 Android Open Source Project.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Mark Brinicombe
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <private/bionic_asm.h>
36 // According to the ARM AAPCS document, we only need to save
37 // the following registers:
41 // VFP d8-d15 (see section 5.1.2.1)
43 // Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
44 // calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
45 // (and can be used for passing arguments or returning results in standard
46 // procedure-call variants). Registers d16-d31 (q8-q15), if present, do
47 // not need to be preserved.
49 // FPSCR saved because glibc does.
51 // The internal structure of a jmp_buf is totally private.
52 // Current layout (may change in the future):
54 // word name description
55 // 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
56 // 1 sigmask signal mask (not used with _setjmp / _longjmp)
57 // 2 float_base base of float registers (d8 to d15)
58 // 18 float_state floating-point status and control register
59 // 19 core_base base of core registers (r4 to r14)
60 // 30 reserved reserved entries (room to grow)
63 // NOTE: float_base must be at an even word index, since the
64 // FP registers will be loaded/stored with instructions
65 // that expect 8-byte alignment.
68 #define _JB_SIGMASK (_JB_SIGFLAG+1)
69 #define _JB_FLOAT_BASE (_JB_SIGMASK+1)
70 #define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
71 #define _JB_CORE_BASE (_JB_FLOAT_STATE+1)
83 #define MANGLE_REGISTERS 1
84 .macro m_mangle_registers reg
100 .macro m_unmangle_registers reg
101 m_mangle_registers \reg
104 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
107 .cfi_def_cfa_offset 8
108 .cfi_rel_offset r0, 0
109 .cfi_rel_offset lr, 4
112 bl __bionic_setjmp_cookie_get
117 // Save the setjmp cookie for later.
120 .cfi_adjust_cfa_offset 4
122 // Record the setjmp cookie and whether or not we're saving the signal mask.
123 str r1, [r0, #(_JB_SIGFLAG * 4)]
125 // Do we need to save the signal mask?
131 .cfi_adjust_cfa_offset 4
133 // Save the current signal mask.
134 add r2, r0, #(_JB_SIGMASK * 4)
135 mov r0, #2 // SIG_SETMASK
139 // Unalign the stack.
141 .cfi_adjust_cfa_offset -4
145 .cfi_adjust_cfa_offset -4
147 .cfi_adjust_cfa_offset -8
151 // Save core registers.
152 add r1, r0, #(_JB_CORE_BASE * 4)
153 m_mangle_registers r2
155 // ARM deprecates using sp in the register list for stmia.
156 stmia r1, {r4-r12, lr}
157 str sp, [r1, #(10 * 4)]
158 m_unmangle_registers r2
160 // Save floating-point registers.
161 add r1, r0, #(_JB_FLOAT_BASE * 4)
164 // Save floating-point state.
166 str r1, [r0, #(_JB_FLOAT_STATE * 4)]
172 // void siglongjmp(sigjmp_buf env, int value);
174 stmfd sp!, {r0, r1, lr}
175 .cfi_def_cfa_offset 12
176 .cfi_rel_offset r0, 0
177 .cfi_rel_offset r1, 4
178 .cfi_rel_offset lr, 8
180 // Fetch the signal flag.
181 ldr r1, [r0, #(_JB_SIGFLAG * 4)]
183 // Do we need to restore the signal mask?
187 // Restore the signal mask.
188 ldr r0, [r0, #(_JB_SIGMASK * 4)]
192 ldmfd sp!, {r0, r1, lr}
193 .cfi_adjust_cfa_offset -12
198 // Restore floating-point registers.
199 add r2, r0, #(_JB_FLOAT_BASE * 4)
202 // Restore floating-point state.
203 ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
206 // Restore core registers.
207 ldr r3, [r0, #(_JB_SIGFLAG * 4)]
209 add r2, r0, #(_JB_CORE_BASE * 4)
211 // ARM deprecates using sp in the register list for ldmia.
212 ldmia r2, {r4-r12, lr}
213 ldr sp, [r2, #(10 * 4)]
214 m_unmangle_registers r3
216 // Save the return value/address and check the setjmp cookie.
218 .cfi_adjust_cfa_offset 8
219 .cfi_rel_offset lr, 4
221 bl __bionic_setjmp_cookie_check
223 // Restore return value/address.
225 .cfi_adjust_cfa_offset -8
233 ALIAS_SYMBOL(longjmp, siglongjmp)
234 ALIAS_SYMBOL(_longjmp, siglongjmp)