]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/ppc/unix_signal.c
xnu-1228.5.20.tar.gz
[apple/xnu.git] / bsd / dev / ppc / unix_signal.c
index 501bc87e86c96a53aa4447e61d491bafc3c0113d..4351231010339c142611fb338b357dc10666a927 100644 (file)
@@ -1,23 +1,29 @@
 /*
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
  *
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * 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.
  * 
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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,
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* 
  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
  */
 /* 
  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 #include <mach/exception_types.h>
 
 #include <sys/param.h>
 #include <mach/exception_types.h>
 
 #include <sys/param.h>
-#include <sys/proc.h>
+#include <sys/proc_internal.h>
 #include <sys/user.h>
 #include <sys/ucontext.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 <ppc/signal.h>
 #include <sys/signalvar.h>
 #include <sys/kdebug.h>
 #include <sys/wait.h>
 #include <kern/thread.h>
-#include <kern/thread_act.h>
 #include <mach/ppc/thread_status.h>
 #include <ppc/proc_reg.h>
 
 #include <mach/ppc/thread_status.h>
 #include <ppc/proc_reg.h>
 
-#define        C_REDZONE_LEN           224
-#define        C_STK_ALIGN                     16
-#define C_PARAMSAVE_LEN                64
-#define        C_LINKAGE_LEN           48
-#define TRUNC_DOWN(a,b,c)  (((((unsigned)a)-(b))/(c)) * (c))
+#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
 
 /*
  * The stack layout possibilities (info style); This needs to mach with signal trampoline code
 #define UC_FLAVOR64_VEC                45
 #define UC_DUAL                        50
 #define UC_DUAL_VEC            55
 #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))
 
  /* 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_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_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_64to32(user_siginfo_t *in, 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(void *,in->si_addr);
+       /* following cast works for sival_int because of padding */
+       out->si_value.sival_ptr = CAST_DOWN(void *,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
 /*
  * Arrange for this process to run a signal handler
  */
 
 void
-sendsig(p, catcher, sig, mask, code)
-       struct proc *p;
-       sig_t catcher;
-       int sig, mask;
-       u_long code;
+sendsig(struct proc *p, user_addr_t catcher, int sig, int mask, __unused u_long code)
 {
        kern_return_t kretn;
 {
        kern_return_t kretn;
-       struct mcontext mctx, *p_mctx;
-       struct mcontext64 mctx64, *p_mctx64;
-       struct ucontext uctx, *p_uctx;
-       siginfo_t sinfo, *p_sinfo;
+       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;
        struct sigacts *ps = p->p_sigacts;
-       int framesize;
        int oonstack;
        int oonstack;
-       unsigned long sp;
-       unsigned long state_count;
-       thread_act_t th_act;
+       user_addr_t sp;
+       mach_msg_type_number_t state_count;
+       thread_t th_act;
        struct uthread *ut;
        struct uthread *ut;
-       unsigned long paramp,linkp;
        int infostyle = UC_TRAD;
        int dualcontext =0;
        int infostyle = UC_TRAD;
        int dualcontext =0;
-       sig_t trampact;
+       user_addr_t trampact;
        int vec_used = 0;
        int stack_size = 0;
        int vec_used = 0;
        int stack_size = 0;
-       int stack_flags = 0;
        void * tstate;
        int flavor;
         int ctx32 = 1;
        void * tstate;
        int flavor;
         int ctx32 = 1;
-       int is_64signalregset(void);
 
 
-       th_act = current_act();
+       th_act = current_thread();
        ut = get_bsdthread_info(th_act);
 
        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 (p->p_sigacts->ps_siginfo & sigmask(sig)) {
-               infostyle = UC_FLAVOR;
-        }
-       if(is_64signalregset() && (infostyle == UC_FLAVOR)) {
-               dualcontext = 1;
-               infostyle = UC_DUAL;    
-       }
-       if (p->p_sigacts->ps_64regset & sigmask(sig))  {
-               dualcontext = 0;
-                ctx32 = 0;
-               infostyle = UC_FLAVOR64;
+               /*
+                * 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;
+               }
        }
        }
-        if (is_64signalregset() && (infostyle == UC_TRAD)) {
-                ctx32=0;
-               infostyle = UC_TRAD64;
-       }
-       
+
+       proc_unlock(p);
+
        /* I need this for SIGINFO anyway */
        flavor = PPC_THREAD_STATE;
        tstate = (void *)&mctx.ss;
        /* I need this for SIGINFO anyway */
        flavor = PPC_THREAD_STATE;
        tstate = (void *)&mctx.ss;
@@ -199,6 +341,7 @@ sendsig(p, catcher, sig, mask, code)
                     state_count = PPC_VECTOR_STATE_COUNT;
                     if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
                     goto bad;
                     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) {
             } 
        
             if ((ctx32 == 0) || dualcontext) {
@@ -207,64 +350,79 @@ sendsig(p, catcher, sig, mask, code)
                     state_count = PPC_VECTOR_STATE_COUNT;
                     if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
                         goto bad;
                     state_count = PPC_VECTOR_STATE_COUNT;
                     if (thread_getstatus(th_act, flavor, (thread_state_t)tstate, &state_count)  != KERN_SUCCESS)
                         goto bad;
+                    infostyle += 5;
            }
            }
-        infostyle += 5;
        }  
 
        trampact = ps->ps_trampact[sig];
        }  
 
        trampact = ps->ps_trampact[sig];
