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