2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
5 #include <mach/mach_types.h>
6 #include <mach/exception_types.h>
9 #include <sys/proc_internal.h>
11 #include <sys/signal.h>
12 #include <sys/ucontext.h>
13 #include <sys/sysproto.h>
14 #include <sys/systm.h>
15 #include <sys/ux_exception.h>
17 #include <arm/signal.h>
18 #include <sys/signalvar.h>
19 #include <sys/kdebug.h>
22 #include <kern/thread.h>
23 #include <mach/arm/thread_status.h>
24 #include <arm/proc_reg.h>
26 #include <kern/assert.h>
28 #include <pexpert/pexpert.h>
30 extern struct arm_saved_state
*get_user_regs(thread_t
);
31 extern user_addr_t
thread_get_cthread_self(void);
32 extern kern_return_t
thread_getstatus(thread_t act
, int flavor
,
33 thread_state_t tstate
, mach_msg_type_number_t
*count
);
34 extern kern_return_t
thread_getstatus_to_user(thread_t act
, int flavor
,
35 thread_state_t tstate
, mach_msg_type_number_t
*count
);
36 extern kern_return_t
machine_thread_state_convert_to_user(thread_t act
, int flavor
,
37 thread_state_t tstate
, mach_msg_type_number_t
*count
);
38 extern kern_return_t
thread_setstatus(thread_t thread
, int flavor
,
39 thread_state_t tstate
, mach_msg_type_number_t count
);
40 extern kern_return_t
thread_setstatus_from_user(thread_t thread
, int flavor
,
41 thread_state_t tstate
, mach_msg_type_number_t count
);
42 /* XXX Put these someplace smarter... */
43 typedef struct mcontext32 mcontext32_t
;
44 typedef struct mcontext64 mcontext64_t
;
46 /* Signal handler flavors supported */
47 /* These defns should match the Libc implmn */
51 /* The following are valid mcontext sizes */
52 #define UC_FLAVOR_SIZE32 ((ARM_THREAD_STATE_COUNT + ARM_EXCEPTION_STATE_COUNT + ARM_VFP_STATE_COUNT) * sizeof(int))
53 #define UC_FLAVOR_SIZE64 ((ARM_THREAD_STATE64_COUNT + ARM_EXCEPTION_STATE64_COUNT + ARM_NEON_STATE64_COUNT) * sizeof(int))
56 #define C_64_REDZONE_LEN 128
60 sendsig_get_state32(thread_t th_act
, arm_thread_state_t
*ts
, mcontext32_t
*mcp
)
63 mach_msg_type_number_t state_count
;
65 assert(!proc_is64bit_data(current_proc()));
68 state_count
= ARM_THREAD_STATE_COUNT
;
69 if (thread_getstatus(th_act
, ARM_THREAD_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
74 tstate
= (void *) &mcp
->ss
;
75 state_count
= ARM_THREAD_STATE_COUNT
;
76 if (machine_thread_state_convert_to_user(th_act
, ARM_THREAD_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
80 tstate
= (void *) &mcp
->es
;
81 state_count
= ARM_EXCEPTION_STATE_COUNT
;
82 if (thread_getstatus(th_act
, ARM_EXCEPTION_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
86 tstate
= (void *) &mcp
->fs
;
87 state_count
= ARM_VFP_STATE_COUNT
;
88 if (thread_getstatus_to_user(th_act
, ARM_VFP_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
95 #if defined(__arm64__)
96 struct user_sigframe64
{
97 /* We can pass the last two args in registers for ARM64 */
98 user64_siginfo_t sinfo
;
99 struct user_ucontext64 uctx
;
104 sendsig_get_state64(thread_t th_act
, arm_thread_state64_t
*ts
, mcontext64_t
*mcp
)
107 mach_msg_type_number_t state_count
;
109 assert(proc_is64bit_data(current_proc()));
111 tstate
= (void *) ts
;
112 state_count
= ARM_THREAD_STATE64_COUNT
;
113 if (thread_getstatus(th_act
, ARM_THREAD_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
118 tstate
= (void *) &mcp
->ss
;
119 state_count
= ARM_THREAD_STATE64_COUNT
;
120 if (machine_thread_state_convert_to_user(th_act
, ARM_THREAD_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
124 tstate
= (void *) &mcp
->es
;
125 state_count
= ARM_EXCEPTION_STATE64_COUNT
;
126 if (thread_getstatus(th_act
, ARM_EXCEPTION_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
130 tstate
= (void *) &mcp
->ns
;
131 state_count
= ARM_NEON_STATE64_COUNT
;
132 if (thread_getstatus_to_user(th_act
, ARM_NEON_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
) {
140 sendsig_fill_uctx64(user_ucontext64_t
*uctx
, int oonstack
, int mask
, user64_addr_t sp
, user64_size_t stack_size
, user64_addr_t p_mctx
)
142 bzero(uctx
, sizeof(*uctx
));
143 uctx
->uc_onstack
= oonstack
;
144 uctx
->uc_sigmask
= mask
;
145 uctx
->uc_stack
.ss_sp
= sp
;
146 uctx
->uc_stack
.ss_size
= stack_size
;
148 uctx
->uc_stack
.ss_flags
|= SS_ONSTACK
;
150 uctx
->uc_link
= (user64_addr_t
)0;
151 uctx
->uc_mcsize
= (user64_size_t
) UC_FLAVOR_SIZE64
;
152 uctx
->uc_mcontext64
= (user64_addr_t
) p_mctx
;
156 sendsig_set_thread_state64(arm_thread_state64_t
*regs
,
157 user64_addr_t catcher
, int infostyle
, int sig
, user64_addr_t p_sinfo
,
158 user64_addr_t p_uctx
, user64_addr_t token
, user64_addr_t trampact
, user64_addr_t sp
, thread_t th_act
)
160 assert(proc_is64bit_data(current_proc()));
162 regs
->x
[0] = catcher
;
163 regs
->x
[1] = infostyle
;
165 regs
->x
[3] = p_sinfo
;
169 regs
->cpsr
= PSR64_USER64_DEFAULT
;
172 return thread_setstatus(th_act
, ARM_THREAD_STATE64
, (void *)regs
, ARM_THREAD_STATE64_COUNT
);
174 #endif /* defined(__arm64__) */
177 sendsig_fill_uctx32(user_ucontext32_t
*uctx
, int oonstack
, int mask
, user_addr_t sp
, user_size_t stack_size
, user_addr_t p_mctx
)
179 bzero(uctx
, sizeof(*uctx
));
180 uctx
->uc_onstack
= oonstack
;
181 uctx
->uc_sigmask
= mask
;
182 uctx
->uc_stack
.ss_sp
= (user32_addr_t
) sp
;
183 uctx
->uc_stack
.ss_size
= (user32_size_t
) stack_size
;
185 uctx
->uc_stack
.ss_flags
|= SS_ONSTACK
;
187 uctx
->uc_link
= (user32_addr_t
)0;
188 uctx
->uc_mcsize
= (user32_size_t
) UC_FLAVOR_SIZE32
;
189 uctx
->uc_mcontext
= (user32_addr_t
) p_mctx
;
193 sendsig_set_thread_state32(arm_thread_state_t
*regs
,
194 user32_addr_t catcher
, int infostyle
, int sig
, user32_addr_t p_sinfo
,
195 user32_addr_t trampact
, user32_addr_t sp
, thread_t th_act
)
197 assert(!proc_is64bit_data(current_proc()));
199 regs
->r
[0] = catcher
;
200 regs
->r
[1] = infostyle
;
202 regs
->r
[3] = p_sinfo
;
204 regs
->pc
= trampact
& ~1;
205 #if defined(__arm64__)
206 regs
->cpsr
= PSR64_USER32_DEFAULT
| PSR64_MODE_USER32_THUMB
;
207 #elif defined(__arm__)
208 regs
->cpsr
= PSR_USERDFLT
| PSR_TF
;
210 #error Unknown architeture.
214 regs
->cpsr
= PSR_USERDFLT
;
218 return thread_setstatus(th_act
, ARM_THREAD_STATE
, (void *)regs
, ARM_THREAD_STATE_COUNT
);
223 sendsig_do_dtrace(uthread_t ut
, user_siginfo_t
*sinfo
, int sig
, user_addr_t catcher
)
225 bzero((caddr_t
)&(ut
->t_dtrace_siginfo
), sizeof(ut
->t_dtrace_siginfo
));
227 ut
->t_dtrace_siginfo
.si_signo
= sinfo
->si_signo
;
228 ut
->t_dtrace_siginfo
.si_code
= sinfo
->si_code
;
229 ut
->t_dtrace_siginfo
.si_pid
= sinfo
->si_pid
;
230 ut
->t_dtrace_siginfo
.si_uid
= sinfo
->si_uid
;
231 ut
->t_dtrace_siginfo
.si_status
= sinfo
->si_status
;
232 /* XXX truncates faulting address to void * */
233 ut
->t_dtrace_siginfo
.si_addr
= CAST_DOWN_EXPLICIT(void *, sinfo
->si_addr
);
235 /* Fire DTrace proc:::fault probe when signal is generated by hardware. */
237 case SIGILL
: case SIGBUS
: case SIGSEGV
: case SIGFPE
: case SIGTRAP
:
238 DTRACE_PROC2(fault
, int, (int)(ut
->uu_code
), siginfo_t
*, &(ut
->t_dtrace_siginfo
));
244 /* XXX truncates faulting address to uintptr_t */
245 DTRACE_PROC3(signal__handle
, int, sig
, siginfo_t
*, &(ut
->t_dtrace_siginfo
),
246 void (*)(void), CAST_DOWN(sig_t
, catcher
));
250 struct user_sigframe32
{
253 user32_siginfo_t sinfo
;
254 struct user_ucontext32 uctx
;
259 * Send an interrupt to process.
268 __unused
uint32_t code
,
274 arm_thread_state_t ss
;
276 #if defined(__arm64__)
278 arm_thread_state64_t ss
;
283 struct user_sigframe32 uf32
;
284 #if defined(__arm64__)
285 struct user_sigframe64 uf64
;
289 user_siginfo_t sinfo
;
290 user_addr_t sp
= 0, trampact
;
291 struct sigacts
*ps
= p
->p_sigacts
;
292 int oonstack
, infostyle
;
295 user_size_t stack_size
= 0;
296 user_addr_t p_uctx
, token_uctx
;
299 th_act
= current_thread();
300 ut
= get_bsdthread_info(th_act
);
302 bzero(&ts
, sizeof(ts
));
303 bzero(&user_frame
, sizeof(user_frame
));
305 if (siginfo
& sigmask(sig
)) {
306 infostyle
= UC_FLAVOR
;
311 trampact
= ps
->ps_trampact
[sig
];
312 oonstack
= ps
->ps_sigstk
.ss_flags
& SA_ONSTACK
;
315 * Get sundry thread state.
317 if (proc_is64bit_data(p
)) {
319 if (sendsig_get_state64(th_act
, &ts
.ts64
.ss
, &user_frame
.uf64
.mctx
) != 0) {
323 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
326 if (sendsig_get_state32(th_act
, &ts
.ts32
.ss
, &user_frame
.uf32
.mctx
) != 0) {
332 * Figure out where our new stack lives.
334 if ((ps
->ps_flags
& SAS_ALTSTACK
) && !oonstack
&&
335 (ps
->ps_sigonstack
& sigmask(sig
))) {
336 sp
= ps
->ps_sigstk
.ss_sp
;
337 sp
+= ps
->ps_sigstk
.ss_size
;
338 stack_size
= ps
->ps_sigstk
.ss_size
;
339 ps
->ps_sigstk
.ss_flags
|= SA_ONSTACK
;
342 * Get stack pointer, and allocate enough space
343 * for signal handler data.
345 if (proc_is64bit_data(p
)) {
346 #if defined(__arm64__)
347 sp
= CAST_USER_ADDR_T(ts
.ts64
.ss
.sp
);
348 sp
= (sp
- sizeof(user_frame
.uf64
) - C_64_REDZONE_LEN
) & ~0xf; /* Make sure to align to 16 bytes and respect red zone */
350 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
353 sp
= CAST_USER_ADDR_T(ts
.ts32
.ss
.sp
);
354 sp
-= sizeof(user_frame
.uf32
);
355 #if defined(__arm__) && (__BIGGEST_ALIGNMENT__ > 4)
356 sp
&= ~0xf; /* Make sure to align to 16 bytes for armv7k */
364 * Fill in ucontext (points to mcontext, i.e. thread states).
366 if (proc_is64bit_data(p
)) {
367 #if defined(__arm64__)
368 sendsig_fill_uctx64(&user_frame
.uf64
.uctx
, oonstack
, mask
, sp
, (user64_size_t
)stack_size
,
369 (user64_addr_t
)&((struct user_sigframe64
*)sp
)->mctx
);
371 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
374 sendsig_fill_uctx32(&user_frame
.uf32
.uctx
, oonstack
, mask
, sp
, (user32_size_t
)stack_size
,
375 (user32_addr_t
)&((struct user_sigframe32
*)sp
)->mctx
);
381 bzero((caddr_t
) &sinfo
, sizeof(sinfo
));
382 sinfo
.si_signo
= sig
;
384 if (proc_is64bit_data(p
)) {
385 #if defined(__arm64__)
386 sinfo
.si_addr
= ts
.ts64
.ss
.pc
;
387 sinfo
.pad
[0] = ts
.ts64
.ss
.sp
;
389 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
392 sinfo
.si_addr
= ts
.ts32
.ss
.pc
;
393 sinfo
.pad
[0] = ts
.ts32
.ss
.sp
;
399 if (mctx
.ss
.srr1
& (1 << (31 - SRR1_PRG_ILL_INS_BIT
))) {
400 sinfo
.si_code
= ILL_ILLOPC
;
401 } else if (mctx
.ss
.srr1
& (1 << (31 - SRR1_PRG_PRV_INS_BIT
))) {
402 sinfo
.si_code
= ILL_PRVOPC
;
403 } else if (mctx
.ss
.srr1
& (1 << (31 - SRR1_PRG_TRAP_BIT
))) {
404 sinfo
.si_code
= ILL_ILLTRP
;
406 sinfo
.si_code
= ILL_NOOP
;
409 sinfo
.si_code
= ILL_ILLTRP
;
414 switch (ut
->uu_code
) {
416 sinfo
.si_code
= FPE_FLTUND
;
419 sinfo
.si_code
= FPE_FLTOVF
;
422 sinfo
.si_code
= FPE_FLTINV
;
425 sinfo
.si_code
= FPE_FLTDIV
;
428 sinfo
.si_code
= FPE_FLTINV
;
431 sinfo
.si_code
= FPE_FLTRES
;
434 sinfo
.si_code
= FPE_NOOP
;
441 if (proc_is64bit_data(p
)) {
442 #if defined(__arm64__)
443 sinfo
.si_addr
= user_frame
.uf64
.mctx
.es
.far
;
445 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
448 sinfo
.si_addr
= user_frame
.uf32
.mctx
.es
.far
;
451 sinfo
.si_code
= BUS_ADRALN
;
455 if (proc_is64bit_data(p
)) {
456 #if defined(__arm64__)
457 sinfo
.si_addr
= user_frame
.uf64
.mctx
.es
.far
;
459 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
462 sinfo
.si_addr
= user_frame
.uf32
.mctx
.es
.far
;
466 /* First check in srr1 and then in dsisr */
467 if (mctx
.ss
.srr1
& (1 << (31 - DSISR_PROT_BIT
))) {
468 sinfo
.si_code
= SEGV_ACCERR
;
469 } else if (mctx
.es
.dsisr
& (1 << (31 - DSISR_PROT_BIT
))) {
470 sinfo
.si_code
= SEGV_ACCERR
;
472 sinfo
.si_code
= SEGV_MAPERR
;
475 sinfo
.si_code
= SEGV_ACCERR
;
481 int status_and_exitcode
;
484 * All other signals need to fill out a minimum set of
485 * information for the siginfo structure passed into
486 * the signal handler, if SA_SIGINFO was specified.
488 * p->si_status actually contains both the status and
489 * the exit code; we save it off in its own variable
490 * for later breakdown.
493 sinfo
.si_pid
= p
->si_pid
;
495 status_and_exitcode
= p
->si_status
;
497 sinfo
.si_uid
= p
->si_uid
;
499 sinfo
.si_code
= p
->si_code
;
502 if (sinfo
.si_code
== CLD_EXITED
) {
503 if (WIFEXITED(status_and_exitcode
)) {
504 sinfo
.si_code
= CLD_EXITED
;
505 } else if (WIFSIGNALED(status_and_exitcode
)) {
506 if (WCOREDUMP(status_and_exitcode
)) {
507 sinfo
.si_code
= CLD_DUMPED
;
508 status_and_exitcode
= W_EXITCODE(status_and_exitcode
, status_and_exitcode
);
510 sinfo
.si_code
= CLD_KILLED
;
511 status_and_exitcode
= W_EXITCODE(status_and_exitcode
, status_and_exitcode
);
516 * The recorded status contains the exit code and the
517 * signal information, but the information to be passed
518 * in the siginfo to the handler is supposed to only
519 * contain the status, so we have to shift it out.
521 sinfo
.si_status
= (WEXITSTATUS(status_and_exitcode
) & 0x00FFFFFF) | (((uint32_t)(p
->p_xhighbits
) << 24) & 0xFF000000);
528 sendsig_do_dtrace(ut
, &sinfo
, sig
, catcher
);
529 #endif /* CONFIG_DTRACE */
532 * Copy signal-handling frame out to user space, set thread state.
534 if (proc_is64bit_data(p
)) {
535 #if defined(__arm64__)
539 * mctx filled in when we get state. uctx filled in by
540 * sendsig_fill_uctx64(). We fill in the sinfo now.
542 siginfo_user_to_user64(&sinfo
, &user_frame
.uf64
.sinfo
);
544 p_uctx
= (user_addr_t
)&((struct user_sigframe64
*)sp
)->uctx
;
546 * Generate the validation token for sigreturn
549 kr
= machine_thread_siguctx_pointer_convert_to_user(th_act
, &token_uctx
);
550 assert(kr
== KERN_SUCCESS
);
551 token
= (user64_addr_t
)token_uctx
^ (user64_addr_t
)ps
->ps_sigreturn_token
;
553 if (copyout(&user_frame
.uf64
, sp
, sizeof(user_frame
.uf64
)) != 0) {
557 if (sendsig_set_thread_state64(&ts
.ts64
.ss
,
558 catcher
, infostyle
, sig
, (user64_addr_t
)&((struct user_sigframe64
*)sp
)->sinfo
,
559 (user64_addr_t
)p_uctx
, token
, trampact
, sp
, th_act
) != KERN_SUCCESS
) {
564 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
570 * mctx filled in when we get state. uctx filled in by
571 * sendsig_fill_uctx32(). We fill in the sinfo, *pointer*
572 * to uctx and token now.
574 siginfo_user_to_user32(&sinfo
, &user_frame
.uf32
.sinfo
);
576 p_uctx
= (user_addr_t
)&((struct user_sigframe32
*)sp
)->uctx
;
578 * Generate the validation token for sigreturn
580 token_uctx
= (user_addr_t
)p_uctx
;
581 kr
= machine_thread_siguctx_pointer_convert_to_user(th_act
, &token_uctx
);
582 assert(kr
== KERN_SUCCESS
);
583 token
= (user32_addr_t
)token_uctx
^ (user32_addr_t
)ps
->ps_sigreturn_token
;
585 user_frame
.uf32
.puctx
= (user32_addr_t
)p_uctx
;
586 user_frame
.uf32
.token
= token
;
588 if (copyout(&user_frame
.uf32
, sp
, sizeof(user_frame
.uf32
)) != 0) {
592 if (sendsig_set_thread_state32(&ts
.ts32
.ss
,
593 CAST_DOWN_EXPLICIT(user32_addr_t
, catcher
), infostyle
, sig
, (user32_addr_t
)&((struct user_sigframe32
*)sp
)->sinfo
,
594 CAST_DOWN_EXPLICIT(user32_addr_t
, trampact
), CAST_DOWN_EXPLICIT(user32_addr_t
, sp
), th_act
) != KERN_SUCCESS
) {
605 SIGACTION(p
, SIGILL
) = SIG_DFL
;
606 sig
= sigmask(SIGILL
);
607 p
->p_sigignore
&= ~sig
;
608 p
->p_sigcatch
&= ~sig
;
609 ut
->uu_sigmask
&= ~sig
;
610 /* sendsig is called with signal lock held */
612 psignal_locked(p
, SIGILL
);
617 * System call to cleanup state after a signal
618 * has been taken. Reset signal mask and
619 * stack state from context left by sendsig (above).
620 * Return to previous * context left by sendsig.
621 * Check carefully to * make sure that the user has not
622 * modified the * spr to gain improper priviledges.
626 sigreturn_copyin_ctx32(struct user_ucontext32
*uctx
, mcontext32_t
*mctx
, user_addr_t uctx_addr
)
630 assert(!proc_is64bit_data(current_proc()));
632 error
= copyin(uctx_addr
, uctx
, sizeof(*uctx
));
637 /* validate the machine context size */
638 switch (uctx
->uc_mcsize
) {
639 case UC_FLAVOR_SIZE32
:
645 assert(uctx
->uc_mcsize
== sizeof(*mctx
));
646 error
= copyin((user_addr_t
)uctx
->uc_mcontext
, mctx
, uctx
->uc_mcsize
);
655 sigreturn_set_state32(thread_t th_act
, mcontext32_t
*mctx
)
657 assert(!proc_is64bit_data(current_proc()));
659 /* validate the thread state, set/reset appropriate mode bits in cpsr */
661 mctx
->ss
.cpsr
= (mctx
->ss
.cpsr
& ~PSR_MODE_MASK
) | PSR_USERDFLT
;
662 #elif defined(__arm64__)
663 mctx
->ss
.cpsr
= (mctx
->ss
.cpsr
& ~PSR64_MODE_MASK
) | PSR64_USER32_DEFAULT
;
665 #error Unknown architecture.
668 if (thread_setstatus_from_user(th_act
, ARM_THREAD_STATE
, (void *)&mctx
->ss
, ARM_THREAD_STATE_COUNT
) != KERN_SUCCESS
) {
671 if (thread_setstatus_from_user(th_act
, ARM_VFP_STATE
, (void *)&mctx
->fs
, ARM_VFP_STATE_COUNT
) != KERN_SUCCESS
) {
678 #if defined(__arm64__)
680 sigreturn_copyin_ctx64(struct user_ucontext64
*uctx
, mcontext64_t
*mctx
, user_addr_t uctx_addr
)
684 assert(proc_is64bit_data(current_proc()));
686 error
= copyin(uctx_addr
, uctx
, sizeof(*uctx
));
691 /* validate the machine context size */
692 switch (uctx
->uc_mcsize
) {
693 case UC_FLAVOR_SIZE64
:
699 assert(uctx
->uc_mcsize
== sizeof(*mctx
));
700 error
= copyin((user_addr_t
)uctx
->uc_mcontext64
, mctx
, uctx
->uc_mcsize
);
709 sigreturn_set_state64(thread_t th_act
, mcontext64_t
*mctx
)
711 assert(proc_is64bit_data(current_proc()));
713 /* validate the thread state, set/reset appropriate mode bits in cpsr */
714 mctx
->ss
.cpsr
= (mctx
->ss
.cpsr
& ~PSR64_MODE_MASK
) | PSR64_USER64_DEFAULT
;
716 if (thread_setstatus_from_user(th_act
, ARM_THREAD_STATE64
, (void *)&mctx
->ss
, ARM_THREAD_STATE64_COUNT
) != KERN_SUCCESS
) {
719 if (thread_setstatus_from_user(th_act
, ARM_NEON_STATE64
, (void *)&mctx
->ns
, ARM_NEON_STATE64_COUNT
) != KERN_SUCCESS
) {
725 #endif /* defined(__arm64__) */
731 struct sigreturn_args
* uap
,
732 __unused
int *retval
)
735 user_ucontext32_t uc32
;
736 #if defined(__arm64__)
737 user_ucontext64_t uc64
;
743 #if defined(__arm64__)
748 struct sigacts
*ps
= p
->p_sigacts
;
749 int error
, sigmask
= 0, onstack
= 0;
752 uint32_t sigreturn_validation
;
753 user_addr_t token_uctx
;
756 th_act
= current_thread();
757 ut
= (struct uthread
*) get_bsdthread_info(th_act
);
759 /* see osfmk/kern/restartable.c */
760 act_set_ast_reset_pcs(th_act
);
762 if (proc_is64bit_data(p
)) {
763 #if defined(__arm64__)
764 error
= sigreturn_copyin_ctx64(&uctx
.uc64
, &mctx
.mc64
, uap
->uctx
);
769 onstack
= uctx
.uc64
.uc_onstack
;
770 sigmask
= uctx
.uc64
.uc_sigmask
;
772 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
775 error
= sigreturn_copyin_ctx32(&uctx
.uc32
, &mctx
.mc32
, uap
->uctx
);
780 onstack
= uctx
.uc32
.uc_onstack
;
781 sigmask
= uctx
.uc32
.uc_sigmask
;
784 if ((onstack
& 01)) {
785 p
->p_sigacts
->ps_sigstk
.ss_flags
|= SA_ONSTACK
;
787 p
->p_sigacts
->ps_sigstk
.ss_flags
&= ~SA_ONSTACK
;
790 ut
->uu_sigmask
= sigmask
& ~sigcantmask
;
791 if (ut
->uu_siglist
& ~ut
->uu_sigmask
) {
792 signal_setast(current_thread());
795 sigreturn_validation
= atomic_load_explicit(
796 &ps
->ps_sigreturn_validation
, memory_order_relaxed
);
797 token_uctx
= uap
->uctx
;
798 kr
= machine_thread_siguctx_pointer_convert_to_user(th_act
, &token_uctx
);
799 assert(kr
== KERN_SUCCESS
);
801 if (proc_is64bit_data(p
)) {
802 #if defined(__arm64__)
804 token
= (user64_addr_t
)token_uctx
^ (user64_addr_t
)ps
->ps_sigreturn_token
;
805 if ((user64_addr_t
)uap
->token
!= token
) {
806 #if DEVELOPMENT || DEBUG
807 printf("process %s[%d] sigreturn token mismatch: received 0x%llx expected 0x%llx\n",
808 p
->p_comm
, p
->p_pid
, (user64_addr_t
)uap
->token
, token
);
809 #endif /* DEVELOPMENT || DEBUG */
810 if (sigreturn_validation
!= PS_SIGRETURN_VALIDATION_DISABLED
) {
814 error
= sigreturn_set_state64(th_act
, &mctx
.mc64
);
816 #if DEVELOPMENT || DEBUG
817 printf("process %s[%d] sigreturn set_state64 error %d\n",
818 p
->p_comm
, p
->p_pid
, error
);
819 #endif /* DEVELOPMENT || DEBUG */
823 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
827 token
= (user32_addr_t
)token_uctx
^ (user32_addr_t
)ps
->ps_sigreturn_token
;
828 if ((user32_addr_t
)uap
->token
!= token
) {
829 #if DEVELOPMENT || DEBUG
830 printf("process %s[%d] sigreturn token mismatch: received 0x%x expected 0x%x\n",
831 p
->p_comm
, p
->p_pid
, (user32_addr_t
)uap
->token
, token
);
832 #endif /* DEVELOPMENT || DEBUG */
833 if (sigreturn_validation
!= PS_SIGRETURN_VALIDATION_DISABLED
) {
837 error
= sigreturn_set_state32(th_act
, &mctx
.mc32
);
839 #if DEVELOPMENT || DEBUG
840 printf("process %s[%d] sigreturn sigreturn_set_state32 error %d\n",
841 p
->p_comm
, p
->p_pid
, error
);
842 #endif /* DEVELOPMENT || DEBUG */
851 * machine_exception() performs machine-dependent translation
852 * of a mach exception to a unix signal.
855 machine_exception(int exception
,
856 __unused mach_exception_code_t code
,
857 __unused mach_exception_subcode_t subcode
)
860 case EXC_BAD_INSTRUCTION
: