]> git.saurik.com Git - apple/xnu.git/blame - bsd/dev/i386/unix_signal.c
xnu-792.22.5.tar.gz
[apple/xnu.git] / bsd / dev / i386 / unix_signal.c
CommitLineData
1c79356b 1/*
4452a7af 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
5d5c5d0d 3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
8f6c56a5
A
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
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/*
29 * Copyright (c) 1992 NeXT, Inc.
30 *
31 * HISTORY
32 * 13 May 1992 ? at NeXT
33 * Created.
34 */
35
36#include <mach/mach_types.h>
37#include <mach/exception.h>
38
39#include <kern/thread.h>
1c79356b 40
91447636 41#include <sys/systm.h>
1c79356b 42#include <sys/param.h>
91447636 43#include <sys/proc_internal.h>
1c79356b 44#include <sys/user.h>
91447636
A
45#include <sys/sysproto.h>
46#include <sys/sysent.h>
4452a7af
A
47#include <sys/ucontext.h>
48#include <sys/wait.h>
91447636 49#include <mach/thread_act.h> /* for thread_abort_safely */
4452a7af
A
50#include <mach/thread_status.h>
51#include <i386/machine_routines.h>
1c79356b 52
4452a7af 53#include <i386/eflags.h>
1c79356b 54#include <i386/psl.h>
91447636 55#include <i386/seg.h>
1c79356b 56
4452a7af 57#include <sys/kdebug.h>
1c79356b 58
91447636
A
59/* Forward: */
60extern boolean_t machine_exception(int, int, int, int *, int *);
4452a7af
A
61extern kern_return_t thread_getstatus(register thread_t act, int flavor,
62 thread_state_t tstate, mach_msg_type_number_t *count);
63extern kern_return_t thread_setstatus(thread_t thread, int flavor,
64 thread_state_t tstate, mach_msg_type_number_t count);
1c79356b 65
55e303ae
A
66/* Signal handler flavors supported */
67/* These defns should match the Libc implmn */
68#define UC_TRAD 1
4452a7af
A
69#define UC_FLAVOR 30
70
71#define C_32_STK_ALIGN 16
72#define C_64_STK_ALIGN 16
73#define C_64_REDZONE_LEN 128
74#define TRUNC_DOWN32(a,c) ((((uint32_t)a)-(c)) & ((uint32_t)(-(c))))
75#define TRUNC_DOWN64(a,c) ((((uint64_t)a)-(c)) & ((uint64_t)(-(c))))
55e303ae 76
1c79356b
A
77/*
78 * Send an interrupt to process.
79 *
80 * Stack is set up to allow sigcode stored
81 * in u. to call routine, followed by chmk
82 * to sigreturn routine below. After sigreturn
83 * resets the signal mask, the stack, the frame
84 * pointer, and the argument pointer, it returns
85 * to the user specified pc, psl.
86 */
4452a7af
A
87struct sigframe32 {
88 int retaddr;
89 sig_t catcher;
90 int sigstyle;
91 int sig;
92 siginfo_t * sinfo;
93 struct ucontext * uctx;
94};
95
96
97
1c79356b 98void
4452a7af 99sendsig(struct proc *p, user_addr_t ua_catcher, int sig, int mask, __unused u_long code)
1c79356b 100{
4452a7af
A
101 union {
102 struct mcontext32 mctx32;
103 struct mcontext64 mctx64;
104 } mctx;
105 user_addr_t ua_sp;
106 user_addr_t ua_fp;
107 user_addr_t ua_cr2;
108 user_addr_t ua_sip;
109 user_addr_t ua_uctxp;
110 user_addr_t ua_mctxp;
111 user_siginfo_t sinfo64;
112
1c79356b 113 struct sigacts *ps = p->p_sigacts;
4452a7af
A
114 int oonstack, flavor;
115 void * state;
116 mach_msg_type_number_t state_count;
117 int uthsigaltstack = 0;
118 int altstack = 0;
119
9bccf70c 120 thread_t thread = current_thread();
9bccf70c 121 struct uthread * ut;
4452a7af
A
122 int stack_size = 0;
123 int infostyle = UC_TRAD;
1c79356b 124
4452a7af
A
125 if (p->p_sigacts->ps_siginfo & sigmask(sig))
126 infostyle = UC_FLAVOR;
127
91447636 128 ut = get_bsdthread_info(thread);
1c79356b 129
4452a7af 130 uthsigaltstack = p->p_lflag & P_LTHSIGSTACK;
1c79356b 131
4452a7af
A
132 if (uthsigaltstack != 0 ) {
133 oonstack = ut->uu_sigstk.ss_flags & SA_ONSTACK;
134 altstack = ut->uu_flag & UT_ALTSTACK;
135 } else {
136 oonstack = ps->ps_sigstk.ss_flags & SA_ONSTACK;
137 altstack = ps->ps_flags & SAS_ALTSTACK;
138 }
9bccf70c 139 /*
4452a7af 140 * init siginfo
9bccf70c 141 */
4452a7af
A
142 bzero((caddr_t)&sinfo64, sizeof(user_siginfo_t));
143 sinfo64.si_signo = sig;
144
145 if (proc_is64bit(p)) {
146 x86_thread_state64_t *tstate64;
147 struct user_ucontext64 uctx64;
148
149 flavor = x86_THREAD_STATE64;
150 state_count = x86_THREAD_STATE64_COUNT;
151 state = (void *)&mctx.mctx64.ss;
152 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
153 goto bad;
154
155 flavor = x86_FLOAT_STATE64;
156 state_count = x86_FLOAT_STATE64_COUNT;
157 state = (void *)&mctx.mctx64.fs;
158 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
159 goto bad;
160
161 flavor = x86_EXCEPTION_STATE64;
162 state_count = x86_EXCEPTION_STATE64_COUNT;
163 state = (void *)&mctx.mctx64.es;
164 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
165 goto bad;
166
167 tstate64 = &mctx.mctx64.ss;
168
169 if (altstack && !oonstack && (ps->ps_sigonstack & sigmask(sig))) {
170 if (uthsigaltstack != 0) {
171 ua_sp = ut->uu_sigstk.ss_sp;
172 stack_size = ut->uu_sigstk.ss_size;
173 ua_sp += stack_size;
174 ut->uu_sigstk.ss_flags |= SA_ONSTACK;
175 } else {
176 ua_sp = ps->ps_sigstk.ss_sp;
177 stack_size = ps->ps_sigstk.ss_size;
178 ua_sp += stack_size;
179 ps->ps_sigstk.ss_flags |= SA_ONSTACK;
180 }
181 } else
182 ua_sp = tstate64->rsp;
183 ua_cr2 = mctx.mctx64.es.faultvaddr;
184
185 /* The x86_64 ABI defines a 128-byte red zone. */
186 ua_sp -= C_64_REDZONE_LEN;
187
188 ua_sp -= sizeof (struct user_ucontext64);
189 ua_uctxp = ua_sp; // someone tramples the first word!
190
191 ua_sp -= sizeof (user_siginfo_t);
192 ua_sip = ua_sp;
193
194 ua_sp -= sizeof (struct mcontext64);
195 ua_mctxp = ua_sp;
196
197 /*
198 * Align the frame and stack pointers to 16 bytes for SSE.
199 * (Note that we use 'ua_fp' as the base of the stack going forward)
200 */
201 ua_fp = TRUNC_DOWN64(ua_sp, C_64_STK_ALIGN);
202
203 /*
204 * But we need to account for the return address so the alignment is
205 * truly "correct" at _sigtramp
206 */
207 ua_fp -= sizeof(user_addr_t);
208
209 /*
210 * Build the signal context to be used by sigreturn.
211 */
212 bzero(&uctx64, sizeof(uctx64));
213
214 uctx64.uc_onstack = oonstack;
215 uctx64.uc_sigmask = mask;
216 uctx64.uc_stack.ss_sp = ua_fp;
217 uctx64.uc_stack.ss_size = stack_size;
218
219 if (oonstack)
220 uctx64.uc_stack.ss_flags |= SS_ONSTACK;
221 uctx64.uc_link = 0;
222
223 uctx64.uc_mcsize = sizeof(struct mcontext64);
224 uctx64.uc_mcontext64 = ua_mctxp;
225
226 if (copyout((caddr_t)&uctx64, ua_uctxp, sizeof (uctx64)))
227 goto bad;
228
229 if (copyout((caddr_t)&mctx.mctx64, ua_mctxp, sizeof (struct mcontext64)))
230 goto bad;
231
232 sinfo64.pad[0] = tstate64->rsp;
233 sinfo64.si_addr = tstate64->rip;
234
235 tstate64->rip = ps->ps_trampact[sig];
236 tstate64->rsp = ua_fp;
237 tstate64->rflags = get_eflags_exportmask();
238 /*
239 * JOE - might not need to set these
240 */
241 tstate64->cs = USER64_CS;
242 tstate64->fs = NULL_SEG;
243 tstate64->gs = USER_CTHREAD;
244
245 /*
246 * Build the argument list for the signal handler.
247 * Handler should call sigreturn to get out of it
248 */
249 tstate64->rdi = ua_catcher;
250 tstate64->rsi = infostyle;
251 tstate64->rdx = sig;
252 tstate64->rcx = ua_sip;
253 tstate64->r8 = ua_uctxp;
254
9bccf70c 255 } else {
4452a7af
A
256 x86_thread_state32_t *tstate32;
257 struct ucontext uctx32;
258 struct sigframe32 frame32;
259
260 flavor = x86_THREAD_STATE32;
261 state_count = x86_THREAD_STATE32_COUNT;
262 state = (void *)&mctx.mctx32.ss;
263 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
264 goto bad;
265
266 flavor = x86_FLOAT_STATE32;
267 state_count = x86_FLOAT_STATE32_COUNT;
268 state = (void *)&mctx.mctx32.fs;
269 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
270 goto bad;
271
272 flavor = x86_EXCEPTION_STATE32;
273 state_count = x86_EXCEPTION_STATE32_COUNT;
274 state = (void *)&mctx.mctx32.es;
275 if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
276 goto bad;
277
278 tstate32 = &mctx.mctx32.ss;
279
280 if (altstack && !oonstack && (ps->ps_sigonstack & sigmask(sig))) {
281 if (uthsigaltstack != 0) {
282 ua_sp = ut->uu_sigstk.ss_sp;
283 stack_size = ut->uu_sigstk.ss_size;
284 ua_sp += stack_size;
285 ut->uu_sigstk.ss_flags |= SA_ONSTACK;
286 } else {
287 ua_sp = ps->ps_sigstk.ss_sp;
288 stack_size = ps->ps_sigstk.ss_size;
289 ua_sp += stack_size;
290 ps->ps_sigstk.ss_flags |= SA_ONSTACK;
291 }
292 } else
293 ua_sp = tstate32->esp;
294 ua_cr2 = mctx.mctx32.es.faultvaddr;
295
296 ua_sp -= sizeof (struct ucontext);
297 ua_uctxp = ua_sp; // someone tramples the first word!
298
299 ua_sp -= sizeof (siginfo_t);
300 ua_sip = ua_sp;
301
302 ua_sp -= sizeof (struct mcontext32);
303 ua_mctxp = ua_sp;
304
305 ua_sp -= sizeof (struct sigframe32);
306 ua_fp = ua_sp;
307
308 /*
309 * Align the frame and stack pointers to 16 bytes for SSE.
310 * (Note that we use 'fp' as the base of the stack going forward)
311 */
312 ua_fp = TRUNC_DOWN32(ua_fp, C_32_STK_ALIGN);
313
314 /*
315 * But we need to account for the return address so the alignment is
316 * truly "correct" at _sigtramp
317 */
318 ua_fp -= sizeof(frame32.retaddr);
319
320 /*
321 * Build the argument list for the signal handler.
322 * Handler should call sigreturn to get out of it
323 */
324 frame32.retaddr = -1;
325 frame32.sigstyle = infostyle;
326 frame32.sig = sig;
327 frame32.catcher = CAST_DOWN(sig_t, ua_catcher);
328 frame32.sinfo = CAST_DOWN(siginfo_t *, ua_sip);
329 frame32.uctx = CAST_DOWN(struct ucontext *, ua_uctxp);
330
331 if (copyout((caddr_t)&frame32, ua_fp, sizeof (frame32)))
332 goto bad;
333
334 /*
335 * Build the signal context to be used by sigreturn.
336 */
337 bzero(&uctx32, sizeof(uctx32));
338
339 uctx32.uc_onstack = oonstack;
340 uctx32.uc_sigmask = mask;
341 uctx32.uc_stack.ss_sp = CAST_DOWN(char *, ua_fp);
342 uctx32.uc_stack.ss_size = stack_size;
343
344 if (oonstack)
345 uctx32.uc_stack.ss_flags |= SS_ONSTACK;
346 uctx32.uc_link = 0;
347
348 uctx32.uc_mcsize = sizeof(struct mcontext32);
349
350 uctx32.uc_mcontext = CAST_DOWN(struct mcontext *, ua_mctxp);
351
352 if (copyout((caddr_t)&uctx32, ua_uctxp, sizeof (uctx32)))
353 goto bad;
354
355 if (copyout((caddr_t)&mctx.mctx32, ua_mctxp, sizeof (struct mcontext32)))
356 goto bad;
357
358 sinfo64.pad[0] = tstate32->esp;
359 sinfo64.si_addr = tstate32->eip;
9bccf70c 360 }
9bccf70c 361
4452a7af
A
362 switch (sig) {
363 case SIGCHLD:
364 sinfo64.si_pid = p->si_pid;
365 p->si_pid =0;
366 sinfo64.si_status = p->si_status;
367 p->si_status = 0;
368 sinfo64.si_uid = p->si_uid;
369 p->si_uid =0;
370 sinfo64.si_code = p->si_code;
371 p->si_code = 0;
372 if (sinfo64.si_code == CLD_EXITED) {
373 if (WIFEXITED(sinfo64.si_status))
374 sinfo64.si_code = CLD_EXITED;
375 else if (WIFSIGNALED(sinfo64.si_status)) {
376 if (WCOREDUMP(sinfo64.si_status))
377 sinfo64.si_code = CLD_DUMPED;
378 else
379 sinfo64.si_code = CLD_KILLED;
380 }
381 }
382 break;
383 case SIGILL:
384 switch (ut->uu_code) {
385 case EXC_I386_INVOP:
386 sinfo64.si_code = ILL_ILLOPC;
387 break;
388 case EXC_I386_GPFLT:
389 sinfo64.si_code = ILL_PRVOPC;
390 break;
391 default:
392 printf("unknown SIGILL code %d\n", ut->uu_code);
393 sinfo64.si_code = ILL_NOOP;
394 }
395 break;
396 case SIGFPE:
397#define FP_IE 0 /* Invalid operation */
398#define FP_DE 1 /* Denormalized operand */
399#define FP_ZE 2 /* Zero divide */
400#define FP_OE 3 /* overflow */
401#define FP_UE 4 /* underflow */
402#define FP_PE 5 /* precision */
403 if (ut->uu_subcode & (1 << FP_ZE)) {
404 sinfo64.si_code = FPE_FLTDIV;
405 } else if (ut->uu_subcode & (1 << FP_OE)) {
406 sinfo64.si_code = FPE_FLTOVF;
407 } else if (ut->uu_subcode & (1 << FP_UE)) {
408 sinfo64.si_code = FPE_FLTUND;
409 } else if (ut->uu_subcode & (1 << FP_PE)) {
410 sinfo64.si_code = FPE_FLTRES;
411 } else if (ut->uu_subcode & (1 << FP_IE)) {
412 sinfo64.si_code = FPE_FLTINV;
413 } else {
414 printf("unknown SIGFPE code %d, subcode %x\n",
415 ut->uu_code, ut->uu_subcode);
416 sinfo64.si_code = FPE_NOOP;
417 }
418 break;
419 case SIGBUS:
420 sinfo64.si_code = BUS_ADRERR;
421 sinfo64.si_addr = ua_cr2;
422 break;
423 case SIGTRAP:
424 sinfo64.si_code = TRAP_BRKPT;
425 break;
426 case SIGSEGV:
427 sinfo64.si_addr = ua_cr2;
428
429 switch (ut->uu_code) {
430 case KERN_PROTECTION_FAILURE:
431 sinfo64.si_code = SEGV_ACCERR;
432 break;
433 case KERN_INVALID_ADDRESS:
434 sinfo64.si_code = SEGV_MAPERR;
435 break;
436 default:
437 printf("unknown SIGSEGV code %d\n", ut->uu_code);
438 sinfo64.si_code = FPE_NOOP;
439 }
440 break;
441 default:
442 break;
443 }
444 if (proc_is64bit(p)) {
445 if (copyout((caddr_t)&sinfo64, ua_sip, sizeof (sinfo64)))
446 goto bad;
9bccf70c 447
4452a7af
A
448 flavor = x86_THREAD_STATE64;
449 state_count = x86_THREAD_STATE64_COUNT;
450 state = (void *)&mctx.mctx64.ss;
451 } else {
452 x86_thread_state32_t *tstate32;
453 siginfo_t sinfo32;
454
455 bzero((caddr_t)&sinfo32, sizeof(siginfo_t));
456
457 sinfo32.si_signo = sinfo64.si_signo;
458 sinfo32.si_code = sinfo64.si_code;
459 sinfo32.si_pid = sinfo64.si_pid;
460 sinfo32.si_uid = sinfo64.si_uid;
461 sinfo32.si_status = sinfo64.si_status;
462 sinfo32.si_addr = CAST_DOWN(void *, sinfo64.si_addr);
463 sinfo32.pad[0] = sinfo64.pad[0];
464
465 if (copyout((caddr_t)&sinfo32, ua_sip, sizeof (sinfo32)))
466 goto bad;
467
468 tstate32 = &mctx.mctx32.ss;
469 tstate32->eip = CAST_DOWN(unsigned int, ps->ps_trampact[sig]);
470 tstate32->esp = CAST_DOWN(unsigned int, ua_fp);
471
472 tstate32->eflags = get_eflags_exportmask();
473
474 tstate32->cs = USER_CS;
475 tstate32->ss = USER_DS;
476 tstate32->ds = USER_DS;
477 tstate32->es = USER_DS;
478 tstate32->fs = NULL_SEG;
479 tstate32->gs = USER_CTHREAD;
480
481 flavor = x86_THREAD_STATE32;
482 state_count = x86_THREAD_STATE32_COUNT;
483 state = (void *)tstate32;
484 }
485 if (thread_setstatus(thread, flavor, (thread_state_t)state, state_count) != KERN_SUCCESS)
486 goto bad;
487 ml_fp_setvalid(FALSE);
9bccf70c 488
9bccf70c 489 return;
1c79356b
A
490
491bad:
492 SIGACTION(p, SIGILL) = SIG_DFL;
493 sig = sigmask(SIGILL);
494 p->p_sigignore &= ~sig;
495 p->p_sigcatch &= ~sig;
9bccf70c 496 ut->uu_sigmask &= ~sig;
1c79356b 497 /* sendsig is called with signal lock held */
9bccf70c 498 psignal_lock(p, SIGILL, 0);
1c79356b
A
499 return;
500}
501
502/*
503 * System call to cleanup state after a signal
504 * has been taken. Reset signal mask and
505 * stack state from context left by sendsig (above).
506 * Return to previous pc and psl as specified by
507 * context left by sendsig. Check carefully to
508 * make sure that the user has not modified the
509 * psl to gain improper priviledges or to cause
510 * a machine fault.
511 */
4452a7af 512
1c79356b 513int
91447636
A
514sigreturn(
515 struct proc *p,
516 struct sigreturn_args *uap,
517 __unused int *retval)
1c79356b 518{
4452a7af
A
519 union {
520 struct mcontext32 mctx32;
521 struct mcontext64 mctx64;
522 } mctx;
523 thread_t thread = current_thread();
9bccf70c 524 struct uthread * ut;
4452a7af
A
525 int error;
526 int uthsigaltstack = 0;
527 int onstack = 0;
c0fea474 528
4452a7af
A
529 mach_msg_type_number_t ts_count;
530 unsigned int ts_flavor;
531 void * ts;
532 mach_msg_type_number_t fs_count;
533 unsigned int fs_flavor;
534 void * fs;
5d5c5d0d 535
4452a7af
A
536 ut = (struct uthread *)get_bsdthread_info(thread);
537 uthsigaltstack = p->p_lflag & P_LTHSIGSTACK;
89b3af67 538
4452a7af
A
539 if (proc_is64bit(p)) {
540 struct user_ucontext64 uctx64;
89b3af67 541
4452a7af
A
542 if ((error = copyin(uap->uctx, (void *)&uctx64, sizeof (uctx64))))
543 return(error);
89b3af67 544
4452a7af
A
545 if ((error = copyin(uctx64.uc_mcontext64, (void *)&mctx.mctx64, sizeof (struct mcontext64))))
546 return(error);
89b3af67 547
4452a7af
A
548 onstack = uctx64.uc_onstack & 01;
549 ut->uu_sigmask = uctx64.uc_sigmask & ~sigcantmask;
5d5c5d0d 550
4452a7af
A
551 ts_flavor = x86_THREAD_STATE64;
552 ts_count = x86_THREAD_STATE64_COUNT;
553 ts = (void *)&mctx.mctx64.ss;
554
555 fs_flavor = x86_FLOAT_STATE64;
556 fs_count = x86_FLOAT_STATE64_COUNT;
557 fs = (void *)&mctx.mctx64.fs;
558
559 } else {
560 struct ucontext uctx32;
561
562 if ((error = copyin(uap->uctx, (void *)&uctx32, sizeof (uctx32))))
563 return(error);
564
565 if ((error = copyin(CAST_USER_ADDR_T(uctx32.uc_mcontext), (void *)&mctx.mctx32, sizeof (struct mcontext32))))
566 return(error);
567
568 onstack = uctx32.uc_onstack & 01;
569 ut->uu_sigmask = uctx32.uc_sigmask & ~sigcantmask;
89b3af67 570
4452a7af
A
571 ts_flavor = x86_THREAD_STATE32;
572 ts_count = x86_THREAD_STATE32_COUNT;
573 ts = (void *)&mctx.mctx32.ss;
574
575 fs_flavor = x86_FLOAT_STATE32;
576 fs_count = x86_FLOAT_STATE32_COUNT;
577 fs = (void *)&mctx.mctx32.fs;
91447636 578 }
4452a7af
A
579 if (onstack) {
580 if (uthsigaltstack != 0)
581 ut->uu_sigstk.ss_flags |= SA_ONSTACK;
582 else
583 p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
584 } else {
585 if (uthsigaltstack != 0)
586 ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;
587 else
588 p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
91447636 589 }
4452a7af
A
590 if (ut->uu_siglist & ~ut->uu_sigmask)
591 signal_setast(thread);
592
593 /*
594 * thread_set_state() does all the needed checks for the passed in content
595 */
596 if (thread_setstatus(thread, ts_flavor, ts, ts_count) != KERN_SUCCESS)
597 return(EINVAL);
598
599 ml_fp_setvalid(TRUE);
600
601 if (thread_setstatus(thread, fs_flavor, fs, fs_count) != KERN_SUCCESS)
602 return(EINVAL);
1c79356b
A
603
604 return (EJUSTRETURN);
605}
606
4452a7af 607
1c79356b
A
608/*
609 * machine_exception() performs MD translation
610 * of a mach exception to a unix signal and code.
611 */
612
613boolean_t
614machine_exception(
91447636
A
615 int exception,
616 int code,
617 __unused int subcode,
618 int *unix_signal,
619 int *unix_code
1c79356b
A
620)
621{
622
623 switch(exception) {
624
625 case EXC_BAD_INSTRUCTION:
626 *unix_signal = SIGILL;
627 *unix_code = code;
628 break;
629
630 case EXC_ARITHMETIC:
631 *unix_signal = SIGFPE;
632 *unix_code = code;
633 break;
634
635 default:
636 return(FALSE);
637 }
638
639 return(TRUE);
640}
91447636
A
641
642#include <sys/systm.h>
643#include <sys/sysent.h>
644
645int __pthread_cset(struct sysent *);
646void __pthread_creset(struct sysent *);
647
648int
649__pthread_cset(struct sysent *callp)
650{
651 unsigned int cancel_enable;
652 thread_t thread;
653 struct uthread * uthread;
654
655 thread = current_thread();
656 uthread = get_bsdthread_info(thread);
657
658 cancel_enable = callp->sy_cancel;
659 if (cancel_enable == _SYSCALL_CANCEL_NONE) {
660 uthread->uu_flag |= UT_NOTCANCELPT;
661 } else {
662 if((uthread->uu_flag & (UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) {
663 if (cancel_enable == _SYSCALL_CANCEL_PRE)
664 return(EINTR);
665 else
666 thread_abort_safely(thread);
667 }
668 }
669 return(0);
670}
671
672
673void
674__pthread_creset(struct sysent *callp)
675{
676
677 unsigned int cancel_enable;
678 thread_t thread;
679 struct uthread * uthread;
680
681 thread = current_thread();
682 uthread = get_bsdthread_info(thread);
683
684 cancel_enable = callp->sy_cancel;
685 if (!cancel_enable)
686 uthread->uu_flag &= ~UT_NOTCANCELPT;
687
688}
689