1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Darwin-specific syscalls, etc.              syswrap-darwin.c ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright (C) 2005-2011 Apple Inc.
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Greg Parker  gparker@apple.com
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_darwin)
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h"
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vkiscnums.h"
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h"   // to keep _threadstate.h happy
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_threadstate.h"
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_aspacemgr.h"
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_xarray.h"
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_clientstate.h"
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuglog.h"
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuginfo.h"    // VG_(di_notify_*)
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_transtab.h"     // VG_(discard_translations)
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_tool_gdbserver.h"    // VG_(gdbserver)
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h"
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h"
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcfile.h"
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h"
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcproc.h"
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcsignal.h"
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_machine.h"      // VG_(get_SP)
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_mallocfree.h"
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h"
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_oset.h"
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_scheduler.h"
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_signals.h"
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syscall.h"
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syswrap.h"
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h"
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_types_n_macros.h"
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_syswrap-darwin.h"    /* for decls of darwin-ish wrappers */
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_syswrap-main.h"
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <mach/mach.h>
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <mach/mach_vm.h>
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <semaphore.h>
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define msgh_request_port      msgh_remote_port
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define msgh_reply_port        msgh_local_port
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define BOOTSTRAP_MAX_NAME_LEN                  128
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef char name_t[BOOTSTRAP_MAX_NAME_LEN];
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef uint64_t mig_addr_t;
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Saved ports
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic mach_port_t vg_host_port = 0;
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic mach_port_t vg_task_port = 0;
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic mach_port_t vg_bootstrap_port = 0;
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Run a thread from beginning to end and return the thread's
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// scheduler-return-code.
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW)
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VgSchedReturnCode ret;
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadId     tid = (ThreadId)tidW;
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst = VG_(get_ThreadState)(tid);
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap-darwin",
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "thread_wrapper(tid=%lld): entry\n",
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (ULong)tidW);
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(tst->status == VgTs_Init);
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* make sure we get the CPU lock before doing anything significant */
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(acquire_BigLock)(tid, "thread_wrapper");
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0)
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("thread tid %d started: stack = %p\n",
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  tid, &tid);
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Make sure error reporting is enabled in the new thread. */
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->err_disablement_level = 0;
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK(pre_thread_first_insn, tid);
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.lwpid = VG_(gettid)();
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.threadgroup = VG_(getpid)();
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Thread created with all signals blocked; scheduler will set the
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      appropriate mask */
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ret = VG_(scheduler)(tid);
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_exiting)(tid));
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(tst->status == VgTs_Runnable);
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_running_thread)(tid));
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap-darwin",
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "thread_wrapper(tid=%lld): done\n",
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (ULong)tidW);
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Return to caller, still holding the lock. */
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ret;
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate a stack for this thread, if it doesn't already have one.
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Returns the initial stack pointer value to use, or 0 if allocation
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   failed. */
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownAddr allocstack ( ThreadId tid )
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst = VG_(get_ThreadState)(tid);
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VgStack*     stack;
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr         initial_SP;
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Either the stack_base and stack_init_SP are both zero (in which
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case a stack hasn't been allocated) or they are both non-zero,
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in which case it has. */
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (tst->os_state.valgrind_stack_base == 0)
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (tst->os_state.valgrind_stack_base != 0)
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If no stack is present, allocate one. */
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (tst->os_state.valgrind_stack_base == 0) {
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      stack = VG_(am_alloc_VgStack)( &initial_SP );
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (stack) {
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tst->os_state.valgrind_stack_base    = (Addr)stack;
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tst->os_state.valgrind_stack_init_SP = initial_SP;
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)( 2, "syswrap-darwin", "stack for tid %d at %p; init_SP=%p\n",
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   tid,
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (void*)tst->os_state.valgrind_stack_base,
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (void*)tst->os_state.valgrind_stack_init_SP );
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_IS_32_ALIGNED(tst->os_state.valgrind_stack_init_SP));
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return tst->os_state.valgrind_stack_init_SP;
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid find_stack_segment(ThreadId tid, Addr sp)
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We don't really know where the client stack is, because it's
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      allocated by the client.  The best we can do is look at the
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      memory mappings and try to derive some useful information.  We
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assume that esp starts near its highest possible value, and can
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      only go down to the start of the mmaped segment. */
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *tst = VG_(get_ThreadState)(tid);
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const NSegment *seg = VG_(am_find_nsegment)(sp);
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (seg && seg->kind != SkResvn) {
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->client_stack_szB = tst->client_stack_highest_word - seg->start;
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (1)
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     tid, seg->start, VG_PGROUNDUP(sp));
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       VG_(printf)("couldn't find user stack\n");
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(message)(Vg_UserMsg, "!? New thread %d starts with SP(%#lx) unmapped\n",
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   tid, sp);
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->client_stack_szB  = 0;
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Run a thread all the way to the end, then do appropriate exit actions
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (this is the last-one-out-turn-off-the-lights bit).
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void run_a_thread_NORETURN ( Word tidW )
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int               c;
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VgSchedReturnCode src;
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadId          tid = (ThreadId)tidW;
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadState*      tst;
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap-darwin",
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "run_a_thread_NORETURN(tid=%lld): pre-thread_wrapper\n",
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (ULong)tidW);
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst = VG_(get_ThreadState)(tid);
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert(tst);
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Run the thread all the way through. */
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   src = thread_wrapper(tid);
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap-darwin",
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "run_a_thread_NORETURN(tid=%lld): post-thread_wrapper\n",
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (ULong)tidW);
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c = VG_(count_living_threads)();
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(c >= 1); /* stay sane */
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Tell the tool this thread is exiting
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( pre_thread_ll_exit, tid );
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* If the thread is exiting with errors disabled, complain loudly;
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      doing so is bad (does the user know this has happened?)  Also,
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      in all cases, be paranoid and clear the flag anyway so that the
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      thread slot is safe in this respect if later reallocated.  This
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      should be unnecessary since the flag should be cleared when the
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      slot is reallocated, in thread_wrapper(). */
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (tst->err_disablement_level > 0) {
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(umsg)(
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "WARNING: exiting thread has error reporting disabled.\n"
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "WARNING: possibly as a result of some mistake in the use\n"
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(debugLog)(
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         1, "syswrap-linux",
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            "run_a_thread_NORETURN(tid=%lld): "
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            "WARNING: exiting thread has err_disablement_level = %u\n",
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            (ULong)tidW, tst->err_disablement_level
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      );
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->err_disablement_level = 0;
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c == 1) {
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(debugLog)(1, "syswrap-darwin",
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       "run_a_thread_NORETURN(tid=%lld): "
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          "last one standing\n",
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          (ULong)tidW);
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We are the last one standing.  Keep hold of the lock and
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         carry on to show final tool results, then exit the entire system.
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Use the continuation pointer set at startup in m_main. */
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src);
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t msg;
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(debugLog)(1, "syswrap-darwin",
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       "run_a_thread_NORETURN(tid=%lld): "
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          "not last one standing\n",
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          (ULong)tidW);
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* OK, thread is dead, but others still exist.  Just exit. */
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This releases the run lock */
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(exit_thread)(tid);
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(tst->status == VgTs_Zombie);
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* tid is now invalid. */
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme exit race
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      msg.msgh_bits = MACH_MSGH_BITS(17, MACH_MSG_TYPE_MAKE_SEND_ONCE);
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      msg.msgh_request_port = VG_(gettid)();
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      msg.msgh_reply_port = 0;
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      msg.msgh_id = 3600;  // thread_terminate
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->status = VgTs_Empty;
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme race here! new thread may claim this V thread stack
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // before we get out here!
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme use bsdthread_terminate for safe cleanup?
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg(&msg, MACH_SEND_MSG|MACH_MSG_OPTION_NONE,
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               sizeof(msg), 0, 0, MACH_MSG_TIMEOUT_NONE, 0);
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // DDD: This is reached sometimes on none/tests/manythreads, maybe
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // because of the race above.
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(core_panic)("Thread exit failed?\n");
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(0);
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate a stack for the main thread, and run it all the way to the
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   end.  Although we already have a working VgStack
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (VG_(interim_stack)) it's better to allocate a new one, so that
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   overflow detection works uniformly for all threads.
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr sp;
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap-darwin",
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "entering VG_(main_thread_wrapper_NORETURN)\n");
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sp = allocstack(tid);
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If we can't even allocate the first thread's stack, we're hosed.
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Give up. */
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert2(sp != 0, "Cannot allocate main thread's stack.");
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* shouldn't be any other threads around yet */
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( VG_(count_living_threads)() == 1 );
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   call_on_new_stack_0_1(
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (Addr)sp,             /* stack */
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      0,                     /*bogus return address*/
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      run_a_thread_NORETURN,  /* fn to call */
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (Word)tid              /* arg to give it */
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(0);
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid start_thread_NORETURN ( Word arg )
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst = (ThreadState*)arg;
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadId     tid = tst->tid;
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   run_a_thread_NORETURN ( (Word)tid );
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(0);
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(cleanup_thread) ( ThreadArchState* arch )
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Mach port tracking (based on syswrap-generic's fd tracker)
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* One of these is allocated for each open port.  */
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct OpenPort
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_port_t port;
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_port_type_t type;         /* right type(s) */
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int send_count;                /* number of send rights */
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char *name;                    /* bootstrap name or NULL */
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ExeContext *where;             /* first allocation only */
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct OpenPort *next, *prev;
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} OpenPort;
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// strlen("0x12345678")
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PORT_STRLEN (2+2*sizeof(mach_port_t))
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* List of allocated ports. */
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic OpenPort *allocated_ports;
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Count of open ports. */
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int allocated_port_count = 0;
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused))
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool port_exists(mach_port_t port)
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i;
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check to see if this port is already open. */
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i = allocated_ports;
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (i) {
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i->port == port) {
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return True;
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i = i->next;
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return False;
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic OpenPort *info_for_port(mach_port_t port)
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i;
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!port) return NULL;
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i = allocated_ports;
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (i) {
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i->port == port) {
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return i;
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i = i->next;
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Give a port a name, without changing its refcount
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// GrP fixme don't override name if it already has a specific one
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__private_extern__ void assign_port_name(mach_port_t port, const char *name)
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i;
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!port) return;
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(name);
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i = info_for_port(port);
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(i);
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (i->name) VG_(arena_free)(VG_AR_CORE, i->name);
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i->name =
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       VG_(arena_malloc)(VG_AR_CORE, "syswrap-darwin.mach-port-name",
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         VG_(strlen)(name) + PORT_STRLEN + 1);
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sprintf)(i->name, name, port);
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Return the name of the given port or "UNKNOWN 0x1234" if not known.
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const char *name_for_port(mach_port_t port)
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static char buf[8 + PORT_STRLEN + 1];
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i;
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // hack
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (port == VG_(gettid)()) return "mach_thread_self()";
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (port == 0) return "NULL";
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i = allocated_ports;
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (i) {
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i->port == port) {
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return i->name;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i = i->next;
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sprintf)(buf, "NONPORT-%#x", port);
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return buf;
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Note the fact that a port was just deallocated. */
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid record_port_mod_refs(mach_port_t port, mach_port_type_t right, Int delta)
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i = allocated_ports;
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!port) return;
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while(i) {
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if(i->port == port) {
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(right != MACH_PORT_TYPE_DEAD_NAME);
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (right & MACH_PORT_TYPE_SEND) {
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // send rights are refcounted
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (delta == INT_MIN) delta = -i->send_count; // INT_MIN == destroy
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            i->send_count += delta;
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (i->send_count > 0) i->type |= MACH_PORT_TYPE_SEND;
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else i->type &= ~MACH_PORT_TYPE_SEND;
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         right = right & ~MACH_PORT_TYPE_SEND;
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (right) {
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // other rights are not refcounted
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (delta > 0) {
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               i->type |= right;
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else if (delta < 0) {
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               i->type &= ~right;
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i->type != 0) return;
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // Port has no rights left. Kill it.
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // VG_(printf)("deleting port %p %s", i->port, i->name);
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if(i->prev)
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            i->prev->next = i->next;
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            allocated_ports = i->next;
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if(i->next)
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            i->next->prev = i->prev;
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if(i->name)
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(arena_free) (VG_AR_CORE, i->name);
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(arena_free) (VG_AR_CORE, i);
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         allocated_port_count--;
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i = i->next;
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("UNKNOWN Mach port modified (port %#x delta %d)\n", port, delta);
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid record_port_insert_rights(mach_port_t port, mach_msg_type_name_t type)
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (type) {
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_TYPE_PORT_NAME:
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // this task has no rights for the name
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_TYPE_PORT_RECEIVE:
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // this task gets receive rights
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      record_port_mod_refs(port, MACH_PORT_TYPE_RECEIVE, 1);
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_TYPE_PORT_SEND:
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // this task gets a send right
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      record_port_mod_refs(port, MACH_PORT_TYPE_SEND, 1);
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_TYPE_PORT_SEND_ONCE:
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // this task gets send-once rights
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      record_port_mod_refs(port, MACH_PORT_TYPE_SEND_ONCE, 1);
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid record_port_dealloc(mach_port_t port)
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // deletes 1 send or send-once right (port can't have both)
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_port_mod_refs(port, MACH_PORT_TYPE_SEND_RIGHTS, -1);
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid record_port_destroy(mach_port_t port)
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // deletes all rights to port
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_port_mod_refs(port, MACH_PORT_TYPE_ALL_RIGHTS, INT_MIN);
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Note the fact that a Mach port was just allocated or transferred.
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If the port is already known, increment its reference count. */
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid record_named_port(ThreadId tid, mach_port_t port,
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       mach_port_right_t right, const char *name)
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i;
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!port) return;
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check to see if this port is already open. */
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   i = allocated_ports;
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (i) {
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i->port == port) {
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (right != -1) record_port_mod_refs(port, MACH_PORT_TYPE(right), 1);
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i = i->next;
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Not already one: allocate an OpenPort */
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (i == NULL) {
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i = VG_(arena_malloc)(VG_AR_CORE, "syswrap-darwin.mach-port",
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            sizeof(OpenPort));
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->prev = NULL;
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->next = allocated_ports;
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if(allocated_ports) allocated_ports->prev = i;
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      allocated_ports = i;
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      allocated_port_count++;
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->port = port;
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid, 0);
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      i->name = NULL;
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (right != -1) {
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->type = MACH_PORT_TYPE(right);
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->send_count = (right == MACH_PORT_RIGHT_SEND) ? 1 : 0;
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->type = 0;
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         i->send_count = 0;
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(port, name);
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Record opening of a nameless port.
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void record_unnamed_port(ThreadId tid, mach_port_t port, mach_port_right_t right)
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, port, right, "unnamed-%p");
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Dump summary of open Mach ports, like VG_(show_open_fds) */
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(show_open_ports)(void)
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OpenPort *i;
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(message)(Vg_UserMsg,
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "MACH PORTS: %d open at exit.", allocated_port_count);
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = allocated_ports; i; i = i->next) {
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i->name) {
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(message)(Vg_UserMsg, "Open Mach port 0x%x: %s", i->port, i->name);
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(message)(Vg_UserMsg, "Open Mach port 0x%x", i->port);
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i->where) {
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(pp_ExeContext)(i->where);
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(message)(Vg_UserMsg, "");
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(message)(Vg_UserMsg, "");
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sync_mappings
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(sync_mappings)(const HChar *when, const HChar *where, Int num)
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Usually the number of segments added/removed in a single calls is very
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // small e.g. 1.  But it sometimes gets up to at least 100 or so (eg. for
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Quicktime).  So we use a repeat-with-bigger-buffers-until-success model,
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // because we can't do dynamic allocation within VG_(get_changed_segments),
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // because it's in m_aspacemgr.
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ChangedSeg* css = NULL;
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int         css_size;
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int         css_used;
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int         i;
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool        ok;
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_trace_syscalls)) {
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       VG_(debugLog)(0, "syswrap-darwin",
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "sync_mappings(\"%s\", \"%s\", %d)\n",
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     when, where, num);
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // 16 is enough for most cases, but small enough that overflow happens
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // occasionally and thus the overflow path gets some test coverage.
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   css_size = 16;
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ok = False;
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (!ok) {
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(free)(css);   // css is NULL on first iteration;  that's ok.
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      css = VG_(malloc)("sys_wrap.sync_mappings", css_size*sizeof(ChangedSeg));
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ok = VG_(get_changed_segments)(when, where, css, css_size, &css_used);
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      css_size *= 2;
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Now add/remove them.
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < css_used; i++) {
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ChangedSeg* cs = &css[i];
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Char* action;
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (cs->is_added) {
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(notify_core_and_tool_of_mmap)(
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cs->start, cs->end - cs->start + 1,
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cs->prot, VKI_MAP_PRIVATE, 0, cs->offset);
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // should this call VG_(di_notify_mmap) also?
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         action = "added";
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(notify_core_and_tool_of_munmap)(
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cs->start, cs->end - cs->start + 1);
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         action = "removed";
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(clo_trace_syscalls)) {
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          VG_(debugLog)(0, "syswrap-darwin",
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        "  %s region 0x%010lx..0x%010lx at %s (%s)\n",
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        action, cs->start, cs->end + 1, where, when);
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(free)(css);
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   wrappers
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE(name)       DEFN_PRE_TEMPLATE(darwin, name)
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST(name)      DEFN_POST_TEMPLATE(darwin, name)
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_FN(name)    vgSysWrap_darwin_##name##_before
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST_FN(name)   vgSysWrap_darwin_##name##_after
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_PRE(name) PRE_FN(name)(tid, layout, arrghs, status, flags)
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CALL_POST(name) POST_FN(name)(tid, arrghs, status)
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Combine two 32-bit values into a 64-bit value
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Always use with low-numbered arg first (e.g. LOHI64(ARG1,ARG2) )
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(VGA_x86)
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define LOHI64(lo,hi)   ( (lo) | ((ULong)(hi) << 32) )
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error unknown architecture
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Retrieve the current Mach thread
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MACH_THREAD ((Addr)VG_(get_ThreadState)(tid)->os_state.lwpid)
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Set the POST handler for a mach_msg derivative
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define AFTER VG_(get_ThreadState)(tid)->os_state.post_mach_trap_fn
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Set or get values saved from Mach messages
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MACH_ARG(x) VG_(get_ThreadState)(tid)->os_state.mach_args.x
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MACH_REMOTE VG_(get_ThreadState)(tid)->os_state.remote_port
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MACH_MSGH_ID VG_(get_ThreadState)(tid)->os_state.msgh_id
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   darwin ioctl wrapper
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(ioctl)
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Handle ioctls that don't take an arg first */
722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switch (ARG2 /* request */) {
723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case VKI_TIOCSCTTY:
724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case VKI_TIOCEXCL:
725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case VKI_TIOCPTYGRANT:
726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case VKI_TIOCPTYUNLK:
727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case VKI_DTRACEHIOC_REMOVE:
728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      PRINT("ioctl ( %ld, 0x%lx )",ARG1,ARG2);
729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      PRE_REG_READ2(long, "ioctl",
730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    unsigned int, fd, unsigned int, request);
731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   default:
733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      PRINT("ioctl ( %ld, 0x%lx, %#lx )",ARG1,ARG2,ARG3);
734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      PRE_REG_READ3(long, "ioctl",
735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    unsigned int, fd, unsigned int, request, unsigned long, arg);
736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2 /* request */) {
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGWINSZ:
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSWINSZ:
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(TIOCSWINSZ)",  ARG3, sizeof(struct vki_winsize) );
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMBIS:
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(TIOCMBIS)",    ARG3, sizeof(unsigned int) );
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMBIC:
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(TIOCMBIC)",    ARG3, sizeof(unsigned int) );
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMSET:
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(TIOCMSET)",    ARG3, sizeof(unsigned int) );
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMGET:
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(TIOCMGET)",   ARG3, sizeof(unsigned int) );
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGPGRP:
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Get process group ID for foreground processing group. */
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSPGRP:
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Set a process group ID? */
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIONBIO:
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(FIONBIO)",    ARG3, sizeof(int) );
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIOASYNC:
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(FIOASYNC)",   ARG3, sizeof(int) );
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIONREAD:                /* identical to SIOCINQ */
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(FIONREAD)",  ARG3, sizeof(int) );
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These all use struct ifreq AFAIK */
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* GrP fixme is sizeof(struct vki_if_req) correct if it's using a sockaddr? */
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFFLAGS:        /* get flags                    */
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFMTU:          /* get MTU size                 */
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFADDR:         /* get PA address               */
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFMETRIC:       /* get metric                   */
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFCONF:         /* get iface list               */
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* WAS:
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         KERNEL_DO_SYSCALL(tid,RES);
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (!VG_(is_kerror)(RES) && RES == 0)
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ( ARG3 ) {
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // TODO len must be readable and writable
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // buf pointer only needs to be readable
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFFLAGS:        /* set flags                    */
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFADDR:         /* set PA address               */
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFMETRIC:       /* set metric                   */
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFMTU:          /* set MTU size                 */
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Routing table calls.  */
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef VKI_SIOCADDRT
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCADDRT:           /* add routing table entry      */
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCDELRT:           /* delete routing table entry   */
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(struct vki_rtentry));
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGPGRP:
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSPGRP:
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //tst->sys_flags &= ~SfMayBlock;
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIODTYPE:
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_DTRACEHIOC_ADDDOF:
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // ttycom.h
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGETA:
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRE_MEM_WRITE( "ioctl(TIOCGETA)", ARG3, sizeof(struct vki_termios) );
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSETA:
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRE_MEM_READ( "ioctl(TIOCSETA)", ARG3, sizeof(struct vki_termios) );
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGETD:
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRE_MEM_WRITE( "ioctl(TIOCGETD)", ARG3, sizeof(int) );
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSETD:
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRE_MEM_READ( "ioctl(TIOCSETD)", ARG3, sizeof(int) );
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCPTYGNAME:
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRE_MEM_WRITE( "ioctl(TIOCPTYGNAME)", ARG3, 128 );
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(ioctl)
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2 /* request */) {
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGWINSZ:
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSWINSZ:
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMBIS:
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMBIC:
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMSET:
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCMGET:
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGPGRP:
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Get process group ID for foreground processing group. */
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSPGRP:
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Set a process group ID? */
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSCTTY:
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIONBIO:
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIOASYNC:
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIONREAD:                /* identical to SIOCINQ */
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(int) );
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These all use struct ifreq AFAIK */
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFFLAGS:        /* get flags                    */
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFMTU:          /* get MTU size                 */
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFADDR:         /* get PA address               */
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFDSTADDR:      /* get remote PA address        */
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFBRDADDR:      /* get broadcast PA address     */
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFNETMASK:      /* get network PA mask          */
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFMETRIC:       /* get metric                   */
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGIFCONF:         /* get iface list               */
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* WAS:
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         KERNEL_DO_SYSCALL(tid,RES);
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (!VG_(is_kerror)(RES) && RES == 0)
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (RES == 0 && ARG3 ) {
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ifc->vki_ifc_buf != NULL)
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFFLAGS:        /* set flags                    */
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFDSTADDR:      /* set remote PA address        */
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFBRDADDR:      /* set broadcast PA address     */
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFNETMASK:      /* set network PA mask          */
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFMETRIC:       /* set metric                   */
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFADDR:         /* set PA address               */
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSIFMTU:          /* set MTU size                 */
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef VKI_SIOCADDRT
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Routing table calls.  */
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCADDRT:           /* add routing table entry      */
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCDELRT:           /* delete routing table entry   */
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCGPGRP:
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG3, sizeof(int));
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SIOCSPGRP:
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FIODTYPE:
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(int) );
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_DTRACEHIOC_REMOVE:
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_DTRACEHIOC_ADDDOF:
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // ttycom.h
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGETA:
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       POST_MEM_WRITE( ARG3, sizeof(struct vki_termios));
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSETA:
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCGETD:
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       POST_MEM_WRITE( ARG3, sizeof(int) );
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCSETD:
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCPTYGNAME:
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       POST_MEM_WRITE( ARG3, 128);
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCPTYGRANT:
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_TIOCPTYUNLK:
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   darwin fcntl wrapper
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const char *name_for_fcntl(UWord cmd) {
1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define F(n) case VKI_##n: return #n
1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (cmd) {
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_CHKCLEAN);
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_RDAHEAD);
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_NOCACHE);
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_FULLFSYNC);
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_FREEZE_FS);
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_THAW_FS);
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_GLOBAL_NOCACHE);
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_PREALLOCATE);
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_SETSIZE);
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_RDADVISE);
1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_READBOOTSTRAP);
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_WRITEBOOTSTRAP);
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_LOG2PHYS);
1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_GETPATH);
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_PATHPKG_CHECK);
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      F(F_ADDSIGS);
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return "UNKNOWN";
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef F
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fcntl)
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2) {
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // These ones ignore ARG3.
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETFD:
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETFL:
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETOWN:
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %ld )", ARG1,ARG2);
1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // These ones use ARG3 as "arg".
1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_DUPFD:
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETFD:
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETFL:
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETOWN:
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // These ones use ARG3 as "lock".
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETLK:
1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETLK:
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETLKW:
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct flock64 *, lock);
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme mem read sizeof(flock64)
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG2 == VKI_F_SETLKW)
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *flags |= SfMayBlock;
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // none
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_CHKCLEAN:
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_RDAHEAD:
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_NOCACHE:
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_FULLFSYNC:
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_FREEZE_FS:
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_THAW_FS:
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GLOBAL_NOCACHE:
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s )", ARG1, name_for_fcntl(ARG1));
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // struct fstore
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_PREALLOCATE:
1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3);
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct fstore *, fstore);
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct vki_fstore *fstore = (struct vki_fstore *)ARG3;
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         fstore->fst_flags );
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         fstore->fst_posmode );
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         fstore->fst_offset );
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         fstore->fst_length );
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_WRITE( "fcntl(F_PREALLOCATE, fstore->fst_bytesalloc)",
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          fstore->fst_bytesalloc);
1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // off_t
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETSIZE:
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3);
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    vki_off_t *, offset);
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // struct radvisory
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_RDADVISE:
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3);
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct vki_radvisory *, radvisory);
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct vki_radvisory *radvisory = (struct vki_radvisory *)ARG3;
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_PREALLOCATE, radvisory->ra_offset)",
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         radvisory->ra_offset );
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_PREALLOCATE, radvisory->ra_count)",
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         radvisory->ra_count );
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // struct fbootstraptransfer
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_READBOOTSTRAP:
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_WRITEBOOTSTRAP:
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3);
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct fbootstraptransfer *, bootstrap);
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "fcntl(F_READ/WRITEBOOTSTRAP, bootstrap)",
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ARG3, sizeof(struct vki_fbootstraptransfer) );
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // struct log2phys (out)
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_LOG2PHYS:
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3);
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    struct log2phys *, l2p);
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "fcntl(F_LOG2PHYS, l2p)",
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ARG3, sizeof(struct vki_log2phys) );
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // char[maxpathlen] (out)
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETPATH:
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx )", ARG1, name_for_fcntl(ARG2), ARG3);
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    char *, pathbuf);
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "fcntl(F_GETPATH, pathbuf)",
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ARG3, VKI_MAXPATHLEN );
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // char[maxpathlen] (in)
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_PATHPKG_CHECK:
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s, %#lx '%s')", ARG1, name_for_fcntl(ARG2), ARG3,
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          (char *)ARG3);
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    char *, pathbuf);
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( "fcntl(F_PATHPKG_CHECK, pathbuf)", ARG3);
1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_ADDSIGS: /* Add detached signatures (for code signing) */
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %s )", ARG1, name_for_fcntl(ARG2));
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "fcntl",
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, fd, unsigned int, cmd,
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    vki_fsignatures_t *, sigs);
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vki_fsignatures_t *fsigs = (vki_fsignatures_t*)ARG3;
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_ADDSIGS, fsigs->fs_blob_start)",
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         fsigs->fs_blob_start);
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_FIELD_READ( "fcntl(F_ADDSIGS, fsigs->fs_blob_size)",
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         fsigs->fs_blob_size);
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (fsigs->fs_blob_start)
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRE_MEM_READ( "fcntl(F_ADDSIGS, fsigs->fs_blob_start)",
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          (Addr)fsigs->fs_blob_start, fsigs->fs_blob_size);
1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("fcntl ( %ld, %ld [??] )", ARG1, ARG2);
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN fcntl %ld!", ARG2);
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fcntl)
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2) {
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_DUPFD:
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(close)(RES);
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         SET_STATUS_Failure( VKI_EMFILE );
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (VG_(clo_track_fds))
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(record_fd_open_named)(tid, RES);
1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETFD:
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETFL:
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETOWN:
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETFD:
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETFL:
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETOWN:
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETLK:
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETLK:
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_SETLKW:
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_PREALLOCATE:
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct vki_fstore *fstore = (struct vki_fstore *)ARG3;
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_FIELD_WRITE( fstore->fst_bytesalloc );
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_LOG2PHYS:
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct vki_log2phys) );
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_F_GETPATH:
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, 1+VG_(strlen)((char *)ARG3) );
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("\"%s\"", (char*)ARG3);
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // DDD: ugh, missing lots of cases here, not nice
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unix syscalls
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(futimes)
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("futimes ( %ld, %#lx )", ARG1,ARG2);
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "futimes", int, fd, struct timeval *, tvp);
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ML_(fd_allowed)(ARG1, "futimes", tid, False)) {
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EBADF );
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else if (ARG2 != 0) {
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_timeval_READ( "futimes(tvp[0])", ARG2 );
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_timeval_READ( "futimes(tvp[1])", ARG2+sizeof(struct vki_timeval) );
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semget)
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semop)
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "semop",
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, semid, struct sembuf *, sops, vki_size_t, nsoops);
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semctl)
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG3) {
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_IPC_STAT:
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_IPC_SET:
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ4(long, "semctl",
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_GETALL:
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SETALL:
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ4(long, "semctl",
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_SETVAL:
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ4(long, "semctl",
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    int, semid, int, semnum, int, cmd, int, arg);
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "semctl",
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    int, semid, int, semnum, int, cmd);
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(semctl)
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_open)
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 & VKI_O_CREAT) {
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // 4-arg version
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("sem_open ( %#lx(%s), %ld, %ld, %ld )",
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ARG1,(char*)ARG1,ARG2,ARG3,ARG4);
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ4(vki_sem_t *, "sem_open",
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const char *, name, int, oflag, vki_mode_t, mode,
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    unsigned int, value);
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // 2-arg version
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("sem_open ( %#lx(%s), %ld )",ARG1,(char*)ARG1,ARG2);
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ2(vki_sem_t *, "sem_open",
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const char *, name, int, oflag);
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "sem_open(name)", ARG1 );
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Otherwise handle normally */
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_close)
1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_close( %#lx )", ARG1);
1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_close", vki_sem_t *, sem);
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_unlink)
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_unlink(  %#lx(%s) )", ARG1,(char*)ARG1);
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_unlink", const char *, name);
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "sem_unlink(name)", ARG1 );
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_post)
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_post( %#lx )", ARG1);
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_post", vki_sem_t *, sem);
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_destroy)
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRINT("sem_destroy( %#lx )", ARG1);
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_REG_READ1(int, "sem_destroy", vki_sem_t *, sem);
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_MEM_READ("sem_destroy(sem)", ARG1, sizeof(vki_sem_t));
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_init)
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRINT("sem_init( %#lx, %ld, %ld )", ARG1, ARG2, ARG3);
1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_REG_READ3(int, "sem_init", vki_sem_t *, sem,
1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                int, pshared, unsigned int, value);
1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_MEM_WRITE("sem_init(sem)", ARG1, sizeof(vki_sem_t));
1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sem_init)
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  POST_MEM_WRITE(ARG1, sizeof(vki_sem_t));
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_wait)
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_wait( %#lx )", ARG1);
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_wait", vki_sem_t *, sem);
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sem_trywait)
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_trywait( %#lx )", ARG1);
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_trywait", vki_sem_t *, sem);
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(kqueue)
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("kqueue()");
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(kqueue)
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ML_(fd_allowed)(RES, "kqueue", tid, True)) {
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(close)(RES);
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EMFILE );
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(clo_track_fds)) {
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(record_fd_open_with_given_name)(tid, RES, NULL);
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(kevent)
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kevent( %ld, %#lx, %ld, %#lx, %ld, %#lx )",
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(int,"kevent", int,kq,
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct vki_kevent *,changelist, int,nchanges,
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct vki_kevent *,eventlist, int,nevents,
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct vki_timespec *,timeout);
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3) PRE_MEM_READ ("kevent(changelist)",
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           ARG2, ARG3 * sizeof(struct vki_kevent));
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) PRE_MEM_WRITE("kevent(eventlist)",
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           ARG4, ARG5 * sizeof(struct vki_kevent));
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG6) PRE_MEM_READ ("kevent(timeout)",
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           ARG6, sizeof(struct vki_timespec));
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(kevent)
1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kevent ret %ld dst %#lx (%zu)", RES, ARG4, sizeof(struct vki_kevent));
1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES > 0) POST_MEM_WRITE(ARG4, RES * sizeof(struct vki_kevent));
1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownAddr pthread_starter = 0;
1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownAddr wqthread_starter = 0;
1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSizeT pthread_structsize = 0;
1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(bsdthread_register)
1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bsdthread_register( %#lx, %#lx, %lu )", ARG1, ARG2, ARG3);
1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int,"__bsdthread_register", void *,"threadstart",
1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *,"wqthread", size_t,"pthsize");
1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_starter = ARG1;
1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   wqthread_starter = ARG2;
1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_structsize = ARG3;
1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG1 = (Word)&pthread_hijack_asm;
1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG2 = (Word)&wqthread_hijack_asm;
1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(workq_open)
1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("workq_open()");
1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(int, "workq_open");
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This creates lots of threads and thread stacks under the covers,
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // but we ignore them all until some work item starts running on it.
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const char *workqop_name(int op)
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (op) {
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_WQOPS_QUEUE_ADD: return "QUEUE_ADD";
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_WQOPS_QUEUE_REMOVE: return "QUEUE_REMOVE";
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_WQOPS_THREAD_RETURN: return "THREAD_RETURN";
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default: return "?";
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(workq_ops)
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("workq_ops( %ld(%s), %#lx, %ld )", ARG1, workqop_name(ARG1), ARG2,
1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG3);
1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int,"workq_ops", int,"options", void *,"item",
1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"priority");
1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG1) {
1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_WQOPS_QUEUE_ADD:
1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_WQOPS_QUEUE_REMOVE:
1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme need anything here?
1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme may block?
1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_WQOPS_THREAD_RETURN: {
1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // The interesting case. The kernel will do one of two things:
1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // 1. Return normally. We continue; libc proceeds to stop the thread.
1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    V does nothing special here.
1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // 2. Jump to wqthread_hijack. This wipes the stack and runs a
1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    new work item, and never returns from workq_ops.
1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    V handles this by longjmp() from wqthread_hijack back to the
1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    scheduler, which continues at the new client SP/IP/state.
1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    This works something like V's signal handling.
1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    To the tool, this looks like workq_ops() sometimes returns
1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //    to a strange address.
1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ThreadState *tst = VG_(get_ThreadState)(tid);
1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->os_state.wq_jmpbuf_valid = True;
1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags |= SfMayBlock;  // GrP fixme true?
1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN workq_ops option %ld\n", ARG1);
1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(workq_ops)
1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *tst = VG_(get_ThreadState)(tid);
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.wq_jmpbuf_valid = False;
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__mac_syscall)
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__mac_syscall( %#lx, %ld, %#lx )", ARG1, ARG2, ARG3);
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int,"__mac_syscall", char *,"policy",
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"call", void *,"arg");
1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme check call's arg?
1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme check policy?
1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Not like syswrap-generic's sys_exit, which exits only one thread.
1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   More like syswrap-generic's sys_exit_group. */
1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(exit)
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadId     t;
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst;
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("darwin exit( %ld )", ARG1);
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "exit", int, status);
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst = VG_(get_ThreadState)(tid);
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* A little complex; find all the threads with the same threadgroup
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      as this one (including this one), and mark them to exit */
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (t = 1; t < VG_N_THREADS; t++) {
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ( /* not alive */
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           VG_(threads)[t].status == VgTs_Empty
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           /* GrP fixme zombie? */
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         )
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(threads)[t].exitreason = VgSrc_ExitProcess;
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(threads)[t].os_state.exitcode = ARG1;
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (t != tid)
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(get_thread_out_of_syscall)(t);     /* unblock it, if blocked */
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We have to claim the syscall already succeeded. */
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Success(0);
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sigaction)
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "sigaction",
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, signum, vki_sigaction_toK_t *, act,
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_sigaction_fromK_t *, oldact);
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 != 0) {
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2;
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "sigaction(act->sa_handler)",
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "sigaction(act->sa_mask)",
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "sigaction(act->sa_flags)",
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 != 0)
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "sigaction(oldact)",
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ARG3, sizeof(vki_sigaction_fromK_t));
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(
1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2,
1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  (vki_sigaction_fromK_t *)ARG3)
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sigaction)
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES == 0 && ARG3 != 0)
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t));
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__pthread_kill)
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__pthread_kill ( %ld, %ld )", ARG1, ARG2);
1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "__pthread_kill", vki_pthread_t*, thread, int, sig);
1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__pthread_sigmask)
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // JRS: arguments are identical to sigprocmask
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // (how, sigset_t*, sigset_t*).  Perhaps behave identically?
1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static Bool warned;
1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!warned) {
1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN __pthread_sigmask is unsupported. "
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  "This warning will not be repeated.\n");
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      warned = True;
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Success( 0 );
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__pthread_canceled)
1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock; /* might kill this thread??? */
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* I don't think so -- I think it just changes the cancellation
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      state.  But taking no chances. */
1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__pthread_canceled ( %ld )", ARG1);
1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "__pthread_canceled", void*, arg1);
1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__pthread_markcancel)
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock; /* might kill this thread??? */
1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__pthread_markcancel ( %#lx )", ARG1);
1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "__pthread_markcancel", void*, arg1);
1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Just let it go through.  No idea if this is correct. */
1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__disable_threadsignal)
1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vki_sigset_t set;
1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__disable_threadsignal(%ld, %ld, %ld)", ARG1, ARG2, ARG3);
1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* I don't think this really looks at its arguments.  So don't
1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bother to check them. */
1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sigfillset)( &set );
1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(
1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_sys_sigprocmask) ( tid, VKI_SIG_BLOCK, &set, NULL )
1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We don't expect that blocking all signals for this thread could
1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cause any more to be delivered (how could it?), but just in case
1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      .. */
1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (SUCCESS)
1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags |= SfPollAfter;
1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(kdebug_trace)
1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kdebug_trace(%ld, %ld, %ld, %ld, %ld, %ld)",
1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*
1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Don't check anything - some clients pass fewer arguments.
1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "kdebug_trace",
1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"code", int,"arg1", int,"arg2",
1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"arg3", int,"arg4", int,"arg5");
1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(seteuid)
1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("seteuid(%ld)", ARG1);
1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_REG_READ1(long, "seteuid", vki_uid_t, "uid");
1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(setegid)
1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("setegid(%ld)", ARG1);
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_REG_READ1(long, "setegid", vki_uid_t, "uid");
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(settid)
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("settid(%ld, %ld)", ARG1, ARG2);
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_REG_READ2(long, "settid", vki_uid_t, "uid", vki_gid_t, "gid");
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* XXX need to check whether we need POST operations for
1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * waitevent, watchevent, modwatch -- jpeach
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(watchevent)
1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("watchevent(%#lx, %#lx)", ARG1, ARG2);
1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_REG_READ2(long, "watchevent",
1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        vki_eventreq *, "event", unsigned int, "eventmask");
1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_MEM_READ("watchevent(event)", ARG1, sizeof(vki_eventreq));
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_MEM_READ("watchevent(eventmask)", ARG2, sizeof(unsigned int));
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    *flags |= SfMayBlock;
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WAITEVENT_FAST_POLL ((Addr)(struct timeval *)-1)
1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(waitevent)
1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("waitevent(%#lx, %#lx)", ARG1, ARG2);
1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "waitevent",
1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_eventreq *, "event", struct timeval *, "timeout");
1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("waitevent(event)", ARG1, sizeof(vki_eventreq));
1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2  &&  ARG2 != WAITEVENT_FAST_POLL) {
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_timeval_READ("waitevent(timeout)", ARG2);
1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* XXX ((timeval*)-1) is valid for ARG2 -- jpeach */
1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(waitevent)
1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, sizeof(vki_eventreq));
1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(modwatch)
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("modwatch(%#lx, %#lx)", ARG1, ARG2);
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "modwatch",
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_eventreq *, "event", unsigned int, "eventmask");
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("modwatch(event)", ARG1, sizeof(vki_eventreq));
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("modwatch(eventmask)", ARG2, sizeof(unsigned int));
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getxattr)
1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getxattr(%#lx(%s), %#lx(%s), %#lx, %lu, %lu, %ld)",
1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, (char *)ARG1, ARG2, (char *)ARG2, ARG3, ARG4, ARG5, ARG6);
1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(vki_ssize_t, "getxattr",
1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                const char *, path, char *, name, void *, value,
1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                vki_size_t, size, uint32_t, position, int, options);
1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("getxattr(path)", ARG1);
1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("getxattr(name)", ARG2);
1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4);
1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getxattr)
1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert((vki_ssize_t)RES >= 0);
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG3, (vki_ssize_t)RES);
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fgetxattr)
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fgetxattr(%ld, %#lx(%s), %#lx, %lu, %lu, %ld)",
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, ARG2, (char *)ARG2, ARG3, ARG4, ARG5, ARG6);
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(vki_ssize_t, "fgetxattr",
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, fd, char *, name, void *, value,
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_size_t, size, uint32_t, position, int, options);
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("getxattr(name)", ARG2);
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4);
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fgetxattr)
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert((vki_ssize_t)RES >= 0);
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG3, (vki_ssize_t)RES);
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(setxattr)
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setxattr ( %#lx(%s), %#lx(%s), %#lx, %lu, %lu, %ld )",
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, (char *)ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5, ARG6 );
1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(int, "setxattr",
1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *,"path", char *,"name", void *,"value",
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_size_t,"size", uint32_t,"position", int,"options" );
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fsetxattr)
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "fsetxattr ( %ld, %#lx(%s), %#lx, %lu, %lu, %ld )",
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1, ARG2, (char*)ARG2, ARG3, ARG4, ARG5, ARG6 );
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(int, "fsetxattr",
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"fd", char *,"name", void *,"value",
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_size_t,"size", uint32_t,"position", int,"options" );
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(removexattr)
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "removexattr ( %#lx(%s), %#lx(%s), %ld )",
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3 );
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "removexattr",
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char*, "path", char*, "attrname", int, "options");
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "removexattr(attrname)", ARG2 );
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fremovexattr)
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "fremovexattr ( %ld, %#lx(%s), %ld )",
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1, ARG2, (HChar*)ARG2, ARG3 );
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "fremovexattr",
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, "fd", char*, "attrname", int, "options");
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "removexattr(attrname)", ARG2 );
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(listxattr)
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "listxattr ( %#lx(%s), %#lx, %lu, %ld )",
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1, (char *)ARG1, ARG2, ARG3, ARG4 );
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4 (long, "listxattr",
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *,"path", char *,"namebuf",
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_size_t,"size", int,"options" );
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "listxattr(namebuf)", ARG2, ARG3 );
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(listxattr)
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert((vki_ssize_t)RES >= 0);
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, (vki_ssize_t)RES );
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(flistxattr)
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "flistxattr ( %ld, %#lx, %lu, %ld )",
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1, ARG2, ARG3, ARG4 );
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4 (long, "flistxattr",
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  int, "fd", char *,"namebuf",
1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_size_t,"size", int,"options" );
1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "flistxattr(namebuf)", ARG2, ARG3 );
1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(flistxattr)
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert((vki_ssize_t)RES >= 0);
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, (vki_ssize_t)RES );
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(shmat)
1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord arg2tmp;
1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "shmat",
1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, shmid, const void *, shmaddr, int, shmflg);
1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (arg2tmp == 0)
1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EINVAL );
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG2 = arg2tmp;  // used in POST
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(shmat)
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(shmctl)
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "shmctl",
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, shmid, int, cmd, struct vki_shmid_ds *, buf);
1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(shmctl)
1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(shmdt)
1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmdt ( %#lx )",ARG1);
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EINVAL );
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(shmdt)
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(shmget)
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(shm_open)
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shm_open(%#lx(%s), %ld, %ld)", ARG1, (char *)ARG1, ARG2, ARG3);
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "shm_open",
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *,"name", int,"flags", vki_mode_t,"mode");
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "shm_open(filename)", ARG1 );
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(shm_open)
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ML_(fd_allowed)(RES, "shm_open", tid, True)) {
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(close)(RES);
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EMFILE );
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(clo_track_fds))
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(stat_extended)
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("stat_extended( %#lx(%s), %#lx, %#lx, %#lx )",
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, (char *)ARG1, ARG2, ARG3, ARG4);
1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "stat_extended", char *, file_name, struct stat *, buf,
1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, fsacl, vki_size_t *, fsacl_size);
1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "stat_extended(file_name)",  ARG1 );
1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE(   "stat_extended(buf)",        ARG2, sizeof(struct vki_stat) );
1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("stat_extended(fsacl)",      ARG3, *(vki_size_t *)ARG4 );
1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ(    "stat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) );
1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(stat_extended)
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 );
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG4, sizeof(vki_size_t) );
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(lstat_extended)
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("lstat_extended( %#lx(%s), %#lx, %#lx, %#lx )",
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, (char *)ARG1, ARG2, ARG3, ARG4);
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "lstat_extended", char *, file_name, struct stat *, buf,
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, fsacl, vki_size_t *, fsacl_size);
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "lstat_extended(file_name)",  ARG1 );
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE(   "lstat_extended(buf)",        ARG2, sizeof(struct vki_stat) );
1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("lstat_extended(fsacl)",      ARG3, *(vki_size_t *)ARG4 );
1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ(    "lstat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) );
1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(lstat_extended)
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 );
1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG4, sizeof(vki_size_t) );
1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fstat_extended)
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fstat_extended( %ld, %#lx, %#lx, %#lx )",
1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, ARG2, ARG3, ARG4);
1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "fstat_extended", int, fd, struct stat *, buf,
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, fsacl, vki_size_t *, fsacl_size);
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE(   "fstat_extended(buf)",        ARG2, sizeof(struct vki_stat) );
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("fstat_extended(fsacl)",      ARG3, *(vki_size_t *)ARG4 );
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ(    "fstat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) );
1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fstat_extended)
1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 );
1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG4, sizeof(vki_size_t) );
1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(stat64_extended)
2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("stat64_extended( %#lx(%s), %#lx, %#lx, %#lx )",
2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, (char *)ARG1, ARG2, ARG3, ARG4);
2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "stat64_extended", char *, file_name, struct stat64 *, buf,
2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, fsacl, vki_size_t *, fsacl_size);
2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "stat64_extended(file_name)",  ARG1 );
2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE(   "stat64_extended(buf)",        ARG2, sizeof(struct vki_stat64) );
2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("stat64_extended(fsacl)",      ARG3, *(vki_size_t *)ARG4 );
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ(    "stat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) );
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(stat64_extended)
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 );
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG4, sizeof(vki_size_t) );
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(lstat64_extended)
2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("lstat64_extended( %#lx(%s), %#lx, %#lx, %#lx )",
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, (char *)ARG1, ARG2, ARG3, ARG4);
2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "lstat64_extended", char *, file_name, struct stat64 *, buf,
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, fsacl, vki_size_t *, fsacl_size);
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "lstat64_extended(file_name)",  ARG1 );
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE(   "lstat64_extended(buf)",        ARG2, sizeof(struct vki_stat64) );
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE(   "lstat64_extended(fsacl)",   ARG3, *(vki_size_t *)ARG4 );
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ(    "lstat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) );
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(lstat64_extended)
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 );
2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG4, sizeof(vki_size_t) );
2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fstat64_extended)
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fstat64_extended( %ld, %#lx, %#lx, %#lx )",
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, ARG2, ARG3, ARG4);
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "fstat64_extended", int, fd, struct stat64 *, buf,
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, fsacl, vki_size_t *, fsacl_size);
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE(   "fstat64_extended(buf)",        ARG2, sizeof(struct vki_stat64) );
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("fstat64_extended(fsacl)",      ARG3, *(vki_size_t *)ARG4 );
2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ(    "fstat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) );
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fstat64_extended)
2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) ))
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 );
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG4, sizeof(vki_size_t) );
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fchmod_extended)
2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: Note: this is not really correct.  Handling of
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      chmod_extended is broken in the same way. */
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fchmod_extended ( %ld, %ld, %ld, %ld, %#lx )",
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5);
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(long, "fchmod_extended",
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, fildes,
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 uid_t, uid,
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 gid_t, gid,
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_mode_t, mode,
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void* /*really,user_addr_t*/, xsecurity);
2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: relative to the xnu sources (kauth_copyinfilesec), this
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      is just way wrong.  [The trouble is with the size, which depends on a
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      non-trival kernel computation] */
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "fchmod_extended(xsecurity)", ARG5,
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(struct vki_kauth_filesec) );
2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(chmod_extended)
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: Note: this is not really correct.  Handling of
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      fchmod_extended is broken in the same way. */
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("chmod_extended ( %#lx(%s), %ld, %ld, %ld, %#lx )",
2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG1 ? (HChar*)ARG1 : "(null)", ARG2, ARG3, ARG4, ARG5);
2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(long, "chmod_extended",
2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, fildes,
2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 uid_t, uid,
2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 gid_t, gid,
2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_mode_t, mode,
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void* /*really,user_addr_t*/, xsecurity);
2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("chmod_extended(path)", ARG1);
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: relative to the xnu sources (kauth_copyinfilesec), this
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      is just way wrong.  [The trouble is with the size, which depends on a
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      non-trival kernel computation] */
2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "chmod_extended(xsecurity)", ARG5,
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(struct vki_kauth_filesec) );
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(open_extended)
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: Note: this is not really correct.  Handling of
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {,f}chmod_extended is broken in the same way. */
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("open_extended ( %#lx(%s), 0x%lx, %ld, %ld, %ld, %#lx )",
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG1 ? (HChar*)ARG1 : "(null)",
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	 ARG2, ARG3, ARG4, ARG5, ARG6);
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "open_extended",
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 char*, path,
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,   flags,
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 uid_t, uid,
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 gid_t, gid,
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_mode_t, mode,
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void* /*really,user_addr_t*/, xsecurity);
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("open_extended(path)", ARG1);
2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: relative to the xnu sources (kauth_copyinfilesec), this
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      is just way wrong.  [The trouble is with the size, which depends on a
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      non-trival kernel computation] */
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG6)
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "open_extended(xsecurity)", ARG6,
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(struct vki_kauth_filesec) );
2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This is a ridiculous syscall.  Specifically, the 'entries' argument points
2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// to a buffer that contains one or more 'accessx_descriptor' structs followed
2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// by one or more strings.  Each accessx_descriptor contains a field,
2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 'ad_name_offset', which points to one of the strings (or it can contain
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// zero which means "reuse the string from the previous accessx_descriptor").
2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// What's really ridiculous is that we are only given the size of the overall
2137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// buffer, not the number of accessx_descriptors, nor the number of strings.
2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// The kernel determines the number of accessx_descriptors by walking through
2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// them one by one, checking that the ad_name_offset points within the buffer,
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// past the current point (or that it's a zero, unless its the first
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// descriptor);  if so, we assume that this really is an accessx_descriptor,
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// if not, we assume we've hit the strings section.  Gah.
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This affects us here because number of entries in the 'results' buffer is
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// determined by the number of accessx_descriptors.  So we have to know that
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// number in order to do PRE_MEM_WRITE/POST_MEM_WRITE of 'results'.  In
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// practice, we skip the PRE_MEM_WRITE step because it's easier to do the
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// computation after the syscall has succeeded, because the kernel will have
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// checked for all the zillion different ways this syscall can fail, and we'll
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// know we have a well-formed 'entries' buffer.  This means we might miss some
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// uses of unaddressable memory but oh well.
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(access_extended)
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("access_extended( %#lx(%s), %lu, %#lx, %lu )",
2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, (char *)ARG1, ARG2, ARG3, ARG4);
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // XXX: the accessx_descriptor struct contains padding, so this can cause
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // unnecessary undefined value errors.  But you arguably shouldn't be
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // passing undefined values to the kernel anyway...
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "access_extended", void *, entries, vki_size_t, size,
2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_errno_t *, results, vki_uid_t *, uid);
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("access_extended(entries)", ARG1, ARG2 );
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // XXX: as mentioned above, this check is too hard to do before the
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // syscall.
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //PRE_MEM_WRITE("access_extended(results)", ARG3, ??? );
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(access_extended)
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // 'n_descs' is the number of descriptors we think are in the buffer.  We
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // start with the maximum possible value, which occurs if we have the
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // shortest possible string section.  The shortest string section allowed
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // consists of a single one-char string (plus the NUL char).  Hence the
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // '2'.
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct vki_accessx_descriptor* entries = (struct vki_accessx_descriptor*)ARG1;
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT size = ARG2;
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int n_descs = (size - 2) / sizeof(struct accessx_descriptor);
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i;         // Current position in the descriptors section array.
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int u;         // Upper bound on the length of the descriptors array
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  //   (recomputed each time around the loop)
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(n_descs > 0);
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Step through the descriptors, lowering 'n_descs' until we know we've
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // reached the string section.
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; True; i++) {
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // If we're past our estimate, we must be one past the end of the
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // descriptors section (ie. at the start of the string section).  Stop.
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i >= n_descs)
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Get the array index for the string, but pretend momentarily that it
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // is actually another accessx_descriptor.  That gives us an upper bound
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // on the length of the descriptors section.  (Unless the index is zero,
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // in which case we have no new info.)
2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      u = entries[i].ad_name_offset / sizeof(struct vki_accessx_descriptor);
2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (u == 0) {
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(i != 0);
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // If the upper bound is below our current estimate, revise that
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // estimate downwards.
2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (u < n_descs)
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         n_descs = u;
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Sanity check.
2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(n_descs <= VKI_ACCESSX_MAX_DESCRIPTORS);
2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG3, n_descs * sizeof(vki_errno_t) );
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(chflags)
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("chflags ( %#lx(%s), %lu )", ARG1, (char *)ARG1, ARG2);
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "chflags", const char *,path, unsigned int,flags);
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("chflags(path)", ARG1);
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme sanity-check flags value?
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fchflags)
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fchflags ( %ld, %lu )", ARG1, ARG2);
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "fchflags", int,fd, unsigned int,flags);
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme sanity-check flags value?
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(stat64)
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("stat64 ( %#lx(%s), %#lx )", ARG1, (char *)ARG1, ARG2);
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "stat", const char *,path, struct stat64 *,buf);
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("stat64(path)", ARG1);
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(stat64)
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(lstat64)
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("lstat64 ( %#lx(%s), %#lx )", ARG1, (char *)ARG1, ARG2);
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "stat", const char *,path, struct stat64 *,buf);
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("lstat64(path)", ARG1);
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(lstat64)
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fstat64)
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fstat64 ( %ld, %#lx )", ARG1,ARG2);
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat64 *, buf);
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fstat64)
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getfsstat)
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getfsstat(%#lx, %ld, %ld)", ARG1, ARG2, ARG3);
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "getfsstat",
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct vki_statfs *, buf, int, bufsize, int, flags);
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1) {
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // ARG2 is a BYTE SIZE
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("getfsstat(buf)", ARG1, ARG2);
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getfsstat)
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1) {
2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // RES is a STRUCT COUNT
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG1, RES * sizeof(struct vki_statfs));
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getfsstat64)
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getfsstat64(%#lx, %ld, %ld)", ARG1, ARG2, ARG3);
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "getfsstat64",
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct vki_statfs64 *, buf, int, bufsize, int, flags);
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1) {
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // ARG2 is a BYTE SIZE
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("getfsstat64(buf)", ARG1, ARG2);
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getfsstat64)
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1) {
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // RES is a STRUCT COUNT
2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG1, RES * sizeof(struct vki_statfs64));
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mount)
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // We are conservative and check everything, except the memory pointed to
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // by 'data'.
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx, %#lx )",
2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1,(Char*)ARG1, ARG2,(Char*)ARG2, ARG3, ARG4);
2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(long, "mount",
2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *, type, const char *, dir,
2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, flags, void *, data);
2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "mount(type)", ARG1);
2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "mount(dir)", ARG2);
2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList,
2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          void *attrBuf, SizeT attrBufSize,
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          void (*fn)(ThreadId, void *attrData, SizeT size)
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          )
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint32_t attrBit;
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int32_t attrSize;
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } attrspec;
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static const attrspec commonattr[] = {
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // This order is important.
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_RETURNED_ATTRS,  sizeof(attribute_set_t) },
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_NAME,            -1 },
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_DEVID,           sizeof(dev_t) },
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_FSID,            sizeof(fsid_t) },
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_OBJTYPE,         sizeof(fsobj_type_t) },
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_OBJTAG,          sizeof(fsobj_tag_t) },
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_OBJID,           sizeof(fsobj_id_t) },
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_OBJPERMANENTID,  sizeof(fsobj_id_t) },
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_PAROBJID,        sizeof(fsobj_id_t) },
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_SCRIPT,          sizeof(text_encoding_t) },
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_CRTIME,          sizeof(struct timespec) },
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_MODTIME,         sizeof(struct timespec) },
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_CHGTIME,         sizeof(struct timespec) },
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_ACCTIME,         sizeof(struct timespec) },
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_BKUPTIME,        sizeof(struct timespec) },
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_FNDRINFO,        32 /*FileInfo+ExtendedFileInfo, or FolderInfo+ExtendedFolderInfo*/ },
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_OWNERID,         sizeof(uid_t) },
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_GRPID,           sizeof(gid_t) },
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_ACCESSMASK,      sizeof(uint32_t) },
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_NAMEDATTRCOUNT,  sizeof(uint32_t) },
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_NAMEDATTRLIST,   -1 },
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_FLAGS,           sizeof(uint32_t) },
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_USERACCESS,      sizeof(uint32_t) },
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_EXTENDED_SECURITY, -1 },
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_UUID,            sizeof(guid_t) },
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_GRPUUID,         sizeof(guid_t) },
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_FILEID,          sizeof(uint64_t) },
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_PARENTID,        sizeof(uint64_t) },
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_CMN_FULLPATH,        -1 },
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { 0,                        0 }
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   };
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static const attrspec volattr[] = {
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // This order is important.
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_INFO,            0 },
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_FSTYPE,          sizeof(uint32_t) },
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_SIGNATURE,       sizeof(uint32_t) },
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_SIZE,            sizeof(off_t) },
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_SPACEFREE,       sizeof(off_t) },
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_SPACEAVAIL,      sizeof(off_t) },
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_MINALLOCATION,   sizeof(off_t) },
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_ALLOCATIONCLUMP, sizeof(off_t) },
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_IOBLOCKSIZE,     sizeof(uint32_t) },
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_OBJCOUNT,        sizeof(uint32_t) },
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_FILECOUNT,       sizeof(uint32_t) },
2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_DIRCOUNT,        sizeof(uint32_t) },
2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_MAXOBJCOUNT,     sizeof(uint32_t) },
2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_MOUNTPOINT,      -1 },
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_NAME,            -1 },
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_MOUNTFLAGS,      sizeof(uint32_t) },
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_MOUNTEDDEVICE,   -1 },
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_ENCODINGSUSED,   sizeof(uint64_t) },
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_CAPABILITIES,    sizeof(vol_capabilities_attr_t) },
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_UUID,            sizeof(uuid_t) },
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_VOL_ATTRIBUTES,      sizeof(vol_attributes_attr_t) },
2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { 0,                        0 }
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   };
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static const attrspec dirattr[] = {
2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // This order is important.
2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_DIR_LINKCOUNT,       sizeof(uint32_t) },
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_DIR_ENTRYCOUNT,      sizeof(uint32_t) },
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_DIR_MOUNTSTATUS,     sizeof(uint32_t) },
2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { 0,                        0 }
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   };
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static const attrspec fileattr[] = {
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // This order is important.
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_LINKCOUNT,      sizeof(uint32_t) },
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_TOTALSIZE,      sizeof(off_t) },
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_ALLOCSIZE,      sizeof(off_t) },
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_IOBLOCKSIZE,    sizeof(uint32_t) },
2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_CLUMPSIZE,      sizeof(uint32_t) },
2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_DEVTYPE,        sizeof(uint32_t) },
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_FILETYPE,       sizeof(uint32_t) },
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_FORKCOUNT,      sizeof(uint32_t) },
2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_FORKLIST,       -1 },
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_DATALENGTH,     sizeof(off_t) },
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_DATAALLOCSIZE,  sizeof(off_t) },
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_DATAEXTENTS,    sizeof(extentrecord) },
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_RSRCLENGTH,     sizeof(off_t) },
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_RSRCALLOCSIZE,  sizeof(off_t) },
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FILE_RSRCEXTENTS,    sizeof(extentrecord) },
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { 0,                        0 }
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   };
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static const attrspec forkattr[] = {
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // This order is important.
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FORK_TOTALSIZE,      sizeof(off_t) },
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ATTR_FORK_ALLOCSIZE,      sizeof(off_t) },
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { 0,                        0 }
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   };
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static const attrspec *attrdefs[5] = {
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      commonattr, volattr, dirattr, fileattr, forkattr
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   };
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   attrgroup_t a[5];
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   uint8_t *d, *dend;
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int g, i;
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(attrList->bitmapcount == 5);
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memcpy)(a, &attrList->commonattr, sizeof(a));
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d = attrBuf;
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dend = d + attrBufSize;
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // ATTR_CMN_RETURNED_ATTRS tells us what's really here, if set
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (a[0] & ATTR_CMN_RETURNED_ATTRS) {
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // fixme range check this?
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       a[0] &= ~ATTR_CMN_RETURNED_ATTRS;
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       fn(tid, d, sizeof(attribute_set_t));
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       VG_(memcpy)(a, d, sizeof(a));
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (g = 0; g < 5; g++) {
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; attrdefs[g][i].attrBit; i++) {
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         uint32_t bit = attrdefs[g][i].attrBit;
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         int32_t size = attrdefs[g][i].attrSize;
2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (a[g] & bit) {
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             a[g] &= ~bit;  // clear bit for error check later
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (size == -1) {
2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               attrreference_t *ref = (attrreference_t *)d;
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               size = MIN(sizeof(attrreference_t), dend - d);
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fn(tid, d, size);
2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (size >= sizeof(attrreference_t)  &&
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   d + ref->attr_dataoffset < dend)
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               {
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  fn(tid, d + ref->attr_dataoffset,
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     MIN(ref->attr_length, dend - (d + ref->attr_dataoffset)));
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               d += size;
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            else {
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               size = MIN(size, dend - d);
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fn(tid, d, size);
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               d += size;
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ((uintptr_t)d % 4) d += 4 - ((uintptr_t)d % 4);
2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (d > dend) d = dend;
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Known bits are cleared. Die if any bits are left.
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (a[g] != 0) {
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(message)(Vg_UserMsg, "UNKNOWN attrlist flags %d:0x%x\n", g, a[g]);
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void get1attr(ThreadId tid, void *attrData, SizeT attrDataSize)
2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE((Addr)attrData, attrDataSize);
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void set1attr(ThreadId tid, void *attrData, SizeT attrDataSize)
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("setattrlist(attrBuf value)", (Addr)attrData, attrDataSize);
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getattrlist)
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)",
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, (char *)ARG1, ARG2, ARG3, ARG4, ARG5);
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(int, "getattrlist",
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *,path, struct vki_attrlist *,attrList,
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *,attrBuf, vki_size_t,attrBufSize, unsigned int,options);
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("getattrlist(path)", ARG1);
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("getattrlist(attrList)", ARG2, sizeof(struct vki_attrlist));
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getattrlist(attrBuf)", ARG3, ARG4);
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getattrlist)
2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG4 > sizeof(vki_uint32_t)) {
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // attrBuf is uint32_t size followed by attr data
2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_uint32_t *sizep = (vki_uint32_t *)ARG3;
2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG3, sizeof(vki_uint32_t));
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG5 & FSOPT_REPORT_FULLSIZE) {
2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // *sizep is bytes required for return value, including *sizep
2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // *sizep is actual bytes returned, including *sizep
2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      scan_attrlist(tid, (struct vki_attrlist *)ARG2, sizep+1, MIN(*sizep, ARG4), &get1attr);
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(setattrlist)
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)",
2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, (char *)ARG1, ARG2, ARG3, ARG4, ARG5);
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(int, "setattrlist",
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *,path, struct vki_attrlist *,attrList,
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *,attrBuf, vki_size_t,attrBufSize, unsigned int,options);
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("setattrlist(path)", ARG1);
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("setattrlist(attrList)", ARG2, sizeof(struct vki_attrlist));
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   scan_attrlist(tid, (struct vki_attrlist *)ARG2, (void*)ARG3, ARG4, &set1attr);
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getdirentriesattr)
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdirentriesattr(%ld, %#lx, %#lx, %ld, %#lx, %#lx, %#lx, %ld)",
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8);
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ8(int, "getdirentriesattr",
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,fd, struct vki_attrlist *,attrList,
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *,attrBuf, size_t,attrBufSize,
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int *,count, unsigned int *,basep,
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int *,newState, unsigned int,options);
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("getdirentriesattr(attrList)",
2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ARG2, sizeof(struct vki_attrlist));
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentriesattr(attrBuf)", ARG3, ARG4);
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("getdirentriesattr(count)", ARG5, sizeof(unsigned int));
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentriesattr(count)", ARG5, sizeof(unsigned int));
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentriesattr(basep)", ARG6, sizeof(unsigned int));
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentriesattr(newState)", ARG7, sizeof(unsigned int));
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getdirentriesattr)
2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   char *p, *end;
2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unsigned int count;
2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unsigned int i;
2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG5, sizeof(unsigned int));
2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG6, sizeof(unsigned int));
2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG7, sizeof(unsigned int));
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // return buffer is concatenation of variable-size structs
2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   count = *(unsigned int *)ARG5;
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p = (char *)ARG3;
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   end = (char *)ARG3 + ARG4;
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < count; i++) {
2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(p < end);  // failure is kernel bug or Valgrind bug
2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += *(unsigned int *)p;
2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG3, p - (char *)ARG3);
2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("got %d records, %ld/%lu bytes\n",
2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         count, (Addr)p-(Addr)ARG3, ARG4);
2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fsgetpath)
2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %llu)",
2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3,
2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ((unsigned int *)ARG3)[0], ((unsigned int *)ARG3)[1],
2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         LOHI64(ARG4, ARG5));
2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(ssize_t, "fsgetpath",
2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*,"buf", size_t,"bufsize",
2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 fsid_t *,"fsid",
2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_uint32_t, "objid_low32", vki_uint32_t, "objid_high32");
2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %lu)",
2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3,
2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ((unsigned int *)ARG3)[0],
2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ((unsigned int *)ARG3)[1], ARG4);
2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(ssize_t, "fsgetpath",
2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*,"buf", size_t,"bufsize",
2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 fsid_t *,"fsid", uint64_t,"objid");
2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("fsgetpath(fsid)", ARG3, sizeof(fsid_t));
2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("fsgetpath(buf)", ARG1, ARG2);
2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fsgetpath)
2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, RES);
2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(audit_session_self)
2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRINT("audit_session_self()");
2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(audit_session_self)
2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "audit-session-%p");
2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRINT("audit-session %#lx", RES);
2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(exchangedata)
2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("exchangedata(%#lx(%s), %#lx(%s), %lu)",
2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, (char*)ARG1, ARG2, (char*)ARG2, ARG3);
2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "exchangedata",
2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 char *, path1, char *, path2, unsigned long, options);
2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "exchangedata(path1)", ARG1 );
2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "exchangedata(path2)", ARG2 );
2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fsctl)
2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fsctl ( %#lx(%s), %ld, %#lx, %ld )",
2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, (char *)ARG1, ARG2, ARG3, ARG4);
2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4( long, "fsctl",
2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  char *,"path", unsigned int,"request",
2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  void *,"data", unsigned int,"options");
2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "fsctl(path)", ARG1 );
2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2) {
2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_afpfsByteRangeLock2FSCTL: {
2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct vki_ByteRangeLockPB2 *pb = (struct vki_ByteRangeLockPB2 *)ARG3;
2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->offset)",
2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     pb->offset);
2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->length)",
2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     pb->length);
2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->unLockFlag)",
2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     pb->unLockFlag);
2646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->startEndFlag)",
2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     pb->startEndFlag);
2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->fd)",
2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     pb->fd);
2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_FIELD_WRITE("fsctl(afpfsByteRangeLock2, pb->retRangeStart)",
2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      pb->retRangeStart);
2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme check fd
2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FSIOC_SYNC_VOLUME:
2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRE_MEM_READ( "fsctl(FSIOC_SYNC_VOLUME)", ARG3, sizeof(int) );
2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // fsctl requests use ioctl encoding
2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3);
2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fsctl)
2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2) {
2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_afpfsByteRangeLock2FSCTL: {
2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct vki_ByteRangeLockPB2 *pb = (struct vki_ByteRangeLockPB2 *)ARG3;
2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_FIELD_WRITE(pb->retRangeStart);
2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_FSIOC_SYNC_VOLUME:
2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       break;
2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // fsctl requests use ioctl encoding
2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3);
2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(initgroups)
2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("initgroups(%s, %#lx, %lu)", (char *)ARG1, ARG2, ARG3);
2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_REG_READ3(long, "initgroups",
2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        int, setlen, vki_gid_t *, gidset, vki_uid_t, gmuid);
2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_MEM_READ("gidset", ARG2, ARG1 * sizeof(vki_gid_t));
2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//--------- posix_spawn ---------//
2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Largely copied from PRE(sys_execve) in syswrap-generic.c, and from
2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the simpler AIX equivalent (syswrap-aix5.c). */
2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Pre_read a char** argument.
2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr a_deref;
2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr* a_p = (Addr*)a;
2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a_deref = *a_p;
2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0 == a_deref)
2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( s2, a_deref );
2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a += sizeof(char*);
2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic SysRes simple_pre_exec_check ( const HChar* exe_name,
2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                      Bool trace_this_child )
2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int fd, ret;
2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes res;
2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool setuid_allowed;
2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check it's readable
2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   res = VG_(open)(exe_name, VKI_O_RDONLY, 0);
2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (sr_isError(res)) {
2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return res;
2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fd = sr_Res(res);
2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(close)(fd);
2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we have execute permissions.  We allow setuid executables
2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // to be run only in the case when we are not simulating them, that
2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // is, they to be run natively.
2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   setuid_allowed = trace_this_child  ? False  : True;
2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ret = VG_(check_executable)(NULL/*&is_setuid*/,
2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (HChar*)exe_name, setuid_allowed);
2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0 != ret) {
2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return VG_(mk_SysRes_Error)(ret);
2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return VG_(mk_SysRes_Success)(0);
2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(posix_spawn)
2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char*        path = NULL;       /* path to executable */
2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char**       envp = NULL;
2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char**       argv = NULL;
2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char**       arg2copy;
2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char*        launcher_basename = NULL;
2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int          i, j, tot_args;
2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes       res;
2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool         trace_this_child;
2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* args: pid_t* pid
2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            char*  path
2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            posix_spawn_file_actions_t* file_actions
2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            char** argv
2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            char** envp
2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )",
2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5 );
2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Standard pre-syscall checks */
2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(int, "posix_spawn", vki_pid_t*, pid, char*, path,
2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, file_actions, char**, argv, char**, envp );
2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("posix_spawn(pid)", ARG1, sizeof(vki_pid_t) );
2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("posix_spawn(path)", ARG2);
2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // DDD: check file_actions
2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG4 != 0)
2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pre_argv_envp( ARG4, tid, "posix_spawn(argv)",
2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                "posix_spawn(argv[i])" );
2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5 != 0)
2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pre_argv_envp( ARG5, tid, "posix_spawn(envp)",
2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                "posix_spawn(envp[i])" );
2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0)
2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )\n",
2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5 );
2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now follows a bunch of logic copied from PRE(sys_execve) in
2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      syswrap-generic.c. */
2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check that the name at least begins in client-accessible storage. */
2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 == 0 /* obviously bogus */
2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       || !VG_(am_is_valid_for_client)( ARG2, 1, VKI_PROT_READ )) {
2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EFAULT );
2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Decide whether or not we want to follow along
2787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { // Make 'child_argv' be a pointer to the child's arg vector
2788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     // (skipping the exe name)
2789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     HChar** child_argv = (HChar**)ARG4;
2790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     if (child_argv && child_argv[0] == NULL)
2791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        child_argv = NULL;
2792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG2, child_argv );
2793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Do the important checks:  it is a file, is executable, permissions are
2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // ok, etc.  We allow setuid executables to run only in the case when
2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // we are not simulating them, that is, they to be run natively.
2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   res = simple_pre_exec_check( (const HChar*)ARG2, trace_this_child );
2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (sr_isError(res)) {
2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( sr_Err(res) );
2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If we're tracing the child, and the launcher name looks bogus
2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (possibly because launcher.c couldn't figure it out, see
2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      comments therein) then we have no option but to fail. */
2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (trace_this_child
2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       && (VG_(name_of_launcher) == NULL
2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           || VG_(name_of_launcher)[0] != '/')) {
2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Ok.  So let's give it a try. */
2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap", "Posix_spawn of %s\n", (Char*)ARG2);
2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // Terminate gdbserver if it is active.
2818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(clo_vgdb)  != Vg_VgdbNo) {
2819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // If the child will not be traced, we need to terminate gdbserver
2820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // to cleanup the gdbserver resources (e.g. the FIFO files).
2821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // If child will be traced, we also terminate gdbserver: the new
2822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // Valgrind will start a fresh gdbserver after exec.
2823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(gdbserver) (tid);
2824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
2825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Set up the child's exe path.
2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (trace_this_child) {
2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // We want to exec the launcher.  Get its pre-remembered path.
2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      path = VG_(name_of_launcher);
2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // VG_(name_of_launcher) should have been acquired by m_main at
2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // startup.  The following two assertions should be assured by
2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // the "If we're tracking the child .." test just above here.
2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(path);
2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(path[0] == '/');
2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      launcher_basename = path;
2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      path = (Char*)ARG2;
2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Set up the child's environment.
2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Remove the valgrind-specific stuff from the environment so the
2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This is done unconditionally, since if we are tracing the child,
2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // the child valgrind will set up the appropriate client environment.
2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Nb: we make a copy of the environment before trying to mangle it
2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // as it might be in read-only memory (this was bug #101881).
2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Then, if tracing the child, set VALGRIND_LIB for it.
2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5 == 0) {
2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      envp = NULL;
2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      envp = VG_(env_clone)( (Char**)ARG5 );
2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(envp);
2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(env_remove_valgrind_env_stuff)( envp );
2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (trace_this_child) {
2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Set VALGRIND_LIB in ARG5 (the environment)
2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Set up the child's args.  If not tracing it, they are
2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // simply ARG4.  Otherwise, they are
2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG2] ++ ARG4[1..]
2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // except that the first VG_(args_for_valgrind_noexecpass) args
2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // are omitted.
2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!trace_this_child) {
2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv = (Char**)ARG4;
2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert( VG_(args_for_valgrind) );
2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert( VG_(args_for_valgrind_noexecpass)
2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* how many args in total will there be? */
2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // launcher basename
2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args = 1;
2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // V's args
2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args -= VG_(args_for_valgrind_noexecpass);
2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // name of client exe
2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args++;
2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // args for client exe, skipping [0]
2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      arg2copy = (Char**)ARG4;
2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (arg2copy && arg2copy[0]) {
2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 1; arg2copy[i]; i++)
2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            tot_args++;
2895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // allocate
2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv = VG_(malloc)( "di.syswrap.pre_sys_execve.1",
2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          (tot_args+1) * sizeof(HChar*) );
2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(argv);
2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // copy
2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      j = 0;
2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv[j++] = launcher_basename;
2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i < VG_(args_for_valgrind_noexecpass))
2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            continue;
2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv[j++] = (Char*)ARG2;
2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (arg2copy && arg2copy[0])
2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 1; arg2copy[i]; i++)
2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            argv[j++] = arg2copy[i];
2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv[j++] = NULL;
2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // check
2914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(j == tot_args+1);
2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* DDD: sort out the signal state.  What signal
2918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      state does the child inherit from the parent?  */
2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) {
2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Char **cpp;
2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("posix_spawn: %s\n", path);
2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (cpp = argv; cpp && *cpp; cpp++)
2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("argv: %s\n", *cpp);
2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (1)
2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (cpp = envp; cpp && *cpp; cpp++)
2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("env: %s\n", *cpp);
2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Let the call go through as usual.  However, we have to poke
2931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the altered arguments back into the argument slots. */
2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG2 = (UWord)path;
2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG4 = (UWord)argv;
2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG5 = (UWord)envp;
2935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* not to mention .. */
2937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(posix_spawn)
2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //POST_MEM_WRITE( ARG1, sizeof(vki_pid_t) );
2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(socket)
2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(socket)
2953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes r;
2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(r);
2958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(setsockopt)
2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setsockopt ( %ld, %ld, %ld, %#lx, %ld )",
2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1,ARG2,ARG3,ARG4,ARG5);
2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(long, "setsockopt",
2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, int, level, int, optname,
2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const void *, optval, vki_socklen_t, optlen);
2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getsockopt)
2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr optval_p = ARG4;
2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr optlen_p = ARG5;
2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",
2977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1,ARG2,ARG3,ARG4,ARG5);
2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(long, "getsockopt",
2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, int, level, int, optname,
2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, optval, vki_socklen_t *, optlen);
2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* int getsockopt(int socket, int level, int option_name,
2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     void *restrict option_value,
2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     socklen_t *restrict option_len); */
2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (optval_p != (Addr)NULL) {
2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p,
2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   "socketcall.getsockopt(optval)",
2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   "socketcall.getsockopt(optlen)" );
2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // DDD: #warning GrP fixme darwin-specific sockopts
2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getsockopt)
2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr optval_p = ARG4;
2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr optlen_p = ARG5;
2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (optval_p != (Addr)NULL) {
2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(buf_and_len_post_check) ( tid, VG_(mk_SysRes_Success)(RES),
3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    optval_p, optlen_p,
3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    "socketcall.getsockopt(optlen_out)" );
3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // DDD: #warning GrP fixme darwin-specific sockopts
3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(connect)
3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "connect",
3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
3014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(accept)
3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "accept",
3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, struct sockaddr *, addr, int, *addrlen);
3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(accept)
3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes r;
3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                         ARG1,ARG2,ARG3);
3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(r);
3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sendto)
3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sendto ( %ld, %s, %ld, %lu, %#lx, %ld )",
3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1,(char *)ARG2,ARG3,ARG4,ARG5,ARG6);
3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "sendto",
3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, const void *, msg, int, len,
3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, flags,
3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct sockaddr *, to, int, tolen);
3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sendfile)
3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sendfile(%ld, %ld, %llu, %#lx, %#lx, %ld)",
3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, LOHI64(ARG3, ARG4), ARG5, ARG6, ARG7);
3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ7(long, "sendfile",
3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int, fromfd, int, tofd,
3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_uint32_t, offset_low32, vki_uint32_t, offset_high32,
3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_uint64_t *, nwritten, struct sf_hdtr *, sf_header, int, flags);
3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("sendfile(nwritten)", ARG5, sizeof(vki_uint64_t));
3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG6) PRE_MEM_WRITE("sendfile(sf_header)", ARG6, sizeof(struct sf_hdtr));
3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sendfile(%ld, %ld, %ld, %#lx, %#lx, %ld)",
3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "sendfile",
3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int, fromfd, int, tofd,
3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_uint64_t, offset,
3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_uint64_t *, nwritten, struct sf_hdtr *, sf_header, int, flags);
3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("sendfile(nwritten)", ARG4, sizeof(vki_uint64_t));
3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) PRE_MEM_WRITE("sendfile(sf_header)", ARG5, sizeof(struct sf_hdtr));
3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sendfile)
3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
3077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG5, sizeof(vki_uint64_t));
3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG6) POST_MEM_WRITE(ARG6, sizeof(struct sf_hdtr));
3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG4, sizeof(vki_uint64_t));
3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) POST_MEM_WRITE(ARG5, sizeof(struct sf_hdtr));
3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(recvfrom)
3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",
3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "recvfrom",
3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, void *, buf, int, len, unsigned int, flags,
3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct sockaddr *, from, int *, fromlen);
3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(recvfrom)
3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                       ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sendmsg)
3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "sendmsg",
3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, const struct msghdr *, msg, int, flags);
3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(recvmsg)
3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(recvmsg)
3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(shutdown)
3129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shutdown ( %ld, %ld )",ARG1,ARG2);
3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "shutdown", int, s, int, how);
3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(bind)
3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "bind",
3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(listen)
3146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("listen ( %ld, %ld )",ARG1,ARG2);
3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "listen", int, s, int, backlog);
3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getsockname)
3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "getsockname",
3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, struct sockaddr *, name, int *, namelen);
3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getsockname)
3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                          ARG1,ARG2,ARG3);
3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getpeername)
3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "getpeername",
3172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, struct sockaddr *, name, int *, namelen);
3173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getpeername)
3177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
3180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                          ARG1,ARG2,ARG3);
3181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(socketpair)
3185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
3187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(long, "socketpair",
3188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, d, int, type, int, protocol, int *, sv);
3189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
3190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(socketpair)
3193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                         ARG1,ARG2,ARG3,ARG4);
3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(gethostuuid)
3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("gethostuuid ( %#lx, %#lx )", ARG1, ARG2);
3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int,"gethostuuid",
3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 char *,"uuid_buf",
3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct vki_timespec *,"timeout");
3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("uuid_buf", ARG1, 16);
3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("timeout", ARG2, sizeof(struct vki_timespec));
3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(gethostuuid)
3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, 16);
3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Darwin pipe() returns the two descriptors in two registers. */
3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(pipe)
3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("pipe ( )");
3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(int, "pipe");
3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(pipe)
3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int p0, p1;
3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p0 = RES;
3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p1 = RESHI;
3232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       !ML_(fd_allowed)(p1, "pipe", tid, True)) {
3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(close)(p0);
3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(close)(p1);
3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EMFILE );
3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(clo_track_fds)) {
3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(record_fd_open_nameless)(tid, p0);
3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(record_fd_open_nameless)(tid, p1);
3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getlogin)
3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getlogin ( %#lx, %ld )", ARG1, ARG2);
3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "getlogin",
3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 char *,"namebuf", unsigned int,"namelen");
3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getlogin(namebuf)", ARG1, ARG2);
3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getlogin)
3257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, ARG2);
3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(ptrace)
3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("ptrace ( %ld, %ld, %#lx, %ld )", ARG1, ARG2, ARG3, ARG4);
3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(long, "ptrace",
3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"request", vki_pid_t,"pid",
3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_caddr_t,"addr", int,"data");
3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Note: some code uses ptrace(random, 0, 0, 0) as a profiling mechanism.
3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme anything needed?
3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(issetugid)
3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("issetugid ( )");
3278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(long, "issetugid");
3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getdtablesize)
3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdtablesize ( )");
3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(long, "getdtablesize");
3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getdtablesize)
3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Subtract Valgrind's fd range from client's dtable
3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES > VG_(fd_hard_limit)) SET_STATUS_Success(VG_(fd_hard_limit));
3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(lseek)
3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("lseek ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(vki_off_t, "lseek",
3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int,fd, int,offset_hi, int,offset_lo,
3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int,whence);
3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(pathconf)
3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("pathconf(%#lx(%s), %ld)", ARG1,(char *)ARG1,ARG2);
3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long,"pathconf", const char *,"path", int,"name");
3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ("pathconf(path)", ARG1);
3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fpathconf)
3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fpathconf(%ld, %ld)", ARG1,ARG2);
3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long,"fpathconf", int,"fd", int,"name");
3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ML_(fd_allowed)(ARG1, "fpathconf", tid, False))
3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EBADF );
3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getdirentries)
3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdirentries(%ld, %#lx, %ld, %#lx)", ARG1, ARG2, ARG3, ARG4);
3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "getdirentries",
3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, fd, char *, buf, int, nbytes, long *, basep);
3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentries(basep)", ARG4, sizeof(long));
3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentries(buf)", ARG2, ARG3);
3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getdirentries)
3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG4, sizeof(long));
3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme be specific about d_name?
3334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG2, RES);
3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(getdirentries64)
3339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdirentries64(%ld, %#lx, %lu, %#lx)", ARG1, ARG2, ARG3, ARG4);
3341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(vki_ssize_t, "getdirentries",
3342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,fd, char *,buf, vki_size_t,nbytes, vki_off_t *,basep);
3343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentries(position)", ARG4, sizeof(vki_off_t));
3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("getdirentries(buf)", ARG2, ARG3);
3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(getdirentries64)
3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG4, sizeof(vki_off_t));
3349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme be specific about d_name? (fixme copied from 32 bit version)
3350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG2, RES);
3351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(statfs64)
3355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("statfs64 ( %#lx(%s), %#lx )",ARG1,(char *)ARG1,ARG2);
3357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "statfs64", const char *, path, struct statfs64 *, buf);
3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
3359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "statfs64(buf)", ARG2, sizeof(struct vki_statfs64) );
3360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(statfs64)
3362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs64) );
3364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(fstatfs64)
3368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fstatfs64 ( %ld, %#lx )",ARG1,ARG2);
3370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "fstatfs64",
3371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, fd, struct statfs *, buf);
3372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "fstatfs64(buf)", ARG2, sizeof(struct vki_statfs64) );
3373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(fstatfs64)
3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs64) );
3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(csops)
3380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("csops ( %ld, %#lx, %#lx, %lu )", ARG1, ARG2, ARG3, ARG4);
3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "csops",
3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_pid_t, pid, uint32_t, ops,
3384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *, useraddr, vki_size_t, usersize);
3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "csops(useraddr)", ARG3, ARG4 );
3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // If the pid is ours, don't mark the program as KILL or HARD
3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Maybe we should keep track of this for later calls to STATUS
3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ARG1 || VG_(getpid)() == ARG1) {
3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (ARG2) {
3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VKI_CS_OPS_MARKINVALID:
3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VKI_CS_OPS_MARKHARD:
3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case VKI_CS_OPS_MARKKILL:
3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         SET_STATUS_Success(0);
3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(csops)
3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG3, ARG4 );
3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(auditon)
3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("auditon ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int,"auditon",
3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"cmd", void*,"data", unsigned int,"length");
3409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG1) {
3411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETPOLICY:
3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETKMASK:
3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETQCTRL:
3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETCOND:
3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETCLASS:
3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETPMASK:
3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETFSIZE:
3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
3420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SENDTRIGGER:
3421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // kernel reads data..data+length
3423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("auditon(data)", ARG2, ARG3);
3424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETKMASK:
3427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETPOLICY:
3428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETQCTRL:
3429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETFSIZE:
3430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCOND:
3431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // kernel writes data..data+length
3432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme be precise about what gets written
3433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("auditon(data)", ARG2, ARG3);
3434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCLASS:
3438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETPINFO:
3439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETPINFO_ADDR:
3440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
3441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETSINFO_ADDR:
3442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // kernel reads and writes data..data+length
3444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme be precise about what gets read and written
3445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("auditon(data)", ARG2, ARG3);
3446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("auditon(data)", ARG2, ARG3);
3447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETKAUDIT:
3450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETSTAT:
3451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETUMASK:
3452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETSMASK:
3453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETKAUDIT:
3454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCWD:
3455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCAR:
3456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETSTAT:
3457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // unimplemented on darwin
3458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
3461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(message)(Vg_UserMsg, "UNKNOWN auditon cmd %ld", ARG1);
3462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(auditon)
3466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG1) {
3468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETPOLICY:
3470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETKMASK:
3471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETQCTRL:
3472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETCOND:
3473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETCLASS:
3474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETPMASK:
3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETFSIZE:
3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
3477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SENDTRIGGER:
3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // kernel reads data..data+length
3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETKMASK:
3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETPOLICY:
3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETQCTRL:
3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETFSIZE:
3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCOND:
3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // kernel writes data..data+length
3488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme be precise about what gets written
3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG2, ARG3);
3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCLASS:
3494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETPINFO:
3495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETPINFO_ADDR:
3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETSINFO_ADDR:
3498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // kernel reads and writes data..data+length
3500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme be precise about what gets read and written
3501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG2, ARG3);
3502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETKAUDIT:
3505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETSTAT:
3506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETUMASK:
3507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_SETSMASK:
3508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETKAUDIT:
3509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCWD:
3510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETCAR:
3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case VKI_A_GETSTAT:
3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // unimplemented on darwin
3513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
3516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mmap)
3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // SysRes r;
3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %lld )",
3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, LOHI64(ARG6, ARG7) );
3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ7(Addr, "mmap",
3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 Addr,start, vki_size_t,length, int,prot, int,flags, int,fd,
3530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned long,offset_hi, unsigned long,offset_lo);
3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme V mmap and kernel mach_msg collided once - don't use
3532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // V's mechanism for now
3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // (Off64T)LOHI64(ARG6, ARG7) );
3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )",
3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "mmap",
3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 Addr,start, vki_size_t,length, int,prot, int,flags, int,fd,
3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 Off64T,offset);
3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // SET_STATUS_from_SysRes(r);
3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mmap)
3549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES != -1) {
3551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(notify_core_and_tool_of_mmap)(RES, ARG2, ARG3, ARG4, ARG5, ARG6);
3552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Try to load symbols from the region
3553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(di_notify_mmap)( (Addr)RES, False/*allow_SkFileV*/,
3554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                           -1/*don't use_fd*/ );
3555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__sysctl)
3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "__sysctl ( %#lx, %ld, %#lx, %#lx, %#lx, %ld )",
3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(int, "__sysctl", int*, name, unsigned int, namelen,
3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, oldp, vki_size_t *, oldlenp,
3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, newp, vki_size_t *, newlenp);
3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("sysctl(name)", ARG1, ARG2);  // reads name[0..namelen-1]
3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG4) {
3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // writes *ARG4
3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("sysctl(oldlenp)", ARG4, sizeof(size_t));
3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG3) {
3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // also reads *ARG4, and writes as much as ARG3[0..ARG4-1]
3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_READ("sysctl(oldlenp)", ARG4, sizeof(size_t));
3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_WRITE("sysctl(oldp)", ARG3, *(size_t *)ARG4);
3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("sysctl(newp)", ARG5, ARG6);
3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_trace_syscalls)) {
3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unsigned int i;
3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int *name = (int *)ARG1;
3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)(" mib: [ ");
3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < ARG2; i++) {
3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("%d ", name[i]);
3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("]");
3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme intercept KERN_PROCARGS and KERN_PROC_PID for our pid
3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // (executable path and arguments and environment
3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Intercept sysctl(kern.usrstack). The kernel's reply would be
3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Valgrind's stack, not the client's stack.
3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme kern_usrstack64
3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG1  &&  ARG2 == 2  &&
3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ((int *)ARG1)[0] == VKI_CTL_KERN  &&
3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ((int *)ARG1)[1] == VKI_KERN_USRSTACK32
3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ((int *)ARG1)[1] == VKI_KERN_USRSTACK64
3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          )
3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      {
3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ARG5/*newp*/  ||  ARG6/*newlen*/) {
3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            SET_STATUS_Failure(VKI_EPERM); // USRSTACK is read-only
3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr *oldp = (Addr *)ARG3;
3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            size_t *oldlenp = (size_t *)ARG4;
3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (oldlenp) {
3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               Addr stack_end = VG_(clstk_end)+1;
3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               size_t oldlen = *oldlenp;
3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               // always return actual size
3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               *oldlenp = sizeof(Addr);
3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (oldp  &&  oldlen >= sizeof(Addr)) {
3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  // oldp is big enough
3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  // copy value and return 0
3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  *oldp = stack_end;
3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  SET_STATUS_Success(0);
3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               } else {
3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  // oldp isn't big enough
3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  // copy as much as possible and return ENOMEM
3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  if (oldp) VG_(memcpy)(oldp, &stack_end, oldlen);
3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  SET_STATUS_Failure(VKI_ENOMEM);
3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!SUCCESS  &&  !FAILURE) {
3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Don't set SfPostOnFail if we've already handled it locally.
3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags |= SfPostOnFail;
3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(__sysctl)
3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (SUCCESS  ||  ERR == VKI_ENOMEM) {
3643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // sysctl can write truncated data and return VKI_ENOMEM
3644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG4) {
3645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE(ARG4, sizeof(size_t));
3646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG3  &&  ARG4) {
3648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE(ARG3, *(size_t *)ARG4);
3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sigpending)
3655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "sigpending ( %#lx )", ARG1 );
3657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "sigpending", vki_sigset_t *, set);
3658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_sigset_t));
3659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sigpending)
3661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
3663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sigprocmask)
3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord arg1;
3669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sigprocmask ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
3670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "sigprocmask",
3671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset);
3672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 != 0)
3673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
3674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 != 0)
3675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
3676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Massage ARG1 ('how').  If ARG2 (the new mask) is NULL then the
3678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      value of 'how' is irrelevant, and it appears that Darwin's libc
3679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      passes zero, which is not equal to any of
3680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SIG_{BLOCK,UNBLOCK,SETMASK}.  This causes
3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_sys_sigprocmask) to complain, since it checks the 'how'
3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      value independently of the other args.  Solution: in this case,
3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      simply pass a valid (but irrelevant) value for 'how'. */
3684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Also, in this case the new set is passed to the kernel by
3685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      reference, not value, as in some other sigmask related Darwin
3686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      syscalls. */
3687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   arg1 = ARG1;
3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 == 0  /* the new-set is NULL */
3689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       && ARG1 != VKI_SIG_BLOCK
3690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       && ARG1 != VKI_SIG_UNBLOCK && ARG1 != VKI_SIG_SETMASK) {
3691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      arg1 = VKI_SIG_SETMASK;
3692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(
3694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_sys_sigprocmask) ( tid, arg1, (vki_sigset_t*)ARG2,
3695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                           (vki_sigset_t*)ARG3 )
3696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
3697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (SUCCESS)
3699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags |= SfPollAfter;
3700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sigprocmask)
3703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES == 0 && ARG3 != 0)
3706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
3707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sigsuspend)
3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Just hand this off to the kernel.  Is that really correct?  And
3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shouldn't we at least set SfPollAfter?  These questions apply to
3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      all the Linux versions too. */
3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* I think the first arg is the 32-bit signal mask (by value), and
3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the other two args are ignored. */
3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
3718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sigsuspend ( mask=0x%08lx )", ARG1 );
3719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sigsuspend", int, sigmask);
3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Be careful about the 4th arg, since that is a uint64_t.  Hence 64-
3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and 32-bit wrappers are different.
3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG5 and ARG6 (buffer, buffersize) specify a buffer start and
3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   length in the usual way.  I have seen values NULL, 0 passed in some
3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cases.  I left the calls to PRE_MEM_WRITE/READ unconditional on the
3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   basis that they don't do anything if the length is zero, so it's OK
3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for the buffer pointer to be NULL in that case (meaning they don't
3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   complain).
3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int proc_info(int32_t callnum, int32_t pid,
3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 uint32_t flavor, uint64_t arg,
3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 user_addr_t buffer, int32_t buffersize)
3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
3737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
3738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(proc_info)
3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
3741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("proc_info(%d, %d, %u, %llu, %#lx, %d)",
3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (Int)ARG1, (Int)ARG2, (UInt)ARG3, LOHI64(ARG4,ARG5), ARG6, (Int)ARG7);
3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ7(int, "proc_info",
3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, callnum, int, pid, unsigned int, flavor,
3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_uint32_t, arg_low32,
3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_uint32_t, arg_high32,
3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, buffer, int, buffersize);
3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("proc_info(buffer)", ARG6, ARG7);
3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("proc_info(%d, %d, %u, %llu, %#lx, %d)",
3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (Int)ARG1, (Int)ARG2, (UInt)ARG3, (ULong)ARG4, ARG5, (Int)ARG6);
3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(int, "proc_info",
3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, callnum, int, pid, unsigned int, flavor,
3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned long long int, arg,
3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, buffer, int, buffersize);
3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("proc_info(buffer)", ARG5, ARG6);
3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(proc_info)
3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 4
3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG6, ARG7);
3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG5, ARG6);
3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* DARWIN_VERS >= DARWIN_10_6 */
3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   aio_*
3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// We must record the aiocbp for each aio_read() in a table so that when
3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// aio_return() is called we can mark the memory written asynchronously by
3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// aio_read() as having been written.  We don't have to do this for
3780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// aio_write().  See bug 197227 for more details.
3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic OSet* aiocbp_table = NULL;
3782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool aio_init_done = False;
3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void aio_init(void)
3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   aiocbp_table = VG_(OSetWord_Create)(VG_(malloc), "syswrap.aio", VG_(free));
3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   aio_init_done = True;
3788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool was_a_successful_aio_read = False;
3791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(aio_return)
3793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
3795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This assumes that the kernel looks at the struct pointer, but not the
3796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // contents of the struct.
3797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "aio_return ( %#lx )", ARG1 );
3798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "aio_return", struct vki_aiocb*, aiocbp);
3799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!aio_init_done) aio_init();
3801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   was_a_successful_aio_read = VG_(OSetWord_Remove)(aiocbp_table, (UWord)aiocbp);
3802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(aio_return)
3804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // If we found the aiocbp in our own table it must have been an aio_read(),
3806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // so mark the buffer as written.  If we didn't find it, it must have been
3807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // an aio_write() or a bogus aio_return() (eg. a second one on the same
3808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // aiocbp).  Either way, the buffer won't have been written so we don't
3809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // have to mark the buffer as written.
3810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (was_a_successful_aio_read) {
3811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
3812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE((Addr)aiocbp->aio_buf, aiocbp->aio_nbytes);
3813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      was_a_successful_aio_read = False;
3814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(aio_suspend)
3818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This assumes that the kernel looks at the struct pointers in the list,
3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // but not the contents of the structs.
3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "aio_suspend ( %#lx )", ARG1 );
3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "aio_suspend",
3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct vki_aiocb *, aiocbp, int, nent,
3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const struct vki_timespec *, timeout);
3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 > 0)
3826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("aio_suspend(list)", ARG1, ARG2 * sizeof(struct vki_aiocb *));
3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3)
3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ ("aio_suspend(timeout)", ARG3, sizeof(struct vki_timespec));
3829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(aio_error)
3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This assumes that the kernel looks at the struct pointer, but not the
3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // contents of the struct.
3835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "aio_error ( %#lx )", ARG1 );
3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "aio_error", struct vki_aiocb*, aiocbp);
3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(aio_read)
3840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "aio_read ( %#lx )", ARG1 );
3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "aio_read", struct vki_aiocb*, aiocbp);
3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "aio_read(aiocbp)", ARG1, sizeof(struct vki_aiocb));
3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)(aiocbp, sizeof(struct vki_aiocb))) {
3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ML_(fd_allowed)(aiocbp->aio_fildes, "aio_read", tid, /*isNewFd*/False)) {
3849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_WRITE("aio_read(aiocbp->aio_buf)",
3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       (Addr)aiocbp->aio_buf, aiocbp->aio_nbytes);
3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         SET_STATUS_Failure( VKI_EBADF );
3853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
3855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EINVAL );
3856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(aio_read)
3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // We have to record the fact that there is an asynchronous read request
3861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // pending.  When a successful aio_return() occurs for this aiocb, then we
3862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // will mark the memory as having been defined.
3863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!aio_init_done) aio_init();
3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // aiocbp shouldn't already be in the table -- if it was a dup, the kernel
3866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // should have caused the aio_read() to fail and we shouldn't have reached
3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // here.
3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(OSetWord_Insert)(aiocbp_table, (UWord)aiocbp);
3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(aio_write)
3872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1;
3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "aio_write ( %#lx )", ARG1 );
3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "aio_write", struct vki_aiocb*, aiocbp);
3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "aio_write(aiocbp)", ARG1, sizeof(struct vki_aiocb));
3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ML_(safe_to_deref)(aiocbp, sizeof(struct vki_aiocb))) {
3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ML_(fd_allowed)(aiocbp->aio_fildes, "aio_write", tid, /*isNewFd*/False)) {
3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_MEM_READ("aio_write(aiocbp->aio_buf)",
3882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      (Addr)aiocbp->aio_buf, aiocbp->aio_nbytes);
3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         SET_STATUS_Failure( VKI_EBADF );
3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EINVAL );
3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: formatted messages
3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic size_t desc_size(mach_msg_descriptor_t *desc)
3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (desc->type.type) {
3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_PORT_DESCRIPTOR:          return sizeof(desc->port);
3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_OOL_DESCRIPTOR:           return sizeof(desc->out_of_line);
3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:  return sizeof(desc->out_of_line);
3901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case MACH_MSG_OOL_PORTS_DESCRIPTOR:     return sizeof(desc->ool_ports);
3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN mach message descriptor %d\n", desc->type.type);
3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return sizeof(desc->type); // guess
3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void assign_port_names(mach_msg_ool_ports_descriptor_t *desc,
3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              const char *name)
3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_size_t i;
3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_port_t *ports = (mach_port_t *)desc->address;
3914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < desc->count; i++) {
3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(ports[i], name);
3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void import_complex_message(ThreadId tid, mach_msg_header_t *mh)
3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_body_t *body;
3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_size_t count, i;
3924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   uint8_t *p;
3925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_descriptor_t *desc;
3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(mh->msgh_bits & MACH_MSGH_BITS_COMPLEX);
3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   body = (mach_msg_body_t *)(mh+1);
3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   count = body->msgh_descriptor_count;
3931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p = (uint8_t *)(body+1);
3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < count; i++) {
3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      desc = (mach_msg_descriptor_t *)p;
3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += desc_size(desc);
3936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (desc->type.type) {
3938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_PORT_DESCRIPTOR:
3939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // single port
3940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         record_unnamed_port(tid, desc->port.name, -1);
3941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         record_port_insert_rights(desc->port.name, desc->port.disposition);
3942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("got port %s;\n", name_for_port(desc->port.name));
3943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_OOL_DESCRIPTOR:
3946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
3947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // out-of-line memory - map it
3948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme how is VOLATILE different? do we care?
3949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme do other flags tell us anything? assume shared for now
3950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme more SF_ flags marking mach_msg memory might be nice
3951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme protection
3952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (desc->out_of_line.size > 0) {
3953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr start = VG_PGROUNDDN((Addr)desc->out_of_line.address);
3954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr end = VG_PGROUNDUP((Addr)desc->out_of_line.address +
3955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (Addr)desc->out_of_line.size);
3956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRINT("got ool mem %p..%#lx;\n", desc->out_of_line.address,
3957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (Addr)desc->out_of_line.address+desc->out_of_line.size);
3958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_mmap)(
3960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               start, end - start, VKI_PROT_READ|VKI_PROT_WRITE,
3961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VKI_MAP_PRIVATE, -1, 0);
3962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme mark only un-rounded part as initialized
3964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_OOL_PORTS_DESCRIPTOR:
3967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // out-of-line array of ports - map it
3968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme see fixmes above
3969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("got %d ool ports %p..%#lx", desc->ool_ports.count, desc->ool_ports.address, (Addr)desc->ool_ports.address+desc->ool_ports.count*sizeof(mach_port_t));
3970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (desc->ool_ports.count > 0) {
3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr start = VG_PGROUNDDN((Addr)desc->ool_ports.address);
3973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr end = VG_PGROUNDUP((Addr)desc->ool_ports.address + desc->ool_ports.count * sizeof(mach_port_t));
3974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            mach_port_t *ports = (mach_port_t *)desc->ool_ports.address;
3975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_mmap)(
3977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               start, end - start, VKI_PROT_READ|VKI_PROT_WRITE,
3978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VKI_MAP_PRIVATE, -1, 0);
3979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRINT(":");
3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            for (i = 0; i < desc->ool_ports.count; i++) {
3982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               record_unnamed_port(tid, ports[i], -1);
3983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               record_port_insert_rights(ports[i], desc->port.disposition);
3984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               PRINT(" %s", name_for_port(ports[i]));
3985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
3986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT(";\n");
3988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
3991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("UNKNOWN Mach descriptor type %u!\n", desc->type.type);
3992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void pre_port_desc_read(ThreadId tid, mach_msg_port_descriptor_t *desc2)
3999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
4002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_t name;
4003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_size_t pad1;
4004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint16_t pad2;
4005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t disposition;
4006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t type;
4007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } *desc = (void*)desc2;
4008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.port.name",        desc->name);
4011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.port.disposition", desc->disposition);
4012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.port.type",        desc->type);
4013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void pre_ool_desc_read(ThreadId tid, mach_msg_ool_descriptor_t *desc2)
4017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
4020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr address;
4021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE != 8
4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_size_t size;
4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t deallocate;
4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t copy;
4026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t pad1;
4027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t type;
4028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 8
4029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_size_t size;
4030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } *desc = (void*)desc2;
4032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.out_of_line.address",    desc->address);
4035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.out_of_line.size",       desc->size);
4036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.out_of_line.deallocate", desc->deallocate);
4037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.out_of_line.copy",       desc->copy);
4038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.out_of_line.type",       desc->type);
4039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void pre_oolports_desc_read(ThreadId tid,
4042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   mach_msg_ool_ports_descriptor_t *desc2)
4043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
4046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr address;
4047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE != 8
4048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_size_t size;
4049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t deallocate;
4051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t copy;
4052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t disposition;
4053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uint8_t type;
4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 8
4055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_size_t size;
4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } *desc = (void*)desc2;
4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.ool_ports.address",     desc->address);
4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.ool_ports.size",        desc->size);
4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.ool_ports.deallocate",  desc->deallocate);
4063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.ool_ports.copy",        desc->copy);
4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.ool_ports.disposition", desc->disposition);
4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_FIELD_READ("msg->desc.ool_ports.type",        desc->type);
4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Returns the size of the descriptor area
4070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// (mach_msg_body_t + any mach_msg_descriptor_t)
4071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic size_t export_complex_message(ThreadId tid, mach_msg_header_t *mh)
4072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_body_t *body;
4074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_size_t count, i;
4075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   uint8_t *p;
4076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_descriptor_t *desc;
4077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(mh->msgh_bits & MACH_MSGH_BITS_COMPLEX);
4079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   body = (mach_msg_body_t *)(mh+1);
4081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("msg->msgh_descriptor_count)", (Addr)body, sizeof(*body));
4082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   count = body->msgh_descriptor_count;
4084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p = (uint8_t *)(body+1);
4085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < count; i++) {
4087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      desc = (mach_msg_descriptor_t *)p;
4088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += desc_size(desc);
4089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (desc->type.type) {
4091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_PORT_DESCRIPTOR:
4092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // single port; no memory map effects
4093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         pre_port_desc_read(tid, &desc->port);
4094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
4095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_OOL_DESCRIPTOR:
4097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_OOL_VOLATILE_DESCRIPTOR:
4098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // out-of-line memory - unmap it if it's marked dealloc
4099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme need to remap if message fails?
4100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme how is VOLATILE different? do we care?
4101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme struct is different for lp64
4102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         pre_ool_desc_read(tid, &desc->out_of_line);
4103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (desc->out_of_line.deallocate  &&  desc->out_of_line.size > 0) {
4105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vm_size_t size = desc->out_of_line.size;
4106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr start = VG_PGROUNDDN((Addr)desc->out_of_line.address);
4107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr end = VG_PGROUNDUP((Addr)desc->out_of_line.address + size);
4108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRINT("kill ool mem %p..%#lx; ", desc->out_of_line.address,
4109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (Addr)desc->out_of_line.address + size);
4110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_munmap)(start, end - start);
4111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
4113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case MACH_MSG_OOL_PORTS_DESCRIPTOR:
4115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // out-of-line array of ports - unmap it if it's marked dealloc
4116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme need to remap if message fails?
4117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme struct different for lp64
4118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         pre_oolports_desc_read(tid, &desc->ool_ports);
4119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (desc->ool_ports.deallocate  &&  desc->ool_ports.count > 0) {
4121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vm_size_t size = desc->ool_ports.count * sizeof(mach_port_t);
4122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr start = VG_PGROUNDDN((Addr)desc->ool_ports.address);
4123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr end = VG_PGROUNDUP((Addr)desc->ool_ports.address + size);
4124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRINT("kill ool port array %p..%#lx; ", desc->ool_ports.address,
4125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (Addr)desc->ool_ports.address + size);
4126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_munmap)(start, end - start);
4127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
4128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
4129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
4130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("UNKNOWN Mach descriptor type %u!\n", desc->type.type);
4131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
4132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return (size_t)((Addr)p - (Addr)body);
4136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
4140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: host-related messages
4141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
4142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(host_info)
4145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t host_info_outCnt;
4152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      integer_t host_info_out[14];
4153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (reply->RetCode) PRINT("mig return %d", reply->RetCode);
4159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(host_info)
4162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      host_flavor_t flavor;
4168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t host_info_outCnt;
4169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("host_info(mach_host_self(), flavor %d)", req->flavor);
4175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(host_info);
4177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(host_page_size)
4181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t out_page_size;
4188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PRINT("page size %llu", (ULong)reply->out_page_size);
4195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(host_page_size)
4201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("host_page_size(mach_host_self(), ...)");
4203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(host_page_size);
4205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(host_get_io_master)
4209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
4214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
4215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t io_master;
4216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
4217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assign_port_name(reply->io_master.name, "io_master-%p");
4223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("%s", name_for_port(reply->io_master.name));
4224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(host_get_io_master)
4227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Request *req = (Request *)ARG1;
4235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("host_get_io_master(mach_host_self())");
4237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(host_get_io_master);
4239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(host_get_clock_service)
4243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
4248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
4249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t clock_serv;
4250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
4251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assign_port_name(reply->clock_serv.name, "clock-%p");
4257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("%s", name_for_port(reply->clock_serv.name));
4258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(host_get_clock_service)
4261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      clock_id_t clock_id;
4267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("host_get_clock_service(mach_host_self(), %d)", req->clock_id);
4273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(host_get_clock_service);
4275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(host_request_notification)
4279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
4284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
4285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t notify_port;
4286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
4287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      host_flavor_t notify_type;
4289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == mach_task_self()) {
4295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (req->notify_type == 0) {
4296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("host_request_notification(mach_host_self(), %s, %s)",
4297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "HOST_NOTIFY_CALENDAR_CHANGE",
4298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               name_for_port(req->notify_port.name));
4299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
4300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("host_request_notification(mach_host_self(), %d, %s)",
4301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               req->notify_type,
4302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               name_for_port(req->notify_port.name));
4303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("host_request_notification(%s, %d, %s)",
4306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE),
4307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            req->notify_type,
4308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(req->notify_port.name));
4309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // GrP fixme only do this on success
4312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assign_port_name(req->notify_port.name, "host_notify-%p");
4313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
4317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: messages to a task
4318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
4319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// JRS 2011-Aug-25: just guessing here.  I have no clear idea how
4321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// these structs are derived.  They obviously relate to the various
4322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// .def files in the xnu sources, and can also be found in some
4323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// form in /usr/include/mach/*.h, but not sure how these all
4324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// relate to each other.
4325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(mach_port_set_context)
4327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
4328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack(4)
4329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   typedef struct {
4330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_header_t Head;
4331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      NDR_record_t NDR;
4332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_port_name_t name;
4333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_vm_address_t context;
4334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } Request;
4335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack()
4336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Request *req = (Request *)ARG1;
4338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("mach_port_set_context(%s, %s, 0x%llx)",
4340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        name_for_port(MACH_REMOTE),
4341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        name_for_port(req->name), req->context);
4342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   AFTER = POST_FN(mach_port_set_context);
4344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
4345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(mach_port_set_context)
4347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
4348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack(4)
4349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   typedef struct {
4350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_header_t Head;
4351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      NDR_record_t NDR;
4352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      kern_return_t RetCode;
4353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } Reply;
4354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack()
4355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
4356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// JRS 2011-Aug-25 FIXME completely bogus
4359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(task_get_exception_ports)
4360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
4361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack(4)
4362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   typedef struct {
4363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_header_t Head;
4364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      NDR_record_t NDR;
4365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      exception_mask_t exception_mask;
4366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } Request;
4367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack()
4368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("task_get_exception_ports(BOGUS)");
4370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   AFTER = POST_FN(task_get_exception_ports);
4371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
4372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(task_get_exception_ports)
4374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
4375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack(4)
4376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   typedef struct {
4377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_header_t Head;
4378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* start of the kernel processed data */
4379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_body_t msgh_body;
4380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_port_descriptor_t old_handlers[32];
4381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* end of the kernel processed data */
4382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      NDR_record_t NDR;
4383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      mach_msg_type_number_t masksCnt;
4384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      exception_mask_t masks[32];
4385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      exception_behavior_t old_behaviors[32];
4386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      thread_state_flavor_t old_flavors[32];
4387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } Reply;
4388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#pragma pack()
4389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
4390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
4392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov///////////////////////////////////////////////////
4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_type)
4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_type(%s, %s, ...)",
4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE), name_for_port(req->name));
4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_type);
4410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_type)
4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_extract_member)
4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t pset;
4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_extract_member(%s, 0x%x, 0x%x)",
4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->name, req->pset);
4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_extract_member);
4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme port tracker?
4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_extract_member)
4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (reply->RetCode) PRINT("mig return %d", reply->RetCode);
4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_allocate)
4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_right_t right;
4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_allocate(mach_task_self(), %d, ...)", req->right);
4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port_allocate.right) = req->right;
4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_allocate);
4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_allocate)
4475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme port tracking is too imprecise
4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // vg_assert(!port_exists(reply->name));
4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         record_unnamed_port(tid, reply->name, MACH_ARG(mach_port_allocate.right));
4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("got port 0x%x", reply->name);
4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("UNKNOWN inserted port 0x%x into remote task\n", reply->name);
4495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_deallocate)
4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_deallocate(%s, %s)",
4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name));
4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port.port) = req->name;
4519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_deallocate);
4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must block to prevent race (other thread allocates and
4523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // notifies after we deallocate but before we notify)
4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
4525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_deallocate)
4528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
4541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // Must have cleared SfMayBlock in PRE to prevent race
4542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         record_port_dealloc(MACH_ARG(mach_port.port));
4543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
4544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("UNKNOWN remote port dealloc\n");
4545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_get_refs)
4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_right_t right;
4560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_get_refs(%s, %s, 0x%x)",
4566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name), req->right);
4568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port_mod_refs.port) = req->name;
4570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port_mod_refs.right) = req->right;
4571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_get_refs);
4573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_get_refs)
4576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_urefs_t refs;
4583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("got refs=%d", reply->refs);
4590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_mod_refs)
4597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_right_t right;
4604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_delta_t delta;
4605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_mod_refs(%s, %s, 0x%x, 0x%x)",
4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name), req->right, req->delta);
4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port_mod_refs.port) = req->name;
4615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port_mod_refs.right) = req->right;
4616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port_mod_refs.delta) = req->delta;
4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_mod_refs);
4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must block to prevent race (other thread allocates and
4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // notifies after we deallocate but before we notify)
4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
4623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_mod_refs)
4626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
4639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // Must have cleared SfMayBlock in PRE to prevent race
4640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         record_port_mod_refs(MACH_ARG(mach_port_mod_refs.port),
4641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              MACH_PORT_TYPE(MACH_ARG(mach_port_mod_refs.right)),
4642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              MACH_ARG(mach_port_mod_refs.delta));
4643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
4644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("UNKNOWN remote port mod refs\n");
4645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_get_set_status)
4653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_get_set_status(%s, %s)",
4665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name));
4667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_get_set_status);
4669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_get_set_status)
4672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
4677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
4678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_ool_descriptor_t members;
4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
4680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t membersCnt;
4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Reply *reply = (Reply *)ARG1;
4687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme nothing to do?
4689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_move_member)
4693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    typedef struct {
4696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        mach_msg_header_t Head;
4697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        NDR_record_t NDR;
4698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        mach_port_name_t member;
4699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        mach_port_name_t after;
4700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    } Request;
4701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    Request *req = (Request *)ARG1;
4704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRINT("mach_port_move_member(%s, %s, %s)",
4706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          name_for_port(MACH_REMOTE),
4707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          name_for_port(req->member),
4708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          name_for_port(req->after));
4709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    /*
4710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    MACH_ARG(mach_port_move_member.member) = req->member;
4711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    MACH_ARG(mach_port_move_member.after) = req->after;
4712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    */
4713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    AFTER = POST_FN(mach_port_move_member);
4714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_move_member)
4717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
4724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // fixme port set tracker?
4731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_destroy)
4738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_destroy(%s, %s)",
4750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name));
4752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_port.port) = req->name;
4754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_destroy);
4756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must block to prevent race (other thread allocates and
4758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // notifies after we deallocate but before we notify)
4759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
4760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_destroy)
4763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
4769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
4770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
4773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
4775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
4776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // Must have cleared SfMayBlock in PRE to prevent race
4777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         record_port_destroy(MACH_ARG(mach_port.port));
4778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
4779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("UNKNOWN remote port destroy\n");
4780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
4783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_request_notification)
4788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
4793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
4794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t notify;
4795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
4796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_id_t msgid;
4799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_mscount_t sync;
4800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_request_notification(%s, %s, %d, %d, %d, %d, ...)",
4806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name), req->msgid, req->sync,
4808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->notify.name, req->notify.disposition);
4809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_request_notification);
4811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_request_notification)
4814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme port tracker? not sure
4816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_insert_right)
4820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
4825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
4826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t poly;
4827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
4828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_insert_right(%s, %s, %d, %d)",
4836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name), req->poly.name, req->poly.disposition);
4838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_insert_right);
4840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == mach_task_self()) {
4842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme import_complex_message handles everything?
4843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // what about export_complex_message for MOVE variants?
4844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN mach_port_insert_right into remote task!\n");
4846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme also may remove rights from this task?
4847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme port tracker?
4850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_insert_right)
4853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_extract_right)
4858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_name_t msgt_name;
4865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_extract_right(%s, %s, %d)",
4871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name), req->msgt_name);
4873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_extract_right);
4875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // fixme port tracker?
4877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_extract_right)
4880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // fixme import_complex_message handles the returned result, right?
4882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_get_attributes)
4886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_flavor_t flavor;
4893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t port_info_outCnt;
4894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_get_attributes(%s, %s, %d, ..., %d)",
4900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
4901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->name), req->flavor, req->port_info_outCnt);
4902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_get_attributes);
4904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_get_attributes)
4907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_set_attributes)
4912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_flavor_t flavor;
4919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t port_infoCnt;
4920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      integer_t port_info[10];
4921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_set_attributes(%s, %s, %d, ..., %d)",
4927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        name_for_port(MACH_REMOTE),
4928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        name_for_port(req->name), req->flavor, req->port_infoCnt);
4929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_set_attributes);
4931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_set_attributes)
4934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_port_insert_member)
4939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t name;
4945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t pset;
4946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_port_insert_member(%s, 0x%x, 0x%x)",
4952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE), req->name, req->pset);
4953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_port_insert_member);
4955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme port tracker?
4957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_port_insert_member)
4960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(task_get_special_port)
4965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
4966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
4967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
4968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
4969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
4970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int which_port;
4971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
4972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
4973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
4975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (req->which_port) {
4977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_KERNEL_PORT:
4978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("task_get_special_port(%s, TASK_KERNEL_PORT)",
4979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE));
4980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
4981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_HOST_PORT:
4982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("task_get_special_port(%s, TASK_HOST_PORT)",
4983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE));
4984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
4985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_BOOTSTRAP_PORT:
4986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("task_get_special_port(%s, TASK_BOOTSTRAP_PORT)",
4987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE));
4988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
4989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_WIRED_LEDGER_PORT:
4990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("task_get_special_port(%s, TASK_WIRED_LEDGER_PORT)",
4991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE));
4992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
4993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_PAGED_LEDGER_PORT:
4994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("task_get_special_port(%s, TASK_PAGED_LEDGER_PORT)",
4995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE));
4996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
4997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
4998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("task_get_special_port(%s, %d)",
4999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name_for_port(MACH_REMOTE), req->which_port);
5000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(task_get_special_port.which_port) = req->which_port;
5004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(task_get_special_port);
5006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(task_get_special_port)
5009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t special_port;
5016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("got port %#x ", reply->special_port.name);
5023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (MACH_ARG(task_get_special_port.which_port)) {
5025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_BOOTSTRAP_PORT:
5026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_bootstrap_port = reply->special_port.name;
5027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->special_port.name, "bootstrap");
5028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_KERNEL_PORT:
5030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->special_port.name, "kernel");
5031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_HOST_PORT:
5033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->special_port.name, "host");
5034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_WIRED_LEDGER_PORT:
5036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->special_port.name, "wired-ledger");
5037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case TASK_PAGED_LEDGER_PORT:
5039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->special_port.name, "paged-ledger");
5040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
5042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->special_port.name, "special-%p");
5043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      break;
5044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("%s", name_for_port(reply->special_port.name));
5047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_create)
5051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int policy;
5057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int value;
5058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_create(%s, ..., %d, %d)",
5064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE), req->policy, req->value);
5065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(semaphore_create);
5067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(semaphore_create)
5070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t semaphore;
5077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assign_port_name(reply->semaphore.name, "semaphore-%p");
5085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("%s", name_for_port(reply->semaphore.name));
5086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_destroy)
5090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t semaphore;
5097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_destroy(%s, %s)",
5105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE), name_for_port(req->semaphore.name));
5106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_port_destroy(req->semaphore.name);
5108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(semaphore_destroy);
5110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(semaphore_destroy)
5113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_ports_lookup)
5132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       mach_msg_header_t Head;
5136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Request *req = (Request *)ARG1;
5140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_ports_lookup(%s)", name_for_port(MACH_REMOTE));
5142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_ports_lookup);
5144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_ports_lookup)
5147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_ool_ports_descriptor_t init_port_set;
5154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t init_port_setCnt;
5157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    // Reply *reply = (Reply *)ARG1;
5161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(task_threads)
5165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Request *req = (Request *)ARG1;
5173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("task_threads(%s)", name_for_port(MACH_REMOTE));
5175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(task_threads);
5177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(task_threads)
5180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_ool_ports_descriptor_t act_list;
5187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t act_listCnt;
5190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == vg_task_port) {
5197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_names(&reply->act_list, "thread-%p");
5198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_names(&reply->act_list, "remote-thread-%p");
5200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(task_suspend)
5205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("task_suspend(%s)", name_for_port(MACH_REMOTE));
5207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == vg_task_port) {
5209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme self-suspend
5210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
5211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // suspend other - no problem
5213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(task_suspend);
5216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(task_suspend)
5219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(task_resume)
5224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("task_resume(%s)", name_for_port(MACH_REMOTE));
5226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == vg_task_port) {
5228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme self-resume
5229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
5230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // resume other - no problem
5232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(task_resume);
5235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(task_resume)
5238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_allocate)
5243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int flags;
5251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_allocate (%s, at %#llx, size %lld, flags %#x)",
5257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size, req->flags);
5259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_allocate.size) = req->size;
5261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_allocate.flags) = req->flags;
5262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_allocate);
5264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_allocate)
5267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        PRINT("allocated at %#llx", (ULong)reply->address);
5283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // requesting 0 bytes returns address 0 with no error
5284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (MACH_ARG(vm_allocate.size)) {
5285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_mmap)(
5286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  reply->address, MACH_ARG(vm_allocate.size),
5287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_ANON, -1, 0);
5288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
5289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
5290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("allocated at %#llx in remote task %s",
5291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               (ULong)reply->address,
5292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               name_for_port(MACH_REMOTE));
5293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_deallocate)
5301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_deallocate(%s, at %#llx, size %lld)",
5314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size);
5316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_deallocate.address) = req->address;
5318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_deallocate.size) = req->size;
5319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_deallocate);
5321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must block to prevent race (other thread allocates and
5323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // notifies after we deallocate but before we notify)
5324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
5325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_deallocate)
5328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (MACH_ARG(vm_deallocate.size)) {
5343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr start = VG_PGROUNDDN(MACH_ARG(vm_deallocate.address));
5344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr end = VG_PGROUNDUP(MACH_ARG(vm_deallocate.address) +
5345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    MACH_ARG(vm_deallocate.size));
5346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // Must have cleared SfMayBlock in PRE to prevent race
5347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_munmap)(start, end - start);
5348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
5349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_protect)
5357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boolean_t set_maximum;
5365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t new_protection;
5366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_protect(%s, at %#llx, size %lld, set_max %d, prot %d)",
5372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size,
5374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->set_maximum, req->new_protection);
5375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_protect.address) = req->address;
5377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_protect.size) = req->size;
5378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_protect.set_maximum) = req->set_maximum;
5379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_protect.new_protection) = req->new_protection;
5380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_protect);
5382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_protect)
5385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Addr start = VG_PGROUNDDN(MACH_ARG(vm_protect.address));
5400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Addr end = VG_PGROUNDUP(MACH_ARG(vm_protect.address) +
5401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 MACH_ARG(vm_protect.size));
5402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt prot = MACH_ARG(vm_protect.new_protection);
5403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (MACH_ARG(vm_protect.set_maximum)) {
5404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             // GrP fixme mprotect max
5405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             VG_(printf)("UNKNOWN vm_protect set maximum");
5406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            //VG_(mprotect_max_range)(start, end-start, prot);
5407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
5408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_mprotect)(start, end-start, prot);
5409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            VG_(di_notify_vm_protect)(start, end-start, prot);
5410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
5411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_inherit)
5419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_inherit_t new_inheritance;
5427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_inherit(%s, at %#llx, size %lld, value %d)",
5433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size,
5435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->new_inheritance);
5436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_inherit);
5438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_inherit)
5441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme do something?
5456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_read)
5464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_read(from %s at %#llx size %llu)",
5477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size);
5479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_read.addr) = req->address;
5481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_read.size) = req->size;
5482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_read);
5484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_read)
5487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_ool_descriptor_t data;
5494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t dataCnt;
5497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Reply *reply = (Reply *)ARG1;
5501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == vg_task_port) {
5503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // vm_read from self
5504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme copy initialized state
5505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_read)
5511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
5517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
5518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_read(from %s at 0x%llx size %llu)",
5524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE), req->address, req->size);
5525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_read.addr) = req->address;
5527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_read.size) = req->size;
5528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_read);
5530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_read)
5533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_ool_descriptor_t data;
5540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t dataCnt;
5543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Reply *reply = (Reply *)ARG1;
5547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (MACH_REMOTE == vg_task_port) {
5549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // vm_read from self
5550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme copy initialized state
5551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_read_overwrite)
5556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t data;
5564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_read_overwrite(from %s at %#llx size %llu to %#llx)",
5570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size, (ULong)req->data);
5572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_read_overwrite.addr) = req->address;
5574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_read_overwrite.size) = req->size;
5575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_read_overwrite.data) = req->data;
5576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("vm_read_overwrite(data)", req->data, req->size);
5578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_read_overwrite);
5580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_read_overwrite)
5583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t outsize;
5590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (reply->RetCode) {
5596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRINT("mig return %d", reply->RetCode);
5597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("read %llu bytes", (unsigned long long)reply->outsize);
5599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // vm_read_overwrite from self
5601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme copy initialized state
5602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE(MACH_ARG(vm_read_overwrite.data), reply->outsize);
5603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
5604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // vm_read_overwrite from remote
5605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE(MACH_ARG(vm_read_overwrite.data), reply->outsize);
5606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_copy)
5612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t source_address;
5618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t dest_address;
5620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_copy(%s, %#llx, %lld, %#llx)",
5626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->source_address,
5628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->size, (ULong)req->dest_address);
5629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_copy.src) = req->source_address;
5631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_copy.dst) = req->dest_address;
5632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_copy.size) = req->size;
5633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_copy);
5635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_copy)
5638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme set dst's initialization equal to src's
5653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // and wipe any symbols or translations in dst
5654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_map)
5662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t object;
5669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t mask;
5674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int flags;
5675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_offset_t offset;
5676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boolean_t copy;
5677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t cur_protection;
5678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t max_protection;
5679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_inherit_t inheritance;
5680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme check these
5686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_map(in %s, at %#llx, size %lld, from %s ...)",
5687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, (ULong)req->size,
5689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->object.name));
5690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_map.size) = req->size;
5692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_map.copy) = req->copy;
5693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_map.protection) = (req->cur_protection & req->max_protection);
5694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_map);
5696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_map)
5699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme check src and dest tasks
5714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PRINT("mapped at %#llx", (ULong)reply->address);
5715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme max prot
5716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(notify_core_and_tool_of_mmap)(
5717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            reply->address, VG_PGROUNDUP(MACH_ARG(vm_map.size)),
5718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            MACH_ARG(vm_map.protection), VKI_MAP_SHARED, -1, 0);
5719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme VKI_MAP_PRIVATE if !copy?
5720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_remap)
5727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t src_task;
5734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t target_address;
5737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_size_t size;
5738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t mask;
5739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boolean_t anywhere;
5740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t src_address;
5741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boolean_t copy;
5742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_inherit_t inheritance;
5743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme check src and dest tasks
5749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_trace_syscalls)) {
5751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_port_name_t source_task = req->src_task.name;
5752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (source_task == mach_task_self()) {
5753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("vm_remap(mach_task_self(), "
5754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "to %#llx size %lld, from mach_task_self() at %#llx, ...)",
5755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               (ULong)req->target_address,
5756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               (ULong)req->size, (ULong)req->src_address);
5757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
5758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("vm_remap(mach_task_self(), "
5759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "to %#llx size %lld, from task %u at %#llx, ...)",
5760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               (ULong)req->target_address, (ULong)req->size,
5761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               source_task, (ULong)req->src_address);
5762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // arg1 is task
5766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // vt->syscall_arg2 = req->target_address;
5767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(vm_remap.size) = req->size;
5768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // vt->syscall_arg4 = req->copy;
5769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_remap);
5771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_remap)
5774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t target_address;
5781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t cur_protection;
5782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t max_protection;
5783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme check src and dest tasks
5791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt prot = reply->cur_protection & reply->max_protection;
5792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme max prot
5793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mapped at %#llx", (ULong)reply->target_address);
5794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(notify_core_and_tool_of_mmap)(
5795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            reply->target_address, VG_PGROUNDUP(MACH_ARG(vm_remap.size)),
5796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            prot, VKI_MAP_SHARED, -1, 0);
5797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme VKI_MAP_FIXED if !copy?
5798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme copy initialized bits from source to dest if source_task is also mach_task_self
5799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_make_memory_entry_64)
5806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
5811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t parent_entry;
5813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
5814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      memory_object_size_t size;
5816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      memory_object_offset_t offset;
5817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t permission;
5818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_make_memory_entry_64(%s, %llu, %llu, %d, ..., %u)",
5824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->size, req->offset, req->permission, req->parent_entry.type);
5826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_make_memory_entry_64);
5828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_make_memory_entry_64)
5831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
5836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t object;
5837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      memory_object_size_t size;
5839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
5845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assign_port_name(reply->object.name, "memory-%p");
5846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("%s", name_for_port(reply->object.name));
5847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(vm_purgable_control)
5852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_address_t address;
5858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_purgable_t control;
5859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int state;
5860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vm_purgable_control(%s, %#llx, %d, %d)",
5866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (ULong)req->address, req->control, req->state);
5868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme verify address?
5870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(vm_purgable_control);
5872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(vm_purgable_control)
5875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int state;
5882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_purgable_control)
5895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
5901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_purgable_t control;
5902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int state;
5903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_purgable_control(%s, 0x%llx, %d, %d)",
5909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (unsigned long long)req->address, req->control, req->state);
5911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme verify address?
5913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_purgable_control);
5915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_purgable_control)
5918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int state;
5925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_allocate)
5938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
5944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
5945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int flags;
5946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
5947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
5950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_allocate (%s, at 0x%llx, size %lld, flags 0x%x)",
5952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
5953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->address, req->size, req->flags);
5954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_allocate.size) = req->size;
5956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_allocate.flags) = req->flags;
5957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_allocate);
5959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_allocate)
5962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
5967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
5968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
5969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
5970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
5971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
5972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
5974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
5976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
5977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("allocated at 0x%llx", reply->address);
5978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // requesting 0 bytes returns address 0 with no error
5979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (MACH_ARG(mach_vm_allocate.size)) {
5980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_mmap)(
5981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  reply->address, MACH_ARG(mach_vm_allocate.size),
5982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_ANON, -1, 0);
5983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
5984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
5985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("allocated at 0x%llx in remote task %s", reply->address,
5986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               name_for_port(MACH_REMOTE));
5987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
5988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
5989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
5990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
5991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
5992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_deallocate)
5995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
5996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
5997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
5998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
5999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
6002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_deallocate(%s, at 0x%llx, size %lld)",
6008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
6009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->address, req->size);
6010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_deallocate.address) = req->address;
6012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_deallocate.size) = req->size;
6013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_deallocate);
6015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must block to prevent race (other thread allocates and
6017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // notifies after we deallocate but before we notify)
6018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
6019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_deallocate)
6022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
6036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (MACH_ARG(mach_vm_deallocate.size)) {
6037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr start = VG_PGROUNDDN(MACH_ARG(mach_vm_deallocate.address));
6038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Addr end = VG_PGROUNDUP(MACH_ARG(mach_vm_deallocate.address) +
6039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    MACH_ARG(mach_vm_deallocate.size));
6040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // Must have cleared SfMayBlock in PRE to prevent race
6041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_munmap)(start, end - start);
6042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
6043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
6044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_protect)
6051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
6058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boolean_t set_maximum;
6059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t new_protection;
6060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_protect(%s, at 0x%llx, size %lld, set_max %d, prot %d)",
6066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE), req->address, req->size,
6067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->set_maximum, req->new_protection);
6068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_protect.address) = req->address;
6070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_protect.size) = req->size;
6071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_protect.set_maximum) = req->set_maximum;
6072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_protect.new_protection) = req->new_protection;
6073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_protect);
6075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_protect)
6078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
6092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Addr start = VG_PGROUNDDN(MACH_ARG(mach_vm_protect.address));
6093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Addr end = VG_PGROUNDUP(MACH_ARG(mach_vm_protect.address) +
6094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 MACH_ARG(mach_vm_protect.size));
6095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt prot = MACH_ARG(mach_vm_protect.new_protection);
6096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (MACH_ARG(mach_vm_protect.set_maximum)) {
6097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // DDD: #warning GrP fixme mprotect max
6098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            //VG_(mprotect_max_range)(start, end-start, prot);
6099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
6100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(notify_core_and_tool_of_mprotect)(start, end-start, prot);
6101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
6102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
6103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_inherit)
6110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
6117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_inherit_t new_inheritance;
6118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_inherit(to %s, at 0x%llx, size %llu, value %u)",
6124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
6125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->address, req->size, req->new_inheritance);
6126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_inherit);
6128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_inherit)
6131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // no V-visible side effects
6145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme except maybe fork/exec
6146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_copy)
6153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t source_address;
6159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
6160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t dest_address;
6161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_copy(%s, 0x%llx, %llu, 0x%llx)",
6167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
6168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->source_address, req->size, req->dest_address);
6169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // arg1 is task
6171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // vt->syscall_arg2 = req->source_address;
6172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // vt->syscall_arg3 = req->size;
6173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // vt->syscall_arg4 = req->dest_address;
6174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_copy);
6176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_copy)
6179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (MACH_REMOTE == vg_task_port) {
6193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme set dest's initialization equal to src's
6194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // BUT vm_copy allocates no memory
6195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
6196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_map)
6203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
6208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
6209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t object;
6210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
6211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
6214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t mask;
6215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int flags;
6216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      memory_object_offset_t offset;
6217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boolean_t copy;
6218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t cur_protection;
6219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_prot_t max_protection;
6220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vm_inherit_t inheritance;
6221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme check these
6227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_map(in %s, at 0x%llx, size %llu, from %s ...)",
6228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
6229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->address, req->size,
6230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->object.name));
6231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_map.size) = req->size;
6233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_map.copy) = req->copy;
6234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(mach_vm_map.protection) =
6235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (req->cur_protection & req->max_protection);
6236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_map);
6238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_map)
6241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme check src and dest tasks
6256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mapped at 0x%llx", reply->address);
6257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme max prot
6258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(notify_core_and_tool_of_mmap)(
6259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            reply->address, VG_PGROUNDUP(MACH_ARG(mach_vm_map.size)),
6260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            MACH_ARG(mach_vm_map.protection), VKI_MAP_SHARED, -1, 0);
6261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme VKI_MAP_PRIVATE if !copy?
6262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_vm_region_recurse)
6269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      natural_t nesting_depth;
6276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t infoCnt;
6277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_vm_region_recurse(in %s, at 0x%llx, depth %u, count %u)",
6283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(MACH_REMOTE),
6284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->address, req->nesting_depth, req->infoCnt);
6285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_vm_region_recurse);
6287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_vm_region_recurse)
6290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_address_t address;
6297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_vm_size_t size;
6298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      natural_t nesting_depth;
6299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t infoCnt;
6300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      int info[19];
6301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRINT("got region at 0x%llx, size %llu, depth %u, count %u",
6308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             reply->address, reply->size,
6309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             reply->nesting_depth, reply->infoCnt);
6310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // GrP fixme mark info contents beyond infoCnt as bogus
6311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
6318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: messages to thread
6319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
6320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_terminate)
6324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_terminate)
6329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool self_terminate = (mh->msgh_request_port == MACH_THREAD);
6332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_terminate(%s)", name_for_port(mh->msgh_request_port));
6334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_terminate);
6336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (self_terminate) {
6338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Terminating this thread.
6339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Copied from sys_exit.
6340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ThreadState *tst = VG_(get_ThreadState)(tid);
6341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->exitreason = VgSrc_ExitThread;
6342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->os_state.exitcode = 0;  // GrP fixme anything better?
6343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // What we would like to do is:
6344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //   SET_STATUS_Success(0);
6345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // but that doesn't work, because this is a MACH-class syscall,
6346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // and SET_STATUS_Success creates a UNIX-class syscall result.
6347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Hence we have to laboriously construct the full SysRes "by hand"
6348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // and use that to set the syscall return status.
6349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_from_SysRes(
6350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(mk_SysRes_x86_darwin)(
6351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_DARWIN_SYSCALL_CLASS_MACH,
6352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            False/*success*/, 0, 0
6353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         )
6354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );
6355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags &= ~SfMayBlock;  // clear flag set by PRE(mach_msg)
6356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Terminating some other thread.
6358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Do keep the scheduler lock while terminating any other thread.
6359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Otherwise we might halt the other thread while it holds the lock,
6360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // which would deadlock the process.
6361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme good enough?
6362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme need to clean up other thread's valgrind data?
6363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_create)
6368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_create)
6373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_create(mach_task_self(), ...)");
6375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_create);
6377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme
6379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(core_panic)("thread_create() unimplemented");
6380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_create_running)
6384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      thread_state_flavor_t flavor;
6390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t new_stateCnt;
6391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      natural_t new_state[144];
6392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req;
6396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   thread_state_t regs;
6397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *new_thread;
6398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_create_running(mach_task_self(), ...)");
6400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // The new thread will immediately begin execution,
6402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // so we need to hijack the register state here.
6403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   req = (Request *)ARG1;
6405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   regs = (thread_state_t)req->new_state;
6406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Build virtual thread.
6408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   new_thread = build_thread(regs, req->flavor, req->new_stateCnt);
6409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Edit the thread state to send to the real kernel.
6411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   hijack_thread_state(regs, req->flavor, req->new_stateCnt, new_thread);
6412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_create_running);
6414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_create_running)
6418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
6423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
6424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t child_act;
6425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
6426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assign_port_name(reply->child_act.name, "thread-%p");
6432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("%s", name_for_port(reply->child_act.name));
6433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(bsdthread_create)
6437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *tst;
6439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bsdthread_create( %#lx, %#lx, %#lx, %#lx, %#lx )",
6441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5);
6442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(pthread_t,"bsdthread_create",
6443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *,"func", void *,"func_arg", void *,"stack",
6444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 pthread_t,"thread", unsigned int,"flags");
6445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // The kernel will call V's pthread_hijack() to launch the thread.
6447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Here we allocate the thread state and pass it to pthread_hijack()
6448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // via the func_arg parameter.
6449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst = VG_(get_ThreadState)(VG_(alloc_ThreadState)());
6451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allocstack(tst->tid);
6452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.func_arg = (Addr)ARG2;
6454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ARG2 = (Word)tst;
6455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Create a semaphore that pthread_hijack will signal once it starts
6457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // POST(bsdthread_create) needs to wait for the new memory map to appear
6458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   semaphore_create(mach_task_self(), &tst->os_state.child_go,
6459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    SYNC_POLICY_FIFO, 0);
6460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   semaphore_create(mach_task_self(), &tst->os_state.child_done,
6461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    SYNC_POLICY_FIFO, 0);
6462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(bsdthread_create)
6465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Tell new thread's pthread_hijack to proceed, and wait for it to finish.
6467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // We hold V's lock on the child's behalf.
6468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // If we return before letting pthread_hijack do its thing, V thinks
6469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // the new pthread struct is still unmapped when we return to libc,
6470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // causing false errors.
6471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *tst = (ThreadState *)ARG2;
6473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   semaphore_signal(tst->os_state.child_go);
6474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   semaphore_wait(tst->os_state.child_done);
6475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   semaphore_destroy(mach_task_self(), tst->os_state.child_go);
6476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   semaphore_destroy(mach_task_self(), tst->os_state.child_done);
6477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme semaphore destroy needed when thread creation fails
6479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme probably other cleanup too
6480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme spinlocks might be good enough?
6481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // DDD: I'm not at all sure this is the right spot for this.  It probably
6483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // should be in pthread_hijack instead, just before the call to
6484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // start_thread_NORETURN(), call_on_new_stack_0_1(), but we don't have the
6485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // parent tid value there...
6486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK ( pre_thread_ll_create, tid, tst->tid );
6487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(bsdthread_terminate)
6491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState *tst;
6493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bsdthread_terminate( %#lx, %lx, %s, %s )",
6495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, name_for_port(ARG3), name_for_port(ARG4));
6496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int,"bsdthread_terminate",
6497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void *,"freeaddr", size_t,"freesize",
6498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,"kport", mach_port_t,"joinsem");
6499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Free memory and signal semaphore.
6501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme errors?
6502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG4) semaphore_signal((semaphore_t)ARG4);
6503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1  &&  ARG2) {
6504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       ML_(notify_core_and_tool_of_munmap)(ARG1, ARG2);
6505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       vm_deallocate(mach_task_self(), (vm_address_t)ARG1, (vm_size_t)ARG2);
6506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Tell V to terminate the thread.
6509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Copied from sys_exit.
6510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst = VG_(get_ThreadState)(tid);
6511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->exitreason = VgSrc_ExitThread;
6512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.exitcode = 0;  // GrP fixme anything better?
6513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Success(0);
6514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_suspend)
6518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_suspend)
6522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool self_suspend = (mh->msgh_request_port == MACH_THREAD);
6525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_suspend(%s)", name_for_port(mh->msgh_request_port));
6527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_suspend);
6529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (self_suspend) {
6531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // Don't keep the scheduler lock while self-suspending.
6532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // Otherwise we might halt while still holding the lock,
6533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // which would deadlock the process.
6534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       *flags |= SfMayBlock;
6535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // Do keep the scheduler lock while suspending any other thread.
6537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // Otherwise we might halt the other thread while it holds the lock,
6538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       // which would deadlock the process.
6539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_get_state)
6544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t old_stateCnt;
6551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      natural_t old_state[144];
6552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // mach_port_t thread = MACH_ARG(thread_get_state.thread);
6558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   thread_state_flavor_t flavor = MACH_ARG(thread_get_state.flavor);
6559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!reply->RetCode) {
6561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      thread_state_from_vex((thread_state_t)reply->old_state,
6562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             flavor, reply->old_stateCnt,
6563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             &VG_(get_ThreadState)(tid)->arch.vex);
6564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("mig return %d", reply->RetCode);
6566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_get_state)
6570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      thread_state_flavor_t flavor;
6576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_type_number_t old_stateCnt;
6577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Bool self = (req->Head.msgh_request_port == MACH_THREAD);
6582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme   if (self) {
6584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_get_state(%s, %d)",
6585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(req->Head.msgh_request_port), req->flavor);
6586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       /*} else {
6587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRINT("thread_get_state(0x%x, %d)",
6588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             req->Head.msgh_request_port, req->flavor);
6589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             }*/
6590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Hack the thread state after making the real call.
6592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(thread_get_state.thread) = req->Head.msgh_request_port;
6593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(thread_get_state.flavor) = req->flavor;
6594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_get_state);
6596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_policy)
6600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Bool self = (mh->msgh_request_port == MACH_THREAD);
6603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme   if (self) {
6605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("thread_policy(%s, ...)", name_for_port(mh->msgh_request_port));
6606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*} else {
6607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("thread_policy(thread 0x%x, ...)", mh->msgh_request_port);
6608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }*/
6609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_policy);
6611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_policy)
6614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_policy_set)
6619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_policy_set(%s, ...)", name_for_port(mh->msgh_request_port));
6623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_policy_set);
6625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_policy_set)
6628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_info)
6633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_info(%s, ...)", name_for_port(mh->msgh_request_port));
6637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme does any thread info need to be hijacked?
6638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(thread_info);
6640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(thread_info)
6643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme mark unused parts of thread_info_out as uninitialized?
6645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
6650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: messages to bootstrap port
6651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
6652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(bootstrap_register)
6655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kern_return_t RetCode;
6661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (reply->RetCode) PRINT("mig return %d", reply->RetCode);
6668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(bootstrap_register)
6671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
6676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
6677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t service_port;
6678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
6679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name_t service_name;
6681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bootstrap_register(port 0x%x, \"%s\")",
6687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         req->service_port.name, req->service_name);
6688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   assign_port_name(req->service_port.name, req->service_name);
6690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(bootstrap_register);
6692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(bootstrap_look_up)
6696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* start of the kernel processed data */
6701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_body_t msgh_body;
6702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_port_descriptor_t service_port;
6703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* end of the kernel processed data */
6704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_trailer_t trailer;
6705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Reply;
6706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Reply *reply = (Reply *)ARG1;
6709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ((reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)  &&
6711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       reply->service_port.name)
6712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
6713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       assign_port_name(reply->service_port.name,
6714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        MACH_ARG(bootstrap_look_up.service_name));
6715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRINT("%s", name_for_port(reply->service_port.name));
6716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
6717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       PRINT("not found");
6718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(arena_free)(VG_AR_CORE, MACH_ARG(bootstrap_look_up.service_name));
6720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(bootstrap_look_up)
6723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack(4)
6725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typedef struct {
6726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mach_msg_header_t Head;
6727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      NDR_record_t NDR;
6728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name_t service_name;
6729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } Request;
6730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#pragma pack()
6731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Request *req = (Request *)ARG1;
6733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bootstrap_look_up(\"%s\")", req->service_name);
6735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACH_ARG(bootstrap_look_up.service_name) =
6737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(arena_strdup)(VG_AR_CORE, "syswrap-darwin.bootstrap-name",
6738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        req->service_name);
6739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(bootstrap_look_up);
6741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
6745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: receiver-specific handlers
6746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
6747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_msg_receive)
6750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme don't know of anything interesting here currently
6754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // import_complex_message handles everything
6755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // PRINT("UNHANDLED reply %d", mh->msgh_id);
6756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Assume the call may have mapped or unmapped memory
6758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(sync_mappings)("after", "mach_msg_receive", 0);
6759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_msg_receive)
6762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_msg_receive(port %s)", name_for_port(mh->msgh_reply_port));
6766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = POST_FN(mach_msg_receive);
6768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // no message sent, only listening for a reply
6770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // assume message may block
6771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
6772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_msg_bootstrap)
6776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // message to bootstrap port
6778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (mh->msgh_id) {
6782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 403:
6783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(bootstrap_register);
6784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 404:
6786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(bootstrap_look_up);
6787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
6790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("UNHANDLED bootstrap message [id %d, to %s, reply 0x%x]\n",
6791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            mh->msgh_id, name_for_port(mh->msgh_request_port),
6792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            mh->msgh_reply_port);
6793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_msg_host)
6799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // message to host self - check for host-level kernel calls
6801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (mh->msgh_id) {
6805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 200:
6806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(host_info);
6807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 202:
6809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(host_page_size);
6810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 205:
6812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(host_get_io_master);
6813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 206:
6815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(host_get_clock_service);
6816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 217:
6818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(host_request_notification);
6819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
6822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // unknown message to host self
6823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN host message [id %d, to %s, reply 0x%x]\n",
6824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  mh->msgh_id, name_for_port(mh->msgh_request_port),
6825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  mh->msgh_reply_port);
6826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// JRS 2011-Aug-25: these magic numbers (3201 etc) come from
6831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// /usr/include/mach/mach_port.h et al (grep in /usr/include
6832b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// for them)
6833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_msg_task)
6834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
6835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // message to a task port
6836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
6838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (mh->msgh_id) {
6840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3201:
6841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_type);
6842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3204:
6844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_allocate);
6845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3205:
6847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_destroy);
6848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3206:
6850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_deallocate);
6851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3207:
6853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_get_refs);
6854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3208:
6856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_mod_refs);
6857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3211:
6859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_get_set_status);
6860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3212:
6862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_move_member);
6863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3213:
6865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_request_notification);
6866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3214:
6868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_insert_right);
6869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3215:
6871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_extract_right);
6872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3217:
6874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_get_attributes);
6875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3218:
6877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_set_attributes);
6878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3226:
6880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_insert_member);
6881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3227:
6883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_port_extract_member);
6884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 3229:
6887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      CALL_PRE(mach_port_set_context);
6888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
6889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3402:
6891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(task_threads);
6892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3404:
6894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_ports_lookup);
6895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3407:
6898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(task_suspend);
6899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3408:
6901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(task_resume);
6902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3409:
6905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(task_get_special_port);
6906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3411:
6908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_create);
6909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3412:
6911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_create_running);
6912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6913b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6914b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 3414:
6915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      CALL_PRE(task_get_exception_ports);
6916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return;
6917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3418:
6919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(semaphore_create);
6920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3419:
6922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(semaphore_destroy);
6923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3801:
6926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_allocate);
6927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3802:
6929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_deallocate);
6930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3803:
6932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_protect);
6933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3804:
6935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_inherit);
6936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3805:
6938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_read);
6939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3808:
6941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_copy);
6942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3809:
6944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_read_overwrite);
6945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3812:
6947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_map);
6948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3814:
6950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_remap);
6951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3825:
6953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_make_memory_entry_64);
6954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3830:
6956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(vm_purgable_control);
6957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4800:
6960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_allocate);
6961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4801:
6963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_deallocate);
6964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4802:
6966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_protect);
6967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4803:
6969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_inherit);
6970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4804:
6972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_read);
6973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4807:
6975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_copy);
6976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4811:
6978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_map);
6979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4815:
6981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_region_recurse);
6982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4817:
6984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_make_memory_entry_64);
6985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 4818:
6987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_vm_purgable_control);
6988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
6991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // unknown message to task self
6992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN task message [id %d, to %s, reply 0x%x]\n",
6993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  mh->msgh_id, name_for_port(mh->msgh_remote_port),
6994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  mh->msgh_reply_port);
6995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
6996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
6997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
6998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_msg_thread)
7001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // message to local thread - check for thread-level kernel calls
7003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
7005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (mh->msgh_id) {
7007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3600:
7008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_terminate);
7009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3603:
7011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_get_state);
7012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3605:
7014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_suspend);
7015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3612:
7017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_info);
7018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3616:
7020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_policy);
7021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   case 3617:
7023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(thread_policy_set);
7024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   default:
7026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // unknown message to a thread
7027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("UNKNOWN thread message [id %d, to %s, reply 0x%x]\n",
7028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  mh->msgh_id, name_for_port(mh->msgh_request_port),
7029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  mh->msgh_reply_port);
7030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int is_thread_port(mach_port_t port)
7036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (port == 0) return False;
7038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return VG_(lwpid_to_vgtid)(port) != VG_INVALID_THREADID;
7040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int is_task_port(mach_port_t port)
7044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (port == 0) return False;
7046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (port == vg_task_port) return True;
7048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return (0 == VG_(strncmp)("task-", name_for_port(port), 5));
7050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
7054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg: base handlers
7055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
7056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_msg)
7058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
7060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_option_t option = (mach_msg_option_t)ARG2;
7061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // mach_msg_size_t send_size = (mach_msg_size_t)ARG3;
7062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_size_t rcv_size = (mach_msg_size_t)ARG4;
7063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // mach_port_t rcv_name = (mach_port_t)ARG5;
7064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   size_t complex_header_size = 0;
7065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ7(long, "mach_msg",
7067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_msg_header_t*,"msg", mach_msg_option_t,"option",
7068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_msg_size_t,"send_size", mach_msg_size_t,"rcv_size",
7069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,"rcv_name", mach_msg_timeout_t,"timeout",
7070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,"notify");
7071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Assume default POST handler until specified otherwise
7073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AFTER = NULL;
7074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Assume call may block unless specified otherwise
7076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (option & MACH_SEND_MSG) {
7079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Validate outgoing message header
7080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("mach_msg(msg.msgh_bits)",
7081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (Addr)&mh->msgh_bits, sizeof(mh->msgh_bits));
7082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // msgh_size not required, use parameter instead
7083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("mach_msg(msg.msgh_remote_port)",
7084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (Addr)&mh->msgh_remote_port, sizeof(mh->msgh_remote_port));
7085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("mach_msg(msg.msgh_local_port)",
7086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (Addr)&mh->msgh_local_port, sizeof(mh->msgh_local_port));
7087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // msgh_reserved not required
7088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("mach_msg(msg.msgh_id)",
7089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (Addr)&mh->msgh_id, sizeof(mh->msgh_id));
7090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (mh->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
7092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // Validate typed message data and handle memory map changes.
7093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         complex_header_size = export_complex_message(tid, mh);
7094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
7095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme handle sender-specified message trailer
7097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // (but is this only for too-secure processes?)
7098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(! (mh->msgh_bits & MACH_SEND_TRAILER));
7099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MACH_REMOTE = mh->msgh_remote_port;
7101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      MACH_MSGH_ID = mh->msgh_id;
7102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (option & MACH_RCV_MSG) {
7105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Pre-validate receive buffer
7106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("mach_msg(receive buffer)", (Addr)mh, rcv_size);
7107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Call a PRE handler. The PRE handler may set an AFTER handler.
7110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!(option & MACH_SEND_MSG)) {
7112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // no message sent, receive only
7113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_msg_receive);
7114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else if (mh->msgh_request_port == vg_host_port) {
7117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // message sent to mach_host_self()
7118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_msg_host);
7119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else if (is_task_port(mh->msgh_request_port)) {
7122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // message sent to a task
7123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_msg_task);
7124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else if (mh->msgh_request_port == vg_bootstrap_port) {
7127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // message sent to bootstrap port
7128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_msg_bootstrap);
7129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else if (is_thread_port(mh->msgh_request_port)) {
7132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // message sent to one of this process's threads
7133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CALL_PRE(mach_msg_thread);
7134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else {
7137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // arbitrary message to arbitrary port
7138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("UNHANDLED mach_msg [id %d, to %s, reply 0x%x]",
7139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            mh->msgh_id, name_for_port(mh->msgh_request_port),
7140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            mh->msgh_reply_port);
7141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      AFTER = POST_FN(mach_msg_unhandled);
7143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Assume the entire message body may be read.
7145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // GrP fixme generates false positives for unknown protocols
7146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*
7147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("mach_msg(payload)",
7148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (Addr)((char*)mh + sizeof(mach_msg_header_t) + complex_header_size),
7149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   send_size - sizeof(mach_msg_header_t) - complex_header_size);
7150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
7151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_msg)
7156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_header_t *mh = (mach_msg_header_t *)ARG1;
7158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_msg_option_t option = (mach_msg_option_t)ARG2;
7159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (option & MACH_RCV_MSG) {
7161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (RES != 0) {
7162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // error during send or receive
7163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme need to clean up port rights?
7164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
7165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         mach_msg_trailer_t *mt =
7166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             (mach_msg_trailer_t *)((Addr)mh + round_msg(mh->msgh_size));
7167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // Assume the entire received message and trailer is initialized
7169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         // GrP fixme would being more specific catch any bugs?
7170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE((Addr)mh,
7171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        round_msg(mh->msgh_size) + mt->msgh_trailer_size);
7172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (mh->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
7174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             // Update memory map for out-of-line message data
7175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             import_complex_message(tid, mh);
7176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
7177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
7178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Call handler chosen by PRE(mach_msg)
7181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (AFTER) {
7182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (*AFTER)(tid, arrghs, status);
7183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_msg_unhandled)
7188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(sync_mappings)("after", "mach_msg_receive (unhandled)", 0);
7190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
7194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   other Mach traps
7195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
7196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_reply_port)
7198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_reply_port()");
7200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_reply_port)
7203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, RES, MACH_PORT_RIGHT_RECEIVE, "reply-%p");
7205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("reply port %s", name_for_port(RES));
7206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_thread_self)
7210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_thread_self()");
7212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_thread_self)
7215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "thread-%p");
7217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread %#lx", RES);
7218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_host_self)
7222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_host_self()");
7224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_host_self)
7227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_host_port = RES;
7229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "mach_host_self()");
7230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("host %#lx", RES);
7231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_task_self)
7235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_task_self()");
7237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_task_self)
7240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_task_port = RES;
7242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "mach_task_self()");
7243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("task %#lx", RES);
7244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(syscall_thread_switch)
7248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("syscall_thread_switch(%s, %ld, %ld)",
7250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      name_for_port(ARG1), ARG2, ARG3);
7251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "syscall_thread_switch",
7252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,"thread", int,"option", natural_t,"timeout");
7253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_signal)
7259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_signal(%s)", name_for_port(ARG1));
7261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "semaphore_signal", semaphore_t,"semaphore");
7262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_signal_all)
7266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_signal_all(%s)", name_for_port(ARG1));
7268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "semaphore_signal_all", semaphore_t,"semaphore");
7269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_signal_thread)
7273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_signal_thread(%s, %s)",
7275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(ARG1), name_for_port(ARG2));
7276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "semaphore_signal_thread",
7277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 semaphore_t,"semaphore", mach_port_t,"thread");
7278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_wait)
7282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_wait(%s)", name_for_port(ARG1));
7284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "semaphore_signal", semaphore_t,"semaphore");
7285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_wait_signal)
7291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_wait_signal(%s, %s)",
7293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(ARG1), name_for_port(ARG2));
7294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "semaphore_wait_signal",
7295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 semaphore_t,"wait_semaphore",
7296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 semaphore_t,"signal_semaphore");
7297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_timedwait)
7303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_timedwait(%s, %g seconds)",
7305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(ARG1), ARG2+ARG3/1000000000.0);
7306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "semaphore_wait_signal",
7307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 semaphore_t,"semaphore",
7308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"wait_time_hi",
7309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"wait_time_lo");
7310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(semaphore_timedwait_signal)
7316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("semaphore_wait_signal(wait %s, signal %s, %g seconds)",
7318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(ARG1), name_for_port(ARG2), ARG3+ARG4/1000000000.0);
7319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(long, "semaphore_wait_signal",
7320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 semaphore_t,"wait_semaphore",
7321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 semaphore_t,"signal_semaphore",
7322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"wait_time_hi",
7323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"wait_time_lo");
7324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__semwait_signal)
7330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* 10.5 args: int cond_sem, int mutex_sem,
7332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int timeout, int relative,
7333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 time_t tv_sec, time_t tv_nsec */
7334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__semwait_signal(wait %s, signal %s, %ld, %ld, %lds:%ldns)",
7335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(ARG1), name_for_port(ARG2), ARG3, ARG4, ARG5, ARG6);
7336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(long, "__semwait_signal",
7337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"cond_sem", int,"mutex_sem",
7338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"timeout", int,"relative",
7339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_time_t,"tv_sec", int,"tv_nsec");
7340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// GrP provided this alternative version for 10.6, but NjN
7344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// reckons the 10.5 is is still correct for 10.6.  So, retaining
7345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Greg's version as a comment just in case we need it later.
7346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//PRE(__semwait_signal)
7347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//{
7348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   /* 10.5 args: int cond_sem, int mutex_sem,
7349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                 int timeout, int relative,
7350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                 const timespec *ts */
7351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   PRINT("__semwait_signal(wait %s, signal %s, %ld, %ld, %#lx)",
7352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//         name_for_port(ARG1), name_for_port(ARG2), ARG3, ARG4, ARG5);
7353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   PRE_REG_READ5(int, "__semwait_signal",
7354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                 int,cond_sem, int,mutex_sem,
7355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                 int,timeout, int,relative,
7356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                 const struct vki_timespec *,ts);
7357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
7358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   if (ARG5) PRE_MEM_READ ("__semwait_signal(ts)",
7359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//                           ARG5, sizeof(struct vki_timespec));
7360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//
7361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   *flags |= SfMayBlock;
7362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//}
7363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(__thread_selfid)
7366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__thread_selfid ()");
7368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(vki_uint64_t, "__thread_selfid");
7369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(task_for_pid)
7372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("task_for_pid(%s, %ld, %#lx)", name_for_port(ARG1), ARG2, ARG3);
7374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "task_for_pid",
7375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,"target",
7376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_pid_t, "pid", mach_port_t *,"task");
7377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("task_for_pid(task)", ARG3, sizeof(mach_port_t));
7378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(task_for_pid)
7381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   mach_port_t task;
7383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG3, sizeof(mach_port_t));
7385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   task = *(mach_port_t *)ARG3;
7387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, task, MACH_PORT_RIGHT_SEND, "task-%p");
7388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("task 0x%x", task);
7389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(pid_for_task)
7393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("pid_for_task(%s, %#lx)", name_for_port(ARG1), ARG2);
7395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "task_for_pid", mach_port_t,"task", vki_pid_t *,"pid");
7396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("task_for_pid(pid)", ARG2, sizeof(vki_pid_t));
7397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(pid_for_task)
7400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vki_pid_t pid;
7402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG2, sizeof(vki_pid_t));
7404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pid = *(vki_pid_t *)ARG2;
7406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("pid %u", pid);
7407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_timebase_info)
7411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_timebase_info(%#lx)", ARG1);
7413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "mach_timebase_info", void *,"info");
7414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("mach_timebase_info(info)", ARG1, sizeof(struct vki_mach_timebase_info));
7415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mach_timebase_info)
7418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, sizeof(struct vki_mach_timebase_info));
7420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mach_wait_until)
7424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 8
7426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_wait_until(%lu)", ARG1);
7427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "mach_wait_until",
7428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned long long,"deadline");
7429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
7430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mach_wait_until(%llu)", LOHI64(ARG1, ARG2));
7431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "mach_wait_until",
7432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"deadline_hi", int,"deadline_lo");
7433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
7434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mk_timer_create)
7439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mk_timer_create()");
7441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(long, "mk_timer_create");
7442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mk_timer_create)
7445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "mk_timer-%p");
7447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mk_timer_destroy)
7451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mk_timer_destroy(%s)", name_for_port(ARG1));
7453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "mk_timer_destroy", mach_port_t,"name");
7454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must block to prevent race (other thread allocates and
7456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // notifies after we deallocate but before we notify)
7457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
7458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mk_timer_destroy)
7461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Must have cleared SfMayBlock in PRE to prevent race
7463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   record_port_destroy(ARG1);
7464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mk_timer_arm)
7468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 8
7470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mk_timer_arm(%s, %lu)", name_for_port(ARG1), ARG2);
7471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "mk_timer_arm", mach_port_t,"name",
7472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned long,"expire_time");
7473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
7474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mk_timer_arm(%s, %llu)", name_for_port(ARG1), LOHI64(ARG2, ARG3));
7475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "mk_timer_arm", mach_port_t,"name",
7476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int,"expire_time_hi", int,"expire_time_lo");
7477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
7478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(mk_timer_cancel)
7482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mk_timer_cancel(%s, %#lx)", name_for_port(ARG1), ARG2);
7484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "mk_timer_cancel",
7485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,"name", Addr,"result_time");
7486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2) {
7487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("mk_timer_cancel(result_time)", ARG2,sizeof(vki_uint64_t));
7488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(mk_timer_cancel)
7492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2) {
7494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG2, sizeof(vki_uint64_t));
7495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(iokit_user_client_trap)
7500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("iokit_user_client_trap(%s, %ld, %lx, %lx, %lx, %lx, %lx, %lx)",
7502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         name_for_port(ARG1), ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8);
7503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ8(kern_return_t, "iokit_user_client_trap",
7504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 mach_port_t,connect, unsigned int,index,
7505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 uintptr_t,p1, uintptr_t,p2, uintptr_t,p3,
7506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 uintptr_t,p4, uintptr_t,p5, uintptr_t,p6);
7507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // can't do anything else with this in general
7509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // might be able to use connect+index to choose something sometimes
7510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(iokit_user_client_trap)
7513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(sync_mappings)("after", "iokit_user_client_trap", ARG2);
7515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(swtch)
7519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("swtch ( )");
7521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(long, "swtch");
7522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(swtch_pri)
7528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("swtch_pri ( %ld )", ARG1);
7530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "swtch_pri", int,"pri");
7531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
7533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(FAKE_SIGRETURN)
7537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
7539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      an explanation of what follows. */
7540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* This handles the fake signal-return system call created by
7541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sigframe-x86-darwin.c. */
7542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* See also comments just below on PRE(sigreturn). */
7543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("FAKE_SIGRETURN ( )");
7545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_valid_tid)(tid));
7547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(tid >= 1 && tid < VG_N_THREADS);
7548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_running_thread)(tid));
7549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Remove the signal frame from this thread's (guest) stack,
7551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in the process restoring the pre-signal guest state. */
7552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sigframe_destroy)(tid, True);
7553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Tell the driver not to update the guest state with the "result",
7555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      and set a bogus result to keep it happy. */
7556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfNoWriteResult;
7557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Success(0);
7558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check to see if any signals arose as a result of this. */
7560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfPollAfter;
7561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sigreturn)
7565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* This is the "real" sigreturn.  But because we construct all the
7567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      signal frames ourselves (of course, in m_sigframe), this cannot
7568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      happen as a result of normal signal delivery.  I think it
7569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      happens only when doing siglongjmp, in which case Darwin's Libc
7570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      appears to use it for two different purposes: to mess with the
7571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      per-thread sigaltstack flags (as per arg 2), or to restore the
7572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      thread's state from a ucontext* (as per arg 1). */
7573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sigreturn ( uctx=%#lx, infostyle=%#lx )", ARG1, ARG2);
7575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_valid_tid)(tid));
7577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(tid >= 1 && tid < VG_N_THREADS);
7578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_running_thread)(tid));
7579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 == VKI_UC_SET_ALT_STACK) {
7581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This is confusing .. the darwin kernel sources imply there is
7582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         a per-thread on-altstack/not-on-altstack flag, which is set
7583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         by this flag.  Just ignore it and claim success for the time
7584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         being. */
7585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(debugLog)(0, "syswrap-darwin",
7586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       "WARNING: Ignoring sigreturn( ..., "
7587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       "UC_SET_ALT_STACK );\n");
7588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Success(0);
7589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 == VKI_UC_RESET_ALT_STACK) {
7592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Ditto */
7593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(debugLog)(0, "syswrap-darwin",
7594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       "WARNING: Ignoring sigreturn( ..., "
7595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       "UC_RESET_ALT_STACK );\n");
7596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Success(0);
7597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
7598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Otherwise claim this isn't supported.  (Could be
7601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      catastrophic).
7602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      What do we have to do if we do need to support it?
7604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      1. Change the second argument of VG_(sigframe_destroy) from
7606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "Bool isRT" to "UInt sysno", so we can pass the syscall
7607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         number, so it can distinguish this case from the
7608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         __NR_DARWIN_FAKE_SIGRETURN case.
7609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      2. In VG_(sigframe_destroy), look at sysno to distinguish the
7611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cases.  For __NR_DARWIN_FAKE_SIGRETURN, behave as at present.
7612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         For this case, restore the thread's CPU state (or at least
7613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the integer regs) from the ucontext in ARG1 (and do all the
7614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         other "signal-returns" stuff too).
7615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      3. For (2), how do we know where the ucontext is?  One way is to
7617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         temporarily copy ARG1 into this thread's guest_EBX (or any
7618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         other int reg), and have VG_(sigframe_destroy) read
7619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         guest_EBX.  Why is it ok to trash guest_EBX (or any other int
7620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         reg)?  Because VG_(sigframe_destroy) is just about to
7621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         overwrite all the regs anyway -- since the primary purpose of
7622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         calling it is to restore the register state from the ucontext
7623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         pointed to by ARG1.
7624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Hey, it's uggerly.  But at least it's documented.
7626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
7627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* But in the meantime ... */
7628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(0, "syswrap-darwin",
7629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "WARNING: Ignoring sigreturn( uctx=..., 0 );\n");
7630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(0, "syswrap-darwin",
7631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "WARNING: Thread/program/Valgrind "
7632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "will likely segfault now.\n");
7633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(0, "syswrap-darwin",
7634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "WARNING: Please file a bug report at "
7635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "http://www.valgrind.org.\n");
7636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Failure( VKI_ENOSYS );
7637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
7641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   machine-dependent traps
7642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
7643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86)
7645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic VexGuestX86SegDescr* alloc_zeroed_x86_LDT ( void )
7646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int nbytes = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
7648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return VG_(arena_calloc)(VG_AR_CORE, "syswrap-darwin.ldt", nbytes, 1);
7649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
7651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(thread_fast_set_cthread_self)
7653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
7654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_fast_set_cthread_self ( %#lx )", ARG1);
7655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "thread_fast_set_cthread_self", struct pthread_t *, self);
7656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86)
7658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Point the USER_CTHREAD ldt entry (slot 6, reg 0x37) at this pthread
7659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
7660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VexGuestX86SegDescr *ldt;
7661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ThreadState *tst = VG_(get_ThreadState)(tid);
7662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt = (VexGuestX86SegDescr *)tst->arch.vex.guest_LDT;
7663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!ldt) {
7664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ldt = alloc_zeroed_x86_LDT();
7665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tst->arch.vex.guest_LDT = (HWord)ldt;
7666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
7667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&ldt[6], 0, sizeof(ldt[6]));
7668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.LimitLow = 1;
7669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.LimitHi = 0;
7670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.BaseLow = ARG1 & 0xffff;
7671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.BaseMid = (ARG1 >> 16) & 0xff;
7672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.BaseHi = (ARG1 >> 24) & 0xff;
7673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.Pres = 1; // ACC_P
7674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.Dpl = 3; // ACC_PL_U
7675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.Type = 0x12; // ACC_DATA_W
7676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.Granularity = 1;  // SZ_G
7677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ldt[6].LdtEnt.Bits.Default_Big = 1;  // SZ_32
7678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->os_state.pthread = ARG1;
7680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->arch.vex.guest_GS = 0x37;
7681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // What we would like to do is:
7683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //   SET_STATUS_Success(0x37);
7684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // but that doesn't work, because this is a MDEP-class syscall,
7685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // and SET_STATUS_Success creates a UNIX-class syscall result.
7686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Hence we have to laboriously construct the full SysRes "by hand"
7687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // and use that to set the syscall return status.
7688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_from_SysRes(
7689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(mk_SysRes_x86_darwin)(
7690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_DARWIN_SYSNO_CLASS(__NR_thread_fast_set_cthread_self),
7691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            False, 0, 0x37
7692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         )
7693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );
7694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_amd64)
7697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme bigger hack than x86
7698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
7699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ThreadState *tst = VG_(get_ThreadState)(tid);
7700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->os_state.pthread = ARG1;
7701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->arch.vex.guest_GS_0x60 = ARG1;
7702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // SET_STATUS_Success(0x60);
7703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // see comments on x86 case just above
7704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_from_SysRes(
7705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(mk_SysRes_amd64_darwin)(
7706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_DARWIN_SYSNO_CLASS(__NR_thread_fast_set_cthread_self),
7707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            False, 0, 0x60
7708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         )
7709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );
7710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
7711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
7713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#error unknown architecture
7714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
7715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
7716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
7719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Added for OSX 10.7 (Lion)
7720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ------------------------------------------------------------------ */
7721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(getaudit_addr)
7723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("getaudit_addr(%#lx, %lu)", ARG1, ARG2);
7725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRE_REG_READ1(void*, "auditinfo_addr", int, "length");
7726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRE_MEM_WRITE("getaudit_addr(auditinfo_addr)", ARG1, ARG2);
7727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(getaudit_addr)
7729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   POST_MEM_WRITE(ARG1, ARG2);
7731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_mutexwait)
7734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_mutexwait(BOGUS)");
7736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *flags |= SfMayBlock;
7737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_mutexwait)
7739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_mutexdrop)
7743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_mutexdrop(BOGUS)");
7745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *flags |= SfMayBlock;
7746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_mutexdrop)
7748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_cvbroad)
7752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_cvbroad(BOGUS)");
7754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_cvbroad)
7756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_cvsignal)
7760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_cvsignal(BOGUS)");
7762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_cvsignal)
7764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_cvwait)
7768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_cvwait(BOGUS)");
7770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *flags |= SfMayBlock;
7771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_cvwait)
7773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_rw_rdlock)
7777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_rw_rdlock(BOGUS)");
7779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *flags |= SfMayBlock;
7780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_rw_rdlock)
7782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_rw_wrlock)
7786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_rw_wrlock(BOGUS)");
7788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *flags |= SfMayBlock;
7789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_rw_wrlock)
7791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_rw_unlock)
7795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_rw_unlock(BOGUS)");
7797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_rw_unlock)
7799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPRE(psynch_cvclrprepost)
7803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   PRINT("psynch_cvclrprepost(BOGUS)");
7805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *flags |= SfMayBlock;
7806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovPOST(psynch_cvclrprepost)
7808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
7809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
7810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ---------------------------------------------------------------------
7813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   syscall tables
7814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
7815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a Darwin-specific, arch-independent wrapper to a syscall table. */
7817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MACX_(sysno, name)    WRAPPER_ENTRY_X_(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name)
7818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MACXY(sysno, name)    WRAPPER_ENTRY_XY(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name)
7819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define _____(sysno) GENX_(sysno, sys_ni_syscall)
7820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     _____ : unsupported by the kernel (sys_ni_syscall)
7823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // _____ : unimplemented in valgrind
7824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     GEN   : handlers are in syswrap-generic.c
7825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     MAC   : handlers are in this file
7826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        X_ : PRE handler only
7827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        XY : PRE and POST handlers
7828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
7829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst SyscallTableEntry ML_(syscall_table)[] = {
7830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_syscall),   // 0
7831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_exit,        exit),
7832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_fork,        sys_fork),
7833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_read,        sys_read),
7834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_write,       sys_write),
7835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_open,        sys_open),
7836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_close,       sys_close),
7837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_wait4,       sys_wait4),
7838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(8)),     // old creat
7839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_link,        sys_link),
7840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_unlink,      sys_unlink),
7841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(11)),    // old execv
7842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_chdir,       sys_chdir),
7843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_fchdir,      sys_fchdir),
7844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_mknod,       sys_mknod),
7845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_chmod,       sys_chmod),
7846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_chown,       sys_chown),
7847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(17)),    // old break
7848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getfsstat,   getfsstat),
7849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(19)),    // old lseek
7850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getpid,      sys_getpid),     // 20
7851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(21)),    // old mount
7852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(22)),    // old umount
7853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_setuid,      sys_setuid),
7854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getuid,      sys_getuid),
7855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_geteuid,     sys_geteuid),
7856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_ptrace,      ptrace),
7857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_recvmsg,     recvmsg),
7858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sendmsg,     sendmsg),
7859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_recvfrom,    recvfrom),
7860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_accept,      accept),
7861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getpeername, getpeername),
7862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getsockname, getsockname),
7863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_access,      sys_access),
7864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_chflags,     chflags),
7865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_fchflags,    fchflags),
7866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_sync,        sys_sync),
7867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_kill,        sys_kill),
7868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(38)),    // old stat
7869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getppid,     sys_getppid),
7870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(40)),    // old lstat
7871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_dup,         sys_dup),
7872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_pipe,        pipe),
7873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getegid,     sys_getegid),
7874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_profil),
7875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(45)),    // old ktrace
7876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_sigaction,   sigaction),
7877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getgid,      sys_getgid),
7878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_sigprocmask, sigprocmask),
7879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getlogin,    getlogin),
7880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setlogin),
7881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_acct),
7882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_sigpending,  sigpending),
7883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_sigaltstack, sys_sigaltstack),
7884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_ioctl,       ioctl),
7885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_reboot),
7886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_revoke),
7887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_symlink,     sys_symlink),   // 57
7888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_readlink,    sys_readlink),
7889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_execve,      sys_execve),
7890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_umask,       sys_umask),     // 60
7891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_chroot,      sys_chroot),
7892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(62)),    // old fstat
7893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(63)),    // used internally, reserved
7894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(64)),    // old getpagesize
7895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_msync,       sys_msync),
7896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_vfork,       sys_fork),              // (We treat vfork as fork.)
7897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(67)),    // old vread
7898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(68)),    // old vwrite
7899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(69)),    // old sbrk
7900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(70)),    // old sstk
7901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(71)),    // old mmap
7902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(72)),    // old vadvise
7903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_munmap,      sys_munmap),
7904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_mprotect,    sys_mprotect),
7905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_madvise,     sys_madvise),
7906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(76)),    // old vhangup
7907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(77)),    // old vlimit
7908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_mincore,     sys_mincore),
7909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_getgroups,   sys_getgroups),
7910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setgroups),   // 80
7911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getpgrp,     sys_getpgrp),
7912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_setpgid,     sys_setpgid),
7913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_setitimer,   sys_setitimer),
7914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(84)),    // old wait
7915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_swapon),
7916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_getitimer,   sys_getitimer),
7917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(87)),    // old gethostname
7918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(88)),    // old sethostname
7919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getdtablesize, getdtablesize),
7920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_dup2,        sys_dup2),
7921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(91)),    // old getdopt
7922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fcntl,       fcntl),
7923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_select,      sys_select),
7924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(94)),    // old setdopt
7925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_fsync,       sys_fsync),
7926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_setpriority, sys_setpriority),
7927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_socket,      socket),
7928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_connect,     connect),
7929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(99)),    // old accept
7930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_getpriority, sys_getpriority),   // 100
7931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(101)),   // old send
7932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(102)),   // old recv
7933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(103)),   // old sigreturn
7934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_bind,        bind),
7935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_setsockopt,  setsockopt),
7936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_listen,      listen),
7937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(107)),   // old vtimes
7938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(108)),   // old sigvec
7939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(109)),   // old sigblock
7940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(110)),   // old sigsetmask
7941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sigsuspend,  sigsuspend),            // old sigsuspend
7942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(112)),   // old sigstack
7943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(113)),   // old recvmsg
7944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(114)),   // old sendmsg
7945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(115)),   // old vtrace
7946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_gettimeofday, sys_gettimeofday),
7947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_getrusage,   sys_getrusage),
7948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getsockopt,  getsockopt),
7949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(119)),   // old resuba
7950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_readv,       sys_readv),        // 120
7951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_writev,      sys_writev),
7952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_settimeofday),
7953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_fchown,      sys_fchown),
7954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_fchmod,      sys_fchmod),
7955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(125)),   // old recvfrom
7956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setreuid),
7957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setregid),
7958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_rename,      sys_rename),
7959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(129)),   // old truncate
7960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(130)),   // old ftruncate
7961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_flock,       sys_flock),
7962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_mkfifo),
7963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sendto,      sendto),
7964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_shutdown,    shutdown),
7965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_socketpair,  socketpair),
7966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_mkdir,       sys_mkdir),
7967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_rmdir,       sys_rmdir),
7968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_utimes,      sys_utimes),
7969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_futimes,     futimes),
7970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_adjtime),     // 140
7971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(141)),   // old getpeername
7972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_gethostuuid, gethostuuid),
7973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(143)),   // old sethostid
7974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(144)),   // old getrlimit
7975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(145)),   // old setrlimit
7976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(146)),   // old killpg
7977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_setsid,      sys_setsid),
7978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(148)),   // old setquota
7979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(149)),   // old qquota
7980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(150)),   // old getsockname
7981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getpgid),
7982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setprivexec),
7983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_pread,       sys_pread64),
7984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_pwrite,      sys_pwrite64),
7985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_nfssvc),
7986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(156)),   // old getdirentries
7987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_statfs,      sys_statfs),
7988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_fstatfs,     sys_fstatfs),
7989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_unmount),
7990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(160)),   // old async_daemon
7991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getfh),
7992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(162)),   // old getdomainname
7993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(163)),   // old setdomainname
7994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(164)),   // ???
7995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_quotactl),
7996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(166)),   // old exportfs
7997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_mount,       mount),
7998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(168)),   // old ustat
7999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_csops,       csops),                 // code-signing ops
8000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(170)),   // old table
8001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(171)),   // old wait3
8002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(172)),   // old rpause
8003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_waitid),
8004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(174)),   // old getdents
8005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(175)),   // old gc_control
8006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_add_profil),
8007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(177)),   // ???
8008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(178)),   // ???
8009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(179)),   // ???
8010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_kdebug_trace, kdebug_trace),     // 180
8011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_setgid,      sys_setgid),
8012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_setegid,     setegid),
8013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_seteuid,     seteuid),
8014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sigreturn,   sigreturn),
8015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_chud),
8016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(186)),   // ???
8017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_fdatasync),
8019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(187)),   // ???
8021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_stat,        sys_newstat),
8023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_fstat,       sys_newfstat),
8024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_lstat,       sys_newlstat),
8025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_pathconf,    pathconf),
8026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_fpathconf,   fpathconf),
8027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(193)),   // ???
8028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_getrlimit,   sys_getrlimit),
8029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_setrlimit,   sys_setrlimit),
8030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getdirentries, getdirentries),
8031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mmap,        mmap),
8032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(198)),   // __syscall
8033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_lseek,       lseek),
8034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_truncate,    sys_truncate64),   // 200
8035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_ftruncate,   sys_ftruncate64),
8036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR___sysctl,    __sysctl),
8037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_mlock,       sys_mlock),
8038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_munlock,     sys_munlock),
8039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_undelete),
8040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATsocket),
8041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATgetmsg),
8042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATputmsg),
8043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATPsndreq),
8044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATPsndrsp),
8045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATPgetreq),
8046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ATPgetrsp),
8047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(213)),   // Reserved for AppleTalk
8048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214)),   // old kqueue_from_portset_np
8050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215)),   // old kqueue_portset_np
8051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_kqueue_from_portset_np),
8053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_kqueue_portset_np),
8054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_mkcomplex),
8056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_statv),
8057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_lstatv),
8058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_fstatv),
8059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getattrlist, getattrlist),   // 220
8060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_setattrlist, setattrlist),
8061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getdirentriesattr, getdirentriesattr),
8062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_exchangedata,      exchangedata),
8063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(224)),   // checkuseraccess
8064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_searchfs),
8065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_delete,      sys_unlink),
8066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_copyfile),
8067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_fgetattrlist),
8069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_fsetattrlist),
8070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(228)),   // ??
8072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(229)),   // ??
8073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_poll,        sys_poll),
8075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_watchevent,  watchevent),
8076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_waitevent,   waitevent),
8077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_modwatch,    modwatch),
8078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getxattr,    getxattr),
8079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fgetxattr,   fgetxattr),
8080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_setxattr,    setxattr),
8081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_fsetxattr,   fsetxattr),
8082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_removexattr, removexattr),
8083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_fremovexattr, fremovexattr),
8084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_listxattr,   listxattr),    // 240
8085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_flistxattr,  flistxattr),
8086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fsctl,       fsctl),
8087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_initgroups,  initgroups),
8088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_posix_spawn, posix_spawn),
8089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_ffsctl),
8091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(245)),   // ???
8093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(246)),   // ???
8095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_nfsclnt),
8096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_fhopen),
8097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(249)),   // ???
8098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_minherit),
8099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_semsys),
8100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgsys),
8101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_shmsys),
8102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_semctl,      semctl),
8103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semget,      semget),
8104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semop,       semop),
8105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(257)),   // ???
8106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgctl),
8107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgget),
8108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgsnd),   // 260
8109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgrcv),
8110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_shmat,       shmat),
8111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_shmctl,      shmctl),
8112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_shmdt,       shmdt),
8113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_shmget,      shmget),
8114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_shm_open,    shm_open),
8115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_shm_unlink),
8116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_open,    sem_open),
8117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_close,   sem_close),
8118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_unlink,  sem_unlink),
8119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_wait,    sem_wait),
8120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_trywait, sem_trywait),
8121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_post,    sem_post),
8122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_sem_getvalue),
8123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_sem_init,    sem_init),
8124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_destroy, sem_destroy),
8125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_open_extended,  open_extended),    // 277
8126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_umask_extended),
8127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_stat_extended,  stat_extended),
8128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_lstat_extended, lstat_extended),   // 280
8129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fstat_extended, fstat_extended),
8130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_chmod_extended, chmod_extended),
8131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_fchmod_extended,fchmod_extended),
8132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_access_extended,access_extended),
8133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_settid,         settid),
8134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_gettid),
8135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setsgroups),
8136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getsgroups),
8137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setwgroups),
8138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getwgroups),
8139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_mkfifo_extended),
8140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_mkdir_extended),
8141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_identitysvc),
8142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_shared_region_check_np),
8143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_shared_region_map_np),
8144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_vm_pressure_monitor),
8146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(296)),   // old load_shared_file
8148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(297)),   // old reset_shared_file
8150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(298)),   // old new_system_shared_regions
8151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(299)),   // old shared_region_map_file_np
8152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(300)),   // old shared_region_make_private_np
8153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_mutexwait, psynch_mutexwait), // 301
8154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_mutexdrop, psynch_mutexdrop), // 302
8155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_cvbroad,   psynch_cvbroad),   // 303
8156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_cvsignal,  psynch_cvsignal),  // 304
8157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_cvwait,    psynch_cvwait),    // 305
8158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_rw_rdlock, psynch_rw_rdlock), // 306
8159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_rw_wrlock, psynch_rw_wrlock), // 307
8160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_rw_unlock, psynch_rw_unlock), // 308
8161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(309)),   // ???
8162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getsid),
8163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_settid_with_pid),
8164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_psynch_cvclrprepost, psynch_cvclrprepost), // 312
8165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_aio_fsync),
8166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_aio_return,     aio_return),
8167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_aio_suspend,    aio_suspend),
8168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_aio_cancel),
8169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_aio_error,      aio_error),
8170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_aio_read,       aio_read),
8171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_aio_write,      aio_write),
8172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_lio_listio),   // 320
8173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(321)),   // ???
8174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_iopolicysys),
8175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(323)),   // ???
8176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_mlockall),
8177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_munlockall),
8178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(326)),   // ???
8179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_issetugid,               issetugid),
8180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___pthread_kill,          __pthread_kill),
8181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___pthread_sigmask,       __pthread_sigmask),
8182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___sigwait),
8183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___disable_threadsignal,  __disable_threadsignal),
8184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___pthread_markcancel,    __pthread_markcancel),
8185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___pthread_canceled,      __pthread_canceled),
8186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___semwait_signal,        __semwait_signal),
8187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(335)),   // old utrace
8188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_proc_info,               proc_info),  // 336
8190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_sendfile,    sendfile),
8192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_stat64,      stat64),
8193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fstat64,     fstat64),
8194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_lstat64,     lstat64),    // 340
8195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_stat64_extended,  stat64_extended),
8196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_lstat64_extended, lstat64_extended),
8197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fstat64_extended, fstat64_extended),
8198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getdirentries64, getdirentries64),
8199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_statfs64,    statfs64),
8200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fstatfs64,   fstatfs64),
8201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_getfsstat64, getfsstat64),
8202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___pthread_chdir),
8203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___pthread_fchdir),
8204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_audit),
8205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_auditon,     auditon),
8206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(352)),   // ???
8207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getauid),
8208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setauid),
8209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getaudit),
8210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setaudit),
8211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if DARWIN_VERS >= DARWIN_10_7
8212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MACXY(__NR_getaudit_addr, getaudit_addr),
8213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
8214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setaudit_addr),
8215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_auditctl),
8216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_bsdthread_create,     bsdthread_create),   // 360
8217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_bsdthread_terminate,  bsdthread_terminate),
8218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_kqueue,      kqueue),
8219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_kevent,      kevent),
8220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_lchown,      sys_lchown),
8221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_stack_snapshot),
8222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_bsdthread_register, bsdthread_register),
8223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_workq_open,  workq_open),
8224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_workq_ops,   workq_ops),
8225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_kevent64),
8227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(369)),   // ???
8229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(370)),   // ???
8231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(371)),   // ???
8232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___thread_selfid, __thread_selfid),
8234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(372)),   // ???
8236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(373)),   // ???
8238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(374)),   // ???
8239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(375)),   // ???
8240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(376)),   // ???
8241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(377)),   // ???
8242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(378)),   // ???
8243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(379)),   // ???
8244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_execve),   // 380
8245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___mac_syscall, __mac_syscall),
8246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_file),
8247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_set_file),
8248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_link),
8249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_set_link),
8250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_proc),
8251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_set_proc),
8252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_fd),
8253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_set_fd),
8254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_pid),
8255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_lcid),
8256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_lctx),
8257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_set_lctx),
8258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_setlcid),
8259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_getlcid),
8260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // GrP fixme need any special nocancel handling?
8261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_read_nocancel,     sys_read),
8262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_write_nocancel,    sys_write),
8263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_open_nocancel,     sys_open),
8264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_close_nocancel,    sys_close),
8265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_wait4_nocancel,    sys_wait4),   // 400
8266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_recvmsg_nocancel,  recvmsg),
8267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sendmsg_nocancel,  sendmsg),
8268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_recvfrom_nocancel, recvfrom),
8269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_accept_nocancel,   accept),
8270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_msync_nocancel,    sys_msync),
8271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fcntl_nocancel,    fcntl),
8272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_select_nocancel,   sys_select),
8273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_fsync_nocancel,    sys_fsync),
8274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_connect_nocancel,  connect),
8275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_sigsuspend_nocancel),
8276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_readv_nocancel,    sys_readv),
8277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_writev_nocancel,   sys_writev),
8278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sendto_nocancel,   sendto),
8279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_pread_nocancel,    sys_pread64),
8280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENX_(__NR_pwrite_nocancel,   sys_pwrite64),
8281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_waitid_nocancel),
8282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GENXY(__NR_poll_nocancel,     sys_poll),
8283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgsnd_nocancel),
8284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_msgrcv_nocancel),
8285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_sem_wait_nocancel, sem_wait), // 420
8286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_aio_suspend_nocancel),
8287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___sigwait_nocancel),
8288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR___semwait_signal_nocancel, __semwait_signal),
8289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_mount),
8290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_get_mount),
8291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR___mac_getfsstat),
8292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if DARWIN_VERS >= DARWIN_10_6
8293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_fsgetpath, fsgetpath),
8294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_audit_session_self, audit_session_self),
8295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_audit_session_join),
8296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_MAXSYSCALL)
8299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_DARWIN_FAKE_SIGRETURN, FAKE_SIGRETURN)
8300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
8301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Mach traps use negative syscall numbers.
8304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Use ML_(mach_trap_table)[-mach_trap_number] .
8305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst SyscallTableEntry ML_(mach_trap_table)[] = {
8307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(0)),
8308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(1)),
8309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(2)),
8310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(3)),
8311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(4)),
8312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(5)),
8313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(6)),
8314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(7)),
8315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(8)),
8316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(9)),
8317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10)),
8318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11)),
8319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12)),
8320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(13)),
8321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14)),
8322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(15)),
8323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16)),
8324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17)),
8325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18)),
8326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19)),
8327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20)),   // -20
8328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21)),
8329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(22)),
8330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(23)),
8331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24)),
8332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(25)),
8333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mach_reply_port, mach_reply_port),
8334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_thread_self_trap, mach_thread_self),
8335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_task_self_trap, mach_task_self),
8336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_host_self_trap, mach_host_self),
8337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(30)),
8338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mach_msg_trap, mach_msg),
8339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_mach_msg_overwrite_trap),
8340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_signal_trap, semaphore_signal),
8341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_signal_all_trap, semaphore_signal_all),
8342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_signal_thread_trap, semaphore_signal_thread),
8343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_wait_trap, semaphore_wait),
8344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_wait_signal_trap, semaphore_wait_signal),
8345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_timedwait_trap, semaphore_timedwait),
8346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_semaphore_timedwait_signal_trap, semaphore_timedwait_signal),
8347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(40)),    // -40
8348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86)
8349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_init_process),
8350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(42)),
8351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_map_fd),
8352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(41)),
8354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(42)),
8355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(43)),
8356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_task_name_for_pid),
8358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_task_for_pid, task_for_pid),
8359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_pid_for_task, pid_for_task),
8360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(47)),
8361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86)
8362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_macx_swapon),
8363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_macx_swapoff),
8364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(50)),
8365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_macx_triggers),
8366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_macx_backing_store_suspend),
8367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_macx_backing_store_recovery),
8368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(48)),
8370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(49)),
8371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(50)),
8372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(51)),
8373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(52)),
8374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(53)),
8375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(54)),
8377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(55)),
8378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(56)),
8379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(57)),
8380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(58)),
8381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_swtch_pri, swtch_pri),
8382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_swtch, swtch),   // -60
8383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_syscall_thread_switch, syscall_thread_switch),
8384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// _____(__NR_clock_sleep_trap),
8385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(63)),
8386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(64)),
8387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(65)),
8388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(66)),
8389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(67)),
8390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(68)),
8391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(69)),
8392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(70)),
8393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(71)),
8394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(72)),
8395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(73)),
8396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(74)),
8397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(75)),
8398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(76)),
8399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(77)),
8400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(78)),
8401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(79)),
8402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(80)),   // -80
8403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(81)),
8404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(82)),
8405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(83)),
8406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(84)),
8407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(85)),
8408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(86)),
8409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(87)),
8410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(88)),
8411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mach_timebase_info, mach_timebase_info),
8412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_mach_wait_until, mach_wait_until),
8413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mk_timer_create, mk_timer_create),
8414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mk_timer_destroy, mk_timer_destroy),
8415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_mk_timer_arm, mk_timer_arm),
8416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_mk_timer_cancel, mk_timer_cancel),
8417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(95)),
8418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(96)),
8419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(97)),
8420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(98)),
8421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(99)),
8422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACXY(__NR_iokit_user_client_trap, iokit_user_client_trap), // -100
8423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
8424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Machine-dependent traps have wacky syscall numbers, and use the Mach trap
8427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// calling convention instead of the syscall convention.
8428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Use ML_(mdep_trap_table)[syscallno - ML_(mdep_trap_base)] .
8429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86)
8431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst SyscallTableEntry ML_(mdep_trap_table)[] = {
8432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_thread_fast_set_cthread_self, thread_fast_set_cthread_self),
8433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
8434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_amd64)
8435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst SyscallTableEntry ML_(mdep_trap_table)[] = {
8436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MACX_(__NR_thread_fast_set_cthread_self, thread_fast_set_cthread_self),
8437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
8438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
8439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#error unknown architecture
8440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
8441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst UInt ML_(syscall_table_size) =
8443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
8444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst UInt ML_(mach_trap_table_size) =
8446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            sizeof(ML_(mach_trap_table)) / sizeof(ML_(mach_trap_table)[0]);
8447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst UInt ML_(mdep_trap_table_size) =
8449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            sizeof(ML_(mdep_trap_table)) / sizeof(ML_(mdep_trap_table)[0]);
8450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGO_darwin)
8452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
8454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
8455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
8456