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.
This commit is contained in:
parent
cc1346b1a2
commit
144bfac97b
@ -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 <sys/cdefs.h>
|
||||
__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,
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -52,6 +52,8 @@ __KERNEL_RCSID(0, "$NetBSD: darwin_signal.c,v 1.7 2003/10/25 18:38:07 christos E
|
||||
|
||||
#include <compat/mach/mach_types.h>
|
||||
#include <compat/mach/mach_vm.h>
|
||||
#include <compat/mach/mach_port.h>
|
||||
#include <compat/mach/mach_notify.h>
|
||||
|
||||
#include <compat/darwin/darwin_signal.h>
|
||||
#include <compat/darwin/darwin_syscallargs.h>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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,
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/ktrace.h> */
|
||||
@ -53,8 +53,11 @@ __KERNEL_RCSID(0, "$NetBSD: mach_notify.c,v 1.2 2003/04/05 19:27:51 manu Exp $")
|
||||
|
||||
#include <compat/mach/mach_types.h>
|
||||
#include <compat/mach/mach_exec.h>
|
||||
#include <compat/mach/mach_thread.h>
|
||||
#include <compat/mach/mach_notify.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -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)},
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <compat/mach/mach_types.h>
|
||||
#include <compat/mach/mach_message.h>
|
||||
|
@ -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
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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"},
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user