-       oonstack = ps->ps_sigstk.ss_flags & SA_ONSTACK;
+       oonstack = ut->uu_sigstk.ss_flags & SA_ONSTACK;
 
        /* figure out where our new stack lives */
 
        /* figure out where our new stack lives */
-       if ((ps->ps_flags & SAS_ALTSTACK) && !oonstack &&
+       if ((ut->uu_flag & UT_ALTSTACK) && !oonstack &&
                (ps->ps_sigonstack & sigmask(sig))) {
                (ps->ps_sigonstack & sigmask(sig))) {
-               sp = (unsigned long)(ps->ps_sigstk.ss_sp);
-               sp += ps->ps_sigstk.ss_size;
-               stack_size = ps->ps_sigstk.ss_size;
-               ps->ps_sigstk.ss_flags |= SA_ONSTACK;
+               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)
        }
        else {
                if (ctx32 == 0)
-                       sp = (unsigned int)mctx64.ss.r1;
+                       sp = mctx64.ss.r1;
                else
                else
-                       sp = mctx.ss.r1;
+                       sp = CAST_USER_ADDR_T(mctx.ss.r1);
        }
 
        
        /* put siginfo on top */
         
        /* preserve RED ZONE area */
        }
 
        
        /* put siginfo on top */
         
        /* preserve RED ZONE area */
-       sp = TRUNC_DOWN(sp, C_REDZONE_LEN, C_STK_ALIGN);
+       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) {
 
         /* next are the saved registers */
         if ((ctx32 == 0) || dualcontext) {
-            sp -= sizeof(*p_mctx64);
-            p_mctx64 = (struct mcontext64 *)sp;
+            sp -= sizeof(struct mcontext64);
+            p_mctx64 = sp;
         }
         if ((ctx32 == 1) || dualcontext) {
         }
         if ((ctx32 == 1) || dualcontext) {
-            sp -= sizeof(*p_mctx);
-            p_mctx = (struct mcontext *)sp;
+            sp -= sizeof(struct mcontext);
+            p_mctx = sp;
         }    
         
         }    
         
