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>
27 #include <pexpert/pexpert.h>
29 extern struct arm_saved_state
*get_user_regs(thread_t
);
30 extern user_addr_t
thread_get_cthread_self(void);
31 extern kern_return_t
thread_getstatus(thread_t act
, int flavor
,
32 thread_state_t tstate
, mach_msg_type_number_t
*count
);
33 extern kern_return_t
thread_getstatus_to_user(thread_t act
, int flavor
,
34 thread_state_t tstate
, mach_msg_type_number_t
*count
);
35 extern kern_return_t
machine_thread_state_convert_to_user(thread_t act
, int flavor
,
36 thread_state_t tstate
, mach_msg_type_number_t
*count
);
37 extern kern_return_t
thread_setstatus(thread_t thread
, int flavor
,
38 thread_state_t tstate
, mach_msg_type_number_t count
);
39 extern kern_return_t
thread_setstatus_from_user(thread_t thread
, int flavor
,
40 thread_state_t tstate
, mach_msg_type_number_t count
);
41 /* XXX Put these someplace smarter... */
42 typedef struct mcontext32 mcontext32_t
;
43 typedef struct mcontext64 mcontext64_t
;
45 /* Signal handler flavors supported */
46 /* These defns should match the Libc implmn */
50 /* The following are valid mcontext sizes */
51 #define UC_FLAVOR_SIZE32 ((ARM_THREAD_STATE_COUNT + ARM_EXCEPTION_STATE_COUNT + ARM_VFP_STATE_COUNT) * sizeof(int))
52 #define UC_FLAVOR_SIZE64 ((ARM_THREAD_STATE64_COUNT + ARM_EXCEPTION_STATE64_COUNT + ARM_NEON_STATE64_COUNT) * sizeof(int))
55 #define C_64_REDZONE_LEN 128
59 sendsig_get_state32(thread_t th_act
, arm_thread_state_t
*ts
, mcontext32_t
*mcp
)
62 mach_msg_type_number_t state_count
;
64 assert(!proc_is64bit_data(current_proc()));
67 state_count
= ARM_THREAD_STATE_COUNT
;
68 if (thread_getstatus(th_act
, ARM_THREAD_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
72 tstate
= (void *) &mcp
->ss
;
73 state_count
= ARM_THREAD_STATE_COUNT
;
74 if (machine_thread_state_convert_to_user(th_act
, ARM_THREAD_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
77 tstate
= (void *) &mcp
->es
;
78 state_count
= ARM_EXCEPTION_STATE_COUNT
;
79 if (thread_getstatus(th_act
, ARM_EXCEPTION_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
82 tstate
= (void *) &mcp
->fs
;
83 state_count
= ARM_VFP_STATE_COUNT
;
84 if (thread_getstatus_to_user(th_act
, ARM_VFP_STATE
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
90 #if defined(__arm64__)
91 struct user_sigframe64
{
92 /* We can pass the last two args in registers for ARM64 */
93 user64_siginfo_t sinfo
;
94 struct user_ucontext64 uctx
;
99 sendsig_get_state64(thread_t th_act
, arm_thread_state64_t
*ts
, mcontext64_t
*mcp
)
102 mach_msg_type_number_t state_count
;
104 assert(proc_is64bit_data(current_proc()));
106 tstate
= (void *) ts
;
107 state_count
= ARM_THREAD_STATE64_COUNT
;
108 if (thread_getstatus(th_act
, ARM_THREAD_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
112 tstate
= (void *) &mcp
->ss
;
113 state_count
= ARM_THREAD_STATE64_COUNT
;
114 if (machine_thread_state_convert_to_user(th_act
, ARM_THREAD_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
117 tstate
= (void *) &mcp
->es
;
118 state_count
= ARM_EXCEPTION_STATE64_COUNT
;
119 if (thread_getstatus(th_act
, ARM_EXCEPTION_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
122 tstate
= (void *) &mcp
->ns
;
123 state_count
= ARM_NEON_STATE64_COUNT
;
124 if (thread_getstatus_to_user(th_act
, ARM_NEON_STATE64
, (thread_state_t
) tstate
, &state_count
) != KERN_SUCCESS
)
131 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
)
133 bzero(uctx
, sizeof(*uctx
));
134 uctx
->uc_onstack
= oonstack
;
135 uctx
->uc_sigmask
= mask
;
136 uctx
->uc_stack
.ss_sp
= sp
;
137 uctx
->uc_stack
.ss_size
= stack_size
;
139 uctx
->uc_stack
.ss_flags
|= SS_ONSTACK
;
140 uctx
->uc_link
= (user64_addr_t
)0;
141 uctx
->uc_mcsize
= (user64_size_t
) UC_FLAVOR_SIZE64
;
142 uctx
->uc_mcontext64
= (user64_addr_t
) p_mctx
;
146 sendsig_set_thread_state64(arm_thread_state64_t
*regs
,
147 user64_addr_t catcher
, int infostyle
, int sig
, user64_addr_t p_sinfo
,
148 user64_addr_t p_uctx
, user64_addr_t token
, user64_addr_t trampact
, user64_addr_t sp
, thread_t th_act
)
150 assert(proc_is64bit_data(current_proc()));
152 regs
->x
[0] = catcher
;
153 regs
->x
[1] = infostyle
;
155 regs
->x
[3] = p_sinfo
;
159 regs
->cpsr
= PSR64_USER64_DEFAULT
;
162 return thread_setstatus(th_act
, ARM_THREAD_STATE64
, (void *)regs
, ARM_THREAD_STATE64_COUNT
);
164 #endif /* defined(__arm64__) */
167 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
)
169 bzero(uctx
, sizeof(*uctx
));
170 uctx
->uc_onstack
= oonstack
;
171 uctx
->uc_sigmask
= mask
;
172 uctx
->uc_stack
.ss_sp
= (user32_addr_t
) sp
;
173 uctx
->uc_stack
.ss_size
= (user32_size_t
) stack_size
;
175 uctx
->uc_stack
.ss_flags
|= SS_ONSTACK
;
176 uctx
->uc_link
= (user32_addr_t
)0;
177 uctx
->uc_mcsize
= (user32_size_t
) UC_FLAVOR_SIZE32
;
178 uctx
->uc_mcontext
= (user32_addr_t
) p_mctx
;
182 sendsig_set_thread_state32(arm_thread_state_t
*regs
,
183 user32_addr_t catcher
, int infostyle
, int sig
, user32_addr_t p_sinfo
,
184 user32_addr_t trampact
, user32_addr_t sp
, thread_t th_act
)
187 assert(!proc_is64bit_data(current_proc()));
189 regs
->r
[0] = catcher
;
190 regs
->r
[1] = infostyle
;
192 regs
->r
[3] = p_sinfo
;
194 regs
->pc
= trampact
& ~1;
195 #if defined(__arm64__)
196 regs
->cpsr
= PSR64_USER32_DEFAULT
| PSR64_MODE_USER32_THUMB
;
197 #elif defined(__arm__)
198 regs
->cpsr
= PSR_USERDFLT
| PSR_TF
;
200 #error Unknown architeture.
204 regs
->cpsr
= PSR_USERDFLT
;
208 return thread_setstatus(th_act
, ARM_THREAD_STATE
, (void *)regs
, ARM_THREAD_STATE_COUNT
);
213 sendsig_do_dtrace(uthread_t ut
, user_siginfo_t
*sinfo
, int sig
, user_addr_t catcher
)
215 bzero((caddr_t
)&(ut
->t_dtrace_siginfo
), sizeof(ut
->t_dtrace_siginfo
));
217 ut
->t_dtrace_siginfo
.si_signo
= sinfo
->si_signo
;
218 ut
->t_dtrace_siginfo
.si_code
= sinfo
->si_code
;
219 ut
->t_dtrace_siginfo
.si_pid
= sinfo
->si_pid
;
220 ut
->t_dtrace_siginfo
.si_uid
= sinfo
->si_uid
;
221 ut
->t_dtrace_siginfo
.si_status
= sinfo
->si_status
;
222 /* XXX truncates faulting address to void * */
223 ut
->t_dtrace_siginfo
.si_addr
= CAST_DOWN_EXPLICIT(void *, sinfo
->si_addr
);
225 /* Fire DTrace proc:::fault probe when signal is generated by hardware. */
227 case SIGILL
: case SIGBUS
: case SIGSEGV
: case SIGFPE
: case SIGTRAP
:
228 DTRACE_PROC2(fault
, int, (int)(ut
->uu_code
), siginfo_t
*, &(ut
->t_dtrace_siginfo
));
234 /* XXX truncates faulting address to uintptr_t */
235 DTRACE_PROC3(signal__handle
, int, sig
, siginfo_t
*, &(ut
->t_dtrace_siginfo
),
236 void (*)(void), CAST_DOWN(sig_t
, catcher
));
240 struct user_sigframe32
{
243 user32_siginfo_t sinfo
;
244 struct user_ucontext32 uctx
;
249 * Send an interrupt to process.
258 __unused
uint32_t code
263 arm_thread_state_t ss
;
265 #if defined(__arm64__)
267 arm_thread_state64_t ss
;
272 struct user_sigframe32 uf32
;
273 #if defined(__arm64__)
274 struct user_sigframe64 uf64
;
278 user_siginfo_t sinfo
;
279 user_addr_t sp
= 0, trampact
;
280 struct sigacts
*ps
= p
->p_sigacts
;
281 int oonstack
, infostyle
;
284 user_size_t stack_size
= 0;
285 user_addr_t p_uctx
, token_uctx
;
288 th_act
= current_thread();
289 ut
= get_bsdthread_info(th_act
);
291 bzero(&ts
, sizeof(ts
));
292 bzero(&user_frame
, sizeof(user_frame
));
294 if (p
->p_sigacts
->ps_siginfo
& sigmask(sig
))
295 infostyle
= UC_FLAVOR
;
299 trampact
= ps
->ps_trampact
[sig
];
300 oonstack
= ps
->ps_sigstk
.ss_flags
& SA_ONSTACK
;
303 * Get sundry thread state.
305 if (proc_is64bit_data(p
)) {
307 if (sendsig_get_state64(th_act
, &ts
.ts64
.ss
, &user_frame
.uf64
.mctx
) != 0) {
311 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
314 if (sendsig_get_state32(th_act
, &ts
.ts32
.ss
, &user_frame
.uf32
.mctx
) != 0) {
320 * Figure out where our new stack lives.
322 if ((ps
->ps_flags
& SAS_ALTSTACK
) && !oonstack
&&
323 (ps
->ps_sigonstack
& sigmask(sig
))) {
324 sp
= ps
->ps_sigstk
.ss_sp
;
325 sp
+= ps
->ps_sigstk
.ss_size
;
326 stack_size
= ps
->ps_sigstk
.ss_size
;
327 ps
->ps_sigstk
.ss_flags
|= SA_ONSTACK
;
330 * Get stack pointer, and allocate enough space
331 * for signal handler data.
333 if (proc_is64bit_data(p
)) {
334 #if defined(__arm64__)
335 sp
= CAST_USER_ADDR_T(ts
.ts64
.ss
.sp
);
336 sp
= (sp
- sizeof(user_frame
.uf64
) - C_64_REDZONE_LEN
) & ~0xf; /* Make sure to align to 16 bytes and respect red zone */
338 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
341 sp
= CAST_USER_ADDR_T(ts
.ts32
.ss
.sp
);
342 sp
-= sizeof(user_frame
.uf32
);
343 #if defined(__arm__) && (__BIGGEST_ALIGNMENT__ > 4)
344 sp
&= ~0xf; /* Make sure to align to 16 bytes for armv7k */
352 * Fill in ucontext (points to mcontext, i.e. thread states).
354 if (proc_is64bit_data(p
)) {
355 #if defined(__arm64__)
356 sendsig_fill_uctx64(&user_frame
.uf64
.uctx
, oonstack
, mask
, sp
, (user64_size_t
)stack_size
,
357 (user64_addr_t
)&((struct user_sigframe64
*)sp
)->mctx
);
359 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
362 sendsig_fill_uctx32(&user_frame
.uf32
.uctx
, oonstack
, mask
, sp
, (user32_size_t
)stack_size
,
363 (user32_addr_t
)&((struct user_sigframe32
*)sp
)->mctx
);
369 bzero((caddr_t
) & sinfo
, sizeof(sinfo
));
370 sinfo
.si_signo
= sig
;
372 if (proc_is64bit_data(p
)) {
373 #if defined(__arm64__)
374 sinfo
.si_addr
= ts
.ts64
.ss
.pc
;
375 sinfo
.pad
[0] = ts
.ts64
.ss
.sp
;
377 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
380 sinfo
.si_addr
= ts
.ts32
.ss
.pc
;
381 sinfo
.pad
[0] = ts
.ts32
.ss
.sp
;
387 if (mctx
.ss
.srr1
& (1 << (31 - SRR1_PRG_ILL_INS_BIT
)))
388 sinfo
.si_code
= ILL_ILLOPC
;
389 else if (mctx
.ss
.srr1
& (1 << (31 - SRR1_PRG_PRV_INS_BIT
)))
390 sinfo
.si_code
= ILL_PRVOPC
;
391 else if (mctx
.ss
.srr1
& (1 << (31 - SRR1_PRG_TRAP_BIT
)))
392 sinfo
.si_code
= ILL_ILLTRP
;
394 sinfo
.si_code
= ILL_NOOP
;
396 sinfo
.si_code
= ILL_ILLTRP
;
404 if (proc_is64bit_data(p
)) {
405 #if defined(__arm64__)
406 sinfo
.si_addr
= user_frame
.uf64
.mctx
.es
.far
;
408 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
411 sinfo
.si_addr
= user_frame
.uf32
.mctx
.es
.far
;
414 sinfo
.si_code
= BUS_ADRALN
;
418 if (proc_is64bit_data(p
)) {
419 #if defined(__arm64__)
420 sinfo
.si_addr
= user_frame
.uf64
.mctx
.es
.far
;
422 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
425 sinfo
.si_addr
= user_frame
.uf32
.mctx
.es
.far
;
429 /* First check in srr1 and then in dsisr */
430 if (mctx
.ss
.srr1
& (1 << (31 - DSISR_PROT_BIT
)))
431 sinfo
.si_code
= SEGV_ACCERR
;
432 else if (mctx
.es
.dsisr
& (1 << (31 - DSISR_PROT_BIT
)))
433 sinfo
.si_code
= SEGV_ACCERR
;
435 sinfo
.si_code
= SEGV_MAPERR
;
437 sinfo
.si_code
= SEGV_ACCERR
;
443 int status_and_exitcode
;
446 * All other signals need to fill out a minimum set of
447 * information for the siginfo structure passed into
448 * the signal handler, if SA_SIGINFO was specified.
450 * p->si_status actually contains both the status and
451 * the exit code; we save it off in its own variable
452 * for later breakdown.
455 sinfo
.si_pid
= p
->si_pid
;
457 status_and_exitcode
= p
->si_status
;
459 sinfo
.si_uid
= p
->si_uid
;
461 sinfo
.si_code
= p
->si_code
;
464 if (sinfo
.si_code
== CLD_EXITED
) {
465 if (WIFEXITED(status_and_exitcode
))
466 sinfo
.si_code
= CLD_EXITED
;
467 else if (WIFSIGNALED(status_and_exitcode
)) {
468 if (WCOREDUMP(status_and_exitcode
)) {
469 sinfo
.si_code
= CLD_DUMPED
;
470 status_and_exitcode
= W_EXITCODE(status_and_exitcode
,status_and_exitcode
);
472 sinfo
.si_code
= CLD_KILLED
;
473 status_and_exitcode
= W_EXITCODE(status_and_exitcode
,status_and_exitcode
);
478 * The recorded status contains the exit code and the
479 * signal information, but the information to be passed
480 * in the siginfo to the handler is supposed to only
481 * contain the status, so we have to shift it out.
483 sinfo
.si_status
= (WEXITSTATUS(status_and_exitcode
) & 0x00FFFFFF) | (((uint32_t)(p
->p_xhighbits
) << 24) & 0xFF000000);
490 sendsig_do_dtrace(ut
, &sinfo
, sig
, catcher
);
491 #endif /* CONFIG_DTRACE */
494 * Copy signal-handling frame out to user space, set thread state.
496 if (proc_is64bit_data(p
)) {
497 #if defined(__arm64__)
501 * mctx filled in when we get state. uctx filled in by
502 * sendsig_fill_uctx64(). We fill in the sinfo now.
504 siginfo_user_to_user64(&sinfo
, &user_frame
.uf64
.sinfo
);
506 p_uctx
= (user_addr_t
)&((struct user_sigframe64
*)sp
)->uctx
;
508 * Generate the validation token for sigreturn
511 kr
= machine_thread_siguctx_pointer_convert_to_user(th_act
, &token_uctx
);
512 assert(kr
== KERN_SUCCESS
);
513 token
= (user64_addr_t
)token_uctx
^ (user64_addr_t
)ps
->ps_sigreturn_token
;
515 if (copyout(&user_frame
.uf64
, sp
, sizeof(user_frame
.uf64
)) != 0) {
519 if (sendsig_set_thread_state64(&ts
.ts64
.ss
,
520 catcher
, infostyle
, sig
, (user64_addr_t
)&((struct user_sigframe64
*)sp
)->sinfo
,
521 (user64_addr_t
)p_uctx
, token
, trampact
, sp
, th_act
) != KERN_SUCCESS
)
525 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
531 * mctx filled in when we get state. uctx filled in by
532 * sendsig_fill_uctx32(). We fill in the sinfo, *pointer*
533 * to uctx and token now.
535 siginfo_user_to_user32(&sinfo
, &user_frame
.uf32
.sinfo
);
537 p_uctx
= (user_addr_t
)&((struct user_sigframe32
*)sp
)->uctx
;
539 * Generate the validation token for sigreturn
541 token_uctx
= (user_addr_t
)p_uctx
;
542 kr
= machine_thread_siguctx_pointer_convert_to_user(th_act
, &token_uctx
);
543 assert(kr
== KERN_SUCCESS
);
544 token
= (user32_addr_t
)token_uctx
^ (user32_addr_t
)ps
->ps_sigreturn_token
;
546 user_frame
.uf32
.puctx
= (user32_addr_t
)p_uctx
;
547 user_frame
.uf32
.token
= token
;
549 if (copyout(&user_frame
.uf32
, sp
, sizeof(user_frame
.uf32
)) != 0) {
553 if (sendsig_set_thread_state32(&ts
.ts32
.ss
,
554 CAST_DOWN_EXPLICIT(user32_addr_t
, catcher
), infostyle
, sig
, (user32_addr_t
)&((struct user_sigframe32
*)sp
)->sinfo
,
555 CAST_DOWN_EXPLICIT(user32_addr_t
, trampact
), CAST_DOWN_EXPLICIT(user32_addr_t
, sp
), th_act
) != KERN_SUCCESS
)
565 SIGACTION(p
, SIGILL
) = SIG_DFL
;
566 sig
= sigmask(SIGILL
);
567 p
->p_sigignore
&= ~sig
;
568 p
->p_sigcatch
&= ~sig
;
569 ut
->uu_sigmask
&= ~sig
;
570 /* sendsig is called with signal lock held */
572 psignal_locked(p
, SIGILL
);
577 * System call to cleanup state after a signal
578 * has been taken. Reset signal mask and
579 * stack state from context left by sendsig (above).
580 * Return to previous * context left by sendsig.
581 * Check carefully to * make sure that the user has not
582 * modified the * spr to gain improper priviledges.
586 sigreturn_copyin_ctx32(struct user_ucontext32
*uctx
, mcontext32_t
*mctx
, user_addr_t uctx_addr
)
590 assert(!proc_is64bit_data(current_proc()));
592 error
= copyin(uctx_addr
, uctx
, sizeof(*uctx
));
597 /* validate the machine context size */
598 switch (uctx
->uc_mcsize
) {
599 case UC_FLAVOR_SIZE32
:
605 assert(uctx
->uc_mcsize
== sizeof(*mctx
));
606 error
= copyin((user_addr_t
)uctx
->uc_mcontext
, mctx
, uctx
->uc_mcsize
);
615 sigreturn_set_state32(thread_t th_act
, mcontext32_t
*mctx
)
617 assert(!proc_is64bit_data(current_proc()));
619 /* validate the thread state, set/reset appropriate mode bits in cpsr */
621 mctx
->ss
.cpsr
= (mctx
->ss
.cpsr
& ~PSR_MODE_MASK
) | PSR_USERDFLT
;
622 #elif defined(__arm64__)
623 mctx
->ss
.cpsr
= (mctx
->ss
.cpsr
& ~PSR64_MODE_MASK
) | PSR64_USER32_DEFAULT
;
625 #error Unknown architecture.
628 if (thread_setstatus_from_user(th_act
, ARM_THREAD_STATE
, (void *)&mctx
->ss
, ARM_THREAD_STATE_COUNT
) != KERN_SUCCESS
) {
631 if (thread_setstatus_from_user(th_act
, ARM_VFP_STATE
, (void *)&mctx
->fs
, ARM_VFP_STATE_COUNT
) != KERN_SUCCESS
) {
638 #if defined(__arm64__)
640 sigreturn_copyin_ctx64(struct user_ucontext64
*uctx
, mcontext64_t
*mctx
, user_addr_t uctx_addr
)
644 assert(proc_is64bit_data(current_proc()));
646 error
= copyin(uctx_addr
, uctx
, sizeof(*uctx
));
651 /* validate the machine context size */
652 switch (uctx
->uc_mcsize
) {
653 case UC_FLAVOR_SIZE64
:
659 assert(uctx
->uc_mcsize
== sizeof(*mctx
));
660 error
= copyin((user_addr_t
)uctx
->uc_mcontext64
, mctx
, uctx
->uc_mcsize
);
669 sigreturn_set_state64(thread_t th_act
, mcontext64_t
*mctx
)
671 assert(proc_is64bit_data(current_proc()));
673 /* validate the thread state, set/reset appropriate mode bits in cpsr */
674 mctx
->ss
.cpsr
= (mctx
->ss
.cpsr
& ~PSR64_MODE_MASK
) | PSR64_USER64_DEFAULT
;
676 if (thread_setstatus_from_user(th_act
, ARM_THREAD_STATE64
, (void *)&mctx
->ss
, ARM_THREAD_STATE64_COUNT
) != KERN_SUCCESS
) {
679 if (thread_setstatus_from_user(th_act
, ARM_NEON_STATE64
, (void *)&mctx
->ns
, ARM_NEON_STATE64_COUNT
) != KERN_SUCCESS
) {
685 #endif /* defined(__arm64__) */
691 struct sigreturn_args
* uap
,
692 __unused
int *retval
)
695 user_ucontext32_t uc32
;
696 #if defined(__arm64__)
697 user_ucontext64_t uc64
;
703 #if defined(__arm64__)
708 struct sigacts
*ps
= p
->p_sigacts
;
709 int error
, sigmask
= 0, onstack
= 0;
712 uint32_t sigreturn_validation
;
713 user_addr_t token_uctx
;
716 th_act
= current_thread();
717 ut
= (struct uthread
*) get_bsdthread_info(th_act
);
719 if (proc_is64bit_data(p
)) {
720 #if defined(__arm64__)
721 error
= sigreturn_copyin_ctx64(&uctx
.uc64
, &mctx
.mc64
, uap
->uctx
);
726 onstack
= uctx
.uc64
.uc_onstack
;
727 sigmask
= uctx
.uc64
.uc_sigmask
;
729 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
732 error
= sigreturn_copyin_ctx32(&uctx
.uc32
, &mctx
.mc32
, uap
->uctx
);
737 onstack
= uctx
.uc32
.uc_onstack
;
738 sigmask
= uctx
.uc32
.uc_sigmask
;
742 p
->p_sigacts
->ps_sigstk
.ss_flags
|= SA_ONSTACK
;
744 p
->p_sigacts
->ps_sigstk
.ss_flags
&= ~SA_ONSTACK
;
746 ut
->uu_sigmask
= sigmask
& ~sigcantmask
;
747 if (ut
->uu_siglist
& ~ut
->uu_sigmask
)
748 signal_setast(current_thread());
750 sigreturn_validation
= atomic_load_explicit(
751 &ps
->ps_sigreturn_validation
, memory_order_relaxed
);
752 token_uctx
= uap
->uctx
;
753 kr
= machine_thread_siguctx_pointer_convert_to_user(th_act
, &token_uctx
);
754 assert(kr
== KERN_SUCCESS
);
756 if (proc_is64bit_data(p
)) {
757 #if defined(__arm64__)
759 token
= (user64_addr_t
)token_uctx
^ (user64_addr_t
)ps
->ps_sigreturn_token
;
760 if ((user64_addr_t
)uap
->token
!= token
) {
761 #if DEVELOPMENT || DEBUG
762 printf("process %s[%d] sigreturn token mismatch: received 0x%llx expected 0x%llx\n",
763 p
->p_comm
, p
->p_pid
, (user64_addr_t
)uap
->token
, token
);
764 #endif /* DEVELOPMENT || DEBUG */
765 if (sigreturn_validation
!= PS_SIGRETURN_VALIDATION_DISABLED
) {
769 error
= sigreturn_set_state64(th_act
, &mctx
.mc64
);
771 #if DEVELOPMENT || DEBUG
772 printf("process %s[%d] sigreturn set_state64 error %d\n",
773 p
->p_comm
, p
->p_pid
, error
);
774 #endif /* DEVELOPMENT || DEBUG */
778 panic("Shouldn't have 64-bit thread states on a 32-bit kernel.");
782 token
= (user32_addr_t
)token_uctx
^ (user32_addr_t
)ps
->ps_sigreturn_token
;
783 if ((user32_addr_t
)uap
->token
!= token
) {
784 #if DEVELOPMENT || DEBUG
785 printf("process %s[%d] sigreturn token mismatch: received 0x%x expected 0x%x\n",
786 p
->p_comm
, p
->p_pid
, (user32_addr_t
)uap
->token
, token
);
787 #endif /* DEVELOPMENT || DEBUG */
788 if (sigreturn_validation
!= PS_SIGRETURN_VALIDATION_DISABLED
) {
792 error
= sigreturn_set_state32(th_act
, &mctx
.mc32
);
794 #if DEVELOPMENT || DEBUG
795 printf("process %s[%d] sigreturn sigreturn_set_state32 error %d\n",
796 p
->p_comm
, p
->p_pid
, error
);
797 #endif /* DEVELOPMENT || DEBUG */
802 return (EJUSTRETURN
);
806 * machine_exception() performs machine-dependent translation
807 * of a mach exception to a unix signal.
810 machine_exception(int exception
,
811 __unused mach_exception_code_t code
,
812 __unused mach_exception_subcode_t subcode
)
815 case EXC_BAD_INSTRUCTION
: