diff options
Diffstat (limited to 'kern/exception.c')
-rw-r--r-- | kern/exception.c | 130 |
1 files changed, 71 insertions, 59 deletions
diff --git a/kern/exception.c b/kern/exception.c index 246c1419..15f29705 100644 --- a/kern/exception.c +++ b/kern/exception.c @@ -45,6 +45,7 @@ #include <kern/task.h> #include <kern/thread.h> #include <kern/processor.h> +#include <kern/printf.h> #include <kern/sched.h> #include <kern/sched_prim.h> #include <kern/exception.h> @@ -84,9 +85,9 @@ boolean_t debug_user_with_kdb = FALSE; void exception( - integer_t _exception, - integer_t code, - integer_t subcode) + integer_t _exception, + integer_t code, + long_integer_t subcode) { ipc_thread_t self = current_thread(); ipc_port_t exc_port; @@ -156,9 +157,9 @@ exception( void exception_try_task( - integer_t _exception, - integer_t code, - integer_t subcode) + integer_t _exception, + integer_t code, + long_integer_t subcode) { ipc_thread_t self = current_thread(); task_t task = self->task; @@ -276,31 +277,47 @@ struct mach_exception { mach_msg_type_t codeType; integer_t code; mach_msg_type_t subcodeType; - integer_t subcode; + rpc_long_integer_t subcode; }; #define INTEGER_T_SIZE_IN_BITS (8 * sizeof(integer_t)) #define INTEGER_T_TYPE MACH_MSG_TYPE_INTEGER_T +#define RPC_LONG_INTEGER_T_SIZE_IN_BITS (8 * sizeof(rpc_long_integer_t)) +#if defined(__x86_64__) && !defined(USER32) +#define RPC_LONG_INTEGER_T_TYPE MACH_MSG_TYPE_INTEGER_64 +#else +#define RPC_LONG_INTEGER_T_TYPE MACH_MSG_TYPE_INTEGER_32 +#endif /* in mach/machine/vm_types.h */ mach_msg_type_t exc_port_proto = { - /* msgt_name = */ MACH_MSG_TYPE_PORT_SEND, - /* msgt_size = */ PORT_T_SIZE_IN_BITS, - /* msgt_number = */ 1, - /* msgt_inline = */ TRUE, - /* msgt_longform = */ FALSE, - /* msgt_deallocate = */ FALSE, - /* msgt_unused = */ 0 + .msgt_name = MACH_MSG_TYPE_PORT_SEND, + .msgt_size = PORT_T_SIZE_IN_BITS, + .msgt_number = 1, + .msgt_inline = TRUE, + .msgt_longform = FALSE, + .msgt_deallocate = FALSE, + .msgt_unused = 0 }; mach_msg_type_t exc_code_proto = { - /* msgt_name = */ INTEGER_T_TYPE, - /* msgt_size = */ INTEGER_T_SIZE_IN_BITS, - /* msgt_number = */ 1, - /* msgt_inline = */ TRUE, - /* msgt_longform = */ FALSE, - /* msgt_deallocate = */ FALSE, - /* msgt_unused = */ 0 + .msgt_name = INTEGER_T_TYPE, + .msgt_size = INTEGER_T_SIZE_IN_BITS, + .msgt_number = 1, + .msgt_inline = TRUE, + .msgt_longform = FALSE, + .msgt_deallocate = FALSE, + .msgt_unused = 0 +}; + +mach_msg_type_t exc_subcode_proto = { + .msgt_name = RPC_LONG_INTEGER_T_TYPE, + .msgt_size = RPC_LONG_INTEGER_T_SIZE_IN_BITS, + .msgt_number = 1, + .msgt_inline = TRUE, + .msgt_longform = FALSE, + .msgt_deallocate = FALSE, + .msgt_unused = 0 }; /* @@ -328,9 +345,9 @@ exception_raise( ipc_port_t dest_port, ipc_port_t thread_port, ipc_port_t task_port, - integer_t _exception, - integer_t code, - integer_t subcode) + integer_t _exception, + integer_t code, + long_integer_t subcode) { ipc_thread_t self = current_thread(); ipc_thread_t receiver; @@ -349,16 +366,9 @@ exception_raise( * and it will give the buffer back with its reply. */ - kmsg = ikm_cache(); - if (kmsg != IKM_NULL) { - ikm_cache() = IKM_NULL; - ikm_check_initialized(kmsg, IKM_SAVED_KMSG_SIZE); - } else { - kmsg = ikm_alloc(IKM_SAVED_MSG_SIZE); - if (kmsg == IKM_NULL) - panic("exception_raise"); - ikm_init(kmsg, IKM_SAVED_MSG_SIZE); - } + kmsg = ikm_cache_alloc(); + if (kmsg == IKM_NULL) + panic("exception_raise"); /* * We need a reply port for the RPC. @@ -448,9 +458,8 @@ exception_raise( receiver = ipc_thread_queue_first(&dest_mqueue->imq_threads); if ((receiver == ITH_NULL) || - !((receiver->swap_func == (void (*)()) mach_msg_continue) || - ((receiver->swap_func == - (void (*)()) mach_msg_receive_continue) && + !((receiver->swap_func == mach_msg_continue) || + ((receiver->swap_func == mach_msg_receive_continue) && (sizeof(struct mach_exception) <= receiver->ith_msize) && ((receiver->ith_option & MACH_RCV_NOTIFY) == 0))) || !thread_handoff(self, exception_raise_continue, receiver)) { @@ -521,7 +530,7 @@ exception_raise( exc->exception = _exception; exc->codeType = exc_code_proto; exc->code = code; - exc->subcodeType = exc_code_proto; + exc->subcodeType = exc_subcode_proto; exc->subcode = subcode; /* @@ -606,10 +615,12 @@ exception_raise( { kern_return_t kr; ipc_entry_t entry; + mach_port_name_t port_name; - kr = ipc_entry_get (space, &exc->Head.msgh_remote_port, &entry); + kr = ipc_entry_get (space, &port_name, &entry); if (kr) goto abort_copyout; + exc->Head.msgh_remote_port = (mach_port_t) port_name; { mach_port_gen_t gen; @@ -656,10 +667,10 @@ exception_raise( * to handle the two ports in the body. */ - mr = (ipc_kmsg_copyout_object(space, (ipc_object_t) thread_port, - MACH_MSG_TYPE_PORT_SEND, &exc->thread) | - ipc_kmsg_copyout_object(space, (ipc_object_t) task_port, - MACH_MSG_TYPE_PORT_SEND, &exc->task)); + mr = (ipc_kmsg_copyout_object_to_port(space, (ipc_object_t) thread_port, + MACH_MSG_TYPE_PORT_SEND, &exc->thread) | + ipc_kmsg_copyout_object_to_port(space, (ipc_object_t) task_port, + MACH_MSG_TYPE_PORT_SEND, &exc->task)); if (mr != MACH_MSG_SUCCESS) { (void) ipc_kmsg_put(receiver->ith_msg, kmsg, kmsg->ikm_header.msgh_size); @@ -677,15 +688,20 @@ exception_raise( assert(kmsg->ikm_size == IKM_SAVED_KMSG_SIZE); if (copyoutmsg(&kmsg->ikm_header, receiver->ith_msg, - sizeof(struct mach_exception)) || - (ikm_cache() != IKM_NULL)) { + sizeof(struct mach_exception))) { + mr = ipc_kmsg_put(receiver->ith_msg, kmsg, + kmsg->ikm_header.msgh_size); + thread_syscall_return(mr); + /*NOTREACHED*/ + } + + if (!ikm_cache_free_try(kmsg)) { mr = ipc_kmsg_put(receiver->ith_msg, kmsg, kmsg->ikm_header.msgh_size); thread_syscall_return(mr); /*NOTREACHED*/ } - ikm_cache() = kmsg; thread_syscall_return(MACH_MSG_SUCCESS); /*NOTREACHED*/ #ifndef __GNUC__ @@ -723,7 +739,7 @@ exception_raise( exc->exception = _exception; exc->codeType = exc_code_proto; exc->code = code; - exc->subcodeType = exc_code_proto; + exc->subcodeType = exc_subcode_proto; exc->subcode = subcode; ipc_mqueue_send_always(kmsg); @@ -762,13 +778,13 @@ exception_raise( /* Type descriptor for the return code. */ mach_msg_type_t exc_RetCode_proto = { - /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, - /* msgt_size = */ 32, - /* msgt_number = */ 1, - /* msgt_inline = */ TRUE, - /* msgt_longform = */ FALSE, - /* msgt_deallocate = */ FALSE, - /* msgt_unused = */ 0 + .msgt_name = MACH_MSG_TYPE_INTEGER_32, + .msgt_size = 32, + .msgt_number = 1, + .msgt_inline = TRUE, + .msgt_longform = FALSE, + .msgt_deallocate = FALSE, + .msgt_unused = 0 }; /* @@ -805,11 +821,7 @@ exception_parse_reply(ipc_kmsg_t kmsg) kr = msg->RetCode; - if ((kmsg->ikm_size == IKM_SAVED_KMSG_SIZE) && - (ikm_cache() == IKM_NULL)) - ikm_cache() = kmsg; - else - ikm_free(kmsg); + ikm_cache_free(kmsg); return kr; } |