-        /* context goes first on stack */
-       sp -= sizeof(*p_uctx);
-       p_uctx = (struct ucontext *) sp;
-
-       /* this is where siginfo goes on stack */
-       sp -= sizeof(*p_sinfo);
-       p_sinfo = (siginfo_t *) sp;
-
-       /* C calling conventions, create param save and linkage
-       *  areas
-       */
-
-       sp = TRUNC_DOWN(sp, C_PARAMSAVE_LEN, C_STK_ALIGN);
-       paramp = sp;
-       sp -= C_LINKAGE_LEN;
-       linkp = 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(user_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(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_onstack = oonstack;
        uctx.uc_sigmask = mask;
-       uctx.uc_stack.ss_sp = (char *)sp;
+       uctx.uc_stack.ss_sp = sp;
        uctx.uc_stack.ss_size = stack_size;
        if (oonstack)
                uctx.uc_stack.ss_flags |= SS_ONSTACK;
        uctx.uc_stack.ss_size = stack_size;
        if (oonstack)
                uctx.uc_stack.ss_flags |= SS_ONSTACK;
@@ -279,47 +437,47 @@ sendsig(p, catcher, sig, mask, code)
                uctx.uc_mcsize += (size_t)(PPC_VECTOR_STATE_COUNT * sizeof(int));
         
        if (ctx32 == 0)
                uctx.uc_mcsize += (size_t)(PPC_VECTOR_STATE_COUNT * sizeof(int));
         
        if (ctx32 == 0)
-             uctx.uc_mcontext = (void *)p_mctx64;
+             uctx.uc_mcontext64 = p_mctx64;
        else
        else
-            uctx.uc_mcontext = (void *)p_mctx;
+            uctx.uc_mcontext64 = p_mctx;
 
        /* setup siginfo */
 
        /* setup siginfo */
-       bzero((caddr_t)&sinfo, sizeof(siginfo_t));
+       bzero((caddr_t)&sinfo, sizeof(user_siginfo_t));
        sinfo.si_signo = sig;
        sinfo.si_signo = sig;
-       sinfo.si_addr = (void *)mctx.ss.srr0;
-       sinfo.pad[0] = (unsigned int)mctx.ss.r1;
+       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) {
 
        switch (sig) {
-               case SIGCHLD:
-                       sinfo.si_pid = p->si_pid;
-                       p->si_pid =0;
-                       sinfo.si_status = 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;
-                       if (sinfo.si_code == CLD_EXITED) {
-                               if (WIFEXITED(sinfo.si_status)) 
-                                       sinfo.si_code = CLD_EXITED;
-                               else if (WIFSIGNALED(sinfo.si_status)) {
-                                       if (WCOREDUMP(sinfo.si_status))
-                                               sinfo.si_code = CLD_DUMPED;
-                                       else    
-                                               sinfo.si_code = CLD_KILLED;
-                               }
-                       }
-                       break;
                case SIGILL:
                case SIGILL:
-                       sinfo.si_addr = (void *)mctx.ss.srr0;
-                       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;
+                       /*
+                        * 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
                        break;
                case SIGFPE:
 #define FPSCR_VX       2
@@ -327,84 +485,212 @@ sendsig(p, catcher, sig, mask, code)
 #define FPSCR_UX       4
 #define FPSCR_ZX       5
 #define FPSCR_XX       6
 #define FPSCR_UX       4
 #define FPSCR_ZX       5
 #define FPSCR_XX       6
-                       sinfo.si_addr = (void *)mctx.ss.srr0;
-                       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;
+                       /*
+                        * 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:
                        break;
 
                case SIGBUS:
-                       sinfo.si_addr = (void *)mctx.ss.srr0;
+                       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:
                        /* on ppc we generate only if EXC_PPC_UNALIGNED */
                        sinfo.si_code = BUS_ADRALN;
                        break;
 
                case SIGSEGV:
-                       sinfo.si_addr = (void *)mctx.ss.srr0;
-                       /* 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;
+                       /*
+                        * 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:
                        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;
                        break;
+               }
        }
 
 
        /* copy info out to user space */
        }
 
 
        /* copy info out to user space */
-       if (copyout((caddr_t)&uctx, (caddr_t)p_uctx, sizeof(struct ucontext)))
-               goto bad;
-       if (copyout((caddr_t)&sinfo, (caddr_t)p_sinfo, sizeof(siginfo_t)))
-               goto bad;
-       if ((ctx32 == 0) || dualcontext) {
-               tstate = &mctx64;
-               if (copyout((caddr_t)tstate, (caddr_t)p_mctx64, (vec_used? UC_FLAVOR64_VEC_SIZE: UC_FLAVOR64_SIZE)))
+       if (IS_64BIT_PROCESS(p)) {
+
+               /* XXX truncates catcher address to uintptr_t */
+               DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &sinfo,
+                       void (*)(void), CAST_DOWN(sig_t, catcher));
+
+               if (copyout(&uctx, p_uctx, sizeof(struct user_ucontext64)))
                        goto bad;
                        goto bad;
-       }
-       if ((ctx32 == 1) || dualcontext) {
-               tstate = &mctx;
-               if (copyout((caddr_t)tstate, (caddr_t)p_mctx, uctx.uc_mcsize))
+               if (copyout(&sinfo, p_sinfo, sizeof(user_siginfo_t)))
                        goto bad;
                        goto bad;
-       }    
+       } else {
+               struct ucontext64 uctx32;
+               siginfo_t sinfo32;
 
 
+               ucontext_64to32(&uctx, &uctx32);
+               siginfo_64to32(&sinfo,&sinfo32);
 
 
-       /* Place our arguments in arg registers: rtm dependent */
+               DTRACE_PROC3(signal__handle, int, sig, siginfo_t *, &sinfo32,
+                       void (*)(void), CAST_DOWN(sig_t, catcher));
 
 
-       mctx.ss.r3 = (unsigned long)catcher;
-       mctx.ss.r4 = (unsigned long)infostyle;
-       mctx.ss.r5 = (unsigned long)sig;
-       mctx.ss.r6 = (unsigned long)p_sinfo;
-       mctx.ss.r7 = (unsigned long)p_uctx;
+               if (copyout(&uctx32, p_uctx, sizeof(struct ucontext64)))
+                       goto bad;
 
 
-       mctx.ss.srr0 = (unsigned long)trampact;
-       mctx.ss.srr1 = get_msr_exportmask();    /* MSR_EXPORT_MASK_SET */
-       mctx.ss.r1 = sp;
-       state_count = PPC_THREAD_STATE_COUNT;
-       if ((kretn = thread_setstatus(th_act, PPC_THREAD_STATE, &mctx.ss, &state_count))  != KERN_SUCCESS) {
-               panic("sendsig: thread_setstatus failed, ret = %08X\n", kretn);
-       }       
+               if (copyout(&sinfo32, p_sinfo, sizeof(siginfo_t)))
+                       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(unsigned long,catcher);
+               mctx.ss.r4 = (unsigned long)infostyle;
+               mctx.ss.r5 = (unsigned long)sig;
+               mctx.ss.r6 = CAST_DOWN(unsigned long,p_sinfo);
+               mctx.ss.r7 = CAST_DOWN(unsigned long,p_uctx);
+
+               mctx.ss.srr0 = CAST_DOWN(unsigned long,trampact);
+               /* MSR_EXPORT_MASK_SET */
+               mctx.ss.srr1 = get_msr_exportmask();
+               mctx.ss.r1 = CAST_DOWN(unsigned long,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:
        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 */
        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 */
-       psignal_lock(p, SIGILL, 0);
+       proc_unlock(p);
+       psignal_locked(p, SIGILL);
+       proc_lock(p);
        return;
 }
 
        return;
 }
 
@@ -419,167 +705,63 @@ bad:
  * a machine fault.
  */
 
  * a machine fault.
  */
 
-#define FOR64_TRANSITION 1
-
-
-#ifdef FOR64_TRANSITION
-
-struct osigreturn_args {
-       struct ucontext *uctx;
-};
-
 /* ARGSUSED */
 int
 /* ARGSUSED */
 int
-osigreturn(p, uap, retval)
-       struct proc *p;
-       struct osigreturn_args *uap;
-       int *retval;
+sigreturn(struct proc *p, struct sigreturn_args *uap, __unused int *retval)
 {
 {
-       struct ucontext uctx;
-       struct ucontext *p_uctx;
-       struct mcontext64 mctx64;
-       struct mcontext64 *p_64mctx;
-       struct mcontext  *p_mctx;
-       int error;
-       thread_act_t th_act;
-       struct sigacts *ps = p->p_sigacts;
-       sigset_t mask;  
-       register sig_t action;
-       unsigned long state_count;
-       unsigned int state_flavor;
-       struct uthread * ut;
-       int vec_used = 0;
-       void *tsptr, *fptr, *vptr, *mactx;
-       void ppc_checkthreadstate(void *, int);
+       struct user_ucontext64 uctx;
 
 
-       th_act = current_act();
-       /* lets use the larger one */
-       mactx = (void *)&mctx64;
-
-       ut = (struct uthread *)get_bsdthread_info(th_act);
-       if (error = copyin(uap->uctx, &uctx, sizeof(struct ucontext))) {
-               return(error);
-       }
-       
-       /* 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);
-       }
-
-       if (error = copyin(uctx.uc_mcontext, mactx, uctx.uc_mcsize)) {
-               return(error);
-       }
-       
-       if (uctx.uc_onstack & 01)
-                       p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
-       else
-               p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
-
-       ut->uu_sigmask = uctx.uc_sigmask & ~sigcantmask;
-       if (ut->uu_siglist & ~ut->uu_sigmask)
-               signal_setast(current_act());   
-
-       vec_used = 0;
-       switch (uctx.uc_mcsize)  {
-               case UC_FLAVOR64_VEC_SIZE :
-                       vec_used = 1;
-               case UC_FLAVOR64_SIZE : {
-                       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_SIZE :
-                       vec_used = 1;
-               case UC_FLAVOR_SIZE:
-               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);
-}
-
-#endif /* FOR64_TRANSITION */
-
-struct sigreturn_args {
-       struct ucontext *uctx;
-        int infostyle;
-};
-
-/* ARGSUSED */
-int
-sigreturn(p, uap, retval)
-       struct proc *p;
-       struct sigreturn_args *uap;
-       int *retval;
-{
-       struct ucontext uctx;
-       struct ucontext *p_uctx;
-        char mactx[sizeof(struct mcontext64)];
-       struct mcontext  *p_mctx;
+       char mactx[sizeof(struct mcontext64)];
+       struct mcontext *p_mctx;
        struct mcontext64 *p_64mctx;
        int error;
        struct mcontext64 *p_64mctx;
        int error;
-       thread_act_t th_act;
+       thread_t th_act;
        struct sigacts *ps = p->p_sigacts;
        sigset_t mask;  
        struct sigacts *ps = p->p_sigacts;
        sigset_t mask;  
-       register sig_t action;
+       user_addr_t action;
        unsigned long state_count;
        unsigned int state_flavor;
        struct uthread * ut;
        int vec_used = 0;
        void *tsptr, *fptr, *vptr;
         int infostyle = uap->infostyle;
        unsigned long state_count;
        unsigned int state_flavor;
        struct uthread * ut;
        int vec_used = 0;
        void *tsptr, *fptr, *vptr;
         int infostyle = uap->infostyle;
-       void ppc_checkthreadstate(void *, int);
 
 
-       th_act = current_act();
+       th_act = current_thread();
 
        ut = (struct uthread *)get_bsdthread_info(th_act);
 
        ut = (struct uthread *)get_bsdthread_info(th_act);
-       if (error = copyin(uap->uctx, &uctx, sizeof(struct ucontext))) {
-               return(error);
+
+       /*
+        * 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:
        /* validate the machine context size */
        switch (uctx.uc_mcsize) {
                case UC_FLAVOR64_VEC_SIZE:
@@ -590,18 +772,23 @@ sigreturn(p, uap, retval)
                default:
                        return(EINVAL);
        }
                default:
                        return(EINVAL);
        }
-       if (error = copyin(uctx.uc_mcontext, mactx, uctx.uc_mcsize)) {
+
+       /*
+        * 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);
                return(error);
-       }
        
        
-       if (uctx.uc_onstack & 01)
-                       p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
+       if ((uctx.uc_onstack & 01))
+                       ut->uu_sigstk.ss_flags |= SA_ONSTACK;
        else
        else
-               p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
+                       ut->uu_sigstk.ss_flags &= ~SA_ONSTACK;
 
        ut->uu_sigmask = uctx.uc_sigmask & ~sigcantmask;
        if (ut->uu_siglist & ~ut->uu_sigmask)
 
        ut->uu_sigmask = uctx.uc_sigmask & ~sigcantmask;
        if (ut->uu_siglist & ~ut->uu_sigmask)
-               signal_setast(current_act());   
+               signal_setast(current_thread());        
 
        vec_used = 0;
        switch (infostyle)  {
 
        vec_used = 0;
        switch (infostyle)  {
@@ -637,12 +824,12 @@ sigreturn(p, uap, retval)
        /* validate the thread state, set/reset appropriate mode bits in srr1 */
        (void)ppc_checkthreadstate(tsptr, state_flavor);
 
        /* 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) {
+       if (thread_setstatus(th_act, state_flavor, tsptr, state_count)  != KERN_SUCCESS) {
                return(EINVAL);
        }       
 
        state_count = PPC_FLOAT_STATE_COUNT;
                return(EINVAL);
        }       
 
        state_count = PPC_FLOAT_STATE_COUNT;
-       if (thread_setstatus(th_act, PPC_FLOAT_STATE, fptr, &state_count)  != KERN_SUCCESS) {
+       if (thread_setstatus(th_act, PPC_FLOAT_STATE, fptr, state_count)  != KERN_SUCCESS) {
                return(EINVAL);
        }       
 
                return(EINVAL);
        }       
 
@@ -656,7 +843,7 @@ sigreturn(p, uap, retval)
 
        if (vec_used) {
                state_count = PPC_VECTOR_STATE_COUNT;
 
        if (vec_used) {
                state_count = PPC_VECTOR_STATE_COUNT;
-               if (thread_setstatus(th_act, PPC_VECTOR_STATE, vptr, &state_count)  != KERN_SUCCESS) {
+               if (thread_setstatus(th_act, PPC_VECTOR_STATE, vptr, state_count)  != KERN_SUCCESS) {
                        return(EINVAL);
                }       
        }
                        return(EINVAL);
                }       
        }
@@ -670,12 +857,11 @@ sigreturn(p, uap, retval)
 
 boolean_t
 machine_exception(
 
 boolean_t
 machine_exception(
-    int                exception,
-    int                code,
-    int                subcode,
-    int                *unix_signal,
-    int                *unix_code
-)
+               int                             exception,
+               mach_exception_code_t           code,
+               __unused mach_exception_subcode_t subcode,
+               int                             *unix_signal,
+               mach_exception_code_t           *unix_code)
 {
     switch(exception) {
 
 {
     switch(exception) {