From 144bfac97b46548cdd2fb1dcfb5b5a8650b55812 Mon Sep 17 00:00:00 2001 From: manu Date: Mon, 17 Nov 2003 01:52:14 +0000 Subject: [PATCH] First work on Mach exceptions. Things that can turn into signals on UNIX may turn into exceptions on Mach: a small message sent by the kernel to the task that requested the exception. On Darwin, when an exception is sent, no signal can be delivered. TODO: more exceptions: arithmetic, bad instructions, emulation, s software, and syscalls (plain and Mach). There is also RPC alert, but I have no idea about what it is. While we are there, remove some user ktrace in notification code, and add a NODEF qualifier in mach_services.master: it will be used for notifications and exceptions, where the kernel is always client and never server: we don't want the message to be displayed as "unimplemented xxx" in kdump (thus UNIMPL is not good), but we don't want to generate the server prototype (therefore, STD is not good either). NODEF will declare it normally in the name tables without creating the prototype. --- sys/compat/darwin/darwin_exec.c | 6 +- sys/compat/darwin/darwin_signal.c | 21 +- sys/compat/darwin/darwin_signal.h | 3 +- sys/compat/mach/mach_exec.c | 6 +- sys/compat/mach/mach_notify.c | 265 ++++++++++++++++++++++++-- sys/compat/mach/mach_notify.h | 106 +++++++++-- sys/compat/mach/mach_port.h | 3 +- sys/compat/mach/mach_services.c | 22 +-- sys/compat/mach/mach_services.h | 6 +- sys/compat/mach/mach_services.master | 18 +- sys/compat/mach/mach_services_names.c | 22 +-- sys/compat/mach/mach_task.c | 40 +++- sys/compat/mach/mach_task.h | 4 +- sys/compat/mach/makemachservices.sh | 7 +- 14 files changed, 442 insertions(+), 87 deletions(-) diff --git a/sys/compat/darwin/darwin_exec.c b/sys/compat/darwin/darwin_exec.c index 02b90a2221d7..29f971cf465e 100644 --- a/sys/compat/darwin/darwin_exec.c +++ b/sys/compat/darwin/darwin_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_exec.c,v 1.22 2003/10/25 10:43:45 manu Exp $ */ +/* $NetBSD: darwin_exec.c,v 1.23 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include "opt_compat_darwin.h" /* For COMPAT_DARWIN in mach_port.h */ #include -__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.22 2003/10/25 10:43:45 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: darwin_exec.c,v 1.23 2003/11/17 01:52:14 manu Exp $"); #include "opt_syscall_debug.h" @@ -110,7 +110,7 @@ const struct emul emul_darwin = { NULL, #endif darwin_sendsig, - trapsignal, + darwin_trapsignal, #if !defined(__HAVE_SIGINFO) || defined(COMPAT_16) sigcode, esigcode, diff --git a/sys/compat/darwin/darwin_signal.c b/sys/compat/darwin/darwin_signal.c index 01afa6f3312c..cbb00146d997 100644 --- a/sys/compat/darwin/darwin_signal.c +++ b/sys/compat/darwin/darwin_signal.c @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_signal.c,v 1.7 2003/10/25 18:38:07 christos Exp $ */ +/* $NetBSD: darwin_signal.c,v 1.8 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: darwin_signal.c,v 1.7 2003/10/25 18:38:07 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: darwin_signal.c,v 1.8 2003/11/17 01:52:14 manu Exp $"); #include #include @@ -52,6 +52,8 @@ __KERNEL_RCSID(0, "$NetBSD: darwin_signal.c,v 1.7 2003/10/25 18:38:07 christos E #include #include +#include +#include #include #include @@ -122,3 +124,18 @@ darwin_sys_sigaction(l, v, retval) return 0; } +void +darwin_trapsignal(l, ksi) + struct lwp *l; + const struct ksiginfo *ksi; +{ + /* + * If mach_trapsignal1 returns 0, the exception was intercepted at + * the Mach level, n signal is to be sent. if it returns an error, + * we call native trapsignal to fire a UNIX signal. + */ + if (mach_trapsignal1(l, ksi) != 0) + trapsignal(l, ksi); + + return; +} diff --git a/sys/compat/darwin/darwin_signal.h b/sys/compat/darwin/darwin_signal.h index d6514267a25e..53bfc1bcff98 100644 --- a/sys/compat/darwin/darwin_signal.h +++ b/sys/compat/darwin/darwin_signal.h @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_signal.h,v 1.8 2003/09/30 21:04:54 manu Exp $ */ +/* $NetBSD: darwin_signal.h,v 1.9 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -80,6 +80,7 @@ struct darwin___sigaction { }; void darwin_sendsig(const ksiginfo_t *, const sigset_t *); +void darwin_trapsignal(struct lwp *, const struct ksiginfo *); #endif /* _DARWIN_SIGNAL_H_ */ diff --git a/sys/compat/mach/mach_exec.c b/sys/compat/mach/mach_exec.c index 12ec95b2d855..a95e35cf2416 100644 --- a/sys/compat/mach/mach_exec.c +++ b/sys/compat/mach/mach_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: mach_exec.c,v 1.34 2003/09/10 16:45:22 christos Exp $ */ +/* $NetBSD: mach_exec.c,v 1.35 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2001-2003 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.34 2003/09/10 16:45:22 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.35 2003/11/17 01:52:14 manu Exp $"); #include "opt_syscall_debug.h" @@ -98,7 +98,7 @@ const struct emul emul_mach = { NULL, #endif sendsig, - trapsignal, + mach_trapsignal, #if !defined(__HAVE_SIGINFO) || defined(COMPAT_16) sigcode, esigcode, diff --git a/sys/compat/mach/mach_notify.c b/sys/compat/mach/mach_notify.c index 78db570c82be..3c092693fafc 100644 --- a/sys/compat/mach/mach_notify.c +++ b/sys/compat/mach/mach_notify.c @@ -1,4 +1,4 @@ -/* $NetBSD: mach_notify.c,v 1.2 2003/04/05 19:27:51 manu Exp $ */ +/* $NetBSD: mach_notify.c,v 1.3 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mach_notify.c,v 1.2 2003/04/05 19:27:51 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mach_notify.c,v 1.3 2003/11/17 01:52:14 manu Exp $"); #include "opt_ktrace.h" #include "opt_compat_mach.h" /* For COMPAT_MACH in */ @@ -53,8 +53,11 @@ __KERNEL_RCSID(0, "$NetBSD: mach_notify.c,v 1.2 2003/04/05 19:27:51 manu Exp $") #include #include +#include #include +static void mach_siginfo_to_exception(const struct ksiginfo *, int *); + void mach_notify_port_destroyed(l, mr) struct lwp *l; @@ -80,14 +83,11 @@ mach_notify_port_destroyed(l, mr) MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); req->req_msgh.msgh_size = sizeof(*req) - sizeof(req->req_trailer); req->req_msgh.msgh_local_port = mr->mr_notify_destroyed->mr_name; - req->req_msgh.msgh_id= MACH_NOTIFY_DESTROYED_MSGID; + req->req_msgh.msgh_id = MACH_NOTIFY_DESTROYED_MSGID; req->req_body.msgh_descriptor_count = 1; req->req_rights.name = mr->mr_name; req->req_trailer.msgh_trailer_size = 8; -#ifdef KTRACE - ktruser(l->l_proc, "notify_port_destroyed", NULL, 0, 0); -#endif (void)mach_message_get((mach_msg_header_t *)req, sizeof(*req), mp, l); #ifdef DEBUG_MACH_MSG printf("pid %d: message queued on port %p (%d) [%p]\n", @@ -127,13 +127,10 @@ mach_notify_port_no_senders(l, mr) MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); req->req_msgh.msgh_size = sizeof(*req) - sizeof(req->req_trailer); req->req_msgh.msgh_local_port = mr->mr_notify_no_senders->mr_name; - req->req_msgh.msgh_id= MACH_NOTIFY_NO_SENDERS_MSGID; + req->req_msgh.msgh_id = MACH_NOTIFY_NO_SENDERS_MSGID; req->req_mscount = mr->mr_refcount; req->req_trailer.msgh_trailer_size = 8; -#ifdef KTRACE - ktruser(l->l_proc, "notify_port_no_senders", NULL, 0, 0); -#endif (void)mach_message_get((mach_msg_header_t *)req, sizeof(*req), mp, l); #ifdef DEBUG_MACH_MSG printf("pid %d: message queued on port %p (%d) [%p]\n", @@ -171,14 +168,10 @@ mach_notify_port_dead_name(l, mr) MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); req->req_msgh.msgh_size = sizeof(*req) - sizeof(req->req_trailer); req->req_msgh.msgh_local_port = mr->mr_notify_dead_name->mr_name; - req->req_msgh.msgh_id= MACH_NOTIFY_DEAD_NAME_MSGID; + req->req_msgh.msgh_id = MACH_NOTIFY_DEAD_NAME_MSGID; req->req_name = mr->mr_name; req->req_trailer.msgh_trailer_size = 8; -#ifdef KTRACE - ktruser(l->l_proc, "notify_port_dead_name", NULL, 0, 0); -#endif - mr->mr_refcount++; mp = mr->mr_notify_dead_name->mr_port; @@ -193,3 +186,245 @@ mach_notify_port_dead_name(l, mr) return; } + +/* + * Exception handler + * Mach does not use signals, so mach_trapsignal will not try to send + * any signal. But systems based on Mach (e.g.: Darwin), can use both + * Mach exceptions and UNIX signals. In order to allow the Mach layer + * to intercept the exception and inhiubit UNIX signals, we have + * mach_trapsignal1 returning an error. If it returns 0, then the + * exception was intercepted at the Mach level, and no signal should + * be produced. Else, a signal might be sent. darwin_trapinfo calls + * mach_trapinfo1 and handle signls if it gets a non zero return value. + */ +void +mach_trapsignal(l, ksi) + struct lwp *l; + const struct ksiginfo *ksi; +{ + (void)mach_trapsignal1(l, ksi); + return; +} + +int +mach_trapsignal1(l, ksi) + struct lwp *l; + const struct ksiginfo *ksi; +{ + struct proc *p = l->l_proc; + struct mach_emuldata *med = (struct mach_emuldata *)p->p_emuldata; + struct mach_port *exc_port; + struct mach_right *task; + struct mach_right *thread; + int exc_no; + + /* XXX Thread and task should have different ports */ + task = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0); + thread = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0); + + switch (ksi->ksi_signo) { + case SIGILL: + exc_no = MACH_EXC_BAD_INSTRUCTION; + break; + case SIGFPE: + exc_no = MACH_EXC_ARITHMETIC; + break; + case SIGSEGV: + case SIGBUS: + exc_no = MACH_EXC_BAD_ACCESS; + break; + case SIGTRAP: + exc_no = MACH_EXC_SOFTWARE; + break; + default: /* SIGCHLD, SIGPOLL */ + return EINVAL; + break; + } + + if ((exc_port = med->med_exc[exc_no]) == NULL) + return EINVAL; + else + return mach_exception(l, ksi, exc_port, exc_no, task, thread); +} + +int +mach_exception(l, ksi, exc_port, exc, task, thread) + struct lwp *l; + const struct ksiginfo *ksi; + struct mach_port *exc_port; + int exc; + struct mach_right *task; + struct mach_right *thread; +{ + int behavior, flavor; + mach_msg_header_t *msgh; + size_t msglen; + struct mach_right *exc_right; + +#ifdef DIAGNOSTIC + if (exc_port->mp_datatype != MACH_MP_EXC_FLAGS) + printf("mach_exception: unexpected datatype"); +#endif + behavior = (int)exc_port->mp_data >> 16; + flavor = (int)exc_port->mp_data & 0xffff; + exc_right = mach_right_get(exc_port, l, MACH_PORT_TYPE_SEND, 0); + + + switch (behavior) { + case MACH_EXCEPTION_DEFAULT: { + mach_exception_raise_request_t *req; + + req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO); + msglen = sizeof(*req); + msgh = (mach_msg_header_t *)req; + + req->req_msgh.msgh_bits = MACH_MSGH_BITS_COMPLEX | + MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND) | + MACH_MSGH_REMOTE_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); + req->req_msgh.msgh_size = + sizeof(*req) - sizeof(req->req_trailer); + req->req_msgh.msgh_local_port = exc_right->mr_name; + req->req_msgh.msgh_id = MACH_EXC_RAISE_MSGID; + req->req_body.msgh_descriptor_count = 2; + req->req_thread.name = thread->mr_name; + req->req_thread.disposition = 0x11; /* XXX */ + req->req_thread.type = 0; /* XXX */ + req->req_task.name = task->mr_name; + req->req_task.disposition = 0x11; /* XXX */ + req->req_task.type = 0; /* XXX */ + req->req_exc = exc; + req->req_codecount = 2; + mach_siginfo_to_exception(ksi, &req->req_code[0]); + req->req_trailer.msgh_trailer_size = 8; + break; + } + + case MACH_EXCEPTION_STATE: { + mach_exception_raise_state_request_t *req; + int dc; + + req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO); + msglen = sizeof(*req); + msgh = (mach_msg_header_t *)req; + + req->req_msgh.msgh_bits = MACH_MSGH_BITS_COMPLEX | + MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND) | + MACH_MSGH_REMOTE_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); + req->req_msgh.msgh_size = + sizeof(*req) - sizeof(req->req_trailer); + req->req_msgh.msgh_local_port = exc_right->mr_name; + req->req_msgh.msgh_id = MACH_EXCEPTION_STATE; + req->req_exc = exc; + req->req_codecount = 2; + mach_siginfo_to_exception(ksi, &req->req_code[0]); + req->req_flavor = flavor; + mach_thread_get_state_machdep(l, flavor, req->req_state, &dc); + /* Trailer */ + req->req_state[(dc / sizeof(req->req_state[0])) + 1] = 8; + + msglen = msglen - + sizeof(req->req_state) + + (dc * sizeof(req->req_state[0])); + break; + } + + case MACH_EXCEPTION_STATE_IDENTITY: { + mach_exception_raise_state_identity_request_t *req; + int dc; + + req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO); + msglen = sizeof(*req); + msgh = (mach_msg_header_t *)req; + + req->req_msgh.msgh_bits = MACH_MSGH_BITS_COMPLEX | + MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND) | + MACH_MSGH_REMOTE_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); + req->req_msgh.msgh_size = + sizeof(*req) - sizeof(req->req_trailer); + req->req_msgh.msgh_local_port = exc_right->mr_name; + req->req_msgh.msgh_id = MACH_EXC_RAISE_STATE_IDENTITY_MSGID; + req->req_body.msgh_descriptor_count = 2; + req->req_thread.name = thread->mr_name; + req->req_thread.disposition = 0x11; /* XXX */ + req->req_thread.type = 0; /* XXX */ + req->req_task.name = task->mr_name; + req->req_task.disposition = 0x11; /* XXX */ + req->req_task.type = 0; /* XXX */ + req->req_exc = exc; + req->req_codecount = 2; + mach_siginfo_to_exception(ksi, &req->req_code[0]); + req->req_flavor = flavor; + mach_thread_get_state_machdep(l, flavor, req->req_state, &dc); + /* Trailer */ + req->req_state[(dc / sizeof(req->req_state[0])) + 1] = 8; + + msglen = msglen - + sizeof(req->req_state) + + (dc * sizeof(req->req_state[0])); + break; + } + + default: + printf("unknown exception bevahior %d\n", behavior); + return EINVAL; + break; + } + + (void)mach_message_get(msgh, msglen, exc_port, l); + wakeup(exc_port->mp_recv->mr_sethead); + + return 0; +} + +static void +mach_siginfo_to_exception(ksi, code) + const struct ksiginfo *ksi; + int *code; +{ + switch (ksi->ksi_signo) { + case SIGBUS: + switch (ksi->ksi_code) { + case BUS_ADRALN: + code[0] = MACH_BUS_ADRALN; + code[1] = (long)ksi->ksi_addr; + break; + default: + printf("untranslated siginfo signo %d, code %d\n", + ksi->ksi_signo, ksi->ksi_code); + break; + } + break; + + case SIGSEGV: + switch (ksi->ksi_code) { + case SEGV_MAPERR: + code[0] = MACH_SEGV_MAPERR; + code[1] = (long)ksi->ksi_addr; + break; + default: + printf("untranslated siginfo signo %d, code %d\n", + ksi->ksi_signo, ksi->ksi_code); + break; + } + break; + + case SIGTRAP: + switch (ksi->ksi_code) { + case TRAP_BRKPT: + code[0] = MACH_TRAP_BRKPT; + code[1] = (long)ksi->ksi_addr; + break; + default: + printf("untranslated siginfo signo %d, code %d\n", + ksi->ksi_signo, ksi->ksi_code); + break; + } + + default: + printf("untranslated siginfo signo %d, code %d\n", + ksi->ksi_signo, ksi->ksi_code); + break; + } + return; +} diff --git a/sys/compat/mach/mach_notify.h b/sys/compat/mach/mach_notify.h index 7c1dabd50fc3..05597dab9f18 100644 --- a/sys/compat/mach/mach_notify.h +++ b/sys/compat/mach/mach_notify.h @@ -1,4 +1,4 @@ -/* $NetBSD: mach_notify.h,v 1.2 2003/04/05 19:27:52 manu Exp $ */ +/* $NetBSD: mach_notify.h,v 1.3 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -39,26 +39,7 @@ #ifndef _MACH_NOTIFICATION_H_ #define _MACH_NOTIFICATION_H_ -#define MACH_EXC_BAD_ACCESS 1 -#define MACH_EXC_BAD_INSTRUCTION 2 -#define MACH_EXC_ARITHMETIC 3 -#define MACH_EXC_EMULATION 4 -#define MACH_EXC_SOFTWARE 5 -#define MACH_EXC_BREAKPOINT 6 -#define MACH_EXC_SYSCALL 7 -#define MACH_EXC_MACH_SYSCALL 8 -#define MACH_EXC_RPC_ALERT 9 -#define MACH_EXC_MAX MACH_EXC_RPC_ALERT - -#define MACH_EXC_MASK_BAD_ACCESS (1 << MACH_EXC_BAD_ACCESS) -#define MACH_EXC_MASK_BAD_INSTRUCTION (1 << MACH_EXC_BAD_INSTRUCTION) -#define MACH_EXC_MASK_ARITHMETIC (1 << MACH_EXC_ARITHMETIC) -#define MACH_EXC_MASK_EMULATION (1 << MACH_EXC_EMULATION) -#define MACH_EXC_MASK_SOFTWARE (1 << MACH_EXC_SOFTWARE) -#define MACH_EXC_MASK_BREAKPOINT (1 << MACH_EXC_BREAKPOINT) -#define MACH_EXC_MASK_SYSCALL (1 << MACH_EXC_SYSCALL) -#define MACH_EXC_MASK_MACH_SYSCALL (1 << MACH_EXC_MACH_SYSCALL) -#define MACH_EXC_MASK_RPC_ALERT (1 << MACH_EXC_RPC_ALERT) +/* Notifications */ #define MACH_NOTIFY_DELETED_MSGID 65 #define MACH_NOTIFY_DESTROYED_MSGID 69 @@ -103,5 +84,88 @@ void mach_notify_port_destroyed(struct lwp *, struct mach_right *); void mach_notify_port_no_senders(struct lwp *, struct mach_right *); void mach_notify_port_dead_name(struct lwp *, struct mach_right *); +/* Exceptions */ + +#define MACH_EXC_BAD_ACCESS 1 +#define MACH_EXC_BAD_INSTRUCTION 2 +#define MACH_EXC_ARITHMETIC 3 +#define MACH_EXC_EMULATION 4 +#define MACH_EXC_SOFTWARE 5 +#define MACH_EXC_BREAKPOINT 6 +#define MACH_EXC_SYSCALL 7 +#define MACH_EXC_MACH_SYSCALL 8 +#define MACH_EXC_RPC_ALERT 9 +#define MACH_EXC_MAX MACH_EXC_RPC_ALERT + +#define MACH_EXC_MASK_BAD_ACCESS (1 << MACH_EXC_BAD_ACCESS) +#define MACH_EXC_MASK_BAD_INSTRUCTION (1 << MACH_EXC_BAD_INSTRUCTION) +#define MACH_EXC_MASK_ARITHMETIC (1 << MACH_EXC_ARITHMETIC) +#define MACH_EXC_MASK_EMULATION (1 << MACH_EXC_EMULATION) +#define MACH_EXC_MASK_SOFTWARE (1 << MACH_EXC_SOFTWARE) +#define MACH_EXC_MASK_BREAKPOINT (1 << MACH_EXC_BREAKPOINT) +#define MACH_EXC_MASK_SYSCALL (1 << MACH_EXC_SYSCALL) +#define MACH_EXC_MASK_MACH_SYSCALL (1 << MACH_EXC_MACH_SYSCALL) +#define MACH_EXC_MASK_RPC_ALERT (1 << MACH_EXC_RPC_ALERT) + +/* exceptions codes */ +#define MACH_BUS_ADRALN 1 +#define MACH_SEGV_MAPERR 2 +#define MACH_TRAP_BRKPT 1 + +/* Exception behaviors and associated messages Id */ + +#define MACH_EXCEPTION_DEFAULT 1 +#define MACH_EXCEPTION_STATE 2 +#define MACH_EXCEPTION_STATE_IDENTITY 3 + +#define MACH_EXC_RAISE_MSGID 2401 +#define MACH_EXC_RAISE_STATE_MSGID 2402 +#define MACH_EXC_RAISE_STATE_IDENTITY_MSGID 2403 + + +typedef struct { + mach_msg_header_t req_msgh; + mach_msg_body_t req_body; + mach_msg_port_descriptor_t req_thread; + mach_msg_port_descriptor_t req_task; + mach_ndr_record_t req_ndr; + mach_exception_type_t req_exc; + mach_msg_type_number_t req_codecount; + mach_integer_t req_code[2]; + mach_msg_trailer_t req_trailer; +} mach_exception_raise_request_t; + +typedef struct { + mach_msg_header_t req_msgh; + mach_ndr_record_t req_ndr; + mach_exception_type_t req_exc; + mach_msg_type_number_t req_codecount; + mach_integer_t req_code[2]; + int req_flavor; + mach_msg_type_number_t req_statecount; + mach_natural_t req_state[144]; + mach_msg_trailer_t req_trailer; +} mach_exception_raise_state_request_t; + +typedef struct { + mach_msg_header_t req_msgh; + mach_msg_body_t req_body; + mach_msg_port_descriptor_t req_thread; + mach_msg_port_descriptor_t req_task; + mach_ndr_record_t req_ndr; + mach_exception_type_t req_exc; + mach_msg_type_number_t req_codecount; + mach_integer_t req_code[2]; + int req_flavor; + mach_msg_type_number_t req_statecount; + mach_natural_t req_state[144]; + mach_msg_trailer_t req_trailer; +} mach_exception_raise_state_identity_request_t; + +void mach_trapsignal(struct lwp *, const struct ksiginfo *); +int mach_trapsignal1(struct lwp *, const struct ksiginfo *); +int mach_exception(struct lwp *, const struct ksiginfo *, + struct mach_port *, int, struct mach_right *, struct mach_right *); + #endif /* _MACH_NOTIFICATION_H_ */ diff --git a/sys/compat/mach/mach_port.h b/sys/compat/mach/mach_port.h index fbb66dc14965..f5ce2c270f28 100644 --- a/sys/compat/mach/mach_port.h +++ b/sys/compat/mach/mach_port.h @@ -1,4 +1,4 @@ -/* $NetBSD: mach_port.h,v 1.29 2003/11/13 13:40:39 manu Exp $ */ +/* $NetBSD: mach_port.h,v 1.30 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2002-2003 The NetBSD Foundation, Inc. @@ -315,6 +315,7 @@ struct mach_port { #define MACH_MP_PROC 0x4 /* (struct proc *) */ #define MACH_MP_NOTIFY_SYNC 0x5 /* int */ #define MACH_MP_MEMORY_ENTRY 0x6 /* (struct mach_memory_entry *) */ +#define MACH_MP_EXC_FLAGS 0x7 /* Two shorts: behavior, flavor */ void mach_port_init(void); struct mach_port *mach_port_get(void); diff --git a/sys/compat/mach/mach_services.c b/sys/compat/mach/mach_services.c index 572e3709e24d..6da967fdb976 100644 --- a/sys/compat/mach/mach_services.c +++ b/sys/compat/mach/mach_services.c @@ -1,14 +1,14 @@ -/* $NetBSD: mach_services.c,v 1.5 2003/11/16 01:14:07 manu Exp $ */ +/* $NetBSD: mach_services.c,v 1.6 2003/11/17 01:52:14 manu Exp $ */ /* * Mach services table. * * DO NOT EDIT -- this file is automatically generated. - * created from $NetBSD: mach_services.c,v 1.5 2003/11/16 01:14:07 manu Exp $ + * created from $NetBSD: mach_services.c,v 1.6 2003/11/17 01:52:14 manu Exp $ */ #include -__KERNEL_RCSID(0, "$NetBSD: mach_services.c,v 1.5 2003/11/16 01:14:07 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mach_services.c,v 1.6 2003/11/17 01:52:14 manu Exp $"); #include #include @@ -27,14 +27,14 @@ __KERNEL_RCSID(0, "$NetBSD: mach_services.c,v 1.5 2003/11/16 01:14:07 manu Exp $ struct mach_service mach_services_table[] = { {64, NULL, "obsolete notify_first", 0, 0}, - {65, NULL, "unimpl. notify_port_deleted", 0, 0}, + {65, NULL, "notify_port_deleted", 0, 0}, {66, NULL, "obsolete notify_msg_accepted", 0, 0}, {67, NULL, "obsolete notify_ownership_rights", 0, 0}, {68, NULL, "obsolete notify_receive_rights", 0, 0}, - {69, NULL, "unimpl. notify_port_destroyed", 0, 0}, - {70, NULL, "unimpl. notify_port_no_senders", 0, 0}, - {71, NULL, "unimpl. notify_port_send_once", 0, 0}, - {72, NULL, "unimpl. notify_port_dead_name", 0, 0}, + {69, NULL, "notify_port_destroyed", 0, 0}, + {70, NULL, "notify_port_no_senders", 0, 0}, + {71, NULL, "notify_port_send_once", 0, 0}, + {72, NULL, "notify_port_dead_name", 0, 0}, {200, mach_host_info, "host_info", sizeof(mach_host_info_request_t), sizeof(mach_host_info_reply_t)}, {201, NULL, "unimpl. host_kernel_version", 0, 0}, {202, mach_host_page_size, "host_page_size", sizeof(mach_host_page_size_request_t), sizeof(mach_host_page_size_reply_t)}, @@ -118,9 +118,9 @@ struct mach_service mach_services_table[] = { {2283, NULL, "unimpl. default_pager_add_file", 0, 0}, {2284, NULL, "unimpl. default_pager_triggers", 0, 0}, {2295, NULL, "unimpl. default_pager_space_alert", 0, 0}, - {2401, NULL, "unimpl. exception_raise", 0, 0}, - {2402, NULL, "unimpl. exception_raise_state", 0, 0}, - {2403, NULL, "unimpl. exception_raise_state_identity", 0, 0}, + {2401, NULL, "exception_raise", 0, 0}, + {2402, NULL, "exception_raise_state", 0, 0}, + {2403, NULL, "exception_raise_state_identity", 0, 0}, {2450, NULL, "unimpl. samples", 0, 0}, {2451, NULL, "unimpl. notices", 0, 0}, {2800, mach_io_object_get_class, "io_object_get_class", sizeof(mach_io_object_get_class_request_t), sizeof(mach_io_object_get_class_reply_t)}, diff --git a/sys/compat/mach/mach_services.h b/sys/compat/mach/mach_services.h index 840478de9015..6476d6d2ae06 100644 --- a/sys/compat/mach/mach_services.h +++ b/sys/compat/mach/mach_services.h @@ -1,15 +1,15 @@ -/* $NetBSD: mach_services.h,v 1.5 2003/11/16 01:14:07 manu Exp $ */ +/* $NetBSD: mach_services.h,v 1.6 2003/11/17 01:52:14 manu Exp $ */ /* * Mach services prototypes. * * DO NOT EDIT -- this file is automatically generated. * DO NOT EDIT -- this file is automatically generated. - * created from $NetBSD: mach_services.h,v 1.5 2003/11/16 01:14:07 manu Exp $ + * created from $NetBSD: mach_services.h,v 1.6 2003/11/17 01:52:14 manu Exp $ */ #include -__KERNEL_RCSID(0, "$NetBSD: mach_services.h,v 1.5 2003/11/16 01:14:07 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mach_services.h,v 1.6 2003/11/17 01:52:14 manu Exp $"); #include #include diff --git a/sys/compat/mach/mach_services.master b/sys/compat/mach/mach_services.master index bc239a627207..20d4561cf712 100644 --- a/sys/compat/mach/mach_services.master +++ b/sys/compat/mach/mach_services.master @@ -1,4 +1,4 @@ - $NetBSD: mach_services.master,v 1.3 2003/11/15 22:55:35 manu Exp $ + $NetBSD: mach_services.master,v 1.4 2003/11/17 01:52:14 manu Exp $ ; ; Mach services list. ; @@ -24,14 +24,14 @@ ; Port Notification messages ; 64 OBSOL notify_first -65 UNIMPL notify_port_deleted +65 NODEF notify_port_deleted 66 OBSOL notify_msg_accepted 67 OBSOL notify_ownership_rights 68 OBSOL notify_receive_rights -69 UNIMPL notify_port_destroyed -70 UNIMPL notify_port_no_senders -71 UNIMPL notify_port_send_once -72 UNIMPL notify_port_dead_name +69 NODEF notify_port_destroyed +70 NODEF notify_port_no_senders +71 NODEF notify_port_send_once +72 NODEF notify_port_dead_name ; ; Host subsystem @@ -166,9 +166,9 @@ ; ; Mach exception interface ; -2401 UNIMPL exception_raise -2402 UNIMPL exception_raise_state -2403 UNIMPL exception_raise_state_identity +2401 NODEF exception_raise +2402 NODEF exception_raise_state +2403 NODEF exception_raise_state_identity ; ; Profiling diff --git a/sys/compat/mach/mach_services_names.c b/sys/compat/mach/mach_services_names.c index ff387e492756..d0ba8c3589e1 100644 --- a/sys/compat/mach/mach_services_names.c +++ b/sys/compat/mach/mach_services_names.c @@ -1,14 +1,14 @@ -/* $NetBSD: mach_services_names.c,v 1.2 2003/11/16 01:14:07 manu Exp $ */ +/* $NetBSD: mach_services_names.c,v 1.3 2003/11/17 01:52:14 manu Exp $ */ /* * Mach services names. This file is not built * by the kernel, it is included by kdump sources. * - * created from $NetBSD: mach_services_names.c,v 1.2 2003/11/16 01:14:07 manu Exp $ + * created from $NetBSD: mach_services_names.c,v 1.3 2003/11/17 01:52:14 manu Exp $ */ #include -__KERNEL_RCSID(0, "$NetBSD: mach_services_names.c,v 1.2 2003/11/16 01:14:07 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mach_services_names.c,v 1.3 2003/11/17 01:52:14 manu Exp $"); struct mach_service_name { int srv_id; @@ -17,14 +17,14 @@ struct mach_service_name { struct mach_service_name mach_services_names[] = { {64, "obsolete notify_first"}, - {65, "unimpl. notify_port_deleted"}, + {65, "notify_port_deleted"}, {66, "obsolete notify_msg_accepted"}, {67, "obsolete notify_ownership_rights"}, {68, "obsolete notify_receive_rights"}, - {69, "unimpl. notify_port_destroyed"}, - {70, "unimpl. notify_port_no_senders"}, - {71, "unimpl. notify_port_send_once"}, - {72, "unimpl. notify_port_dead_name"}, + {69, "notify_port_destroyed"}, + {70, "notify_port_no_senders"}, + {71, "notify_port_send_once"}, + {72, "notify_port_dead_name"}, {200, "host_info"}, {201, "unimpl. host_kernel_version"}, {202, "host_page_size"}, @@ -108,9 +108,9 @@ struct mach_service_name mach_services_names[] = { {2283, "unimpl. default_pager_add_file"}, {2284, "unimpl. default_pager_triggers"}, {2295, "unimpl. default_pager_space_alert"}, - {2401, "unimpl. exception_raise"}, - {2402, "unimpl. exception_raise_state"}, - {2403, "unimpl. exception_raise_state_identity"}, + {2401, "exception_raise"}, + {2402, "exception_raise_state"}, + {2403, "exception_raise_state_identity"}, {2450, "unimpl. samples"}, {2451, "unimpl. notices"}, {2800, "io_object_get_class"}, diff --git a/sys/compat/mach/mach_task.c b/sys/compat/mach/mach_task.c index 6e8b1c829393..146e44318867 100644 --- a/sys/compat/mach/mach_task.c +++ b/sys/compat/mach/mach_task.c @@ -1,4 +1,4 @@ -/* $NetBSD: mach_task.c,v 1.33 2003/11/15 17:44:39 manu Exp $ */ +/* $NetBSD: mach_task.c,v 1.34 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2002-2003 The NetBSD Foundation, Inc. @@ -39,7 +39,7 @@ #include "opt_compat_darwin.h" #include -__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.33 2003/11/15 17:44:39 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.34 2003/11/17 01:52:14 manu Exp $"); #include #include @@ -374,10 +374,42 @@ mach_task_set_exception_ports(args) struct lwp *l = args->l; size_t *msglen = args->rsize; struct mach_emuldata *med; + mach_port_name_t mn; + struct mach_right *mr; + struct mach_port *mp; + + mn = req->req_new_port.name; + if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_SEND)) == 0) + return mach_msg_error(args, EPERM); + + mp = mr->mr_port; +#ifdef DIAGNOSTIC + if ((mp->mp_datatype != MACH_MP_EXC_FLAGS) && + (mp->mp_datatype != MACH_MP_NONE)) + printf("mach_task_set_exception_ports: data exists\n"); +#endif + mp->mp_datatype = MACH_MP_EXC_FLAGS; + mp->mp_data = (void *)((req->req_behavior << 16) | req->req_flavor); med = l->l_proc->p_emuldata; - - uprintf("Unimplemented mach_task_set_exception_ports\n"); + if (req->req_mask & MACH_EXC_MASK_BAD_ACCESS) + med->med_exc[MACH_EXC_BAD_ACCESS] = mp; + if (req->req_mask & MACH_EXC_MASK_BAD_INSTRUCTION) + med->med_exc[MACH_EXC_BAD_INSTRUCTION] = mp; + if (req->req_mask & MACH_EXC_MASK_ARITHMETIC) + med->med_exc[MACH_EXC_ARITHMETIC] = mp; + if (req->req_mask & MACH_EXC_MASK_EMULATION) + med->med_exc[MACH_EXC_EMULATION] = mp; + if (req->req_mask & MACH_EXC_MASK_SOFTWARE) + med->med_exc[MACH_EXC_SOFTWARE] = mp; + if (req->req_mask & MACH_EXC_MASK_BREAKPOINT) + med->med_exc[MACH_EXC_BREAKPOINT] = mp; + if (req->req_mask & MACH_EXC_MASK_SYSCALL) + med->med_exc[MACH_EXC_SYSCALL] = mp; + if (req->req_mask & MACH_EXC_MASK_MACH_SYSCALL) + med->med_exc[MACH_EXC_MACH_SYSCALL] = mp; + if (req->req_mask & MACH_EXC_MASK_RPC_ALERT) + med->med_exc[MACH_EXC_RPC_ALERT] = mp; rep->rep_msgh.msgh_bits = MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE); diff --git a/sys/compat/mach/mach_task.h b/sys/compat/mach/mach_task.h index 7f2089d65620..c7ff2e4bab61 100644 --- a/sys/compat/mach/mach_task.h +++ b/sys/compat/mach/mach_task.h @@ -1,4 +1,4 @@ -/* $NetBSD: mach_task.h,v 1.9 2003/11/13 13:40:39 manu Exp $ */ +/* $NetBSD: mach_task.h,v 1.10 2003/11/17 01:52:14 manu Exp $ */ /*- * Copyright (c) 2002-2003 The NetBSD Foundation, Inc. @@ -136,7 +136,7 @@ typedef struct { mach_ndr_record_t req_ndr; mach_exception_mask_t req_mask; mach_exception_behavior_t req_behavior; - mach_thread_state_flavor_t req_new_flavor; + mach_thread_state_flavor_t req_flavor; } mach_task_set_exception_ports_request_t; typedef struct { diff --git a/sys/compat/mach/makemachservices.sh b/sys/compat/mach/makemachservices.sh index 0ef5507593cb..0e23c421fb75 100755 --- a/sys/compat/mach/makemachservices.sh +++ b/sys/compat/mach/makemachservices.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $NetBSD: makemachservices.sh,v 1.3 2003/11/15 22:55:35 manu Exp $ +# $NetBSD: makemachservices.sh,v 1.4 2003/11/17 01:52:14 manu Exp $ # # Copyright (c) 2003 The NetBSD Foundation, Inc. # All rights reserved. @@ -110,6 +110,11 @@ BEGIN{ printf("int mach_%s(struct mach_trap_args *);\n", $3) > headers; printf(" {%d, \"%s\"},\n", $1, $3) > names; } +(intable && $2 == "NODEF") { + printf(" {%d, NULL, \"%s\", 0, 0},\n", \ + $1, $3, $3, $3, $3) > table; + printf(" {%d, \"%s\"},\n", $1, $3) > names; +} (intable && $2 == "UNIMPL") { printf(" {%d, NULL, \"unimpl. %s\", 0, 0},\n", \ $1, $3, $3, $3, $3) > table;