xref: /xnu-8020.140.41/osfmk/mach/arm/_structs.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1 /*
2  * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 #ifndef _MACH_ARM__STRUCTS_H_
32 #define _MACH_ARM__STRUCTS_H_
33 
34 #if defined (__arm__) || defined (__arm64__)
35 
36 #include <sys/cdefs.h> /* __DARWIN_UNIX03 */
37 #include <machine/types.h> /* __uint32_t */
38 
39 #if __DARWIN_UNIX03
40 #define _STRUCT_ARM_EXCEPTION_STATE struct __darwin_arm_exception_state
41 _STRUCT_ARM_EXCEPTION_STATE
42 {
43 	__uint32_t __exception; /* number of arm exception taken */
44 	__uint32_t __fsr;       /* Fault status */
45 	__uint32_t __far;       /* Virtual Fault Address */
46 };
47 #else /* !__DARWIN_UNIX03 */
48 #define _STRUCT_ARM_EXCEPTION_STATE struct arm_exception_state
49 _STRUCT_ARM_EXCEPTION_STATE
50 {
51 	__uint32_t exception;   /* number of arm exception taken */
52 	__uint32_t fsr;         /* Fault status */
53 	__uint32_t far;         /* Virtual Fault Address */
54 };
55 #endif /* __DARWIN_UNIX03 */
56 
57 #if __DARWIN_UNIX03
58 #define _STRUCT_ARM_EXCEPTION_STATE64 struct __darwin_arm_exception_state64
59 _STRUCT_ARM_EXCEPTION_STATE64
60 {
61 	__uint64_t __far;       /* Virtual Fault Address */
62 	__uint32_t __esr;       /* Exception syndrome */
63 	__uint32_t __exception; /* number of arm exception taken */
64 };
65 #else /* !__DARWIN_UNIX03 */
66 #define _STRUCT_ARM_EXCEPTION_STATE64 struct arm_exception_state64
67 _STRUCT_ARM_EXCEPTION_STATE64
68 {
69 	__uint64_t far;         /* Virtual Fault Address */
70 	__uint32_t esr;         /* Exception syndrome */
71 	__uint32_t exception;   /* number of arm exception taken */
72 };
73 #endif /* __DARWIN_UNIX03 */
74 
75 #if __DARWIN_UNIX03
76 #define _STRUCT_ARM_THREAD_STATE struct __darwin_arm_thread_state
77 _STRUCT_ARM_THREAD_STATE
78 {
79 	__uint32_t __r[13]; /* General purpose register r0-r12 */
80 	__uint32_t __sp;    /* Stack pointer r13 */
81 	__uint32_t __lr;    /* Link register r14 */
82 	__uint32_t __pc;    /* Program counter r15 */
83 	__uint32_t __cpsr;  /* Current program status register */
84 };
85 #else /* !__DARWIN_UNIX03 */
86 #define _STRUCT_ARM_THREAD_STATE struct arm_thread_state
87 _STRUCT_ARM_THREAD_STATE
88 {
89 	__uint32_t r[13];   /* General purpose register r0-r12 */
90 	__uint32_t sp;      /* Stack pointer r13 */
91 	__uint32_t lr;      /* Link register r14 */
92 	__uint32_t pc;      /* Program counter r15 */
93 	__uint32_t cpsr;    /* Current program status register */
94 };
95 #endif /* __DARWIN_UNIX03 */
96 
97 #if defined(KERNEL)
98 
99 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 0
100 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH 0x1
101 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR 0x2
102 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC 0x4
103 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR 0x8
104 
105 #define __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK 0xff000000
106 #define __DARWIN_ARM_THREAD_STATE64_SIGRETURN_PC_MASK 0x000f0000
107 #define __DARWIN_ARM_THREAD_STATE64_SIGRETURN_LR_MASK 0x00f00000
108 
109 #define __DARWIN_ARM_THREAD_STATE64_SET_SIGRETURN_TOKEN(ts, token, mask) \
110     ((ts)->flags |= (((uint32_t)(token)) & (mask)))
111 
112 #define __DARWIN_ARM_THREAD_STATE64_CHECK_SIGRETURN_TOKEN(ts, token, mask) \
113     (((ts)->flags & (mask)) == \
114     (((uint32_t)(token)) & (mask)))
115 
116 #define _STRUCT_ARM_THREAD_STATE64      struct arm_thread_state64
117 _STRUCT_ARM_THREAD_STATE64
118 {
119 	__uint64_t    x[29];    /* General purpose registers x0-x28 */
120 	__uint64_t    fp;               /* Frame pointer x29 */
121 	__uint64_t    lr;               /* Link register x30 */
122 	__uint64_t    sp;               /* Stack pointer x31 */
123 	__uint64_t    pc;               /* Program counter */
124 	__uint32_t    cpsr;             /* Current program status register */
125 	__uint32_t    flags;    /* Flags describing structure format */
126 };
127 
128 #else /* defined(KERNEL) */
129 
130 /*
131  * By default, the pointer fields in the arm_thread_state64_t structure are
132  * opaque on the arm64e architecture and require the use of accessor macros.
133  * This mode can also be enabled on the arm64 architecture by building with
134  * -D__DARWIN_OPAQUE_ARM_THREAD_STATE64=1.
135  */
136 #if defined(__arm64__) && defined(__LP64__)
137 
138 #if __has_feature(ptrauth_calls)
139 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 1
140 #define __DARWIN_PTRAUTH_ARM_THREAD_STATE64 1
141 #endif /* __has_feature(ptrauth_calls) */
142 
143 #ifndef __DARWIN_OPAQUE_ARM_THREAD_STATE64
144 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 0
145 #endif
146 
147 #else /* defined(__arm64__) && defined(__LP64__) */
148 
149 #undef __DARWIN_OPAQUE_ARM_THREAD_STATE64
150 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 0
151 
152 #endif /* defined(__arm64__) && defined(__LP64__) */
153 
154 #if __DARWIN_UNIX03
155 #define _STRUCT_ARM_THREAD_STATE64 struct __darwin_arm_thread_state64
156 #if __DARWIN_OPAQUE_ARM_THREAD_STATE64
157 _STRUCT_ARM_THREAD_STATE64
158 {
159 	__uint64_t __x[29];     /* General purpose registers x0-x28 */
160 	void*      __opaque_fp; /* Frame pointer x29 */
161 	void*      __opaque_lr; /* Link register x30 */
162 	void*      __opaque_sp; /* Stack pointer x31 */
163 	void*      __opaque_pc; /* Program counter */
164 	__uint32_t __cpsr;      /* Current program status register */
165 	__uint32_t __opaque_flags; /* Flags describing structure format */
166 };
167 #else /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
168 _STRUCT_ARM_THREAD_STATE64
169 {
170 	__uint64_t __x[29]; /* General purpose registers x0-x28 */
171 	__uint64_t __fp;    /* Frame pointer x29 */
172 	__uint64_t __lr;    /* Link register x30 */
173 	__uint64_t __sp;    /* Stack pointer x31 */
174 	__uint64_t __pc;    /* Program counter */
175 	__uint32_t __cpsr;  /* Current program status register */
176 	__uint32_t __pad;   /* Same size for 32-bit or 64-bit clients */
177 };
178 #endif /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
179 #else /* !__DARWIN_UNIX03 */
180 #define _STRUCT_ARM_THREAD_STATE64 struct arm_thread_state64
181 #if __DARWIN_OPAQUE_ARM_THREAD_STATE64
182 _STRUCT_ARM_THREAD_STATE64
183 {
184 	__uint64_t x[29];       /* General purpose registers x0-x28 */
185 	void*      __opaque_fp; /* Frame pointer x29 */
186 	void*      __opaque_lr; /* Link register x30 */
187 	void*      __opaque_sp; /* Stack pointer x31 */
188 	void*      __opaque_pc; /* Program counter */
189 	__uint32_t cpsr;        /* Current program status register */
190 	__uint32_t __opaque_flags; /* Flags describing structure format */
191 };
192 #else /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
193 _STRUCT_ARM_THREAD_STATE64
194 {
195 	__uint64_t x[29]; /* General purpose registers x0-x28 */
196 	__uint64_t fp;    /* Frame pointer x29 */
197 	__uint64_t lr;    /* Link register x30 */
198 	__uint64_t sp;    /* Stack pointer x31 */
199 	__uint64_t pc;    /* Program counter */
200 	__uint32_t cpsr;  /* Current program status register */
201 	__uint32_t __pad; /* Same size for 32-bit or 64-bit clients */
202 };
203 #endif /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
204 #endif /* __DARWIN_UNIX03 */
205 
206 #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL && defined(__arm64__)
207 
208 /* Accessor macros for arm_thread_state64_t pointer fields */
209 
210 #if __has_feature(ptrauth_calls) && defined(__LP64__)
211 #include <ptrauth.h>
212 
213 #if !__DARWIN_OPAQUE_ARM_THREAD_STATE64 || !__DARWIN_PTRAUTH_ARM_THREAD_STATE64
214 #error "Invalid configuration"
215 #endif
216 
217 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH 0x1
218 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR 0x2
219 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC 0x4
220 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR 0x8
221 
222 #define __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK 0xff000000
223 
224 /* Return pc field of arm_thread_state64_t as a data pointer value */
225 #define __darwin_arm_thread_state64_get_pc(ts) \
226 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
227 	(uintptr_t)(__tsp->__opaque_pc && !(__tsp->__opaque_flags &       \
228 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
229 	ptrauth_auth_data(__tsp->__opaque_pc,                             \
230 	ptrauth_key_process_independent_code,                             \
231 	((__tsp->__opaque_flags &                                         \
232 	__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC) == 0 &&       \
233 	(__tsp->__opaque_flags &                                          \
234 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK)) ?             \
235 	ptrauth_blend_discriminator((void *)(unsigned long)               \
236 	(__tsp->__opaque_flags &                                          \
237 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK),               \
238 	ptrauth_string_discriminator("pc")) :                             \
239 	ptrauth_string_discriminator("pc")) : __tsp->__opaque_pc); })
240 /* Return pc field of arm_thread_state64_t as a function pointer. May return
241  * NULL if a valid function pointer cannot be constructed, the caller should
242  * fall back to the __darwin_arm_thread_state64_get_pc() macro in that case. */
243 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
244 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
245 	(__tsp->__opaque_pc && !(__tsp->__opaque_flags &                  \
246 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
247 	ptrauth_auth_function(__tsp->__opaque_pc,                         \
248 	ptrauth_key_process_independent_code,                             \
249 	((__tsp->__opaque_flags &                                         \
250 	__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC) == 0 &&       \
251 	(__tsp->__opaque_flags &                                          \
252 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK)) ?             \
253 	ptrauth_blend_discriminator((void *)(unsigned long)               \
254 	(__tsp->__opaque_flags &                                          \
255 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK),               \
256 	ptrauth_string_discriminator("pc")) :                             \
257 	ptrauth_string_discriminator("pc")) : NULL); })
258 /* Set pc field of arm_thread_state64_t to a function pointer */
259 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
260 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts);   \
261 	__typeof__(fptr) __f = (fptr); __tsp->__opaque_pc =           \
262 	(__f ? (!(__tsp->__opaque_flags &                             \
263 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?               \
264 	ptrauth_auth_and_resign(__f, ptrauth_key_function_pointer, 0, \
265 	ptrauth_key_process_independent_code,                         \
266 	(__tsp->__opaque_flags &                                      \
267 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK) ?          \
268 	ptrauth_blend_discriminator((void *)(unsigned long)           \
269 	(__tsp->__opaque_flags &                                      \
270 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK),           \
271 	ptrauth_string_discriminator("pc")) :                         \
272 	ptrauth_string_discriminator("pc")) : ptrauth_auth_data(__f,  \
273 	ptrauth_key_function_pointer, 0)) : __f);                     \
274 	__tsp->__opaque_flags &=                                      \
275 	~__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC; })
276 /* Return lr field of arm_thread_state64_t as a data pointer value */
277 #define __darwin_arm_thread_state64_get_lr(ts) \
278 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
279 	(uintptr_t)(__tsp->__opaque_lr && !(__tsp->__opaque_flags & (     \
280 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH |                    \
281 	__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) ?                \
282 	ptrauth_auth_data(__tsp->__opaque_lr,                             \
283 	ptrauth_key_process_independent_code,                             \
284 	((__tsp->__opaque_flags &                                         \
285 	__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR) == 0 &&       \
286 	(__tsp->__opaque_flags &                                          \
287 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK)) ?             \
288 	ptrauth_blend_discriminator((void *)(unsigned long)               \
289 	(__tsp->__opaque_flags &                                          \
290 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK),               \
291 	ptrauth_string_discriminator("lr")) :                             \
292 	ptrauth_string_discriminator("lr")) : __tsp->__opaque_lr); })
293 /* Return lr field of arm_thread_state64_t as a function pointer. May return
294  * NULL if a valid function pointer cannot be constructed, the caller should
295  * fall back to the __darwin_arm_thread_state64_get_lr() macro in that case. */
296 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
297 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
298 	(__tsp->__opaque_lr && !(__tsp->__opaque_flags & (                \
299 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH |                    \
300 	__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) ?                \
301 	ptrauth_auth_function(__tsp->__opaque_lr,                         \
302 	ptrauth_key_process_independent_code,                             \
303 	((__tsp->__opaque_flags &                                         \
304 	__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR) == 0 &&       \
305 	(__tsp->__opaque_flags &                                          \
306 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK)) ?             \
307 	ptrauth_blend_discriminator((void *)(unsigned long)               \
308 	(__tsp->__opaque_flags &                                          \
309 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK),               \
310 	ptrauth_string_discriminator("lr")) :                             \
311 	ptrauth_string_discriminator("lr")) : NULL); })
312 /* Set lr field of arm_thread_state64_t to a function pointer */
313 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
314 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts);            \
315 	__typeof__(fptr) __f = (fptr); __tsp->__opaque_lr =                    \
316 	(__f ? (!(__tsp->__opaque_flags &                                      \
317 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? (__tsp->__opaque_flags \
318 	&= ~__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR ,                   \
319 	ptrauth_auth_and_resign(__f, ptrauth_key_function_pointer, 0,          \
320 	ptrauth_key_process_independent_code,                                  \
321 	(__tsp->__opaque_flags &                                               \
322 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK) ?                   \
323 	ptrauth_blend_discriminator((void *)(unsigned long)                    \
324 	(__tsp->__opaque_flags &                                               \
325 	__DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK),                    \
326 	ptrauth_string_discriminator("lr")) :                                  \
327 	ptrauth_string_discriminator("lr"))) : ptrauth_auth_data(__f,          \
328 	ptrauth_key_function_pointer, 0)) : __f); __tsp->__opaque_flags &=     \
329 	~__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR; })
330 /* Return sp field of arm_thread_state64_t as a data pointer value */
331 #define __darwin_arm_thread_state64_get_sp(ts) \
332 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
333 	(uintptr_t)(__tsp->__opaque_sp && !(__tsp->__opaque_flags &       \
334 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
335 	ptrauth_auth_data(__tsp->__opaque_sp,                             \
336 	ptrauth_key_process_independent_data,                             \
337 	ptrauth_string_discriminator("sp")) : __tsp->__opaque_sp); })
338 /* Set sp field of arm_thread_state64_t to a data pointer value */
339 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
340 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
341 	void *__p = (void*)(uintptr_t)(ptr); __tsp->__opaque_sp =   \
342 	(__p && !(__tsp->__opaque_flags &                           \
343 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?             \
344 	ptrauth_sign_unauthenticated(__p,                           \
345 	ptrauth_key_process_independent_data,                       \
346 	ptrauth_string_discriminator("sp")) : __p); })
347 /* Return fp field of arm_thread_state64_t as a data pointer value */
348 #define __darwin_arm_thread_state64_get_fp(ts) \
349 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
350 	(uintptr_t)(__tsp->__opaque_fp && !(__tsp->__opaque_flags &       \
351 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
352 	ptrauth_auth_data(__tsp->__opaque_fp,                             \
353 	ptrauth_key_process_independent_data,                             \
354 	ptrauth_string_discriminator("fp")) : __tsp->__opaque_fp); })
355 /* Set fp field of arm_thread_state64_t to a data pointer value */
356 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
357 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
358 	void *__p = (void*)(uintptr_t)(ptr); __tsp->__opaque_fp =   \
359 	(__p && !(__tsp->__opaque_flags &                           \
360 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?             \
361 	ptrauth_sign_unauthenticated(__p,                           \
362 	ptrauth_key_process_independent_data,                       \
363 	ptrauth_string_discriminator("fp")) : __p); })
364 
365 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
366 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
367 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts);               \
368 	__tsp->__opaque_pc = ((__tsp->__opaque_flags &                            \
369 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? __tsp->__opaque_pc :      \
370 	ptrauth_strip(__tsp->__opaque_pc, ptrauth_key_process_independent_code)); \
371 	__tsp->__opaque_lr = ((__tsp->__opaque_flags &                            \
372 	(__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH |                           \
373 	__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) ? __tsp->__opaque_lr :   \
374 	ptrauth_strip(__tsp->__opaque_lr, ptrauth_key_process_independent_code)); \
375 	__tsp->__opaque_sp = ((__tsp->__opaque_flags &                            \
376 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? __tsp->__opaque_sp :      \
377 	ptrauth_strip(__tsp->__opaque_sp, ptrauth_key_process_independent_data)); \
378 	__tsp->__opaque_fp = ((__tsp->__opaque_flags &                            \
379 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? __tsp->__opaque_fp :      \
380 	ptrauth_strip(__tsp->__opaque_fp, ptrauth_key_process_independent_data)); \
381 	__tsp->__opaque_flags |=                                                  \
382 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH; __tsp->__opaque_flags &=    \
383 	~(__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC |                    \
384 	__DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR); })
385 
386 #else /* __has_feature(ptrauth_calls) && defined(__LP64__) */
387 
388 #if __DARWIN_OPAQUE_ARM_THREAD_STATE64
389 
390 #ifndef __LP64__
391 #error "Invalid configuration"
392 #endif
393 
394 /* Return pc field of arm_thread_state64_t as a data pointer value */
395 #define __darwin_arm_thread_state64_get_pc(ts) \
396 	((uintptr_t)((ts).__opaque_pc))
397 /* Return pc field of arm_thread_state64_t as a function pointer */
398 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
399 	((ts).__opaque_pc)
400 /* Set pc field of arm_thread_state64_t to a function pointer */
401 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
402 	((ts).__opaque_pc = (fptr))
403 /* Return lr field of arm_thread_state64_t as a data pointer value */
404 #define __darwin_arm_thread_state64_get_lr(ts) \
405 	((uintptr_t)((ts).__opaque_lr))
406 /* Return lr field of arm_thread_state64_t as a function pointer */
407 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
408 	((ts).__opaque_lr)
409 /* Set lr field of arm_thread_state64_t to a function pointer */
410 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
411 	((ts).__opaque_lr = (fptr))
412 /* Return sp field of arm_thread_state64_t as a data pointer value */
413 #define __darwin_arm_thread_state64_get_sp(ts) \
414 	((uintptr_t)((ts).__opaque_sp))
415 /* Set sp field of arm_thread_state64_t to a data pointer value */
416 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
417 	((ts).__opaque_sp = (void*)(uintptr_t)(ptr))
418 /* Return fp field of arm_thread_state64_t as a data pointer value */
419 #define __darwin_arm_thread_state64_get_fp(ts) \
420 	((uintptr_t)((ts).__opaque_fp))
421 /* Set fp field of arm_thread_state64_t to a data pointer value */
422 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
423 	((ts).__opaque_fp = (void*)(uintptr_t)(ptr))
424 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
425 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
426 	(void)(ts)
427 
428 #else /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
429 #if __DARWIN_UNIX03
430 
431 /* Return pc field of arm_thread_state64_t as a data pointer value */
432 #define __darwin_arm_thread_state64_get_pc(ts) \
433 	((ts).__pc)
434 /* Return pc field of arm_thread_state64_t as a function pointer */
435 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
436 	((void*)(uintptr_t)((ts).__pc))
437 /* Set pc field of arm_thread_state64_t to a function pointer */
438 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
439 	((ts).__pc = (uintptr_t)(fptr))
440 /* Return lr field of arm_thread_state64_t as a data pointer value */
441 #define __darwin_arm_thread_state64_get_lr(ts) \
442 	((ts).__lr)
443 /* Return lr field of arm_thread_state64_t as a function pointer */
444 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
445 	((void*)(uintptr_t)((ts).__lr))
446 /* Set lr field of arm_thread_state64_t to a function pointer */
447 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
448 	((ts).__lr = (uintptr_t)(fptr))
449 /* Return sp field of arm_thread_state64_t as a data pointer value */
450 #define __darwin_arm_thread_state64_get_sp(ts) \
451 	((ts).__sp)
452 /* Set sp field of arm_thread_state64_t to a data pointer value */
453 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
454 	((ts).__sp = (uintptr_t)(ptr))
455 /* Return fp field of arm_thread_state64_t as a data pointer value */
456 #define __darwin_arm_thread_state64_get_fp(ts) \
457 	((ts).__fp)
458 /* Set fp field of arm_thread_state64_t to a data pointer value */
459 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
460 	((ts).__fp = (uintptr_t)(ptr))
461 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
462 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
463 	(void)(ts)
464 
465 #else /* __DARWIN_UNIX03 */
466 
467 /* Return pc field of arm_thread_state64_t as a data pointer value */
468 #define __darwin_arm_thread_state64_get_pc(ts) \
469 	((ts).pc)
470 /* Return pc field of arm_thread_state64_t as a function pointer */
471 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
472 	((void*)(uintptr_t)((ts).pc))
473 /* Set pc field of arm_thread_state64_t to a function pointer */
474 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
475 	((ts).pc = (uintptr_t)(fptr))
476 /* Return lr field of arm_thread_state64_t as a data pointer value */
477 #define __darwin_arm_thread_state64_get_lr(ts) \
478 	((ts).lr)
479 /* Return lr field of arm_thread_state64_t as a function pointer */
480 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
481 	((void*)(uintptr_t)((ts).lr))
482 /* Set lr field of arm_thread_state64_t to a function pointer */
483 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
484 	((ts).lr = (uintptr_t)(fptr))
485 /* Return sp field of arm_thread_state64_t as a data pointer value */
486 #define __darwin_arm_thread_state64_get_sp(ts) \
487 	((ts).sp)
488 /* Set sp field of arm_thread_state64_t to a data pointer value */
489 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
490 	((ts).sp = (uintptr_t)(ptr))
491 /* Return fp field of arm_thread_state64_t as a data pointer value */
492 #define __darwin_arm_thread_state64_get_fp(ts) \
493 	((ts).fp)
494 /* Set fp field of arm_thread_state64_t to a data pointer value */
495 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
496 	((ts).fp = (uintptr_t)(ptr))
497 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
498 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
499 	(void)(ts)
500 
501 #endif /* __DARWIN_UNIX03 */
502 #endif /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
503 
504 #endif /* __has_feature(ptrauth_calls) && defined(__LP64__) */
505 #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL && defined(__arm64__) */
506 #endif /* !defined(KERNEL) */
507 
508 #if __DARWIN_UNIX03
509 #define _STRUCT_ARM_VFP_STATE struct __darwin_arm_vfp_state
510 _STRUCT_ARM_VFP_STATE
511 {
512 	__uint32_t __r[64];
513 	__uint32_t __fpscr;
514 };
515 #else /* !__DARWIN_UNIX03 */
516 #define _STRUCT_ARM_VFP_STATE struct arm_vfp_state
517 _STRUCT_ARM_VFP_STATE
518 {
519 	__uint32_t r[64];
520 	__uint32_t fpscr;
521 };
522 #endif /* __DARWIN_UNIX03 */
523 
524 #if __DARWIN_UNIX03
525 #define _STRUCT_ARM_NEON_STATE64 struct __darwin_arm_neon_state64
526 #define _STRUCT_ARM_NEON_STATE   struct __darwin_arm_neon_state
527 
528 #if defined(__arm64__)
529 _STRUCT_ARM_NEON_STATE64
530 {
531 	__uint128_t __v[32];
532 	__uint32_t  __fpsr;
533 	__uint32_t  __fpcr;
534 };
535 
536 _STRUCT_ARM_NEON_STATE
537 {
538 	__uint128_t __v[16];
539 	__uint32_t  __fpsr;
540 	__uint32_t  __fpcr;
541 };
542 #elif defined(__arm__)
543 /*
544  * No 128-bit intrinsic for ARM; leave it opaque for now.
545  */
546 _STRUCT_ARM_NEON_STATE64
547 {
548 	char opaque[(32 * 16) + (2 * sizeof(__uint32_t))];
549 } __attribute__((aligned(16)));
550 
551 _STRUCT_ARM_NEON_STATE
552 {
553 	char opaque[(16 * 16) + (2 * sizeof(__uint32_t))];
554 } __attribute__((aligned(16)));
555 
556 #else
557 #error Unknown architecture.
558 #endif
559 
560 #else /* !__DARWIN_UNIX03 */
561 #define _STRUCT_ARM_NEON_STATE64 struct arm_neon_state64
562 #define _STRUCT_ARM_NEON_STATE struct arm_neon_state
563 
564 #if defined(__arm64__)
565 _STRUCT_ARM_NEON_STATE64
566 {
567 	__uint128_t q[32];
568 	uint32_t    fpsr;
569 	uint32_t    fpcr;
570 };
571 
572 _STRUCT_ARM_NEON_STATE
573 {
574 	__uint128_t q[16];
575 	uint32_t    fpsr;
576 	uint32_t    fpcr;
577 };
578 #elif defined(__arm__)
579 /*
580  * No 128-bit intrinsic for ARM; leave it opaque for now.
581  */
582 _STRUCT_ARM_NEON_STATE64
583 {
584 	char opaque[(32 * 16) + (2 * sizeof(__uint32_t))];
585 } __attribute__((aligned(16)));
586 
587 _STRUCT_ARM_NEON_STATE
588 {
589 	char opaque[(16 * 16) + (2 * sizeof(__uint32_t))];
590 } __attribute__((aligned(16)));
591 
592 #else
593 #error Unknown architecture.
594 #endif
595 
596 #endif /* __DARWIN_UNIX03 */
597 
598 
599 #define _STRUCT_ARM_PAGEIN_STATE struct __arm_pagein_state
600 _STRUCT_ARM_PAGEIN_STATE
601 {
602 	int __pagein_error;
603 };
604 
605 /*
606  * Debug State
607  */
608 #if defined(__arm__)
609 /* Old-fashioned debug state is only for ARM */
610 
611 #if __DARWIN_UNIX03
612 #define _STRUCT_ARM_DEBUG_STATE struct __darwin_arm_debug_state
613 _STRUCT_ARM_DEBUG_STATE
614 {
615 	__uint32_t __bvr[16];
616 	__uint32_t __bcr[16];
617 	__uint32_t __wvr[16];
618 	__uint32_t __wcr[16];
619 };
620 #else /* !__DARWIN_UNIX03 */
621 #define _STRUCT_ARM_DEBUG_STATE struct arm_debug_state
622 _STRUCT_ARM_DEBUG_STATE
623 {
624 	__uint32_t bvr[16];
625 	__uint32_t bcr[16];
626 	__uint32_t wvr[16];
627 	__uint32_t wcr[16];
628 };
629 #endif /* __DARWIN_UNIX03 */
630 
631 #elif defined(__arm64__)
632 
633 /* ARM's arm_debug_state is ARM64's arm_legacy_debug_state */
634 
635 #if __DARWIN_UNIX03
636 #define _STRUCT_ARM_LEGACY_DEBUG_STATE struct __arm_legacy_debug_state
637 _STRUCT_ARM_LEGACY_DEBUG_STATE
638 {
639 	__uint32_t __bvr[16];
640 	__uint32_t __bcr[16];
641 	__uint32_t __wvr[16];
642 	__uint32_t __wcr[16];
643 };
644 #else /* __DARWIN_UNIX03 */
645 #define _STRUCT_ARM_LEGACY_DEBUG_STATE struct arm_legacy_debug_state
646 _STRUCT_ARM_LEGACY_DEBUG_STATE
647 {
648 	__uint32_t bvr[16];
649 	__uint32_t bcr[16];
650 	__uint32_t wvr[16];
651 	__uint32_t wcr[16];
652 };
653 #endif /* __DARWIN_UNIX03 */
654 #else
655 #error unknown architecture
656 #endif
657 
658 #if __DARWIN_UNIX03
659 #define _STRUCT_ARM_DEBUG_STATE32 struct __darwin_arm_debug_state32
660 _STRUCT_ARM_DEBUG_STATE32
661 {
662 	__uint32_t __bvr[16];
663 	__uint32_t __bcr[16];
664 	__uint32_t __wvr[16];
665 	__uint32_t __wcr[16];
666 	__uint64_t __mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
667 };
668 
669 #define _STRUCT_ARM_DEBUG_STATE64 struct __darwin_arm_debug_state64
670 _STRUCT_ARM_DEBUG_STATE64
671 {
672 	__uint64_t __bvr[16];
673 	__uint64_t __bcr[16];
674 	__uint64_t __wvr[16];
675 	__uint64_t __wcr[16];
676 	__uint64_t __mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
677 };
678 #else /* !__DARWIN_UNIX03 */
679 #define _STRUCT_ARM_DEBUG_STATE32 struct arm_debug_state32
680 _STRUCT_ARM_DEBUG_STATE32
681 {
682 	__uint32_t bvr[16];
683 	__uint32_t bcr[16];
684 	__uint32_t wvr[16];
685 	__uint32_t wcr[16];
686 	__uint64_t mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
687 };
688 
689 #define _STRUCT_ARM_DEBUG_STATE64 struct arm_debug_state64
690 _STRUCT_ARM_DEBUG_STATE64
691 {
692 	__uint64_t bvr[16];
693 	__uint64_t bcr[16];
694 	__uint64_t wvr[16];
695 	__uint64_t wcr[16];
696 	__uint64_t mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
697 };
698 #endif /* __DARWIN_UNIX03 */
699 
700 #if __DARWIN_UNIX03
701 #define _STRUCT_ARM_CPMU_STATE64 struct __darwin_arm_cpmu_state64
702 _STRUCT_ARM_CPMU_STATE64
703 {
704 	__uint64_t __ctrs[16];
705 };
706 #else /* __DARWIN_UNIX03 */
707 #define _STRUCT_ARM_CPMU_STATE64 struct arm_cpmu_state64
708 _STRUCT_ARM_CPMU_STATE64
709 {
710 	__uint64_t ctrs[16];
711 };
712 #endif /* !__DARWIN_UNIX03 */
713 
714 #endif /* defined (__arm__) || defined (__arm64__) */
715 
716 #endif /* _MACH_ARM__STRUCTS_H_ */
717