]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/uxkern/ux_exception.c
xnu-792.1.5.tar.gz
[apple/xnu.git] / bsd / uxkern / ux_exception.c
index 7a4e53e45aa0d0f1d10a04abe84bac61036dc9e9..e576ad299f006954a9856b51855ff58712c17f27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/kern_return.h>
 #include <mach/message.h>
 #include <mach/port.h>
+#include <mach/mach_port.h>
 #include <mach/mig_errors.h>
+#include <mach/exc_server.h>
 #include <kern/task.h>
 #include <kern/thread.h>
-#include <kern/thread_act.h>
+#include <kern/sched_prim.h>
 #include <kern/kalloc.h>
 
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/ux_exception.h>
 
+#include <vm/vm_protos.h>      /* get_task_ipcspace() */
+
+/*
+ * XXX Things that should be retrieved from Mach headers, but aren't
+ */
+struct ipc_object;
+extern kern_return_t ipc_object_copyin(ipc_space_t space, mach_port_name_t name,
+               mach_msg_type_name_t msgt_name, struct ipc_object **objectp);
+extern mach_msg_return_t mach_msg_receive(mach_msg_header_t *msg,
+               mach_msg_option_t option, mach_msg_size_t rcv_size,
+               mach_port_name_t rcv_name, mach_msg_timeout_t rcv_timeout,
+               void (*continuation)(mach_msg_return_t),
+               mach_msg_size_t slist_size);
+extern mach_msg_return_t mach_msg_send(mach_msg_header_t *msg,
+               mach_msg_option_t option, mach_msg_size_t send_size,
+               mach_msg_timeout_t send_timeout, mach_port_name_t notify);
+extern thread_t convert_port_to_thread(ipc_port_t port);
+extern void ipc_port_release(ipc_port_t);
+
+
+
+
 /*
  *     Unix exception handler.
  */
 
-static void    ux_exception();
+static void    ux_exception(int exception, int code, int subcode,
+                               int *ux_signal, int *ux_code);
 
-decl_simple_lock_data(static,  ux_handler_init_lock)
 mach_port_name_t               ux_exception_port;
 static task_t                  ux_handler_self;
 
