blob: 8220c0825a9d26cc4012123b30f3b819862aea45 [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001/*
2 * Copyright (c) 1997 Mark Brinicombe
David 'Digit' Turner68b5f552010-03-25 09:54:33 -07003 * Copyright (c) 2010 Android Open Source Project.
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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.
20 *
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
31 * SUCH DAMAGE.
32 */
33
Elliott Hughes851e68a2014-02-19 16:53:20 -080034#include <private/bionic_asm.h>
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080035
Elliott Hughesb3932992014-12-05 15:39:51 -080036// According to the ARM AAPCS document, we only need to save
37// the following registers:
38//
39// Core r4-r14
40//
41// VFP d8-d15 (see section 5.1.2.1)
42//
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.
48//
49// FPSCR saved because glibc does.
50
51// The internal structure of a jmp_buf is totally private.
52// Current layout (may change in the future):
53//
54// word name description
55// 0 magic magic number
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)
61// 64
62//
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.
66
Elliott Hughes75096222014-12-08 16:01:20 -080067#define _JB_SIGFLAG 0
68#define _JB_SIGMASK (_JB_SIGFLAG+1)
Elliott Hughesb3932992014-12-05 15:39:51 -080069#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)
72
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080073ENTRY(setjmp)
Elliott Hughesb3932992014-12-05 15:39:51 -080074 mov r1, #1
75 b sigsetjmp
Kenny Root420878c2011-02-16 11:55:58 -080076END(setjmp)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080077
Elliott Hughesb3932992014-12-05 15:39:51 -080078ENTRY(_setjmp)
79 mov r1, #0
80 b sigsetjmp
81END(_setjmp)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080082
Elliott Hughesb3932992014-12-05 15:39:51 -080083// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
84ENTRY(sigsetjmp)
Elliott Hughes75096222014-12-08 16:01:20 -080085 // Record whether or not we're saving the signal mask.
86 str r1, [r0, #(_JB_SIGFLAG * 4)]
87
Elliott Hughesb3932992014-12-05 15:39:51 -080088 // Do we need to save the signal mask?
89 teq r1, #0
Elliott Hughesb3932992014-12-05 15:39:51 -080090 beq 1f
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080091
Elliott Hughesb3932992014-12-05 15:39:51 -080092 // Get current signal mask.
93 stmfd sp!, {r0, r14}
94 .cfi_def_cfa_offset 8
95 .cfi_rel_offset r0, 0
96 .cfi_rel_offset r14, 4
97 mov r0, #0
98 bl sigblock
99 mov r1, r0
100 ldmfd sp!, {r0, r14}
101 .cfi_def_cfa_offset 0
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800102
Elliott Hughes75096222014-12-08 16:01:20 -0800103 // Save the signal mask.
Elliott Hughesb3932992014-12-05 15:39:51 -0800104 str r1, [r0, #(_JB_SIGMASK * 4)]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800105
Elliott Hughesb3932992014-12-05 15:39:51 -08001061:
Elliott Hughesb3932992014-12-05 15:39:51 -0800107 // Save core registers.
108 add r1, r0, #(_JB_CORE_BASE * 4)
109 stmia r1, {r4-r14}
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800110
Elliott Hughesb3932992014-12-05 15:39:51 -0800111 // Save floating-point registers.
112 add r1, r0, #(_JB_FLOAT_BASE * 4)
113 vstmia r1, {d8-d15}
David 'Digit' Turner68b5f552010-03-25 09:54:33 -0700114
Elliott Hughesb3932992014-12-05 15:39:51 -0800115 // Save floating-point state.
116 fmrx r1, fpscr
117 str r1, [r0, #(_JB_FLOAT_STATE * 4)]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800118
Elliott Hughesb3932992014-12-05 15:39:51 -0800119 mov r0, #0
120 bx lr
121END(sigsetjmp)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -0800122
Elliott Hughesb3932992014-12-05 15:39:51 -0800123// void siglongjmp(sigjmp_buf env, int value);
124ENTRY(siglongjmp)
Elliott Hughes75096222014-12-08 16:01:20 -0800125 // Do we need to restore the signal mask?
126 ldr r2, [r0, #(_JB_SIGFLAG * 4)]
127 teq r2, #0
Elliott Hughesb3932992014-12-05 15:39:51 -0800128 beq 1f
Elliott Hughesb3932992014-12-05 15:39:51 -0800129
Elliott Hughes75096222014-12-08 16:01:20 -0800130 // Restore the signal mask.
Elliott Hughesb3932992014-12-05 15:39:51 -0800131 stmfd sp!, {r0, r1, r14}
132 .cfi_def_cfa_offset 12
133 .cfi_rel_offset r0, 0
134 .cfi_rel_offset r1, 4
135 .cfi_rel_offset r14, 8
136 sub sp, sp, #4 // Align the stack.
137 .cfi_adjust_cfa_offset 4
138
139 ldr r0, [r0, #(_JB_SIGMASK * 4)]
140 bl sigsetmask
141
142 add sp, sp, #4 // Unalign the stack.
143 .cfi_adjust_cfa_offset -4
144 ldmfd sp!, {r0, r1, r14}
145 .cfi_def_cfa_offset 0
146
1471:
148 // Restore floating-point registers.
149 add r2, r0, #(_JB_FLOAT_BASE * 4)
150 vldmia r2, {d8-d15}
151
152 // Restore floating-point state.
153 ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
154 fmxr fpscr, r2
155
156 // Restore core registers.
157 add r2, r0, #(_JB_CORE_BASE * 4)
158 ldmia r2, {r4-r14}
159
160 // Validate sp and r14.
161 teq sp, #0
162 teqne r14, #0
163 bleq longjmperror
164
165 // Set return value.
166 mov r0, r1
167 teq r0, #0
168 moveq r0, #1
169 bx lr
170END(siglongjmp)
171
Christopher Ferris24958512015-03-25 09:12:00 -0700172ALIAS_SYMBOL(longjmp, siglongjmp)
173ALIAS_SYMBOL(_longjmp, siglongjmp)