blob: c06a671578a9fb5d21bf513c54e922f189d28825 [file] [log] [blame]
Serban Constantinescue2104882013-09-26 11:37:10 +01001/*
2 * Copyright (C) 2013 The Android Open Source Project
Elliott Hughes54a74942014-01-03 16:40:37 -08003 * All rights reserved.
Serban Constantinescue2104882013-09-26 11:37:10 +01004 *
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
Elliott Hughes851e68a2014-02-19 16:53:20 -080029#include <private/bionic_asm.h>
Serban Constantinescue2104882013-09-26 11:37:10 +010030
Elliott Hughes9fb536d2014-12-05 12:17:25 -080031// According to AARCH64 PCS document we need to save the following
32// registers:
33//
34// Core x19 - x30, sp (see section 5.1.1)
35// VFP d8 - d15 (see section 5.1.2)
36//
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -080037// NOTE: All the registers saved here will have 64 bit vales.
Elliott Hughes9fb536d2014-12-05 12:17:25 -080038// AAPCS mandates that the higher part of q registers do not need to
39// be saved by the callee.
Elliott Hughes9fb536d2014-12-05 12:17:25 -080040
Elliott Hughes75096222014-12-08 16:01:20 -080041#define _JB_SIGFLAG 0
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -080042#define _JB_SIGMASK (_JB_SIGFLAG + 1)
43#define _JB_X30_SP (_JB_SIGMASK + 1)
44#define _JB_X28_X29 (_JB_X30_SP + 2)
45#define _JB_X26_X27 (_JB_X28_X29 + 2)
46#define _JB_X24_X25 (_JB_X26_X27 + 2)
47#define _JB_X22_X23 (_JB_X24_X25 + 2)
48#define _JB_X20_X21 (_JB_X22_X23 + 2)
49#define _JB_X19 (_JB_X20_X21 + 2)
50#define _JB_D14_D15 (_JB_X19 + 1)
51#define _JB_D12_D13 (_JB_D14_D15 + 2)
Duane Sanddbaab262015-01-26 16:20:05 -080052#define _JB_D10_D11 (_JB_D12_D13 + 2)
53#define _JB_D8_D9 (_JB_D10_D11 + 2)
Serban Constantinescue2104882013-09-26 11:37:10 +010054
Josh Gao54db0df2015-09-11 15:23:32 -070055#define MANGLE_REGISTERS 1
56.macro m_mangle_registers reg, sp_reg
57#if MANGLE_REGISTERS
58 eor x19, x19, \reg
59 eor x20, x20, \reg
60 eor x21, x21, \reg
61 eor x22, x22, \reg
62 eor x23, x23, \reg
63 eor x24, x24, \reg
64 eor x25, x25, \reg
65 eor x26, x26, \reg
66 eor x27, x27, \reg
67 eor x28, x28, \reg
68 eor x29, x29, \reg
69 eor x30, x30, \reg
70 eor \sp_reg, \sp_reg, \reg
71#endif
72.endm
73
74.macro m_unmangle_registers reg, sp_reg
75 m_mangle_registers \reg, sp_reg=\sp_reg
76.endm
77
Serban Constantinescue2104882013-09-26 11:37:10 +010078ENTRY(setjmp)
Elliott Hughes9fb536d2014-12-05 12:17:25 -080079 mov w1, #1
80 b sigsetjmp
Serban Constantinescue2104882013-09-26 11:37:10 +010081END(setjmp)
82
Elliott Hughes9fb536d2014-12-05 12:17:25 -080083ENTRY(_setjmp)
84 mov w1, #0
85 b sigsetjmp
86END(_setjmp)
Serban Constantinescue2104882013-09-26 11:37:10 +010087
Elliott Hughes9fb536d2014-12-05 12:17:25 -080088// int sigsetjmp(sigjmp_buf env, int save_signal_mask);
89ENTRY(sigsetjmp)
Josh Gao54db0df2015-09-11 15:23:32 -070090 stp x0, x30, [sp, #-16]!
91 .cfi_def_cfa_offset 16
92 .cfi_rel_offset x0, 0
93 .cfi_rel_offset x30, 8
94
95 // Get the cookie and store it along with the signal flag.
96 mov x0, x1
97 bl __bionic_setjmp_cookie_get
98 mov x1, x0
99 ldr x0, [sp, #0]
100 str x1, [x0, #(_JB_SIGFLAG * 8)]
Elliott Hughes75096222014-12-08 16:01:20 -0800101
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800102 // Do we need to save the signal mask?
Josh Gao54db0df2015-09-11 15:23:32 -0700103 tbz w1, #0, 1f
104
105 // Save the cookie for later.
106 stp x1, xzr, [sp, #-16]!
107 .cfi_adjust_cfa_offset 16
Serban Constantinescue2104882013-09-26 11:37:10 +0100108
Elliott Hughes7b78e812014-12-05 22:57:55 -0800109 // Save current signal mask.
Elliott Hughes7b78e812014-12-05 22:57:55 -0800110 // The 'how' argument is ignored if new_mask is NULL.
111 mov x1, #0 // NULL.
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800112 add x2, x0, #(_JB_SIGMASK * 8) // old_mask.
Elliott Hughes7b78e812014-12-05 22:57:55 -0800113 bl sigprocmask
Josh Gao54db0df2015-09-11 15:23:32 -0700114
115 ldp x1, xzr, [sp], #16
116 .cfi_adjust_cfa_offset -16
Serban Constantinescue2104882013-09-26 11:37:10 +0100117
Elliott Hughes9fb536d2014-12-05 12:17:25 -08001181:
Josh Gao54db0df2015-09-11 15:23:32 -0700119 // Restore original x0 and lr.
120 ldp x0, x30, [sp], #16
121 .cfi_adjust_cfa_offset -16
122 .cfi_restore x0
123 .cfi_restore x30
124
125 // Mask off the signal flag bit.
126 bic x1, x1, #1
127
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800128 // Save core registers.
129 mov x10, sp
Josh Gao54db0df2015-09-11 15:23:32 -0700130 m_mangle_registers x1, sp_reg=x10
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800131 stp x30, x10, [x0, #(_JB_X30_SP * 8)]
132 stp x28, x29, [x0, #(_JB_X28_X29 * 8)]
133 stp x26, x27, [x0, #(_JB_X26_X27 * 8)]
134 stp x24, x25, [x0, #(_JB_X24_X25 * 8)]
135 stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
136 stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
137 str x19, [x0, #(_JB_X19 * 8)]
Josh Gao54db0df2015-09-11 15:23:32 -0700138 m_unmangle_registers x1, sp_reg=x10
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800139
140 // Save floating point registers.
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800141 stp d14, d15, [x0, #(_JB_D14_D15 * 8)]
142 stp d12, d13, [x0, #(_JB_D12_D13 * 8)]
143 stp d10, d11, [x0, #(_JB_D10_D11 * 8)]
144 stp d8, d9, [x0, #(_JB_D8_D9 * 8)]
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800145
Elliott Hughes75096222014-12-08 16:01:20 -0800146 mov w0, #0
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800147 ret
148END(sigsetjmp)
149
150// void siglongjmp(sigjmp_buf env, int value);
151ENTRY(siglongjmp)
Elliott Hughes75096222014-12-08 16:01:20 -0800152 // Do we need to restore the signal mask?
Josh Gao54db0df2015-09-11 15:23:32 -0700153 ldr x2, [x0, #(_JB_SIGFLAG * 8)]
154 tbz w2, #0, 1f
155
156 stp x0, x30, [sp, #-16]!
157 .cfi_adjust_cfa_offset 16
158 .cfi_rel_offset x0, 0
159 .cfi_rel_offset x30, 8
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800160
161 // Restore signal mask.
Elliott Hughes7b78e812014-12-05 22:57:55 -0800162 mov x19, x1 // Save 'value'.
Josh Gao54db0df2015-09-11 15:23:32 -0700163
Elliott Hughes7b78e812014-12-05 22:57:55 -0800164 mov x2, x0
165 mov x0, #2 // SIG_SETMASK
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800166 add x1, x2, #(_JB_SIGMASK * 8) // new_mask.
Elliott Hughes7b78e812014-12-05 22:57:55 -0800167 mov x2, #0 // NULL.
168 bl sigprocmask
169 mov x1, x19 // Restore 'value'.
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800170
Josh Gao54db0df2015-09-11 15:23:32 -0700171 // Restore original x0 and lr.
172 ldp x0, x30, [sp], #16
173 .cfi_adjust_cfa_offset -16
174 .cfi_restore x0
175 .cfi_restore x30
176
177 ldr x2, [x0, #(_JB_SIGFLAG * 8)]
Elliott Hughes9fb536d2014-12-05 12:17:25 -08001781:
179 // Restore core registers.
Josh Gao54db0df2015-09-11 15:23:32 -0700180 bic x2, x2, #1
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800181 ldp x30, x10, [x0, #(_JB_X30_SP * 8)]
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800182 ldp x28, x29, [x0, #(_JB_X28_X29 * 8)]
183 ldp x26, x27, [x0, #(_JB_X26_X27 * 8)]
184 ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
185 ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
186 ldp x20, x21, [x0, #(_JB_X20_X21 * 8)]
187 ldr x19, [x0, #(_JB_X19 * 8)]
Josh Gao54db0df2015-09-11 15:23:32 -0700188 m_unmangle_registers x2, sp_reg=x10
189 mov sp, x10
190
191 stp x0, x1, [sp, #-16]!
192 .cfi_adjust_cfa_offset 16
193 .cfi_rel_offset x0, 0
194 .cfi_rel_offset x1, 8
195 stp x30, xzr, [sp, #-16]!
196 .cfi_adjust_cfa_offset 16
197 .cfi_rel_offset x30, 0
198 ldr x0, [x0, #(_JB_SIGFLAG * 8)]
199 bl __bionic_setjmp_cookie_check
200 ldp x30, xzr, [sp], #16
201 .cfi_adjust_cfa_offset -16
202 .cfi_restore x30
203 ldp x0, x1, [sp], #16
204 .cfi_adjust_cfa_offset -16
205 .cfi_restore x0
206 .cfi_restore x1
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800207
208 // Restore floating point registers.
Elliott Hughes9fa2cfb2014-12-08 16:23:10 -0800209 ldp d14, d15, [x0, #(_JB_D14_D15 * 8)]
210 ldp d12, d13, [x0, #(_JB_D12_D13 * 8)]
211 ldp d10, d11, [x0, #(_JB_D10_D11 * 8)]
212 ldp d8, d9, [x0, #(_JB_D8_D9 * 8)]
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800213
Elliott Hughes9fb536d2014-12-05 12:17:25 -0800214 // Set return value.
215 cmp w1, wzr
216 csinc w0, w1, wzr, ne
217 ret
218END(siglongjmp)
219
Christopher Ferris24958512015-03-25 09:12:00 -0700220ALIAS_SYMBOL(longjmp, siglongjmp)
221ALIAS_SYMBOL(_longjmp, siglongjmp)