@@ -153,43 +177,33 @@ ux_handler(void)
 void
 ux_handler_init(void)
 {
-       task_t  handler_task;
-
-       simple_lock_init(&ux_handler_init_lock);
        ux_exception_port = MACH_PORT_NULL;
-       if (kernel_task_create(kernel_task, 
-               0, 0, &handler_task) != MACH_MSG_SUCCESS) {
-               panic("Failed to created ux handler task\n");
-       }
-       (void) kernel_thread(handler_task, ux_handler);
-       simple_lock(&ux_handler_init_lock);
+       (void) kernel_thread(kernel_task, ux_handler);
        if (ux_exception_port == MACH_PORT_NULL)  {
-               simple_unlock(&ux_handler_init_lock);
                assert_wait(&ux_exception_port, THREAD_UNINT);
-               thread_block((void (*)(void)) 0);
+               thread_block(THREAD_CONTINUE_NULL);
                }
-       else
-               simple_unlock(&ux_handler_init_lock);
 }
 
 kern_return_t
 catch_exception_raise(
-    mach_port_name_t   exception_port,
-    mach_port_name_t   thread_name,
-    mach_port_name_t   task_name,
-    int                        exception,
-    exception_data_t           code,
-    mach_msg_type_number_t     codecnt
+        __unused mach_port_t exception_port,
+        mach_port_t thread,
+        mach_port_t task,
+        exception_type_t exception,
+        exception_data_t code,
+        __unused mach_msg_type_number_t codeCnt
 )
 {
        task_t          self = current_task();
-       thread_act_t    th_act;
+       thread_t        th_act;
        ipc_port_t      thread_port;
-       ipc_port_t      task_port;
        kern_return_t   result = MACH_MSG_SUCCESS;
-       int                     signal = 0;
+       int             ux_signal = 0;
        u_long          ucode = 0;
        struct uthread *ut;
+       mach_port_name_t thread_name = (mach_port_name_t)thread; /* XXX */
+       mach_port_name_t task_name = (mach_port_name_t)task;    /* XXX */
 
    /*
      * Convert local thread name to global port.
@@ -198,32 +212,32 @@ catch_exception_raise(
        (ipc_object_copyin(get_task_ipcspace(self), thread_name,
                       MACH_MSG_TYPE_PORT_SEND,
                       (void *) &thread_port) == MACH_MSG_SUCCESS)) {
-        if (IPC_OBJECT_VALID(thread_port)) {
-          th_act = (thread_act_t)convert_port_to_act(thread_port);
+        if (IPC_PORT_VALID(thread_port)) {
+          th_act = convert_port_to_thread(thread_port);
           ipc_port_release(thread_port);
        } else {
-          th_act = THR_ACT_NULL;
+          th_act = THREAD_NULL;
        }
 
        /*
         *      Catch bogus ports
         */
-       if (th_act != THR_ACT_NULL) {
+       if (th_act != THREAD_NULL) {
   
            /*
             *  Convert exception to unix signal and code.
             */
                ut = get_bsdthread_info(th_act);
            ux_exception(exception, code[0], code[1],
-                               &signal, &ucode);
+                               &ux_signal, (int *)&ucode);
 
            /*
             *  Send signal.
             */
-           if (signal != 0)
-               threadsignal(th_act, signal, ucode);
+           if (ux_signal != 0)
+               threadsignal(th_act, ux_signal, ucode);
 
-           act_deallocate(th_act);
+           thread_deallocate(th_act);
        }
        else
            result = KERN_INVALID_ARGUMENT;
@@ -235,23 +249,43 @@ catch_exception_raise(
      * Delete our send rights to the task and thread ports.
      */
     (void)mach_port_deallocate(get_task_ipcspace(ux_handler_self), task_name);
-    (void)mach_port_deallocate(get_task_ipcspace(ux_handler_self),thread_name);
+    (void)mach_port_deallocate(get_task_ipcspace(ux_handler_self), thread_name);
 
     return (result);
 }
+
 kern_return_t
-catch_exception_raise_state(mach_port_name_t exception_port, int exception, exception_data_t code, mach_msg_type_number_t codeCnt, int flavor, thread_state_t old_state, int old_stateCnt, thread_state_t new_state, int new_stateCnt)
+catch_exception_raise_state(
+        __unused mach_port_t exception_port,
+        __unused exception_type_t exception,
+        __unused const exception_data_t code,
+        __unused mach_msg_type_number_t codeCnt,
+        __unused int *flavor,
+        __unused const thread_state_t old_state,
+        __unused mach_msg_type_number_t old_stateCnt,
+        __unused thread_state_t new_state,
+        __unused mach_msg_type_number_t *new_stateCnt)
 {
        return(KERN_INVALID_ARGUMENT);
 }
+
 kern_return_t
-catch_exception_raise_state_identity(mach_port_name_t exception_port, mach_port_t thread, mach_port_t task, int exception, exception_data_t code, mach_msg_type_number_t codeCnt, int flavor, thread_state_t old_state, int old_stateCnt, thread_state_t new_state, int new_stateCnt)
+catch_exception_raise_state_identity(
+        __unused mach_port_t exception_port,
+        __unused mach_port_t thread,
+        __unused mach_port_t task,
+        __unused exception_type_t exception,
+        __unused exception_data_t code,
+        __unused mach_msg_type_number_t codeCnt,
+        __unused int *flavor,
+        __unused thread_state_t old_state,
+        __unused mach_msg_type_number_t old_stateCnt,
+        __unused thread_state_t new_state,
+        __unused mach_msg_type_number_t *new_stateCnt)
 {
        return(KERN_INVALID_ARGUMENT);
 }
 
-boolean_t      machine_exception();
-
 /*
  *     ux_exception translates a mach exception, code and subcode to
  *     a signal and u.u_code.  Calls machine_exception (machine dependent)
@@ -306,6 +340,9 @@ void ux_exception(
            case EXC_UNIX_ABORT:
                *ux_signal = SIGABRT;
                break;
+           case EXC_SOFT_SIGNAL:
+               *ux_signal = SIGKILL;
+               break;
            }
            break;