/*
- * 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;
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.
(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;
* 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)
case EXC_UNIX_ABORT:
*ux_signal = SIGABRT;
break;
+ case EXC_SOFT_SIGNAL:
+ *ux_signal = SIGKILL;
+ break;
}
break;