]> git.saurik.com Git - apple/libplatform.git/blame - src/ucontext/arm64/_setcontext.s
libplatform-254.40.4.tar.gz
[apple/libplatform.git] / src / ucontext / arm64 / _setcontext.s
CommitLineData
442fbc9d
A
1/*
2 * Copyright (c) 2020 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include "asm_help.h"
25#include <os/tsd.h>
26#include <TargetConditionals.h>
27/*
28 * void setcontext(ucontext_t *ucp);
29 *
30 * _STRUCT_UCONTEXT {
31 * int uc_onstack;
32 * __darwin_sigset_t uc_sigmask; // signal mask used by this context
33 * _STRUCT_SIGALTSTACK uc_stack; // stack used by this context
34 * _STRUCT_UCONTEXT *uc_link; // pointer to resuming context
35 * __darwin_size_t uc_mcsize; // size of the machine context passed in
36 * _STRUCT_MCONTEXT *uc_mcontext; // pointer to machine specific context
37 * #ifdef _XOPEN_SOURCE
38 * _STRUCT_MCONTEXT __mcontext_data;
39 * #endif
40 * };
41 *
42 * From the standard:
43 * The setcontext() function shall restore the user context pointed to by
44 * ucp. A successful call to setcontext() shall not return; program execution
45 * resumes at the point specified by the ucp argument passed to setcontext().
46 * The ucp argument should be created either by a prior call to getcontext()
47 * or makecontext(), or by being passed as an argument to a signal handler.
48 * If the ucp argument was created with getcontext(), program execution continues
49 * as if the corresponding call of getcontext() had just returned.
50 *
51 * setcontext restores the following fields (with the help of a helper function):
52 * uc_sigmask
53 * machine data pointed by uc_mcontext
54 *
55 * The ASM below mainly handles restoring the machine context data - note that
56 * in coordination with getcontext, only the arm64 callee save registers are
57 * being restored.
58 */
59
60.text
61
62#if TARGET_OS_OSX || TARGET_OS_DRIVERKIT
63/* Helper macro for authenticating fp, sp and lr and moves the auth-ed values to
64 * the right registers
65 *
66 * Uses x9
67 * Modifies input registers, fp, sp and lr
68 */
69.macro PTR_AUTH_FP_SP_LR fp, sp, lr, flags
70#if defined(__arm64e__)
71 // Auth sp with constant discriminator
72 mov x9, #52205 // x9 = ptrauth_string_discriminator("sp")
73 autda \sp, x9
74 ldr xzr, [\sp] // Probe the new stack pointer to catch a corrupt stack
75 mov sp, \sp
76
77 // Auth fp with constant discriminator
78 mov x9, #17687 // x9 = ptrauth_string_discriminator("fp")
79 autda \fp, x9
80 mov fp, \fp
81
82 // Check to see how the lr is signed. If it is signed with B key, nothing to
83 // do
84 mov lr, \lr
85 tbnz \flags, LR_SIGNED_WITH_IB_BIT, 2f
86
87 // Auth the input LR per the scheme in the thread state
88 mov x16, \lr
89 mov x17, x16 // x16 = x17 = lr
90
91 mov x9, #30675 // x9 = ptrauth_string_discriminator("lr")
92 autia x16, x9
93 xpaci x17
94 cmp x16, x17
95 b.eq 1f
96 brk #666
97
981:
99 // Auth succeeded - resign the lr with the sp, auth will happen again on
100 // return
101 mov lr, x16
102 pacibsp
1032:
104#else
105 mov sp, \sp
106 mov fp, \fp
107 mov lr, \lr
108#endif
109.endmacro
110
111.private_extern __setcontext
112.align 2
113__setcontext:
114 // x0 = mcontext
115
116 // Restore x19-x28
117 ldp x19, x20, [x0, MCONTEXT_OFFSET_X19_X20]
118 ldp x21, x22, [x0, MCONTEXT_OFFSET_X21_X22]
119 ldp x23, x24, [x0, MCONTEXT_OFFSET_X23_X24]
120 ldp x25, x26, [x0, MCONTEXT_OFFSET_X25_X26]
121 ldp x27, x28, [x0, MCONTEXT_OFFSET_X27_X28]
122
123 // Restore NEON registers
124 ldr d8, [x0, MCONTEXT_OFFSET_D8]
125 ldr d9, [x0, MCONTEXT_OFFSET_D9]
126 ldr d10, [x0, MCONTEXT_OFFSET_D10]
127 ldr d11, [x0, MCONTEXT_OFFSET_D11]
128 ldr d12, [x0, MCONTEXT_OFFSET_D12]
129 ldr d13, [x0, MCONTEXT_OFFSET_D13]
130 ldr d14, [x0, MCONTEXT_OFFSET_D14]
131 ldr d15, [x0, MCONTEXT_OFFSET_D15]
132
133 // Restore sp, fp, lr.
134 ldp x10, x12, [x0, MCONTEXT_OFFSET_FP_LR]
135 ldr x11, [x0, MCONTEXT_OFFSET_SP]
136 ldr w13, [x0, MCONTEXT_OFFSET_FLAGS]
137
138 // x10 = signed fp
139 // x11 = signed sp
140 // x12 = signed lr
141 // x13 = flags
142
143 // Auth the ptrs and move them to the right registers
144 PTR_AUTH_FP_SP_LR x10, x11, x12, w13
145
146 // Restore return value
147 mov x0, xzr
148
149 ARM64_STACK_EPILOG
150
151#endif /* TARGET_OS_OSX || TARGET_OS_DRIVERKIT */