]> git.saurik.com Git - apple/libplatform.git/blame - src/setjmp/arm64/setjmp.s
libplatform-254.40.4.tar.gz
[apple/libplatform.git] / src / setjmp / arm64 / setjmp.s
CommitLineData
ada7c492 1/*
438624e0 2 * Copyright (c) 2011-2018 Apple Inc. All rights reserved.
ada7c492
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
442fbc9d 5 *
ada7c492
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
442fbc9d 12 *
ada7c492
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
442fbc9d 20 *
ada7c492
A
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#define JMP_r19_20 #0x00
25#define JMP_r21_22 #0x10
26#define JMP_r23_24 #0x20
27#define JMP_r25_26 #0x30
28#define JMP_r27_28 #0x40
438624e0
A
29#define JMP_fp_lr #0x50
30#define JMP_sp_rsvd #0x60 /* second field is reserved/unused */
ada7c492
A
31#define JMP_d8_d9 #0x70
32#define JMP_d10_d11 #0x80
33#define JMP_d12_d13 #0x90
34#define JMP_d14_d15 #0xA0
442fbc9d 35#define JMP_sigmask #0xB0
ada7c492 36#define JMP_sigflag #0xB8
442fbc9d
A
37#define JMP_sigonstack #0xBC /* whether the thread is on sigaltstack or not */
38
39#define STACK_SSFLAGS 16 // offsetof(stack_t, ss_flags)
ada7c492
A
40
41#include <architecture/arm/asm_help.h>
438624e0
A
42#include <os/tsd.h>
43
ada7c492
A
44
45/* int _setjmp(jmp_buf env); */
46ENTRY_POINT(__setjmp)
fedab584 47 mov x12, sp
438624e0
A
48 _OS_PTR_MUNGE_TOKEN(x16, x16)
49 _OS_PTR_MUNGE(x10, fp, x16)
50 _OS_PTR_MUNGE(x11, lr, x16)
438624e0 51 _OS_PTR_MUNGE(x12, x12, x16)
ada7c492
A
52 stp x19, x20, [x0, JMP_r19_20]
53 stp x21, x22, [x0, JMP_r21_22]
54 stp x23, x24, [x0, JMP_r23_24]
55 stp x25, x26, [x0, JMP_r25_26]
56 stp x27, x28, [x0, JMP_r27_28]
438624e0
A
57 stp x10, x11, [x0, JMP_fp_lr]
58 str x12, [x0, JMP_sp_rsvd]
ada7c492
A
59 stp d8, d9, [x0, JMP_d8_d9]
60 stp d10, d11, [x0, JMP_d10_d11]
61 stp d12, d13, [x0, JMP_d12_d13]
62 stp d14, d15, [x0, JMP_d14_d15]
438624e0 63 mov w0, #0
ada7c492
A
64 ret
65
66/* void _longjmp(jmp_buf env, int val); */
67ENTRY_POINT(__longjmp)
68 ldp x19, x20, [x0, JMP_r19_20]
69 ldp x21, x22, [x0, JMP_r21_22]
70 ldp x23, x24, [x0, JMP_r23_24]
71 ldp x25, x26, [x0, JMP_r25_26]
72 ldp x27, x28, [x0, JMP_r27_28]
438624e0
A
73 ldp x10, x11, [x0, JMP_fp_lr]
74 ldr x12, [x0, JMP_sp_rsvd]
ada7c492
A
75 ldp d8, d9, [x0, JMP_d8_d9]
76 ldp d10, d11, [x0, JMP_d10_d11]
77 ldp d12, d13, [x0, JMP_d12_d13]
78 ldp d14, d15, [x0, JMP_d14_d15]
fedab584 79 _OS_PTR_MUNGE_TOKEN(x16, x16)
438624e0
A
80 _OS_PTR_UNMUNGE(fp, x10, x16)
81 _OS_PTR_UNMUNGE(lr, x11, x16)
82 _OS_PTR_UNMUNGE(x12, x12, x16)
442fbc9d 83 ldrb w16, [sp] /* probe to detect absolutely corrupt stack pointers */
438624e0
A
84 mov sp, x12
85 cmp w1, #0
86 csinc w0, w1, wzr, ne
87 ret
ada7c492
A
88
89/* int sigsetjmp(sigjmp_buf env, int savemask); */
90ENTRY_POINT(_sigsetjmp)
438624e0
A
91 str w1, [x0, JMP_sigflag]
92 cbnz w1, 1f
ada7c492
A
93 b __setjmp
941:
95 /* else, fall through */
96
97/* int setjmp(jmp_buf env); */
98ENTRY_POINT(_setjmp)
442fbc9d
A
99 stp x21, lr, [x0] // Store x21 and lr in jmpbuf (for now)
100 mov x21, x0 // x21 = x0
438624e0 101
442fbc9d
A
102 // Save the sigmask
103 orr w0, wzr, #0x1 // x0 = how = SIG_BLOCK
104 mov x1, #0 // x1 = set = 0
105 add x2, x21, JMP_sigmask // x2 = oset = (x21 + JMP_sigmask)
ada7c492
A
106 CALL_EXTERNAL(_sigprocmask)
107
442fbc9d
A
108 // Get current sigaltstack status
109 sub sp, sp, #32 // 24 bytes for a stack_t on the stack, +8 for alignment of stack
110 mov x0, xzr // x0 = ss = NULL
111 mov x1, sp // x1 = oss = the place on the stack where the stack_t is located
112 CALL_EXTERNAL(___sigaltstack) // sigaltstack(NULL, oss)
113 ldr w0, [sp, STACK_SSFLAGS] // w0 = ss flags from stack_t
114 str w0, [x21, JMP_sigonstack] // *(x21 + JMP_sigonstack) = w0
115 add sp, sp, #32 // Reset sp
116
117 mov x0, x21 // x0 = x21
ada7c492
A
118 ldp x21, lr, [x0]
119 b __setjmp
120
438624e0 121
ada7c492
A
122/* void siglongjmp(sigjmp_buf env, int val); */
123ENTRY_POINT(_siglongjmp)
438624e0
A
124 ldr w8, [x0, JMP_sigflag]
125 cbnz w8, 1f
ada7c492
A
126 b __longjmp
1271:
128 /* else, fall through */
129
130/* void longjmp(jmp_buf env, int val); */
131ENTRY_POINT(_longjmp)
132 sub sp, sp, #16
133 mov x21, x0 // x21/x22 will be restored by __longjmp
134 mov x22, x1
442fbc9d
A
135
136 // Restore the signal mask
137 ldr x8, [x21, JMP_sigmask] // restore the signal mask
438624e0 138 str x8, [sp, #8]
ada7c492 139 orr w0, wzr, #0x3 // SIG_SETMASK
438624e0
A
140 add x1, sp, #8 // set
141 mov x2, #0 // oset
ada7c492 142 CALL_EXTERNAL(_sigprocmask)
442fbc9d
A
143
144 // Restore the sigaltstack status
145 ldr x0, [x21, JMP_sigonstack] // x0 = saved sigonstack info
146 CALL_EXTERNAL(__sigunaltstack)
147
ada7c492
A
148 mov x0, x21
149 mov x1, x22
150 add sp, sp, #16
151 b __longjmp