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 
98 /*
99  * By default, the pointer fields in the arm_thread_state64_t structure are
100  * opaque on the arm64e architecture and require the use of accessor macros.
101  * This mode can also be enabled on the arm64 architecture by building with
102  * -D__DARWIN_OPAQUE_ARM_THREAD_STATE64=1.
103  */
104 #if defined(__arm64__) && defined(__LP64__)
105 
106 #if __has_feature(ptrauth_calls)
107 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 1
108 #define __DARWIN_PTRAUTH_ARM_THREAD_STATE64 1
109 #endif /* __has_feature(ptrauth_calls) */
110 
111 #ifndef __DARWIN_OPAQUE_ARM_THREAD_STATE64
112 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 0
113 #endif
114 
115 #else /* defined(__arm64__) && defined(__LP64__) */
116 
117 #undef __DARWIN_OPAQUE_ARM_THREAD_STATE64
118 #define __DARWIN_OPAQUE_ARM_THREAD_STATE64 0
119 
120 #endif /* defined(__arm64__) && defined(__LP64__) */
121 
122 #if __DARWIN_UNIX03
123 #define _STRUCT_ARM_THREAD_STATE64 struct __darwin_arm_thread_state64
124 #if __DARWIN_OPAQUE_ARM_THREAD_STATE64
125 _STRUCT_ARM_THREAD_STATE64
126 {
127 	__uint64_t __x[29];     /* General purpose registers x0-x28 */
128 	void*      __opaque_fp; /* Frame pointer x29 */
129 	void*      __opaque_lr; /* Link register x30 */
130 	void*      __opaque_sp; /* Stack pointer x31 */
131 	void*      __opaque_pc; /* Program counter */
132 	__uint32_t __cpsr;      /* Current program status register */
133 	__uint32_t __opaque_flags; /* Flags describing structure format */
134 };
135 #else /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
136 _STRUCT_ARM_THREAD_STATE64
137 {
138 	__uint64_t __x[29]; /* General purpose registers x0-x28 */
139 	__uint64_t __fp;    /* Frame pointer x29 */
140 	__uint64_t __lr;    /* Link register x30 */
141 	__uint64_t __sp;    /* Stack pointer x31 */
142 	__uint64_t __pc;    /* Program counter */
143 	__uint32_t __cpsr;  /* Current program status register */
144 	__uint32_t __pad;   /* Same size for 32-bit or 64-bit clients */
145 };
146 #endif /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
147 #else /* !__DARWIN_UNIX03 */
148 #define _STRUCT_ARM_THREAD_STATE64 struct arm_thread_state64
149 #if __DARWIN_OPAQUE_ARM_THREAD_STATE64
150 _STRUCT_ARM_THREAD_STATE64
151 {
152 	__uint64_t x[29];       /* General purpose registers x0-x28 */
153 	void*      __opaque_fp; /* Frame pointer x29 */
154 	void*      __opaque_lr; /* Link register x30 */
155 	void*      __opaque_sp; /* Stack pointer x31 */
156 	void*      __opaque_pc; /* Program counter */
157 	__uint32_t cpsr;        /* Current program status register */
158 	__uint32_t __opaque_flags; /* Flags describing structure format */
159 };
160 #else /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
161 _STRUCT_ARM_THREAD_STATE64
162 {
163 	__uint64_t x[29]; /* General purpose registers x0-x28 */
164 	__uint64_t fp;    /* Frame pointer x29 */
165 	__uint64_t lr;    /* Link register x30 */
166 	__uint64_t sp;    /* Stack pointer x31 */
167 	__uint64_t pc;    /* Program counter */
168 	__uint32_t cpsr;  /* Current program status register */
169 	__uint32_t __pad; /* Same size for 32-bit or 64-bit clients */
170 };
171 #endif /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
172 #endif /* __DARWIN_UNIX03 */
173 
174 #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL && defined(__arm64__)
175 
176 /* Accessor macros for arm_thread_state64_t pointer fields */
177 
178 #if __has_feature(ptrauth_calls) && defined(__LP64__)
179 #include <ptrauth.h>
180 
181 #if !__DARWIN_OPAQUE_ARM_THREAD_STATE64 || !__DARWIN_PTRAUTH_ARM_THREAD_STATE64
182 #error "Invalid configuration"
183 #endif
184 
185 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH 0x1
186 #define __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR 0x2
187 
188 /* Return pc field of arm_thread_state64_t as a data pointer value */
189 #define __darwin_arm_thread_state64_get_pc(ts) \
190 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
191 	(uintptr_t)(__tsp->__opaque_pc && !(__tsp->__opaque_flags &       \
192 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
193 	ptrauth_auth_data(__tsp->__opaque_pc,                             \
194 	ptrauth_key_process_independent_code,                             \
195 	ptrauth_string_discriminator("pc")) : __tsp->__opaque_pc); })
196 /* Return pc field of arm_thread_state64_t as a function pointer. May return
197  * NULL if a valid function pointer cannot be constructed, the caller should
198  * fall back to the __darwin_arm_thread_state64_get_pc() macro in that case. */
199 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
200 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
201 	(__tsp->__opaque_pc && !(__tsp->__opaque_flags &                  \
202 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
203 	ptrauth_auth_function(__tsp->__opaque_pc,                         \
204 	ptrauth_key_process_independent_code,                             \
205 	ptrauth_string_discriminator("pc")) : NULL); })
206 /* Set pc field of arm_thread_state64_t to a function pointer */
207 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
208 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts);   \
209 	__typeof__(fptr) __f = (fptr); __tsp->__opaque_pc =           \
210 	(__f ? (!(__tsp->__opaque_flags &                             \
211 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?               \
212 	ptrauth_auth_and_resign(__f, ptrauth_key_function_pointer, 0, \
213 	ptrauth_key_process_independent_code,                         \
214 	ptrauth_string_discriminator("pc")) : ptrauth_auth_data(__f,  \
215 	ptrauth_key_function_pointer, 0)) : __f); })
216 /* Return lr field of arm_thread_state64_t as a data pointer value */
217 #define __darwin_arm_thread_state64_get_lr(ts) \
218 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
219 	(uintptr_t)(__tsp->__opaque_lr && !(__tsp->__opaque_flags & (     \
220 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH |                    \
221 	__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) ?                \
222 	ptrauth_auth_data(__tsp->__opaque_lr,                             \
223 	ptrauth_key_process_independent_code,                             \
224 	ptrauth_string_discriminator("lr")) : __tsp->__opaque_lr); })
225 /* Return lr field of arm_thread_state64_t as a function pointer. May return
226  * NULL if a valid function pointer cannot be constructed, the caller should
227  * fall back to the __darwin_arm_thread_state64_get_lr() macro in that case. */
228 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
229 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
230 	(__tsp->__opaque_lr && !(__tsp->__opaque_flags & (                \
231 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH |                    \
232 	__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) ?                \
233 	ptrauth_auth_function(__tsp->__opaque_lr,                         \
234 	ptrauth_key_process_independent_code,                             \
235 	ptrauth_string_discriminator("lr")) : NULL); })
236 /* Set lr field of arm_thread_state64_t to a function pointer */
237 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
238 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts);            \
239 	__typeof__(fptr) __f = (fptr); __tsp->__opaque_lr =                    \
240 	(__f ? (!(__tsp->__opaque_flags &                                      \
241 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? (__tsp->__opaque_flags \
242 	&= ~__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR ,                   \
243 	ptrauth_auth_and_resign(__f, ptrauth_key_function_pointer, 0,          \
244 	ptrauth_key_process_independent_code,                                  \
245 	ptrauth_string_discriminator("lr"))) : ptrauth_auth_data(__f,          \
246 	ptrauth_key_function_pointer, 0)) : __f); })
247 /* Return sp field of arm_thread_state64_t as a data pointer value */
248 #define __darwin_arm_thread_state64_get_sp(ts) \
249 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
250 	(uintptr_t)(__tsp->__opaque_sp && !(__tsp->__opaque_flags &       \
251 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
252 	ptrauth_auth_data(__tsp->__opaque_sp,                             \
253 	ptrauth_key_process_independent_data,                             \
254 	ptrauth_string_discriminator("sp")) : __tsp->__opaque_sp); })
255 /* Set sp field of arm_thread_state64_t to a data pointer value */
256 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
257 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
258 	void *__p = (void*)(uintptr_t)(ptr); __tsp->__opaque_sp =   \
259 	(__p && !(__tsp->__opaque_flags &                           \
260 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?             \
261 	ptrauth_sign_unauthenticated(__p,                           \
262 	ptrauth_key_process_independent_data,                       \
263 	ptrauth_string_discriminator("sp")) : __p); })
264 /* Return fp field of arm_thread_state64_t as a data pointer value */
265 #define __darwin_arm_thread_state64_get_fp(ts) \
266 	__extension__ ({ const _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
267 	(uintptr_t)(__tsp->__opaque_fp && !(__tsp->__opaque_flags &       \
268 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?                   \
269 	ptrauth_auth_data(__tsp->__opaque_fp,                             \
270 	ptrauth_key_process_independent_data,                             \
271 	ptrauth_string_discriminator("fp")) : __tsp->__opaque_fp); })
272 /* Set fp field of arm_thread_state64_t to a data pointer value */
273 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
274 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts); \
275 	void *__p = (void*)(uintptr_t)(ptr); __tsp->__opaque_fp =   \
276 	(__p && !(__tsp->__opaque_flags &                           \
277 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ?             \
278 	ptrauth_sign_unauthenticated(__p,                           \
279 	ptrauth_key_process_independent_data,                       \
280 	ptrauth_string_discriminator("fp")) : __p); })
281 
282 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
283 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
284 	__extension__ ({ _STRUCT_ARM_THREAD_STATE64 *__tsp = &(ts);               \
285 	__tsp->__opaque_pc = ((__tsp->__opaque_flags &                            \
286 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? __tsp->__opaque_pc :      \
287 	ptrauth_strip(__tsp->__opaque_pc, ptrauth_key_process_independent_code)); \
288 	__tsp->__opaque_lr = ((__tsp->__opaque_flags &                            \
289 	(__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH |                           \
290 	__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) ? __tsp->__opaque_lr :   \
291 	ptrauth_strip(__tsp->__opaque_lr, ptrauth_key_process_independent_code)); \
292 	__tsp->__opaque_sp = ((__tsp->__opaque_flags &                            \
293 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? __tsp->__opaque_sp :      \
294 	ptrauth_strip(__tsp->__opaque_sp, ptrauth_key_process_independent_data)); \
295 	__tsp->__opaque_fp = ((__tsp->__opaque_flags &                            \
296 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) ? __tsp->__opaque_fp :      \
297 	ptrauth_strip(__tsp->__opaque_fp, ptrauth_key_process_independent_data)); \
298 	__tsp->__opaque_flags |=                                                  \
299 	__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH; })
300 
301 #else /* __has_feature(ptrauth_calls) && defined(__LP64__) */
302 
303 #if __DARWIN_OPAQUE_ARM_THREAD_STATE64
304 
305 #ifndef __LP64__
306 #error "Invalid configuration"
307 #endif
308 
309 /* Return pc field of arm_thread_state64_t as a data pointer value */
310 #define __darwin_arm_thread_state64_get_pc(ts) \
311 	((uintptr_t)((ts).__opaque_pc))
312 /* Return pc field of arm_thread_state64_t as a function pointer */
313 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
314 	((ts).__opaque_pc)
315 /* Set pc field of arm_thread_state64_t to a function pointer */
316 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
317 	((ts).__opaque_pc = (fptr))
318 /* Return lr field of arm_thread_state64_t as a data pointer value */
319 #define __darwin_arm_thread_state64_get_lr(ts) \
320 	((uintptr_t)((ts).__opaque_lr))
321 /* Return lr field of arm_thread_state64_t as a function pointer */
322 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
323 	((ts).__opaque_lr)
324 /* Set lr field of arm_thread_state64_t to a function pointer */
325 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
326 	((ts).__opaque_lr = (fptr))
327 /* Return sp field of arm_thread_state64_t as a data pointer value */
328 #define __darwin_arm_thread_state64_get_sp(ts) \
329 	((uintptr_t)((ts).__opaque_sp))
330 /* Set sp field of arm_thread_state64_t to a data pointer value */
331 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
332 	((ts).__opaque_sp = (void*)(uintptr_t)(ptr))
333 /* Return fp field of arm_thread_state64_t as a data pointer value */
334 #define __darwin_arm_thread_state64_get_fp(ts) \
335 	((uintptr_t)((ts).__opaque_fp))
336 /* Set fp field of arm_thread_state64_t to a data pointer value */
337 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
338 	((ts).__opaque_fp = (void*)(uintptr_t)(ptr))
339 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
340 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
341 	(void)(ts)
342 
343 #else /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
344 #if __DARWIN_UNIX03
345 
346 /* Return pc field of arm_thread_state64_t as a data pointer value */
347 #define __darwin_arm_thread_state64_get_pc(ts) \
348 	((ts).__pc)
349 /* Return pc field of arm_thread_state64_t as a function pointer */
350 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
351 	((void*)(uintptr_t)((ts).__pc))
352 /* Set pc field of arm_thread_state64_t to a function pointer */
353 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
354 	((ts).__pc = (uintptr_t)(fptr))
355 /* Return lr field of arm_thread_state64_t as a data pointer value */
356 #define __darwin_arm_thread_state64_get_lr(ts) \
357 	((ts).__lr)
358 /* Return lr field of arm_thread_state64_t as a function pointer */
359 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
360 	((void*)(uintptr_t)((ts).__lr))
361 /* Set lr field of arm_thread_state64_t to a function pointer */
362 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
363 	((ts).__lr = (uintptr_t)(fptr))
364 /* Return sp field of arm_thread_state64_t as a data pointer value */
365 #define __darwin_arm_thread_state64_get_sp(ts) \
366 	((ts).__sp)
367 /* Set sp field of arm_thread_state64_t to a data pointer value */
368 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
369 	((ts).__sp = (uintptr_t)(ptr))
370 /* Return fp field of arm_thread_state64_t as a data pointer value */
371 #define __darwin_arm_thread_state64_get_fp(ts) \
372 	((ts).__fp)
373 /* Set fp field of arm_thread_state64_t to a data pointer value */
374 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
375 	((ts).__fp = (uintptr_t)(ptr))
376 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
377 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
378 	(void)(ts)
379 
380 #else /* __DARWIN_UNIX03 */
381 
382 /* Return pc field of arm_thread_state64_t as a data pointer value */
383 #define __darwin_arm_thread_state64_get_pc(ts) \
384 	((ts).pc)
385 /* Return pc field of arm_thread_state64_t as a function pointer */
386 #define __darwin_arm_thread_state64_get_pc_fptr(ts) \
387 	((void*)(uintptr_t)((ts).pc))
388 /* Set pc field of arm_thread_state64_t to a function pointer */
389 #define __darwin_arm_thread_state64_set_pc_fptr(ts, fptr) \
390 	((ts).pc = (uintptr_t)(fptr))
391 /* Return lr field of arm_thread_state64_t as a data pointer value */
392 #define __darwin_arm_thread_state64_get_lr(ts) \
393 	((ts).lr)
394 /* Return lr field of arm_thread_state64_t as a function pointer */
395 #define __darwin_arm_thread_state64_get_lr_fptr(ts) \
396 	((void*)(uintptr_t)((ts).lr))
397 /* Set lr field of arm_thread_state64_t to a function pointer */
398 #define __darwin_arm_thread_state64_set_lr_fptr(ts, fptr) \
399 	((ts).lr = (uintptr_t)(fptr))
400 /* Return sp field of arm_thread_state64_t as a data pointer value */
401 #define __darwin_arm_thread_state64_get_sp(ts) \
402 	((ts).sp)
403 /* Set sp field of arm_thread_state64_t to a data pointer value */
404 #define __darwin_arm_thread_state64_set_sp(ts, ptr) \
405 	((ts).sp = (uintptr_t)(ptr))
406 /* Return fp field of arm_thread_state64_t as a data pointer value */
407 #define __darwin_arm_thread_state64_get_fp(ts) \
408 	((ts).fp)
409 /* Set fp field of arm_thread_state64_t to a data pointer value */
410 #define __darwin_arm_thread_state64_set_fp(ts, ptr) \
411 	((ts).fp = (uintptr_t)(ptr))
412 /* Strip ptr auth bits from pc, lr, sp and fp field of arm_thread_state64_t */
413 #define __darwin_arm_thread_state64_ptrauth_strip(ts) \
414 	(void)(ts)
415 
416 #endif /* __DARWIN_UNIX03 */
417 #endif /* __DARWIN_OPAQUE_ARM_THREAD_STATE64 */
418 
419 #endif /* __has_feature(ptrauth_calls) && defined(__LP64__) */
420 #endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL && defined(__arm64__) */
421 
422 #if __DARWIN_UNIX03
423 #define _STRUCT_ARM_VFP_STATE struct __darwin_arm_vfp_state
424 _STRUCT_ARM_VFP_STATE
425 {
426 	__uint32_t __r[64];
427 	__uint32_t __fpscr;
428 };
429 #else /* !__DARWIN_UNIX03 */
430 #define _STRUCT_ARM_VFP_STATE struct arm_vfp_state
431 _STRUCT_ARM_VFP_STATE
432 {
433 	__uint32_t r[64];
434 	__uint32_t fpscr;
435 };
436 #endif /* __DARWIN_UNIX03 */
437 
438 #if __DARWIN_UNIX03
439 #define _STRUCT_ARM_NEON_STATE64 struct __darwin_arm_neon_state64
440 #define _STRUCT_ARM_NEON_STATE   struct __darwin_arm_neon_state
441 
442 #if defined(__arm64__)
443 _STRUCT_ARM_NEON_STATE64
444 {
445 	__uint128_t __v[32];
446 	__uint32_t  __fpsr;
447 	__uint32_t  __fpcr;
448 };
449 
450 _STRUCT_ARM_NEON_STATE
451 {
452 	__uint128_t __v[16];
453 	__uint32_t  __fpsr;
454 	__uint32_t  __fpcr;
455 };
456 #elif defined(__arm__)
457 /*
458  * No 128-bit intrinsic for ARM; leave it opaque for now.
459  */
460 _STRUCT_ARM_NEON_STATE64
461 {
462 	char opaque[(32 * 16) + (2 * sizeof(__uint32_t))];
463 } __attribute__((aligned(16)));
464 
465 _STRUCT_ARM_NEON_STATE
466 {
467 	char opaque[(16 * 16) + (2 * sizeof(__uint32_t))];
468 } __attribute__((aligned(16)));
469 
470 #else
471 #error Unknown architecture.
472 #endif
473 
474 #else /* !__DARWIN_UNIX03 */
475 #define _STRUCT_ARM_NEON_STATE64 struct arm_neon_state64
476 #define _STRUCT_ARM_NEON_STATE struct arm_neon_state
477 
478 #if defined(__arm64__)
479 _STRUCT_ARM_NEON_STATE64
480 {
481 	__uint128_t q[32];
482 	uint32_t    fpsr;
483 	uint32_t    fpcr;
484 };
485 
486 _STRUCT_ARM_NEON_STATE
487 {
488 	__uint128_t q[16];
489 	uint32_t    fpsr;
490 	uint32_t    fpcr;
491 };
492 #elif defined(__arm__)
493 /*
494  * No 128-bit intrinsic for ARM; leave it opaque for now.
495  */
496 _STRUCT_ARM_NEON_STATE64
497 {
498 	char opaque[(32 * 16) + (2 * sizeof(__uint32_t))];
499 } __attribute__((aligned(16)));
500 
501 _STRUCT_ARM_NEON_STATE
502 {
503 	char opaque[(16 * 16) + (2 * sizeof(__uint32_t))];
504 } __attribute__((aligned(16)));
505 
506 #else
507 #error Unknown architecture.
508 #endif
509 
510 #endif /* __DARWIN_UNIX03 */
511 
512 
513 #define _STRUCT_ARM_PAGEIN_STATE struct __arm_pagein_state
514 _STRUCT_ARM_PAGEIN_STATE
515 {
516 	int __pagein_error;
517 };
518 
519 /*
520  * Debug State
521  */
522 #if defined(__arm__)
523 /* Old-fashioned debug state is only for ARM */
524 
525 #if __DARWIN_UNIX03
526 #define _STRUCT_ARM_DEBUG_STATE struct __darwin_arm_debug_state
527 _STRUCT_ARM_DEBUG_STATE
528 {
529 	__uint32_t __bvr[16];
530 	__uint32_t __bcr[16];
531 	__uint32_t __wvr[16];
532 	__uint32_t __wcr[16];
533 };
534 #else /* !__DARWIN_UNIX03 */
535 #define _STRUCT_ARM_DEBUG_STATE struct arm_debug_state
536 _STRUCT_ARM_DEBUG_STATE
537 {
538 	__uint32_t bvr[16];
539 	__uint32_t bcr[16];
540 	__uint32_t wvr[16];
541 	__uint32_t wcr[16];
542 };
543 #endif /* __DARWIN_UNIX03 */
544 
545 #elif defined(__arm64__)
546 
547 /* ARM's arm_debug_state is ARM64's arm_legacy_debug_state */
548 
549 #if __DARWIN_UNIX03
550 #define _STRUCT_ARM_LEGACY_DEBUG_STATE struct __arm_legacy_debug_state
551 _STRUCT_ARM_LEGACY_DEBUG_STATE
552 {
553 	__uint32_t __bvr[16];
554 	__uint32_t __bcr[16];
555 	__uint32_t __wvr[16];
556 	__uint32_t __wcr[16];
557 };
558 #else /* __DARWIN_UNIX03 */
559 #define _STRUCT_ARM_LEGACY_DEBUG_STATE struct arm_legacy_debug_state
560 _STRUCT_ARM_LEGACY_DEBUG_STATE
561 {
562 	__uint32_t bvr[16];
563 	__uint32_t bcr[16];
564 	__uint32_t wvr[16];
565 	__uint32_t wcr[16];
566 };
567 #endif /* __DARWIN_UNIX03 */
568 #else
569 #error unknown architecture
570 #endif
571 
572 #if __DARWIN_UNIX03
573 #define _STRUCT_ARM_DEBUG_STATE32 struct __darwin_arm_debug_state32
574 _STRUCT_ARM_DEBUG_STATE32
575 {
576 	__uint32_t __bvr[16];
577 	__uint32_t __bcr[16];
578 	__uint32_t __wvr[16];
579 	__uint32_t __wcr[16];
580 	__uint64_t __mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
581 };
582 
583 #define _STRUCT_ARM_DEBUG_STATE64 struct __darwin_arm_debug_state64
584 _STRUCT_ARM_DEBUG_STATE64
585 {
586 	__uint64_t __bvr[16];
587 	__uint64_t __bcr[16];
588 	__uint64_t __wvr[16];
589 	__uint64_t __wcr[16];
590 	__uint64_t __mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
591 };
592 #else /* !__DARWIN_UNIX03 */
593 #define _STRUCT_ARM_DEBUG_STATE32 struct arm_debug_state32
594 _STRUCT_ARM_DEBUG_STATE32
595 {
596 	__uint32_t bvr[16];
597 	__uint32_t bcr[16];
598 	__uint32_t wvr[16];
599 	__uint32_t wcr[16];
600 	__uint64_t mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
601 };
602 
603 #define _STRUCT_ARM_DEBUG_STATE64 struct arm_debug_state64
604 _STRUCT_ARM_DEBUG_STATE64
605 {
606 	__uint64_t bvr[16];
607 	__uint64_t bcr[16];
608 	__uint64_t wvr[16];
609 	__uint64_t wcr[16];
610 	__uint64_t mdscr_el1; /* Bit 0 is SS (Hardware Single Step) */
611 };
612 #endif /* __DARWIN_UNIX03 */
613 
614 #if __DARWIN_UNIX03
615 #define _STRUCT_ARM_CPMU_STATE64 struct __darwin_arm_cpmu_state64
616 _STRUCT_ARM_CPMU_STATE64
617 {
618 	__uint64_t __ctrs[16];
619 };
620 #else /* __DARWIN_UNIX03 */
621 #define _STRUCT_ARM_CPMU_STATE64 struct arm_cpmu_state64
622 _STRUCT_ARM_CPMU_STATE64
623 {
624 	__uint64_t ctrs[16];
625 };
626 #endif /* !__DARWIN_UNIX03 */
627 
628 #endif /* defined (__arm__) || defined (__arm64__) */
629 
630 #endif /* _MACH_ARM__STRUCTS_H_ */