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