2 * Copyright (c) 2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 #include <TargetConditionals.h>
28 * void setcontext(ucontext_t *ucp);
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;
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.
51 * setcontext restores the following fields (with the help of a helper function):
53 * machine data pointed by uc_mcontext
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
62 #if TARGET_OS_OSX || TARGET_OS_DRIVERKIT
63 /* Helper macro for authenticating fp, sp and lr and moves the auth-ed values to
67 * Modifies input registers, fp, sp and lr
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")
74 ldr xzr, [\sp] // Probe the new stack pointer to catch a corrupt stack
77 // Auth fp with constant discriminator
78 mov x9, #17687 // x9 = ptrauth_string_discriminator("fp")
82 // Check to see how the lr is signed. If it is signed with B key, nothing to
85 tbnz \flags, LR_SIGNED_WITH_IB_BIT, 2f
87 // Auth the input LR per the scheme in the thread state
89 mov x17, x16 // x16 = x17 = lr
91 mov x9, #30675 // x9 = ptrauth_string_discriminator("lr")
99 // Auth succeeded - resign the lr with the sp, auth will happen again on
111 .private_extern __setcontext
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]
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]
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]
143 // Auth the ptrs and move them to the right registers
144 PTR_AUTH_FP_SP_LR x10, x11, x12, w13
146 // Restore return value
151 #endif /* TARGET_OS_OSX || TARGET_OS_DRIVERKIT */