]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/ppc/unix_signal.c
xnu-1699.22.73.tar.gz
[apple/xnu.git] / bsd / dev / ppc / unix_signal.c
diff --git a/bsd/dev/ppc/unix_signal.c b/bsd/dev/ppc/unix_signal.c
deleted file mode 100644 (file)
index 4ca48b0..0000000
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- * 
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-/* 
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- */
-
-#include <mach/mach_types.h>
-#include <mach/exception_types.h>
-
-#include <sys/param.h>
-#include <sys/proc_internal.h>
-#include <sys/user.h>
-#include <sys/ucontext.h>
-#include <sys/sysproto.h>
-#include <sys/systm.h>
-#include <sys/ux_exception.h>
-
-#include <ppc/signal.h>
-#include <sys/signalvar.h>
-#include <sys/kdebug.h>
-#include <sys/wait.h>
-#include <kern/thread.h>
-#include <mach/ppc/thread_status.h>
-#include <ppc/proc_reg.h>
-
-#include <sys/sdt.h>
-
-// #include <machine/thread.h> XXX include path messed up for some reason...
-
-/* XXX functions not in a Mach headers */
-extern kern_return_t thread_getstatus(register thread_t act, int flavor,
-                       thread_state_t tstate, mach_msg_type_number_t *count);
-extern unsigned int get_msr_exportmask(void);
-extern kern_return_t thread_setstatus(thread_t thread, int flavor,
-                       thread_state_t tstate, mach_msg_type_number_t count);
-extern void ppc_checkthreadstate(void *, int);
-extern struct savearea_vec *find_user_vec_curr(void);
-extern int thread_enable_fpe(thread_t act, int onoff);
-
-
-
-#define        C_32_REDZONE_LEN        224
-#define        C_32_STK_ALIGN          16
-#define C_32_PARAMSAVE_LEN     64
-#define        C_32_LINKAGE_LEN        48
-
-#define        C_64_REDZONE_LEN        320
-#define        C_64_STK_ALIGN          32
-#define        C_64_PARAMSAVE_LEN      64
-#define        C_64_LINKAGE_LEN        48
-
-#define TRUNC_DOWN32(a,b,c)    ((((uint32_t)a)-(b)) & ((uint32_t)(-(c))))
-#define TRUNC_DOWN64(a,b,c)    ((((uint64_t)a)-(b)) & ((uint64_t)(-(c))))
-
-/*
- * The stack layout possibilities (info style); This needs to mach with signal trampoline code
- *
- * Traditional:                        1
- * Traditional64:              20
- * Traditional64with vec:      25
- * 32bit context               30
- * 32bit context with vector   35
- * 64bit context               40
- * 64bit context with vector   45
- * Dual context                        50
- * Dual context with vector    55
- *
- */
-#define UC_TRAD                        1
-#define UC_TRAD_VEC            6
-#define UC_TRAD64              20
-#define UC_TRAD64_VEC          25
-#define UC_FLAVOR              30
-#define UC_FLAVOR_VEC          35
-#define UC_FLAVOR64            40
-#define UC_FLAVOR64_VEC                45
-#define UC_DUAL                        50
-#define UC_DUAL_VEC            55
-#define        UC_SET_ALT_STACK        0x40000000
-#define UC_RESET_ALT_STACK     0x80000000
-
- /* The following are valid mcontext sizes */
-#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
-
-#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
-
-#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
-
-#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
-
-
-/*
- * NOTE: Source and target may *NOT* overlap!
- */
-static void
-ucontext_32to64(struct ucontext64 *in, struct user_ucontext64 *out)
-{
-       out->uc_onstack         = in->uc_onstack;
-       out->uc_sigmask         = in->uc_sigmask;
-
-       /* internal "structure assign" */
-       out->uc_stack.ss_sp     = CAST_USER_ADDR_T(in->uc_stack.ss_sp);
-       out->uc_stack.ss_size   = in->uc_stack.ss_size;
-       out->uc_stack.ss_flags  = in->uc_stack.ss_flags;
-
-       out->uc_link            = CAST_USER_ADDR_T(in->uc_link);
-       out->uc_mcsize          = in->uc_mcsize;
-       out->uc_mcontext64      = CAST_USER_ADDR_T(in->uc_mcontext64);
-}
-
-/*
- * This conversion is safe, since if we are converting for a 32 bit process,
- * then it's values of uc-stack.ss_size and uc_mcsize will never exceed 4G.
- *
- * NOTE: Source and target may *NOT* overlap!
- */
-static void
-ucontext_64to32(struct user_ucontext64 *in, struct ucontext64 *out)
-{
-       out->uc_onstack         = in->uc_onstack;
-       out->uc_sigmask         = in->uc_sigmask;
-
-       /* internal "structure assign" */
-       out->uc_stack.ss_sp     = CAST_DOWN(void *,in->uc_stack.ss_sp);
-       out->uc_stack.ss_size   = in->uc_stack.ss_size; /* range reduction */
-       out->uc_stack.ss_flags  = in->uc_stack.ss_flags;
-
-       out->uc_link            = CAST_DOWN(void *,in->uc_link);
-       out->uc_mcsize          = in->uc_mcsize;        /* range reduction */
-       out->uc_mcontext64      = CAST_DOWN(void *,in->uc_mcontext64);
-}
-
-/*
- * NOTE: Source and target may *NOT* overlap!
- */
-static void
-siginfo_user_to_user32(user_siginfo_t *in, user32_siginfo_t *out)
-{
-       out->si_signo   = in->si_signo;
-       out->si_errno   = in->si_errno;
-       out->si_code    = in->si_code;
-       out->si_pid     = in->si_pid;
-       out->si_uid     = in->si_uid;
-       out->si_status  = in->si_status;
-       out->si_addr    = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_addr);
-       /* following cast works for sival_int because of padding */
-       out->si_value.sival_ptr = CAST_DOWN_EXPLICIT(user32_addr_t,in->si_value.sival_ptr);
-       out->si_band    = in->si_band;                  /* range reduction */
-       out->__pad[0]   = in->pad[0];                   /* mcontext.ss.r1 */
-}
-
-static void
-siginfo_user_to_user64(user_siginfo_t *in, user64_siginfo_t *out)
-{
-       out->si_signo   = in->si_signo;
-       out->si_errno   = in->si_errno;
-       out->si_code    = in->si_code;
-       out->si_pid     = in->si_pid;
-       out->si_uid     = in->si_uid;
-       out->si_status  = in->si_status;
-       out->si_addr    = in->si_addr;
-       out->si_value.sival_ptr = in->si_value.sival_ptr;
-       out->si_band    = in->si_band;                  /* range reduction */
-       out->__pad[0]   = in->pad[0];                   /* mcontext.ss.r1 */
-}
-
-
-/*
- * Arrange for this process to run a signal handler
- */
-
-void
-sendsig(struct proc *p, user_addr_t catcher, int sig, int mask, __unused uint32_t code)
-{
-       kern_return_t kretn;
-       struct mcontext mctx;
-       user_addr_t p_mctx = USER_ADDR_NULL;            /* mcontext dest. */
-       struct mcontext64 mctx64;
-       user_addr_t p_mctx64 = USER_ADDR_NULL;          /* mcontext dest. */
-       struct user_ucontext64 uctx;
-       user_addr_t p_uctx;             /* user stack addr top copy ucontext */
-       user_siginfo_t sinfo;
-       user_addr_t p_sinfo;            /* user stack addr top copy siginfo */
-       struct sigacts *ps = p->p_sigacts;
-       int oonstack;
-       user_addr_t sp;
-       mach_msg_type_number_t state_count;
-       thread_t th_act;
-       struct uthread *ut;
-       int infostyle = UC_TRAD;
-       int dualcontext =0;
-       user_addr_t trampact;
-       int vec_used = 0;
-       int stack_size = 0;
-       void * tstate;
-       int flavor;
-        int ctx32 = 1;
-
-       th_act = current_thread();
-       ut = get_bsdthread_info(th_act);
-
-       /*
-        * XXX We conditionalize type passed here based on SA_SIGINFO, but
-        * XXX we always send up all the information, regardless; perhaps
-        * XXX this should not be conditionalized?  Defer making this change
-        * XXX now, due to possible tools impact.
-        */
-       if (p->p_sigacts->ps_siginfo & sigmask(sig)) {
-               /*
-                * If SA_SIGINFO is set, then we must provide the user
-                * process both a siginfo_t and a context argument.  We call
-                * this "FLAVORED", as opposed to "TRADITIONAL", which doesn't
-                * expect a context.  "DUAL" is a type of "FLAVORED".
-                */
-               if (is_64signalregset()) {
-                       /*
-                        * If this is a 64 bit CPU, we must include a 64 bit
-                        * context in the data we pass to user space; we may
-                        * or may not also include a 32 bit context at the
-                        * same time, for non-leaf functions.
-                        *
-                        * The user may also explicitly choose to not receive
-                        * a 32 bit context, at their option; we only allow
-                        * this to happen on 64 bit processors, for obvious
-                        * reasons.
-                        */
-                       if (IS_64BIT_PROCESS(p) ||
-                           (p->p_sigacts->ps_64regset & sigmask(sig))) {
-                                /*
-                                 * For a 64 bit process, there is no 32 bit
-                                 * context.
-                                 */
-                               ctx32 = 0;
-                               infostyle = UC_FLAVOR64;
-                       } else {
-                               /*
-                                * For a 32 bit process on a 64 bit CPU, we
-                                * may have 64 bit leaf functions, so we need
-                                * both contexts.
-                                */
-                               dualcontext = 1;
-                               infostyle = UC_DUAL;
-                       }
-               } else {
-                       /*
-                        * If this is a 32 bit CPU, then we only have a 32 bit
-                        * context to contend with.
-                        */
-                       infostyle = UC_FLAVOR;
-               }
-        } else {
-               /*
-                * If SA_SIGINFO is not set, then we have a traditional style
-                * call which does not need additional context passed.  The
-                * default is 32 bit traditional.
-                *
-                * XXX The second check is redundant on PPC32; keep it anyway.
-                */
-               if (is_64signalregset() || IS_64BIT_PROCESS(p)) {
-                       /*
-                        * However, if this is a 64 bit CPU, we need to change
-                        * this to 64 bit traditional, and drop the 32 bit
-                        * context.
-                        */
-                       ctx32 = 0;
-                       infostyle = UC_TRAD64;
-               }
-       }
-
-       proc_unlock(p);
-
-       /* I need this for SIGINFO anyway */
-       flavor = PPC_THREAD_STATE;
-       tstate = (void *)&mctx.ss;
-       state_count = PPC_THREAD_STATE_COUNT;
-       if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-               goto bad;
-
-       if ((ctx32 == 0) || dualcontext) {
-               flavor = PPC_THREAD_STATE64;
-               tstate = (void *)&mctx64.ss;
-               state_count = PPC_THREAD_STATE64_COUNT;
-                if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                    goto bad;
-       }
-
-        if ((ctx32 == 1) || dualcontext) {
-                flavor = PPC_EXCEPTION_STATE;
-               tstate = (void *)&mctx.es;
-               state_count = PPC_EXCEPTION_STATE_COUNT;
-                if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                    goto bad;
-       } 
-       
-       if ((ctx32 == 0) || dualcontext) {
-               flavor = PPC_EXCEPTION_STATE64;
-               tstate = (void *)&mctx64.es;
-               state_count = PPC_EXCEPTION_STATE64_COUNT;
-       
-                if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                    goto bad;
-                
-        }
-       
-
-        if ((ctx32 == 1) || dualcontext) {
-                flavor = PPC_FLOAT_STATE;
-               tstate = (void *)&mctx.fs;
-               state_count = PPC_FLOAT_STATE_COUNT;
-                if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                    goto bad;
-       } 
-       
-       if ((ctx32 == 0) || dualcontext) {
-               flavor = PPC_FLOAT_STATE;
-               tstate = (void *)&mctx64.fs;
-               state_count = PPC_FLOAT_STATE_COUNT;
-                       if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                    goto bad;
-                
-        }
-
-
-       if (find_user_vec_curr()) {
-               vec_used = 1;
-
-                if ((ctx32 == 1) || dualcontext) {
-                    flavor = PPC_VECTOR_STATE;
-                    tstate = (void *)&mctx.vs;
-                    state_count = PPC_VECTOR_STATE_COUNT;
-                    if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                    goto bad;
-                    infostyle += 5;
-            } 
-       
-            if ((ctx32 == 0) || dualcontext) {
-                    flavor = PPC_VECTOR_STATE;
-                    tstate = (void *)&mctx64.vs;
-                    state_count = PPC_VECTOR_STATE_COUNT;
-                    if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
-                        goto bad;
-                    infostyle += 5;
-           }
-       }  
-
-       trampact = ps->ps_trampact[sig];
-       oonstack = ut->uu_sigstk.ss_flags & SA_ONSTACK;
-
-       /* figure out where our new stack lives */
-       if ((ut->uu_flag & UT_ALTSTACK) && !oonstack &&
-               (ps->ps_sigonstack & sigmask(sig))) {
-               sp = ut->uu_sigstk.ss_sp;
-               sp += ut->uu_sigstk.ss_size;
-               stack_size = ut->uu_sigstk.ss_size;
-               ut->uu_sigstk.ss_flags |= SA_ONSTACK;
-       }
-       else {
-               if (ctx32 == 0)
-                       sp = mctx64.ss.r1;
-               else
-                       sp = CAST_USER_ADDR_T(mctx.ss.r1);
-       }
-
-       
-       /* put siginfo on top */
-        
-       /* preserve RED ZONE area */
-       if (IS_64BIT_PROCESS(p))
-               sp = TRUNC_DOWN64(sp, C_64_REDZONE_LEN, C_64_STK_ALIGN);
-       else
-               sp = TRUNC_DOWN32(sp, C_32_REDZONE_LEN, C_32_STK_ALIGN);
-
-        /* next are the saved registers */
-        if ((ctx32 == 0) || dualcontext) {
-            sp -= sizeof(struct mcontext64);
-            p_mctx64 = sp;
-        }
-        if ((ctx32 == 1) || dualcontext) {
-            sp -= sizeof(struct mcontext);
-            p_mctx = sp;
-        }    
-        
-       if (IS_64BIT_PROCESS(p)) {
-               /* context goes first on stack */
-               sp -= sizeof(struct user_ucontext64);
-               p_uctx = sp;
-
-               /* this is where siginfo goes on stack */
-               sp -= sizeof(user64_siginfo_t);
-               p_sinfo = sp;
-               
-               sp = TRUNC_DOWN64(sp, C_64_PARAMSAVE_LEN+C_64_LINKAGE_LEN, C_64_STK_ALIGN);
-       } else {
-               /*
-                * struct ucontext and struct ucontext64 are identical in
-                * size and content; the only difference is the internal
-                * pointer type for the last element, which makes no
-                * difference for the copyout().
-                */
-
-               /* context goes first on stack */
-               sp -= sizeof(struct ucontext64);
-               p_uctx = sp;
-
-               /* this is where siginfo goes on stack */
-               sp -= sizeof(user32_siginfo_t);
-               p_sinfo = sp;
-
-               sp = TRUNC_DOWN32(sp, C_32_PARAMSAVE_LEN+C_32_LINKAGE_LEN, C_32_STK_ALIGN);
-       }
-
-       uctx.uc_onstack = oonstack;
-       uctx.uc_sigmask = mask;
-       uctx.uc_stack.ss_sp = sp;
-       uctx.uc_stack.ss_size = stack_size;
-       if (oonstack)
-               uctx.uc_stack.ss_flags |= SS_ONSTACK;
-               
-       uctx.uc_link = 0;
-       if (ctx32 == 0)
-               uctx.uc_mcsize = (size_t)((PPC_EXCEPTION_STATE64_COUNT + PPC_THREAD_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int));
-       else
-               uctx.uc_mcsize = (size_t)((PPC_EXCEPTION_STATE_COUNT + PPC_THREAD_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int));
-       
-       if (vec_used) 
-               uctx.uc_mcsize += (size_t)(PPC_VECTOR_STATE_COUNT * sizeof(int));
-        
-       if (ctx32 == 0)
-             uctx.uc_mcontext64 = p_mctx64;
-       else
-            uctx.uc_mcontext64 = p_mctx;
-
-       /* setup siginfo */
-       bzero((caddr_t)&sinfo, sizeof(sinfo));
-       sinfo.si_signo = sig;
-       if (ctx32 == 0) {
-               sinfo.si_addr = mctx64.ss.srr0;
-               sinfo.pad[0] = mctx64.ss.r1;
-       } else {
-               sinfo.si_addr = CAST_USER_ADDR_T(mctx.ss.srr0);
-               sinfo.pad[0] = CAST_USER_ADDR_T(mctx.ss.r1);
-       }
-
-       switch (sig) {
-               case SIGILL:
-                       /*
-                        * If it's 64 bit and not a dual context, mctx will
-                        * contain uninitialized data, so we have to use
-                        * mctx64 here.
-                        */
-                       if(ctx32 == 0) {
-                               if (mctx64.ss.srr1 & (1 << (31 - SRR1_PRG_ILL_INS_BIT)))
-                                       sinfo.si_code = ILL_ILLOPC;
-                               else if (mctx64.ss.srr1 & (1 << (31 - SRR1_PRG_PRV_INS_BIT)))
-                                       sinfo.si_code = ILL_PRVOPC;
-                               else if (mctx64.ss.srr1 & (1 << (31 - SRR1_PRG_TRAP_BIT)))
-                                       sinfo.si_code = ILL_ILLTRP;
-                               else
-                                       sinfo.si_code = ILL_NOOP;
-                       } else {
-                               if (mctx.ss.srr1 & (1 << (31 - SRR1_PRG_ILL_INS_BIT)))
-                                       sinfo.si_code = ILL_ILLOPC;
-                               else if (mctx.ss.srr1 & (1 << (31 - SRR1_PRG_PRV_INS_BIT)))
-                                       sinfo.si_code = ILL_PRVOPC;
-                               else if (mctx.ss.srr1 & (1 << (31 - SRR1_PRG_TRAP_BIT)))
-                                       sinfo.si_code = ILL_ILLTRP;
-                               else
-                                       sinfo.si_code = ILL_NOOP;
-                       }
-                       break;
-               case SIGFPE:
-#define FPSCR_VX       2
-#define FPSCR_OX       3
-#define FPSCR_UX       4
-#define FPSCR_ZX       5
-#define FPSCR_XX       6
-                       /*
-                        * If it's 64 bit and not a dual context, mctx will
-                        * contain uninitialized data, so we have to use
-                        * mctx64 here.
-                        */
-                       if(ctx32 == 0) {
-                               if (mctx64.fs.fpscr & (1 << (31 - FPSCR_VX)))
-                                       sinfo.si_code = FPE_FLTINV;
-                               else if (mctx64.fs.fpscr & (1 << (31 - FPSCR_OX)))
-                                       sinfo.si_code = FPE_FLTOVF;
-                               else if (mctx64.fs.fpscr & (1 << (31 - FPSCR_UX)))
-                                       sinfo.si_code = FPE_FLTUND;
-                               else if (mctx64.fs.fpscr & (1 << (31 - FPSCR_ZX)))
-                                       sinfo.si_code = FPE_FLTDIV;
-                               else if (mctx64.fs.fpscr & (1 << (31 - FPSCR_XX)))
-                                       sinfo.si_code = FPE_FLTRES;
-                               else
-                                       sinfo.si_code = FPE_NOOP;
-                       } else {
-                               if (mctx.fs.fpscr & (1 << (31 - FPSCR_VX)))
-                                       sinfo.si_code = FPE_FLTINV;
-                               else if (mctx.fs.fpscr & (1 << (31 - FPSCR_OX)))
-                                       sinfo.si_code = FPE_FLTOVF;
-                               else if (mctx.fs.fpscr & (1 << (31 - FPSCR_UX)))
-                                       sinfo.si_code = FPE_FLTUND;
-                               else if (mctx.fs.fpscr & (1 << (31 - FPSCR_ZX)))
-                                       sinfo.si_code = FPE_FLTDIV;
-                               else if (mctx.fs.fpscr & (1 << (31 - FPSCR_XX)))
-                                       sinfo.si_code = FPE_FLTRES;
-                               else
-                                       sinfo.si_code = FPE_NOOP;
-                       }
-                       break;
-
-               case SIGBUS:
-                       if (ctx32 == 0) {
-                               sinfo.si_addr = mctx64.es.dar;
-                       } else {
-                               sinfo.si_addr = CAST_USER_ADDR_T(mctx.es.dar);
-                       }
-                       /* on ppc we generate only if EXC_PPC_UNALIGNED */
-                       sinfo.si_code = BUS_ADRALN;
-                       break;
-
-               case SIGSEGV:
-                       /*
-                        * If it's 64 bit and not a dual context, mctx will
-                        * contain uninitialized data, so we have to use
-                        * mctx64 here.
-                        */
-                       if (ctx32 == 0) {
-                               sinfo.si_addr = mctx64.es.dar;
-                               /* First check in srr1 and then in dsisr */
-                               if (mctx64.ss.srr1 & (1 << (31 - DSISR_PROT_BIT)))
-                                       sinfo.si_code = SEGV_ACCERR;
-                               else if (mctx64.es.dsisr & (1 << (31 - DSISR_PROT_BIT)))
-                                       sinfo.si_code = SEGV_ACCERR;
-                               else
-                                       sinfo.si_code = SEGV_MAPERR;
-                       } else {
-                               sinfo.si_addr = CAST_USER_ADDR_T(mctx.es.dar);
-                               /* First check in srr1 and then in dsisr */
-                               if (mctx.ss.srr1 & (1 << (31 - DSISR_PROT_BIT)))
-                                       sinfo.si_code = SEGV_ACCERR;
-                               else if (mctx.es.dsisr & (1 << (31 - DSISR_PROT_BIT)))
-                                       sinfo.si_code = SEGV_ACCERR;
-                               else
-                                       sinfo.si_code = SEGV_MAPERR;
-                       }
-                       break;
-               default:
-               {
-                       int status_and_exitcode;
-
-                       /*
-                        * All other signals need to fill out a minimum set of
-                        * information for the siginfo structure passed into
-                        * the signal handler, if SA_SIGINFO was specified.
-                        *
-                        * p->si_status actually contains both the status and
-                        * the exit code; we save it off in its own variable
-                        * for later breakdown.
-                        */
-                       proc_lock(p);
-                       sinfo.si_pid = p->si_pid;
-                       p->si_pid = 0;
-                       status_and_exitcode = p->si_status;
-                       p->si_status = 0;
-                       sinfo.si_uid = p->si_uid;
-                       p->si_uid = 0;
-                       sinfo.si_code = p->si_code;
-                       p->si_code = 0;
-                       proc_unlock(p);
-                       if (sinfo.si_code == CLD_EXITED) {
-                               if (WIFEXITED(status_and_exitcode)) 
-                                       sinfo.si_code = CLD_EXITED;
-                               else if (WIFSIGNALED(status_and_exitcode)) {
-                                       if (WCOREDUMP(status_and_exitcode)) {
-                                               sinfo.si_code = CLD_DUMPED;
-                                               status_and_exitcode = W_EXITCODE(status_and_exitcode,status_and_exitcode);
-                                       } else {
-                                               sinfo.si_code = CLD_KILLED;
-                                               status_and_exitcode = W_EXITCODE(status_and_exitcode,status_and_exitcode);
-                                       }
-                               }
-                       }
-                       /*
-                        * The recorded status contains the exit code and the
-                        * signal information, but the information to be passed
-                        * in the siginfo to the handler is supposed to only
-                        * contain the status, so we have to shift it out.
-                        */
-                       sinfo.si_status = WEXITSTATUS(status_and_exitcode);
-                       break;
-               }
-       }
-
-
-       /* copy info out to user space */
-       if (IS_64BIT_PROCESS(p)) {
-               user64_siginfo_t sinfo64;
-
-               siginfo_user_to_user64(&sinfo,&sinfo64);
-
-#if CONFIG_DTRACE              
-        bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo));
-
-        ut->t_dtrace_siginfo.si_signo = sinfo.si_signo;
-        ut->t_dtrace_siginfo.si_code = sinfo.si_code;
-        ut->t_dtrace_siginfo.si_pid = sinfo.si_pid;
-        ut->t_dtrace_siginfo.si_uid = sinfo.si_uid;
-        ut->t_dtrace_siginfo.si_status = sinfo.si_status;
-               /* XXX truncates faulting address to void * on K32  */
-        ut->t_dtrace_siginfo.si_addr = CAST_DOWN(void *, sinfo.si_addr);
-
-
-        /* Fire DTrace proc:::fault probe when signal is generated by hardware. */
-        switch (sig) {
-        case SIGILL: case SIGBUS: case SIGSEGV: case SIGFPE: case SIGTRAP:
-            DTRACE_PROC2(fault, int, (int)(ut->uu_code), siginfo_t *, &(ut->t_dtrace_siginfo));
-            break;
-        default:
-            break;
-        }
-
-               /* XXX truncates catcher address to uintptr_t */
-               DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &(ut->t_dtrace_siginfo),
-                       void (*)(void), CAST_DOWN(sig_t, catcher));
-#endif /* CONFIG_DTRACE */
-
-               if (copyout(&uctx, p_uctx, sizeof(struct user_ucontext64)))
-                       goto bad;
-               if (copyout(&sinfo64, p_sinfo, sizeof(sinfo64)))
-                       goto bad;
-       } else {
-               struct ucontext64 uctx32;
-               user32_siginfo_t sinfo32;
-
-               ucontext_64to32(&uctx, &uctx32);
-               siginfo_user_to_user32(&sinfo,&sinfo32);
-
-#if CONFIG_DTRACE
-        bzero((caddr_t)&(ut->t_dtrace_siginfo), sizeof(ut->t_dtrace_siginfo));
-
-        ut->t_dtrace_siginfo.si_signo = sinfo.si_signo;
-        ut->t_dtrace_siginfo.si_code = sinfo.si_code;
-        ut->t_dtrace_siginfo.si_pid = sinfo.si_pid;
-        ut->t_dtrace_siginfo.si_uid = sinfo.si_uid;
-        ut->t_dtrace_siginfo.si_status = sinfo.si_status;
-        ut->t_dtrace_siginfo.si_addr = CAST_DOWN(void *, sinfo.si_addr);
-
-
-        /* Fire DTrace proc:::fault probe when signal is generated by hardware. */
-        switch (sig) {
-        case SIGILL: case SIGBUS: case SIGSEGV: case SIGFPE: case SIGTRAP:
-            DTRACE_PROC2(fault, int, (int)(ut->uu_code), siginfo_t *, &(ut->t_dtrace_siginfo));
-            break;
-        default:
-            break;
-        }
-
-               DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &(ut->t_dtrace_siginfo),
-                       void (*)(void), CAST_DOWN(sig_t, catcher));
-#endif /* CONFIG_DTRACE */
-
-               if (copyout(&uctx32, p_uctx, sizeof(struct ucontext64)))
-                       goto bad;
-
-               if (copyout(&sinfo32, p_sinfo, sizeof(sinfo32)))
-                       goto bad;
-       }
-        if ((ctx32 == 0) || dualcontext) {
-           /*
-            * NOTE: Size of mcontext is not variant between 64bit and
-            * 32bit programs usng 64bit registers.
-            */
-            if (copyout(&mctx64, p_mctx64, (vec_used? UC_FLAVOR64_VEC_SIZE: UC_FLAVOR64_SIZE)))
-               goto bad;
-        }
-        if ((ctx32 == 1) || dualcontext) {
-            if (copyout(&mctx, p_mctx, uctx.uc_mcsize))
-               goto bad;
-        }    
-
-
-       /* Place our arguments in arg registers: rtm dependent */
-       if(IS_64BIT_PROCESS(p)) {
-               mctx64.ss.r3 = catcher;
-               mctx64.ss.r4 = CAST_USER_ADDR_T(infostyle);
-               mctx64.ss.r5 = CAST_USER_ADDR_T(sig);
-               mctx64.ss.r6 = p_sinfo;
-               mctx64.ss.r7 = p_uctx;
-
-               mctx64.ss.srr0 = trampact;
-               /* MSR_EXPORT_MASK_SET */
-               mctx64.ss.srr1 = CAST_USER_ADDR_T(get_msr_exportmask());
-               mctx64.ss.r1 = sp;
-               state_count = PPC_THREAD_STATE64_COUNT;
-               if ((kretn = thread_setstatus(th_act, PPC_THREAD_STATE64, (void *)&mctx64.ss, state_count))  != KERN_SUCCESS) {
-                       panic("sendsig: thread_setstatus failed, ret = %08X\n", kretn);
-               }       
-       } else {
-               mctx.ss.r3 = CAST_DOWN(uint32_t,catcher);
-               mctx.ss.r4 = (uint32_t)infostyle;
-               mctx.ss.r5 = (uint32_t)sig;
-               mctx.ss.r6 = CAST_DOWN(uint32_t,p_sinfo);
-               mctx.ss.r7 = CAST_DOWN(uint32_t,p_uctx);
-
-               mctx.ss.srr0 = CAST_DOWN(uint32_t,trampact);
-               /* MSR_EXPORT_MASK_SET */
-               mctx.ss.srr1 = get_msr_exportmask();
-               mctx.ss.r1 = CAST_DOWN(uint32_t,sp);
-               state_count = PPC_THREAD_STATE_COUNT;
-               if ((kretn = thread_setstatus(th_act, PPC_THREAD_STATE, (void *)&mctx.ss, state_count))  != KERN_SUCCESS) {
-                       panic("sendsig: thread_setstatus failed, ret = %08X\n", kretn);
-               }       
-       }
-
-       proc_lock(p);
-       return;
-
-bad:
-       proc_lock(p);
-       SIGACTION(p, SIGILL) = SIG_DFL;
-       sig = sigmask(SIGILL);
-       p->p_sigignore &= ~sig;
-       p->p_sigcatch &= ~sig;
-       ut->uu_sigmask &= ~sig;
-       /* sendsig is called with signal lock held */
-       proc_unlock(p);
-       psignal_locked(p, SIGILL);
-       proc_lock(p);
-       return;
-}
-
-/*
- * System call to cleanup state after a signal
- * has been taken.  Reset signal mask and
- * stack state from context left by sendsig (above).
- * Return to previous pc and psl as specified by
- * context left by sendsig. Check carefully to
- * make sure that the user has not modified the
- * psl to gain improper priviledges or to cause
- * a machine fault.
- */
-
-/* ARGSUSED */
-int
-sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval)
-{
-       struct user_ucontext64 uctx;
-
-       char mactx[sizeof(struct mcontext64)];
-       struct mcontext *p_mctx;
-       struct mcontext64 *p_64mctx;
-       int error;
-       thread_t th_act;
-       struct sigacts *ps = p->p_sigacts;
-       sigset_t mask;  
-       user_addr_t action;
-       uint32_t state_count;
-       unsigned int state_flavor;
-       struct uthread * ut;
-       int vec_used = 0;
-       void *tsptr, *fptr, *vptr;
-        int infostyle = uap->infostyle;
-
-       th_act = current_thread();
-
-       ut = (struct uthread *)get_bsdthread_info(th_act);
-
-       /*
-        * If we are being asked to change the altstack flag on the thread, we
-        * just rest it and return (the uap->uctx is not used).
-        */
-       if (infostyle == UC_SET_ALT_STACK) {
-               ut->uu_sigstk.ss_flags |= SA_ONSTACK;
-               return (0);
-       } else if ((unsigned int)infostyle == UC_RESET_ALT_STACK) {
-               ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;
-               return (0);
-       }
-
-       if (IS_64BIT_PROCESS(p)) {
-               error = copyin(uap->uctx, &uctx, sizeof(struct user_ucontext64));
-               if (error)
-                       return(error);
-       } else {
-               struct ucontext64 uctx32;
-
-               /*
-                * struct ucontext and struct ucontext64 are identical in
-                * size and content; the only difference is the internal
-                * pointer type for the last element, which makes no
-                * difference for the copyin().
-                */
-               error = copyin(uap->uctx, &uctx32, sizeof(struct ucontext));
-               if (error)
-                       return(error);
-               ucontext_32to64(&uctx32, &uctx);
-       }
-        
-
-       /* validate the machine context size */
-       switch (uctx.uc_mcsize) {
-               case UC_FLAVOR64_VEC_SIZE:
-               case UC_FLAVOR64_SIZE:
-               case UC_FLAVOR_VEC_SIZE:
-               case UC_FLAVOR_SIZE:
-                       break;
-               default:
-                       return(EINVAL);
-       }
-
-       /*
-        * The 64 bit process mcontext is identical to the mcontext64, so
-        * there is no conversion necessary.
-        */
-       error = copyin(uctx.uc_mcontext64, mactx, uctx.uc_mcsize);
-       if (error)
-               return(error);
-       
-       if ((uctx.uc_onstack & 01))
-                       ut->uu_sigstk.ss_flags |= SA_ONSTACK;
-       else
-                       ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;
-
-       ut->uu_sigmask = uctx.uc_sigmask & ~sigcantmask;
-       if (ut->uu_siglist & ~ut->uu_sigmask)
-               signal_setast(current_thread());        
-
-       vec_used = 0;
-       switch (infostyle)  {
-                case UC_FLAVOR64_VEC:
-                case UC_TRAD64_VEC:
-                                vec_used = 1;
-                case UC_TRAD64:
-               case UC_FLAVOR64:  {
-                            p_64mctx = (struct mcontext64 *)mactx;     
-                            tsptr = (void *)&p_64mctx->ss;
-                            fptr = (void *)&p_64mctx->fs;
-                            vptr = (void *)&p_64mctx->vs;
-                            state_flavor = PPC_THREAD_STATE64;
-                            state_count = PPC_THREAD_STATE64_COUNT;
-                    } 
-                    break;
-               case UC_FLAVOR_VEC :
-               case UC_TRAD_VEC :
-                                vec_used = 1;
-               case UC_FLAVOR :
-               case UC_TRAD :
-               default: {
-                       p_mctx = (struct mcontext *)mactx;      
-                       tsptr = (void *)&p_mctx->ss;
-                       fptr = (void *)&p_mctx->fs;
-                       vptr = (void *)&p_mctx->vs;
-                       state_flavor = PPC_THREAD_STATE;
-                       state_count = PPC_THREAD_STATE_COUNT;
-               }
-               break;
-       } /* switch () */
-
-       /* validate the thread state, set/reset appropriate mode bits in srr1 */
-       (void)ppc_checkthreadstate(tsptr, state_flavor);
-
-       if (thread_setstatus(th_act, state_flavor, tsptr, state_count)  != KERN_SUCCESS) {
-               return(EINVAL);
-       }       
-
-       state_count = PPC_FLOAT_STATE_COUNT;
-       if (thread_setstatus(th_act, PPC_FLOAT_STATE, fptr, state_count)  != KERN_SUCCESS) {
-               return(EINVAL);
-       }       
-
-       mask = sigmask(SIGFPE);
-       if (((ut->uu_sigmask & mask) == 0) && (p->p_sigcatch & mask) && ((p->p_sigignore & mask) == 0)) {
-               action = ps->ps_sigact[SIGFPE];
-               if((action != SIG_DFL) && (action != SIG_IGN)) {
-                       thread_enable_fpe(th_act, 1);
-               }
-       }
-
-       if (vec_used) {
-               state_count = PPC_VECTOR_STATE_COUNT;
-               if (thread_setstatus(th_act, PPC_VECTOR_STATE, vptr, state_count)  != KERN_SUCCESS) {
-                       return(EINVAL);
-               }       
-       }
-       return (EJUSTRETURN);
-}
-
-/*
- * machine_exception() performs MD translation
- * of a mach exception to a unix signal and code.
- */
-
-boolean_t
-machine_exception(
-               int                             exception,
-               mach_exception_code_t           code,
-               __unused mach_exception_subcode_t subcode,
-               int                             *unix_signal,
-               mach_exception_code_t           *unix_code)
-{
-    switch(exception) {
-
-    case EXC_BAD_INSTRUCTION:
-       *unix_signal = SIGILL;
-       *unix_code = code;
-       break;
-
-    case EXC_ARITHMETIC:
-       *unix_signal = SIGFPE;
-       *unix_code = code;
-       break;
-
-    case EXC_SOFTWARE:
-       if (code == EXC_PPC_TRAP) {
-               *unix_signal = SIGTRAP;
-               *unix_code = code;
-               break;
-       } else
-               return(FALSE);
-
-    default:
-       return(FALSE);
-    }
-   
-    return(TRUE);
-}
-