1From 134c31447edb5e8453986ba28bd14b41f2dfbed1 Mon Sep 17 00:00:00 2001
2From: Matthew Macy <kmacy@freebsd.org>
3Date: Thu, 6 Nov 2014 10:21:26 -0800
4Subject: [PATCH] important NetBSD COMPAT_MACH bits from Attic
5
6(cherry picked from commit 36d8b8f9ba66a2288e967f5acd73abd48898cc41)
7Signed-off-by: Scott K <scott@ixsystems.com>
8---
9 sys/compat/mach/Makefile                           |   16 +
10 sys/compat/mach/arch/powerpc/fasttraps/Makefile    |   14 +
11 .../arch/powerpc/fasttraps/mach_fasttraps_cpu.c    |   72 ++
12 .../powerpc/fasttraps/mach_fasttraps_syscall.h     |   29 +
13 .../powerpc/fasttraps/mach_fasttraps_syscallargs.h |   51 +
14 .../powerpc/fasttraps/mach_fasttraps_syscalls.c    |   41 +
15 .../arch/powerpc/fasttraps/mach_fasttraps_sysent.c |   60 +
16 .../arch/powerpc/fasttraps/mach_fasttraps_thread.c |   83 ++
17 .../mach/arch/powerpc/fasttraps/syscalls.conf      |   13 +
18 .../mach/arch/powerpc/fasttraps/syscalls.master    |   61 +
19 sys/compat/mach/arch/powerpc/files.mach_powerpc    |   10 +
20 sys/compat/mach/arch/powerpc/ppccalls/Makefile     |   14 +
21 .../arch/powerpc/ppccalls/mach_ppccalls_syscall.h  |   17 +
22 .../powerpc/ppccalls/mach_ppccalls_syscallargs.h   |   38 +
23 .../arch/powerpc/ppccalls/mach_ppccalls_syscalls.c |   42 +
24 .../arch/powerpc/ppccalls/mach_ppccalls_sysent.c   |   61 +
25 .../mach/arch/powerpc/ppccalls/syscalls.conf       |   13 +
26 .../mach/arch/powerpc/ppccalls/syscalls.master     |   62 +
27 sys/compat/mach/files.mach                         |   27 +
28 sys/compat/mach/mach_bootstrap.c                   |   81 ++
29 sys/compat/mach/mach_bootstrap.h                   |   52 +
30 sys/compat/mach/mach_clock.c                       |  135 +++
31 sys/compat/mach/mach_clock.h                       |   64 +
32 sys/compat/mach/mach_errno.c                       |  176 +++
33 sys/compat/mach/mach_errno.h                       |  106 ++
34 sys/compat/mach/mach_exception.c                   |  530 +++++++++
35 sys/compat/mach/mach_exception.h                   |  160 +++
36 sys/compat/mach/mach_exec.c                        |  458 ++++++++
37 sys/compat/mach/mach_exec.h                        |   78 ++
38 sys/compat/mach/mach_host.c                        |  241 ++++
39 sys/compat/mach/mach_host.h                        |  184 +++
40 sys/compat/mach/mach_iokit.c                       | 1211 +++++++++++++++++++
41 sys/compat/mach/mach_iokit.h                       |  547 +++++++++
42 sys/compat/mach/mach_message.c                     | 1230 ++++++++++++++++++++
43 sys/compat/mach/mach_message.h                     |  276 +++++
44 sys/compat/mach/mach_misc.c                        |  217 ++++
45 sys/compat/mach/mach_notify.c                      |  182 +++
46 sys/compat/mach/mach_notify.h                      |   79 ++
47 sys/compat/mach/mach_port.c                        | 1004 ++++++++++++++++
48 sys/compat/mach/mach_port.h                        |  363 ++++++
49 sys/compat/mach/mach_semaphore.c                   |  438 +++++++
50 sys/compat/mach/mach_semaphore.h                   |   91 ++
51 sys/compat/mach/mach_services.c                    |  362 ++++++
52 sys/compat/mach/mach_services.h                    |   99 ++
53 sys/compat/mach/mach_services.master               |  481 ++++++++
54 sys/compat/mach/mach_services_names.c              |  351 ++++++
55 sys/compat/mach/mach_syscall.h                     |  110 ++
56 sys/compat/mach/mach_syscallargs.h                 |  258 ++++
57 sys/compat/mach/mach_syscalls.c                    |  159 +++
58 sys/compat/mach/mach_sysctl.c                      |   73 ++
59 sys/compat/mach/mach_sysctl.h                      |   43 +
60 sys/compat/mach/mach_sysent.c                      |  289 +++++
61 sys/compat/mach/mach_task.c                        |  707 +++++++++++
62 sys/compat/mach/mach_task.h                        |  227 ++++
63 sys/compat/mach/mach_thread.c                      |  486 ++++++++
64 sys/compat/mach/mach_thread.h                      |  249 ++++
65 sys/compat/mach/mach_types.h                       |  113 ++
66 sys/compat/mach/mach_vm.c                          |  881 ++++++++++++++
67 sys/compat/mach/mach_vm.h                          |  391 +++++++
68 sys/compat/mach/makemachservices.sh                |  133 +++
69 sys/compat/mach/syscalls.conf                      |   14 +
70 sys/compat/mach/syscalls.master                    |  241 ++++
71 62 files changed, 14294 insertions(+)
72 create mode 100644 sys/compat/mach/Makefile
73 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/Makefile
74 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_cpu.c
75 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscall.h
76 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h
77 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscalls.c
78 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_sysent.c
79 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_thread.c
80 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/syscalls.conf
81 create mode 100644 sys/compat/mach/arch/powerpc/fasttraps/syscalls.master
82 create mode 100644 sys/compat/mach/arch/powerpc/files.mach_powerpc
83 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/Makefile
84 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscall.h
85 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h
86 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscalls.c
87 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_sysent.c
88 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/syscalls.conf
89 create mode 100644 sys/compat/mach/arch/powerpc/ppccalls/syscalls.master
90 create mode 100644 sys/compat/mach/files.mach
91 create mode 100644 sys/compat/mach/mach_bootstrap.c
92 create mode 100644 sys/compat/mach/mach_bootstrap.h
93 create mode 100644 sys/compat/mach/mach_clock.c
94 create mode 100644 sys/compat/mach/mach_clock.h
95 create mode 100644 sys/compat/mach/mach_errno.c
96 create mode 100644 sys/compat/mach/mach_errno.h
97 create mode 100644 sys/compat/mach/mach_exception.c
98 create mode 100644 sys/compat/mach/mach_exception.h
99 create mode 100644 sys/compat/mach/mach_exec.c
100 create mode 100644 sys/compat/mach/mach_exec.h
101 create mode 100644 sys/compat/mach/mach_host.c
102 create mode 100644 sys/compat/mach/mach_host.h
103 create mode 100644 sys/compat/mach/mach_iokit.c
104 create mode 100644 sys/compat/mach/mach_iokit.h
105 create mode 100644 sys/compat/mach/mach_message.c
106 create mode 100644 sys/compat/mach/mach_message.h
107 create mode 100644 sys/compat/mach/mach_misc.c
108 create mode 100644 sys/compat/mach/mach_notify.c
109 create mode 100644 sys/compat/mach/mach_notify.h
110 create mode 100644 sys/compat/mach/mach_port.c
111 create mode 100644 sys/compat/mach/mach_port.h
112 create mode 100644 sys/compat/mach/mach_semaphore.c
113 create mode 100644 sys/compat/mach/mach_semaphore.h
114 create mode 100644 sys/compat/mach/mach_services.c
115 create mode 100644 sys/compat/mach/mach_services.h
116 create mode 100644 sys/compat/mach/mach_services.master
117 create mode 100644 sys/compat/mach/mach_services_names.c
118 create mode 100644 sys/compat/mach/mach_syscall.h
119 create mode 100644 sys/compat/mach/mach_syscallargs.h
120 create mode 100644 sys/compat/mach/mach_syscalls.c
121 create mode 100644 sys/compat/mach/mach_sysctl.c
122 create mode 100644 sys/compat/mach/mach_sysctl.h
123 create mode 100644 sys/compat/mach/mach_sysent.c
124 create mode 100644 sys/compat/mach/mach_task.c
125 create mode 100644 sys/compat/mach/mach_task.h
126 create mode 100644 sys/compat/mach/mach_thread.c
127 create mode 100644 sys/compat/mach/mach_thread.h
128 create mode 100644 sys/compat/mach/mach_types.h
129 create mode 100644 sys/compat/mach/mach_vm.c
130 create mode 100644 sys/compat/mach/mach_vm.h
131 create mode 100755 sys/compat/mach/makemachservices.sh
132 create mode 100644 sys/compat/mach/syscalls.conf
133 create mode 100644 sys/compat/mach/syscalls.master
134
135diff --git a/sys/compat/mach/Makefile b/sys/compat/mach/Makefile
136new file mode 100644
137index 0000000..7cc43a8
138--- /dev/null
139+++ b/sys/compat/mach/Makefile
140@@ -0,0 +1,16 @@
141+#	$NetBSD: Makefile,v 1.7 2005/12/11 12:20:20 christos Exp $
142+
143+SYSCALL_DEP=	syscalls.conf syscalls.master ../../kern/makesyscalls.sh
144+SYSCALL_OBJS=	mach_sysent.c mach_syscalls.c mach_syscall.h mach_syscallargs.h
145+MACH_DEP=	mach_services.master makemachservices.sh
146+MACH_OBJ=	mach_services.c mach_services.h mach_services_names.c
147+
148+all:	${SYSCALL_OBJS} ${MACH_OBJ}
149+
150+.include <bsd.sys.mk>		# for HOST_SH
151+
152+${SYSCALL_OBJS}: ${SYSCALL_DEP}
153+	${HOST_SH} ../../kern/makesyscalls.sh syscalls.conf syscalls.master
154+
155+${MACH_OBJ}: ${MACH_DEP}
156+	${HOSH_SH} ./makemachservices.sh
157diff --git a/sys/compat/mach/arch/powerpc/fasttraps/Makefile b/sys/compat/mach/arch/powerpc/fasttraps/Makefile
158new file mode 100644
159index 0000000..a7d164d
160--- /dev/null
161+++ b/sys/compat/mach/arch/powerpc/fasttraps/Makefile
162@@ -0,0 +1,14 @@
163+#	$NetBSD: Makefile,v 1.5 2005/12/11 12:20:21 christos Exp $
164+
165+.include <bsd.sys.mk>		# for HOST_SH
166+
167+DEP=	syscalls.conf syscalls.master ../../../../../kern/makesyscalls.sh
168+OBJS=	mach_fasttraps_sysent.c mach_fasttraps_syscalls.c \
169+	mach_fasttraps_syscall.h mach_fasttraps_syscallargs.h
170+
171+${OBJS}: ${DEP}
172+	${HOST_SH} ../../../../../kern/makesyscalls.sh syscalls.conf syscalls.master
173+
174+all: ${OBJS}
175+
176+.include <bsd.kinc.mk>
177diff --git a/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_cpu.c b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_cpu.c
178new file mode 100644
179index 0000000..3969e1d
180--- /dev/null
181+++ b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_cpu.c
182@@ -0,0 +1,72 @@
183+/*	$NetBSD: mach_fasttraps_cpu.c,v 1.8 2008/04/28 20:23:45 martin Exp $ */
184+
185+/*-
186+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
187+ * All rights reserved.
188+ *
189+ * This code is derived from software contributed to The NetBSD Foundation
190+ * by Emmanuel Dreyfus.
191+ *
192+ * Redistribution and use in source and binary forms, with or without
193+ * modification, are permitted provided that the following conditions
194+ * are met:
195+ * 1. Redistributions of source code must retain the above copyright
196+ *    notice, this list of conditions and the following disclaimer.
197+ * 2. Redistributions in binary form must reproduce the above copyright
198+ *    notice, this list of conditions and the following disclaimer in the
199+ *    documentation and/or other materials provided with the distribution.
200+ *
201+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
202+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
203+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
204+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
205+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
206+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
207+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
208+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
209+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
210+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
211+ * POSSIBILITY OF SUCH DAMAGE.
212+ */
213+
214+#include <sys/cdefs.h>
215+__KERNEL_RCSID(0, "$NetBSD: mach_fasttraps_cpu.c,v 1.8 2008/04/28 20:23:45 martin Exp $");
216+
217+#include <sys/types.h>
218+#include <sys/systm.h>
219+
220+#include <compat/mach/mach_types.h>
221+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscall.h>
222+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h>
223+
224+#define mach_ignoreZeroFaultbit	0
225+#define mach_floatUsedbit	1
226+#define mach_vectorUsedbit	2
227+#define mach_runningVMbit	4
228+#define mach_floatCngbit	5
229+#define mach_vectorCngbit	6
230+#define mach_timerPopbit	7
231+#define mach_userProtKeybit	8
232+#define mach_trapUnalignbit	9
233+#define mach_notifyUnalignbit	10
234+#define mach_bbThreadbit	28
235+#define mach_bbNoMachSCbit	29
236+#define mach_bbPreemptivebit	30
237+#define mach_spfReserved1	31
238+
239+/* We do not emulate anything here right now */
240+int
241+mach_sys_processor_facilities_used(struct lwp *l, const void *v, register_t *retval)
242+{
243+	*retval = 0;
244+	return 0;
245+}
246+
247+/* This seems to be called only from within the kernel in Mach */
248+int
249+mach_sys_load_msr(struct lwp *l, const void *v, register_t *retval)
250+{
251+	printf("mach_sys_load_msr()\n");
252+	return 0;
253+}
254+
255diff --git a/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscall.h b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscall.h
256new file mode 100644
257index 0000000..7d01d22
258--- /dev/null
259+++ b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscall.h
260@@ -0,0 +1,29 @@
261+/* $NetBSD: mach_fasttraps_syscall.h,v 1.13 2009/01/13 22:33:11 pooka Exp $ */
262+
263+/*
264+ * System call numbers.
265+ *
266+ * DO NOT EDIT-- this file is automatically generated.
267+ * created from	NetBSD: syscalls.master,v 1.8 2009/01/13 22:27:43 pooka Exp
268+ */
269+
270+#ifndef _MACH_FASTTRAPS_SYS_SYSCALL_H_
271+#define	_MACH_FASTTRAPS_SYS_SYSCALL_H_
272+
273+#define	MACH_FASTTRAPS_SYS_MAXSYSARGS	8
274+
275+/* syscall: "cthread_set_self" ret: "void" args: "mach_cproc_t" */
276+#define	MACH_FASTTRAPS_SYS_cthread_set_self	1
277+
278+/* syscall: "cthread_self" ret: "mach_cproc_t" args: */
279+#define	MACH_FASTTRAPS_SYS_cthread_self	2
280+
281+/* syscall: "processor_facilities_used" ret: "int" args: */
282+#define	MACH_FASTTRAPS_SYS_processor_facilities_used	3
283+
284+/* syscall: "load_msr" ret: "void" args: */
285+#define	MACH_FASTTRAPS_SYS_load_msr	4
286+
287+#define	MACH_FASTTRAPS_SYS_MAXSYSCALL	16
288+#define	MACH_FASTTRAPS_SYS_NSYSENT	16
289+#endif /* _MACH_FASTTRAPS_SYS_SYSCALL_H_ */
290diff --git a/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h
291new file mode 100644
292index 0000000..ec67911
293--- /dev/null
294+++ b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h
295@@ -0,0 +1,51 @@
296+/* $NetBSD: mach_fasttraps_syscallargs.h,v 1.13 2009/01/13 22:33:11 pooka Exp $ */
297+
298+/*
299+ * System call argument lists.
300+ *
301+ * DO NOT EDIT-- this file is automatically generated.
302+ * created from	NetBSD: syscalls.master,v 1.8 2009/01/13 22:27:43 pooka Exp
303+ */
304+
305+#ifndef _MACH_FASTTRAPS_SYS_SYSCALLARGS_H_
306+#define	_MACH_FASTTRAPS_SYS_SYSCALLARGS_H_
307+
308+#define	MACH_FASTTRAPS_SYS_MAXSYSARGS	8
309+
310+#undef	syscallarg
311+#define	syscallarg(x)							\
312+	union {								\
313+		register_t pad;						\
314+		struct { x datum; } le;					\
315+		struct { /* LINTED zero array dimension */		\
316+			int8_t pad[  /* CONSTCOND */			\
317+				(sizeof (register_t) < sizeof (x))	\
318+				? 0					\
319+				: sizeof (register_t) - sizeof (x)];	\
320+			x datum;					\
321+		} be;							\
322+	}
323+
324+#undef check_syscall_args
325+#define check_syscall_args(call) \
326+	typedef char call##_check_args[sizeof (struct call##_args) \
327+		<= MACH_FASTTRAPS_SYS_MAXSYSARGS * sizeof (register_t) ? 1 : -1];
328+
329+struct mach_sys_cthread_set_self_args {
330+	syscallarg(mach_cproc_t) p;
331+};
332+check_syscall_args(mach_sys_cthread_set_self)
333+
334+/*
335+ * System call prototypes.
336+ */
337+
338+int	mach_sys_cthread_set_self(struct lwp *, const struct mach_sys_cthread_set_self_args *, register_t *);
339+
340+int	mach_sys_cthread_self(struct lwp *, const void *, register_t *);
341+
342+int	mach_sys_processor_facilities_used(struct lwp *, const void *, register_t *);
343+
344+int	mach_sys_load_msr(struct lwp *, const void *, register_t *);
345+
346+#endif /* _MACH_FASTTRAPS_SYS_SYSCALLARGS_H_ */
347diff --git a/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscalls.c b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscalls.c
348new file mode 100644
349index 0000000..21f4c35
350--- /dev/null
351+++ b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscalls.c
352@@ -0,0 +1,41 @@
353+/* $NetBSD: mach_fasttraps_syscalls.c,v 1.14 2009/01/13 22:33:11 pooka Exp $ */
354+
355+/*
356+ * System call names.
357+ *
358+ * DO NOT EDIT-- this file is automatically generated.
359+ * created from	NetBSD: syscalls.master,v 1.8 2009/01/13 22:27:43 pooka Exp
360+ */
361+
362+#include <sys/cdefs.h>
363+__KERNEL_RCSID(0, "$NetBSD: mach_fasttraps_syscalls.c,v 1.14 2009/01/13 22:33:11 pooka Exp $");
364+
365+#if defined(_KERNEL_OPT)
366+#include <sys/param.h>
367+#include <sys/systm.h>
368+#include <sys/signal.h>
369+#include <sys/mount.h>
370+#include <sys/poll.h>
371+#include <sys/syscallargs.h>
372+#include <compat/mach/mach_types.h>
373+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h>
374+#endif /* _KERNEL_OPT */
375+
376+const char *const mach_fasttraps_syscallnames[] = {
377+	/*   0 */	"#0 (unimplemented)",
378+	/*   1 */	"cthread_set_self",
379+	/*   2 */	"cthread_self",
380+	/*   3 */	"processor_facilities_used",
381+	/*   4 */	"load_msr",
382+	/*   5 */	"#5 (unimplemented)",
383+	/*   6 */	"#6 (unimplemented)",
384+	/*   7 */	"#7 (unimplemented)",
385+	/*   8 */	"#8 (unimplemented)",
386+	/*   9 */	"#9 (unimplemented)",
387+	/*  10 */	"#10 (unimplemented special_bluebox)",
388+	/*  11 */	"#11 (unimplemented)",
389+	/*  12 */	"#12 (unimplemented)",
390+	/*  13 */	"#13 (unimplemented)",
391+	/*  14 */	"#14 (unimplemented)",
392+	/*  15 */	"#15 (unimplemented)",
393+};
394diff --git a/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_sysent.c b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_sysent.c
395new file mode 100644
396index 0000000..a5a59e6
397--- /dev/null
398+++ b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_sysent.c
399@@ -0,0 +1,60 @@
400+/* $NetBSD: mach_fasttraps_sysent.c,v 1.14 2009/01/13 22:33:11 pooka Exp $ */
401+
402+/*
403+ * System call switch table.
404+ *
405+ * DO NOT EDIT-- this file is automatically generated.
406+ * created from	NetBSD: syscalls.master,v 1.8 2009/01/13 22:27:43 pooka Exp
407+ */
408+
409+#include <sys/cdefs.h>
410+__KERNEL_RCSID(0, "$NetBSD: mach_fasttraps_sysent.c,v 1.14 2009/01/13 22:33:11 pooka Exp $");
411+
412+#include <sys/param.h>
413+#include <sys/systm.h>
414+#include <sys/signal.h>
415+#include <sys/mount.h>
416+#include <sys/poll.h>
417+#include <sys/syscallargs.h>
418+#include <compat/mach/mach_types.h>
419+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h>
420+
421+#define	s(type)	sizeof(type)
422+#define	n(type)	(sizeof(type)/sizeof (register_t))
423+#define	ns(type)	n(type), s(type)
424+
425+struct sysent mach_fasttraps_sysent[] = {
426+	{ 0, 0, 0,
427+	    sys_nosys },			/* 0 = unimplemented */
428+	{ ns(struct mach_sys_cthread_set_self_args), 0,
429+	    (sy_call_t *)mach_sys_cthread_set_self },/* 1 = cthread_set_self */
430+	{ 0, 0, 0,
431+	    (sy_call_t *)mach_sys_cthread_self },/* 2 = cthread_self */
432+	{ 0, 0, 0,
433+	    (sy_call_t *)mach_sys_processor_facilities_used },/* 3 = processor_facilities_used */
434+	{ 0, 0, 0,
435+	    (sy_call_t *)mach_sys_load_msr },	/* 4 = load_msr */
436+	{ 0, 0, 0,
437+	    sys_nosys },			/* 5 = unimplemented */
438+	{ 0, 0, 0,
439+	    sys_nosys },			/* 6 = unimplemented */
440+	{ 0, 0, 0,
441+	    sys_nosys },			/* 7 = unimplemented */
442+	{ 0, 0, 0,
443+	    sys_nosys },			/* 8 = unimplemented */
444+	{ 0, 0, 0,
445+	    sys_nosys },			/* 9 = unimplemented */
446+	{ 0, 0, 0,
447+	    sys_nosys },			/* 10 = unimplemented special_bluebox */
448+	{ 0, 0, 0,
449+	    sys_nosys },			/* 11 = unimplemented */
450+	{ 0, 0, 0,
451+	    sys_nosys },			/* 12 = unimplemented */
452+	{ 0, 0, 0,
453+	    sys_nosys },			/* 13 = unimplemented */
454+	{ 0, 0, 0,
455+	    sys_nosys },			/* 14 = unimplemented */
456+	{ 0, 0, 0,
457+	    sys_nosys },			/* 15 = unimplemented */
458+};
459+
460diff --git a/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_thread.c b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_thread.c
461new file mode 100644
462index 0000000..7b70585
463--- /dev/null
464+++ b/sys/compat/mach/arch/powerpc/fasttraps/mach_fasttraps_thread.c
465@@ -0,0 +1,83 @@
466+/*	$NetBSD: mach_fasttraps_thread.c,v 1.12 2008/04/28 20:23:45 martin Exp $ */
467+
468+/*-
469+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
470+ * All rights reserved.
471+ *
472+ * This code is derived from software contributed to The NetBSD Foundation
473+ * by Emmanuel Dreyfus.
474+ *
475+ * Redistribution and use in source and binary forms, with or without
476+ * modification, are permitted provided that the following conditions
477+ * are met:
478+ * 1. Redistributions of source code must retain the above copyright
479+ *    notice, this list of conditions and the following disclaimer.
480+ * 2. Redistributions in binary form must reproduce the above copyright
481+ *    notice, this list of conditions and the following disclaimer in the
482+ *    documentation and/or other materials provided with the distribution.
483+ *
484+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
485+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
486+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
487+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
488+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
489+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
490+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
491+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
492+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
493+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
494+ * POSSIBILITY OF SUCH DAMAGE.
495+ */
496+
497+#include <sys/cdefs.h>
498+__KERNEL_RCSID(0, "$NetBSD: mach_fasttraps_thread.c,v 1.12 2008/04/28 20:23:45 martin Exp $");
499+
500+#include <sys/types.h>
501+#include <sys/systm.h>
502+#include <sys/param.h>
503+#include <sys/signal.h>
504+#include <sys/proc.h>
505+#include <sys/exec.h>
506+
507+#include <compat/mach/mach_types.h>
508+#include <compat/mach/mach_exec.h>
509+
510+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscall.h>
511+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h>
512+
513+int
514+mach_sys_cthread_set_self(struct lwp *l, const struct mach_sys_cthread_set_self_args *uap, register_t *retval)
515+{
516+	/* {
517+		syscallarg(mach_cproc_t) p;
518+	} */
519+	struct mach_emuldata *med;
520+
521+	l->l_private = (void *)SCARG(uap, p);
522+
523+	med = l->l_proc->p_emuldata;
524+	med->med_dirty_thid = 0;
525+
526+	return 0;
527+}
528+
529+int
530+mach_sys_cthread_self(struct lwp *l, const void *v, register_t *retval)
531+{
532+	struct mach_emuldata *med;
533+
534+	/*
535+	 * After a fork or exec, l_private is not initialized.
536+	 * We have no way of setting it before, so we keep track
537+	 * of it being uninitialized with med_dirty_thid.
538+	 * XXX This is probably not the most efficient way
539+	 */
540+	med = l->l_proc->p_emuldata;
541+	if (med->med_dirty_thid != 0) {
542+		l->l_private = NULL;
543+		med->med_dirty_thid = 0;
544+	}
545+
546+	*retval = (register_t)l->l_private;
547+	return 0;
548+}
549diff --git a/sys/compat/mach/arch/powerpc/fasttraps/syscalls.conf b/sys/compat/mach/arch/powerpc/fasttraps/syscalls.conf
550new file mode 100644
551index 0000000..3697dff
552--- /dev/null
553+++ b/sys/compat/mach/arch/powerpc/fasttraps/syscalls.conf
554@@ -0,0 +1,13 @@
555+#	$NetBSD: syscalls.conf,v 1.1 2002/11/03 23:17:21 manu Exp $
556+
557+sysnames="mach_fasttraps_syscalls.c"
558+sysnumhdr="mach_fasttraps_syscall.h"
559+syssw="mach_fasttraps_sysent.c"
560+sysarghdr="mach_fasttraps_syscallargs.h"
561+compatopts=""
562+libcompatopts=""
563+
564+switchname="mach_fasttraps_sysent"
565+namesname="mach_fasttraps_syscallnames"
566+constprefix="MACH_FASTTRAPS_SYS_"
567+nsysent=16
568diff --git a/sys/compat/mach/arch/powerpc/fasttraps/syscalls.master b/sys/compat/mach/arch/powerpc/fasttraps/syscalls.master
569new file mode 100644
570index 0000000..f22eed7
571--- /dev/null
572+++ b/sys/compat/mach/arch/powerpc/fasttraps/syscalls.master
573@@ -0,0 +1,61 @@
574+	$NetBSD: syscalls.master,v 1.8 2009/01/13 22:27:43 pooka Exp $
575+
576+;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
577+
578+; NetBSD COMPAT_MACH PowerPC-only fast traos calls name/number "master" file.
579+; This is used for the negative mach syscalls.
580+; (See syscalls.conf to see what it is processed into.)
581+;
582+; Fields: number type [type-dependent ...]
583+;	number	system call number, must be in order
584+;	type	one of STD, OBSOL, UNIMPL, NODEF, NOARGS, or one of
585+;		the compatibility options defined in syscalls.conf.
586+;
587+; types:
588+;	STD	always included
589+;	OBSOL	obsolete, not included in system
590+;	UNIMPL	unimplemented, not included in system
591+;	NODEF	included, but don't define the syscall number
592+;	NOARGS	included, but don't define the syscall args structure
593+;
594+; The compat options are defined in the syscalls.conf file, and the
595+; compat option name is prefixed to the syscall name.  Other than
596+; that, they're like NODEF (for 'compat' options), or STD (for
597+; 'libcompat' options).
598+;
599+; The type-dependent arguments are as follows:
600+; For STD, NODEF, NOARGS, and compat syscalls:
601+;	{ pseudo-proto } [alias]
602+; For other syscalls:
603+;	[comment]
604+;
605+; #ifdef's, etc. may be included, and are copied to the output files.
606+; #include's are copied to the syscall names and switch definition files only.
607+
608+#include <sys/param.h>
609+#include <sys/systm.h>
610+#include <sys/signal.h>
611+#include <sys/mount.h>
612+#include <sys/poll.h>
613+#include <sys/syscallargs.h>
614+
615+#include <compat/mach/mach_types.h>
616+#include <compat/mach/arch/powerpc/fasttraps/mach_fasttraps_syscallargs.h>
617+%%
618+
619+0	UNIMPL
620+1	STD		{ void|mach_sys||cthread_set_self(mach_cproc_t p); }
621+2	STD		{ mach_cproc_t|mach_sys||cthread_self(void); }
622+3	STD		{ int|mach_sys||processor_facilities_used(void); }
623+4	STD		{ void|mach_sys||load_msr(void); }
624+5	UNIMPL
625+6	UNIMPL
626+7	UNIMPL
627+8	UNIMPL
628+9	UNIMPL
629+10	UNIMPL		special_bluebox
630+11	UNIMPL
631+12	UNIMPL
632+13	UNIMPL
633+14	UNIMPL
634+15	UNIMPL
635diff --git a/sys/compat/mach/arch/powerpc/files.mach_powerpc b/sys/compat/mach/arch/powerpc/files.mach_powerpc
636new file mode 100644
637index 0000000..08f3a1e
638--- /dev/null
639+++ b/sys/compat/mach/arch/powerpc/files.mach_powerpc
640@@ -0,0 +1,10 @@
641+#	$NetBSD: files.mach_powerpc,v 1.1 2002/11/03 23:17:19 manu Exp $
642+#
643+# Config file description for PowerPC only calls Mach compat code.
644+# Included by ports that need it.
645+
646+file	compat/mach/arch/powerpc/ppccalls/mach_ppccalls_sysent.c    compat_mach
647+
648+file	compat/mach/arch/powerpc/fasttraps/mach_fasttraps_sysent.c  compat_mach
649+file	compat/mach/arch/powerpc/fasttraps/mach_fasttraps_thread.c  compat_mach
650+file	compat/mach/arch/powerpc/fasttraps/mach_fasttraps_cpu.c     compat_mach
651diff --git a/sys/compat/mach/arch/powerpc/ppccalls/Makefile b/sys/compat/mach/arch/powerpc/ppccalls/Makefile
652new file mode 100644
653index 0000000..c3ec1a8
654--- /dev/null
655+++ b/sys/compat/mach/arch/powerpc/ppccalls/Makefile
656@@ -0,0 +1,14 @@
657+#	$NetBSD: Makefile,v 1.4 2005/12/11 12:20:22 christos Exp $
658+
659+.include <bsd.sys.mk>		# for HOST_SH
660+
661+DEP=	syscalls.conf syscalls.master ../../../../../kern/makesyscalls.sh
662+OBJS=	mach_ppccalls_sysent.c mach_ppccalls_syscalls.c \
663+	mach_ppccalls_syscall.h mach_ppccalls_syscallargs.h
664+
665+${OBJS}: ${DEP}
666+	${HOST_SH} ../../../../../kern/makesyscalls.sh syscalls.conf syscalls.master
667+
668+all: ${OBJS}
669+
670+.include <bsd.kinc.mk>
671diff --git a/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscall.h b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscall.h
672new file mode 100644
673index 0000000..6152851
674--- /dev/null
675+++ b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscall.h
676@@ -0,0 +1,17 @@
677+/* $NetBSD: mach_ppccalls_syscall.h,v 1.8 2009/01/13 22:33:11 pooka Exp $ */
678+
679+/*
680+ * System call numbers.
681+ *
682+ * DO NOT EDIT-- this file is automatically generated.
683+ * created from	NetBSD: syscalls.master,v 1.5 2007/02/09 21:55:22 ad Exp
684+ */
685+
686+#ifndef _MACH_PPCCALLS_SYS_SYSCALL_H_
687+#define	_MACH_PPCCALLS_SYS_SYSCALL_H_
688+
689+#define	MACH_PPCCALLS_SYS_MAXSYSARGS	8
690+
691+#define	MACH_PPCCALLS_SYS_MAXSYSCALL	16
692+#define	MACH_PPCCALLS_SYS_NSYSENT	16
693+#endif /* _MACH_PPCCALLS_SYS_SYSCALL_H_ */
694diff --git a/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h
695new file mode 100644
696index 0000000..92d6275
697--- /dev/null
698+++ b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h
699@@ -0,0 +1,38 @@
700+/* $NetBSD: mach_ppccalls_syscallargs.h,v 1.8 2009/01/13 22:33:11 pooka Exp $ */
701+
702+/*
703+ * System call argument lists.
704+ *
705+ * DO NOT EDIT-- this file is automatically generated.
706+ * created from	NetBSD: syscalls.master,v 1.5 2007/02/09 21:55:22 ad Exp
707+ */
708+
709+#ifndef _MACH_PPCCALLS_SYS_SYSCALLARGS_H_
710+#define	_MACH_PPCCALLS_SYS_SYSCALLARGS_H_
711+
712+#define	MACH_PPCCALLS_SYS_MAXSYSARGS	8
713+
714+#undef	syscallarg
715+#define	syscallarg(x)							\
716+	union {								\
717+		register_t pad;						\
718+		struct { x datum; } le;					\
719+		struct { /* LINTED zero array dimension */		\
720+			int8_t pad[  /* CONSTCOND */			\
721+				(sizeof (register_t) < sizeof (x))	\
722+				? 0					\
723+				: sizeof (register_t) - sizeof (x)];	\
724+			x datum;					\
725+		} be;							\
726+	}
727+
728+#undef check_syscall_args
729+#define check_syscall_args(call) \
730+	typedef char call##_check_args[sizeof (struct call##_args) \
731+		<= MACH_PPCCALLS_SYS_MAXSYSARGS * sizeof (register_t) ? 1 : -1];
732+
733+/*
734+ * System call prototypes.
735+ */
736+
737+#endif /* _MACH_PPCCALLS_SYS_SYSCALLARGS_H_ */
738diff --git a/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscalls.c b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscalls.c
739new file mode 100644
740index 0000000..8f489c1
741--- /dev/null
742+++ b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscalls.c
743@@ -0,0 +1,42 @@
744+/* $NetBSD: mach_ppccalls_syscalls.c,v 1.9 2009/01/13 22:33:11 pooka Exp $ */
745+
746+/*
747+ * System call names.
748+ *
749+ * DO NOT EDIT-- this file is automatically generated.
750+ * created from	NetBSD: syscalls.master,v 1.5 2007/02/09 21:55:22 ad Exp
751+ */
752+
753+#include <sys/cdefs.h>
754+__KERNEL_RCSID(0, "$NetBSD: mach_ppccalls_syscalls.c,v 1.9 2009/01/13 22:33:11 pooka Exp $");
755+
756+#if defined(_KERNEL_OPT)
757+#include <sys/param.h>
758+#include <sys/systm.h>
759+#include <sys/signal.h>
760+#include <sys/mount.h>
761+#include <sys/poll.h>
762+#include <sys/syscallargs.h>
763+#include <compat/mach/mach_types.h>
764+#include <compat/mach/mach_message.h>
765+#include <compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h>
766+#endif /* _KERNEL_OPT */
767+
768+const char *const mach_ppccalls_syscallnames[] = {
769+	/*   0 */	"#0 (unimplemented diagcall)",
770+	/*   1 */	"#1 (unimplemented vmm_get_version)",
771+	/*   2 */	"#2 (unimplemented vmm_get_features)",
772+	/*   3 */	"#3 (unimplemented vmm_init_context)",
773+	/*   4 */	"#4 (unimplemented vmm_dispatch)",
774+	/*   5 */	"#5 (unimplemented bb_enable_bluebox)",
775+	/*   6 */	"#6 (unimplemented bb_disable_bluebox)",
776+	/*   7 */	"#7 (unimplemented bb_settaskenv)",
777+	/*   8 */	"#8 (unimplemented vmm_stop_vm)",
778+	/*   9 */	"#9 (unimplemented dis)",
779+	/*  10 */	"#10 (unimplemented)",
780+	/*  11 */	"#11 (unimplemented)",
781+	/*  12 */	"#12 (unimplemented)",
782+	/*  13 */	"#13 (unimplemented)",
783+	/*  14 */	"#14 (unimplemented)",
784+	/*  15 */	"#15 (unimplemented)",
785+};
786diff --git a/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_sysent.c b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_sysent.c
787new file mode 100644
788index 0000000..21579d0
789--- /dev/null
790+++ b/sys/compat/mach/arch/powerpc/ppccalls/mach_ppccalls_sysent.c
791@@ -0,0 +1,61 @@
792+/* $NetBSD: mach_ppccalls_sysent.c,v 1.9 2009/01/13 22:33:11 pooka Exp $ */
793+
794+/*
795+ * System call switch table.
796+ *
797+ * DO NOT EDIT-- this file is automatically generated.
798+ * created from	NetBSD: syscalls.master,v 1.5 2007/02/09 21:55:22 ad Exp
799+ */
800+
801+#include <sys/cdefs.h>
802+__KERNEL_RCSID(0, "$NetBSD: mach_ppccalls_sysent.c,v 1.9 2009/01/13 22:33:11 pooka Exp $");
803+
804+#include <sys/param.h>
805+#include <sys/systm.h>
806+#include <sys/signal.h>
807+#include <sys/mount.h>
808+#include <sys/poll.h>
809+#include <sys/syscallargs.h>
810+#include <compat/mach/mach_types.h>
811+#include <compat/mach/mach_message.h>
812+#include <compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h>
813+
814+#define	s(type)	sizeof(type)
815+#define	n(type)	(sizeof(type)/sizeof (register_t))
816+#define	ns(type)	n(type), s(type)
817+
818+struct sysent mach_ppccalls_sysent[] = {
819+	{ 0, 0, 0,
820+	    sys_nosys },			/* 0 = unimplemented diagcall */
821+	{ 0, 0, 0,
822+	    sys_nosys },			/* 1 = unimplemented vmm_get_version */
823+	{ 0, 0, 0,
824+	    sys_nosys },			/* 2 = unimplemented vmm_get_features */
825+	{ 0, 0, 0,
826+	    sys_nosys },			/* 3 = unimplemented vmm_init_context */
827+	{ 0, 0, 0,
828+	    sys_nosys },			/* 4 = unimplemented vmm_dispatch */
829+	{ 0, 0, 0,
830+	    sys_nosys },			/* 5 = unimplemented bb_enable_bluebox */
831+	{ 0, 0, 0,
832+	    sys_nosys },			/* 6 = unimplemented bb_disable_bluebox */
833+	{ 0, 0, 0,
834+	    sys_nosys },			/* 7 = unimplemented bb_settaskenv */
835+	{ 0, 0, 0,
836+	    sys_nosys },			/* 8 = unimplemented vmm_stop_vm */
837+	{ 0, 0, 0,
838+	    sys_nosys },			/* 9 = unimplemented dis */
839+	{ 0, 0, 0,
840+	    sys_nosys },			/* 10 = unimplemented */
841+	{ 0, 0, 0,
842+	    sys_nosys },			/* 11 = unimplemented */
843+	{ 0, 0, 0,
844+	    sys_nosys },			/* 12 = unimplemented */
845+	{ 0, 0, 0,
846+	    sys_nosys },			/* 13 = unimplemented */
847+	{ 0, 0, 0,
848+	    sys_nosys },			/* 14 = unimplemented */
849+	{ 0, 0, 0,
850+	    sys_nosys },			/* 15 = unimplemented */
851+};
852+
853diff --git a/sys/compat/mach/arch/powerpc/ppccalls/syscalls.conf b/sys/compat/mach/arch/powerpc/ppccalls/syscalls.conf
854new file mode 100644
855index 0000000..93215d0
856--- /dev/null
857+++ b/sys/compat/mach/arch/powerpc/ppccalls/syscalls.conf
858@@ -0,0 +1,13 @@
859+#	$NetBSD: syscalls.conf,v 1.1 2002/11/03 23:17:22 manu Exp $
860+
861+sysnames="mach_ppccalls_syscalls.c"
862+sysnumhdr="mach_ppccalls_syscall.h"
863+syssw="mach_ppccalls_sysent.c"
864+sysarghdr="mach_ppccalls_syscallargs.h"
865+compatopts=""
866+libcompatopts=""
867+
868+switchname="mach_ppccalls_sysent"
869+namesname="mach_ppccalls_syscallnames"
870+constprefix="MACH_PPCCALLS_SYS_"
871+nsysent=16
872diff --git a/sys/compat/mach/arch/powerpc/ppccalls/syscalls.master b/sys/compat/mach/arch/powerpc/ppccalls/syscalls.master
873new file mode 100644
874index 0000000..4ec3cb9
875--- /dev/null
876+++ b/sys/compat/mach/arch/powerpc/ppccalls/syscalls.master
877@@ -0,0 +1,62 @@
878+	$NetBSD: syscalls.master,v 1.5 2007/02/09 21:55:22 ad Exp $
879+
880+;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
881+
882+; NetBSD COMPAT_MACH PowerPC-only system call name/number "master" file.
883+; This is used for the negative mach syscalls.
884+; (See syscalls.conf to see what it is processed into.)
885+;
886+; Fields: number type [type-dependent ...]
887+;	number	system call number, must be in order
888+;	type	one of STD, OBSOL, UNIMPL, NODEF, NOARGS, or one of
889+;		the compatibility options defined in syscalls.conf.
890+;
891+; types:
892+;	STD	always included
893+;	OBSOL	obsolete, not included in system
894+;	UNIMPL	unimplemented, not included in system
895+;	NODEF	included, but don't define the syscall number
896+;	NOARGS	included, but don't define the syscall args structure
897+;
898+; The compat options are defined in the syscalls.conf file, and the
899+; compat option name is prefixed to the syscall name.  Other than
900+; that, they're like NODEF (for 'compat' options), or STD (for
901+; 'libcompat' options).
902+;
903+; The type-dependent arguments are as follows:
904+; For STD, NODEF, NOARGS, and compat syscalls:
905+;	{ pseudo-proto } [alias]
906+; For other syscalls:
907+;	[comment]
908+;
909+; #ifdef's, etc. may be included, and are copied to the output files.
910+; #include's are copied to the syscall names and switch definition files only.
911+
912+#include <sys/param.h>
913+#include <sys/systm.h>
914+#include <sys/signal.h>
915+#include <sys/mount.h>
916+#include <sys/poll.h>
917+#include <sys/syscallargs.h>
918+
919+#include <compat/mach/mach_types.h>
920+#include <compat/mach/mach_message.h>
921+#include <compat/mach/arch/powerpc/ppccalls/mach_ppccalls_syscallargs.h>
922+%%
923+
924+0	UNIMPL			diagcall
925+1	UNIMPL			vmm_get_version
926+2	UNIMPL			vmm_get_features
927+3	UNIMPL			vmm_init_context
928+4	UNIMPL			vmm_dispatch
929+5	UNIMPL			bb_enable_bluebox
930+6	UNIMPL			bb_disable_bluebox
931+7	UNIMPL			bb_settaskenv
932+8	UNIMPL			vmm_stop_vm
933+9	UNIMPL			dis
934+10	UNIMPL
935+11	UNIMPL
936+12	UNIMPL
937+13	UNIMPL
938+14	UNIMPL
939+15	UNIMPL
940diff --git a/sys/compat/mach/files.mach b/sys/compat/mach/files.mach
941new file mode 100644
942index 0000000..c5b8359
943--- /dev/null
944+++ b/sys/compat/mach/files.mach
945@@ -0,0 +1,27 @@
946+#	$NetBSD: files.mach,v 1.16 2005/12/11 12:20:20 christos Exp $
947+#
948+# Config file description for machine-independent Mach compat code.
949+# Included by ports that need it.
950+
951+# ports should define any machine-specific files they need in their
952+# own file lists.
953+
954+file	compat/mach/mach_bootstrap.c	compat_mach | compat_darwin
955+file	compat/mach/mach_clock.c	compat_mach | compat_darwin
956+file	compat/mach/mach_errno.c	compat_mach | compat_darwin
957+file	compat/mach/mach_exception.c	compat_mach | compat_darwin
958+file	compat/mach/mach_exec.c		compat_mach | compat_darwin
959+file	compat/mach/mach_host.c		compat_mach | compat_darwin
960+file	compat/mach/mach_iokit.c	compat_mach | compat_darwin
961+file	compat/mach/mach_misc.c		compat_mach | compat_darwin
962+file	compat/mach/mach_message.c	compat_mach | compat_darwin
963+file	compat/mach/mach_notify.c	compat_mach | compat_darwin
964+file	compat/mach/mach_port.c		compat_mach | compat_darwin
965+file	compat/mach/mach_semaphore.c	compat_mach | compat_darwin
966+file	compat/mach/mach_services.c	compat_mach | compat_darwin
967+file	compat/mach/mach_syscalls.c	compat_mach | compat_darwin
968+file	compat/mach/mach_sysctl.c	compat_mach | compat_darwin
969+file	compat/mach/mach_sysent.c	compat_mach | compat_darwin
970+file	compat/mach/mach_task.c		compat_mach | compat_darwin
971+file	compat/mach/mach_thread.c	compat_mach | compat_darwin
972+file	compat/mach/mach_vm.c		compat_mach | compat_darwin
973diff --git a/sys/compat/mach/mach_bootstrap.c b/sys/compat/mach/mach_bootstrap.c
974new file mode 100644
975index 0000000..e40c488
976--- /dev/null
977+++ b/sys/compat/mach/mach_bootstrap.c
978@@ -0,0 +1,81 @@
979+/*	$NetBSD: mach_bootstrap.c,v 1.14 2008/04/28 20:23:44 martin Exp $ */
980+
981+/*-
982+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
983+ * All rights reserved.
984+ *
985+ * This code is derived from software contributed to The NetBSD Foundation
986+ * by Emmanuel Dreyfus
987+ *
988+ * Redistribution and use in source and binary forms, with or without
989+ * modification, are permitted provided that the following conditions
990+ * are met:
991+ * 1. Redistributions of source code must retain the above copyright
992+ *    notice, this list of conditions and the following disclaimer.
993+ * 2. Redistributions in binary form must reproduce the above copyright
994+ *    notice, this list of conditions and the following disclaimer in the
995+ *    documentation and/or other materials provided with the distribution.
996+ *
997+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
998+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
999+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1000+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1001+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1002+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1003+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1004+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1005+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1006+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1007+ * POSSIBILITY OF SUCH DAMAGE.
1008+ */
1009+
1010+#include <sys/cdefs.h>
1011+__KERNEL_RCSID(0, "$NetBSD: mach_bootstrap.c,v 1.14 2008/04/28 20:23:44 martin Exp $");
1012+
1013+#include <sys/types.h>
1014+#include <sys/param.h>
1015+#include <sys/systm.h>
1016+#include <sys/signal.h>
1017+#include <sys/proc.h>
1018+
1019+#include <compat/mach/mach_types.h>
1020+#include <compat/mach/mach_message.h>
1021+#include <compat/mach/mach_port.h>
1022+#include <compat/mach/mach_bootstrap.h>
1023+#include <compat/mach/mach_errno.h>
1024+#include <compat/mach/mach_services.h>
1025+
1026+int
1027+mach_bootstrap_look_up(struct mach_trap_args *args)
1028+{
1029+	mach_bootstrap_look_up_request_t *req = args->smsg;
1030+	mach_bootstrap_look_up_reply_t *rep = args->rmsg;
1031+	struct lwp *l = args->l;
1032+	size_t *msglen = args->rsize;
1033+	const char service_name[] = "lookup\021"; /* XXX Why */
1034+	int service_name_len;
1035+	struct mach_right *mr;
1036+	size_t len;
1037+
1038+	/* The trailer is word aligned  */
1039+	service_name_len = (sizeof(service_name) + 1) & ~0x7UL;
1040+	len = sizeof(*rep) - sizeof(rep->rep_service_name) + service_name_len;
1041+
1042+	if (len > *msglen)
1043+		return mach_msg_error(args, EINVAL);
1044+	*msglen = len;
1045+
1046+	mr = mach_right_get(NULL, l, MACH_PORT_TYPE_DEAD_NAME, 0);
1047+
1048+	mach_set_header(rep, req, *msglen);
1049+
1050+	rep->rep_count = 1;
1051+	rep->rep_bootstrap_port = mr->mr_name;
1052+	strncpy((char *)rep->rep_service_name, service_name,
1053+	    service_name_len);
1054+
1055+	mach_set_trailer(rep, *msglen);
1056+
1057+	return 0;
1058+}
1059+
1060diff --git a/sys/compat/mach/mach_bootstrap.h b/sys/compat/mach/mach_bootstrap.h
1061new file mode 100644
1062index 0000000..b798ace
1063--- /dev/null
1064+++ b/sys/compat/mach/mach_bootstrap.h
1065@@ -0,0 +1,52 @@
1066+/*	$NetBSD: mach_bootstrap.h,v 1.5 2008/04/28 20:23:44 martin Exp $ */
1067+
1068+/*-
1069+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
1070+ * All rights reserved.
1071+ *
1072+ * This code is derived from software contributed to The NetBSD Foundation
1073+ * by Emmanuel Dreyfus
1074+ *
1075+ * Redistribution and use in source and binary forms, with or without
1076+ * modification, are permitted provided that the following conditions
1077+ * are met:
1078+ * 1. Redistributions of source code must retain the above copyright
1079+ *    notice, this list of conditions and the following disclaimer.
1080+ * 2. Redistributions in binary form must reproduce the above copyright
1081+ *    notice, this list of conditions and the following disclaimer in the
1082+ *    documentation and/or other materials provided with the distribution.
1083+ *
1084+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1085+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1086+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1087+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1088+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1089+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1090+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1091+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1092+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1093+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1094+ * POSSIBILITY OF SUCH DAMAGE.
1095+ */
1096+
1097+#ifndef	_MACH_BOOTSTRAP_H_
1098+#define	_MACH_BOOTSTRAP_H_
1099+
1100+/* bootstrap_look_up */
1101+
1102+#define MACH_BOOTSTRAP_MAX_NAME_LEN 128
1103+typedef char mach_name_t[MACH_BOOTSTRAP_MAX_NAME_LEN];
1104+
1105+typedef struct {
1106+	mach_msg_header_t req_msgh;
1107+} mach_bootstrap_look_up_request_t;
1108+
1109+typedef struct {
1110+	mach_msg_header_t rep_msgh;
1111+	mach_integer_t rep_count;
1112+	mach_port_t rep_bootstrap_port;
1113+	mach_name_t rep_service_name;
1114+	mach_msg_trailer_t rep_trailer;
1115+} mach_bootstrap_look_up_reply_t;
1116+
1117+#endif /* _MACH_BOOTSTRAP_H_ */
1118diff --git a/sys/compat/mach/mach_clock.c b/sys/compat/mach/mach_clock.c
1119new file mode 100644
1120index 0000000..d802315
1121--- /dev/null
1122+++ b/sys/compat/mach/mach_clock.c
1123@@ -0,0 +1,135 @@
1124+/*	$NetBSD: mach_clock.c,v 1.19 2008/04/28 20:23:44 martin Exp $ */
1125+
1126+/*-
1127+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
1128+ * All rights reserved.
1129+ *
1130+ * This code is derived from software contributed to The NetBSD Foundation
1131+ * by Emmanuel Dreyfus
1132+ *
1133+ * Redistribution and use in source and binary forms, with or without
1134+ * modification, are permitted provided that the following conditions
1135+ * are met:
1136+ * 1. Redistributions of source code must retain the above copyright
1137+ *    notice, this list of conditions and the following disclaimer.
1138+ * 2. Redistributions in binary form must reproduce the above copyright
1139+ *    notice, this list of conditions and the following disclaimer in the
1140+ *    documentation and/or other materials provided with the distribution.
1141+ *
1142+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1143+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1144+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1145+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1146+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1147+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1148+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1149+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1150+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1151+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1152+ * POSSIBILITY OF SUCH DAMAGE.
1153+ */
1154+
1155+#include <sys/cdefs.h>
1156+__KERNEL_RCSID(0, "$NetBSD: mach_clock.c,v 1.19 2008/04/28 20:23:44 martin Exp $");
1157+
1158+#include <sys/types.h>
1159+#include <sys/param.h>
1160+#include <sys/kernel.h>
1161+#include <sys/systm.h>
1162+#include <sys/signal.h>
1163+#include <sys/proc.h>
1164+#include <sys/time.h>
1165+
1166+#include <compat/mach/mach_types.h>
1167+#include <compat/mach/mach_message.h>
1168+#include <compat/mach/mach_port.h>
1169+#include <compat/mach/mach_clock.h>
1170+#include <compat/mach/mach_services.h>
1171+#include <compat/mach/mach_syscallargs.h>
1172+
1173+int
1174+mach_sys_clock_sleep_trap(struct lwp *l, const struct mach_sys_clock_sleep_trap_args *uap, register_t *retval)
1175+{
1176+	/* {
1177+		syscallarg(mach_clock_port_t) clock_name;
1178+		syscallarg(mach_sleep_type_t) sleep_type;
1179+		syscallarg(int) sleep_sec;
1180+		syscallarg(int) sleep_nsec;
1181+		syscallarg(mach_timespec_t *) wakeup_time;
1182+	} */
1183+	struct timespec mts, cts, tts;
1184+	mach_timespec_t mcts;
1185+	int dontcare;
1186+	int error;
1187+	int ticks;
1188+
1189+	mts.tv_sec = SCARG(uap, sleep_sec);
1190+	mts.tv_nsec = SCARG(uap, sleep_nsec);
1191+
1192+	if (SCARG(uap, sleep_type) == MACH_TIME_ABSOLUTE) {
1193+		nanotime(&cts);
1194+		timespecsub(&mts, &cts, &tts);
1195+	} else {
1196+		tts.tv_sec = mts.tv_sec;
1197+		tts.tv_nsec = mts.tv_nsec;
1198+	}
1199+
1200+	ticks = tts.tv_sec * hz;
1201+	ticks += (tts.tv_nsec * hz) / 100000000L;
1202+
1203+	tsleep(&dontcare, PZERO|PCATCH, "sleep", ticks);
1204+
1205+	if (SCARG(uap, wakeup_time) != NULL) {
1206+		nanotime(&cts);
1207+		mcts.tv_sec = cts.tv_sec;
1208+		mcts.tv_nsec = cts.tv_nsec;
1209+		error = copyout(&mcts, SCARG(uap, wakeup_time), sizeof(mcts));
1210+		if (error != 0)
1211+			return error;
1212+	}
1213+
1214+	return 0;
1215+}
1216+
1217+int
1218+mach_sys_timebase_info(struct lwp *l, const struct mach_sys_timebase_info_args *uap, register_t *retval)
1219+{
1220+	/* {
1221+		syscallarg(mach_timebase_info_t) info;
1222+	} */
1223+	int error;
1224+	struct mach_timebase_info info;
1225+
1226+	/* XXX This is probably bus speed, fill it accurately */
1227+	info.numer = 4000000000UL;
1228+	info.denom = 75189611UL;
1229+
1230+	if ((error = copyout(&info, (void *)SCARG(uap, info),
1231+	    sizeof(info))) != 0)
1232+		return error;
1233+
1234+	return 0;
1235+}
1236+
1237+
1238+
1239+int
1240+mach_clock_get_time(struct mach_trap_args *args)
1241+{
1242+	mach_clock_get_time_request_t *req = args->smsg;
1243+	mach_clock_get_time_reply_t *rep = args->rmsg;
1244+	size_t *msglen = args->rsize;
1245+	struct timeval tv;
1246+
1247+	microtime(&tv);
1248+
1249+	*msglen = sizeof(*rep);
1250+	mach_set_header(rep, req, *msglen);
1251+
1252+	rep->rep_cur_time.tv_sec = tv.tv_sec;
1253+	rep->rep_cur_time.tv_nsec = tv.tv_usec * 1000;
1254+
1255+	mach_set_trailer(rep, *msglen);
1256+
1257+	return 0;
1258+}
1259diff --git a/sys/compat/mach/mach_clock.h b/sys/compat/mach/mach_clock.h
1260new file mode 100644
1261index 0000000..ea3584e
1262--- /dev/null
1263+++ b/sys/compat/mach/mach_clock.h
1264@@ -0,0 +1,64 @@
1265+/*	$NetBSD: mach_clock.h,v 1.8 2008/04/28 20:23:44 martin Exp $ */
1266+
1267+/*-
1268+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
1269+ * All rights reserved.
1270+ *
1271+ * This code is derived from software contributed to The NetBSD Foundation
1272+ * by Emmanuel Dreyfus
1273+ *
1274+ * Redistribution and use in source and binary forms, with or without
1275+ * modification, are permitted provided that the following conditions
1276+ * are met:
1277+ * 1. Redistributions of source code must retain the above copyright
1278+ *    notice, this list of conditions and the following disclaimer.
1279+ * 2. Redistributions in binary form must reproduce the above copyright
1280+ *    notice, this list of conditions and the following disclaimer in the
1281+ *    documentation and/or other materials provided with the distribution.
1282+ *
1283+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1284+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1285+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1286+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1287+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1288+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1289+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1290+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1291+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1292+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1293+ * POSSIBILITY OF SUCH DAMAGE.
1294+ */
1295+
1296+#ifndef	_MACH_CLOCK_H_
1297+#define	_MACH_CLOCK_H_
1298+
1299+#include <sys/types.h>
1300+#include <sys/param.h>
1301+#include <sys/signal.h>
1302+#include <sys/proc.h>
1303+
1304+#include <compat/mach/mach_types.h>
1305+#include <compat/mach/mach_message.h>
1306+
1307+/* clock_get_time */
1308+#define MACH_TIME_ABSOLUTE 0x00
1309+#define MACH_TIME_RELATIVE 0x01
1310+
1311+typedef struct {
1312+	unsigned int tv_sec;
1313+	int tv_nsec;
1314+} mach_timespec_t;
1315+
1316+typedef struct {
1317+	mach_msg_header_t req_msgh;
1318+} mach_clock_get_time_request_t;
1319+
1320+typedef struct {
1321+	mach_msg_header_t rep_msgh;
1322+	mach_ndr_record_t rep_ndr;
1323+	mach_kern_return_t rep_retval;
1324+	mach_timespec_t rep_cur_time;
1325+	mach_msg_trailer_t rep_trailer;
1326+} mach_clock_get_time_reply_t;
1327+
1328+#endif /* _MACH_CLOCK_H_ */
1329diff --git a/sys/compat/mach/mach_errno.c b/sys/compat/mach/mach_errno.c
1330new file mode 100644
1331index 0000000..7e59e98
1332--- /dev/null
1333+++ b/sys/compat/mach/mach_errno.c
1334@@ -0,0 +1,176 @@
1335+/*	$NetBSD: mach_errno.c,v 1.18 2008/04/28 20:23:44 martin Exp $ */
1336+
1337+/*-
1338+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
1339+ * All rights reserved.
1340+ *
1341+ * This code is derived from software contributed to The NetBSD Foundation
1342+ * by Emmanuel Dreyfus
1343+ *
1344+ * Redistribution and use in source and binary forms, with or without
1345+ * modification, are permitted provided that the following conditions
1346+ * are met:
1347+ * 1. Redistributions of source code must retain the above copyright
1348+ *    notice, this list of conditions and the following disclaimer.
1349+ * 2. Redistributions in binary form must reproduce the above copyright
1350+ *    notice, this list of conditions and the following disclaimer in the
1351+ *    documentation and/or other materials provided with the distribution.
1352+ *
1353+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1354+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1355+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1356+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1357+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1358+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1359+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1360+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1361+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1362+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1363+ * POSSIBILITY OF SUCH DAMAGE.
1364+ */
1365+
1366+#include <sys/cdefs.h>
1367+__KERNEL_RCSID(0, "$NetBSD: mach_errno.c,v 1.18 2008/04/28 20:23:44 martin Exp $");
1368+
1369+#include <sys/types.h>
1370+#include <sys/systm.h>
1371+#include <sys/null.h>
1372+#include <sys/queue.h>
1373+#include <sys/errno.h>
1374+
1375+#include <compat/mach/mach_types.h>
1376+#include <compat/mach/mach_message.h>
1377+#include <compat/mach/mach_errno.h>
1378+
1379+int native_to_mach_errno[] = {
1380+	MACH_KERN_SUCCESS,					/* 0 */
1381+	MACH_KERN_PROTECTION_FAILURE, 		/* EPERM */
1382+	MACH_KERN_FAILURE, 			/* ENOENT */
1383+	MACH_KERN_FAILURE, 			/* ESRCH */
1384+	MACH_KERN_FAILURE, 			/* EINTR */
1385+	MACH_KERN_FAILURE, 			/* EIO */	/* 5 */
1386+	MACH_KERN_FAILURE,			/* ENXIO */
1387+	MACH_KERN_FAILURE,			/* E2BIG */
1388+	MACH_KERN_FAILURE,			/* ENOEXEC */
1389+	MACH_KERN_FAILURE,			/* EBADF */
1390+	MACH_KERN_FAILURE,			/* ECHILD */	/* 10 */
1391+	MACH_KERN_FAILURE,			/* EDEADLK */
1392+	MACH_KERN_NO_SPACE,			/* ENOMEM */
1393+	MACH_KERN_FAILURE,			/* EACCES */
1394+	MACH_KERN_INVALID_ADDRESS,		/* EFAULT */
1395+	MACH_KERN_FAILURE,			/* ENOTBLK */	/* 15 */
1396+	MACH_KERN_FAILURE,			/* EBUSY */
1397+	MACH_KERN_FAILURE,			/* EEXIST */
1398+	MACH_KERN_FAILURE,			/* EXDEV */
1399+	MACH_KERN_FAILURE,			/* ENODEV */
1400+	MACH_KERN_FAILURE,			/* ENOTDIR */	/* 20 */
1401+	MACH_KERN_FAILURE,			/* EISDIR */
1402+	MACH_KERN_INVALID_ARGUMENT,		/* EINVAL */
1403+	MACH_KERN_FAILURE,			/* ENFILE */
1404+	MACH_KERN_FAILURE,			/* EMFILE */
1405+	MACH_KERN_FAILURE,			/* ENOTTY */	/* 25 */
1406+	MACH_KERN_FAILURE,			/* ETXTBSY */
1407+	MACH_KERN_FAILURE,			/* EFBIG */
1408+	MACH_KERN_FAILURE,			/* ENOSPC */
1409+	MACH_KERN_FAILURE,			/* ESPIPE */
1410+	MACH_KERN_FAILURE,			/* EROFS */	/* 30 */
1411+	MACH_KERN_FAILURE,			/* EMLINK */
1412+	MACH_KERN_FAILURE,			/* EPIPE */
1413+	MACH_KERN_FAILURE,			/* EDOM */
1414+	MACH_KERN_FAILURE,			/* ERANGE */
1415+	MACH_KERN_FAILURE,			/* EAGAIN */	/* 35 */
1416+	MACH_KERN_FAILURE,			/* EWOULDBLOCK */
1417+	MACH_KERN_FAILURE,			/* EINPROGRESS */
1418+	MACH_KERN_FAILURE,			/* EALREADY */
1419+	MACH_KERN_FAILURE,			/* ENOTSOCK */
1420+	MACH_KERN_FAILURE,			/* EDESTADDRREQ */ /* 40 */
1421+	MACH_KERN_FAILURE,			/* EMSGSIZE */
1422+	MACH_KERN_FAILURE,			/* EPROTOTYPE */
1423+	MACH_KERN_FAILURE,			/* ENOPROTOOPT */
1424+	MACH_KERN_FAILURE,			/* ESOCKTNOSUPPORT */
1425+	MACH_KERN_FAILURE,			/* EOPNOTSUPP */ /* 45 */
1426+	MACH_KERN_FAILURE,			/* EPFNOSUPPORT */
1427+	MACH_KERN_FAILURE,			/* EAFNOSUPPORT */
1428+	MACH_KERN_FAILURE,			/* EADDRINUSE */
1429+	MACH_KERN_FAILURE,			/* EADDRNOTAVAIL */
1430+	MACH_KERN_FAILURE,			/* ENETDOWN */	/* 50 */
1431+	MACH_KERN_FAILURE,			/* ENETUNREACH */
1432+	MACH_KERN_FAILURE,			/* ENETRESET */
1433+	MACH_KERN_FAILURE,			/* ECONNABORTED */
1434+	MACH_KERN_FAILURE,			/* ECONNRESET */
1435+	MACH_KERN_FAILURE,			/* ENOBUFS */	/* 55 */
1436+	MACH_KERN_FAILURE,			/* EISCONN */
1437+	MACH_KERN_FAILURE,			/* ENOTCONN */
1438+	MACH_KERN_FAILURE,			/* ESHUTDOWN */
1439+	MACH_KERN_FAILURE,			/* ETOOMANYREFS */
1440+	MACH_KERN_FAILURE,			/* ETIMEDOUT */	/* 60 */
1441+	MACH_KERN_FAILURE,			/* ECONNREFUSED */
1442+	MACH_KERN_FAILURE,			/* ELOOP */
1443+	MACH_KERN_FAILURE,			/* ENAMETOOLONG */
1444+	MACH_KERN_FAILURE,			/* EHOSTDOWN */
1445+	MACH_KERN_FAILURE,			/* EHOSTUNREACH */ /* 65 */
1446+	MACH_KERN_FAILURE,			/* ENOTEMPTY */
1447+	MACH_KERN_FAILURE,			/* EPROCLIM */
1448+	MACH_KERN_FAILURE,			/* EUSERS */
1449+	MACH_KERN_FAILURE,			/* EDQUOT */
1450+	MACH_KERN_FAILURE,			/* ESTALE */	/* 70 */
1451+	MACH_KERN_FAILURE,			/* EREMOTE */
1452+	MACH_KERN_FAILURE,			/* EBADRPC */
1453+	MACH_KERN_FAILURE,			/* ERPCMISMATCH */
1454+	MACH_KERN_FAILURE,			/* EPROGUNAVAIL */
1455+	MACH_KERN_FAILURE,			/* EPROGMISMATCH */ /* 75 */
1456+	MACH_KERN_FAILURE,			/* EPROCUNAVAIL */
1457+	MACH_KERN_FAILURE,			/* ENOLCK */
1458+	MACH_KERN_FAILURE,			/* ENOSYS */
1459+	MACH_KERN_FAILURE,			/* EFTYPE */
1460+	MACH_KERN_FAILURE,			/* EAUTH */	/* 80 */
1461+	MACH_KERN_FAILURE,			/* ENEEDAUTH */
1462+	MACH_KERN_FAILURE,			/* EIDRM */
1463+	MACH_KERN_FAILURE,			/* ENOMSG */
1464+	MACH_KERN_FAILURE,			/* EOVERFLOW */
1465+	MACH_KERN_FAILURE,			/* EILSEQ */	/* 85 */
1466+};
1467+
1468+int
1469+mach_msg_error(struct mach_trap_args *args, int error)
1470+{
1471+	mach_msg_header_t *req = args->smsg;
1472+	mach_error_reply_t *rep = args->rmsg;
1473+	size_t *msglen = args->rsize;
1474+
1475+	*msglen = sizeof(*rep);
1476+	mach_set_header(rep, req, *msglen);
1477+
1478+	rep->rep_retval = native_to_mach_errno[error];
1479+
1480+	mach_set_trailer(rep, *msglen);
1481+
1482+#ifdef DEBUG_MACH
1483+	if (error != 0)
1484+		printf("failure in kernel service %d (err %x, native %d)\n",
1485+		    req->msgh_id, (int)rep->rep_retval, error);
1486+#endif
1487+	return 0;
1488+}
1489+
1490+int
1491+mach_iokit_error(struct mach_trap_args *args, int error)
1492+{
1493+	mach_msg_header_t *req = args->smsg;
1494+	mach_error_reply_t *rep = args->rmsg;
1495+	size_t *msglen = args->rsize;
1496+
1497+	*msglen = sizeof(*rep);
1498+	mach_set_header(rep, req, *msglen);
1499+
1500+	rep->rep_retval = error;
1501+
1502+#ifdef DEBUG_MACH
1503+	if (error != 0)
1504+		printf("failure in kernel service %d (Mach err %x)\n",
1505+		    req->msgh_id, error);
1506+#endif
1507+	mach_set_trailer(rep, *msglen);
1508+
1509+	return 0;
1510+}
1511diff --git a/sys/compat/mach/mach_errno.h b/sys/compat/mach/mach_errno.h
1512new file mode 100644
1513index 0000000..8a45e5c
1514--- /dev/null
1515+++ b/sys/compat/mach/mach_errno.h
1516@@ -0,0 +1,106 @@
1517+/*	$NetBSD: mach_errno.h,v 1.9 2008/04/28 20:23:44 martin Exp $ */
1518+
1519+/*-
1520+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
1521+ * All rights reserved.
1522+ *
1523+ * This code is derived from software contributed to The NetBSD Foundation
1524+ * by Emmanuel Dreyfus
1525+ *
1526+ * Redistribution and use in source and binary forms, with or without
1527+ * modification, are permitted provided that the following conditions
1528+ * are met:
1529+ * 1. Redistributions of source code must retain the above copyright
1530+ *    notice, this list of conditions and the following disclaimer.
1531+ * 2. Redistributions in binary form must reproduce the above copyright
1532+ *    notice, this list of conditions and the following disclaimer in the
1533+ *    documentation and/or other materials provided with the distribution.
1534+ *
1535+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1536+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1537+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1538+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1539+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1540+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1541+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1542+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1543+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1544+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1545+ * POSSIBILITY OF SUCH DAMAGE.
1546+ */
1547+
1548+#ifndef _MACH_ERRNO_H_
1549+#define _MACH_ERRNO_H_
1550+
1551+extern int native_to_mach_errno[];
1552+
1553+#define MACH_KERN_SUCCESS			0
1554+#define MACH_KERN_INVALID_ADDRESS		1
1555+#define MACH_KERN_PROTECTION_FAILURE		2
1556+#define MACH_KERN_NO_SPACE			3
1557+#define MACH_KERN_INVALID_ARGUMENT		4
1558+#define MACH_KERN_FAILURE			5
1559+#define MACH_KERN_RESOURCE_SHORTAGE		6
1560+#define MACH_KERN_NOT_RECEIVER			7
1561+#define MACH_KERN_NO_ACCESS			8
1562+#define MACH_KERN_MEMORY_FAILURE		9
1563+#define MACH_KERN_MEMORY_ERROR			10
1564+#define	MACH_KERN_ALREADY_IN_SET		11
1565+#define MACH_KERN_NOT_IN_SET			12
1566+#define MACH_KERN_NAME_EXISTS			13
1567+#define MACH_KERN_ABORTED			14
1568+#define MACH_KERN_INVALID_NAME			15
1569+#define	MACH_KERN_INVALID_TASK			16
1570+#define MACH_KERN_INVALID_RIGHT			17
1571+#define MACH_KERN_INVALID_VALUE			18
1572+#define	MACH_KERN_UREFS_OVERFLOW		19
1573+#define	MACH_KERN_INVALID_CAPABILITY		20
1574+#define MACH_KERN_RIGHT_EXISTS			21
1575+#define	MACH_KERN_INVALID_HOST			22
1576+#define MACH_KERN_MEMORY_PRESENT		23
1577+#define MACH_KERN_MEMORY_DATA_MOVED		24
1578+#define MACH_KERN_MEMORY_RESTART_COPY		25
1579+#define MACH_KERN_INVALID_PROCESSOR_SET		26
1580+#define MACH_KERN_POLICY_LIMIT			27
1581+#define MACH_KERN_INVALID_POLICY		28
1582+#define MACH_KERN_INVALID_OBJECT		29
1583+#define MACH_KERN_ALREADY_WAITING		30
1584+#define MACH_KERN_DEFAULT_SET			31
1585+#define MACH_KERN_EXCEPTION_PROTECTED		32
1586+#define MACH_KERN_INVALID_LEDGER		33
1587+#define MACH_KERN_INVALID_MEMORY_CONTROL	34
1588+#define MACH_KERN_INVALID_SECURITY		35
1589+#define MACH_KERN_NOT_DEPRESSED			36
1590+#define MACH_KERN_TERMINATED			37
1591+#define MACH_KERN_LOCK_SET_DESTROYED		38
1592+#define MACH_KERN_LOCK_UNSTABLE			39
1593+#define MACH_KERN_LOCK_OWNED			40
1594+#define MACH_KERN_LOCK_OWNED_SELF		41
1595+#define MACH_KERN_SEMAPHORE_DESTROYED		42
1596+#define MACH_KERN_RPC_SERVER_TERMINATED		43
1597+#define MACH_KERN_RPC_TERMINATE_ORPHAN		44
1598+#define MACH_KERN_RPC_CONTINUE_ORPHAN		45
1599+#define	MACH_KERN_NOT_SUPPORTED			46
1600+#define	MACH_KERN_NODE_DOWN			47
1601+#define MACH_KERN_NOT_WAITING			48
1602+#define	MACH_KERN_OPERATION_TIMED_OUT		49
1603+
1604+/* IOKit errors */
1605+#define MACH_IOKIT_ENOMEM       0xe00002bd
1606+#define MACH_IOKIT_ENODEV       0xe00002c0
1607+#define MACH_IOKIT_EAGAIN       0xe00002be
1608+#define MACH_IOKIT_EPERM        0xe00002c1
1609+#define MACH_IOKIT_EINVAL       0xe00002c2
1610+#define MACH_IOKIT_ENOENT	0xe00002f0
1611+
1612+typedef struct {
1613+	mach_msg_header_t rep_msgh;
1614+	mach_ndr_record_t rep_ndr;
1615+	mach_kern_return_t rep_retval;
1616+	mach_msg_trailer_t rep_trailer;
1617+} mach_error_reply_t;
1618+
1619+int mach_msg_error(struct mach_trap_args *, int);
1620+int mach_iokit_error(struct mach_trap_args *, int);
1621+
1622+#endif	/* _MACH_ERRNO_H_ */
1623diff --git a/sys/compat/mach/mach_exception.c b/sys/compat/mach/mach_exception.c
1624new file mode 100644
1625index 0000000..907e122
1626--- /dev/null
1627+++ b/sys/compat/mach/mach_exception.c
1628@@ -0,0 +1,530 @@
1629+/*	$NetBSD: mach_exception.c,v 1.14 2009/03/14 21:04:18 dsl Exp $ */
1630+
1631+/*-
1632+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
1633+ * All rights reserved.
1634+ *
1635+ * This code is derived from software contributed to The NetBSD Foundation
1636+ * by Emmanuel Dreyfus
1637+ *
1638+ * Redistribution and use in source and binary forms, with or without
1639+ * modification, are permitted provided that the following conditions
1640+ * are met:
1641+ * 1. Redistributions of source code must retain the above copyright
1642+ *    notice, this list of conditions and the following disclaimer.
1643+ * 2. Redistributions in binary form must reproduce the above copyright
1644+ *    notice, this list of conditions and the following disclaimer in the
1645+ *    documentation and/or other materials provided with the distribution.
1646+ *
1647+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1648+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1649+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1650+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1651+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1652+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1653+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1654+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1655+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1656+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1657+ * POSSIBILITY OF SUCH DAMAGE.
1658+ */
1659+
1660+#include <sys/cdefs.h>
1661+__KERNEL_RCSID(0, "$NetBSD: mach_exception.c,v 1.14 2009/03/14 21:04:18 dsl Exp $");
1662+
1663+#include "opt_compat_darwin.h"
1664+
1665+#include <sys/types.h>
1666+#include <sys/param.h>
1667+#include <sys/signal.h>
1668+#include <sys/proc.h>
1669+#include <sys/malloc.h>
1670+
1671+#ifdef COMPAT_DARWIN
1672+#include <compat/darwin/darwin_exec.h>
1673+#endif
1674+
1675+#include <compat/mach/mach_types.h>
1676+#include <compat/mach/mach_exec.h>
1677+#include <compat/mach/mach_errno.h>
1678+#include <compat/mach/mach_thread.h>
1679+#include <compat/mach/mach_exception.h>
1680+#include <compat/mach/mach_message.h>
1681+#include <compat/mach/mach_services.h>
1682+#include <compat/mach/mach_sysctl.h>
1683+
1684+#include <machine/mach_machdep.h>
1685+
1686+static void mach_siginfo_to_exception(const struct ksiginfo *, int *);
1687+
1688+/*
1689+ * Exception handler
1690+ * Mach does not use signals. But systems based on Mach (e.g.: Darwin),
1691+ * can use both Mach exceptions and UNIX signals. In order to allow the
1692+ * Mach layer to intercept the exception and inhibit UNIX signals, we have
1693+ * mach_trapsignal1 returning an error. If it returns 0, then the
1694+ * exception was intercepted at the Mach level, and no signal should
1695+ * be produced. Else, a signal might be sent. darwin_trapinfo calls
1696+ * mach_trapinfo1 and handle signals if it gets a non zero return value.
1697+ */
1698+void
1699+mach_trapsignal(struct lwp *l, struct ksiginfo *ksi)
1700+{
1701+	if (mach_trapsignal1(l, ksi) != 0)
1702+		trapsignal(l, ksi);
1703+	return;
1704+}
1705+
1706+int
1707+mach_trapsignal1(struct lwp *l, struct ksiginfo *ksi)
1708+{
1709+	struct proc *p = l->l_proc;
1710+	struct mach_emuldata *med;
1711+	int exc_no;
1712+	int code[2];
1713+
1714+	/* Don't inhinbit non maskable signals */
1715+	if (sigprop[ksi->ksi_signo] & SA_CANTMASK)
1716+		return EINVAL;
1717+
1718+	med = (struct mach_emuldata *)p->p_emuldata;
1719+
1720+	switch (ksi->ksi_signo) {
1721+	case SIGILL:
1722+		exc_no = MACH_EXC_BAD_INSTRUCTION;
1723+		break;
1724+	case SIGFPE:
1725+		exc_no = MACH_EXC_ARITHMETIC;
1726+		break;
1727+	case SIGSEGV:
1728+	case SIGBUS:
1729+		exc_no = MACH_EXC_BAD_ACCESS;
1730+		break;
1731+	case SIGTRAP:
1732+		exc_no = MACH_EXC_BREAKPOINT;
1733+		break;
1734+	default: /* SIGCHLD, SIGPOLL */
1735+		return EINVAL;
1736+		break;
1737+	}
1738+
1739+	mach_siginfo_to_exception(ksi, code);
1740+
1741+	return mach_exception(l, exc_no, code);
1742+}
1743+
1744+int
1745+mach_exception(struct lwp *exc_l, int exc, int *code)
1746+	/* exc_l:	 currently running lwp */
1747+{
1748+	int behavior, flavor;
1749+	mach_msg_header_t *msgh;
1750+	size_t msglen;
1751+	struct mach_right *exc_mr;
1752+	struct mach_emuldata *exc_med;
1753+	struct mach_lwp_emuldata *exc_mle;
1754+	struct mach_emuldata *catcher_med;
1755+	struct mach_right *kernel_mr;
1756+	struct lwp *catcher_l;	/* The lwp catching the exception */
1757+	struct mach_right *exc_task;
1758+	struct mach_right *exc_thread;
1759+	struct mach_port *exc_port;
1760+	struct mach_exc_info *mei;
1761+	int error = 0;
1762+
1763+#ifdef DIAGNOSTIC
1764+	if (exc_l == NULL) {
1765+		printf("mach_exception: exc_l = %p\n", exc_l);
1766+		return ESRCH;
1767+	}
1768+#endif
1769+#ifdef DEBUG_MACH
1770+	printf("mach_exception: %d.%d, exc %d, code (%d, %d)\n",
1771+	    exc_l->l_proc->p_pid, exc_l->l_lid, exc, code[0], code[1]);
1772+#endif
1773+
1774+	/*
1775+	 * It's extremely useful to have the ability of catching
1776+	 * the process at the time it dies.
1777+	 */
1778+	if (mach_exception_hang) {
1779+		struct proc *p = exc_l->l_proc;
1780+
1781+		sigminusset(&contsigmask, &exc_l->l_sigpendset->sp_set);
1782+		lwp_lock(exc_l);
1783+		p->p_pptr->p_nstopchild++;
1784+		p->p_stat = SSTOP;
1785+		exc_l->l_stat = LSSTOP;
1786+		p->p_nrlwps--;
1787+		KERNEL_UNLOCK_ALL(exc_l, &exc_l->l_biglocks);
1788+		mi_switch(exc_l);
1789+		KERNEL_LOCK(exc_l->l_biglocks, exc_l);
1790+	}
1791+
1792+	/*
1793+	 * No exception if there is no exception port or if it has no receiver
1794+	 */
1795+	exc_mle = exc_l->l_emuldata;
1796+	exc_med = exc_l->l_proc->p_emuldata;
1797+	if ((exc_port = exc_med->med_exc[exc]) == NULL)
1798+		return EINVAL;
1799+
1800+	MACH_PORT_REF(exc_port);
1801+	if (exc_port->mp_recv == NULL) {
1802+		error = EINVAL;
1803+		goto out;
1804+	}
1805+
1806+#ifdef DEBUG_MACH
1807+	printf("catcher is %d.%d, state %d\n",
1808+	    exc_port->mp_recv->mr_lwp->l_proc->p_pid,
1809+	    exc_port->mp_recv->mr_lwp->l_lid,
1810+	    exc_port->mp_recv->mr_lwp->l_proc->p_stat);
1811+#endif
1812+	/*
1813+	 * Don't send exceptions to dying processes
1814+	 */
1815+	if (P_ZOMBIE(exc_port->mp_recv->mr_lwp->l_proc)) {
1816+		error = ESRCH;
1817+		goto out;
1818+	}
1819+
1820+	/*
1821+	 * XXX Avoid a nasty deadlock because process in TX state
1822+	 * (traced and suspended) are invulnerable to kill -9.
1823+	 *
1824+	 * The scenario:
1825+	 * - the parent gets Child's signals though Mach exceptions
1826+	 * - the parent is killed. Before calling the emulation hook
1827+	 *   mach_exit(), it will wait for the child
1828+	 * - the child receives SIGHUP, which is turned into a Mach
1829+	 *   exception. The child sleeps awaiting for the parent
1830+	 *   to tell it to continue.
1831+	 *   For some reason I do not understand, it goes in the
1832+	 *   suspended state instead of the sleeping state.
1833+	 * - Parents waits for the child, child is suspended, we
1834+	 *   are stuck.
1835+	 *
1836+	 * By preventing exception to traced processes with
1837+	 * a dying parent, a signal is sent instead of the
1838+	 * notification, this fixes the problem.
1839+	 */
1840+	if ((exc_l->l_proc->p_slflag & PSL_TRACED) &&
1841+	    (exc_l->l_proc->p_pptr->p_sflag & PS_WEXIT)) {
1842+#ifdef DEBUG_MACH
1843+		printf("mach_exception: deadlock avoided\n");
1844+#endif
1845+		error = EINVAL;
1846+		goto out;
1847+	}
1848+
1849+	if (exc_port->mp_datatype != MACH_MP_EXC_INFO) {
1850+#ifdef DIAGNOSTIC
1851+		printf("mach_exception: unexpected datatype");
1852+#endif
1853+		error = EINVAL;
1854+		goto out;
1855+	}
1856+	mei = exc_port->mp_data;
1857+	behavior = mei->mei_behavior;
1858+	flavor = mei->mei_flavor;
1859+
1860+	/*
1861+	 * We want the port names in the target process, that is,
1862+	 * the process with receive right for exc_port.
1863+	 */
1864+	catcher_l = exc_port->mp_recv->mr_lwp;
1865+	catcher_med = catcher_l->l_proc->p_emuldata;
1866+	exc_mr = mach_right_get(exc_port, catcher_l, MACH_PORT_TYPE_SEND, 0);
1867+	kernel_mr = mach_right_get(catcher_med->med_kernel,
1868+	    catcher_l, MACH_PORT_TYPE_SEND, 0);
1869+
1870+	exc_task = mach_right_get(exc_med->med_kernel,
1871+	    catcher_l, MACH_PORT_TYPE_SEND, 0);
1872+	exc_thread = mach_right_get(exc_mle->mle_kernel,
1873+	    catcher_l, MACH_PORT_TYPE_SEND, 0);
1874+
1875+	switch (behavior) {
1876+	case MACH_EXCEPTION_DEFAULT: {
1877+		mach_exception_raise_request_t *req;
1878+
1879+		req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO);
1880+		msglen = sizeof(*req);
1881+		msgh = (mach_msg_header_t *)req;
1882+
1883+		req->req_msgh.msgh_bits =
1884+		    MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND) |
1885+		    MACH_MSGH_REMOTE_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
1886+		req->req_msgh.msgh_size =
1887+		    sizeof(*req) - sizeof(req->req_trailer);
1888+		req->req_msgh.msgh_remote_port = kernel_mr->mr_name;
1889+		req->req_msgh.msgh_local_port = exc_mr->mr_name;
1890+		req->req_msgh.msgh_id = MACH_EXC_RAISE_MSGID;
1891+
1892+		mach_add_port_desc(req, exc_thread->mr_name);
1893+		mach_add_port_desc(req, exc_task->mr_name);
1894+
1895+		req->req_exc = exc;
1896+		req->req_codecount = 2;
1897+		memcpy(&req->req_code[0], code, sizeof(req->req_code));
1898+
1899+		mach_set_trailer(req, msglen);
1900+
1901+		break;
1902+	}
1903+
1904+	case MACH_EXCEPTION_STATE: {
1905+		mach_exception_raise_state_request_t *req;
1906+		int dc;
1907+
1908+		req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO);
1909+		msglen = sizeof(*req);
1910+		msgh = (mach_msg_header_t *)req;
1911+
1912+		req->req_msgh.msgh_bits =
1913+		    MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND) |
1914+		    MACH_MSGH_REMOTE_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
1915+		req->req_msgh.msgh_size =
1916+		    sizeof(*req) - sizeof(req->req_trailer);
1917+		req->req_msgh.msgh_remote_port = kernel_mr->mr_name;
1918+		req->req_msgh.msgh_local_port = exc_mr->mr_name;
1919+		req->req_msgh.msgh_id = MACH_EXCEPTION_STATE;
1920+		req->req_exc = exc;
1921+		req->req_codecount = 2;
1922+		memcpy(&req->req_code[0], code, sizeof(req->req_code));
1923+		req->req_flavor = flavor;
1924+		mach_thread_get_state_machdep(exc_l,
1925+		    flavor, req->req_state, &dc);
1926+
1927+		msglen = msglen -
1928+			 sizeof(req->req_state) +
1929+			 (dc * sizeof(req->req_state[0]));
1930+		mach_set_trailer(req, msglen);
1931+
1932+		break;
1933+	}
1934+
1935+	case MACH_EXCEPTION_STATE_IDENTITY: {
1936+		mach_exception_raise_state_identity_request_t *req;
1937+		int dc;
1938+
1939+		req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO);
1940+		msglen = sizeof(*req);
1941+		msgh = (mach_msg_header_t *)req;
1942+
1943+		req->req_msgh.msgh_bits =
1944+		    MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND) |
1945+		    MACH_MSGH_REMOTE_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
1946+		req->req_msgh.msgh_size =
1947+		    sizeof(*req) - sizeof(req->req_trailer);
1948+		req->req_msgh.msgh_remote_port = kernel_mr->mr_name;
1949+		req->req_msgh.msgh_local_port = exc_mr->mr_name;
1950+		req->req_msgh.msgh_id = MACH_EXC_RAISE_STATE_IDENTITY_MSGID;
1951+		req->req_body.msgh_descriptor_count = 2;
1952+
1953+		mach_add_port_desc(req, exc_thread->mr_name);
1954+		mach_add_port_desc(req, exc_task->mr_name);
1955+
1956+		req->req_exc = exc;
1957+		req->req_codecount = 2;
1958+		memcpy(&req->req_code[0], code, sizeof(req->req_code));
1959+		req->req_flavor = flavor;
1960+		mach_thread_get_state_machdep(exc_l,
1961+		    flavor, req->req_state, &dc);
1962+
1963+		msglen = msglen -
1964+			 sizeof(req->req_state) +
1965+			 (dc * sizeof(req->req_state[0]));
1966+
1967+		mach_set_trailer(req, msglen);
1968+
1969+		break;
1970+	}
1971+
1972+	default:
1973+		printf("unknown exception bevahior %d\n", behavior);
1974+		error = EINVAL;
1975+		goto out;
1976+		break;
1977+	}
1978+
1979+	mach_set_trailer(msgh, msglen);
1980+
1981+	/*
1982+	 * Once an exception is sent on the exception port,
1983+	 * no new exception will be taken until the catcher
1984+	 * acknowledge the first one.
1985+	 */
1986+	rw_enter(&catcher_med->med_exclock, RW_WRITER);
1987+
1988+	/*
1989+	 * If the catcher died, we are done.
1990+	 */
1991+	if (((exc_port = exc_med->med_exc[exc]) == NULL) ||
1992+	    (exc_port->mp_recv == NULL) ||
1993+	    (P_ZOMBIE(exc_port->mp_recv->mr_lwp->l_proc))) {
1994+		error = ESRCH;
1995+		goto out;
1996+	}
1997+
1998+	(void)mach_message_get(msgh, msglen, exc_port, NULL);
1999+	wakeup(exc_port->mp_recv->mr_sethead);
2000+
2001+	/*
2002+	 * The thread that caused the exception is now
2003+	 * supposed to wait for a reply to its message.
2004+	 */
2005+#ifdef DEBUG_MACH
2006+	printf("mach_exception: %d.%d sleep on catcher_med->med_exclock = %p\n",
2007+	    exc_l->l_proc->p_pid, exc_l->l_lid, &catcher_med->med_exclock);
2008+#endif
2009+	error = tsleep(&catcher_med->med_exclock, PZERO, "mach_exc", 0);
2010+#ifdef DEBUG_MACH
2011+	printf("mach_exception: %d.%d resumed, error = %d\n",
2012+	    exc_l->l_proc->p_pid, exc_l->l_lid, error);
2013+#endif
2014+
2015+	/*
2016+	 * Unlock the catcher's exception handler
2017+	 */
2018+	rw_exit(&catcher_med->med_exclock);
2019+
2020+out:
2021+	MACH_PORT_UNREF(exc_port);
2022+	return error;
2023+}
2024+
2025+static void
2026+mach_siginfo_to_exception(const struct ksiginfo *ksi, int *code)
2027+{
2028+	code[1] = (long)ksi->ksi_addr;
2029+	switch (ksi->ksi_signo) {
2030+	case SIGBUS:
2031+		switch (ksi->ksi_code) {
2032+		case BUS_ADRALN:
2033+			code[0] = MACH_BUS_ADRALN;
2034+			break;
2035+		default:
2036+			printf("untranslated siginfo signo %d, code %d\n",
2037+			    ksi->ksi_signo, ksi->ksi_code);
2038+			break;
2039+		}
2040+		break;
2041+
2042+	case SIGSEGV:
2043+		switch (ksi->ksi_code) {
2044+		case SEGV_MAPERR:
2045+			code[0] = MACH_SEGV_MAPERR;
2046+			break;
2047+		case SEGV_ACCERR:
2048+			code[0] = MACH_SEGV_ACCERR;
2049+			break;
2050+		default:
2051+			printf("untranslated siginfo signo %d, code %d\n",
2052+			    ksi->ksi_signo, ksi->ksi_code);
2053+			break;
2054+		}
2055+		break;
2056+
2057+	case SIGTRAP:
2058+		switch (ksi->ksi_code) {
2059+		case TRAP_BRKPT:
2060+			code[0] = MACH_TRAP_BRKPT;
2061+			code[1] = (long)ksi->ksi_addr;
2062+			break;
2063+		default:
2064+			printf("untranslated siginfo signo %d, code %d\n",
2065+			    ksi->ksi_signo, ksi->ksi_code);
2066+			break;
2067+		}
2068+		break;
2069+
2070+	case SIGILL:
2071+		switch (ksi->ksi_code) {
2072+		case ILL_ILLOPC:
2073+		case ILL_ILLOPN:
2074+		case ILL_ILLADR:
2075+			code[0] = MACH_ILL_ILLOPC;
2076+			break;
2077+		case ILL_PRVOPC:
2078+		case ILL_PRVREG:
2079+			code[0] = MACH_ILL_PRVOPC;
2080+			break;
2081+		case ILL_ILLTRP:
2082+			code[0] = MACH_ILL_ILLTRP;
2083+			break;
2084+		default:
2085+			printf("untranslated siginfo signo %d, code %d\n",
2086+			    ksi->ksi_signo, ksi->ksi_code);
2087+			break;
2088+		}
2089+		break;
2090+
2091+	default:
2092+		printf("untranslated siginfo signo %d, code %d\n",
2093+		    ksi->ksi_signo, ksi->ksi_code);
2094+		break;
2095+	}
2096+}
2097+
2098+int
2099+mach_exception_raise(struct mach_trap_args *args)
2100+{
2101+	struct lwp *l = args->l;
2102+	mach_exception_raise_reply_t *rep;
2103+	struct mach_emuldata *med;
2104+
2105+	/*
2106+	 * No typo here: the reply is in the sent message.
2107+	 * The kernel is acting as a client that gets the
2108+	 * reply message to its exception message.
2109+	 */
2110+	rep = args->smsg;
2111+
2112+	/*
2113+	 * This message is sent by the process catching the
2114+	 * exception to release the process that raised the exception.
2115+	 * We wake it up if the return value is 0 (no error), else
2116+	 * we should ignore this message.
2117+	 */
2118+#ifdef DEBUG_MACH
2119+	printf("mach_excpetion_raise: retval = %ld\n", (long)rep->rep_retval);
2120+#endif
2121+	if (rep->rep_retval != 0)
2122+		return 0;
2123+
2124+	med = l->l_proc->p_emuldata;
2125+
2126+	/*
2127+	 * Check for unexpected exception acknowledge, whereas
2128+	 * the kernel sent no exception message.
2129+	 */
2130+	if (!rw_lock_held(&med->med_exclock)) {
2131+#ifdef DEBUG_MACH
2132+		printf("spurious mach_exception_raise\n");
2133+#endif
2134+		return mach_msg_error(args, EINVAL);
2135+	}
2136+
2137+	/*
2138+	 * Wakeup the thread that raised the exception.
2139+	 */
2140+#ifdef DEBUG_MACH
2141+	printf("mach_exception_raise: wakeup at %p\n", &med->med_exclock);
2142+#endif
2143+	wakeup(&med->med_exclock);
2144+
2145+	return 0;
2146+}
2147+
2148+int
2149+mach_exception_raise_state(struct mach_trap_args *args)
2150+{
2151+	return mach_exception_raise(args);
2152+}
2153+
2154+int
2155+mach_exception_raise_state_identity(struct mach_trap_args *args)
2156+{
2157+	return mach_exception_raise(args);
2158+}
2159diff --git a/sys/compat/mach/mach_exception.h b/sys/compat/mach/mach_exception.h
2160new file mode 100644
2161index 0000000..de1e630
2162--- /dev/null
2163+++ b/sys/compat/mach/mach_exception.h
2164@@ -0,0 +1,160 @@
2165+/*	$NetBSD: mach_exception.h,v 1.8 2008/04/28 20:23:44 martin Exp $ */
2166+
2167+/*-
2168+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
2169+ * All rights reserved.
2170+ *
2171+ * This code is derived from software contributed to The NetBSD Foundation
2172+ * by Emmanuel Dreyfus
2173+ *
2174+ * Redistribution and use in source and binary forms, with or without
2175+ * modification, are permitted provided that the following conditions
2176+ * are met:
2177+ * 1. Redistributions of source code must retain the above copyright
2178+ *    notice, this list of conditions and the following disclaimer.
2179+ * 2. Redistributions in binary form must reproduce the above copyright
2180+ *    notice, this list of conditions and the following disclaimer in the
2181+ *    documentation and/or other materials provided with the distribution.
2182+ *
2183+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2184+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2185+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2186+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2187+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2188+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2189+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2190+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2191+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2192+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2193+ * POSSIBILITY OF SUCH DAMAGE.
2194+ */
2195+
2196+#ifndef _MACH_EXCEPTION_H_
2197+#define _MACH_EXCEPTION_H_
2198+
2199+/* really should be in mach_signal.h or siginfo.h */
2200+#define MACH_BUS_ADRALN         1
2201+
2202+#define MACH_SEGV_MAPERR        1
2203+#define MACH_SEGV_ACCERR        2
2204+
2205+#define MACH_TRAP_BRKPT         1
2206+
2207+#define MACH_ILL_ILLOPC         1
2208+#define MACH_ILL_ILLTRP         2
2209+#define MACH_ILL_PRVOPC         3
2210+
2211+#define MACH_EXC_BAD_ACCESS		1
2212+#define MACH_EXC_BAD_INSTRUCTION	2
2213+#define MACH_EXC_ARITHMETIC		3
2214+#define MACH_EXC_EMULATION		4
2215+#define MACH_EXC_SOFTWARE		5
2216+#define MACH_EXC_BREAKPOINT		6
2217+#define MACH_EXC_SYSCALL		7
2218+#define MACH_EXC_MACH_SYSCALL		8
2219+#define MACH_EXC_RPC_ALERT		9
2220+#define MACH_EXC_MAX			MACH_EXC_RPC_ALERT
2221+
2222+#define MACH_EXC_MASK_BAD_ACCESS	(1 << MACH_EXC_BAD_ACCESS)
2223+#define MACH_EXC_MASK_BAD_INSTRUCTION	(1 << MACH_EXC_BAD_INSTRUCTION)
2224+#define MACH_EXC_MASK_ARITHMETIC	(1 << MACH_EXC_ARITHMETIC)
2225+#define MACH_EXC_MASK_EMULATION		(1 << MACH_EXC_EMULATION)
2226+#define MACH_EXC_MASK_SOFTWARE		(1 << MACH_EXC_SOFTWARE)
2227+#define MACH_EXC_MASK_BREAKPOINT	(1 << MACH_EXC_BREAKPOINT)
2228+#define MACH_EXC_MASK_SYSCALL		(1 << MACH_EXC_SYSCALL)
2229+#define MACH_EXC_MASK_MACH_SYSCALL	(1 << MACH_EXC_MACH_SYSCALL)
2230+#define MACH_EXC_MASK_RPC_ALERT		(1 << MACH_EXC_RPC_ALERT)
2231+
2232+/*
2233+ * Exception codes. Values < 0x10000 are machine dependent, and
2234+ * are defined in sys/<arch>/include/mach_machdep.h.
2235+ */
2236+#define MACH_EXC_UNIX_BAD_SYSCALL	0x10000	/* unused ? */
2237+#define MACH_EXC_UNIX_BAD_PIPE		0x10001	/* unused ? */
2238+#define MACH_EXC_UNIX_ABORT		0x10002 /* unused ? */
2239+#define MACH_SOFT_SIGNAL		0x10003
2240+
2241+/* Exception behaviors and associated messages Id */
2242+
2243+#define MACH_EXCEPTION_DEFAULT		1
2244+#define MACH_EXCEPTION_STATE		2
2245+#define MACH_EXCEPTION_STATE_IDENTITY	3
2246+
2247+#define MACH_EXC_RAISE_MSGID		2401
2248+#define MACH_EXC_RAISE_STATE_MSGID	2402
2249+#define MACH_EXC_RAISE_STATE_IDENTITY_MSGID	2403
2250+
2251+/* exception_raise. The kernel is the client, not the server */
2252+
2253+typedef struct {
2254+	mach_msg_header_t req_msgh;
2255+	mach_msg_body_t req_body;
2256+	mach_msg_port_descriptor_t req_thread;
2257+	mach_msg_port_descriptor_t req_task;
2258+	mach_ndr_record_t req_ndr;
2259+	mach_exception_type_t req_exc;
2260+	mach_msg_type_number_t req_codecount;
2261+	mach_integer_t req_code[2];
2262+	mach_msg_trailer_t req_trailer;
2263+} mach_exception_raise_request_t;
2264+
2265+typedef struct {
2266+	mach_msg_header_t rep_msgh;
2267+	mach_ndr_record_t rep_ndr;
2268+	mach_kern_return_t rep_retval;
2269+} mach_exception_raise_reply_t;
2270+
2271+/* exception_raise_state. The kernel is the client, not the server */
2272+
2273+typedef struct {
2274+	mach_msg_header_t req_msgh;
2275+	mach_ndr_record_t req_ndr;
2276+	mach_exception_type_t req_exc;
2277+	mach_msg_type_number_t req_codecount;
2278+	mach_integer_t req_code[2];
2279+	int req_flavor;
2280+	mach_msg_type_number_t req_statecount;
2281+	mach_natural_t req_state[144];
2282+	mach_msg_trailer_t req_trailer;
2283+} mach_exception_raise_state_request_t;
2284+
2285+typedef struct {
2286+	mach_msg_header_t rep_msgh;
2287+	mach_ndr_record_t rep_ndr;
2288+	mach_kern_return_t rep_retval;
2289+} mach_exception_raise_state_reply_t;
2290+
2291+/* exception_raise_state_identity. The kernel is the client, not the server */
2292+
2293+typedef struct {
2294+	mach_msg_header_t req_msgh;
2295+	mach_msg_body_t req_body;
2296+	mach_msg_port_descriptor_t req_thread;
2297+	mach_msg_port_descriptor_t req_task;
2298+	mach_ndr_record_t req_ndr;
2299+	mach_exception_type_t req_exc;
2300+	mach_msg_type_number_t req_codecount;
2301+	mach_integer_t req_code[2];
2302+	int req_flavor;
2303+	mach_msg_type_number_t req_statecount;
2304+	mach_natural_t req_state[144];
2305+	mach_msg_trailer_t req_trailer;
2306+} mach_exception_raise_state_identity_request_t;
2307+
2308+typedef struct {
2309+	mach_msg_header_t rep_msgh;
2310+	mach_ndr_record_t rep_ndr;
2311+	mach_kern_return_t rep_retval;
2312+} mach_exception_raise_state_identity_reply_t;
2313+
2314+struct mach_exc_info {
2315+	int mei_flavor;
2316+	int mei_behavior;
2317+};
2318+
2319+void mach_trapsignal(struct lwp *, struct ksiginfo *);
2320+int mach_trapsignal1(struct lwp *, struct ksiginfo *);
2321+int mach_exception(struct lwp *, int, int *);
2322+
2323+#endif /* _MACH_EXCEPTION_H_ */
2324+
2325diff --git a/sys/compat/mach/mach_exec.c b/sys/compat/mach/mach_exec.c
2326new file mode 100644
2327index 0000000..ac46629
2328--- /dev/null
2329+++ b/sys/compat/mach/mach_exec.c
2330@@ -0,0 +1,458 @@
2331+/*	$NetBSD: mach_exec.c,v 1.74 2010/07/25 11:25:57 jym Exp $	 */
2332+
2333+/*-
2334+ * Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
2335+ * All rights reserved.
2336+ *
2337+ * This code is derived from software contributed to The NetBSD Foundation
2338+ * by Christos Zoulas and Emmanuel Dreyfus.
2339+ *
2340+ * Redistribution and use in source and binary forms, with or without
2341+ * modification, are permitted provided that the following conditions
2342+ * are met:
2343+ * 1. Redistributions of source code must retain the above copyright
2344+ *    notice, this list of conditions and the following disclaimer.
2345+ * 2. Redistributions in binary form must reproduce the above copyright
2346+ *    notice, this list of conditions and the following disclaimer in the
2347+ *    documentation and/or other materials provided with the distribution.
2348+ *
2349+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2350+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2351+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2352+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2353+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2354+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2355+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2356+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2357+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2358+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2359+ * POSSIBILITY OF SUCH DAMAGE.
2360+ */
2361+
2362+#include <sys/cdefs.h>
2363+__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.74 2010/07/25 11:25:57 jym Exp $");
2364+
2365+#include "opt_syscall_debug.h"
2366+
2367+#include <sys/param.h>
2368+#include <sys/systm.h>
2369+#include <sys/proc.h>
2370+#include <sys/exec.h>
2371+#include <sys/queue.h>
2372+#include <sys/exec_macho.h>
2373+#include <sys/malloc.h>
2374+
2375+#include <sys/syscall.h>
2376+#include <sys/syscallvar.h>
2377+
2378+#include <uvm/uvm_extern.h>
2379+#include <uvm/uvm_param.h>
2380+
2381+#include <compat/mach/mach_types.h>
2382+#include <compat/mach/mach_message.h>
2383+#include <compat/mach/mach_port.h>
2384+#include <compat/mach/mach_semaphore.h>
2385+#include <compat/mach/mach_notify.h>
2386+#include <compat/mach/mach_exec.h>
2387+
2388+static int mach_cold = 1; /* Have we initialized COMPAT_MACH structures? */
2389+static void mach_init(void);
2390+
2391+extern struct sysent sysent[];
2392+extern const char * const mach_syscallnames[];
2393+#ifndef __HAVE_SYSCALL_INTERN
2394+void syscall(void);
2395+#else
2396+void mach_syscall_intern(struct proc *);
2397+#endif
2398+
2399+#ifdef COMPAT_16
2400+extern char sigcode[], esigcode[];
2401+struct uvm_object *emul_mach_object;
2402+#endif
2403+
2404+struct emul emul_mach = {
2405+	.e_name =		"mach",
2406+	.e_path =		"/emul/mach",
2407+#ifndef __HAVE_MINIMAL_EMUL
2408+	.e_flags =		0,
2409+	.e_errno =		NULL,
2410+	.e_nosys =		SYS_syscall,
2411+	.e_nsysent =		SYS_NSYSENT,
2412+#endif
2413+	.e_sysent =		sysent,
2414+#ifdef SYSCALL_DEBUG
2415+	.e_syscallnames =	mach_syscallnames,
2416+#else
2417+	.e_syscallnames =	NULL,
2418+#endif
2419+	.e_sendsig =		sendsig,
2420+	.e_trapsignal =		mach_trapsignal,
2421+	.e_tracesig =		NULL,
2422+#ifdef COMPAT_16
2423+	.e_sigcode =		sigcode,
2424+	.e_esigcode =		esigcode,
2425+	.e_sigobject =		&emul_mach_object,
2426+#else
2427+	.e_sigcode =		NULL,
2428+	.e_esigcode =		NULL,
2429+	.e_sigobject =		NULL,
2430+#endif
2431+	.e_setregs =		setregs,
2432+	.e_proc_exec =		mach_e_proc_exec,
2433+	.e_proc_fork =		mach_e_proc_fork,
2434+	.e_proc_exit =		mach_e_proc_exit,
2435+	.e_lwp_fork =		mach_e_lwp_fork,
2436+	.e_lwp_exit =		mach_e_lwp_exit,
2437+#ifdef __HAVE_SYSCALL_INTERN
2438+	.e_syscall_intern =	mach_syscall_intern,
2439+#else
2440+	.e_syscall_intern =	syscall,
2441+#endif
2442+	.e_sysctlovly =		NULL,
2443+	.e_fault =		NULL,
2444+	.e_vm_default_addr =	uvm_default_mapaddr,
2445+	.e_usertrap =		NULL,
2446+	.e_sa =			NULL,
2447+	.e_ucsize =		0,
2448+	.e_startlwp =		NULL
2449+};
2450+
2451+/*
2452+ * Copy arguments onto the stack in the normal way, but add some
2453+ * extra information in case of dynamic binding.
2454+ * XXX This needs a cleanup: it is not used anymore by the Darwin
2455+ * emulation, and it probably contains Darwin specific bits.
2456+ */
2457+int
2458+exec_mach_copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, char **stackp, void *argp)
2459+{
2460+	struct exec_macho_emul_arg *emea;
2461+	struct exec_macho_object_header *macho_hdr;
2462+	size_t len;
2463+	size_t zero = 0;
2464+	int error;
2465+
2466+	*stackp = (char *)(((unsigned long)*stackp - 1) & ~0xfUL);
2467+
2468+	emea = (struct exec_macho_emul_arg *)pack->ep_emul_arg;
2469+	macho_hdr = (struct exec_macho_object_header *)emea->macho_hdr;
2470+	if ((error = copyout(&macho_hdr, *stackp, sizeof(macho_hdr))) != 0)
2471+		return error;
2472+
2473+	*stackp += sizeof(macho_hdr);
2474+
2475+	if ((error = copyargs(l, pack, arginfo, stackp, argp)) != 0) {
2476+		DPRINTF(("mach: copyargs failed\n"));
2477+		return error;
2478+	}
2479+
2480+	if ((error = copyout(&zero, *stackp, sizeof(zero))) != 0)
2481+		return error;
2482+	*stackp += sizeof(zero);
2483+
2484+	if ((error = copyoutstr(emea->filename,
2485+	    *stackp, MAXPATHLEN, &len)) != 0) {
2486+		DPRINTF(("mach: copyout path failed\n"));
2487+		return error;
2488+	}
2489+	*stackp += len + 1;
2490+
2491+	/* We don't need this anymore */
2492+	free(pack->ep_emul_arg, M_TEMP);
2493+	pack->ep_emul_arg = NULL;
2494+
2495+	len = len % sizeof(zero);
2496+	if (len) {
2497+		if ((error = copyout(&zero, *stackp, len)) != 0)
2498+			return error;
2499+		*stackp += len;
2500+	}
2501+
2502+	if ((error = copyout(&zero, *stackp, sizeof(zero))) != 0)
2503+		return error;
2504+	*stackp += sizeof(zero);
2505+
2506+	return 0;
2507+}
2508+
2509+int
2510+exec_mach_probe(const char **path)
2511+{
2512+	*path = emul_mach.e_path;
2513+	return 0;
2514+}
2515+
2516+void
2517+mach_e_proc_exec(struct proc *p, struct exec_package *epp)
2518+{
2519+	mach_e_proc_init(p);
2520+
2521+	if (p->p_emul != epp->ep_esch->es_emul) {
2522+		struct lwp *l = LIST_FIRST(&p->p_lwps);
2523+		KASSERT(l != NULL);
2524+		mach_e_lwp_fork(NULL, l);
2525+	}
2526+
2527+	return;
2528+}
2529+
2530+void
2531+mach_e_proc_fork(struct proc *p2, struct lwp *l1, int forkflags)
2532+{
2533+	mach_e_proc_fork1(p2, l1, 1);
2534+	return;
2535+}
2536+
2537+void
2538+mach_e_proc_fork1(struct proc *p2, struct lwp *l1, int allocate)
2539+{
2540+	struct mach_emuldata *med1;
2541+	struct mach_emuldata *med2;
2542+	int i;
2543+
2544+	/*
2545+	 * For Darwin binaries, p2->p_emuldata has already been
2546+	 * allocated, no need to throw it away and allocate it again.
2547+	 */
2548+	if (allocate)
2549+		p2->p_emuldata = NULL;
2550+
2551+	mach_e_proc_init(p2);
2552+
2553+	med1 = p2->p_emuldata;
2554+	med2 = l1->l_proc->p_emuldata;
2555+
2556+	/*
2557+	 * Exception ports are inherited between forks,
2558+	 * but we need to double their reference counts,
2559+	 * since the ports are referenced by rights in the
2560+	 * parent and in the child.
2561+	 *
2562+	 * XXX we need to convert all the parent's rights
2563+	 * to the child namespace. This will make the
2564+	 * following fixup obsolete.
2565+	 */
2566+	for (i = 0; i <= MACH_EXC_MAX; i++) {
2567+		med1->med_exc[i] = med2->med_exc[i];
2568+		if (med1->med_exc[i] !=  NULL)
2569+			med1->med_exc[i]->mp_refcount *= 2;
2570+	}
2571+
2572+	return;
2573+}
2574+
2575+void
2576+mach_e_proc_init(struct proc *p)
2577+{
2578+	struct mach_emuldata *med;
2579+	struct mach_right *mr;
2580+
2581+	/*
2582+	 * Initialize various things if needed.
2583+	 * XXX Not the best place for this.
2584+	 */
2585+	if (mach_cold == 1)
2586+		mach_init();
2587+
2588+	/*
2589+	 * For Darwin binaries, p->p_emuldata is always allocated:
2590+	 * from the previous program if it had the same emulation,
2591+	 * or from darwin_e_proc_exec(). In the latter situation,
2592+	 * everything has been set to zero.
2593+	 */
2594+	if (!p->p_emuldata) {
2595+#ifdef DIAGNOSTIC
2596+		if (p->p_emul != &emul_mach)
2597+			printf("mach_emuldata allocated for non Mach binary\n");
2598+#endif
2599+		p->p_emuldata = malloc(sizeof(struct mach_emuldata),
2600+		    M_EMULDATA, M_WAITOK | M_ZERO);
2601+	}
2602+
2603+	med = (struct mach_emuldata *)p->p_emuldata;
2604+
2605+	/*
2606+	 * p->p_emudata has med_inited set if we inherited it from
2607+	 * the program that called exec(). In that situation, we
2608+	 * must free anything that will not be used anymore.
2609+	 */
2610+	if (med->med_inited != 0) {
2611+		rw_enter(&med->med_rightlock, RW_WRITER);
2612+		while ((mr = LIST_FIRST(&med->med_right)) != NULL)
2613+			mach_right_put_exclocked(mr, MACH_PORT_TYPE_ALL_RIGHTS);
2614+		rw_exit(&med->med_rightlock);
2615+
2616+		/*
2617+		 * Do not touch special ports. Some other process (eg: gdb)
2618+		 * might have grabbed them to control the process, and the
2619+		 * controller intend to keep in control even after exec().
2620+		 */
2621+	} else {
2622+		/*
2623+		 * p->p_emuldata is uninitialized. Go ahead and initialize it.
2624+		 */
2625+		LIST_INIT(&med->med_right);
2626+		rw_init(&med->med_rightlock);
2627+		rw_init(&med->med_exclock);
2628+
2629+		/*
2630+		 * For debugging purpose, it's convenient to have each process
2631+		 * using distinct port names, so we prefix the first port name
2632+		 * by the PID. Darwin does not do that, but we can remove it
2633+		 * when we want, it will not hurt.
2634+		 */
2635+		med->med_nextright = p->p_pid << 16;
2636+
2637+		/*
2638+		 * Initialize special ports. Bootstrap port is shared
2639+		 * among all Mach processes in our implementation.
2640+		 */
2641+		med->med_kernel = mach_port_get();
2642+		med->med_host = mach_port_get();
2643+
2644+		med->med_kernel->mp_flags |= MACH_MP_INKERNEL;
2645+		med->med_host->mp_flags |= MACH_MP_INKERNEL;
2646+
2647+		med->med_kernel->mp_data = (void *)p;
2648+		med->med_host->mp_data = (void *)p;
2649+
2650+		med->med_kernel->mp_datatype = MACH_MP_PROC;
2651+		med->med_host->mp_datatype = MACH_MP_PROC;
2652+
2653+		MACH_PORT_REF(med->med_kernel);
2654+		MACH_PORT_REF(med->med_host);
2655+
2656+		med->med_bootstrap = mach_bootstrap_port;
2657+		MACH_PORT_REF(med->med_bootstrap);
2658+	}
2659+
2660+	/*
2661+	 * Exception ports are inherited accross exec() calls.
2662+	 * If the structure is initialized, the ports are just
2663+	 * here, so leave them untouched. If the structure is
2664+	 * uninitalized, the ports are all set to zero, which
2665+	 * is the default, so do not touch them either.
2666+	 */
2667+
2668+	med->med_dirty_thid = 1;
2669+	med->med_suspend = 0;
2670+	med->med_inited = 1;
2671+
2672+	return;
2673+}
2674+
2675+void
2676+mach_e_proc_exit(struct proc *p)
2677+{
2678+	struct mach_emuldata *med;
2679+	struct mach_right *mr;
2680+	struct lwp *l;
2681+	int i;
2682+
2683+	/* There is only one lwp remaining... */
2684+	l = LIST_FIRST(&p->p_lwps);
2685+	KASSERT(l != NULL);
2686+	mach_e_lwp_exit(l);
2687+
2688+	med = (struct mach_emuldata *)p->p_emuldata;
2689+
2690+	rw_enter(&med->med_rightlock, RW_WRITER);
2691+	while ((mr = LIST_FIRST(&med->med_right)) != NULL)
2692+		mach_right_put_exclocked(mr, MACH_PORT_TYPE_ALL_RIGHTS);
2693+	rw_exit(&med->med_rightlock);
2694+
2695+	MACH_PORT_UNREF(med->med_bootstrap);
2696+
2697+	/*
2698+	 * If the lock on this task exception handler is held,
2699+	 * release it now as it will never be released by the
2700+	 * exception handler.
2701+	 */
2702+	if (rw_lock_held(&med->med_exclock))
2703+		wakeup(&med->med_exclock);
2704+
2705+	/*
2706+	 * If the kernel and host port are still referenced, remove
2707+	 * the pointer to this process' struct proc, as it will
2708+	 * become invalid once the process will exit.
2709+	 */
2710+	med->med_kernel->mp_datatype = MACH_MP_NONE;
2711+	med->med_kernel->mp_data = NULL;
2712+	MACH_PORT_UNREF(med->med_kernel);
2713+
2714+	med->med_host->mp_datatype = MACH_MP_NONE;
2715+	med->med_host->mp_data = NULL;
2716+	MACH_PORT_UNREF(med->med_host);
2717+
2718+	for (i = 0; i <= MACH_EXC_MAX; i++)
2719+		if (med->med_exc[i] != NULL)
2720+			MACH_PORT_UNREF(med->med_exc[i]);
2721+
2722+	rw_destroy(&med->med_exclock);
2723+	rw_destroy(&med->med_rightlock);
2724+	free(med, M_EMULDATA);
2725+	p->p_emuldata = NULL;
2726+
2727+	return;
2728+}
2729+
2730+void
2731+mach_e_lwp_fork(struct lwp *l1, struct lwp *l2)
2732+{
2733+	struct mach_lwp_emuldata *mle;
2734+
2735+	mle = malloc(sizeof(*mle), M_EMULDATA, M_WAITOK);
2736+	l2->l_emuldata = mle;
2737+
2738+	mle->mle_kernel = mach_port_get();
2739+	MACH_PORT_REF(mle->mle_kernel);
2740+
2741+	mle->mle_kernel->mp_flags |= MACH_MP_INKERNEL;
2742+	mle->mle_kernel->mp_datatype = MACH_MP_LWP;
2743+	mle->mle_kernel->mp_data = (void *)l2;
2744+
2745+#if 0
2746+	/* Nothing to copy from parent thread for now */
2747+	if (l1 != NULL);
2748+#endif
2749+
2750+	return;
2751+}
2752+
2753+void
2754+mach_e_lwp_exit(struct lwp *l)
2755+{
2756+	struct mach_lwp_emuldata *mle;
2757+
2758+	mach_semaphore_cleanup(l);
2759+
2760+#ifdef DIAGNOSTIC
2761+	if (l->l_emuldata == NULL) {
2762+		printf("lwp_emuldata already freed\n");
2763+		return;
2764+	}
2765+#endif
2766+	mle = l->l_emuldata;
2767+
2768+	mle->mle_kernel->mp_data = NULL;
2769+	mle->mle_kernel->mp_datatype = MACH_MP_NONE;
2770+	MACH_PORT_UNREF(mle->mle_kernel);
2771+
2772+	free(mle, M_EMULDATA);
2773+	l->l_emuldata = NULL;
2774+
2775+	return;
2776+}
2777+
2778+static void
2779+mach_init(void)
2780+{
2781+	mach_semaphore_init();
2782+	mach_message_init();
2783+	mach_port_init();
2784+
2785+	mach_cold = 0;
2786+
2787+	return;
2788+}
2789diff --git a/sys/compat/mach/mach_exec.h b/sys/compat/mach/mach_exec.h
2790new file mode 100644
2791index 0000000..06a8914
2792--- /dev/null
2793+++ b/sys/compat/mach/mach_exec.h
2794@@ -0,0 +1,78 @@
2795+/*	$NetBSD: mach_exec.h,v 1.35 2011/03/05 23:51:47 joerg Exp $	 */
2796+
2797+/*-
2798+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
2799+ * All rights reserved.
2800+ *
2801+ * This code is derived from software contributed to The NetBSD Foundation
2802+ * by Christos Zoulas.
2803+ *
2804+ * Redistribution and use in source and binary forms, with or without
2805+ * modification, are permitted provided that the following conditions
2806+ * are met:
2807+ * 1. Redistributions of source code must retain the above copyright
2808+ *    notice, this list of conditions and the following disclaimer.
2809+ * 2. Redistributions in binary form must reproduce the above copyright
2810+ *    notice, this list of conditions and the following disclaimer in the
2811+ *    documentation and/or other materials provided with the distribution.
2812+ *
2813+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2814+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2815+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2816+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2817+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2818+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2819+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2820+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2821+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2822+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2823+ * POSSIBILITY OF SUCH DAMAGE.
2824+ */
2825+
2826+#ifndef	_MACH_EXEC_H_
2827+#define	_MACH_EXEC_H_
2828+
2829+#include <uvm/uvm_extern.h>
2830+
2831+#include <compat/mach/mach_types.h>
2832+#include <compat/mach/mach_message.h>
2833+#include <compat/mach/mach_port.h>
2834+#include <compat/mach/mach_exception.h>
2835+
2836+
2837+struct mach_emuldata {
2838+	int med_inited;			/* Is this structure initialized? */
2839+	int med_thpri;			/* Saved priority */
2840+	LIST_HEAD(med_right, mach_right) med_right;
2841+	krwlock_t med_rightlock;	/* process right list and lock */
2842+	mach_port_t med_nextright;	/* next unused right */
2843+
2844+	struct mach_port *med_bootstrap;/* task bootstrap port */
2845+	struct mach_port *med_kernel;	/* task kernel port */
2846+	struct mach_port *med_host;	/* task host port */
2847+	struct mach_port *med_exc[MACH_EXC_MAX + 1];	/* Exception ports */
2848+
2849+	int med_dirty_thid;		/* Thread id not yet initialized */
2850+	int med_suspend;		/* Suspend semaphore */
2851+	krwlock_t med_exclock;		/* Process exception handler lock */
2852+};
2853+
2854+struct mach_lwp_emuldata {
2855+	struct mach_port *mle_kernel;	/* Thread's kernel port */
2856+};
2857+
2858+struct ps_strings;
2859+int exec_mach_copyargs(struct lwp *, struct exec_package *,
2860+    struct ps_strings *, char **, void *);
2861+int exec_mach_probe(const char **);
2862+void mach_e_proc_init(struct proc *);
2863+void mach_e_proc_exit(struct proc *);
2864+void mach_e_proc_exec(struct proc *, struct exec_package *);
2865+void mach_e_proc_fork(struct proc *, struct lwp *, int);
2866+void mach_e_proc_fork1(struct proc *, struct lwp *, int);
2867+void mach_e_lwp_fork(struct lwp *, struct lwp *);
2868+void mach_e_lwp_exit(struct lwp *);
2869+
2870+extern struct emul emul_mach;
2871+
2872+#endif /* !_MACH_EXEC_H_ */
2873diff --git a/sys/compat/mach/mach_host.c b/sys/compat/mach/mach_host.c
2874new file mode 100644
2875index 0000000..767348c
2876--- /dev/null
2877+++ b/sys/compat/mach/mach_host.c
2878@@ -0,0 +1,241 @@
2879+/*	$NetBSD: mach_host.c,v 1.31 2008/04/28 20:23:44 martin Exp $ */
2880+
2881+/*-
2882+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
2883+ * All rights reserved.
2884+ *
2885+ * This code is derived from software contributed to The NetBSD Foundation
2886+ * by Emmanuel Dreyfus
2887+ *
2888+ * Redistribution and use in source and binary forms, with or without
2889+ * modification, are permitted provided that the following conditions
2890+ * are met:
2891+ * 1. Redistributions of source code must retain the above copyright
2892+ *    notice, this list of conditions and the following disclaimer.
2893+ * 2. Redistributions in binary form must reproduce the above copyright
2894+ *    notice, this list of conditions and the following disclaimer in the
2895+ *    documentation and/or other materials provided with the distribution.
2896+ *
2897+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2898+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2899+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2900+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2901+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2902+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2903+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2904+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2905+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2906+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2907+ * POSSIBILITY OF SUCH DAMAGE.
2908+ */
2909+
2910+#include <sys/cdefs.h>
2911+__KERNEL_RCSID(0, "$NetBSD: mach_host.c,v 1.31 2008/04/28 20:23:44 martin Exp $");
2912+
2913+#include <sys/types.h>
2914+#include <sys/malloc.h>
2915+#include <sys/param.h>
2916+#include <sys/kernel.h>
2917+#include <sys/systm.h>
2918+#include <sys/signal.h>
2919+#include <sys/proc.h>
2920+
2921+#include <uvm/uvm_extern.h>
2922+#include <uvm/uvm_param.h>
2923+
2924+#include <compat/mach/mach_types.h>
2925+#include <compat/mach/mach_host.h>
2926+#include <compat/mach/mach_port.h>
2927+#include <compat/mach/mach_clock.h>
2928+#include <compat/mach/mach_errno.h>
2929+#include <compat/mach/mach_services.h>
2930+
2931+int
2932+mach_host_info(struct mach_trap_args *args)
2933+{
2934+	mach_host_info_request_t *req = args->smsg;
2935+	mach_host_info_reply_t *rep = args->rmsg;
2936+	size_t *msglen = args->rsize;
2937+	mach_host_info_reply_simple_t *reps;
2938+
2939+	*msglen = sizeof(*rep);
2940+	mach_set_header(rep, req, *msglen);
2941+
2942+	switch(req->req_flavor) {
2943+	case MACH_HOST_BASIC_INFO: {
2944+		struct mach_host_basic_info *info
2945+		    = (struct mach_host_basic_info *)&rep->rep_data[0];
2946+
2947+		rep->rep_msgh.msgh_size = sizeof(*reps)
2948+		    - sizeof(rep->rep_trailer) + sizeof(*info);
2949+		rep->rep_count = sizeof(*info) / sizeof(mach_integer_t);
2950+		mach_host_basic_info(info);
2951+		break;
2952+	}
2953+
2954+	case MACH_HOST_PRIORITY_INFO: {
2955+		struct mach_host_priority_info *info
2956+		    = (struct mach_host_priority_info *)&rep->rep_data[0];
2957+
2958+		rep->rep_msgh.msgh_size = sizeof(*reps)
2959+		    - sizeof(rep->rep_trailer) + sizeof(*info);
2960+		rep->rep_count = sizeof(*info) / sizeof(mach_integer_t);
2961+		mach_host_priority_info(info);
2962+		break;
2963+	}
2964+
2965+	case MACH_HOST_SEMAPHORE_TRAPS:
2966+	case MACH_HOST_MACH_MSG_TRAP:
2967+		reps = (mach_host_info_reply_simple_t *)rep;
2968+		reps->rep_msgh.msgh_size =
2969+		    sizeof(*reps) - sizeof(reps->rep_trailer);
2970+		*msglen = sizeof(*reps);
2971+		break;
2972+
2973+	case MACH_HOST_SCHED_INFO: {
2974+		struct mach_host_sched_info *info
2975+		    = (struct mach_host_sched_info *)&rep->rep_data[0];
2976+
2977+		rep->rep_msgh.msgh_size = sizeof(*reps)
2978+		    - sizeof(rep->rep_trailer) + sizeof(*info);
2979+		rep->rep_count = sizeof(*info) / sizeof(mach_integer_t);
2980+
2981+		info->min_timeout = 1000 / hz; /* XXX timout in ms */
2982+		info->min_quantum = 1000 / hz; /* quantum in ms */
2983+
2984+		break;
2985+	}
2986+
2987+	case MACH_HOST_RESOURCE_SIZES:
2988+		uprintf("mach_host_info() Unimplemented host_info flavor %d\n",
2989+		    req->req_flavor);
2990+	default:
2991+		uprintf("Unknown host_info flavor %d\n", req->req_flavor);
2992+		rep->rep_retval = native_to_mach_errno[EINVAL];
2993+		break;
2994+	}
2995+
2996+	mach_set_trailer(rep, *msglen);
2997+
2998+	return 0;
2999+}
3000+
3001+
3002+int
3003+mach_host_page_size(struct mach_trap_args *args)
3004+{
3005+	mach_host_page_size_request_t *req = args->smsg;
3006+	mach_host_page_size_reply_t *rep = args->rmsg;
3007+	size_t *msglen = args->rsize;
3008+
3009+	*msglen = sizeof(*rep);
3010+	mach_set_header(rep, req, *msglen);
3011+
3012+	rep->rep_page_size = PAGE_SIZE;
3013+
3014+	mach_set_trailer(rep, *msglen);
3015+
3016+	return 0;
3017+}
3018+
3019+int
3020+mach_host_get_clock_service(struct mach_trap_args *args)
3021+{
3022+	mach_host_get_clock_service_request_t *req = args->smsg;
3023+	mach_host_get_clock_service_reply_t *rep = args->rmsg;
3024+	size_t *msglen = args->rsize;
3025+	struct lwp *l = args->l;
3026+	struct mach_right *mr;
3027+
3028+	mr = mach_right_get(mach_clock_port, l, MACH_PORT_TYPE_SEND, 0);
3029+
3030+	*msglen = sizeof(*rep);
3031+	mach_set_header(rep, req, *msglen);
3032+	mach_add_port_desc(rep, mr->mr_name);
3033+	mach_set_trailer(rep, *msglen);
3034+
3035+	return 0;
3036+}
3037+
3038+void
3039+mach_host_priority_info(struct mach_host_priority_info *info)
3040+{
3041+	/* XXX One day, try to fill this correctly */
3042+	info->kernel_priority = 0x50;
3043+	info->system_priority = 0x50;
3044+	info->server_priority = 0x40;
3045+	info->user_priority = 0x1f;
3046+	info->depress_priority = 0x00;
3047+	info->idle_priority = 0x00;
3048+	info->minimum_priority = 0x00;
3049+	info->maximum_priority = 0x4f;
3050+
3051+	return;
3052+}
3053+
3054+int
3055+mach_host_get_io_master(struct mach_trap_args *args)
3056+{
3057+	mach_host_get_io_master_request_t *req = args->smsg;
3058+	mach_host_get_io_master_reply_t *rep = args->rmsg;
3059+	size_t *msglen = args->rsize;
3060+	struct lwp *l = args->l;
3061+	struct mach_right *mr;
3062+
3063+	mr = mach_right_get(mach_io_master_port, l, MACH_PORT_TYPE_SEND, 0);
3064+
3065+	*msglen = sizeof(*rep);
3066+	mach_set_header(rep, req, *msglen);
3067+	mach_add_port_desc(rep, mr->mr_name);
3068+	mach_set_trailer(rep, *msglen);
3069+
3070+	return 0;
3071+}
3072+
3073+int
3074+mach_processor_set_default(struct mach_trap_args *args)
3075+{
3076+	mach_processor_set_default_request_t *req = args->smsg;
3077+	mach_processor_set_default_reply_t *rep = args->rmsg;
3078+	size_t *msglen = args->rsize;
3079+	struct lwp *l = args->l;
3080+	struct mach_right *mr;
3081+	struct mach_port *mp;
3082+
3083+	mp = mach_port_get();
3084+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3085+
3086+	*msglen = sizeof(*rep);
3087+	mach_set_header(rep, req, *msglen);
3088+	mach_add_port_desc(rep, mr->mr_name);
3089+	mach_set_trailer(rep, *msglen);
3090+
3091+	return 0;
3092+}
3093+
3094+int
3095+mach_host_processor_set_priv(struct mach_trap_args *args)
3096+{
3097+	mach_host_processor_set_priv_request_t *req = args->smsg;
3098+	mach_host_processor_set_priv_reply_t *rep = args->rmsg;
3099+	size_t *msglen = args->rsize;
3100+	struct lwp *l = args->l;
3101+	mach_port_t mn;
3102+	struct mach_right *mr;
3103+	struct mach_right *smr;
3104+	struct mach_port *smp;
3105+
3106+	mn = req->req_set.name;
3107+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3108+		return mach_msg_error(args, EINVAL);
3109+
3110+	smp = mach_port_get();
3111+	smr = mach_right_get(smp, l, MACH_PORT_TYPE_SEND, 0);
3112+
3113+	*msglen = sizeof(*rep);
3114+	mach_set_header(rep, req, *msglen);
3115+	mach_add_port_desc(rep, smr->mr_name);
3116+	mach_set_trailer(rep, *msglen);
3117+
3118+	return 0;
3119+}
3120diff --git a/sys/compat/mach/mach_host.h b/sys/compat/mach/mach_host.h
3121new file mode 100644
3122index 0000000..ed57c90
3123--- /dev/null
3124+++ b/sys/compat/mach/mach_host.h
3125@@ -0,0 +1,184 @@
3126+/*	$NetBSD: mach_host.h,v 1.17 2008/04/28 20:23:44 martin Exp $ */
3127+
3128+/*-
3129+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
3130+ * All rights reserved.
3131+ *
3132+ * This code is derived from software contributed to The NetBSD Foundation
3133+ * by Emmanuel Dreyfus
3134+ *
3135+ * Redistribution and use in source and binary forms, with or without
3136+ * modification, are permitted provided that the following conditions
3137+ * are met:
3138+ * 1. Redistributions of source code must retain the above copyright
3139+ *    notice, this list of conditions and the following disclaimer.
3140+ * 2. Redistributions in binary form must reproduce the above copyright
3141+ *    notice, this list of conditions and the following disclaimer in the
3142+ *    documentation and/or other materials provided with the distribution.
3143+ *
3144+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
3145+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
3146+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3147+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3148+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3149+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3150+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3151+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3152+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3153+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3154+ * POSSIBILITY OF SUCH DAMAGE.
3155+ */
3156+
3157+#ifndef	_MACH_HOST_H_
3158+#define	_MACH_HOST_H_
3159+
3160+#include <sys/types.h>
3161+#include <sys/param.h>
3162+#include <sys/signal.h>
3163+#include <sys/proc.h>
3164+
3165+#include <compat/mach/mach_types.h>
3166+#include <compat/mach/mach_message.h>
3167+
3168+/* host_info */
3169+
3170+typedef mach_integer_t mach_host_flavor_t;
3171+
3172+typedef struct {
3173+	mach_msg_header_t req_msgh;
3174+	mach_ndr_record_t req_ndr;
3175+	mach_host_flavor_t req_flavor;
3176+	mach_msg_type_number_t req_count;
3177+} mach_host_info_request_t;
3178+
3179+typedef struct {
3180+	mach_msg_header_t rep_msgh;
3181+	mach_ndr_record_t rep_ndr;
3182+	mach_kern_return_t rep_retval;
3183+	mach_msg_type_number_t rep_count;
3184+	mach_integer_t rep_data[12];
3185+	mach_msg_trailer_t rep_trailer;
3186+} mach_host_info_reply_t;
3187+
3188+typedef struct {
3189+	mach_msg_header_t rep_msgh;
3190+	mach_ndr_record_t rep_ndr;
3191+	mach_kern_return_t rep_retval;
3192+	mach_msg_type_number_t rep_count;
3193+	mach_msg_trailer_t rep_trailer;
3194+} mach_host_info_reply_simple_t;
3195+
3196+#define MACH_HOST_BASIC_INFO		1
3197+#define MACH_HOST_SCHED_INFO		3
3198+#define MACH_HOST_RESOURCE_SIZES	4
3199+#define MACH_HOST_PRIORITY_INFO		5
3200+#define MACH_HOST_SEMAPHORE_TRAPS	7
3201+#define MACH_HOST_MACH_MSG_TRAP		8
3202+
3203+struct mach_host_basic_info {
3204+	mach_integer_t		max_cpus;
3205+	mach_integer_t		avail_cpus;
3206+	mach_vm_size_t		memory_size;
3207+	mach_cpu_type_t		cpu_type;
3208+	mach_cpu_subtype_t	cpu_subtype;
3209+};
3210+
3211+struct mach_host_sched_info {
3212+	mach_integer_t		min_timeout;
3213+	mach_integer_t		min_quantum;
3214+};
3215+
3216+struct mach_kernel_resource_sizes {
3217+	mach_vm_size_t	 task;
3218+	mach_vm_size_t	 thread;
3219+	mach_vm_size_t	 port;
3220+	mach_vm_size_t	 memory_region;
3221+	mach_vm_size_t	 memory_object;
3222+};
3223+
3224+struct mach_host_priority_info {
3225+	mach_integer_t	kernel_priority;
3226+	mach_integer_t	system_priority;
3227+	mach_integer_t	server_priority;
3228+	mach_integer_t	user_priority;
3229+	mach_integer_t	depress_priority;
3230+	mach_integer_t	idle_priority;
3231+	mach_integer_t	minimum_priority;
3232+	mach_integer_t	maximum_priority;
3233+};
3234+
3235+/* host_page_size */
3236+
3237+typedef struct {
3238+	mach_msg_header_t req_msgh;
3239+} mach_host_page_size_request_t;
3240+
3241+typedef struct {
3242+	mach_msg_header_t rep_msgh;
3243+	mach_ndr_record_t rep_ndr;
3244+	mach_kern_return_t rep_retval;
3245+	mach_vm_size_t rep_page_size;
3246+	mach_msg_trailer_t rep_trailer;
3247+} mach_host_page_size_reply_t;
3248+
3249+/* host_get_clock_service */
3250+
3251+typedef struct {
3252+	mach_msg_header_t req_msgh;
3253+	mach_ndr_record_t req_ndr;
3254+	mach_clock_id_t req_clock_id;
3255+} mach_host_get_clock_service_request_t;
3256+
3257+typedef struct {
3258+	mach_msg_header_t rep_msgh;
3259+	mach_msg_body_t rep_body;
3260+	mach_msg_port_descriptor_t rep_clock_serv;
3261+	mach_msg_trailer_t rep_trailer;
3262+} mach_host_get_clock_service_reply_t;
3263+
3264+/* host_get_io_master */
3265+
3266+typedef struct {
3267+	mach_msg_header_t req_msgh;
3268+} mach_host_get_io_master_request_t;
3269+
3270+typedef struct {
3271+	mach_msg_header_t rep_msgh;
3272+	mach_msg_body_t rep_body;
3273+	mach_msg_port_descriptor_t rep_iomaster;
3274+	mach_msg_trailer_t rep_trailer;
3275+} mach_host_get_io_master_reply_t;
3276+
3277+/* processor_set_default */
3278+
3279+typedef struct {
3280+	mach_msg_header_t req_msgh;
3281+} mach_processor_set_default_request_t;
3282+
3283+typedef struct {
3284+	mach_msg_header_t rep_msgh;
3285+	mach_msg_body_t rep_body;
3286+	mach_msg_port_descriptor_t rep_defaultset;
3287+	mach_msg_trailer_t rep_trailer;
3288+} mach_processor_set_default_reply_t;
3289+
3290+/* host_processor_set_priv */
3291+
3292+typedef struct {
3293+	mach_msg_header_t req_msgh;
3294+	mach_msg_body_t req_body;
3295+	mach_msg_port_descriptor_t req_set;
3296+} mach_host_processor_set_priv_request_t;
3297+
3298+typedef struct {
3299+	mach_msg_header_t rep_msgh;
3300+	mach_msg_body_t rep_body;
3301+	mach_msg_port_descriptor_t rep_ctlset;
3302+	 mach_msg_trailer_t rep_trailer;
3303+} mach_host_processor_set_priv_reply_t;
3304+
3305+/* These are machine dependent functions */
3306+void mach_host_basic_info(struct mach_host_basic_info *);
3307+void mach_host_priority_info(struct mach_host_priority_info *);
3308+
3309+#endif /* _MACH_HOST_H_ */
3310diff --git a/sys/compat/mach/mach_iokit.c b/sys/compat/mach/mach_iokit.c
3311new file mode 100644
3312index 0000000..502ea2b
3313--- /dev/null
3314+++ b/sys/compat/mach/mach_iokit.c
3315@@ -0,0 +1,1211 @@
3316+/*	$NetBSD: mach_iokit.c,v 1.36 2008/04/28 20:23:44 martin Exp $ */
3317+
3318+/*-
3319+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
3320+ * All rights reserved.
3321+ *
3322+ * This code is derived from software contributed to The NetBSD Foundation
3323+ * by Emmanuel Dreyfus.
3324+ *
3325+ * Redistribution and use in source and binary forms, with or without
3326+ * modification, are permitted provided that the following conditions
3327+ * are met:
3328+ * 1. Redistributions of source code must retain the above copyright
3329+ *    notice, this list of conditions and the following disclaimer.
3330+ * 2. Redistributions in binary form must reproduce the above copyright
3331+ *    notice, this list of conditions and the following disclaimer in the
3332+ *    documentation and/or other materials provided with the distribution.
3333+ *
3334+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
3335+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
3336+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3337+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
3338+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3339+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3340+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3341+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3342+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3343+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3344+ * POSSIBILITY OF SUCH DAMAGE.
3345+ */
3346+
3347+#include "opt_compat_darwin.h"
3348+#include <sys/cdefs.h>
3349+__KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.36 2008/04/28 20:23:44 martin Exp $");
3350+
3351+#include <sys/types.h>
3352+#include <sys/param.h>
3353+#include <sys/systm.h>
3354+#include <sys/malloc.h>
3355+#include <sys/signal.h>
3356+#include <sys/mount.h>
3357+#include <sys/proc.h>
3358+#include <sys/ktrace.h>
3359+#include <sys/device.h>
3360+#include <compat/mach/mach_types.h>
3361+#include <compat/mach/mach_message.h>
3362+#include <compat/mach/mach_port.h>
3363+#include <compat/mach/mach_errno.h>
3364+#include <compat/mach/mach_iokit.h>
3365+#include <compat/mach/mach_services.h>
3366+
3367+#ifdef COMPAT_DARWIN
3368+#include <compat/darwin/darwin_iokit.h>
3369+#endif
3370+
3371+struct mach_iokit_devclass mach_ioroot_devclass = {
3372+	"(unknwon)",
3373+	{ NULL },
3374+	"<dict ID=\"0\"></dict>",
3375+	NULL,
3376+	NULL,
3377+	NULL,
3378+	NULL,
3379+	NULL,
3380+	NULL,
3381+	"Root",
3382+	NULL,
3383+};
3384+
3385+struct mach_iokit_devclass *mach_iokit_devclasses[] = {
3386+	&mach_ioroot_devclass,
3387+#ifdef COMPAT_DARWIN
3388+	DARWIN_IOKIT_DEVCLASSES
3389+#endif
3390+	NULL,
3391+};
3392+
3393+
3394+static int mach_fill_child_iterator(struct mach_device_iterator *, int, int,
3395+    struct mach_iokit_devclass *);
3396+static int mach_fill_parent_iterator(struct mach_device_iterator *, int, int,
3397+    struct mach_iokit_devclass *);
3398+
3399+int
3400+mach_io_service_get_matching_services(struct mach_trap_args *args)
3401+{
3402+	mach_io_service_get_matching_services_request_t *req = args->smsg;
3403+	mach_io_service_get_matching_services_reply_t *rep = args->rmsg;
3404+	size_t *msglen = args->rsize;
3405+	struct lwp *l = args->l;
3406+	struct mach_port *mp;
3407+	struct mach_right *mr;
3408+	struct mach_iokit_devclass *mid;
3409+	struct mach_device_iterator *mdi;
3410+	size_t size;
3411+	int end_offset;
3412+	int i;
3413+
3414+	/* Sanity check req_size */
3415+	end_offset = req->req_size;
3416+	if (MACH_REQMSG_OVERFLOW(args, req->req_string[end_offset]))
3417+		return mach_msg_error(args, EINVAL);
3418+
3419+	mp = mach_port_get();
3420+	mp->mp_flags |= MACH_MP_INKERNEL;
3421+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3422+
3423+	mp->mp_data = NULL;
3424+	i = 0;
3425+	while ((mid = mach_iokit_devclasses[i++]) != NULL) {
3426+		if (memcmp(req->req_string, mid->mid_string,
3427+		    req->req_size) == 0) {
3428+			mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
3429+
3430+			size = sizeof(*mdi)
3431+			    + sizeof(struct mach_device_iterator *);
3432+			mdi = malloc(size, M_EMULDATA, M_WAITOK);
3433+			mdi->mdi_devices[0] = mid;
3434+			mdi->mdi_devices[1] = NULL;
3435+			mdi->mdi_current = 0;
3436+
3437+			mp->mp_data = mdi;
3438+			break;
3439+		}
3440+	}
3441+
3442+	if (mp->mp_data == NULL)
3443+		return mach_iokit_error(args, MACH_IOKIT_ENOENT);
3444+
3445+	*msglen = sizeof(*rep);
3446+	mach_set_header(rep, req, *msglen);
3447+	mach_add_port_desc(rep, mr->mr_name);
3448+	mach_set_trailer(rep, *msglen);
3449+
3450+	return 0;
3451+}
3452+
3453+int
3454+mach_io_iterator_next(struct mach_trap_args *args)
3455+{
3456+	mach_io_iterator_next_request_t *req = args->smsg;
3457+	mach_io_iterator_next_reply_t *rep = args->rmsg;
3458+	size_t *msglen = args->rsize;
3459+	struct lwp *l = args->l;
3460+	struct mach_port *mp;
3461+	struct mach_right *mr;
3462+	struct mach_device_iterator *mdi;
3463+	mach_port_t mn;
3464+
3465+	mn = req->req_msgh.msgh_remote_port;
3466+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3467+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3468+
3469+	if (mr->mr_port->mp_datatype != MACH_MP_DEVICE_ITERATOR)
3470+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3471+
3472+	mdi = mr->mr_port->mp_data;
3473+
3474+	/* Is there something coming next? */
3475+	if (mdi->mdi_devices[mdi->mdi_current] == NULL)
3476+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3477+
3478+	mp = mach_port_get();
3479+	mp->mp_flags |= MACH_MP_INKERNEL;
3480+	mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
3481+	mp->mp_data = mdi->mdi_devices[mdi->mdi_current++];
3482+
3483+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3484+
3485+	*msglen = sizeof(*rep);
3486+	mach_set_header(rep, req, *msglen);
3487+	mach_add_port_desc(rep, mr->mr_name);
3488+	mach_set_trailer(rep, *msglen);
3489+
3490+	return 0;
3491+}
3492+
3493+int
3494+mach_io_service_open(struct mach_trap_args *args)
3495+{
3496+	mach_io_service_open_request_t *req = args->smsg;
3497+	mach_io_service_open_reply_t *rep = args->rmsg;
3498+	size_t *msglen = args->rsize;
3499+	struct lwp *l = args->l;
3500+	struct mach_port *mp;
3501+	struct mach_right *mr;
3502+	mach_port_t mn;
3503+
3504+	mn = req->req_msgh.msgh_remote_port;
3505+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3506+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3507+
3508+	mp = mach_port_get();
3509+	mp->mp_flags |= MACH_MP_INKERNEL;
3510+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
3511+		mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
3512+		mp->mp_data = mr->mr_port->mp_data;
3513+	}
3514+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3515+
3516+	*msglen = sizeof(*rep);
3517+	mach_set_header(rep, req, *msglen);
3518+	mach_add_port_desc(rep, mr->mr_name);
3519+	mach_set_trailer(rep, *msglen);
3520+
3521+	return 0;
3522+}
3523+
3524+int
3525+mach_io_connect_method_scalari_scalaro(struct mach_trap_args *args)
3526+{
3527+	mach_io_connect_method_scalari_scalaro_request_t *req = args->smsg;
3528+	struct lwp *l = args->l;
3529+	mach_port_t mn;
3530+	struct mach_right *mr;
3531+	struct mach_iokit_devclass *mid;
3532+	int end_offset, outcount;
3533+
3534+	/*
3535+	 * Sanity check req_incount
3536+	 * the +1 gives us the last field of the message, req_outcount
3537+	 */
3538+	end_offset = req->req_incount +
3539+		     (sizeof(req->req_outcount) / sizeof(req->req_in[0]));
3540+	if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
3541+		return mach_msg_error(args, EINVAL);
3542+
3543+	/* Sanity check req->req_outcount */
3544+	outcount = req->req_in[req->req_incount];
3545+	if (outcount > 16)
3546+		return mach_msg_error(args, EINVAL);
3547+
3548+	mn = req->req_msgh.msgh_remote_port;
3549+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3550+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3551+
3552+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
3553+		mid = mr->mr_port->mp_data;
3554+		if (mid->mid_connect_method_scalari_scalaro == NULL)
3555+			printf("no connect_method_scalari_scalaro method "
3556+			    "for darwin_iokit_class %s\n", mid->mid_name);
3557+		else
3558+			return (mid->mid_connect_method_scalari_scalaro)(args);
3559+	}
3560+
3561+	return mach_iokit_error(args, MACH_IOKIT_ENODEV);
3562+}
3563+
3564+int
3565+mach_io_connect_get_service(struct mach_trap_args *args)
3566+{
3567+	mach_io_connect_get_service_request_t *req = args->smsg;
3568+	mach_io_connect_get_service_reply_t *rep = args->rmsg;
3569+	size_t *msglen = args->rsize;
3570+	struct lwp *l = args->l;
3571+	struct mach_port *mp;
3572+	struct mach_right *mr;
3573+	mach_port_t mn;
3574+
3575+	mn = req->req_msgh.msgh_remote_port;
3576+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3577+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3578+
3579+	mp = mach_port_get();
3580+	mp->mp_flags |= MACH_MP_INKERNEL;
3581+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
3582+		mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
3583+		mp->mp_data = mr->mr_port->mp_data;
3584+	}
3585+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3586+
3587+	/*
3588+	 * XXX Bump the refcount to workaround an emulation bug
3589+	 * that causes Windowserver to release the port too early.
3590+	 */
3591+	mr->mr_refcount++;
3592+
3593+	*msglen = sizeof(*rep);
3594+	mach_set_header(rep, req, *msglen);
3595+	mach_add_port_desc(rep, mr->mr_name);
3596+	mach_set_trailer(rep, *msglen);
3597+
3598+	return 0;
3599+}
3600+
3601+int
3602+mach_io_registry_entry_create_iterator(struct mach_trap_args *args)
3603+{
3604+	mach_io_registry_entry_create_iterator_request_t *req = args->smsg;
3605+	mach_io_registry_entry_create_iterator_reply_t *rep = args->rmsg;
3606+	size_t *msglen = args->rsize;
3607+	struct lwp *l = args->l;
3608+	struct mach_port *mp;
3609+	mach_port_t mn;
3610+	struct mach_right *mr;
3611+	struct mach_iokit_devclass *mid;
3612+	struct mach_device_iterator *mdi;
3613+	struct mach_iokit_devclass **midp;
3614+	int maxdev, index;
3615+	size_t size;
3616+	int end_offset;
3617+
3618+	/*
3619+	 * req_planeoffset is not used.
3620+	 * Sanity check req_planecount
3621+	 */
3622+	end_offset = req->req_planecount +
3623+		     (sizeof(req->req_options) / sizeof(req->req_plane[0]));
3624+	if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
3625+		return mach_msg_error(args, EINVAL);
3626+
3627+	mn = req->req_msgh.msgh_remote_port;
3628+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3629+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3630+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
3631+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3632+	mid = (struct mach_iokit_devclass *)mr->mr_port->mp_data;
3633+
3634+	mp = mach_port_get();
3635+	mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
3636+	mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
3637+
3638+	maxdev = sizeof(mach_iokit_devclasses);
3639+	size = sizeof(*mdi) + (maxdev * sizeof(struct mach_iokit_devclass *));
3640+	mdi = malloc(size, M_EMULDATA, M_WAITOK);
3641+	mp->mp_data = mdi;
3642+
3643+	if (req->req_options & MACH_IOKIT_PARENT_ITERATOR)
3644+		index = mach_fill_parent_iterator(mdi, maxdev, 0, mid);
3645+	else
3646+		index = mach_fill_child_iterator(mdi, maxdev, 0, mid);
3647+
3648+	/* XXX This is untested */
3649+	if (req->req_options & MACH_IOKIT_RECURSIVE_ITERATOR) {
3650+		for (midp = mdi->mdi_devices; *midp != NULL; midp++) {
3651+			if (req->req_options & MACH_IOKIT_PARENT_ITERATOR)
3652+				index = mach_fill_parent_iterator(mdi,
3653+				    maxdev, index, *midp);
3654+			else
3655+				index = mach_fill_child_iterator(mdi,
3656+				    maxdev, index, *midp);
3657+		}
3658+	}
3659+
3660+	mdi->mdi_current = 0;
3661+
3662+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3663+
3664+#ifdef DEBUG_MACH
3665+	printf("io_registry_entry_create_iterator\n");
3666+#endif
3667+
3668+	*msglen = sizeof(*rep);
3669+	mach_set_header(rep, req, *msglen);
3670+	mach_add_port_desc(rep, mr->mr_name);
3671+	mach_set_trailer(rep, *msglen);
3672+
3673+	return 0;
3674+}
3675+
3676+int
3677+mach_io_object_conforms_to(struct mach_trap_args *args)
3678+{
3679+	mach_io_object_conforms_to_request_t *req = args->smsg;
3680+	mach_io_object_conforms_to_reply_t *rep = args->rmsg;
3681+	size_t *msglen = args->rsize;
3682+	int end_offset;
3683+
3684+	/*
3685+	 * req_classnameoffset is not used.
3686+	 * Sanity check req_classnamecount.
3687+	 */
3688+	end_offset = req->req_classnamecount;
3689+	if (MACH_REQMSG_OVERFLOW(args, req->req_classname[end_offset]))
3690+		return mach_msg_error(args, EINVAL);
3691+
3692+#ifdef DEBUG_DARWIN
3693+	uprintf("Unimplemented mach_io_object_conforms_to\n");
3694+#endif
3695+
3696+	*msglen = sizeof(*rep);
3697+	mach_set_header(rep, req, *msglen);
3698+
3699+	rep->rep_conforms = 1; /* XXX */
3700+
3701+	mach_set_trailer(rep, *msglen);
3702+
3703+	return 0;
3704+}
3705+
3706+int
3707+mach_io_service_add_interest_notification(struct mach_trap_args *args)
3708+{
3709+	mach_io_service_add_interest_notification_request_t *req = args->smsg;
3710+	mach_io_service_add_interest_notification_reply_t *rep = args->rmsg;
3711+	size_t *msglen = args->rsize;
3712+	struct lwp *l = args->l;
3713+	struct mach_port *mp;
3714+	struct mach_right *mr;
3715+	int end_offset, refcount_offset;
3716+	int item_size, refitem_size, refcount;
3717+
3718+	/*
3719+	 * req_typeofinterestoffset is not used.
3720+	 * Sanity checks: first check refcount is not
3721+	 * outside the message. NB: it is word aligned
3722+	 */
3723+	refcount_offset = (req->req_typeofinterestcount & ~0x3UL) + 4;
3724+	if (MACH_REQMSG_OVERFLOW(args,
3725+	    req->req_typeofinterest[refcount_offset]))
3726+		return mach_msg_error(args, EINVAL);
3727+	refcount = req->req_typeofinterest[refcount_offset];
3728+
3729+	/*
3730+	 * Sanity check typeofinterestcount and refcount
3731+	 */
3732+	item_size = sizeof(req->req_typeofinterest[0]);
3733+	refitem_size = sizeof(req->req_ref[0]);
3734+	end_offset = req->req_typeofinterestcount +
3735+		     (sizeof(refcount) / item_size) +
3736+		     (refcount * refitem_size / item_size);
3737+	if (MACH_REQMSG_OVERFLOW(args, req->req_typeofinterest[end_offset]))
3738+		return mach_msg_error(args, EINVAL);
3739+
3740+	mp = mach_port_get();
3741+	mp->mp_flags |= MACH_MP_INKERNEL;
3742+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3743+
3744+#ifdef DEBUG_DARWIN
3745+	uprintf("Unimplemented mach_io_service_add_interest_notification\n");
3746+#endif
3747+	*msglen = sizeof(*rep);
3748+	mach_set_header(rep, req, *msglen);
3749+	mach_add_port_desc(rep, mr->mr_name);
3750+	mach_set_trailer(rep, *msglen);
3751+
3752+	return 0;
3753+}
3754+
3755+int
3756+mach_io_connect_set_notification_port(struct mach_trap_args *args)
3757+{
3758+	mach_io_connect_set_notification_port_request_t *req = args->smsg;
3759+	mach_io_connect_set_notification_port_reply_t *rep = args->rmsg;
3760+	struct lwp *l = args->l;
3761+	size_t *msglen = args->rsize;
3762+	mach_port_t mnn, mn;
3763+	struct mach_right *mrn;
3764+	struct mach_right *mr;
3765+	struct mach_iokit_devclass *mid;
3766+
3767+#ifdef DEBUG_DARWIN
3768+	printf("mach_io_connect_set_notification_port\n");
3769+#endif
3770+	mnn = req->req_port.name;
3771+	if ((mrn = mach_right_check(mnn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3772+		return mach_msg_error(args, EINVAL);
3773+
3774+	mn = req->req_msgh.msgh_remote_port;
3775+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3776+		return mach_msg_error(args, EINVAL);
3777+
3778+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
3779+		return mach_msg_error(args, EINVAL);
3780+
3781+#ifdef DEBUG_DARWIN
3782+	printf("notification on right %p, name %x\n", mrn, mrn->mr_name);
3783+#endif
3784+	mid = (struct mach_iokit_devclass *)mr->mr_port->mp_data;
3785+	mid->mid_notify = mrn;
3786+
3787+	*msglen = sizeof(*rep);
3788+	mach_set_header(rep, req, *msglen);
3789+
3790+	rep->rep_retval = 0;
3791+
3792+	mach_set_trailer(rep, *msglen);
3793+
3794+	return 0;
3795+}
3796+
3797+int
3798+mach_io_registry_get_root_entry(struct mach_trap_args *args)
3799+{
3800+	mach_io_registry_get_root_entry_request_t *req = args->smsg;
3801+	mach_io_registry_get_root_entry_reply_t *rep = args->rmsg;
3802+	size_t *msglen = args->rsize;
3803+	struct lwp *l = args->l;
3804+	struct mach_port *mp;
3805+	struct mach_right *mr;
3806+
3807+	mp = mach_port_get();
3808+	mp->mp_flags |= MACH_MP_INKERNEL;
3809+	mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
3810+	mp->mp_data = &mach_ioroot_devclass;
3811+
3812+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3813+
3814+	*msglen = sizeof(*rep);
3815+	mach_set_header(rep, req, *msglen);
3816+	mach_add_port_desc(rep, mr->mr_name);
3817+	mach_set_trailer(rep, *msglen);
3818+
3819+	return 0;
3820+}
3821+
3822+int
3823+mach_io_registry_entry_get_child_iterator(struct mach_trap_args *args)
3824+{
3825+	mach_io_registry_entry_get_child_iterator_request_t *req = args->smsg;
3826+	mach_io_registry_entry_get_child_iterator_reply_t *rep = args->rmsg;
3827+	size_t *msglen = args->rsize;
3828+	struct lwp *l = args->l;
3829+	struct mach_port *mp;
3830+	struct mach_right *mr;
3831+	mach_port_t mn;
3832+	struct mach_iokit_devclass *mid;
3833+	struct mach_device_iterator *mdi;
3834+	int maxdev;
3835+	size_t size;
3836+	int end_offset;
3837+
3838+	/*
3839+	 * req_planeoffset is not used.
3840+	 * Sanity check req_planecount.
3841+	 */
3842+	end_offset = req->req_planecount;
3843+	if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
3844+		return mach_msg_error(args, EINVAL);
3845+
3846+	mn = req->req_msgh.msgh_remote_port;
3847+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3848+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3849+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
3850+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3851+	mid = (struct mach_iokit_devclass *)mr->mr_port->mp_data;
3852+
3853+	mp = mach_port_get();
3854+	mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
3855+	mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
3856+
3857+	maxdev = sizeof(mach_iokit_devclasses);
3858+	size = sizeof(*mdi) + (maxdev * sizeof(struct mach_iokit_devclass *));
3859+	mdi = malloc(size, M_EMULDATA, M_WAITOK);
3860+	mp->mp_data = mdi;
3861+
3862+	(void)mach_fill_child_iterator(mdi, maxdev, 0, mid);
3863+	mdi->mdi_current = 0;
3864+
3865+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
3866+
3867+	*msglen = sizeof(*rep);
3868+	mach_set_header(rep, req, *msglen);
3869+	mach_add_port_desc(rep, mr->mr_name);
3870+	mach_set_trailer(rep, *msglen);
3871+
3872+	return 0;
3873+}
3874+
3875+int
3876+mach_io_registry_entry_get_name_in_plane(struct mach_trap_args *args)
3877+{
3878+	mach_io_registry_entry_get_name_in_plane_request_t *req = args->smsg;
3879+	mach_io_registry_entry_get_name_in_plane_reply_t *rep = args->rmsg;
3880+	size_t *msglen = args->rsize;
3881+	struct lwp *l = args->l;
3882+	struct mach_right *mr;
3883+	mach_port_t mn;
3884+	struct mach_iokit_devclass *mid;
3885+	int end_offset;
3886+
3887+	/*
3888+	 * req_planeoffset is not used.
3889+	 * Sanity check req_planecount.
3890+	 */
3891+	end_offset = req->req_planecount;
3892+	if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
3893+		return mach_msg_error(args, EINVAL);
3894+
3895+	mn = req->req_msgh.msgh_remote_port;
3896+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3897+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3898+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
3899+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3900+	mid = mr->mr_port->mp_data;
3901+
3902+	*msglen = sizeof(*rep);
3903+	mach_set_header(rep, req, *msglen);
3904+
3905+	rep->rep_namecount = strlen(mid->mid_name);
3906+	if (rep->rep_namecount >= 128)
3907+		rep->rep_namecount = 128;
3908+	memcpy(&rep->rep_name, mid->mid_name, rep->rep_namecount);
3909+
3910+	mach_set_trailer(rep, *msglen);
3911+
3912+	return 0;
3913+}
3914+
3915+int
3916+mach_io_object_get_class(struct mach_trap_args *args)
3917+{
3918+	mach_io_object_get_class_request_t *req = args->smsg;
3919+	mach_io_object_get_class_reply_t *rep = args->rmsg;
3920+	size_t *msglen = args->rsize;
3921+	char classname[] = "unknownClass";
3922+
3923+	*msglen = sizeof(*rep);
3924+	mach_set_header(rep, req, *msglen);
3925+
3926+	/* XXX Just return a dummy name for now */
3927+	rep->rep_namecount = strlen(classname);
3928+	if (rep->rep_namecount >= 128)
3929+		rep->rep_namecount = 128;
3930+	memcpy(&rep->rep_name, classname, rep->rep_namecount);
3931+
3932+	mach_set_trailer(rep, *msglen);
3933+
3934+	return 0;
3935+}
3936+
3937+int
3938+mach_io_registry_entry_get_location_in_plane(struct mach_trap_args *args)
3939+{
3940+	mach_io_registry_entry_get_location_in_plane_request_t *req =
3941+	    args->smsg;
3942+	mach_io_registry_entry_get_location_in_plane_reply_t *rep = args->rmsg;
3943+	size_t *msglen = args->rsize;
3944+	char location[] = "";
3945+	int end_offset;
3946+
3947+	/*
3948+	 * req_nameoffset is not used.
3949+	 * Sanity check req_namecount.
3950+	 */
3951+	end_offset = req->req_namecount;
3952+	if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
3953+		return mach_msg_error(args, EINVAL);
3954+
3955+	*msglen = sizeof(*rep);
3956+	mach_set_header(rep, req, *msglen);
3957+
3958+	/* XXX Just return a dummy name for now */
3959+	rep->rep_locationcount = sizeof(location);
3960+	memcpy(&rep->rep_location, location, sizeof(location));
3961+
3962+	mach_set_trailer(rep, *msglen);
3963+
3964+	return 0;
3965+}
3966+
3967+int
3968+mach_io_registry_entry_get_properties(struct mach_trap_args *args)
3969+{
3970+	mach_io_registry_entry_get_properties_request_t *req = args->smsg;
3971+	mach_io_registry_entry_get_properties_reply_t *rep = args->rmsg;
3972+	size_t *msglen = args->rsize;
3973+	struct lwp *l = args->l;
3974+	int error;
3975+	void *uaddr;
3976+	size_t size;
3977+	mach_port_t mn;
3978+	struct mach_right *mr;
3979+	struct mach_iokit_devclass *mid;
3980+
3981+	mn = req->req_msgh.msgh_remote_port;
3982+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
3983+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
3984+
3985+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
3986+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3987+
3988+	mid = mr->mr_port->mp_data;
3989+	if (mid->mid_properties == NULL)
3990+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
3991+	size = strlen(mid->mid_properties) + 1; /* Include trailing zero */
3992+
3993+	if ((error = mach_ool_copyout(l,
3994+	    mid->mid_properties, &uaddr, size, MACH_OOL_TRACE)) != 0) {
3995+#ifdef DEBUG_MACH
3996+		printf("pid %d.%d: copyout iokit properties failed\n",
3997+		    l->l_proc->p_pid, l->l_lid);
3998+#endif
3999+	}
4000+
4001+	*msglen = sizeof(*rep);
4002+	mach_set_header(rep, req, *msglen);
4003+	mach_add_ool_desc(rep, uaddr, size);
4004+
4005+	rep->rep_count = size;
4006+
4007+	mach_set_trailer(rep, *msglen);
4008+
4009+	return 0;
4010+}
4011+
4012+int
4013+mach_io_registry_entry_get_property(struct mach_trap_args *args)
4014+{
4015+	mach_io_registry_entry_get_property_request_t *req = args->smsg;
4016+	mach_io_registry_entry_get_property_reply_t *rep = args->rmsg;
4017+	size_t *msglen = args->rsize;
4018+	struct lwp *l = args->l;
4019+	int error;
4020+	void *uaddr;
4021+	size_t size;
4022+	mach_port_t mn;
4023+	struct mach_right *mr;
4024+	struct mach_iokit_devclass *mid;
4025+	struct mach_iokit_property *mip;
4026+	int end_offset;
4027+
4028+	/*
4029+	 * req_property_nameoffset is not used.
4030+	 * Sanity check req_property_namecount.
4031+	 */
4032+	end_offset = req->req_property_namecount;
4033+	if (MACH_REQMSG_OVERFLOW(args, req->req_property_name[end_offset]))
4034+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4035+
4036+	/* Find the port */
4037+	mn = req->req_msgh.msgh_remote_port;
4038+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4039+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4040+
4041+	/* Find the devclass information */
4042+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
4043+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4044+
4045+	mid = mr->mr_port->mp_data;
4046+	if (mid->mid_properties_array == NULL)
4047+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4048+
4049+	/* Lookup the property name */
4050+	for (mip = mid->mid_properties_array; mip->mip_name; mip++)
4051+		if (memcmp(mip->mip_name, req->req_property_name,
4052+		    req->req_property_namecount) == 0)
4053+			break;
4054+
4055+	if (mip->mip_value == NULL)
4056+		return mach_iokit_error(args, MACH_IOKIT_ENOENT);
4057+	size = strlen(mip->mip_value) + 1; /* Include trailing zero */
4058+
4059+	/* And copyout its associated value */
4060+	if ((error = mach_ool_copyout(l,
4061+	    mip->mip_value, &uaddr, size, MACH_OOL_TRACE)) != 0) {
4062+#ifdef DEBUG_MACH
4063+		printf("pid %d.%d: copyout iokit property failed\n",
4064+		    l->l_proc->p_pid, l->l_lid);
4065+#endif
4066+	}
4067+
4068+	*msglen = sizeof(*rep);
4069+	mach_set_header(rep, req, *msglen);
4070+	mach_add_ool_desc(rep, uaddr, size);
4071+
4072+	rep->rep_properties_count = size;
4073+
4074+	mach_set_trailer(rep, *msglen);
4075+
4076+	return 0;
4077+}
4078+
4079+int
4080+mach_io_registry_entry_get_path(struct mach_trap_args *args)
4081+{
4082+	mach_io_registry_entry_get_path_request_t *req = args->smsg;
4083+	mach_io_registry_entry_get_path_reply_t *rep = args->rmsg;
4084+	size_t *msglen = args->rsize;
4085+	char location[] = ":/GossamerPE/pci@80000000/AppleGracklePCI/"
4086+	    "ATY,264LT-G@11/.Display_Video_ATI_mach64-01018002/"
4087+	    "display0/AppleBacklightDisplay";
4088+	char *cp;
4089+	size_t len, plen;
4090+	int end_offset;
4091+
4092+	/*
4093+	 * req_offset is not used.
4094+	 * Sanity check req_count.
4095+	 */
4096+	end_offset = req->req_count;
4097+	if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
4098+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4099+
4100+	/* XXX Just return a dummy name for now */
4101+	len = req->req_count + strlen(location) - 1;
4102+
4103+	/* Sanity check for len */
4104+	if (len > 512)
4105+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4106+	plen = (len & ~0x3UL) + 4;	/* Round to an int */
4107+
4108+	*msglen = sizeof(*rep) + (plen - 512);
4109+	mach_set_header(rep, req, *msglen);
4110+
4111+	rep->rep_retval = 0;
4112+	rep->rep_count = len;
4113+
4114+	cp = &rep->rep_path[0];
4115+	memcpy(cp, &req->req_plane, req->req_count);
4116+	cp += (req->req_count - 1);	/* overwrite trailing \0 */
4117+	memcpy(cp, location, strlen(location));
4118+	cp += strlen(location);
4119+	*cp = '\0';
4120+
4121+	mach_set_trailer(rep, *msglen);
4122+
4123+	return 0;
4124+}
4125+
4126+int
4127+mach_io_connect_map_memory(struct mach_trap_args *args)
4128+{
4129+	mach_io_connect_map_memory_request_t *req = args->smsg;
4130+	struct lwp *l = args->l;
4131+	mach_port_t mn;
4132+	struct mach_right *mr;
4133+	struct mach_iokit_devclass *mid;
4134+
4135+	mn = req->req_msgh.msgh_remote_port;
4136+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4137+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4138+
4139+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
4140+		mid = mr->mr_port->mp_data;
4141+		if (mid->mid_connect_map_memory == NULL)
4142+			printf("no connect_map_memory method "
4143+			    "for darwin_iokit_class %s\n", mid->mid_name);
4144+		else
4145+			return (mid->mid_connect_map_memory)(args);
4146+	}
4147+
4148+	return mach_iokit_error(args, MACH_IOKIT_ENODEV);
4149+}
4150+
4151+int
4152+mach_io_iterator_reset(struct mach_trap_args *args)
4153+{
4154+	mach_io_iterator_reset_request_t *req = args->smsg;
4155+	mach_io_iterator_reset_reply_t *rep = args->rmsg;
4156+	size_t *msglen = args->rsize;
4157+	struct lwp *l = args->l;
4158+	mach_port_t mn;
4159+	struct mach_right *mr;
4160+	struct mach_device_iterator *mdi;
4161+
4162+	mn = req->req_msgh.msgh_remote_port;
4163+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4164+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4165+
4166+	if (mr->mr_port->mp_datatype != MACH_MP_DEVICE_ITERATOR)
4167+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4168+
4169+	mdi = mr->mr_port->mp_data;
4170+	mdi->mdi_current = 0;
4171+
4172+	*msglen = sizeof(*rep);
4173+	mach_set_header(rep, req, *msglen);
4174+
4175+	rep->rep_retval = 0;
4176+
4177+	mach_set_trailer(rep, *msglen);
4178+
4179+	return 0;
4180+}
4181+
4182+int
4183+mach_io_connect_method_scalari_structo(struct mach_trap_args *args)
4184+{
4185+	mach_io_connect_method_scalari_structo_request_t *req = args->smsg;
4186+	struct lwp *l = args->l;
4187+	mach_port_t mn;
4188+	struct mach_right *mr;
4189+	struct mach_iokit_devclass *mid;
4190+	int end_offset;
4191+
4192+	/* Sanity check req_incount */
4193+	end_offset = req->req_incount +
4194+		     (sizeof(req->req_outcount) / sizeof(req->req_in[0]));
4195+	if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
4196+		return mach_msg_error(args, EINVAL);
4197+
4198+	/* Sanity check req_outcount */
4199+	if (req->req_outcount > 4096)
4200+		return mach_msg_error(args, EINVAL);
4201+
4202+	mn = req->req_msgh.msgh_remote_port;
4203+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4204+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4205+
4206+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
4207+		mid = mr->mr_port->mp_data;
4208+		if (mid->mid_connect_method_scalari_structo == NULL)
4209+			printf("no connect_method_scalari_structo method "
4210+			    "for darwin_iokit_class %s\n", mid->mid_name);
4211+		else
4212+			return (mid->mid_connect_method_scalari_structo)(args);
4213+	}
4214+
4215+	return mach_iokit_error(args, MACH_IOKIT_ENODEV);
4216+}
4217+
4218+int
4219+mach_io_connect_method_structi_structo(struct mach_trap_args *args)
4220+{
4221+	mach_io_connect_method_structi_structo_request_t *req = args->smsg;
4222+	struct lwp *l = args->l;
4223+	mach_port_t mn;
4224+	struct mach_right *mr;
4225+	struct mach_iokit_devclass *mid;
4226+	int end_offset;
4227+	int outcount;
4228+
4229+	/* Sanity check req_incount */
4230+	end_offset = req->req_incount +
4231+		     (sizeof(req->req_outcount) / sizeof(req->req_in[0]));
4232+	if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
4233+		return mach_msg_error(args, EINVAL);
4234+
4235+	/* Sanity check outcount. It is word aligned */
4236+	outcount = req->req_in[(req->req_incount & ~0x3UL) + 4];
4237+	if (outcount > 4096)
4238+		return mach_msg_error(args, EINVAL);
4239+
4240+	mn = req->req_msgh.msgh_remote_port;
4241+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4242+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4243+
4244+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
4245+		mid = mr->mr_port->mp_data;
4246+		if (mid->mid_connect_method_structi_structo == NULL)
4247+			printf("no connect_method_structi_structo method "
4248+			    "for darwin_iokit_class %s\n", mid->mid_name);
4249+		else
4250+			return (mid->mid_connect_method_structi_structo)(args);
4251+	}
4252+
4253+	return mach_iokit_error(args, MACH_IOKIT_ENODEV);
4254+}
4255+
4256+int
4257+mach_io_connect_set_properties(struct mach_trap_args *args)
4258+{
4259+	mach_io_connect_set_properties_request_t *req = args->smsg;
4260+	mach_io_connect_set_properties_reply_t *rep = args->rmsg;
4261+	size_t *msglen = args->rsize;
4262+
4263+#ifdef DEBUG_MACH
4264+	uprintf("Unimplemented mach_io_connect_set_properties\n");
4265+#endif
4266+
4267+	*msglen = sizeof(*rep);
4268+	mach_set_header(rep, req, *msglen);
4269+
4270+	mach_set_trailer(rep, *msglen);
4271+
4272+	return 0;
4273+}
4274+
4275+int
4276+mach_io_service_close(struct mach_trap_args *args)
4277+{
4278+	mach_io_service_close_request_t *req = args->smsg;
4279+	mach_io_service_close_reply_t *rep = args->rmsg;
4280+	size_t *msglen = args->rsize;
4281+
4282+#ifdef DEBUG_MACH
4283+	uprintf("Unimplemented mach_io_service_close\n");
4284+#endif
4285+
4286+	*msglen = sizeof(*rep);
4287+	mach_set_header(rep, req, *msglen);
4288+
4289+	rep->rep_retval = 0;
4290+
4291+	mach_set_trailer(rep, *msglen);
4292+
4293+	return 0;
4294+}
4295+
4296+int
4297+mach_io_connect_add_client(struct mach_trap_args *args)
4298+{
4299+	mach_io_connect_add_client_request_t *req = args->smsg;
4300+	mach_io_connect_add_client_reply_t *rep = args->rmsg;
4301+	size_t *msglen = args->rsize;
4302+
4303+#ifdef DEBUG_MACH
4304+	uprintf("Unimplemented mach_io_connect_add_client\n");
4305+#endif
4306+
4307+	*msglen = sizeof(*rep);
4308+	mach_set_header(rep, req, *msglen);
4309+
4310+	rep->rep_retval = 0;
4311+
4312+	mach_set_trailer(rep, *msglen);
4313+
4314+	return 0;
4315+}
4316+
4317+int
4318+mach_io_connect_method_scalari_structi(struct mach_trap_args *args)
4319+{
4320+	mach_io_connect_method_scalari_structi_request_t *req = args->smsg;
4321+	struct lwp *l = args->l;
4322+	mach_port_t mn;
4323+	struct mach_right *mr;
4324+	struct mach_iokit_devclass *mid;
4325+	int end_offset;
4326+	int scalar_size, struct_size, instructcount;
4327+
4328+	/* Sanity check req_incount and get instructcount */
4329+	if (MACH_REQMSG_OVERFLOW(args, req->req_in[req->req_incount]))
4330+		return mach_msg_error(args, EINVAL);
4331+	instructcount = req->req_in[req->req_incount];
4332+
4333+	/* Sanity check instructcount */
4334+	scalar_size = sizeof(req->req_in[0]);
4335+	struct_size = sizeof(req->req_instruct[0]);
4336+	end_offset = req->req_incount +
4337+		     (sizeof(instructcount) / scalar_size) +
4338+		     (instructcount * struct_size / scalar_size);
4339+	if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
4340+		return mach_msg_error(args, EINVAL);
4341+
4342+	mn = req->req_msgh.msgh_remote_port;
4343+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4344+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4345+
4346+	if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
4347+		mid = mr->mr_port->mp_data;
4348+		if (mid->mid_connect_method_scalari_structi == NULL)
4349+			printf("no connect_method_scalari_structi method "
4350+			    "for darwin_iokit_class %s\n", mid->mid_name);
4351+		else
4352+			return (mid->mid_connect_method_scalari_structi)(args);
4353+	}
4354+
4355+	return mach_iokit_error(args, MACH_IOKIT_ENODEV);
4356+}
4357+
4358+int
4359+mach_io_registry_entry_from_path(struct mach_trap_args *args)
4360+{
4361+	mach_io_registry_entry_from_path_request_t *req = args->smsg;
4362+	mach_io_registry_entry_from_path_reply_t *rep = args->rmsg;
4363+	size_t *msglen = args->rsize;
4364+	struct lwp *l = args->l;
4365+	struct mach_port *mp;
4366+	struct mach_right *mr;
4367+	struct mach_iokit_devclass *mid;
4368+	int i, len;
4369+	int end_offset;
4370+
4371+	/*
4372+	 * req_pathoffset is not used.
4373+	 * Sanity check req_pathcount.
4374+	 */
4375+	end_offset = req->req_pathcount;
4376+	if (MACH_REQMSG_OVERFLOW(args, req->req_path[end_offset]))
4377+		return mach_msg_error(args, EINVAL);
4378+
4379+#ifdef DEBUG_MACH
4380+	printf("mach_io_registry_entry_from_path: path = %s\n", req->req_path);
4381+#endif
4382+
4383+	mp = mach_port_get();
4384+	mp->mp_flags |= MACH_MP_INKERNEL;
4385+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
4386+
4387+	i = 0;
4388+	while ((mid = mach_iokit_devclasses[i++]) != NULL) {
4389+		len = strlen(mid->mid_name);
4390+#ifdef DEBUG_MACH
4391+		printf("trying \"%s\" vs \"%s\"\n",
4392+		    &req->req_path[req->req_pathcount - 1 - len],
4393+		    mid->mid_name);
4394+#endif
4395+		if (memcmp(&req->req_path[req->req_pathcount - 1 - len],
4396+		    mid->mid_name, len) == 0) {
4397+			mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
4398+			mp->mp_data = mid;
4399+			break;
4400+		}
4401+	}
4402+
4403+	*msglen = sizeof(*rep);
4404+	mach_set_header(rep, req, *msglen);
4405+	mach_add_port_desc(rep, mr->mr_name);
4406+	mach_set_trailer(rep, *msglen);
4407+
4408+	return 0;
4409+}
4410+
4411+int
4412+mach_io_registry_entry_get_parent_iterator(struct mach_trap_args *args)
4413+{
4414+	mach_io_registry_entry_get_parent_iterator_request_t *req = args->smsg;
4415+	mach_io_registry_entry_get_parent_iterator_reply_t *rep = args->rmsg;
4416+	size_t *msglen = args->rsize;
4417+	struct lwp *l = args->l;
4418+	struct mach_port *mp;
4419+	struct mach_right *mr;
4420+	struct mach_iokit_devclass *mid;
4421+	struct mach_device_iterator *mdi;
4422+	mach_port_t mn;
4423+	int maxdev;
4424+	size_t size;
4425+	int end_offset;
4426+
4427+	/*
4428+	 * req_offset is unused
4429+	 * Sanity check req_count
4430+	 */
4431+	end_offset = req->req_count;
4432+	if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
4433+		return mach_msg_error(args, EINVAL);
4434+
4435+#ifdef DEBUG_MACH
4436+	printf("mach_io_registry_entry_get_parent_iterator: plane = %s\n",
4437+	    req->req_plane);
4438+#endif
4439+
4440+	mn = req->req_msgh.msgh_remote_port;
4441+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
4442+		return mach_iokit_error(args, MACH_IOKIT_EPERM);
4443+
4444+	if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
4445+		return mach_iokit_error(args, MACH_IOKIT_EINVAL);
4446+	mid = mr->mr_port->mp_data;
4447+
4448+	mp = mach_port_get();
4449+	mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
4450+	mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
4451+
4452+	maxdev = sizeof(mach_iokit_devclasses);
4453+	size = sizeof(*mdi) + (maxdev * sizeof(struct mach_iokit_devclass *));
4454+	mdi = malloc(size, M_EMULDATA, M_WAITOK);
4455+	mp->mp_data = mdi;
4456+
4457+	(void)mach_fill_parent_iterator(mdi, maxdev, 0, mid);
4458+	mdi->mdi_current = 0;
4459+
4460+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
4461+
4462+	*msglen = sizeof(*rep);
4463+	mach_set_header(rep, req, *msglen);
4464+	mach_add_port_desc(rep, mr->mr_name);
4465+	mach_set_trailer(rep, *msglen);
4466+
4467+	return 0;
4468+}
4469+
4470+void
4471+mach_iokit_cleanup_notify(struct mach_right *mr)
4472+{
4473+	int i;
4474+	struct mach_iokit_devclass *mid;
4475+
4476+	i = 0;
4477+	while ((mid = mach_iokit_devclasses[i++]) != NULL)
4478+		if (mid->mid_notify == mr)
4479+			mid->mid_notify = NULL;
4480+
4481+	return;
4482+}
4483+
4484+static int
4485+mach_fill_child_iterator(struct mach_device_iterator *mdi, int size, int index, struct mach_iokit_devclass *mid)
4486+{
4487+	struct mach_iokit_devclass **midp;
4488+	struct mach_iokit_devclass **midq;
4489+
4490+	for (midp = mach_iokit_devclasses; *midp != NULL; midp++) {
4491+		for (midq = (*midp)->mid_parent; *midq != NULL; midq++) {
4492+			if (*midq == mid) {
4493+				mdi->mdi_devices[index++] = *midp;
4494+				break;
4495+			}
4496+		}
4497+#ifdef DIAGNOSTIC
4498+		if (index >= size) {
4499+			printf("mach_device_iterator overflow\n");
4500+			break;
4501+		}
4502+#endif
4503+	}
4504+	mdi->mdi_devices[index] = NULL;
4505+
4506+	return index;
4507+}
4508+
4509+static int
4510+mach_fill_parent_iterator(struct mach_device_iterator *mdi, int size, int index, struct mach_iokit_devclass *mid)
4511+{
4512+	struct mach_iokit_devclass **midp;
4513+
4514+	for (midp = mid->mid_parent; *midp != NULL; midp++) {
4515+		mdi->mdi_devices[index++] = *midp;
4516+#ifdef DIAGNOSTIC
4517+		if (index >= size) {
4518+			printf("mach_device_iterator overflow\n");
4519+			break;
4520+		}
4521+#endif
4522+	}
4523+	mdi->mdi_devices[index] = NULL;
4524+
4525+	return index;
4526+}
4527diff --git a/sys/compat/mach/mach_iokit.h b/sys/compat/mach/mach_iokit.h
4528new file mode 100644
4529index 0000000..2981964
4530--- /dev/null
4531+++ b/sys/compat/mach/mach_iokit.h
4532@@ -0,0 +1,547 @@
4533+/*	$NetBSD: mach_iokit.h,v 1.26 2008/04/28 20:23:44 martin Exp $ */
4534+
4535+/*-
4536+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
4537+ * All rights reserved.
4538+ *
4539+ * This code is derived from software contributed to The NetBSD Foundation
4540+ * by Emmanuel Dreyfus
4541+ *
4542+ * Redistribution and use in source and binary forms, with or without
4543+ * modification, are permitted provided that the following conditions
4544+ * are met:
4545+ * 1. Redistributions of source code must retain the above copyright
4546+ *    notice, this list of conditions and the following disclaimer.
4547+ * 2. Redistributions in binary form must reproduce the above copyright
4548+ *    notice, this list of conditions and the following disclaimer in the
4549+ *    documentation and/or other materials provided with the distribution.
4550+ *
4551+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
4552+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
4553+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4554+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
4555+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
4556+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
4557+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4558+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
4559+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4560+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4561+ * POSSIBILITY OF SUCH DAMAGE.
4562+ */
4563+
4564+#ifndef	_MACH_IOKIT_H_
4565+#define	_MACH_IOKIT_H_
4566+
4567+typedef struct mach_io_object *mach_io_object_t;
4568+
4569+/* mach_io_service_get_matching_services */
4570+
4571+typedef struct {
4572+	mach_msg_header_t req_msgh;
4573+	mach_ndr_record_t req_ndr;
4574+	mach_io_object_t req_io_master;
4575+	mach_msg_size_t req_size;
4576+	char req_string[0];
4577+} mach_io_service_get_matching_services_request_t;
4578+
4579+typedef struct {
4580+	mach_msg_header_t rep_msgh;
4581+	mach_msg_body_t rep_body;
4582+	mach_msg_port_descriptor_t rep_match;
4583+	mach_msg_trailer_t rep_trailer;
4584+} mach_io_service_get_matching_services_reply_t;
4585+
4586+/* mach_io_iterator_next */
4587+
4588+typedef struct {
4589+	mach_msg_header_t req_msgh;
4590+} mach_io_iterator_next_request_t;
4591+
4592+typedef struct {
4593+	mach_msg_header_t rep_msgh;
4594+	mach_msg_body_t rep_body;
4595+	mach_msg_port_descriptor_t rep_object;
4596+	mach_msg_trailer_t rep_trailer;
4597+} mach_io_iterator_next_reply_t;
4598+
4599+/* mach_io_service_open */
4600+
4601+typedef struct {
4602+	mach_msg_header_t req_msgh;
4603+	mach_msg_body_t req_body;
4604+	mach_msg_port_descriptor_t req_owningtask;
4605+	mach_ndr_record_t req_ndr;
4606+	int mach_connect_type;
4607+} mach_io_service_open_request_t;
4608+
4609+typedef struct {
4610+	mach_msg_header_t rep_msgh;
4611+	mach_msg_body_t rep_body;
4612+	mach_msg_port_descriptor_t rep_connect;
4613+	mach_msg_trailer_t rep_trailer;
4614+} mach_io_service_open_reply_t;
4615+
4616+/* mach_io_connect_method_scalari_scalaro */
4617+
4618+typedef struct {
4619+	mach_msg_header_t req_msgh;
4620+	mach_ndr_record_t req_ndr;
4621+	int req_selector;
4622+	mach_msg_type_number_t req_incount;
4623+	int req_in[0];
4624+	mach_msg_type_number_t req_outcount;
4625+} mach_io_connect_method_scalari_scalaro_request_t;
4626+
4627+typedef struct {
4628+	mach_msg_header_t rep_msgh;
4629+	mach_ndr_record_t rep_ndr;
4630+	mach_kern_return_t rep_retval;
4631+	mach_msg_type_number_t rep_outcount;
4632+	int rep_out[16];
4633+	mach_msg_trailer_t rep_trailer;
4634+} mach_io_connect_method_scalari_scalaro_reply_t;
4635+
4636+/* io_connect_get_service */
4637+
4638+typedef struct {
4639+	mach_msg_header_t req_msgh;
4640+} mach_io_connect_get_service_request_t;
4641+
4642+typedef struct {
4643+	mach_msg_header_t rep_msgh;
4644+	mach_msg_body_t rep_body;
4645+	mach_msg_port_descriptor_t rep_service;
4646+	mach_msg_trailer_t rep_trailer;
4647+} mach_io_connect_get_service_reply_t;
4648+
4649+/* io_registry_entry_get_property */
4650+
4651+typedef struct {
4652+	mach_msg_header_t req_msgh;
4653+	mach_ndr_record_t req_ndr;
4654+	mach_msg_type_number_t req_property_nameoffset;
4655+	mach_msg_type_number_t req_property_namecount;
4656+	char req_property_name[0];
4657+} mach_io_registry_entry_get_property_request_t;
4658+
4659+typedef struct {
4660+	mach_msg_header_t rep_msgh;
4661+	mach_msg_body_t rep_body;
4662+	mach_msg_ool_descriptor_t rep_properties;
4663+	mach_ndr_record_t rep_ndr;
4664+	mach_msg_type_number_t rep_properties_count;
4665+	mach_msg_trailer_t rep_trailer;
4666+} mach_io_registry_entry_get_property_reply_t;
4667+
4668+/* io_registry_entry_create_iterator */
4669+
4670+#define MACH_IOKIT_RECURSIVE_ITERATOR	1
4671+#define MACH_IOKIT_PARENT_ITERATOR	2
4672+typedef struct {
4673+	mach_msg_header_t req_msgh;
4674+	mach_ndr_record_t req_ndr;
4675+	mach_msg_type_number_t req_planeoffset;
4676+	mach_msg_type_number_t req_planecount;
4677+	char req_plane[0];
4678+	int req_options;
4679+} mach_io_registry_entry_create_iterator_request_t;
4680+
4681+typedef struct {
4682+	mach_msg_header_t rep_msgh;
4683+	mach_msg_body_t rep_body;
4684+	mach_msg_port_descriptor_t rep_iterator;
4685+	mach_msg_trailer_t rep_trailer;
4686+} mach_io_registry_entry_create_iterator_reply_t;
4687+
4688+/* io_object_conforms_to */
4689+
4690+typedef struct {
4691+	mach_msg_header_t req_msgh;
4692+	mach_ndr_record_t req_ndr;
4693+	mach_msg_type_number_t req_classnameoffset;
4694+	mach_msg_type_number_t req_classnamecount;
4695+	char req_classname[0];
4696+} mach_io_object_conforms_to_request_t;
4697+
4698+typedef struct {
4699+	mach_msg_header_t rep_msgh;
4700+	mach_ndr_record_t rep_ndr;
4701+	mach_kern_return_t rep_retval;
4702+	mach_boolean_t rep_conforms;
4703+	mach_msg_trailer_t rep_trailer;
4704+} mach_io_object_conforms_to_reply_t;
4705+
4706+/* io_service_add_interest_notification */
4707+
4708+typedef struct {
4709+	mach_msg_header_t req_msgh;
4710+	mach_msg_body_t req_body;
4711+	mach_msg_port_descriptor_t req_wake_port;
4712+	mach_ndr_record_t req_ndr;
4713+	mach_msg_type_number_t req_typeofinterestoffset;
4714+	mach_msg_type_number_t req_typeofinterestcount;
4715+	char req_typeofinterest[0];
4716+	mach_msg_type_number_t req_refcount;
4717+	mach_natural_t req_ref[0];
4718+} mach_io_service_add_interest_notification_request_t;
4719+
4720+typedef struct {
4721+	mach_msg_header_t rep_msgh;
4722+	mach_msg_body_t rep_body;
4723+	mach_msg_port_descriptor_t rep_notification;
4724+	mach_msg_trailer_t rep_trailer;
4725+} mach_io_service_add_interest_notification_reply_t;
4726+
4727+/* io_connect_set_notification_port */
4728+
4729+typedef struct {
4730+	mach_msg_header_t req_msgh;
4731+	mach_msg_body_t req_body;
4732+	mach_msg_port_descriptor_t req_port;
4733+	mach_ndr_record_t req_ndr;
4734+	int req_notification_type;
4735+	int req_reference;
4736+} mach_io_connect_set_notification_port_request_t;
4737+
4738+typedef struct {
4739+	mach_msg_header_t rep_msgh;
4740+	mach_ndr_record_t rep_ndr;
4741+	mach_kern_return_t rep_retval;
4742+	mach_msg_trailer_t rep_trailer;
4743+} mach_io_connect_set_notification_port_reply_t;
4744+
4745+/* io_registry_get_root_entry */
4746+
4747+typedef struct {
4748+	mach_msg_header_t req_msgh;
4749+} mach_io_registry_get_root_entry_request_t;
4750+
4751+typedef struct {
4752+	mach_msg_header_t rep_msgh;
4753+	mach_msg_body_t rep_body;
4754+	mach_msg_port_descriptor_t rep_root;
4755+	mach_msg_trailer_t rep_trailer;
4756+} mach_io_registry_get_root_entry_reply_t;
4757+
4758+/* io_registry_entry_get_child_iterator */
4759+
4760+typedef struct {
4761+	mach_msg_header_t req_msgh;
4762+	mach_ndr_record_t req_ndr;
4763+	mach_msg_type_number_t req_planeoffset;
4764+	mach_msg_type_number_t req_planecount;
4765+	char req_plane[0];
4766+} mach_io_registry_entry_get_child_iterator_request_t;
4767+
4768+typedef struct {
4769+	mach_msg_header_t rep_msgh;
4770+	mach_msg_body_t rep_body;
4771+	mach_msg_port_descriptor_t rep_iterator;
4772+	mach_msg_trailer_t rep_trailer;
4773+} mach_io_registry_entry_get_child_iterator_reply_t;
4774+
4775+/* io_registry_entry_get_name_in_plane */
4776+
4777+typedef struct {
4778+	mach_msg_header_t req_msgh;
4779+	mach_ndr_record_t req_ndr;
4780+	mach_msg_type_number_t req_planeoffset;
4781+	mach_msg_type_number_t req_planecount;
4782+	char req_plane[0];
4783+} mach_io_registry_entry_get_name_in_plane_request_t;
4784+
4785+typedef struct {
4786+	mach_msg_header_t rep_msgh;
4787+	mach_ndr_record_t rep_ndr;
4788+	mach_kern_return_t rep_retval;
4789+	mach_msg_type_number_t rep_nameoffset;
4790+	mach_msg_type_number_t rep_namecount;
4791+	char rep_name[128];
4792+	mach_msg_trailer_t rep_trailer;
4793+} mach_io_registry_entry_get_name_in_plane_reply_t;
4794+
4795+/* io_object_get_class */
4796+
4797+typedef struct {
4798+	mach_msg_header_t req_msgh;
4799+} mach_io_object_get_class_request_t;
4800+
4801+typedef struct {
4802+	mach_msg_header_t rep_msgh;
4803+	mach_ndr_record_t rep_ndr;
4804+	mach_kern_return_t rep_retval;
4805+	mach_msg_type_number_t rep_nameoffset;
4806+	mach_msg_type_number_t rep_namecount;
4807+	char rep_name[128];
4808+	mach_msg_trailer_t rep_trailer;
4809+} mach_io_object_get_class_reply_t;
4810+
4811+/* io_registry_entry_get_location_in_plane */
4812+
4813+typedef struct {
4814+	mach_msg_header_t req_msgh;
4815+	mach_ndr_record_t req_ndr;
4816+	mach_msg_type_number_t req_nameoffset;
4817+	mach_msg_type_number_t req_namecount;
4818+	char req_plane[0];
4819+} mach_io_registry_entry_get_location_in_plane_request_t;
4820+
4821+typedef struct {
4822+	mach_msg_header_t rep_msgh;
4823+	mach_ndr_record_t rep_ndr;
4824+	mach_kern_return_t rep_retval;
4825+	mach_msg_type_number_t rep_locationoffset;
4826+	mach_msg_type_number_t rep_locationcount;
4827+	char rep_location[128];
4828+	mach_msg_trailer_t rep_trailer;
4829+} mach_io_registry_entry_get_location_in_plane_reply_t;
4830+
4831+/* io_registry_entry_get_properties */
4832+
4833+typedef struct {
4834+	mach_msg_header_t req_msgh;
4835+} mach_io_registry_entry_get_properties_request_t;
4836+
4837+typedef struct {
4838+	mach_msg_header_t rep_msgh;
4839+	mach_msg_body_t rep_body;
4840+	mach_msg_ool_descriptor_t rep_properties;
4841+	mach_ndr_record_t rep_ndr;
4842+	mach_msg_type_number_t rep_count;
4843+	mach_msg_trailer_t rep_trailer;
4844+} mach_io_registry_entry_get_properties_reply_t;
4845+
4846+/* io_registry_entry_get_path */
4847+
4848+typedef struct {
4849+	mach_msg_header_t req_msgh;
4850+	mach_ndr_record_t req_ndr;
4851+	mach_msg_type_number_t req_offset;
4852+	mach_msg_type_number_t req_count;
4853+	char req_plane[0];
4854+} mach_io_registry_entry_get_path_request_t;
4855+
4856+typedef struct {
4857+	mach_msg_header_t rep_msgh;
4858+	mach_ndr_record_t rep_ndr;
4859+	mach_kern_return_t rep_retval;
4860+	mach_msg_type_number_t rep_offset;
4861+	mach_msg_type_number_t rep_count;
4862+	char rep_path[512];
4863+	mach_msg_trailer_t rep_trailer;
4864+} mach_io_registry_entry_get_path_reply_t;
4865+
4866+/* io_connect_map_memory */
4867+
4868+typedef struct {
4869+	mach_msg_header_t req_msgh;
4870+	mach_msg_body_t req_body;
4871+	mach_msg_port_descriptor_t req_task;
4872+	mach_ndr_record_t req_ndr;
4873+	int req_memtype;
4874+	mach_vm_address_t req_addr;
4875+	mach_vm_size_t req_len;
4876+	int req_flags;
4877+} mach_io_connect_map_memory_request_t;
4878+
4879+typedef struct {
4880+	mach_msg_header_t rep_msgh;
4881+	mach_ndr_record_t rep_ndr;
4882+	mach_kern_return_t rep_retval;
4883+	mach_vm_address_t rep_addr;
4884+	mach_vm_size_t rep_len;
4885+	mach_msg_trailer_t rep_trailer;
4886+} mach_io_connect_map_memory_reply_t;
4887+
4888+/* io_iterator_reset */
4889+
4890+typedef struct {
4891+	mach_msg_header_t req_msgh;
4892+#if 0	/* Is it optional? Darwin don't include them */
4893+	mach_ndr_record_t req_ndr;
4894+	int req_flags;
4895+#endif
4896+} mach_io_iterator_reset_request_t;
4897+
4898+typedef struct {
4899+	mach_msg_header_t rep_msgh;
4900+	mach_ndr_record_t rep_ndr;
4901+	mach_kern_return_t rep_retval;
4902+	mach_msg_trailer_t rep_trailer;
4903+} mach_io_iterator_reset_reply_t;
4904+
4905+/* io_connect_set_properties */
4906+
4907+typedef struct {
4908+	mach_msg_header_t req_msgh;
4909+	mach_msg_body_t req_body;
4910+	mach_msg_ool_descriptor_t req_properties;
4911+	mach_ndr_record_t req_ndr;
4912+	mach_msg_type_number_t req_count;
4913+} mach_io_connect_set_properties_request_t;
4914+
4915+typedef struct {
4916+	mach_msg_header_t rep_msgh;
4917+	mach_ndr_record_t rep_ndr;
4918+	mach_kern_return_t rep_retval;
4919+	mach_natural_t rep_result;
4920+	mach_msg_trailer_t rep_trailer;
4921+} mach_io_connect_set_properties_reply_t;
4922+
4923+/* io_connect_method_scalari_structo */
4924+
4925+typedef struct {
4926+	mach_msg_header_t req_msgh;
4927+	mach_ndr_record_t req_ndr;
4928+	int req_selector;
4929+	mach_msg_type_number_t req_incount;
4930+	int req_in[0];
4931+	mach_msg_type_number_t req_outcount;
4932+} mach_io_connect_method_scalari_structo_request_t;
4933+
4934+typedef struct {
4935+	mach_msg_header_t rep_msgh;
4936+	mach_ndr_record_t rep_ndr;
4937+	mach_kern_return_t rep_retval;
4938+	mach_msg_type_number_t rep_outcount;
4939+	char rep_out[4096];
4940+	mach_msg_trailer_t rep_trailer;
4941+} mach_io_connect_method_scalari_structo_reply_t;
4942+
4943+/* io_connect_method_structi_structo */
4944+
4945+typedef struct {
4946+	mach_msg_header_t req_msgh;
4947+	mach_ndr_record_t req_ndr;
4948+	int req_selector;
4949+	mach_msg_type_number_t req_incount;
4950+	char req_in[0];
4951+	mach_msg_type_number_t req_outcount;
4952+} mach_io_connect_method_structi_structo_request_t;
4953+
4954+typedef struct {
4955+	mach_msg_header_t rep_msgh;
4956+	mach_ndr_record_t rep_ndr;
4957+	mach_kern_return_t rep_retval;
4958+	mach_msg_type_number_t rep_outcount;
4959+	char rep_out[4096];
4960+	mach_msg_trailer_t rep_trailer;
4961+} mach_io_connect_method_structi_structo_reply_t;
4962+
4963+/* io_service_close */
4964+
4965+typedef struct {
4966+	mach_msg_header_t req_msgh;
4967+} mach_io_service_close_request_t;
4968+
4969+typedef struct {
4970+	mach_msg_header_t rep_msgh;
4971+	mach_ndr_record_t rep_ndr;
4972+	mach_kern_return_t rep_retval;
4973+	mach_msg_trailer_t rep_trailer;
4974+} mach_io_service_close_reply_t;
4975+
4976+/* io_connect_add_client */
4977+
4978+typedef struct {
4979+	mach_msg_header_t req_msgh;
4980+	mach_msg_body_t req_body;
4981+	mach_msg_port_descriptor_t req_connect;
4982+} mach_io_connect_add_client_request_t;
4983+
4984+typedef struct {
4985+	mach_msg_header_t rep_msgh;
4986+	mach_ndr_record_t rep_ndr;
4987+	mach_kern_return_t rep_retval;
4988+	mach_msg_trailer_t rep_trailer;
4989+} mach_io_connect_add_client_reply_t;
4990+
4991+/* io_connect_method_scalari_structi */
4992+
4993+typedef struct {
4994+	mach_msg_header_t req_msgh;
4995+	mach_ndr_record_t req_ndr;
4996+	int req_selector;
4997+	mach_msg_type_number_t req_incount;
4998+	int req_in[0];
4999+	mach_msg_type_number_t req_instructcount;
5000+	char req_instruct[0];
5001+} mach_io_connect_method_scalari_structi_request_t;
5002+
5003+typedef struct {
5004+	mach_msg_header_t rep_msgh;
5005+	mach_ndr_record_t rep_ndr;
5006+	mach_kern_return_t rep_retval;
5007+	mach_msg_trailer_t rep_trailer;
5008+} mach_io_connect_method_scalari_structi_reply_t;
5009+
5010+/* io_registry_entry_from_path */
5011+
5012+typedef struct {
5013+	mach_msg_header_t req_msgh;
5014+	mach_ndr_record_t req_ndr;
5015+	mach_msg_type_number_t req_pathoffset;
5016+	mach_msg_type_number_t req_pathcount;
5017+	char req_path[0];
5018+} mach_io_registry_entry_from_path_request_t;
5019+
5020+typedef struct {
5021+	mach_msg_header_t rep_msgh;
5022+	mach_msg_body_t rep_body;
5023+	mach_msg_port_descriptor_t rep_entry;
5024+	mach_msg_trailer_t rep_trailer;
5025+} mach_io_registry_entry_from_path_reply_t;
5026+
5027+/* io_registry_entry_get_parent_iterator */
5028+
5029+typedef struct {
5030+	mach_msg_header_t req_msgh;
5031+	mach_ndr_record_t req_ndr;
5032+	mach_msg_type_number_t req_offset;
5033+	mach_msg_type_number_t req_count;
5034+	char req_plane[0];
5035+} mach_io_registry_entry_get_parent_iterator_request_t;
5036+
5037+typedef struct {
5038+	mach_msg_header_t rep_msgh;
5039+	mach_msg_body_t rep_body;
5040+	mach_msg_port_descriptor_t rep_iterator;
5041+	mach_msg_trailer_t rep_trailer;
5042+} mach_io_registry_entry_get_parent_iterator_reply_t;
5043+
5044+
5045+/* Kernel-private structures */
5046+
5047+extern struct mach_iokit_devclass *mach_iokit_devclasses[];
5048+
5049+struct mach_iokit_property {
5050+	const char *mip_name;
5051+	const char *mip_value;
5052+};
5053+
5054+struct mach_device_iterator {
5055+	int mdi_current;
5056+	struct mach_iokit_devclass *mdi_devices[1];
5057+};
5058+
5059+/* Make this dynamic if it ever gets useful */
5060+#define MACH_IOKIT_MAX_PARENTS	8
5061+struct mach_iokit_devclass {
5062+	const char *mid_string;
5063+	struct mach_iokit_devclass *mid_parent[MACH_IOKIT_MAX_PARENTS];
5064+	const char *mid_properties;
5065+	struct mach_iokit_property *mid_properties_array;
5066+	int (*mid_connect_method_scalari_scalaro)(struct mach_trap_args *);
5067+	int (*mid_connect_method_scalari_structo)(struct mach_trap_args *);
5068+	int (*mid_connect_method_structi_structo)(struct mach_trap_args *);
5069+	int (*mid_connect_method_scalari_structi)(struct mach_trap_args *);
5070+	int (*mid_connect_map_memory)(struct mach_trap_args *);
5071+	const char *mid_name;
5072+	struct mach_right *mid_notify;
5073+};
5074+
5075+extern struct mach_iokit_devclass mach_ioroot_devclass;
5076+
5077+void mach_iokit_cleanup_notify(struct mach_right *);
5078+
5079+#endif /* _MACH_IOKIT_H_ */
5080diff --git a/sys/compat/mach/mach_message.c b/sys/compat/mach/mach_message.c
5081new file mode 100644
5082index 0000000..c7e60a7
5083--- /dev/null
5084+++ b/sys/compat/mach/mach_message.c
5085@@ -0,0 +1,1230 @@
5086+/*	$NetBSD: mach_message.c,v 1.59 2009/03/18 16:00:17 cegger Exp $ */
5087+
5088+/*-
5089+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
5090+ * All rights reserved.
5091+ *
5092+ * This code is derived from software contributed to The NetBSD Foundation
5093+ * by Emmanuel Dreyfus
5094+ *
5095+ * Redistribution and use in source and binary forms, with or without
5096+ * modification, are permitted provided that the following conditions
5097+ * are met:
5098+ * 1. Redistributions of source code must retain the above copyright
5099+ *    notice, this list of conditions and the following disclaimer.
5100+ * 2. Redistributions in binary form must reproduce the above copyright
5101+ *    notice, this list of conditions and the following disclaimer in the
5102+ *    documentation and/or other materials provided with the distribution.
5103+ *
5104+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
5105+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
5106+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5107+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
5108+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5109+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5110+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5111+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
5112+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5113+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5114+ * POSSIBILITY OF SUCH DAMAGE.
5115+ */
5116+
5117+#include <sys/cdefs.h>
5118+__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.59 2009/03/18 16:00:17 cegger Exp $");
5119+
5120+#include "opt_compat_mach.h" /* For COMPAT_MACH in <sys/ktrace.h> */
5121+#include "opt_compat_darwin.h"
5122+
5123+#include <sys/types.h>
5124+#include <sys/param.h>
5125+#include <sys/systm.h>
5126+#include <sys/signal.h>
5127+#include <sys/proc.h>
5128+#include <sys/kernel.h>
5129+#include <sys/queue.h>
5130+#include <sys/malloc.h>
5131+#include <sys/pool.h>
5132+#include <sys/ktrace.h>
5133+
5134+#include <uvm/uvm_extern.h>
5135+#include <uvm/uvm_map.h>
5136+
5137+#include <compat/mach/mach_types.h>
5138+#include <compat/mach/mach_message.h>
5139+#include <compat/mach/mach_port.h>
5140+#include <compat/mach/mach_exec.h>
5141+#include <compat/mach/mach_clock.h>
5142+#include <compat/mach/mach_syscallargs.h>
5143+
5144+#ifdef COMPAT_DARWIN
5145+#include <compat/darwin/darwin_exec.h>
5146+#endif
5147+
5148+/* Mach message pool */
5149+static struct pool mach_message_pool;
5150+
5151+static inline
5152+    int mach_msg_send(struct lwp *, mach_msg_header_t *, int *, size_t);
5153+static inline int mach_msg_recv(struct lwp *, mach_msg_header_t *,
5154+    int, size_t, unsigned int, mach_port_t);
5155+static inline
5156+    struct lwp *mach_get_target_task(struct lwp *, struct mach_port *);
5157+static inline void mach_drop_rights(struct mach_right *, int);
5158+static inline
5159+    void mach_trade_rights(struct lwp *, struct lwp *, mach_port_t *, int);
5160+static inline
5161+    int mach_trade_rights_complex(struct lwp *, struct mach_message *);
5162+
5163+int
5164+mach_sys_msg_overwrite_trap(struct lwp *l, const struct mach_sys_msg_overwrite_trap_args *uap, register_t *retval)
5165+{
5166+	/* {
5167+		syscallarg(mach_msg_header_t *) msg;
5168+		syscallarg(mach_msg_option_t) option;
5169+		syscallarg(mach_msg_size_t) send_size;
5170+		syscallarg(mach_msg_size_t) rcv_size;
5171+		syscallarg(mach_port_name_t) rcv_name;
5172+		syscallarg(mach_msg_timeout_t) timeout;
5173+		syscallarg(mach_port_name_t) notify;
5174+		syscallarg(mach_msg_header_t *) rcv_msg;
5175+		syscallarg(mach_msg_size_t) scatter_list_size;
5176+	} */
5177+	size_t send_size, recv_size;
5178+	mach_msg_header_t *msg;
5179+	int opt;
5180+
5181+	*retval = MACH_MSG_SUCCESS;
5182+	send_size = SCARG(uap, send_size);
5183+	recv_size = SCARG(uap, rcv_size);
5184+	opt = SCARG(uap, option);
5185+
5186+	/* XXX not safe enough: lots of big messages will kill us */
5187+	if (send_size > MACH_MAX_MSG_LEN) {
5188+		*retval = MACH_SEND_TOO_LARGE;
5189+		return 0;
5190+	}
5191+	if (recv_size > MACH_MAX_MSG_LEN) {
5192+		*retval = MACH_RCV_TOO_LARGE;
5193+		return 0;
5194+	}
5195+
5196+	/*
5197+	 * Two options: receive or send. If both are
5198+	 * set, we must send, and then receive. If
5199+	 * send fail, then we skip recieve.
5200+	 */
5201+	msg = SCARG(uap, msg);
5202+	if (opt & MACH_SEND_MSG)
5203+		*retval = mach_msg_send(l, msg, &opt, send_size);
5204+
5205+	if ((opt & MACH_RCV_MSG) && (*retval == MACH_MSG_SUCCESS)) {
5206+		/*
5207+		 * Find a buffer for the reply.
5208+		 */
5209+		if (SCARG(uap, rcv_msg) != NULL)
5210+			msg = SCARG(uap, rcv_msg);
5211+		else if (SCARG(uap, msg) != NULL)
5212+			msg = SCARG(uap, msg);
5213+		else {
5214+			*retval = MACH_RCV_INVALID_DATA;
5215+			return 0;
5216+		}
5217+
5218+		*retval = mach_msg_recv(l, msg, opt, recv_size,
5219+		    SCARG(uap, timeout), SCARG(uap, rcv_name));
5220+	}
5221+
5222+	return 0;
5223+}
5224+
5225+/*
5226+ * Send a Mach message. This returns a Mach message error code.
5227+ */
5228+static inline int
5229+mach_msg_send(struct lwp *l, mach_msg_header_t *msg, int *option, size_t send_size)
5230+{
5231+	struct mach_emuldata *med;
5232+	struct mach_port *mp;
5233+	struct proc *p = l->l_proc;
5234+	mach_msg_header_t *sm;
5235+	struct mach_service *srv;
5236+	mach_port_t ln;
5237+	mach_port_t rn;
5238+	struct mach_right *lr = NULL;
5239+	struct mach_right *rr;
5240+	int rights;
5241+	int bits;
5242+	int ret;
5243+	size_t reply_size;
5244+	int error = 0;
5245+
5246+	if (msg == NULL)
5247+		return MACH_SEND_INVALID_DATA;
5248+
5249+	/*
5250+	 * Allocate memory for the message and its reply,
5251+	 * and copy the whole message in the kernel.
5252+	 */
5253+	sm = malloc(send_size, M_EMULDATA, M_WAITOK);
5254+	if ((error = copyin(msg, sm, send_size)) != 0) {
5255+		ret = MACH_SEND_INVALID_DATA;
5256+		goto out1;
5257+	}
5258+
5259+	/* Dump the Mach message */
5260+	ktrmmsg((char *)sm, send_size);
5261+
5262+	/*
5263+	 * Handle rights in the message
5264+	 */
5265+	ln = sm->msgh_local_port;
5266+	rn = sm->msgh_remote_port;
5267+
5268+	lr = mach_right_check(ln, l, MACH_PORT_TYPE_ALL_RIGHTS);
5269+	rr = mach_right_check(rn, l, MACH_PORT_TYPE_ALL_RIGHTS);
5270+	if ((rr == NULL) || (rr->mr_port == NULL)) {
5271+#ifdef DEBUG_MACH
5272+		printf("msg id %d: invalid dest\n", sm->msgh_id);
5273+#endif
5274+		ret = MACH_SEND_INVALID_DEST;
5275+		goto out1;
5276+	}
5277+
5278+	/*
5279+	 * Check that the process has a send right on
5280+	 * the remote port.
5281+	 */
5282+	rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_SEND_ONCE);
5283+	if (mach_right_check(rn, l, rights) == NULL) {
5284+		ret = MACH_SEND_INVALID_RIGHT;
5285+		goto out1;
5286+	}
5287+
5288+	/*
5289+	 * If the remote port is a special port (host, kernel,
5290+	 * clock, or io_master), the message will be handled
5291+	 * by the kernel.
5292+	 */
5293+	med = (struct mach_emuldata *)p->p_emuldata;
5294+	mp = rr->mr_port;
5295+	if (mp->mp_flags & MACH_MP_INKERNEL) {
5296+		struct mach_trap_args args;
5297+		mach_msg_header_t *rm;
5298+		size_t min_reqlen, max_replen;
5299+
5300+		/*
5301+		 * Look for the function that will handle it,
5302+		 * using the message id.
5303+		 */
5304+		for (srv = mach_services_table; srv->srv_id; srv++)
5305+			if (srv->srv_id == sm->msgh_id)
5306+				break;
5307+
5308+		/*
5309+		 * If no match, give up, and display a warning.
5310+		 */
5311+		if (srv->srv_handler == NULL) {
5312+			uprintf("No mach server for id = %d\n",
5313+			    sm->msgh_id);
5314+			ret = MACH_SEND_INVALID_DEST;
5315+			goto out1;
5316+		}
5317+		min_reqlen = srv->srv_reqlen;
5318+		max_replen = srv->srv_replen;
5319+
5320+		/*
5321+		 * Special case when the kernel behaves as
5322+		 * the client: replies to exceptions and
5323+		 * notifications. There will be no reply,
5324+		 * as we already receive a reply.
5325+		 * - request and reply are swapped
5326+		 * - there will be no reply, so set lr to NULL.
5327+		 * - skip the lr == NULL tests
5328+		 * XXX This is inelegant.
5329+		 */
5330+		if ((sm->msgh_id >= 2501) && (sm->msgh_id <= 2503)) {
5331+			min_reqlen = srv->srv_replen;
5332+			max_replen = srv->srv_reqlen;
5333+			lr = NULL;
5334+			goto skip_null_lr;
5335+		}
5336+
5337+		/*
5338+		 * Check that the local port is valid, else
5339+		 * we will not be able to send the reply
5340+		 */
5341+		if ((lr == NULL) ||
5342+		    (lr->mr_port == NULL) ||
5343+		    (lr->mr_port->mp_recv == NULL)) {
5344+#ifdef DEBUG_MACH
5345+			printf("msg id %d: invalid src\n", sm->msgh_id);
5346+#endif
5347+			ret = MACH_SEND_INVALID_REPLY;
5348+			goto out1;
5349+		}
5350+skip_null_lr:
5351+
5352+		/*
5353+		 * Sanity check message length. We do not want the
5354+		 * server to:
5355+		 * 1) use kernel memory located after
5356+		 *    the end of the request message.
5357+		 */
5358+		if (send_size < min_reqlen) {
5359+#ifdef DEBUG_MACH
5360+			printf("mach server %s: smsg overflow: "
5361+			    "send = %d, min = %d\n",
5362+			    srv->srv_name, send_size, min_reqlen);
5363+#endif
5364+			ret = MACH_SEND_MSG_TOO_SMALL;
5365+			goto out1;
5366+		}
5367+
5368+		/*
5369+		 * 2) Overwrite kernel memory after the end of the
5370+		 *    reply message buffer. This check is the
5371+		 *    responsibility of the server.
5372+		 */
5373+
5374+
5375+		/*
5376+		 * Invoke the server. We give it the opportunity
5377+		 * to shorten recv_size if there is less data in
5378+		 * the reply than what the sender expected.
5379+		 * If lr is NULL, this is a no reply operation.
5380+		 */
5381+		reply_size = max_replen;
5382+		if (lr != NULL)
5383+			rm = malloc(reply_size, M_EMULDATA, M_WAITOK | M_ZERO);
5384+		else
5385+			rm = NULL;
5386+
5387+		args.l = l;
5388+		args.tl = mach_get_target_task(l, mp);
5389+		args.smsg = sm;
5390+		args.rmsg = rm;
5391+		args.rsize = &reply_size;
5392+		args.ssize = send_size;
5393+		if ((ret = (*srv->srv_handler)(&args)) != 0)
5394+			goto out1;
5395+
5396+		/*
5397+		 * No-reply opration: everything is done.
5398+		 * Change option so that we skip the
5399+		 * receive stage.
5400+		 */
5401+		if (lr == NULL) {
5402+			*option &= ~MACH_RCV_MSG;
5403+			return MACH_MSG_SUCCESS;
5404+		}
5405+
5406+#ifdef DIAGNOSTIC
5407+		/*
5408+		 * Catch potential bug in the server (sanity
5409+		 * check #2): did it output a larger message
5410+		 * then the one that was allocated?
5411+		 */
5412+		if ((*option & MACH_RCV_MSG) && (reply_size > max_replen)) {
5413+			uprintf("mach_msg: reply too big in %s\n",
5414+			    srv->srv_name);
5415+		}
5416+#endif
5417+
5418+		/*
5419+		 * Queue the reply.
5420+		 */
5421+		mp = lr->mr_port;
5422+		(void)mach_message_get(rm, reply_size, mp, NULL);
5423+#ifdef DEBUG_MACH_MSG
5424+		printf("pid %d: message queued on port %p (%d) [%p]\n",
5425+		    p->p_pid, mp, rm->msgh_id,
5426+		    mp->mp_recv->mr_sethead);
5427+		if (sm->msgh_id == 404)
5428+			printf("*** msg to bootstrap. port = %p, "
5429+			    "recv = %p [%p]\n", mach_bootstrap_port,
5430+			    mach_bootstrap_port->mp_recv,
5431+			    mach_bootstrap_port->mp_recv->mr_sethead);
5432+#endif
5433+		wakeup(mp->mp_recv->mr_sethead);
5434+		ret = MACH_MSG_SUCCESS;
5435+out1:
5436+		free(sm, M_EMULDATA);
5437+
5438+		return ret;
5439+	}
5440+
5441+	/*
5442+	 * The message is not to be handled by the kernel.
5443+	 * Check that there is a valid receiver, and
5444+	 * queue the message in the remote port.
5445+	 */
5446+	mp = rr->mr_port; /* (mp != NULL) already checked */
5447+	if (mp->mp_recv == NULL) {
5448+#ifdef DEBUG_MACH
5449+		printf("msg id %d: invalid dst\n", sm->msgh_id);
5450+#endif
5451+		free(sm, M_EMULDATA);
5452+		return MACH_SEND_INVALID_DEST;
5453+	}
5454+
5455+	(void)mach_message_get(sm, send_size, mp, l);
5456+#ifdef DEBUG_MACH_MSG
5457+	printf("pid %d: message queued on port %p (%d) [%p]\n",
5458+	    p->p_pid, mp, sm->msgh_id,
5459+	    mp->mp_recv->mr_sethead);
5460+#endif
5461+	/*
5462+	 * Drop any right carried by the message.
5463+	 */
5464+	if (lr != NULL) {
5465+		bits = MACH_MSGH_LOCAL_BITS(sm->msgh_bits);
5466+		mach_drop_rights(lr, bits);
5467+	}
5468+
5469+	if (rr != NULL) {
5470+		bits = MACH_MSGH_REMOTE_BITS(sm->msgh_bits);
5471+		mach_drop_rights(rr, bits);
5472+	}
5473+
5474+	/*
5475+	 * Wakeup any process awaiting for this message.
5476+	 */
5477+	wakeup(mp->mp_recv->mr_sethead);
5478+
5479+	return MACH_MSG_SUCCESS;
5480+}
5481+
5482+/*
5483+ * Receive a Mach message. This returns a Mach message error code.
5484+ */
5485+static inline int
5486+mach_msg_recv(struct lwp *l, mach_msg_header_t *urm, int option, size_t recv_size, unsigned int timeout, mach_port_t mn)
5487+{
5488+	struct mach_port *mp;
5489+#if defined(DEBUG_MACH_MSG) || defined(KTRACE)
5490+	struct proc *p = l->l_proc;
5491+#endif
5492+	struct mach_message *mm;
5493+	mach_port_t tmp;
5494+	struct mach_right *cmr;
5495+	struct mach_right *mr;
5496+	int bits;
5497+	int ret;
5498+	int error = 0;
5499+
5500+	mp = NULL;
5501+
5502+	if (option & MACH_RCV_TIMEOUT)
5503+		timeout = timeout * hz / 1000;
5504+	else
5505+		timeout = 0;
5506+
5507+	/*
5508+	 * Check for receive right on the port.
5509+	 */
5510+	mr = mach_right_check(mn, l, MACH_PORT_TYPE_RECEIVE);
5511+	if (mr == NULL) {
5512+
5513+		/*
5514+		 * Is it a port set?
5515+		 */
5516+		mr = mach_right_check(mn, l, MACH_PORT_TYPE_PORT_SET);
5517+		if (mr == NULL)
5518+			return MACH_RCV_INVALID_NAME;
5519+
5520+		/*
5521+		 * This is a port set. For each port in the
5522+		 * port set, check we have receive right, and
5523+		 * and check if we have some message.
5524+		 */
5525+		LIST_FOREACH(cmr, &mr->mr_set, mr_setlist) {
5526+			if ((mach_right_check(cmr->mr_name, l,
5527+			    MACH_PORT_TYPE_RECEIVE)) == NULL)
5528+				return MACH_RCV_INVALID_NAME;
5529+
5530+			mp = cmr->mr_port;
5531+#ifdef DEBUG_MACH
5532+			if (mp->mp_recv != cmr)
5533+				uprintf("mach_msg_trap: bad receive "
5534+				    "port/right\n");
5535+#endif
5536+			if (mp->mp_count != 0)
5537+				break;
5538+		}
5539+
5540+		/*
5541+		 * If cmr is NULL then we found no message on
5542+		 * any port. Sleep on the port set until we get
5543+		 * some or until we get a timeout.
5544+		 */
5545+		if (cmr == NULL) {
5546+#ifdef DEBUG_MACH_MSG
5547+			printf("pid %d: wait on port %p [%p]\n",
5548+			    p->p_pid, mp, mr->mr_sethead);
5549+#endif
5550+			error = tsleep(mr->mr_sethead, PZERO|PCATCH,
5551+			    "mach_msg", timeout);
5552+			if ((error == ERESTART) || (error == EINTR))
5553+				return MACH_RCV_INTERRUPTED;
5554+
5555+			/*
5556+			 * Check we did not loose the receive right
5557+			 * while we were sleeping.
5558+			 */
5559+			if ((mach_right_check(mn, l,
5560+			     MACH_PORT_TYPE_PORT_SET)) == NULL)
5561+				return  MACH_RCV_PORT_DIED;
5562+
5563+			/*
5564+			 * Is there any pending message for
5565+			 * a port in the port set?
5566+			 */
5567+			LIST_FOREACH(cmr, &mr->mr_set, mr_setlist) {
5568+				mp = cmr->mr_port;
5569+				if (mp->mp_count != 0)
5570+					break;
5571+			}
5572+
5573+			if (cmr == NULL)
5574+				return MACH_RCV_TIMED_OUT;
5575+		}
5576+
5577+		/*
5578+		 * We found a port with a pending message.
5579+		 */
5580+		mp = cmr->mr_port;
5581+
5582+	} else {
5583+		/*
5584+		 * This is a receive on a simple port (no port set).
5585+		 * If there is no message queued on the port,
5586+		 * block until we get some.
5587+		 */
5588+		mp = mr->mr_port;
5589+
5590+#ifdef DEBUG_MACH
5591+		if (mp->mp_recv != mr)
5592+			uprintf("mach_msg_trap: bad receive "
5593+			    "port/right\n");
5594+#endif
5595+#ifdef DEBUG_MACH_MSG
5596+		printf("pid %d: wait on port %p [%p]\n",
5597+		    p->p_pid, mp, mr->mr_sethead);
5598+#endif
5599+		if (mp->mp_count == 0) {
5600+			error = tsleep(mr->mr_sethead, PZERO|PCATCH,
5601+			    "mach_msg", timeout);
5602+			if ((error == ERESTART) || (error == EINTR))
5603+				return MACH_RCV_INTERRUPTED;
5604+
5605+			/*
5606+			 * Check we did not lose the receive right
5607+			 * while we were sleeping.
5608+			 */
5609+			if ((mach_right_check(mn, l,
5610+			     MACH_PORT_TYPE_RECEIVE)) == NULL)
5611+				return MACH_RCV_PORT_DIED;
5612+
5613+			if (mp->mp_count == 0)
5614+				return MACH_RCV_TIMED_OUT;
5615+		}
5616+	}
5617+
5618+	/*
5619+	 * Dequeue the message.
5620+	 * XXX Do we really need to lock here? There could be
5621+	 * only one reader process, so mm will not disapear
5622+	 * except if there is a port refcount error in our code.
5623+	 */
5624+	rw_enter(&mp->mp_msglock, RW_READER);
5625+	mm = TAILQ_FIRST(&mp->mp_msglist);
5626+#ifdef DEBUG_MACH_MSG
5627+	printf("pid %d: dequeue message on port %p (id %d)\n",
5628+	    p->p_pid, mp, mm->mm_msg->msgh_id);
5629+#endif
5630+
5631+	ret = MACH_MSG_SUCCESS;
5632+	if (mm->mm_size > recv_size) {
5633+		struct mach_short_reply sr;
5634+
5635+		ret = MACH_RCV_TOO_LARGE;
5636+		/*
5637+		 * If MACH_RCV_LARGE was not set, destroy the message.
5638+		 */
5639+		if ((option & MACH_RCV_LARGE) == 0) {
5640+			free(mm->mm_msg, M_EMULDATA);
5641+			mach_message_put_shlocked(mm);
5642+			goto unlock;
5643+		}
5644+
5645+		/*
5646+		 * If MACH_RCV_TOO_LARGE is set, then return
5647+		 * a message with just header and trailer. The
5648+		 * size in the header should correspond to the
5649+		 * whole message, so just copy the whole header.
5650+		 */
5651+		memcpy(&sr, mm->mm_msg, sizeof(mach_msg_header_t));
5652+		mach_set_trailer(&sr, sizeof(sr));
5653+
5654+		if ((error = copyout(&sr, urm, sizeof(sr))) != 0) {
5655+			ret = MACH_RCV_INVALID_DATA;
5656+			goto unlock;
5657+		}
5658+
5659+		/* Dump the Mach message */
5660+		ktrmmsg((char *)&sr, sizeof(sr));
5661+		goto unlock;
5662+	}
5663+
5664+	/*
5665+	 * Get rights carried by the message if it is not a
5666+	 * reply from the kernel.
5667+	 * XXX mm->mm_l could contain stall data. Reference
5668+	 * the thread's kernel port instead?
5669+	 */
5670+	if (mm->mm_l != NULL) {
5671+		mach_port_t *mnp;
5672+#ifdef DEBUG_MACH
5673+		printf("mach_msg: non kernel-reply message\n");
5674+#endif
5675+		/*
5676+		 * Turn local and remote port names into
5677+		 * names in the local process namespace.
5678+		 */
5679+		bits = MACH_MSGH_LOCAL_BITS(mm->mm_msg->msgh_bits);
5680+		mnp = &mm->mm_msg->msgh_local_port;
5681+		mach_trade_rights(l, mm->mm_l, mnp, bits);
5682+
5683+		bits = MACH_MSGH_REMOTE_BITS(mm->mm_msg->msgh_bits);
5684+		mnp = &mm->mm_msg->msgh_remote_port;
5685+		mach_trade_rights(l, mm->mm_l, mnp, bits);
5686+
5687+		/*
5688+		 * The same operation must be done to all
5689+		 * port descriptors carried with the message.
5690+		 */
5691+		if ((mm->mm_msg->msgh_bits & MACH_MSGH_BITS_COMPLEX) &&
5692+		    ((ret = mach_trade_rights_complex(l, mm)) != 0))
5693+			goto unlock;
5694+
5695+		/*
5696+		 * swap local and remote ports, and
5697+		 * corresponding bits as well.
5698+		 */
5699+		bits = (bits & 0xffff0000) |
5700+		    ((bits & 0xff00) >> 8) |
5701+		    ((bits & 0x00ff) << 8);
5702+		tmp = mm->mm_msg->msgh_remote_port;
5703+		mm->mm_msg->msgh_remote_port =
5704+		    mm->mm_msg->msgh_local_port;
5705+		mm->mm_msg->msgh_local_port = tmp;
5706+	}
5707+
5708+	/*
5709+	 * Copy the message to userland.
5710+	 */
5711+	if ((error = copyout(mm->mm_msg, urm, mm->mm_size)) != 0) {
5712+		ret = MACH_RCV_INVALID_DATA;
5713+		goto unlock;
5714+	}
5715+
5716+	/* Dump the Mach message */
5717+	ktrmmsg((char *)mm->mm_msg, mm->mm_size);
5718+
5719+	free(mm->mm_msg, M_EMULDATA);
5720+	mach_message_put_shlocked(mm); /* decrease mp_count */
5721+unlock:
5722+	rw_exit(&mp->mp_msglock);
5723+
5724+	return ret;
5725+}
5726+
5727+
5728+int
5729+mach_sys_msg_trap(struct lwp *l, const struct mach_sys_msg_trap_args *uap, register_t *retval)
5730+{
5731+	/* {
5732+		syscallarg(mach_msg_header_t *) msg;
5733+		syscallarg(mach_msg_option_t) option;
5734+		syscallarg(mach_msg_size_t) send_size;
5735+		syscallarg(mach_msg_size_t) rcv_size;
5736+		syscallarg(mach_port_name_t) rcv_name;
5737+		syscallarg(mach_msg_timeout_t) timeout;
5738+		syscallarg(mach_port_name_t) notify;
5739+	} */
5740+	struct mach_sys_msg_overwrite_trap_args cup;
5741+
5742+	SCARG(&cup, msg) = SCARG(uap, msg);
5743+	SCARG(&cup, option) = SCARG(uap, option);
5744+	SCARG(&cup, send_size) = SCARG(uap, send_size);
5745+	SCARG(&cup, rcv_size) = SCARG(uap, rcv_size);
5746+	SCARG(&cup, rcv_name) = SCARG(uap, rcv_name);
5747+	SCARG(&cup, timeout) = SCARG(uap, timeout);
5748+	SCARG(&cup, notify) = SCARG(uap, notify);
5749+	SCARG(&cup, rcv_msg) = NULL;
5750+	SCARG(&cup, scatter_list_size) = 0;
5751+
5752+	return mach_sys_msg_overwrite_trap(l, &cup, retval);
5753+}
5754+
5755+static inline  struct lwp *
5756+mach_get_target_task(struct lwp *l, struct mach_port *mp)
5757+{
5758+	struct proc *tp;
5759+	struct lwp *tl;
5760+
5761+	switch (mp->mp_datatype) {
5762+	case MACH_MP_PROC:
5763+		tp = (struct proc *)mp->mp_data;
5764+		tl = LIST_FIRST(&tp->p_lwps);
5765+		KASSERT(tl != NULL);
5766+		break;
5767+
5768+	case MACH_MP_LWP:
5769+		tl = (struct lwp *)mp->mp_data;
5770+		break;
5771+
5772+	default:
5773+		tl = l;
5774+		break;
5775+	}
5776+
5777+	return tl;
5778+}
5779+
5780+static inline void
5781+mach_drop_rights(struct mach_right *mr, int bits)
5782+{
5783+	int rights;
5784+
5785+	switch (bits) {
5786+	case MACH_MSG_TYPE_MOVE_SEND:
5787+		rights = MACH_PORT_TYPE_SEND;
5788+		break;
5789+	case MACH_MSG_TYPE_MOVE_SEND_ONCE:
5790+		rights = MACH_PORT_TYPE_SEND_ONCE;
5791+		break;
5792+	case MACH_MSG_TYPE_MOVE_RECEIVE:
5793+		/* Recv. right is lost when msg is received */
5794+	case MACH_MSG_TYPE_MAKE_SEND:
5795+	case MACH_MSG_TYPE_COPY_SEND:
5796+	case MACH_MSG_TYPE_MAKE_SEND_ONCE:
5797+	default:
5798+		rights = 0;
5799+		break;
5800+	}
5801+
5802+	if (rights != 0)
5803+		mach_right_put(mr, rights);
5804+
5805+	return;
5806+}
5807+
5808+/*
5809+ * When a messages is transmitted from one process to another,
5810+ * we need to make sure the port names are in the receiver process
5811+ * namespace.
5812+ */
5813+static inline void
5814+mach_trade_rights(struct lwp *ll, struct lwp *rl, mach_port_t *mnp, int bits)
5815+	/* ll:		 local lwp (receiver, current lwp) */
5816+	/* rl:		 remote lwp (sender) */
5817+	/* mnp:	 pointer to the port name */
5818+	/* bits:		 right bits */
5819+{
5820+	int lr;			/* local right type (to be added) */
5821+	int rr;			/* remote right type */
5822+	struct mach_right *lmr;	/* right in the local process */
5823+	struct mach_right *rmr;	/* right in the remote process */
5824+
5825+	switch (bits) {
5826+	case MACH_MSG_TYPE_MAKE_SEND:
5827+		rr = MACH_PORT_TYPE_RECEIVE;
5828+		lr = MACH_PORT_TYPE_SEND;
5829+		break;
5830+
5831+	case MACH_MSG_TYPE_COPY_SEND:
5832+	case MACH_MSG_TYPE_MOVE_SEND:
5833+		rr = MACH_PORT_TYPE_SEND;
5834+		lr = MACH_PORT_TYPE_SEND;
5835+		break;
5836+
5837+	case MACH_MSG_TYPE_MAKE_SEND_ONCE:
5838+		rr = MACH_PORT_TYPE_RECEIVE;
5839+		lr = MACH_PORT_TYPE_SEND_ONCE;
5840+		break;
5841+
5842+	case MACH_MSG_TYPE_MOVE_SEND_ONCE:
5843+		rr = MACH_PORT_TYPE_SEND_ONCE;
5844+		lr = MACH_PORT_TYPE_SEND_ONCE;
5845+		break;
5846+
5847+	case MACH_MSG_TYPE_MOVE_RECEIVE:
5848+		rr = MACH_PORT_TYPE_RECEIVE;
5849+		lr = MACH_PORT_TYPE_RECEIVE;
5850+		break;
5851+
5852+	default:
5853+		rr = 0;
5854+		lr = 0;
5855+		break;
5856+	}
5857+
5858+	/* Get the right in the remote process (sender) */
5859+	rmr = NULL;
5860+	if (lr != 0)
5861+		rmr = mach_right_check(*mnp, rl, rr);
5862+
5863+	/* Translate it into a right in the local process (receiver) */
5864+	if (rmr != NULL) {
5865+		lmr = mach_right_get(rmr->mr_port, ll, lr, 0);
5866+		*mnp = lmr->mr_name;
5867+	} else {
5868+		*mnp = 0;
5869+	}
5870+
5871+	return;
5872+}
5873+
5874+/*
5875+ * Turn rights carried by complex messages into rights in
5876+ * the local namespace. Returns a Mach messsage error
5877+ * XXX Nothing is there yet to remove the rights from the
5878+ * sender namespace, it should be done at send time and it
5879+ * is not done yet.
5880+ */
5881+static inline int
5882+mach_trade_rights_complex(struct lwp *l, struct mach_message *mm)
5883+{
5884+	struct mach_complex_msg *mcm;
5885+	unsigned int i, count;
5886+	unsigned long begin, end;
5887+
5888+	/*
5889+	 * Sanity check the descriptor count.
5890+	 * Note that all descriptor types
5891+	 * have the same size, hence it is
5892+	 * safe to not take the descriptor
5893+	 * type into account here.
5894+	 */
5895+	mcm = (struct mach_complex_msg *)mm->mm_msg;
5896+	count = mcm->mcm_body.msgh_descriptor_count;
5897+	begin = (u_long)mcm;
5898+	end = (u_long)&mcm->mcm_desc.gen[count];
5899+
5900+	if ((end - begin) > mm->mm_size) {
5901+#ifdef DEBUG_MACH
5902+		printf("msg id %d: invalid count\n", mm->mm_msg->msgh_id);
5903+#endif
5904+		return MACH_SEND_INVALID_DATA;
5905+	}
5906+
5907+	for (i = 0; i < count; i++) {
5908+		switch (mcm->mcm_desc.gen[i].type) {
5909+		case MACH_MSG_PORT_DESCRIPTOR:
5910+			mach_trade_rights(l, mm->mm_l,
5911+			    &mcm->mcm_desc.port[i].name,
5912+			    mcm->mcm_desc.port[i].disposition);
5913+			break;
5914+
5915+		case MACH_MSG_OOL_PORTS_DESCRIPTOR: {	/* XXX untested */
5916+			struct lwp *rl;		/* remote LWP */
5917+			void *lumnp;		/* local user address */
5918+			void *rumnp;		/* remote user address */
5919+			int disp;		/* disposition*/
5920+			size_t size;		/* data size */
5921+			int mcount;		/* descriptor count */
5922+			mach_port_t *kmnp;
5923+			void *kaddr;
5924+			int error;
5925+			int j;
5926+
5927+			rl = mm->mm_l;
5928+			disp = mcm->mcm_desc.ool_ports[i].disposition;
5929+			rumnp = mcm->mcm_desc.ool_ports[i].address;
5930+			mcount = mcm->mcm_desc.ool_ports[i].count;
5931+			size = mcount * sizeof(*kmnp);
5932+			kaddr = NULL;
5933+			lumnp = NULL;
5934+
5935+			/* This allocates kmnp */
5936+			error = mach_ool_copyin(rl, rumnp, &kaddr, size, 0);
5937+			if (error != 0)
5938+				return MACH_SEND_INVALID_DATA;
5939+
5940+			kmnp = (mach_port_t *)kaddr;
5941+			for (j = 0; j < mcount; j++)
5942+				mach_trade_rights(l, mm->mm_l, &kmnp[j], disp);
5943+
5944+			/* This frees kmnp */
5945+			if ((error = mach_ool_copyout(l, kmnp, &lumnp,
5946+			    size, MACH_OOL_FREE|MACH_OOL_TRACE)) != 0)
5947+				return MACH_SEND_INVALID_DATA;
5948+
5949+			mcm->mcm_desc.ool_ports[i].address = lumnp;
5950+			break;
5951+		}
5952+
5953+		case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
5954+#ifdef DEBUG_MACH
5955+			printf("MACH_MSG_OOL_VOLATILE_DESCRIPTOR\n");
5956+#endif
5957+			/* FALLTHROUGH */
5958+		case MACH_MSG_OOL_DESCRIPTOR: {	/* XXX untested */
5959+			struct lwp *rl;		/* remote LWP */
5960+			void *ludata;		/* local user address */
5961+			void *rudata;		/* remote user address */
5962+			size_t size;		/* data size */
5963+			void *kdata;
5964+			int error;
5965+
5966+			rl = mm->mm_l;
5967+			rudata = mcm->mcm_desc.ool[i].address;
5968+			size = mcm->mcm_desc.ool[i].size;
5969+			kdata = NULL;
5970+			ludata = NULL;
5971+
5972+			/*
5973+			 * XXX This is inefficient for large chunk of OOL
5974+			 * memory. Think about remapping COW when possible.
5975+			 */
5976+
5977+			/* This allocates kdata */
5978+			error = mach_ool_copyin(rl, rudata, &kdata, size, 0);
5979+			if (error != 0)
5980+				return MACH_SEND_INVALID_DATA;
5981+
5982+			/* This frees kdata */
5983+			if ((error = mach_ool_copyout(l, kdata, &ludata,
5984+			    size, MACH_OOL_FREE|MACH_OOL_TRACE)) != 0)
5985+				return MACH_SEND_INVALID_DATA;
5986+
5987+			mcm->mcm_desc.ool_ports[i].address = ludata;
5988+			break;
5989+		}
5990+		default:
5991+#ifdef DEBUG_MACH
5992+			printf("unknown descriptor type %d\n",
5993+			    mcm->mcm_desc.gen[i].type);
5994+#endif
5995+			break;
5996+		}
5997+	}
5998+
5999+	return MACH_MSG_SUCCESS;
6000+}
6001+
6002+inline int
6003+mach_ool_copyin(struct lwp *l, const void *uaddr, void **kaddr, size_t size, int flags)
6004+{
6005+	int error;
6006+	void *kbuf;
6007+	struct proc *p = l->l_proc;
6008+
6009+	/*
6010+	 * Sanity check OOL size to avoid DoS on malloc: useless once
6011+	 * we remap data instead of copying it. In the meantime,
6012+	 * disabled since it makes some OOL transfer fail.
6013+	 */
6014+#if 0
6015+	if (size > MACH_MAX_OOL_LEN)
6016+		return ENOMEM;
6017+#endif
6018+
6019+	if (*kaddr == NULL)
6020+		kbuf = malloc(size, M_EMULDATA, M_WAITOK);
6021+	else
6022+		kbuf = *kaddr;
6023+
6024+	if ((error = copyin_proc(p, uaddr, kbuf, size)) != 0) {
6025+		if (*kaddr == NULL)
6026+			free(kbuf, M_EMULDATA);
6027+		return error;
6028+	}
6029+
6030+	if (size > PAGE_SIZE)
6031+		size = PAGE_SIZE;
6032+	if ((flags & MACH_OOL_TRACE))
6033+		ktrmool(kaddr, size, uaddr);
6034+
6035+	*kaddr = kbuf;
6036+	return 0;
6037+}
6038+
6039+inline int
6040+mach_ool_copyout(struct lwp *l, const void *kaddr, void **uaddr, size_t size, int flags)
6041+{
6042+	vaddr_t ubuf;
6043+	int error = 0;
6044+	struct proc *p = l->l_proc;
6045+
6046+	/*
6047+	 * Sanity check OOL size to avoid DoS on malloc: useless once
6048+	 * we remap data instead of copying it. In the meantime,
6049+	 * disabled since it makes some OOL transfer fail.
6050+	 */
6051+#if 0
6052+	if (size > MACH_MAX_OOL_LEN) {
6053+		error = ENOMEM;
6054+		goto out;
6055+	}
6056+#endif
6057+
6058+	if (*uaddr == NULL)
6059+		ubuf = (vaddr_t)vm_map_min(&p->p_vmspace->vm_map);
6060+	else
6061+		ubuf = (vaddr_t)*uaddr;
6062+
6063+	/* Never map anything at address zero: this is a red zone */
6064+	if (ubuf == (vaddr_t)NULL)
6065+		ubuf += PAGE_SIZE;
6066+
6067+	if ((error = uvm_map(&p->p_vmspace->vm_map, &ubuf,
6068+	    round_page(size), NULL, UVM_UNKNOWN_OFFSET, 0,
6069+	    UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL,
6070+	    UVM_INH_COPY, UVM_ADV_NORMAL, UVM_FLAG_COPYONW))) != 0)
6071+		goto out;
6072+
6073+	if ((error = copyout_proc(p, kaddr, (void *)ubuf, size)) != 0)
6074+		goto out;
6075+
6076+	if (size > PAGE_SIZE)
6077+		size = PAGE_SIZE;
6078+	if ((flags & MACH_OOL_TRACE))
6079+		ktrmool(kaddr, size, (void *)ubuf);
6080+
6081+out:
6082+	if (flags & MACH_OOL_FREE)
6083+		free(__UNCONST(kaddr), M_EMULDATA); /*XXXUNCONST*/
6084+
6085+	if (error == 0)
6086+		*uaddr = (void *)ubuf;
6087+	return error;
6088+}
6089+
6090+
6091+inline void
6092+mach_set_trailer(void *msgh, size_t size)
6093+{
6094+	mach_msg_trailer_t *trailer;
6095+	char *msg = (char *)msgh;
6096+
6097+	trailer = (mach_msg_trailer_t *)&msg[size - sizeof(*trailer)];
6098+	trailer->msgh_trailer_type = MACH_MSG_TRAILER_FORMAT_0;
6099+	trailer->msgh_trailer_size = sizeof(*trailer);
6100+
6101+	return;
6102+}
6103+
6104+inline void
6105+mach_set_header(void *rep, void *req, size_t size)
6106+{
6107+	mach_msg_header_t *rephdr = rep;
6108+	mach_msg_header_t *reqhdr = req;
6109+
6110+	rephdr->msgh_bits =
6111+		MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
6112+	rephdr->msgh_size = size - sizeof(mach_msg_trailer_t);
6113+	rephdr->msgh_local_port = reqhdr->msgh_local_port;
6114+	rephdr->msgh_remote_port = 0;
6115+	rephdr->msgh_id = reqhdr->msgh_id + 100;
6116+
6117+	return;
6118+}
6119+
6120+inline void
6121+mach_add_port_desc(void *msg, mach_port_name_t name)
6122+{
6123+	struct mach_complex_msg *mcm = msg;
6124+	int i;
6125+
6126+	if ((mcm->mcm_header.msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0) {
6127+		mcm->mcm_header.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
6128+		mcm->mcm_body.msgh_descriptor_count = 0;
6129+	}
6130+
6131+	i = mcm->mcm_body.msgh_descriptor_count;
6132+
6133+	mcm->mcm_desc.port[i].name = name;
6134+	mcm->mcm_desc.port[i].disposition = MACH_MSG_TYPE_MOVE_SEND;
6135+	mcm->mcm_desc.port[i].type = MACH_MSG_PORT_DESCRIPTOR;
6136+
6137+	mcm->mcm_body.msgh_descriptor_count++;
6138+	return;
6139+}
6140+
6141+inline void
6142+mach_add_ool_ports_desc(void *msg, void *addr, int count)
6143+{
6144+	struct mach_complex_msg *mcm = msg;
6145+	int i;
6146+
6147+	if ((mcm->mcm_header.msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0) {
6148+		mcm->mcm_header.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
6149+		mcm->mcm_body.msgh_descriptor_count = 0;
6150+	}
6151+
6152+	i = mcm->mcm_body.msgh_descriptor_count;
6153+
6154+	mcm->mcm_desc.ool_ports[i].address = addr;
6155+	mcm->mcm_desc.ool_ports[i].count = count;
6156+	mcm->mcm_desc.ool_ports[i].copy = MACH_MSG_ALLOCATE;
6157+	mcm->mcm_desc.ool_ports[i].disposition = MACH_MSG_TYPE_MOVE_SEND;
6158+	mcm->mcm_desc.ool_ports[i].type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
6159+
6160+	mcm->mcm_body.msgh_descriptor_count++;
6161+	return;
6162+}
6163+
6164+inline void mach_add_ool_desc(msg, addr, size)
6165+	void *msg;
6166+	void *addr;
6167+	size_t size;
6168+{
6169+	struct mach_complex_msg *mcm = msg;
6170+	int i;
6171+
6172+	if ((mcm->mcm_header.msgh_bits & MACH_MSGH_BITS_COMPLEX) == 0) {
6173+		mcm->mcm_header.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
6174+		mcm->mcm_body.msgh_descriptor_count = 0;
6175+	}
6176+
6177+	i = mcm->mcm_body.msgh_descriptor_count;
6178+
6179+	mcm->mcm_desc.ool[i].address = addr;
6180+	mcm->mcm_desc.ool[i].size = size;
6181+	mcm->mcm_desc.ool[i].deallocate = 0;
6182+	mcm->mcm_desc.ool[i].copy = MACH_MSG_ALLOCATE;
6183+	mcm->mcm_desc.ool[i].type = MACH_MSG_OOL_DESCRIPTOR;
6184+
6185+	mcm->mcm_body.msgh_descriptor_count++;
6186+	return;
6187+}
6188+
6189+void
6190+mach_message_init(void)
6191+{
6192+	pool_init(&mach_message_pool, sizeof (struct mach_message),
6193+	    0, 0, 0, "mach_message_pool", NULL, IPL_NONE);
6194+	return;
6195+}
6196+
6197+struct mach_message *
6198+mach_message_get(mach_msg_header_t *msgh, size_t size, struct mach_port *mp, struct lwp *l)
6199+{
6200+	struct mach_message *mm;
6201+
6202+	mm = (struct mach_message *)pool_get(&mach_message_pool, PR_WAITOK);
6203+	memset(mm, 0, sizeof(*mm));
6204+	mm->mm_msg = msgh;
6205+	mm->mm_size = size;
6206+	mm->mm_port = mp;
6207+	mm->mm_l = l;
6208+
6209+	rw_enter(&mp->mp_msglock, RW_WRITER);
6210+	TAILQ_INSERT_TAIL(&mp->mp_msglist, mm, mm_list);
6211+	mp->mp_count++;
6212+	rw_exit(&mp->mp_msglock);
6213+
6214+	return mm;
6215+}
6216+
6217+void
6218+mach_message_put(struct mach_message *mm)
6219+{
6220+	struct mach_port *mp;
6221+
6222+	mp = mm->mm_port;
6223+
6224+	rw_enter(&mp->mp_msglock, RW_WRITER);
6225+	mach_message_put_exclocked(mm);
6226+	rw_exit(&mp->mp_msglock);
6227+
6228+	return;
6229+}
6230+
6231+void
6232+mach_message_put_shlocked(struct mach_message *mm)
6233+{
6234+	struct mach_port *mp;
6235+
6236+	mp = mm->mm_port;
6237+
6238+	if (!rw_tryupgrade(&mp->mp_msglock)) {
6239+		/* XXX  */
6240+		rw_exit(&mp->mp_msglock);
6241+		rw_enter(&mp->mp_msglock, RW_WRITER);
6242+	}
6243+	mach_message_put_exclocked(mm);
6244+	rw_downgrade(&mp->mp_msglock);
6245+
6246+	return;
6247+}
6248+
6249+void
6250+mach_message_put_exclocked(struct mach_message *mm)
6251+{
6252+	struct mach_port *mp;
6253+
6254+	mp = mm->mm_port;
6255+
6256+	TAILQ_REMOVE(&mp->mp_msglist, mm, mm_list);
6257+	mp->mp_count--;
6258+
6259+	pool_put(&mach_message_pool, mm);
6260+
6261+	return;
6262+}
6263+
6264+#ifdef DEBUG_MACH
6265+void
6266+mach_debug_message(void)
6267+{
6268+	struct lwp *l;
6269+	struct mach_emuldata *med;
6270+	struct mach_right *mr;
6271+	struct mach_right *mrs;
6272+	struct mach_port *mp;
6273+	struct mach_message *mm;
6274+
6275+	LIST_FOREACH(l, &alllwp, l_list) {
6276+		if ((l->l_proc->p_emul != &emul_mach) &&
6277+#ifdef COMPAT_DARWIN
6278+		    (l->l_proc->p_emul != &emul_darwin) &&
6279+#endif
6280+		    1)
6281+			continue;
6282+
6283+		med = l->l_proc->p_emuldata;
6284+		LIST_FOREACH(mr, &med->med_right, mr_list)
6285+			if ((mr->mr_type & MACH_PORT_TYPE_PORT_SET) == 0) {
6286+				mp = mr->mr_port;
6287+				if (mp == NULL)
6288+					continue;
6289+
6290+				printf("port %p(%d) ", mp, mp->mp_count);
6291+
6292+				TAILQ_FOREACH(mm, &mp->mp_msglist, mm_list)
6293+					printf("%d ", mm->mm_msg->msgh_id);
6294+
6295+				printf("\n");
6296+				continue;
6297+			}
6298+			/* Port set... */
6299+			LIST_FOREACH(mrs, &mr->mr_set, mr_setlist) {
6300+				mp = mrs->mr_port;
6301+				if (mp == NULL)
6302+					continue;
6303+
6304+				printf("port %p(%d) ", mp, mp->mp_count);
6305+
6306+				TAILQ_FOREACH(mm, &mp->mp_msglist, mm_list)
6307+					printf("%d ", mm->mm_msg->msgh_id);
6308+
6309+				printf("\n");
6310+			}
6311+	}
6312+	return;
6313+}
6314+
6315+#endif /* DEBUG_MACH */
6316diff --git a/sys/compat/mach/mach_message.h b/sys/compat/mach/mach_message.h
6317new file mode 100644
6318index 0000000..570a336
6319--- /dev/null
6320+++ b/sys/compat/mach/mach_message.h
6321@@ -0,0 +1,276 @@
6322+/*	$NetBSD: mach_message.h,v 1.30 2008/04/28 20:23:44 martin Exp $	 */
6323+
6324+/*-
6325+ * Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
6326+ * All rights reserved.
6327+ *
6328+ * This code is derived from software contributed to The NetBSD Foundation
6329+ * by Christos Zoulas and Emmanuel Dreyfus.
6330+ *
6331+ * Redistribution and use in source and binary forms, with or without
6332+ * modification, are permitted provided that the following conditions
6333+ * are met:
6334+ * 1. Redistributions of source code must retain the above copyright
6335+ *    notice, this list of conditions and the following disclaimer.
6336+ * 2. Redistributions in binary form must reproduce the above copyright
6337+ *    notice, this list of conditions and the following disclaimer in the
6338+ *    documentation and/or other materials provided with the distribution.
6339+ *
6340+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
6341+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
6342+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
6343+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
6344+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
6345+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
6346+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6347+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
6348+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
6349+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6350+ * POSSIBILITY OF SUCH DAMAGE.
6351+ */
6352+
6353+#ifndef	_MACH_MESSAGE_H_
6354+#define	_MACH_MESSAGE_H_
6355+
6356+typedef unsigned int mach_msg_bits_t;
6357+typedef unsigned int mach_msg_size_t;
6358+typedef unsigned int mach_msg_id_t;
6359+typedef unsigned int mach_msg_timeout_t;
6360+typedef unsigned int mach_msg_option_t;
6361+typedef unsigned int mach_msg_type_name_t;
6362+typedef unsigned int mach_msg_type_number_t;
6363+
6364+/*
6365+ * Options
6366+ */
6367+#define MACH_MSG_OPTION_NONE	0x00000000
6368+#define	MACH_SEND_MSG		0x00000001
6369+#define	MACH_RCV_MSG		0x00000002
6370+#define MACH_RCV_LARGE		0x00000004
6371+#define MACH_SEND_TIMEOUT	0x00000010
6372+#define MACH_SEND_INTERRUPT	0x00000040
6373+#define MACH_SEND_CANCEL	0x00000080
6374+#define MACH_RCV_TIMEOUT	0x00000100
6375+#define MACH_RCV_NOTIFY		0x00000200
6376+#define MACH_RCV_INTERRUPT	0x00000400
6377+#define MACH_RCV_OVERWRITE	0x00001000
6378+#define MACH_SEND_ALWAYS	0x00010000
6379+#define MACH_SEND_TRAILER	0x00020000
6380+
6381+/* mach_msg error codes */
6382+#define MACH_MSG_SUCCESS		0x00000000
6383+#define MACH_MSG_MASK			0x00003e00
6384+#define MACH_MSG_IPC_SPACE		0x00002000
6385+#define MACH_MSG_VM_SPACE		0x00001000
6386+#define MACH_MSG_IPC_KERNEL		0x00000800
6387+#define MACH_MSG_VM_KERNEL		0x00000400
6388+#define MACH_SEND_MSG			0x00000001
6389+#define MACH_SEND_TIMEOUT		0x00000010
6390+#define MACH_SEND_INTERRUPT		0x00000040
6391+#define MACH_SEND_CANCEL		0x00000080
6392+#define MACH_SEND_ALWAYS		0x00010000
6393+#define MACH_SEND_TRAILER		0x00020000
6394+#define MACH_SEND_IN_PROGRESS		0x10000001
6395+#define MACH_SEND_INVALID_DATA		0x10000002
6396+#define MACH_SEND_INVALID_DEST		0x10000003
6397+#define MACH_SEND_TIMED_OUT		0x10000004
6398+#define MACH_SEND_INTERRUPTED		0x10000007
6399+#define MACH_SEND_MSG_TOO_SMALL	 	0x10000008
6400+#define MACH_SEND_INVALID_REPLY	 	0x10000009
6401+#define MACH_SEND_INVALID_RIGHT	 	0x1000000a
6402+#define MACH_SEND_INVALID_NOTIFY	0x1000000b
6403+#define MACH_SEND_INVALID_MEMORY	0x1000000c
6404+#define MACH_SEND_NO_BUFFER		0x1000000d
6405+#define MACH_SEND_TOO_LARGE		0x1000000e
6406+#define MACH_SEND_INVALID_TYPE		0x1000000f
6407+#define MACH_SEND_INVALID_HEADER	0x10000010
6408+#define MACH_SEND_INVALID_TRAILER	0x10000011
6409+#define MACH_SEND_INVALID_RT_OOL_SIZE	0x10000015
6410+#define MACH_RCV_IN_PROGRESS		0x10004001
6411+#define MACH_RCV_INVALID_NAME		0x10004002
6412+#define MACH_RCV_TIMED_OUT		0x10004003
6413+#define MACH_RCV_TOO_LARGE		0x10004004
6414+#define MACH_RCV_INTERRUPTED		0x10004005
6415+#define MACH_RCV_PORT_CHANGED		0x10004006
6416+#define MACH_RCV_INVALID_NOTIFY	 	0x10004007
6417+#define MACH_RCV_INVALID_DATA		0x10004008
6418+#define MACH_RCV_PORT_DIED		0x10004009
6419+#define MACH_RCV_IN_SET		 	0x1000400a
6420+#define MACH_RCV_HEADER_ERROR		0x1000400b
6421+#define MACH_RCV_BODY_ERROR		0x1000400c
6422+#define MACH_RCV_INVALID_TYPE		0x1000400d
6423+#define MACH_RCV_SCATTER_SMALL		0x1000400e
6424+#define MACH_RCV_INVALID_TRAILER	0x1000400f
6425+#define MACH_RCV_IN_PROGRESS_TIMED	0x10004011
6426+
6427+#define MACH_MSG_OPTION_BITS	"\177\20" \
6428+    "b\00send_msg\0b\01rcv_msg\0" \
6429+    "b\02rcv_large\0b\03invalid[0x8]\0" \
6430+    "b\04send_timeout\0b05invalid[0x20]\0" \
6431+    "b\06send_interrupt\0b\05send_cancel\0" \
6432+    "b\06rcv_timeout\0b\07rcv_notify\0" \
6433+    "b\10rcv_interrupt\0b\11invalid[0x800]\0" \
6434+    "b\12rcv_overwrite\0b\13invalid[0x2000]\0" \
6435+    "b\14invalid[0x4000]\0b\15invalid[0x8000]\0" \
6436+    "b\16send_always\0b\17send_trailer\0"
6437+
6438+#define MACH_MSGH_BITS_REMOTE_MASK	0x000000ff
6439+#define MACH_MSGH_BITS_LOCAL_MASK	0x0000ff00
6440+#define MACH_MSGH_BITS_COMPLEX		0x80000000
6441+#define MACH_MSGH_LOCAL_BITS(bits)	(((bits) >> 8) & 0xff)
6442+#define MACH_MSGH_REMOTE_BITS(bits)	((bits) & 0xff)
6443+#define MACH_MSGH_REPLY_LOCAL_BITS(bits)	(((bits) << 8) & 0xff00)
6444+
6445+#define MACH_MSG_TYPE_MOVE_RECEIVE	16
6446+#define MACH_MSG_TYPE_MOVE_SEND		17
6447+#define MACH_MSG_TYPE_MOVE_SEND_ONCE	18
6448+#define MACH_MSG_TYPE_COPY_SEND		19
6449+#define MACH_MSG_TYPE_MAKE_SEND		20
6450+#define MACH_MSG_TYPE_MAKE_SEND_ONCE	21
6451+#define MACH_MSG_TYPE_COPY_RECEIVE	22
6452+
6453+typedef unsigned int mach_msg_copy_options_t;
6454+
6455+#define MACH_MSG_PHYSICAL_COPY		0
6456+#define MACH_MSG_VIRTUAL_COPY   	1
6457+#define MACH_MSG_ALLOCATE		2
6458+#define MACH_MSG_OVERWRITE		3
6459+#define MACH_MSG_KALLOC_COPY_T		4
6460+#define MACH_MSG_PAGE_LIST_COPY_T	5
6461+
6462+typedef unsigned int mach_msg_descriptor_type_t;
6463+
6464+#define MACH_MSG_PORT_DESCRIPTOR 		0
6465+#define MACH_MSG_OOL_DESCRIPTOR  		1
6466+#define MACH_MSG_OOL_PORTS_DESCRIPTOR 		2
6467+#define MACH_MSG_OOL_VOLATILE_DESCRIPTOR  	3
6468+
6469+#define MACH_MAX_MSG_LEN 65536
6470+
6471+typedef	struct {
6472+	mach_msg_bits_t	msgh_bits;
6473+	mach_msg_size_t	msgh_size;
6474+	mach_port_t	msgh_remote_port;
6475+	mach_port_t	msgh_local_port;
6476+	mach_msg_size_t msgh_reserved;
6477+	mach_msg_id_t	msgh_id;
6478+} mach_msg_header_t;
6479+
6480+#define MACH_MSG_TRAILER_FORMAT_0	0
6481+typedef u_int32_t mach_msg_trailer_type_t;
6482+typedef u_int32_t mach_msg_trailer_size_t;
6483+typedef struct {
6484+	mach_msg_trailer_type_t       msgh_trailer_type;
6485+	mach_msg_trailer_size_t       msgh_trailer_size;
6486+} mach_msg_trailer_t;
6487+
6488+typedef struct {
6489+	void*			pad1;
6490+	mach_msg_size_t		pad2;
6491+	unsigned int		pad3 : 24;
6492+	mach_msg_descriptor_type_t type : 8;
6493+} mach_msg_type_descriptor_t;
6494+
6495+typedef struct {
6496+	mach_port_t		name;
6497+	mach_msg_size_t		pad1;
6498+	unsigned int		pad2 : 16;
6499+	mach_msg_type_name_t	disposition : 8;
6500+	mach_msg_descriptor_type_t type : 8;
6501+} mach_msg_port_descriptor_t;
6502+
6503+typedef struct {
6504+	void *			address;
6505+	mach_msg_size_t		count;
6506+	mach_boolean_t		deallocate: 8;
6507+	mach_msg_copy_options_t	copy: 8;
6508+	mach_msg_type_name_t	disposition : 8;
6509+	mach_msg_descriptor_type_t type : 8;
6510+} mach_msg_ool_ports_descriptor_t;
6511+
6512+typedef struct {
6513+       void *			  address;
6514+       mach_msg_size_t		  size;
6515+       mach_boolean_t		  deallocate : 8;
6516+       mach_msg_copy_options_t	  copy : 8;
6517+       unsigned int		  pad1 : 8;
6518+       mach_msg_descriptor_type_t type : 8;
6519+} mach_msg_ool_descriptor_t;
6520+
6521+typedef struct {
6522+	mach_msg_size_t	msgh_descriptor_count;
6523+} mach_msg_body_t;
6524+
6525+#define MACH_REQMSG_OVERFLOW(args, test) \
6526+    (((u_long)&test - (u_long)args->smsg) > args->ssize)
6527+
6528+struct mach_short_reply {
6529+	mach_msg_header_t sr_header;
6530+	mach_msg_trailer_t sr_trailer;
6531+};
6532+
6533+struct mach_complex_msg {
6534+	mach_msg_header_t mcm_header;
6535+	mach_msg_body_t mcm_body;
6536+	union {
6537+		mach_msg_type_descriptor_t gen[1];
6538+		mach_msg_port_descriptor_t port[1];
6539+		mach_msg_ool_ports_descriptor_t ool_ports[1];
6540+		mach_msg_ool_descriptor_t ool[1];
6541+	} mcm_desc;
6542+};
6543+
6544+/* Kernel-private structures */
6545+
6546+struct mach_trap_args {
6547+	struct lwp *l;	/* Current task (doing the Mach system call) */
6548+	struct lwp *tl; /* Target task */
6549+	void *smsg;	/* Sent message */
6550+	void *rmsg;	/* Reply message */
6551+	size_t ssize;	/* Sent message size */
6552+	size_t *rsize;	/* Reply message maximum size, may be lowered */
6553+};
6554+
6555+struct mach_service {
6556+	int	srv_id;
6557+	int	(*srv_handler)(struct mach_trap_args *);
6558+	const char	*srv_name;
6559+	size_t	srv_reqlen; /* Minimum length of the request message */
6560+	size_t	srv_replen; /* Maximum length of the reply message */
6561+};
6562+extern struct mach_service mach_services_table[];
6563+
6564+
6565+/* In-kernel Mach messages description */
6566+struct mach_message {
6567+	mach_msg_header_t *mm_msg;	/* In-kernel copy of the message */
6568+	size_t mm_size;			/* Message size */
6569+	TAILQ_ENTRY(mach_message) mm_list;
6570+					/* List of pending messages */
6571+	struct mach_port *mm_port;	/* The port on which msg is queued */
6572+	struct lwp *mm_l;		/* The thread that sent it */
6573+};
6574+
6575+/* Flags for mach_ool_copy{in|out} */
6576+#define MACH_OOL_NONE	0x0
6577+#define MACH_OOL_FREE	0x1	/* Free kernel buffer after copyout */
6578+#define MACH_OOL_TRACE	0x2	/* ktrace OOL data */
6579+
6580+__inline int mach_ool_copyin(struct lwp *, const void *, void **, size_t, int);
6581+__inline int mach_ool_copyout(struct lwp *, const void *, void **, size_t, int);
6582+__inline void mach_set_trailer(void *, size_t);
6583+__inline void mach_set_header(void *, void *, size_t);
6584+__inline void mach_add_port_desc(void *, mach_port_name_t);
6585+__inline void mach_add_ool_ports_desc(void *, void *, int);
6586+__inline void mach_add_ool_desc(void *, void *, size_t);
6587+void mach_message_init(void);
6588+struct mach_message *mach_message_get(mach_msg_header_t *,
6589+    size_t, struct mach_port *, struct lwp *);
6590+void mach_message_put(struct mach_message *);
6591+void mach_message_put_shlocked(struct mach_message *);
6592+void mach_message_put_exclocked(struct mach_message *);
6593+#ifdef DEBUG_MACH
6594+void mach_debug_message(void);
6595+#endif
6596+
6597+#endif /* !_MACH_MESSAGE_H_ */
6598diff --git a/sys/compat/mach/mach_misc.c b/sys/compat/mach/mach_misc.c
6599new file mode 100644
6600index 0000000..84f9c83
6601--- /dev/null
6602+++ b/sys/compat/mach/mach_misc.c
6603@@ -0,0 +1,217 @@
6604+/*	$NetBSD: mach_misc.c,v 1.28 2008/04/28 20:23:44 martin Exp $	 */
6605+
6606+/*-
6607+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
6608+ * All rights reserved.
6609+ *
6610+ * This code is derived from software contributed to The NetBSD Foundation
6611+ * by Christos Zoulas.
6612+ *
6613+ * Redistribution and use in source and binary forms, with or without
6614+ * modification, are permitted provided that the following conditions
6615+ * are met:
6616+ * 1. Redistributions of source code must retain the above copyright
6617+ *    notice, this list of conditions and the following disclaimer.
6618+ * 2. Redistributions in binary form must reproduce the above copyright
6619+ *    notice, this list of conditions and the following disclaimer in the
6620+ *    documentation and/or other materials provided with the distribution.
6621+ *
6622+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
6623+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
6624+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
6625+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
6626+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
6627+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
6628+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6629+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
6630+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
6631+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6632+ * POSSIBILITY OF SUCH DAMAGE.
6633+ */
6634+
6635+/*
6636+ * MACH compatibility module.
6637+ *
6638+ * We actually don't implement anything here yet!
6639+ */
6640+
6641+#include <sys/cdefs.h>
6642+__KERNEL_RCSID(0, "$NetBSD: mach_misc.c,v 1.28 2008/04/28 20:23:44 martin Exp $");
6643+
6644+#include <sys/param.h>
6645+#include <sys/systm.h>
6646+#include <sys/namei.h>
6647+#include <sys/dirent.h>
6648+#include <sys/proc.h>
6649+#include <sys/file.h>
6650+#include <sys/stat.h>
6651+#include <sys/time.h>
6652+#include <sys/filedesc.h>
6653+#include <sys/ioctl.h>
6654+#include <sys/kernel.h>
6655+#include <sys/malloc.h>
6656+#include <sys/pool.h>
6657+#include <sys/mbuf.h>
6658+#include <sys/mman.h>
6659+#include <sys/mount.h>
6660+#include <sys/resource.h>
6661+#include <sys/resourcevar.h>
6662+#include <sys/socket.h>
6663+#include <sys/vnode.h>
6664+#include <sys/uio.h>
6665+#include <sys/wait.h>
6666+#include <sys/utsname.h>
6667+#include <sys/unistd.h>
6668+#include <sys/times.h>
6669+#include <sys/sem.h>
6670+#include <sys/msg.h>
6671+#include <sys/ptrace.h>
6672+#include <sys/signalvar.h>
6673+
6674+#include <netinet/in.h>
6675+#include <sys/syscallargs.h>
6676+
6677+#include <miscfs/specfs/specdev.h>
6678+
6679+#include <compat/mach/mach_types.h>
6680+#include <compat/mach/mach_message.h>
6681+#include <compat/mach/mach_clock.h>
6682+#include <compat/mach/mach_syscallargs.h>
6683+
6684+
6685+int
6686+mach_sys_semaphore_timedwait_trap(struct lwp *l, const struct mach_sys_semaphore_timedwait_trap_args *uap, register_t *retval)
6687+{
6688+
6689+	*retval = 0;
6690+	DPRINTF(("mach_sys_semaphore_timedwait_trap(0x%x, %d, %d);\n",
6691+	    SCARG(uap, wait_name), SCARG(uap, sec), SCARG(uap, nsec)));
6692+	return 0;
6693+}
6694+
6695+
6696+int
6697+mach_sys_semaphore_timedwait_signal_trap(struct lwp *l, const struct mach_sys_semaphore_timedwait_signal_trap_args *uap, register_t *retval)
6698+{
6699+
6700+	*retval = 0;
6701+	DPRINTF((
6702+	    "mach_sys_semaphore_timedwait_signal_trap(0x%x, 0x%x, %d, %d);\n",
6703+	    SCARG(uap, wait_name), SCARG(uap, signal_name), SCARG(uap, sec),
6704+	    SCARG(uap, nsec)));
6705+	return 0;
6706+}
6707+
6708+
6709+int
6710+mach_sys_init_process(struct lwp *l, const void *v, register_t *retval)
6711+{
6712+	*retval = 0;
6713+	DPRINTF(("mach_sys_init_process();\n"));
6714+	return 0;
6715+}
6716+
6717+
6718+int
6719+mach_sys_pid_for_task(struct lwp *l, const struct mach_sys_pid_for_task_args *uap, register_t *retval)
6720+{
6721+
6722+	*retval = 0;
6723+	DPRINTF(("mach_sys_pid_for_task(0x%x, %p);\n",
6724+	    SCARG(uap, t), SCARG(uap, x)));
6725+	return 0;
6726+}
6727+
6728+
6729+int
6730+mach_sys_macx_swapon(struct lwp *l, const struct mach_sys_macx_swapon_args *uap, register_t *retval)
6731+{
6732+
6733+	*retval = 0;
6734+	DPRINTF(("mach_sys_macx_swapon(%p, %d, %d, %d);\n",
6735+	    SCARG(uap, name), SCARG(uap, flags), SCARG(uap, size),
6736+	    SCARG(uap, priority)));
6737+	return 0;
6738+}
6739+
6740+int
6741+mach_sys_macx_swapoff(struct lwp *l, const struct mach_sys_macx_swapoff_args *uap, register_t *retval)
6742+{
6743+
6744+	*retval = 0;
6745+	DPRINTF(("mach_sys_macx_swapoff(%p, %d);\n",
6746+	    SCARG(uap, name), SCARG(uap, flags)));
6747+	return 0;
6748+}
6749+
6750+int
6751+mach_sys_macx_triggers(struct lwp *l, const struct mach_sys_macx_triggers_args *uap, register_t *retval)
6752+{
6753+
6754+	*retval = 0;
6755+	DPRINTF(("mach_sys_macx_triggers(%d, %d, %d, 0x%x);\n",
6756+	    SCARG(uap, hi_water), SCARG(uap, low_water), SCARG(uap, flags),
6757+	    SCARG(uap, alert_port)));
6758+	return 0;
6759+}
6760+
6761+
6762+int
6763+mach_sys_wait_until(struct lwp *l, const struct mach_sys_wait_until_args *uap, register_t *retval)
6764+{
6765+
6766+	*retval = 0;
6767+	DPRINTF(("mach_sys_wait_until(%lld);\n",
6768+	    SCARG(uap, deadline)));
6769+	return 0;
6770+}
6771+
6772+
6773+int
6774+mach_sys_timer_create(struct lwp *l, const void *v, register_t *retval)
6775+{
6776+	*retval = 0;
6777+	DPRINTF(("mach_sys_timer_create();\n"));
6778+	return 0;
6779+}
6780+
6781+
6782+int
6783+mach_sys_timer_destroy(struct lwp *l, const struct mach_sys_timer_destroy_args *uap, register_t *retval)
6784+{
6785+
6786+	*retval = 0;
6787+	DPRINTF(("mach_sys_timer_destroy(0x%x);\n", SCARG(uap, name)));
6788+	return 0;
6789+}
6790+
6791+
6792+int
6793+mach_sys_timer_arm(struct lwp *l, const struct mach_sys_timer_arm_args *uap, register_t *retval)
6794+{
6795+
6796+	*retval = 0;
6797+	DPRINTF(("mach_sys_timer_arm(0x%x, %d);\n",
6798+	    SCARG(uap, name), SCARG(uap, expire_time)));
6799+	return 0;
6800+}
6801+
6802+
6803+int
6804+mach_sys_timer_cancel(struct lwp *l, const struct mach_sys_timer_cancel_args *uap, register_t *retval)
6805+{
6806+
6807+	*retval = 0;
6808+	DPRINTF(("mach_sys_timer_cancel(0x%x, %p);\n",
6809+	    SCARG(uap, name), SCARG(uap, result_time)));
6810+	return 0;
6811+}
6812+
6813+
6814+int
6815+mach_sys_get_time_base_info(struct lwp *l, const void *v, register_t *retval)
6816+{
6817+	*retval = 0;
6818+	DPRINTF(("mach_sys_get_time_base_info();\n"));
6819+	return 0;
6820+}
6821diff --git a/sys/compat/mach/mach_notify.c b/sys/compat/mach/mach_notify.c
6822new file mode 100644
6823index 0000000..3f5f8fb
6824--- /dev/null
6825+++ b/sys/compat/mach/mach_notify.c
6826@@ -0,0 +1,182 @@
6827+/*	$NetBSD: mach_notify.c,v 1.20 2008/04/28 20:23:44 martin Exp $ */
6828+
6829+/*-
6830+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
6831+ * All rights reserved.
6832+ *
6833+ * This code is derived from software contributed to The NetBSD Foundation
6834+ * by Emmanuel Dreyfus
6835+ *
6836+ * Redistribution and use in source and binary forms, with or without
6837+ * modification, are permitted provided that the following conditions
6838+ * are met:
6839+ * 1. Redistributions of source code must retain the above copyright
6840+ *    notice, this list of conditions and the following disclaimer.
6841+ * 2. Redistributions in binary form must reproduce the above copyright
6842+ *    notice, this list of conditions and the following disclaimer in the
6843+ *    documentation and/or other materials provided with the distribution.
6844+ *
6845+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
6846+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
6847+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
6848+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
6849+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
6850+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
6851+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
6852+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
6853+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
6854+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6855+ * POSSIBILITY OF SUCH DAMAGE.
6856+ */
6857+
6858+#include <sys/cdefs.h>
6859+__KERNEL_RCSID(0, "$NetBSD: mach_notify.c,v 1.20 2008/04/28 20:23:44 martin Exp $");
6860+
6861+#include <sys/types.h>
6862+#include <sys/param.h>
6863+#include <sys/signal.h>
6864+#include <sys/proc.h>
6865+#include <sys/malloc.h>
6866+
6867+#include <compat/mach/mach_types.h>
6868+#include <compat/mach/mach_exec.h>
6869+#include <compat/mach/mach_thread.h>
6870+#include <compat/mach/mach_notify.h>
6871+#include <compat/mach/mach_message.h>
6872+#include <compat/mach/mach_services.h>
6873+
6874+void
6875+mach_notify_port_destroyed(struct lwp *l, struct mach_right *mr)
6876+{
6877+	struct mach_port *mp;
6878+	mach_notify_port_destroyed_request_t *req;
6879+
6880+	if (mr->mr_notify_destroyed == NULL)
6881+		return;
6882+
6883+	mp = mr->mr_notify_destroyed->mr_port;
6884+
6885+#ifdef DIAGNOSTIC
6886+	if ((mp == NULL) || (mp->mp_recv == NULL)) {
6887+		printf("mach_notify_port_destroyed: bad port or receiver\n");
6888+		return;
6889+	}
6890+#endif
6891+
6892+	MACH_PORT_REF(mp);
6893+
6894+	req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO);
6895+
6896+	req->req_msgh.msgh_bits =
6897+	    MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
6898+	req->req_msgh.msgh_size = sizeof(*req) - sizeof(req->req_trailer);
6899+	req->req_msgh.msgh_local_port = mr->mr_notify_destroyed->mr_name;
6900+	req->req_msgh.msgh_id = MACH_NOTIFY_DESTROYED_MSGID;
6901+	req->req_body.msgh_descriptor_count = 1;
6902+	req->req_rights.name = mr->mr_name;
6903+
6904+	mach_set_trailer(req, sizeof(*req));
6905+
6906+	(void)mach_message_get((mach_msg_header_t *)req, sizeof(*req), mp, l);
6907+#ifdef DEBUG_MACH_MSG
6908+	printf("pid %d: message queued on port %p (%d) [%p]\n",
6909+	    l->l_proc->p_pid, mp, req->req_msgh.msgh_id,
6910+	    mp->mp_recv->mr_sethead);
6911+#endif
6912+	wakeup(mp->mp_recv->mr_sethead);
6913+
6914+	MACH_PORT_UNREF(mp);
6915+
6916+	return;
6917+}
6918+
6919+void
6920+mach_notify_port_no_senders(struct lwp *l, struct mach_right *mr)
6921+{
6922+	struct mach_port *mp;
6923+	mach_notify_port_no_senders_request_t *req;
6924+
6925+	if ((mr->mr_notify_no_senders == NULL) ||
6926+	    (mr->mr_notify_no_senders->mr_port == NULL))
6927+		return;
6928+	mp = mr->mr_notify_no_senders->mr_port;
6929+
6930+#ifdef DIAGNOSTIC
6931+	if ((mp == NULL) ||
6932+	    (mp->mp_recv == NULL) ||
6933+	    (mp->mp_datatype != MACH_MP_NOTIFY_SYNC)) {
6934+		printf("mach_notify_port_no_senders: bad port or reciever\n");
6935+		return;
6936+	}
6937+#endif
6938+	MACH_PORT_REF(mp);
6939+	if ((int)mp->mp_data >= mr->mr_refcount)
6940+		goto out;
6941+
6942+	req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO);
6943+
6944+	req->req_msgh.msgh_bits =
6945+	    MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
6946+	req->req_msgh.msgh_size = sizeof(*req) - sizeof(req->req_trailer);
6947+	req->req_msgh.msgh_local_port = mr->mr_notify_no_senders->mr_name;
6948+	req->req_msgh.msgh_id = MACH_NOTIFY_NO_SENDERS_MSGID;
6949+	req->req_mscount = mr->mr_refcount;
6950+
6951+	mach_set_trailer(req, sizeof(*req));
6952+
6953+	(void)mach_message_get((mach_msg_header_t *)req, sizeof(*req), mp, l);
6954+#ifdef DEBUG_MACH_MSG
6955+	printf("pid %d: message queued on port %p (%d) [%p]\n",
6956+	    l->l_proc->p_pid, mp, req->req_msgh.msgh_id,
6957+	    mp->mp_recv->mr_sethead);
6958+#endif
6959+	wakeup(mp->mp_recv->mr_sethead);
6960+
6961+out:
6962+	MACH_PORT_UNREF(mp);
6963+	return;
6964+}
6965+
6966+void
6967+mach_notify_port_dead_name(struct lwp *l, struct mach_right *mr)
6968+{
6969+	struct mach_port *mp;
6970+	mach_notify_port_dead_name_request_t *req;
6971+
6972+	if ((mr->mr_notify_dead_name == NULL) ||
6973+	    (mr->mr_notify_dead_name->mr_port == NULL))
6974+		return;
6975+	mp = mr->mr_notify_dead_name->mr_port;
6976+
6977+#ifdef DIAGNOSTIC
6978+	if ((mp == NULL) || (mp->mp_recv)) {
6979+		printf("mach_notify_port_dead_name: bad port or reciever\n");
6980+		return;
6981+	}
6982+#endif
6983+	MACH_PORT_REF(mp);
6984+
6985+	req = malloc(sizeof(*req), M_EMULDATA, M_WAITOK | M_ZERO);
6986+
6987+	req->req_msgh.msgh_bits =
6988+	    MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
6989+	req->req_msgh.msgh_size = sizeof(*req) - sizeof(req->req_trailer);
6990+	req->req_msgh.msgh_local_port = mr->mr_notify_dead_name->mr_name;
6991+	req->req_msgh.msgh_id = MACH_NOTIFY_DEAD_NAME_MSGID;
6992+	req->req_name = mr->mr_name;
6993+
6994+	mach_set_trailer(req, sizeof(*req));
6995+
6996+	mr->mr_refcount++;
6997+
6998+	(void)mach_message_get((mach_msg_header_t *)req, sizeof(*req), mp, l);
6999+#ifdef DEBUG_MACH_MSG
7000+	printf("pid %d: message queued on port %p (%d) [%p]\n",
7001+	    l->l_proc->p_pid, mp, req->req_msgh.msgh_id,
7002+	    mp->mp_recv->mr_sethead);
7003+#endif
7004+	wakeup(mp->mp_recv->mr_sethead);
7005+	MACH_PORT_UNREF(mp);
7006+
7007+	return;
7008+}
7009diff --git a/sys/compat/mach/mach_notify.h b/sys/compat/mach/mach_notify.h
7010new file mode 100644
7011index 0000000..06b2bd4
7012--- /dev/null
7013+++ b/sys/compat/mach/mach_notify.h
7014@@ -0,0 +1,79 @@
7015+/*	$NetBSD: mach_notify.h,v 1.10 2008/04/28 20:23:44 martin Exp $ */
7016+
7017+/*-
7018+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
7019+ * All rights reserved.
7020+ *
7021+ * This code is derived from software contributed to The NetBSD Foundation
7022+ * by Emmanuel Dreyfus
7023+ *
7024+ * Redistribution and use in source and binary forms, with or without
7025+ * modification, are permitted provided that the following conditions
7026+ * are met:
7027+ * 1. Redistributions of source code must retain the above copyright
7028+ *    notice, this list of conditions and the following disclaimer.
7029+ * 2. Redistributions in binary form must reproduce the above copyright
7030+ *    notice, this list of conditions and the following disclaimer in the
7031+ *    documentation and/or other materials provided with the distribution.
7032+ *
7033+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
7034+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
7035+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
7036+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
7037+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
7038+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
7039+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7040+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
7041+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
7042+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
7043+ * POSSIBILITY OF SUCH DAMAGE.
7044+ */
7045+
7046+#ifndef _MACH_NOTIFICATION_H_
7047+#define _MACH_NOTIFICATION_H_
7048+
7049+#define MACH_NOTIFY_DELETED_MSGID 65
7050+#define MACH_NOTIFY_DESTROYED_MSGID 69
7051+#define MACH_NOTIFY_NO_SENDERS_MSGID 70
7052+#define MACH_NOTIFY_SEND_ONCE_MSGID 71
7053+#define MACH_NOTIFY_DEAD_NAME_MSGID 72
7054+
7055+typedef struct {
7056+	mach_msg_header_t req_msgh;
7057+	mach_ndr_record_t req_ndr;
7058+	mach_port_name_t req_name;
7059+	mach_msg_trailer_t req_trailer;
7060+} mach_notify_port_deleted_request_t;
7061+
7062+typedef struct {
7063+	mach_msg_header_t req_msgh;
7064+	mach_msg_body_t req_body;
7065+	mach_msg_port_descriptor_t req_rights;
7066+	mach_msg_trailer_t req_trailer;
7067+} mach_notify_port_destroyed_request_t;
7068+
7069+typedef struct {
7070+	mach_msg_header_t req_msgh;
7071+	mach_ndr_record_t req_ndr;
7072+	mach_port_mscount_t req_mscount;
7073+	mach_msg_trailer_t req_trailer;
7074+} mach_notify_port_no_senders_request_t;
7075+
7076+typedef struct {
7077+	mach_msg_header_t req_msgh;
7078+	mach_msg_trailer_t req_trailer;
7079+} mach_notify_send_once_request_t;
7080+
7081+typedef struct {
7082+	mach_msg_header_t req_msgh;
7083+	mach_ndr_record_t req_ndr;
7084+	mach_port_name_t req_name;
7085+	mach_msg_trailer_t req_trailer;
7086+} mach_notify_port_dead_name_request_t;
7087+
7088+void mach_notify_port_destroyed(struct lwp *, struct mach_right *);
7089+void mach_notify_port_no_senders(struct lwp *, struct mach_right *);
7090+void mach_notify_port_dead_name(struct lwp *, struct mach_right *);
7091+
7092+#endif /* _MACH_NOTIFICATION_H_ */
7093+
7094diff --git a/sys/compat/mach/mach_port.c b/sys/compat/mach/mach_port.c
7095new file mode 100644
7096index 0000000..a891600
7097--- /dev/null
7098+++ b/sys/compat/mach/mach_port.c
7099@@ -0,0 +1,1004 @@
7100+/*	$NetBSD: mach_port.c,v 1.66 2009/03/18 16:00:17 cegger Exp $ */
7101+
7102+/*-
7103+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
7104+ * All rights reserved.
7105+ *
7106+ * This code is derived from software contributed to The NetBSD Foundation
7107+ * by Emmanuel Dreyfus
7108+ *
7109+ * Redistribution and use in source and binary forms, with or without
7110+ * modification, are permitted provided that the following conditions
7111+ * are met:
7112+ * 1. Redistributions of source code must retain the above copyright
7113+ *    notice, this list of conditions and the following disclaimer.
7114+ * 2. Redistributions in binary form must reproduce the above copyright
7115+ *    notice, this list of conditions and the following disclaimer in the
7116+ *    documentation and/or other materials provided with the distribution.
7117+ *
7118+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
7119+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
7120+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
7121+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
7122+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
7123+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
7124+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7125+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
7126+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
7127+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
7128+ * POSSIBILITY OF SUCH DAMAGE.
7129+ */
7130+
7131+#include "opt_compat_darwin.h"
7132+
7133+#include <sys/cdefs.h>
7134+__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.66 2009/03/18 16:00:17 cegger Exp $");
7135+
7136+#include <sys/types.h>
7137+#include <sys/param.h>
7138+#include <sys/systm.h>
7139+#include <sys/signal.h>
7140+#include <sys/pool.h>
7141+#include <sys/queue.h>
7142+#include <sys/malloc.h>
7143+#include <sys/proc.h>
7144+
7145+#include <compat/mach/mach_types.h>
7146+#include <compat/mach/mach_message.h>
7147+#include <compat/mach/mach_port.h>
7148+#include <compat/mach/mach_iokit.h>
7149+#include <compat/mach/mach_clock.h>
7150+#include <compat/mach/mach_exec.h>
7151+#include <compat/mach/mach_errno.h>
7152+#include <compat/mach/mach_notify.h>
7153+#include <compat/mach/mach_services.h>
7154+#include <compat/mach/mach_syscallargs.h>
7155+
7156+#ifdef COMPAT_DARWIN
7157+#include <compat/darwin/darwin_exec.h>
7158+#endif
7159+
7160+/* Right and port pools, list of all rights and its lock */
7161+static struct pool mach_port_pool;
7162+static struct pool mach_right_pool;
7163+
7164+struct mach_port *mach_bootstrap_port;
7165+struct mach_port *mach_clock_port;
7166+struct mach_port *mach_io_master_port;
7167+struct mach_port *mach_saved_bootstrap_port;
7168+
7169+int
7170+mach_sys_reply_port(struct lwp *l, const void *v, register_t *retval)
7171+{
7172+	struct mach_right *mr;
7173+
7174+	mr = mach_right_get(mach_port_get(), l, MACH_PORT_TYPE_RECEIVE, 0);
7175+	*retval = (register_t)mr->mr_name;
7176+
7177+	return 0;
7178+}
7179+
7180+int
7181+mach_sys_thread_self_trap(struct lwp *l, const void *v, register_t *retval)
7182+{
7183+	struct mach_lwp_emuldata *mle;
7184+	struct mach_right *mr;
7185+
7186+	mle = l->l_emuldata;
7187+	mr = mach_right_get(mle->mle_kernel, l, MACH_PORT_TYPE_SEND, 0);
7188+	*retval = (register_t)mr->mr_name;
7189+
7190+	return 0;
7191+}
7192+
7193+
7194+int
7195+mach_sys_task_self_trap(struct lwp *l, const void *v, register_t *retval)
7196+{
7197+	struct mach_emuldata *med;
7198+	struct mach_right *mr;
7199+
7200+	med = (struct mach_emuldata *)l->l_proc->p_emuldata;
7201+	mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
7202+	*retval = (register_t)mr->mr_name;
7203+
7204+	return 0;
7205+}
7206+
7207+
7208+int
7209+mach_sys_host_self_trap(struct lwp *l, const void *v, register_t *retval)
7210+{
7211+	struct mach_emuldata *med;
7212+	struct mach_right *mr;
7213+
7214+	med = (struct mach_emuldata *)l->l_proc->p_emuldata;
7215+	mr = mach_right_get(med->med_host, l, MACH_PORT_TYPE_SEND, 0);
7216+	*retval = (register_t)mr->mr_name;
7217+
7218+	return 0;
7219+}
7220+
7221+int
7222+mach_port_deallocate(struct mach_trap_args *args)
7223+{
7224+	mach_port_deallocate_request_t *req = args->smsg;
7225+	mach_port_deallocate_reply_t *rep = args->rmsg;
7226+	size_t *msglen = args->rsize;
7227+	struct lwp *l = args->l;
7228+	mach_port_t mn;
7229+	struct mach_right *mr;
7230+
7231+	mn = req->req_name;
7232+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_REF_RIGHTS)) != NULL)
7233+		mach_right_put(mr, MACH_PORT_TYPE_REF_RIGHTS);
7234+
7235+	*msglen = sizeof(*rep);
7236+	mach_set_header(rep, req, *msglen);
7237+
7238+	rep->rep_retval = 0;
7239+
7240+	mach_set_trailer(rep, *msglen);
7241+
7242+	return 0;
7243+}
7244+
7245+int
7246+mach_port_destroy(struct mach_trap_args *args)
7247+{
7248+	mach_port_destroy_request_t *req = args->smsg;
7249+	mach_port_destroy_reply_t *rep = args->rmsg;
7250+	size_t *msglen = args->rsize;
7251+	struct lwp *l = args->l;
7252+	mach_port_t mn;
7253+	struct mach_right *mr;
7254+
7255+#ifdef DEBUG_MACH
7256+	printf("mach_port_destroy mn = %x\n", req->req_name);
7257+#endif
7258+	mn = req->req_name;
7259+	if ((mr = mach_right_check(mn,
7260+	    l, MACH_PORT_TYPE_ALL_RIGHTS)) != NULL) {
7261+		MACH_PORT_UNREF(mr->mr_port);
7262+		mr->mr_port = NULL;
7263+		mach_right_put(mr, MACH_PORT_TYPE_ALL_RIGHTS);
7264+	}
7265+
7266+	*msglen = sizeof(*rep);
7267+	mach_set_header(rep, req, *msglen);
7268+
7269+	rep->rep_retval = 0;
7270+
7271+	mach_set_trailer(rep, *msglen);
7272+
7273+	return 0;
7274+}
7275+
7276+int
7277+mach_port_allocate(struct mach_trap_args *args)
7278+{
7279+	mach_port_allocate_request_t *req = args->smsg;
7280+	mach_port_allocate_reply_t *rep = args->rmsg;
7281+	size_t *msglen = args->rsize;
7282+	struct lwp *l = args->l;
7283+	struct mach_right *mr;
7284+	struct mach_port *mp;
7285+
7286+	switch (req->req_right) {
7287+	case MACH_PORT_RIGHT_RECEIVE:
7288+		mp = mach_port_get();
7289+		mr = mach_right_get(mp, l, MACH_PORT_TYPE_RECEIVE, 0);
7290+		break;
7291+
7292+	case MACH_PORT_RIGHT_DEAD_NAME:
7293+		mr = mach_right_get(NULL, l, MACH_PORT_TYPE_DEAD_NAME, 0);
7294+		break;
7295+
7296+	case MACH_PORT_RIGHT_PORT_SET:
7297+		mr = mach_right_get(NULL, l, MACH_PORT_TYPE_PORT_SET, 0);
7298+		break;
7299+
7300+	default:
7301+		uprintf("mach_port_allocate: unknown right %x\n",
7302+		    req->req_right);
7303+		return mach_msg_error(args, EINVAL);
7304+		break;
7305+	}
7306+
7307+	*msglen = sizeof(*rep);
7308+	mach_set_header(rep, req, *msglen);
7309+
7310+	rep->rep_retval = 0;
7311+	rep->rep_name = (mach_port_name_t)mr->mr_name;
7312+
7313+	mach_set_trailer(rep, *msglen);
7314+
7315+	return 0;
7316+}
7317+
7318+int
7319+mach_port_insert_right(struct mach_trap_args *args)
7320+{
7321+	mach_port_insert_right_request_t *req = args->smsg;
7322+	mach_port_insert_right_reply_t *rep = args->rmsg;
7323+	size_t *msglen = args->rsize;
7324+	struct lwp *l = args->l;
7325+	mach_port_t name;
7326+	mach_port_t right;
7327+	struct mach_right *mr;
7328+	struct mach_right *nmr;
7329+
7330+	name = req->req_name;
7331+	right = req->req_poly.name;
7332+	nmr = NULL;
7333+
7334+	mr = mach_right_check(right, l, MACH_PORT_TYPE_ALL_RIGHTS);
7335+	if (mr == NULL)
7336+		return mach_msg_error(args, EPERM);
7337+
7338+	switch (req->req_poly.disposition) {
7339+	case MACH_MSG_TYPE_MAKE_SEND:
7340+	case MACH_MSG_TYPE_MOVE_SEND:
7341+	case MACH_MSG_TYPE_COPY_SEND:
7342+		nmr = mach_right_get(mr->mr_port,
7343+		    l, MACH_PORT_TYPE_SEND, name);
7344+		break;
7345+
7346+	case MACH_MSG_TYPE_MAKE_SEND_ONCE:
7347+	case MACH_MSG_TYPE_MOVE_SEND_ONCE:
7348+		nmr = mach_right_get(mr->mr_port,
7349+		    l, MACH_PORT_TYPE_SEND_ONCE, name);
7350+		break;
7351+
7352+	case MACH_MSG_TYPE_MOVE_RECEIVE:
7353+		nmr = mach_right_get(mr->mr_port,
7354+		    l, MACH_PORT_TYPE_RECEIVE, name);
7355+		break;
7356+
7357+	default:
7358+		uprintf("mach_port_insert_right: unknown right %x\n",
7359+		    req->req_poly.disposition);
7360+		break;
7361+	}
7362+
7363+	*msglen = sizeof(*rep);
7364+	mach_set_header(rep, req, *msglen);
7365+
7366+	rep->rep_retval = 0;
7367+
7368+	mach_set_trailer(rep, *msglen);
7369+
7370+	return 0;
7371+}
7372+
7373+int
7374+mach_port_type(struct mach_trap_args *args)
7375+{
7376+	mach_port_type_request_t *req = args->smsg;
7377+	mach_port_type_reply_t *rep = args->rmsg;
7378+	size_t *msglen = args->rsize;
7379+	struct lwp *l = args->l;
7380+	mach_port_t mn;
7381+	struct mach_right *mr;
7382+
7383+	mn = req->req_name;
7384+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
7385+		return mach_msg_error(args, EPERM);
7386+
7387+	*msglen = sizeof(*rep);
7388+	mach_set_header(rep, req, *msglen);
7389+
7390+	rep->rep_retval = 0;
7391+	rep->rep_ptype = mr->mr_type;
7392+
7393+	mach_set_trailer(rep, *msglen);
7394+
7395+	return 0;
7396+}
7397+
7398+int
7399+mach_port_set_attributes(struct mach_trap_args *args)
7400+{
7401+	mach_port_set_attributes_request_t *req = args->smsg;
7402+	mach_port_set_attributes_reply_t *rep = args->rmsg;
7403+	size_t *msglen = args->rsize;
7404+	int end_offset;
7405+
7406+	/* Sanity check req->req_count */
7407+	end_offset = req->req_count;
7408+	if (MACH_REQMSG_OVERFLOW(args, req->req_port_info[end_offset]))
7409+		 return mach_msg_error(args, EINVAL);
7410+
7411+	switch(req->req_flavor) {
7412+	case MACH_PORT_LIMITS_INFO:
7413+	case MACH_PORT_RECEIVE_STATUS:
7414+	case MACH_PORT_DNREQUESTS_SIZE:
7415+		break;
7416+	default:
7417+		uprintf("mach_port_set_attributes: unknown flavor %d\n",
7418+		    req->req_flavor);
7419+		break;
7420+	}
7421+
7422+	*msglen = sizeof(*rep);
7423+	mach_set_header(rep, req, *msglen);
7424+
7425+	rep->rep_retval = 0;
7426+
7427+	mach_set_trailer(rep, *msglen);
7428+
7429+	return 0;
7430+}
7431+
7432+int
7433+mach_port_get_attributes(struct mach_trap_args *args)
7434+{
7435+	mach_port_get_attributes_request_t *req = args->smsg;
7436+	mach_port_get_attributes_reply_t *rep = args->rmsg;
7437+	size_t *msglen = args->rsize;
7438+	struct lwp *l = args->l;
7439+	mach_port_t mn;
7440+	struct mach_right *mr;
7441+
7442+	/* Sanity check req_count */
7443+	if (req->req_count > 10)
7444+		return mach_msg_error(args, EINVAL);
7445+
7446+	mn = req->req_msgh.msgh_remote_port;
7447+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
7448+		return mach_msg_error(args, EPERM);
7449+
7450+	switch (req->req_flavor) {
7451+	case MACH_PORT_LIMITS_INFO: {
7452+		struct mach_port_limits *mpl;
7453+
7454+		if (req->req_count < (sizeof(*mpl) / sizeof(rep->rep_info[0])))
7455+			return mach_msg_error(args, EINVAL);
7456+
7457+		mpl = (struct mach_port_limits *)&rep->rep_info[0];
7458+		mpl->mpl_qlimit = MACH_PORT_QLIMIT_DEFAULT; /* XXX fake limit */
7459+
7460+		rep->rep_count = sizeof(*mpl);
7461+
7462+		break;
7463+	}
7464+
7465+	case MACH_PORT_RECEIVE_STATUS: {
7466+		struct mach_port_status *mps;
7467+		struct mach_port *mp;
7468+
7469+		if (req->req_count < (sizeof(*mps) / sizeof(rep->rep_info[0])))
7470+			return mach_msg_error(args, EINVAL);
7471+
7472+		mps = (struct mach_port_status *)&rep->rep_info[0];
7473+		memset(mps, 0, sizeof(*mps));
7474+
7475+		if (mr->mr_sethead != NULL)
7476+			mps->mps_pset = mr->mr_sethead->mr_name;
7477+		mps->mps_seqno = 0; /* XXX */
7478+		mps->mps_qlimit = MACH_PORT_QLIMIT_DEFAULT; /* XXX fake limit */
7479+		if ((mp = mr->mr_port) != NULL) {
7480+			mps->mps_mscount = mp->mp_refcount; /* XXX */
7481+			mps->mps_msgcount = mp->mp_count;
7482+		} else {
7483+			mps->mps_mscount = 0;
7484+			mps->mps_msgcount = 0;
7485+		}
7486+		mps->mps_sorights = 0; /* XXX */
7487+		mps->mps_srights =  0; /* XXX */
7488+		if (mr->mr_notify_destroyed != NULL)
7489+			mps->mps_pdrequest = 1;
7490+		if (mr->mr_notify_no_senders != NULL)
7491+			mps->mps_nsrequest = 1;
7492+		mps->mps_flags = 0; /* XXX */
7493+
7494+		rep->rep_count = sizeof(*mps);
7495+		break;
7496+	}
7497+
7498+	default:
7499+		printf("mach_port_get_attributes: unknown flavor %d\n",
7500+		    req->req_flavor);
7501+		return mach_msg_error(args, EINVAL);
7502+
7503+		break;
7504+	};
7505+
7506+	*msglen = sizeof(*rep) - 10 + rep->rep_count;
7507+	mach_set_header(rep, req, *msglen);
7508+
7509+	rep->rep_retval = 0;
7510+
7511+	mach_set_trailer(rep, *msglen);
7512+
7513+	return 0;
7514+}
7515+
7516+/* XXX insert a recv right into a port set without removing it from another */
7517+int
7518+mach_port_insert_member(struct mach_trap_args *args)
7519+{
7520+	mach_port_insert_member_request_t *req = args->smsg;
7521+	mach_port_insert_member_reply_t *rep = args->rmsg;
7522+	size_t *msglen = args->rsize;
7523+
7524+	uprintf("Unimplemented mach_port_insert_member\n");
7525+
7526+	*msglen = sizeof(*rep);
7527+	mach_set_header(rep, req, *msglen);
7528+
7529+	rep->rep_retval = 0;
7530+
7531+	mach_set_trailer(rep, *msglen);
7532+
7533+	return 0;
7534+}
7535+
7536+int
7537+mach_port_move_member(struct mach_trap_args *args)
7538+{
7539+	mach_port_move_member_request_t *req = args->smsg;
7540+	mach_port_move_member_reply_t *rep = args->rmsg;
7541+	size_t *msglen = args->rsize;
7542+	struct lwp *l = args->l;
7543+	struct mach_emuldata *med = l->l_proc->p_emuldata;
7544+	mach_port_t member = req->req_member;
7545+	mach_port_t after = req->req_after;
7546+	struct mach_right *mrr;
7547+	struct mach_right *mrs;
7548+
7549+	mrr = mach_right_check(member, l, MACH_PORT_TYPE_RECEIVE);
7550+	if (mrr == NULL)
7551+		return mach_msg_error(args, EPERM);
7552+
7553+	mrs = mach_right_check(after, l, MACH_PORT_TYPE_PORT_SET);
7554+	if (mrs == NULL)
7555+		return mach_msg_error(args, EPERM);
7556+
7557+	rw_enter(&med->med_rightlock, RW_WRITER);
7558+
7559+	/* Remove it from an existing port set */
7560+	if (mrr->mr_sethead != mrr)
7561+		LIST_REMOVE(mrr, mr_setlist);
7562+
7563+	/* Insert it into the new port set */
7564+	LIST_INSERT_HEAD(&mrs->mr_set, mrr, mr_setlist);
7565+	mrr->mr_sethead = mrs;
7566+
7567+	rw_exit(&med->med_rightlock);
7568+
7569+	*msglen = sizeof(*rep);
7570+	mach_set_header(rep, req, *msglen);
7571+
7572+	rep->rep_retval = 0;
7573+
7574+	mach_set_trailer(rep, *msglen);
7575+
7576+	return 0;
7577+}
7578+
7579+int
7580+mach_port_request_notification(struct mach_trap_args *args)
7581+{
7582+	mach_port_request_notification_request_t *req = args->smsg;
7583+	mach_port_request_notification_reply_t *rep = args->rmsg;
7584+	struct lwp *l = args->l;
7585+	size_t *msglen = args->rsize;
7586+	mach_port_t mn;
7587+	struct mach_right *nmr;
7588+	struct mach_right *tmr;
7589+	struct mach_right *oldnmr;
7590+	mach_port_t oldmn;
7591+
7592+#ifdef DEBUG_MACH
7593+	printf("mach_port_request_notification, notify = %08x, target = %08x\n",
7594+	    req->req_notify.name, mn = req->req_name);
7595+#endif
7596+	mn = req->req_notify.name;
7597+	if ((nmr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
7598+		return mach_msg_error(args, EINVAL);
7599+
7600+	mn = req->req_name;
7601+	if ((tmr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
7602+		return mach_msg_error(args, EINVAL);
7603+
7604+#ifdef DEBUG_MACH
7605+	if (nmr->mr_port == NULL) {
7606+		printf("Notification right without a port\n");
7607+		printf("mr->mr_port = %p, mr = %08x\n", nmr->mr_port, nmr->mr_name);
7608+		return mach_msg_error(args, EINVAL);
7609+	}
7610+#endif
7611+
7612+
7613+	oldnmr = NULL;
7614+	switch(req->req_msgid) {
7615+	case MACH_NOTIFY_DESTROYED_MSGID:
7616+		oldnmr = tmr->mr_notify_destroyed;
7617+		tmr->mr_notify_destroyed = mach_right_get(nmr->mr_port,
7618+		    l, MACH_PORT_TYPE_SEND_ONCE, req->req_notify.name);
7619+		break;
7620+
7621+	case MACH_NOTIFY_NO_SENDERS_MSGID:
7622+		oldnmr = tmr->mr_notify_no_senders;
7623+		tmr->mr_notify_no_senders = mach_right_get(nmr->mr_port,
7624+		    l, MACH_PORT_TYPE_SEND_ONCE, req->req_notify.name);
7625+		tmr->mr_notify_no_senders->mr_port->mp_datatype =
7626+		    MACH_MP_NOTIFY_SYNC;
7627+		tmr->mr_notify_no_senders->mr_port->mp_data = (void *)
7628+		    req->req_count;
7629+		break;
7630+
7631+	case MACH_NOTIFY_DEAD_NAME_MSGID:
7632+		oldnmr = tmr->mr_notify_dead_name;
7633+		tmr->mr_notify_dead_name = mach_right_get(nmr->mr_port,
7634+		    l, MACH_PORT_TYPE_SEND_ONCE, req->req_notify.name);
7635+		break;
7636+
7637+	case MACH_NOTIFY_SEND_ONCE_MSGID:
7638+	case MACH_NOTIFY_DELETED_MSGID:
7639+	default:
7640+#ifdef DEBUG_MACH
7641+		printf("unsupported notify request %d\n", req->req_msgid);
7642+		return mach_msg_error(args, EINVAL);
7643+#endif
7644+		break;
7645+	}
7646+
7647+	if (oldnmr != NULL) {
7648+		oldnmr->mr_refcount++;
7649+		oldmn = oldnmr->mr_name;
7650+	} else {
7651+		oldmn = (mach_port_t)MACH_PORT_NULL;
7652+	}
7653+
7654+	*msglen = sizeof(*rep);
7655+	mach_set_header(rep, req, *msglen);
7656+	mach_add_port_desc(rep, oldmn);
7657+	mach_set_trailer(rep, *msglen);
7658+
7659+	return 0;
7660+}
7661+
7662+int
7663+mach_port_get_refs(struct mach_trap_args *args)
7664+{
7665+	mach_port_get_refs_request_t *req = args->smsg;
7666+	mach_port_get_refs_reply_t *rep = args->rmsg;
7667+	size_t *msglen = args->rsize;
7668+	struct lwp *l = args->l;
7669+	mach_port_t mn;
7670+	struct mach_right *mr;
7671+	mach_port_right_t right = req->req_right;
7672+
7673+	mn = req->req_name;
7674+	if ((mr = mach_right_check(mn, l, right)) == NULL)
7675+		return mach_msg_error(args, EINVAL);
7676+
7677+	*msglen = sizeof(*rep);
7678+	mach_set_header(rep, req, *msglen);
7679+
7680+	rep->rep_retval = 0;
7681+	rep->rep_refs = mr->mr_refcount;
7682+
7683+	mach_set_trailer(rep, *msglen);
7684+
7685+	return 0;
7686+}
7687+
7688+int
7689+mach_port_mod_refs(struct mach_trap_args *args)
7690+{
7691+	mach_port_mod_refs_request_t *req = args->smsg;
7692+	mach_port_mod_refs_reply_t *rep = args->rmsg;
7693+	size_t *msglen = args->rsize;
7694+#if 0
7695+	struct lwp *l = args->l;
7696+	mach_port_t mn;
7697+	struct mach_right *mr;
7698+	mach_port_right_t right = req->req_right;
7699+
7700+	mn = req->req_name;
7701+	if ((mr = mach_right_check(mn, l, right)) == NULL)
7702+		return mach_msg_error(args, EINVAL);
7703+
7704+	/*
7705+	 * Changing the refcount is likely to cause crashes,
7706+	 * as we will free a right which might still be referenced
7707+	 * within the kernel. Add a user refcount field?
7708+	 */
7709+	mr->mr_refcount += req->req_delta;
7710+	if (mr->mr_refcount <= 0)
7711+		mach_right_put(mr, right);
7712+#endif
7713+
7714+	*msglen = sizeof(*rep);
7715+	mach_set_header(rep, req, *msglen);
7716+
7717+	rep->rep_retval = 0;
7718+
7719+	mach_set_trailer(rep, *msglen);
7720+
7721+	return 0;
7722+}
7723+
7724+void
7725+mach_port_init(void)
7726+{
7727+	pool_init(&mach_port_pool, sizeof (struct mach_port),
7728+	    0, 0, 0, "mach_port_pool", NULL, IPL_NONE);
7729+	pool_init(&mach_right_pool, sizeof (struct mach_right),
7730+	    0, 0, 0, "mach_right_pool", NULL, IPL_NONE);
7731+
7732+	mach_bootstrap_port = mach_port_get();
7733+	mach_clock_port = mach_port_get();
7734+	mach_io_master_port = mach_port_get();
7735+
7736+	mach_bootstrap_port->mp_flags |= MACH_MP_INKERNEL;
7737+	mach_clock_port->mp_flags |= MACH_MP_INKERNEL;
7738+	mach_io_master_port->mp_flags |= MACH_MP_INKERNEL;
7739+
7740+	mach_saved_bootstrap_port = mach_bootstrap_port;
7741+
7742+	return;
7743+}
7744+
7745+struct mach_port *
7746+mach_port_get(void)
7747+{
7748+	struct mach_port *mp;
7749+
7750+	mp = (struct mach_port *)pool_get(&mach_port_pool, PR_WAITOK);
7751+	memset(mp, 0, sizeof(*mp));
7752+	mp->mp_recv = NULL;
7753+	mp->mp_count = 0;
7754+	mp->mp_flags = 0;
7755+	mp->mp_datatype = MACH_MP_NONE;
7756+	mp->mp_data = NULL;
7757+	TAILQ_INIT(&mp->mp_msglist);
7758+	rw_init(&mp->mp_msglock);
7759+
7760+	return mp;
7761+}
7762+
7763+void
7764+mach_port_put(struct mach_port *mp)
7765+{
7766+	struct mach_message *mm;
7767+
7768+#ifdef DIAGNOSTIC
7769+	if (mp->mp_refcount > 0) {
7770+		uprintf("mach_port_put: trying to free a referenced port\n");
7771+		return;
7772+	}
7773+#endif
7774+
7775+	rw_enter(&mp->mp_msglock, RW_WRITER);
7776+	while ((mm = TAILQ_FIRST(&mp->mp_msglist)) != NULL)
7777+		mach_message_put_exclocked(mm);
7778+	rw_exit(&mp->mp_msglock);
7779+	rw_destroy(&mp->mp_msglock);
7780+
7781+	if (mp->mp_flags & MACH_MP_DATA_ALLOCATED)
7782+		free(mp->mp_data, M_EMULDATA);
7783+
7784+	pool_put(&mach_port_pool, mp);
7785+
7786+	return;
7787+}
7788+
7789+struct mach_right *
7790+mach_right_get(struct mach_port *mp, struct lwp *l, int type, mach_port_t hint)
7791+{
7792+	struct mach_right *mr;
7793+	struct mach_emuldata *med;
7794+	int rights;
7795+
7796+#ifdef DEBUG_MACH
7797+	if (type == 0)
7798+		uprintf("mach_right_get: right = 0\n");
7799+#endif
7800+	med = (struct mach_emuldata *)l->l_proc->p_emuldata;
7801+
7802+	if (mp != NULL)
7803+		MACH_PORT_REF(mp);
7804+
7805+	/* Send and receive right must return an existing right */
7806+	rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_RECEIVE);
7807+	if (type & rights) {
7808+		rw_enter(&med->med_rightlock, RW_READER);
7809+		LIST_FOREACH(mr, &med->med_right, mr_list) {
7810+			if ((mr->mr_port == mp) && (mr->mr_type & rights))
7811+				break;
7812+		}
7813+		rw_exit(&med->med_rightlock);
7814+
7815+		if (mr != NULL) {
7816+			mr->mr_type |= type;
7817+			if (type & MACH_PORT_TYPE_SEND)
7818+				mr->mr_refcount++;
7819+			goto rcvck;
7820+		}
7821+	}
7822+
7823+	mr = pool_get(&mach_right_pool, PR_WAITOK);
7824+
7825+	mr->mr_port = mp;
7826+	mr->mr_lwp = l;
7827+	mr->mr_type = type;
7828+	mr->mr_sethead = mr;
7829+	mr->mr_refcount = 1;
7830+	mr->mr_notify_destroyed = NULL;
7831+	mr->mr_notify_dead_name = NULL;
7832+	mr->mr_notify_no_senders = NULL;
7833+
7834+	LIST_INIT(&mr->mr_set);
7835+
7836+	/* Insert the right in the right lists */
7837+	if (type & MACH_PORT_TYPE_ALL_RIGHTS) {
7838+		rw_enter(&med->med_rightlock, RW_WRITER);
7839+		mr->mr_name = mach_right_newname(l, hint);
7840+#ifdef DEBUG_MACH_RIGHT
7841+		printf("mach_right_get: insert right %x(%x)\n",
7842+		    mr->mr_name, mr->mr_type);
7843+#endif
7844+		LIST_INSERT_HEAD(&med->med_right, mr, mr_list);
7845+		rw_exit(&med->med_rightlock);
7846+	}
7847+
7848+rcvck:
7849+	if (type & MACH_PORT_TYPE_RECEIVE) {
7850+		/*
7851+		 * Destroy the former receive right on this port, and
7852+		 * register the new right.
7853+		 */
7854+		if (mr->mr_port->mp_recv != NULL)
7855+			mach_right_put(mr->mr_port->mp_recv,
7856+			    MACH_PORT_TYPE_RECEIVE);
7857+		mr->mr_port->mp_recv = mr;
7858+	}
7859+	return mr;
7860+}
7861+
7862+void
7863+mach_right_put(struct mach_right *mr, int right)
7864+{
7865+	struct mach_emuldata *med = mr->mr_lwp->l_proc->p_emuldata;
7866+
7867+	rw_enter(&med->med_rightlock, RW_WRITER);
7868+	mach_right_put_exclocked(mr, right);
7869+	rw_exit(&med->med_rightlock);
7870+
7871+	return;
7872+}
7873+
7874+void
7875+mach_right_put_shlocked(struct mach_right *mr, int right)
7876+{
7877+	struct mach_emuldata *med = mr->mr_lwp->l_proc->p_emuldata;
7878+
7879+	if (!rw_tryupgrade(&med->med_rightlock)) {
7880+		/* XXX */
7881+		rw_exit(&med->med_rightlock);
7882+		rw_enter(&med->med_rightlock, RW_WRITER);
7883+	}
7884+	mach_right_put_exclocked(mr, right);
7885+	rw_downgrade(&med->med_rightlock);
7886+
7887+	return;
7888+}
7889+
7890+void
7891+mach_right_put_exclocked(struct mach_right *mr, int right)
7892+{
7893+	struct mach_right *cmr;
7894+	struct mach_emuldata *med;
7895+	int lright;
7896+	int kill_right;
7897+
7898+	med = mr->mr_lwp->l_proc->p_emuldata;
7899+
7900+#ifdef DEBUG_MACH_RIGHT
7901+	printf("mach_right_put: mr = %p\n", mr);
7902+	printf("right %x(%x) refcount %d, deallocate %x\n",
7903+	    mr->mr_name, mr->mr_type, mr->mr_refcount, right);
7904+	if ((mr->mr_type & right) == 0)
7905+		printf("mach_right_put: dropping nonexistant right %x on %x\n",
7906+		    right, mr->mr_name);
7907+	LIST_FOREACH(cmr, &med->med_right, mr_list)
7908+		if (cmr == mr)
7909+			break;
7910+	if (cmr == NULL) {
7911+		printf("mach_right_put: dropping already dropped right %x\n",
7912+		    mr->mr_name);
7913+		return;
7914+	}
7915+#endif
7916+	kill_right = 0;
7917+
7918+	/* When receive right is deallocated, the port should die */
7919+	lright = (right & MACH_PORT_TYPE_RECEIVE);
7920+#ifdef DEBUG_MACH_RIGHT
7921+	printf("mr->mr_type = %x, lright = %x, right = %x, refcount = %d\n",
7922+	    mr->mr_type, lright, right, mr->mr_refcount);
7923+#endif
7924+	if (mr->mr_type & lright) {
7925+		if (mr->mr_refcount <= 0) {
7926+			mr->mr_type &= ~MACH_PORT_TYPE_RECEIVE;
7927+			kill_right = 1;
7928+		} else {
7929+			mr->mr_type &= ~MACH_PORT_TYPE_RECEIVE;
7930+			mr->mr_type |= MACH_PORT_TYPE_DEAD_NAME;
7931+			mach_notify_port_dead_name(mr->mr_lwp, mr);
7932+		}
7933+		if (mr->mr_port != NULL) {
7934+			/* There is no more receiver */
7935+#ifdef DIAGNOSTIC
7936+			if (mr->mr_port->mp_recv != mr)
7937+				printf("several receiver on a single port\n");
7938+#endif
7939+			mr->mr_port->mp_recv = NULL;
7940+
7941+			MACH_PORT_UNREF(mr->mr_port);
7942+			mr->mr_port = NULL;
7943+		}
7944+	}
7945+
7946+	/* send, send_once and dead_name */
7947+	lright = (right & MACH_PORT_TYPE_REF_RIGHTS);
7948+	if (mr->mr_type & lright) {
7949+		mr->mr_refcount--;
7950+
7951+		mach_notify_port_no_senders(mr->mr_lwp, mr);
7952+
7953+		if (mr->mr_refcount <= 0) {
7954+			mr->mr_type &= ~MACH_PORT_TYPE_REF_RIGHTS;
7955+			if ((mr->mr_type & MACH_PORT_TYPE_RECEIVE) == 0)
7956+				kill_right = 1;
7957+		}
7958+	}
7959+
7960+	lright = (right & MACH_PORT_TYPE_PORT_SET);
7961+	if ((mr->mr_type & lright) || (kill_right == 1)) {
7962+		while ((cmr = LIST_FIRST(&mr->mr_set)) != NULL) {
7963+			LIST_REMOVE(cmr, mr_setlist);
7964+			cmr->mr_sethead = cmr;
7965+		}
7966+		mr->mr_type &= ~MACH_PORT_TYPE_PORT_SET;
7967+		if ((mr->mr_type & MACH_PORT_TYPE_RECEIVE) == 0)
7968+			kill_right = 1;
7969+	}
7970+
7971+	/* Should we kill it? */
7972+	if (kill_right == 1) {
7973+#ifdef DEBUG_MACH_RIGHT
7974+		printf("mach_right_put: kill name %x\n", mr->mr_name);
7975+#endif
7976+		/* If the right is used for an IO notification, remove it */
7977+		mach_iokit_cleanup_notify(mr);
7978+
7979+		mach_notify_port_destroyed(mr->mr_lwp, mr);
7980+		LIST_REMOVE(mr, mr_list);
7981+		pool_put(&mach_right_pool, mr);
7982+	}
7983+	return;
7984+}
7985+
7986+/*
7987+ * Check that a process has a given right.
7988+ */
7989+struct mach_right *
7990+mach_right_check(mach_port_t mn, struct lwp *l, int type)
7991+{
7992+	struct mach_right *cmr;
7993+	struct mach_emuldata *med;
7994+
7995+	if ((mn == 0) || (mn == -1) || (l == NULL))
7996+		return NULL;
7997+
7998+	med = (struct mach_emuldata *)l->l_proc->p_emuldata;
7999+
8000+	rw_enter(&med->med_rightlock, RW_READER);
8001+
8002+#ifdef DEBUG_MACH_RIGHT
8003+	printf("mach_right_check: type = %x, mn = %x\n", type, mn);
8004+#endif
8005+	LIST_FOREACH(cmr, &med->med_right, mr_list) {
8006+#ifdef DEBUG_MACH_RIGHT
8007+		printf("cmr = %p, cmr->mr_name = %x, cmr->mr_type = %x\n",
8008+		    cmr, cmr->mr_name, cmr->mr_type);
8009+#endif
8010+		if (cmr->mr_name != mn)
8011+			continue;
8012+		if (type & cmr->mr_type)
8013+			break;
8014+	}
8015+
8016+	rw_exit(&med->med_rightlock);
8017+
8018+	return cmr;
8019+}
8020+
8021+
8022+/*
8023+ * Find an usnused port name in a given lwp.
8024+ * Right lists should be locked.
8025+ */
8026+mach_port_t
8027+mach_right_newname(struct lwp *l, mach_port_t hint)
8028+{
8029+	struct mach_emuldata *med;
8030+	struct mach_right *mr;
8031+	mach_port_t newname = -1;
8032+
8033+	med = l->l_proc->p_emuldata;
8034+
8035+	if (hint == 0)
8036+		hint = med->med_nextright;
8037+
8038+	while (newname == -1) {
8039+		LIST_FOREACH(mr, &med->med_right, mr_list)
8040+			if (mr->mr_name == hint)
8041+				break;
8042+		if (mr == NULL)
8043+			newname = hint;
8044+		hint++;
8045+	}
8046+
8047+	med->med_nextright = hint;
8048+
8049+	return newname;
8050+}
8051+
8052+#ifdef DEBUG_MACH
8053+void
8054+mach_debug_port(void)
8055+{
8056+	struct mach_emuldata *med;
8057+	struct mach_right *mr;
8058+	struct mach_right *mrs;
8059+	struct proc *p;
8060+
8061+	PROCLIST_FOREACH(p, &allproc) {
8062+		if ((p->p_emul != &emul_mach) &&
8063+#ifdef COMPAT_DARWIN
8064+		    (p->p_emul != &emul_darwin) &&
8065+#endif
8066+		    1)
8067+			continue;
8068+
8069+		med = p->p_emuldata;
8070+		LIST_FOREACH(mr, &med->med_right, mr_list) {
8071+			if ((mr->mr_type & MACH_PORT_TYPE_PORT_SET) == 0) {
8072+				printf("pid %d: %p(%x)=>%p",
8073+				    p->p_pid, mr, mr->mr_type, mr->mr_port);
8074+				if (mr->mr_port && mr->mr_port->mp_recv)
8075+					printf("[%p]\n",
8076+					    mr->mr_port->mp_recv->mr_sethead);
8077+				else
8078+					printf("[NULL]\n");
8079+
8080+				continue;
8081+			}
8082+
8083+			/* Port set... */
8084+			printf("pid %d: set %p(%x) ",
8085+			    p->p_pid, mr, mr->mr_type);
8086+			LIST_FOREACH(mrs, &mr->mr_set, mr_setlist) {
8087+				printf("%p(%x)=>%p",
8088+				    mrs, mrs->mr_type, mrs->mr_port);
8089+				if (mrs->mr_port && mrs->mr_port->mp_recv)
8090+					printf("[%p]",
8091+					    mrs->mr_port->mp_recv->mr_sethead);
8092+				else
8093+					printf("[NULL]");
8094+
8095+				printf(" ");
8096+			}
8097+			printf("\n");
8098+		}
8099+	}
8100+	return;
8101+}
8102+
8103+#endif /* DEBUG_MACH */
8104diff --git a/sys/compat/mach/mach_port.h b/sys/compat/mach/mach_port.h
8105new file mode 100644
8106index 0000000..8399791
8107--- /dev/null
8108+++ b/sys/compat/mach/mach_port.h
8109@@ -0,0 +1,363 @@
8110+/*	$NetBSD: mach_port.h,v 1.40 2008/04/28 20:23:44 martin Exp $ */
8111+
8112+/*-
8113+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
8114+ * All rights reserved.
8115+ *
8116+ * This code is derived from software contributed to The NetBSD Foundation
8117+ * by Emmanuel Dreyfus
8118+ *
8119+ * Redistribution and use in source and binary forms, with or without
8120+ * modification, are permitted provided that the following conditions
8121+ * are met:
8122+ * 1. Redistributions of source code must retain the above copyright
8123+ *    notice, this list of conditions and the following disclaimer.
8124+ * 2. Redistributions in binary form must reproduce the above copyright
8125+ *    notice, this list of conditions and the following disclaimer in the
8126+ *    documentation and/or other materials provided with the distribution.
8127+ *
8128+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
8129+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
8130+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
8131+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
8132+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8133+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
8134+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8135+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
8136+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8137+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8138+ * POSSIBILITY OF SUCH DAMAGE.
8139+ */
8140+
8141+#ifndef	_MACH_PORT_H_
8142+#define	_MACH_PORT_H_
8143+
8144+#define MACH_PORT_REF(mp)	(mp)->mp_refcount++
8145+#define MACH_PORT_UNREF(mp)	if (--(mp)->mp_refcount <= 0) mach_port_put(mp)
8146+
8147+#define MACH_PORT_NULL			(struct mach_right *)0
8148+#define MACH_PORT_DEAD			(struct mach_right *)-1
8149+
8150+#define MACH_PORT_RIGHT_SEND		0
8151+#define MACH_PORT_RIGHT_RECEIVE		1
8152+#define MACH_PORT_RIGHT_SEND_ONCE	2
8153+#define MACH_PORT_RIGHT_PORT_SET	3
8154+#define MACH_PORT_RIGHT_DEAD_NAME	4
8155+#define MACH_PORT_RIGHT_NUMBER		5
8156+
8157+#define MACH_PORT_TYPE_SEND		(1 << (MACH_PORT_RIGHT_SEND + 16))
8158+#define MACH_PORT_TYPE_RECEIVE		(1 << (MACH_PORT_RIGHT_RECEIVE + 16))
8159+#define MACH_PORT_TYPE_SEND_ONCE	(1 << (MACH_PORT_RIGHT_SEND_ONCE + 16))
8160+#define MACH_PORT_TYPE_PORT_SET		(1 << (MACH_PORT_RIGHT_PORT_SET + 16))
8161+#define MACH_PORT_TYPE_DEAD_NAME	(1 << (MACH_PORT_RIGHT_DEAD_NAME + 16))
8162+#define MACH_PORT_TYPE_PORT_RIGHTS \
8163+    (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_RECEIVE | MACH_PORT_TYPE_SEND_ONCE)
8164+#define MACH_PORT_TYPE_PORT_OR_DEAD \
8165+    (MACH_PORT_TYPE_PORT_RIGHTS | MACH_PORT_TYPE_DEAD_NAME)
8166+#define MACH_PORT_TYPE_ALL_RIGHTS \
8167+    (MACH_PORT_TYPE_PORT_OR_DEAD|MACH_PORT_TYPE_PORT_SET)
8168+#define MACH_PORT_TYPE_REF_RIGHTS \
8169+    (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_SEND_ONCE | MACH_PORT_TYPE_DEAD_NAME)
8170+
8171+/* port_deallocate */
8172+
8173+typedef struct {
8174+	mach_msg_header_t req_msgh;
8175+	mach_ndr_record_t req_ndr;
8176+	mach_port_name_t req_name;
8177+} mach_port_deallocate_request_t;
8178+
8179+typedef struct {
8180+	mach_msg_header_t rep_msgh;
8181+	mach_ndr_record_t rep_ndr;
8182+	mach_kern_return_t rep_retval;
8183+	mach_msg_trailer_t rep_trailer;
8184+} mach_port_deallocate_reply_t;
8185+
8186+/* port_allocate */
8187+
8188+typedef struct {
8189+	mach_msg_header_t req_msgh;
8190+	mach_ndr_record_t req_ndr;
8191+	mach_port_right_t req_right;
8192+} mach_port_allocate_request_t;
8193+
8194+typedef struct {
8195+	mach_msg_header_t rep_msgh;
8196+	mach_ndr_record_t rep_ndr;
8197+	mach_kern_return_t rep_retval;
8198+	mach_port_name_t rep_name;
8199+	mach_msg_trailer_t rep_trailer;
8200+} mach_port_allocate_reply_t;
8201+
8202+/* port_insert_right */
8203+
8204+typedef struct {
8205+	mach_msg_header_t req_msgh;
8206+	mach_msg_body_t req_body;
8207+	mach_msg_port_descriptor_t req_poly;
8208+	mach_ndr_record_t req_ndr;
8209+	mach_port_name_t req_name;
8210+} mach_port_insert_right_request_t;
8211+
8212+typedef struct {
8213+	mach_msg_header_t rep_msgh;
8214+	mach_ndr_record_t rep_ndr;
8215+	mach_kern_return_t rep_retval;
8216+	mach_msg_trailer_t rep_trailer;
8217+} mach_port_insert_right_reply_t;
8218+
8219+/* port_type */
8220+
8221+typedef struct {
8222+	mach_msg_header_t req_msgh;
8223+	mach_ndr_record_t req_ndr;
8224+	mach_port_name_t req_name;
8225+} mach_port_type_request_t;
8226+
8227+typedef struct {
8228+	mach_msg_header_t rep_msgh;
8229+	mach_ndr_record_t rep_ndr;
8230+	mach_kern_return_t rep_retval;
8231+	mach_port_type_t rep_ptype;
8232+	mach_msg_trailer_t rep_trailer;
8233+} mach_port_type_reply_t;
8234+
8235+/* port_set_attributes */
8236+
8237+#define MACH_PORT_LIMITS_INFO 1
8238+#define MACH_PORT_RECEIVE_STATUS 2
8239+#define MACH_PORT_DNREQUESTS_SIZE 3
8240+
8241+typedef struct mach_port_status {
8242+	mach_port_name_t	mps_pset;
8243+	mach_port_seqno_t	mps_seqno;
8244+	mach_port_mscount_t	mps_mscount;
8245+	mach_port_msgcount_t	mps_qlimit;
8246+	mach_port_msgcount_t	mps_msgcount;
8247+	mach_port_rights_t	mps_sorights;
8248+	mach_boolean_t		mps_srights;
8249+	mach_boolean_t		mps_pdrequest;
8250+	mach_boolean_t		mps_nsrequest;
8251+	unsigned int		mps_flags;
8252+} mach_port_status_t;
8253+
8254+typedef struct mach_port_limits {
8255+	mach_port_msgcount_t	mpl_qlimit;
8256+} mach_port_limits_t;
8257+
8258+typedef struct {
8259+	mach_msg_header_t req_msgh;
8260+	mach_ndr_record_t req_ndr;
8261+	mach_port_name_t req_name;
8262+	mach_port_flavor_t req_flavor;
8263+	mach_msg_type_number_t req_count;
8264+	mach_integer_t req_port_info[0];
8265+} mach_port_set_attributes_request_t;
8266+
8267+typedef struct {
8268+	mach_msg_header_t rep_msgh;
8269+	mach_ndr_record_t rep_ndr;
8270+	mach_kern_return_t rep_retval;
8271+	mach_msg_trailer_t rep_trailer;
8272+} mach_port_set_attributes_reply_t;
8273+
8274+/* port_get_attributes */
8275+
8276+#define MACH_PORT_QLIMIT_DEFAULT ((mach_port_msgcount_t) 5)
8277+#define MACH_PORT_QLIMIT_MAX ((mach_port_msgcount_t) 16)
8278+
8279+typedef struct {
8280+	mach_msg_header_t req_msgh;
8281+	mach_ndr_record_t req_ndr;
8282+	mach_port_name_t req_name;
8283+	mach_port_flavor_t req_flavor;
8284+	mach_msg_type_number_t req_count;
8285+} mach_port_get_attributes_request_t;
8286+
8287+typedef struct {
8288+	mach_msg_header_t rep_msgh;
8289+	mach_ndr_record_t rep_ndr;
8290+	mach_kern_return_t rep_retval;
8291+	mach_msg_type_number_t rep_count;
8292+	mach_integer_t rep_info[10];
8293+	mach_msg_trailer_t rep_trailer;
8294+} mach_port_get_attributes_reply_t;
8295+
8296+/* port_insert_member */
8297+
8298+typedef struct {
8299+	mach_msg_header_t req_msgh;
8300+	mach_ndr_record_t req_ndr;
8301+	mach_port_name_t req_name;
8302+	mach_port_name_t req_pset;
8303+} mach_port_insert_member_request_t;
8304+
8305+typedef struct {
8306+	mach_msg_header_t rep_msgh;
8307+	mach_ndr_record_t rep_ndr;
8308+	mach_kern_return_t rep_retval;
8309+	mach_msg_trailer_t rep_trailer;
8310+} mach_port_insert_member_reply_t;
8311+
8312+/* port_move_member */
8313+
8314+typedef struct {
8315+	mach_msg_header_t req_msgh;
8316+	mach_ndr_record_t req_ndr;
8317+	mach_port_name_t req_member;
8318+	mach_port_name_t req_after;
8319+} mach_port_move_member_request_t;
8320+
8321+typedef struct {
8322+	mach_msg_header_t rep_msgh;
8323+	mach_ndr_record_t rep_ndr;
8324+	mach_kern_return_t rep_retval;
8325+	mach_msg_trailer_t rep_trailer;
8326+} mach_port_move_member_reply_t;
8327+
8328+/* port_destroy */
8329+
8330+typedef struct {
8331+	mach_msg_header_t req_msgh;
8332+	mach_ndr_record_t req_ndr;
8333+	mach_port_name_t req_name;
8334+} mach_port_destroy_request_t;
8335+
8336+typedef struct {
8337+	mach_msg_header_t rep_msgh;
8338+	mach_ndr_record_t rep_ndr;
8339+	mach_kern_return_t rep_retval;
8340+	mach_msg_trailer_t rep_trailer;
8341+} mach_port_destroy_reply_t;
8342+
8343+/* port_request_notification */
8344+
8345+typedef struct {
8346+	mach_msg_header_t req_msgh;
8347+	mach_msg_body_t req_body;
8348+	mach_msg_port_descriptor_t req_notify;
8349+	mach_ndr_record_t req_ndr;
8350+	mach_port_name_t req_name;
8351+	mach_msg_id_t req_msgid;
8352+	mach_port_mscount_t req_count;
8353+} mach_port_request_notification_request_t;
8354+
8355+typedef struct {
8356+	mach_msg_header_t rep_msgh;
8357+	mach_msg_body_t rep_body;
8358+	mach_msg_port_descriptor_t rep_previous;
8359+	mach_msg_trailer_t rep_trailer;
8360+} mach_port_request_notification_reply_t;
8361+
8362+/* port_get_refs */
8363+
8364+typedef struct {
8365+	mach_msg_header_t req_msgh;
8366+	mach_ndr_record_t req_ndr;
8367+	mach_port_name_t req_name;
8368+	mach_port_right_t req_right;
8369+} mach_port_get_refs_request_t;
8370+
8371+typedef struct {
8372+	mach_msg_header_t rep_msgh;
8373+	mach_ndr_record_t rep_ndr;
8374+	mach_kern_return_t rep_retval;
8375+	mach_port_urefs_t rep_refs;
8376+	mach_msg_trailer_t rep_trailer;
8377+} mach_port_get_refs_reply_t;
8378+
8379+/* port_mod_refs */
8380+
8381+typedef struct {
8382+	mach_msg_header_t req_msgh;
8383+	mach_ndr_record_t req_ndr;
8384+	mach_port_name_t req_name;
8385+	mach_port_right_t req_right;
8386+	mach_port_delta_t req_delta;
8387+} mach_port_mod_refs_request_t;
8388+
8389+typedef struct {
8390+	mach_msg_header_t rep_msgh;
8391+	mach_ndr_record_t rep_ndr;
8392+	mach_kern_return_t rep_retval;
8393+	mach_msg_trailer_t rep_trailer;
8394+} mach_port_mod_refs_reply_t;
8395+
8396+/* Kernel-private structures */
8397+
8398+extern struct mach_port *mach_clock_port;
8399+extern struct mach_port *mach_io_master_port;
8400+extern struct mach_port *mach_bootstrap_port;
8401+extern struct mach_port *mach_saved_bootstrap_port;
8402+
8403+/* In-kernel Mach port right description */
8404+struct mach_right {
8405+	mach_port_t mr_name;		/* The right name */
8406+	struct lwp *mr_lwp;		/* points back to struct lwp */
8407+	int mr_type;			/* right type (recv, send, sendonce) */
8408+	LIST_ENTRY(mach_right) mr_list; /* Right list for a process */
8409+	int mr_refcount;		/* Reference count */
8410+	struct mach_right *mr_notify_destroyed;		/* notify destroyed */
8411+	struct mach_right *mr_notify_dead_name;		/* notify dead name */
8412+	struct mach_right *mr_notify_no_senders;	/* notify no senders */
8413+
8414+	/* Revelant only if the right is on a port set */
8415+	LIST_HEAD(mr_set, mach_right) mr_set;
8416+					/* The right set list */
8417+
8418+	/* Revelant only if the right is not on a port set */
8419+	struct mach_port *mr_port;	/* Port we have the right on */
8420+	LIST_ENTRY(mach_right) mr_setlist; /* Set list */
8421+
8422+	/* Revelant only if the right is part of a port set */
8423+	struct mach_right *mr_sethead;	/* Points back to right set */
8424+};
8425+
8426+mach_port_t mach_right_newname(struct lwp *, mach_port_t);
8427+struct mach_right *mach_right_get(struct mach_port *,
8428+    struct lwp *, int, mach_port_t);
8429+void mach_right_put(struct mach_right *, int);
8430+void mach_right_put_shlocked(struct mach_right *, int);
8431+void mach_right_put_exclocked(struct mach_right *, int);
8432+struct mach_right *mach_right_check(mach_port_t, struct lwp *, int);
8433+
8434+/* In-kernel Mach port description */
8435+struct mach_port {
8436+	struct mach_right *mp_recv;	/* The receive right on this port */
8437+	int mp_count;			/* Count of queued messages */
8438+	TAILQ_HEAD(mp_msglist,		/* Queue pending messages */
8439+	    mach_message) mp_msglist;
8440+	krwlock_t mp_msglock;		/* Lock for the queue */
8441+	int mp_refcount;		/* Reference count */
8442+	int mp_flags;			/* Flags, see below */
8443+	int mp_datatype;		/* Type of field mp_data, see below */
8444+	void *mp_data;			/* Data attached to the port */
8445+};
8446+
8447+/* mp_flags for struct mach_port */
8448+#define MACH_MP_INKERNEL	0x01	/* Receiver is inside the kernel */
8449+#define MACH_MP_DATA_ALLOCATED	0x02	/* mp_data was malloc'ed */
8450+
8451+/* mp_datatype for struct mach_port */
8452+#define	MACH_MP_NONE		0x0	/* No data */
8453+#define MACH_MP_LWP		0x1	/* (struct lwp *) */
8454+#define MACH_MP_DEVICE_ITERATOR	0x2	/* (struct mach_device_iterator *) */
8455+#define MACH_MP_IOKIT_DEVCLASS	0x3	/* (struct mach_iokit_devclass *) */
8456+#define MACH_MP_PROC		0x4	/* (struct proc *) */
8457+#define MACH_MP_NOTIFY_SYNC	0x5	/* int */
8458+#define MACH_MP_MEMORY_ENTRY	0x6	/* (struct mach_memory_entry *) */
8459+#define MACH_MP_EXC_INFO	0x7	/* (struct mach_exc_info *) */
8460+#define MACH_MP_SEMAPHORE	0x8	/* (struct mach_semaphore *) */
8461+
8462+void mach_port_init(void);
8463+struct mach_port *mach_port_get(void);
8464+void mach_port_put(struct mach_port *);
8465+void mach_remove_recvport(struct mach_port *);
8466+void mach_add_recvport(struct mach_port *, struct lwp *);
8467+int mach_port_check(struct mach_port *);
8468+#ifdef DEBUG_MACH
8469+void mach_debug_port(void);
8470+#endif
8471+
8472+#endif /* _MACH_PORT_H_ */
8473diff --git a/sys/compat/mach/mach_semaphore.c b/sys/compat/mach/mach_semaphore.c
8474new file mode 100644
8475index 0000000..327c893
8476--- /dev/null
8477+++ b/sys/compat/mach/mach_semaphore.c
8478@@ -0,0 +1,438 @@
8479+/*	$NetBSD: mach_semaphore.c,v 1.19 2008/04/28 20:23:44 martin Exp $ */
8480+
8481+/*-
8482+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
8483+ * All rights reserved.
8484+ *
8485+ * This code is derived from software contributed to The NetBSD Foundation
8486+ * by Emmanuel Dreyfus
8487+ *
8488+ * Redistribution and use in source and binary forms, with or without
8489+ * modification, are permitted provided that the following conditions
8490+ * are met:
8491+ * 1. Redistributions of source code must retain the above copyright
8492+ *    notice, this list of conditions and the following disclaimer.
8493+ * 2. Redistributions in binary form must reproduce the above copyright
8494+ *    notice, this list of conditions and the following disclaimer in the
8495+ *    documentation and/or other materials provided with the distribution.
8496+ *
8497+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
8498+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
8499+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
8500+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
8501+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8502+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
8503+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8504+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
8505+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8506+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8507+ * POSSIBILITY OF SUCH DAMAGE.
8508+ */
8509+
8510+#include <sys/cdefs.h>
8511+__KERNEL_RCSID(0, "$NetBSD: mach_semaphore.c,v 1.19 2008/04/28 20:23:44 martin Exp $");
8512+
8513+#include <sys/types.h>
8514+#include <sys/param.h>
8515+#include <sys/systm.h>
8516+#include <sys/signal.h>
8517+#include <sys/pool.h>
8518+#include <sys/rwlock.h>
8519+#include <sys/malloc.h>
8520+#include <sys/proc.h>
8521+
8522+#include <compat/mach/mach_types.h>
8523+#include <compat/mach/mach_message.h>
8524+#include <compat/mach/mach_semaphore.h>
8525+#include <compat/mach/mach_clock.h>
8526+#include <compat/mach/mach_errno.h>
8527+#include <compat/mach/mach_port.h>
8528+#include <compat/mach/mach_services.h>
8529+#include <compat/mach/mach_syscallargs.h>
8530+
8531+/* Semaphore list, lock, pools */
8532+static LIST_HEAD(mach_semaphore_list, mach_semaphore) mach_semaphore_list;
8533+static krwlock_t mach_semaphore_list_lock;
8534+static struct pool mach_semaphore_list_pool;
8535+static struct pool mach_waiting_lwp_pool;
8536+
8537+/* Function to manipulate them */
8538+static struct mach_semaphore *mach_semaphore_get(int, int);
8539+static void mach_semaphore_put(struct mach_semaphore *);
8540+static struct mach_waiting_lwp *mach_waiting_lwp_get
8541+    (struct lwp *, struct mach_semaphore *);
8542+static void mach_waiting_lwp_put
8543+    (struct mach_waiting_lwp *, struct mach_semaphore *, int);
8544+
8545+int
8546+mach_sys_semaphore_wait_trap(struct lwp *l, const struct mach_sys_semaphore_wait_trap_args *uap, register_t *retval)
8547+{
8548+	/* {
8549+		syscallarg(mach_port_name_t) wait_name;
8550+	} */
8551+	struct mach_semaphore *ms;
8552+	struct mach_waiting_lwp *mwl;
8553+	struct mach_right *mr;
8554+	mach_port_t mn;
8555+	int blocked = 0;
8556+
8557+	mn = SCARG(uap, wait_name);
8558+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
8559+		return EPERM;
8560+
8561+	if (mr->mr_port->mp_datatype != MACH_MP_SEMAPHORE)
8562+		return EINVAL;
8563+
8564+	ms = (struct mach_semaphore *)mr->mr_port->mp_data;
8565+
8566+	rw_enter(&ms->ms_lock, RW_WRITER);
8567+	ms->ms_value--;
8568+	if (ms->ms_value < 0)
8569+		blocked = 1;
8570+	rw_exit(&ms->ms_lock);
8571+
8572+	if (blocked != 0) {
8573+		mwl = mach_waiting_lwp_get(l, ms);
8574+		while (ms->ms_value < 0)
8575+			tsleep(mwl, PZERO|PCATCH, "sem_wait", 0);
8576+		mach_waiting_lwp_put(mwl, ms, 0);
8577+	}
8578+	return 0;
8579+}
8580+
8581+int
8582+mach_sys_semaphore_signal_trap(struct lwp *l, const struct mach_sys_semaphore_signal_trap_args *uap, register_t *retval)
8583+{
8584+	/* {
8585+		syscallarg(mach_port_name_t) signal_name;
8586+	} */
8587+	struct mach_semaphore *ms;
8588+	struct mach_waiting_lwp *mwl;
8589+	struct mach_right *mr;
8590+	mach_port_t mn;
8591+	int unblocked = 0;
8592+
8593+	mn = SCARG(uap, signal_name);
8594+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
8595+		return EPERM;
8596+
8597+	if (mr->mr_port->mp_datatype != MACH_MP_SEMAPHORE)
8598+		return EINVAL;
8599+
8600+	ms = (struct mach_semaphore *)mr->mr_port->mp_data;
8601+
8602+	rw_enter(&ms->ms_lock, RW_WRITER);
8603+	ms->ms_value++;
8604+	if (ms->ms_value >= 0)
8605+		unblocked = 1;
8606+	rw_exit(&ms->ms_lock);
8607+
8608+	if (unblocked != 0) {
8609+		rw_enter(&ms->ms_lock, RW_READER);
8610+		mwl = TAILQ_FIRST(&ms->ms_waiting);
8611+		wakeup(mwl);
8612+		rw_exit(&ms->ms_lock);
8613+	}
8614+	return 0;
8615+}
8616+
8617+int
8618+mach_semaphore_create(struct mach_trap_args *args)
8619+{
8620+	mach_semaphore_create_request_t *req = args->smsg;
8621+	mach_semaphore_create_reply_t *rep = args->rmsg;
8622+	size_t *msglen = args->rsize;
8623+	struct lwp *l = args->l;
8624+	struct mach_semaphore *ms;
8625+	struct mach_port *mp;
8626+	struct mach_right *mr;
8627+
8628+	ms = mach_semaphore_get(req->req_value, req->req_policy);
8629+
8630+	mp = mach_port_get();
8631+	mp->mp_datatype = MACH_MP_SEMAPHORE;
8632+	mp->mp_data = (void *)ms;
8633+
8634+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
8635+
8636+	*msglen = sizeof(*rep);
8637+	mach_set_header(rep, req, *msglen);
8638+	mach_add_port_desc(rep, mr->mr_name);
8639+	mach_set_trailer(rep, *msglen);
8640+
8641+	return 0;
8642+}
8643+
8644+int
8645+mach_semaphore_destroy(struct mach_trap_args *args)
8646+{
8647+	mach_semaphore_destroy_request_t *req = args->smsg;
8648+	mach_semaphore_destroy_reply_t *rep = args->rmsg;
8649+	struct lwp *l = args->l;
8650+	size_t *msglen = args->rsize;
8651+	struct mach_semaphore *ms;
8652+	struct mach_right *mr;
8653+	mach_port_t mn;
8654+
8655+	mn = req->req_sem.name;
8656+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
8657+		return mach_msg_error(args, EPERM);
8658+
8659+	if (mr->mr_port->mp_datatype != MACH_MP_SEMAPHORE)
8660+		return mach_msg_error(args, EINVAL);
8661+
8662+	ms = (struct mach_semaphore *)mr->mr_port->mp_data;
8663+	mach_semaphore_put(ms);
8664+	mach_right_put(mr, MACH_PORT_TYPE_REF_RIGHTS);
8665+
8666+	*msglen = sizeof(*rep);
8667+	mach_set_header(rep, req, *msglen);
8668+
8669+	rep->rep_retval = 0;
8670+
8671+	mach_set_trailer(rep, *msglen);
8672+
8673+	return 0;
8674+}
8675+
8676+void
8677+mach_semaphore_init(void)
8678+{
8679+	LIST_INIT(&mach_semaphore_list);
8680+	rw_init(&mach_semaphore_list_lock);
8681+	pool_init(&mach_semaphore_list_pool, sizeof (struct mach_semaphore),
8682+	    0, 0, 0, "mach_sem_pool", NULL, IPL_NONE);
8683+	pool_init(&mach_waiting_lwp_pool, sizeof (struct mach_waiting_lwp),
8684+	    0, 0, 0, "mach_waitp_pool", NULL, IPL_NONE);
8685+
8686+	return;
8687+}
8688+
8689+static struct mach_semaphore *
8690+mach_semaphore_get(int value, int policy)
8691+{
8692+	struct mach_semaphore *ms;
8693+
8694+	ms = (struct mach_semaphore *)pool_get(&mach_semaphore_list_pool,
8695+	    M_WAITOK);
8696+	ms->ms_value = value;
8697+	ms->ms_policy = policy;
8698+	TAILQ_INIT(&ms->ms_waiting);
8699+	rw_init(&ms->ms_lock);
8700+
8701+	rw_enter(&mach_semaphore_list_lock, RW_WRITER);
8702+	LIST_INSERT_HEAD(&mach_semaphore_list, ms, ms_list);
8703+	rw_exit(&mach_semaphore_list_lock);
8704+
8705+	return ms;
8706+}
8707+
8708+static void
8709+mach_semaphore_put(struct mach_semaphore *ms)
8710+{
8711+	struct mach_waiting_lwp *mwl;
8712+
8713+	rw_enter(&ms->ms_lock, RW_WRITER);
8714+	while ((mwl = TAILQ_FIRST(&ms->ms_waiting)) != NULL)
8715+		mach_waiting_lwp_put(mwl, ms, 0);
8716+	rw_exit(&ms->ms_lock);
8717+	rw_destroy(&ms->ms_lock);
8718+
8719+	rw_enter(&mach_semaphore_list_lock, RW_WRITER);
8720+	LIST_REMOVE(ms, ms_list);
8721+	rw_exit(&mach_semaphore_list_lock);
8722+
8723+	pool_put(&mach_semaphore_list_pool, ms);
8724+
8725+	return;
8726+}
8727+
8728+static struct mach_waiting_lwp *
8729+mach_waiting_lwp_get(struct lwp *l, struct mach_semaphore *ms)
8730+{
8731+	struct mach_waiting_lwp *mwl;
8732+
8733+	mwl = (struct mach_waiting_lwp *)pool_get(&mach_waiting_lwp_pool,
8734+	    M_WAITOK);
8735+	mwl->mwl_l = l;
8736+
8737+	rw_enter(&ms->ms_lock, RW_WRITER);
8738+	TAILQ_INSERT_TAIL(&ms->ms_waiting, mwl, mwl_list);
8739+	rw_exit(&ms->ms_lock);
8740+
8741+	return mwl;
8742+}
8743+
8744+static void
8745+mach_waiting_lwp_put(struct mach_waiting_lwp *mwl, struct mach_semaphore *ms, int locked)
8746+{
8747+	if (!locked)
8748+		rw_enter(&ms->ms_lock, RW_WRITER);
8749+	TAILQ_REMOVE(&ms->ms_waiting, mwl, mwl_list);
8750+	if (!locked)
8751+		rw_exit(&ms->ms_lock);
8752+	pool_put(&mach_waiting_lwp_pool, mwl);
8753+
8754+	return;
8755+}
8756+
8757+/*
8758+ * Cleanup after process exit. Need improvements, there
8759+ * can be some memory leaks here.
8760+ */
8761+void
8762+mach_semaphore_cleanup(struct lwp *l)
8763+{
8764+	struct mach_semaphore *ms;
8765+	struct mach_waiting_lwp *mwl;
8766+
8767+	rw_enter(&mach_semaphore_list_lock, RW_READER);
8768+	LIST_FOREACH(ms, &mach_semaphore_list, ms_list) {
8769+		rw_enter(&ms->ms_lock, RW_WRITER);
8770+		TAILQ_FOREACH(mwl, &ms->ms_waiting, mwl_list)
8771+			if (mwl->mwl_l == l) {
8772+				mach_waiting_lwp_put(mwl, ms, 0);
8773+				ms->ms_value++;
8774+				if (ms->ms_value >= 0)
8775+					wakeup(TAILQ_FIRST(&ms->ms_waiting));
8776+			}
8777+		rw_exit(&ms->ms_lock);
8778+	}
8779+	rw_exit(&mach_semaphore_list_lock);
8780+
8781+	return;
8782+}
8783+
8784+int
8785+mach_sys_semaphore_wait_signal_trap(struct lwp *l, const struct mach_sys_semaphore_wait_signal_trap_args *uap, register_t *retval)
8786+{
8787+	/* {
8788+		syscallarg(mach_port_name_t) wait_name;
8789+		syscallarg(mach_port_name_t) signal_name;
8790+	} */
8791+	struct mach_sys_semaphore_wait_trap_args cupwait;
8792+	struct mach_sys_semaphore_signal_trap_args cupsig;
8793+	int error;
8794+
8795+	SCARG(&cupsig, signal_name) = SCARG(uap, signal_name);
8796+	if ((error = mach_sys_semaphore_signal_trap(l, &cupsig, retval)) != 0)
8797+		return error;
8798+
8799+	SCARG(&cupwait, wait_name) = SCARG(uap, wait_name);
8800+	if ((error = mach_sys_semaphore_wait_trap(l, &cupwait, retval)) != 0)
8801+		return error;
8802+
8803+	return 0;
8804+}
8805+
8806+
8807+int
8808+mach_sys_semaphore_signal_thread_trap(struct lwp *l, const struct mach_sys_semaphore_signal_thread_trap_args *uap, register_t *retval)
8809+{
8810+	/* {
8811+		syscallarg(mach_port_name_t) signal_name;
8812+		syscallarg(mach_port_name_t) thread;
8813+	} */
8814+	struct mach_right *mr;
8815+	struct mach_semaphore *ms;
8816+	mach_port_t mn;
8817+	struct mach_waiting_lwp *mwl;
8818+	int unblocked = 0;
8819+
8820+	/*
8821+	 * Get the semaphore
8822+	 */
8823+	mn = SCARG(uap, signal_name);
8824+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
8825+		return EINVAL;
8826+
8827+	if (mr->mr_port->mp_datatype != MACH_MP_SEMAPHORE)
8828+		return EINVAL;
8829+
8830+	ms = (struct mach_semaphore *)mr->mr_port->mp_data;
8831+
8832+	/*
8833+	 * Get the thread, and check that it is waiting for our semaphore
8834+	 * If no thread was supplied, pick up the first one.
8835+	 */
8836+	mn = SCARG(uap, thread);
8837+	if (mn != 0) {
8838+		if ((mr = mach_right_check(mn, l,
8839+		    MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
8840+			return EINVAL;
8841+
8842+		if (mr->mr_port->mp_datatype != MACH_MP_LWP)
8843+			return EINVAL;
8844+
8845+		rw_enter(&ms->ms_lock, RW_WRITER);
8846+		TAILQ_FOREACH(mwl, &ms->ms_waiting, mwl_list)
8847+			if (mwl->mwl_l == (struct lwp *)mr->mr_port->mp_data)
8848+				break;
8849+	} else {
8850+		rw_enter(&ms->ms_lock, RW_WRITER);
8851+		mwl = TAILQ_FIRST(&ms->ms_waiting);
8852+	}
8853+
8854+	/*
8855+	 * No thread was awaiting for this semaphore,
8856+	 * exit without touching the semaphore.
8857+	 */
8858+	if (mwl == NULL) {
8859+		rw_exit(&ms->ms_lock);
8860+		return 0; /* Should be KERN_NOT_WAITING */
8861+	}
8862+
8863+	ms->ms_value++;
8864+	if (ms->ms_value >= 0)
8865+		unblocked = 1;
8866+	rw_exit(&ms->ms_lock);
8867+
8868+	if (unblocked != 0)
8869+		wakeup(mwl);
8870+
8871+	return 0;
8872+}
8873+
8874+
8875+int
8876+mach_sys_semaphore_signal_all_trap(struct lwp *l, const struct mach_sys_semaphore_signal_all_trap_args *uap, register_t *retval)
8877+{
8878+	/* {
8879+		syscallarg(mach_port_name_t) signal_name;
8880+	} */
8881+	struct mach_right *mr;
8882+	struct mach_semaphore *ms;
8883+	mach_port_t mn;
8884+	struct mach_waiting_lwp *mwl;
8885+	int unblocked = 0;
8886+
8887+	/*
8888+	 * Get the semaphore
8889+	 */
8890+	mn = SCARG(uap, signal_name);
8891+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
8892+		return EINVAL;
8893+
8894+	if (mr->mr_port->mp_datatype != MACH_MP_SEMAPHORE)
8895+		return EINVAL;
8896+
8897+	ms = (struct mach_semaphore *)mr->mr_port->mp_data;
8898+
8899+	rw_enter(&ms->ms_lock, RW_WRITER);
8900+	ms->ms_value++;
8901+	if (ms->ms_value >= 0)
8902+		unblocked = 1;
8903+
8904+	/*
8905+	 * Wakeup all threads sleeping on it.
8906+	 */
8907+	if (unblocked != 0)
8908+		TAILQ_FOREACH(mwl, &ms->ms_waiting, mwl_list)
8909+			wakeup(mwl);
8910+
8911+	rw_exit(&ms->ms_lock);
8912+
8913+	return 0;
8914+}
8915+
8916+
8917diff --git a/sys/compat/mach/mach_semaphore.h b/sys/compat/mach/mach_semaphore.h
8918new file mode 100644
8919index 0000000..337ca3e
8920--- /dev/null
8921+++ b/sys/compat/mach/mach_semaphore.h
8922@@ -0,0 +1,91 @@
8923+/*	$NetBSD: mach_semaphore.h,v 1.7 2008/04/28 20:23:44 martin Exp $ */
8924+
8925+/*-
8926+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
8927+ * All rights reserved.
8928+ *
8929+ * This code is derived from software contributed to The NetBSD Foundation
8930+ * by Emmanuel Dreyfus
8931+ *
8932+ * Redistribution and use in source and binary forms, with or without
8933+ * modification, are permitted provided that the following conditions
8934+ * are met:
8935+ * 1. Redistributions of source code must retain the above copyright
8936+ *    notice, this list of conditions and the following disclaimer.
8937+ * 2. Redistributions in binary form must reproduce the above copyright
8938+ *    notice, this list of conditions and the following disclaimer in the
8939+ *    documentation and/or other materials provided with the distribution.
8940+ *
8941+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
8942+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
8943+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
8944+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
8945+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8946+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
8947+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
8948+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
8949+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8950+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
8951+ * POSSIBILITY OF SUCH DAMAGE.
8952+ */
8953+
8954+#ifndef	_MACH_SEMAPHORE_H_
8955+#define	_MACH_SEMAPHORE_H_
8956+
8957+#include <sys/rwlock.h>
8958+#include <sys/queue.h>
8959+
8960+extern int mach_semaphore_cold;
8961+
8962+struct mach_waiting_lwp {
8963+	TAILQ_ENTRY(mach_waiting_lwp) mwl_list;
8964+	struct lwp *mwl_l;
8965+};
8966+
8967+struct mach_semaphore {
8968+	int ms_value;
8969+	int ms_policy;
8970+	LIST_ENTRY(mach_semaphore) ms_list;
8971+	TAILQ_HEAD(ms_waiting, mach_waiting_lwp) ms_waiting;
8972+	krwlock_t ms_lock;
8973+};
8974+
8975+/* semaphore_create */
8976+
8977+#define MACH_SYNC_POLICY_FIFO 0
8978+#define MACH_SYNC_POLICY_FIXED_PRIORITY 1
8979+
8980+typedef struct {
8981+	mach_msg_header_t req_msgh;
8982+	mach_ndr_record_t req_ndr;
8983+	int req_policy;
8984+	int req_value;
8985+} mach_semaphore_create_request_t;
8986+
8987+typedef struct {
8988+	mach_msg_header_t rep_msgh;
8989+	mach_msg_body_t rep_body;
8990+	mach_msg_port_descriptor_t rep_sem;
8991+	mach_msg_trailer_t rep_trailer;
8992+} mach_semaphore_create_reply_t;
8993+
8994+/* semaphore_destroy */
8995+
8996+typedef struct {
8997+	mach_msg_header_t req_msgh;
8998+	mach_msg_body_t req_body;
8999+	mach_msg_port_descriptor_t req_sem;
9000+} mach_semaphore_destroy_request_t;
9001+
9002+typedef struct {
9003+	mach_msg_header_t rep_msgh;
9004+	mach_ndr_record_t rep_ndr;
9005+	mach_kern_return_t rep_retval;
9006+	mach_msg_trailer_t rep_trailer;
9007+} mach_semaphore_destroy_reply_t;
9008+
9009+void mach_semaphore_init(void);
9010+void mach_semaphore_cleanup(struct lwp *);
9011+
9012+#endif /* _MACH_SEMAPHORE_H_ */
9013+
9014diff --git a/sys/compat/mach/mach_services.c b/sys/compat/mach/mach_services.c
9015new file mode 100644
9016index 0000000..bf10124
9017--- /dev/null
9018+++ b/sys/compat/mach/mach_services.c
9019@@ -0,0 +1,362 @@
9020+/* $NetBSD: mach_services.c,v 1.19 2009/01/13 22:33:10 pooka Exp $ */
9021+
9022+/*
9023+ * Mach services table.
9024+ *
9025+ * DO NOT EDIT -- this file is automatically generated.
9026+ * created from NetBSD: mach_services.master,v 1.13 2005/12/11 12:20:20 christos Exp
9027+ */
9028+
9029+#include <sys/cdefs.h>
9030+__KERNEL_RCSID(0, "$NetBSD: mach_services.c,v 1.19 2009/01/13 22:33:10 pooka Exp $");
9031+
9032+#include <sys/types.h>
9033+#include <sys/param.h>
9034+#include <compat/mach/mach_types.h>
9035+#include <compat/mach/mach_message.h>
9036+#include <compat/mach/mach_bootstrap.h>
9037+#include <compat/mach/mach_iokit.h>
9038+#include <compat/mach/mach_clock.h>
9039+#include <compat/mach/mach_host.h>
9040+#include <compat/mach/mach_port.h>
9041+#include <compat/mach/mach_task.h>
9042+#include <compat/mach/mach_thread.h>
9043+#include <compat/mach/mach_semaphore.h>
9044+#include <compat/mach/mach_notify.h>
9045+#include <compat/mach/mach_exception.h>
9046+#include <compat/mach/mach_vm.h>
9047+#include <compat/mach/mach_services.h>
9048+
9049+struct mach_service mach_services_table[] = {
9050+	{64, NULL, "obsolete notify_first", 0, 0},
9051+	{65, NULL, "notify_port_deleted", 0, 0},
9052+	{66, NULL, "obsolete notify_msg_accepted", 0, 0},
9053+	{67, NULL, "obsolete notify_ownership_rights", 0, 0},
9054+	{68, NULL, "obsolete notify_receive_rights", 0, 0},
9055+	{69, NULL, "notify_port_destroyed", 0, 0},
9056+	{70, NULL, "notify_port_no_senders", 0, 0},
9057+	{71, NULL, "notify_port_send_once", 0, 0},
9058+	{72, NULL, "notify_port_dead_name", 0, 0},
9059+	{200, mach_host_info, "host_info", sizeof(mach_host_info_request_t), sizeof(mach_host_info_reply_t)},
9060+	{201, NULL, "unimpl. host_kernel_version", 0, 0},
9061+	{202, mach_host_page_size, "host_page_size", sizeof(mach_host_page_size_request_t), sizeof(mach_host_page_size_reply_t)},
9062+	{203, NULL, "unimpl. memory_object_memory_entry", 0, 0},
9063+	{204, NULL, "unimpl. host_processor_info", 0, 0},
9064+	{205, mach_host_get_io_master, "host_get_io_master", sizeof(mach_host_get_io_master_request_t), sizeof(mach_host_get_io_master_reply_t)},
9065+	{206, mach_host_get_clock_service, "host_get_clock_service", sizeof(mach_host_get_clock_service_request_t), sizeof(mach_host_get_clock_service_reply_t)},
9066+	{207, NULL, "unimpl. kmod_get_info", 0, 0},
9067+	{208, NULL, "unimpl. host_zone_info", 0, 0},
9068+	{209, NULL, "unimpl. host_virtual_physical_table_info", 0, 0},
9069+	{210, NULL, "unimpl. host_ipc_hash_info", 0, 0},
9070+	{211, NULL, "unimpl. enable_bluebox", 0, 0},
9071+	{212, NULL, "unimpl. disable_bluebox", 0, 0},
9072+	{213, mach_processor_set_default, "processor_set_default", sizeof(mach_processor_set_default_request_t), sizeof(mach_processor_set_default_reply_t)},
9073+	{214, NULL, "unimpl. processor_set_create", 0, 0},
9074+	{215, NULL, "unimpl. memory_object_memory_entry_64", 0, 0},
9075+	{216, NULL, "unimpl. host_statistics", 0, 0},
9076+	{400, NULL, "unimpl. host_get_boot_info", 0, 0},
9077+	{401, NULL, "unimpl. host_reboot", 0, 0},
9078+	{402, NULL, "unimpl. host_priv_statistics", 0, 0},
9079+	{403, NULL, "unimpl. boostrap_register", 0, 0},
9080+	{404, mach_bootstrap_look_up, "bootstrap_look_up", sizeof(mach_bootstrap_look_up_request_t), sizeof(mach_bootstrap_look_up_reply_t)},
9081+	{405, NULL, "unimpl. thread_wire", 0, 0},
9082+	{406, NULL, "unimpl. vm_allocate_cpm", 0, 0},
9083+	{407, NULL, "unimpl. host_processors", 0, 0},
9084+	{408, NULL, "unimpl. host_get_clock_control", 0, 0},
9085+	{409, NULL, "unimpl. kmod_create", 0, 0},
9086+	{410, NULL, "unimpl. kmod_destroy", 0, 0},
9087+	{411, NULL, "unimpl. kmod_control", 0, 0},
9088+	{412, NULL, "unimpl. host_get_special_port", 0, 0},
9089+	{413, NULL, "unimpl. host_set_special_port", 0, 0},
9090+	{414, NULL, "unimpl. host_set_exception_ports", 0, 0},
9091+	{415, NULL, "unimpl. host_get_exception_ports", 0, 0},
9092+	{416, NULL, "unimpl. host_swap_exception_ports", 0, 0},
9093+	{417, NULL, "unimpl. host_load_symbol_table", 0, 0},
9094+	{418, NULL, "unimpl. task_swappable", 0, 0},
9095+	{419, NULL, "unimpl. host_processor_sets", 0, 0},
9096+	{420, mach_host_processor_set_priv, "host_processor_set_priv", sizeof(mach_host_processor_set_priv_request_t), sizeof(mach_host_processor_set_priv_reply_t)},
9097+	{421, NULL, "unimpl. set_dp_control_port", 0, 0},
9098+	{422, NULL, "unimpl. get_dp_control_port", 0, 0},
9099+	{423, NULL, "unimpl. host_set_UNDServer", 0, 0},
9100+	{424, NULL, "unimpl. host_get_UNDServer", 0, 0},
9101+	{600, NULL, "unimpl. host_security_create_task_token", 0, 0},
9102+	{601, NULL, "unimpl. host_security_set_task_token", 0, 0},
9103+	{1000, mach_clock_get_time, "clock_get_time", sizeof(mach_clock_get_time_request_t), sizeof(mach_clock_get_time_reply_t)},
9104+	{1001, NULL, "unimpl. clock_get_attributes", 0, 0},
9105+	{1002, NULL, "unimpl. clock_alarm", 0, 0},
9106+	{1200, NULL, "unimpl. clock_set_time", 0, 0},
9107+	{1201, NULL, "unimpl. clock_set_attributes", 0, 0},
9108+	{2000, NULL, "unimpl. memory_object_get_attributes", 0, 0},
9109+	{2001, NULL, "unimpl. memory_object_change_attributes", 0, 0},
9110+	{2002, NULL, "unimpl. memory_object_synchronize_completed", 0, 0},
9111+	{2003, NULL, "unimpl. memory_object_lock_request", 0, 0},
9112+	{2004, NULL, "unimpl. memory_object_destroy", 0, 0},
9113+	{2005, NULL, "unimpl. memory_object_upl_request", 0, 0},
9114+	{2006, NULL, "unimpl. memory_object_super_upl_request", 0, 0},
9115+	{2007, NULL, "unimpl. memory_object_page_op", 0, 0},
9116+	{2008, NULL, "unimpl. memory_object_recover_named", 0, 0},
9117+	{2009, NULL, "unimpl. memory_object_release_name", 0, 0},
9118+	{2050, NULL, "unimpl. upl_abort", 0, 0},
9119+	{2051, NULL, "unimpl. upl_abort_range", 0, 0},
9120+	{2052, NULL, "unimpl. upl_commit", 0, 0},
9121+	{2053, NULL, "unimpl. upl_commit_range", 0, 0},
9122+	{2200, NULL, "unimpl. memory_object_init", 0, 0},
9123+	{2201, NULL, "unimpl. memory_object_terminate", 0, 0},
9124+	{2202, NULL, "unimpl. memory_object_data_request", 0, 0},
9125+	{2203, NULL, "unimpl. memory_object_data_return", 0, 0},
9126+	{2204, NULL, "unimpl. memory_object_data_initialize", 0, 0},
9127+	{2205, NULL, "unimpl. memory_object_data_unlock", 0, 0},
9128+	{2206, NULL, "unimpl. memory_object_synchronize", 0, 0},
9129+	{2207, NULL, "unimpl. memory_object_unmap", 0, 0},
9130+	{2250, NULL, "unimpl. memory_object_create", 0, 0},
9131+	{2275, NULL, "unimpl. default_pager_object_create", 0, 0},
9132+	{2276, NULL, "unimpl. default_pager_info", 0, 0},
9133+	{2277, NULL, "unimpl. default_pager_objects", 0, 0},
9134+	{2278, NULL, "unimpl. default_pager_object_pages", 0, 0},
9135+	{2279, NULL, "unimpl. default_pager_backing_store_create", 0, 0},
9136+	{2280, NULL, "unimpl. default_pager_backing_store_delete", 0, 0},
9137+	{2281, NULL, "unimpl. default_pager_add_segment", 0, 0},
9138+	{2282, NULL, "unimpl. default_pager_backing_store_info", 0, 0},
9139+	{2283, NULL, "unimpl. default_pager_add_file", 0, 0},
9140+	{2284, NULL, "unimpl. default_pager_triggers", 0, 0},
9141+	{2295, NULL, "unimpl. default_pager_space_alert", 0, 0},
9142+	{2401, NULL, "exception_raise", 0, 0},
9143+	{2402, NULL, "exception_raise_state", 0, 0},
9144+	{2403, NULL, "exception_raise_state_identity", 0, 0},
9145+	{2450, NULL, "unimpl. samples", 0, 0},
9146+	{2451, NULL, "unimpl. notices", 0, 0},
9147+	{2501, mach_exception_raise, "exception_raise", sizeof(mach_exception_raise_request_t), sizeof(mach_exception_raise_reply_t)},
9148+	{2502, mach_exception_raise_state, "exception_raise_state", sizeof(mach_exception_raise_state_request_t), sizeof(mach_exception_raise_state_reply_t)},
9149+	{2503, mach_exception_raise_state_identity, "exception_raise_state_identity", sizeof(mach_exception_raise_state_identity_request_t), sizeof(mach_exception_raise_state_identity_reply_t)},
9150+	{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)},
9151+	{2801, mach_io_object_conforms_to, "io_object_conforms_to", sizeof(mach_io_object_conforms_to_request_t), sizeof(mach_io_object_conforms_to_reply_t)},
9152+	{2802, mach_io_iterator_next, "io_iterator_next", sizeof(mach_io_iterator_next_request_t), sizeof(mach_io_iterator_next_reply_t)},
9153+	{2803, mach_io_iterator_reset, "io_iterator_reset", sizeof(mach_io_iterator_reset_request_t), sizeof(mach_io_iterator_reset_reply_t)},
9154+	{2804, mach_io_service_get_matching_services, "io_service_get_matching_services", sizeof(mach_io_service_get_matching_services_request_t), sizeof(mach_io_service_get_matching_services_reply_t)},
9155+	{2805, mach_io_registry_entry_get_property, "io_registry_entry_get_property", sizeof(mach_io_registry_entry_get_property_request_t), sizeof(mach_io_registry_entry_get_property_reply_t)},
9156+	{2806, NULL, "unimpl. io_registry_create_iterator", 0, 0},
9157+	{2807, NULL, "unimpl. io_registry_iterator_enter_entry", 0, 0},
9158+	{2808, NULL, "unimpl. io_registry_iterator_exit_entry", 0, 0},
9159+	{2809, mach_io_registry_entry_from_path, "io_registry_entry_from_path", sizeof(mach_io_registry_entry_from_path_request_t), sizeof(mach_io_registry_entry_from_path_reply_t)},
9160+	{2810, NULL, "unimpl. io_registry_entry_get_name", 0, 0},
9161+	{2811, mach_io_registry_entry_get_properties, "io_registry_entry_get_properties", sizeof(mach_io_registry_entry_get_properties_request_t), sizeof(mach_io_registry_entry_get_properties_reply_t)},
9162+	{2812, NULL, "unimpl. io_registry_entry_get_property_bytes", 0, 0},
9163+	{2813, mach_io_registry_entry_get_child_iterator, "io_registry_entry_get_child_iterator", sizeof(mach_io_registry_entry_get_child_iterator_request_t), sizeof(mach_io_registry_entry_get_child_iterator_reply_t)},
9164+	{2814, mach_io_registry_entry_get_parent_iterator, "io_registry_entry_get_parent_iterator", sizeof(mach_io_registry_entry_get_parent_iterator_request_t), sizeof(mach_io_registry_entry_get_parent_iterator_reply_t)},
9165+	{2815, mach_io_service_open, "io_service_open", sizeof(mach_io_service_open_request_t), sizeof(mach_io_service_open_reply_t)},
9166+	{2816, mach_io_service_close, "io_service_close", sizeof(mach_io_service_close_request_t), sizeof(mach_io_service_close_reply_t)},
9167+	{2817, mach_io_connect_get_service, "io_connect_get_service", sizeof(mach_io_connect_get_service_request_t), sizeof(mach_io_connect_get_service_reply_t)},
9168+	{2818, mach_io_connect_set_notification_port, "io_connect_set_notification_port", sizeof(mach_io_connect_set_notification_port_request_t), sizeof(mach_io_connect_set_notification_port_reply_t)},
9169+	{2819, mach_io_connect_map_memory, "io_connect_map_memory", sizeof(mach_io_connect_map_memory_request_t), sizeof(mach_io_connect_map_memory_reply_t)},
9170+	{2820, mach_io_connect_add_client, "io_connect_add_client", sizeof(mach_io_connect_add_client_request_t), sizeof(mach_io_connect_add_client_reply_t)},
9171+	{2821, mach_io_connect_set_properties, "io_connect_set_properties", sizeof(mach_io_connect_set_properties_request_t), sizeof(mach_io_connect_set_properties_reply_t)},
9172+	{2822, mach_io_connect_method_scalari_scalaro, "io_connect_method_scalari_scalaro", sizeof(mach_io_connect_method_scalari_scalaro_request_t), sizeof(mach_io_connect_method_scalari_scalaro_reply_t)},
9173+	{2823, mach_io_connect_method_scalari_structo, "io_connect_method_scalari_structo", sizeof(mach_io_connect_method_scalari_structo_request_t), sizeof(mach_io_connect_method_scalari_structo_reply_t)},
9174+	{2824, mach_io_connect_method_scalari_structi, "io_connect_method_scalari_structi", sizeof(mach_io_connect_method_scalari_structi_request_t), sizeof(mach_io_connect_method_scalari_structi_reply_t)},
9175+	{2825, mach_io_connect_method_structi_structo, "io_connect_method_structi_structo", sizeof(mach_io_connect_method_structi_structo_request_t), sizeof(mach_io_connect_method_structi_structo_reply_t)},
9176+	{2826, mach_io_registry_entry_get_path, "io_registry_entry_get_path", sizeof(mach_io_registry_entry_get_path_request_t), sizeof(mach_io_registry_entry_get_path_reply_t)},
9177+	{2827, mach_io_registry_get_root_entry, "io_registry_get_root_entry", sizeof(mach_io_registry_get_root_entry_request_t), sizeof(mach_io_registry_get_root_entry_reply_t)},
9178+	{2828, NULL, "unimpl. io_registry_entry_set_properties", 0, 0},
9179+	{2829, NULL, "unimpl. io_registry_entry_in_plane", 0, 0},
9180+	{2830, NULL, "unimpl. io_object_get_retain_count", 0, 0},
9181+	{2831, NULL, "unimpl. io_service_get_busy_state", 0, 0},
9182+	{2832, NULL, "unimpl. io_service_wait_quiet", 0, 0},
9183+	{2833, mach_io_registry_entry_create_iterator, "io_registry_entry_create_iterator", sizeof(mach_io_registry_entry_create_iterator_request_t), sizeof(mach_io_registry_entry_create_iterator_reply_t)},
9184+	{2834, NULL, "unimpl. io_iterator_is_valid", 0, 0},
9185+	{2835, NULL, "unimpl. io_make_matching", 0, 0},
9186+	{2836, NULL, "unimpl. io_catalog_send_data", 0, 0},
9187+	{2837, NULL, "unimpl. io_catalog_terminate", 0, 0},
9188+	{2838, NULL, "unimpl. io_catalog_get_data", 0, 0},
9189+	{2839, NULL, "unimpl. io_catalog_get_gen_count", 0, 0},
9190+	{2840, NULL, "unimpl. io_catalog_module_loaded", 0, 0},
9191+	{2841, NULL, "unimpl. io_catalog_reset", 0, 0},
9192+	{2842, NULL, "unimpl. io_service_request_probe", 0, 0},
9193+	{2843, mach_io_registry_entry_get_name_in_plane, "io_registry_entry_get_name_in_plane", sizeof(mach_io_registry_entry_get_name_in_plane_request_t), sizeof(mach_io_registry_entry_get_name_in_plane_reply_t)},
9194+	{2844, NULL, "unimpl. io_service_match_property_table", 0, 0},
9195+	{2845, NULL, "unimpl. io_async_method_scalari_scalaro", 0, 0},
9196+	{2846, NULL, "unimpl. io_async_method_scalari_structo", 0, 0},
9197+	{2847, NULL, "unimpl. io_async_method_scalari_structi", 0, 0},
9198+	{2848, NULL, "unimpl. io_async_method_structi_structo", 0, 0},
9199+	{2849, NULL, "unimpl. io_service_add_notification", 0, 0},
9200+	{2850, mach_io_service_add_interest_notification, "io_service_add_interest_notification", sizeof(mach_io_service_add_interest_notification_request_t), sizeof(mach_io_service_add_interest_notification_reply_t)},
9201+	{2851, NULL, "unimpl. io_service_acknowledge_notification", 0, 0},
9202+	{2852, NULL, "unimpl. io_connect_get_notification_semaphore", 0, 0},
9203+	{2853, NULL, "unimpl. io_connect_unmap_memory", 0, 0},
9204+	{2854, mach_io_registry_entry_get_location_in_plane, "io_registry_entry_get_location_in_plane", sizeof(mach_io_registry_entry_get_location_in_plane_request_t), sizeof(mach_io_registry_entry_get_location_in_plane_reply_t)},
9205+	{2855, NULL, "unimpl. io_registry_entry_get_property_recursively", 0, 0},
9206+	{3000, NULL, "unimpl. processor_start", 0, 0},
9207+	{3001, NULL, "unimpl. processor_exit", 0, 0},
9208+	{3002, NULL, "unimpl. processor_info", 0, 0},
9209+	{3003, NULL, "unimpl. processor_control", 0, 0},
9210+	{3004, NULL, "unimpl. processor_assign", 0, 0},
9211+	{3005, NULL, "unimpl. processor_get_assignment", 0, 0},
9212+	{3200, NULL, "unimpl. port_names", 0, 0},
9213+	{3201, mach_port_type, "port_type", sizeof(mach_port_type_request_t), sizeof(mach_port_type_reply_t)},
9214+	{3202, NULL, "unimpl. port_rename", 0, 0},
9215+	{3203, NULL, "unimpl. port_allocate_name", 0, 0},
9216+	{3204, mach_port_allocate, "port_allocate", sizeof(mach_port_allocate_request_t), sizeof(mach_port_allocate_reply_t)},
9217+	{3205, mach_port_destroy, "port_destroy", sizeof(mach_port_destroy_request_t), sizeof(mach_port_destroy_reply_t)},
9218+	{3206, mach_port_deallocate, "port_deallocate", sizeof(mach_port_deallocate_request_t), sizeof(mach_port_deallocate_reply_t)},
9219+	{3207, mach_port_get_refs, "port_get_refs", sizeof(mach_port_get_refs_request_t), sizeof(mach_port_get_refs_reply_t)},
9220+	{3208, mach_port_mod_refs, "port_mod_refs", sizeof(mach_port_mod_refs_request_t), sizeof(mach_port_mod_refs_reply_t)},
9221+	{3210, NULL, "unimpl. port_set_mscount", 0, 0},
9222+	{3211, NULL, "unimpl. port_get_set_status", 0, 0},
9223+	{3212, mach_port_move_member, "port_move_member", sizeof(mach_port_move_member_request_t), sizeof(mach_port_move_member_reply_t)},
9224+	{3213, mach_port_request_notification, "port_request_notification", sizeof(mach_port_request_notification_request_t), sizeof(mach_port_request_notification_reply_t)},
9225+	{3214, mach_port_insert_right, "port_insert_right", sizeof(mach_port_insert_right_request_t), sizeof(mach_port_insert_right_reply_t)},
9226+	{3215, NULL, "unimpl. port_extract_right", 0, 0},
9227+	{3216, NULL, "unimpl. port_set_seqno", 0, 0},
9228+	{3217, mach_port_get_attributes, "port_get_attributes", sizeof(mach_port_get_attributes_request_t), sizeof(mach_port_get_attributes_reply_t)},
9229+	{3218, mach_port_set_attributes, "port_set_attributes", sizeof(mach_port_set_attributes_request_t), sizeof(mach_port_set_attributes_reply_t)},
9230+	{3219, NULL, "unimpl. port_allocate_qos", 0, 0},
9231+	{3220, NULL, "unimpl. port_allocate_full", 0, 0},
9232+	{3221, NULL, "unimpl. task_set_port_space", 0, 0},
9233+	{3222, NULL, "unimpl. port_get_srights", 0, 0},
9234+	{3223, NULL, "unimpl. port_space_info", 0, 0},
9235+	{3224, NULL, "unimpl. port_dnrequest_info", 0, 0},
9236+	{3225, NULL, "unimpl. port_kernel_object", 0, 0},
9237+	{3226, mach_port_insert_member, "port_insert_member", sizeof(mach_port_insert_member_request_t), sizeof(mach_port_insert_member_reply_t)},
9238+	{3227, NULL, "unimpl. port_extract_member", 0, 0},
9239+	{3400, NULL, "unimpl. task_create", 0, 0},
9240+	{3401, mach_task_terminate, "task_terminate", sizeof(mach_task_terminate_request_t), sizeof(mach_task_terminate_reply_t)},
9241+	{3402, mach_task_threads, "task_threads", sizeof(mach_task_threads_request_t), sizeof(mach_task_threads_reply_t)},
9242+	{3403, NULL, "unimpl. ports_register", 0, 0},
9243+	{3404, mach_ports_lookup, "ports_lookup", sizeof(mach_ports_lookup_request_t), sizeof(mach_ports_lookup_reply_t)},
9244+	{3405, mach_task_info, "task_info", sizeof(mach_task_info_request_t), sizeof(mach_task_info_reply_t)},
9245+	{3406, NULL, "unimpl. task_set_info", 0, 0},
9246+	{3407, mach_task_suspend, "task_suspend", sizeof(mach_task_suspend_request_t), sizeof(mach_task_suspend_reply_t)},
9247+	{3408, mach_task_resume, "task_resume", sizeof(mach_task_resume_request_t), sizeof(mach_task_resume_reply_t)},
9248+	{3409, mach_task_get_special_port, "task_get_special_port", sizeof(mach_task_get_special_port_request_t), sizeof(mach_task_get_special_port_reply_t)},
9249+	{3410, mach_task_set_special_port, "task_set_special_port", sizeof(mach_task_set_special_port_request_t), sizeof(mach_task_set_special_port_reply_t)},
9250+	{3411, NULL, "unimpl. thread_create", 0, 0},
9251+	{3412, mach_thread_create_running, "thread_create_running", sizeof(mach_thread_create_running_request_t), sizeof(mach_thread_create_running_reply_t)},
9252+	{3413, mach_task_set_exception_ports, "task_set_exception_ports", sizeof(mach_task_set_exception_ports_request_t), sizeof(mach_task_set_exception_ports_reply_t)},
9253+	{3414, mach_task_get_exception_ports, "task_get_exception_ports", sizeof(mach_task_get_exception_ports_request_t), sizeof(mach_task_get_exception_ports_reply_t)},
9254+	{3415, NULL, "unimpl. task_swap_exception_ports", 0, 0},
9255+	{3416, NULL, "unimpl. lock_set_create", 0, 0},
9256+	{3417, NULL, "unimpl. lock_set_destroy", 0, 0},
9257+	{3418, mach_semaphore_create, "semaphore_create", sizeof(mach_semaphore_create_request_t), sizeof(mach_semaphore_create_reply_t)},
9258+	{3419, mach_semaphore_destroy, "semaphore_destroy", sizeof(mach_semaphore_destroy_request_t), sizeof(mach_semaphore_destroy_reply_t)},
9259+	{3420, NULL, "unimpl. task_policy_set", 0, 0},
9260+	{3421, NULL, "unimpl. task_policy_get", 0, 0},
9261+	{3422, NULL, "unimpl. task_sample", 0, 0},
9262+	{3423, NULL, "unimpl. task_policy", 0, 0},
9263+	{3424, NULL, "unimpl. task_set_emulation", 0, 0},
9264+	{3425, NULL, "unimpl. task_get_emulation_vector", 0, 0},
9265+	{3426, NULL, "unimpl. task_set_emulation_vector", 0, 0},
9266+	{3427, NULL, "unimpl. task_set_ras_pc", 0, 0},
9267+	{3428, NULL, "unimpl. kernel_task_create", 0, 0},
9268+	{3429, NULL, "unimpl. task_assign", 0, 0},
9269+	{3430, NULL, "unimpl. task_assign_default", 0, 0},
9270+	{3431, NULL, "unimpl. task_get_assignment", 0, 0},
9271+	{3432, NULL, "unimpl. task_set_policy", 0, 0},
9272+	{3600, NULL, "unimpl. thread_terminate", 0, 0},
9273+	{3601, NULL, "unimpl. act_get_state", 0, 0},
9274+	{3602, NULL, "unimpl. act_set_state", 0, 0},
9275+	{3603, mach_thread_get_state, "thread_get_state", sizeof(mach_thread_get_state_request_t), sizeof(mach_thread_get_state_reply_t)},
9276+	{3604, mach_thread_set_state, "thread_set_state", sizeof(mach_thread_set_state_request_t), sizeof(mach_thread_set_state_reply_t)},
9277+	{3605, mach_thread_suspend, "thread_suspend", sizeof(mach_thread_suspend_request_t), sizeof(mach_thread_suspend_reply_t)},
9278+	{3606, mach_thread_resume, "thread_resume", sizeof(mach_thread_resume_request_t), sizeof(mach_thread_resume_reply_t)},
9279+	{3607, mach_thread_abort, "thread_abort", sizeof(mach_thread_abort_request_t), sizeof(mach_thread_abort_reply_t)},
9280+	{3608, NULL, "unimpl. thread_abort_safely", 0, 0},
9281+	{3609, NULL, "unimpl. thread_depress_abort", 0, 0},
9282+	{3610, NULL, "unimpl. thread_get_special_port", 0, 0},
9283+	{3611, NULL, "unimpl. thread_set_special_port", 0, 0},
9284+	{3612, mach_thread_info, "thread_info", sizeof(mach_thread_info_request_t), sizeof(mach_thread_info_reply_t)},
9285+	{3613, NULL, "unimpl. thread_set_exception_ports", 0, 0},
9286+	{3614, NULL, "unimpl. thread_get_exception_ports", 0, 0},
9287+	{3615, NULL, "unimpl. thread_swap_exception_ports", 0, 0},
9288+	{3616, mach_thread_policy, "thread_policy", sizeof(mach_thread_policy_request_t), sizeof(mach_thread_policy_reply_t)},
9289+	{3617, NULL, "unimpl. thread_policy_set", 0, 0},
9290+	{3618, NULL, "unimpl. thread_policy_get", 0, 0},
9291+	{3619, NULL, "unimpl. thread_sample", 0, 0},
9292+	{3620, NULL, "unimpl. etap_trace_thread", 0, 0},
9293+	{3621, NULL, "unimpl. thread_assign", 0, 0},
9294+	{3622, NULL, "unimpl. thread_assign_default", 0, 0},
9295+	{3623, NULL, "unimpl. thread_get_assignment", 0, 0},
9296+	{3624, mach_thread_set_policy, "thread_set_policy", sizeof(mach_thread_set_policy_request_t), sizeof(mach_thread_set_policy_reply_t)},
9297+	{3800, mach_vm_region, "vm_region", sizeof(mach_vm_region_request_t), sizeof(mach_vm_region_reply_t)},
9298+	{3801, mach_vm_allocate, "vm_allocate", sizeof(mach_vm_allocate_request_t), sizeof(mach_vm_allocate_reply_t)},
9299+	{3802, mach_vm_deallocate, "vm_deallocate", sizeof(mach_vm_deallocate_request_t), sizeof(mach_vm_deallocate_reply_t)},
9300+	{3803, mach_vm_protect, "vm_protect", sizeof(mach_vm_protect_request_t), sizeof(mach_vm_protect_reply_t)},
9301+	{3804, mach_vm_inherit, "vm_inherit", sizeof(mach_vm_inherit_request_t), sizeof(mach_vm_inherit_reply_t)},
9302+	{3805, mach_vm_read, "vm_read", sizeof(mach_vm_read_request_t), sizeof(mach_vm_read_reply_t)},
9303+	{3806, NULL, "unimpl. vm_read_list", 0, 0},
9304+	{3807, mach_vm_write, "vm_write", sizeof(mach_vm_write_request_t), sizeof(mach_vm_write_reply_t)},
9305+	{3808, mach_vm_copy, "vm_copy", sizeof(mach_vm_copy_request_t), sizeof(mach_vm_copy_reply_t)},
9306+	{3809, NULL, "unimpl. vm_read_overwrite", 0, 0},
9307+	{3810, mach_vm_msync, "vm_msync", sizeof(mach_vm_msync_request_t), sizeof(mach_vm_msync_reply_t)},
9308+	{3811, NULL, "unimpl. vm_behavior_set", 0, 0},
9309+	{3812, mach_vm_map, "vm_map", sizeof(mach_vm_map_request_t), sizeof(mach_vm_map_reply_t)},
9310+	{3813, mach_vm_machine_attribute, "vm_machine_attribute", sizeof(mach_vm_machine_attribute_request_t), sizeof(mach_vm_machine_attribute_reply_t)},
9311+	{3814, NULL, "unimpl. vm_remap", 0, 0},
9312+	{3815, NULL, "unimpl. task_wire", 0, 0},
9313+	{3816, NULL, "unimpl. make_memory_entry", 0, 0},
9314+	{3817, NULL, "unimpl. vm_map_page_query", 0, 0},
9315+	{3818, NULL, "unimpl. vm_region_info", 0, 0},
9316+	{3819, NULL, "unimpl. vm_mapped_pages_info", 0, 0},
9317+	{3820, NULL, "unimpl. vm_region_object_create", 0, 0},
9318+	{3821, NULL, "unimpl. vm_region_recurse", 0, 0},
9319+	{3822, NULL, "unimpl. vm_region_recurse_64", 0, 0},
9320+	{3823, NULL, "unimpl. vm_region_info_64", 0, 0},
9321+	{3824, mach_vm_region_64, "vm_region_64", sizeof(mach_vm_region_64_request_t), sizeof(mach_vm_region_64_reply_t)},
9322+	{3825, mach_make_memory_entry_64, "make_memory_entry_64", sizeof(mach_make_memory_entry_64_request_t), sizeof(mach_make_memory_entry_64_reply_t)},
9323+	{3826, NULL, "unimpl. vm_map_64", 0, 0},
9324+	{3827, NULL, "unimpl. vm_map_get_upl", 0, 0},
9325+	{3828, NULL, "unimpl. vm_upl_map", 0, 0},
9326+	{3829, NULL, "unimpl. vm_upl_unmap", 0, 0},
9327+	{4000, NULL, "unimpl. processor_set_statistics", 0, 0},
9328+	{4001, NULL, "unimpl. processor_set_destroy", 0, 0},
9329+	{4002, NULL, "unimpl. processor_set_max_priority", 0, 0},
9330+	{4003, NULL, "unimpl. processor_set_policy_enable", 0, 0},
9331+	{4004, NULL, "unimpl. processor_set_policy_disable", 0, 0},
9332+	{4005, NULL, "unimpl. processor_set_tasks", 0, 0},
9333+	{4006, NULL, "unimpl. processor_set_threads", 0, 0},
9334+	{4007, NULL, "unimpl. processor_set_policy_control", 0, 0},
9335+	{4008, NULL, "unimpl. processor_set_stack_usage", 0, 0},
9336+	{4009, NULL, "unimpl. processor_set_info", 0, 0},
9337+	{5000, NULL, "unimpl. ledger_create", 0, 0},
9338+	{5001, NULL, "unimpl. ledger_terminate", 0, 0},
9339+	{5002, NULL, "unimpl. ledger_transfer", 0, 0},
9340+	{5003, NULL, "unimpl. ledger_read", 0, 0},
9341+	{6000, NULL, "unimpl. und_execute_rpc", 0, 0},
9342+	{6001, NULL, "unimpl. und_display_notice_from_bundle_rpc", 0, 0},
9343+	{6002, NULL, "unimpl. und_display_alert_from_bundle_rpc", 0, 0},
9344+	{6003, NULL, "unimpl. und_display_custom_from_bundle_rpc", 0, 0},
9345+	{6004, NULL, "unimpl. und_display_custom_from_dictionary_rpc", 0, 0},
9346+	{6005, NULL, "unimpl. und_cancel_notification_rpc", 0, 0},
9347+	{6006, NULL, "unimpl. und_display_notice_simple_rpc", 0, 0},
9348+	{6007, NULL, "unimpl. und_display_alert_simple_rpc", 0, 0},
9349+	{6200, NULL, "unimpl. und_alert_completed_with_result_rpc", 0, 0},
9350+	{6201, NULL, "unimpl. und_notification_created_rpc(", 0, 0},
9351+	{555001, NULL, "unimpl. task_set_child_node", 0, 0},
9352+	{555002, NULL, "unimpl. norma_node_self", 0, 0},
9353+	{555005, NULL, "unimpl. norma_task_clone", 0, 0},
9354+	{555006, NULL, "unimpl. norma_task_create", 0, 0},
9355+	{555007, NULL, "unimpl. norma_get_special_port", 0, 0},
9356+	{555008, NULL, "unimpl. norma_set_special_port", 0, 0},
9357+	{555009, NULL, "unimpl. norma_task_teleport", 0, 0},
9358+	{555012, NULL, "unimpl. norma_port_location_hint", 0, 0},
9359+	{617000, NULL, "unimpl. lock_acquire", 0, 0},
9360+	{617001, NULL, "unimpl. lock_release", 0, 0},
9361+	{617002, NULL, "unimpl. lock_try", 0, 0},
9362+	{617003, NULL, "unimpl. lock_make_stable", 0, 0},
9363+	{617004, NULL, "unimpl. lock_handoff", 0, 0},
9364+	{617005, NULL, "unimpl. lock_handoff_accept", 0, 0},
9365+	{617005, NULL, "unimpl. lock_set_create", 0, 0},
9366+	{617006, NULL, "unimpl. lock_set_destroy", 0, 0},
9367+	{617007, NULL, "unimpl. lock_acquire", 0, 0},
9368+	{617008, NULL, "unimpl. lock_release", 0, 0},
9369+	{617009, NULL, "unimpl. lock_try", 0, 0},
9370+	{617010, NULL, "unimpl. lock_make_stable", 0, 0},
9371+	{617011, NULL, "unimpl. lock_handoff", 0, 0},
9372+	{617012, NULL, "unimpl. lock_handoff_accept", 0, 0},
9373+	{617200, NULL, "unimpl. semaphore_signal", 0, 0},
9374+	{617201, NULL, "unimpl. semaphore_signal_all", 0, 0},
9375+	{617202, NULL, "unimpl. semaphore_wait", 0, 0},
9376+	{617203, NULL, "unimpl. semaphore_signal_thread", 0, 0},
9377+	{617204, NULL, "unimpl. semaphore_timedwait", 0, 0},
9378+	{617205, NULL, "unimpl. semaphore_wait_signal", 0, 0},
9379+	{617206, NULL, "unimpl. semaphore_timedwait_signal", 0, 0},
9380+	{0, NULL, NULL, 0, 0}
9381+};
9382diff --git a/sys/compat/mach/mach_services.h b/sys/compat/mach/mach_services.h
9383new file mode 100644
9384index 0000000..4894a3a
9385--- /dev/null
9386+++ b/sys/compat/mach/mach_services.h
9387@@ -0,0 +1,99 @@
9388+/* $NetBSD: mach_services.h,v 1.19 2009/01/13 22:33:10 pooka Exp $ */
9389+
9390+/*
9391+ * Mach services prototypes.
9392+ *
9393+ * DO NOT EDIT -- this file is automatically generated.
9394+ * created from NetBSD: mach_services.master,v 1.13 2005/12/11 12:20:20 christos Exp
9395+ */
9396+
9397+#include <sys/cdefs.h>
9398+__KERNEL_RCSID(0, "$NetBSD: mach_services.h,v 1.19 2009/01/13 22:33:10 pooka Exp $");
9399+
9400+#include <compat/mach/mach_types.h>
9401+#include <compat/mach/mach_message.h>
9402+
9403+int mach_host_info(struct mach_trap_args *);
9404+int mach_host_page_size(struct mach_trap_args *);
9405+int mach_host_get_io_master(struct mach_trap_args *);
9406+int mach_host_get_clock_service(struct mach_trap_args *);
9407+int mach_processor_set_default(struct mach_trap_args *);
9408+int mach_bootstrap_look_up(struct mach_trap_args *);
9409+int mach_host_processor_set_priv(struct mach_trap_args *);
9410+int mach_clock_get_time(struct mach_trap_args *);
9411+int mach_exception_raise(struct mach_trap_args *);
9412+int mach_exception_raise_state(struct mach_trap_args *);
9413+int mach_exception_raise_state_identity(struct mach_trap_args *);
9414+int mach_io_object_get_class(struct mach_trap_args *);
9415+int mach_io_object_conforms_to(struct mach_trap_args *);
9416+int mach_io_iterator_next(struct mach_trap_args *);
9417+int mach_io_iterator_reset(struct mach_trap_args *);
9418+int mach_io_service_get_matching_services(struct mach_trap_args *);
9419+int mach_io_registry_entry_get_property(struct mach_trap_args *);
9420+int mach_io_registry_entry_from_path(struct mach_trap_args *);
9421+int mach_io_registry_entry_get_properties(struct mach_trap_args *);
9422+int mach_io_registry_entry_get_child_iterator(struct mach_trap_args *);
9423+int mach_io_registry_entry_get_parent_iterator(struct mach_trap_args *);
9424+int mach_io_service_open(struct mach_trap_args *);
9425+int mach_io_service_close(struct mach_trap_args *);
9426+int mach_io_connect_get_service(struct mach_trap_args *);
9427+int mach_io_connect_set_notification_port(struct mach_trap_args *);
9428+int mach_io_connect_map_memory(struct mach_trap_args *);
9429+int mach_io_connect_add_client(struct mach_trap_args *);
9430+int mach_io_connect_set_properties(struct mach_trap_args *);
9431+int mach_io_connect_method_scalari_scalaro(struct mach_trap_args *);
9432+int mach_io_connect_method_scalari_structo(struct mach_trap_args *);
9433+int mach_io_connect_method_scalari_structi(struct mach_trap_args *);
9434+int mach_io_connect_method_structi_structo(struct mach_trap_args *);
9435+int mach_io_registry_entry_get_path(struct mach_trap_args *);
9436+int mach_io_registry_get_root_entry(struct mach_trap_args *);
9437+int mach_io_registry_entry_create_iterator(struct mach_trap_args *);
9438+int mach_io_registry_entry_get_name_in_plane(struct mach_trap_args *);
9439+int mach_io_service_add_interest_notification(struct mach_trap_args *);
9440+int mach_io_registry_entry_get_location_in_plane(struct mach_trap_args *);
9441+int mach_port_type(struct mach_trap_args *);
9442+int mach_port_allocate(struct mach_trap_args *);
9443+int mach_port_destroy(struct mach_trap_args *);
9444+int mach_port_deallocate(struct mach_trap_args *);
9445+int mach_port_get_refs(struct mach_trap_args *);
9446+int mach_port_mod_refs(struct mach_trap_args *);
9447+int mach_port_move_member(struct mach_trap_args *);
9448+int mach_port_request_notification(struct mach_trap_args *);
9449+int mach_port_insert_right(struct mach_trap_args *);
9450+int mach_port_get_attributes(struct mach_trap_args *);
9451+int mach_port_set_attributes(struct mach_trap_args *);
9452+int mach_port_insert_member(struct mach_trap_args *);
9453+int mach_task_terminate(struct mach_trap_args *);
9454+int mach_task_threads(struct mach_trap_args *);
9455+int mach_ports_lookup(struct mach_trap_args *);
9456+int mach_task_info(struct mach_trap_args *);
9457+int mach_task_suspend(struct mach_trap_args *);
9458+int mach_task_resume(struct mach_trap_args *);
9459+int mach_task_get_special_port(struct mach_trap_args *);
9460+int mach_task_set_special_port(struct mach_trap_args *);
9461+int mach_thread_create_running(struct mach_trap_args *);
9462+int mach_task_set_exception_ports(struct mach_trap_args *);
9463+int mach_task_get_exception_ports(struct mach_trap_args *);
9464+int mach_semaphore_create(struct mach_trap_args *);
9465+int mach_semaphore_destroy(struct mach_trap_args *);
9466+int mach_thread_get_state(struct mach_trap_args *);
9467+int mach_thread_set_state(struct mach_trap_args *);
9468+int mach_thread_suspend(struct mach_trap_args *);
9469+int mach_thread_resume(struct mach_trap_args *);
9470+int mach_thread_abort(struct mach_trap_args *);
9471+int mach_thread_info(struct mach_trap_args *);
9472+int mach_thread_policy(struct mach_trap_args *);
9473+int mach_thread_set_policy(struct mach_trap_args *);
9474+int mach_vm_region(struct mach_trap_args *);
9475+int mach_vm_allocate(struct mach_trap_args *);
9476+int mach_vm_deallocate(struct mach_trap_args *);
9477+int mach_vm_protect(struct mach_trap_args *);
9478+int mach_vm_inherit(struct mach_trap_args *);
9479+int mach_vm_read(struct mach_trap_args *);
9480+int mach_vm_write(struct mach_trap_args *);
9481+int mach_vm_copy(struct mach_trap_args *);
9482+int mach_vm_msync(struct mach_trap_args *);
9483+int mach_vm_map(struct mach_trap_args *);
9484+int mach_vm_machine_attribute(struct mach_trap_args *);
9485+int mach_vm_region_64(struct mach_trap_args *);
9486+int mach_make_memory_entry_64(struct mach_trap_args *);
9487diff --git a/sys/compat/mach/mach_services.master b/sys/compat/mach/mach_services.master
9488new file mode 100644
9489index 0000000..f5ee01c
9490--- /dev/null
9491+++ b/sys/compat/mach/mach_services.master
9492@@ -0,0 +1,481 @@
9493+ $NetBSD: mach_services.master,v 1.13 2005/12/11 12:20:20 christos Exp $
9494+;
9495+; Mach services list.
9496+;
9497+#include <sys/types.h>
9498+#include <sys/param.h>
9499+
9500+#include <compat/mach/mach_types.h>
9501+#include <compat/mach/mach_message.h>
9502+#include <compat/mach/mach_bootstrap.h>
9503+#include <compat/mach/mach_iokit.h>
9504+#include <compat/mach/mach_clock.h>
9505+#include <compat/mach/mach_host.h>
9506+#include <compat/mach/mach_port.h>
9507+#include <compat/mach/mach_task.h>
9508+#include <compat/mach/mach_thread.h>
9509+#include <compat/mach/mach_semaphore.h>
9510+#include <compat/mach/mach_notify.h>
9511+#include <compat/mach/mach_exception.h>
9512+#include <compat/mach/mach_vm.h>
9513+#include <compat/mach/mach_services.h>
9514+
9515+%%
9516+
9517+;
9518+; Port Notification messages
9519+;
9520+64	OBSOL	notify_first
9521+65	NODEF	notify_port_deleted
9522+66	OBSOL	notify_msg_accepted
9523+67	OBSOL	notify_ownership_rights
9524+68	OBSOL	notify_receive_rights
9525+69	NODEF	notify_port_destroyed
9526+70	NODEF	notify_port_no_senders
9527+71	NODEF	notify_port_send_once
9528+72	NODEF	notify_port_dead_name
9529+
9530+;
9531+; Host subsystem
9532+;
9533+200	STD	host_info
9534+201	UNIMPL	host_kernel_version
9535+202	STD	host_page_size
9536+203	UNIMPL	memory_object_memory_entry
9537+204	UNIMPL	host_processor_info
9538+205	STD	host_get_io_master
9539+206	STD	host_get_clock_service
9540+207	UNIMPL	kmod_get_info
9541+208	UNIMPL	host_zone_info
9542+209	UNIMPL	host_virtual_physical_table_info
9543+210	UNIMPL	host_ipc_hash_info
9544+; Probably Darwin specific...
9545+211	UNIMPL	enable_bluebox
9546+212	UNIMPL	disable_bluebox
9547+213	STD	processor_set_default
9548+214	UNIMPL	processor_set_create
9549+215	UNIMPL	memory_object_memory_entry_64
9550+216	UNIMPL	host_statistics
9551+
9552+;
9553+; Host subsystem (private)
9554+;
9555+400	UNIMPL	host_get_boot_info
9556+401	UNIMPL	host_reboot
9557+402	UNIMPL	host_priv_statistics
9558+; Implemented by mach_init, clashes with host_default_memory_manager
9559+403	UNIMPL	boostrap_register
9560+; Implemented by mach_init, clashes with vm_wire
9561+404	STD	bootstrap_look_up
9562+405	UNIMPL	thread_wire
9563+406	UNIMPL	vm_allocate_cpm
9564+407	UNIMPL	host_processors
9565+408	UNIMPL	host_get_clock_control
9566+409	UNIMPL	kmod_create
9567+410	UNIMPL	kmod_destroy
9568+411	UNIMPL	kmod_control
9569+412	UNIMPL	host_get_special_port
9570+413	UNIMPL	host_set_special_port
9571+414	UNIMPL	host_set_exception_ports
9572+415	UNIMPL	host_get_exception_ports
9573+416	UNIMPL	host_swap_exception_ports
9574+417	UNIMPL	host_load_symbol_table
9575+418	UNIMPL	task_swappable
9576+419	UNIMPL	host_processor_sets
9577+420	STD	host_processor_set_priv
9578+421	UNIMPL	set_dp_control_port
9579+422	UNIMPL	get_dp_control_port
9580+423	UNIMPL	host_set_UNDServer
9581+424	UNIMPL	host_get_UNDServer
9582+
9583+;
9584+; Host security
9585+;
9586+600	UNIMPL	host_security_create_task_token
9587+601	UNIMPL	host_security_set_task_token
9588+
9589+;
9590+; Clock subsystem
9591+;
9592+1000	STD	clock_get_time
9593+1001	UNIMPL	clock_get_attributes
9594+1002	UNIMPL	clock_alarm
9595+
9596+;
9597+; Clock subsystem (private)
9598+;
9599+1200	UNIMPL	clock_set_time
9600+1201	UNIMPL	clock_set_attributes
9601+
9602+;
9603+; Memoey management
9604+;
9605+2000	UNIMPL	memory_object_get_attributes
9606+2001	UNIMPL	memory_object_change_attributes
9607+2002	UNIMPL	memory_object_synchronize_completed
9608+2003	UNIMPL	memory_object_lock_request
9609+2004	UNIMPL	memory_object_destroy
9610+2005	UNIMPL	memory_object_upl_request
9611+2006	UNIMPL	memory_object_super_upl_request
9612+2007	UNIMPL	memory_object_page_op
9613+2008	UNIMPL	memory_object_recover_named
9614+2009	UNIMPL	memory_object_release_name
9615+
9616+;
9617+; UPL (External memory management)
9618+;
9619+2050	UNIMPL	upl_abort
9620+2051	UNIMPL	upl_abort_range
9621+2052	UNIMPL	upl_commit
9622+2053	UNIMPL	upl_commit_range
9623+
9624+;
9625+; Memory management (control)
9626+;
9627+2200	UNIMPL	memory_object_init
9628+2201	UNIMPL	memory_object_terminate
9629+2202	UNIMPL	memory_object_data_request
9630+2203	UNIMPL	memory_object_data_return
9631+2204	UNIMPL	memory_object_data_initialize
9632+2205	UNIMPL	memory_object_data_unlock
9633+2206	UNIMPL	memory_object_synchronize
9634+2207	UNIMPL	memory_object_unmap
9635+
9636+;
9637+; Memory management (default)
9638+;
9639+2250	UNIMPL	memory_object_create
9640+
9641+;
9642+; Default pager (object)
9643+;
9644+2275	UNIMPL	default_pager_object_create
9645+2276	UNIMPL	default_pager_info
9646+2277	UNIMPL	default_pager_objects
9647+2278	UNIMPL	default_pager_object_pages
9648+2279	UNIMPL	default_pager_backing_store_create
9649+2280	UNIMPL	default_pager_backing_store_delete
9650+2281	UNIMPL	default_pager_add_segment
9651+2282	UNIMPL	default_pager_backing_store_info
9652+2283	UNIMPL	default_pager_add_file
9653+2284	UNIMPL	default_pager_triggers
9654+
9655+;
9656+; Default pager (alerts)
9657+;
9658+2295	UNIMPL	default_pager_space_alert
9659+
9660+;
9661+; Mach exception interface
9662+;
9663+2401	NODEF	exception_raise
9664+2402	NODEF	exception_raise_state
9665+2403	NODEF	exception_raise_state_identity
9666+
9667+;
9668+; Profiling
9669+;
9670+2450	UNIMPL	samples
9671+2451	UNIMPL	notices
9672+
9673+;
9674+; Mach exception Replies.
9675+; Defined because the kernel is the client here:
9676+; it has to handle replies instead of reequest.
9677+;
9678+2501	STD	exception_raise
9679+2502	STD	exception_raise_state
9680+2503	STD	exception_raise_state_identity
9681+
9682+;
9683+; Mach IOKit
9684+;
9685+2800	STD	io_object_get_class
9686+2801	STD	io_object_conforms_to
9687+2802	STD	io_iterator_next
9688+2803	STD	io_iterator_reset
9689+2804	STD	io_service_get_matching_services
9690+2805	STD	io_registry_entry_get_property
9691+2806	UNIMPL	io_registry_create_iterator
9692+2807	UNIMPL	io_registry_iterator_enter_entry
9693+2808	UNIMPL	io_registry_iterator_exit_entry
9694+2809	STD	io_registry_entry_from_path
9695+2810	UNIMPL	io_registry_entry_get_name
9696+2811	STD	io_registry_entry_get_properties
9697+2812	UNIMPL	io_registry_entry_get_property_bytes
9698+2813	STD	io_registry_entry_get_child_iterator
9699+2814	STD	io_registry_entry_get_parent_iterator
9700+2815	STD	io_service_open
9701+2816	STD	io_service_close
9702+2817	STD	io_connect_get_service
9703+2818	STD	io_connect_set_notification_port
9704+2819	STD	io_connect_map_memory
9705+2820	STD	io_connect_add_client
9706+2821	STD	io_connect_set_properties
9707+2822	STD	io_connect_method_scalari_scalaro
9708+2823	STD	io_connect_method_scalari_structo
9709+2824	STD	io_connect_method_scalari_structi
9710+2825	STD	io_connect_method_structi_structo
9711+2826	STD	io_registry_entry_get_path
9712+2827	STD	io_registry_get_root_entry
9713+2828	UNIMPL	io_registry_entry_set_properties
9714+2829	UNIMPL	io_registry_entry_in_plane
9715+2830	UNIMPL	io_object_get_retain_count
9716+2831	UNIMPL	io_service_get_busy_state
9717+2832	UNIMPL	io_service_wait_quiet
9718+2833	STD	io_registry_entry_create_iterator
9719+2834	UNIMPL	io_iterator_is_valid
9720+2835	UNIMPL	io_make_matching
9721+2836	UNIMPL	io_catalog_send_data
9722+2837	UNIMPL	io_catalog_terminate
9723+2838	UNIMPL	io_catalog_get_data
9724+2839	UNIMPL	io_catalog_get_gen_count
9725+2840	UNIMPL	io_catalog_module_loaded
9726+2841	UNIMPL	io_catalog_reset
9727+2842	UNIMPL	io_service_request_probe
9728+2843	STD	io_registry_entry_get_name_in_plane
9729+2844	UNIMPL	io_service_match_property_table
9730+2845	UNIMPL	io_async_method_scalari_scalaro
9731+2846	UNIMPL	io_async_method_scalari_structo
9732+2847	UNIMPL	io_async_method_scalari_structi
9733+2848	UNIMPL	io_async_method_structi_structo
9734+2849	UNIMPL	io_service_add_notification
9735+2850	STD	io_service_add_interest_notification
9736+2851	UNIMPL	io_service_acknowledge_notification
9737+2852	UNIMPL	io_connect_get_notification_semaphore
9738+2853	UNIMPL	io_connect_unmap_memory
9739+2854	STD	io_registry_entry_get_location_in_plane
9740+2855	UNIMPL	io_registry_entry_get_property_recursively
9741+
9742+;
9743+; Processor subsystem
9744+;
9745+3000	UNIMPL	processor_start
9746+3001	UNIMPL	processor_exit
9747+3002	UNIMPL	processor_info
9748+3003	UNIMPL	processor_control
9749+3004	UNIMPL	processor_assign
9750+3005	UNIMPL	processor_get_assignment
9751+
9752+;
9753+; Mach ports
9754+;
9755+3200	UNIMPL	port_names
9756+3201	STD	port_type
9757+3202	UNIMPL	port_rename
9758+3203	UNIMPL	port_allocate_name
9759+3204	STD	port_allocate
9760+3205	STD	port_destroy
9761+3206	STD	port_deallocate
9762+3207	STD	port_get_refs
9763+3208	STD	port_mod_refs
9764+3210	UNIMPL	port_set_mscount
9765+3211	UNIMPL	port_get_set_status
9766+3212	STD	port_move_member
9767+3213	STD	port_request_notification
9768+3214	STD	port_insert_right
9769+3215	UNIMPL	port_extract_right
9770+3216	UNIMPL	port_set_seqno
9771+3217	STD	port_get_attributes
9772+3218	STD	port_set_attributes
9773+3219	UNIMPL	port_allocate_qos
9774+3220	UNIMPL	port_allocate_full
9775+3221	UNIMPL	task_set_port_space
9776+3222	UNIMPL	port_get_srights
9777+3223	UNIMPL	port_space_info
9778+3224	UNIMPL	port_dnrequest_info
9779+3225	UNIMPL	port_kernel_object
9780+3226	STD	port_insert_member
9781+3227	UNIMPL	port_extract_member
9782+
9783+;
9784+; Mach tasks
9785+;
9786+3400	UNIMPL	task_create
9787+3401	STD	task_terminate
9788+3402	STD	task_threads
9789+3403	UNIMPL	ports_register
9790+3404	STD	ports_lookup
9791+3405	STD	task_info
9792+3406	UNIMPL	task_set_info
9793+3407	STD	task_suspend
9794+3408	STD	task_resume
9795+3409	STD	task_get_special_port
9796+3410	STD	task_set_special_port
9797+3411	UNIMPL	thread_create
9798+3412	STD	thread_create_running
9799+3413	STD	task_set_exception_ports
9800+3414	STD	task_get_exception_ports
9801+3415	UNIMPL	task_swap_exception_ports
9802+3416	UNIMPL	lock_set_create
9803+3417	UNIMPL	lock_set_destroy
9804+3418	STD	semaphore_create
9805+3419	STD	semaphore_destroy
9806+3420	UNIMPL	task_policy_set
9807+3421	UNIMPL	task_policy_get
9808+3422	UNIMPL	task_sample
9809+3423	UNIMPL	task_policy
9810+3424	UNIMPL	task_set_emulation
9811+3425	UNIMPL	task_get_emulation_vector
9812+3426	UNIMPL	task_set_emulation_vector
9813+3427	UNIMPL	task_set_ras_pc
9814+3428	UNIMPL	kernel_task_create
9815+3429	UNIMPL	task_assign
9816+3430	UNIMPL	task_assign_default
9817+3431	UNIMPL	task_get_assignment
9818+3432	UNIMPL	task_set_policy
9819+
9820+;
9821+; Mach threads
9822+;
9823+3600	UNIMPL	thread_terminate
9824+3601	UNIMPL	act_get_state
9825+3602	UNIMPL	act_set_state
9826+3603	STD	thread_get_state
9827+3604	STD	thread_set_state
9828+3605	STD	thread_suspend
9829+3606	STD	thread_resume
9830+3607	STD	thread_abort
9831+3608	UNIMPL	thread_abort_safely
9832+3609	UNIMPL	thread_depress_abort
9833+3610	UNIMPL	thread_get_special_port
9834+3611	UNIMPL	thread_set_special_port
9835+3612	STD	thread_info
9836+3613	UNIMPL	thread_set_exception_ports
9837+3614	UNIMPL	thread_get_exception_ports
9838+3615	UNIMPL	thread_swap_exception_ports
9839+3616	STD	thread_policy
9840+3617	UNIMPL	thread_policy_set
9841+3618	UNIMPL	thread_policy_get
9842+3619	UNIMPL	thread_sample
9843+3620	UNIMPL	etap_trace_thread
9844+3621	UNIMPL	thread_assign
9845+3622	UNIMPL	thread_assign_default
9846+3623	UNIMPL	thread_get_assignment
9847+3624	STD	thread_set_policy
9848+
9849+;
9850+; VM mappings
9851+;
9852+3800	STD	vm_region
9853+3801	STD	vm_allocate
9854+3802	STD	vm_deallocate
9855+3803	STD	vm_protect
9856+3804	STD	vm_inherit
9857+3805	STD	vm_read
9858+3806	UNIMPL	vm_read_list
9859+3807	STD	vm_write
9860+3808	STD	vm_copy
9861+3809	UNIMPL	vm_read_overwrite
9862+3810	STD	vm_msync
9863+3811	UNIMPL	vm_behavior_set
9864+3812	STD	vm_map
9865+3813	STD	vm_machine_attribute
9866+3814	UNIMPL	vm_remap
9867+3815	UNIMPL	task_wire
9868+3816	UNIMPL	make_memory_entry
9869+3817	UNIMPL	vm_map_page_query
9870+3818	UNIMPL	vm_region_info
9871+3819	UNIMPL	vm_mapped_pages_info
9872+3820	UNIMPL	vm_region_object_create
9873+3821	UNIMPL	vm_region_recurse
9874+3822	UNIMPL	vm_region_recurse_64
9875+3823	UNIMPL	vm_region_info_64
9876+3824	STD	vm_region_64
9877+3825	STD	make_memory_entry_64
9878+3826	UNIMPL	vm_map_64
9879+3827	UNIMPL	vm_map_get_upl
9880+3828	UNIMPL	vm_upl_map
9881+3829	UNIMPL	vm_upl_unmap
9882+
9883+;
9884+; Processor set
9885+;
9886+4000	UNIMPL	processor_set_statistics
9887+4001	UNIMPL	processor_set_destroy
9888+4002	UNIMPL	processor_set_max_priority
9889+4003	UNIMPL	processor_set_policy_enable
9890+4004	UNIMPL	processor_set_policy_disable
9891+4005	UNIMPL	processor_set_tasks
9892+4006	UNIMPL	processor_set_threads
9893+4007	UNIMPL	processor_set_policy_control
9894+4008	UNIMPL	processor_set_stack_usage
9895+4009	UNIMPL	processor_set_info
9896+
9897+;
9898+; Ledger
9899+;
9900+5000	UNIMPL	ledger_create
9901+5001	UNIMPL	ledger_terminate
9902+5002	UNIMPL	ledger_transfer
9903+5003	UNIMPL	ledger_read
9904+
9905+;
9906+; User Notification subsystem (UNDRequest)
9907+;
9908+6000	UNIMPL	und_execute_rpc
9909+6001	UNIMPL	und_display_notice_from_bundle_rpc
9910+6002	UNIMPL	und_display_alert_from_bundle_rpc
9911+6003	UNIMPL	und_display_custom_from_bundle_rpc
9912+6004	UNIMPL	und_display_custom_from_dictionary_rpc
9913+6005	UNIMPL	und_cancel_notification_rpc
9914+6006	UNIMPL	und_display_notice_simple_rpc
9915+6007	UNIMPL	und_display_alert_simple_rpc
9916+
9917+;
9918+; User Notification subsystem (UNDReply)
9919+;
9920+6200	UNIMPL	und_alert_completed_with_result_rpc
9921+6201	UNIMPL	und_notification_created_rpc(
9922+
9923+;
9924+; Mach Norma
9925+;
9926+555001	UNIMPL	task_set_child_node
9927+555002	UNIMPL	norma_node_self
9928+555005	UNIMPL	norma_task_clone
9929+555006	UNIMPL	norma_task_create
9930+555007	UNIMPL	norma_get_special_port
9931+555008	UNIMPL	norma_set_special_port
9932+555009	UNIMPL	norma_task_teleport
9933+555012	UNIMPL	norma_port_location_hint
9934+
9935+;
9936+; Sync, overlapping with Lock set
9937+;
9938+;617000	UNIMPL	semaphore_create
9939+;617001	UNIMPL	semaphore_destroy
9940+;617002	UNIMPL	semaphore_signal
9941+;617003	UNIMPL	semaphore_signal_all
9942+;617004	UNIMPL	semaphore_wait
9943+;617013	UNIMPL	semaphore_signal_thread
9944+;617014	UNIMPL	semaphore_timedwait
9945+
9946+;
9947+; Lock set
9948+;
9949+617000	UNIMPL	lock_acquire
9950+617001	UNIMPL	lock_release
9951+617002	UNIMPL	lock_try
9952+617003	UNIMPL	lock_make_stable
9953+617004	UNIMPL	lock_handoff
9954+617005	UNIMPL	lock_handoff_accept
9955+617005	UNIMPL	lock_set_create
9956+617006	UNIMPL	lock_set_destroy
9957+617007	UNIMPL	lock_acquire
9958+617008	UNIMPL	lock_release
9959+617009	UNIMPL	lock_try
9960+617010	UNIMPL	lock_make_stable
9961+617011	UNIMPL	lock_handoff
9962+617012	UNIMPL	lock_handoff_accept
9963+
9964+;
9965+; Semaphores
9966+;
9967+617200	UNIMPL	semaphore_signal
9968+617201	UNIMPL	semaphore_signal_all
9969+617202	UNIMPL	semaphore_wait
9970+617203	UNIMPL	semaphore_signal_thread
9971+617204	UNIMPL	semaphore_timedwait
9972+617205	UNIMPL	semaphore_wait_signal
9973+617206	UNIMPL	semaphore_timedwait_signal
9974diff --git a/sys/compat/mach/mach_services_names.c b/sys/compat/mach/mach_services_names.c
9975new file mode 100644
9976index 0000000..dd0a3c7
9977--- /dev/null
9978+++ b/sys/compat/mach/mach_services_names.c
9979@@ -0,0 +1,351 @@
9980+/* $NetBSD: mach_services_names.c,v 1.16 2009/01/13 22:33:10 pooka Exp $ */
9981+
9982+/*
9983+ * Mach services names. This file is not built
9984+ * by the kernel, it is included by kdump sources.
9985+ *
9986+ * DO NOT EDIT -- this file is automatically generated.
9987+ * created from NetBSD: mach_services.master,v 1.13 2005/12/11 12:20:20 christos Exp
9988+ */
9989+
9990+#include <sys/cdefs.h>
9991+__KERNEL_RCSID(0, "$NetBSD: mach_services_names.c,v 1.16 2009/01/13 22:33:10 pooka Exp $");
9992+
9993+struct mach_service_name {
9994+	int srv_id;
9995+	const char *srv_name;
9996+};
9997+
9998+struct mach_service_name mach_services_names[] = {
9999+	{64, "obsolete notify_first"},
10000+	{65, "notify_port_deleted"},
10001+	{66, "obsolete notify_msg_accepted"},
10002+	{67, "obsolete notify_ownership_rights"},
10003+	{68, "obsolete notify_receive_rights"},
10004+	{69, "notify_port_destroyed"},
10005+	{70, "notify_port_no_senders"},
10006+	{71, "notify_port_send_once"},
10007+	{72, "notify_port_dead_name"},
10008+	{200, "host_info"},
10009+	{201, "unimpl. host_kernel_version"},
10010+	{202, "host_page_size"},
10011+	{203, "unimpl. memory_object_memory_entry"},
10012+	{204, "unimpl. host_processor_info"},
10013+	{205, "host_get_io_master"},
10014+	{206, "host_get_clock_service"},
10015+	{207, "unimpl. kmod_get_info"},
10016+	{208, "unimpl. host_zone_info"},
10017+	{209, "unimpl. host_virtual_physical_table_info"},
10018+	{210, "unimpl. host_ipc_hash_info"},
10019+	{211, "unimpl. enable_bluebox"},
10020+	{212, "unimpl. disable_bluebox"},
10021+	{213, "processor_set_default"},
10022+	{214, "unimpl. processor_set_create"},
10023+	{215, "unimpl. memory_object_memory_entry_64"},
10024+	{216, "unimpl. host_statistics"},
10025+	{400, "unimpl. host_get_boot_info"},
10026+	{401, "unimpl. host_reboot"},
10027+	{402, "unimpl. host_priv_statistics"},
10028+	{403, "unimpl. boostrap_register"},
10029+	{404, "bootstrap_look_up"},
10030+	{405, "unimpl. thread_wire"},
10031+	{406, "unimpl. vm_allocate_cpm"},
10032+	{407, "unimpl. host_processors"},
10033+	{408, "unimpl. host_get_clock_control"},
10034+	{409, "unimpl. kmod_create"},
10035+	{410, "unimpl. kmod_destroy"},
10036+	{411, "unimpl. kmod_control"},
10037+	{412, "unimpl. host_get_special_port"},
10038+	{413, "unimpl. host_set_special_port"},
10039+	{414, "unimpl. host_set_exception_ports"},
10040+	{415, "unimpl. host_get_exception_ports"},
10041+	{416, "unimpl. host_swap_exception_ports"},
10042+	{417, "unimpl. host_load_symbol_table"},
10043+	{418, "unimpl. task_swappable"},
10044+	{419, "unimpl. host_processor_sets"},
10045+	{420, "host_processor_set_priv"},
10046+	{421, "unimpl. set_dp_control_port"},
10047+	{422, "unimpl. get_dp_control_port"},
10048+	{423, "unimpl. host_set_UNDServer"},
10049+	{424, "unimpl. host_get_UNDServer"},
10050+	{600, "unimpl. host_security_create_task_token"},
10051+	{601, "unimpl. host_security_set_task_token"},
10052+	{1000, "clock_get_time"},
10053+	{1001, "unimpl. clock_get_attributes"},
10054+	{1002, "unimpl. clock_alarm"},
10055+	{1200, "unimpl. clock_set_time"},
10056+	{1201, "unimpl. clock_set_attributes"},
10057+	{2000, "unimpl. memory_object_get_attributes"},
10058+	{2001, "unimpl. memory_object_change_attributes"},
10059+	{2002, "unimpl. memory_object_synchronize_completed"},
10060+	{2003, "unimpl. memory_object_lock_request"},
10061+	{2004, "unimpl. memory_object_destroy"},
10062+	{2005, "unimpl. memory_object_upl_request"},
10063+	{2006, "unimpl. memory_object_super_upl_request"},
10064+	{2007, "unimpl. memory_object_page_op"},
10065+	{2008, "unimpl. memory_object_recover_named"},
10066+	{2009, "unimpl. memory_object_release_name"},
10067+	{2050, "unimpl. upl_abort"},
10068+	{2051, "unimpl. upl_abort_range"},
10069+	{2052, "unimpl. upl_commit"},
10070+	{2053, "unimpl. upl_commit_range"},
10071+	{2200, "unimpl. memory_object_init"},
10072+	{2201, "unimpl. memory_object_terminate"},
10073+	{2202, "unimpl. memory_object_data_request"},
10074+	{2203, "unimpl. memory_object_data_return"},
10075+	{2204, "unimpl. memory_object_data_initialize"},
10076+	{2205, "unimpl. memory_object_data_unlock"},
10077+	{2206, "unimpl. memory_object_synchronize"},
10078+	{2207, "unimpl. memory_object_unmap"},
10079+	{2250, "unimpl. memory_object_create"},
10080+	{2275, "unimpl. default_pager_object_create"},
10081+	{2276, "unimpl. default_pager_info"},
10082+	{2277, "unimpl. default_pager_objects"},
10083+	{2278, "unimpl. default_pager_object_pages"},
10084+	{2279, "unimpl. default_pager_backing_store_create"},
10085+	{2280, "unimpl. default_pager_backing_store_delete"},
10086+	{2281, "unimpl. default_pager_add_segment"},
10087+	{2282, "unimpl. default_pager_backing_store_info"},
10088+	{2283, "unimpl. default_pager_add_file"},
10089+	{2284, "unimpl. default_pager_triggers"},
10090+	{2295, "unimpl. default_pager_space_alert"},
10091+	{2401, "exception_raise"},
10092+	{2402, "exception_raise_state"},
10093+	{2403, "exception_raise_state_identity"},
10094+	{2450, "unimpl. samples"},
10095+	{2451, "unimpl. notices"},
10096+	{2501, "exception_raise"},
10097+	{2502, "exception_raise_state"},
10098+	{2503, "exception_raise_state_identity"},
10099+	{2800, "io_object_get_class"},
10100+	{2801, "io_object_conforms_to"},
10101+	{2802, "io_iterator_next"},
10102+	{2803, "io_iterator_reset"},
10103+	{2804, "io_service_get_matching_services"},
10104+	{2805, "io_registry_entry_get_property"},
10105+	{2806, "unimpl. io_registry_create_iterator"},
10106+	{2807, "unimpl. io_registry_iterator_enter_entry"},
10107+	{2808, "unimpl. io_registry_iterator_exit_entry"},
10108+	{2809, "io_registry_entry_from_path"},
10109+	{2810, "unimpl. io_registry_entry_get_name"},
10110+	{2811, "io_registry_entry_get_properties"},
10111+	{2812, "unimpl. io_registry_entry_get_property_bytes"},
10112+	{2813, "io_registry_entry_get_child_iterator"},
10113+	{2814, "io_registry_entry_get_parent_iterator"},
10114+	{2815, "io_service_open"},
10115+	{2816, "io_service_close"},
10116+	{2817, "io_connect_get_service"},
10117+	{2818, "io_connect_set_notification_port"},
10118+	{2819, "io_connect_map_memory"},
10119+	{2820, "io_connect_add_client"},
10120+	{2821, "io_connect_set_properties"},
10121+	{2822, "io_connect_method_scalari_scalaro"},
10122+	{2823, "io_connect_method_scalari_structo"},
10123+	{2824, "io_connect_method_scalari_structi"},
10124+	{2825, "io_connect_method_structi_structo"},
10125+	{2826, "io_registry_entry_get_path"},
10126+	{2827, "io_registry_get_root_entry"},
10127+	{2828, "unimpl. io_registry_entry_set_properties"},
10128+	{2829, "unimpl. io_registry_entry_in_plane"},
10129+	{2830, "unimpl. io_object_get_retain_count"},
10130+	{2831, "unimpl. io_service_get_busy_state"},
10131+	{2832, "unimpl. io_service_wait_quiet"},
10132+	{2833, "io_registry_entry_create_iterator"},
10133+	{2834, "unimpl. io_iterator_is_valid"},
10134+	{2835, "unimpl. io_make_matching"},
10135+	{2836, "unimpl. io_catalog_send_data"},
10136+	{2837, "unimpl. io_catalog_terminate"},
10137+	{2838, "unimpl. io_catalog_get_data"},
10138+	{2839, "unimpl. io_catalog_get_gen_count"},
10139+	{2840, "unimpl. io_catalog_module_loaded"},
10140+	{2841, "unimpl. io_catalog_reset"},
10141+	{2842, "unimpl. io_service_request_probe"},
10142+	{2843, "io_registry_entry_get_name_in_plane"},
10143+	{2844, "unimpl. io_service_match_property_table"},
10144+	{2845, "unimpl. io_async_method_scalari_scalaro"},
10145+	{2846, "unimpl. io_async_method_scalari_structo"},
10146+	{2847, "unimpl. io_async_method_scalari_structi"},
10147+	{2848, "unimpl. io_async_method_structi_structo"},
10148+	{2849, "unimpl. io_service_add_notification"},
10149+	{2850, "io_service_add_interest_notification"},
10150+	{2851, "unimpl. io_service_acknowledge_notification"},
10151+	{2852, "unimpl. io_connect_get_notification_semaphore"},
10152+	{2853, "unimpl. io_connect_unmap_memory"},
10153+	{2854, "io_registry_entry_get_location_in_plane"},
10154+	{2855, "unimpl. io_registry_entry_get_property_recursively"},
10155+	{3000, "unimpl. processor_start"},
10156+	{3001, "unimpl. processor_exit"},
10157+	{3002, "unimpl. processor_info"},
10158+	{3003, "unimpl. processor_control"},
10159+	{3004, "unimpl. processor_assign"},
10160+	{3005, "unimpl. processor_get_assignment"},
10161+	{3200, "unimpl. port_names"},
10162+	{3201, "port_type"},
10163+	{3202, "unimpl. port_rename"},
10164+	{3203, "unimpl. port_allocate_name"},
10165+	{3204, "port_allocate"},
10166+	{3205, "port_destroy"},
10167+	{3206, "port_deallocate"},
10168+	{3207, "port_get_refs"},
10169+	{3208, "port_mod_refs"},
10170+	{3210, "unimpl. port_set_mscount"},
10171+	{3211, "unimpl. port_get_set_status"},
10172+	{3212, "port_move_member"},
10173+	{3213, "port_request_notification"},
10174+	{3214, "port_insert_right"},
10175+	{3215, "unimpl. port_extract_right"},
10176+	{3216, "unimpl. port_set_seqno"},
10177+	{3217, "port_get_attributes"},
10178+	{3218, "port_set_attributes"},
10179+	{3219, "unimpl. port_allocate_qos"},
10180+	{3220, "unimpl. port_allocate_full"},
10181+	{3221, "unimpl. task_set_port_space"},
10182+	{3222, "unimpl. port_get_srights"},
10183+	{3223, "unimpl. port_space_info"},
10184+	{3224, "unimpl. port_dnrequest_info"},
10185+	{3225, "unimpl. port_kernel_object"},
10186+	{3226, "port_insert_member"},
10187+	{3227, "unimpl. port_extract_member"},
10188+	{3400, "unimpl. task_create"},
10189+	{3401, "task_terminate"},
10190+	{3402, "task_threads"},
10191+	{3403, "unimpl. ports_register"},
10192+	{3404, "ports_lookup"},
10193+	{3405, "task_info"},
10194+	{3406, "unimpl. task_set_info"},
10195+	{3407, "task_suspend"},
10196+	{3408, "task_resume"},
10197+	{3409, "task_get_special_port"},
10198+	{3410, "task_set_special_port"},
10199+	{3411, "unimpl. thread_create"},
10200+	{3412, "thread_create_running"},
10201+	{3413, "task_set_exception_ports"},
10202+	{3414, "task_get_exception_ports"},
10203+	{3415, "unimpl. task_swap_exception_ports"},
10204+	{3416, "unimpl. lock_set_create"},
10205+	{3417, "unimpl. lock_set_destroy"},
10206+	{3418, "semaphore_create"},
10207+	{3419, "semaphore_destroy"},
10208+	{3420, "unimpl. task_policy_set"},
10209+	{3421, "unimpl. task_policy_get"},
10210+	{3422, "unimpl. task_sample"},
10211+	{3423, "unimpl. task_policy"},
10212+	{3424, "unimpl. task_set_emulation"},
10213+	{3425, "unimpl. task_get_emulation_vector"},
10214+	{3426, "unimpl. task_set_emulation_vector"},
10215+	{3427, "unimpl. task_set_ras_pc"},
10216+	{3428, "unimpl. kernel_task_create"},
10217+	{3429, "unimpl. task_assign"},
10218+	{3430, "unimpl. task_assign_default"},
10219+	{3431, "unimpl. task_get_assignment"},
10220+	{3432, "unimpl. task_set_policy"},
10221+	{3600, "unimpl. thread_terminate"},
10222+	{3601, "unimpl. act_get_state"},
10223+	{3602, "unimpl. act_set_state"},
10224+	{3603, "thread_get_state"},
10225+	{3604, "thread_set_state"},
10226+	{3605, "thread_suspend"},
10227+	{3606, "thread_resume"},
10228+	{3607, "thread_abort"},
10229+	{3608, "unimpl. thread_abort_safely"},
10230+	{3609, "unimpl. thread_depress_abort"},
10231+	{3610, "unimpl. thread_get_special_port"},
10232+	{3611, "unimpl. thread_set_special_port"},
10233+	{3612, "thread_info"},
10234+	{3613, "unimpl. thread_set_exception_ports"},
10235+	{3614, "unimpl. thread_get_exception_ports"},
10236+	{3615, "unimpl. thread_swap_exception_ports"},
10237+	{3616, "thread_policy"},
10238+	{3617, "unimpl. thread_policy_set"},
10239+	{3618, "unimpl. thread_policy_get"},
10240+	{3619, "unimpl. thread_sample"},
10241+	{3620, "unimpl. etap_trace_thread"},
10242+	{3621, "unimpl. thread_assign"},
10243+	{3622, "unimpl. thread_assign_default"},
10244+	{3623, "unimpl. thread_get_assignment"},
10245+	{3624, "thread_set_policy"},
10246+	{3800, "vm_region"},
10247+	{3801, "vm_allocate"},
10248+	{3802, "vm_deallocate"},
10249+	{3803, "vm_protect"},
10250+	{3804, "vm_inherit"},
10251+	{3805, "vm_read"},
10252+	{3806, "unimpl. vm_read_list"},
10253+	{3807, "vm_write"},
10254+	{3808, "vm_copy"},
10255+	{3809, "unimpl. vm_read_overwrite"},
10256+	{3810, "vm_msync"},
10257+	{3811, "unimpl. vm_behavior_set"},
10258+	{3812, "vm_map"},
10259+	{3813, "vm_machine_attribute"},
10260+	{3814, "unimpl. vm_remap"},
10261+	{3815, "unimpl. task_wire"},
10262+	{3816, "unimpl. make_memory_entry"},
10263+	{3817, "unimpl. vm_map_page_query"},
10264+	{3818, "unimpl. vm_region_info"},
10265+	{3819, "unimpl. vm_mapped_pages_info"},
10266+	{3820, "unimpl. vm_region_object_create"},
10267+	{3821, "unimpl. vm_region_recurse"},
10268+	{3822, "unimpl. vm_region_recurse_64"},
10269+	{3823, "unimpl. vm_region_info_64"},
10270+	{3824, "vm_region_64"},
10271+	{3825, "make_memory_entry_64"},
10272+	{3826, "unimpl. vm_map_64"},
10273+	{3827, "unimpl. vm_map_get_upl"},
10274+	{3828, "unimpl. vm_upl_map"},
10275+	{3829, "unimpl. vm_upl_unmap"},
10276+	{4000, "unimpl. processor_set_statistics"},
10277+	{4001, "unimpl. processor_set_destroy"},
10278+	{4002, "unimpl. processor_set_max_priority"},
10279+	{4003, "unimpl. processor_set_policy_enable"},
10280+	{4004, "unimpl. processor_set_policy_disable"},
10281+	{4005, "unimpl. processor_set_tasks"},
10282+	{4006, "unimpl. processor_set_threads"},
10283+	{4007, "unimpl. processor_set_policy_control"},
10284+	{4008, "unimpl. processor_set_stack_usage"},
10285+	{4009, "unimpl. processor_set_info"},
10286+	{5000, "unimpl. ledger_create"},
10287+	{5001, "unimpl. ledger_terminate"},
10288+	{5002, "unimpl. ledger_transfer"},
10289+	{5003, "unimpl. ledger_read"},
10290+	{6000, "unimpl. und_execute_rpc"},
10291+	{6001, "unimpl. und_display_notice_from_bundle_rpc"},
10292+	{6002, "unimpl. und_display_alert_from_bundle_rpc"},
10293+	{6003, "unimpl. und_display_custom_from_bundle_rpc"},
10294+	{6004, "unimpl. und_display_custom_from_dictionary_rpc"},
10295+	{6005, "unimpl. und_cancel_notification_rpc"},
10296+	{6006, "unimpl. und_display_notice_simple_rpc"},
10297+	{6007, "unimpl. und_display_alert_simple_rpc"},
10298+	{6200, "unimpl. und_alert_completed_with_result_rpc"},
10299+	{6201, "unimpl. und_notification_created_rpc("},
10300+	{555001, "unimpl. task_set_child_node"},
10301+	{555002, "unimpl. norma_node_self"},
10302+	{555005, "unimpl. norma_task_clone"},
10303+	{555006, "unimpl. norma_task_create"},
10304+	{555007, "unimpl. norma_get_special_port"},
10305+	{555008, "unimpl. norma_set_special_port"},
10306+	{555009, "unimpl. norma_task_teleport"},
10307+	{555012, "unimpl. norma_port_location_hint"},
10308+	{617000, "unimpl. lock_acquire"},
10309+	{617001, "unimpl. lock_release"},
10310+	{617002, "unimpl. lock_try"},
10311+	{617003, "unimpl. lock_make_stable"},
10312+	{617004, "unimpl. lock_handoff"},
10313+	{617005, "unimpl. lock_handoff_accept"},
10314+	{617005, "unimpl. lock_set_create"},
10315+	{617006, "unimpl. lock_set_destroy"},
10316+	{617007, "unimpl. lock_acquire"},
10317+	{617008, "unimpl. lock_release"},
10318+	{617009, "unimpl. lock_try"},
10319+	{617010, "unimpl. lock_make_stable"},
10320+	{617011, "unimpl. lock_handoff"},
10321+	{617012, "unimpl. lock_handoff_accept"},
10322+	{617200, "unimpl. semaphore_signal"},
10323+	{617201, "unimpl. semaphore_signal_all"},
10324+	{617202, "unimpl. semaphore_wait"},
10325+	{617203, "unimpl. semaphore_signal_thread"},
10326+	{617204, "unimpl. semaphore_timedwait"},
10327+	{617205, "unimpl. semaphore_wait_signal"},
10328+	{617206, "unimpl. semaphore_timedwait_signal"},
10329+	{0, NULL}
10330+};
10331diff --git a/sys/compat/mach/mach_syscall.h b/sys/compat/mach/mach_syscall.h
10332new file mode 100644
10333index 0000000..cbab9dc
10334--- /dev/null
10335+++ b/sys/compat/mach/mach_syscall.h
10336@@ -0,0 +1,110 @@
10337+/* $NetBSD: mach_syscall.h,v 1.21 2009/12/14 00:58:37 matt Exp $ */
10338+
10339+/*
10340+ * System call numbers.
10341+ *
10342+ * DO NOT EDIT-- this file is automatically generated.
10343+ * created from	NetBSD: syscalls.master,v 1.10 2009/01/13 22:27:43 pooka Exp
10344+ */
10345+
10346+#ifndef _MACH_SYS_SYSCALL_H_
10347+#define	_MACH_SYS_SYSCALL_H_
10348+
10349+#define	MACH_SYS_MAXSYSARGS	9
10350+
10351+/* syscall: "reply_port" ret: "mach_port_name_t" args: */
10352+#define	MACH_SYS_reply_port	26
10353+
10354+/* syscall: "thread_self_trap" ret: "mach_port_name_t" args: */
10355+#define	MACH_SYS_thread_self_trap	27
10356+
10357+/* syscall: "task_self_trap" ret: "mach_port_name_t" args: */
10358+#define	MACH_SYS_task_self_trap	28
10359+
10360+/* syscall: "host_self_trap" ret: "mach_port_name_t" args: */
10361+#define	MACH_SYS_host_self_trap	29
10362+
10363+/* syscall: "msg_trap" ret: "mach_msg_return_t" args: "mach_msg_header_t *" "mach_msg_option_t" "mach_msg_size_t" "mach_msg_size_t" "mach_port_name_t" "mach_msg_timeout_t" "mach_port_name_t" */
10364+#define	MACH_SYS_msg_trap	31
10365+
10366+/* syscall: "msg_overwrite_trap" ret: "mach_kern_return_t" args: "mach_msg_header_t *" "mach_msg_option_t" "mach_msg_size_t" "mach_msg_size_t" "mach_port_name_t" "mach_msg_timeout_t" "mach_port_name_t" "mach_msg_header_t *" "mach_msg_size_t" */
10367+#define	MACH_SYS_msg_overwrite_trap	32
10368+
10369+/* syscall: "semaphore_signal_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" */
10370+#define	MACH_SYS_semaphore_signal_trap	33
10371+
10372+/* syscall: "semaphore_signal_all_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" */
10373+#define	MACH_SYS_semaphore_signal_all_trap	34
10374+
10375+/* syscall: "semaphore_signal_thread_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" "mach_port_name_t" */
10376+#define	MACH_SYS_semaphore_signal_thread_trap	35
10377+
10378+/* syscall: "semaphore_wait_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" */
10379+#define	MACH_SYS_semaphore_wait_trap	36
10380+
10381+/* syscall: "semaphore_wait_signal_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" "mach_port_name_t" */
10382+#define	MACH_SYS_semaphore_wait_signal_trap	37
10383+
10384+/* syscall: "semaphore_timedwait_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" "unsigned int" "mach_clock_res_t" */
10385+#define	MACH_SYS_semaphore_timedwait_trap	38
10386+
10387+/* syscall: "semaphore_timedwait_signal_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" "mach_port_name_t" "unsigned int" "mach_clock_res_t" */
10388+#define	MACH_SYS_semaphore_timedwait_signal_trap	39
10389+
10390+/* syscall: "init_process" ret: "mach_kern_return_t" args: */
10391+#define	MACH_SYS_init_process	41
10392+
10393+/* syscall: "map_fd" ret: "mach_kern_return_t" args: "int" "mach_vm_offset_t" "mach_vm_offset_t *" "mach_boolean_t" "mach_vm_size_t" */
10394+#define	MACH_SYS_map_fd	43
10395+
10396+/* syscall: "task_for_pid" ret: "mach_kern_return_t" args: "mach_port_t" "int" "mach_port_t *" */
10397+#define	MACH_SYS_task_for_pid	45
10398+
10399+/* syscall: "pid_for_task" ret: "mach_kern_return_t" args: "mach_port_t" "int *" */
10400+#define	MACH_SYS_pid_for_task	46
10401+
10402+/* syscall: "macx_swapon" ret: "mach_kern_return_t" args: "char *" "int" "int" "int" */
10403+#define	MACH_SYS_macx_swapon	48
10404+
10405+/* syscall: "macx_swapoff" ret: "mach_kern_return_t" args: "char *" "int" */
10406+#define	MACH_SYS_macx_swapoff	49
10407+
10408+/* syscall: "macx_triggers" ret: "mach_kern_return_t" args: "int" "int" "int" "mach_port_t" */
10409+#define	MACH_SYS_macx_triggers	51
10410+
10411+/* syscall: "swtch_pri" ret: "mach_kern_return_t" args: "int" */
10412+#define	MACH_SYS_swtch_pri	59
10413+
10414+/* syscall: "swtch" ret: "mach_kern_return_t" args: */
10415+#define	MACH_SYS_swtch	60
10416+
10417+/* syscall: "syscall_thread_switch" ret: "mach_kern_return_t" args: "mach_port_name_t" "int" "mach_msg_timeout_t" */
10418+#define	MACH_SYS_syscall_thread_switch	61
10419+
10420+/* syscall: "clock_sleep_trap" ret: "mach_kern_return_t" args: "mach_port_name_t" "mach_sleep_type_t" "int" "int" "mach_timespec_t *" */
10421+#define	MACH_SYS_clock_sleep_trap	62
10422+
10423+/* syscall: "timebase_info" ret: "mach_kern_return_t" args: "mach_timebase_info_t" */
10424+#define	MACH_SYS_timebase_info	89
10425+
10426+/* syscall: "wait_until" ret: "mach_kern_return_t" args: "u_int64_t" */
10427+#define	MACH_SYS_wait_until	90
10428+
10429+/* syscall: "timer_create" ret: "mach_port_name_t" args: */
10430+#define	MACH_SYS_timer_create	91
10431+
10432+/* syscall: "timer_destroy" ret: "mach_kern_return_t" args: "mach_port_name_t" */
10433+#define	MACH_SYS_timer_destroy	92
10434+
10435+/* syscall: "timer_arm" ret: "mach_kern_return_t" args: "mach_port_name_t" "mach_absolute_time_t" */
10436+#define	MACH_SYS_timer_arm	93
10437+
10438+/* syscall: "timer_cancel" ret: "mach_kern_return_t" args: "mach_port_name_t" "mach_absolute_time_t *" */
10439+#define	MACH_SYS_timer_cancel	94
10440+
10441+/* syscall: "get_time_base_info" ret: "mach_kern_return_t" args: */
10442+#define	MACH_SYS_get_time_base_info	95
10443+
10444+#define	MACH_SYS_MAXSYSCALL	128
10445+#define	MACH_SYS_NSYSENT	128
10446+#endif /* _MACH_SYS_SYSCALL_H_ */
10447diff --git a/sys/compat/mach/mach_syscallargs.h b/sys/compat/mach/mach_syscallargs.h
10448new file mode 100644
10449index 0000000..4361eb2
10450--- /dev/null
10451+++ b/sys/compat/mach/mach_syscallargs.h
10452@@ -0,0 +1,258 @@
10453+/* $NetBSD: mach_syscallargs.h,v 1.21 2009/12/14 00:58:37 matt Exp $ */
10454+
10455+/*
10456+ * System call argument lists.
10457+ *
10458+ * DO NOT EDIT-- this file is automatically generated.
10459+ * created from	NetBSD: syscalls.master,v 1.10 2009/01/13 22:27:43 pooka Exp
10460+ */
10461+
10462+#ifndef _MACH_SYS_SYSCALLARGS_H_
10463+#define	_MACH_SYS_SYSCALLARGS_H_
10464+
10465+#define	MACH_SYS_MAXSYSARGS	9
10466+
10467+#undef	syscallarg
10468+#define	syscallarg(x)							\
10469+	union {								\
10470+		register_t pad;						\
10471+		struct { x datum; } le;					\
10472+		struct { /* LINTED zero array dimension */		\
10473+			int8_t pad[  /* CONSTCOND */			\
10474+				(sizeof (register_t) < sizeof (x))	\
10475+				? 0					\
10476+				: sizeof (register_t) - sizeof (x)];	\
10477+			x datum;					\
10478+		} be;							\
10479+	}
10480+
10481+#undef check_syscall_args
10482+#define check_syscall_args(call) \
10483+	typedef char call##_check_args[sizeof (struct call##_args) \
10484+		<= MACH_SYS_MAXSYSARGS * sizeof (register_t) ? 1 : -1];
10485+
10486+struct mach_sys_msg_trap_args {
10487+	syscallarg(mach_msg_header_t *) msg;
10488+	syscallarg(mach_msg_option_t) option;
10489+	syscallarg(mach_msg_size_t) send_size;
10490+	syscallarg(mach_msg_size_t) rcv_size;
10491+	syscallarg(mach_port_name_t) rcv_name;
10492+	syscallarg(mach_msg_timeout_t) timeout;
10493+	syscallarg(mach_port_name_t) notify;
10494+};
10495+check_syscall_args(mach_sys_msg_trap)
10496+
10497+struct mach_sys_msg_overwrite_trap_args {
10498+	syscallarg(mach_msg_header_t *) msg;
10499+	syscallarg(mach_msg_option_t) option;
10500+	syscallarg(mach_msg_size_t) send_size;
10501+	syscallarg(mach_msg_size_t) rcv_size;
10502+	syscallarg(mach_port_name_t) rcv_name;
10503+	syscallarg(mach_msg_timeout_t) timeout;
10504+	syscallarg(mach_port_name_t) notify;
10505+	syscallarg(mach_msg_header_t *) rcv_msg;
10506+	syscallarg(mach_msg_size_t) scatter_list_size;
10507+};
10508+check_syscall_args(mach_sys_msg_overwrite_trap)
10509+
10510+struct mach_sys_semaphore_signal_trap_args {
10511+	syscallarg(mach_port_name_t) signal_name;
10512+};
10513+check_syscall_args(mach_sys_semaphore_signal_trap)
10514+
10515+struct mach_sys_semaphore_signal_all_trap_args {
10516+	syscallarg(mach_port_name_t) signal_name;
10517+};
10518+check_syscall_args(mach_sys_semaphore_signal_all_trap)
10519+
10520+struct mach_sys_semaphore_signal_thread_trap_args {
10521+	syscallarg(mach_port_name_t) signal_name;
10522+	syscallarg(mach_port_name_t) thread;
10523+};
10524+check_syscall_args(mach_sys_semaphore_signal_thread_trap)
10525+
10526+struct mach_sys_semaphore_wait_trap_args {
10527+	syscallarg(mach_port_name_t) wait_name;
10528+};
10529+check_syscall_args(mach_sys_semaphore_wait_trap)
10530+
10531+struct mach_sys_semaphore_wait_signal_trap_args {
10532+	syscallarg(mach_port_name_t) wait_name;
10533+	syscallarg(mach_port_name_t) signal_name;
10534+};
10535+check_syscall_args(mach_sys_semaphore_wait_signal_trap)
10536+
10537+struct mach_sys_semaphore_timedwait_trap_args {
10538+	syscallarg(mach_port_name_t) wait_name;
10539+	syscallarg(unsigned int) sec;
10540+	syscallarg(mach_clock_res_t) nsec;
10541+};
10542+check_syscall_args(mach_sys_semaphore_timedwait_trap)
10543+
10544+struct mach_sys_semaphore_timedwait_signal_trap_args {
10545+	syscallarg(mach_port_name_t) wait_name;
10546+	syscallarg(mach_port_name_t) signal_name;
10547+	syscallarg(unsigned int) sec;
10548+	syscallarg(mach_clock_res_t) nsec;
10549+};
10550+check_syscall_args(mach_sys_semaphore_timedwait_signal_trap)
10551+
10552+struct mach_sys_map_fd_args {
10553+	syscallarg(int) fd;
10554+	syscallarg(mach_vm_offset_t) offset;
10555+	syscallarg(mach_vm_offset_t *) va;
10556+	syscallarg(mach_boolean_t) findspace;
10557+	syscallarg(mach_vm_size_t) size;
10558+};
10559+check_syscall_args(mach_sys_map_fd)
10560+
10561+struct mach_sys_task_for_pid_args {
10562+	syscallarg(mach_port_t) target_tport;
10563+	syscallarg(int) pid;
10564+	syscallarg(mach_port_t *) t;
10565+};
10566+check_syscall_args(mach_sys_task_for_pid)
10567+
10568+struct mach_sys_pid_for_task_args {
10569+	syscallarg(mach_port_t) t;
10570+	syscallarg(int *) x;
10571+};
10572+check_syscall_args(mach_sys_pid_for_task)
10573+
10574+struct mach_sys_macx_swapon_args {
10575+	syscallarg(char *) name;
10576+	syscallarg(int) flags;
10577+	syscallarg(int) size;
10578+	syscallarg(int) priority;
10579+};
10580+check_syscall_args(mach_sys_macx_swapon)
10581+
10582+struct mach_sys_macx_swapoff_args {
10583+	syscallarg(char *) name;
10584+	syscallarg(int) flags;
10585+};
10586+check_syscall_args(mach_sys_macx_swapoff)
10587+
10588+struct mach_sys_macx_triggers_args {
10589+	syscallarg(int) hi_water;
10590+	syscallarg(int) low_water;
10591+	syscallarg(int) flags;
10592+	syscallarg(mach_port_t) alert_port;
10593+};
10594+check_syscall_args(mach_sys_macx_triggers)
10595+
10596+struct mach_sys_swtch_pri_args {
10597+	syscallarg(int) pri;
10598+};
10599+check_syscall_args(mach_sys_swtch_pri)
10600+
10601+struct mach_sys_syscall_thread_switch_args {
10602+	syscallarg(mach_port_name_t) thread_name;
10603+	syscallarg(int) option;
10604+	syscallarg(mach_msg_timeout_t) option_time;
10605+};
10606+check_syscall_args(mach_sys_syscall_thread_switch)
10607+
10608+struct mach_sys_clock_sleep_trap_args {
10609+	syscallarg(mach_port_name_t) clock_name;
10610+	syscallarg(mach_sleep_type_t) sleep_type;
10611+	syscallarg(int) sleep_sec;
10612+	syscallarg(int) sleep_nsec;
10613+	syscallarg(mach_timespec_t *) wakeup_time;
10614+};
10615+check_syscall_args(mach_sys_clock_sleep_trap)
10616+
10617+struct mach_sys_timebase_info_args {
10618+	syscallarg(mach_timebase_info_t) info;
10619+};
10620+check_syscall_args(mach_sys_timebase_info)
10621+
10622+struct mach_sys_wait_until_args {
10623+	syscallarg(u_int64_t) deadline;
10624+};
10625+check_syscall_args(mach_sys_wait_until)
10626+
10627+struct mach_sys_timer_destroy_args {
10628+	syscallarg(mach_port_name_t) name;
10629+};
10630+check_syscall_args(mach_sys_timer_destroy)
10631+
10632+struct mach_sys_timer_arm_args {
10633+	syscallarg(mach_port_name_t) name;
10634+	syscallarg(mach_absolute_time_t) expire_time;
10635+};
10636+check_syscall_args(mach_sys_timer_arm)
10637+
10638+struct mach_sys_timer_cancel_args {
10639+	syscallarg(mach_port_name_t) name;
10640+	syscallarg(mach_absolute_time_t *) result_time;
10641+};
10642+check_syscall_args(mach_sys_timer_cancel)
10643+
10644+/*
10645+ * System call prototypes.
10646+ */
10647+
10648+int	mach_sys_reply_port(struct lwp *, const void *, register_t *);
10649+
10650+int	mach_sys_thread_self_trap(struct lwp *, const void *, register_t *);
10651+
10652+int	mach_sys_task_self_trap(struct lwp *, const void *, register_t *);
10653+
10654+int	mach_sys_host_self_trap(struct lwp *, const void *, register_t *);
10655+
10656+int	mach_sys_msg_trap(struct lwp *, const struct mach_sys_msg_trap_args *, register_t *);
10657+
10658+int	mach_sys_msg_overwrite_trap(struct lwp *, const struct mach_sys_msg_overwrite_trap_args *, register_t *);
10659+
10660+int	mach_sys_semaphore_signal_trap(struct lwp *, const struct mach_sys_semaphore_signal_trap_args *, register_t *);
10661+
10662+int	mach_sys_semaphore_signal_all_trap(struct lwp *, const struct mach_sys_semaphore_signal_all_trap_args *, register_t *);
10663+
10664+int	mach_sys_semaphore_signal_thread_trap(struct lwp *, const struct mach_sys_semaphore_signal_thread_trap_args *, register_t *);
10665+
10666+int	mach_sys_semaphore_wait_trap(struct lwp *, const struct mach_sys_semaphore_wait_trap_args *, register_t *);
10667+
10668+int	mach_sys_semaphore_wait_signal_trap(struct lwp *, const struct mach_sys_semaphore_wait_signal_trap_args *, register_t *);
10669+
10670+int	mach_sys_semaphore_timedwait_trap(struct lwp *, const struct mach_sys_semaphore_timedwait_trap_args *, register_t *);
10671+
10672+int	mach_sys_semaphore_timedwait_signal_trap(struct lwp *, const struct mach_sys_semaphore_timedwait_signal_trap_args *, register_t *);
10673+
10674+int	mach_sys_init_process(struct lwp *, const void *, register_t *);
10675+
10676+int	mach_sys_map_fd(struct lwp *, const struct mach_sys_map_fd_args *, register_t *);
10677+
10678+int	mach_sys_task_for_pid(struct lwp *, const struct mach_sys_task_for_pid_args *, register_t *);
10679+
10680+int	mach_sys_pid_for_task(struct lwp *, const struct mach_sys_pid_for_task_args *, register_t *);
10681+
10682+int	mach_sys_macx_swapon(struct lwp *, const struct mach_sys_macx_swapon_args *, register_t *);
10683+
10684+int	mach_sys_macx_swapoff(struct lwp *, const struct mach_sys_macx_swapoff_args *, register_t *);
10685+
10686+int	mach_sys_macx_triggers(struct lwp *, const struct mach_sys_macx_triggers_args *, register_t *);
10687+
10688+int	mach_sys_swtch_pri(struct lwp *, const struct mach_sys_swtch_pri_args *, register_t *);
10689+
10690+int	mach_sys_swtch(struct lwp *, const void *, register_t *);
10691+
10692+int	mach_sys_syscall_thread_switch(struct lwp *, const struct mach_sys_syscall_thread_switch_args *, register_t *);
10693+
10694+int	mach_sys_clock_sleep_trap(struct lwp *, const struct mach_sys_clock_sleep_trap_args *, register_t *);
10695+
10696+int	mach_sys_timebase_info(struct lwp *, const struct mach_sys_timebase_info_args *, register_t *);
10697+
10698+int	mach_sys_wait_until(struct lwp *, const struct mach_sys_wait_until_args *, register_t *);
10699+
10700+int	mach_sys_timer_create(struct lwp *, const void *, register_t *);
10701+
10702+int	mach_sys_timer_destroy(struct lwp *, const struct mach_sys_timer_destroy_args *, register_t *);
10703+
10704+int	mach_sys_timer_arm(struct lwp *, const struct mach_sys_timer_arm_args *, register_t *);
10705+
10706+int	mach_sys_timer_cancel(struct lwp *, const struct mach_sys_timer_cancel_args *, register_t *);
10707+
10708+int	mach_sys_get_time_base_info(struct lwp *, const void *, register_t *);
10709+
10710+#endif /* _MACH_SYS_SYSCALLARGS_H_ */
10711diff --git a/sys/compat/mach/mach_syscalls.c b/sys/compat/mach/mach_syscalls.c
10712new file mode 100644
10713index 0000000..f8f7d7b
10714--- /dev/null
10715+++ b/sys/compat/mach/mach_syscalls.c
10716@@ -0,0 +1,159 @@
10717+/* $NetBSD: mach_syscalls.c,v 1.22 2009/12/14 00:58:37 matt Exp $ */
10718+
10719+/*
10720+ * System call names.
10721+ *
10722+ * DO NOT EDIT-- this file is automatically generated.
10723+ * created from	NetBSD: syscalls.master,v 1.10 2009/01/13 22:27:43 pooka Exp
10724+ */
10725+
10726+#include <sys/cdefs.h>
10727+__KERNEL_RCSID(0, "$NetBSD: mach_syscalls.c,v 1.22 2009/12/14 00:58:37 matt Exp $");
10728+
10729+#if defined(_KERNEL_OPT)
10730+#if defined(_KERNEL_OPT)
10731+#include "opt_ntp.h"
10732+#include "opt_sysv.h"
10733+#endif
10734+#include <sys/param.h>
10735+#include <sys/systm.h>
10736+#include <sys/signal.h>
10737+#include <sys/mount.h>
10738+#include <sys/poll.h>
10739+#include <sys/syscallargs.h>
10740+#include <compat/mach/mach_types.h>
10741+#include <compat/mach/mach_message.h>
10742+#include <compat/mach/mach_clock.h>
10743+#include <compat/mach/mach_syscallargs.h>
10744+#endif /* _KERNEL_OPT */
10745+
10746+const char *const mach_syscallnames[] = {
10747+	/*   0 */	"#0 (unimplemented)",
10748+	/*   1 */	"#1 (unimplemented)",
10749+	/*   2 */	"#2 (unimplemented)",
10750+	/*   3 */	"#3 (unimplemented)",
10751+	/*   4 */	"#4 (unimplemented)",
10752+	/*   5 */	"#5 (unimplemented)",
10753+	/*   6 */	"#6 (unimplemented)",
10754+	/*   7 */	"#7 (unimplemented)",
10755+	/*   8 */	"#8 (unimplemented)",
10756+	/*   9 */	"#9 (unimplemented)",
10757+	/*  10 */	"#10 (unimplemented)",
10758+	/*  11 */	"#11 (unimplemented)",
10759+	/*  12 */	"#12 (unimplemented)",
10760+	/*  13 */	"#13 (unimplemented)",
10761+	/*  14 */	"#14 (unimplemented)",
10762+	/*  15 */	"#15 (unimplemented)",
10763+	/*  16 */	"#16 (unimplemented)",
10764+	/*  17 */	"#17 (unimplemented)",
10765+	/*  18 */	"#18 (unimplemented)",
10766+	/*  19 */	"#19 (unimplemented)",
10767+	/*  20 */	"#20 (unimplemented)",
10768+	/*  21 */	"#21 (unimplemented)",
10769+	/*  22 */	"#22 (unimplemented)",
10770+	/*  23 */	"#23 (unimplemented)",
10771+	/*  24 */	"#24 (unimplemented)",
10772+	/*  25 */	"#25 (unimplemented)",
10773+	/*  26 */	"reply_port",
10774+	/*  27 */	"thread_self_trap",
10775+	/*  28 */	"task_self_trap",
10776+	/*  29 */	"host_self_trap",
10777+	/*  30 */	"#30 (unimplemented)",
10778+	/*  31 */	"msg_trap",
10779+	/*  32 */	"msg_overwrite_trap",
10780+	/*  33 */	"semaphore_signal_trap",
10781+	/*  34 */	"semaphore_signal_all_trap",
10782+	/*  35 */	"semaphore_signal_thread_trap",
10783+	/*  36 */	"semaphore_wait_trap",
10784+	/*  37 */	"semaphore_wait_signal_trap",
10785+	/*  38 */	"semaphore_timedwait_trap",
10786+	/*  39 */	"semaphore_timedwait_signal_trap",
10787+	/*  40 */	"#40 (unimplemented)",
10788+	/*  41 */	"init_process",
10789+	/*  42 */	"#42 (unimplemented)",
10790+	/*  43 */	"map_fd",
10791+	/*  44 */	"#44 (unimplemented)",
10792+	/*  45 */	"task_for_pid",
10793+	/*  46 */	"pid_for_task",
10794+	/*  47 */	"#47 (unimplemented)",
10795+	/*  48 */	"macx_swapon",
10796+	/*  49 */	"macx_swapoff",
10797+	/*  50 */	"#50 (unimplemented)",
10798+	/*  51 */	"macx_triggers",
10799+	/*  52 */	"#52 (unimplemented)",
10800+	/*  53 */	"#53 (unimplemented)",
10801+	/*  54 */	"#54 (unimplemented)",
10802+	/*  55 */	"#55 (unimplemented)",
10803+	/*  56 */	"#56 (unimplemented)",
10804+	/*  57 */	"#57 (unimplemented)",
10805+	/*  58 */	"#58 (unimplemented)",
10806+	/*  59 */	"swtch_pri",
10807+	/*  60 */	"swtch",
10808+	/*  61 */	"syscall_thread_switch",
10809+	/*  62 */	"clock_sleep_trap",
10810+	/*  63 */	"#63 (unimplemented)",
10811+	/*  64 */	"#64 (unimplemented)",
10812+	/*  65 */	"#65 (unimplemented)",
10813+	/*  66 */	"#66 (unimplemented)",
10814+	/*  67 */	"#67 (unimplemented)",
10815+	/*  68 */	"#68 (unimplemented)",
10816+	/*  69 */	"#69 (unimplemented)",
10817+	/*  70 */	"#70 (unimplemented)",
10818+	/*  71 */	"#71 (unimplemented)",
10819+	/*  72 */	"#72 (unimplemented)",
10820+	/*  73 */	"#73 (unimplemented)",
10821+	/*  74 */	"#74 (unimplemented)",
10822+	/*  75 */	"#75 (unimplemented)",
10823+	/*  76 */	"#76 (unimplemented)",
10824+	/*  77 */	"#77 (unimplemented)",
10825+	/*  78 */	"#78 (unimplemented)",
10826+	/*  79 */	"#79 (unimplemented)",
10827+	/*  80 */	"#80 (unimplemented)",
10828+	/*  81 */	"#81 (unimplemented)",
10829+	/*  82 */	"#82 (unimplemented)",
10830+	/*  83 */	"#83 (unimplemented)",
10831+	/*  84 */	"#84 (unimplemented)",
10832+	/*  85 */	"#85 (unimplemented)",
10833+	/*  86 */	"#86 (unimplemented)",
10834+	/*  87 */	"#87 (unimplemented)",
10835+	/*  88 */	"#88 (unimplemented)",
10836+	/*  89 */	"timebase_info",
10837+	/*  90 */	"wait_until",
10838+	/*  91 */	"timer_create",
10839+	/*  92 */	"timer_destroy",
10840+	/*  93 */	"timer_arm",
10841+	/*  94 */	"timer_cancel",
10842+	/*  95 */	"get_time_base_info",
10843+	/*  96 */	"#96 (unimplemented)",
10844+	/*  97 */	"#97 (unimplemented)",
10845+	/*  98 */	"#98 (unimplemented)",
10846+	/*  99 */	"#99 (unimplemented)",
10847+	/* 100 */	"#100 (unimplemented)",
10848+	/* 101 */	"#101 (unimplemented)",
10849+	/* 102 */	"#102 (unimplemented)",
10850+	/* 103 */	"#103 (unimplemented)",
10851+	/* 104 */	"#104 (unimplemented)",
10852+	/* 105 */	"#105 (unimplemented)",
10853+	/* 106 */	"#106 (unimplemented)",
10854+	/* 107 */	"#107 (unimplemented)",
10855+	/* 108 */	"#108 (unimplemented)",
10856+	/* 109 */	"#109 (unimplemented)",
10857+	/* 110 */	"#110 (unimplemented)",
10858+	/* 111 */	"#111 (unimplemented)",
10859+	/* 112 */	"#112 (unimplemented)",
10860+	/* 113 */	"#113 (unimplemented)",
10861+	/* 114 */	"#114 (unimplemented)",
10862+	/* 115 */	"#115 (unimplemented)",
10863+	/* 116 */	"#116 (unimplemented)",
10864+	/* 117 */	"#117 (unimplemented)",
10865+	/* 118 */	"#118 (unimplemented)",
10866+	/* 119 */	"#119 (unimplemented)",
10867+	/* 120 */	"#120 (unimplemented)",
10868+	/* 121 */	"#121 (unimplemented)",
10869+	/* 122 */	"#122 (unimplemented)",
10870+	/* 123 */	"#123 (unimplemented)",
10871+	/* 124 */	"#124 (unimplemented)",
10872+	/* 125 */	"#125 (unimplemented)",
10873+	/* 126 */	"#126 (unimplemented)",
10874+	/* 127 */	"#127 (unimplemented)",
10875+};
10876diff --git a/sys/compat/mach/mach_sysctl.c b/sys/compat/mach/mach_sysctl.c
10877new file mode 100644
10878index 0000000..07421ee
10879--- /dev/null
10880+++ b/sys/compat/mach/mach_sysctl.c
10881@@ -0,0 +1,73 @@
10882+/*	$NetBSD: mach_sysctl.c,v 1.4 2008/04/28 20:23:44 martin Exp $ */
10883+
10884+/*-
10885+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
10886+ * All rights reserved.
10887+ *
10888+ * This code is derived from software contributed to The NetBSD Foundation
10889+ * by Emmanuel Dreyfus
10890+ *
10891+ * Redistribution and use in source and binary forms, with or without
10892+ * modification, are permitted provided that the following conditions
10893+ * are met:
10894+ * 1. Redistributions of source code must retain the above copyright
10895+ *    notice, this list of conditions and the following disclaimer.
10896+ * 2. Redistributions in binary form must reproduce the above copyright
10897+ *    notice, this list of conditions and the following disclaimer in the
10898+ *    documentation and/or other materials provided with the distribution.
10899+ *
10900+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
10901+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
10902+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10903+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
10904+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
10905+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
10906+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
10907+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
10908+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10909+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
10910+ * POSSIBILITY OF SUCH DAMAGE.
10911+ */
10912+
10913+#include <sys/cdefs.h>
10914+__KERNEL_RCSID(0, "$NetBSD: mach_sysctl.c,v 1.4 2008/04/28 20:23:44 martin Exp $");
10915+
10916+#include <sys/param.h>
10917+#include <sys/types.h>
10918+#include <sys/resource.h>
10919+#include <sys/sysctl.h>
10920+
10921+#include <compat/mach/mach_sysctl.h>
10922+
10923+int mach_exception_hang = 0;
10924+
10925+SYSCTL_SETUP(sysctl_emul_mach_setup, "sysctl emul.mach subtree setup")
10926+{
10927+
10928+	sysctl_createv(clog, 0, NULL, NULL,
10929+		       CTLFLAG_PERMANENT,
10930+		       CTLTYPE_NODE, "emul", NULL,
10931+		       NULL, 0, NULL, 0,
10932+		       CTL_EMUL, CTL_EOL);
10933+	sysctl_createv(clog, 0, NULL, NULL,
10934+		       CTLFLAG_PERMANENT,
10935+		       CTLTYPE_NODE, "mach",
10936+		       SYSCTL_DESCR("Mach emulation settings"),
10937+		       NULL, 0, NULL, 0,
10938+		       CTL_EMUL, EMUL_MACH, CTL_EOL);
10939+	sysctl_createv(clog, 0, NULL, NULL,
10940+		       CTLFLAG_PERMANENT,
10941+		       CTLTYPE_NODE, "exception",
10942+		       SYSCTL_DESCR("Mach exceptions settings"),
10943+		       NULL, 0, NULL, 0,
10944+		       CTL_EMUL, EMUL_MACH,
10945+		       EMUL_MACH_EXCEPTION, CTL_EOL);
10946+	sysctl_createv(clog, 0, NULL, NULL,
10947+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
10948+		       CTLTYPE_INT, "hang",
10949+		       SYSCTL_DESCR("Mach exceptions hang the process"),
10950+		       NULL, 0, &mach_exception_hang, 0,
10951+		       CTL_EMUL, EMUL_MACH, EMUL_MACH_EXCEPTION,
10952+		       EMUL_MACH_EXCEPTION_HANG, CTL_EOL);
10953+}
10954+
10955diff --git a/sys/compat/mach/mach_sysctl.h b/sys/compat/mach/mach_sysctl.h
10956new file mode 100644
10957index 0000000..6f6a422
10958--- /dev/null
10959+++ b/sys/compat/mach/mach_sysctl.h
10960@@ -0,0 +1,43 @@
10961+/*	$NetBSD: mach_sysctl.h,v 1.3 2008/04/28 20:23:44 martin Exp $ */
10962+
10963+/*-
10964+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
10965+ * All rights reserved.
10966+ *
10967+ * This code is derived from software contributed to The NetBSD Foundation
10968+ * by Emmanuel Dreyfus
10969+ *
10970+ * Redistribution and use in source and binary forms, with or without
10971+ * modification, are permitted provided that the following conditions
10972+ * are met:
10973+ * 1. Redistributions of source code must retain the above copyright
10974+ *    notice, this list of conditions and the following disclaimer.
10975+ * 2. Redistributions in binary form must reproduce the above copyright
10976+ *    notice, this list of conditions and the following disclaimer in the
10977+ *    documentation and/or other materials provided with the distribution.
10978+ *
10979+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
10980+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
10981+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10982+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
10983+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
10984+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
10985+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
10986+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
10987+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10988+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
10989+ * POSSIBILITY OF SUCH DAMAGE.
10990+ */
10991+
10992+#ifndef	_MACH_SYSCTL_H_
10993+#define	_MACH_SYSCTL_H_
10994+
10995+extern int mach_exception_hang;
10996+
10997+#define EMUL_MACH_EXCEPTION		1
10998+#define EMUL_MACH_MAXID			2
10999+
11000+#define EMUL_MACH_EXCEPTION_HANG	1
11001+#define EMUL_MACH_EXCEPTION_MAXID	2
11002+
11003+#endif /* _MACH_SYSCTL_H_ */
11004diff --git a/sys/compat/mach/mach_sysent.c b/sys/compat/mach/mach_sysent.c
11005new file mode 100644
11006index 0000000..fc925f6
11007--- /dev/null
11008+++ b/sys/compat/mach/mach_sysent.c
11009@@ -0,0 +1,289 @@
11010+/* $NetBSD: mach_sysent.c,v 1.23 2009/12/14 00:58:37 matt Exp $ */
11011+
11012+/*
11013+ * System call switch table.
11014+ *
11015+ * DO NOT EDIT-- this file is automatically generated.
11016+ * created from	NetBSD: syscalls.master,v 1.10 2009/01/13 22:27:43 pooka Exp
11017+ */
11018+
11019+#include <sys/cdefs.h>
11020+__KERNEL_RCSID(0, "$NetBSD: mach_sysent.c,v 1.23 2009/12/14 00:58:37 matt Exp $");
11021+
11022+#if defined(_KERNEL_OPT)
11023+#include "opt_ntp.h"
11024+#include "opt_sysv.h"
11025+#endif
11026+#include <sys/param.h>
11027+#include <sys/systm.h>
11028+#include <sys/signal.h>
11029+#include <sys/mount.h>
11030+#include <sys/poll.h>
11031+#include <sys/syscallargs.h>
11032+#include <compat/mach/mach_types.h>
11033+#include <compat/mach/mach_message.h>
11034+#include <compat/mach/mach_clock.h>
11035+#include <compat/mach/mach_syscallargs.h>
11036+
11037+#define	s(type)	sizeof(type)
11038+#define	n(type)	(sizeof(type)/sizeof (register_t))
11039+#define	ns(type)	n(type), s(type)
11040+
11041+struct sysent mach_sysent[] = {
11042+	{ 0, 0, 0,
11043+	    sys_nosys },			/* 0 = unimplemented */
11044+	{ 0, 0, 0,
11045+	    sys_nosys },			/* 1 = unimplemented */
11046+	{ 0, 0, 0,
11047+	    sys_nosys },			/* 2 = unimplemented */
11048+	{ 0, 0, 0,
11049+	    sys_nosys },			/* 3 = unimplemented */
11050+	{ 0, 0, 0,
11051+	    sys_nosys },			/* 4 = unimplemented */
11052+	{ 0, 0, 0,
11053+	    sys_nosys },			/* 5 = unimplemented */
11054+	{ 0, 0, 0,
11055+	    sys_nosys },			/* 6 = unimplemented */
11056+	{ 0, 0, 0,
11057+	    sys_nosys },			/* 7 = unimplemented */
11058+	{ 0, 0, 0,
11059+	    sys_nosys },			/* 8 = unimplemented */
11060+	{ 0, 0, 0,
11061+	    sys_nosys },			/* 9 = unimplemented */
11062+	{ 0, 0, 0,
11063+	    sys_nosys },			/* 10 = unimplemented */
11064+	{ 0, 0, 0,
11065+	    sys_nosys },			/* 11 = unimplemented */
11066+	{ 0, 0, 0,
11067+	    sys_nosys },			/* 12 = unimplemented */
11068+	{ 0, 0, 0,
11069+	    sys_nosys },			/* 13 = unimplemented */
11070+	{ 0, 0, 0,
11071+	    sys_nosys },			/* 14 = unimplemented */
11072+	{ 0, 0, 0,
11073+	    sys_nosys },			/* 15 = unimplemented */
11074+	{ 0, 0, 0,
11075+	    sys_nosys },			/* 16 = unimplemented */
11076+	{ 0, 0, 0,
11077+	    sys_nosys },			/* 17 = unimplemented */
11078+	{ 0, 0, 0,
11079+	    sys_nosys },			/* 18 = unimplemented */
11080+	{ 0, 0, 0,
11081+	    sys_nosys },			/* 19 = unimplemented */
11082+	{ 0, 0, 0,
11083+	    sys_nosys },			/* 20 = unimplemented */
11084+	{ 0, 0, 0,
11085+	    sys_nosys },			/* 21 = unimplemented */
11086+	{ 0, 0, 0,
11087+	    sys_nosys },			/* 22 = unimplemented */
11088+	{ 0, 0, 0,
11089+	    sys_nosys },			/* 23 = unimplemented */
11090+	{ 0, 0, 0,
11091+	    sys_nosys },			/* 24 = unimplemented */
11092+	{ 0, 0, 0,
11093+	    sys_nosys },			/* 25 = unimplemented */
11094+	{ 0, 0, 0,
11095+	    (sy_call_t *)mach_sys_reply_port },	/* 26 = reply_port */
11096+	{ 0, 0, 0,
11097+	    (sy_call_t *)mach_sys_thread_self_trap },/* 27 = thread_self_trap */
11098+	{ 0, 0, 0,
11099+	    (sy_call_t *)mach_sys_task_self_trap },/* 28 = task_self_trap */
11100+	{ 0, 0, 0,
11101+	    (sy_call_t *)mach_sys_host_self_trap },/* 29 = host_self_trap */
11102+	{ 0, 0, 0,
11103+	    sys_nosys },			/* 30 = unimplemented */
11104+	{ ns(struct mach_sys_msg_trap_args), 0,
11105+	    (sy_call_t *)mach_sys_msg_trap },	/* 31 = msg_trap */
11106+	{ ns(struct mach_sys_msg_overwrite_trap_args), 0,
11107+	    (sy_call_t *)mach_sys_msg_overwrite_trap },/* 32 = msg_overwrite_trap */
11108+	{ ns(struct mach_sys_semaphore_signal_trap_args), 0,
11109+	    (sy_call_t *)mach_sys_semaphore_signal_trap },/* 33 = semaphore_signal_trap */
11110+	{ ns(struct mach_sys_semaphore_signal_all_trap_args), 0,
11111+	    (sy_call_t *)mach_sys_semaphore_signal_all_trap },/* 34 = semaphore_signal_all_trap */
11112+	{ ns(struct mach_sys_semaphore_signal_thread_trap_args), 0,
11113+	    (sy_call_t *)mach_sys_semaphore_signal_thread_trap },/* 35 = semaphore_signal_thread_trap */
11114+	{ ns(struct mach_sys_semaphore_wait_trap_args), 0,
11115+	    (sy_call_t *)mach_sys_semaphore_wait_trap },/* 36 = semaphore_wait_trap */
11116+	{ ns(struct mach_sys_semaphore_wait_signal_trap_args), 0,
11117+	    (sy_call_t *)mach_sys_semaphore_wait_signal_trap },/* 37 = semaphore_wait_signal_trap */
11118+	{ ns(struct mach_sys_semaphore_timedwait_trap_args), 0,
11119+	    (sy_call_t *)mach_sys_semaphore_timedwait_trap },/* 38 = semaphore_timedwait_trap */
11120+	{ ns(struct mach_sys_semaphore_timedwait_signal_trap_args), 0,
11121+	    (sy_call_t *)mach_sys_semaphore_timedwait_signal_trap },/* 39 = semaphore_timedwait_signal_trap */
11122+	{ 0, 0, 0,
11123+	    sys_nosys },			/* 40 = unimplemented */
11124+	{ 0, 0, 0,
11125+	    (sy_call_t *)mach_sys_init_process },/* 41 = init_process */
11126+	{ 0, 0, 0,
11127+	    sys_nosys },			/* 42 = unimplemented */
11128+	{ ns(struct mach_sys_map_fd_args), 0,
11129+	    (sy_call_t *)mach_sys_map_fd },	/* 43 = map_fd */
11130+	{ 0, 0, 0,
11131+	    sys_nosys },			/* 44 = unimplemented */
11132+	{ ns(struct mach_sys_task_for_pid_args), 0,
11133+	    (sy_call_t *)mach_sys_task_for_pid },/* 45 = task_for_pid */
11134+	{ ns(struct mach_sys_pid_for_task_args), 0,
11135+	    (sy_call_t *)mach_sys_pid_for_task },/* 46 = pid_for_task */
11136+	{ 0, 0, 0,
11137+	    sys_nosys },			/* 47 = unimplemented */
11138+	{ ns(struct mach_sys_macx_swapon_args), 0,
11139+	    (sy_call_t *)mach_sys_macx_swapon },/* 48 = macx_swapon */
11140+	{ ns(struct mach_sys_macx_swapoff_args), 0,
11141+	    (sy_call_t *)mach_sys_macx_swapoff },/* 49 = macx_swapoff */
11142+	{ 0, 0, 0,
11143+	    sys_nosys },			/* 50 = unimplemented */
11144+	{ ns(struct mach_sys_macx_triggers_args), 0,
11145+	    (sy_call_t *)mach_sys_macx_triggers },/* 51 = macx_triggers */
11146+	{ 0, 0, 0,
11147+	    sys_nosys },			/* 52 = unimplemented */
11148+	{ 0, 0, 0,
11149+	    sys_nosys },			/* 53 = unimplemented */
11150+	{ 0, 0, 0,
11151+	    sys_nosys },			/* 54 = unimplemented */
11152+	{ 0, 0, 0,
11153+	    sys_nosys },			/* 55 = unimplemented */
11154+	{ 0, 0, 0,
11155+	    sys_nosys },			/* 56 = unimplemented */
11156+	{ 0, 0, 0,
11157+	    sys_nosys },			/* 57 = unimplemented */
11158+	{ 0, 0, 0,
11159+	    sys_nosys },			/* 58 = unimplemented */
11160+	{ ns(struct mach_sys_swtch_pri_args), 0,
11161+	    (sy_call_t *)mach_sys_swtch_pri },	/* 59 = swtch_pri */
11162+	{ 0, 0, 0,
11163+	    (sy_call_t *)mach_sys_swtch },	/* 60 = swtch */
11164+	{ ns(struct mach_sys_syscall_thread_switch_args), 0,
11165+	    (sy_call_t *)mach_sys_syscall_thread_switch },/* 61 = syscall_thread_switch */
11166+	{ ns(struct mach_sys_clock_sleep_trap_args), 0,
11167+	    (sy_call_t *)mach_sys_clock_sleep_trap },/* 62 = clock_sleep_trap */
11168+	{ 0, 0, 0,
11169+	    sys_nosys },			/* 63 = unimplemented */
11170+	{ 0, 0, 0,
11171+	    sys_nosys },			/* 64 = unimplemented */
11172+	{ 0, 0, 0,
11173+	    sys_nosys },			/* 65 = unimplemented */
11174+	{ 0, 0, 0,
11175+	    sys_nosys },			/* 66 = unimplemented */
11176+	{ 0, 0, 0,
11177+	    sys_nosys },			/* 67 = unimplemented */
11178+	{ 0, 0, 0,
11179+	    sys_nosys },			/* 68 = unimplemented */
11180+	{ 0, 0, 0,
11181+	    sys_nosys },			/* 69 = unimplemented */
11182+	{ 0, 0, 0,
11183+	    sys_nosys },			/* 70 = unimplemented */
11184+	{ 0, 0, 0,
11185+	    sys_nosys },			/* 71 = unimplemented */
11186+	{ 0, 0, 0,
11187+	    sys_nosys },			/* 72 = unimplemented */
11188+	{ 0, 0, 0,
11189+	    sys_nosys },			/* 73 = unimplemented */
11190+	{ 0, 0, 0,
11191+	    sys_nosys },			/* 74 = unimplemented */
11192+	{ 0, 0, 0,
11193+	    sys_nosys },			/* 75 = unimplemented */
11194+	{ 0, 0, 0,
11195+	    sys_nosys },			/* 76 = unimplemented */
11196+	{ 0, 0, 0,
11197+	    sys_nosys },			/* 77 = unimplemented */
11198+	{ 0, 0, 0,
11199+	    sys_nosys },			/* 78 = unimplemented */
11200+	{ 0, 0, 0,
11201+	    sys_nosys },			/* 79 = unimplemented */
11202+	{ 0, 0, 0,
11203+	    sys_nosys },			/* 80 = unimplemented */
11204+	{ 0, 0, 0,
11205+	    sys_nosys },			/* 81 = unimplemented */
11206+	{ 0, 0, 0,
11207+	    sys_nosys },			/* 82 = unimplemented */
11208+	{ 0, 0, 0,
11209+	    sys_nosys },			/* 83 = unimplemented */
11210+	{ 0, 0, 0,
11211+	    sys_nosys },			/* 84 = unimplemented */
11212+	{ 0, 0, 0,
11213+	    sys_nosys },			/* 85 = unimplemented */
11214+	{ 0, 0, 0,
11215+	    sys_nosys },			/* 86 = unimplemented */
11216+	{ 0, 0, 0,
11217+	    sys_nosys },			/* 87 = unimplemented */
11218+	{ 0, 0, 0,
11219+	    sys_nosys },			/* 88 = unimplemented */
11220+	{ ns(struct mach_sys_timebase_info_args), 0,
11221+	    (sy_call_t *)mach_sys_timebase_info },/* 89 = timebase_info */
11222+	{ ns(struct mach_sys_wait_until_args), 0,
11223+	    (sy_call_t *)mach_sys_wait_until },	/* 90 = wait_until */
11224+	{ 0, 0, 0,
11225+	    (sy_call_t *)mach_sys_timer_create },/* 91 = timer_create */
11226+	{ ns(struct mach_sys_timer_destroy_args), 0,
11227+	    (sy_call_t *)mach_sys_timer_destroy },/* 92 = timer_destroy */
11228+	{ ns(struct mach_sys_timer_arm_args), 0,
11229+	    (sy_call_t *)mach_sys_timer_arm },	/* 93 = timer_arm */
11230+	{ ns(struct mach_sys_timer_cancel_args), 0,
11231+	    (sy_call_t *)mach_sys_timer_cancel },/* 94 = timer_cancel */
11232+	{ 0, 0, 0,
11233+	    (sy_call_t *)mach_sys_get_time_base_info },/* 95 = get_time_base_info */
11234+	{ 0, 0, 0,
11235+	    sys_nosys },			/* 96 = unimplemented */
11236+	{ 0, 0, 0,
11237+	    sys_nosys },			/* 97 = unimplemented */
11238+	{ 0, 0, 0,
11239+	    sys_nosys },			/* 98 = unimplemented */
11240+	{ 0, 0, 0,
11241+	    sys_nosys },			/* 99 = unimplemented */
11242+	{ 0, 0, 0,
11243+	    sys_nosys },			/* 100 = unimplemented */
11244+	{ 0, 0, 0,
11245+	    sys_nosys },			/* 101 = unimplemented */
11246+	{ 0, 0, 0,
11247+	    sys_nosys },			/* 102 = unimplemented */
11248+	{ 0, 0, 0,
11249+	    sys_nosys },			/* 103 = unimplemented */
11250+	{ 0, 0, 0,
11251+	    sys_nosys },			/* 104 = unimplemented */
11252+	{ 0, 0, 0,
11253+	    sys_nosys },			/* 105 = unimplemented */
11254+	{ 0, 0, 0,
11255+	    sys_nosys },			/* 106 = unimplemented */
11256+	{ 0, 0, 0,
11257+	    sys_nosys },			/* 107 = unimplemented */
11258+	{ 0, 0, 0,
11259+	    sys_nosys },			/* 108 = unimplemented */
11260+	{ 0, 0, 0,
11261+	    sys_nosys },			/* 109 = unimplemented */
11262+	{ 0, 0, 0,
11263+	    sys_nosys },			/* 110 = unimplemented */
11264+	{ 0, 0, 0,
11265+	    sys_nosys },			/* 111 = unimplemented */
11266+	{ 0, 0, 0,
11267+	    sys_nosys },			/* 112 = unimplemented */
11268+	{ 0, 0, 0,
11269+	    sys_nosys },			/* 113 = unimplemented */
11270+	{ 0, 0, 0,
11271+	    sys_nosys },			/* 114 = unimplemented */
11272+	{ 0, 0, 0,
11273+	    sys_nosys },			/* 115 = unimplemented */
11274+	{ 0, 0, 0,
11275+	    sys_nosys },			/* 116 = unimplemented */
11276+	{ 0, 0, 0,
11277+	    sys_nosys },			/* 117 = unimplemented */
11278+	{ 0, 0, 0,
11279+	    sys_nosys },			/* 118 = unimplemented */
11280+	{ 0, 0, 0,
11281+	    sys_nosys },			/* 119 = unimplemented */
11282+	{ 0, 0, 0,
11283+	    sys_nosys },			/* 120 = unimplemented */
11284+	{ 0, 0, 0,
11285+	    sys_nosys },			/* 121 = unimplemented */
11286+	{ 0, 0, 0,
11287+	    sys_nosys },			/* 122 = unimplemented */
11288+	{ 0, 0, 0,
11289+	    sys_nosys },			/* 123 = unimplemented */
11290+	{ 0, 0, 0,
11291+	    sys_nosys },			/* 124 = unimplemented */
11292+	{ 0, 0, 0,
11293+	    sys_nosys },			/* 125 = unimplemented */
11294+	{ 0, 0, 0,
11295+	    sys_nosys },			/* 126 = unimplemented */
11296+	{ 0, 0, 0,
11297+	    sys_nosys },			/* 127 = unimplemented */
11298+};
11299diff --git a/sys/compat/mach/mach_task.c b/sys/compat/mach/mach_task.c
11300new file mode 100644
11301index 0000000..d37c571
11302--- /dev/null
11303+++ b/sys/compat/mach/mach_task.c
11304@@ -0,0 +1,707 @@
11305+/*	$NetBSD: mach_task.c,v 1.72 2010/07/01 02:38:29 rmind Exp $ */
11306+
11307+/*-
11308+ * Copyright (c) 2002-2003, 2008 The NetBSD Foundation, Inc.
11309+ * All rights reserved.
11310+ *
11311+ * This code is derived from software contributed to The NetBSD Foundation
11312+ * by Emmanuel Dreyfus
11313+ *
11314+ * Redistribution and use in source and binary forms, with or without
11315+ * modification, are permitted provided that the following conditions
11316+ * are met:
11317+ * 1. Redistributions of source code must retain the above copyright
11318+ *    notice, this list of conditions and the following disclaimer.
11319+ * 2. Redistributions in binary form must reproduce the above copyright
11320+ *    notice, this list of conditions and the following disclaimer in the
11321+ *    documentation and/or other materials provided with the distribution.
11322+ *
11323+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
11324+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
11325+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
11326+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
11327+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
11328+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
11329+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
11330+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
11331+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
11332+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
11333+ * POSSIBILITY OF SUCH DAMAGE.
11334+ */
11335+
11336+#include "opt_compat_darwin.h"
11337+
11338+#include <sys/cdefs.h>
11339+__KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.72 2010/07/01 02:38:29 rmind Exp $");
11340+
11341+#include <sys/types.h>
11342+#include <sys/param.h>
11343+#include <sys/exec.h>
11344+#include <sys/systm.h>
11345+#include <sys/proc.h>
11346+#include <sys/ktrace.h>
11347+#include <sys/resourcevar.h>
11348+#include <sys/malloc.h>
11349+#include <sys/mount.h>
11350+#include <sys/syscallargs.h>
11351+#include <sys/kauth.h>
11352+
11353+#include <uvm/uvm_extern.h>
11354+#include <uvm/uvm_param.h>
11355+
11356+#include <compat/mach/mach_types.h>
11357+#include <compat/mach/mach_message.h>
11358+#include <compat/mach/mach_clock.h>
11359+#include <compat/mach/mach_errno.h>
11360+#include <compat/mach/mach_exec.h>
11361+#include <compat/mach/mach_port.h>
11362+#include <compat/mach/mach_task.h>
11363+#include <compat/mach/mach_services.h>
11364+#include <compat/mach/mach_syscallargs.h>
11365+
11366+#ifdef COMPAT_DARWIN
11367+#include <compat/darwin/darwin_exec.h>
11368+#endif
11369+
11370+#define ISSET(t, f)     ((t) & (f))
11371+
11372+static void
11373+update_exception_port(struct mach_emuldata *, int exc, struct mach_port *);
11374+
11375+int
11376+mach_task_get_special_port(struct mach_trap_args *args)
11377+{
11378+	mach_task_get_special_port_request_t *req = args->smsg;
11379+	mach_task_get_special_port_reply_t *rep = args->rmsg;
11380+	size_t *msglen = args->rsize;
11381+	struct lwp *l = args->l;
11382+	struct lwp *tl = args->tl;
11383+	struct mach_emuldata *med;
11384+	struct mach_right *mr;
11385+
11386+	med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
11387+
11388+	switch (req->req_which_port) {
11389+	case MACH_TASK_KERNEL_PORT:
11390+		mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
11391+		break;
11392+
11393+	case MACH_TASK_HOST_PORT:
11394+		mr = mach_right_get(med->med_host, l, MACH_PORT_TYPE_SEND, 0);
11395+		break;
11396+
11397+	case MACH_TASK_BOOTSTRAP_PORT:
11398+		mr = mach_right_get(med->med_bootstrap,
11399+		    l, MACH_PORT_TYPE_SEND, 0);
11400+		break;
11401+
11402+	case MACH_TASK_WIRED_LEDGER_PORT:
11403+	case MACH_TASK_PAGED_LEDGER_PORT:
11404+	default:
11405+		uprintf("mach_task_get_special_port(): unimpl. port %d\n",
11406+		    req->req_which_port);
11407+		return mach_msg_error(args, EINVAL);
11408+		break;
11409+	}
11410+
11411+	*msglen = sizeof(*rep);
11412+	mach_set_header(rep, req, *msglen);
11413+	mach_add_port_desc(rep, mr->mr_name);
11414+	mach_set_trailer(rep, *msglen);
11415+
11416+	return 0;
11417+}
11418+
11419+int
11420+mach_ports_lookup(struct mach_trap_args *args)
11421+{
11422+	mach_ports_lookup_request_t *req = args->smsg;
11423+	mach_ports_lookup_reply_t *rep = args->rmsg;
11424+	size_t *msglen = args->rsize;
11425+	struct lwp *l = args->l;
11426+	struct lwp *tl = args->tl;
11427+	struct mach_emuldata *med;
11428+	struct mach_right *mr;
11429+	mach_port_name_t mnp[7];
11430+	void *uaddr;
11431+	int error;
11432+	int count;
11433+
11434+	/*
11435+	 * This is some out of band data sent with the reply. In the
11436+	 * encountered situation, the out of band data has always been null
11437+	 * filled. We have to see more of this in order to fully understand
11438+	 * how this trap works.
11439+	 */
11440+	med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
11441+	mnp[0] = (mach_port_name_t)MACH_PORT_DEAD;
11442+	mnp[3] = (mach_port_name_t)MACH_PORT_DEAD;
11443+	mnp[5] = (mach_port_name_t)MACH_PORT_DEAD;
11444+	mnp[6] = (mach_port_name_t)MACH_PORT_DEAD;
11445+
11446+	mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
11447+	mnp[MACH_TASK_KERNEL_PORT] = mr->mr_name;
11448+	mr = mach_right_get(med->med_host, l, MACH_PORT_TYPE_SEND, 0);
11449+	mnp[MACH_TASK_HOST_PORT] = mr->mr_name;
11450+	mr = mach_right_get(med->med_bootstrap, l, MACH_PORT_TYPE_SEND, 0);
11451+	mnp[MACH_TASK_BOOTSTRAP_PORT] = mr->mr_name;
11452+
11453+	/*
11454+	 * On Darwin, the data seems always null...
11455+	 */
11456+	uaddr = NULL;
11457+	if ((error = mach_ool_copyout(l, &mnp[0],
11458+	    &uaddr, sizeof(mnp), MACH_OOL_TRACE)) != 0)
11459+		return mach_msg_error(args, error);
11460+
11461+	count = 3; /* XXX Shouldn't this be 7? */
11462+
11463+	*msglen = sizeof(*rep);
11464+	mach_set_header(rep, req, *msglen);
11465+	mach_add_ool_ports_desc(rep, uaddr, count);
11466+
11467+	rep->rep_init_port_set_count = count;
11468+
11469+	mach_set_trailer(rep, *msglen);
11470+
11471+	return 0;
11472+}
11473+
11474+int
11475+mach_task_set_special_port(struct mach_trap_args *args)
11476+{
11477+	mach_task_set_special_port_request_t *req = args->smsg;
11478+	mach_task_set_special_port_reply_t *rep = args->rmsg;
11479+	size_t *msglen = args->rsize;
11480+	struct lwp *l = args->l;
11481+	struct lwp *tl = args->tl;
11482+	mach_port_t mn;
11483+	struct mach_right *mr;
11484+	struct mach_port *mp;
11485+	struct mach_emuldata *med;
11486+
11487+	mn = req->req_special_port.name;
11488+
11489+	/* Null port ? */
11490+	if (mn == 0)
11491+		return mach_msg_error(args, 0);
11492+
11493+	/* Does the inserted port exists? */
11494+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
11495+		return mach_msg_error(args, EPERM);
11496+
11497+	if (mr->mr_type == MACH_PORT_TYPE_DEAD_NAME)
11498+		return mach_msg_error(args, EINVAL);
11499+
11500+	med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
11501+
11502+	switch (req->req_which_port) {
11503+	case MACH_TASK_KERNEL_PORT:
11504+		mp = med->med_kernel;
11505+		med->med_kernel = mr->mr_port;
11506+		if (mr->mr_port != NULL)
11507+			MACH_PORT_REF(mr->mr_port);
11508+		MACH_PORT_UNREF(mp);
11509+		break;
11510+
11511+	case MACH_TASK_HOST_PORT:
11512+		mp = med->med_host;
11513+		med->med_host = mr->mr_port;
11514+		if (mr->mr_port != NULL)
11515+			MACH_PORT_REF(mr->mr_port);
11516+		MACH_PORT_UNREF(mp);
11517+		break;
11518+
11519+	case MACH_TASK_BOOTSTRAP_PORT:
11520+		mp = med->med_bootstrap;
11521+		med->med_bootstrap = mr->mr_port;
11522+		if (mr->mr_port != NULL)
11523+			MACH_PORT_REF(mr->mr_port);
11524+		MACH_PORT_UNREF(mp);
11525+#ifdef COMPAT_DARWIN
11526+		/*
11527+		 * mach_init sets the bootstrap port for any new process.
11528+		 */
11529+		{
11530+			struct darwin_emuldata *ded;
11531+
11532+			ded = tl->l_proc->p_emuldata;
11533+			if (ded->ded_fakepid == 1) {
11534+				mach_bootstrap_port = med->med_bootstrap;
11535+#ifdef DEBUG_DARWIN
11536+				printf("*** New bootstrap port %p, "
11537+				    "recv %p [%p]\n",
11538+				    mach_bootstrap_port,
11539+				    mach_bootstrap_port->mp_recv,
11540+				    mach_bootstrap_port->mp_recv->mr_sethead);
11541+#endif /* DEBUG_DARWIN */
11542+			}
11543+		}
11544+#endif /* COMPAT_DARWIN */
11545+		break;
11546+
11547+	default:
11548+		uprintf("mach_task_set_special_port: unimplemented port %d\n",
11549+		    req->req_which_port);
11550+	}
11551+
11552+	*msglen = sizeof(*rep);
11553+	mach_set_header(rep, req, *msglen);
11554+
11555+	rep->rep_retval = 0;
11556+
11557+	mach_set_trailer(rep, *msglen);
11558+
11559+	return 0;
11560+}
11561+
11562+int
11563+mach_task_threads(struct mach_trap_args *args)
11564+{
11565+	mach_task_threads_request_t *req = args->smsg;
11566+	mach_task_threads_reply_t *rep = args->rmsg;
11567+	size_t *msglen = args->rsize;
11568+	struct lwp *l = args->l;
11569+	struct lwp *tl = args->tl;
11570+	struct proc *tp = tl->l_proc;
11571+	struct lwp *cl;
11572+	struct mach_emuldata *med;
11573+	struct mach_lwp_emuldata *mle;
11574+	int error;
11575+	void *uaddr;
11576+	size_t size;
11577+	int i = 0;
11578+	struct mach_right *mr;
11579+	mach_port_name_t *mnp;
11580+
11581+	med = tp->p_emuldata;
11582+	size = tp->p_nlwps * sizeof(*mnp);
11583+	mnp = malloc(size, M_TEMP, M_WAITOK);
11584+	uaddr = NULL;
11585+
11586+	LIST_FOREACH(cl, &tp->p_lwps, l_sibling) {
11587+		mle = cl->l_emuldata;
11588+		mr = mach_right_get(mle->mle_kernel, l, MACH_PORT_TYPE_SEND, 0);
11589+		mnp[i++] = mr->mr_name;
11590+	}
11591+
11592+	/* This will free mnp */
11593+	if ((error = mach_ool_copyout(l, mnp, &uaddr,
11594+	    size, MACH_OOL_TRACE|MACH_OOL_FREE)) != 0)
11595+		return mach_msg_error(args, error);
11596+
11597+	*msglen = sizeof(*rep);
11598+	mach_set_header(rep, req, *msglen);
11599+	mach_add_ool_ports_desc(rep, uaddr, tp->p_nlwps);
11600+
11601+	rep->rep_count = tp->p_nlwps;
11602+
11603+	mach_set_trailer(rep, *msglen);
11604+
11605+	return 0;
11606+}
11607+
11608+int
11609+mach_task_get_exception_ports(struct mach_trap_args *args)
11610+{
11611+	mach_task_get_exception_ports_request_t *req = args->smsg;
11612+	mach_task_get_exception_ports_reply_t *rep = args->rmsg;
11613+	struct lwp *l = args->l;
11614+	struct lwp *tl = args->tl;
11615+	size_t *msglen = args->rsize;
11616+	struct mach_emuldata *med;
11617+	struct mach_right *mr;
11618+	struct mach_exc_info *mei;
11619+	int i, j, count;
11620+
11621+	med = tl->l_proc->p_emuldata;
11622+
11623+	/* It always returns an array of 32 ports even if only 9 can be used */
11624+	count = sizeof(rep->rep_old_handler) / sizeof(rep->rep_old_handler[0]);
11625+
11626+	mach_set_header(rep, req, *msglen);
11627+
11628+	rep->rep_masks_count = count;
11629+
11630+	j = 0;
11631+	for (i = 0; i <= MACH_EXC_MAX; i++) {
11632+		if (med->med_exc[i] == NULL)
11633+			continue;
11634+
11635+		if (med->med_exc[i]->mp_datatype != MACH_MP_EXC_INFO) {
11636+#ifdef DIAGNOSTIC
11637+			printf("Exception port without mach_exc_info\n");
11638+#endif
11639+			continue;
11640+		}
11641+		mei = med->med_exc[i]->mp_data;
11642+
11643+		mr = mach_right_get(med->med_exc[i], l, MACH_PORT_TYPE_SEND, 0);
11644+
11645+		mach_add_port_desc(rep, mr->mr_name);
11646+
11647+		rep->rep_masks[j] = 1 << i;
11648+		rep->rep_old_behaviors[j] = mei->mei_behavior;
11649+		rep->rep_old_flavors[j] = mei->mei_flavor;
11650+
11651+		j++;
11652+	}
11653+
11654+	*msglen = sizeof(*rep);
11655+	mach_set_trailer(rep, *msglen);
11656+
11657+	return 0;
11658+}
11659+
11660+static void
11661+update_exception_port(struct mach_emuldata *med, int exc, struct mach_port *mp)
11662+{
11663+	if (med->med_exc[exc] != NULL)
11664+		MACH_PORT_UNREF(med->med_exc[exc]);
11665+	med->med_exc[exc] = mp;
11666+	MACH_PORT_REF(mp);
11667+
11668+	return;
11669+}
11670+
11671+int
11672+mach_task_set_exception_ports(struct mach_trap_args *args)
11673+{
11674+	mach_task_set_exception_ports_request_t *req = args->smsg;
11675+	mach_task_set_exception_ports_reply_t *rep = args->rmsg;
11676+	struct lwp *l = args->l;
11677+	struct lwp *tl = args->tl;
11678+	size_t *msglen = args->rsize;
11679+	struct mach_emuldata *med;
11680+	mach_port_name_t mn;
11681+	struct mach_right *mr;
11682+	struct mach_port *mp;
11683+	struct mach_exc_info *mei;
11684+
11685+	mn = req->req_new_port.name;
11686+	if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_SEND)) == 0)
11687+		return mach_msg_error(args, EPERM);
11688+
11689+	mp = mr->mr_port;
11690+#ifdef DIAGNOSTIC
11691+	if ((mp->mp_datatype != MACH_MP_EXC_INFO) &&
11692+	    (mp->mp_datatype != MACH_MP_NONE))
11693+		printf("mach_task_set_exception_ports: data exists\n");
11694+#endif
11695+	mei = malloc(sizeof(*mei), M_EMULDATA, M_WAITOK);
11696+	mei->mei_flavor = req->req_flavor;
11697+	mei->mei_behavior = req->req_behavior;
11698+
11699+	mp->mp_data = mei;
11700+	mp->mp_flags |= MACH_MP_DATA_ALLOCATED;
11701+	mp->mp_datatype = MACH_MP_EXC_INFO;
11702+
11703+	med = tl->l_proc->p_emuldata;
11704+	if (req->req_mask & MACH_EXC_MASK_BAD_ACCESS)
11705+		update_exception_port(med, MACH_EXC_BAD_ACCESS, mp);
11706+	if (req->req_mask & MACH_EXC_MASK_BAD_INSTRUCTION)
11707+		update_exception_port(med, MACH_EXC_BAD_INSTRUCTION, mp);
11708+	if (req->req_mask & MACH_EXC_MASK_ARITHMETIC)
11709+		update_exception_port(med, MACH_EXC_ARITHMETIC, mp);
11710+	if (req->req_mask & MACH_EXC_MASK_EMULATION)
11711+		update_exception_port(med, MACH_EXC_EMULATION, mp);
11712+	if (req->req_mask & MACH_EXC_MASK_SOFTWARE)
11713+		update_exception_port(med, MACH_EXC_SOFTWARE, mp);
11714+	if (req->req_mask & MACH_EXC_MASK_BREAKPOINT)
11715+		update_exception_port(med, MACH_EXC_BREAKPOINT, mp);
11716+	if (req->req_mask & MACH_EXC_MASK_SYSCALL)
11717+		update_exception_port(med, MACH_EXC_SYSCALL, mp);
11718+	if (req->req_mask & MACH_EXC_MASK_MACH_SYSCALL)
11719+		update_exception_port(med, MACH_EXC_MACH_SYSCALL, mp);
11720+	if (req->req_mask & MACH_EXC_MASK_RPC_ALERT)
11721+		update_exception_port(med, MACH_EXC_RPC_ALERT, mp);
11722+
11723+#ifdef DEBUG_MACH
11724+	if (req->req_mask & (MACH_EXC_ARITHMETIC |
11725+	    MACH_EXC_EMULATION | MACH_EXC_MASK_SYSCALL |
11726+	    MACH_EXC_MASK_MACH_SYSCALL | MACH_EXC_RPC_ALERT))
11727+		printf("mach_set_exception_ports: some exceptions are "
11728+		    "not supported (mask %x)\n", req->req_mask);
11729+#endif
11730+
11731+	*msglen = sizeof(*rep);
11732+	mach_set_header(rep, req, *msglen);
11733+
11734+	rep->rep_retval = 0;
11735+
11736+	mach_set_trailer(rep, *msglen);
11737+
11738+	return 0;
11739+}
11740+
11741+int
11742+mach_task_info(struct mach_trap_args *args)
11743+{
11744+	mach_task_info_request_t *req = args->smsg;
11745+	mach_task_info_reply_t *rep = args->rmsg;
11746+	struct lwp *tl = args->tl;
11747+	size_t *msglen = args->rsize;
11748+	int count;
11749+	struct proc *tp = tl->l_proc;
11750+
11751+	switch(req->req_flavor) {
11752+	case MACH_TASK_BASIC_INFO: {
11753+		struct mach_task_basic_info *mtbi;
11754+		struct rusage ru;
11755+
11756+		count = sizeof(*mtbi) / sizeof(rep->rep_info[0]);
11757+		if (req->req_count < count)
11758+			return mach_msg_error(args, ENOBUFS);
11759+
11760+		ru = tp->p_stats->p_ru;
11761+		mtbi = (struct mach_task_basic_info *)&rep->rep_info[0];
11762+		mutex_enter(tp->p_lock);
11763+		rulwps(tp, &ru);
11764+		mutex_exit(tp->p_lock);
11765+
11766+		mtbi->mtbi_suspend_count = ru.ru_nvcsw + ru.ru_nivcsw;
11767+		mtbi->mtbi_virtual_size = ru.ru_ixrss;
11768+		mtbi->mtbi_resident_size = ru.ru_maxrss;
11769+		mtbi->mtbi_user_time.seconds = ru.ru_utime.tv_sec;
11770+		mtbi->mtbi_user_time.microseconds = ru.ru_utime.tv_usec;
11771+		mtbi->mtbi_system_time.seconds = ru.ru_stime.tv_sec;
11772+		mtbi->mtbi_system_time.microseconds = ru.ru_stime.tv_usec;
11773+		mtbi->mtbi_policy = 0;
11774+
11775+		*msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mtbi);
11776+		break;
11777+	}
11778+
11779+	/* XXX this is supposed to be about threads, not processes... */
11780+	case MACH_TASK_THREAD_TIMES_INFO: {
11781+		struct mach_task_thread_times_info *mttti;
11782+		struct rusage ru;
11783+
11784+		count = sizeof(*mttti) / sizeof(rep->rep_info[0]);
11785+		if (req->req_count < count)
11786+			return mach_msg_error(args, ENOBUFS);
11787+
11788+		ru = tp->p_stats->p_ru;
11789+		mttti = (struct mach_task_thread_times_info *)&rep->rep_info[0];
11790+
11791+		mttti->mttti_user_time.seconds = ru.ru_utime.tv_sec;
11792+		mttti->mttti_user_time.microseconds = ru.ru_utime.tv_usec;
11793+		mttti->mttti_system_time.seconds = ru.ru_stime.tv_sec;
11794+		mttti->mttti_system_time.microseconds = ru.ru_stime.tv_usec;
11795+
11796+		*msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mttti);
11797+		break;
11798+	}
11799+
11800+	/* XXX a few statistics missing here */
11801+	case MACH_TASK_EVENTS_INFO: {
11802+		struct mach_task_events_info *mtei;
11803+		struct rusage ru;
11804+
11805+		count = sizeof(*mtei) / sizeof(rep->rep_info[0]);
11806+		if (req->req_count < count)
11807+			return mach_msg_error(args, ENOBUFS);
11808+
11809+		mtei = (struct mach_task_events_info *)&rep->rep_info[0];
11810+		ru = tp->p_stats->p_ru;
11811+		mutex_enter(tp->p_lock);
11812+		rulwps(tp, &ru);
11813+		mutex_exit(tp->p_lock);
11814+
11815+		mtei->mtei_faults = ru.ru_majflt;
11816+		mtei->mtei_pageins = ru.ru_minflt;
11817+		mtei->mtei_cow_faults = 0; /* XXX */
11818+		mtei->mtei_message_sent = ru.ru_msgsnd;
11819+		mtei->mtei_message_received = ru.ru_msgrcv;
11820+		mtei->mtei_syscalls_mach = 0; /* XXX */
11821+		mtei->mtei_syscalls_unix = 0; /* XXX */
11822+		mtei->mtei_csw = 0; /* XXX */
11823+
11824+		*msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mtei);
11825+		break;
11826+	}
11827+
11828+	default:
11829+		uprintf("mach_task_info: unsupported flavor %d\n",
11830+		    req->req_flavor);
11831+		return mach_msg_error(args, EINVAL);
11832+	};
11833+
11834+	mach_set_header(rep, req, *msglen);
11835+
11836+	rep->rep_count = count;
11837+
11838+	mach_set_trailer(rep, *msglen);
11839+
11840+	return 0;
11841+}
11842+
11843+int
11844+mach_task_suspend(struct mach_trap_args *args)
11845+{
11846+	mach_task_suspend_request_t *req = args->smsg;
11847+	mach_task_suspend_reply_t *rep = args->rmsg;
11848+	size_t *msglen = args->rsize;
11849+	struct lwp *tl = args->tl;
11850+	struct lwp *lp;
11851+	struct mach_emuldata *med;
11852+	struct proc *tp = tl->l_proc;
11853+
11854+	med = tp->p_emuldata;
11855+	med->med_suspend++; /* XXX Mach also has a per thread semaphore */
11856+
11857+	LIST_FOREACH(lp, &tp->p_lwps, l_sibling) {
11858+		switch(lp->l_stat) {
11859+		case LSONPROC:
11860+		case LSRUN:
11861+		case LSSLEEP:
11862+		case LSSUSPENDED:
11863+		case LSZOMB:
11864+			break;
11865+		default:
11866+			return mach_msg_error(args, 0);
11867+			break;
11868+		}
11869+	}
11870+	mutex_enter(proc_lock);
11871+	mutex_enter(tp->p_lock);
11872+	proc_stop(tp, 0, SIGSTOP);
11873+	mutex_enter(tp->p_lock);
11874+	mutex_enter(proc_lock);
11875+
11876+	*msglen = sizeof(*rep);
11877+	mach_set_header(rep, req, *msglen);
11878+
11879+	rep->rep_retval = 0;
11880+
11881+	mach_set_trailer(rep, *msglen);
11882+
11883+	return 0;
11884+}
11885+
11886+int
11887+mach_task_resume(struct mach_trap_args *args)
11888+{
11889+	mach_task_resume_request_t *req = args->smsg;
11890+	mach_task_resume_reply_t *rep = args->rmsg;
11891+	size_t *msglen = args->rsize;
11892+	struct lwp *tl = args->tl;
11893+	struct mach_emuldata *med;
11894+	struct proc *tp = tl->l_proc;
11895+
11896+	med = tp->p_emuldata;
11897+	med->med_suspend--; /* XXX Mach also has a per thread semaphore */
11898+#if 0
11899+	if (med->med_suspend > 0)
11900+		return mach_msg_error(args, 0); /* XXX error code */
11901+#endif
11902+
11903+	/* XXX We should also wake up the stopped thread... */
11904+#ifdef DEBUG_MACH
11905+	printf("resuming pid %d\n", tp->p_pid);
11906+#endif
11907+	mutex_enter(proc_lock);
11908+	mutex_enter(tp->p_lock);
11909+	(void)proc_unstop(tp);
11910+	mutex_enter(tp->p_lock);
11911+	mutex_enter(proc_lock);
11912+
11913+	*msglen = sizeof(*rep);
11914+	mach_set_header(rep, req, *msglen);
11915+
11916+	rep->rep_retval = 0;
11917+
11918+	mach_set_trailer(rep, *msglen);
11919+
11920+	return 0;
11921+}
11922+
11923+int
11924+mach_task_terminate(struct mach_trap_args *args)
11925+{
11926+	mach_task_resume_request_t *req = args->smsg;
11927+	mach_task_resume_reply_t *rep = args->rmsg;
11928+	size_t *msglen = args->rsize;
11929+	struct lwp *tl = args->tl;
11930+	struct sys_exit_args cup;
11931+	register_t retval;
11932+	int error;
11933+
11934+
11935+	SCARG(&cup, rval) = 0;
11936+	error = sys_exit(tl, &cup, &retval);
11937+
11938+	*msglen = sizeof(*rep);
11939+	mach_set_header(rep, req, *msglen);
11940+
11941+	rep->rep_retval = native_to_mach_errno[error];
11942+
11943+	mach_set_trailer(rep, *msglen);
11944+
11945+	return 0;
11946+}
11947+
11948+int
11949+mach_sys_task_for_pid(struct lwp *l, const struct mach_sys_task_for_pid_args *uap, register_t *retval)
11950+{
11951+	/* {
11952+		syscallarg(mach_port_t) target_tport;
11953+		syscallarg(int) pid;
11954+		syscallarg(mach_port_t) *t;
11955+	} */
11956+	struct mach_right *mr;
11957+	struct mach_emuldata *med;
11958+	struct proc *t;
11959+	int error;
11960+
11961+	/*
11962+	 * target_tport is used because the task may be on
11963+	 * a different host. (target_tport, pid) is unique.
11964+	 * We don't support multiple-host configuration
11965+	 * yet, so this parameter should be useless.
11966+	 * However, we still validate it.
11967+	 */
11968+	if ((mr = mach_right_check(SCARG(uap, target_tport),
11969+	    l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
11970+		return EPERM;
11971+
11972+	mutex_enter(proc_lock);
11973+	if ((t = proc_find(SCARG(uap, pid))) == NULL) {
11974+		mutex_exit(proc_lock);
11975+		return ESRCH;
11976+	}
11977+	mutex_enter(t->p_lock);
11978+	mutex_exit(proc_lock);
11979+
11980+	/* Allowed only if the UID match, if setuid, or if superuser */
11981+	if ((kauth_cred_getuid(t->p_cred) != kauth_cred_getuid(l->l_cred) ||
11982+	    ISSET(t->p_flag, PK_SUGID)) && (error = kauth_authorize_generic(l->l_cred,
11983+	    KAUTH_GENERIC_ISSUSER, NULL)) != 0) {
11984+		mutex_exit(t->p_lock);
11985+		return (error);
11986+	}
11987+
11988+	/* This will only work on a Mach process */
11989+	if ((t->p_emul != &emul_mach) &&
11990+#ifdef COMPAT_DARWIN
11991+	    (t->p_emul != &emul_darwin) &&
11992+#endif
11993+	    1) {
11994+		mutex_exit(t->p_lock);
11995+		return EINVAL;
11996+	}
11997+	mutex_exit(t->p_lock);
11998+
11999+	/* XXX: Unlocked, broken. */
12000+	med = t->p_emuldata;
12001+	mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
12002+	if (mr) {
12003+		error = copyout(&mr->mr_name, SCARG(uap, t),
12004+		    sizeof(mr->mr_name));
12005+	} else {
12006+		error = EINVAL;
12007+	}
12008+
12009+	return error;
12010+}
12011+
12012diff --git a/sys/compat/mach/mach_task.h b/sys/compat/mach/mach_task.h
12013new file mode 100644
12014index 0000000..e0ea1f8
12015--- /dev/null
12016+++ b/sys/compat/mach/mach_task.h
12017@@ -0,0 +1,227 @@
12018+/*	$NetBSD: mach_task.h,v 1.16 2008/04/28 20:23:44 martin Exp $ */
12019+
12020+/*-
12021+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
12022+ * All rights reserved.
12023+ *
12024+ * This code is derived from software contributed to The NetBSD Foundation
12025+ * by Emmanuel Dreyfus
12026+ *
12027+ * Redistribution and use in source and binary forms, with or without
12028+ * modification, are permitted provided that the following conditions
12029+ * are met:
12030+ * 1. Redistributions of source code must retain the above copyright
12031+ *    notice, this list of conditions and the following disclaimer.
12032+ * 2. Redistributions in binary form must reproduce the above copyright
12033+ *    notice, this list of conditions and the following disclaimer in the
12034+ *    documentation and/or other materials provided with the distribution.
12035+ *
12036+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
12037+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
12038+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12039+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
12040+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
12041+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
12042+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
12043+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
12044+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
12045+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
12046+ * POSSIBILITY OF SUCH DAMAGE.
12047+ */
12048+
12049+#ifndef	_MACH_TASK_H_
12050+#define	_MACH_TASK_H_
12051+
12052+/* task_get_special_port */
12053+
12054+#define MACH_TASK_KERNEL_PORT		1
12055+#define MACH_TASK_HOST_PORT		2
12056+#define MACH_TASK_BOOTSTRAP_PORT	4
12057+#define MACH_TASK_WIRED_LEDGER_PORT	5
12058+#define MACH_TASK_PAGED_LEDGER_PORT	6
12059+
12060+typedef struct {
12061+	mach_msg_header_t req_msgh;
12062+	mach_ndr_record_t req_ndr;
12063+	int req_which_port;
12064+} mach_task_get_special_port_request_t;
12065+
12066+typedef struct {
12067+	mach_msg_header_t rep_msgh;
12068+	mach_msg_body_t rep_msgh_body;
12069+	mach_msg_port_descriptor_t rep_special_port;
12070+	mach_msg_trailer_t rep_trailer;
12071+} mach_task_get_special_port_reply_t;
12072+
12073+/* mach_ports_lookup */
12074+
12075+typedef struct {
12076+	mach_msg_header_t req_msgh;
12077+} mach_ports_lookup_request_t;
12078+
12079+typedef struct {
12080+	mach_msg_header_t rep_msgh;
12081+	mach_msg_body_t rep_msgh_body;
12082+	mach_msg_ool_ports_descriptor_t rep_init_port_set;
12083+	mach_ndr_record_t rep_ndr;
12084+	mach_msg_type_number_t rep_init_port_set_count;
12085+	mach_msg_trailer_t rep_trailer;
12086+} mach_ports_lookup_reply_t;
12087+
12088+/* mach_set_special_port */
12089+
12090+typedef struct {
12091+	mach_msg_header_t req_msgh;
12092+	mach_msg_body_t req_msgh_body;
12093+	mach_msg_port_descriptor_t req_special_port;
12094+	mach_ndr_record_t req_ndr;
12095+	int req_which_port;
12096+} mach_task_set_special_port_request_t;
12097+
12098+typedef struct {
12099+	mach_msg_header_t rep_msgh;
12100+	mach_ndr_record_t rep_ndr;
12101+	mach_kern_return_t rep_retval;
12102+	mach_msg_trailer_t rep_trailer;
12103+} mach_task_set_special_port_reply_t;
12104+
12105+/* task_threads */
12106+
12107+typedef struct {
12108+	 mach_msg_header_t req_msgh;
12109+} mach_task_threads_request_t;
12110+
12111+typedef struct {
12112+	mach_msg_header_t rep_msgh;
12113+	mach_msg_body_t rep_body;
12114+	mach_msg_ool_ports_descriptor_t rep_list;
12115+	mach_ndr_record_t rep_ndr;
12116+	mach_msg_type_number_t rep_count;
12117+	mach_msg_trailer_t rep_trailer;
12118+} mach_task_threads_reply_t;
12119+
12120+/* task_get_exception_ports */
12121+
12122+typedef struct {
12123+	mach_msg_header_t req_msgh;
12124+	mach_ndr_record_t req_ndr;
12125+	mach_exception_mask_t req_mask;
12126+} mach_task_get_exception_ports_request_t;
12127+
12128+typedef struct {
12129+	mach_msg_header_t rep_msgh;
12130+	mach_msg_body_t rep_body;
12131+	mach_msg_port_descriptor_t rep_old_handler[32];
12132+	mach_ndr_record_t rep_ndr;
12133+	mach_msg_type_number_t rep_masks_count;
12134+	mach_exception_mask_t rep_masks[32];
12135+	mach_exception_behavior_t rep_old_behaviors[32];
12136+	mach_thread_state_flavor_t rep_old_flavors[32];
12137+	mach_msg_trailer_t rep_trailer;
12138+} mach_task_get_exception_ports_reply_t;
12139+
12140+/* task_set_exception_ports */
12141+
12142+typedef struct {
12143+	mach_msg_header_t req_msgh;
12144+	mach_msg_body_t req_body;
12145+	mach_msg_port_descriptor_t req_new_port;
12146+	mach_ndr_record_t req_ndr;
12147+	mach_exception_mask_t req_mask;
12148+	mach_exception_behavior_t req_behavior;
12149+	mach_thread_state_flavor_t req_flavor;
12150+} mach_task_set_exception_ports_request_t;
12151+
12152+typedef struct {
12153+	mach_msg_header_t rep_msgh;
12154+	mach_ndr_record_t rep_ndr;
12155+	mach_kern_return_t rep_retval;
12156+	mach_msg_trailer_t rep_trailer;
12157+} mach_task_set_exception_ports_reply_t;
12158+
12159+/* task_info */
12160+
12161+#define MACH_TASK_BASIC_INFO 4
12162+struct mach_task_basic_info {
12163+	mach_integer_t mtbi_suspend_count;
12164+	mach_vm_size_t mtbi_virtual_size;
12165+	mach_vm_size_t mtbi_resident_size;
12166+	mach_time_value_t mtbi_user_time;
12167+	mach_time_value_t mtbi_system_time;
12168+	mach_policy_t mtbi_policy;
12169+};
12170+
12171+#define MACH_TASK_EVENTS_INFO 2
12172+struct mach_task_events_info {
12173+	mach_integer_t mtei_faults;
12174+	mach_integer_t mtei_pageins;
12175+	mach_integer_t mtei_cow_faults;
12176+	mach_integer_t mtei_message_sent;
12177+	mach_integer_t mtei_message_received;
12178+	mach_integer_t mtei_syscalls_mach;
12179+	mach_integer_t mtei_syscalls_unix;
12180+	mach_integer_t mtei_csw;
12181+};
12182+
12183+#define MACH_TASK_THREAD_TIMES_INFO 3
12184+struct mach_task_thread_times_info {
12185+	mach_time_value_t mttti_user_time;
12186+	mach_time_value_t mttti_system_time;
12187+};
12188+
12189+typedef struct {
12190+	mach_msg_header_t req_msgh;
12191+	mach_ndr_record_t req_ndr;
12192+	mach_task_flavor_t req_flavor;
12193+	mach_msg_type_number_t req_count;
12194+} mach_task_info_request_t;
12195+
12196+typedef struct {
12197+	mach_msg_header_t rep_msgh;
12198+	mach_ndr_record_t rep_ndr;
12199+	mach_kern_return_t rep_retval;
12200+	mach_msg_type_number_t rep_count;
12201+	mach_integer_t rep_info[8];
12202+	mach_msg_trailer_t rep_trailer;
12203+} mach_task_info_reply_t;
12204+
12205+/* task_suspend */
12206+
12207+typedef struct {
12208+	mach_msg_header_t req_msgh;
12209+} mach_task_suspend_request_t;
12210+
12211+typedef struct {
12212+	mach_msg_header_t rep_msgh;
12213+	mach_ndr_record_t rep_ndr;
12214+	mach_kern_return_t rep_retval;
12215+	mach_msg_trailer_t rep_trailer;
12216+} mach_task_suspend_reply_t;
12217+
12218+/* task_resume */
12219+
12220+typedef struct {
12221+	mach_msg_header_t req_msgh;
12222+} mach_task_resume_request_t;
12223+
12224+typedef struct {
12225+	mach_msg_header_t rep_msgh;
12226+	mach_ndr_record_t rep_ndr;
12227+	mach_kern_return_t rep_retval;
12228+	mach_msg_trailer_t rep_trailer;
12229+} mach_task_resume_reply_t;
12230+
12231+/* task_terminate */
12232+
12233+typedef struct {
12234+	mach_msg_header_t req_msgh;
12235+} mach_task_terminate_request_t;
12236+
12237+typedef struct {
12238+	mach_msg_header_t rep_msgh;
12239+	mach_ndr_record_t rep_ndr;
12240+	mach_kern_return_t rep_retval;
12241+	mach_msg_trailer_t rep_trailer;
12242+} mach_task_terminate_reply_t;
12243+
12244+#endif /* _MACH_TASK_H_ */
12245diff --git a/sys/compat/mach/mach_thread.c b/sys/compat/mach/mach_thread.c
12246new file mode 100644
12247index 0000000..a5abd61
12248--- /dev/null
12249+++ b/sys/compat/mach/mach_thread.c
12250@@ -0,0 +1,486 @@
12251+/*	$NetBSD: mach_thread.c,v 1.50 2010/06/13 04:13:31 yamt Exp $ */
12252+
12253+/*-
12254+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
12255+ * All rights reserved.
12256+ *
12257+ * This code is derived from software contributed to The NetBSD Foundation
12258+ * by Emmanuel Dreyfus
12259+ *
12260+ * Redistribution and use in source and binary forms, with or without
12261+ * modification, are permitted provided that the following conditions
12262+ * are met:
12263+ * 1. Redistributions of source code must retain the above copyright
12264+ *    notice, this list of conditions and the following disclaimer.
12265+ * 2. Redistributions in binary form must reproduce the above copyright
12266+ *    notice, this list of conditions and the following disclaimer in the
12267+ *    documentation and/or other materials provided with the distribution.
12268+ *
12269+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
12270+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
12271+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12272+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
12273+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
12274+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
12275+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
12276+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
12277+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
12278+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
12279+ * POSSIBILITY OF SUCH DAMAGE.
12280+ */
12281+
12282+#include <sys/cdefs.h>
12283+__KERNEL_RCSID(0, "$NetBSD: mach_thread.c,v 1.50 2010/06/13 04:13:31 yamt Exp $");
12284+
12285+#include <sys/types.h>
12286+#include <sys/param.h>
12287+#include <sys/kernel.h>
12288+#include <sys/systm.h>
12289+#include <sys/signal.h>
12290+#include <sys/rwlock.h>
12291+#include <sys/queue.h>
12292+#include <sys/proc.h>
12293+#include <sys/resource.h>
12294+#include <sys/resourcevar.h>
12295+#include <sys/sa.h>
12296+#include <sys/savar.h>
12297+
12298+#include <compat/mach/mach_types.h>
12299+#include <compat/mach/mach_message.h>
12300+#include <compat/mach/mach_exec.h>
12301+#include <compat/mach/mach_clock.h>
12302+#include <compat/mach/mach_port.h>
12303+#include <compat/mach/mach_task.h>
12304+#include <compat/mach/mach_thread.h>
12305+#include <compat/mach/mach_errno.h>
12306+#include <compat/mach/mach_services.h>
12307+#include <compat/mach/mach_syscallargs.h>
12308+
12309+int
12310+mach_sys_syscall_thread_switch(struct lwp *l, const struct mach_sys_syscall_thread_switch_args *uap, register_t *retval)
12311+{
12312+	/* {
12313+		syscallarg(mach_port_name_t) thread_name;
12314+		syscallarg(int) option;
12315+		syscallarg(mach_msg_timeout_t) option_time;
12316+	} */
12317+	int timeout;
12318+	struct mach_emuldata *med;
12319+
12320+	med = (struct mach_emuldata *)l->l_proc->p_emuldata;
12321+	timeout = SCARG(uap, option_time) * hz / 1000;
12322+
12323+	/*
12324+	 * The day we will be able to find out the struct proc from
12325+	 * the port number, try to use preempt() to call the right thread.
12326+	 * [- but preempt() is for _involuntary_ context switches.]
12327+	 */
12328+	switch(SCARG(uap, option)) {
12329+	case MACH_SWITCH_OPTION_NONE:
12330+		yield();
12331+		break;
12332+
12333+	case MACH_SWITCH_OPTION_WAIT:
12334+		med->med_thpri = 1;
12335+		while (med->med_thpri != 0)
12336+			(void)tsleep(&med->med_thpri, PZERO|PCATCH,
12337+			    "thread_switch", timeout);
12338+		break;
12339+
12340+	case MACH_SWITCH_OPTION_DEPRESS:
12341+	case MACH_SWITCH_OPTION_IDLE:
12342+		/* Use a callout to restore the priority after depression? */
12343+		med->med_thpri = l->l_priority;
12344+		l->l_priority = MAXPRI;
12345+		break;
12346+
12347+	default:
12348+		uprintf("mach_sys_syscall_thread_switch(): unknown option %d\n",		    SCARG(uap, option));
12349+		break;
12350+	}
12351+	return 0;
12352+}
12353+
12354+int
12355+mach_sys_swtch_pri(struct lwp *l, const struct mach_sys_swtch_pri_args *uap, register_t *retval)
12356+{
12357+	/* {
12358+		syscallarg(int) pri;
12359+	} */
12360+
12361+	/*
12362+	 * Copied from preempt(9). We cannot just call preempt
12363+	 * because we want to return mi_switch(9) return value.
12364+	 */
12365+	KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
12366+	lwp_lock(l);
12367+	if (l->l_stat == LSONPROC)
12368+		l->l_proc->p_stats->p_ru.ru_nivcsw++;	/* XXXSMP */
12369+	*retval = mi_switch(l);
12370+	KERNEL_LOCK(l->l_biglocks, l);
12371+
12372+	return 0;
12373+}
12374+
12375+int
12376+mach_sys_swtch(struct lwp *l, const void *v, register_t *retval)
12377+{
12378+	struct mach_sys_swtch_pri_args cup;
12379+
12380+	SCARG(&cup, pri) = 0;
12381+
12382+	return mach_sys_swtch_pri(l, &cup, retval);
12383+}
12384+
12385+
12386+int
12387+mach_thread_policy(struct mach_trap_args *args)
12388+{
12389+	mach_thread_policy_request_t *req = args->smsg;
12390+	mach_thread_policy_reply_t *rep = args->rmsg;
12391+	size_t *msglen = args->rsize;
12392+	int end_offset;
12393+
12394+	/* Sanity check req_count */
12395+	end_offset = req->req_count +
12396+		     (sizeof(req->req_setlimit) / sizeof(req->req_base[0]));
12397+	if (MACH_REQMSG_OVERFLOW(args, req->req_base[end_offset]))
12398+		return mach_msg_error(args, EINVAL);
12399+
12400+	uprintf("Unimplemented mach_thread_policy\n");
12401+
12402+	*msglen = sizeof(*rep);
12403+	mach_set_header(rep, req, *msglen);
12404+
12405+	rep->rep_retval = 0;
12406+
12407+	mach_set_trailer(rep, *msglen);
12408+
12409+	return 0;
12410+}
12411+
12412+/* XXX it might be possible to use this on another task */
12413+int
12414+mach_thread_create_running(struct mach_trap_args *args)
12415+{
12416+	mach_thread_create_running_request_t *req = args->smsg;
12417+	mach_thread_create_running_reply_t *rep = args->rmsg;
12418+	size_t *msglen = args->rsize;
12419+	struct lwp *l = args->l;
12420+	struct proc *p = l->l_proc;
12421+	struct mach_create_thread_child_args mctc;
12422+	struct mach_right *child_mr;
12423+	struct mach_lwp_emuldata *mle;
12424+	vaddr_t uaddr;
12425+	int flags;
12426+	int error;
12427+	int end_offset;
12428+
12429+	/* Sanity check req_count */
12430+	end_offset = req->req_count;
12431+	if (MACH_REQMSG_OVERFLOW(args, req->req_state[end_offset]))
12432+		return mach_msg_error(args, EINVAL);
12433+
12434+	/*
12435+	 * Prepare the data we want to transmit to the child.
12436+	 */
12437+	mctc.mctc_flavor = req->req_flavor;
12438+	mctc.mctc_oldlwp = l;
12439+	mctc.mctc_child_done = 0;
12440+	mctc.mctc_state = req->req_state;
12441+
12442+	uaddr = uvm_uarea_alloc();
12443+	if (__predict_false(uaddr == 0))
12444+		return ENOMEM;
12445+
12446+	flags = 0;
12447+	if ((error = lwp_create(l, p, uaddr, flags, NULL, 0,
12448+	    mach_create_thread_child, (void *)&mctc, &mctc.mctc_lwp,
12449+	    SCHED_OTHER)) != 0)
12450+	{
12451+		uvm_uarea_free(uaddr);
12452+		return mach_msg_error(args, error);
12453+	}
12454+
12455+	/*
12456+	 * Make the child runnable.
12457+	 */
12458+	mutex_enter(p->p_lock);
12459+	lwp_lock(mctc.mctc_lwp);
12460+	mctc.mctc_lwp->l_private = 0;
12461+	mctc.mctc_lwp->l_stat = LSRUN;
12462+	sched_enqueue(mctc.mctc_lwp, false);
12463+	lwp_unlock(mctc.mctc_lwp);
12464+	mutex_exit(p->p_lock);
12465+
12466+	/*
12467+	 * Get the child's kernel port
12468+	 */
12469+	mle = mctc.mctc_lwp->l_emuldata;
12470+	child_mr = mach_right_get(mle->mle_kernel, l, MACH_PORT_TYPE_SEND, 0);
12471+
12472+	/*
12473+	 * The child relies on some values in mctc, so we should not
12474+	 * exit until it is finished with it. We catch signals so that
12475+	 * the process can be killed with kill -9, but we loop to avoid
12476+	 * spurious wakeups due to other signals.
12477+	 */
12478+	while(mctc.mctc_child_done == 0)
12479+		(void)tsleep(&mctc.mctc_child_done,
12480+		    PZERO|PCATCH, "mach_thread", 0);
12481+
12482+	*msglen = sizeof(*rep);
12483+	mach_set_header(rep, req, *msglen);
12484+	mach_add_port_desc(rep, child_mr->mr_name);
12485+	mach_set_trailer(rep, *msglen);
12486+
12487+	return 0;
12488+}
12489+
12490+int
12491+mach_thread_info(struct mach_trap_args *args)
12492+{
12493+	mach_thread_info_request_t *req = args->smsg;
12494+	mach_thread_info_reply_t *rep = args->rmsg;
12495+	size_t *msglen = args->rsize;
12496+	struct lwp *l = args->l;
12497+	struct lwp *tl = args->tl;
12498+	struct proc *tp = tl->l_proc;
12499+
12500+	/* Sanity check req->req_count */
12501+	if (req->req_count > 12)
12502+		return mach_msg_error(args, EINVAL);
12503+
12504+	rep->rep_count = req->req_count;
12505+
12506+	*msglen = sizeof(*rep) + ((req->req_count - 12) * sizeof(int));
12507+	mach_set_header(rep, req, *msglen);
12508+
12509+	switch (req->req_flavor) {
12510+	case MACH_THREAD_BASIC_INFO: {
12511+		struct mach_thread_basic_info *tbi;
12512+
12513+		if (req->req_count != (sizeof(*tbi) / sizeof(int))) /* 10 */
12514+			return mach_msg_error(args, EINVAL);
12515+
12516+		tbi = (struct mach_thread_basic_info *)rep->rep_out;
12517+		tbi->user_time.seconds = tp->p_uticks * hz / 1000000;
12518+		tbi->user_time.microseconds =
12519+		    (tp->p_uticks) * hz - tbi->user_time.seconds;
12520+		tbi->system_time.seconds = tp->p_sticks * hz / 1000000;
12521+		tbi->system_time.microseconds =
12522+		    (tp->p_sticks) * hz - tbi->system_time.seconds;
12523+		tbi->cpu_usage = tp->p_pctcpu;
12524+		tbi->policy = MACH_THREAD_STANDARD_POLICY;
12525+
12526+		/* XXX this is not very accurate */
12527+		tbi->run_state = MACH_TH_STATE_RUNNING;
12528+		tbi->flags = 0;
12529+		switch (l->l_stat) {
12530+		case LSRUN:
12531+			tbi->run_state = MACH_TH_STATE_RUNNING;
12532+			break;
12533+		case LSSTOP:
12534+			tbi->run_state = MACH_TH_STATE_STOPPED;
12535+			break;
12536+		case LSSLEEP:
12537+			tbi->run_state = MACH_TH_STATE_WAITING;
12538+			break;
12539+		case LSIDL:
12540+			tbi->run_state = MACH_TH_STATE_RUNNING;
12541+			tbi->flags = MACH_TH_FLAGS_IDLE;
12542+			break;
12543+		default:
12544+			break;
12545+		}
12546+
12547+		tbi->suspend_count = 0;
12548+		tbi->sleep_time = tl->l_slptime;
12549+		break;
12550+	}
12551+
12552+	case MACH_THREAD_SCHED_TIMESHARE_INFO: {
12553+		struct mach_policy_timeshare_info *pti;
12554+
12555+		if (req->req_count != (sizeof(*pti) / sizeof(int))) /* 5 */
12556+			return mach_msg_error(args, EINVAL);
12557+
12558+		pti = (struct mach_policy_timeshare_info *)rep->rep_out;
12559+
12560+		pti->max_priority = tl->l_priority;
12561+		pti->base_priority = tl->l_priority;
12562+		pti->cur_priority = tl->l_priority;
12563+		pti->depressed = 0;
12564+		pti->depress_priority = tl->l_priority;
12565+		break;
12566+	}
12567+
12568+	case MACH_THREAD_SCHED_RR_INFO:
12569+	case MACH_THREAD_SCHED_FIFO_INFO:
12570+		uprintf("Unimplemented thread_info flavor %d\n",
12571+		    req->req_flavor);
12572+	default:
12573+		return mach_msg_error(args, EINVAL);
12574+		break;
12575+	}
12576+
12577+	mach_set_trailer(rep, *msglen);
12578+
12579+	return 0;
12580+}
12581+
12582+int
12583+mach_thread_get_state(struct mach_trap_args *args)
12584+{
12585+	mach_thread_get_state_request_t *req = args->smsg;
12586+	mach_thread_get_state_reply_t *rep = args->rmsg;
12587+	size_t *msglen = args->rsize;
12588+	struct lwp *tl = args->tl;
12589+	int error;
12590+	int size;
12591+
12592+	/* Sanity check req->req_count */
12593+	if (req->req_count > 144)
12594+		return mach_msg_error(args, EINVAL);
12595+
12596+	if ((error = mach_thread_get_state_machdep(tl,
12597+	    req->req_flavor, &rep->rep_state, &size)) != 0)
12598+		return mach_msg_error(args, error);
12599+
12600+	rep->rep_count = size / sizeof(int);
12601+	*msglen = sizeof(*rep) + ((req->req_count - 144) * sizeof(int));
12602+	mach_set_header(rep, req, *msglen);
12603+	mach_set_trailer(rep, *msglen);
12604+
12605+	return 0;
12606+}
12607+
12608+int
12609+mach_thread_set_state(struct mach_trap_args *args)
12610+{
12611+	mach_thread_set_state_request_t *req = args->smsg;
12612+	mach_thread_set_state_reply_t *rep = args->rmsg;
12613+	size_t *msglen = args->rsize;
12614+	struct lwp *tl = args->tl;
12615+	int error;
12616+	int end_offset;
12617+
12618+	/* Sanity check req_count */
12619+	end_offset = req->req_count;
12620+	if (MACH_REQMSG_OVERFLOW(args, req->req_state[end_offset]))
12621+		return mach_msg_error(args, EINVAL);
12622+
12623+	if ((error = mach_thread_set_state_machdep(tl,
12624+	    req->req_flavor, &req->req_state)) != 0)
12625+		return mach_msg_error(args, error);
12626+
12627+	*msglen = sizeof(*rep);
12628+	mach_set_header(rep, req, *msglen);
12629+
12630+	rep->rep_retval = 0;
12631+
12632+	mach_set_trailer(rep, *msglen);
12633+
12634+	return 0;
12635+}
12636+
12637+int
12638+mach_thread_suspend(struct mach_trap_args *args)
12639+{
12640+	mach_thread_suspend_request_t *req = args->smsg;
12641+	mach_thread_suspend_reply_t *rep = args->rmsg;
12642+	size_t *msglen = args->rsize;
12643+	struct lwp *l = args->l;
12644+	struct lwp *tl = args->tl;
12645+	struct proc *p = tl->l_proc;
12646+	int error;
12647+
12648+	mutex_enter(p->p_lock);
12649+	lwp_lock(tl);
12650+	error = lwp_suspend(l, tl);
12651+	mutex_exit(p->p_lock);
12652+
12653+	*msglen = sizeof(*rep);
12654+	mach_set_header(rep, req, *msglen);
12655+	rep->rep_retval = native_to_mach_errno[error];
12656+	mach_set_trailer(rep, *msglen);
12657+
12658+	return 0;
12659+}
12660+
12661+int
12662+mach_thread_resume(struct mach_trap_args *args)
12663+{
12664+	mach_thread_resume_request_t *req = args->smsg;
12665+	mach_thread_resume_reply_t *rep = args->rmsg;
12666+	size_t *msglen = args->rsize;
12667+	struct lwp *tl = args->tl;
12668+	struct proc *p = tl->l_proc;
12669+
12670+	mutex_enter(p->p_lock);
12671+	lwp_lock(tl);
12672+	lwp_continue(tl);
12673+	mutex_exit(p->p_lock);
12674+
12675+	*msglen = sizeof(*rep);
12676+	mach_set_header(rep, req, *msglen);
12677+	rep->rep_retval = 0;
12678+	mach_set_trailer(rep, *msglen);
12679+
12680+	return 0;
12681+}
12682+
12683+int
12684+mach_thread_abort(struct mach_trap_args *args)
12685+{
12686+	mach_thread_abort_request_t *req = args->smsg;
12687+	mach_thread_abort_reply_t *rep = args->rmsg;
12688+	size_t *msglen = args->rsize;
12689+	struct lwp *tl = args->tl;
12690+
12691+	lwp_exit(tl);
12692+
12693+	*msglen = sizeof(*rep);
12694+	mach_set_header(rep, req, *msglen);
12695+	rep->rep_retval = 0;
12696+	mach_set_trailer(rep, *msglen);
12697+
12698+	return 0;
12699+}
12700+
12701+int
12702+mach_thread_set_policy(struct mach_trap_args *args)
12703+{
12704+	mach_thread_set_policy_request_t *req = args->smsg;
12705+	mach_thread_set_policy_reply_t *rep = args->rmsg;
12706+	size_t *msglen = args->rsize;
12707+	struct lwp *tl = args->tl;
12708+	mach_port_t mn;
12709+	struct mach_right *mr;
12710+	int limit_count_offset, limit_offset;
12711+	int limit_count;
12712+	int *limit;
12713+
12714+	limit_count_offset = req->req_base_count;
12715+	if (MACH_REQMSG_OVERFLOW(args, req->req_base[limit_count_offset]))
12716+		return mach_msg_error(args, EINVAL);
12717+
12718+	limit_count = req->req_base[limit_count_offset];
12719+	limit_offset = limit_count_offset +
12720+	    (sizeof(req->req_limit_count) / sizeof(req->req_base[0]));
12721+	limit = &req->req_base[limit_offset];
12722+	if (MACH_REQMSG_OVERFLOW(args, limit[limit_count]))
12723+		return mach_msg_error(args, EINVAL);
12724+
12725+	mn = req->req_pset.name;
12726+	if ((mr = mach_right_check(mn, tl, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
12727+		return mach_msg_error(args, EINVAL);
12728+
12729+	*msglen = sizeof(*rep);
12730+	mach_set_header(rep, req, *msglen);
12731+	rep->rep_retval = 0;
12732+	mach_set_trailer(rep, *msglen);
12733+
12734+	return 0;
12735+}
12736+
12737diff --git a/sys/compat/mach/mach_thread.h b/sys/compat/mach/mach_thread.h
12738new file mode 100644
12739index 0000000..9a10ebb
12740--- /dev/null
12741+++ b/sys/compat/mach/mach_thread.h
12742@@ -0,0 +1,249 @@
12743+/*	$NetBSD: mach_thread.h,v 1.19 2008/04/28 20:23:44 martin Exp $ */
12744+
12745+/*-
12746+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
12747+ * All rights reserved.
12748+ *
12749+ * This code is derived from software contributed to The NetBSD Foundation
12750+ * by Emmanuel Dreyfus
12751+ *
12752+ * Redistribution and use in source and binary forms, with or without
12753+ * modification, are permitted provided that the following conditions
12754+ * are met:
12755+ * 1. Redistributions of source code must retain the above copyright
12756+ *    notice, this list of conditions and the following disclaimer.
12757+ * 2. Redistributions in binary form must reproduce the above copyright
12758+ *    notice, this list of conditions and the following disclaimer in the
12759+ *    documentation and/or other materials provided with the distribution.
12760+ *
12761+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
12762+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
12763+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12764+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
12765+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
12766+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
12767+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
12768+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
12769+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
12770+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
12771+ * POSSIBILITY OF SUCH DAMAGE.
12772+ */
12773+
12774+#ifndef	_MACH_THREAD_H_
12775+#define	_MACH_THREAD_H_
12776+
12777+#include <sys/types.h>
12778+#include <sys/param.h>
12779+#include <sys/signal.h>
12780+#include <sys/proc.h>
12781+
12782+#include <compat/mach/mach_types.h>
12783+#include <compat/mach/mach_message.h>
12784+
12785+/* For mach_create_thread_child() */
12786+struct mach_create_thread_child_args {
12787+	struct lwp *mctc_lwp;
12788+	struct lwp *mctc_oldlwp;
12789+	mach_natural_t *mctc_state;
12790+	int mctc_flavor;
12791+	int mctc_child_done;
12792+};
12793+
12794+/* For mach_sys_syscall_thread_switch() */
12795+#define MACH_SWITCH_OPTION_NONE	0
12796+#define MACH_SWITCH_OPTION_DEPRESS	1
12797+#define MACH_SWITCH_OPTION_WAIT	2
12798+#define MACH_SWITCH_OPTION_IDLE	3
12799+
12800+/* For mach_thread_info */
12801+#define MACH_THREAD_BASIC_INFO 3
12802+struct mach_thread_basic_info {
12803+	mach_time_value_t	user_time;
12804+	mach_time_value_t	system_time;
12805+	mach_integer_t	cpu_usage;
12806+	mach_policy_t	policy;
12807+	mach_integer_t	run_state;
12808+	mach_integer_t	flags;
12809+	mach_integer_t	suspend_count;
12810+	mach_integer_t	sleep_time;
12811+};
12812+#define MACH_TH_STATE_RUNNING		1
12813+#define MACH_TH_STATE_STOPPED		2
12814+#define MACH_TH_STATE_WAITING		3
12815+#define MACH_TH_STATE_UNINTERRUPTIBLE	4
12816+#define MACH_TH_STATE_HALTED		5
12817+
12818+#define MACH_TH_FLAGS_SWAPPED	1
12819+#define MACH_TH_FLAGS_IDLE	2
12820+
12821+#define MACH_THREAD_SCHED_TIMESHARE_INFO 10
12822+struct mach_policy_timeshare_info {
12823+	mach_integer_t max_priority;
12824+	mach_integer_t base_priority;
12825+	mach_integer_t cur_priority;
12826+	mach_boolean_t depressed;
12827+	mach_integer_t depress_priority;
12828+};
12829+
12830+#define MACH_THREAD_SCHED_RR_INFO	11
12831+#define MACH_THREAD_SCHED_FIFO_INFO	12
12832+
12833+/* For mach_policy_t */
12834+#define MACH_THREAD_STANDARD_POLICY	1
12835+#define MACH_THREAD_TIME_CONSTRAINT_POLICY 2
12836+#define MACH_THREAD_PRECEDENCE_POLICY	3
12837+
12838+/* thread_policy */
12839+
12840+typedef struct {
12841+	mach_msg_header_t req_msgh;
12842+	mach_ndr_record_t req_ndr;
12843+	mach_policy_t req_policy;
12844+	mach_msg_type_number_t req_count;
12845+	mach_integer_t req_base[0];
12846+	mach_boolean_t req_setlimit;
12847+} mach_thread_policy_request_t;
12848+
12849+typedef struct {
12850+	mach_msg_header_t rep_msgh;
12851+	mach_ndr_record_t rep_ndr;
12852+	mach_kern_return_t rep_retval;
12853+	mach_msg_trailer_t rep_trailer;
12854+} mach_thread_policy_reply_t;
12855+
12856+/* mach_thread_create_running */
12857+
12858+typedef struct {
12859+	mach_msg_header_t req_msgh;
12860+	mach_ndr_record_t req_ndr;
12861+	mach_thread_state_flavor_t req_flavor;
12862+	mach_msg_type_number_t req_count;
12863+	mach_natural_t req_state[0];
12864+} mach_thread_create_running_request_t;
12865+
12866+typedef struct {
12867+	mach_msg_header_t rep_msgh;
12868+	mach_msg_body_t rep_body;
12869+	mach_msg_port_descriptor_t rep_child_act;
12870+	mach_msg_trailer_t rep_trailer;
12871+} mach_thread_create_running_reply_t;
12872+
12873+/* mach_thread_info */
12874+
12875+typedef struct {
12876+	mach_msg_header_t req_msgh;
12877+	mach_ndr_record_t req_ndr;
12878+	mach_thread_flavor_t req_flavor;
12879+	mach_msg_type_number_t req_count;
12880+} mach_thread_info_request_t;
12881+
12882+typedef struct {
12883+	mach_msg_header_t rep_msgh;
12884+	mach_ndr_record_t rep_ndr;
12885+	mach_kern_return_t rep_retval;
12886+	mach_msg_type_number_t rep_count;
12887+	mach_integer_t rep_out[12];
12888+	mach_msg_trailer_t rep_trailer;
12889+} mach_thread_info_reply_t;
12890+
12891+/* thread_get_state */
12892+
12893+typedef struct {
12894+	mach_msg_header_t req_msgh;
12895+	mach_ndr_record_t req_ndr;
12896+	mach_thread_state_flavor_t req_flavor;
12897+	mach_msg_type_number_t req_count;
12898+} mach_thread_get_state_request_t;
12899+
12900+typedef struct {
12901+	mach_msg_header_t rep_msgh;
12902+	mach_ndr_record_t rep_ndr;
12903+	mach_kern_return_t rep_retval;
12904+	mach_msg_type_number_t rep_count;
12905+	mach_integer_t rep_state[144];
12906+	mach_msg_trailer_t rep_trailer;
12907+} mach_thread_get_state_reply_t;
12908+
12909+/* mach_thread_set_state */
12910+
12911+typedef struct {
12912+	mach_msg_header_t req_msgh;
12913+	mach_ndr_record_t req_ndr;
12914+	mach_thread_state_flavor_t req_flavor;
12915+	mach_msg_type_number_t req_count;
12916+	mach_integer_t req_state[0];
12917+} mach_thread_set_state_request_t;
12918+
12919+typedef struct {
12920+	mach_msg_header_t rep_msgh;
12921+	mach_ndr_record_t rep_ndr;
12922+	mach_kern_return_t rep_retval;
12923+	mach_msg_trailer_t rep_trailer;
12924+} mach_thread_set_state_reply_t;
12925+
12926+/* thread_suspend */
12927+
12928+typedef struct {
12929+	mach_msg_header_t req_msgh;
12930+} mach_thread_suspend_request_t;
12931+
12932+typedef struct {
12933+	mach_msg_header_t rep_msgh;
12934+	mach_ndr_record_t rep_ndr;
12935+	mach_kern_return_t rep_retval;
12936+	mach_msg_trailer_t rep_trailer;
12937+} mach_thread_suspend_reply_t;
12938+
12939+/* thread_resume */
12940+
12941+typedef struct {
12942+	mach_msg_header_t req_msgh;
12943+} mach_thread_resume_request_t;
12944+
12945+typedef struct {
12946+	mach_msg_header_t rep_msgh;
12947+	mach_ndr_record_t rep_ndr;
12948+	mach_kern_return_t rep_retval;
12949+	mach_msg_trailer_t rep_trailer;
12950+} mach_thread_resume_reply_t;
12951+
12952+/* thread_abort */
12953+
12954+typedef struct {
12955+	mach_msg_header_t req_msgh;
12956+} mach_thread_abort_request_t;
12957+
12958+typedef struct {
12959+	mach_msg_header_t rep_msgh;
12960+	mach_ndr_record_t rep_ndr;
12961+	mach_kern_return_t rep_retval;
12962+	mach_msg_trailer_t rep_trailer;
12963+} mach_thread_abort_reply_t;
12964+
12965+/* thread_set_policy */
12966+
12967+typedef struct {
12968+	mach_msg_header_t req_msgh;
12969+	mach_msg_body_t req_body;
12970+	mach_msg_port_descriptor_t req_pset;
12971+	mach_ndr_record_t req_ndr;
12972+	mach_policy_t req_policy;
12973+	mach_msg_type_number_t req_base_count;
12974+	mach_integer_t req_base[0];
12975+	mach_msg_type_number_t req_limit_count;
12976+	mach_integer_t req_limit[0];
12977+} mach_thread_set_policy_request_t;
12978+
12979+typedef struct {
12980+	mach_msg_header_t rep_msgh;
12981+	mach_ndr_record_t rep_ndr;
12982+	mach_kern_return_t rep_retval;
12983+	mach_msg_trailer_t rep_trailer;
12984+} mach_thread_set_policy_reply_t;
12985+
12986+/* These are machine dependent functions */
12987+int mach_thread_get_state_machdep(struct lwp *, int, void *, int *);
12988+int mach_thread_set_state_machdep(struct lwp *, int, void *);
12989+void mach_create_thread_child(void *);
12990+
12991+#endif /* _MACH_THREAD_H_ */
12992diff --git a/sys/compat/mach/mach_types.h b/sys/compat/mach/mach_types.h
12993new file mode 100644
12994index 0000000..7a2617b
12995--- /dev/null
12996+++ b/sys/compat/mach/mach_types.h
12997@@ -0,0 +1,113 @@
12998+/*	$NetBSD: mach_types.h,v 1.24 2008/04/28 20:23:44 martin Exp $	 */
12999+
13000+/*-
13001+ * Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
13002+ * All rights reserved.
13003+ *
13004+ * This code is derived from software contributed to The NetBSD Foundation
13005+ * by Christos Zoulas and Emmanuel Dreyfus.
13006+ *
13007+ * Redistribution and use in source and binary forms, with or without
13008+ * modification, are permitted provided that the following conditions
13009+ * are met:
13010+ * 1. Redistributions of source code must retain the above copyright
13011+ *    notice, this list of conditions and the following disclaimer.
13012+ * 2. Redistributions in binary form must reproduce the above copyright
13013+ *    notice, this list of conditions and the following disclaimer in the
13014+ *    documentation and/or other materials provided with the distribution.
13015+ *
13016+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
13017+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
13018+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13019+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
13020+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
13021+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
13022+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
13023+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
13024+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
13025+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
13026+ * POSSIBILITY OF SUCH DAMAGE.
13027+ */
13028+
13029+#ifndef	_MACH_TYPES_H_
13030+#define	_MACH_TYPES_H_
13031+
13032+typedef int mach_port_t;
13033+typedef int mach_port_name_t;
13034+typedef int mach_port_type_t;
13035+typedef register_t mach_kern_return_t;
13036+typedef int mach_clock_res_t;
13037+typedef int mach_clock_id_t;
13038+typedef int mach_boolean_t;
13039+typedef int mach_sleep_type_t;
13040+typedef int mach_absolute_time_t;
13041+typedef int mach_integer_t;
13042+typedef int mach_cpu_type_t;
13043+typedef int mach_cpu_subtype_t;
13044+typedef int mach_port_right_t;
13045+typedef register_t mach_vm_address_t;
13046+typedef int mach_vm_inherit_t;
13047+typedef int mach_vm_prot_t;
13048+typedef int mach_thread_state_flavor_t;
13049+typedef unsigned int mach_natural_t;
13050+typedef unsigned long mach_vm_size_t;
13051+typedef uint64_t mach_memory_object_size_t;
13052+typedef unsigned long mach_vm_offset_t;
13053+typedef uint64_t mach_memory_object_offset_t;
13054+typedef int mach_vm_region_flavor_t;
13055+typedef int mach_vm_behavior_t;
13056+typedef int mach_vm_sync_t;
13057+typedef int mach_exception_type_t;
13058+typedef int mach_exception_behavior_t;
13059+typedef unsigned int mach_exception_mask_t;
13060+typedef int mach_port_flavor_t;
13061+typedef mach_natural_t mach_port_seqno_t;
13062+typedef mach_natural_t mach_port_mscount_t;
13063+typedef mach_natural_t mach_port_msgcount_t;
13064+typedef mach_natural_t mach_port_rights_t;
13065+typedef mach_natural_t mach_task_flavor_t;
13066+typedef mach_natural_t mach_thread_flavor_t;
13067+typedef int mach_policy_t;
13068+typedef int mach_vm_machine_attribute_val_t;
13069+typedef unsigned int mach_vm_machine_attribute_t;
13070+typedef mach_natural_t mach_port_urefs_t;
13071+typedef int mach_port_delta_t;
13072+
13073+
13074+/*
13075+ * This is called cproc_t in Mach (cthread_t in Darwin). It is a pointer to
13076+ * a struct cproc (struct cthread in Darwin), which is stored in userland and
13077+ * seems to be opaque to the kernel. The kernel just has to store and restore
13078+ * it with cthread_self() (pthread_self() in Darwin) and _cthread_set_self()
13079+ * (_pthread_set_self() in Darwin).
13080+ */
13081+typedef void *mach_cproc_t;
13082+
13083+typedef struct mach_timebase_info {
13084+	u_int32_t	numer;
13085+	u_int32_t	denom;
13086+} *mach_timebase_info_t;
13087+
13088+typedef struct {
13089+	u_int8_t       mig_vers;
13090+	u_int8_t       if_vers;
13091+	u_int8_t       reserved1;
13092+	u_int8_t       mig_encoding;
13093+	u_int8_t       int_rep;
13094+	u_int8_t       char_rep;
13095+	u_int8_t       float_rep;
13096+	u_int8_t       reserved2;
13097+} mach_ndr_record_t;
13098+
13099+typedef struct {
13100+	mach_integer_t seconds;
13101+	mach_integer_t microseconds;
13102+} mach_time_value_t;
13103+
13104+#ifdef DEBUG_MACH
13105+#define DPRINTF(a) printf a
13106+#else
13107+#define DPRINTF(a)
13108+#endif /* DEBUG_MACH */
13109+
13110+#endif /* !_MACH_TYPES_H_ */
13111diff --git a/sys/compat/mach/mach_vm.c b/sys/compat/mach/mach_vm.c
13112new file mode 100644
13113index 0000000..b495add
13114--- /dev/null
13115+++ b/sys/compat/mach/mach_vm.c
13116@@ -0,0 +1,881 @@
13117+/*	$NetBSD: mach_vm.c,v 1.62 2010/06/24 13:03:07 hannken Exp $ */
13118+
13119+/*-
13120+ * Copyright (c) 2002-2003, 2008 The NetBSD Foundation, Inc.
13121+ * All rights reserved.
13122+ *
13123+ * This code is derived from software contributed to The NetBSD Foundation
13124+ * by Emmanuel Dreyfus
13125+ *
13126+ * Redistribution and use in source and binary forms, with or without
13127+ * modification, are permitted provided that the following conditions
13128+ * are met:
13129+ * 1. Redistributions of source code must retain the above copyright
13130+ *    notice, this list of conditions and the following disclaimer.
13131+ * 2. Redistributions in binary form must reproduce the above copyright
13132+ *    notice, this list of conditions and the following disclaimer in the
13133+ *    documentation and/or other materials provided with the distribution.
13134+ *
13135+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
13136+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
13137+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13138+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
13139+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
13140+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
13141+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
13142+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
13143+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
13144+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
13145+ * POSSIBILITY OF SUCH DAMAGE.
13146+ */
13147+
13148+#include <sys/cdefs.h>
13149+__KERNEL_RCSID(0, "$NetBSD: mach_vm.c,v 1.62 2010/06/24 13:03:07 hannken Exp $");
13150+
13151+#include <sys/types.h>
13152+#include <sys/param.h>
13153+#include <sys/systm.h>
13154+#include <sys/mount.h>
13155+#include <sys/proc.h>
13156+#include <sys/mman.h>
13157+#include <sys/malloc.h>
13158+#include <sys/vnode.h>
13159+#include <sys/file.h>
13160+#include <sys/filedesc.h>
13161+#include <sys/ktrace.h>
13162+#include <sys/exec.h>
13163+#include <sys/syscallargs.h>
13164+
13165+#include <uvm/uvm_prot.h>
13166+#include <uvm/uvm_map.h>
13167+#include <uvm/uvm_extern.h>
13168+
13169+#include <compat/mach/mach_types.h>
13170+#include <compat/mach/mach_message.h>
13171+#include <compat/mach/mach_clock.h>
13172+#include <compat/mach/mach_vm.h>
13173+#include <compat/mach/mach_errno.h>
13174+#include <compat/mach/mach_port.h>
13175+#include <compat/mach/mach_services.h>
13176+#include <compat/mach/mach_syscallargs.h>
13177+
13178+int
13179+mach_vm_map(struct mach_trap_args *args)
13180+{
13181+	mach_vm_map_request_t *req = args->smsg;
13182+	mach_vm_map_reply_t *rep = args->rmsg;
13183+	size_t *msglen = args->rsize;
13184+	struct lwp *tl = args->tl;
13185+	struct proc *tp = tl->l_proc;
13186+	struct sys_mmap_args cup;
13187+	vaddr_t addr;
13188+	int error, flags;
13189+	void *ret;
13190+
13191+#ifdef DEBUG_MACH_VM
13192+	printf("mach_vm_map(addr = %p, size = 0x%08lx, obj = 0x%x, "
13193+	    "mask = 0x%08lx, flags = 0x%x, offset = 0x%08llx, "
13194+	    "copy = %d, cur_prot = 0x%x, max_prot = 0x%x, inh = 0x%x);\n",
13195+	    (void *)req->req_address, (long)req->req_size, req->req_object.name,
13196+	    (long)req->req_mask, req->req_flags, (off_t)req->req_offset,
13197+	    req->req_copy, req->req_cur_protection, req->req_max_protection,
13198+	    req->req_inherance);
13199+#endif
13200+
13201+	/* XXX Darwin fails on mapping a page at address 0 */
13202+	if (req->req_address == 0)
13203+		return mach_msg_error(args, ENOMEM);
13204+
13205+	req->req_size = round_page(req->req_size);
13206+
13207+	/* Where Mach uses 0x00ff, we use 0x0100 */
13208+	if ((req->req_mask & (req->req_mask + 1)) || (req->req_mask == 0))
13209+		req->req_mask = 0;
13210+	else
13211+		req->req_mask += 1;
13212+
13213+	if (req->req_flags & MACH_VM_FLAGS_ANYWHERE) {
13214+		SCARG(&cup, flags) = MAP_ANON;
13215+		flags = 0;
13216+	} else {
13217+		SCARG(&cup, flags) = MAP_ANON | MAP_FIXED;
13218+		flags = MAP_FIXED;
13219+	}
13220+
13221+	/*
13222+	 * Use uvm_map_findspace to find a place which conforms to the
13223+	 * requested alignement.
13224+	 */
13225+	vm_map_lock(&tp->p_vmspace->vm_map);
13226+	ret = uvm_map_findspace(&tp->p_vmspace->vm_map,
13227+	    trunc_page(req->req_address), req->req_size, &addr,
13228+	    NULL, 0, req->req_mask, flags);
13229+	vm_map_unlock(&tp->p_vmspace->vm_map);
13230+
13231+	if (ret == NULL)
13232+		return mach_msg_error(args, ENOMEM);
13233+
13234+	switch(req->req_inherance) {
13235+	case MACH_VM_INHERIT_SHARE:
13236+		SCARG(&cup, flags) |= MAP_INHERIT;
13237+		break;
13238+	case MACH_VM_INHERIT_COPY:
13239+		SCARG(&cup, flags) |= MAP_COPY;
13240+		break;
13241+	case MACH_VM_INHERIT_NONE:
13242+		break;
13243+	case MACH_VM_INHERIT_DONATE_COPY:
13244+	default:
13245+		uprintf("mach_vm_map: unsupported inherance flag %d\n",
13246+		    req->req_inherance);
13247+		break;
13248+	}
13249+
13250+	SCARG(&cup, addr) = (void *)addr;
13251+	SCARG(&cup, len) = req->req_size;
13252+	SCARG(&cup, prot) = req->req_cur_protection;
13253+	SCARG(&cup, fd) = -1;		/* XXX For now, no object mapping */
13254+	SCARG(&cup, pos) = req->req_offset;
13255+
13256+	if ((error = sys_mmap(tl, &cup, &rep->rep_retval)) != 0)
13257+		return mach_msg_error(args, error);
13258+
13259+	*msglen = sizeof(*rep);
13260+	mach_set_header(rep, req, *msglen);
13261+	mach_set_trailer(rep, *msglen);
13262+
13263+	return 0;
13264+}
13265+
13266+int
13267+mach_vm_allocate(struct mach_trap_args *args)
13268+{
13269+	mach_vm_allocate_request_t *req = args->smsg;
13270+	mach_vm_allocate_reply_t *rep = args->rmsg;
13271+	size_t *msglen = args->rsize;
13272+	struct lwp *tl = args->tl;
13273+	struct proc *tp = tl->l_proc;
13274+	struct sys_mmap_args cup;
13275+	vaddr_t addr;
13276+	size_t size;
13277+	int error;
13278+
13279+	addr = req->req_address;
13280+	size = req->req_size;
13281+
13282+#ifdef DEBUG_MACH_VM
13283+	printf("mach_vm_allocate(addr = %p, size = 0x%08x);\n",
13284+	    (void *)addr, size);
13285+#endif
13286+
13287+	/*
13288+	 * Avoid mappings at address zero: it should
13289+	 * be a "red zone" with nothing mapped on it.
13290+	 */
13291+	if (addr == 0) {
13292+		if (req->req_flags & MACH_VM_FLAGS_ANYWHERE)
13293+			addr = 0x1000;
13294+		else
13295+			return mach_msg_error(args, EINVAL);
13296+#ifdef DEBUG_MACH_VM
13297+		printf("mach_vm_allocate: trying addr = %p\n", (void *)addr);
13298+#endif
13299+	}
13300+
13301+	size = round_page(size);
13302+	if (req->req_flags & MACH_VM_FLAGS_ANYWHERE)
13303+		addr = vm_map_min(&tp->p_vmspace->vm_map);
13304+	else
13305+		addr = trunc_page(addr);
13306+
13307+	if (((addr + size) > vm_map_max(&tp->p_vmspace->vm_map)) ||
13308+	    ((addr + size) <= addr))
13309+		addr = vm_map_min(&tp->p_vmspace->vm_map);
13310+
13311+	if (size == 0)
13312+		goto out;
13313+
13314+	SCARG(&cup, addr) = (void *)addr;
13315+	SCARG(&cup, len) = size;
13316+	SCARG(&cup, prot) = PROT_READ | PROT_WRITE;
13317+	SCARG(&cup, flags) = MAP_ANON;
13318+	if ((req->req_flags & MACH_VM_FLAGS_ANYWHERE) == 0)
13319+		SCARG(&cup, flags) |= MAP_FIXED;
13320+	SCARG(&cup, fd) = -1;
13321+	SCARG(&cup, pos) = 0;
13322+
13323+	if ((error = sys_mmap(tl, &cup, &rep->rep_address)) != 0)
13324+		return mach_msg_error(args, error);
13325+#ifdef DEBUG_MACH_VM
13326+	printf("vm_allocate: success at %p\n", (void *)rep->rep_address);
13327+#endif
13328+
13329+out:
13330+	*msglen = sizeof(*rep);
13331+	mach_set_header(rep, req, *msglen);
13332+
13333+	rep->rep_retval = 0;
13334+
13335+	mach_set_trailer(rep, *msglen);
13336+
13337+	return 0;
13338+}
13339+
13340+int
13341+mach_vm_deallocate(struct mach_trap_args *args)
13342+{
13343+	mach_vm_deallocate_request_t *req = args->smsg;
13344+	mach_vm_deallocate_reply_t *rep = args->rmsg;
13345+	size_t *msglen = args->rsize;
13346+	struct lwp *tl = args->tl;
13347+	struct sys_munmap_args cup;
13348+	int error;
13349+
13350+#ifdef DEBUG_MACH_VM
13351+	printf("mach_vm_deallocate(addr = %p, size = 0x%08lx);\n",
13352+	    (void *)req->req_address, (long)req->req_size);
13353+#endif
13354+
13355+	SCARG(&cup, addr) = (void *)req->req_address;
13356+	SCARG(&cup, len) = req->req_size;
13357+
13358+	if ((error = sys_munmap(tl, &cup, &rep->rep_retval)) != 0)
13359+		return mach_msg_error(args, error);
13360+
13361+	*msglen = sizeof(*rep);
13362+	mach_set_header(rep, req, *msglen);
13363+	mach_set_trailer(rep, *msglen);
13364+
13365+	return 0;
13366+}
13367+
13368+/*
13369+ * XXX This server message Id clashes with bootstrap_look_up.
13370+ * Is there a way to resolve this easily?
13371+ */
13372+#if 0
13373+int
13374+mach_vm_wire(struct mach_trap_args *args)
13375+{
13376+	mach_vm_wire_request_t *req = args->smsg;
13377+	mach_vm_wire_reply_t *rep = args->rmsg;
13378+	size_t *msglen = args->rsize;
13379+	struct lwp *tl = args->tl;
13380+	register_t retval;
13381+	int error;
13382+
13383+#ifdef DEBUG_MACH_VM
13384+	printf("mach_vm_wire(addr = %p, size = 0x%08x, prot = 0x%x);\n",
13385+	    (void *)req->req_address, req->req_size, req->req_access);
13386+#endif
13387+
13388+	memset(&rep, 0, sizeof(*rep));
13389+
13390+	if ((req->req_access & ~VM_PROT_ALL) != 0)
13391+		return mach_msg_error(args, EINVAL);
13392+
13393+	/*
13394+	 * Mach maintains a count of how many times a page is wired
13395+	 * and unwire it once the count is zero. We cannot do that yet.
13396+	 */
13397+	if (req->req_access == 0) {
13398+		struct sys_munlock_args cup;
13399+
13400+		SCARG(&cup, addr) = (void *)req->req_address;
13401+		SCARG(&cup, len) = req->req_size;
13402+		error = sys_munlock(tl, &cup, &retval);
13403+	} else {
13404+		struct sys_mlock_args cup;
13405+
13406+		SCARG(&cup, addr) = (void *)req->req_address;
13407+		SCARG(&cup, len) = req->req_size;
13408+		error = sys_mlock(tl, &cup, &retval);
13409+	}
13410+	if (error != 0)
13411+		return mach_msg_error(args, error);
13412+
13413+	if ((error = uvm_map_protect(&tl->l_proc->p_vmspace->vm_map,
13414+	    req->req_address, req->req_address + req->req_size,
13415+	    req->req_access, 0)) != 0)
13416+		return mach_msg_error(args, error);
13417+
13418+	*msglen = sizeof(*rep);
13419+	mach_set_header(rep, req, *msglen);
13420+	mach_set_trailer(rep, *msglen);
13421+
13422+	return 0;
13423+}
13424+#endif
13425+
13426+int
13427+mach_vm_protect(struct mach_trap_args *args)
13428+{
13429+	mach_vm_protect_request_t *req = args->smsg;
13430+	mach_vm_protect_reply_t *rep = args->rmsg;
13431+	size_t *msglen = args->rsize;
13432+	struct lwp *tl = args->tl;
13433+	struct sys_mprotect_args cup;
13434+	register_t retval;
13435+	int error;
13436+
13437+	SCARG(&cup, addr) = (void *)req->req_addr;
13438+	SCARG(&cup, len) = req->req_size;
13439+	SCARG(&cup, prot) = req->req_prot;
13440+
13441+	if ((error = sys_mprotect(tl, &cup, &retval)) != 0)
13442+		return mach_msg_error(args, error);
13443+
13444+	*msglen = sizeof(*rep);
13445+	mach_set_header(rep, req, *msglen);
13446+	mach_set_trailer(rep, *msglen);
13447+
13448+	return 0;
13449+}
13450+
13451+int
13452+mach_sys_map_fd(struct lwp *l, const struct mach_sys_map_fd_args *uap, register_t *retval)
13453+{
13454+	/* {
13455+		syscallarg(int) fd;
13456+		syscallarg(mach_vm_offset_t) offset;
13457+		syscallarg(mach_vm_offset_t *) va;
13458+		syscallarg(mach_boolean_t) findspace;
13459+		syscallarg(mach_vm_size_t) size;
13460+	} */
13461+	file_t *fp;
13462+	struct vnode *vp;
13463+	struct exec_vmcmd evc;
13464+	struct vm_map_entry *ret;
13465+	struct proc *p = l->l_proc;
13466+	register_t dontcare;
13467+	struct sys_munmap_args cup;
13468+	void *va;
13469+	int error;
13470+
13471+	if ((error = copyin(SCARG(uap, va), (void *)&va, sizeof(va))) != 0)
13472+		return error;
13473+
13474+	if (SCARG(uap, findspace) == 0) {
13475+		/* Make some free space XXX probably not The Right Way */
13476+		SCARG(&cup, addr) = va;
13477+		SCARG(&cup, len) = SCARG(uap, size);
13478+		(void)sys_munmap(l, &cup, &dontcare);
13479+	}
13480+
13481+	fp = fd_getfile(SCARG(uap, fd));
13482+	if (fp == NULL)
13483+		return EBADF;
13484+
13485+	vp = fp->f_data;
13486+	vref(vp);
13487+
13488+#ifdef DEBUG_MACH_VM
13489+	printf("vm_map_fd: addr = %p len = 0x%08lx\n",
13490+	    va, (long)SCARG(uap, size));
13491+#endif
13492+	memset(&evc, 0, sizeof(evc));
13493+	evc.ev_addr = (u_long)va;
13494+	evc.ev_len = SCARG(uap, size);
13495+	evc.ev_prot = VM_PROT_ALL;
13496+	evc.ev_flags = SCARG(uap, findspace) ? 0 : VMCMD_FIXED;
13497+	evc.ev_proc = vmcmd_map_readvn;
13498+	evc.ev_offset = SCARG(uap, offset);
13499+	evc.ev_vp = vp;
13500+
13501+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
13502+	if ((error = (*evc.ev_proc)(l, &evc)) != 0) {
13503+		VOP_UNLOCK(vp);
13504+
13505+#ifdef DEBUG_MACH_VM
13506+		printf("mach_sys_map_fd: mapping at %p failed\n", va);
13507+#endif
13508+
13509+		if (SCARG(uap, findspace) == 0)
13510+			goto bad2;
13511+
13512+		vm_map_lock(&p->p_vmspace->vm_map);
13513+		if ((ret = uvm_map_findspace(&p->p_vmspace->vm_map,
13514+		    vm_map_min(&p->p_vmspace->vm_map), evc.ev_len,
13515+		    (vaddr_t *)&evc.ev_addr, NULL, 0, PAGE_SIZE, 0)) == NULL) {
13516+			vm_map_unlock(&p->p_vmspace->vm_map);
13517+			goto bad2;
13518+		}
13519+		vm_map_unlock(&p->p_vmspace->vm_map);
13520+
13521+		va = (void *)evc.ev_addr;
13522+
13523+		memset(&evc, 0, sizeof(evc));
13524+		evc.ev_addr = (u_long)va;
13525+		evc.ev_len = SCARG(uap, size);
13526+		evc.ev_prot = VM_PROT_ALL;
13527+		evc.ev_flags = 0;
13528+		evc.ev_proc = vmcmd_map_readvn;
13529+		evc.ev_offset = SCARG(uap, offset);
13530+		evc.ev_vp = vp;
13531+
13532+#ifdef DEBUG_MACH_VM
13533+		printf("mach_sys_map_fd: trying at %p\n", va);
13534+#endif
13535+		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
13536+		if ((error = (*evc.ev_proc)(l, &evc)) != 0)
13537+			goto bad1;
13538+	}
13539+
13540+	vput(vp);
13541+	fd_putfile(SCARG(uap, fd));
13542+#ifdef DEBUG_MACH_VM
13543+	printf("mach_sys_map_fd: mapping at %p\n", (void *)evc.ev_addr);
13544+#endif
13545+
13546+	va = (mach_vm_offset_t *)evc.ev_addr;
13547+
13548+	if ((error = copyout((void *)&va, SCARG(uap, va), sizeof(va))) != 0)
13549+		return error;
13550+
13551+	return 0;
13552+
13553+bad1:
13554+	VOP_UNLOCK(vp);
13555+bad2:
13556+	vrele(vp);
13557+	fd_putfile(SCARG(uap, fd));
13558+#ifdef DEBUG_MACH_VM
13559+	printf("mach_sys_map_fd: mapping at %p failed, error = %d\n",
13560+	    (void *)evc.ev_addr, error);
13561+#endif
13562+	return error;
13563+}
13564+
13565+int
13566+mach_vm_inherit(struct mach_trap_args *args)
13567+{
13568+	mach_vm_inherit_request_t *req = args->smsg;
13569+	mach_vm_inherit_reply_t *rep = args->rmsg;
13570+	size_t *msglen = args->rsize;
13571+	struct lwp *tl = args->tl;
13572+	struct sys_minherit_args cup;
13573+	register_t retval;
13574+	int error;
13575+
13576+	SCARG(&cup, addr) = (void *)req->req_addr;
13577+	SCARG(&cup, len) = req->req_size;
13578+	/* Flags map well between Mach and NetBSD */
13579+	SCARG(&cup, inherit) = req->req_inh;
13580+
13581+	if ((error = sys_minherit(tl, &cup, &retval)) != 0)
13582+		return mach_msg_error(args, error);
13583+
13584+	*msglen = sizeof(*rep);
13585+	mach_set_header(rep, req, *msglen);
13586+	mach_set_trailer(rep, *msglen);
13587+
13588+	return 0;
13589+}
13590+
13591+int
13592+mach_make_memory_entry_64(struct mach_trap_args *args)
13593+{
13594+	mach_make_memory_entry_64_request_t *req = args->smsg;
13595+	mach_make_memory_entry_64_reply_t *rep = args->rmsg;
13596+	size_t *msglen = args->rsize;
13597+	struct lwp *l = args->l;
13598+	struct lwp *tl = args->tl;
13599+	struct mach_port *mp;
13600+	struct mach_right *mr;
13601+	struct mach_memory_entry *mme;
13602+
13603+	printf("mach_make_memory_entry_64, offset 0x%lx, size 0x%lx\n",
13604+	    (u_long)req->req_offset, (u_long)req->req_size);
13605+
13606+	mp = mach_port_get();
13607+	mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
13608+	mp->mp_datatype = MACH_MP_MEMORY_ENTRY;
13609+
13610+	mme = malloc(sizeof(*mme), M_EMULDATA, M_WAITOK);
13611+	mme->mme_proc = tl->l_proc;
13612+	mme->mme_offset = req->req_offset;
13613+	mme->mme_size = req->req_size;
13614+	mp->mp_data = mme;
13615+
13616+	mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
13617+
13618+	*msglen = sizeof(*rep);
13619+	mach_set_header(rep, req, *msglen);
13620+	mach_add_port_desc(rep, mr->mr_name);
13621+
13622+	rep->rep_size = req->req_size;
13623+
13624+	mach_set_trailer(rep, *msglen);
13625+
13626+	return 0;
13627+}
13628+
13629+int
13630+mach_vm_region(struct mach_trap_args *args)
13631+{
13632+	mach_vm_region_request_t *req = args->smsg;
13633+	mach_vm_region_reply_t *rep = args->rmsg;
13634+	size_t *msglen = args->rsize;
13635+	struct lwp *tl = args->tl;
13636+	struct mach_vm_region_basic_info *rbi;
13637+	struct vm_map *map;
13638+	struct vm_map_entry *vme;
13639+	int error;
13640+
13641+	/* Sanity check req_count */
13642+	if (req->req_count > 9)
13643+		return mach_msg_error(args, EINVAL);
13644+
13645+	/*
13646+	 * MACH_VM_REGION_BASIC_INFO is the only
13647+	 * supported flavor in Darwin.
13648+	 */
13649+	if (req->req_flavor != MACH_VM_REGION_BASIC_INFO)
13650+		return mach_msg_error(args, EINVAL);
13651+	if (req->req_count != (sizeof(*rbi) / sizeof(int))) /* This is 8 */
13652+		return mach_msg_error(args, EINVAL);
13653+	*msglen = sizeof(*rep) + ((req->req_count - 9) * sizeof(int));
13654+
13655+	map = &tl->l_proc->p_vmspace->vm_map;
13656+
13657+	vm_map_lock(map);
13658+	error = uvm_map_lookup_entry(map, req->req_addr, &vme);
13659+	vm_map_unlock(map);
13660+
13661+	if (error == 0)
13662+		return mach_msg_error(args, ENOMEM);
13663+
13664+	mach_set_header(rep, req, *msglen);
13665+	mach_add_port_desc(rep, 0); /* XXX Why this null name */
13666+
13667+	rep->rep_addr = vme->start;
13668+	rep->rep_size = vme->end - vme->start;
13669+	rep->rep_count = req->req_count;
13670+
13671+	rbi = (struct mach_vm_region_basic_info *)&rep->rep_info[0];
13672+	rbi->protection = vme->protection;
13673+	rbi->inheritance = 1; /* vme->inheritance */
13674+	rbi->shared = 0; /* XXX how can we know? */
13675+	rbi->offset = vme->offset;
13676+	rbi->behavior = MACH_VM_BEHAVIOR_DEFAULT; /* XXX What is it? */
13677+	rbi->user_wired_count = vme->wired_count;
13678+
13679+	/* XXX Why this? */
13680+	*(short *)((u_long)&rbi->user_wired_count + sizeof(short)) = 1;
13681+
13682+	mach_set_trailer(rep, *msglen);
13683+
13684+	return 0;
13685+}
13686+
13687+int
13688+mach_vm_region_64(struct mach_trap_args *args)
13689+{
13690+	mach_vm_region_64_request_t *req = args->smsg;
13691+	mach_vm_region_64_reply_t *rep = args->rmsg;
13692+	size_t *msglen = args->rsize;
13693+	struct lwp *tl = args->tl;
13694+	struct mach_vm_region_basic_info_64 *rbi;
13695+	struct vm_map *map;
13696+	struct vm_map_entry *vme;
13697+	int error;
13698+
13699+	/* Sanity check req_count */
13700+	if (req->req_count > 10)
13701+		return mach_msg_error(args, EINVAL);
13702+
13703+	/*
13704+	 * MACH_VM_REGION_BASIC_INFO is the only
13705+	 * supported flavor in Darwin.
13706+	 */
13707+	if (req->req_flavor != MACH_VM_REGION_BASIC_INFO)
13708+		return mach_msg_error(args, EINVAL);
13709+	if (req->req_count != (sizeof(*rbi) / sizeof(int))) /* This is 8 */
13710+		return mach_msg_error(args, EINVAL);
13711+	*msglen = sizeof(*rep) + ((req->req_count - 9) * sizeof(int));
13712+
13713+	map = &tl->l_proc->p_vmspace->vm_map;
13714+
13715+	vm_map_lock(map);
13716+	error = uvm_map_lookup_entry(map, req->req_addr, &vme);
13717+	vm_map_unlock(map);
13718+
13719+	if (error == 0)
13720+		return mach_msg_error(args, ENOMEM);
13721+
13722+	mach_set_header(rep, req, *msglen);
13723+	mach_add_port_desc(rep, 0);	/* XXX null port ? */
13724+
13725+	rep->rep_size = PAGE_SIZE; /* XXX Why? */
13726+	rep->rep_count = req->req_count;
13727+
13728+	rbi = (struct mach_vm_region_basic_info_64 *)&rep->rep_info[0];
13729+	rbi->protection = vme->protection;
13730+	rbi->inheritance = 1; /* vme->inheritance */
13731+	rbi->shared = 0; /* XXX how can we know? */
13732+	rbi->offset = vme->offset;
13733+	rbi->behavior = MACH_VM_BEHAVIOR_DEFAULT; /* XXX What is it? */
13734+	rbi->user_wired_count = vme->wired_count;
13735+
13736+	/* XXX Why this? */
13737+	*(short *)((u_long)&rbi->user_wired_count + sizeof(short)) = 1;
13738+
13739+	mach_set_trailer(rep, *msglen);
13740+
13741+	return 0;
13742+}
13743+
13744+int
13745+mach_vm_msync(struct mach_trap_args *args)
13746+{
13747+	mach_vm_msync_request_t *req = args->smsg;
13748+	mach_vm_msync_reply_t *rep = args->rmsg;
13749+	size_t *msglen = args->rsize;
13750+	struct lwp *tl = args->tl;
13751+	struct sys___msync13_args cup;
13752+	int error;
13753+	register_t dontcare;
13754+
13755+	SCARG(&cup, addr) = (void *)req->req_addr;
13756+	SCARG(&cup, len) = req->req_size;
13757+	SCARG(&cup, flags) = 0;
13758+	if (req->req_flags & MACH_VM_SYNC_ASYNCHRONOUS)
13759+		SCARG(&cup, flags) |= MS_ASYNC;
13760+	if (req->req_flags & MACH_VM_SYNC_SYNCHRONOUS)
13761+		SCARG(&cup, flags) |= MS_SYNC;
13762+	if (req->req_flags & MACH_VM_SYNC_INVALIDATE)
13763+		SCARG(&cup, flags) |= MS_INVALIDATE;
13764+
13765+	error = sys___msync13(tl, &cup, &dontcare);
13766+
13767+	*msglen = sizeof(*rep);
13768+	mach_set_header(rep, req, *msglen);
13769+
13770+	rep->rep_retval = native_to_mach_errno[error];
13771+
13772+	mach_set_trailer(rep, *msglen);
13773+
13774+	return 0;
13775+}
13776+
13777+/* XXX Do it for remote task */
13778+int
13779+mach_vm_copy(struct mach_trap_args *args)
13780+{
13781+	mach_vm_copy_request_t *req = args->smsg;
13782+	mach_vm_copy_reply_t *rep = args->rmsg;
13783+	size_t *msglen = args->rsize;
13784+	char *tmpbuf;
13785+	int error;
13786+	char *src, *dst;
13787+	size_t size;
13788+
13789+#ifdef DEBUG_MACH_VM
13790+	printf("mach_vm_copy: src = 0x%08lx, size = 0x%08lx, addr = 0x%08lx\n",
13791+	    (long)req->req_src, (long)req->req_size, (long)req->req_addr);
13792+#endif
13793+	if ((req->req_src & (PAGE_SIZE - 1)) ||
13794+	    (req->req_addr & (PAGE_SIZE - 1)) ||
13795+	    (req->req_size & (PAGE_SIZE - 1)))
13796+		return mach_msg_error(args, EINVAL);
13797+
13798+	src = (void *)req->req_src;
13799+	dst = (void *)req->req_addr;
13800+	size = (size_t)req->req_size;
13801+
13802+	tmpbuf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
13803+
13804+	/* Is there an easy way of dealing with that efficiently? */
13805+	do {
13806+		if ((error = copyin(src, tmpbuf, PAGE_SIZE)) != 0)
13807+			goto out;
13808+
13809+		if ((error = copyout(tmpbuf, dst, PAGE_SIZE)) != 0)
13810+			goto out;
13811+
13812+		src += PAGE_SIZE;
13813+		dst += PAGE_SIZE;
13814+		size -= PAGE_SIZE;
13815+	} while (size > 0);
13816+
13817+	*msglen = sizeof(*rep);
13818+	mach_set_header(rep, req, *msglen);
13819+
13820+	rep->rep_retval = 0;
13821+
13822+	mach_set_trailer(rep, *msglen);
13823+
13824+	free(tmpbuf, M_TEMP);
13825+	return 0;
13826+
13827+out:
13828+	free(tmpbuf, M_TEMP);
13829+	return mach_msg_error(args, error);
13830+}
13831+
13832+int
13833+mach_vm_read(struct mach_trap_args *args)
13834+{
13835+	mach_vm_read_request_t *req = args->smsg;
13836+	mach_vm_read_reply_t *rep = args->rmsg;
13837+	size_t *msglen = args->rsize;
13838+	struct lwp *l = args->l;
13839+	struct lwp *tl = args->tl;
13840+	char *tbuf;
13841+	void *addr;
13842+	vaddr_t va;
13843+	size_t size;
13844+	int error;
13845+
13846+	size = req->req_size;
13847+	va = vm_map_min(&l->l_proc->p_vmspace->vm_map);
13848+	if ((error = uvm_map(&l->l_proc->p_vmspace->vm_map, &va,
13849+	    round_page(size), NULL, UVM_UNKNOWN_OFFSET, 0,
13850+	    UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_ALL,
13851+	    UVM_INH_COPY, UVM_ADV_NORMAL, UVM_FLAG_COPYONW))) != 0) {
13852+		printf("uvm_map error = %d\n", error);
13853+		return mach_msg_error(args, EFAULT);
13854+	}
13855+
13856+	/*
13857+	 * Copy the data from the target process to the current process
13858+	 * This is reasonable for small chunk of data, but we should
13859+	 * remap COW for areas bigger than a page.
13860+	 */
13861+	tbuf = malloc(size, M_EMULDATA, M_WAITOK);
13862+
13863+	addr = (void *)req->req_addr;
13864+	if ((error = copyin_proc(tl->l_proc, addr, tbuf, size)) != 0) {
13865+		printf("copyin_proc error = %d, addr = %p, size = %x\n", error, addr, size);
13866+		free(tbuf, M_WAITOK);
13867+		return mach_msg_error(args, EFAULT);
13868+	}
13869+
13870+	if ((error = copyout(tbuf, (void *)va, size)) != 0) {
13871+		printf("copyout error = %d\n", error);
13872+		free(tbuf, M_WAITOK);
13873+		return mach_msg_error(args, EFAULT);
13874+	}
13875+
13876+	if (error == 0)
13877+		ktrmool(tbuf, size, (void *)va);
13878+
13879+	free(tbuf, M_WAITOK);
13880+
13881+	*msglen = sizeof(*rep);
13882+	mach_set_header(rep, req, *msglen);
13883+	mach_add_ool_desc(rep, (void *)va, size);
13884+
13885+	rep->rep_count = size;
13886+
13887+	mach_set_trailer(rep, *msglen);
13888+
13889+	return 0;
13890+}
13891+
13892+int
13893+mach_vm_write(struct mach_trap_args *args)
13894+{
13895+	mach_vm_write_request_t *req = args->smsg;
13896+	mach_vm_write_reply_t *rep = args->rmsg;
13897+	size_t *msglen = args->rsize;
13898+	struct lwp *tl = args->tl;
13899+	size_t size;
13900+	void *addr;
13901+	char *tbuf;
13902+	int error;
13903+
13904+#ifdef DEBUG_MACH
13905+	if (req->req_body.msgh_descriptor_count != 1)
13906+		printf("mach_vm_write: OOL descriptor count is not 1\n");
13907+#endif
13908+
13909+	/*
13910+	 * Copy the data from the current process to the target process
13911+	 * This is reasonable for small chunk of data, but we should
13912+	 * remap COW for areas bigger than a page.
13913+	 */
13914+	size = req->req_data.size;
13915+	tbuf = malloc(size, M_EMULDATA, M_WAITOK);
13916+
13917+	if ((error = copyin(req->req_data.address, tbuf, size)) != 0) {
13918+		printf("copyin error = %d\n", error);
13919+		free(tbuf, M_WAITOK);
13920+		return mach_msg_error(args, EFAULT);
13921+	}
13922+
13923+	addr = (void *)req->req_addr;
13924+	if ((error = copyout_proc(tl->l_proc, tbuf, addr, size)) != 0) {
13925+		printf("copyout_proc error = %d\n", error);
13926+		free(tbuf, M_WAITOK);
13927+		return mach_msg_error(args, EFAULT);
13928+	}
13929+
13930+	if (error == 0)
13931+		ktrmool(tbuf, size, (void *)addr);
13932+
13933+	free(tbuf, M_WAITOK);
13934+
13935+	*msglen = sizeof(*rep);
13936+	mach_set_header(rep, req, *msglen);
13937+
13938+	rep->rep_retval = 0;
13939+
13940+	mach_set_trailer(rep, *msglen);
13941+
13942+	return 0;
13943+}
13944+
13945+int
13946+mach_vm_machine_attribute(struct mach_trap_args *args)
13947+{
13948+	mach_vm_machine_attribute_request_t *req = args->smsg;
13949+	mach_vm_machine_attribute_reply_t *rep = args->rmsg;
13950+	size_t *msglen = args->rsize;
13951+	struct lwp *tl = args->tl;
13952+	int error = 0;
13953+	int attribute, value;
13954+
13955+	attribute = req->req_attribute;
13956+	value = req->req_value;
13957+
13958+	switch (attribute) {
13959+	case MACH_MATTR_CACHE:
13960+		switch(value) {
13961+		case MACH_MATTR_VAL_CACHE_FLUSH:
13962+		case MACH_MATTR_VAL_DCACHE_FLUSH:
13963+		case MACH_MATTR_VAL_ICACHE_FLUSH:
13964+		case MACH_MATTR_VAL_CACHE_SYNC:
13965+			error = mach_vm_machine_attribute_machdep(tl,
13966+			    req->req_addr, req->req_size, &value);
13967+			break;
13968+		default:
13969+#ifdef DEBUG_MACH
13970+			printf("unimplemented value %d\n", req->req_value);
13971+#endif
13972+			error = EINVAL;
13973+			break;
13974+		}
13975+		break;
13976+
13977+	case MACH_MATTR_MIGRATE:
13978+	case MACH_MATTR_REPLICATE:
13979+	default:
13980+#ifdef DEBUG_MACH
13981+		printf("unimplemented attribute %d\n", req->req_attribute);
13982+#endif
13983+		error = EINVAL;
13984+		break;
13985+	}
13986+
13987+	*msglen = sizeof(*rep);
13988+	mach_set_header(rep, req, *msglen);
13989+
13990+	rep->rep_retval = native_to_mach_errno[error];
13991+	if (error != 0)
13992+		rep->rep_value = value;
13993+
13994+	mach_set_trailer(rep, *msglen);
13995+
13996+	return 0;
13997+}
13998diff --git a/sys/compat/mach/mach_vm.h b/sys/compat/mach/mach_vm.h
13999new file mode 100644
14000index 0000000..0c887d9
14001--- /dev/null
14002+++ b/sys/compat/mach/mach_vm.h
14003@@ -0,0 +1,391 @@
14004+/*	$NetBSD: mach_vm.h,v 1.30 2008/04/28 20:23:45 martin Exp $ */
14005+
14006+/*-
14007+ * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
14008+ * All rights reserved.
14009+ *
14010+ * This code is derived from software contributed to The NetBSD Foundation
14011+ * by Emmanuel Dreyfus
14012+ *
14013+ * Redistribution and use in source and binary forms, with or without
14014+ * modification, are permitted provided that the following conditions
14015+ * are met:
14016+ * 1. Redistributions of source code must retain the above copyright
14017+ *    notice, this list of conditions and the following disclaimer.
14018+ * 2. Redistributions in binary form must reproduce the above copyright
14019+ *    notice, this list of conditions and the following disclaimer in the
14020+ *    documentation and/or other materials provided with the distribution.
14021+ *
14022+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
14023+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
14024+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
14025+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
14026+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
14027+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
14028+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
14029+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
14030+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
14031+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
14032+ * POSSIBILITY OF SUCH DAMAGE.
14033+ */
14034+
14035+#ifndef	_MACH_VM_H_
14036+#define	_MACH_VM_H_
14037+
14038+
14039+#include <sys/types.h>
14040+#include <sys/param.h>
14041+
14042+#include <compat/mach/mach_types.h>
14043+#include <compat/mach/mach_message.h>
14044+
14045+#define	MACH_ALTERNATE_LOAD_SITE	1
14046+#define MACH_NEW_LOCAL_SHARED_REGIONS	2
14047+#define MACH_QUERY_IS_SYSTEM_REGION	4
14048+#define MACH_SF_PREV_LOADED		1
14049+#define MACH_SYSTEM_REGION_BACKED	2
14050+
14051+#define MACH_VM_PROT_COW	0x8
14052+#define MACH_VM_PROT_ZF		0x10
14053+
14054+typedef struct mach_sf_mapping {
14055+	mach_vm_offset_t mapping_offset;
14056+	mach_vm_size_t size;
14057+	mach_vm_offset_t file_offset;
14058+	mach_vm_prot_t protection;
14059+	mach_vm_offset_t cksum;
14060+} mach_sf_mapping_t;
14061+
14062+struct mach_vm_region_basic_info {
14063+	mach_vm_prot_t protection;
14064+	mach_vm_prot_t max_protection;
14065+	mach_vm_inherit_t inheritance;
14066+	mach_boolean_t shared;
14067+	mach_boolean_t reserved;
14068+	mach_vm_offset_t offset;
14069+	mach_vm_behavior_t behavior;
14070+	unsigned short user_wired_count;
14071+};
14072+
14073+/* There is no difference between 32 and 64 bits versions */
14074+struct mach_vm_region_basic_info_64 {
14075+	mach_vm_prot_t protection;
14076+	mach_vm_prot_t max_protection;
14077+	mach_vm_inherit_t inheritance;
14078+	mach_boolean_t shared;
14079+	mach_boolean_t reserved;
14080+	mach_vm_offset_t offset;
14081+	mach_vm_behavior_t behavior;
14082+	unsigned short user_wired_count;
14083+};
14084+
14085+/* mach_vm_behavior_t values */
14086+#define MACH_VM_BEHAVIOR_DEFAULT 0
14087+#define MACH_VM_BEHAVIOR_RANDOM 1
14088+#define MACH_VM_BEHAVIOR_SEQUENTIAL 2
14089+#define MACH_VM_BEHAVIOR_RSEQNTL 3
14090+#define MACH_VM_BEHAVIOR_WILLNEED 4
14091+#define MACH_VM_BEHAVIOR_DONTNEED 5
14092+
14093+/* vm_map */
14094+#define MACH_VM_INHERIT_SHARE 0
14095+#define MACH_VM_INHERIT_COPY 1
14096+#define MACH_VM_INHERIT_NONE 2
14097+#define MACH_VM_INHERIT_DONATE_COPY 3
14098+typedef struct {
14099+	mach_msg_header_t req_msgh;
14100+	mach_msg_body_t req_body;
14101+	mach_msg_port_descriptor_t req_object;
14102+	mach_ndr_record_t req_ndr;
14103+	mach_vm_address_t req_address;
14104+	mach_vm_size_t req_size;
14105+	mach_vm_address_t req_mask;
14106+	int req_flags;
14107+	mach_vm_offset_t req_offset;
14108+	mach_boolean_t req_copy;
14109+	mach_vm_prot_t req_cur_protection;
14110+	mach_vm_prot_t req_max_protection;
14111+	mach_vm_inherit_t req_inherance;
14112+} mach_vm_map_request_t;
14113+
14114+typedef struct {
14115+	mach_msg_header_t rep_msgh;
14116+	mach_ndr_record_t rep_ndr;
14117+	mach_kern_return_t rep_retval;
14118+	mach_vm_address_t rep_address;
14119+	mach_msg_trailer_t rep_trailer;
14120+} mach_vm_map_reply_t;
14121+
14122+/* vm_allocate */
14123+#define MACH_VM_FLAGS_ANYWHERE 1
14124+typedef struct {
14125+	mach_msg_header_t req_msgh;
14126+	mach_ndr_record_t req_ndr;
14127+	mach_vm_address_t req_address;
14128+	mach_vm_size_t req_size;
14129+	int req_flags;
14130+} mach_vm_allocate_request_t;
14131+
14132+
14133+typedef struct {
14134+	mach_msg_header_t rep_msgh;
14135+	mach_ndr_record_t rep_ndr;
14136+	mach_kern_return_t rep_retval;
14137+	mach_vm_address_t rep_address;
14138+	mach_msg_trailer_t rep_trailer;
14139+} mach_vm_allocate_reply_t;
14140+
14141+/* vm_deallocate */
14142+
14143+typedef struct {
14144+	mach_msg_header_t req_msgh;
14145+	mach_ndr_record_t req_ndr;
14146+	mach_vm_address_t req_address;
14147+	mach_vm_size_t req_size;
14148+} mach_vm_deallocate_request_t;
14149+
14150+typedef struct {
14151+	mach_msg_header_t rep_msgh;
14152+	mach_ndr_record_t rep_ndr;
14153+	mach_kern_return_t rep_retval;
14154+	mach_msg_trailer_t rep_trailer;
14155+} mach_vm_deallocate_reply_t;
14156+
14157+/* vm_wire */
14158+
14159+typedef struct {
14160+	mach_msg_header_t req_msgh;
14161+	mach_msg_body_t req_body;
14162+	mach_msg_port_descriptor_t req_task;
14163+	mach_ndr_record_t req_ndr;
14164+	mach_vm_address_t req_address;
14165+	mach_vm_size_t req_size;
14166+	mach_vm_prot_t req_access;
14167+} mach_vm_wire_request_t;
14168+
14169+typedef struct {
14170+	mach_msg_header_t rep_msgh;
14171+	mach_ndr_record_t rep_ndr;
14172+	mach_kern_return_t rep_retval;
14173+	mach_msg_trailer_t rep_trailer;
14174+} mach_vm_wire_reply_t;
14175+
14176+/* vm_protect */
14177+
14178+typedef struct {
14179+	mach_msg_header_t req_msgh;
14180+	mach_ndr_record_t req_ndr;
14181+	mach_vm_address_t req_addr;
14182+	mach_vm_size_t req_size;
14183+	mach_boolean_t req_set_maximum;
14184+	mach_vm_prot_t req_prot;
14185+} mach_vm_protect_request_t;
14186+
14187+typedef struct {
14188+	mach_msg_header_t rep_msgh;
14189+	mach_ndr_record_t rep_ndr;
14190+	mach_kern_return_t rep_retval;
14191+	mach_msg_trailer_t rep_trailer;
14192+} mach_vm_protect_reply_t;
14193+
14194+/* vm_inherit */
14195+typedef struct {
14196+	mach_msg_header_t req_msgh;
14197+	mach_ndr_record_t req_ndr;
14198+	mach_vm_address_t req_addr;
14199+	mach_vm_size_t req_size;
14200+	mach_vm_inherit_t req_inh;
14201+} mach_vm_inherit_request_t;
14202+
14203+typedef struct {
14204+	mach_msg_header_t rep_msgh;
14205+	mach_ndr_record_t rep_ndr;
14206+	mach_kern_return_t rep_retval;
14207+	mach_msg_trailer_t rep_trailer;
14208+} mach_vm_inherit_reply_t;
14209+
14210+/*
14211+ * make_memory_entry_64
14212+ */
14213+
14214+typedef struct {
14215+	mach_msg_header_t req_msgh;
14216+	mach_msg_body_t req_body;
14217+	mach_msg_port_descriptor_t req_parent_entry;
14218+	mach_ndr_record_t req_ndr;
14219+	mach_memory_object_size_t req_size;
14220+	mach_memory_object_offset_t req_offset;
14221+	mach_vm_prot_t req_perm;
14222+} __packed mach_make_memory_entry_64_request_t;
14223+
14224+typedef struct {
14225+	mach_msg_header_t rep_msgh;
14226+	mach_msg_body_t rep_body;
14227+	mach_msg_port_descriptor_t rep_obj_handle;
14228+	mach_ndr_record_t rep_ndr;
14229+	mach_memory_object_size_t rep_size;
14230+	mach_msg_trailer_t rep_trailer;
14231+} __packed mach_make_memory_entry_64_reply_t;
14232+
14233+/* vm_region */
14234+
14235+#define MACH_VM_REGION_BASIC_INFO 10
14236+typedef struct {
14237+	mach_msg_header_t req_msgh;
14238+	mach_ndr_record_t req_ndr;
14239+	mach_vm_address_t req_addr;
14240+	mach_vm_region_flavor_t req_flavor;
14241+	mach_msg_type_number_t req_count;
14242+} mach_vm_region_request_t;
14243+
14244+typedef struct {
14245+	mach_msg_header_t rep_msgh;
14246+	mach_msg_body_t rep_body;
14247+	mach_msg_port_descriptor_t rep_obj;
14248+	mach_ndr_record_t rep_ndr;
14249+	mach_msg_type_number_t rep_addr;
14250+	mach_vm_size_t rep_size;
14251+	mach_msg_type_number_t rep_count;
14252+	int rep_info[9];
14253+	mach_msg_trailer_t rep_trailer;
14254+} mach_vm_region_reply_t;
14255+
14256+/* vm_region_64 */
14257+
14258+typedef struct {
14259+	mach_msg_header_t req_msgh;
14260+	mach_ndr_record_t req_ndr;
14261+	mach_vm_address_t req_addr;
14262+	mach_vm_region_flavor_t req_flavor;
14263+	mach_msg_type_number_t req_count;
14264+} mach_vm_region_64_request_t;
14265+
14266+typedef struct {
14267+	mach_msg_header_t rep_msgh;
14268+	mach_msg_body_t rep_body;
14269+	mach_msg_port_descriptor_t rep_obj;
14270+	mach_ndr_record_t rep_ndr;
14271+	mach_vm_address_t rep_addr;
14272+	mach_vm_size_t rep_size;
14273+	mach_msg_type_number_t rep_count;
14274+	int rep_info[10];
14275+	mach_msg_trailer_t rep_trailer;
14276+} mach_vm_region_64_reply_t;
14277+
14278+/* vm_msync */
14279+#define MACH_VM_SYNC_ASYNCHRONOUS 0x01
14280+#define MACH_VM_SYNC_SYNCHRONOUS 0x02
14281+#define MACH_VM_SYNC_INVALIDATE 0x04
14282+#define MACH_VM_SYNC_KILLPAGES 0x08
14283+#define MACH_VM_SYNC_DEACTIVATE 0x10
14284+typedef struct {
14285+	mach_msg_header_t req_msgh;
14286+	mach_ndr_record_t req_ndr;
14287+	mach_vm_address_t req_addr;
14288+	mach_vm_size_t req_size;
14289+	mach_vm_sync_t req_flags;
14290+} mach_vm_msync_request_t;
14291+
14292+typedef struct {
14293+	mach_msg_header_t rep_msgh;
14294+	mach_ndr_record_t rep_ndr;
14295+	mach_kern_return_t rep_retval;
14296+	mach_msg_trailer_t rep_trailer;
14297+} mach_vm_msync_reply_t;
14298+
14299+/* vm_copy */
14300+typedef struct {
14301+	mach_msg_header_t req_msgh;
14302+	mach_ndr_record_t req_ndr;
14303+	mach_vm_address_t req_src;
14304+	mach_vm_size_t req_size;
14305+	mach_vm_address_t req_addr;
14306+} mach_vm_copy_request_t;
14307+
14308+typedef struct {
14309+	mach_msg_header_t rep_msgh;
14310+	mach_ndr_record_t rep_ndr;
14311+	mach_kern_return_t rep_retval;
14312+	mach_msg_trailer_t rep_trailer;
14313+} mach_vm_copy_reply_t;
14314+
14315+/* vm_read */
14316+
14317+typedef struct {
14318+	mach_msg_header_t req_msgh;
14319+	mach_ndr_record_t req_ndr;
14320+	mach_vm_address_t req_addr;
14321+	mach_vm_size_t req_size;
14322+} mach_vm_read_request_t;
14323+
14324+typedef struct {
14325+	mach_msg_header_t rep_msgh;
14326+	mach_msg_body_t rep_body;
14327+	mach_msg_ool_descriptor_t rep_data;
14328+	mach_ndr_record_t rep_ndr;
14329+	mach_msg_type_number_t rep_count;
14330+	mach_msg_trailer_t rep_trailer;
14331+} mach_vm_read_reply_t;
14332+
14333+/* vm_write */
14334+
14335+typedef struct {
14336+	mach_msg_header_t req_msgh;
14337+	mach_msg_body_t req_body;
14338+	mach_msg_ool_descriptor_t req_data;
14339+	mach_ndr_record_t req_ndr;
14340+	mach_vm_address_t req_addr;
14341+	mach_msg_type_number_t req_count;
14342+} mach_vm_write_request_t;
14343+
14344+typedef struct {
14345+	mach_msg_header_t rep_msgh;
14346+	mach_ndr_record_t rep_ndr;
14347+	mach_msg_type_number_t rep_retval;
14348+	mach_msg_trailer_t rep_trailer;
14349+} mach_vm_write_reply_t;
14350+
14351+/* vm_machine_attribute */
14352+
14353+#define MACH_MATTR_CACHE		1
14354+#define MACH_MATTR_MIGRATE		2
14355+#define MACH_MATTR_REPLICATE		4
14356+
14357+#define MACH_MATTR_VAL_OFF		0
14358+#define MACH_MATTR_VAL_ON		1
14359+#define MACH_MATTR_VAL_GET		2
14360+#define MACH_MATTR_VAL_CACHE_FLUSH	6
14361+#define MACH_MATTR_VAL_DCACHE_FLUSH	7
14362+#define MACH_MATTR_VAL_ICACHE_FLUSH	8
14363+#define MACH_MATTR_VAL_CACHE_SYNC	9
14364+#define MACH_MATTR_VAL_GET_INFO		10
14365+
14366+typedef struct {
14367+	mach_msg_header_t req_msgh;
14368+	mach_ndr_record_t req_ndr;
14369+	mach_vm_address_t req_addr;
14370+	mach_vm_address_t req_size;
14371+	mach_vm_machine_attribute_t req_attribute;
14372+	mach_vm_machine_attribute_val_t req_value;
14373+} mach_vm_machine_attribute_request_t;
14374+
14375+typedef struct {
14376+	mach_msg_header_t rep_msgh;
14377+	mach_ndr_record_t rep_ndr;
14378+	mach_msg_type_number_t rep_retval;
14379+	mach_vm_machine_attribute_val_t rep_value;
14380+	mach_msg_trailer_t rep_trailer;
14381+} mach_vm_machine_attribute_reply_t;
14382+
14383+/* Kernel-private structures */
14384+
14385+struct mach_memory_entry {
14386+	struct proc *mme_proc;
14387+	vaddr_t	mme_offset;
14388+	size_t mme_size;
14389+};
14390+
14391+/* These are machine dependent functions */
14392+int mach_vm_machine_attribute_machdep(struct lwp *, vaddr_t, size_t, int *);
14393+
14394+#endif /* _MACH_VM_H_ */
14395diff --git a/sys/compat/mach/makemachservices.sh b/sys/compat/mach/makemachservices.sh
14396new file mode 100755
14397index 0000000..34c2be6
14398--- /dev/null
14399+++ b/sys/compat/mach/makemachservices.sh
14400@@ -0,0 +1,133 @@
14401+#!/bin/sh
14402+#	$NetBSD: makemachservices.sh,v 1.8 2008/05/04 00:43:55 martin Exp $
14403+#
14404+# Copyright (c) 2003 The NetBSD Foundation, Inc.
14405+# All rights reserved.
14406+# This code is derived from software contributed to The NetBSD Foundation
14407+# by Emmanuel Dreyfus.
14408+#
14409+# Redistribution and use in source and binary forms, with or without
14410+# modification, are permitted provided that the following conditions
14411+# are met:
14412+# 1. Redistributions of source code must retain the above copyright
14413+#    notice, this list of conditions and the following disclaimer.
14414+# 2. Redistributions in binary form must reproduce the above copyright
14415+#    notice, this list of conditions and the following disclaimer in the
14416+#    documentation and/or other materials provided with the distribution.
14417+#
14418+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
14419+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
14420+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
14421+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
14422+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
14423+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
14424+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
14425+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
14426+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
14427+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
14428+# POSSIBILITY OF SUCH DAMAGE.
14429+
14430+master="mach_services.master"
14431+table="mach_services.c"
14432+headers="mach_services.h"
14433+names="mach_services_names.c"
14434+
14435+sed -e '
14436+:join
14437+	/\\$/{a\
14438+
14439+	N
14440+	s/\\\n//
14441+	b join
14442+	}
14443+' $master | awk '
14444+BEGIN{
14445+	intable = 0;
14446+	table = "'$table'";
14447+	headers = "'$headers'";
14448+	names = "'$names'";
14449+
14450+	printf("/* \$NetBSD\$ *\/\n\n") > table;
14451+	printf("/*\n * Mach services table.\n *\n") > table;
14452+	printf(" * DO NOT EDIT -- this file is automatically generated.\n") > \
14453+	    table;
14454+
14455+	printf("/* \$NetBSD\$ *\/\n\n") > headers;
14456+	printf("/*\n * Mach services prototypes.\n *\n") > headers;
14457+	printf(" * DO NOT EDIT -- this file is automatically generated.\n") > \
14458+	    headers;
14459+
14460+	printf("/* \$NetBSD\$ *\/\n\n") > names;
14461+	printf("/*\n * Mach services names. This file is not built\n") > names;
14462+	printf(" * by the kernel, it is included by kdump sources.\n *\n") > \
14463+	    names;
14464+	printf(" * DO NOT EDIT -- this file is automatically generated.\n") > \
14465+	    names;
14466+}
14467+(NR == 1) {
14468+	gsub(/^[^\$]*\$/, "", $0);
14469+	gsub(/\$.*$/, "", $0);
14470+	sub(/ $/, "");
14471+	printf(" * created from %s\n */\n\n", $0) > table;
14472+	printf("#include \<sys/cdefs.h\>\n__KERNEL_RCSID(0, " \
14473+	    "\"\$NetBSD\$\");\n\n") > table;
14474+
14475+	printf(" * created from %s\n */\n\n", $0) > headers;
14476+	printf("#include \<sys/cdefs.h\>\n__KERNEL_RCSID(0, " \
14477+	    "\"\$NetBSD\$\");\n\n") > headers;
14478+	printf("#include <compat/mach/mach_types.h>\n") > headers;
14479+	printf("#include <compat/mach/mach_message.h>\n") > headers;
14480+
14481+	printf(" * created from %s\n */\n\n", $0) > names;
14482+	printf("#include \<sys/cdefs.h\>\n__KERNEL_RCSID(0, " \
14483+	    "\"\$NetBSD\$\");\n\n") > names;
14484+	printf("struct mach_service_name {\n") > names;
14485+	printf("	int srv_id;\n") > names;
14486+	printf("	const char *srv_name;\n") > names;
14487+	printf("};\n\n") > names;
14488+	next;
14489+}
14490+(NF == 0 || $1 ~ /^;/) {
14491+	next;
14492+}
14493+($0 ~ /^%%$/) {
14494+	intable = 1;
14495+	printf("\nstruct mach_service mach_services_table[] = {\n") > table;
14496+	printf("\n") > headers;
14497+	printf("struct mach_service_name mach_services_names[] = {\n") > names;
14498+	next;
14499+}
14500+(!intable) {
14501+	printf("%s\n", $0) > table;
14502+	next;
14503+}
14504+(intable && $2 == "STD") {
14505+	printf("	{%d, mach_%s, \"%s\", " \
14506+	    "sizeof(mach_%s_request_t), sizeof(mach_%s_reply_t)},\n", \
14507+	    $1, $3, $3, $3, $3) > table;
14508+	printf("int mach_%s(struct mach_trap_args *);\n", $3) > headers;
14509+	printf("	{%d, \"%s\"},\n", $1, $3) > names;
14510+}
14511+(intable && $2 == "NODEF") {
14512+	printf("	{%d, NULL, \"%s\", 0, 0},\n", \
14513+	    $1, $3, $3, $3, $3) > table;
14514+	printf("	{%d, \"%s\"},\n", $1, $3) > names;
14515+}
14516+(intable && $2 == "UNIMPL") {
14517+	printf("	{%d, NULL, \"unimpl. %s\", 0, 0},\n", \
14518+	    $1, $3, $3, $3, $3) > table;
14519+	printf("	{%d, \"unimpl. %s\"},\n", $1, $3) > names;
14520+}
14521+(intable && $2 == "OBSOL") {
14522+	printf("	{%d, NULL, \"obsolete %s\", 0, 0},\n", \
14523+	    $1, $3, $3, $3, $3) > table;
14524+	printf("	{%d, \"obsolete %s\"},\n", $1, $3) > names;
14525+}
14526+END {
14527+	printf("	{0, NULL, NULL, 0, 0}\n") > table;
14528+	printf("};\n") > table;
14529+
14530+	printf("	{0, NULL}\n") > names;
14531+	printf("};\n") > names;
14532+}
14533+'
14534diff --git a/sys/compat/mach/syscalls.conf b/sys/compat/mach/syscalls.conf
14535new file mode 100644
14536index 0000000..c416d08
14537--- /dev/null
14538+++ b/sys/compat/mach/syscalls.conf
14539@@ -0,0 +1,14 @@
14540+#	$NetBSD: syscalls.conf,v 1.2 2007/12/10 22:32:15 dsl Exp $
14541+
14542+sysnames="mach_syscalls.c"
14543+sysnumhdr="mach_syscall.h"
14544+syssw="mach_sysent.c"
14545+sysarghdr="mach_syscallargs.h"
14546+compatopts=""
14547+libcompatopts=""
14548+
14549+switchname="mach_sysent"
14550+namesname="mach_syscallnames"
14551+constprefix="MACH_SYS_"
14552+nsysent=128
14553+maxsysargs=9
14554diff --git a/sys/compat/mach/syscalls.master b/sys/compat/mach/syscalls.master
14555new file mode 100644
14556index 0000000..001a094
14557--- /dev/null
14558+++ b/sys/compat/mach/syscalls.master
14559@@ -0,0 +1,241 @@
14560+	$NetBSD: syscalls.master,v 1.10 2009/01/13 22:27:43 pooka Exp $
14561+
14562+;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
14563+
14564+; NetBSD COMPAT_MACH system call name/number "master" file.
14565+; This is used for the negative mach syscalls.
14566+; (See syscalls.conf to see what it is processed into.)
14567+;
14568+; Fields: number type [type-dependent ...]
14569+;	number	system call number, must be in order
14570+;	type	one of STD, OBSOL, UNIMPL, NODEF, NOARGS, or one of
14571+;		the compatibility options defined in syscalls.conf.
14572+;
14573+; types:
14574+;	STD	always included
14575+;	OBSOL	obsolete, not included in system
14576+;	UNIMPL	unimplemented, not included in system
14577+;	NODEF	included, but don't define the syscall number
14578+;	NOARGS	included, but don't define the syscall args structure
14579+;
14580+; The compat options are defined in the syscalls.conf file, and the
14581+; compat option name is prefixed to the syscall name.  Other than
14582+; that, they're like NODEF (for 'compat' options), or STD (for
14583+; 'libcompat' options).
14584+;
14585+; The type-dependent arguments are as follows:
14586+; For STD, NODEF, NOARGS, and compat syscalls:
14587+;	{ pseudo-proto } [alias]
14588+; For other syscalls:
14589+;	[comment]
14590+;
14591+; #ifdef's, etc. may be included, and are copied to the output files.
14592+; #include's are copied to the syscall names and switch definition files only.
14593+
14594+#if defined(_KERNEL_OPT)
14595+#include "opt_ntp.h"
14596+#include "opt_sysv.h"
14597+#endif
14598+
14599+#include <sys/param.h>
14600+#include <sys/systm.h>
14601+#include <sys/signal.h>
14602+#include <sys/mount.h>
14603+#include <sys/poll.h>
14604+#include <sys/syscallargs.h>
14605+
14606+#include <compat/mach/mach_types.h>
14607+#include <compat/mach/mach_message.h>
14608+#include <compat/mach/mach_clock.h>
14609+#include <compat/mach/mach_syscallargs.h>
14610+%%
14611+
14612+0	UNIMPL
14613+1	UNIMPL
14614+2	UNIMPL
14615+3	UNIMPL
14616+4	UNIMPL
14617+5	UNIMPL
14618+6	UNIMPL
14619+7	UNIMPL
14620+8	UNIMPL
14621+9	UNIMPL
14622+10	UNIMPL
14623+11	UNIMPL
14624+12	UNIMPL
14625+13	UNIMPL
14626+14	UNIMPL
14627+15	UNIMPL
14628+16	UNIMPL
14629+17	UNIMPL
14630+18	UNIMPL
14631+19	UNIMPL
14632+20	UNIMPL
14633+21	UNIMPL
14634+22	UNIMPL
14635+23	UNIMPL
14636+24	UNIMPL
14637+25	UNIMPL
14638+26	STD		{ mach_port_name_t|mach_sys||reply_port(void); }
14639+27	STD		{ mach_port_name_t|mach_sys||thread_self_trap(void); }
14640+28	STD		{ mach_port_name_t|mach_sys||task_self_trap(void); }
14641+29	STD		{ mach_port_name_t|mach_sys||host_self_trap(void); }
14642+30	UNIMPL
14643+31	STD		{ mach_msg_return_t|mach_sys||msg_trap( \
14644+			    mach_msg_header_t	*msg, \
14645+			    mach_msg_option_t	option, \
14646+			    mach_msg_size_t	send_size, \
14647+			    mach_msg_size_t	rcv_size, \
14648+			    mach_port_name_t	rcv_name, \
14649+			    mach_msg_timeout_t	timeout, \
14650+			    mach_port_name_t	notify); }
14651+32	STD		{ mach_kern_return_t|mach_sys||msg_overwrite_trap( \
14652+			    mach_msg_header_t	*msg, \
14653+			    mach_msg_option_t	option, \
14654+			    mach_msg_size_t	send_size, \
14655+			    mach_msg_size_t	rcv_size, \
14656+			    mach_port_name_t	rcv_name, \
14657+			    mach_msg_timeout_t	timeout, \
14658+			    mach_port_name_t	notify, \
14659+			    mach_msg_header_t	*rcv_msg, \
14660+			    mach_msg_size_t	scatter_list_size); }
14661+33	STD		{ mach_kern_return_t|\
14662+			    mach_sys||semaphore_signal_trap( \
14663+			    mach_port_name_t signal_name); }
14664+34	STD		{ mach_kern_return_t|\
14665+			    mach_sys||semaphore_signal_all_trap( \
14666+			    mach_port_name_t signal_name); }
14667+35	STD		{ mach_kern_return_t|\
14668+			    mach_sys||semaphore_signal_thread_trap( \
14669+			    mach_port_name_t signal_name, \
14670+			    mach_port_name_t thread); }
14671+36	STD		{ mach_kern_return_t|\
14672+			    mach_sys||semaphore_wait_trap( \
14673+			    mach_port_name_t wait_name); }
14674+37	STD		{ mach_kern_return_t|\
14675+			    mach_sys||semaphore_wait_signal_trap( \
14676+			    mach_port_name_t wait_name, \
14677+			    mach_port_name_t signal_name); }
14678+38	STD		{ mach_kern_return_t|\
14679+			    mach_sys||semaphore_timedwait_trap( \
14680+			    mach_port_name_t wait_name, \
14681+			    unsigned int sec, \
14682+			    mach_clock_res_t nsec); }
14683+39	STD		{ mach_kern_return_t|\
14684+			    mach_sys||semaphore_timedwait_signal_trap( \
14685+			    mach_port_name_t wait_name, \
14686+			    mach_port_name_t signal_name, \
14687+			    unsigned int sec, \
14688+			    mach_clock_res_t nsec); }
14689+40	UNIMPL
14690+41	STD		{ mach_kern_return_t|mach_sys||init_process(void); }
14691+42	UNIMPL
14692+43	STD		{ mach_kern_return_t|mach_sys||map_fd(int fd, \
14693+			    mach_vm_offset_t offset, mach_vm_offset_t *va, \
14694+			    mach_boolean_t findspace, mach_vm_size_t size); }
14695+44	UNIMPL
14696+45	STD		{ mach_kern_return_t|mach_sys||task_for_pid( \
14697+			    mach_port_t target_tport, int pid, \
14698+			    mach_port_t *t); }
14699+46	STD		{ mach_kern_return_t|mach_sys||pid_for_task( \
14700+			    mach_port_t t, int *x); }
14701+47	UNIMPL
14702+48	STD		{ mach_kern_return_t|mach_sys||macx_swapon( \
14703+			    char *name, int flags, int size, int priority); }
14704+49	STD		{ mach_kern_return_t|mach_sys||macx_swapoff( \
14705+			    char *name, int flags); }
14706+50	UNIMPL
14707+51	STD		{ mach_kern_return_t|mach_sys||macx_triggers( \
14708+			    int hi_water, int low_water, int flags, \
14709+			    mach_port_t alert_port); }
14710+52	UNIMPL
14711+53	UNIMPL
14712+54	UNIMPL
14713+55	UNIMPL
14714+56	UNIMPL
14715+57	UNIMPL
14716+58	UNIMPL
14717+59	STD		{ mach_kern_return_t|mach_sys||swtch_pri( \
14718+			    int pri); }
14719+60	STD		{ mach_kern_return_t|mach_sys||swtch(void); }
14720+61	STD		{ mach_kern_return_t|mach_sys||syscall_thread_switch( \
14721+			    mach_port_name_t thread_name, \
14722+			    int option, \
14723+			    mach_msg_timeout_t option_time); }
14724+62	STD		{ mach_kern_return_t|mach_sys||clock_sleep_trap( \
14725+			    mach_port_name_t clock_name, \
14726+			    mach_sleep_type_t sleep_type, \
14727+			    int sleep_sec, int sleep_nsec, \
14728+			    mach_timespec_t *wakeup_time); }
14729+63	UNIMPL
14730+64	UNIMPL
14731+65	UNIMPL
14732+66	UNIMPL
14733+67	UNIMPL
14734+68	UNIMPL
14735+69	UNIMPL
14736+70	UNIMPL
14737+71	UNIMPL
14738+72	UNIMPL
14739+73	UNIMPL
14740+74	UNIMPL
14741+75	UNIMPL
14742+76	UNIMPL
14743+77	UNIMPL
14744+78	UNIMPL
14745+79	UNIMPL
14746+80	UNIMPL
14747+81	UNIMPL
14748+82	UNIMPL
14749+83	UNIMPL
14750+84	UNIMPL
14751+85	UNIMPL
14752+86	UNIMPL
14753+87	UNIMPL
14754+88	UNIMPL
14755+89	STD		{ mach_kern_return_t|mach_sys||timebase_info( \
14756+			    mach_timebase_info_t info); }
14757+90	STD		{ mach_kern_return_t|mach_sys||wait_until( \
14758+			    u_int64_t deadline); }
14759+91	STD		{ mach_port_name_t|mach_sys||timer_create(void); }
14760+92	STD		{ mach_kern_return_t|mach_sys||timer_destroy( \
14761+			    mach_port_name_t name); }
14762+93	STD		{ mach_kern_return_t|mach_sys||timer_arm( \
14763+			    mach_port_name_t name, \
14764+			    mach_absolute_time_t expire_time); }
14765+94	STD		{ mach_kern_return_t|mach_sys||timer_cancel( \
14766+			    mach_port_name_t name, \
14767+			    mach_absolute_time_t *result_time); }
14768+95	STD		{ mach_kern_return_t|mach_sys||get_time_base_info(void); }
14769+96	UNIMPL
14770+97	UNIMPL
14771+98	UNIMPL
14772+99	UNIMPL
14773+100	UNIMPL
14774+101	UNIMPL
14775+102	UNIMPL
14776+103	UNIMPL
14777+104	UNIMPL
14778+105	UNIMPL
14779+106	UNIMPL
14780+107	UNIMPL
14781+108	UNIMPL
14782+109	UNIMPL
14783+110	UNIMPL
14784+111	UNIMPL
14785+112	UNIMPL
14786+113	UNIMPL
14787+114	UNIMPL
14788+115	UNIMPL
14789+116	UNIMPL
14790+117	UNIMPL
14791+118	UNIMPL
14792+119	UNIMPL
14793+120	UNIMPL
14794+121	UNIMPL
14795+122	UNIMPL
14796+123	UNIMPL
14797+124	UNIMPL
14798+125	UNIMPL
14799+126	UNIMPL
14800+127	UNIMPL
14801--
148021.8.4.2
14803
14804