2 /*--------------------------------------------------------------------*/
3 /*--- Darwin-specific syscalls, etc. syswrap-darwin.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2005-2017 Apple Inc.
11 Greg Parker gparker@apple.com
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGO_darwin)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_xarray.h"
37 #include "pub_core_clientstate.h"
38 #include "pub_core_debuglog.h"
39 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
40 #include "pub_core_transtab.h" // VG_(discard_translations)
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcfile.h"
44 #include "pub_core_libcprint.h"
45 #include "pub_core_libcproc.h"
46 #include "pub_core_libcsignal.h"
47 #include "pub_core_machine.h" // VG_(get_SP)
48 #include "pub_core_mallocfree.h"
49 #include "pub_core_options.h"
50 #include "pub_core_oset.h"
51 #include "pub_core_scheduler.h"
52 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
53 #include "pub_core_signals.h"
54 #include "pub_core_stacks.h"
55 #include "pub_core_syscall.h"
56 #include "pub_core_syswrap.h"
57 #include "pub_core_tooliface.h"
58 #include "pub_core_wordfm.h"
60 #include "priv_types_n_macros.h"
61 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
62 #include "priv_syswrap-darwin.h" /* for decls of darwin-ish wrappers */
63 #include "priv_syswrap-main.h"
65 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
66 #include <mach/mach.h>
67 #include <mach/mach_vm.h>
68 #include <semaphore.h>
69 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
71 #define msgh_request_port msgh_remote_port
72 #define msgh_reply_port msgh_local_port
73 #define BOOTSTRAP_MAX_NAME_LEN 128
74 typedef HChar name_t
[BOOTSTRAP_MAX_NAME_LEN
];
76 typedef uint64_t mig_addr_t
;
80 static mach_port_t vg_host_port
= 0;
81 static mach_port_t vg_task_port
= 0;
82 static mach_port_t vg_bootstrap_port
= 0;
84 // Run a thread from beginning to end and return the thread's
85 // scheduler-return-code.
86 static VgSchedReturnCode
thread_wrapper(Word
/*ThreadId*/ tidW
)
88 VgSchedReturnCode ret
;
89 ThreadId tid
= (ThreadId
)tidW
;
90 Int lwpid
= VG_(gettid
)();
91 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
93 VG_(debugLog
)(1, "syswrap-darwin",
94 "thread_wrapper(tid=%u,lwpid=%d): entry\n",
97 vg_assert(tst
->status
== VgTs_Init
);
99 /* make sure we get the CPU lock before doing anything significant */
100 VG_(acquire_BigLock
)(tid
, "thread_wrapper");
103 VG_(printf
)("thread tid %u started: stack = %p\n",
106 /* Make sure error reporting is enabled in the new thread. */
107 tst
->err_disablement_level
= 0;
109 VG_TRACK(pre_thread_first_insn
, tid
);
111 tst
->os_state
.lwpid
= lwpid
;
112 tst
->os_state
.threadgroup
= VG_(getpid
)();
114 /* Thread created with all signals blocked; scheduler will set the
117 ret
= VG_(scheduler
)(tid
);
119 vg_assert(VG_(is_exiting
)(tid
));
121 vg_assert(tst
->status
== VgTs_Runnable
);
122 vg_assert(VG_(is_running_thread
)(tid
));
124 VG_(debugLog
)(1, "syswrap-darwin",
125 "thread_wrapper(tid=%u,lwpid=%d): done\n",
128 /* Return to caller, still holding the lock. */
134 /* Allocate a stack for this thread, if it doesn't already have one.
135 Returns the initial stack pointer value to use, or 0 if allocation
138 Addr
allocstack ( ThreadId tid
)
140 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
144 /* Either the stack_base and stack_init_SP are both zero (in which
145 case a stack hasn't been allocated) or they are both non-zero,
146 in which case it has. */
148 if (tst
->os_state
.valgrind_stack_base
== 0)
149 vg_assert(tst
->os_state
.valgrind_stack_init_SP
== 0);
151 if (tst
->os_state
.valgrind_stack_base
!= 0)
152 vg_assert(tst
->os_state
.valgrind_stack_init_SP
!= 0);
154 /* If no stack is present, allocate one. */
156 if (tst
->os_state
.valgrind_stack_base
== 0) {
157 stack
= VG_(am_alloc_VgStack
)( &initial_SP
);
159 tst
->os_state
.valgrind_stack_base
= (Addr
)stack
;
160 tst
->os_state
.valgrind_stack_init_SP
= initial_SP
;
164 VG_(debugLog
)( 2, "syswrap-darwin", "stack for tid %u at %p; init_SP=%p\n",
166 (void*)tst
->os_state
.valgrind_stack_base
,
167 (void*)tst
->os_state
.valgrind_stack_init_SP
);
169 vg_assert(VG_IS_32_ALIGNED(tst
->os_state
.valgrind_stack_init_SP
));
171 return tst
->os_state
.valgrind_stack_init_SP
;
175 void find_stack_segment(ThreadId tid
, Addr sp
)
177 ML_(guess_and_register_stack
) (sp
, VG_(get_ThreadState
)(tid
));
181 /* Run a thread all the way to the end, then do appropriate exit actions
182 (this is the last-one-out-turn-off-the-lights bit).
184 static void run_a_thread_NORETURN ( Word tidW
)
187 VgSchedReturnCode src
;
188 ThreadId tid
= (ThreadId
)tidW
;
191 VG_(debugLog
)(1, "syswrap-darwin",
192 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
195 tst
= VG_(get_ThreadState
)(tid
);
198 /* Run the thread all the way through. */
199 src
= thread_wrapper(tid
);
201 VG_(debugLog
)(1, "syswrap-darwin",
202 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
205 c
= VG_(count_living_threads
)();
206 vg_assert(c
>= 1); /* stay sane */
208 /* Deregister thread's stack. */
209 if (tst
->os_state
.stk_id
!= NULL_STK_ID
)
210 VG_(deregister_stack
)(tst
->os_state
.stk_id
);
212 // Tell the tool this thread is exiting
213 VG_TRACK( pre_thread_ll_exit
, tid
);
215 /* If the thread is exiting with errors disabled, complain loudly;
216 doing so is bad (does the user know this has happened?) Also,
217 in all cases, be paranoid and clear the flag anyway so that the
218 thread slot is safe in this respect if later reallocated. This
219 should be unnecessary since the flag should be cleared when the
220 slot is reallocated, in thread_wrapper(). */
221 if (tst
->err_disablement_level
> 0) {
223 "WARNING: exiting thread has error reporting disabled.\n"
224 "WARNING: possibly as a result of some mistake in the use\n"
225 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
229 "run_a_thread_NORETURN(tid=%u): "
230 "WARNING: exiting thread has err_disablement_level = %u\n",
231 tid
, tst
->err_disablement_level
234 tst
->err_disablement_level
= 0;
238 VG_(debugLog
)(1, "syswrap-darwin",
239 "run_a_thread_NORETURN(tid=%u): "
240 "last one standing\n",
243 /* We are the last one standing. Keep hold of the lock and
244 carry on to show final tool results, then exit the entire system.
245 Use the continuation pointer set at startup in m_main. */
246 ( * VG_(address_of_m_main_shutdown_actions_NORETURN
) ) (tid
, src
);
250 mach_msg_header_t msg
;
252 VG_(debugLog
)(1, "syswrap-darwin",
253 "run_a_thread_NORETURN(tid=%u): "
254 "not last one standing\n",
257 /* OK, thread is dead, but others still exist. Just exit. */
259 /* This releases the run lock */
260 VG_(exit_thread
)(tid
);
261 vg_assert(tst
->status
== VgTs_Zombie
);
263 /* tid is now invalid. */
265 // GrP fixme exit race
266 msg
.msgh_bits
= MACH_MSGH_BITS(17, MACH_MSG_TYPE_MAKE_SEND_ONCE
);
267 msg
.msgh_request_port
= VG_(gettid
)();
268 msg
.msgh_reply_port
= 0;
269 msg
.msgh_id
= 3600; // thread_terminate
271 tst
->status
= VgTs_Empty
;
272 // GrP fixme race here! new thread may claim this V thread stack
273 // before we get out here!
274 // GrP fixme use bsdthread_terminate for safe cleanup?
275 mach_msg(&msg
, MACH_SEND_MSG
|MACH_MSG_OPTION_NONE
,
276 sizeof(msg
), 0, 0, MACH_MSG_TIMEOUT_NONE
, 0);
278 // DDD: This is reached sometimes on none/tests/manythreads, maybe
279 // because of the race above.
280 VG_(core_panic
)("Thread exit failed?\n");
288 /* Allocate a stack for the main thread, and run it all the way to the
289 end. Although we already have a working VgStack
290 (VG_(interim_stack)) it's better to allocate a new one, so that
291 overflow detection works uniformly for all threads.
293 void VG_(main_thread_wrapper_NORETURN
)(ThreadId tid
)
296 VG_(debugLog
)(1, "syswrap-darwin",
297 "entering VG_(main_thread_wrapper_NORETURN)\n");
299 sp
= allocstack(tid
);
301 /* If we can't even allocate the first thread's stack, we're hosed.
303 vg_assert2(sp
!= 0, "Cannot allocate main thread's stack.");
305 /* shouldn't be any other threads around yet */
306 vg_assert( VG_(count_living_threads
)() == 1 );
308 call_on_new_stack_0_1(
309 (Addr
)sp
, /* stack */
310 0, /*bogus return address*/
311 run_a_thread_NORETURN
, /* fn to call */
312 (Word
)tid
/* arg to give it */
320 void start_thread_NORETURN ( Word arg
)
322 ThreadState
* tst
= (ThreadState
*)arg
;
323 ThreadId tid
= tst
->tid
;
325 run_a_thread_NORETURN ( (Word
)tid
);
331 void VG_(cleanup_thread
) ( ThreadArchState
* arch
)
336 /* ---------------------------------------------------------------------
337 Message reporting, with duplicate removal
338 ------------------------------------------------------------------ */
340 static WordFM
* decaying_string_table
= NULL
; /* HChar* -> UWord */
342 static Word
decaying_string_table_cmp ( UWord s1
, UWord s2
) {
343 return (Word
)VG_(strcmp
)( (HChar
*)s1
, (HChar
*)s2
);
346 static void log_decaying ( const HChar
* format
, ... ) PRINTF_CHECK(1, 2);
347 static void log_decaying ( const HChar
* format
, ... )
349 // get the message into a stack-allocated string.
351 VG_(memset
)(buf
, 0, sizeof(buf
));
353 va_start(vargs
,format
);
354 (void) VG_(vsnprintf
)(buf
, sizeof(buf
), format
, vargs
);
356 buf
[sizeof(buf
)-1] = 0;
358 // Now see if it already exists in the table of strings that we have.
359 if (!decaying_string_table
) {
360 decaying_string_table
361 = VG_(newFM
)( VG_(malloc
), "syswrap-darwin.pd.1",
362 VG_(free
), decaying_string_table_cmp
);
365 const HChar
* key
= NULL
;
367 if (!VG_(lookupFM
)(decaying_string_table
,
368 (UWord
*)&key
, &val
, (UWord
)&buf
[0])) {
369 // We haven't seen this string before, so strdup it and add
371 vg_assert(key
== NULL
&& val
== 0);
372 key
= VG_(strdup
)("syswrap-darwin.pd.2", buf
);
373 VG_(addToFM
)(decaying_string_table
, (UWord
)key
, (UWord
)0);
376 vg_assert(key
!= NULL
&& key
!= &buf
[0]);
378 // So, finally, |key| is in the tree, and |val| is what it is
379 // currently associated with. Increment that counter.
381 Bool b
= VG_(addToFM
)(decaying_string_table
, (UWord
)key
, (UWord
)val
);
384 if (-1 != VG_(log2
)( (UInt
)val
)) {
386 VG_(dmsg
)("%s\n", key
);
388 VG_(dmsg
)("%s (repeated %lu times)\n", key
, val
);
393 /* ---------------------------------------------------------------------
394 Mach port tracking (based on syswrap-generic's fd tracker)
395 ------------------------------------------------------------------ */
397 /* One of these is allocated for each open port. */
398 typedef struct OpenPort
401 mach_port_type_t type
; /* right type(s) */
402 Int send_count
; /* number of send rights */
403 HChar
*name
; /* bootstrap name or NULL */
404 ExeContext
*where
; /* first allocation only */
405 struct OpenPort
*next
, *prev
;
408 // strlen("0x12345678")
409 #define PORT_STRLEN (2+2*sizeof(mach_port_t))
411 /* List of allocated ports. */
412 static OpenPort
*allocated_ports
;
414 /* Count of open ports. */
415 static Int allocated_port_count
= 0;
417 /* Create an entry for |port|, with no other info. Assumes it doesn't
419 static void port_create_vanilla(mach_port_t port
)
422 = VG_(calloc
)("syswrap-darwin.port_create_vanilla", sizeof(OpenPort
), 1);
424 /* Add it to the list. */
425 op
->next
= allocated_ports
;
426 if (allocated_ports
) allocated_ports
->prev
= op
;
427 allocated_ports
= op
;
428 allocated_port_count
++;
431 __attribute__((unused
))
432 static Bool
port_exists(mach_port_t port
)
436 /* Check to see if this port is already open. */
439 if (i
->port
== port
) {
448 static OpenPort
*info_for_port(mach_port_t port
)
451 if (!port
) return NULL
;
455 if (i
->port
== port
) {
465 // Give a port a name, without changing its refcount
466 // GrP fixme don't override name if it already has a specific one
467 __private_extern__
void assign_port_name(mach_port_t port
, const HChar
*name
)
473 i
= info_for_port(port
);
476 if (i
->name
) VG_(free
)(i
->name
);
478 VG_(malloc
)("syswrap-darwin.mach-port-name",
479 VG_(strlen
)(name
) + PORT_STRLEN
+ 1);
480 VG_(sprintf
)(i
->name
, name
, port
);
484 // Return the name of the given port or "UNKNOWN 0x1234" if not known.
485 static const HChar
*name_for_port(mach_port_t port
)
487 static HChar buf
[8 + PORT_STRLEN
+ 1];
491 if (port
== VG_(gettid
)()) return "mach_thread_self()";
492 if (port
== 0) return "NULL";
496 if (i
->port
== port
) {
502 VG_(sprintf
)(buf
, "NONPORT-%#x", port
);
506 /* Note the fact that a port was just deallocated. */
509 void record_port_mod_refs(mach_port_t port
, mach_port_type_t right
, Int delta
)
511 OpenPort
*i
= allocated_ports
;
515 if(i
->port
== port
) {
516 vg_assert(right
!= MACH_PORT_TYPE_DEAD_NAME
);
517 if (right
& MACH_PORT_TYPE_SEND
) {
518 // send rights are refcounted
519 if (delta
== INT_MIN
) delta
= -i
->send_count
; // INT_MIN == destroy
520 i
->send_count
+= delta
;
521 if (i
->send_count
> 0) i
->type
|= MACH_PORT_TYPE_SEND
;
522 else i
->type
&= ~MACH_PORT_TYPE_SEND
;
524 right
= right
& ~MACH_PORT_TYPE_SEND
;
526 // other rights are not refcounted
529 } else if (delta
< 0) {
534 if (i
->type
!= 0) return;
536 // Port has no rights left. Kill it.
537 // VG_(printf)("deleting port %p %s", i->port, i->name);
539 i
->prev
->next
= i
->next
;
541 allocated_ports
= i
->next
;
543 i
->next
->prev
= i
->prev
;
547 allocated_port_count
--;
553 VG_(printf
)("UNKNOWN Mach port modified (port %#x delta %d)\n", port
, delta
);
557 void record_port_insert_rights(mach_port_t port
, mach_msg_type_name_t type
)
560 case MACH_MSG_TYPE_PORT_NAME
:
561 // this task has no rights for the name
563 case MACH_MSG_TYPE_PORT_RECEIVE
:
564 // this task gets receive rights
565 record_port_mod_refs(port
, MACH_PORT_TYPE_RECEIVE
, 1);
567 case MACH_MSG_TYPE_PORT_SEND
:
568 // this task gets a send right
569 record_port_mod_refs(port
, MACH_PORT_TYPE_SEND
, 1);
571 case MACH_MSG_TYPE_PORT_SEND_ONCE
:
572 // this task gets send-once rights
573 record_port_mod_refs(port
, MACH_PORT_TYPE_SEND_ONCE
, 1);
582 void record_port_dealloc(mach_port_t port
)
584 // deletes 1 send or send-once right (port can't have both)
585 record_port_mod_refs(port
, MACH_PORT_TYPE_SEND_RIGHTS
, -1);
589 void record_port_destroy(mach_port_t port
)
591 // deletes all rights to port
592 record_port_mod_refs(port
, MACH_PORT_TYPE_ALL_RIGHTS
, INT_MIN
);
596 /* Note the fact that a Mach port was just allocated or transferred.
597 If the port is already known, increment its reference count. */
598 void record_named_port(ThreadId tid
, mach_port_t port
,
599 mach_port_right_t right
, const HChar
*name
)
604 /* Check to see if this port is already open. */
607 if (i
->port
== port
) {
608 if (right
!= -1) record_port_mod_refs(port
, MACH_PORT_TYPE(right
), 1);
614 /* Not already one: allocate an OpenPort */
616 i
= VG_(malloc
)("syswrap-darwin.mach-port", sizeof(OpenPort
));
619 i
->next
= allocated_ports
;
620 if(allocated_ports
) allocated_ports
->prev
= i
;
622 allocated_port_count
++;
625 i
->where
= (tid
== -1) ? NULL
: VG_(record_ExeContext
)(tid
, 0);
628 i
->type
= MACH_PORT_TYPE(right
);
629 i
->send_count
= (right
== MACH_PORT_RIGHT_SEND
) ? 1 : 0;
635 assign_port_name(port
, name
);
640 // Record opening of a nameless port.
641 static void record_unnamed_port(ThreadId tid
, mach_port_t port
, mach_port_right_t right
)
643 record_named_port(tid
, port
, right
, "unnamed-%p");
647 /* Dump summary of open Mach ports, like VG_(show_open_fds) */
648 void VG_(show_open_ports
)(void)
652 VG_(message
)(Vg_UserMsg
,
653 "MACH PORTS: %d open at exit.\n", allocated_port_count
);
655 for (i
= allocated_ports
; i
; i
= i
->next
) {
657 VG_(message
)(Vg_UserMsg
, "Open Mach port 0x%x: %s\n", i
->port
,
660 VG_(message
)(Vg_UserMsg
, "Open Mach port 0x%x\n", i
->port
);
664 VG_(pp_ExeContext
)(i
->where
);
665 VG_(message
)(Vg_UserMsg
, "\n");
669 VG_(message
)(Vg_UserMsg
, "\n");
673 /* ---------------------------------------------------------------------
675 ------------------------------------------------------------------ */
678 enum { CheckAlways
=1, CheckEvery20
, CheckNever
}
681 static const HChar
* show_CheckHowOften ( CheckHowOften cho
) {
683 case CheckAlways
: return "Always ";
684 case CheckEvery20
: return "Every20";
685 case CheckNever
: return "Never ";
686 default: vg_assert(0);
690 /* Statistics for one particular resync-call set of arguments,
691 as specified by key1, key2 and key3. */
699 ULong n_mappings_added
;
700 ULong n_mappings_removed
;
704 static Bool
cmp_eqkeys_SyncStats ( SyncStats
* ss1
, SyncStats
* ss2
) {
705 return ss1
->key3
== ss2
->key3
706 && 0 == VG_(strcmp
)(ss1
->key1
, ss2
->key1
)
707 && 0 == VG_(strcmp
)(ss1
->key2
, ss2
->key2
);
710 /* The filter data. */
711 #define N_SYNCSTATS 1000
712 static Int syncstats_used
= 0;
713 static SyncStats syncstats
[N_SYNCSTATS
];
715 /* Statistics overall, for the filter. */
716 static ULong n_syncsRequested
= 0; // Total number requested
717 static ULong n_syncsPerformed
= 0; // Number carried out (the rest skipped)
721 void update_syncstats ( CheckHowOften cho
,
722 const HChar
* key1
, const HChar
* key2
,
724 UInt n_mappings_added
, UInt n_mappings_removed
)
726 SyncStats dummy
= { CheckAlways
, key1
, key2
, key3
, 0, 0, 0 };
728 for (i
= 0; i
< syncstats_used
; i
++) {
729 if (cmp_eqkeys_SyncStats(&syncstats
[i
], &dummy
))
732 vg_assert(i
>= 0 && i
<= syncstats_used
);
733 if (i
== syncstats_used
) {
735 vg_assert(syncstats_used
< N_SYNCSTATS
);
737 syncstats
[i
] = dummy
;
738 syncstats
[i
].cho
= cho
;
740 vg_assert(cmp_eqkeys_SyncStats(&syncstats
[i
], &dummy
));
741 syncstats
[i
].n_checks
++;
742 syncstats
[i
].n_mappings_added
+= (ULong
)n_mappings_added
;
743 syncstats
[i
].n_mappings_removed
+= (ULong
)n_mappings_removed
;
745 static UInt reorder_ctr
= 0;
746 if (i
> 0 && 0 == (1 & reorder_ctr
++)) {
747 SyncStats tmp
= syncstats
[i
-1];
748 syncstats
[i
-1] = syncstats
[i
];
754 static void maybe_show_syncstats ( void )
759 if (0 == (n_syncsRequested
& 0xFF)) {
760 VG_(printf
)("Resync filter: %'llu requested, %'llu performed (%llu%%)\n",
761 n_syncsRequested
, n_syncsPerformed
,
762 (100 * n_syncsPerformed
) /
763 (n_syncsRequested
== 0 ? 1 : n_syncsRequested
));
764 for (i
= 0; i
< syncstats_used
; i
++) {
765 if (i
>= 40) break; // just show the top 40
766 VG_(printf
)(" [%3d] (%s) upd %6llu diff %4llu+,%3llu-"
768 i
, show_CheckHowOften(syncstats
[i
].cho
),
769 syncstats
[i
].n_checks
,
770 syncstats
[i
].n_mappings_added
,
771 syncstats
[i
].n_mappings_removed
,
772 syncstats
[i
].key1
, syncstats
[i
].key2
,
773 (ULong
)syncstats
[i
].key3
);
775 if (i
< syncstats_used
) {
776 VG_(printf
)(" and %d more entries not shown.\n", syncstats_used
- i
);
783 Bool
ML_(sync_mappings
)(const HChar
* when
, const HChar
* where
, UWord num
)
785 // If VG(clo_resync_filter) == 0, the filter is disabled, and
786 // we must always honour the resync request.
788 // If VG(clo_resync_filter) == 1, the filter is enabled,
789 // so we try to avoid doing the sync if possible, but keep
792 // If VG(clo_resync_filter) == 2, the filter is enabled,
793 // so we try to avoid doing the sync if possible, and also
794 // periodically show stats, so that the filter can be updated.
797 if (VG_(clo_resync_filter
) >= 2)
798 maybe_show_syncstats();
802 // Usually the number of segments added/removed in a single call is very
803 // small e.g. 1. But it sometimes gets up to at least 100 or so (eg. for
804 // Quicktime). So we use a repeat-with-bigger-buffers-until-success model,
805 // because we can't do dynamic allocation within VG_(get_changed_segments),
806 // because it's in m_aspacemgr.
807 ChangedSeg
* css
= NULL
;
813 // -------------- BEGIN resync-filter-kludge --------------
815 // Some kludges to try and avoid the worst case cost hit of doing
816 // zillions of resyncs (huge). The idea is that many of the most
817 // common resyncs never appear to cause a delta, so we just ignore
818 // them (CheckNever). Then, a bunch of them also happen a lot, but
819 // only very occasionally cause a delta. We resync after 20 of those
820 // (CheckEvery20). Finally, the rest form a long tail, so we always
821 // resync after those (CheckAlways).
823 // Assume this is kernel-version and word-size specific, so develop
824 // filters accordingly. This might be overly conservative --
827 # define STREQ(_s1, _s2) (0 == VG_(strcmp)((_s1),(_s2)))
828 Bool when_in
= STREQ(when
, "in");
829 Bool when_after
= STREQ(when
, "after");
830 Bool where_mmr
= STREQ(where
, "mach_msg_receive");
831 Bool where_mmrU
= STREQ(where
, "mach_msg_receive-UNHANDLED");
832 Bool where_iuct
= STREQ(where
, "iokit_user_client_trap");
833 Bool where_MwcN
= STREQ(where
, "ML_(wqthread_continue_NORETURN)");
834 Bool where_woQR
= STREQ(where
, "workq_ops(QUEUE_REQTHREADS)");
835 Bool where_woQ2
= STREQ(where
, "workq_ops(QUEUE_REQTHREADS2)");
836 Bool where_woTR
= STREQ(where
, "workq_ops(THREAD_RETURN)");
837 Bool where_ke64
= STREQ(where
, "kevent64");
841 1 >= ( (where_mmr
? 1 : 0) + (where_mmrU
? 1 : 0)
842 + (where_iuct
? 1 : 0) + (where_MwcN
? 1 : 0)
843 + (where_woQR
? 1 : 0) + (where_woQ2
? 1 : 0)
844 + (where_woTR
? 1 : 0) + (where_ke64
? 1 : 0)
846 // merely to stop gcc complaining of non-use in the case where
847 // there's no filter:
848 vg_assert(when_in
== True
|| when_in
== False
);
849 vg_assert(when_after
== True
|| when_after
== False
);
851 CheckHowOften check
= CheckAlways
;
853 # if DARWIN_VERS == DARWIN_10_9 && VG_WORDSIZE == 8
854 /* ---------- BEGIN filter for 64-bit 10.9.x ---------- */
855 if (when_after
&& where_mmr
) {
856 // "after mach_msg_receive <number>"
858 case 0x00000000: // upd 12414 diff 36+,0-
859 check
= CheckEvery20
;
866 if (when_after
&& where_mmrU
) {
867 // "after mach_msg_receive-UNHANDLED <number>"
869 case 0x00000000: // upd 16687 diff 73+,0-
870 case 0x00000001: // upd 5106 diff 89+,0-
871 case 0x00000002: // upd 1609 diff 1+,0-
872 case 0x00000003: // upd 1987 diff 6+,0-
873 // case 0x00000b95: // upd 2894 diff 57+,1- <==dangerous
874 case 0x000072d9: // upd 2616 diff 11+,0-
875 case 0x000072cb: // upd 2616 diff 9+,0-
876 case 0x000074d5: // upd 172 diff 0+,0-
877 check
= CheckEvery20
;
884 if (when_in
&& where_MwcN
&& num
== 0x00000000) {
885 // in ML_(wqthread_continue_NORETURN) 0x00000000
886 // upd 4346 diff 0+,0-
887 check
= CheckEvery20
;
890 if (when_after
&& where_woQR
&& num
== 0x00000000) {
891 // after workq_ops(QUEUE_REQTHREADS) 0x00000000
892 // upd 14434 diff 102+,0-
893 check
= CheckEvery20
;
895 /* if (when_after && where_woQ2 && num == 0x00000000) {
896 // after workq_ops(QUEUE_REQTHREADS2) 0x00000000
897 // upd XXXX diff XX+,0-
898 check = CheckEvery20;
901 if (when_after
&& where_woTR
&& num
== 0x00000000) {
902 // after workq_ops(THREAD_RETURN) 0x00000000
903 // upd 14434 diff 102+,0-
904 check
= CheckEvery20
;
907 if (when_after
&& where_ke64
&& num
== 0x00000000) {
908 // after kevent64 0x00000000
909 // upd 1736 diff 78+,0-
910 check
= CheckEvery20
;
912 /* ----------- END filter for 64-bit 10.9.x ----------- */
913 # endif /* DARWIN_VERS == DARWIN_10_9 && VG_WORDSIZE == 8 */
915 # if DARWIN_VERS == DARWIN_10_10 && VG_WORDSIZE == 8
916 /* ---------- BEGIN filter for 64-bit 10.10.x ---------- */
917 if (when_after
&& where_mmr
) {
918 // "after mach_msg_receive <number>"
920 case 0x00000000: // upd 2380 diff 23+,0-
921 check
= CheckEvery20
;
928 if (when_after
&& where_mmrU
) {
929 // "after mach_msg_receive-UNHANDLED <number>"
931 case 0x00000000: // upd 2370 diff 93+,1- <==dangerous
932 case 0x0000004f: // upd 212 diff 2+,0-
933 case 0x00000b95: // upd 9826 diff 163+,1- diff scale, dangerous
934 case 0x00000ba5: // upd 304 diff 0+,0-
935 case 0x0000157f: // upd 201 diff 2+,0-
936 case 0x0000157d: // upd 197 diff 1+,0-
937 case 0x0000333d: // upd 112 diff 0+,0-
938 case 0x0000333f: // upd 223 diff 10+,0-
939 case 0x000072cd: // upd 8286 diff 98+,0- diff scale
940 case 0x000072ae: // upd 193 diff 10+,0-
941 case 0x000072ec: // upd 319 diff 7+,0-
942 case 0x77303074: // upd 113 diff 3+,0-
943 case 0x10000000: // upd 314 diff 6+,0-
944 check
= CheckEvery20
;
951 if (when_in
&& where_MwcN
&& num
== 0x00000000) {
952 // in ML_(wqthread_continue_NORETURN) 0x00000000
953 // upd 1110 diff 37+,0-
954 check
= CheckEvery20
;
957 if (when_after
&& where_woQR
&& num
== 0x00000000) {
958 // after workq_ops(QUEUE_REQTHREADS) 0x00000000
959 // upd 1099 diff 37+,0-
960 check
= CheckEvery20
;
962 /* if (when_after && where_woQ2 && num == 0x00000000) {
963 // after workq_ops(QUEUE_REQTHREADS2) 0x00000000
964 // upd XXXX diff XX+,0-
965 check = CheckEvery20;
968 if (when_after
&& where_woTR
&& num
== 0x00000000) {
969 // after workq_ops(THREAD_RETURN) 0x00000000
971 check
= CheckEvery20
;
974 if (when_after
&& where_ke64
&& num
== 0x00000000) {
975 // after kevent64 0x00000000
976 // upd 1463 diff 15+,0-
977 check
= CheckEvery20
;
979 /* ----------- END filter for 64-bit 10.10.x ----------- */
980 # endif /* DARWIN_VERS == DARWIN_10_10 && VG_WORDSIZE == 8 */
982 /* Regardless of what the filter says, force a sync every 1 time in
983 1000, to stop things getting too far out of sync. */
985 static UInt ctr1k
= 0;
987 if ((ctr1k
% 1000) == 0)
991 /* If the filter is disabled, we must always check. */
992 if (VG_(clo_resync_filter
) == 0)
999 // only resync once every 20th time
1000 static UInt ctr10
= 0;
1002 if ((ctr10
% 20) != 0) return False
;
1011 // --------------- END resync-filter-kludge ---------------
1013 if (0 || VG_(clo_trace_syscalls
)) {
1014 VG_(debugLog
)(0, "syswrap-darwin",
1015 "sync_mappings (%s) (\"%s\", \"%s\", 0x%lx)\n",
1016 show_CheckHowOften(check
), when
, where
, num
);
1019 // 16 is enough for most cases, but small enough that overflow happens
1020 // occasionally and thus the overflow path gets some test coverage.
1024 VG_(free
)(css
); // css is NULL on first iteration; that's ok.
1025 css
= VG_(calloc
)("sys_wrap.sync_mappings",
1026 css_size
, sizeof(ChangedSeg
));
1027 ok
= VG_(get_changed_segments
)(when
, where
, css
, css_size
, &css_used
);
1031 UInt css_added
= 0, css_removed
= 0;
1033 // Now add/remove them.
1034 for (i
= 0; i
< css_used
; i
++) {
1035 ChangedSeg
* cs
= &css
[i
];
1038 ML_(notify_core_and_tool_of_mmap
)(
1039 cs
->start
, cs
->end
- cs
->start
+ 1,
1040 cs
->prot
, VKI_MAP_PRIVATE
, 0, cs
->offset
);
1041 // should this call VG_(di_notify_mmap) also?
1044 ML_(notify_core_and_tool_of_munmap
)(
1045 cs
->start
, cs
->end
- cs
->start
+ 1);
1047 if (VG_(clo_trace_syscalls
)) {
1049 VG_(debugLog
)(0, "syswrap-darwin",
1050 " added region 0x%010lx..0x%010lx prot %u at %s (%s)\n",
1051 cs
->start
, cs
->end
+ 1, (UInt
)cs
->prot
, where
, when
);
1053 VG_(debugLog
)(0, "syswrap-darwin",
1054 " removed region 0x%010lx..0x%010lx at %s (%s)\n",
1055 cs
->start
, cs
->end
+ 1, where
, when
);
1063 VG_(debugLog
)(0, "syswrap-darwin", "SYNC: %d %s %s\n",
1064 css_used
, when
, where
);
1066 // Update the stats, so we can derive the filter above.
1068 update_syncstats(check
, when
, where
, num
, css_added
, css_removed
);
1070 return css_used
> 0;
1073 /* ---------------------------------------------------------------------
1075 ------------------------------------------------------------------ */
1077 #define PRE(name) DEFN_PRE_TEMPLATE(darwin, name)
1078 #define POST(name) DEFN_POST_TEMPLATE(darwin, name)
1080 #define PRE_FN(name) vgSysWrap_darwin_##name##_before
1081 #define POST_FN(name) vgSysWrap_darwin_##name##_after
1083 #define CALL_PRE(name) PRE_FN(name)(tid, layout, arrghs, status, flags)
1084 #define CALL_POST(name) POST_FN(name)(tid, arrghs, status)
1086 // Retrieve the current Mach thread
1087 #define MACH_THREAD ((Addr)VG_(get_ThreadState)(tid)->os_state.lwpid)
1089 // Set the POST handler for a mach_msg derivative
1090 #define AFTER VG_(get_ThreadState)(tid)->os_state.post_mach_trap_fn
1092 // Set or get values saved from Mach messages
1093 #define MACH_ARG(x) VG_(get_ThreadState)(tid)->os_state.mach_args.x
1094 #define MACH_REMOTE VG_(get_ThreadState)(tid)->os_state.remote_port
1095 #define MACH_MSGH_ID VG_(get_ThreadState)(tid)->os_state.msgh_id
1097 /* ---------------------------------------------------------------------
1098 darwin ioctl wrapper
1099 ------------------------------------------------------------------ */
1103 *flags
|= SfMayBlock
;
1105 /* Handle ioctls that don't take an arg first */
1106 switch (ARG2
/* request */) {
1111 case VKI_TIOCPTYGRANT
:
1112 case VKI_TIOCPTYUNLK
:
1113 case VKI_DTRACEHIOC_REMOVE
:
1115 case VKI_BIOCPROMISC
:
1116 PRINT("ioctl ( %lu, 0x%lx )", ARG1
, ARG2
);
1117 PRE_REG_READ2(long, "ioctl",
1118 unsigned int, fd
, unsigned int, request
);
1121 PRINT("ioctl ( %lu, 0x%lx, %#lx )", ARG1
, ARG2
, ARG3
);
1122 PRE_REG_READ3(long, "ioctl",
1123 unsigned int, fd
, unsigned int, request
, unsigned long, arg
);
1126 switch (ARG2
/* request */) {
1127 case VKI_TIOCGWINSZ
:
1128 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3
, sizeof(struct vki_winsize
) );
1130 case VKI_TIOCSWINSZ
:
1131 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3
, sizeof(struct vki_winsize
) );
1134 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3
, sizeof(unsigned int) );
1137 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3
, sizeof(unsigned int) );
1140 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3
, sizeof(unsigned int) );
1143 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3
, sizeof(unsigned int) );
1146 /* Get process group ID for foreground processing group. */
1147 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3
, sizeof(vki_pid_t
) );
1150 /* Set a process group ID? */
1151 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3
, sizeof(vki_pid_t
) );
1154 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3
, sizeof(int) );
1157 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3
, sizeof(int) );
1159 case VKI_FIONREAD
: /* identical to SIOCINQ */
1160 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3
, sizeof(int) );
1164 /* These all use struct ifreq AFAIK */
1165 /* GrP fixme is sizeof(struct vki_if_req) correct if it's using a sockaddr? */
1166 case VKI_SIOCGIFFLAGS
: /* get flags */
1167 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
1168 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1169 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3
, sizeof(struct vki_ifreq
));
1171 case VKI_SIOCGIFMTU
: /* get MTU size */
1172 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
1173 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1174 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3
, sizeof(struct vki_ifreq
));
1176 case VKI_SIOCGIFADDR
: /* get PA address */
1177 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
1178 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1179 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3
, sizeof(struct vki_ifreq
));
1181 case VKI_SIOCGIFNETMASK
: /* get network PA mask */
1182 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
1183 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1184 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3
, sizeof(struct vki_ifreq
));
1186 case VKI_SIOCGIFMETRIC
: /* get metric */
1187 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
1188 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1189 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3
, sizeof(struct vki_ifreq
));
1191 case VKI_SIOCGIFDSTADDR
: /* get remote PA address */
1192 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
1193 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1194 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3
, sizeof(struct vki_ifreq
));
1196 case VKI_SIOCGIFBRDADDR
: /* get broadcast PA address */
1197 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
1198 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1199 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3
, sizeof(struct vki_ifreq
));
1201 case VKI_SIOCGIFCONF
: /* get iface list */
1203 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
1204 KERNEL_DO_SYSCALL(tid,RES);
1205 if (!VG_(is_kerror)(RES) && RES == 0)
1206 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
1208 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
1209 (Addr
)&((struct vki_ifconf
*)ARG3
)->ifc_len
,
1210 sizeof(((struct vki_ifconf
*)ARG3
)->ifc_len
));
1211 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
1212 (Addr
)&((struct vki_ifconf
*)ARG3
)->vki_ifc_buf
,
1213 sizeof(((struct vki_ifconf
*)ARG3
)->vki_ifc_buf
));
1215 // TODO len must be readable and writable
1216 // buf pointer only needs to be readable
1217 struct vki_ifconf
*ifc
= (struct vki_ifconf
*) ARG3
;
1218 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
1219 (Addr
)(ifc
->vki_ifc_buf
), ifc
->ifc_len
);
1223 case VKI_SIOCSIFFLAGS
: /* set flags */
1224 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
1225 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1226 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
1227 (Addr
)&((struct vki_ifreq
*)ARG3
)->vki_ifr_flags
,
1228 sizeof(((struct vki_ifreq
*)ARG3
)->vki_ifr_flags
) );
1230 case VKI_SIOCSIFADDR
: /* set PA address */
1231 case VKI_SIOCSIFDSTADDR
: /* set remote PA address */
1232 case VKI_SIOCSIFBRDADDR
: /* set broadcast PA address */
1233 case VKI_SIOCSIFNETMASK
: /* set network PA mask */
1234 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
1235 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1236 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
1237 (Addr
)&((struct vki_ifreq
*)ARG3
)->ifr_addr
,
1238 sizeof(((struct vki_ifreq
*)ARG3
)->ifr_addr
) );
1240 case VKI_SIOCSIFMETRIC
: /* set metric */
1241 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
1242 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1243 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
1244 (Addr
)&((struct vki_ifreq
*)ARG3
)->vki_ifr_metric
,
1245 sizeof(((struct vki_ifreq
*)ARG3
)->vki_ifr_metric
) );
1247 case VKI_SIOCSIFMTU
: /* set MTU size */
1248 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
1249 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1250 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
1251 (Addr
)&((struct vki_ifreq
*)ARG3
)->vki_ifr_mtu
,
1252 sizeof(((struct vki_ifreq
*)ARG3
)->vki_ifr_mtu
) );
1254 /* Routing table calls. */
1255 #ifdef VKI_SIOCADDRT
1256 case VKI_SIOCADDRT
: /* add routing table entry */
1257 case VKI_SIOCDELRT
: /* delete routing table entry */
1258 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3
,
1259 sizeof(struct vki_rtentry
));
1264 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3
, sizeof(int) );
1267 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3
, sizeof(int) );
1268 //tst->sys_flags &= ~SfMayBlock;
1272 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3
, sizeof(int) );
1275 case VKI_DTRACEHIOC_ADDDOF
:
1280 PRE_MEM_WRITE( "ioctl(TIOCGETA)", ARG3
, sizeof(struct vki_termios
) );
1283 PRE_MEM_READ( "ioctl(TIOCSETA)", ARG3
, sizeof(struct vki_termios
) );
1286 PRE_MEM_WRITE( "ioctl(TIOCGETD)", ARG3
, sizeof(int) );
1289 PRE_MEM_READ( "ioctl(TIOCSETD)", ARG3
, sizeof(int) );
1291 case VKI_TIOCPTYGNAME
:
1292 PRE_MEM_WRITE( "ioctl(TIOCPTYGNAME)", ARG3
, 128 );
1302 case VKI_BIOCSETF
: /* set BPF filter */
1304 * struct bpf_program has a 32-bit count of instructions,
1305 * followed by a pointer to an array of those instructions.
1306 * In 64-bit mode, there's padding between those two elements.
1308 * So that we don't bogusly complain about the padding bytes,
1309 * we just report that we read bf_len and and bf_insns.
1311 * We then make sure that what bf_insns points to is valid.
1313 PRE_MEM_READ( "ioctl(BIOCSETF)",
1314 (Addr
)&((struct vki_bpf_program
*)ARG3
)->vki_bf_len
,
1315 sizeof(((struct vki_bpf_program
*)ARG3
)->vki_bf_len
) );
1316 PRE_MEM_READ( "ioctl(BIOCSETF)",
1317 (Addr
)&((struct vki_bpf_program
*)ARG3
)->vki_bf_insns
,
1318 sizeof(((struct vki_bpf_program
*)ARG3
)->vki_bf_insns
) );
1320 /* bf_len * sizeof (*bf_insns) */
1321 struct vki_bpf_program
*bp
= (struct vki_bpf_program
*)ARG3
;
1322 if ( bp
->bf_insns
!= NULL
)
1323 PRE_MEM_READ( "ioctl(BIOCSETF) points to a struct bpf_program whose bf_insns member",
1324 (Addr
)(bp
->vki_bf_insns
),
1325 bp
->vki_bf_len
* sizeof(*bp
->vki_bf_insns
) );
1328 case VKI_BIOCSETIF
: /* set BPF interface */
1329 PRE_MEM_RASCIIZ( "ioctl(BIOCSETIF)",
1330 (Addr
)((struct vki_ifreq
*)ARG3
)->vki_ifr_name
);
1332 case VKI_BIOCSRTIMEOUT
: /* set BPF timeout */
1334 * 64-bit struct timeval starts with a 64-bit "seconds since the
1335 * Epoch" value, followed by a 32-bit microseconds value. The
1336 * resulting structure is padded to a multiple of 8 bytes, so
1337 * there are 4 padding bytes at the end.
1339 * So that we don't bogusly complain about the padding bytes,
1340 * we just report that we read tv_sec and tv_usec.
1342 PRE_MEM_READ( "ioctl(BIOCSRTIMEOUT)",
1343 (Addr
)&((struct vki_timeval
*)ARG3
)->vki_tv_sec
,
1344 sizeof(((struct vki_timeval
*)ARG3
)->vki_tv_sec
) );
1345 PRE_MEM_READ( "ioctl(BIOCSRTIMEOUT)",
1346 (Addr
)&((struct vki_timeval
*)ARG3
)->vki_tv_usec
,
1347 sizeof(((struct vki_timeval
*)ARG3
)->vki_tv_usec
) );
1349 case VKI_BIOCGDLTLIST
: /* get list of BPF DLTs */
1350 PRE_MEM_READ( "ioctl(BIOCGDLTLIST).bfl_len",
1351 (Addr
)&((struct vki_bpf_dltlist
*)ARG3
)->vki_bfl_list
,
1352 sizeof(((struct vki_bpf_dltlist
*)ARG3
)->vki_bfl_list
) );
1354 /* bfl_len * sizeof (*bfl_list) */
1355 struct vki_bpf_dltlist
*bdl
= (struct vki_bpf_dltlist
*)ARG3
;
1356 if ( bdl
->bfl_list
!= NULL
)
1357 PRE_MEM_READ( "ioctl(BIOCGDLTLIST).bfl_len",
1358 (Addr
)&((struct vki_bpf_dltlist
*)ARG3
)->vki_bfl_len
,
1359 sizeof(((struct vki_bpf_dltlist
*)ARG3
)->vki_bfl_len
) );
1360 PRE_MEM_WRITE( "ioctl(BIOCGDLTLIST) points to a struct bpf_dltlist whose bfl_list member",
1361 (Addr
)(bdl
->vki_bfl_list
),
1362 bdl
->bfl_len
* sizeof(*bdl
->vki_bfl_list
) );
1367 ML_(PRE_unknown_ioctl
)(tid
, ARG2
, ARG3
);
1376 switch (ARG2
/* request */) {
1377 case VKI_TIOCGWINSZ
:
1378 POST_MEM_WRITE( ARG3
, sizeof(struct vki_winsize
) );
1380 case VKI_TIOCSWINSZ
:
1386 POST_MEM_WRITE( ARG3
, sizeof(unsigned int) );
1389 /* Get process group ID for foreground processing group. */
1390 POST_MEM_WRITE( ARG3
, sizeof(vki_pid_t
) );
1393 /* Set a process group ID? */
1394 POST_MEM_WRITE( ARG3
, sizeof(vki_pid_t
) );
1402 case VKI_FIONREAD
: /* identical to SIOCINQ */
1403 POST_MEM_WRITE( ARG3
, sizeof(int) );
1406 /* These all use struct ifreq AFAIK */
1407 case VKI_SIOCGIFFLAGS
: /* get flags */
1408 POST_MEM_WRITE( (Addr
)&((struct vki_ifreq
*)ARG3
)->vki_ifr_flags
,
1409 sizeof(((struct vki_ifreq
*)ARG3
)->vki_ifr_flags
) );
1411 case VKI_SIOCGIFMTU
: /* get MTU size */
1412 POST_MEM_WRITE( (Addr
)&((struct vki_ifreq
*)ARG3
)->vki_ifr_mtu
,
1413 sizeof(((struct vki_ifreq
*)ARG3
)->vki_ifr_mtu
) );
1415 case VKI_SIOCGIFADDR
: /* get PA address */
1416 case VKI_SIOCGIFDSTADDR
: /* get remote PA address */
1417 case VKI_SIOCGIFBRDADDR
: /* get broadcast PA address */
1418 case VKI_SIOCGIFNETMASK
: /* get network PA mask */
1420 (Addr
)&((struct vki_ifreq
*)ARG3
)->ifr_addr
,
1421 sizeof(((struct vki_ifreq
*)ARG3
)->ifr_addr
) );
1423 case VKI_SIOCGIFMETRIC
: /* get metric */
1425 (Addr
)&((struct vki_ifreq
*)ARG3
)->vki_ifr_metric
,
1426 sizeof(((struct vki_ifreq
*)ARG3
)->vki_ifr_metric
) );
1428 case VKI_SIOCGIFCONF
: /* get iface list */
1430 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
1431 KERNEL_DO_SYSCALL(tid,RES);
1432 if (!VG_(is_kerror)(RES) && RES == 0)
1433 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
1435 if (RES
== 0 && ARG3
) {
1436 struct vki_ifconf
*ifc
= (struct vki_ifconf
*) ARG3
;
1437 if (ifc
->vki_ifc_buf
!= NULL
)
1438 POST_MEM_WRITE( (Addr
)(ifc
->vki_ifc_buf
), ifc
->ifc_len
);
1442 case VKI_SIOCSIFFLAGS
: /* set flags */
1443 case VKI_SIOCSIFDSTADDR
: /* set remote PA address */
1444 case VKI_SIOCSIFBRDADDR
: /* set broadcast PA address */
1445 case VKI_SIOCSIFNETMASK
: /* set network PA mask */
1446 case VKI_SIOCSIFMETRIC
: /* set metric */
1447 case VKI_SIOCSIFADDR
: /* set PA address */
1448 case VKI_SIOCSIFMTU
: /* set MTU size */
1451 #ifdef VKI_SIOCADDRT
1452 /* Routing table calls. */
1453 case VKI_SIOCADDRT
: /* add routing table entry */
1454 case VKI_SIOCDELRT
: /* delete routing table entry */
1459 POST_MEM_WRITE(ARG3
, sizeof(int));
1465 POST_MEM_WRITE( ARG3
, sizeof(int) );
1468 case VKI_DTRACEHIOC_REMOVE
:
1469 case VKI_DTRACEHIOC_ADDDOF
:
1474 POST_MEM_WRITE( ARG3
, sizeof(struct vki_termios
));
1479 POST_MEM_WRITE( ARG3
, sizeof(int) );
1483 case VKI_TIOCPTYGNAME
:
1484 POST_MEM_WRITE( ARG3
, 128);
1486 case VKI_TIOCSBRK
: /* set break bit */
1487 case VKI_TIOCCBRK
: /* clear break bit */
1488 case VKI_TIOCPTYGRANT
:
1489 case VKI_TIOCPTYUNLK
:
1493 case VKI_BIOCGDLTLIST
: /* get list of BPF DLTs */
1494 if (RES
== 0 && ARG3
) {
1495 /* bfl_len * sizeof (*bfl_list) */
1496 struct vki_bpf_dltlist
*bdl
= (struct vki_bpf_dltlist
*)ARG3
;
1497 if ( bdl
->vki_bfl_list
!= NULL
)
1498 POST_MEM_WRITE( (Addr
)(bdl
->vki_bfl_list
),
1499 bdl
->bfl_len
* sizeof(*bdl
->vki_bfl_list
) );
1504 ML_(POST_unknown_ioctl
)(tid
, RES
, ARG2
, ARG3
);
1510 /* ---------------------------------------------------------------------
1511 darwin fcntl wrapper
1512 ------------------------------------------------------------------ */
1513 static const HChar
*name_for_fcntl(UWord cmd
) {
1514 #define F(n) case VKI_##n: return #n
1522 F(F_GLOBAL_NOCACHE
);
1526 # if DARWIN_VERS < DARWIN_10_9
1528 F(F_WRITEBOOTSTRAP
);
1534 # if DARWIN_VERS >= DARWIN_10_9
1537 # if DARWIN_VERS >= DARWIN_10_11
1538 F(F_ADDFILESIGS_FOR_DYLD_SIM
);
1540 F(F_ADDFILESIGS_RETURN
);
1551 // These ones ignore ARG3.
1555 PRINT("fcntl ( %lu, %lu )", ARG1
,ARG2
);
1556 PRE_REG_READ2(long, "fcntl", unsigned int, fd
, unsigned int, cmd
);
1559 // These ones use ARG3 as "arg".
1564 PRINT("fcntl[ARG3=='arg'] ( %lu, %lu, %lu )", ARG1
,ARG2
,ARG3
);
1565 PRE_REG_READ3(long, "fcntl",
1566 unsigned int, fd
, unsigned int, cmd
, unsigned long, arg
);
1569 // These ones use ARG3 as "lock".
1573 PRINT("fcntl[ARG3=='lock'] ( %lu, %lu, %#lx )", ARG1
,ARG2
,ARG3
);
1574 PRE_REG_READ3(long, "fcntl",
1575 unsigned int, fd
, unsigned int, cmd
,
1576 struct flock64
*, lock
);
1577 // GrP fixme mem read sizeof(flock64)
1578 if (ARG2
== VKI_F_SETLKW
)
1579 *flags
|= SfMayBlock
;
1581 # if DARWIN_VERS >= DARWIN_10_10
1582 case VKI_F_SETLKWTIMEOUT
:
1583 PRINT("fcntl[ARG3=='locktimeout'] ( %lu, %lu, %#lx )", ARG1
,ARG2
,ARG3
);
1584 PRE_REG_READ3(long, "fcntl",
1585 unsigned int, fd
, unsigned int, cmd
,
1586 struct flocktimeout
*, lock
);
1587 *flags
|= SfMayBlock
;
1592 case VKI_F_CHKCLEAN
:
1595 case VKI_F_FULLFSYNC
:
1596 case VKI_F_FREEZE_FS
:
1598 case VKI_F_GLOBAL_NOCACHE
:
1599 PRINT("fcntl ( %lu, %s, %lu )", ARG1
, name_for_fcntl(ARG1
), ARG2
);
1600 PRE_REG_READ2(long, "fcntl", unsigned int, fd
, unsigned int, cmd
);
1604 case VKI_F_PREALLOCATE
:
1605 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1606 PRE_REG_READ3(long, "fcntl",
1607 unsigned int, fd
, unsigned int, cmd
,
1608 struct fstore
*, fstore
);
1610 struct vki_fstore
*fstore
= (struct vki_fstore
*)ARG3
;
1611 PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1612 fstore
->fst_flags
);
1613 PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1614 fstore
->fst_posmode
);
1615 PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1616 fstore
->fst_offset
);
1617 PRE_FIELD_READ( "fcntl(F_PREALLOCATE, fstore->fst_flags)",
1618 fstore
->fst_length
);
1619 PRE_FIELD_WRITE( "fcntl(F_PREALLOCATE, fstore->fst_bytesalloc)",
1620 fstore
->fst_bytesalloc
);
1626 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1627 PRE_REG_READ3(long, "fcntl",
1628 unsigned int, fd
, unsigned int, cmd
,
1629 vki_off_t
*, offset
);
1633 case VKI_F_RDADVISE
:
1634 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1635 PRE_REG_READ3(long, "fcntl",
1636 unsigned int, fd
, unsigned int, cmd
,
1637 struct vki_radvisory
*, radvisory
);
1639 struct vki_radvisory
*radvisory
= (struct vki_radvisory
*)ARG3
;
1640 PRE_FIELD_READ( "fcntl(F_PREALLOCATE, radvisory->ra_offset)",
1641 radvisory
->ra_offset
);
1642 PRE_FIELD_READ( "fcntl(F_PREALLOCATE, radvisory->ra_count)",
1643 radvisory
->ra_count
);
1647 # if DARWIN_VERS < DARWIN_10_9
1648 // struct fbootstraptransfer
1649 case VKI_F_READBOOTSTRAP
:
1650 case VKI_F_WRITEBOOTSTRAP
:
1651 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1652 PRE_REG_READ3(long, "fcntl",
1653 unsigned int, fd
, unsigned int, cmd
,
1654 struct fbootstraptransfer
*, bootstrap
);
1655 PRE_MEM_READ( "fcntl(F_READ/WRITEBOOTSTRAP, bootstrap)",
1656 ARG3
, sizeof(struct vki_fbootstraptransfer
) );
1660 // struct log2phys (out)
1661 case VKI_F_LOG2PHYS
:
1662 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1663 PRE_REG_READ3(long, "fcntl",
1664 unsigned int, fd
, unsigned int, cmd
,
1665 struct log2phys
*, l2p
);
1666 PRE_MEM_WRITE( "fcntl(F_LOG2PHYS, l2p)",
1667 ARG3
, sizeof(struct vki_log2phys
) );
1670 // char[maxpathlen] (out)
1672 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1673 PRE_REG_READ3(long, "fcntl",
1674 unsigned int, fd
, unsigned int, cmd
,
1676 PRE_MEM_WRITE( "fcntl(F_GETPATH, pathbuf)",
1677 ARG3
, VKI_MAXPATHLEN
);
1680 // char[maxpathlen] (in)
1681 case VKI_F_PATHPKG_CHECK
:
1682 PRINT("fcntl ( %lu, %s, %#lx '%s')", ARG1
, name_for_fcntl(ARG2
), ARG3
,
1684 PRE_REG_READ3(long, "fcntl",
1685 unsigned int, fd
, unsigned int, cmd
,
1687 PRE_MEM_RASCIIZ( "fcntl(F_PATHPKG_CHECK, pathbuf)", ARG3
);
1690 case VKI_F_ADDSIGS
: /* Add detached signatures (for code signing) */
1691 PRINT("fcntl ( %lu, %s )", ARG1
, name_for_fcntl(ARG2
));
1692 PRE_REG_READ3(long, "fcntl",
1693 unsigned int, fd
, unsigned int, cmd
,
1694 vki_fsignatures_t
*, sigs
);
1697 vki_fsignatures_t
*fsigs
= (vki_fsignatures_t
*)ARG3
;
1698 PRE_FIELD_READ( "fcntl(F_ADDSIGS, fsigs->fs_blob_start)",
1699 fsigs
->fs_blob_start
);
1700 PRE_FIELD_READ( "fcntl(F_ADDSIGS, fsigs->fs_blob_size)",
1701 fsigs
->fs_blob_size
);
1703 if (fsigs
->fs_blob_start
)
1704 PRE_MEM_READ( "fcntl(F_ADDSIGS, fsigs->fs_blob_start)",
1705 (Addr
)fsigs
->fs_blob_start
, fsigs
->fs_blob_size
);
1709 case VKI_F_ADDFILESIGS
: /* Add signature from same file (used by dyld for shared libs) */
1710 PRINT("fcntl ( %lu, %s, %#lx )", ARG1
, name_for_fcntl(ARG2
), ARG3
);
1711 PRE_REG_READ3(long, "fcntl",
1712 unsigned int, fd
, unsigned int, cmd
,
1713 vki_fsignatures_t
*, sigs
);
1716 vki_fsignatures_t
*fsigs
= (vki_fsignatures_t
*)ARG3
;
1717 PRE_FIELD_READ( "fcntl(F_ADDFILESIGS, fsigs->fs_blob_start)",
1718 fsigs
->fs_blob_start
);
1719 PRE_FIELD_READ( "fcntl(F_ADDFILESIGS, fsigs->fs_blob_size)",
1720 fsigs
->fs_blob_size
);
1724 # if DARWIN_VERS >= DARWIN_10_11
1725 case VKI_F_ADDFILESIGS_FOR_DYLD_SIM
: /* Add signature from same file, only if it is signed
1726 by Apple used by dyld for simulator */
1730 case VKI_F_BARRIERFSYNC
: /* fsync + issue barrier to drive */
1734 case VKI_F_ADDFILESIGS_RETURN
: /* Add signature from same file, return end offset in
1735 structure on success */
1741 PRINT("fcntl ( %lu, %lu [??] )", ARG1
, ARG2
);
1742 log_decaying("UNKNOWN fcntl %lu!", ARG2
);
1752 if (!ML_(fd_allowed
)(RES
, "fcntl(DUPFD)", tid
, True
)) {
1754 SET_STATUS_Failure( VKI_EMFILE
);
1756 if (VG_(clo_track_fds
))
1757 ML_(record_fd_open_named
)(tid
, RES
);
1770 # if DARWIN_VERS >= DARWIN_10_10
1771 case VKI_F_SETLKWTIMEOUT
:
1775 case VKI_F_PREALLOCATE
:
1777 struct vki_fstore
*fstore
= (struct vki_fstore
*)ARG3
;
1778 POST_FIELD_WRITE( fstore
->fst_bytesalloc
);
1782 case VKI_F_LOG2PHYS
:
1783 POST_MEM_WRITE( ARG3
, sizeof(struct vki_log2phys
) );
1787 POST_MEM_WRITE( ARG3
, 1+VG_(strlen
)((char *)ARG3
) );
1788 PRINT("\"%s\"", (char*)ARG3
);
1792 // DDD: ugh, missing lots of cases here, not nice
1797 /* ---------------------------------------------------------------------
1799 ------------------------------------------------------------------ */
1803 PRINT("futimes ( %ld, %#lx )", SARG1
, ARG2
);
1804 PRE_REG_READ2(long, "futimes", int, fd
, struct timeval
*, tvp
);
1805 if (!ML_(fd_allowed
)(ARG1
, "futimes", tid
, False
)) {
1806 SET_STATUS_Failure( VKI_EBADF
);
1807 } else if (ARG2
!= 0) {
1808 PRE_timeval_READ( "futimes(tvp[0])", ARG2
);
1809 PRE_timeval_READ( "futimes(tvp[1])", ARG2
+sizeof(struct vki_timeval
) );
1815 PRINT("semget ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
1816 PRE_REG_READ3(long, "semget", vki_key_t
, key
, int, nsems
, int, semflg
);
1821 *flags
|= SfMayBlock
;
1822 PRINT("semop ( %ld, %#lx, %lu )", SARG1
, ARG2
, ARG3
);
1823 PRE_REG_READ3(long, "semop",
1824 int, semid
, struct sembuf
*, sops
, vki_size_t
, nsoops
);
1825 ML_(generic_PRE_sys_semop
)(tid
, ARG1
,ARG2
,ARG3
);
1833 PRINT("semctl ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
1834 PRE_REG_READ4(long, "semctl",
1835 int, semid
, int, semnum
, int, cmd
, struct semid_ds
*, arg
);
1839 PRINT("semctl ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
1840 PRE_REG_READ4(long, "semctl",
1841 int, semid
, int, semnum
, int, cmd
, unsigned short *, arg
);
1844 PRINT("semctl ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
1845 PRE_REG_READ4(long, "semctl",
1846 int, semid
, int, semnum
, int, cmd
, int, arg
);
1849 PRINT("semctl ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
1850 PRE_REG_READ3(long, "semctl",
1851 int, semid
, int, semnum
, int, cmd
);
1854 ML_(generic_PRE_sys_semctl
)(tid
, ARG1
,ARG2
,ARG3
,ARG4
);
1858 ML_(generic_POST_sys_semctl
)(tid
, RES
,ARG1
,ARG2
,ARG3
,ARG4
);
1863 if (ARG2
& VKI_O_CREAT
) {
1865 PRINT("sem_open ( %#lx(%s), %ld, %lu, %lu )",
1866 ARG1
, (HChar
*)ARG1
, SARG2
, ARG3
, ARG4
);
1867 PRE_REG_READ4(vki_sem_t
*, "sem_open",
1868 const char *, name
, int, oflag
, vki_mode_t
, mode
,
1869 unsigned int, value
);
1872 PRINT("sem_open ( %#lx(%s), %ld )", ARG1
, (HChar
*)ARG1
, SARG2
);
1873 PRE_REG_READ2(vki_sem_t
*, "sem_open",
1874 const char *, name
, int, oflag
);
1876 PRE_MEM_RASCIIZ( "sem_open(name)", ARG1
);
1878 /* Otherwise handle normally */
1879 *flags
|= SfMayBlock
;
1884 PRINT("sem_close( %#lx )", ARG1
);
1885 PRE_REG_READ1(int, "sem_close", vki_sem_t
*, sem
);
1890 PRINT("sem_unlink( %#lx(%s) )", ARG1
, (HChar
*)ARG1
);
1891 PRE_REG_READ1(int, "sem_unlink", const char *, name
);
1892 PRE_MEM_RASCIIZ( "sem_unlink(name)", ARG1
);
1897 PRINT("sem_post( %#lx )", ARG1
);
1898 PRE_REG_READ1(int, "sem_post", vki_sem_t
*, sem
);
1899 *flags
|= SfMayBlock
;
1904 PRINT("sem_destroy( %#lx )", ARG1
);
1905 PRE_REG_READ1(int, "sem_destroy", vki_sem_t
*, sem
);
1906 PRE_MEM_READ("sem_destroy(sem)", ARG1
, sizeof(vki_sem_t
));
1911 PRINT("sem_init( %#lx, %ld, %lu )", ARG1
, SARG2
, ARG3
);
1912 PRE_REG_READ3(int, "sem_init", vki_sem_t
*, sem
,
1913 int, pshared
, unsigned int, value
);
1914 PRE_MEM_WRITE("sem_init(sem)", ARG1
, sizeof(vki_sem_t
));
1919 POST_MEM_WRITE(ARG1
, sizeof(vki_sem_t
));
1924 PRINT("sem_wait( %#lx )", ARG1
);
1925 PRE_REG_READ1(int, "sem_wait", vki_sem_t
*, sem
);
1926 *flags
|= SfMayBlock
;
1931 PRINT("sem_trywait( %#lx )", ARG1
);
1932 PRE_REG_READ1(int, "sem_trywait", vki_sem_t
*, sem
);
1933 *flags
|= SfMayBlock
;
1943 if (!ML_(fd_allowed
)(RES
, "kqueue", tid
, True
)) {
1945 SET_STATUS_Failure( VKI_EMFILE
);
1947 if (VG_(clo_track_fds
)) {
1948 ML_(record_fd_open_with_given_name
)(tid
, RES
, NULL
);
1953 PRE(fileport_makeport
)
1955 PRINT("fileport_makeport(fd:%#lx, portnamep:%#lx) FIXME",
1959 PRE(guarded_open_np
)
1961 PRINT("guarded_open_np(path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx) FIXME",
1962 ARG1
, (char*)ARG1
, ARG2
, ARG3
, ARG4
);
1965 PRE(guarded_kqueue_np
)
1967 PRINT("guarded_kqueue_np(guard:%#lx, guardflags:%#lx) FIXME",
1971 POST(guarded_kqueue_np
)
1973 if (!ML_(fd_allowed
)(RES
, "guarded_kqueue_np", tid
, True
)) {
1975 SET_STATUS_Failure( VKI_EMFILE
);
1977 if (VG_(clo_track_fds
)) {
1978 ML_(record_fd_open_with_given_name
)(tid
, RES
, NULL
);
1983 PRE(guarded_close_np
)
1985 PRINT("guarded_close_np(fd:%#lx, guard:%#lx) FIXME",
1989 PRE(change_fdguard_np
)
1991 PRINT("change_fdguard_np(fd:%#lx, guard:%#lx, guardflags:%#lx, nguard:%#lx, nguardflags:%#lx, fdflagsp:%#lx) FIXME",
1992 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
1997 PRINT("connectx(s:%#lx, src:%#lx, srclen:%#lx, dsts:%#lx, dstlen:%#lx, ifscope:%#lx, aid:%#lx, out_cid:%#lx) FIXME",
1998 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
, ARG8
);
2003 PRINT("disconnectx(s:%#lx, aid:%#lx, cid:%#lx) FIXME",
2010 PRINT("kevent( %ld, %#lx, %ld, %#lx, %ld, %#lx )",
2011 SARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
2012 PRE_REG_READ6(int,"kevent", int,kq
,
2013 const struct vki_kevent
*,changelist
, int,nchanges
,
2014 struct vki_kevent
*,eventlist
, int,nevents
,
2015 const struct vki_timespec
*,timeout
);
2017 if (ARG3
) PRE_MEM_READ ("kevent(changelist)",
2018 ARG2
, ARG3
* sizeof(struct vki_kevent
));
2019 if (ARG5
) PRE_MEM_WRITE("kevent(eventlist)",
2020 ARG4
, ARG5
* sizeof(struct vki_kevent
));
2021 if (ARG6
) PRE_MEM_READ ("kevent(timeout)",
2022 ARG6
, sizeof(struct vki_timespec
));
2024 *flags
|= SfMayBlock
;
2029 PRINT("kevent ret %ld dst %#lx (%zu)", RES
, ARG4
, sizeof(struct vki_kevent
));
2030 if (RES
> 0) POST_MEM_WRITE(ARG4
, RES
* sizeof(struct vki_kevent
));
2036 PRINT("kevent64( %ld, %#lx, %ld, %#lx, %ld, %#lx )",
2037 SARG1
, ARG2
, SARG3
, ARG4
, SARG5
, ARG6
);
2038 PRE_REG_READ6(int,"kevent64", int,kq
,
2039 const struct vki_kevent64
*,changelist
, int,nchanges
,
2040 struct vki_kevent64
*,eventlist
, int,nevents
,
2041 const struct vki_timespec
*,timeout
);
2043 if (ARG3
) PRE_MEM_READ ("kevent64(changelist)",
2044 ARG2
, ARG3
* sizeof(struct vki_kevent64
));
2045 if (ARG5
) PRE_MEM_WRITE("kevent64(eventlist)",
2046 ARG4
, ARG5
* sizeof(struct vki_kevent64
));
2047 if (ARG6
) PRE_MEM_READ ("kevent64(timeout)",
2048 ARG6
, sizeof(struct vki_timespec
));
2050 *flags
|= SfMayBlock
;
2055 PRINT("kevent64 ret %ld dst %#lx (%zu)", RES
, ARG4
, sizeof(struct vki_kevent64
));
2057 ML_(sync_mappings
)("after", "kevent64", 0);
2058 POST_MEM_WRITE(ARG4
, RES
* sizeof(struct vki_kevent64
));
2063 Addr pthread_starter
= 0;
2064 Addr wqthread_starter
= 0;
2065 SizeT pthread_structsize
= 0;
2066 SizeT pthread_tsd_offset
= 0;
2068 PRE(bsdthread_register
)
2070 #if DARWIN_VERS >= DARWIN_10_12
2071 PRINT("bsdthread_register( %#lx, %#lx, %lu, %#lx, %#lx, %#lx, %#lx )",
2072 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
);
2073 PRE_REG_READ7(int,"__bsdthread_register", void *,"threadstart",
2074 void *,"wqthread", size_t,"pthsize",
2075 void *,"stack_addr_hint", void *,"targetconc_ptr",
2076 uint32_t,"dispatchqueue_offset", uint32_t,"tsd_offset");
2078 PRINT("bsdthread_register( %#lx, %#lx, %lu )", ARG1
, ARG2
, ARG3
);
2079 PRE_REG_READ3(int,"__bsdthread_register", void *,"threadstart",
2080 void *,"wqthread", size_t,"pthsize");
2083 pthread_starter
= ARG1
;
2084 wqthread_starter
= ARG2
;
2085 pthread_structsize
= ARG3
;
2086 #if DARWIN_VERS >= DARWIN_10_12
2089 uint64_t dispatch_queue_offset
;
2091 uint32_t tsd_offset
;
2092 uint32_t return_to_kernel_offset
;
2093 uint32_t mach_thread_self_offset
;
2094 } __attribute__ ((packed
)) _pthread_registration_data
;
2096 pthread_tsd_offset
= ((_pthread_registration_data
*) ARG4
)->tsd_offset
;
2098 ARG1
= (Word
)&pthread_hijack_asm
;
2099 ARG2
= (Word
)&wqthread_hijack_asm
;
2104 PRINT("workq_open()");
2105 PRE_REG_READ0(int, "workq_open");
2107 // This creates lots of threads and thread stacks under the covers,
2108 // but we ignore them all until some work item starts running on it.
2111 static const HChar
*workqop_name(int op
)
2114 case VKI_WQOPS_QUEUE_ADD
: return "QUEUE_ADD";
2115 case VKI_WQOPS_QUEUE_REMOVE
: return "QUEUE_REMOVE";
2116 case VKI_WQOPS_THREAD_RETURN
: return "THREAD_RETURN";
2117 case VKI_WQOPS_THREAD_SETCONC
: return "THREAD_SETCONC";
2118 case VKI_WQOPS_QUEUE_NEWSPISUPP
: return "QUEUE_NEWSPISUPP";
2119 case VKI_WQOPS_QUEUE_REQTHREADS
: return "QUEUE_REQTHREADS";
2120 case VKI_WQOPS_QUEUE_REQTHREADS2
: return "QUEUE_REQTHREADS2";
2121 case VKI_WQOPS_THREAD_KEVENT_RETURN
: return "THREAD_KEVENT_RETURN";
2122 case VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY
: return "SET_EVENT_MANAGER_PRIORITY";
2123 case VKI_WQOPS_THREAD_WORKLOOP_RETURN
: return "THREAD_WORKLOOP_RETURN";
2124 case VKI_WQOPS_SHOULD_NARROW
: return "SHOULD_NARROW";
2125 default: return "?";
2132 PRINT("workq_ops( %ld(%s), %#lx, %ld )", SARG1
, workqop_name(ARG1
), ARG2
,
2134 PRE_REG_READ3(int,"workq_ops", int,"options", void *,"item",
2138 case VKI_WQOPS_QUEUE_ADD
:
2139 case VKI_WQOPS_QUEUE_REMOVE
:
2140 // GrP fixme need anything here?
2141 // GrP fixme may block?
2143 case VKI_WQOPS_THREAD_RETURN
: {
2144 // The interesting case. The kernel will do one of two things:
2145 // 1. Return normally. We continue; libc proceeds to stop the thread.
2146 // V does nothing special here.
2147 // 2. Jump to wqthread_hijack. This wipes the stack and runs a
2148 // new work item, and never returns from workq_ops.
2149 // V handles this by longjmp() from wqthread_hijack back to the
2150 // scheduler, which continues at the new client SP/IP/state.
2151 // This works something like V's signal handling.
2152 // To the tool, this looks like workq_ops() sometimes returns
2153 // to a strange address.
2154 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
2155 tst
->os_state
.wq_jmpbuf_valid
= True
;
2156 *flags
|= SfMayBlock
; // GrP fixme true?
2159 case VKI_WQOPS_THREAD_SETCONC
:
2160 // RK fixme need anything here?
2161 // RK fixme may block?
2163 case VKI_WQOPS_QUEUE_NEWSPISUPP
:
2164 // JRS don't think we need to do anything here -- this just checks
2165 // whether some newer functionality is supported
2167 case VKI_WQOPS_QUEUE_REQTHREADS
:
2168 case VKI_WQOPS_QUEUE_REQTHREADS2
:
2169 // JRS uh, looks like it queues up a bunch of threads, or some such?
2170 *flags
|= SfMayBlock
; // the kernel sources take a spinlock, so play safe
2172 case VKI_WQOPS_THREAD_KEVENT_RETURN
:
2173 // RK fixme need anything here?
2174 // perhaps similar to VKI_WQOPS_THREAD_RETURN above?
2176 case VKI_WQOPS_SET_EVENT_MANAGER_PRIORITY
:
2177 // RK fixme this just sets scheduling priorities - don't think we need
2178 // to do anything here
2180 case VKI_WQOPS_THREAD_WORKLOOP_RETURN
:
2181 case VKI_WQOPS_SHOULD_NARROW
:
2182 // RK fixme need anything here?
2183 // RK fixme may block?
2186 VG_(printf
)("UNKNOWN workq_ops option %ld\n", ARG1
);
2192 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
2193 tst
->os_state
.wq_jmpbuf_valid
= False
;
2195 case VKI_WQOPS_THREAD_RETURN
:
2196 ML_(sync_mappings
)("after", "workq_ops(THREAD_RETURN)", 0);
2198 case VKI_WQOPS_QUEUE_REQTHREADS
:
2199 ML_(sync_mappings
)("after", "workq_ops(QUEUE_REQTHREADS)", 0);
2201 case VKI_WQOPS_QUEUE_REQTHREADS2
:
2202 ML_(sync_mappings
)("after", "workq_ops(QUEUE_REQTHREADS2)", 0);
2213 PRINT("__mac_syscall( %#lx(%s), %ld, %#lx )",
2214 ARG1
, (HChar
*)ARG1
, SARG2
, ARG3
);
2215 PRE_REG_READ3(int,"__mac_syscall", char *,"policy",
2216 int,"call", void *,"arg");
2218 // GrP fixme check call's arg?
2219 // GrP fixme check policy?
2223 /* Not like syswrap-generic's sys_exit, which exits only one thread.
2224 More like syswrap-generic's sys_exit_group. */
2229 PRINT("darwin exit( %ld )", SARG1
);
2230 PRE_REG_READ1(void, "exit", int, status
);
2232 /* A little complex; find all the threads with the same threadgroup
2233 as this one (including this one), and mark them to exit */
2234 for (t
= 1; t
< VG_N_THREADS
; t
++) {
2235 if ( /* not alive */
2236 VG_(threads
)[t
].status
== VgTs_Empty
2237 /* GrP fixme zombie? */
2241 VG_(threads
)[t
].exitreason
= VgSrc_ExitProcess
;
2242 VG_(threads
)[t
].os_state
.exitcode
= ARG1
;
2245 VG_(get_thread_out_of_syscall
)(t
); /* unblock it, if blocked */
2248 /* We have to claim the syscall already succeeded. */
2249 SET_STATUS_Success(0);
2255 PRINT("sigaction ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
2256 PRE_REG_READ3(long, "sigaction",
2257 int, signum
, vki_sigaction_toK_t
*, act
,
2258 vki_sigaction_fromK_t
*, oldact
);
2261 vki_sigaction_toK_t
*sa
= (vki_sigaction_toK_t
*)ARG2
;
2262 PRE_MEM_READ( "sigaction(act->sa_handler)",
2263 (Addr
)&sa
->ksa_handler
, sizeof(sa
->ksa_handler
));
2264 PRE_MEM_READ( "sigaction(act->sa_mask)",
2265 (Addr
)&sa
->sa_mask
, sizeof(sa
->sa_mask
));
2266 PRE_MEM_READ( "sigaction(act->sa_flags)",
2267 (Addr
)&sa
->sa_flags
, sizeof(sa
->sa_flags
));
2270 PRE_MEM_WRITE( "sigaction(oldact)",
2271 ARG3
, sizeof(vki_sigaction_fromK_t
));
2273 SET_STATUS_from_SysRes(
2274 VG_(do_sys_sigaction
)(ARG1
, (const vki_sigaction_toK_t
*)ARG2
,
2275 (vki_sigaction_fromK_t
*)ARG3
)
2281 if (RES
== 0 && ARG3
!= 0)
2282 POST_MEM_WRITE( ARG3
, sizeof(vki_sigaction_fromK_t
));
2288 PRINT("__pthread_kill ( %#lx, %ld )", ARG1
, SARG2
);
2289 PRE_REG_READ2(long, "__pthread_kill", vki_pthread_t
*, thread
, int, sig
);
2293 PRE(__pthread_sigmask
)
2295 // arguments are identical to sigprocmask (how, sigset_t*, sigset_t*).
2297 PRINT("__pthread_sigmask ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
2298 PRE_REG_READ3(long, "__pthread_sigmask",
2299 int, how
, vki_sigset_t
*, set
, vki_sigset_t
*, oldset
);
2301 PRE_MEM_READ( "__pthread_sigmask(set)", ARG2
, sizeof(vki_sigset_t
));
2303 PRE_MEM_WRITE( "__pthread_sigmask(oldset)", ARG3
, sizeof(vki_sigset_t
));
2305 /* Massage ARG1 ('how'). If ARG2 (the new mask) is NULL then the
2306 value of 'how' is irrelevant, and it appears that Darwin's libc
2307 passes zero, which is not equal to any of
2308 SIG_{BLOCK,UNBLOCK,SETMASK}. This causes
2309 VG_(do_sys_sigprocmask) to complain, since it checks the 'how'
2310 value independently of the other args. Solution: in this case,
2311 simply pass a valid (but irrelevant) value for 'how'. */
2312 /* Also, in this case the new set is passed to the kernel by
2313 reference, not value, as in some other sigmask related Darwin
2316 if (ARG2
== 0 /* the new-set is NULL */
2317 && ARG1
!= VKI_SIG_BLOCK
2318 && ARG1
!= VKI_SIG_UNBLOCK
&& ARG1
!= VKI_SIG_SETMASK
) {
2319 arg1
= VKI_SIG_SETMASK
;
2321 SET_STATUS_from_SysRes(
2322 VG_(do_sys_sigprocmask
) ( tid
, arg1
, (vki_sigset_t
*)ARG2
,
2323 (vki_sigset_t
*)ARG3
)
2327 *flags
|= SfPollAfter
;
2329 POST(__pthread_sigmask
)
2332 if (RES
== 0 && ARG3
!= 0)
2333 POST_MEM_WRITE( ARG3
, sizeof(vki_sigset_t
));
2337 // SYS___sigwait 330
2338 // int sigwait(const sigset_t * __restrict, int * __restrict) __DARWIN_ALIAS_C(sigwait);
2341 *flags
|= SfMayBlock
;
2342 PRINT("sys_sigwait ( %#" FMT_REGWORD
"x, %#" FMT_REGWORD
"x )",
2344 PRE_REG_READ2(int, "sigwait",
2345 const vki_sigset_t
*, set
, int *, sig
);
2347 PRE_MEM_READ( "sigwait(set)", ARG1
, sizeof(vki_sigset_t
));
2350 PRE_MEM_WRITE( "sigwait(sig)", ARG2
, sizeof(int));
2357 POST_MEM_WRITE( ARG2
, sizeof(int));
2361 PRE(__pthread_canceled
)
2363 *flags
|= SfMayBlock
; /* might kill this thread??? */
2364 /* I don't think so -- I think it just changes the cancellation
2365 state. But taking no chances. */
2366 PRINT("__pthread_canceled ( %#lx )", ARG1
);
2367 PRE_REG_READ1(long, "__pthread_canceled", void*, arg1
);
2371 PRE(__pthread_markcancel
)
2373 *flags
|= SfMayBlock
; /* might kill this thread??? */
2374 PRINT("__pthread_markcancel ( %#lx )", ARG1
);
2375 PRE_REG_READ1(long, "__pthread_markcancel", void*, arg1
);
2376 /* Just let it go through. No idea if this is correct. */
2380 PRE(__disable_threadsignal
)
2383 PRINT("__disable_threadsignal(%ld, %ld, %ld)", SARG1
, SARG2
, SARG3
);
2384 /* I don't think this really looks at its arguments. So don't
2385 bother to check them. */
2387 VG_(sigfillset
)( &set
);
2388 SET_STATUS_from_SysRes(
2389 VG_(do_sys_sigprocmask
) ( tid
, VKI_SIG_BLOCK
, &set
, NULL
)
2392 /* We don't expect that blocking all signals for this thread could
2393 cause any more to be delivered (how could it?), but just in case
2396 *flags
|= SfPollAfter
;
2400 PRE(__pthread_chdir
)
2402 PRINT("__pthread_chdir ( %#lx(%s) )", ARG1
, (HChar
*)ARG1
);
2403 PRE_REG_READ1(long, "__pthread_chdir", const char *, path
);
2404 PRE_MEM_RASCIIZ( "__pthread_chdir(path)", ARG1
);
2409 PRE(__pthread_fchdir
)
2411 PRINT("__pthread_fchdir ( %lu )", ARG1
);
2412 PRE_REG_READ1(long, "__pthread_fchdir", unsigned int, fd
);
2418 PRINT("kdebug_trace(%ld, %ld, %ld, %ld, %ld, %ld)",
2419 SARG1
, SARG2
, SARG3
, SARG4
, SARG5
, SARG6
);
2421 Don't check anything - some clients pass fewer arguments.
2422 PRE_REG_READ6(long, "kdebug_trace",
2423 int,"code", int,"arg1", int,"arg2",
2424 int,"arg3", int,"arg4", int,"arg5");
2431 PRINT("seteuid(%lu)", ARG1
);
2432 PRE_REG_READ1(long, "seteuid", vki_uid_t
, "uid");
2438 PRINT("setegid(%lu)", ARG1
);
2439 PRE_REG_READ1(long, "setegid", vki_uid_t
, "uid");
2444 PRINT("settid(%lu, %lu)", ARG1
, ARG2
);
2445 PRE_REG_READ2(long, "settid", vki_uid_t
, "uid", vki_gid_t
, "gid");
2451 PRE_REG_READ0(long, gettid
);
2454 /* XXX need to check whether we need POST operations for
2455 * waitevent, watchevent, modwatch -- jpeach
2459 PRINT("watchevent(%#lx, %#lx)", ARG1
, ARG2
);
2460 PRE_REG_READ2(long, "watchevent",
2461 vki_eventreq
*, "event", unsigned int, "eventmask");
2463 PRE_MEM_READ("watchevent(event)", ARG1
, sizeof(vki_eventreq
));
2464 PRE_MEM_READ("watchevent(eventmask)", ARG2
, sizeof(unsigned int));
2465 *flags
|= SfMayBlock
;
2468 #define WAITEVENT_FAST_POLL ((Addr)(struct timeval *)-1)
2471 PRINT("waitevent(%#lx, %#lx)", ARG1
, ARG2
);
2472 PRE_REG_READ2(long, "waitevent",
2473 vki_eventreq
*, "event", struct timeval
*, "timeout");
2474 PRE_MEM_WRITE("waitevent(event)", ARG1
, sizeof(vki_eventreq
));
2476 if (ARG2
&& ARG2
!= WAITEVENT_FAST_POLL
) {
2477 PRE_timeval_READ("waitevent(timeout)", ARG2
);
2480 /* XXX ((timeval*)-1) is valid for ARG2 -- jpeach */
2481 *flags
|= SfMayBlock
;
2486 POST_MEM_WRITE(ARG1
, sizeof(vki_eventreq
));
2491 PRINT("modwatch(%#lx, %#lx)", ARG1
, ARG2
);
2492 PRE_REG_READ2(long, "modwatch",
2493 vki_eventreq
*, "event", unsigned int, "eventmask");
2495 PRE_MEM_READ("modwatch(event)", ARG1
, sizeof(vki_eventreq
));
2496 PRE_MEM_READ("modwatch(eventmask)", ARG2
, sizeof(unsigned int));
2501 PRINT("getxattr(%#lx(%s), %#lx(%s), %#lx, %lu, %lu, %ld)",
2502 ARG1
, (HChar
*)ARG1
, ARG2
, (HChar
*)ARG2
, ARG3
, ARG4
, ARG5
, SARG6
);
2504 PRE_REG_READ6(vki_ssize_t
, "getxattr",
2505 const char *, path
, char *, name
, void *, value
,
2506 vki_size_t
, size
, uint32_t, position
, int, options
);
2507 PRE_MEM_RASCIIZ("getxattr(path)", ARG1
);
2508 PRE_MEM_RASCIIZ("getxattr(name)", ARG2
);
2510 PRE_MEM_WRITE( "getxattr(value)", ARG3
, ARG4
);
2515 vg_assert((vki_ssize_t
)RES
>= 0);
2517 POST_MEM_WRITE(ARG3
, (vki_ssize_t
)RES
);
2522 PRINT("fgetxattr(%ld, %#lx(%s), %#lx, %lu, %lu, %ld)",
2523 SARG1
, ARG2
, (HChar
*)ARG2
, ARG3
, ARG4
, ARG5
, SARG6
);
2525 PRE_REG_READ6(vki_ssize_t
, "fgetxattr",
2526 int, fd
, char *, name
, void *, value
,
2527 vki_size_t
, size
, uint32_t, position
, int, options
);
2528 PRE_MEM_RASCIIZ("getxattr(name)", ARG2
);
2529 PRE_MEM_WRITE( "getxattr(value)", ARG3
, ARG4
);
2534 vg_assert((vki_ssize_t
)RES
>= 0);
2535 POST_MEM_WRITE(ARG3
, (vki_ssize_t
)RES
);
2540 PRINT("setxattr ( %#lx(%s), %#lx(%s), %#lx, %lu, %lu, %ld )",
2541 ARG1
, (HChar
*)ARG1
, ARG2
, (HChar
*)ARG2
, ARG3
, ARG4
, ARG5
, SARG6
);
2542 PRE_REG_READ6(int, "setxattr",
2543 const char *,"path", char *,"name", void *,"value",
2544 vki_size_t
,"size", uint32_t,"position", int,"options" );
2546 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1
);
2547 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2
);
2548 PRE_MEM_READ( "setxattr(value)", ARG3
, ARG4
);
2554 PRINT( "fsetxattr ( %ld, %#lx(%s), %#lx, %lu, %lu, %ld )",
2555 SARG1
, ARG2
, (HChar
*)ARG2
, ARG3
, ARG4
, ARG5
, SARG6
);
2556 PRE_REG_READ6(int, "fsetxattr",
2557 int,"fd", char *,"name", void *,"value",
2558 vki_size_t
,"size", uint32_t,"position", int,"options" );
2560 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2
);
2561 PRE_MEM_READ( "fsetxattr(value)", ARG3
, ARG4
);
2567 PRINT( "removexattr ( %#lx(%s), %#lx(%s), %ld )",
2568 ARG1
, (HChar
*)ARG1
, ARG2
, (HChar
*)ARG2
, SARG3
);
2569 PRE_REG_READ3(int, "removexattr",
2570 const char*, "path", char*, "attrname", int, "options");
2571 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1
);
2572 PRE_MEM_RASCIIZ( "removexattr(attrname)", ARG2
);
2578 PRINT( "fremovexattr ( %ld, %#lx(%s), %ld )",
2579 SARG1
, ARG2
, (HChar
*)ARG2
, SARG3
);
2580 PRE_REG_READ3(int, "fremovexattr",
2581 int, "fd", char*, "attrname", int, "options");
2582 PRE_MEM_RASCIIZ( "removexattr(attrname)", ARG2
);
2588 PRINT( "listxattr ( %#lx(%s), %#lx, %lu, %ld )",
2589 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, SARG4
);
2590 PRE_REG_READ4 (long, "listxattr",
2591 const char *,"path", char *,"namebuf",
2592 vki_size_t
,"size", int,"options" );
2594 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1
);
2595 PRE_MEM_WRITE( "listxattr(namebuf)", ARG2
, ARG3
);
2596 *flags
|= SfMayBlock
;
2601 vg_assert((vki_ssize_t
)RES
>= 0);
2602 POST_MEM_WRITE( ARG2
, (vki_ssize_t
)RES
);
2608 PRINT( "flistxattr ( %ld, %#lx, %lu, %ld )",
2609 SARG1
, ARG2
, ARG3
, SARG4
);
2610 PRE_REG_READ4 (long, "flistxattr",
2611 int, "fd", char *,"namebuf",
2612 vki_size_t
,"size", int,"options" );
2613 PRE_MEM_WRITE( "flistxattr(namebuf)", ARG2
, ARG3
);
2614 *flags
|= SfMayBlock
;
2619 vg_assert((vki_ssize_t
)RES
>= 0);
2620 POST_MEM_WRITE( ARG2
, (vki_ssize_t
)RES
);
2627 PRINT("shmat ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
2628 PRE_REG_READ3(long, "shmat",
2629 int, shmid
, const void *, shmaddr
, int, shmflg
);
2630 arg2tmp
= ML_(generic_PRE_sys_shmat
)(tid
, ARG1
,ARG2
,ARG3
);
2632 SET_STATUS_Failure( VKI_EINVAL
);
2634 ARG2
= arg2tmp
; // used in POST
2638 ML_(generic_POST_sys_shmat
)(tid
, RES
,ARG1
,ARG2
,ARG3
);
2643 PRINT("shmctl ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
2644 PRE_REG_READ3(long, "shmctl",
2645 int, shmid
, int, cmd
, struct vki_shmid_ds
*, buf
);
2646 ML_(generic_PRE_sys_shmctl
)(tid
, ARG1
,ARG2
,ARG3
);
2650 ML_(generic_POST_sys_shmctl
)(tid
, RES
,ARG1
,ARG2
,ARG3
);
2655 PRINT("shmdt ( %#lx )",ARG1
);
2656 PRE_REG_READ1(long, "shmdt", const void *, shmaddr
);
2657 if (!ML_(generic_PRE_sys_shmdt
)(tid
, ARG1
))
2658 SET_STATUS_Failure( VKI_EINVAL
);
2662 ML_(generic_POST_sys_shmdt
)(tid
, RES
,ARG1
);
2667 PRINT("shmget ( %ld, %lu, %ld )", SARG1
, ARG2
, SARG3
);
2668 PRE_REG_READ3(long, "shmget", vki_key_t
, key
, vki_size_t
, size
, int, shmflg
);
2673 PRINT("shm_open(%#lx(%s), %ld, %lu)", ARG1
, (HChar
*)ARG1
, SARG2
, ARG3
);
2674 PRE_REG_READ3(long, "shm_open",
2675 const char *,"name", int,"flags", vki_mode_t
,"mode");
2677 PRE_MEM_RASCIIZ( "shm_open(filename)", ARG1
);
2679 *flags
|= SfMayBlock
;
2684 if (!ML_(fd_allowed
)(RES
, "shm_open", tid
, True
)) {
2686 SET_STATUS_Failure( VKI_EMFILE
);
2688 if (VG_(clo_track_fds
))
2689 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*)ARG1
);
2695 *flags
|= SfMayBlock
;
2696 PRINT("shm_unlink ( %#lx(%s) )", ARG1
, (HChar
*)ARG1
);
2697 PRE_REG_READ1(long, "shm_unlink", const char *, pathname
);
2698 PRE_MEM_RASCIIZ( "shm_unlink(pathname)", ARG1
);
2702 /* My reading of the man page suggests that a call may cause memory
2703 mappings to change: "if no references exist at the time of the
2704 call to shm_unlink(), the resources are reclaimed immediately".
2705 So we need to resync here, sigh. */
2706 ML_(sync_mappings
)("after", "shm_unlink", 0);
2711 PRINT("stat_extended( %#lx(%s), %#lx, %#lx, %#lx )",
2712 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
);
2713 PRE_REG_READ4(int, "stat_extended", char *, file_name
, struct stat
*, buf
,
2714 void *, fsacl
, vki_size_t
*, fsacl_size
);
2715 PRE_MEM_RASCIIZ( "stat_extended(file_name)", ARG1
);
2716 PRE_MEM_WRITE( "stat_extended(buf)", ARG2
, sizeof(struct vki_stat
) );
2717 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2718 PRE_MEM_WRITE("stat_extended(fsacl)", ARG3
, *(vki_size_t
*)ARG4
);
2719 PRE_MEM_READ( "stat_extended(fsacl_size)", ARG4
, sizeof(vki_size_t
) );
2723 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat
) );
2724 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2725 POST_MEM_WRITE( ARG3
, *(vki_size_t
*)ARG4
);
2726 POST_MEM_WRITE( ARG4
, sizeof(vki_size_t
) );
2732 PRINT("lstat_extended( %#lx(%s), %#lx, %#lx, %#lx )",
2733 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
);
2734 PRE_REG_READ4(int, "lstat_extended", char *, file_name
, struct stat
*, buf
,
2735 void *, fsacl
, vki_size_t
*, fsacl_size
);
2736 PRE_MEM_RASCIIZ( "lstat_extended(file_name)", ARG1
);
2737 PRE_MEM_WRITE( "lstat_extended(buf)", ARG2
, sizeof(struct vki_stat
) );
2738 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2739 PRE_MEM_WRITE("lstat_extended(fsacl)", ARG3
, *(vki_size_t
*)ARG4
);
2740 PRE_MEM_READ( "lstat_extended(fsacl_size)", ARG4
, sizeof(vki_size_t
) );
2742 POST(lstat_extended
)
2744 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat
) );
2745 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2746 POST_MEM_WRITE( ARG3
, *(vki_size_t
*)ARG4
);
2747 POST_MEM_WRITE( ARG4
, sizeof(vki_size_t
) );
2753 PRINT("fstat_extended( %ld, %#lx, %#lx, %#lx )",
2754 SARG1
, ARG2
, ARG3
, ARG4
);
2755 PRE_REG_READ4(int, "fstat_extended", int, fd
, struct stat
*, buf
,
2756 void *, fsacl
, vki_size_t
*, fsacl_size
);
2757 PRE_MEM_WRITE( "fstat_extended(buf)", ARG2
, sizeof(struct vki_stat
) );
2758 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2759 PRE_MEM_WRITE("fstat_extended(fsacl)", ARG3
, *(vki_size_t
*)ARG4
);
2760 PRE_MEM_READ( "fstat_extended(fsacl_size)", ARG4
, sizeof(vki_size_t
) );
2762 POST(fstat_extended
)
2764 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat
) );
2765 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2766 POST_MEM_WRITE( ARG3
, *(vki_size_t
*)ARG4
);
2767 POST_MEM_WRITE( ARG4
, sizeof(vki_size_t
) );
2771 PRE(stat64_extended
)
2773 PRINT("stat64_extended( %#lx(%s), %#lx, %#lx, %#lx )",
2774 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
);
2775 PRE_REG_READ4(int, "stat64_extended", char *, file_name
, struct stat64
*, buf
,
2776 void *, fsacl
, vki_size_t
*, fsacl_size
);
2777 PRE_MEM_RASCIIZ( "stat64_extended(file_name)", ARG1
);
2778 PRE_MEM_WRITE( "stat64_extended(buf)", ARG2
, sizeof(struct vki_stat64
) );
2779 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2780 PRE_MEM_WRITE("stat64_extended(fsacl)", ARG3
, *(vki_size_t
*)ARG4
);
2781 PRE_MEM_READ( "stat64_extended(fsacl_size)", ARG4
, sizeof(vki_size_t
) );
2783 POST(stat64_extended
)
2785 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat64
) );
2786 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2787 POST_MEM_WRITE( ARG3
, *(vki_size_t
*)ARG4
);
2788 POST_MEM_WRITE( ARG4
, sizeof(vki_size_t
) );
2792 PRE(lstat64_extended
)
2794 PRINT("lstat64_extended( %#lx(%s), %#lx, %#lx, %#lx )",
2795 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
);
2796 PRE_REG_READ4(int, "lstat64_extended", char *, file_name
, struct stat64
*, buf
,
2797 void *, fsacl
, vki_size_t
*, fsacl_size
);
2798 PRE_MEM_RASCIIZ( "lstat64_extended(file_name)", ARG1
);
2799 PRE_MEM_WRITE( "lstat64_extended(buf)", ARG2
, sizeof(struct vki_stat64
) );
2800 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2801 PRE_MEM_WRITE( "lstat64_extended(fsacl)", ARG3
, *(vki_size_t
*)ARG4
);
2802 PRE_MEM_READ( "lstat64_extended(fsacl_size)", ARG4
, sizeof(vki_size_t
) );
2804 POST(lstat64_extended
)
2806 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat64
) );
2807 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2808 POST_MEM_WRITE( ARG3
, *(vki_size_t
*)ARG4
);
2809 POST_MEM_WRITE( ARG4
, sizeof(vki_size_t
) );
2813 PRE(fstat64_extended
)
2815 PRINT("fstat64_extended( %ld, %#lx, %#lx, %#lx )",
2816 SARG1
, ARG2
, ARG3
, ARG4
);
2817 PRE_REG_READ4(int, "fstat64_extended", int, fd
, struct stat64
*, buf
,
2818 void *, fsacl
, vki_size_t
*, fsacl_size
);
2819 PRE_MEM_WRITE( "fstat64_extended(buf)", ARG2
, sizeof(struct vki_stat64
) );
2820 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2821 PRE_MEM_WRITE("fstat64_extended(fsacl)", ARG3
, *(vki_size_t
*)ARG4
);
2822 PRE_MEM_READ( "fstat64_extended(fsacl_size)", ARG4
, sizeof(vki_size_t
) );
2824 POST(fstat64_extended
)
2826 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat64
) );
2827 if (ML_(safe_to_deref
)( (void*)ARG4
, sizeof(vki_size_t
) ))
2828 POST_MEM_WRITE( ARG3
, *(vki_size_t
*)ARG4
);
2829 POST_MEM_WRITE( ARG4
, sizeof(vki_size_t
) );
2833 PRE(fchmod_extended
)
2835 /* DDD: Note: this is not really correct. Handling of
2836 chmod_extended is broken in the same way. */
2837 PRINT("fchmod_extended ( %lu, %lu, %lu, %lu, %#lx )",
2838 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
2839 PRE_REG_READ5(long, "fchmod_extended",
2840 unsigned int, fildes
,
2844 void* /*really,user_addr_t*/, xsecurity
);
2845 /* DDD: relative to the xnu sources (kauth_copyinfilesec), this
2846 is just way wrong. [The trouble is with the size, which depends on a
2847 non-trival kernel computation] */
2849 PRE_MEM_READ( "fchmod_extended(xsecurity)", ARG5
,
2850 sizeof(struct vki_kauth_filesec
) );
2856 /* DDD: Note: this is not really correct. Handling of
2857 fchmod_extended is broken in the same way. */
2858 PRINT("chmod_extended ( %#lx(%s), %ld, %ld, %ld, %#lx )",
2859 ARG1
, ARG1
? (HChar
*)ARG1
: "(null)", ARG2
, ARG3
, ARG4
, ARG5
);
2860 PRE_REG_READ5(long, "chmod_extended",
2861 unsigned int, fildes
,
2865 void* /*really,user_addr_t*/, xsecurity
);
2866 PRE_MEM_RASCIIZ("chmod_extended(path)", ARG1
);
2867 /* DDD: relative to the xnu sources (kauth_copyinfilesec), this
2868 is just way wrong. [The trouble is with the size, which depends on a
2869 non-trival kernel computation] */
2871 PRE_MEM_READ( "chmod_extended(xsecurity)", ARG5
,
2872 sizeof(struct vki_kauth_filesec
) );
2878 /* DDD: Note: this is not really correct. Handling of
2879 {,f}chmod_extended is broken in the same way. */
2880 PRINT("open_extended ( %#lx(%s), %ld, %lu, %lu, %lu, %#lx )",
2881 ARG1
, ARG1
? (HChar
*)ARG1
: "(null)",
2882 SARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
2883 PRE_REG_READ6(long, "open_extended",
2889 void* /*really,user_addr_t*/, xsecurity
);
2890 PRE_MEM_RASCIIZ("open_extended(path)", ARG1
);
2891 /* DDD: relative to the xnu sources (kauth_copyinfilesec), this
2892 is just way wrong. [The trouble is with the size, which depends on a
2893 non-trival kernel computation] */
2895 PRE_MEM_READ( "open_extended(xsecurity)", ARG6
,
2896 sizeof(struct vki_kauth_filesec
) );
2899 // This is a ridiculous syscall. Specifically, the 'entries' argument points
2900 // to a buffer that contains one or more 'accessx_descriptor' structs followed
2901 // by one or more strings. Each accessx_descriptor contains a field,
2902 // 'ad_name_offset', which points to one of the strings (or it can contain
2903 // zero which means "reuse the string from the previous accessx_descriptor").
2905 // What's really ridiculous is that we are only given the size of the overall
2906 // buffer, not the number of accessx_descriptors, nor the number of strings.
2907 // The kernel determines the number of accessx_descriptors by walking through
2908 // them one by one, checking that the ad_name_offset points within the buffer,
2909 // past the current point (or that it's a zero, unless its the first
2910 // descriptor); if so, we assume that this really is an accessx_descriptor,
2911 // if not, we assume we've hit the strings section. Gah.
2913 // This affects us here because number of entries in the 'results' buffer is
2914 // determined by the number of accessx_descriptors. So we have to know that
2915 // number in order to do PRE_MEM_WRITE/POST_MEM_WRITE of 'results'. In
2916 // practice, we skip the PRE_MEM_WRITE step because it's easier to do the
2917 // computation after the syscall has succeeded, because the kernel will have
2918 // checked for all the zillion different ways this syscall can fail, and we'll
2919 // know we have a well-formed 'entries' buffer. This means we might miss some
2920 // uses of unaddressable memory but oh well.
2922 PRE(access_extended
)
2924 PRINT("access_extended( %#lx(%s), %lu, %#lx, %lu )",
2925 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
);
2926 // XXX: the accessx_descriptor struct contains padding, so this can cause
2927 // unnecessary undefined value errors. But you arguably shouldn't be
2928 // passing undefined values to the kernel anyway...
2929 PRE_REG_READ4(int, "access_extended", void *, entries
, vki_size_t
, size
,
2930 vki_errno_t
*, results
, vki_uid_t
*, uid
);
2931 PRE_MEM_READ("access_extended(entries)", ARG1
, ARG2
);
2933 // XXX: as mentioned above, this check is too hard to do before the
2935 //PRE_MEM_WRITE("access_extended(results)", ARG3, ??? );
2937 POST(access_extended
)
2939 // 'n_descs' is the number of descriptors we think are in the buffer. We
2940 // start with the maximum possible value, which occurs if we have the
2941 // shortest possible string section. The shortest string section allowed
2942 // consists of a single one-char string (plus the NUL char). Hence the
2944 struct vki_accessx_descriptor
* entries
= (struct vki_accessx_descriptor
*)ARG1
;
2946 Int n_descs
= (size
- 2) / sizeof(struct accessx_descriptor
);
2947 Int i
; // Current position in the descriptors section array.
2948 Int u
; // Upper bound on the length of the descriptors array
2949 // (recomputed each time around the loop)
2950 vg_assert(n_descs
> 0);
2952 // Step through the descriptors, lowering 'n_descs' until we know we've
2953 // reached the string section.
2954 for (i
= 0; True
; i
++) {
2955 // If we're past our estimate, we must be one past the end of the
2956 // descriptors section (ie. at the start of the string section). Stop.
2960 // Get the array index for the string, but pretend momentarily that it
2961 // is actually another accessx_descriptor. That gives us an upper bound
2962 // on the length of the descriptors section. (Unless the index is zero,
2963 // in which case we have no new info.)
2964 u
= entries
[i
].ad_name_offset
/ sizeof(struct vki_accessx_descriptor
);
2970 // If the upper bound is below our current estimate, revise that
2971 // estimate downwards.
2977 vg_assert(n_descs
<= VKI_ACCESSX_MAX_DESCRIPTORS
);
2979 POST_MEM_WRITE( ARG3
, n_descs
* sizeof(vki_errno_t
) );
2985 PRINT("chflags ( %#lx(%s), %lu )", ARG1
, (HChar
*)ARG1
, ARG2
);
2986 PRE_REG_READ2(int, "chflags", const char *,path
, unsigned int,flags
);
2987 PRE_MEM_RASCIIZ("chflags(path)", ARG1
);
2989 // GrP fixme sanity-check flags value?
2994 PRINT("fchflags ( %ld, %lu )", SARG1
, ARG2
);
2995 PRE_REG_READ2(int, "fchflags", int,fd
, unsigned int,flags
);
2997 // GrP fixme sanity-check flags value?
3002 PRINT("stat64 ( %#lx(%s), %#lx )", ARG1
, (HChar
*)ARG1
, ARG2
);
3003 PRE_REG_READ2(long, "stat", const char *,path
, struct stat64
*,buf
);
3004 PRE_MEM_RASCIIZ("stat64(path)", ARG1
);
3005 PRE_MEM_WRITE( "stat64(buf)", ARG2
, sizeof(struct vki_stat64
) );
3009 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat64
) );
3014 PRINT("lstat64 ( %#lx(%s), %#lx )", ARG1
, (HChar
*)ARG1
, ARG2
);
3015 PRE_REG_READ2(long, "stat", const char *,path
, struct stat64
*,buf
);
3016 PRE_MEM_RASCIIZ("lstat64(path)", ARG1
);
3017 PRE_MEM_WRITE( "lstat64(buf)", ARG2
, sizeof(struct vki_stat64
) );
3021 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat64
) );
3026 PRINT("fstat64 ( %lu, %#lx )", ARG1
,ARG2
);
3027 PRE_REG_READ2(long, "fstat", unsigned int, fd
, struct stat64
*, buf
);
3028 PRE_MEM_WRITE( "fstat64(buf)", ARG2
, sizeof(struct vki_stat64
) );
3032 POST_MEM_WRITE( ARG2
, sizeof(struct vki_stat64
) );
3037 PRINT("getfsstat(%#lx, %ld, %ld)", ARG1
, SARG2
, SARG3
);
3038 PRE_REG_READ3(int, "getfsstat",
3039 struct vki_statfs
*, buf
, int, bufsize
, int, flags
);
3041 // ARG2 is a BYTE SIZE
3042 PRE_MEM_WRITE("getfsstat(buf)", ARG1
, ARG2
);
3048 // RES is a STRUCT COUNT
3049 POST_MEM_WRITE(ARG1
, RES
* sizeof(struct vki_statfs
));
3055 PRINT("getfsstat64(%#lx, %ld, %ld)", ARG1
, SARG2
, SARG3
);
3056 PRE_REG_READ3(int, "getfsstat64",
3057 struct vki_statfs64
*, buf
, int, bufsize
, int, flags
);
3059 // ARG2 is a BYTE SIZE
3060 PRE_MEM_WRITE("getfsstat64(buf)", ARG1
, ARG2
);
3066 // RES is a STRUCT COUNT
3067 POST_MEM_WRITE(ARG1
, RES
* sizeof(struct vki_statfs64
));
3073 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
3074 // We are conservative and check everything, except the memory pointed to
3076 *flags
|= SfMayBlock
;
3077 PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx, %#lx )",
3078 ARG1
, (HChar
*)ARG1
, ARG2
, (HChar
*)ARG2
, ARG3
, ARG4
);
3079 PRE_REG_READ4(long, "mount",
3080 const char *, type
, const char *, dir
,
3081 int, flags
, void *, data
);
3082 PRE_MEM_RASCIIZ( "mount(type)", ARG1
);
3083 PRE_MEM_RASCIIZ( "mount(dir)", ARG2
);
3087 static void scan_attrlist(ThreadId tid
, struct vki_attrlist
*attrList
,
3088 void *attrBuf
, SizeT attrBufSize
,
3089 void (*fn
)(ThreadId
, void *attrData
, SizeT size
)
3096 static const attrspec commonattr
[] = {
3097 // This order is important.
3098 #if DARWIN_VERS >= DARWIN_10_6
3099 { ATTR_CMN_RETURNED_ATTRS
, sizeof(attribute_set_t
) },
3101 { ATTR_CMN_NAME
, -1 },
3102 { ATTR_CMN_DEVID
, sizeof(dev_t
) },
3103 { ATTR_CMN_FSID
, sizeof(fsid_t
) },
3104 { ATTR_CMN_OBJTYPE
, sizeof(fsobj_type_t
) },
3105 { ATTR_CMN_OBJTAG
, sizeof(fsobj_tag_t
) },
3106 { ATTR_CMN_OBJID
, sizeof(fsobj_id_t
) },
3107 { ATTR_CMN_OBJPERMANENTID
, sizeof(fsobj_id_t
) },
3108 { ATTR_CMN_PAROBJID
, sizeof(fsobj_id_t
) },
3109 { ATTR_CMN_SCRIPT
, sizeof(text_encoding_t
) },
3110 { ATTR_CMN_CRTIME
, sizeof(struct timespec
) },
3111 { ATTR_CMN_MODTIME
, sizeof(struct timespec
) },
3112 { ATTR_CMN_CHGTIME
, sizeof(struct timespec
) },
3113 { ATTR_CMN_ACCTIME
, sizeof(struct timespec
) },
3114 { ATTR_CMN_BKUPTIME
, sizeof(struct timespec
) },
3115 { ATTR_CMN_FNDRINFO
, 32 /*FileInfo+ExtendedFileInfo, or FolderInfo+ExtendedFolderInfo*/ },
3116 { ATTR_CMN_OWNERID
, sizeof(uid_t
) },
3117 { ATTR_CMN_GRPID
, sizeof(gid_t
) },
3118 { ATTR_CMN_ACCESSMASK
, sizeof(uint32_t) },
3119 { ATTR_CMN_NAMEDATTRCOUNT
, sizeof(uint32_t) },
3120 { ATTR_CMN_NAMEDATTRLIST
, -1 },
3121 { ATTR_CMN_FLAGS
, sizeof(uint32_t) },
3122 { ATTR_CMN_USERACCESS
, sizeof(uint32_t) },
3123 { ATTR_CMN_EXTENDED_SECURITY
, -1 },
3124 { ATTR_CMN_UUID
, sizeof(guid_t
) },
3125 { ATTR_CMN_GRPUUID
, sizeof(guid_t
) },
3126 { ATTR_CMN_FILEID
, sizeof(uint64_t) },
3127 { ATTR_CMN_PARENTID
, sizeof(uint64_t) },
3128 #if DARWIN_VERS >= DARWIN_10_6
3129 { ATTR_CMN_FULLPATH
, -1 },
3131 #if DARWIN_VERS >= DARWIN_10_8
3132 { ATTR_CMN_ADDEDTIME
, -1 },
3136 static const attrspec volattr
[] = {
3137 // This order is important.
3138 { ATTR_VOL_INFO
, 0 },
3139 { ATTR_VOL_FSTYPE
, sizeof(uint32_t) },
3140 { ATTR_VOL_SIGNATURE
, sizeof(uint32_t) },
3141 { ATTR_VOL_SIZE
, sizeof(off_t
) },
3142 { ATTR_VOL_SPACEFREE
, sizeof(off_t
) },
3143 { ATTR_VOL_SPACEAVAIL
, sizeof(off_t
) },
3144 { ATTR_VOL_MINALLOCATION
, sizeof(off_t
) },
3145 { ATTR_VOL_ALLOCATIONCLUMP
, sizeof(off_t
) },
3146 { ATTR_VOL_IOBLOCKSIZE
, sizeof(uint32_t) },
3147 { ATTR_VOL_OBJCOUNT
, sizeof(uint32_t) },
3148 { ATTR_VOL_FILECOUNT
, sizeof(uint32_t) },
3149 { ATTR_VOL_DIRCOUNT
, sizeof(uint32_t) },
3150 { ATTR_VOL_MAXOBJCOUNT
, sizeof(uint32_t) },
3151 { ATTR_VOL_MOUNTPOINT
, -1 },
3152 { ATTR_VOL_NAME
, -1 },
3153 { ATTR_VOL_MOUNTFLAGS
, sizeof(uint32_t) },
3154 { ATTR_VOL_MOUNTEDDEVICE
, -1 },
3155 { ATTR_VOL_ENCODINGSUSED
, sizeof(uint64_t) },
3156 { ATTR_VOL_CAPABILITIES
, sizeof(vol_capabilities_attr_t
) },
3157 #if DARWIN_VERS >= DARWIN_10_6
3158 { ATTR_VOL_UUID
, sizeof(uuid_t
) },
3160 { ATTR_VOL_ATTRIBUTES
, sizeof(vol_attributes_attr_t
) },
3163 static const attrspec dirattr
[] = {
3164 // This order is important.
3165 { ATTR_DIR_LINKCOUNT
, sizeof(uint32_t) },
3166 { ATTR_DIR_ENTRYCOUNT
, sizeof(uint32_t) },
3167 { ATTR_DIR_MOUNTSTATUS
, sizeof(uint32_t) },
3170 static const attrspec fileattr
[] = {
3171 // This order is important.
3172 { ATTR_FILE_LINKCOUNT
, sizeof(uint32_t) },
3173 { ATTR_FILE_TOTALSIZE
, sizeof(off_t
) },
3174 { ATTR_FILE_ALLOCSIZE
, sizeof(off_t
) },
3175 { ATTR_FILE_IOBLOCKSIZE
, sizeof(uint32_t) },
3176 { ATTR_FILE_CLUMPSIZE
, sizeof(uint32_t) },
3177 { ATTR_FILE_DEVTYPE
, sizeof(uint32_t) },
3178 { ATTR_FILE_FILETYPE
, sizeof(uint32_t) },
3179 { ATTR_FILE_FORKCOUNT
, sizeof(uint32_t) },
3180 { ATTR_FILE_FORKLIST
, -1 },
3181 { ATTR_FILE_DATALENGTH
, sizeof(off_t
) },
3182 { ATTR_FILE_DATAALLOCSIZE
, sizeof(off_t
) },
3183 { ATTR_FILE_DATAEXTENTS
, sizeof(extentrecord
) },
3184 { ATTR_FILE_RSRCLENGTH
, sizeof(off_t
) },
3185 { ATTR_FILE_RSRCALLOCSIZE
, sizeof(off_t
) },
3186 { ATTR_FILE_RSRCEXTENTS
, sizeof(extentrecord
) },
3189 static const attrspec forkattr
[] = {
3190 // This order is important.
3191 { ATTR_FORK_TOTALSIZE
, sizeof(off_t
) },
3192 { ATTR_FORK_ALLOCSIZE
, sizeof(off_t
) },
3196 static const attrspec
*attrdefs
[5] = {
3197 commonattr
, volattr
, dirattr
, fileattr
, forkattr
3203 vg_assert(attrList
->bitmapcount
== 5);
3204 VG_(memcpy
)(a
, &attrList
->commonattr
, sizeof(a
));
3206 dend
= d
+ attrBufSize
;
3208 #if DARWIN_VERS >= DARWIN_10_6
3209 // ATTR_CMN_RETURNED_ATTRS tells us what's really here, if set
3210 if (a
[0] & ATTR_CMN_RETURNED_ATTRS
) {
3211 // fixme range check this?
3212 a
[0] &= ~ATTR_CMN_RETURNED_ATTRS
;
3213 fn(tid
, d
, sizeof(attribute_set_t
));
3214 VG_(memcpy
)(a
, d
, sizeof(a
));
3218 for (g
= 0; g
< 5; g
++) {
3219 for (i
= 0; attrdefs
[g
][i
].attrBit
; i
++) {
3220 uint32_t bit
= attrdefs
[g
][i
].attrBit
;
3221 int32_t size
= attrdefs
[g
][i
].attrSize
;
3224 a
[g
] &= ~bit
; // clear bit for error check later
3226 attrreference_t
*ref
= (attrreference_t
*)d
;
3227 size
= MIN(sizeof(attrreference_t
), dend
- d
);
3229 if (size
>= sizeof(attrreference_t
) &&
3230 d
+ ref
->attr_dataoffset
< dend
)
3232 fn(tid
, d
+ ref
->attr_dataoffset
,
3233 MIN(ref
->attr_length
, dend
- (d
+ ref
->attr_dataoffset
)));
3238 size
= MIN(size
, dend
- d
);
3243 if ((uintptr_t)d
% 4) d
+= 4 - ((uintptr_t)d
% 4);
3244 if (d
> dend
) d
= dend
;
3248 // Known bits are cleared. Die if any bits are left.
3250 VG_(message
)(Vg_UserMsg
, "UNKNOWN attrlist flags %d:0x%x\n", g
, a
[g
]);
3255 static void get1attr(ThreadId tid
, void *attrData
, SizeT attrDataSize
)
3257 POST_MEM_WRITE((Addr
)attrData
, attrDataSize
);
3260 static void set1attr(ThreadId tid
, void *attrData
, SizeT attrDataSize
)
3262 PRE_MEM_READ("setattrlist(attrBuf value)", (Addr
)attrData
, attrDataSize
);
3267 PRINT("getattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)",
3268 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
3269 PRE_REG_READ5(int, "getattrlist",
3270 const char *,path
, struct vki_attrlist
*,attrList
,
3271 void *,attrBuf
, vki_size_t
,attrBufSize
, unsigned int,options
);
3272 PRE_MEM_RASCIIZ("getattrlist(path)", ARG1
);
3273 PRE_MEM_READ("getattrlist(attrList)", ARG2
, sizeof(struct vki_attrlist
));
3274 PRE_MEM_WRITE("getattrlist(attrBuf)", ARG3
, ARG4
);
3279 if (ARG4
> sizeof(vki_uint32_t
)) {
3280 // attrBuf is uint32_t size followed by attr data
3281 vki_uint32_t
*sizep
= (vki_uint32_t
*)ARG3
;
3282 POST_MEM_WRITE(ARG3
, sizeof(vki_uint32_t
));
3283 if (ARG5
& FSOPT_REPORT_FULLSIZE
) {
3284 // *sizep is bytes required for return value, including *sizep
3286 // *sizep is actual bytes returned, including *sizep
3288 scan_attrlist(tid
, (struct vki_attrlist
*)ARG2
, sizep
+1, MIN(*sizep
, ARG4
), &get1attr
);
3295 PRINT("setattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)",
3296 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
3297 PRE_REG_READ5(int, "setattrlist",
3298 const char *,path
, struct vki_attrlist
*,attrList
,
3299 void *,attrBuf
, vki_size_t
,attrBufSize
, unsigned int,options
);
3300 PRE_MEM_RASCIIZ("setattrlist(path)", ARG1
);
3301 PRE_MEM_READ("setattrlist(attrList)", ARG2
, sizeof(struct vki_attrlist
));
3302 scan_attrlist(tid
, (struct vki_attrlist
*)ARG2
, (void*)ARG3
, ARG4
, &set1attr
);
3306 PRE(getdirentriesattr
)
3308 PRINT("getdirentriesattr(%ld, %#lx, %#lx, %lu, %#lx, %#lx, %#lx, %lu)",
3309 SARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
, ARG8
);
3310 PRE_REG_READ8(int, "getdirentriesattr",
3311 int,fd
, struct vki_attrlist
*,attrList
,
3312 void *,attrBuf
, size_t,attrBufSize
,
3313 unsigned int *,count
, unsigned int *,basep
,
3314 unsigned int *,newState
, unsigned int,options
);
3315 PRE_MEM_READ("getdirentriesattr(attrList)",
3316 ARG2
, sizeof(struct vki_attrlist
));
3317 PRE_MEM_WRITE("getdirentriesattr(attrBuf)", ARG3
, ARG4
);
3318 PRE_MEM_READ("getdirentriesattr(count)", ARG5
, sizeof(unsigned int));
3319 PRE_MEM_WRITE("getdirentriesattr(count)", ARG5
, sizeof(unsigned int));
3320 PRE_MEM_WRITE("getdirentriesattr(basep)", ARG6
, sizeof(unsigned int));
3321 PRE_MEM_WRITE("getdirentriesattr(newState)", ARG7
, sizeof(unsigned int));
3323 POST(getdirentriesattr
)
3329 POST_MEM_WRITE(ARG5
, sizeof(unsigned int));
3330 POST_MEM_WRITE(ARG6
, sizeof(unsigned int));
3331 POST_MEM_WRITE(ARG7
, sizeof(unsigned int));
3333 // return buffer is concatenation of variable-size structs
3334 count
= *(unsigned int *)ARG5
;
3336 end
= (char *)ARG3
+ ARG4
;
3337 for (i
= 0; i
< count
; i
++) {
3338 vg_assert(p
< end
); // failure is kernel bug or Valgrind bug
3339 p
+= *(unsigned int *)p
;
3342 POST_MEM_WRITE(ARG3
, p
- (char *)ARG3
);
3344 PRINT("got %d records, %ld/%lu bytes\n",
3345 count
, (Addr
)p
-(Addr
)ARG3
, ARG4
);
3350 PRINT("exchangedata(%#lx(%s), %#lx(%s), %lu)",
3351 ARG1
, (HChar
*)ARG1
, ARG2
, (HChar
*)ARG2
, ARG3
);
3352 PRE_REG_READ3(int, "exchangedata",
3353 char *, path1
, char *, path2
, unsigned long, options
);
3354 PRE_MEM_RASCIIZ( "exchangedata(path1)", ARG1
);
3355 PRE_MEM_RASCIIZ( "exchangedata(path2)", ARG2
);
3360 PRINT("fsctl ( %#lx(%s), %lu, %#lx, %lu )",
3361 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
);
3362 PRE_REG_READ4( long, "fsctl",
3363 char *,"path", unsigned int,"request",
3364 void *,"data", unsigned int,"options");
3366 PRE_MEM_RASCIIZ( "fsctl(path)", ARG1
);
3369 case VKI_afpfsByteRangeLock2FSCTL
: {
3370 struct vki_ByteRangeLockPB2
*pb
= (struct vki_ByteRangeLockPB2
*)ARG3
;
3371 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->offset)",
3373 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->length)",
3375 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->unLockFlag)",
3377 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->startEndFlag)",
3379 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->fd)",
3382 PRE_FIELD_WRITE("fsctl(afpfsByteRangeLock2, pb->retRangeStart)",
3385 // GrP fixme check fd
3388 case VKI_FSIOC_SYNC_VOLUME
:
3389 PRE_MEM_READ( "fsctl(FSIOC_SYNC_VOLUME)", ARG3
, sizeof(int) );
3393 // fsctl requests use ioctl encoding
3394 ML_(PRE_unknown_ioctl
)(tid
, ARG2
, ARG3
);
3402 case VKI_afpfsByteRangeLock2FSCTL
: {
3403 struct vki_ByteRangeLockPB2
*pb
= (struct vki_ByteRangeLockPB2
*)ARG3
;
3404 POST_FIELD_WRITE(pb
->retRangeStart
);
3407 case VKI_FSIOC_SYNC_VOLUME
:
3411 // fsctl requests use ioctl encoding
3412 ML_(POST_unknown_ioctl
)(tid
, RES
, ARG2
, ARG3
);
3419 PRINT("initgroups(%s, %#lx, %lu)", (HChar
*)ARG1
, ARG2
, ARG3
);
3420 PRE_REG_READ3(long, "initgroups",
3421 int, setlen
, vki_gid_t
*, gidset
, vki_uid_t
, gmuid
);
3422 PRE_MEM_READ("gidset", ARG2
, ARG1
* sizeof(vki_gid_t
));
3426 //--------- posix_spawn ---------//
3427 /* Largely copied from PRE(sys_execve) in syswrap-generic.c, and from
3428 the simpler AIX equivalent (syswrap-aix5.c). */
3429 // Pre_read a char** argument.
3430 static void pre_argv_envp(Addr a
, ThreadId tid
, const HChar
* s1
, const HChar
* s2
)
3434 Addr
* a_p
= (Addr
*)a
;
3435 PRE_MEM_READ( s1
, (Addr
)a_p
, sizeof(Addr
) );
3439 PRE_MEM_RASCIIZ( s2
, a_deref
);
3443 static SysRes
simple_pre_exec_check ( const HChar
* exe_name
,
3444 Bool trace_this_child
)
3448 Bool setuid_allowed
;
3450 // Check it's readable
3451 res
= VG_(open
)(exe_name
, VKI_O_RDONLY
, 0);
3452 if (sr_isError(res
)) {
3458 // Check we have execute permissions. We allow setuid executables
3459 // to be run only in the case when we are not simulating them, that
3460 // is, they to be run natively.
3461 setuid_allowed
= trace_this_child
? False
: True
;
3462 ret
= VG_(check_executable
)(NULL
/*&is_setuid*/,
3463 exe_name
, setuid_allowed
);
3465 return VG_(mk_SysRes_Error
)(ret
);
3467 return VG_(mk_SysRes_Success
)(0);
3471 HChar
* path
= NULL
; /* path to executable */
3472 HChar
** envp
= NULL
;
3473 HChar
** argv
= NULL
;
3475 HChar
* launcher_basename
= NULL
;
3478 Bool trace_this_child
;
3482 posix_spawn_file_actions_t* file_actions
3486 PRINT("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )",
3487 ARG1
, ARG2
, ARG2
? (HChar
*)ARG2
: "(null)", ARG3
, ARG4
, ARG5
);
3489 /* Standard pre-syscall checks */
3491 PRE_REG_READ5(int, "posix_spawn", vki_pid_t
*, pid
, char*, path
,
3492 void*, file_actions
, char**, argv
, char**, envp
);
3493 PRE_MEM_WRITE("posix_spawn(pid)", ARG1
, sizeof(vki_pid_t
) );
3494 PRE_MEM_RASCIIZ("posix_spawn(path)", ARG2
);
3495 // DDD: check file_actions
3497 pre_argv_envp( ARG4
, tid
, "posix_spawn(argv)",
3498 "posix_spawn(argv[i])" );
3500 pre_argv_envp( ARG5
, tid
, "posix_spawn(envp)",
3501 "posix_spawn(envp[i])" );
3504 VG_(printf
)("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )\n",
3505 ARG1
, ARG2
, ARG2
? (HChar
*)ARG2
: "(null)", ARG3
, ARG4
, ARG5
);
3507 /* Now follows a bunch of logic copied from PRE(sys_execve) in
3508 syswrap-generic.c. */
3510 /* Check that the name at least begins in client-accessible storage. */
3511 if (ARG2
== 0 /* obviously bogus */
3512 || !VG_(am_is_valid_for_client
)( ARG2
, 1, VKI_PROT_READ
)) {
3513 SET_STATUS_Failure( VKI_EFAULT
);
3517 // Decide whether or not we want to follow along
3518 { // Make 'child_argv' be a pointer to the child's arg vector
3519 // (skipping the exe name)
3520 const HChar
** child_argv
= (const HChar
**)ARG4
;
3521 if (child_argv
&& child_argv
[0] == NULL
)
3523 trace_this_child
= VG_(should_we_trace_this_child
)( (HChar
*)ARG2
, child_argv
);
3526 // Do the important checks: it is a file, is executable, permissions are
3527 // ok, etc. We allow setuid executables to run only in the case when
3528 // we are not simulating them, that is, they to be run natively.
3529 res
= simple_pre_exec_check( (const HChar
*)ARG2
, trace_this_child
);
3530 if (sr_isError(res
)) {
3531 SET_STATUS_Failure( sr_Err(res
) );
3535 /* If we're tracing the child, and the launcher name looks bogus
3536 (possibly because launcher.c couldn't figure it out, see
3537 comments therein) then we have no option but to fail. */
3538 if (trace_this_child
3539 && (VG_(name_of_launcher
) == NULL
3540 || VG_(name_of_launcher
)[0] != '/')) {
3541 SET_STATUS_Failure( VKI_ECHILD
); /* "No child processes" */
3545 /* Ok. So let's give it a try. */
3546 VG_(debugLog
)(1, "syswrap", "Posix_spawn of %s\n", (HChar
*)ARG2
);
3548 /* posix_spawn on Darwin is combining the fork and exec in one syscall.
3549 So, we should not terminate gdbserver : this is still the parent
3550 running, which will terminate its gdbserver when exiting.
3551 If the child process is traced, it will start a fresh gdbserver
3552 after posix_spawn. */
3554 // Set up the child's exe path.
3556 if (trace_this_child
) {
3558 // We want to exec the launcher. Get its pre-remembered path.
3559 path
= VG_(name_of_launcher
);
3560 // VG_(name_of_launcher) should have been acquired by m_main at
3561 // startup. The following two assertions should be assured by
3562 // the "If we're tracking the child .." test just above here.
3564 vg_assert(path
[0] == '/');
3565 launcher_basename
= path
;
3568 path
= (HChar
*)ARG2
;
3571 // Set up the child's environment.
3573 // Remove the valgrind-specific stuff from the environment so the
3574 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
3575 // This is done unconditionally, since if we are tracing the child,
3576 // the child valgrind will set up the appropriate client environment.
3577 // Nb: we make a copy of the environment before trying to mangle it
3578 // as it might be in read-only memory (this was bug #101881).
3580 // Then, if tracing the child, set VALGRIND_LIB for it.
3585 envp
= VG_(env_clone
)( (HChar
**)ARG5
);
3587 VG_(env_remove_valgrind_env_stuff
)( envp
, /* ro_strings */ False
, NULL
);
3590 if (trace_this_child
) {
3591 // Set VALGRIND_LIB in ARG5 (the environment)
3592 VG_(env_setenv
)( &envp
, VALGRIND_LIB
, VG_(libdir
));
3595 // Set up the child's args. If not tracing it, they are
3596 // simply ARG4. Otherwise, they are
3598 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG2] ++ ARG4[1..]
3600 // except that the first VG_(args_for_valgrind_noexecpass) args
3603 if (!trace_this_child
) {
3604 argv
= (HChar
**)ARG4
;
3606 vg_assert( VG_(args_for_valgrind
) );
3607 vg_assert( VG_(args_for_valgrind_noexecpass
) >= 0 );
3608 vg_assert( VG_(args_for_valgrind_noexecpass
)
3609 <= VG_(sizeXA
)( VG_(args_for_valgrind
) ) );
3610 /* how many args in total will there be? */
3611 // launcher basename
3614 tot_args
+= VG_(sizeXA
)( VG_(args_for_valgrind
) );
3615 tot_args
-= VG_(args_for_valgrind_noexecpass
);
3616 // name of client exe
3618 // args for client exe, skipping [0]
3619 arg2copy
= (HChar
**)ARG4
;
3620 if (arg2copy
&& arg2copy
[0]) {
3621 for (i
= 1; arg2copy
[i
]; i
++)
3625 argv
= VG_(malloc
)( "di.syswrap.pre_sys_execve.1",
3626 (tot_args
+1) * sizeof(HChar
*) );
3629 argv
[j
++] = launcher_basename
;
3630 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_valgrind
) ); i
++) {
3631 if (i
< VG_(args_for_valgrind_noexecpass
))
3633 argv
[j
++] = * (HChar
**) VG_(indexXA
)( VG_(args_for_valgrind
), i
);
3635 argv
[j
++] = (HChar
*)ARG2
;
3636 if (arg2copy
&& arg2copy
[0])
3637 for (i
= 1; arg2copy
[i
]; i
++)
3638 argv
[j
++] = arg2copy
[i
];
3641 vg_assert(j
== tot_args
+1);
3644 /* DDD: sort out the signal state. What signal
3645 state does the child inherit from the parent? */
3649 VG_(printf
)("posix_spawn: %s\n", path
);
3650 for (cpp
= argv
; cpp
&& *cpp
; cpp
++)
3651 VG_(printf
)("argv: %s\n", *cpp
);
3653 for (cpp
= envp
; cpp
&& *cpp
; cpp
++)
3654 VG_(printf
)("env: %s\n", *cpp
);
3657 /* Let the call go through as usual. However, we have to poke
3658 the altered arguments back into the argument slots. */
3663 /* not to mention .. */
3664 *flags
|= SfMayBlock
;
3670 POST_MEM_WRITE( ARG1
, sizeof(vki_pid_t
) );
3677 PRINT("socket ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
3678 PRE_REG_READ3(long, "socket", int, domain
, int, type
, int, protocol
);
3685 r
= ML_(generic_POST_sys_socket
)(tid
, VG_(mk_SysRes_Success
)(RES
));
3686 SET_STATUS_from_SysRes(r
);
3692 PRINT("setsockopt ( %ld, %ld, %ld, %#lx, %ld )",
3693 SARG1
, SARG2
, SARG3
, ARG4
, SARG5
);
3694 PRE_REG_READ5(long, "setsockopt",
3695 int, s
, int, level
, int, optname
,
3696 const void *, optval
, vki_socklen_t
, optlen
);
3697 ML_(generic_PRE_sys_setsockopt
)(tid
, ARG1
,ARG2
,ARG3
,ARG4
,ARG5
);
3703 Addr optval_p
= ARG4
;
3704 Addr optlen_p
= ARG5
;
3705 PRINT("getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",
3706 SARG1
, SARG2
, SARG3
, ARG4
, ARG5
);
3707 PRE_REG_READ5(long, "getsockopt",
3708 int, s
, int, level
, int, optname
,
3709 void *, optval
, vki_socklen_t
*, optlen
);
3710 /* int getsockopt(int socket, int level, int option_name,
3711 void *restrict option_value,
3712 socklen_t *restrict option_len); */
3713 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
3714 if (optval_p
!= (Addr
)NULL
) {
3715 ML_(buf_and_len_pre_check
) ( tid
, optval_p
, optlen_p
,
3716 "socketcall.getsockopt(optval)",
3717 "socketcall.getsockopt(optlen)" );
3719 // DDD: #warning GrP fixme darwin-specific sockopts
3724 Addr optval_p
= ARG4
;
3725 Addr optlen_p
= ARG5
;
3727 if (optval_p
!= (Addr
)NULL
) {
3728 ML_(buf_and_len_post_check
) ( tid
, VG_(mk_SysRes_Success
)(RES
),
3730 "socketcall.getsockopt(optlen_out)" );
3731 // DDD: #warning GrP fixme darwin-specific sockopts
3738 *flags
|= SfMayBlock
;
3739 PRINT("connect ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
3740 PRE_REG_READ3(long, "connect",
3741 int, sockfd
, struct sockaddr
*, serv_addr
, int, addrlen
);
3742 ML_(generic_PRE_sys_connect
)(tid
, ARG1
,ARG2
,ARG3
);
3748 *flags
|= SfMayBlock
;
3749 PRINT("accept ( %ld, %#lx, %#lx )", SARG1
, ARG2
, SARG3
);
3750 PRE_REG_READ3(long, "accept",
3751 int, s
, struct sockaddr
*, addr
, int *, addrlen
);
3752 ML_(generic_PRE_sys_accept
)(tid
, ARG1
,ARG2
,ARG3
);
3759 r
= ML_(generic_POST_sys_accept
)(tid
, VG_(mk_SysRes_Success
)(RES
),
3761 SET_STATUS_from_SysRes(r
);
3766 *flags
|= SfMayBlock
;
3767 PRINT("mkfifo ( %#lx(%s), %lx )", ARG1
, (HChar
*)ARG1
, ARG2
);
3768 PRE_REG_READ2(long, "mkfifo", const char *, path
, vki_mode_t
, mode
);
3769 PRE_MEM_RASCIIZ( "mkfifo(path)", ARG1
);
3775 if (!ML_(fd_allowed
)(RES
, "mkfifo", tid
, True
)) {
3777 SET_STATUS_Failure( VKI_EMFILE
);
3779 if (VG_(clo_track_fds
))
3780 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*)ARG1
);
3786 *flags
|= SfMayBlock
;
3787 PRINT("sendto ( %ld, %s, %ld, %lu, %#lx, %ld )",
3788 SARG1
, (HChar
*)ARG2
, SARG3
, ARG4
, ARG5
, SARG6
);
3789 PRE_REG_READ6(long, "sendto",
3790 int, s
, const void *, msg
, int, len
,
3791 unsigned int, flags
,
3792 const struct sockaddr
*, to
, int, tolen
);
3793 ML_(generic_PRE_sys_sendto
)(tid
, ARG1
,ARG2
,ARG3
,ARG4
,ARG5
,ARG6
);
3798 #if VG_WORDSIZE == 4
3799 PRINT("sendfile(%ld, %ld, %llu, %#lx, %#lx, %ld)",
3800 SARG1
, SARG2
, LOHI64(ARG3
, ARG4
), ARG5
, ARG6
, SARG7
);
3802 PRE_REG_READ7(long, "sendfile",
3803 int, fromfd
, int, tofd
,
3804 vki_uint32_t
, offset_low32
, vki_uint32_t
, offset_high32
,
3805 vki_uint64_t
*, nwritten
, struct sf_hdtr
*, sf_header
, int, flags
);
3806 PRE_MEM_WRITE("sendfile(nwritten)", ARG5
, sizeof(vki_uint64_t
));
3807 if (ARG6
) PRE_MEM_WRITE("sendfile(sf_header)", ARG6
, sizeof(struct sf_hdtr
));
3809 PRINT("sendfile(%ld, %ld, %lu, %#lx, %#lx, %ld)",
3810 SARG1
, SARG2
, ARG3
, ARG4
, ARG5
, SARG6
);
3812 PRE_REG_READ6(long, "sendfile",
3813 int, fromfd
, int, tofd
,
3814 vki_uint64_t
, offset
,
3815 vki_uint64_t
*, nwritten
, struct sf_hdtr
*, sf_header
, int, flags
);
3816 PRE_MEM_WRITE("sendfile(nwritten)", ARG4
, sizeof(vki_uint64_t
));
3817 if (ARG5
) PRE_MEM_WRITE("sendfile(sf_header)", ARG5
, sizeof(struct sf_hdtr
));
3820 *flags
|= SfMayBlock
;
3824 #if VG_WORDSIZE == 4
3825 POST_MEM_WRITE(ARG5
, sizeof(vki_uint64_t
));
3826 if (ARG6
) POST_MEM_WRITE(ARG6
, sizeof(struct sf_hdtr
));
3828 POST_MEM_WRITE(ARG4
, sizeof(vki_uint64_t
));
3829 if (ARG5
) POST_MEM_WRITE(ARG5
, sizeof(struct sf_hdtr
));
3835 *flags
|= SfMayBlock
;
3836 PRINT("recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",
3837 SARG1
, ARG2
, SARG3
, ARG4
, ARG5
, ARG6
);
3838 PRE_REG_READ6(long, "recvfrom",
3839 int, s
, void *, buf
, int, len
, unsigned int, flags
,
3840 struct sockaddr
*, from
, int *, fromlen
);
3841 ML_(generic_PRE_sys_recvfrom
)(tid
, ARG1
,ARG2
,ARG3
,ARG4
,ARG5
,ARG6
);
3847 ML_(generic_POST_sys_recvfrom
)(tid
, VG_(mk_SysRes_Success
)(RES
),
3848 ARG1
,ARG2
,ARG3
,ARG4
,ARG5
,ARG6
);
3854 *flags
|= SfMayBlock
;
3855 PRINT("sendmsg ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
3856 PRE_REG_READ3(long, "sendmsg",
3857 int, s
, const struct msghdr
*, msg
, int, flags
);
3858 ML_(generic_PRE_sys_sendmsg
)(tid
, "msg", (struct vki_msghdr
*)ARG2
);
3864 *flags
|= SfMayBlock
;
3865 PRINT("recvmsg ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
3866 PRE_REG_READ3(long, "recvmsg", int, s
, struct msghdr
*, msg
, int, flags
);
3867 ML_(generic_PRE_sys_recvmsg
)(tid
, "msg", (struct vki_msghdr
*)ARG2
);
3872 ML_(generic_POST_sys_recvmsg
)(tid
, "msg", (struct vki_msghdr
*)ARG2
, RES
);
3878 *flags
|= SfMayBlock
;
3879 PRINT("shutdown ( %ld, %ld )", SARG1
, SARG2
);
3880 PRE_REG_READ2(int, "shutdown", int, s
, int, how
);
3886 PRINT("bind ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
3887 PRE_REG_READ3(long, "bind",
3888 int, sockfd
, struct sockaddr
*, my_addr
, int, addrlen
);
3889 ML_(generic_PRE_sys_bind
)(tid
, ARG1
,ARG2
,ARG3
);
3895 PRINT("listen ( %ld, %ld )", SARG1
, SARG2
);
3896 PRE_REG_READ2(long, "listen", int, s
, int, backlog
);
3902 PRINT("getsockname ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
3903 PRE_REG_READ3(long, "getsockname",
3904 int, s
, struct sockaddr
*, name
, int *, namelen
);
3905 ML_(generic_PRE_sys_getsockname
)(tid
, ARG1
,ARG2
,ARG3
);
3911 ML_(generic_POST_sys_getsockname
)(tid
, VG_(mk_SysRes_Success
)(RES
),
3918 PRINT("getpeername ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
3919 PRE_REG_READ3(long, "getpeername",
3920 int, s
, struct sockaddr
*, name
, int *, namelen
);
3921 ML_(generic_PRE_sys_getpeername
)(tid
, ARG1
,ARG2
,ARG3
);
3927 ML_(generic_POST_sys_getpeername
)(tid
, VG_(mk_SysRes_Success
)(RES
),
3934 PRINT("socketpair ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
3935 PRE_REG_READ4(long, "socketpair",
3936 int, d
, int, type
, int, protocol
, int *, sv
);
3937 ML_(generic_PRE_sys_socketpair
)(tid
, ARG1
,ARG2
,ARG3
,ARG4
);
3943 ML_(generic_POST_sys_socketpair
)(tid
, VG_(mk_SysRes_Success
)(RES
),
3944 ARG1
,ARG2
,ARG3
,ARG4
);
3950 PRINT("gethostuuid ( %#lx, %#lx )", ARG1
, ARG2
);
3951 PRE_REG_READ2(int,"gethostuuid",
3953 const struct vki_timespec
*,"timeout");
3955 PRE_MEM_WRITE("uuid_buf", ARG1
, 16);
3956 PRE_MEM_READ("timeout", ARG2
, sizeof(struct vki_timespec
));
3958 *flags
|= SfMayBlock
;
3964 POST_MEM_WRITE(ARG1
, 16);
3967 /* Darwin pipe() returns the two descriptors in two registers. */
3971 PRE_REG_READ0(int, "pipe");
3981 if (!ML_(fd_allowed
)(p0
, "pipe", tid
, True
) ||
3982 !ML_(fd_allowed
)(p1
, "pipe", tid
, True
)) {
3985 SET_STATUS_Failure( VKI_EMFILE
);
3987 if (VG_(clo_track_fds
)) {
3988 ML_(record_fd_open_nameless
)(tid
, p0
);
3989 ML_(record_fd_open_nameless
)(tid
, p1
);
3997 PRINT("getlogin ( %#lx, %lu )", ARG1
, ARG2
);
3998 PRE_REG_READ2(long, "getlogin",
3999 char *,"namebuf", unsigned int,"namelen");
4001 PRE_MEM_WRITE("getlogin(namebuf)", ARG1
, ARG2
);
4006 POST_MEM_WRITE(ARG1
, ARG2
);
4012 PRINT("ptrace ( %ld, %ld, %#lx, %ld )", SARG1
, SARG2
, ARG3
, SARG4
);
4013 PRE_REG_READ4(long, "ptrace",
4014 int,"request", vki_pid_t
,"pid",
4015 vki_caddr_t
,"addr", int,"data");
4017 // Note: some code uses ptrace(random, 0, 0, 0) as a profiling mechanism.
4019 // GrP fixme anything needed?
4025 PRINT("issetugid ( )");
4026 PRE_REG_READ0(long, "issetugid");
4032 PRINT("getdtablesize ( )");
4033 PRE_REG_READ0(long, "getdtablesize");
4038 // Subtract Valgrind's fd range from client's dtable
4039 if (RES
> VG_(fd_hard_limit
)) SET_STATUS_Success(VG_(fd_hard_limit
));
4044 PRINT("lseek ( %lu, %ld, %ld )", ARG1
, SARG2
, SARG3
);
4045 PRE_REG_READ4(vki_off_t
, "lseek",
4046 unsigned int,fd
, int,offset_hi
, int,offset_lo
,
4047 unsigned int,whence
);
4053 PRINT("pathconf(%#lx(%s), %ld)", ARG1
, (HChar
*)ARG1
, SARG2
);
4054 PRE_REG_READ2(long,"pathconf", const char *,"path", int,"name");
4055 PRE_MEM_RASCIIZ("pathconf(path)", ARG1
);
4061 PRINT("fpathconf(%ld, %ld)", SARG1
, SARG2
);
4062 PRE_REG_READ2(long,"fpathconf", int,"fd", int,"name");
4064 if (!ML_(fd_allowed
)(ARG1
, "fpathconf", tid
, False
))
4065 SET_STATUS_Failure( VKI_EBADF
);
4071 PRINT("getdirentries(%ld, %#lx, %ld, %#lx)", SARG1
, ARG2
, SARG3
, ARG4
);
4072 PRE_REG_READ4(int, "getdirentries",
4073 int, fd
, char *, buf
, int, nbytes
, long *, basep
);
4074 PRE_MEM_WRITE("getdirentries(basep)", ARG4
, sizeof(long));
4075 PRE_MEM_WRITE("getdirentries(buf)", ARG2
, ARG3
);
4080 POST_MEM_WRITE(ARG4
, sizeof(long));
4081 // GrP fixme be specific about d_name?
4082 POST_MEM_WRITE(ARG2
, RES
);
4086 PRE(getdirentries64
)
4088 PRINT("getdirentries64(%ld, %#lx, %lu, %#lx)", SARG1
, ARG2
, ARG3
, ARG4
);
4089 PRE_REG_READ4(vki_ssize_t
, "getdirentries",
4090 int,fd
, char *,buf
, vki_size_t
,nbytes
, vki_off_t
*,basep
);
4091 /* JRS 18-Nov-2014: it appears that sometimes |basep| doesn't point
4092 to valid memory and the kernel doesn't modify it. I can't
4093 determine the conditions under which that happens. But it
4094 causes Memcheck to complain, confusingly. So disable this check
4097 PRE_MEM_WRITE("getdirentries64(position)", ARG4, sizeof(vki_off_t));
4099 PRE_MEM_WRITE("getdirentries64(buf)", ARG2
, ARG3
);
4101 POST(getdirentries64
)
4103 /* Disabled; see comments in the PRE wrapper.
4104 POST_MEM_WRITE(ARG4, sizeof(vki_off_t));
4106 // GrP fixme be specific about d_name? (fixme copied from 32 bit version)
4107 POST_MEM_WRITE(ARG2
, RES
);
4113 PRINT("statfs64 ( %#lx(%s), %#lx )", ARG1
, (HChar
*)ARG1
, ARG2
);
4114 PRE_REG_READ2(long, "statfs64", const char *, path
, struct statfs64
*, buf
);
4115 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1
);
4116 PRE_MEM_WRITE( "statfs64(buf)", ARG2
, sizeof(struct vki_statfs64
) );
4120 POST_MEM_WRITE( ARG2
, sizeof(struct vki_statfs64
) );
4126 PRINT("fstatfs64 ( %lu, %#lx )", ARG1
, ARG2
);
4127 PRE_REG_READ2(long, "fstatfs64",
4128 unsigned int, fd
, struct statfs
*, buf
);
4129 PRE_MEM_WRITE( "fstatfs64(buf)", ARG2
, sizeof(struct vki_statfs64
) );
4133 POST_MEM_WRITE( ARG2
, sizeof(struct vki_statfs64
) );
4138 PRINT("csops ( %ld, %#lx, %#lx, %lu )", SARG1
, ARG2
, ARG3
, ARG4
);
4139 PRE_REG_READ4(int, "csops",
4140 vki_pid_t
, pid
, uint32_t, ops
,
4141 void *, useraddr
, vki_size_t
, usersize
);
4143 PRE_MEM_WRITE( "csops(useraddr)", ARG3
, ARG4
);
4145 // If the pid is ours, don't mark the program as KILL or HARD
4146 // Maybe we should keep track of this for later calls to STATUS
4147 if (!ARG1
|| VG_(getpid
)() == ARG1
) {
4149 case VKI_CS_OPS_MARKINVALID
:
4150 case VKI_CS_OPS_MARKHARD
:
4151 case VKI_CS_OPS_MARKKILL
:
4152 SET_STATUS_Success(0);
4158 POST_MEM_WRITE( ARG3
, ARG4
);
4163 PRINT("auditon ( %ld, %#lx, %lu )", SARG1
, ARG2
, ARG3
);
4164 PRE_REG_READ3(int,"auditon",
4165 int,"cmd", void*,"data", unsigned int,"length");
4169 case VKI_A_SETPOLICY
:
4170 case VKI_A_SETKMASK
:
4171 case VKI_A_SETQCTRL
:
4173 case VKI_A_SETCLASS
:
4174 case VKI_A_SETPMASK
:
4175 case VKI_A_SETFSIZE
:
4176 #if DARWIN_VERS >= DARWIN_10_6
4177 case VKI_A_SENDTRIGGER
:
4179 // kernel reads data..data+length
4180 PRE_MEM_READ("auditon(data)", ARG2
, ARG3
);
4183 case VKI_A_GETKMASK
:
4184 case VKI_A_GETPOLICY
:
4185 case VKI_A_GETQCTRL
:
4186 case VKI_A_GETFSIZE
:
4188 // kernel writes data..data+length
4189 // GrP fixme be precise about what gets written
4190 PRE_MEM_WRITE("auditon(data)", ARG2
, ARG3
);
4194 case VKI_A_GETCLASS
:
4195 case VKI_A_GETPINFO
:
4196 case VKI_A_GETPINFO_ADDR
:
4197 #if DARWIN_VERS >= DARWIN_10_6
4198 case VKI_A_GETSINFO_ADDR
:
4200 // kernel reads and writes data..data+length
4201 // GrP fixme be precise about what gets read and written
4202 PRE_MEM_READ("auditon(data)", ARG2
, ARG3
);
4203 PRE_MEM_WRITE("auditon(data)", ARG2
, ARG3
);
4206 case VKI_A_SETKAUDIT
:
4208 case VKI_A_SETUMASK
:
4209 case VKI_A_SETSMASK
:
4210 case VKI_A_GETKAUDIT
:
4214 // unimplemented on darwin
4218 VG_(message
)(Vg_UserMsg
, "UNKNOWN auditon cmd %ld\n", ARG1
);
4226 case VKI_A_SETPOLICY
:
4227 case VKI_A_SETKMASK
:
4228 case VKI_A_SETQCTRL
:
4230 case VKI_A_SETCLASS
:
4231 case VKI_A_SETPMASK
:
4232 case VKI_A_SETFSIZE
:
4233 #if DARWIN_VERS >= DARWIN_10_6
4234 case VKI_A_SENDTRIGGER
:
4236 // kernel reads data..data+length
4239 case VKI_A_GETKMASK
:
4240 case VKI_A_GETPOLICY
:
4241 case VKI_A_GETQCTRL
:
4242 case VKI_A_GETFSIZE
:
4244 // kernel writes data..data+length
4245 // GrP fixme be precise about what gets written
4246 POST_MEM_WRITE(ARG2
, ARG3
);
4250 case VKI_A_GETCLASS
:
4251 case VKI_A_GETPINFO
:
4252 case VKI_A_GETPINFO_ADDR
:
4253 #if DARWIN_VERS >= DARWIN_10_6
4254 case VKI_A_GETSINFO_ADDR
:
4256 // kernel reads and writes data..data+length
4257 // GrP fixme be precise about what gets read and written
4258 POST_MEM_WRITE(ARG2
, ARG3
);
4261 case VKI_A_SETKAUDIT
:
4263 case VKI_A_SETUMASK
:
4264 case VKI_A_SETSMASK
:
4265 case VKI_A_GETKAUDIT
:
4269 // unimplemented on darwin
4279 PRINT("getaudit_addr(%#lx, %ld)", ARG1
, SARG2
);
4280 PRE_REG_READ1(void*, "auditinfo_addr", int, "length");
4281 PRE_MEM_WRITE("getaudit_addr(auditinfo_addr)", ARG1
, ARG2
);
4285 POST_MEM_WRITE(ARG1
, ARG2
);
4292 if (0) VG_(am_do_sync_check
)("(PRE_MMAP)",__FILE__
,__LINE__
);
4294 #if VG_WORDSIZE == 4
4295 PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %llu )",
4296 ARG1
, ARG2
, SARG3
, SARG4
, SARG5
, LOHI64(ARG6
, ARG7
) );
4297 PRE_REG_READ7(Addr
, "mmap",
4298 Addr
,start
, vki_size_t
,length
, int,prot
, int,flags
, int,fd
,
4299 unsigned long,offset_hi
, unsigned long,offset_lo
);
4300 // GrP fixme V mmap and kernel mach_msg collided once - don't use
4301 // V's mechanism for now
4302 // r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
4303 // (Off64T)LOHI64(ARG6, ARG7) );
4305 PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )",
4306 ARG1
, ARG2
, SARG3
, SARG4
, SARG5
, SARG6
);
4307 PRE_REG_READ6(long, "mmap",
4308 Addr
,start
, vki_size_t
,length
, int,prot
, int,flags
, int,fd
,
4310 // r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
4314 // SET_STATUS_from_SysRes(r);
4320 ML_(notify_core_and_tool_of_mmap
)(RES
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
4321 // Try to load symbols from the region
4322 VG_(di_notify_mmap
)( (Addr
)RES
, False
/*allow_SkFileV*/,
4323 -1/*don't use_fd*/ );
4324 ML_(sync_mappings
)("after", "mmap", 0);
4329 /* This function holds common elements of PRE(__sysctl) and
4330 PRE(sysctlbyname). */
4331 static void common_PRE_sysctl (
4333 ThreadId tid
, /*OUT*/SyscallStatus
* status
, /*OUT*/UWord
* flags
,
4335 Bool is_kern_dot_userstack
,
4336 UWord oldp
, UWord oldlenp
,
4337 UWord newp
, UWord newlen
)
4341 PRE_MEM_WRITE("sysctl(oldlenp)", oldlenp
, sizeof(size_t));
4343 // also reads *oldlenp, and writes up to oldp[0..(*oldlenp)-1]
4344 PRE_MEM_READ("sysctl(oldlenp)", oldlenp
, sizeof(size_t));
4345 PRE_MEM_WRITE("sysctl(oldp)", oldp
, *(size_t*)oldlenp
);
4349 PRE_MEM_READ("sysctl(newp)", newp
, newlen
);
4352 // GrP fixme intercept KERN_PROCARGS and KERN_PROC_PID for our pid
4353 // (executable path and arguments and environment
4355 if (is_kern_dot_userstack
) {
4356 // Intercept sysctl(kern.usrstack). The kernel's reply
4357 // would be Valgrind's stack, not the client's stack.
4358 // GrP fixme kern_usrstack64 */
4359 if (newp
|| newlen
) {
4360 SET_STATUS_Failure(VKI_EPERM
); // USRSTACK is read-only */
4362 Addr
* t_oldp
= (Addr
*)oldp
;
4363 size_t* t_oldlenp
= (size_t*)oldlenp
;
4365 // According to some searches on the net, it looks like
4366 // USRSTACK gives the address of the byte following the
4367 // highest byte of the stack. As VG_(clstk_end) is the
4368 // address of the highest addressable byte, we add 1.
4369 Addr stack_end
= VG_(clstk_end
)+1;
4370 size_t oldlen
= *t_oldlenp
;
4371 // always return actual size
4372 *t_oldlenp
= sizeof(Addr
);
4373 if (t_oldp
&& oldlen
>= sizeof(Addr
)) {
4374 // oldp is big enough. copy value and return 0
4375 *t_oldp
= stack_end
;
4376 SET_STATUS_Success(0);
4378 // oldp isn't big enough. copy as much as possible
4379 // and return ENOMEM
4380 if (t_oldp
) VG_(memcpy
)(t_oldp
, &stack_end
, oldlen
);
4381 SET_STATUS_Failure(VKI_ENOMEM
);
4387 if (!SUCCESS
&& !FAILURE
) {
4388 // Don't set SfPostOnFail if we've already handled it locally.
4389 *flags
|= SfPostOnFail
;
4397 UWord namelen
= ARG2
;
4399 UWord oldlenp
= ARG4
;
4401 UWord newlen
= ARG6
;
4403 PRINT( "__sysctl ( %#lx, %lu, %#lx, %#lx, %#lx, %#lx )",
4404 name
, namelen
, oldp
, oldlenp
, newp
, newlen
);
4406 PRE_REG_READ6(int, "__sysctl", int*, name
, unsigned int, namelen
,
4407 void*, oldp
, vki_size_t
*, oldlenp
,
4408 void*, newp
, vki_size_t
*, newlenp
);
4410 PRE_MEM_READ("sysctl(name)", name
, namelen
); // reads name[0..namelen-1]
4412 if (VG_(clo_trace_syscalls
)) {
4414 Int
* t_name
= (Int
*)name
;
4415 VG_(printf
)(" mib: [ ");
4416 for (i
= 0; i
< namelen
; i
++) {
4417 VG_(printf
)("%d ", t_name
[i
]);
4422 Int vKI_KERN_USRSTACKXX
4423 = VG_WORDSIZE
== 4 ? VKI_KERN_USRSTACK32
: VKI_KERN_USRSTACK64
;
4424 Bool is_kern_dot_userstack
4425 = name
&& namelen
== 2
4426 && ((Int
*)name
)[0] == VKI_CTL_KERN
4427 && ((Int
*)name
)[1] == vKI_KERN_USRSTACKXX
;
4429 common_PRE_sysctl( /*IMPLICIT ARGS*/tid
,status
,flags
,/*!IMPLICIT_ARGS*/
4430 is_kern_dot_userstack
, oldp
, oldlenp
, newp
, newlen
);
4436 UWord oldlenp
= ARG4
;
4438 if (SUCCESS
|| ERR
== VKI_ENOMEM
) {
4439 // sysctl can write truncated data and return VKI_ENOMEM
4441 POST_MEM_WRITE(oldlenp
, sizeof(size_t));
4443 if (oldp
&& oldlenp
) {
4444 POST_MEM_WRITE(oldp
, *(size_t*)oldlenp
);
4452 PRINT( "sigpending ( %#lx )", ARG1
);
4453 PRE_REG_READ1(long, "sigpending", vki_sigset_t
*, set
);
4454 PRE_MEM_WRITE( "sigpending(set)", ARG1
, sizeof(vki_sigset_t
));
4458 POST_MEM_WRITE( ARG1
, sizeof(vki_sigset_t
) ) ;
4465 PRINT("sigprocmask ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
4466 PRE_REG_READ3(long, "sigprocmask",
4467 int, how
, vki_sigset_t
*, set
, vki_sigset_t
*, oldset
);
4469 PRE_MEM_READ( "sigprocmask(set)", ARG2
, sizeof(vki_sigset_t
));
4471 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3
, sizeof(vki_sigset_t
));
4473 /* Massage ARG1 ('how'). If ARG2 (the new mask) is NULL then the
4474 value of 'how' is irrelevant, and it appears that Darwin's libc
4475 passes zero, which is not equal to any of
4476 SIG_{BLOCK,UNBLOCK,SETMASK}. This causes
4477 VG_(do_sys_sigprocmask) to complain, since it checks the 'how'
4478 value independently of the other args. Solution: in this case,
4479 simply pass a valid (but irrelevant) value for 'how'. */
4480 /* Also, in this case the new set is passed to the kernel by
4481 reference, not value, as in some other sigmask related Darwin
4484 if (ARG2
== 0 /* the new-set is NULL */
4485 && ARG1
!= VKI_SIG_BLOCK
4486 && ARG1
!= VKI_SIG_UNBLOCK
&& ARG1
!= VKI_SIG_SETMASK
) {
4487 arg1
= VKI_SIG_SETMASK
;
4489 SET_STATUS_from_SysRes(
4490 VG_(do_sys_sigprocmask
) ( tid
, arg1
, (vki_sigset_t
*)ARG2
,
4491 (vki_sigset_t
*)ARG3
)
4495 *flags
|= SfPollAfter
;
4501 if (RES
== 0 && ARG3
!= 0)
4502 POST_MEM_WRITE( ARG3
, sizeof(vki_sigset_t
));
4508 /* Just hand this off to the kernel. Is that really correct? And
4509 shouldn't we at least set SfPollAfter? These questions apply to
4510 all the Linux versions too. */
4511 /* I think the first arg is the 32-bit signal mask (by value), and
4512 the other two args are ignored. */
4513 *flags
|= SfMayBlock
;
4514 PRINT("sigsuspend ( mask=0x%08lx )", ARG1
);
4515 PRE_REG_READ1(int, "sigsuspend", int, sigmask
);
4519 /* Be careful about the 4th arg, since that is a uint64_t. Hence 64-
4520 and 32-bit wrappers are different.
4522 ARG5 and ARG6 (buffer, buffersize) specify a buffer start and
4523 length in the usual way. I have seen values NULL, 0 passed in some
4524 cases. I left the calls to PRE_MEM_WRITE/READ unconditional on the
4525 basis that they don't do anything if the length is zero, so it's OK
4526 for the buffer pointer to be NULL in that case (meaning they don't
4529 int proc_info(int32_t callnum, int32_t pid,
4530 uint32_t flavor, uint64_t arg,
4531 user_addr_t buffer, int32_t buffersize)
4535 #if VG_WORDSIZE == 4
4536 PRINT("proc_info(%d, %d, %u, %llu, %#lx, %d)",
4537 (Int
)ARG1
, (Int
)ARG2
, (UInt
)ARG3
, LOHI64(ARG4
,ARG5
), ARG6
, (Int
)ARG7
);
4538 PRE_REG_READ7(int, "proc_info",
4539 int, callnum
, int, pid
, unsigned int, flavor
,
4540 vki_uint32_t
, arg_low32
,
4541 vki_uint32_t
, arg_high32
,
4542 void*, buffer
, int, buffersize
);
4543 PRE_MEM_WRITE("proc_info(buffer)", ARG6
, ARG7
);
4545 PRINT("proc_info(%d, %d, %u, %llu, %#lx, %d)",
4546 (Int
)ARG1
, (Int
)ARG2
, (UInt
)ARG3
, (ULong
)ARG4
, ARG5
, (Int
)ARG6
);
4547 PRE_REG_READ6(int, "proc_info",
4548 int, callnum
, int, pid
, unsigned int, flavor
,
4549 unsigned long long int, arg
,
4550 void*, buffer
, int, buffersize
);
4551 PRE_MEM_WRITE("proc_info(buffer)", ARG5
, ARG6
);
4557 #if VG_WORDSIZE == 4
4560 // Intercept internal call to proc_setcontrol() where flavor = 2, arg = 0
4561 if (ARG1
== 5 && ARG3
== 2 && LOHI64(ARG4
,ARG5
) == 0 )
4563 const HChar
* new_name
= (const HChar
*) ARG6
;
4564 if (new_name
) { // Paranoia
4565 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
4566 SizeT new_len
= VG_(strlen
)(new_name
);
4568 /* Don't bother reusing the memory. This is a rare event. */
4570 VG_(realloc
)("syscall(proc_info)", tst
->thread_name
, new_len
+ 1);
4571 VG_(strcpy
)(tst
->thread_name
, new_name
);
4575 POST_MEM_WRITE(ARG6
, ARG7
);
4579 // Intercept internal call to proc_setcontrol() where flavor = 2, arg = 0
4580 if (ARG1
== 5 && ARG3
== 2 && ARG4
== 0 )
4582 const HChar
* new_name
= (const HChar
*) ARG5
;
4583 if (new_name
) { // Paranoia
4584 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
4585 SizeT new_len
= VG_(strlen
)(new_name
);
4587 /* Don't bother reusing the memory. This is a rare event. */
4589 VG_(realloc
)("syscall(proc_info)", tst
->thread_name
, new_len
+ 1);
4590 VG_(strcpy
)(tst
->thread_name
, new_name
);
4594 POST_MEM_WRITE(ARG5
, ARG6
);
4599 /* ---------------------------------------------------------------------
4601 ------------------------------------------------------------------ */
4603 // We must record the aiocbp for each aio_read() in a table so that when
4604 // aio_return() is called we can mark the memory written asynchronously by
4605 // aio_read() as having been written. We don't have to do this for
4606 // aio_write(). See bug 197227 for more details.
4607 static OSet
* aiocbp_table
= NULL
;
4608 static Bool aio_init_done
= False
;
4610 static void aio_init(void)
4612 aiocbp_table
= VG_(OSetWord_Create
)(VG_(malloc
), "syswrap.aio", VG_(free
));
4613 aio_init_done
= True
;
4618 // This assumes that the kernel looks at the struct pointer, but not the
4619 // contents of the struct.
4620 PRINT( "aio_return ( %#lx )", ARG1
);
4621 PRE_REG_READ1(long, "aio_return", struct vki_aiocb
*, aiocbp
);
4622 if (ML_(safe_to_deref
)((struct vki_aiocb
*)ARG1
, sizeof(struct vki_aiocb
))) {
4623 SET_STATUS_from_SysRes(VG_(do_syscall1
)(SYSNO
, ARG1
));
4624 if (SUCCESS
&& RES
>= 0) {
4625 struct vki_aiocb
* aiocbp
= (struct vki_aiocb
*)ARG1
;
4626 if (!aio_init_done
) {
4629 if (VG_(OSetWord_Remove
)(aiocbp_table
, (UWord
)aiocbp
)) {
4630 POST_MEM_WRITE((Addr
)aiocbp
->aio_buf
, aiocbp
->aio_nbytes
);
4634 SET_STATUS_Failure(VKI_EINVAL
);
4641 // This assumes that the kernel looks at the struct pointers in the list,
4642 // but not the contents of the structs.
4643 PRINT( "aio_suspend ( %#lx )", ARG1
);
4644 PRE_REG_READ3(long, "aio_suspend",
4645 const struct vki_aiocb
* const *, aiocbp
, int, nent
,
4646 const struct vki_timespec
*, timeout
);
4648 PRE_MEM_READ("aio_suspend(list)", ARG1
, ARG2
* sizeof(struct vki_aiocb
*));
4651 PRE_MEM_READ ("aio_suspend(timeout)", ARG3
, sizeof(struct vki_timespec
));
4657 // This assumes that the kernel looks at the struct pointer, but not the
4658 // contents of the struct.
4659 PRINT( "aio_error ( %#lx )", ARG1
);
4660 PRE_REG_READ1(long, "aio_error", struct vki_aiocb
*, aiocbp
);
4665 struct vki_aiocb
* aiocbp
= (struct vki_aiocb
*)ARG1
;
4667 PRINT( "aio_read ( %#lx )", ARG1
);
4668 PRE_REG_READ1(long, "aio_read", struct vki_aiocb
*, aiocbp
);
4669 PRE_MEM_READ( "aio_read(aiocbp)", ARG1
, sizeof(struct vki_aiocb
));
4671 if (ML_(safe_to_deref
)(aiocbp
, sizeof(struct vki_aiocb
))) {
4672 if (ML_(fd_allowed
)(aiocbp
->aio_fildes
, "aio_read", tid
, /*isNewFd*/False
)) {
4673 PRE_MEM_WRITE("aio_read(aiocbp->aio_buf)",
4674 (Addr
)aiocbp
->aio_buf
, aiocbp
->aio_nbytes
);
4676 SET_STATUS_Failure( VKI_EBADF
);
4679 SET_STATUS_Failure( VKI_EINVAL
);
4684 // We have to record the fact that there is an asynchronous read request
4685 // pending. When a successful aio_return() occurs for this aiocb, then we
4686 // will mark the memory as having been defined.
4687 struct vki_aiocb
* aiocbp
= (struct vki_aiocb
*)ARG1
;
4688 if (!aio_init_done
) aio_init();
4689 // aiocbp shouldn't already be in the table -- if it was a dup, the kernel
4690 // should have caused the aio_read() to fail and we shouldn't have reached
4692 VG_(OSetWord_Insert
)(aiocbp_table
, (UWord
)aiocbp
);
4697 struct vki_aiocb
* aiocbp
= (struct vki_aiocb
*)ARG1
;
4699 PRINT( "aio_write ( %#lx )", ARG1
);
4700 PRE_REG_READ1(long, "aio_write", struct vki_aiocb
*, aiocbp
);
4701 PRE_MEM_READ( "aio_write(aiocbp)", ARG1
, sizeof(struct vki_aiocb
));
4703 if (ML_(safe_to_deref
)(aiocbp
, sizeof(struct vki_aiocb
))) {
4704 if (ML_(fd_allowed
)(aiocbp
->aio_fildes
, "aio_write", tid
, /*isNewFd*/False
)) {
4705 PRE_MEM_READ("aio_write(aiocbp->aio_buf)",
4706 (Addr
)aiocbp
->aio_buf
, aiocbp
->aio_nbytes
);
4708 SET_STATUS_Failure( VKI_EBADF
);
4711 SET_STATUS_Failure( VKI_EINVAL
);
4715 /* ---------------------------------------------------------------------
4716 mach_msg: formatted messages
4717 ------------------------------------------------------------------ */
4719 static size_t desc_size(mach_msg_descriptor_t
*desc
)
4721 switch (desc
->type
.type
) {
4722 case MACH_MSG_PORT_DESCRIPTOR
: return sizeof(desc
->port
);
4723 case MACH_MSG_OOL_DESCRIPTOR
: return sizeof(desc
->out_of_line
);
4724 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
: return sizeof(desc
->out_of_line
);
4725 case MACH_MSG_OOL_PORTS_DESCRIPTOR
: return sizeof(desc
->ool_ports
);
4727 VG_(printf
)("UNKNOWN mach message descriptor %d\n", desc
->type
.type
);
4728 return sizeof(desc
->type
); // guess
4733 static void assign_port_names(mach_msg_ool_ports_descriptor_t
*desc
,
4737 mach_port_t
*ports
= (mach_port_t
*)desc
->address
;
4738 for (i
= 0; i
< desc
->count
; i
++) {
4739 assign_port_name(ports
[i
], name
);
4744 static void import_complex_message(ThreadId tid
, mach_msg_header_t
*mh
)
4746 mach_msg_body_t
*body
;
4747 mach_msg_size_t count
, i
;
4749 mach_msg_descriptor_t
*desc
;
4751 vg_assert(mh
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
);
4753 body
= (mach_msg_body_t
*)(mh
+1);
4754 count
= body
->msgh_descriptor_count
;
4755 p
= (uint8_t *)(body
+1);
4757 for (i
= 0; i
< count
; i
++) {
4758 desc
= (mach_msg_descriptor_t
*)p
;
4759 p
+= desc_size(desc
);
4761 switch (desc
->type
.type
) {
4762 case MACH_MSG_PORT_DESCRIPTOR
:
4764 record_unnamed_port(tid
, desc
->port
.name
, -1);
4765 record_port_insert_rights(desc
->port
.name
, desc
->port
.disposition
);
4766 PRINT("got port %s;\n", name_for_port(desc
->port
.name
));
4769 case MACH_MSG_OOL_DESCRIPTOR
:
4770 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
4771 // out-of-line memory - map it
4772 // GrP fixme how is VOLATILE different? do we care?
4773 // GrP fixme do other flags tell us anything? assume shared for now
4774 // GrP fixme more SF_ flags marking mach_msg memory might be nice
4775 // GrP fixme protection
4776 if (desc
->out_of_line
.size
> 0) {
4777 Addr start
= VG_PGROUNDDN((Addr
)desc
->out_of_line
.address
);
4778 Addr end
= VG_PGROUNDUP((Addr
)desc
->out_of_line
.address
+
4779 (Addr
)desc
->out_of_line
.size
);
4780 PRINT("got ool mem %p..%p;\n", desc
->out_of_line
.address
,
4781 (char*)desc
->out_of_line
.address
+desc
->out_of_line
.size
);
4783 ML_(notify_core_and_tool_of_mmap
)(
4784 start
, end
- start
, VKI_PROT_READ
|VKI_PROT_WRITE
,
4785 VKI_MAP_PRIVATE
, -1, 0);
4787 // GrP fixme mark only un-rounded part as initialized
4790 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
4791 // out-of-line array of ports - map it
4792 // GrP fixme see fixmes above
4793 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
));
4795 if (desc
->ool_ports
.count
> 0) {
4796 Addr start
= VG_PGROUNDDN((Addr
)desc
->ool_ports
.address
);
4797 Addr end
= VG_PGROUNDUP((Addr
)desc
->ool_ports
.address
+ desc
->ool_ports
.count
* sizeof(mach_port_t
));
4798 mach_port_t
*ports
= (mach_port_t
*)desc
->ool_ports
.address
;
4800 ML_(notify_core_and_tool_of_mmap
)(
4801 start
, end
- start
, VKI_PROT_READ
|VKI_PROT_WRITE
,
4802 VKI_MAP_PRIVATE
, -1, 0);
4805 for (i
= 0; i
< desc
->ool_ports
.count
; i
++) {
4806 record_unnamed_port(tid
, ports
[i
], -1);
4807 record_port_insert_rights(ports
[i
], desc
->port
.disposition
);
4808 PRINT(" %s", name_for_port(ports
[i
]));
4815 VG_(printf
)("UNKNOWN Mach descriptor type %u!\n", desc
->type
.type
);
4822 static void pre_port_desc_read(ThreadId tid
, mach_msg_port_descriptor_t
*desc2
)
4827 mach_msg_size_t pad1
;
4829 uint8_t disposition
;
4831 } *desc
= (void*)desc2
;
4834 PRE_FIELD_READ("msg->desc.port.name", desc
->name
);
4835 PRE_FIELD_READ("msg->desc.port.disposition", desc
->disposition
);
4836 PRE_FIELD_READ("msg->desc.port.type", desc
->type
);
4840 static void pre_ool_desc_read(ThreadId tid
, mach_msg_ool_descriptor_t
*desc2
)
4845 #if VG_WORDSIZE != 8
4846 mach_msg_size_t size
;
4852 #if VG_WORDSIZE == 8
4853 mach_msg_size_t size
;
4855 } *desc
= (void*)desc2
;
4858 PRE_FIELD_READ("msg->desc.out_of_line.address", desc
->address
);
4859 PRE_FIELD_READ("msg->desc.out_of_line.size", desc
->size
);
4860 PRE_FIELD_READ("msg->desc.out_of_line.deallocate", desc
->deallocate
);
4861 PRE_FIELD_READ("msg->desc.out_of_line.copy", desc
->copy
);
4862 PRE_FIELD_READ("msg->desc.out_of_line.type", desc
->type
);
4865 static void pre_oolports_desc_read(ThreadId tid
,
4866 mach_msg_ool_ports_descriptor_t
*desc2
)
4871 #if VG_WORDSIZE != 8
4872 mach_msg_size_t size
;
4876 uint8_t disposition
;
4878 #if VG_WORDSIZE == 8
4879 mach_msg_size_t size
;
4881 } *desc
= (void*)desc2
;
4884 PRE_FIELD_READ("msg->desc.ool_ports.address", desc
->address
);
4885 PRE_FIELD_READ("msg->desc.ool_ports.size", desc
->size
);
4886 PRE_FIELD_READ("msg->desc.ool_ports.deallocate", desc
->deallocate
);
4887 PRE_FIELD_READ("msg->desc.ool_ports.copy", desc
->copy
);
4888 PRE_FIELD_READ("msg->desc.ool_ports.disposition", desc
->disposition
);
4889 PRE_FIELD_READ("msg->desc.ool_ports.type", desc
->type
);
4893 // Returns the size of the descriptor area
4894 // (mach_msg_body_t + any mach_msg_descriptor_t)
4895 static size_t export_complex_message(ThreadId tid
, mach_msg_header_t
*mh
)
4897 mach_msg_body_t
*body
;
4898 mach_msg_size_t count
, i
;
4900 mach_msg_descriptor_t
*desc
;
4902 vg_assert(mh
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
);
4904 body
= (mach_msg_body_t
*)(mh
+1);
4905 PRE_MEM_READ("msg->msgh_descriptor_count)", (Addr
)body
, sizeof(*body
));
4907 count
= body
->msgh_descriptor_count
;
4908 p
= (uint8_t *)(body
+1);
4910 for (i
= 0; i
< count
; i
++) {
4911 desc
= (mach_msg_descriptor_t
*)p
;
4912 p
+= desc_size(desc
);
4914 switch (desc
->type
.type
) {
4915 case MACH_MSG_PORT_DESCRIPTOR
:
4916 // single port; no memory map effects
4917 pre_port_desc_read(tid
, &desc
->port
);
4920 case MACH_MSG_OOL_DESCRIPTOR
:
4921 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR
:
4922 // out-of-line memory - unmap it if it's marked dealloc
4923 // GrP fixme need to remap if message fails?
4924 // GrP fixme how is VOLATILE different? do we care?
4925 // GrP fixme struct is different for lp64
4926 pre_ool_desc_read(tid
, &desc
->out_of_line
);
4928 if (desc
->out_of_line
.deallocate
&& desc
->out_of_line
.size
> 0) {
4929 vm_size_t size
= desc
->out_of_line
.size
;
4930 Addr start
= VG_PGROUNDDN((Addr
)desc
->out_of_line
.address
);
4931 Addr end
= VG_PGROUNDUP((Addr
)desc
->out_of_line
.address
+ size
);
4932 PRINT("kill ool mem %p..%#lx; ", desc
->out_of_line
.address
,
4933 (Addr
)desc
->out_of_line
.address
+ size
);
4934 ML_(notify_core_and_tool_of_munmap
)(start
, end
- start
);
4938 case MACH_MSG_OOL_PORTS_DESCRIPTOR
:
4939 // out-of-line array of ports - unmap it if it's marked dealloc
4940 // GrP fixme need to remap if message fails?
4941 // GrP fixme struct different for lp64
4942 pre_oolports_desc_read(tid
, &desc
->ool_ports
);
4944 if (desc
->ool_ports
.deallocate
&& desc
->ool_ports
.count
> 0) {
4945 vm_size_t size
= desc
->ool_ports
.count
* sizeof(mach_port_t
);
4946 Addr start
= VG_PGROUNDDN((Addr
)desc
->ool_ports
.address
);
4947 Addr end
= VG_PGROUNDUP((Addr
)desc
->ool_ports
.address
+ size
);
4948 PRINT("kill ool port array %p..%#lx; ", desc
->ool_ports
.address
,
4949 (Addr
)desc
->ool_ports
.address
+ size
);
4950 ML_(notify_core_and_tool_of_munmap
)(start
, end
- start
);
4954 VG_(printf
)("UNKNOWN Mach descriptor type %u!\n", desc
->type
.type
);
4959 return (size_t)((Addr
)p
- (Addr
)body
);
4963 /* ---------------------------------------------------------------------
4964 mach_msg: host-related messages
4965 ------------------------------------------------------------------ */
4972 mach_msg_header_t Head
;
4974 kern_return_t RetCode
;
4975 mach_msg_type_number_t host_info_outCnt
;
4976 integer_t host_info_out
[14];
4980 Reply
*reply
= (Reply
*)ARG1
;
4982 if (reply
->RetCode
) PRINT("mig return %d", reply
->RetCode
);
4989 mach_msg_header_t Head
;
4991 host_flavor_t flavor
;
4992 mach_msg_type_number_t host_info_outCnt
;
4996 Request
*req
= (Request
*)ARG1
;
4998 PRINT("host_info(mach_host_self(), flavor %d)", req
->flavor
);
5000 AFTER
= POST_FN(host_info
);
5004 POST(host_page_size
)
5008 mach_msg_header_t Head
;
5010 kern_return_t RetCode
;
5011 vm_size_t out_page_size
;
5015 Reply
*reply
= (Reply
*)ARG1
;
5017 if (!reply
->RetCode
) {
5018 PRINT("page size %llu", (ULong
)reply
->out_page_size
);
5020 PRINT("mig return %d", reply
->RetCode
);
5026 PRINT("host_page_size(mach_host_self(), ...)");
5028 AFTER
= POST_FN(host_page_size
);
5032 POST(host_get_io_master
)
5036 mach_msg_header_t Head
;
5037 /* start of the kernel processed data */
5038 mach_msg_body_t msgh_body
;
5039 mach_msg_port_descriptor_t io_master
;
5040 /* end of the kernel processed data */
5044 Reply
*reply
= (Reply
*)ARG1
;
5046 assign_port_name(reply
->io_master
.name
, "io_master-%p");
5047 PRINT("%s", name_for_port(reply
->io_master
.name
));
5050 PRE(host_get_io_master
)
5054 // mach_msg_header_t Head;
5058 // Request *req = (Request *)ARG1;
5060 PRINT("host_get_io_master(mach_host_self())");
5062 AFTER
= POST_FN(host_get_io_master
);
5066 POST(host_get_clock_service
)
5070 mach_msg_header_t Head
;
5071 /* start of the kernel processed data */
5072 mach_msg_body_t msgh_body
;
5073 mach_msg_port_descriptor_t clock_serv
;
5074 /* end of the kernel processed data */
5078 Reply
*reply
= (Reply
*)ARG1
;
5080 assign_port_name(reply
->clock_serv
.name
, "clock-%p");
5081 PRINT("%s", name_for_port(reply
->clock_serv
.name
));
5084 PRE(host_get_clock_service
)
5088 mach_msg_header_t Head
;
5090 clock_id_t clock_id
;
5094 Request
*req
= (Request
*)ARG1
;
5096 PRINT("host_get_clock_service(mach_host_self(), %d)", req
->clock_id
);
5098 AFTER
= POST_FN(host_get_clock_service
);
5102 PRE(host_request_notification
)
5106 mach_msg_header_t Head
;
5107 /* start of the kernel processed data */
5108 mach_msg_body_t msgh_body
;
5109 mach_msg_port_descriptor_t notify_port
;
5110 /* end of the kernel processed data */
5112 host_flavor_t notify_type
;
5116 Request
*req
= (Request
*)ARG1
;
5118 if (MACH_REMOTE
== mach_task_self()) {
5119 if (req
->notify_type
== 0) {
5120 PRINT("host_request_notification(mach_host_self(), %s, %s)",
5121 "HOST_NOTIFY_CALENDAR_CHANGE",
5122 name_for_port(req
->notify_port
.name
));
5124 PRINT("host_request_notification(mach_host_self(), %d, %s)",
5126 name_for_port(req
->notify_port
.name
));
5129 PRINT("host_request_notification(%s, %d, %s)",
5130 name_for_port(MACH_REMOTE
),
5132 name_for_port(req
->notify_port
.name
));
5135 // GrP fixme only do this on success
5136 assign_port_name(req
->notify_port
.name
, "host_notify-%p");
5140 PRE(host_create_mach_voucher
)
5144 mach_msg_header_t Head
;
5146 mach_msg_type_number_t recipesCnt
;
5147 uint8_t recipes
[5120];
5151 Request
*req
= (Request
*)ARG1
;
5153 PRINT("host_create_mach_voucher(count %u)",
5156 AFTER
= POST_FN(host_create_mach_voucher
);
5160 POST(host_create_mach_voucher
)
5164 mach_msg_header_t Head
;
5165 /* start of the kernel processed data */
5166 mach_msg_body_t msgh_body
;
5167 mach_msg_port_descriptor_t voucher
;
5168 /* end of the kernel processed data */
5172 Reply
*reply
= (Reply
*)ARG1
;
5174 // RK fixme properly parse this return type
5175 PRINT("got voucher %#x ", reply
->voucher
.name
);
5179 PRE(host_get_special_port
)
5183 mach_msg_header_t Head
;
5190 Request
*req
= (Request
*)ARG1
;
5192 PRINT("host_get_special_port(node %d)", req
->node
);
5194 switch (req
->which
) {
5196 PRINT("host_get_special_port(%s, HOST_PORT)",
5197 name_for_port(MACH_REMOTE
));
5199 case HOST_PRIV_PORT
:
5200 PRINT("host_get_special_port(%s, HOST_PRIV_PORT)",
5201 name_for_port(MACH_REMOTE
));
5203 case HOST_IO_MASTER_PORT
:
5204 PRINT("host_get_special_port(%s, HOST_IO_MASTER_PORT)",
5205 name_for_port(MACH_REMOTE
));
5207 // Not provided by kernel
5208 case HOST_DYNAMIC_PAGER_PORT
:
5209 PRINT("host_get_special_port(%s, HOST_DYNAMIC_PAGER_PORT)",
5210 name_for_port(MACH_REMOTE
));
5212 case HOST_AUDIT_CONTROL_PORT
:
5213 PRINT("host_get_special_port(%s, HOST_AUDIT_CONTROL_PORT)",
5214 name_for_port(MACH_REMOTE
));
5216 case HOST_USER_NOTIFICATION_PORT
:
5217 PRINT("host_get_special_port(%s, HOST_USER_NOTIFICATION_PORT)",
5218 name_for_port(MACH_REMOTE
));
5223 PRINT("host_get_special_port(%s, %d)",
5224 name_for_port(MACH_REMOTE
), req
->which
);
5228 MACH_ARG(host_get_special_port
.which
) = req
->which
;
5230 AFTER
= POST_FN(host_get_special_port
);
5234 POST(host_get_special_port
)
5238 mach_msg_header_t Head
;
5239 /* start of the kernel processed data */
5240 mach_msg_body_t msgh_body
;
5241 mach_msg_port_descriptor_t port
;
5242 /* end of the kernel processed data */
5246 Reply
*reply
= (Reply
*)ARG1
;
5248 PRINT("got port %#x ", reply
->port
.name
);
5250 /* The required entry in the allocated_ports list (mapping) might
5251 not exist, due perhaps to broken syscall wrappers (mach__N etc).
5252 Create a minimal entry so that assign_port_name below doesn't
5253 cause an assertion. */
5254 if (!port_exists(reply
->port
.name
)) {
5255 port_create_vanilla(reply
->port
.name
);
5258 switch (MACH_ARG(host_get_special_port
.which
)) {
5260 assign_port_name(reply
->port
.name
, "port-%p");
5262 case HOST_PRIV_PORT
:
5263 assign_port_name(reply
->port
.name
, "priv-%p");
5265 case HOST_IO_MASTER_PORT
:
5266 assign_port_name(reply
->port
.name
, "io-master-%p");
5268 // Not provided by kernel
5269 case HOST_DYNAMIC_PAGER_PORT
:
5270 assign_port_name(reply
->port
.name
, "dynamic-pager-%p");
5272 case HOST_AUDIT_CONTROL_PORT
:
5273 assign_port_name(reply
->port
.name
, "audit-control-%p");
5275 case HOST_USER_NOTIFICATION_PORT
:
5276 assign_port_name(reply
->port
.name
, "user-notification-%p");
5281 assign_port_name(reply
->port
.name
, "special-%p");
5285 PRINT("%s", name_for_port(reply
->port
.name
));
5288 /* ---------------------------------------------------------------------
5289 mach_msg: messages to a task
5290 ------------------------------------------------------------------ */
5292 // JRS 2011-Aug-25: just guessing here. I have no clear idea how
5293 // these structs are derived. They obviously relate to the various
5294 // .def files in the xnu sources, and can also be found in some
5295 // form in /usr/include/mach/*.h, but not sure how these all
5296 // relate to each other.
5298 PRE(mach_port_set_context
)
5302 mach_msg_header_t Head
;
5304 mach_port_name_t name
;
5305 mach_vm_address_t context
;
5309 Request
*req
= (Request
*)ARG1
;
5311 PRINT("mach_port_set_context(%s, %s, 0x%llx)",
5312 name_for_port(MACH_REMOTE
),
5313 name_for_port(req
->name
), req
->context
);
5315 AFTER
= POST_FN(mach_port_set_context
);
5318 POST(mach_port_set_context
)
5322 // mach_msg_header_t Head;
5323 // NDR_record_t NDR;
5324 // kern_return_t RetCode;
5330 // JRS 2011-Aug-25 FIXME completely bogus
5331 PRE(task_get_exception_ports
)
5335 // mach_msg_header_t Head;
5336 // NDR_record_t NDR;
5337 // exception_mask_t exception_mask;
5341 PRINT("task_get_exception_ports(BOGUS)");
5342 AFTER
= POST_FN(task_get_exception_ports
);
5345 POST(task_get_exception_ports
)
5349 // mach_msg_header_t Head;
5350 // /* start of the kernel processed data */
5351 // mach_msg_body_t msgh_body;
5352 // mach_msg_port_descriptor_t old_handlers[32];
5353 // /* end of the kernel processed data */
5354 // NDR_record_t NDR;
5355 // mach_msg_type_number_t masksCnt;
5356 // exception_mask_t masks[32];
5357 // exception_behavior_t old_behaviors[32];
5358 // thread_state_flavor_t old_flavors[32];
5364 ///////////////////////////////////////////////////
5370 mach_msg_header_t Head
;
5372 mach_port_name_t name
;
5376 Request
*req
= (Request
*)ARG1
;
5378 PRINT("mach_port_type(%s, %s, ...)",
5379 name_for_port(MACH_REMOTE
), name_for_port(req
->name
));
5381 AFTER
= POST_FN(mach_port_type
);
5384 POST(mach_port_type
)
5389 PRE(mach_port_extract_member
)
5393 mach_msg_header_t Head
;
5395 mach_port_name_t name
;
5396 mach_port_name_t pset
;
5400 Request
*req
= (Request
*)ARG1
;
5402 PRINT("mach_port_extract_member(%s, 0x%x, 0x%x)",
5403 name_for_port(MACH_REMOTE
),
5404 req
->name
, req
->pset
);
5406 AFTER
= POST_FN(mach_port_extract_member
);
5408 // GrP fixme port tracker?
5411 POST(mach_port_extract_member
)
5415 mach_msg_header_t Head
;
5417 kern_return_t RetCode
;
5421 Reply
*reply
= (Reply
*)ARG1
;
5423 if (reply
->RetCode
) PRINT("mig return %d", reply
->RetCode
);
5427 PRE(mach_port_allocate
)
5431 mach_msg_header_t Head
;
5433 mach_port_right_t right
;
5437 Request
*req
= (Request
*)ARG1
;
5439 PRINT("mach_port_allocate(mach_task_self(), %d, ...)", req
->right
);
5441 MACH_ARG(mach_port_allocate
.right
) = req
->right
;
5443 AFTER
= POST_FN(mach_port_allocate
);
5446 POST(mach_port_allocate
)
5450 mach_msg_header_t Head
;
5452 kern_return_t RetCode
;
5453 mach_port_name_t name
;
5457 Reply
*reply
= (Reply
*)ARG1
;
5459 if (!reply
->RetCode
) {
5460 if (MACH_REMOTE
== vg_task_port
) {
5461 // GrP fixme port tracking is too imprecise
5462 // vg_assert(!port_exists(reply->name));
5463 record_unnamed_port(tid
, reply
->name
, MACH_ARG(mach_port_allocate
.right
));
5464 PRINT("got port 0x%x", reply
->name
);
5466 VG_(printf
)("UNKNOWN inserted port 0x%x into remote task\n", reply
->name
);
5469 PRINT("mig return %d", reply
->RetCode
);
5474 PRE(mach_port_deallocate
)
5478 mach_msg_header_t Head
;
5480 mach_port_name_t name
;
5484 Request
*req
= (Request
*)ARG1
;
5486 PRINT("mach_port_deallocate(%s, %s)",
5487 name_for_port(MACH_REMOTE
),
5488 name_for_port(req
->name
));
5490 MACH_ARG(mach_port
.port
) = req
->name
;
5492 AFTER
= POST_FN(mach_port_deallocate
);
5494 // Must block to prevent race (other thread allocates and
5495 // notifies after we deallocate but before we notify)
5496 *flags
&= ~SfMayBlock
;
5499 POST(mach_port_deallocate
)
5503 mach_msg_header_t Head
;
5505 kern_return_t RetCode
;
5509 Reply
*reply
= (Reply
*)ARG1
;
5511 if (!reply
->RetCode
) {
5512 if (MACH_REMOTE
== vg_task_port
) {
5513 // Must have cleared SfMayBlock in PRE to prevent race
5514 record_port_dealloc(MACH_ARG(mach_port
.port
));
5516 VG_(printf
)("UNKNOWN remote port dealloc\n");
5519 PRINT("mig return %d", reply
->RetCode
);
5524 PRE(mach_port_get_refs
)
5528 mach_msg_header_t Head
;
5530 mach_port_name_t name
;
5531 mach_port_right_t right
;
5535 Request
*req
= (Request
*)ARG1
;
5537 PRINT("mach_port_get_refs(%s, %s, 0x%x)",
5538 name_for_port(MACH_REMOTE
),
5539 name_for_port(req
->name
), req
->right
);
5541 MACH_ARG(mach_port_mod_refs
.port
) = req
->name
;
5542 MACH_ARG(mach_port_mod_refs
.right
) = req
->right
;
5544 AFTER
= POST_FN(mach_port_get_refs
);
5547 POST(mach_port_get_refs
)
5551 mach_msg_header_t Head
;
5553 kern_return_t RetCode
;
5554 mach_port_urefs_t refs
;
5558 Reply
*reply
= (Reply
*)ARG1
;
5560 if (!reply
->RetCode
) {
5561 PRINT("got refs=%d", reply
->refs
);
5563 PRINT("mig return %d", reply
->RetCode
);
5568 PRE(mach_port_mod_refs
)
5572 mach_msg_header_t Head
;
5574 mach_port_name_t name
;
5575 mach_port_right_t right
;
5576 mach_port_delta_t delta
;
5580 Request
*req
= (Request
*)ARG1
;
5582 PRINT("mach_port_mod_refs(%s, %s, 0x%x, 0x%x)",
5583 name_for_port(MACH_REMOTE
),
5584 name_for_port(req
->name
), req
->right
, req
->delta
);
5586 MACH_ARG(mach_port_mod_refs
.port
) = req
->name
;
5587 MACH_ARG(mach_port_mod_refs
.right
) = req
->right
;
5588 MACH_ARG(mach_port_mod_refs
.delta
) = req
->delta
;
5590 AFTER
= POST_FN(mach_port_mod_refs
);
5592 // Must block to prevent race (other thread allocates and
5593 // notifies after we deallocate but before we notify)
5594 *flags
&= ~SfMayBlock
;
5597 POST(mach_port_mod_refs
)
5601 mach_msg_header_t Head
;
5603 kern_return_t RetCode
;
5607 Reply
*reply
= (Reply
*)ARG1
;
5609 if (!reply
->RetCode
) {
5610 if (MACH_REMOTE
== vg_task_port
) {
5611 // Must have cleared SfMayBlock in PRE to prevent race
5612 record_port_mod_refs(MACH_ARG(mach_port_mod_refs
.port
),
5613 MACH_PORT_TYPE(MACH_ARG(mach_port_mod_refs
.right
)),
5614 MACH_ARG(mach_port_mod_refs
.delta
));
5616 VG_(printf
)("UNKNOWN remote port mod refs\n");
5619 PRINT("mig return %d", reply
->RetCode
);
5624 PRE(mach_port_get_set_status
)
5628 mach_msg_header_t Head
;
5630 mach_port_name_t name
;
5634 Request
*req
= (Request
*)ARG1
;
5636 PRINT("mach_port_get_set_status(%s, %s)",
5637 name_for_port(MACH_REMOTE
),
5638 name_for_port(req
->name
));
5640 AFTER
= POST_FN(mach_port_get_set_status
);
5643 POST(mach_port_get_set_status
)
5647 // mach_msg_header_t Head;
5648 // /* start of the kernel processed data */
5649 // mach_msg_body_t msgh_body;
5650 // mach_msg_ool_descriptor_t members;
5651 // /* end of the kernel processed data */
5652 // NDR_record_t NDR;
5653 // mach_msg_type_number_t membersCnt;
5654 // mach_msg_trailer_t trailer;
5658 // Reply *reply = (Reply *)ARG1;
5660 // GrP fixme nothing to do?
5664 PRE(mach_port_move_member
)
5668 mach_msg_header_t Head
;
5670 mach_port_name_t member
;
5671 mach_port_name_t after
;
5675 Request
*req
= (Request
*)ARG1
;
5677 PRINT("mach_port_move_member(%s, %s, %s)",
5678 name_for_port(MACH_REMOTE
),
5679 name_for_port(req
->member
),
5680 name_for_port(req
->after
));
5682 MACH_ARG(mach_port_move_member.member) = req->member;
5683 MACH_ARG(mach_port_move_member.after) = req->after;
5685 AFTER
= POST_FN(mach_port_move_member
);
5688 POST(mach_port_move_member
)
5692 mach_msg_header_t Head
;
5694 kern_return_t RetCode
;
5695 mach_msg_trailer_t trailer
;
5699 Reply
*reply
= (Reply
*)ARG1
;
5701 if (!reply
->RetCode
) {
5702 // fixme port set tracker?
5704 PRINT("mig return %d", reply
->RetCode
);
5709 PRE(mach_port_destroy
)
5713 mach_msg_header_t Head
;
5715 mach_port_name_t name
;
5719 Request
*req
= (Request
*)ARG1
;
5721 PRINT("mach_port_destroy(%s, %s)",
5722 name_for_port(MACH_REMOTE
),
5723 name_for_port(req
->name
));
5725 MACH_ARG(mach_port
.port
) = req
->name
;
5727 AFTER
= POST_FN(mach_port_destroy
);
5729 // Must block to prevent race (other thread allocates and
5730 // notifies after we deallocate but before we notify)
5731 *flags
&= ~SfMayBlock
;
5734 POST(mach_port_destroy
)
5738 mach_msg_header_t Head
;
5740 kern_return_t RetCode
;
5744 Reply
*reply
= (Reply
*)ARG1
;
5746 if (!reply
->RetCode
) {
5747 if (MACH_REMOTE
== vg_task_port
) {
5748 // Must have cleared SfMayBlock in PRE to prevent race
5749 record_port_destroy(MACH_ARG(mach_port
.port
));
5751 VG_(printf
)("UNKNOWN remote port destroy\n");
5754 PRINT("mig return %d", reply
->RetCode
);
5759 PRE(mach_port_request_notification
)
5763 mach_msg_header_t Head
;
5764 /* start of the kernel processed data */
5765 mach_msg_body_t msgh_body
;
5766 mach_msg_port_descriptor_t notify
;
5767 /* end of the kernel processed data */
5769 mach_port_name_t name
;
5770 mach_msg_id_t msgid
;
5771 mach_port_mscount_t sync
;
5775 Request
*req
= (Request
*)ARG1
;
5777 PRINT("mach_port_request_notification(%s, %s, %d, %d, %d, %d, ...)",
5778 name_for_port(MACH_REMOTE
),
5779 name_for_port(req
->name
), req
->msgid
, req
->sync
,
5780 req
->notify
.name
, req
->notify
.disposition
);
5782 AFTER
= POST_FN(mach_port_request_notification
);
5785 POST(mach_port_request_notification
)
5787 // GrP fixme port tracker? not sure
5791 PRE(mach_port_insert_right
)
5795 mach_msg_header_t Head
;
5796 /* start of the kernel processed data */
5797 mach_msg_body_t msgh_body
;
5798 mach_msg_port_descriptor_t poly
;
5799 /* end of the kernel processed data */
5801 mach_port_name_t name
;
5805 Request
*req
= (Request
*)ARG1
;
5807 PRINT("mach_port_insert_right(%s, %s, %d, %d)",
5808 name_for_port(MACH_REMOTE
),
5809 name_for_port(req
->name
), req
->poly
.name
, req
->poly
.disposition
);
5811 AFTER
= POST_FN(mach_port_insert_right
);
5813 if (MACH_REMOTE
== mach_task_self()) {
5814 // GrP fixme import_complex_message handles everything?
5815 // what about export_complex_message for MOVE variants?
5817 VG_(printf
)("UNKNOWN mach_port_insert_right into remote task!\n");
5818 // GrP fixme also may remove rights from this task?
5821 // GrP fixme port tracker?
5824 POST(mach_port_insert_right
)
5829 PRE(mach_port_extract_right
)
5833 mach_msg_header_t Head
;
5835 mach_port_name_t name
;
5836 mach_msg_type_name_t msgt_name
;
5840 Request
*req
= (Request
*)ARG1
;
5842 PRINT("mach_port_extract_right(%s, %s, %d)",
5843 name_for_port(MACH_REMOTE
),
5844 name_for_port(req
->name
), req
->msgt_name
);
5846 AFTER
= POST_FN(mach_port_extract_right
);
5848 // fixme port tracker?
5851 POST(mach_port_extract_right
)
5853 // fixme import_complex_message handles the returned result, right?
5857 PRE(mach_port_get_attributes
)
5861 mach_msg_header_t Head
;
5863 mach_port_name_t name
;
5864 mach_port_flavor_t flavor
;
5865 mach_msg_type_number_t port_info_outCnt
;
5869 Request
*req
= (Request
*)ARG1
;
5871 PRINT("mach_port_get_attributes(%s, %s, %d, ..., %d)",
5872 name_for_port(MACH_REMOTE
),
5873 name_for_port(req
->name
), req
->flavor
, req
->port_info_outCnt
);
5875 AFTER
= POST_FN(mach_port_get_attributes
);
5878 POST(mach_port_get_attributes
)
5883 PRE(mach_port_set_attributes
)
5887 mach_msg_header_t Head
;
5889 mach_port_name_t name
;
5890 mach_port_flavor_t flavor
;
5891 mach_msg_type_number_t port_infoCnt
;
5892 integer_t port_info
[10];
5896 Request
*req
= (Request
*)ARG1
;
5898 PRINT("mach_port_set_attributes(%s, %s, %d, ..., %d)",
5899 name_for_port(MACH_REMOTE
),
5900 name_for_port(req
->name
), req
->flavor
, req
->port_infoCnt
);
5902 AFTER
= POST_FN(mach_port_set_attributes
);
5905 POST(mach_port_set_attributes
)
5910 PRE(mach_port_insert_member
)
5914 mach_msg_header_t Head
;
5916 mach_port_name_t name
;
5917 mach_port_name_t pset
;
5921 Request
*req
= (Request
*)ARG1
;
5923 PRINT("mach_port_insert_member(%s, 0x%x, 0x%x)",
5924 name_for_port(MACH_REMOTE
), req
->name
, req
->pset
);
5926 AFTER
= POST_FN(mach_port_insert_member
);
5928 // GrP fixme port tracker?
5931 POST(mach_port_insert_member
)
5936 PRE(task_get_special_port
)
5940 mach_msg_header_t Head
;
5946 Request
*req
= (Request
*)ARG1
;
5948 switch (req
->which_port
) {
5949 case TASK_KERNEL_PORT
:
5950 PRINT("task_get_special_port(%s, TASK_KERNEL_PORT)",
5951 name_for_port(MACH_REMOTE
));
5953 case TASK_HOST_PORT
:
5954 PRINT("task_get_special_port(%s, TASK_HOST_PORT)",
5955 name_for_port(MACH_REMOTE
));
5957 case TASK_BOOTSTRAP_PORT
:
5958 PRINT("task_get_special_port(%s, TASK_BOOTSTRAP_PORT)",
5959 name_for_port(MACH_REMOTE
));
5961 #if DARWIN_VERS < DARWIN_10_8
5962 /* These disappeared in 10.8 */
5963 case TASK_WIRED_LEDGER_PORT
:
5964 PRINT("task_get_special_port(%s, TASK_WIRED_LEDGER_PORT)",
5965 name_for_port(MACH_REMOTE
));
5967 case TASK_PAGED_LEDGER_PORT
:
5968 PRINT("task_get_special_port(%s, TASK_PAGED_LEDGER_PORT)",
5969 name_for_port(MACH_REMOTE
));
5973 PRINT("task_get_special_port(%s, %d)",
5974 name_for_port(MACH_REMOTE
), req
->which_port
);
5978 MACH_ARG(task_get_special_port
.which_port
) = req
->which_port
;
5980 AFTER
= POST_FN(task_get_special_port
);
5983 POST(task_get_special_port
)
5987 mach_msg_header_t Head
;
5988 /* start of the kernel processed data */
5989 mach_msg_body_t msgh_body
;
5990 mach_msg_port_descriptor_t special_port
;
5991 /* end of the kernel processed data */
5995 Reply
*reply
= (Reply
*)ARG1
;
5997 PRINT("got port %#x ", reply
->special_port
.name
);
5999 switch (MACH_ARG(task_get_special_port
.which_port
)) {
6000 case TASK_BOOTSTRAP_PORT
:
6001 vg_bootstrap_port
= reply
->special_port
.name
;
6002 assign_port_name(reply
->special_port
.name
, "bootstrap");
6004 case TASK_KERNEL_PORT
:
6005 assign_port_name(reply
->special_port
.name
, "kernel");
6007 case TASK_HOST_PORT
:
6008 assign_port_name(reply
->special_port
.name
, "host");
6010 #if DARWIN_VERS < DARWIN_10_8
6011 /* These disappeared in 10.8 */
6012 case TASK_WIRED_LEDGER_PORT
:
6013 assign_port_name(reply
->special_port
.name
, "wired-ledger");
6015 case TASK_PAGED_LEDGER_PORT
:
6016 assign_port_name(reply
->special_port
.name
, "paged-ledger");
6020 assign_port_name(reply
->special_port
.name
, "special-%p");
6024 PRINT("%s", name_for_port(reply
->special_port
.name
));
6028 PRE(task_set_special_port
)
6032 mach_msg_header_t Head
;
6033 /* start of the kernel processed data */
6034 mach_msg_body_t msgh_body
;
6035 mach_msg_port_descriptor_t special_port
;
6036 /* end of the kernel processed data */
6042 Request
*req
= (Request
*)ARG1
;
6044 PRINT("got port %#x ", req
->special_port
.name
);
6046 // MACH_ARG(task_set_special_port.which_port) = req->which_port;
6047 PRINT("%s", name_for_port(req
->special_port
.name
));
6049 AFTER
= POST_FN(task_set_special_port
);
6052 POST(task_set_special_port
)
6056 mach_msg_header_t Head
;
6058 kern_return_t RetCode
;
6062 Reply
*reply
= (Reply
*)ARG1
;
6063 if (!reply
->RetCode
) {
6065 PRINT("mig return %d", reply
->RetCode
);
6070 PRE(semaphore_create
)
6074 mach_msg_header_t Head
;
6081 Request
*req
= (Request
*)ARG1
;
6083 PRINT("semaphore_create(%s, ..., %d, %d)",
6084 name_for_port(MACH_REMOTE
), req
->policy
, req
->value
);
6086 AFTER
= POST_FN(semaphore_create
);
6089 POST(semaphore_create
)
6093 mach_msg_header_t Head
;
6094 /* start of the kernel processed data */
6095 mach_msg_body_t msgh_body
;
6096 mach_msg_port_descriptor_t semaphore
;
6097 /* end of the kernel processed data */
6098 mach_msg_trailer_t trailer
;
6102 Reply
*reply
= (Reply
*)ARG1
;
6104 assign_port_name(reply
->semaphore
.name
, "semaphore-%p");
6105 PRINT("%s", name_for_port(reply
->semaphore
.name
));
6109 PRE(semaphore_destroy
)
6113 mach_msg_header_t Head
;
6114 /* start of the kernel processed data */
6115 mach_msg_body_t msgh_body
;
6116 mach_msg_port_descriptor_t semaphore
;
6117 /* end of the kernel processed data */
6118 mach_msg_trailer_t trailer
;
6122 Request
*req
= (Request
*)ARG1
;
6124 PRINT("semaphore_destroy(%s, %s)",
6125 name_for_port(MACH_REMOTE
), name_for_port(req
->semaphore
.name
));
6127 record_port_destroy(req
->semaphore
.name
);
6129 AFTER
= POST_FN(semaphore_destroy
);
6132 POST(semaphore_destroy
)
6136 mach_msg_header_t Head
;
6138 kern_return_t RetCode
;
6139 mach_msg_trailer_t trailer
;
6143 Reply
*reply
= (Reply
*)ARG1
;
6144 if (!reply
->RetCode
) {
6146 PRINT("mig return %d", reply
->RetCode
);
6150 PRE(task_policy_set
)
6154 mach_msg_header_t Head
;
6156 task_policy_flavor_t flavor
;
6157 mach_msg_type_number_t policy_infoCnt
;
6158 integer_t policy_info
[16];
6162 Request
*req
= (Request
*)ARG1
;
6164 PRINT("task_policy_set(%s) flavor:%d", name_for_port(MACH_REMOTE
), req
->flavor
);
6166 AFTER
= POST_FN(task_policy_set
);
6169 POST(task_policy_set
)
6173 mach_msg_header_t Head
;
6175 kern_return_t RetCode
;
6179 Reply
*reply
= (Reply
*)ARG1
;
6180 if (!reply
->RetCode
) {
6182 PRINT("mig return %d", reply
->RetCode
);
6187 PRE(mach_ports_register
)
6191 // mach_msg_header_t Head;
6192 // /* start of the kernel processed data */
6193 // mach_msg_body_t msgh_body;
6194 // mach_msg_ool_ports_descriptor_t init_port_set;
6195 // /* end of the kernel processed data */
6196 // NDR_record_t NDR;
6197 // mach_msg_type_number_t init_port_setCnt;
6201 // Request *req = (Request *)ARG1;
6203 PRINT("mach_ports_register(%s)", name_for_port(MACH_REMOTE
));
6205 AFTER
= POST_FN(mach_ports_register
);
6208 POST(mach_ports_register
)
6212 mach_msg_header_t Head
;
6214 kern_return_t RetCode
;
6218 Reply
*reply
= (Reply
*)ARG1
;
6219 if (!reply
->RetCode
) {
6221 PRINT("mig return %d", reply
->RetCode
);
6226 PRE(mach_ports_lookup
)
6230 // mach_msg_header_t Head;
6234 // Request *req = (Request *)ARG1;
6236 PRINT("mach_ports_lookup(%s)", name_for_port(MACH_REMOTE
));
6238 AFTER
= POST_FN(mach_ports_lookup
);
6241 POST(mach_ports_lookup
)
6245 // mach_msg_header_t Head;
6246 // /* start of the kernel processed data */
6247 // mach_msg_body_t msgh_body;
6248 // mach_msg_ool_ports_descriptor_t init_port_set;
6249 // /* end of the kernel processed data */
6250 // NDR_record_t NDR;
6251 // mach_msg_type_number_t init_port_setCnt;
6255 // Reply *reply = (Reply *)ARG1;
6263 mach_msg_header_t Head
;
6265 task_flavor_t flavor
;
6266 mach_msg_type_number_t task_info_outCnt
;
6270 Request
*req
= (Request
*)ARG1
;
6272 PRINT("task_info(%s) flavor:%d", name_for_port(MACH_REMOTE
), req
->flavor
);
6274 AFTER
= POST_FN(task_info
);
6281 mach_msg_header_t Head
;
6283 kern_return_t RetCode
;
6284 mach_msg_type_number_t task_info_outCnt
;
6285 integer_t task_info_out
[52];
6289 Reply
*reply
= (Reply
*)ARG1
;
6290 if (!reply
->RetCode
) {
6292 PRINT("mig return %d", reply
->RetCode
);
6301 mach_msg_header_t Head
;
6303 task_flavor_t flavor
;
6304 mach_msg_type_number_t task_info_inCnt
;
6305 integer_t task_info_in
[52];
6309 Request
*req
= (Request
*)ARG1
;
6311 PRINT("task_set_info(%s) flavor:%d", name_for_port(MACH_REMOTE
), req
->flavor
);
6313 AFTER
= POST_FN(task_set_info
);
6320 mach_msg_header_t Head
;
6322 kern_return_t RetCode
;
6326 Reply
*reply
= (Reply
*)ARG1
;
6327 if (!reply
->RetCode
) {
6329 PRINT("mig return %d", reply
->RetCode
);
6337 // mach_msg_header_t Head;
6341 // Request *req = (Request *)ARG1;
6343 PRINT("task_threads(%s)", name_for_port(MACH_REMOTE
));
6345 AFTER
= POST_FN(task_threads
);
6352 mach_msg_header_t Head
;
6353 /* start of the kernel processed data */
6354 mach_msg_body_t msgh_body
;
6355 mach_msg_ool_ports_descriptor_t act_list
;
6356 /* end of the kernel processed data */
6358 mach_msg_type_number_t act_listCnt
;
6359 mach_msg_trailer_t trailer
;
6363 Reply
*reply
= (Reply
*)ARG1
;
6365 if (MACH_REMOTE
== vg_task_port
) {
6366 assign_port_names(&reply
->act_list
, "thread-%p");
6368 assign_port_names(&reply
->act_list
, "remote-thread-%p");
6375 PRINT("task_suspend(%s)", name_for_port(MACH_REMOTE
));
6377 if (MACH_REMOTE
== vg_task_port
) {
6378 // GrP fixme self-suspend
6381 // suspend other - no problem
6384 AFTER
= POST_FN(task_suspend
);
6394 PRINT("task_resume(%s)", name_for_port(MACH_REMOTE
));
6396 if (MACH_REMOTE
== vg_task_port
) {
6397 // GrP fixme self-resume
6400 // resume other - no problem
6403 AFTER
= POST_FN(task_resume
);
6415 mach_msg_header_t Head
;
6417 vm_address_t address
;
6423 Request
*req
= (Request
*)ARG1
;
6425 PRINT("vm_allocate (%s, at %#llx, size %llu, flags %#x)",
6426 name_for_port(MACH_REMOTE
),
6427 (ULong
)req
->address
, (ULong
)req
->size
, req
->flags
);
6429 MACH_ARG(vm_allocate
.size
) = req
->size
;
6430 MACH_ARG(vm_allocate
.flags
) = req
->flags
;
6432 AFTER
= POST_FN(vm_allocate
);
6439 mach_msg_header_t Head
;
6441 kern_return_t RetCode
;
6442 vm_address_t address
;
6443 mach_msg_trailer_t trailer
;
6447 Reply
*reply
= (Reply
*)ARG1
;
6449 if (!reply
->RetCode
) {
6450 if (MACH_REMOTE
== vg_task_port
) {
6451 PRINT("allocated at %#llx", (ULong
)reply
->address
);
6452 // requesting 0 bytes returns address 0 with no error
6453 if (MACH_ARG(vm_allocate
.size
)) {
6454 ML_(notify_core_and_tool_of_mmap
)(
6455 reply
->address
, MACH_ARG(vm_allocate
.size
),
6456 VKI_PROT_READ
|VKI_PROT_WRITE
, VKI_MAP_ANON
, -1, 0);
6459 PRINT("allocated at %#llx in remote task %s",
6460 (ULong
)reply
->address
,
6461 name_for_port(MACH_REMOTE
));
6464 PRINT("mig return %d", reply
->RetCode
);
6473 mach_msg_header_t Head
;
6475 vm_address_t address
;
6480 Request
*req
= (Request
*)ARG1
;
6482 PRINT("vm_deallocate(%s, at %#llx, size %llu)",
6483 name_for_port(MACH_REMOTE
),
6484 (ULong
)req
->address
, (ULong
)req
->size
);
6486 MACH_ARG(vm_deallocate
.address
) = req
->address
;
6487 MACH_ARG(vm_deallocate
.size
) = req
->size
;
6489 AFTER
= POST_FN(vm_deallocate
);
6491 // Must block to prevent race (other thread allocates and
6492 // notifies after we deallocate but before we notify)
6493 *flags
&= ~SfMayBlock
;
6500 mach_msg_header_t Head
;
6502 kern_return_t RetCode
;
6503 mach_msg_trailer_t trailer
;
6507 Reply
*reply
= (Reply
*)ARG1
;
6509 if (!reply
->RetCode
) {
6510 if (MACH_REMOTE
== vg_task_port
) {
6511 if (MACH_ARG(vm_deallocate
.size
)) {
6512 Addr start
= VG_PGROUNDDN(MACH_ARG(vm_deallocate
.address
));
6513 Addr end
= VG_PGROUNDUP(MACH_ARG(vm_deallocate
.address
) +
6514 MACH_ARG(vm_deallocate
.size
));
6515 // Must have cleared SfMayBlock in PRE to prevent race
6516 ML_(notify_core_and_tool_of_munmap
)(start
, end
- start
);
6520 PRINT("mig return %d", reply
->RetCode
);
6529 mach_msg_header_t Head
;
6531 vm_address_t address
;
6533 boolean_t set_maximum
;
6534 vm_prot_t new_protection
;
6538 Request
*req
= (Request
*)ARG1
;
6540 PRINT("vm_protect(%s, at %#llx, size %llu, set_max %d, prot %d)",
6541 name_for_port(MACH_REMOTE
),
6542 (ULong
)req
->address
, (ULong
)req
->size
,
6543 req
->set_maximum
, req
->new_protection
);
6545 MACH_ARG(vm_protect
.address
) = req
->address
;
6546 MACH_ARG(vm_protect
.size
) = req
->size
;
6547 MACH_ARG(vm_protect
.set_maximum
) = req
->set_maximum
;
6548 MACH_ARG(vm_protect
.new_protection
) = req
->new_protection
;
6550 AFTER
= POST_FN(vm_protect
);
6557 mach_msg_header_t Head
;
6559 kern_return_t RetCode
;
6560 mach_msg_trailer_t trailer
;
6564 Reply
*reply
= (Reply
*)ARG1
;
6566 if (!reply
->RetCode
) {
6567 if (MACH_REMOTE
== vg_task_port
) {
6568 Addr start
= VG_PGROUNDDN(MACH_ARG(vm_protect
.address
));
6569 Addr end
= VG_PGROUNDUP(MACH_ARG(vm_protect
.address
) +
6570 MACH_ARG(vm_protect
.size
));
6571 UInt prot
= MACH_ARG(vm_protect
.new_protection
);
6572 if (MACH_ARG(vm_protect
.set_maximum
)) {
6573 // GrP fixme mprotect max
6574 VG_(printf
)("UNKNOWN vm_protect set maximum");
6575 //VG_(mprotect_max_range)(start, end-start, prot);
6577 ML_(notify_core_and_tool_of_mprotect
)(start
, end
-start
, prot
);
6578 VG_(di_notify_vm_protect
)(start
, end
-start
, prot
);
6582 PRINT("mig return %d", reply
->RetCode
);
6591 mach_msg_header_t Head
;
6593 vm_address_t address
;
6595 vm_inherit_t new_inheritance
;
6599 Request
*req
= (Request
*)ARG1
;
6601 PRINT("vm_inherit(%s, at %#llx, size %llu, value %d)",
6602 name_for_port(MACH_REMOTE
),
6603 (ULong
)req
->address
, (ULong
)req
->size
,
6604 req
->new_inheritance
);
6606 AFTER
= POST_FN(vm_inherit
);
6613 mach_msg_header_t Head
;
6615 kern_return_t RetCode
;
6616 mach_msg_trailer_t trailer
;
6620 Reply
*reply
= (Reply
*)ARG1
;
6622 if (!reply
->RetCode
) {
6623 if (MACH_REMOTE
== vg_task_port
) {
6624 // GrP fixme do something?
6627 PRINT("mig return %d", reply
->RetCode
);
6636 mach_msg_header_t Head
;
6638 vm_address_t address
;
6643 Request
*req
= (Request
*)ARG1
;
6645 PRINT("vm_read(from %s at %#llx size %llu)",
6646 name_for_port(MACH_REMOTE
),
6647 (ULong
)req
->address
, (ULong
)req
->size
);
6649 MACH_ARG(vm_read
.addr
) = req
->address
;
6650 MACH_ARG(vm_read
.size
) = req
->size
;
6652 AFTER
= POST_FN(vm_read
);
6659 // mach_msg_header_t Head;
6660 // /* start of the kernel processed data */
6661 // mach_msg_body_t msgh_body;
6662 // mach_msg_ool_descriptor_t data;
6663 // /* end of the kernel processed data */
6664 // NDR_record_t NDR;
6665 // mach_msg_type_number_t dataCnt;
6669 // Reply *reply = (Reply *)ARG1;
6671 if (MACH_REMOTE
== vg_task_port
) {
6672 // vm_read from self
6673 // GrP fixme copy initialized state
6683 mach_msg_header_t Head
;
6685 mach_vm_address_t address
;
6686 mach_vm_size_t size
;
6690 Request
*req
= (Request
*)ARG1
;
6692 PRINT("mach_vm_read(from %s at 0x%llx size %llu)",
6693 name_for_port(MACH_REMOTE
), req
->address
, req
->size
);
6695 MACH_ARG(mach_vm_read
.addr
) = req
->address
;
6696 MACH_ARG(mach_vm_read
.size
) = req
->size
;
6698 AFTER
= POST_FN(mach_vm_read
);
6705 // mach_msg_header_t Head;
6706 // /* start of the kernel processed data */
6707 // mach_msg_body_t msgh_body;
6708 // mach_msg_ool_descriptor_t data;
6709 // /* end of the kernel processed data */
6710 // NDR_record_t NDR;
6711 // mach_msg_type_number_t dataCnt;
6715 // Reply *reply = (Reply *)ARG1;
6717 if (MACH_REMOTE
== vg_task_port
) {
6718 // vm_read from self
6719 // GrP fixme copy initialized state
6724 PRE(vm_read_overwrite
)
6728 mach_msg_header_t Head
;
6730 vm_address_t address
;
6736 Request
*req
= (Request
*)ARG1
;
6738 PRINT("vm_read_overwrite(from %s at %#llx size %llu to %#llx)",
6739 name_for_port(MACH_REMOTE
),
6740 (ULong
)req
->address
, (ULong
)req
->size
, (ULong
)req
->data
);
6742 MACH_ARG(vm_read_overwrite
.addr
) = req
->address
;
6743 MACH_ARG(vm_read_overwrite
.size
) = req
->size
;
6744 MACH_ARG(vm_read_overwrite
.data
) = req
->data
;
6746 PRE_MEM_WRITE("vm_read_overwrite(data)", req
->data
, req
->size
);
6748 AFTER
= POST_FN(vm_read_overwrite
);
6751 POST(vm_read_overwrite
)
6755 mach_msg_header_t Head
;
6757 kern_return_t RetCode
;
6762 Reply
*reply
= (Reply
*)ARG1
;
6764 if (reply
->RetCode
) {
6765 PRINT("mig return %d", reply
->RetCode
);
6767 PRINT("read %llu bytes", (unsigned long long)reply
->outsize
);
6768 if (MACH_REMOTE
== vg_task_port
) {
6769 // vm_read_overwrite from self
6770 // GrP fixme copy initialized state
6771 POST_MEM_WRITE(MACH_ARG(vm_read_overwrite
.data
), reply
->outsize
);
6773 // vm_read_overwrite from remote
6774 POST_MEM_WRITE(MACH_ARG(vm_read_overwrite
.data
), reply
->outsize
);
6784 mach_msg_header_t Head
;
6786 vm_address_t source_address
;
6788 vm_address_t dest_address
;
6792 Request
*req
= (Request
*)ARG1
;
6794 PRINT("vm_copy(%s, %#llx, %lld, %#llx)",
6795 name_for_port(MACH_REMOTE
),
6796 (ULong
)req
->source_address
,
6797 (ULong
)req
->size
, (ULong
)req
->dest_address
);
6799 MACH_ARG(vm_copy
.src
) = req
->source_address
;
6800 MACH_ARG(vm_copy
.dst
) = req
->dest_address
;
6801 MACH_ARG(vm_copy
.size
) = req
->size
;
6803 AFTER
= POST_FN(vm_copy
);
6810 mach_msg_header_t Head
;
6812 kern_return_t RetCode
;
6813 mach_msg_trailer_t trailer
;
6817 Reply
*reply
= (Reply
*)ARG1
;
6819 if (!reply
->RetCode
) {
6820 if (MACH_REMOTE
== vg_task_port
) {
6821 // GrP fixme set dst's initialization equal to src's
6822 // and wipe any symbols or translations in dst
6825 PRINT("mig return %d", reply
->RetCode
);
6834 mach_msg_header_t Head
;
6835 /* start of the kernel processed data */
6836 mach_msg_body_t msgh_body
;
6837 mach_msg_port_descriptor_t object
;
6838 /* end of the kernel processed data */
6840 vm_address_t address
;
6846 vm_prot_t cur_protection
;
6847 vm_prot_t max_protection
;
6848 vm_inherit_t inheritance
;
6852 Request
*req
= (Request
*)ARG1
;
6854 // GrP fixme check these
6855 PRINT("vm_map(in %s, at %#llx, size %llu, from %s ...)",
6856 name_for_port(MACH_REMOTE
),
6857 (ULong
)req
->address
, (ULong
)req
->size
,
6858 name_for_port(req
->object
.name
));
6860 MACH_ARG(vm_map
.size
) = req
->size
;
6861 MACH_ARG(vm_map
.copy
) = req
->copy
;
6862 MACH_ARG(vm_map
.protection
) = (req
->cur_protection
& req
->max_protection
);
6864 AFTER
= POST_FN(vm_map
);
6871 mach_msg_header_t Head
;
6873 kern_return_t RetCode
;
6874 vm_address_t address
;
6875 mach_msg_trailer_t trailer
;
6879 Reply
*reply
= (Reply
*)ARG1
;
6881 if (!reply
->RetCode
) {
6882 // GrP fixme check src and dest tasks
6883 PRINT("mapped at %#llx", (ULong
)reply
->address
);
6884 // GrP fixme max prot
6885 ML_(notify_core_and_tool_of_mmap
)(
6886 reply
->address
, VG_PGROUNDUP(MACH_ARG(vm_map
.size
)),
6887 MACH_ARG(vm_map
.protection
), VKI_MAP_SHARED
, -1, 0);
6888 // GrP fixme VKI_MAP_PRIVATE if !copy?
6890 PRINT("mig return %d", reply
->RetCode
);
6899 mach_msg_header_t Head
;
6900 /* start of the kernel processed data */
6901 mach_msg_body_t msgh_body
;
6902 mach_msg_port_descriptor_t src_task
;
6903 /* end of the kernel processed data */
6905 vm_address_t target_address
;
6909 vm_address_t src_address
;
6911 vm_inherit_t inheritance
;
6915 Request
*req
= (Request
*)ARG1
;
6917 // GrP fixme check src and dest tasks
6919 if (VG_(clo_trace_syscalls
)) {
6920 mach_port_name_t source_task
= req
->src_task
.name
;
6921 if (source_task
== mach_task_self()) {
6922 PRINT("vm_remap(mach_task_self(), "
6923 "to %#llx size %llu, from mach_task_self() at %#llx, ...)",
6924 (ULong
)req
->target_address
,
6925 (ULong
)req
->size
, (ULong
)req
->src_address
);
6927 PRINT("vm_remap(mach_task_self(), "
6928 "to %#llx size %llu, from task %u at %#llx, ...)",
6929 (ULong
)req
->target_address
, (ULong
)req
->size
,
6930 source_task
, (ULong
)req
->src_address
);
6935 // vt->syscall_arg2 = req->target_address;
6936 MACH_ARG(vm_remap
.size
) = req
->size
;
6937 // vt->syscall_arg4 = req->copy;
6939 AFTER
= POST_FN(vm_remap
);
6946 mach_msg_header_t Head
;
6948 kern_return_t RetCode
;
6949 vm_address_t target_address
;
6950 vm_prot_t cur_protection
;
6951 vm_prot_t max_protection
;
6952 mach_msg_trailer_t trailer
;
6956 Reply
*reply
= (Reply
*)ARG1
;
6958 if (!reply
->RetCode
) {
6959 // GrP fixme check src and dest tasks
6960 UInt prot
= reply
->cur_protection
& reply
->max_protection
;
6961 // GrP fixme max prot
6962 PRINT("mapped at %#llx", (ULong
)reply
->target_address
);
6963 ML_(notify_core_and_tool_of_mmap
)(
6964 reply
->target_address
, VG_PGROUNDUP(MACH_ARG(vm_remap
.size
)),
6965 prot
, VKI_MAP_SHARED
, -1, 0);
6966 // GrP fixme VKI_MAP_FIXED if !copy?
6967 // GrP fixme copy initialized bits from source to dest if source_task is also mach_task_self
6969 PRINT("mig return %d", reply
->RetCode
);
6974 PRE(mach_make_memory_entry_64
)
6978 mach_msg_header_t Head
;
6979 /* start of the kernel processed data */
6980 mach_msg_body_t msgh_body
;
6981 mach_msg_port_descriptor_t parent_entry
;
6982 /* end of the kernel processed data */
6984 memory_object_size_t size
;
6985 memory_object_offset_t offset
;
6986 vm_prot_t permission
;
6990 Request
*req
= (Request
*)ARG1
;
6992 PRINT("mach_make_memory_entry_64(%s, %llu, %llu, %d, ..., %u)",
6993 name_for_port(MACH_REMOTE
),
6994 req
->size
, req
->offset
, req
->permission
, req
->parent_entry
.type
);
6996 AFTER
= POST_FN(mach_make_memory_entry_64
);
6999 POST(mach_make_memory_entry_64
)
7003 mach_msg_header_t Head
;
7004 mach_msg_body_t msgh_body
;
7005 mach_msg_port_descriptor_t object
;
7007 memory_object_size_t size
;
7011 Reply
*reply
= (Reply
*)ARG1
;
7013 if (reply
->Head
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
7014 assign_port_name(reply
->object
.name
, "memory-%p");
7015 PRINT("%s", name_for_port(reply
->object
.name
));
7020 PRE(vm_purgable_control
)
7024 mach_msg_header_t Head
;
7026 vm_address_t address
;
7027 vm_purgable_t control
;
7032 Request
*req
= (Request
*)ARG1
;
7034 PRINT("vm_purgable_control(%s, %#llx, %d, %d)",
7035 name_for_port(MACH_REMOTE
),
7036 (ULong
)req
->address
, req
->control
, req
->state
);
7038 // GrP fixme verify address?
7040 AFTER
= POST_FN(vm_purgable_control
);
7043 POST(vm_purgable_control
)
7047 mach_msg_header_t Head
;
7049 kern_return_t RetCode
;
7054 Reply
*reply
= (Reply
*)ARG1
;
7056 if (!reply
->RetCode
) {
7058 PRINT("mig return %d", reply
->RetCode
);
7063 PRE(mach_vm_purgable_control
)
7067 mach_msg_header_t Head
;
7069 mach_vm_address_t address
;
7070 vm_purgable_t control
;
7075 Request
*req
= (Request
*)ARG1
;
7077 PRINT("mach_vm_purgable_control(%s, 0x%llx, %d, %d)",
7078 name_for_port(MACH_REMOTE
),
7079 (ULong
)req
->address
, req
->control
, req
->state
);
7081 // GrP fixme verify address?
7083 AFTER
= POST_FN(mach_vm_purgable_control
);
7086 POST(mach_vm_purgable_control
)
7090 mach_msg_header_t Head
;
7092 kern_return_t RetCode
;
7097 Reply
*reply
= (Reply
*)ARG1
;
7099 if (!reply
->RetCode
) {
7101 PRINT("mig return %d", reply
->RetCode
);
7106 PRE(mach_vm_allocate
)
7110 mach_msg_header_t Head
;
7112 mach_vm_address_t address
;
7113 mach_vm_size_t size
;
7118 Request
*req
= (Request
*)ARG1
;
7120 PRINT("mach_vm_allocate (%s, at 0x%llx, size %llu, flags 0x%x)",
7121 name_for_port(MACH_REMOTE
),
7122 req
->address
, req
->size
, req
->flags
);
7124 MACH_ARG(mach_vm_allocate
.size
) = req
->size
;
7125 MACH_ARG(mach_vm_allocate
.flags
) = req
->flags
;
7127 AFTER
= POST_FN(mach_vm_allocate
);
7130 POST(mach_vm_allocate
)
7134 mach_msg_header_t Head
;
7136 kern_return_t RetCode
;
7137 mach_vm_address_t address
;
7138 mach_msg_trailer_t trailer
;
7142 Reply
*reply
= (Reply
*)ARG1
;
7144 if (!reply
->RetCode
) {
7145 if (MACH_REMOTE
== vg_task_port
) {
7146 PRINT("allocated at 0x%llx", reply
->address
);
7147 // requesting 0 bytes returns address 0 with no error
7148 if (MACH_ARG(mach_vm_allocate
.size
)) {
7149 ML_(notify_core_and_tool_of_mmap
)(
7150 reply
->address
, MACH_ARG(mach_vm_allocate
.size
),
7151 VKI_PROT_READ
|VKI_PROT_WRITE
, VKI_MAP_ANON
, -1, 0);
7154 PRINT("allocated at 0x%llx in remote task %s", reply
->address
,
7155 name_for_port(MACH_REMOTE
));
7158 PRINT("mig return %d", reply
->RetCode
);
7163 PRE(mach_vm_deallocate
)
7167 mach_msg_header_t Head
;
7169 mach_vm_address_t address
;
7170 mach_vm_size_t size
;
7174 Request
*req
= (Request
*)ARG1
;
7176 PRINT("mach_vm_deallocate(%s, at 0x%llx, size %llu)",
7177 name_for_port(MACH_REMOTE
),
7178 req
->address
, req
->size
);
7180 MACH_ARG(mach_vm_deallocate
.address
) = req
->address
;
7181 MACH_ARG(mach_vm_deallocate
.size
) = req
->size
;
7183 AFTER
= POST_FN(mach_vm_deallocate
);
7185 // Must block to prevent race (other thread allocates and
7186 // notifies after we deallocate but before we notify)
7187 *flags
&= ~SfMayBlock
;
7190 POST(mach_vm_deallocate
)
7194 mach_msg_header_t Head
;
7196 kern_return_t RetCode
;
7197 mach_msg_trailer_t trailer
;
7201 Reply
*reply
= (Reply
*)ARG1
;
7203 if (!reply
->RetCode
) {
7204 if (MACH_REMOTE
== vg_task_port
) {
7205 if (MACH_ARG(mach_vm_deallocate
.size
)) {
7206 Addr start
= VG_PGROUNDDN(MACH_ARG(mach_vm_deallocate
.address
));
7207 Addr end
= VG_PGROUNDUP(MACH_ARG(mach_vm_deallocate
.address
) +
7208 MACH_ARG(mach_vm_deallocate
.size
));
7209 // Must have cleared SfMayBlock in PRE to prevent race
7210 ML_(notify_core_and_tool_of_munmap
)(start
, end
- start
);
7214 PRINT("mig return %d", reply
->RetCode
);
7219 PRE(mach_vm_protect
)
7223 mach_msg_header_t Head
;
7225 mach_vm_address_t address
;
7226 mach_vm_size_t size
;
7227 boolean_t set_maximum
;
7228 vm_prot_t new_protection
;
7232 Request
*req
= (Request
*)ARG1
;
7234 PRINT("mach_vm_protect(%s, at 0x%llx, size %llu, set_max %d, prot %d)",
7235 name_for_port(MACH_REMOTE
), req
->address
, req
->size
,
7236 req
->set_maximum
, req
->new_protection
);
7238 MACH_ARG(mach_vm_protect
.address
) = req
->address
;
7239 MACH_ARG(mach_vm_protect
.size
) = req
->size
;
7240 MACH_ARG(mach_vm_protect
.set_maximum
) = req
->set_maximum
;
7241 MACH_ARG(mach_vm_protect
.new_protection
) = req
->new_protection
;
7243 AFTER
= POST_FN(mach_vm_protect
);
7246 POST(mach_vm_protect
)
7250 mach_msg_header_t Head
;
7252 kern_return_t RetCode
;
7253 mach_msg_trailer_t trailer
;
7257 Reply
*reply
= (Reply
*)ARG1
;
7259 if (!reply
->RetCode
) {
7260 if (MACH_REMOTE
== vg_task_port
) {
7261 Addr start
= VG_PGROUNDDN(MACH_ARG(mach_vm_protect
.address
));
7262 Addr end
= VG_PGROUNDUP(MACH_ARG(mach_vm_protect
.address
) +
7263 MACH_ARG(mach_vm_protect
.size
));
7264 UInt prot
= MACH_ARG(mach_vm_protect
.new_protection
);
7265 if (MACH_ARG(mach_vm_protect
.set_maximum
)) {
7266 // DDD: #warning GrP fixme mprotect max
7267 //VG_(mprotect_max_range)(start, end-start, prot);
7269 ML_(notify_core_and_tool_of_mprotect
)(start
, end
-start
, prot
);
7273 PRINT("mig return %d", reply
->RetCode
);
7278 PRE(mach_vm_inherit
)
7282 mach_msg_header_t Head
;
7284 mach_vm_address_t address
;
7285 mach_vm_size_t size
;
7286 vm_inherit_t new_inheritance
;
7290 Request
*req
= (Request
*)ARG1
;
7292 PRINT("mach_vm_inherit(to %s, at 0x%llx, size %llu, value %u)",
7293 name_for_port(MACH_REMOTE
),
7294 req
->address
, req
->size
, req
->new_inheritance
);
7296 AFTER
= POST_FN(mach_vm_inherit
);
7299 POST(mach_vm_inherit
)
7303 mach_msg_header_t Head
;
7305 kern_return_t RetCode
;
7306 mach_msg_trailer_t trailer
;
7310 Reply
*reply
= (Reply
*)ARG1
;
7312 if (!reply
->RetCode
) {
7313 // no V-visible side effects
7314 // GrP fixme except maybe fork/exec
7316 PRINT("mig return %d", reply
->RetCode
);
7325 mach_msg_header_t Head
;
7327 mach_vm_address_t source_address
;
7328 mach_vm_size_t size
;
7329 mach_vm_address_t dest_address
;
7333 Request
*req
= (Request
*)ARG1
;
7335 PRINT("mach_vm_copy(%s, 0x%llx, %llu, 0x%llx)",
7336 name_for_port(MACH_REMOTE
),
7337 req
->source_address
, req
->size
, req
->dest_address
);
7340 // vt->syscall_arg2 = req->source_address;
7341 // vt->syscall_arg3 = req->size;
7342 // vt->syscall_arg4 = req->dest_address;
7344 AFTER
= POST_FN(mach_vm_copy
);
7351 mach_msg_header_t Head
;
7353 kern_return_t RetCode
;
7354 mach_msg_trailer_t trailer
;
7358 Reply
*reply
= (Reply
*)ARG1
;
7360 if (!reply
->RetCode
) {
7361 if (MACH_REMOTE
== vg_task_port
) {
7362 // GrP fixme set dest's initialization equal to src's
7363 // BUT vm_copy allocates no memory
7366 PRINT("mig return %d", reply
->RetCode
);
7370 PRE(mach_vm_read_overwrite
)
7374 mach_msg_header_t Head
;
7376 mach_vm_address_t address
;
7377 mach_vm_size_t size
;
7378 mach_vm_address_t data
;
7382 Request
*req
= (Request
*)ARG1
;
7384 PRINT("mach_vm_read_overwrite(%s, 0x%llx, %llu, 0x%llx)",
7385 name_for_port(MACH_REMOTE
),
7386 req
->address
, req
->size
, req
->data
);
7388 AFTER
= POST_FN(mach_vm_read_overwrite
);
7391 POST(mach_vm_read_overwrite
)
7395 mach_msg_header_t Head
;
7397 kern_return_t RetCode
;
7398 mach_vm_size_t outsize
;
7402 Reply
*reply
= (Reply
*)ARG1
;
7404 if (!reply
->RetCode
) {
7405 if (MACH_REMOTE
== vg_task_port
) {
7406 // GrP fixme set dest's initialization equal to src's
7407 // BUT vm_copy allocates no memory
7410 PRINT("mig return %d", reply
->RetCode
);
7418 mach_msg_header_t Head
;
7419 /* start of the kernel processed data */
7420 mach_msg_body_t msgh_body
;
7421 mach_msg_port_descriptor_t object
;
7422 /* end of the kernel processed data */
7424 mach_vm_address_t address
;
7425 mach_vm_size_t size
;
7426 mach_vm_address_t mask
;
7428 memory_object_offset_t offset
;
7430 vm_prot_t cur_protection
;
7431 vm_prot_t max_protection
;
7432 vm_inherit_t inheritance
;
7436 Request
*req
= (Request
*)ARG1
;
7438 // GrP fixme check these
7439 PRINT("mach_vm_map(in %s->%s at 0x%llx, size %llu, cur_prot:%x max_prot:%x ...)",
7440 name_for_port(req
->Head
.msgh_remote_port
),
7441 name_for_port(req
->object
.name
),
7442 req
->address
, req
->size
,
7443 req
->cur_protection
,
7444 req
->max_protection
);
7446 MACH_ARG(mach_vm_map
.size
) = req
->size
;
7447 MACH_ARG(mach_vm_map
.copy
) = req
->copy
;
7448 MACH_ARG(mach_vm_map
.protection
) =
7449 (req
->cur_protection
& req
->max_protection
);
7451 AFTER
= POST_FN(mach_vm_map
);
7458 mach_msg_header_t Head
;
7460 kern_return_t RetCode
;
7461 mach_vm_address_t address
;
7462 mach_msg_trailer_t trailer
;
7466 Reply
*reply
= (Reply
*)ARG1
;
7468 if (!reply
->RetCode
) {
7469 // GrP fixme check src and dest tasks
7470 PRINT("mapped at 0x%llx", reply
->address
);
7472 // GrP fixme max prot
7473 ML_(notify_core_and_tool_of_mmap
)(
7474 reply
->address
, VG_PGROUNDUP(MACH_ARG(mach_vm_map
.size
)),
7475 MACH_ARG(mach_vm_map
.protection
), VKI_MAP_SHARED
, -1, 0);
7476 // GrP fixme VKI_MAP_PRIVATE if !copy?
7478 ML_(sync_mappings
)("after", "mach_vm_map", 0);
7481 PRINT("mig return %d", reply
->RetCode
);
7490 mach_msg_header_t Head
;
7491 /* start of the kernel processed data */
7492 mach_msg_body_t msgh_body
;
7493 mach_msg_port_descriptor_t src_task
;
7494 /* end of the kernel processed data */
7496 mach_vm_address_t target_address
;
7497 mach_vm_size_t size
;
7498 mach_vm_offset_t mask
;
7500 mach_vm_address_t src_address
;
7502 vm_inherit_t inheritance
;
7506 Request
*req
= (Request
*)ARG1
;
7508 // GrP fixme check these
7509 PRINT("mach_vm_remap(in %s, at 0x%llx, size %llu, from %s ...)",
7510 name_for_port(MACH_REMOTE
),
7511 req
->target_address
, req
->size
,
7512 name_for_port(req
->src_task
.name
));
7514 MACH_ARG(mach_vm_remap
.size
) = req
->size
;
7515 MACH_ARG(mach_vm_remap
.copy
) = req
->copy
;
7517 AFTER
= POST_FN(mach_vm_remap
);
7524 mach_msg_header_t Head
;
7526 kern_return_t RetCode
;
7527 mach_vm_address_t target_address
;
7528 vm_prot_t cur_protection
;
7529 vm_prot_t max_protection
;
7533 Reply
*reply
= (Reply
*)ARG1
;
7535 if (!reply
->RetCode
) {
7536 // GrP fixme check src and dest tasks
7537 PRINT("mapped at 0x%llx", reply
->target_address
);
7538 // GrP fixme max prot
7539 ML_(notify_core_and_tool_of_mmap
)(
7540 reply
->target_address
, VG_PGROUNDUP(MACH_ARG(mach_vm_remap
.size
)),
7541 reply
->cur_protection
, VKI_MAP_SHARED
, -1, 0);
7542 // GrP fixme VKI_MAP_PRIVATE if !copy?
7544 PRINT("mig return %d", reply
->RetCode
);
7549 PRE(mach_vm_region_recurse
)
7553 mach_msg_header_t Head
;
7555 mach_vm_address_t address
;
7556 natural_t nesting_depth
;
7557 mach_msg_type_number_t infoCnt
;
7561 Request
*req
= (Request
*)ARG1
;
7563 PRINT("mach_vm_region_recurse(in %s, at 0x%llx, depth %u, count %u)",
7564 name_for_port(MACH_REMOTE
),
7565 req
->address
, req
->nesting_depth
, req
->infoCnt
);
7567 AFTER
= POST_FN(mach_vm_region_recurse
);
7570 POST(mach_vm_region_recurse
)
7574 mach_msg_header_t Head
;
7576 kern_return_t RetCode
;
7577 mach_vm_address_t address
;
7578 mach_vm_size_t size
;
7579 natural_t nesting_depth
;
7580 mach_msg_type_number_t infoCnt
;
7585 Reply
*reply
= (Reply
*)ARG1
;
7587 if (!reply
->RetCode
) {
7588 PRINT("got region at 0x%llx, size %llu, depth %u, count %u",
7589 reply
->address
, reply
->size
,
7590 reply
->nesting_depth
, reply
->infoCnt
);
7591 // GrP fixme mark info contents beyond infoCnt as bogus
7593 PRINT("mig return %d", reply
->RetCode
);
7598 /* ---------------------------------------------------------------------
7599 mach_msg: messages to thread
7600 ------------------------------------------------------------------ */
7604 POST(thread_terminate
)
7609 PRE(thread_terminate
)
7611 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
7612 Bool self_terminate
= (mh
->msgh_request_port
== MACH_THREAD
);
7614 PRINT("thread_terminate(%s)", name_for_port(mh
->msgh_request_port
));
7616 AFTER
= POST_FN(thread_terminate
);
7618 if (self_terminate
) {
7619 // Terminating this thread.
7620 // Copied from sys_exit.
7621 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
7622 tst
->exitreason
= VgSrc_ExitThread
;
7623 tst
->os_state
.exitcode
= 0; // GrP fixme anything better?
7624 // What we would like to do is:
7625 // SET_STATUS_Success(0);
7626 // but that doesn't work, because this is a MACH-class syscall,
7627 // and SET_STATUS_Success creates a UNIX-class syscall result.
7628 // Hence we have to laboriously construct the full SysRes "by hand"
7629 // and use that to set the syscall return status.
7630 #if defined(VGA_x86)
7631 SET_STATUS_from_SysRes(
7632 VG_(mk_SysRes_x86_darwin
)(
7633 VG_DARWIN_SYSCALL_CLASS_MACH
,
7634 False
/*success*/, 0, 0
7637 #elif defined(VGA_amd64)
7638 SET_STATUS_from_SysRes(
7639 VG_(mk_SysRes_amd64_darwin
)(
7640 VG_DARWIN_SYSCALL_CLASS_MACH
,
7641 False
/*success*/, 0, 0
7645 #error unknown architecture
7647 *flags
&= ~SfMayBlock
; // clear flag set by PRE(mach_msg)
7649 // Terminating some other thread.
7650 // Do keep the scheduler lock while terminating any other thread.
7651 // Otherwise we might halt the other thread while it holds the lock,
7652 // which would deadlock the process.
7653 // GrP fixme good enough?
7654 // GrP fixme need to clean up other thread's valgrind data?
7666 PRINT("thread_create(mach_task_self(), ...)");
7668 AFTER
= POST_FN(thread_create
);
7671 VG_(core_panic
)("thread_create() unimplemented");
7675 PRE(thread_create_running
)
7679 mach_msg_header_t Head
;
7681 thread_state_flavor_t flavor
;
7682 mach_msg_type_number_t new_stateCnt
;
7683 natural_t new_state
[144];
7688 thread_state_t regs
;
7689 ThreadState
*new_thread
;
7691 PRINT("thread_create_running(mach_task_self(), ...)");
7693 // The new thread will immediately begin execution,
7694 // so we need to hijack the register state here.
7696 req
= (Request
*)ARG1
;
7697 regs
= (thread_state_t
)req
->new_state
;
7699 // Build virtual thread.
7700 new_thread
= build_thread(regs
, req
->flavor
, req
->new_stateCnt
);
7702 // Edit the thread state to send to the real kernel.
7703 hijack_thread_state(regs
, req
->flavor
, req
->new_stateCnt
, new_thread
);
7705 AFTER
= POST_FN(thread_create_running
);
7709 POST(thread_create_running
)
7713 mach_msg_header_t Head
;
7714 /* start of the kernel processed data */
7715 mach_msg_body_t msgh_body
;
7716 mach_msg_port_descriptor_t child_act
;
7717 /* end of the kernel processed data */
7721 Reply
*reply
= (Reply
*)ARG1
;
7723 assign_port_name(reply
->child_act
.name
, "thread-%p");
7724 PRINT("%s", name_for_port(reply
->child_act
.name
));
7728 PRE(bsdthread_create
)
7732 PRINT("bsdthread_create( %#lx, %#lx, %#lx, %#lx, %#lx )",
7733 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
7734 PRE_REG_READ5(pthread_t
,"bsdthread_create",
7735 void *,"func", void *,"func_arg", void *,"stack",
7736 pthread_t
,"thread", unsigned int,"flags");
7738 // The kernel will call V's pthread_hijack() to launch the thread.
7739 // Here we allocate the thread state and pass it to pthread_hijack()
7740 // via the func_arg parameter.
7742 tst
= VG_(get_ThreadState
)(VG_(alloc_ThreadState
)());
7743 allocstack(tst
->tid
);
7745 tst
->os_state
.func_arg
= (Addr
)ARG2
;
7748 // Create a semaphore that pthread_hijack will signal once it starts
7749 // POST(bsdthread_create) needs to wait for the new memory map to appear
7750 semaphore_create(mach_task_self(), &tst
->os_state
.child_go
,
7751 SYNC_POLICY_FIFO
, 0);
7752 semaphore_create(mach_task_self(), &tst
->os_state
.child_done
,
7753 SYNC_POLICY_FIFO
, 0);
7756 POST(bsdthread_create
)
7758 // Tell new thread's pthread_hijack to proceed, and wait for it to finish.
7759 // We hold V's lock on the child's behalf.
7760 // If we return before letting pthread_hijack do its thing, V thinks
7761 // the new pthread struct is still unmapped when we return to libc,
7762 // causing false errors.
7764 ThreadState
*tst
= (ThreadState
*)ARG2
;
7765 semaphore_signal(tst
->os_state
.child_go
);
7766 semaphore_wait(tst
->os_state
.child_done
);
7767 semaphore_destroy(mach_task_self(), tst
->os_state
.child_go
);
7768 semaphore_destroy(mach_task_self(), tst
->os_state
.child_done
);
7770 // GrP fixme semaphore destroy needed when thread creation fails
7771 // GrP fixme probably other cleanup too
7772 // GrP fixme spinlocks might be good enough?
7774 // DDD: I'm not at all sure this is the right spot for this. It probably
7775 // should be in pthread_hijack instead, just before the call to
7776 // start_thread_NORETURN(), call_on_new_stack_0_1(), but we don't have the
7777 // parent tid value there...
7778 vg_assert(VG_(owns_BigLock_LL
)(tid
));
7779 VG_TRACK ( pre_thread_ll_create
, tid
, tst
->tid
);
7783 PRE(bsdthread_terminate
)
7787 PRINT("bsdthread_terminate( %#lx, %lx, %s, %s )",
7788 ARG1
, ARG2
, name_for_port(ARG3
), name_for_port(ARG4
));
7789 PRE_REG_READ4(int,"bsdthread_terminate",
7790 void *,"freeaddr", size_t,"freesize",
7791 mach_port_t
,"kport", mach_port_t
,"joinsem");
7793 // Free memory and signal semaphore.
7794 // GrP fixme errors?
7795 if (ARG4
) semaphore_signal((semaphore_t
)ARG4
);
7797 ML_(notify_core_and_tool_of_munmap
)(ARG1
, ARG2
);
7798 # if DARWIN_VERS >= DARWIN_10_8
7799 /* JRS 2012 Aug 02: ugly hack: vm_deallocate disappeared from
7800 the mig output. Work around it for the time being. */
7801 VG_(do_syscall2
)(__NR_munmap
, ARG1
, ARG2
);
7803 vm_deallocate(mach_task_self(), (vm_address_t
)ARG1
, (vm_size_t
)ARG2
);
7807 // Tell V to terminate the thread.
7808 // Copied from sys_exit.
7809 tst
= VG_(get_ThreadState
)(tid
);
7810 tst
->exitreason
= VgSrc_ExitThread
;
7811 tst
->os_state
.exitcode
= 0; // GrP fixme anything better?
7812 SET_STATUS_Success(0);
7816 POST(thread_suspend
)
7822 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
7823 Bool self_suspend
= (mh
->msgh_request_port
== MACH_THREAD
);
7825 PRINT("thread_suspend(%s)", name_for_port(mh
->msgh_request_port
));
7827 AFTER
= POST_FN(thread_suspend
);
7830 // Don't keep the scheduler lock while self-suspending.
7831 // Otherwise we might halt while still holding the lock,
7832 // which would deadlock the process.
7833 *flags
|= SfMayBlock
;
7835 // Do keep the scheduler lock while suspending any other thread.
7836 // Otherwise we might halt the other thread while it holds the lock,
7837 // which would deadlock the process.
7838 *flags
&= ~SfMayBlock
;
7849 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
7850 Bool self_resume
= (mh
->msgh_request_port
== MACH_THREAD
);
7852 PRINT("thread_resume(%s)", name_for_port(mh
->msgh_request_port
));
7854 AFTER
= POST_FN(thread_resume
);
7857 // This doesn't make much sense. If we are resuming ourself, we can't
7858 // already be running. So I don't see how we can ever get here.
7861 // Resuming some other thread. It might not yet come back to life
7862 // (if the suspend count is still above zero) so make sure we keep
7863 // holding the lock.
7864 *flags
&= ~SfMayBlock
;
7869 POST(thread_get_state
)
7873 mach_msg_header_t Head
;
7875 kern_return_t RetCode
;
7876 mach_msg_type_number_t old_stateCnt
;
7877 natural_t old_state
[144];
7878 mach_msg_trailer_t trailer
;
7882 Reply
*reply
= (Reply
*)ARG1
;
7883 // mach_port_t thread = MACH_ARG(thread_get_state.thread);
7884 thread_state_flavor_t flavor
= MACH_ARG(thread_get_state
.flavor
);
7886 if (!reply
->RetCode
) {
7887 thread_state_from_vex((thread_state_t
)reply
->old_state
,
7888 flavor
, reply
->old_stateCnt
,
7889 &VG_(get_ThreadState
)(tid
)->arch
.vex
);
7891 PRINT("mig return %d", reply
->RetCode
);
7895 PRE(thread_get_state
)
7899 mach_msg_header_t Head
;
7901 thread_state_flavor_t flavor
;
7902 mach_msg_type_number_t old_stateCnt
;
7906 Request
*req
= (Request
*)ARG1
;
7907 // Bool self = (req->Head.msgh_request_port == MACH_THREAD);
7909 // GrP fixme if (self) {
7910 PRINT("thread_get_state(%s, %d)",
7911 name_for_port(req
->Head
.msgh_request_port
), req
->flavor
);
7913 PRINT("thread_get_state(0x%x, %d)",
7914 req->Head.msgh_request_port, req->flavor);
7917 // Hack the thread state after making the real call.
7918 MACH_ARG(thread_get_state
.thread
) = req
->Head
.msgh_request_port
;
7919 MACH_ARG(thread_get_state
.flavor
) = req
->flavor
;
7921 AFTER
= POST_FN(thread_get_state
);
7927 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
7928 // Bool self = (mh->msgh_request_port == MACH_THREAD);
7930 // GrP fixme if (self) {
7931 PRINT("thread_policy(%s, ...)", name_for_port(mh
->msgh_request_port
));
7933 PRINT("thread_policy(thread 0x%x, ...)", mh->msgh_request_port);
7936 AFTER
= POST_FN(thread_policy
);
7944 PRE(thread_policy_set
)
7946 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
7948 PRINT("thread_policy_set(%s, ...)", name_for_port(mh
->msgh_request_port
));
7950 AFTER
= POST_FN(thread_policy_set
);
7953 POST(thread_policy_set
)
7960 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
7962 PRINT("thread_info(%s, ...)", name_for_port(mh
->msgh_request_port
));
7963 // GrP fixme does any thread info need to be hijacked?
7965 AFTER
= POST_FN(thread_info
);
7970 // GrP fixme mark unused parts of thread_info_out as uninitialized?
7975 /* ---------------------------------------------------------------------
7976 mach_msg: messages to bootstrap port
7977 ------------------------------------------------------------------ */
7980 POST(bootstrap_register
)
7984 mach_msg_header_t Head
;
7986 kern_return_t RetCode
;
7987 mach_msg_trailer_t trailer
;
7991 Reply
*reply
= (Reply
*)ARG1
;
7993 if (reply
->RetCode
) PRINT("mig return %d", reply
->RetCode
);
7996 PRE(bootstrap_register
)
8000 mach_msg_header_t Head
;
8001 /* start of the kernel processed data */
8002 mach_msg_body_t msgh_body
;
8003 mach_msg_port_descriptor_t service_port
;
8004 /* end of the kernel processed data */
8006 name_t service_name
;
8010 Request
*req
= (Request
*)ARG1
;
8012 PRINT("bootstrap_register(port 0x%x, \"%s\")",
8013 req
->service_port
.name
, req
->service_name
);
8015 /* The required entry in the allocated_ports list (mapping) might
8016 not exist, due perhaps to broken syscall wrappers (mach__N etc).
8017 Create a minimal entry so that assign_port_name below doesn't
8018 cause an assertion. */
8019 if (!port_exists(req
->service_port
.name
)) {
8020 port_create_vanilla(req
->service_port
.name
);
8023 assign_port_name(req
->service_port
.name
, req
->service_name
);
8025 AFTER
= POST_FN(bootstrap_register
);
8029 POST(bootstrap_look_up
)
8033 mach_msg_header_t Head
;
8034 /* start of the kernel processed data */
8035 mach_msg_body_t msgh_body
;
8036 mach_msg_port_descriptor_t service_port
;
8037 /* end of the kernel processed data */
8038 mach_msg_trailer_t trailer
;
8042 Reply
*reply
= (Reply
*)ARG1
;
8044 if ((reply
->Head
.msgh_bits
& MACH_MSGH_BITS_COMPLEX
) &&
8045 reply
->service_port
.name
)
8047 assign_port_name(reply
->service_port
.name
,
8048 MACH_ARG(bootstrap_look_up
.service_name
));
8049 PRINT("%s", name_for_port(reply
->service_port
.name
));
8053 VG_(free
)(MACH_ARG(bootstrap_look_up
.service_name
));
8056 PRE(bootstrap_look_up
)
8060 mach_msg_header_t Head
;
8062 name_t service_name
;
8066 Request
*req
= (Request
*)ARG1
;
8068 PRINT("bootstrap_look_up(\"%s\")", req
->service_name
);
8070 MACH_ARG(bootstrap_look_up
.service_name
) =
8071 VG_(strdup
)("syswrap-darwin.bootstrap-name", req
->service_name
);
8073 AFTER
= POST_FN(bootstrap_look_up
);
8077 /* ---------------------------------------------------------------------
8078 mach_msg: receiver-specific handlers
8079 ------------------------------------------------------------------ */
8082 POST(mach_msg_receive
)
8084 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8086 // GrP fixme don't know of anything interesting here currently
8087 // import_complex_message handles everything
8088 // PRINT("UNHANDLED reply %d", mh->msgh_id);
8090 // Assume the call may have mapped or unmapped memory
8091 ML_(sync_mappings
)("after", "mach_msg_receive", mh
->msgh_id
);
8094 PRE(mach_msg_receive
)
8096 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8098 PRINT("mach_msg_receive(port %s)", name_for_port(mh
->msgh_reply_port
));
8100 AFTER
= POST_FN(mach_msg_receive
);
8102 // no message sent, only listening for a reply
8103 // assume message may block
8104 *flags
|= SfMayBlock
;
8108 PRE(mach_msg_bootstrap
)
8110 // message to bootstrap port
8112 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8114 switch (mh
->msgh_id
) {
8116 CALL_PRE(bootstrap_register
);
8119 CALL_PRE(bootstrap_look_up
);
8123 PRINT("UNHANDLED bootstrap message [id %d, to %s, reply 0x%x]\n",
8124 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8125 mh
->msgh_reply_port
);
8133 // message to host self - check for host-level kernel calls
8135 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8137 switch (mh
->msgh_id
) {
8139 CALL_PRE(host_info
);
8142 CALL_PRE(host_page_size
);
8145 CALL_PRE(host_get_io_master
);
8148 CALL_PRE(host_get_clock_service
);
8151 CALL_PRE(host_request_notification
);
8154 CALL_PRE(host_create_mach_voucher
);
8158 CALL_PRE(host_get_special_port
);
8162 // unknown message to host self
8163 log_decaying("UNKNOWN host message [id %d, to %s, reply 0x%x]",
8164 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8165 mh
->msgh_reply_port
);
8170 // JRS 2011-Aug-25: these magic numbers (3201 etc) come from
8171 // /usr/include/mach/mach_port.h et al (grep in /usr/include
8175 // message to a task port
8177 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8179 switch (mh
->msgh_id
) {
8181 CALL_PRE(mach_port_type
);
8184 CALL_PRE(mach_port_allocate
);
8187 CALL_PRE(mach_port_destroy
);
8190 CALL_PRE(mach_port_deallocate
);
8193 CALL_PRE(mach_port_get_refs
);
8196 CALL_PRE(mach_port_mod_refs
);
8199 CALL_PRE(mach_port_get_set_status
);
8202 CALL_PRE(mach_port_move_member
);
8205 CALL_PRE(mach_port_request_notification
);
8208 CALL_PRE(mach_port_insert_right
);
8211 CALL_PRE(mach_port_extract_right
);
8214 CALL_PRE(mach_port_get_attributes
);
8217 CALL_PRE(mach_port_set_attributes
);
8220 CALL_PRE(mach_port_insert_member
);
8223 CALL_PRE(mach_port_extract_member
);
8227 CALL_PRE(mach_port_set_context
);
8231 CALL_PRE(task_threads
);
8234 CALL_PRE(mach_ports_register
);
8237 CALL_PRE(mach_ports_lookup
);
8240 CALL_PRE(task_info
);
8243 CALL_PRE(task_set_info
);
8246 CALL_PRE(task_suspend
);
8249 CALL_PRE(task_resume
);
8252 CALL_PRE(task_get_special_port
);
8255 CALL_PRE(task_set_special_port
);
8258 CALL_PRE(thread_create
);
8261 CALL_PRE(thread_create_running
);
8265 CALL_PRE(task_get_exception_ports
);
8269 CALL_PRE(semaphore_create
);
8272 CALL_PRE(semaphore_destroy
);
8275 CALL_PRE(task_policy_set
);
8278 #if DARWIN_VERS >= DARWIN_10_12
8280 CALL_PRE(task_register_dyld_image_infos
);
8284 CALL_PRE(task_register_dyld_shared_cache_image_info
);
8286 #endif /* DARWIN_VERS >= DARWIN_10_12 */
8289 CALL_PRE(vm_allocate
);
8292 CALL_PRE(vm_deallocate
);
8295 CALL_PRE(vm_protect
);
8298 CALL_PRE(vm_inherit
);
8307 CALL_PRE(vm_read_overwrite
);
8316 CALL_PRE(mach_make_memory_entry_64
);
8319 CALL_PRE(vm_purgable_control
);
8323 CALL_PRE(mach_vm_allocate
);
8326 CALL_PRE(mach_vm_deallocate
);
8329 CALL_PRE(mach_vm_protect
);
8332 CALL_PRE(mach_vm_inherit
);
8335 CALL_PRE(mach_vm_read
);
8338 CALL_PRE(mach_vm_copy
);
8341 CALL_PRE(mach_vm_read_overwrite
);
8344 CALL_PRE(mach_vm_map
);
8347 CALL_PRE(mach_vm_remap
);
8350 CALL_PRE(mach_vm_region_recurse
);
8353 CALL_PRE(mach_make_memory_entry_64
);
8356 CALL_PRE(mach_vm_purgable_control
);
8360 // unknown message to task self
8361 log_decaying("UNKNOWN task message [id %d, to %s, reply 0x%x]",
8362 mh
->msgh_id
, name_for_port(mh
->msgh_remote_port
),
8363 mh
->msgh_reply_port
);
8369 PRE(mach_msg_thread
)
8371 // message to local thread - check for thread-level kernel calls
8373 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8375 switch (mh
->msgh_id
) {
8377 CALL_PRE(thread_terminate
);
8380 CALL_PRE(thread_get_state
);
8383 CALL_PRE(thread_suspend
);
8386 CALL_PRE(thread_resume
);
8389 CALL_PRE(thread_info
);
8392 CALL_PRE(thread_policy
);
8395 CALL_PRE(thread_policy_set
);
8398 // unknown message to a thread
8399 VG_(printf
)("UNKNOWN thread message [id %d, to %s, reply 0x%x]\n",
8400 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8401 mh
->msgh_reply_port
);
8407 static int is_thread_port(mach_port_t port
)
8409 if (port
== 0) return False
;
8411 return VG_(lwpid_to_vgtid
)(port
) != VG_INVALID_THREADID
;
8415 static int is_task_port(mach_port_t port
)
8417 if (port
== 0) return False
;
8419 if (port
== vg_task_port
) return True
;
8421 return (0 == VG_(strncmp
)("task-", name_for_port(port
), 5));
8425 /* ---------------------------------------------------------------------
8426 mach_msg: base handlers
8427 ------------------------------------------------------------------ */
8431 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8432 mach_msg_option_t option
= (mach_msg_option_t
)ARG2
;
8433 // mach_msg_size_t send_size = (mach_msg_size_t)ARG3;
8434 mach_msg_size_t rcv_size
= (mach_msg_size_t
)ARG4
;
8435 // mach_port_t rcv_name = (mach_port_t)ARG5;
8436 size_t complex_header_size
= 0;
8438 PRE_REG_READ7(long, "mach_msg",
8439 mach_msg_header_t
*,"msg", mach_msg_option_t
,"option",
8440 mach_msg_size_t
,"send_size", mach_msg_size_t
,"rcv_size",
8441 mach_port_t
,"rcv_name", mach_msg_timeout_t
,"timeout",
8442 mach_port_t
,"notify");
8444 // Assume default POST handler until specified otherwise
8447 // Assume call may block unless specified otherwise
8448 *flags
|= SfMayBlock
;
8450 if (option
& MACH_SEND_MSG
) {
8451 // Validate outgoing message header
8452 PRE_MEM_READ("mach_msg(msg.msgh_bits)",
8453 (Addr
)&mh
->msgh_bits
, sizeof(mh
->msgh_bits
));
8454 // msgh_size not required, use parameter instead
8455 PRE_MEM_READ("mach_msg(msg.msgh_remote_port)",
8456 (Addr
)&mh
->msgh_remote_port
, sizeof(mh
->msgh_remote_port
));
8457 PRE_MEM_READ("mach_msg(msg.msgh_local_port)",
8458 (Addr
)&mh
->msgh_local_port
, sizeof(mh
->msgh_local_port
));
8459 // msgh_reserved not required
8460 PRE_MEM_READ("mach_msg(msg.msgh_id)",
8461 (Addr
)&mh
->msgh_id
, sizeof(mh
->msgh_id
));
8463 if (mh
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
8464 // Validate typed message data and handle memory map changes.
8465 complex_header_size
= export_complex_message(tid
, mh
);
8468 // GrP fixme handle sender-specified message trailer
8469 // (but is this only for too-secure processes?)
8470 // JRS 11 Nov 2014: this assertion is OK for <= 10.9 but fails on 10.10
8471 # if DARWIN_VERS >= DARWIN_10_10
8472 if (mh
->msgh_bits
& MACH_SEND_TRAILER
) {
8473 log_decaying("UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option");
8476 vg_assert(! (mh
->msgh_bits
& MACH_SEND_TRAILER
));
8479 MACH_REMOTE
= mh
->msgh_remote_port
;
8480 MACH_MSGH_ID
= mh
->msgh_id
;
8483 if (option
& MACH_RCV_MSG
) {
8484 // Pre-validate receive buffer
8485 PRE_MEM_WRITE("mach_msg(receive buffer)", (Addr
)mh
, rcv_size
);
8488 // Call a PRE handler. The PRE handler may set an AFTER handler.
8490 if (!(option
& MACH_SEND_MSG
)) {
8491 // no message sent, receive only
8492 CALL_PRE(mach_msg_receive
);
8495 else if (mh
->msgh_request_port
== vg_host_port
) {
8496 // message sent to mach_host_self()
8497 CALL_PRE(mach_msg_host
);
8500 else if (is_task_port(mh
->msgh_request_port
)) {
8501 // message sent to a task
8502 CALL_PRE(mach_msg_task
);
8505 else if (mh
->msgh_request_port
== vg_bootstrap_port
) {
8506 // message sent to bootstrap port
8507 CALL_PRE(mach_msg_bootstrap
);
8510 else if (is_thread_port(mh
->msgh_request_port
)) {
8511 // message sent to one of this process's threads
8512 CALL_PRE(mach_msg_thread
);
8516 // this is an attempt to optimize mapping sync
8517 // but there are always some cases hard to find
8519 Bool do_mapping_update
= False
;
8520 // sorted by msgh_id, we suppose that msgh_id are different for each service,
8521 // which is obviously not true...
8522 switch (mh
->msgh_id
) {
8523 // com.apple.windowserver.active
8524 case 29008: // this one opens a port type 'a'
8526 // com.apple.windowserver.active 'a' port
8529 case 29820: // adds a vm mapping
8530 case 29809: // contains a ool mem
8531 case 29800: // opens a port type 'b'
8533 case 29876: // adds a vm mapping
8535 // com.apple.windowserver.active 'b' port
8545 case 29237: // contains a ool mem
8550 case 29570: // contains a ool mem
8552 case 29569: // contains a ool mem
8557 if (mh
->msgh_id
== 29820 ||
8558 mh
->msgh_id
== 29876)
8559 do_mapping_update
= True
;
8561 PRINT("com.apple.windowserver.active service mach_msg [id %d, to %s, reply 0x%x]",
8562 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8563 mh
->msgh_reply_port
);
8566 // com.apple.FontServer
8568 PRINT("com.apple.FontServerservice mach_msg [id %d, to %s, reply 0x%x]",
8569 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8570 mh
->msgh_reply_port
);
8573 // com.apple.system.notification_center
8576 case 78945695: // contains a ool mem
8579 if (mh
->msgh_id
== 78945695)
8580 do_mapping_update
= False
;
8581 PRINT("com.apple.system.notification_center mach_msg [id %d, to %s, reply 0x%x]",
8582 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8583 mh
->msgh_reply_port
);
8586 // com.apple.CoreServices.coreservicesd
8589 case 10002: // adds vm mappings
8590 case 10003: // adds vm mappings
8595 case 13016: // contains a ool mem
8596 if (mh
->msgh_id
== 10002||
8597 mh
->msgh_id
== 10003)
8598 do_mapping_update
= True
;
8599 PRINT("com.apple.CoreServices.coreservicesd mach_msg [id %d, to %s, reply 0x%x]",
8600 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8601 mh
->msgh_reply_port
);
8604 // com.apple.system.logger
8606 PRINT("com.apple.system.logger mach_msg [id %d, to %s, reply 0x%x]",
8607 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8608 mh
->msgh_reply_port
);
8611 // com.apple.coreservices.launchservicesd, and others
8612 case 1999646836: // might adds vm mapping
8613 if (mh
->msgh_id
== 1999646836)
8614 do_mapping_update
= True
;
8615 PRINT("om.apple.coreservices.launchservicesd mach_msg [id %d, to %s, reply 0x%x]",
8616 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8617 mh
->msgh_reply_port
);
8622 PRINT("com.apple.ocspd mach_msg [id %d, to %s, reply 0x%x]",
8623 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8624 mh
->msgh_reply_port
);
8627 // arbitrary message to arbitrary port
8628 do_mapping_update
= True
;
8629 PRINT("UNHANDLED mach_msg [id %d, to %s, reply 0x%x]",
8630 mh
->msgh_id
, name_for_port(mh
->msgh_request_port
),
8631 mh
->msgh_reply_port
);
8634 // this is an optimization, don't check mapping on known mach_msg
8635 if (do_mapping_update
)
8636 AFTER
= POST_FN(mach_msg_unhandled
);
8638 AFTER
= POST_FN(mach_msg_unhandled_check
);
8640 AFTER
= POST_FN(mach_msg_unhandled
);
8643 // Assume the entire message body may be read.
8644 // GrP fixme generates false positives for unknown protocols
8646 PRE_MEM_READ("mach_msg(payload)",
8647 (Addr)((char*)mh + sizeof(mach_msg_header_t) + complex_header_size),
8648 send_size - sizeof(mach_msg_header_t) - complex_header_size);
8656 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8657 mach_msg_option_t option
= (mach_msg_option_t
)ARG2
;
8659 if (option
& MACH_RCV_MSG
) {
8661 // error during send or receive
8662 // GrP fixme need to clean up port rights?
8664 mach_msg_trailer_t
*mt
=
8665 (mach_msg_trailer_t
*)((Addr
)mh
+ round_msg(mh
->msgh_size
));
8667 // Assume the entire received message and trailer is initialized
8668 // GrP fixme would being more specific catch any bugs?
8669 POST_MEM_WRITE((Addr
)mh
,
8670 round_msg(mh
->msgh_size
) + mt
->msgh_trailer_size
);
8672 if (mh
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
) {
8673 // Update memory map for out-of-line message data
8674 import_complex_message(tid
, mh
);
8679 // Call handler chosen by PRE(mach_msg)
8681 (*AFTER
)(tid
, arrghs
, status
);
8686 POST(mach_msg_unhandled
)
8688 mach_msg_header_t
*mh
= (mach_msg_header_t
*)ARG1
;
8689 ML_(sync_mappings
)("after", "mach_msg_receive-UNHANDLED", mh
->msgh_id
);
8692 POST(mach_msg_unhandled_check
)
8694 if (ML_(sync_mappings
)("after", "mach_msg_receive (unhandled_check)", 0))
8695 PRINT("mach_msg_unhandled_check tid:%d missed mapping change()", tid
);
8699 /* ---------------------------------------------------------------------
8701 ------------------------------------------------------------------ */
8703 PRE(mach_reply_port
)
8705 PRINT("mach_reply_port()");
8708 POST(mach_reply_port
)
8710 record_named_port(tid
, RES
, MACH_PORT_RIGHT_RECEIVE
, "reply-%p");
8711 PRINT("reply port %s", name_for_port(RES
));
8715 PRE(mach_thread_self
)
8717 PRINT("mach_thread_self()");
8720 POST(mach_thread_self
)
8722 record_named_port(tid
, RES
, MACH_PORT_RIGHT_SEND
, "thread-%p");
8723 PRINT("thread %#lx", RES
);
8729 PRINT("mach_host_self()");
8732 POST(mach_host_self
)
8735 record_named_port(tid
, RES
, MACH_PORT_RIGHT_SEND
, "mach_host_self()");
8736 PRINT("host %#lx", RES
);
8742 PRINT("mach_task_self()");
8745 POST(mach_task_self
)
8748 record_named_port(tid
, RES
, MACH_PORT_RIGHT_SEND
, "mach_task_self()");
8749 PRINT("task %#lx", RES
);
8753 PRE(syscall_thread_switch
)
8755 PRINT("syscall_thread_switch(%s, %ld, %ld)",
8756 name_for_port(ARG1
), SARG2
, SARG3
);
8757 PRE_REG_READ3(long, "syscall_thread_switch",
8758 mach_port_t
,"thread", int,"option", natural_t
,"timeout");
8760 *flags
|= SfMayBlock
;
8764 PRE(semaphore_signal
)
8766 PRINT("semaphore_signal(%s)", name_for_port(ARG1
));
8767 PRE_REG_READ1(long, "semaphore_signal", semaphore_t
,"semaphore");
8771 PRE(semaphore_signal_all
)
8773 PRINT("semaphore_signal_all(%s)", name_for_port(ARG1
));
8774 PRE_REG_READ1(long, "semaphore_signal_all", semaphore_t
,"semaphore");
8778 PRE(semaphore_signal_thread
)
8780 PRINT("semaphore_signal_thread(%s, %s)",
8781 name_for_port(ARG1
), name_for_port(ARG2
));
8782 PRE_REG_READ2(long, "semaphore_signal_thread",
8783 semaphore_t
,"semaphore", mach_port_t
,"thread");
8789 PRINT("semaphore_wait(%s)", name_for_port(ARG1
));
8790 PRE_REG_READ1(long, "semaphore_signal", semaphore_t
,"semaphore");
8792 *flags
|= SfMayBlock
;
8796 PRE(semaphore_wait_signal
)
8798 PRINT("semaphore_wait_signal(%s, %s)",
8799 name_for_port(ARG1
), name_for_port(ARG2
));
8800 PRE_REG_READ2(long, "semaphore_wait_signal",
8801 semaphore_t
,"wait_semaphore",
8802 semaphore_t
,"signal_semaphore");
8804 *flags
|= SfMayBlock
;
8808 PRE(semaphore_timedwait
)
8810 PRINT("semaphore_timedwait(%s, %g seconds)",
8811 name_for_port(ARG1
), ARG2
+ARG3
/1000000000.0);
8812 PRE_REG_READ3(long, "semaphore_wait_signal",
8813 semaphore_t
,"semaphore",
8815 int,"wait_time_lo");
8817 *flags
|= SfMayBlock
;
8821 PRE(semaphore_timedwait_signal
)
8823 PRINT("semaphore_wait_signal(wait %s, signal %s, %g seconds)",
8824 name_for_port(ARG1
), name_for_port(ARG2
), ARG3
+ARG4
/1000000000.0);
8825 PRE_REG_READ4(long, "semaphore_wait_signal",
8826 semaphore_t
,"wait_semaphore",
8827 semaphore_t
,"signal_semaphore",
8829 int,"wait_time_lo");
8831 *flags
|= SfMayBlock
;
8835 PRE(__semwait_signal
)
8837 /* 10.5 args: int cond_sem, int mutex_sem,
8838 int timeout, int relative,
8839 time_t tv_sec, time_t tv_nsec */
8840 PRINT("__semwait_signal(wait %s, signal %s, %ld, %ld, %lds:%ldns)",
8841 name_for_port(ARG1
), name_for_port(ARG2
), SARG3
, SARG4
, SARG5
, SARG6
);
8842 PRE_REG_READ6(long, "__semwait_signal",
8843 int,"cond_sem", int,"mutex_sem",
8844 int,"timeout", int,"relative",
8845 vki_time_t
,"tv_sec", int,"tv_nsec");
8847 *flags
|= SfMayBlock
;
8849 // GrP provided this alternative version for 10.6, but NjN
8850 // reckons the 10.5 is is still correct for 10.6. So, retaining
8851 // Greg's version as a comment just in case we need it later.
8852 //PRE(__old_semwait_signal)
8854 // /* 10.5 args: int cond_sem, int mutex_sem,
8855 // int timeout, int relative,
8856 // const timespec *ts */
8857 // PRINT("__old_semwait_signal(wait %s, signal %s, %ld, %ld, %#lx)",
8858 // name_for_port(ARG1), name_for_port(ARG2), ARG3, ARG4, ARG5);
8859 // PRE_REG_READ5(int, "__old_semwait_signal",
8860 // int,cond_sem, int,mutex_sem,
8861 // int,timeout, int,relative,
8862 // const struct vki_timespec *,ts);
8864 // if (ARG5) PRE_MEM_READ ("__old_semwait_signal(ts)",
8865 // ARG5, sizeof(struct vki_timespec));
8867 // *flags |= SfMayBlock;
8873 PRINT("task_for_pid(%s, %ld, %#lx)", name_for_port(ARG1
), SARG2
, ARG3
);
8874 PRE_REG_READ3(long, "task_for_pid",
8875 mach_port_t
,"target",
8876 vki_pid_t
, "pid", mach_port_t
*,"task");
8877 PRE_MEM_WRITE("task_for_pid(task)", ARG3
, sizeof(mach_port_t
));
8884 POST_MEM_WRITE(ARG3
, sizeof(mach_port_t
));
8886 task
= *(mach_port_t
*)ARG3
;
8887 record_named_port(tid
, task
, MACH_PORT_RIGHT_SEND
, "task-%p");
8888 PRINT("task 0x%x", task
);
8894 PRINT("pid_for_task(%s, %#lx)", name_for_port(ARG1
), ARG2
);
8895 PRE_REG_READ2(long, "task_for_pid", mach_port_t
,"task", vki_pid_t
*,"pid");
8896 PRE_MEM_WRITE("task_for_pid(pid)", ARG2
, sizeof(vki_pid_t
));
8903 POST_MEM_WRITE(ARG2
, sizeof(vki_pid_t
));
8905 pid
= *(vki_pid_t
*)ARG2
;
8906 PRINT("pid %u", pid
);
8910 PRE(mach_timebase_info
)
8912 PRINT("mach_timebase_info(%#lx)", ARG1
);
8913 PRE_REG_READ1(long, "mach_timebase_info", void *,"info");
8914 PRE_MEM_WRITE("mach_timebase_info(info)", ARG1
, sizeof(struct vki_mach_timebase_info
));
8917 POST(mach_timebase_info
)
8919 POST_MEM_WRITE(ARG1
, sizeof(struct vki_mach_timebase_info
));
8923 PRE(mach_wait_until
)
8925 #if VG_WORDSIZE == 8
8926 PRINT("mach_wait_until(%lu)", ARG1
);
8927 PRE_REG_READ1(long, "mach_wait_until",
8928 unsigned long long,"deadline");
8930 PRINT("mach_wait_until(%llu)", LOHI64(ARG1
, ARG2
));
8931 PRE_REG_READ2(long, "mach_wait_until",
8932 int,"deadline_hi", int,"deadline_lo");
8934 *flags
|= SfMayBlock
;
8938 PRE(mk_timer_create
)
8940 PRINT("mk_timer_create()");
8941 PRE_REG_READ0(long, "mk_timer_create");
8944 POST(mk_timer_create
)
8946 record_named_port(tid
, RES
, MACH_PORT_RIGHT_SEND
, "mk_timer-%p");
8950 PRE(mk_timer_destroy
)
8952 PRINT("mk_timer_destroy(%s)", name_for_port(ARG1
));
8953 PRE_REG_READ1(long, "mk_timer_destroy", mach_port_t
,"name");
8955 // Must block to prevent race (other thread allocates and
8956 // notifies after we deallocate but before we notify)
8957 *flags
&= ~SfMayBlock
;
8960 POST(mk_timer_destroy
)
8962 // Must have cleared SfMayBlock in PRE to prevent race
8963 record_port_destroy(ARG1
);
8969 #if VG_WORDSIZE == 8
8970 PRINT("mk_timer_arm(%s, %lu)", name_for_port(ARG1
), ARG2
);
8971 PRE_REG_READ2(long, "mk_timer_arm", mach_port_t
,"name",
8972 unsigned long,"expire_time");
8974 PRINT("mk_timer_arm(%s, %llu)", name_for_port(ARG1
), LOHI64(ARG2
, ARG3
));
8975 PRE_REG_READ3(long, "mk_timer_arm", mach_port_t
,"name",
8976 int,"expire_time_hi", int,"expire_time_lo");
8981 PRE(mk_timer_cancel
)
8983 PRINT("mk_timer_cancel(%s, %#lx)", name_for_port(ARG1
), ARG2
);
8984 PRE_REG_READ2(long, "mk_timer_cancel",
8985 mach_port_t
,"name", Addr
,"result_time");
8987 PRE_MEM_WRITE("mk_timer_cancel(result_time)", ARG2
,sizeof(vki_uint64_t
));
8991 POST(mk_timer_cancel
)
8994 POST_MEM_WRITE(ARG2
, sizeof(vki_uint64_t
));
8999 PRE(iokit_user_client_trap
)
9001 PRINT("iokit_user_client_trap(%s, %ld, %lx, %lx, %lx, %lx, %lx, %lx)",
9002 name_for_port(ARG1
), ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
, ARG8
);
9003 PRE_REG_READ8(kern_return_t
, "iokit_user_client_trap",
9004 mach_port_t
,connect
, unsigned int,index
,
9005 uintptr_t,p1
, uintptr_t,p2
, uintptr_t,p3
,
9006 uintptr_t,p4
, uintptr_t,p5
, uintptr_t,p6
);
9008 // can't do anything else with this in general
9009 // might be able to use connect+index to choose something sometimes
9012 POST(iokit_user_client_trap
)
9014 ML_(sync_mappings
)("after", "iokit_user_client_trap", ARG2
);
9021 PRE_REG_READ0(long, "swtch");
9023 *flags
|= SfMayBlock
;
9029 PRINT("swtch_pri ( %ld )", SARG1
);
9030 PRE_REG_READ1(long, "swtch_pri", int,"pri");
9032 *flags
|= SfMayBlock
;
9038 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
9039 an explanation of what follows. */
9040 /* This handles the fake signal-return system call created by
9041 sigframe-x86-darwin.c. */
9042 /* See also comments just below on PRE(sigreturn). */
9044 PRINT("FAKE_SIGRETURN ( )");
9046 vg_assert(VG_(is_valid_tid
)(tid
));
9047 vg_assert(tid
>= 1 && tid
< VG_N_THREADS
);
9048 vg_assert(VG_(is_running_thread
)(tid
));
9050 /* Remove the signal frame from this thread's (guest) stack,
9051 in the process restoring the pre-signal guest state. */
9052 VG_(sigframe_destroy
)(tid
, True
);
9054 /* Tell the driver not to update the guest state with the "result",
9055 and set a bogus result to keep it happy. */
9056 *flags
|= SfNoWriteResult
;
9057 SET_STATUS_Success(0);
9059 /* Check to see if any signals arose as a result of this. */
9060 *flags
|= SfPollAfter
;
9066 /* This is the "real" sigreturn. But because we construct all the
9067 signal frames ourselves (of course, in m_sigframe), this cannot
9068 happen as a result of normal signal delivery. I think it
9069 happens only when doing siglongjmp, in which case Darwin's Libc
9070 appears to use it for two different purposes: to mess with the
9071 per-thread sigaltstack flags (as per arg 2), or to restore the
9072 thread's state from a ucontext* (as per arg 1). */
9074 PRINT("sigreturn ( uctx=%#lx, infostyle=%#lx )", ARG1
, ARG2
);
9076 vg_assert(VG_(is_valid_tid
)(tid
));
9077 vg_assert(tid
>= 1 && tid
< VG_N_THREADS
);
9078 vg_assert(VG_(is_running_thread
)(tid
));
9080 if (ARG2
== VKI_UC_SET_ALT_STACK
) {
9081 /* This is confusing .. the darwin kernel sources imply there is
9082 a per-thread on-altstack/not-on-altstack flag, which is set
9083 by this flag. Just ignore it and claim success for the time
9085 VG_(debugLog
)(1, "syswrap-darwin",
9086 "WARNING: Ignoring sigreturn( ..., "
9087 "UC_SET_ALT_STACK );\n");
9088 SET_STATUS_Success(0);
9091 if (ARG2
== VKI_UC_RESET_ALT_STACK
) {
9093 VG_(debugLog
)(1, "syswrap-darwin",
9094 "WARNING: Ignoring sigreturn( ..., "
9095 "UC_RESET_ALT_STACK );\n");
9096 SET_STATUS_Success(0);
9100 /* Otherwise claim this isn't supported. (Could be
9103 What do we have to do if we do need to support it?
9105 1. Change the second argument of VG_(sigframe_destroy) from
9106 "Bool isRT" to "UInt sysno", so we can pass the syscall
9107 number, so it can distinguish this case from the
9108 __NR_DARWIN_FAKE_SIGRETURN case.
9110 2. In VG_(sigframe_destroy), look at sysno to distinguish the
9111 cases. For __NR_DARWIN_FAKE_SIGRETURN, behave as at present.
9112 For this case, restore the thread's CPU state (or at least
9113 the integer regs) from the ucontext in ARG1 (and do all the
9114 other "signal-returns" stuff too).
9116 3. For (2), how do we know where the ucontext is? One way is to
9117 temporarily copy ARG1 into this thread's guest_EBX (or any
9118 other int reg), and have VG_(sigframe_destroy) read
9119 guest_EBX. Why is it ok to trash guest_EBX (or any other int
9120 reg)? Because VG_(sigframe_destroy) is just about to
9121 overwrite all the regs anyway -- since the primary purpose of
9122 calling it is to restore the register state from the ucontext
9125 Hey, it's uggerly. But at least it's documented.
9127 /* But in the meantime ... */
9128 VG_(debugLog
)(0, "syswrap-darwin",
9129 "WARNING: Ignoring sigreturn( uctx=..., 0 );\n");
9130 VG_(debugLog
)(0, "syswrap-darwin",
9131 "WARNING: Thread/program/Valgrind "
9132 "will likely segfault now.\n");
9133 VG_(debugLog
)(0, "syswrap-darwin",
9134 "WARNING: Please file a bug report at "
9135 "http://www.valgrind.org.\n");
9136 SET_STATUS_Failure( VKI_ENOSYS
);
9140 /* ---------------------------------------------------------------------
9141 machine-dependent traps
9142 ------------------------------------------------------------------ */
9144 #if defined(VGA_x86)
9145 static VexGuestX86SegDescr
* alloc_zeroed_x86_LDT ( void )
9147 Int nbytes
= VEX_GUEST_X86_LDT_NENT
* sizeof(VexGuestX86SegDescr
);
9148 return VG_(calloc
)("syswrap-darwin.ldt", nbytes
, 1);
9152 PRE(thread_fast_set_cthread_self
)
9154 PRINT("thread_fast_set_cthread_self ( %#lx )", ARG1
);
9155 PRE_REG_READ1(void, "thread_fast_set_cthread_self", struct pthread_t
*, self
);
9157 #if defined(VGA_x86)
9158 // Point the USER_CTHREAD ldt entry (slot 6, reg 0x37) at this pthread
9160 VexGuestX86SegDescr
*ldt
;
9161 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
9162 ldt
= (VexGuestX86SegDescr
*)tst
->arch
.vex
.guest_LDT
;
9164 ldt
= alloc_zeroed_x86_LDT();
9165 tst
->arch
.vex
.guest_LDT
= (HWord
)ldt
;
9167 VG_(memset
)(&ldt
[6], 0, sizeof(ldt
[6]));
9168 ldt
[6].LdtEnt
.Bits
.LimitLow
= 1;
9169 ldt
[6].LdtEnt
.Bits
.LimitHi
= 0;
9170 ldt
[6].LdtEnt
.Bits
.BaseLow
= ARG1
& 0xffff;
9171 ldt
[6].LdtEnt
.Bits
.BaseMid
= (ARG1
>> 16) & 0xff;
9172 ldt
[6].LdtEnt
.Bits
.BaseHi
= (ARG1
>> 24) & 0xff;
9173 ldt
[6].LdtEnt
.Bits
.Pres
= 1; // ACC_P
9174 ldt
[6].LdtEnt
.Bits
.Dpl
= 3; // ACC_PL_U
9175 ldt
[6].LdtEnt
.Bits
.Type
= 0x12; // ACC_DATA_W
9176 ldt
[6].LdtEnt
.Bits
.Granularity
= 1; // SZ_G
9177 ldt
[6].LdtEnt
.Bits
.Default_Big
= 1; // SZ_32
9179 tst
->os_state
.pthread
= ARG1
;
9180 tst
->arch
.vex
.guest_GS
= 0x37;
9182 // What we would like to do is:
9183 // SET_STATUS_Success(0x37);
9184 // but that doesn't work, because this is a MDEP-class syscall,
9185 // and SET_STATUS_Success creates a UNIX-class syscall result.
9186 // Hence we have to laboriously construct the full SysRes "by hand"
9187 // and use that to set the syscall return status.
9188 SET_STATUS_from_SysRes(
9189 VG_(mk_SysRes_x86_darwin
)(
9190 VG_DARWIN_SYSNO_CLASS(__NR_thread_fast_set_cthread_self
),
9196 #elif defined(VGA_amd64)
9197 // GrP fixme bigger hack than x86
9199 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
9200 tst
->os_state
.pthread
= ARG1
;
9201 tst
->arch
.vex
.guest_GS_CONST
= ARG1
;
9202 // SET_STATUS_Success(0x60);
9203 // see comments on x86 case just above
9204 SET_STATUS_from_SysRes(
9205 VG_(mk_SysRes_amd64_darwin
)(
9206 VG_DARWIN_SYSNO_CLASS(__NR_thread_fast_set_cthread_self
),
9213 #error unknown architecture
9218 /* ---------------------------------------------------------------------
9219 Added for OSX 10.6 (Snow Leopard)
9220 ------------------------------------------------------------------ */
9222 #if DARWIN_VERS >= DARWIN_10_6
9224 PRE(psynch_mutexwait
)
9226 PRINT("psynch_mutexwait(BOGUS)");
9227 *flags
|= SfMayBlock
;
9229 POST(psynch_mutexwait
)
9233 PRE(psynch_mutexdrop
)
9235 PRINT("psynch_mutexdrop(BOGUS)");
9236 *flags
|= SfMayBlock
;
9238 POST(psynch_mutexdrop
)
9244 PRINT("psynch_cvbroad(BOGUS)");
9246 POST(psynch_cvbroad
)
9250 PRE(psynch_cvsignal
)
9252 PRINT("psynch_cvsignal(BOGUS)");
9254 POST(psynch_cvsignal
)
9260 PRINT("psynch_cvwait(BOGUS)");
9261 *flags
|= SfMayBlock
;
9267 PRE(psynch_rw_rdlock
)
9269 PRINT("psynch_rw_rdlock(BOGUS)");
9270 *flags
|= SfMayBlock
;
9272 POST(psynch_rw_rdlock
)
9276 PRE(psynch_rw_wrlock
)
9278 PRINT("psynch_rw_wrlock(BOGUS)");
9279 *flags
|= SfMayBlock
;
9281 POST(psynch_rw_wrlock
)
9285 PRE(psynch_rw_unlock
)
9287 PRINT("psynch_rw_unlock(BOGUS)");
9289 POST(psynch_rw_unlock
)
9293 PRE(__thread_selfid
)
9295 PRINT("__thread_selfid ()");
9296 PRE_REG_READ0(vki_uint64_t
, "__thread_selfid");
9301 #if VG_WORDSIZE == 4
9302 PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %llu)",
9304 ((unsigned int *)ARG3
)[0], ((unsigned int *)ARG3
)[1],
9305 LOHI64(ARG4
, ARG5
));
9306 PRE_REG_READ5(ssize_t
, "fsgetpath",
9307 void*,"buf", size_t,"bufsize",
9309 vki_uint32_t
, "objid_low32", vki_uint32_t
, "objid_high32");
9311 PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %lu)",
9313 ((unsigned int *)ARG3
)[0],
9314 ((unsigned int *)ARG3
)[1], ARG4
);
9315 PRE_REG_READ4(ssize_t
, "fsgetpath",
9316 void*,"buf", size_t,"bufsize",
9317 fsid_t
*,"fsid", uint64_t,"objid");
9319 PRE_MEM_READ("fsgetpath(fsid)", ARG3
, sizeof(fsid_t
));
9320 PRE_MEM_WRITE("fsgetpath(buf)", ARG1
, ARG2
);
9325 POST_MEM_WRITE(ARG1
, RES
);
9328 PRE(audit_session_self
)
9330 PRINT("audit_session_self()");
9332 POST(audit_session_self
)
9334 record_named_port(tid
, RES
, MACH_PORT_RIGHT_SEND
, "audit-session-%p");
9335 PRINT("audit-session %#lx", RES
);
9340 PRINT("fgetattrlist(%ld, %#lx, %#lx, %lu, %lu)",
9341 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9342 PRE_REG_READ5(int, "fgetattrlist",
9343 int,fd
, struct vki_attrlist
*,attrList
,
9344 void *,attrBuf
, vki_size_t
,attrBufSize
, unsigned int,options
);
9345 PRE_MEM_READ("fgetattrlist(attrList)", ARG2
, sizeof(struct vki_attrlist
));
9346 PRE_MEM_WRITE("fgetattrlist(attrBuf)", ARG3
, ARG4
);
9350 if (ARG4
> sizeof(vki_uint32_t
)) {
9351 // attrBuf is uint32_t size followed by attr data
9352 vki_uint32_t
*sizep
= (vki_uint32_t
*)ARG3
;
9353 POST_MEM_WRITE(ARG3
, sizeof(vki_uint32_t
));
9354 if (ARG5
& FSOPT_REPORT_FULLSIZE
) {
9355 // *sizep is bytes required for return value, including *sizep
9357 // *sizep is actual bytes returned, including *sizep
9359 scan_attrlist(tid
, (struct vki_attrlist
*)ARG2
, sizep
+1, MIN(*sizep
, ARG4
), &get1attr
);
9363 #endif /* DARWIN_VERS >= DARWIN_10_6 */
9366 /* ---------------------------------------------------------------------
9367 Added for OSX 10.7 (Lion)
9368 ------------------------------------------------------------------ */
9370 #if DARWIN_VERS >= DARWIN_10_7
9372 PRE(psynch_cvclrprepost
)
9374 PRINT("psynch_cvclrprepost(BOGUS)");
9375 *flags
|= SfMayBlock
;
9377 POST(psynch_cvclrprepost
)
9381 #endif /* DARWIN_VERS >= DARWIN_10_7 */
9384 /* ---------------------------------------------------------------------
9385 Added for OSX 10.8 (Mountain Lion)
9386 ------------------------------------------------------------------ */
9388 /* About munge tags, eg munge_wllww.
9390 Means the syscall takes 5 args. For a 64 bit process each arg
9391 occupies one 64-bit value and so the mapping to ARGn macros is
9392 direct. For a 32 bit process, this is more complex: 'w' denotes a
9393 32-bit word and 'l' a 64-bit word. Hence the wllww denotation
9394 indicates that, in a 64 bit process, the args are: ARG1 ARG2 ARG3
9395 ARG4 ARG5, but in a 32 bit process they are: ARG1 ARG3:ARG2
9396 ARG5:ARG4 ARG6 ARG7. And we have to laboriously reconstruct them
9397 in order to get sane values for the arguments in 32-bit
9400 static void munge_wwl(UWord
* a1
, UWord
* a2
, ULong
* a3
,
9401 UWord aRG1
, UWord aRG2
, UWord aRG3
, UWord aRG4
)
9403 # if defined(VGA_x86)
9404 *a1
= aRG1
; *a2
= aRG2
; *a3
= LOHI64(aRG3
,aRG4
);
9406 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
;
9410 static void munge_wll(UWord
* a1
, ULong
* a2
, ULong
* a3
,
9411 UWord aRG1
, UWord aRG2
, UWord aRG3
,
9412 UWord aRG4
, UWord aRG5
)
9414 # if defined(VGA_x86)
9415 *a1
= aRG1
; *a2
= LOHI64(aRG2
,aRG3
); *a3
= LOHI64(aRG4
,aRG5
);
9417 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
;
9421 static void munge_wwlw(UWord
* a1
, UWord
* a2
, ULong
* a3
, UWord
* a4
,
9422 UWord aRG1
, UWord aRG2
, UWord aRG3
,
9423 UWord aRG4
, UWord aRG5
)
9425 # if defined(VGA_x86)
9426 *a1
= aRG1
; *a2
= aRG2
; *a3
= LOHI64(aRG3
,aRG4
); *a4
= aRG5
;
9428 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
; *a4
= aRG4
;
9432 static void munge_wwwl(UWord
* a1
, UWord
* a2
, UWord
* a3
, ULong
* a4
,
9433 UWord aRG1
, UWord aRG2
, UWord aRG3
,
9434 UWord aRG4
, UWord aRG5
)
9436 # if defined(VGA_x86)
9437 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
; *a4
= LOHI64(aRG4
,aRG5
);
9439 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
; *a4
= aRG4
;
9443 static void munge_wllww(UWord
* a1
, ULong
* a2
, ULong
* a3
, UWord
* a4
, UWord
* a5
,
9444 UWord aRG1
, UWord aRG2
, UWord aRG3
,
9445 UWord aRG4
, UWord aRG5
, UWord aRG6
, UWord aRG7
)
9447 # if defined(VGA_x86)
9448 *a1
= aRG1
; *a2
= LOHI64(aRG2
,aRG3
); *a3
= LOHI64(aRG4
,aRG5
);
9449 *a4
= aRG6
; *a5
= aRG7
;
9451 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
; *a4
= aRG4
; *a5
= aRG5
;
9455 static void munge_wwllww(UWord
* a1
, UWord
* a2
, ULong
* a3
,
9456 ULong
* a4
, UWord
* a5
, UWord
* a6
,
9457 UWord aRG1
, UWord aRG2
, UWord aRG3
, UWord aRG4
,
9458 UWord aRG5
, UWord aRG6
, UWord aRG7
, UWord aRG8
)
9460 # if defined(VGA_x86)
9461 *a1
= aRG1
; *a2
= aRG2
;
9462 *a3
= LOHI64(aRG3
,aRG4
); *a4
= LOHI64(aRG5
,aRG6
);
9463 *a5
= aRG7
; *a6
= aRG8
;
9465 *a1
= aRG1
; *a2
= aRG2
; *a3
= aRG3
; *a4
= aRG4
; *a5
= aRG5
; *a6
= aRG6
;
9469 #if DARWIN_VERS >= DARWIN_10_8
9471 PRE(kernelrpc_mach_vm_allocate_trap
)
9473 UWord a1
; UWord a2
; ULong a3
; UWord a4
;
9474 munge_wwlw(&a1
, &a2
, &a3
, &a4
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9475 PRINT("kernelrpc_mach_vm_allocate_trap"
9476 "(target:%s, address:%p, size:%#llx, flags:%#lx)",
9477 name_for_port(a1
), *(void**)a2
, a3
, a4
);
9478 PRE_MEM_WRITE("kernelrpc_mach_vm_allocate_trap(address)",
9481 POST(kernelrpc_mach_vm_allocate_trap
)
9483 UWord a1
; UWord a2
; ULong a3
; UWord a4
;
9484 munge_wwlw(&a1
, &a2
, &a3
, &a4
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9485 PRINT("address:%p size:%#llx", *(void**)a2
, a3
);
9486 if (ML_(safe_to_deref
)((void*)a2
, sizeof(void*))) {
9487 POST_MEM_WRITE(a2
, sizeof(void*));
9489 if (a1
== mach_task_self()) {
9491 ML_(sync_mappings
)("POST(kernelrpc_mach_vm_allocate_trap)", "??", 0);
9493 /* This is nearly right, but not always -- sometimes the mapping
9494 appears to be r--, for some reason. Hence resync. */
9495 ML_(notify_core_and_tool_of_mmap
)(
9497 VKI_PROT_READ
|VKI_PROT_WRITE
, VKI_MAP_ANON
, -1, 0);
9502 PRE(kernelrpc_mach_vm_deallocate_trap
)
9504 UWord a1
; ULong a2
; ULong a3
;
9505 munge_wll(&a1
, &a2
, &a3
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9506 PRINT("kernelrpc_mach_vm_deallocate_trap"
9507 "(target:%#lx, address:%#llx, size:%#llx)", a1
, a2
, a3
);
9509 POST(kernelrpc_mach_vm_deallocate_trap
)
9511 UWord a1
; ULong a2
; ULong a3
;
9512 munge_wll(&a1
, &a2
, &a3
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9513 // kernelrpc_mach_vm_deallocate_trap could be call with
9514 // address ==0 && size == 0,
9515 // we shall not notify any unmap then
9517 ML_(notify_core_and_tool_of_munmap
)(a2
, a3
);
9520 PRE(kernelrpc_mach_vm_protect_trap
)
9522 UWord a1
; ULong a2
; ULong a3
; UWord a4
; UWord a5
;
9523 munge_wllww(&a1
, &a2
, &a3
, &a4
, &a5
,
9524 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
);
9525 PRINT("kernelrpc_mach_vm_protect_trap"
9526 "(task:%#lx, address:%#llx, size:%#llx,"
9527 " set_maximum:%#lx, new_prot:%#lx)", a1
, a2
, a3
, a4
, a5
);
9529 POST(kernelrpc_mach_vm_protect_trap
)
9531 UWord a1
; ULong a2
; ULong a3
; UWord a4
; UWord a5
;
9532 munge_wllww(&a1
, &a2
, &a3
, &a4
, &a5
,
9533 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
);
9534 if (/*a4 set_maximum == 0 && */a1
== mach_task_self()) {
9535 ML_(notify_core_and_tool_of_mprotect
)((Addr
)a2
, (SizeT
)a3
, (Int
)a5
);
9536 VG_(di_notify_vm_protect
)((Addr
)a2
, (SizeT
)a3
, (UInt
)a5
);
9540 PRE(kernelrpc_mach_port_allocate_trap
)
9542 // munge_www -- no need to call helper
9543 PRINT("kernelrpc_mach_port_allocate_trap(task:%#lx, mach_port_right_t:%#lx)",
9545 PRE_MEM_WRITE("kernelrpc_mach_port_allocate_trap(name)",
9546 ARG3
, sizeof(mach_port_name_t
));
9548 POST(kernelrpc_mach_port_allocate_trap
)
9550 // munge_www -- no need to call helper
9551 POST_MEM_WRITE(ARG3
, sizeof(mach_port_name_t
));
9552 PRINT(", name:%#x", *(mach_port_name_t
*)ARG3
);
9553 record_unnamed_port(tid
, *(mach_port_name_t
*)ARG3
, ARG2
);
9556 PRE(kernelrpc_mach_port_destroy_trap
)
9558 // munge_ww -- no need to call helper
9559 PRINT("kernelrpc_mach_port_destroy_trap(task:%#lx, name:%#lx)", ARG1
, ARG2
);
9560 record_port_destroy(ARG2
);
9563 PRE(kernelrpc_mach_port_deallocate_trap
)
9565 // munge_ww -- no need to call helper
9566 PRINT("kernelrpc_mach_port_deallocate_trap(task:%#lx, name:%#lx ) FIXME",
9569 POST(kernelrpc_mach_port_deallocate_trap
)
9571 // munge_ww -- no need to call helper
9574 PRE(kernelrpc_mach_port_mod_refs_trap
)
9576 // munge_wwww -- no need to call helper
9577 PRINT("kernelrpc_mach_port_mod_refs_trap"
9578 "(task:%#lx, name:%#lx, right:%#lx refs:%#lx) FIXME",
9579 ARG1
, ARG2
, ARG3
, ARG4
);
9582 PRE(kernelrpc_mach_port_move_member_trap
)
9584 // munge_www -- no need to call helper
9585 PRINT("kernelrpc_mach_port_move_member_trap"
9586 "(task:%#lx, name:%#lx, after:%#lx ) FIXME",
9590 PRE(kernelrpc_mach_port_insert_right_trap
)
9592 //munge_wwww -- no need to call helper
9593 PRINT("kernelrpc_mach_port_insert_right_trap(FIXME)"
9594 "(%lx,%lx,%lx,%lx)", ARG1
, ARG2
, ARG3
, ARG4
);
9597 PRE(kernelrpc_mach_port_insert_member_trap
)
9599 // munge_www -- no need to call helper
9600 PRINT("kernelrpc_mach_port_insert_member_trap(FIXME)"
9601 "(%lx,%lx,%lx)", ARG1
, ARG2
, ARG3
);
9604 PRE(kernelrpc_mach_port_extract_member_trap
)
9606 // munge_www -- no need to call helper
9607 PRINT("kernelrpc_mach_port_extract_member_trap(FIXME)"
9608 "(%lx,%lx,%lx)", ARG1
, ARG2
, ARG3
);
9614 PRINT("iopolicysys(FIXME)(0x%lx, 0x%lx, 0x%lx)", ARG1
, ARG2
, ARG3
);
9615 /* mem effects unknown */
9625 PRINT("process_policy(FIXME)("
9626 "scope:0x%lx, action:0x%lx, policy:0x%lx, policy_subtype:0x%lx,"
9627 " attr:%lx, target_pid:%lx, target_threadid:%lx)",
9628 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
);
9629 /* mem effects unknown */
9631 POST(process_policy
)
9636 PRE(csops_audittoken
)
9638 PRINT("csops_audittoken(%ld, %#lx, %#lx, %lu, %#lx)", SARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9639 PRE_REG_READ5(int, "csops_audittoken",
9640 vki_pid_t
, pid
, uint32_t, ops
,
9641 void *, useraddr
, vki_size_t
, usersize
, void *, uaudittoken
);
9644 SET_STATUS_Failure( VKI_EINVAL
);
9648 PRE_MEM_WRITE( "csops_audittoken(useraddr)", ARG3
, ARG4
);
9650 // If the pid is ours, don't mark the program as KILL or HARD
9651 // Maybe we should keep track of this for later calls to STATUS
9652 if (!ARG1
|| VG_(getpid
)() == ARG1
) {
9654 case VKI_CS_OPS_MARKINVALID
:
9655 case VKI_CS_OPS_MARKHARD
:
9656 case VKI_CS_OPS_MARKKILL
:
9657 SET_STATUS_Success(0);
9662 POST(csops_audittoken
)
9664 POST_MEM_WRITE( ARG3
, ARG4
);
9667 #endif /* DARWIN_VERS >= DARWIN_10_8 */
9670 /* ---------------------------------------------------------------------
9671 Added for OSX 10.9 (Mavericks)
9672 ------------------------------------------------------------------ */
9674 #if DARWIN_VERS >= DARWIN_10_9
9676 PRE(kernelrpc_mach_vm_map_trap
)
9678 UWord a1
; UWord a2
; ULong a3
; ULong a4
; UWord a5
; UWord a6
;
9679 munge_wwllww(&a1
, &a2
, &a3
, &a4
, &a5
, &a6
,
9680 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
, ARG8
);
9681 PRINT("kernelrpc_mach_vm_map_trap"
9682 "(target:%#lx, address:%p, size:%#llx,"
9683 " mask:%#llx, flags:%#lx, cur_prot:%#lx)",
9684 a1
, *(void**)a2
, a3
, a4
, a5
, a6
);
9685 PRE_MEM_WRITE("kernelrpc_mach_vm_map_trap(address)", a2
, sizeof(void*));
9687 POST(kernelrpc_mach_vm_map_trap
)
9689 UWord a1
; UWord a2
; ULong a3
; ULong a4
; UWord a5
; UWord a6
;
9690 munge_wwllww(&a1
, &a2
, &a3
, &a4
, &a5
, &a6
,
9691 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
, ARG8
);
9692 PRINT("-> address:%p", *(void**)a2
);
9693 if (ML_(safe_to_deref
)((void*)a2
, sizeof(void*))) {
9694 POST_MEM_WRITE(a2
, sizeof(void*));
9696 ML_(notify_core_and_tool_of_mmap
)(
9697 *(mach_vm_address_t
*)a2
, a3
,
9698 VKI_PROT_READ
|VKI_PROT_WRITE
, VKI_MAP_ANON
, -1, 0);
9699 // ML_(sync_mappings)("after", "kernelrpc_mach_vm_map_trap", 0);
9702 PRE(kernelrpc_mach_port_construct_trap
)
9704 UWord a1
; UWord a2
; ULong a3
; UWord a4
;
9705 munge_wwlw(&a1
, &a2
, &a3
, &a4
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9706 PRINT("kernelrpc_mach_port_construct_trap"
9707 "(target: %s, options: %#lx, content: %llx, name: %p)",
9708 name_for_port(a1
), a2
, a3
, *(mach_port_name_t
**)a4
);
9709 PRE_MEM_WRITE("kernelrpc_mach_port_construct_trap(name)", a4
,
9710 sizeof(mach_port_name_t
*));
9712 POST(kernelrpc_mach_port_construct_trap
)
9714 UWord a1
; UWord a2
; ULong a3
; UWord a4
;
9715 munge_wwlw(&a1
, &a2
, &a3
, &a4
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9716 PRINT("-> name:%p", *(mach_port_name_t
**)a4
);
9717 if (ML_(safe_to_deref
)((mach_port_name_t
*)a4
, sizeof(mach_port_name_t
*))) {
9718 POST_MEM_WRITE(a4
, sizeof(mach_port_name_t
*));
9722 PRE(kernelrpc_mach_port_destruct_trap
)
9724 UWord a1
; UWord a2
; UWord a3
; ULong a4
;
9725 munge_wwwl(&a1
, &a2
, &a3
, &a4
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9726 PRINT("kernelrpc_mach_port_destruct_trap(FIXME)"
9727 "(%lx,%lx,%lx,%llx)", a1
, a2
, a3
, a4
);
9730 PRE(kernelrpc_mach_port_guard_trap
)
9732 UWord a1
; UWord a2
; ULong a3
; UWord a4
;
9733 munge_wwlw(&a1
, &a2
, &a3
, &a4
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9734 PRINT("kernelrpc_mach_port_guard_trap(FIXME)"
9735 "(%lx,%lx,%llx,%lx)", a1
, a2
, a3
, a4
);
9738 PRE(kernelrpc_mach_port_unguard_trap
)
9741 UWord a1
; UWord a2
; ULong a3
;
9742 munge_wwl(&a1
, &a2
, &a3
, ARG1
, ARG2
, ARG3
, ARG4
);
9743 PRINT("kernelrpc_mach_port_unguard_trap(FIXME)"
9744 "(%lx,%lx,%llx)", a1
, a2
, a3
);
9747 #endif /* DARWIN_VERS >= DARWIN_10_9 */
9750 /* ---------------------------------------------------------------------
9751 Added for OSX 10.10 (Yosemite)
9752 ------------------------------------------------------------------ */
9754 #if DARWIN_VERS >= DARWIN_10_10
9756 PRE(necp_match_policy
)
9758 // int necp_match_policy(uint8_t *parameters, size_t parameters_size,
9759 // struct necp_aggregate_result *returned_result)
9760 PRINT("necp_match_policy(FIXME)(%lx,%lu, %lx)", ARG1
, ARG2
, ARG3
);
9761 PRE_REG_READ3(int, "necp_match_policy", uint8_t*, parameters
,
9762 size_t, parameters_size
, struct necp_aggregate_result
*,
9764 PRE_MEM_READ("necp_match_policy(returned_result)", ARG1
, ARG2
);
9766 POST(necp_match_policy
)
9768 POST_MEM_WRITE(ARG3
, sizeof(struct vki_necp_aggregate_result
));
9774 UWord namelen
= ARG2
;
9776 UWord oldlenp
= ARG4
;
9778 UWord newlen
= ARG6
; // FIXME: or newlenp ??
9780 PRINT( "sysctlbyname ( %#lx,%lu, %#lx,%#lx, %#lx,%lu )",
9781 name
, namelen
, oldp
, oldlenp
, newp
, newlen
);
9783 PRE_REG_READ6(int, "sysctlbyname", char*, name
, size_t, namelen
,
9784 void*, oldp
, vki_size_t
*, oldlenp
,
9785 void*, newp
, vki_size_t
*, newlenp
); // <---<<
9787 // reads name[0..namelen-1]
9788 PRE_MEM_READ("sysctlbyname(name)", name
, namelen
);
9790 if (VG_(clo_trace_syscalls
)) {
9792 const HChar
* t_name
= (const HChar
*)name
;
9793 VG_(printf
)(" name: ");
9794 for (i
= 0; i
< namelen
; i
++) {
9795 VG_(printf
)("%c", t_name
[i
]);
9800 Bool is_kern_dot_userstack
9803 common_PRE_sysctl( /*IMPLICIT ARGS*/tid
,status
,flags
,/*!IMPLICIT_ARGS*/
9804 is_kern_dot_userstack
, oldp
, oldlenp
, newp
, newlen
);
9809 UWord oldlenp
= ARG4
;
9811 if (SUCCESS
|| ERR
== VKI_ENOMEM
) {
9812 // sysctl can write truncated data and return VKI_ENOMEM
9814 POST_MEM_WRITE(oldlenp
, sizeof(size_t));
9816 if (oldp
&& oldlenp
) {
9817 POST_MEM_WRITE(oldp
, *(size_t*)oldlenp
);
9822 PRE(getattrlistbulk
)
9824 // int getattrlistbulk(int dirfd, struct attrlist *alist,
9825 // void *attributeBuffer, size_t bufferSize,
9826 // uint64_t options);
9827 // Presumably the last arg is value-pair in the 32 bit case.
9828 PRINT("getattrlistbulk(FIXME)(%ld, %lx, %lx,%lu, %lu)",
9829 SARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
9830 PRE_REG_READ5(int, "getattrlistbulk", int, dirfd
, void*, list
,
9831 void*, attributeBuffer
, size_t, bufferSize
,
9832 uint32_t, options_lo32
);
9833 PRE_MEM_READ("getattrlistbulk(alist)", ARG2
, sizeof(struct vki_attrlist
));
9834 PRE_MEM_WRITE("getattrlistbulk(attributeBuffer)", ARG3
, ARG4
);
9836 POST(getattrlistbulk
)
9838 // FIXME: this isn't right. It seems as if what is returned is a
9839 // set of variable-length records -- see complication in
9840 // POST(getattrlist). For now, just paint the entire result buffer
9841 // as defined. Sigh.
9843 if (ARG3
&& /* "at least one output element was written" */RES
> 0)
9844 POST_MEM_WRITE(ARG3
, ARG4
);
9850 PRINT("faccessat(fd:%d, path:%#lx(%s), amode:%#lx, flag:%#lx)",
9851 fd
, ARG2
, ARG2
? (HChar
*)ARG2
: "null", ARG3
, ARG4
);
9852 PRE_REG_READ4(int, "faccessat",
9853 int, fd
, user_addr_t
, path
, int, amode
, int, flag
);
9855 if (fd
!= VKI_AT_FDCWD
&& !ML_(fd_allowed
)(fd
, "faccessat", tid
, False
)) {
9856 SET_STATUS_Failure( VKI_EBADF
);
9858 PRE_MEM_RASCIIZ( "faccessat(path)", ARG2
);
9864 PRINT("fstatat64(fd:%d, path:%#lx(%s), ub:%#lx, flag:%#lx)",
9865 fd
, ARG2
, ARG2
? (HChar
*)ARG2
: "null", ARG3
, ARG4
);
9866 PRE_REG_READ4(int, "fstatat64",
9867 int, fd
, user_addr_t
, path
, user_addr_t
, ub
, int, flag
);
9869 if (fd
!= VKI_AT_FDCWD
&& !ML_(fd_allowed
)(fd
, "fstatat64", tid
, False
)) {
9870 SET_STATUS_Failure( VKI_EBADF
);
9872 PRE_MEM_RASCIIZ( "fstatat64(path)", ARG2
);
9873 PRE_MEM_WRITE( "fstatat64(ub)", ARG3
, sizeof(struct vki_stat64
) );
9877 POST_MEM_WRITE( ARG3
, sizeof(struct vki_stat64
) );
9884 PRINT("readlinkat ( %ld, %#lx(%s), %#lx, %ld )",
9885 SARG1
, ARG2
, (HChar
*)ARG2
, ARG3
, SARG4
);
9886 PRE_REG_READ4(long, "readlinkat",
9887 int, dfd
, const char *, path
, char *, buf
, int, bufsiz
);
9888 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2
);
9889 PRE_MEM_WRITE( "readlinkat(buf)", ARG3
,ARG4
);
9892 * Refer to coregrind/m_syswrap/syswrap-linux.c
9896 SET_STATUS_from_SysRes( VG_(do_syscall4
)(saved
, ARG1
, ARG2
, ARG3
, ARG4
));
9899 if (SUCCESS
&& RES
> 0)
9900 POST_MEM_WRITE( ARG3
, RES
);
9905 // int bsdthread_ctl(user_addr_t cmd, user_addr_t arg1,
9906 // user_addr_t arg2, user_addr_t arg3)
9907 PRINT("bsdthread_ctl(FIXME)(%lx,%lx,%lx,%lx)", ARG1
, ARG2
, ARG3
, ARG4
);
9908 PRE_REG_READ4(int, "bsdthreadctl",
9909 void*, cmd
, void*, arg1
, void*, arg2
, void*, arg3
);
9912 // syscalls.master says
9913 // int csrctl(uint32_t op, user_addr_t useraddr, user_addr_t usersize) NO_SYSCALL_STUB;
9914 // but https://github.com/search?q=repo%3Aapple-open-source%2Fmacos%20__csrctl&type=code says
9915 // int __csrctl(csr_op_t op, void *buffer, size_t size);
9920 PRINT("csrctl(op:CSR_CHECK, useraddr:%#lx, usersize:%#lx)", ARG2
, ARG3
);
9921 PRE_REG_READ3(int, "csrctl",
9922 uint32_t, op
, void*, useraddr
, size_t, usersize
);
9923 PRE_MEM_READ( "csrctl(useraddr)", ARG2
, ARG3
);
9926 case VKI_CSR_GET_ACTIVE_CONFIG
:
9927 PRINT("csrctl(op:CSR_GET_ACTIVE_CONFIG, useraddr:%#lx, usersize:%#lx)", ARG2
, ARG3
);
9928 PRE_REG_READ3(int, "csrctl",
9929 uint32_t, op
, void*, useraddr
, size_t, usersize
);
9930 PRE_MEM_WRITE( "csrctl(useraddr)", ARG2
, ARG3
);
9934 PRINT("csrctl(op:%ld [??], useraddr:%#lx, usersize:%#lx)", ARG1
, ARG2
, ARG3
);
9935 log_decaying("UNKNOWN csrctl %ld!", ARG1
);
9943 case VKI_CSR_GET_ACTIVE_CONFIG
:
9944 POST_MEM_WRITE( ARG2
, ARG3
);
9952 PRE(guarded_open_dprotected_np
)
9954 PRINT("guarded_open_dprotected_np("
9955 "path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx, "
9956 "dpclass:%#lx, dpflags: %#lx) FIXME",
9957 ARG1
, (HChar
*)ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
9960 PRE(guarded_write_np
)
9962 PRINT("guarded_write_np(fd:%ld, guard:%#lx, cbuf:%#lx, nbyte:%llu) FIXME",
9963 ARG1
, ARG2
, ARG3
, (ULong
)ARG4
);
9966 PRE(guarded_pwrite_np
)
9968 PRINT("guarded_pwrite_np(fd:%ld, guard:%#lx, buf:%#lx, nbyte:%llu, offset:%lld) FIXME",
9969 ARG1
, ARG2
, ARG3
, (ULong
)ARG4
, (Long
)ARG5
);
9972 PRE(guarded_writev_np
)
9974 PRINT("guarded_writev_np(fd:%ld, guard:%#lx, iovp:%#lx, iovcnt:%llu) FIXME",
9975 ARG1
, ARG2
, ARG3
, (ULong
)ARG4
);
9980 if (ARG3
& VKI_O_CREAT
) {
9982 PRINT("sys_openat ( %ld, %#" FMT_REGWORD
"x(%s), %ld, %ld )",
9983 SARG1
, ARG2
, (HChar
*)(Addr
)ARG2
, SARG3
, SARG4
);
9984 PRE_REG_READ4(long, "openat",
9985 int, dfd
, const char *, filename
, int, flags
, int, mode
);
9988 PRINT("sys_openat ( %ld, %#" FMT_REGWORD
"x(%s), %ld )",
9989 SARG1
, ARG2
, (HChar
*)(Addr
)ARG2
, SARG3
);
9990 PRE_REG_READ3(long, "openat",
9991 int, dfd
, const char *, filename
, int, flags
);
9993 PRE_MEM_RASCIIZ( "openat(filename)", ARG2
);
9995 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
9996 filename is relative to cwd. When comparing dfd against AT_FDCWD,
9997 be sure only to compare the bottom 32 bits. */
9998 if (ML_(safe_to_deref
)( (void*)(Addr
)ARG2
, 1 )
9999 && *(Char
*)(Addr
)ARG2
!= '/'
10000 && ((Int
)ARG1
) != ((Int
)VKI_AT_FDCWD
)
10001 && !ML_(fd_allowed
)(ARG1
, "openat", tid
, False
))
10002 SET_STATUS_Failure( VKI_EBADF
);
10004 /* Otherwise handle normally */
10005 *flags
|= SfMayBlock
;
10010 vg_assert(SUCCESS
);
10011 if (!ML_(fd_allowed
)(RES
, "openat", tid
, True
)) {
10013 SET_STATUS_Failure( VKI_EMFILE
);
10015 if (VG_(clo_track_fds
))
10016 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*)(Addr
)ARG2
);
10020 #endif /* DARWIN_VERS >= DARWIN_10_10 */
10023 /* ---------------------------------------------------------------------
10024 Added for OSX 10.11 (El Capitan)
10025 ------------------------------------------------------------------ */
10027 #if DARWIN_VERS >= DARWIN_10_11
10031 PRINT("kevent_qos( %ld, %#lx, %ld, %#lx, %ld, %#lx, %ld, %ld )",
10032 SARG1
, ARG2
, SARG3
, ARG4
, SARG5
, ARG6
, SARG7
, ARG8
);
10033 PRE_REG_READ8(int,"kevent_qos",
10035 const struct vki_kevent_qos_s
*,changelist
,
10037 struct vki_kevent_qos_s
*,eventlist
,
10040 size_t*,data_available
,
10041 unsigned int,flags
);
10043 if (ARG3
) PRE_MEM_READ ("kevent_qos(changelist)",
10044 ARG2
, ARG3
* sizeof(struct vki_kevent_qos_s
));
10045 if (ARG5
) PRE_MEM_WRITE("kevent_qos(eventlist)",
10046 ARG4
, ARG5
* sizeof(struct vki_kevent_qos_s
));
10047 if (ARG7
) PRE_MEM_WRITE("kevent_qos(data_out)",
10048 ARG6
, ARG7
* sizeof(void*));
10050 *flags
|= SfMayBlock
;
10055 PRINT("kevent_qos ret %ld dst %#lx (%zu)", RES
, ARG4
, sizeof(struct vki_kevent_qos_s
));
10057 ML_(sync_mappings
)("after", "kevent_qos", 0);
10058 POST_MEM_WRITE(ARG4
, RES
* sizeof(struct vki_kevent_qos_s
));
10065 *flags
|= SfMayBlock
;
10066 PRINT("pselect ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )", SARG1
, ARG2
, ARG3
,
10068 PRE_REG_READ5(long, "pselect",
10069 int, n
, vki_fd_set
*, readfds
, vki_fd_set
*, writefds
,
10070 vki_fd_set
*, exceptfds
, struct vki_timeval
*, timeout
);
10071 // XXX: this possibly understates how much memory is read.
10073 PRE_MEM_READ( "pselect(readfds)",
10074 ARG2
, ARG1
/8 /* __FD_SETSIZE/8 */ );
10076 PRE_MEM_READ( "pselect(writefds)",
10077 ARG3
, ARG1
/8 /* __FD_SETSIZE/8 */ );
10079 PRE_MEM_READ( "pselect(exceptfds)",
10080 ARG4
, ARG1
/8 /* __FD_SETSIZE/8 */ );
10082 PRE_timeval_READ( "pselect(timeout)", ARG5
);
10084 PRE_MEM_READ( "pselect(sigmask)", ARG6
, sizeof(vki_sigset_t
) );
10087 #endif /* DARWIN_VERS >= DARWIN_10_11 */
10090 /* ---------------------------------------------------------------------
10091 Added for macOS 10.12 (Sierra)
10092 ------------------------------------------------------------------ */
10094 #if DARWIN_VERS >= DARWIN_10_12
10098 PRINT("getentropy(buffer:%#lx, size:%ld)", ARG1
, ARG2
);
10099 PRE_REG_READ2(int, "getentropy",
10100 void*, buffer
, size_t, size
);
10101 PRE_MEM_WRITE( "getentropy(buffer)", ARG1
, ARG2
);
10106 vg_assert(SUCCESS
);
10107 POST_MEM_WRITE( ARG1
, ARG2
);
10112 PRINT("necp_open(%#lx)", ARG1
);
10113 PRE_REG_READ1(int, "necp_open", int, flags
);
10116 PRE(necp_client_action
)
10118 PRINT("necp_client_action(%lu, %#lx, %#lx, %lu, %#lx, %lu)",
10119 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
10120 PRE_REG_READ6(int, "necp_client_action",
10121 int, necp_fd
, uint32_t, action
,
10122 unsigned char*, client_id
, size_t, client_id_len
,
10123 uint8_t*, buffer
, size_t, buffer_size
);
10125 switch (ARG2
/* request */) {
10126 case VKI_NECP_CLIENT_ACTION_ADD
:
10127 if (ARG4
!= sizeof(uuid_t
) || ARG6
== 0 || ARG6
> VKI_NECP_MAX_CLIENT_PARAMETERS_SIZE
) {
10128 SET_STATUS_Failure( VKI_EINVAL
);
10130 PRE_MEM_WRITE( "necp_client_action(ADD, client_id)", ARG3
, ARG4
);
10131 PRE_MEM_READ( "necp_client_action(ADD, buffer)", ARG5
, ARG6
);
10133 case VKI_NECP_CLIENT_ACTION_CLAIM
:
10134 if (ARG4
!= sizeof(uuid_t
)) {
10135 SET_STATUS_Failure( VKI_EINVAL
);
10137 PRE_MEM_READ( "necp_client_action(CLAIM, client_id)", ARG3
, ARG4
);
10139 case VKI_NECP_CLIENT_ACTION_REMOVE
:
10140 if (ARG4
!= sizeof(uuid_t
) || (ARG5
!= 0 && ARG6
!= VKI_IFNET_STATS_PER_FLOW_SIZE
)) {
10141 SET_STATUS_Failure( VKI_EINVAL
);
10143 PRE_MEM_READ( "necp_client_action(REMOVE, client_id)", ARG3
, ARG4
);
10144 PRE_MEM_READ( "necp_client_action(REMOVE, buffer)", ARG5
, ARG6
);
10146 case VKI_NECP_CLIENT_ACTION_COPY_PARAMETERS
:
10147 if ((ARG3
!= 0 && ARG4
!= sizeof(uuid_t
)) || ARG6
== 0) {
10148 SET_STATUS_Failure( VKI_EINVAL
);
10151 PRE_MEM_READ( "necp_client_action(COPY_PARAMETERS, client_id)", ARG3
, ARG4
);
10153 PRE_MEM_READ( "necp_client_action(COPY_PARAMETERS, buffer)", ARG5
, ARG6
);
10155 case VKI_NECP_CLIENT_ACTION_COPY_RESULT
:
10156 if ((ARG3
!= 0 && ARG4
!= sizeof(uuid_t
)) || ARG6
== 0) {
10157 SET_STATUS_Failure( VKI_EINVAL
);
10160 PRE_MEM_READ( "necp_client_action(COPY_RESULT, client_id)", ARG3
, ARG4
);
10162 PRE_MEM_READ( "necp_client_action(COPY_RESULT, buffer)", ARG5
, ARG6
);
10164 case VKI_NECP_CLIENT_ACTION_COPY_UPDATED_RESULT
:
10165 if ((ARG3
!= 0 && ARG4
!= sizeof(uuid_t
)) || ARG6
== 0) {
10166 SET_STATUS_Failure( VKI_EINVAL
);
10169 PRE_MEM_READ( "necp_client_action(COPY_UPDATED_RESULT, client_id)", ARG3
, ARG4
);
10171 PRE_MEM_READ( "necp_client_action(COPY_UPDATED_RESULT, buffer)", ARG5
, ARG6
);
10173 case VKI_NECP_CLIENT_ACTION_COPY_LIST
:
10174 if (ARG6
< sizeof(u_int32_t
)) {
10175 SET_STATUS_Failure( VKI_EINVAL
);
10177 PRE_MEM_READ( "necp_client_action(COPY_LIST, buffer)", ARG5
, ARG6
);
10179 case VKI_NECP_CLIENT_ACTION_AGENT
:
10180 if (ARG4
!= sizeof(uuid_t
) || ARG6
== 0) {
10181 SET_STATUS_Failure( VKI_EINVAL
);
10183 PRE_MEM_READ( "necp_client_action(AGENT, client_id)", ARG3
, ARG4
);
10184 PRE_MEM_READ( "necp_client_action(AGENT, buffer)", ARG5
, ARG6
);
10186 case VKI_NECP_CLIENT_ACTION_COPY_AGENT
:
10187 if (ARG4
!= sizeof(uuid_t
) || ARG6
== 0) {
10188 SET_STATUS_Failure( VKI_EINVAL
);
10190 PRE_MEM_READ( "necp_client_action(COPY_AGENT, client_id)", ARG3
, ARG4
);
10191 PRE_MEM_READ( "necp_client_action(COPY_AGENT, buffer)", ARG5
, ARG6
);
10192 PRE_MEM_WRITE( "necp_client_action(COPY_AGENT, buffer)", ARG5
, ARG6
);
10194 case VKI_NECP_CLIENT_ACTION_AGENT_USE
:
10195 if (ARG4
!= sizeof(uuid_t
) || ARG6
!= sizeof(struct vki_necp_agent_use_parameters
)) {
10196 SET_STATUS_Failure( VKI_EINVAL
);
10198 PRE_MEM_READ( "necp_client_action(AGENT_USE, client_id)", ARG3
, ARG4
);
10199 PRE_MEM_READ( "necp_client_action(AGENT_USE, buffer)", ARG5
, ARG6
);
10200 PRE_MEM_WRITE( "necp_client_action(AGENT_USE, buffer)", ARG5
, ARG6
);
10202 case VKI_NECP_CLIENT_ACTION_COPY_INTERFACE
:
10203 if (ARG4
!= sizeof(u_int32_t
) || ARG6
< sizeof(struct vki_necp_interface_details_legacy
)) {
10204 SET_STATUS_Failure( VKI_EINVAL
);
10206 PRE_MEM_READ( "necp_client_action(COPY_INTERFACE, client_id)", ARG3
, ARG4
);
10207 PRE_MEM_WRITE( "necp_client_action(COPY_INTERFACE, buffer)", ARG5
, ARG6
);
10209 case VKI_NECP_CLIENT_ACTION_COPY_ROUTE_STATISTICS
:
10210 if (ARG4
!= sizeof(uuid_t
) || ARG6
< VKI_NECP_STAT_COUNTS_SIZE
) {
10211 SET_STATUS_Failure( VKI_EINVAL
);
10213 PRE_MEM_READ( "necp_client_action(COPY_ROUTE_STATISTICS, client_id)", ARG3
, ARG4
);
10214 PRE_MEM_WRITE( "necp_client_action(COPY_ROUTE_STATISTICS, buffer)", ARG5
, ARG6
);
10216 case VKI_NECP_CLIENT_ACTION_UPDATE_CACHE
:
10217 if (ARG4
!= sizeof(uuid_t
) || ARG6
!= sizeof(struct vki_necp_cache_buffer
)) {
10218 SET_STATUS_Failure( VKI_EINVAL
);
10220 PRE_MEM_READ( "necp_client_action(UPDATE_CACHE, client_id)", ARG3
, ARG4
);
10221 PRE_MEM_READ( "necp_client_action(UPDATE_CACHE, buffer)", ARG5
, ARG6
);
10223 case VKI_NECP_CLIENT_ACTION_COPY_CLIENT_UPDATE
:
10224 if (ARG4
!= sizeof(uuid_t
) || ARG6
== 0) {
10225 SET_STATUS_Failure( VKI_EINVAL
);
10227 PRE_MEM_WRITE( "necp_client_action(COPY_CLIENT_UPDATE, client_id)", ARG3
, ARG4
);
10228 PRE_MEM_WRITE( "necp_client_action(COPY_CLIENT_UPDATE, buffer)", ARG5
, ARG6
);
10230 case VKI_NECP_CLIENT_ACTION_SIGN
:
10231 if (ARG4
< sizeof(struct vki_necp_client_signable
) || ARG6
!= VKI_NECP_CLIENT_ACTION_SIGN_TAG_LENGTH
) {
10232 SET_STATUS_Failure( VKI_EINVAL
);
10234 PRE_MEM_READ( "necp_client_action(SIGN, client_id)", ARG3
, ARG4
);
10235 PRE_MEM_WRITE( "necp_client_action(SIGN, buffer)", ARG5
, ARG6
);
10238 VG_(printf
)("UNKNOWN necp_client_action action %#lx\n", ARG2
);
10243 static const HChar
*ulop_name(int op
)
10246 case VKI_UL_UNFAIR_LOCK
: return "UL_UNFAIR_LOCK";
10247 case VKI_UL_COMPARE_AND_WAIT
: return "UL_COMPARE_AND_WAIT";
10248 default: return "??";
10254 uint ul_opcode
= ARG1
& VKI_UL_OPCODE_MASK
;
10255 uint ul_flags
= ARG1
& VKI_UL_FLAGS_MASK
;
10256 switch (ul_opcode
) {
10257 case VKI_UL_UNFAIR_LOCK
:
10258 case VKI_UL_COMPARE_AND_WAIT
: {
10259 const char* name
= ulop_name(ul_opcode
);
10260 if (ul_flags
& VKI_ULF_WAKE_THREAD
) {
10261 PRINT("ulock_wake(operation:%s (flags: %#x), addr:%#lx, wake_value:%s)",
10262 name
, ul_flags
, ARG2
, name_for_port(ARG3
));
10264 PRINT("ulock_wake(operation:%s (flags: %#x), addr:%#lx, wake_value:%ld /*unused*/)",
10265 name
, ul_flags
, ARG2
, ARG3
);
10267 PRE_REG_READ3(int, "ulock_wake",
10268 uint32_t, operation
, void*, addr
, uint64_t, wake_value
);
10273 PRINT("ulock_wake(operation:%ld (opcode: %u [??], flags: %#x), addr:%#lx, wake_value:%ld)", ARG1
, ul_opcode
, ul_flags
, ARG2
, ARG3
);
10274 log_decaying("UNKNOWN ulock_wake %ld (opcode: %u [??], flags: %#x)!", ARG1
, ul_opcode
, ul_flags
);
10281 uint ul_opcode
= ARG1
& VKI_UL_OPCODE_MASK
;
10282 uint ul_flags
= ARG1
& VKI_UL_FLAGS_MASK
;
10284 switch (ul_opcode
) {
10285 case VKI_UL_UNFAIR_LOCK
:
10286 case VKI_UL_COMPARE_AND_WAIT
: {
10287 const char* name
= ulop_name(ul_opcode
);
10288 PRINT("ulock_wait(operation:%s (flags: %#x), addr:%#lx, value:%ld, timeout:%ld)",
10289 name
, ul_flags
, ARG2
, ARG3
, ARG4
);
10290 PRE_REG_READ4(int, "ulock_wait",
10291 uint32_t, operation
, void*, addr
, uint64_t, value
, uint32_t, timeout
);
10292 PRE_MEM_READ("ulock_wait(addr)", ARG2
, 4 );
10297 PRINT("ulock_wait(operation:%ld (opcode: %u [??], flags: %#x), addr:%#lx, value:%ld, timeout:%ld)", ARG1
, ul_opcode
, ul_flags
, ARG2
, ARG3
, ARG4
);
10298 log_decaying("UNKNOWN ulock_wait %ld (opcode: %u [??], flags: %#x)!", ARG1
, ul_opcode
, ul_flags
);
10302 *flags
|= SfMayBlock
;
10305 PRE(terminate_with_payload
)
10307 PRINT("terminate_with_payload"
10308 "(pid: %ld, reason_namespace:%ld, reason_code:%ld, payload:%#lx, payload_size:%ld, reason_string:%s, reason_flags:%#x)",
10309 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, (char*)ARG6
, (uint
)ARG7
);
10310 PRE_REG_READ7(int, "terminate_with_payload", int, pid
,
10311 uint32_t, reason_namespace
, uint64_t, reason_code
, void*, payload
,
10312 uint32_t, payload_size
, const char*, reason_string
, uint64_t, reason_flags
);
10313 PRE_MEM_READ("abort_with_payload(payload)", ARG4
, ARG5
);
10314 PRE_MEM_RASCIIZ("abort_with_payload(reason_string)", ARG6
);
10317 PRE(abort_with_payload
)
10319 PRINT("abort_with_payload"
10320 "(reason_namespace:%ld, reason_code:%ld, payload:%#lx, payload_size:%ld, reason_string:%s, reason_flags:%#x)",
10321 ARG1
, ARG2
, ARG3
, ARG4
, (char*)ARG5
, (uint
)ARG6
);
10322 PRE_REG_READ6(uint32_t, "abort_with_payload",
10323 uint32_t, reason_namespace
, uint64_t, reason_code
, void*, payload
,
10324 uint32_t, payload_size
, const char*, reason_string
, uint64_t, reason_flags
);
10325 PRE_MEM_READ("abort_with_payload(payload)", ARG3
, ARG4
);
10326 PRE_MEM_RASCIIZ("abort_with_payload(reason_string)", ARG5
);
10329 PRE(host_create_mach_voucher_trap
)
10331 // munge_wwww -- no need to call helper
10332 PRINT("host_create_mach_voucher_trap"
10333 "(host:%s, recipes:%#lx, recipes_size:%ld, voucher:%#lx)",
10334 name_for_port(ARG1
), ARG2
, ARG3
, ARG4
);
10335 PRE_MEM_READ( "host_create_mach_voucher_trap(recipes)", ARG2
, ARG3
);
10336 PRE_MEM_WRITE( "host_create_mach_voucher_trap(voucher)", ARG4
, sizeof(mach_port_name_t
) );
10338 POST(host_create_mach_voucher_trap
)
10340 vg_assert(SUCCESS
);
10341 POST_MEM_WRITE( ARG4
, sizeof(mach_port_name_t
) );
10344 PRE(task_register_dyld_image_infos
)
10347 // typedef struct {
10348 // mach_msg_header_t Head;
10349 // /* start of the kernel processed data */
10350 // mach_msg_body_t msgh_body;
10351 // mach_msg_ool_descriptor_t dyld_images;
10352 // /* end of the kernel processed data */
10353 // NDR_record_t NDR;
10354 // mach_msg_type_number_t dyld_imagesCnt;
10358 // Request *req = (Request *)ARG1;
10360 PRINT("task_register_dyld_image_infos(%s)", name_for_port(MACH_REMOTE
));
10362 AFTER
= POST_FN(task_register_dyld_image_infos
);
10365 POST(task_register_dyld_image_infos
)
10369 mach_msg_header_t Head
;
10371 kern_return_t RetCode
;
10375 Reply
*reply
= (Reply
*)ARG1
;
10376 if (!reply
->RetCode
) {
10378 PRINT("mig return %d", reply
->RetCode
);
10382 PRE(task_register_dyld_shared_cache_image_info
)
10385 // typedef struct {
10386 // mach_msg_header_t Head;
10387 // NDR_record_t NDR;
10388 // dyld_kernel_image_info_t dyld_cache_image;
10389 // boolean_t no_cache;
10390 // boolean_t private_cache;
10394 // Request *req = (Request *)ARG1;
10396 PRINT("task_register_dyld_shared_cache_image_info(%s)",
10397 name_for_port(MACH_REMOTE
));
10399 AFTER
= POST_FN(task_register_dyld_shared_cache_image_info
);
10402 POST(task_register_dyld_shared_cache_image_info
)
10406 mach_msg_header_t Head
;
10408 kern_return_t RetCode
;
10412 Reply
*reply
= (Reply
*)ARG1
;
10413 if (!reply
->RetCode
) {
10415 PRINT("mig return %d", reply
->RetCode
);
10419 PRE(mach_generate_activity_id
)
10421 // munge_www -- no need to call helper
10422 PRINT("mach_generate_activity_id"
10423 "(target:%s, count:%ld)",
10424 name_for_port(ARG1
), ARG2
);
10425 PRE_REG_READ3(long, "mach_generate_activity_id",
10426 mach_port_name_t
, target
, int, count
, uint64_t *, activity_id
);
10427 if (ARG2
<= 0 || ARG2
> MACH_ACTIVITY_ID_COUNT_MAX
) {
10428 SET_STATUS_Failure( VKI_EINVAL
);
10430 if (ML_(safe_to_deref
)( (void*)ARG3
, sizeof(vki_uint64_t
*) )) {
10431 PRE_MEM_WRITE( "mach_generate_activity_id(activity_id)", ARG3
, sizeof(vki_uint64_t
) );
10433 SET_STATUS_Failure( VKI_EFAULT
);
10437 POST(mach_generate_activity_id
)
10439 if (ML_(safe_to_deref
)( (void*)ARG3
, sizeof(vki_uint64_t
*) )) {
10440 POST_MEM_WRITE( ARG3
, sizeof(vki_uint64_t
) );
10441 PRINT("-> activity_id:%#llx", *(uint64_t*)ARG3
);
10445 #endif /* DARWIN_VERS >= DARWIN_10_12 */
10447 /* ---------------------------------------------------------------------
10448 Added for macOS 10.13 (High Sierra)
10449 ------------------------------------------------------------------ */
10451 #if DARWIN_VERS >= DARWIN_10_13
10453 PRE(openat_nocancel
)
10455 if (ARG3
& VKI_O_CREAT
) {
10457 PRINT("openat_nocancel ( %ld, %#" FMT_REGWORD
"x(%s), %ld, %ld )",
10458 SARG1
, ARG2
, (HChar
*)(Addr
)ARG2
, SARG3
, SARG4
);
10459 PRE_REG_READ4(long, "openat_nocancel",
10460 int, dfd
, const char *, filename
, int, flags
, int, mode
);
10463 PRINT("openat_nocancel ( %ld, %#" FMT_REGWORD
"x(%s), %ld )",
10464 SARG1
, ARG2
, (HChar
*)(Addr
)ARG2
, SARG3
);
10465 PRE_REG_READ3(long, "openat_nocancel",
10466 int, dfd
, const char *, filename
, int, flags
);
10468 PRE_MEM_RASCIIZ( "openat_nocancel(filename)", ARG2
);
10470 /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD,
10471 filename is relative to cwd. When comparing dfd against AT_FDCWD,
10472 be sure only to compare the bottom 32 bits. */
10473 if (ML_(safe_to_deref
)( (void*)(Addr
)ARG2
, 1 )
10474 && *(Char
*)(Addr
)ARG2
!= '/'
10475 && ((Int
)ARG1
) != ((Int
)VKI_AT_FDCWD
)
10476 && !ML_(fd_allowed
)(ARG1
, "openat_nocancel", tid
, False
))
10477 SET_STATUS_Failure( VKI_EBADF
);
10479 /* Otherwise handle normally */
10480 *flags
|= SfMayBlock
;
10482 POST(openat_nocancel
)
10484 vg_assert(SUCCESS
);
10485 if (!ML_(fd_allowed
)(RES
, "openat_nocancel", tid
, True
)) {
10487 SET_STATUS_Failure( VKI_EMFILE
);
10489 if (VG_(clo_track_fds
))
10490 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*)(Addr
)ARG2
);
10496 PRINT("kevent_id(id:%ld, changelist:%#lx, nchanges:%ld, eventlist:%#lx, nevents:%ld, data_out:%#lx, data_available:%ld, flags:%lx)",
10497 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
, ARG7
, ARG8
);
10498 PRE_REG_READ8(int,"kevent_id",
10500 const struct vki_kevent_qos_s
*,changelist
,
10502 struct vki_kevent_qos_s
*,eventlist
,
10505 size_t*,data_available
,
10506 unsigned int,flags
);
10508 if (ARG3
) PRE_MEM_READ ("kevent_id(changelist)",
10509 ARG2
, ARG3
* sizeof(struct vki_kevent_qos_s
));
10510 if (ARG5
) PRE_MEM_WRITE("kevent_id(eventlist)",
10511 ARG4
, ARG5
* sizeof(struct vki_kevent_qos_s
));
10512 if (ARG7
) PRE_MEM_WRITE ("kevent_id(data_out)",
10513 ARG6
, ARG7
* sizeof(void*));
10515 *flags
|= SfMayBlock
;
10520 PRINT("kevent_id ret %ld dst %#lx (%zu)", RES
, ARG4
, sizeof(struct vki_kevent_qos_s
));
10522 POST_MEM_WRITE(ARG4
, RES
* sizeof(struct vki_kevent_qos_s
));
10526 PRE(thread_get_special_reply_port
)
10528 PRINT("thread_get_special_reply_port()");
10531 POST(thread_get_special_reply_port
)
10533 record_named_port(tid
, RES
, MACH_PORT_RIGHT_RECEIVE
, "special-reply-%p");
10534 PRINT("special reply port %s", name_for_port(RES
));
10537 #endif /* DARWIN_VERS >= DARWIN_10_13 */
10539 /* ---------------------------------------------------------------------
10541 ------------------------------------------------------------------ */
10543 /* Add a Darwin-specific, arch-independent wrapper to a syscall table. */
10545 #define MACX_(sysno, name) \
10546 WRAPPER_ENTRY_X_(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name)
10548 #define MACXY(sysno, name) \
10549 WRAPPER_ENTRY_XY(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name)
10551 #define _____(sysno) GENX_(sysno, sys_ni_syscall) /* UNIX style only */
10554 _____ : unsupported by the kernel (sys_ni_syscall) (UNIX-style only)
10555 unfortunately misused for Mach too, causing assertion failures
10556 // _____ : unimplemented in valgrind
10557 GEN : handlers are in syswrap-generic.c
10558 MAC : handlers are in this file
10559 X_ : PRE handler only
10560 XY : PRE and POST handlers
10562 const SyscallTableEntry
ML_(syscall_table
)[] = {
10563 // _____(__NR_syscall), // 0
10564 MACX_(__NR_exit
, exit
),
10565 GENX_(__NR_fork
, sys_fork
),
10566 GENXY(__NR_read
, sys_read
),
10567 GENX_(__NR_write
, sys_write
),
10568 GENXY(__NR_open
, sys_open
),
10569 GENX_(__NR_close
, sys_close
),
10570 GENXY(__NR_wait4
, sys_wait4
),
10571 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(8)), // old creat
10572 GENX_(__NR_link
, sys_link
),
10573 GENX_(__NR_unlink
, sys_unlink
),
10574 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(11)), // old execv
10575 GENX_(__NR_chdir
, sys_chdir
),
10576 GENX_(__NR_fchdir
, sys_fchdir
),
10577 GENX_(__NR_mknod
, sys_mknod
),
10578 GENX_(__NR_chmod
, sys_chmod
),
10579 GENX_(__NR_chown
, sys_chown
),
10580 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(17)), // old break
10581 MACXY(__NR_getfsstat
, getfsstat
),
10582 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(19)), // old lseek
10583 GENX_(__NR_getpid
, sys_getpid
), // 20
10584 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(21)), // old mount
10585 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(22)), // old umount
10586 GENX_(__NR_setuid
, sys_setuid
),
10587 GENX_(__NR_getuid
, sys_getuid
),
10588 GENX_(__NR_geteuid
, sys_geteuid
),
10589 MACX_(__NR_ptrace
, ptrace
),
10590 MACXY(__NR_recvmsg
, recvmsg
),
10591 MACX_(__NR_sendmsg
, sendmsg
),
10592 MACXY(__NR_recvfrom
, recvfrom
),
10593 MACXY(__NR_accept
, accept
),
10594 MACXY(__NR_getpeername
, getpeername
),
10595 MACXY(__NR_getsockname
, getsockname
),
10596 GENX_(__NR_access
, sys_access
),
10597 MACX_(__NR_chflags
, chflags
),
10598 MACX_(__NR_fchflags
, fchflags
),
10599 GENX_(__NR_sync
, sys_sync
),
10600 GENX_(__NR_kill
, sys_kill
),
10601 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(38)), // old stat
10602 GENX_(__NR_getppid
, sys_getppid
),
10603 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(40)), // old lstat
10604 GENXY(__NR_dup
, sys_dup
),
10605 MACXY(__NR_pipe
, pipe
),
10606 GENX_(__NR_getegid
, sys_getegid
),
10607 #if DARWIN_VERS >= DARWIN_10_7
10608 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(44)), // old profil
10610 // _____(__NR_profil),
10612 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(45)), // old ktrace
10613 MACXY(__NR_sigaction
, sigaction
),
10614 GENX_(__NR_getgid
, sys_getgid
),
10615 MACXY(__NR_sigprocmask
, sigprocmask
),
10616 MACXY(__NR_getlogin
, getlogin
),
10617 // _____(__NR_setlogin),
10618 // _____(__NR_acct),
10619 MACXY(__NR_sigpending
, sigpending
),
10620 GENXY(__NR_sigaltstack
, sys_sigaltstack
),
10621 MACXY(__NR_ioctl
, ioctl
),
10622 // _____(__NR_reboot),
10623 // _____(__NR_revoke),
10624 GENX_(__NR_symlink
, sys_symlink
), // 57
10625 GENX_(__NR_readlink
, sys_readlink
),
10626 GENX_(__NR_execve
, sys_execve
),
10627 GENX_(__NR_umask
, sys_umask
), // 60
10628 GENX_(__NR_chroot
, sys_chroot
),
10629 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(62)), // old fstat
10630 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(63)), // used internally, reserved
10631 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(64)), // old getpagesize
10632 GENX_(__NR_msync
, sys_msync
),
10633 GENX_(__NR_vfork
, sys_fork
), // (We treat vfork as fork.)
10634 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(67)), // old vread
10635 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(68)), // old vwrite
10636 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(69)), // old sbrk
10637 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(70)), // old sstk
10638 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(71)), // old mmap
10639 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(72)), // old vadvise
10640 GENXY(__NR_munmap
, sys_munmap
),
10641 GENXY(__NR_mprotect
, sys_mprotect
),
10642 GENX_(__NR_madvise
, sys_madvise
),
10643 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(76)), // old vhangup
10644 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(77)), // old vlimit
10645 GENXY(__NR_mincore
, sys_mincore
),
10646 GENXY(__NR_getgroups
, sys_getgroups
),
10647 // _____(__NR_setgroups), // 80
10648 GENX_(__NR_getpgrp
, sys_getpgrp
),
10649 GENX_(__NR_setpgid
, sys_setpgid
),
10650 GENXY(__NR_setitimer
, sys_setitimer
),
10651 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(84)), // old wait
10652 // _____(__NR_swapon),
10653 GENXY(__NR_getitimer
, sys_getitimer
),
10654 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(87)), // old gethostname
10655 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(88)), // old sethostname
10656 MACXY(__NR_getdtablesize
, getdtablesize
),
10657 GENXY(__NR_dup2
, sys_dup2
),
10658 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(91)), // old getdopt
10659 MACXY(__NR_fcntl
, fcntl
),
10660 GENX_(__NR_select
, sys_select
),
10661 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(94)), // old setdopt
10662 GENX_(__NR_fsync
, sys_fsync
),
10663 GENX_(__NR_setpriority
, sys_setpriority
),
10664 MACXY(__NR_socket
, socket
),
10665 MACX_(__NR_connect
, connect
),
10666 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(99)), // old accept
10667 GENX_(__NR_getpriority
, sys_getpriority
), // 100
10668 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(101)), // old send
10669 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(102)), // old recv
10670 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(103)), // old sigreturn
10671 MACX_(__NR_bind
, bind
),
10672 MACX_(__NR_setsockopt
, setsockopt
),
10673 MACX_(__NR_listen
, listen
),
10674 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(107)), // old vtimes
10675 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(108)), // old sigvec
10676 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(109)), // old sigblock
10677 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(110)), // old sigsetmask
10678 MACX_(__NR_sigsuspend
, sigsuspend
), // old sigsuspend
10679 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(112)), // old sigstack
10680 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(113)), // old recvmsg
10681 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(114)), // old sendmsg
10682 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(115)), // old vtrace
10683 GENXY(__NR_gettimeofday
, sys_gettimeofday
),
10684 GENXY(__NR_getrusage
, sys_getrusage
),
10685 MACXY(__NR_getsockopt
, getsockopt
),
10686 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(119)), // old resuba
10687 GENXY(__NR_readv
, sys_readv
), // 120
10688 GENX_(__NR_writev
, sys_writev
),
10689 // _____(__NR_settimeofday),
10690 GENX_(__NR_fchown
, sys_fchown
),
10691 GENX_(__NR_fchmod
, sys_fchmod
),
10692 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(125)), // old recvfrom
10693 // _____(__NR_setreuid),
10694 // _____(__NR_setregid),
10695 GENX_(__NR_rename
, sys_rename
),
10696 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(129)), // old truncate
10697 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(130)), // old ftruncate
10698 GENX_(__NR_flock
, sys_flock
),
10699 MACXY(__NR_mkfifo
, mkfifo
),
10700 MACX_(__NR_sendto
, sendto
),
10701 MACX_(__NR_shutdown
, shutdown
),
10702 MACXY(__NR_socketpair
, socketpair
),
10703 GENX_(__NR_mkdir
, sys_mkdir
),
10704 GENX_(__NR_rmdir
, sys_rmdir
),
10705 GENX_(__NR_utimes
, sys_utimes
),
10706 MACX_(__NR_futimes
, futimes
),
10707 // _____(__NR_adjtime), // 140
10708 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(141)), // old getpeername
10709 MACXY(__NR_gethostuuid
, gethostuuid
),
10710 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(143)), // old sethostid
10711 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(144)), // old getrlimit
10712 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(145)), // old setrlimit
10713 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(146)), // old killpg
10714 GENX_(__NR_setsid
, sys_setsid
),
10715 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(148)), // old setquota
10716 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(149)), // old qquota
10717 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(150)), // old getsockname
10718 // _____(__NR_getpgid),
10719 // _____(__NR_setprivexec),
10720 GENXY(__NR_pread
, sys_pread64
),
10721 GENX_(__NR_pwrite
, sys_pwrite64
),
10722 // _____(__NR_nfssvc),
10723 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(156)), // old getdirentries
10724 GENXY(__NR_statfs
, sys_statfs
),
10725 GENXY(__NR_fstatfs
, sys_fstatfs
),
10726 // _____(__NR_unmount),
10727 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(160)), // old async_daemon
10728 // _____(__NR_getfh),
10729 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(162)), // old getdomainname
10730 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(163)), // old setdomainname
10731 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(164)), // ???
10732 // _____(__NR_quotactl),
10733 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(166)), // old exportfs
10734 MACX_(__NR_mount
, mount
),
10735 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(168)), // old ustat
10736 MACXY(__NR_csops
, csops
), // code-signing ops
10737 #if DARWIN_VERS >= DARWIN_10_8
10738 MACXY(__NR_csops_audittoken
, csops_audittoken
), // 170
10740 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(170)), // old table
10742 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(171)), // old wait3
10743 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(172)), // old rpause
10744 // _____(__NR_waitid),
10745 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(174)), // old getdents
10746 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(175)), // old gc_control
10747 // _____(__NR_add_profil),
10748 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(177)), // ???
10749 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(178)), // ???
10750 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(179)), // ???
10751 MACX_(__NR_kdebug_trace
, kdebug_trace
), // 180
10752 GENX_(__NR_setgid
, sys_setgid
),
10753 MACX_(__NR_setegid
, setegid
),
10754 MACX_(__NR_seteuid
, seteuid
),
10755 MACX_(__NR_sigreturn
, sigreturn
),
10756 // _____(__NR_chud),
10757 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(186)), // ???
10758 #if DARWIN_VERS >= DARWIN_10_6
10759 // _____(__NR_fdatasync),
10761 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(187)), // ???
10763 GENXY(__NR_stat
, sys_newstat
),
10764 GENXY(__NR_fstat
, sys_newfstat
),
10765 GENXY(__NR_lstat
, sys_newlstat
),
10766 MACX_(__NR_pathconf
, pathconf
),
10767 MACX_(__NR_fpathconf
, fpathconf
),
10768 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(193)), // ???
10769 GENXY(__NR_getrlimit
, sys_getrlimit
),
10770 GENX_(__NR_setrlimit
, sys_setrlimit
),
10771 MACXY(__NR_getdirentries
, getdirentries
),
10772 MACXY(__NR_mmap
, mmap
),
10773 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(198)), // __syscall
10774 MACX_(__NR_lseek
, lseek
),
10775 GENX_(__NR_truncate
, sys_truncate64
), // 200
10776 GENX_(__NR_ftruncate
, sys_ftruncate64
),
10777 MACXY(__NR___sysctl
, __sysctl
),
10778 GENX_(__NR_mlock
, sys_mlock
),
10779 GENX_(__NR_munlock
, sys_munlock
),
10780 // _____(__NR_undelete),
10781 // _____(__NR_ATsocket),
10782 // _____(__NR_ATgetmsg),
10783 // _____(__NR_ATputmsg),
10784 // _____(__NR_ATPsndreq),
10785 // _____(__NR_ATPsndrsp),
10786 // _____(__NR_ATPgetreq),
10787 // _____(__NR_ATPgetrsp),
10788 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(213)), // Reserved for AppleTalk
10789 #if DARWIN_VERS >= DARWIN_10_6
10790 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214)), // old kqueue_from_portset_np
10791 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215)), // old kqueue_portset_np
10793 // _____(__NR_kqueue_from_portset_np),
10794 // _____(__NR_kqueue_portset_np),
10796 // _____(__NR_mkcomplex),
10797 // _____(__NR_statv),
10798 // _____(__NR_lstatv),
10799 // _____(__NR_fstatv),
10800 MACXY(__NR_getattrlist
, getattrlist
), // 220
10801 MACX_(__NR_setattrlist
, setattrlist
),
10802 MACXY(__NR_getdirentriesattr
, getdirentriesattr
),
10803 MACX_(__NR_exchangedata
, exchangedata
),
10804 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(224)), // checkuseraccess
10805 // _____(__NR_searchfs),
10806 GENX_(__NR_delete
, sys_unlink
),
10807 // _____(__NR_copyfile),
10808 #if DARWIN_VERS >= DARWIN_10_6
10809 MACX_(__NR_fgetattrlist
, fgetattrlist
), // 228
10810 // _____(__NR_fsetattrlist),
10812 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(228)), // ??
10813 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(229)), // ??
10815 GENXY(__NR_poll
, sys_poll
),
10816 MACX_(__NR_watchevent
, watchevent
),
10817 MACXY(__NR_waitevent
, waitevent
),
10818 MACX_(__NR_modwatch
, modwatch
),
10819 MACXY(__NR_getxattr
, getxattr
),
10820 MACXY(__NR_fgetxattr
, fgetxattr
),
10821 MACX_(__NR_setxattr
, setxattr
),
10822 MACX_(__NR_fsetxattr
, fsetxattr
),
10823 MACX_(__NR_removexattr
, removexattr
),
10824 MACX_(__NR_fremovexattr
, fremovexattr
),
10825 MACXY(__NR_listxattr
, listxattr
), // 240
10826 MACXY(__NR_flistxattr
, flistxattr
),
10827 MACXY(__NR_fsctl
, fsctl
),
10828 MACX_(__NR_initgroups
, initgroups
),
10829 MACXY(__NR_posix_spawn
, posix_spawn
),
10830 #if DARWIN_VERS >= DARWIN_10_6
10831 // _____(__NR_ffsctl),
10833 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(245)), // ???
10835 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(246)), // ???
10836 // _____(__NR_nfsclnt),
10837 // _____(__NR_fhopen),
10838 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(249)), // ???
10839 // _____(__NR_minherit),
10840 // _____(__NR_semsys),
10841 // _____(__NR_msgsys),
10842 // _____(__NR_shmsys),
10843 MACXY(__NR_semctl
, semctl
),
10844 MACX_(__NR_semget
, semget
),
10845 MACX_(__NR_semop
, semop
),
10846 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(257)), // ???
10847 // _____(__NR_msgctl),
10848 // _____(__NR_msgget),
10849 // _____(__NR_msgsnd), // 260
10850 // _____(__NR_msgrcv),
10851 MACXY(__NR_shmat
, shmat
),
10852 MACXY(__NR_shmctl
, shmctl
),
10853 MACXY(__NR_shmdt
, shmdt
),
10854 MACX_(__NR_shmget
, shmget
),
10855 MACXY(__NR_shm_open
, shm_open
),
10856 MACXY(__NR_shm_unlink
, shm_unlink
),
10857 MACX_(__NR_sem_open
, sem_open
),
10858 MACX_(__NR_sem_close
, sem_close
),
10859 MACX_(__NR_sem_unlink
, sem_unlink
),
10860 MACX_(__NR_sem_wait
, sem_wait
),
10861 MACX_(__NR_sem_trywait
, sem_trywait
),
10862 MACX_(__NR_sem_post
, sem_post
),
10863 // 274 seems to have been repurposed for 10.10. Was sem_getvalue,
10864 // has become sysctlbyname. See below.
10865 MACXY(__NR_sem_init
, sem_init
),
10866 MACX_(__NR_sem_destroy
, sem_destroy
),
10867 MACX_(__NR_open_extended
, open_extended
), // 277
10868 // _____(__NR_umask_extended),
10869 MACXY(__NR_stat_extended
, stat_extended
),
10870 MACXY(__NR_lstat_extended
, lstat_extended
), // 280
10871 MACXY(__NR_fstat_extended
, fstat_extended
),
10872 MACX_(__NR_chmod_extended
, chmod_extended
),
10873 MACX_(__NR_fchmod_extended
,fchmod_extended
),
10874 MACXY(__NR_access_extended
,access_extended
),
10875 MACX_(__NR_settid
, settid
),
10876 #if DARWIN_VERS >= DARWIN_10_8
10877 MACX_(__NR_gettid
, gettid
), // 286
10879 // _____(__NR_setsgroups),
10880 // _____(__NR_getsgroups),
10881 // _____(__NR_setwgroups),
10882 // _____(__NR_getwgroups),
10883 // _____(__NR_mkfifo_extended),
10884 // _____(__NR_mkdir_extended),
10885 // _____(__NR_identitysvc),
10886 // _____(__NR_shared_region_check_np),
10887 // _____(__NR_shared_region_map_np),
10888 #if DARWIN_VERS >= DARWIN_10_6
10889 // _____(__NR_vm_pressure_monitor),
10890 // _____(__NR_psynch_rw_longrdlock),
10891 // _____(__NR_psynch_rw_yieldwrlock),
10892 // _____(__NR_psynch_rw_downgrade),
10893 // _____(__NR_psynch_rw_upgrade),
10894 MACXY(__NR_psynch_mutexwait
, psynch_mutexwait
), // 301
10895 MACXY(__NR_psynch_mutexdrop
, psynch_mutexdrop
), // 302
10896 MACXY(__NR_psynch_cvbroad
, psynch_cvbroad
), // 303
10897 MACXY(__NR_psynch_cvsignal
, psynch_cvsignal
), // 304
10898 MACXY(__NR_psynch_cvwait
, psynch_cvwait
), // 305
10899 MACXY(__NR_psynch_rw_rdlock
, psynch_rw_rdlock
), // 306
10900 MACXY(__NR_psynch_rw_wrlock
, psynch_rw_wrlock
), // 307
10901 MACXY(__NR_psynch_rw_unlock
, psynch_rw_unlock
), // 308
10902 // _____(__NR_psynch_rw_unlock2),
10904 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(296)), // old load_shared_file
10905 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(297)), // old reset_shared_file
10906 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(298)), // old new_system_shared_regions
10907 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(299)), // old shared_region_map_file_np
10908 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(300)), // old shared_region_make_private_np
10909 // _____(__NR___pthread_mutex_destroy),
10910 // _____(__NR___pthread_mutex_init),
10911 // _____(__NR___pthread_mutex_lock),
10912 // _____(__NR___pthread_mutex_trylock),
10913 // _____(__NR___pthread_mutex_unlock),
10914 // _____(__NR___pthread_cond_init),
10915 // _____(__NR___pthread_cond_destroy),
10916 // _____(__NR___pthread_cond_broadcast),
10917 // _____(__NR___pthread_cond_signal),
10919 // _____(__NR_getsid),
10920 // _____(__NR_settid_with_pid),
10921 #if DARWIN_VERS >= DARWIN_10_7
10922 MACXY(__NR_psynch_cvclrprepost
, psynch_cvclrprepost
), // 312
10924 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)), // old __pthread_cond_timedwait
10926 // _____(__NR_aio_fsync),
10927 MACX_(__NR_aio_return
, aio_return
),
10928 MACX_(__NR_aio_suspend
, aio_suspend
),
10929 // _____(__NR_aio_cancel),
10930 MACX_(__NR_aio_error
, aio_error
),
10931 MACXY(__NR_aio_read
, aio_read
),
10932 MACX_(__NR_aio_write
, aio_write
),
10933 // _____(__NR_lio_listio), // 320
10934 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(321)), // ???
10936 #if DARWIN_VERS >= DARWIN_10_8
10937 MACXY(__NR_iopolicysys
, iopolicysys
),
10938 MACXY(__NR_process_policy
, process_policy
),
10940 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(322)), // ???
10941 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(323)), // ???
10943 // _____(__NR_mlockall),
10944 // _____(__NR_munlockall),
10945 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(326)), // ???
10946 MACX_(__NR_issetugid
, issetugid
),
10947 MACX_(__NR___pthread_kill
, __pthread_kill
),
10948 MACX_(__NR___pthread_sigmask
, __pthread_sigmask
),
10949 MACXY(__NR___sigwait
, __sigwait
), // 330
10950 MACX_(__NR___disable_threadsignal
, __disable_threadsignal
),
10951 MACX_(__NR___pthread_markcancel
, __pthread_markcancel
),
10952 MACX_(__NR___pthread_canceled
, __pthread_canceled
),
10953 MACX_(__NR___semwait_signal
, __semwait_signal
),
10954 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(335)), // old utrace
10955 MACXY(__NR_proc_info
, proc_info
), // 336
10956 MACXY(__NR_sendfile
, sendfile
),
10957 MACXY(__NR_stat64
, stat64
),
10958 MACXY(__NR_fstat64
, fstat64
),
10959 MACXY(__NR_lstat64
, lstat64
), // 340
10960 MACXY(__NR_stat64_extended
, stat64_extended
),
10961 MACXY(__NR_lstat64_extended
, lstat64_extended
),
10962 MACXY(__NR_fstat64_extended
, fstat64_extended
),
10963 MACXY(__NR_getdirentries64
, getdirentries64
),
10964 MACXY(__NR_statfs64
, statfs64
),
10965 MACXY(__NR_fstatfs64
, fstatfs64
),
10966 MACXY(__NR_getfsstat64
, getfsstat64
),
10967 MACX_(__NR___pthread_chdir
, __pthread_chdir
),
10968 MACX_(__NR___pthread_fchdir
, __pthread_fchdir
),
10969 // _____(__NR_audit),
10970 MACXY(__NR_auditon
, auditon
),
10971 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(352)), // ???
10972 // _____(__NR_getauid),
10973 // _____(__NR_setauid),
10974 // _____(__NR_getaudit),
10975 // _____(__NR_setaudit),
10976 MACXY(__NR_getaudit_addr
, getaudit_addr
),
10977 // _____(__NR_setaudit_addr),
10978 // _____(__NR_auditctl),
10979 MACXY(__NR_bsdthread_create
, bsdthread_create
), // 360
10980 MACX_(__NR_bsdthread_terminate
, bsdthread_terminate
),
10981 MACXY(__NR_kqueue
, kqueue
),
10982 MACXY(__NR_kevent
, kevent
),
10983 GENX_(__NR_lchown
, sys_lchown
),
10984 // _____(__NR_stack_snapshot),
10985 MACX_(__NR_bsdthread_register
, bsdthread_register
),
10986 MACX_(__NR_workq_open
, workq_open
),
10987 MACXY(__NR_workq_ops
, workq_ops
),
10988 #if DARWIN_VERS >= DARWIN_10_6
10989 MACXY(__NR_kevent64
, kevent64
),
10991 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(369)), // ???
10993 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(370)), // old semwait_signal
10994 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(371)), // old semwait_signal_nocancel
10995 #if DARWIN_VERS >= DARWIN_10_6
10996 MACX_(__NR___thread_selfid
, __thread_selfid
),
10998 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(372)), // ???
11000 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(373)), // ???
11001 #if DARWIN_VERS < DARWIN_10_11
11002 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(374)), // ???
11004 #if DARWIN_VERS < DARWIN_10_13
11005 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(375)), // ???
11007 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(376)), // ???
11008 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(377)), // ???
11009 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(378)), // ???
11010 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(379)), // ???
11011 // _____(__NR___mac_execve), // 380
11012 MACX_(__NR___mac_syscall
, __mac_syscall
),
11013 // _____(__NR___mac_get_file),
11014 // _____(__NR___mac_set_file),
11015 // _____(__NR___mac_get_link),
11016 // _____(__NR___mac_set_link),
11017 // _____(__NR___mac_get_proc),
11018 // _____(__NR___mac_set_proc),
11019 // _____(__NR___mac_get_fd),
11020 // _____(__NR___mac_set_fd),
11021 // _____(__NR___mac_get_pid),
11022 // _____(__NR___mac_get_lcid),
11023 // _____(__NR___mac_get_lctx),
11024 // _____(__NR___mac_set_lctx),
11025 // _____(__NR_setlcid),
11026 // _____(__NR_getlcid),
11027 // GrP fixme need any special nocancel handling?
11028 GENXY(__NR_read_nocancel
, sys_read
),
11029 GENX_(__NR_write_nocancel
, sys_write
),
11030 GENXY(__NR_open_nocancel
, sys_open
),
11031 GENX_(__NR_close_nocancel
, sys_close
),
11032 GENXY(__NR_wait4_nocancel
, sys_wait4
), // 400
11033 MACXY(__NR_recvmsg_nocancel
, recvmsg
),
11034 MACX_(__NR_sendmsg_nocancel
, sendmsg
),
11035 MACXY(__NR_recvfrom_nocancel
, recvfrom
),
11036 MACXY(__NR_accept_nocancel
, accept
),
11037 GENX_(__NR_msync_nocancel
, sys_msync
),
11038 MACXY(__NR_fcntl_nocancel
, fcntl
),
11039 GENX_(__NR_select_nocancel
, sys_select
),
11040 GENX_(__NR_fsync_nocancel
, sys_fsync
),
11041 MACX_(__NR_connect_nocancel
, connect
),
11042 MACX_(__NR_sigsuspend_nocancel
, sigsuspend
),
11043 GENXY(__NR_readv_nocancel
, sys_readv
),
11044 GENX_(__NR_writev_nocancel
, sys_writev
),
11045 MACX_(__NR_sendto_nocancel
, sendto
),
11046 GENXY(__NR_pread_nocancel
, sys_pread64
),
11047 GENX_(__NR_pwrite_nocancel
, sys_pwrite64
),
11048 // _____(__NR_waitid_nocancel),
11049 GENXY(__NR_poll_nocancel
, sys_poll
),
11050 // _____(__NR_msgsnd_nocancel),
11051 // _____(__NR_msgrcv_nocancel),
11052 MACX_(__NR_sem_wait_nocancel
, sem_wait
), // 420
11053 // _____(__NR_aio_suspend_nocancel),
11054 // _____(__NR___sigwait_nocancel),
11055 MACX_(__NR___semwait_signal_nocancel
, __semwait_signal
),
11056 // _____(__NR___mac_mount),
11057 // _____(__NR___mac_get_mount),
11058 // _____(__NR___mac_getfsstat),
11059 #if DARWIN_VERS >= DARWIN_10_6
11060 MACXY(__NR_fsgetpath
, fsgetpath
),
11061 MACXY(__NR_audit_session_self
, audit_session_self
),
11062 // _____(__NR_audit_session_join),
11064 #if DARWIN_VERS >= DARWIN_10_9
11065 MACX_(__NR_fileport_makeport
, fileport_makeport
),
11066 // _____(__NR_fileport_makefd), // 431
11067 // _____(__NR_audit_session_port), // 432
11068 // _____(__NR_pid_suspend), // 433
11069 // _____(__NR_pid_resume), // 434
11070 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(435)), // ???
11071 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(436)), // ???
11072 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(437)), // ???
11073 // _____(__NR_shared_region_map_and_slide_np), // 438
11074 // _____(__NR_kas_info), // 439
11075 // _____(__NR_memorystatus_control), // 440
11076 MACX_(__NR_guarded_open_np
, guarded_open_np
),
11077 MACX_(__NR_guarded_close_np
, guarded_close_np
),
11078 MACX_(__NR_guarded_kqueue_np
, guarded_kqueue_np
),
11079 MACX_(__NR_change_fdguard_np
, change_fdguard_np
),
11080 MACX_(__NR_connectx
, connectx
),
11081 MACX_(__NR_disconnectx
, disconnectx
),
11083 #if DARWIN_VERS >= DARWIN_10_10
11084 MACXY(__NR_sysctlbyname
, sysctlbyname
), // 274
11085 MACXY(__NR_necp_match_policy
, necp_match_policy
), // 460
11086 MACXY(__NR_getattrlistbulk
, getattrlistbulk
), // 461
11087 MACXY(__NR_openat
, openat
), // 463
11088 #if DARWIN_VERS >= DARWIN_10_13
11089 MACXY(__NR_openat_nocancel
, openat_nocancel
), // 464
11091 MACX_(__NR_faccessat
, faccessat
), // 466
11092 MACXY(__NR_fstatat64
, fstatat64
), // 470
11093 MACX_(__NR_readlinkat
, readlinkat
), // 473
11094 MACX_(__NR_bsdthread_ctl
, bsdthread_ctl
), // 478
11095 MACXY(__NR_csrctl
, csrctl
), // 483
11096 MACX_(__NR_guarded_open_dprotected_np
, guarded_open_dprotected_np
), // 484
11097 MACX_(__NR_guarded_write_np
, guarded_write_np
), // 485
11098 MACX_(__NR_guarded_pwrite_np
, guarded_pwrite_np
), // 486
11099 MACX_(__NR_guarded_writev_np
, guarded_writev_np
), // 487
11100 // _____(__NR___mremap_encrypted), // 489
11102 #if DARWIN_VERS >= DARWIN_10_11
11103 // _____(__NR_kdebug_trace_string), // 178
11104 MACXY(__NR_kevent_qos
, kevent_qos
), // 374
11105 MACX_(__NR_pselect
, pselect
), // 394
11106 // _____(__NR_netagent_trigger), // 490
11107 // _____(__NR_stack_snapshot_with_config), // 491
11108 // _____(__NR_microstackshot), // 492
11109 // _____(__NR_grab_pgo_data), // 493
11110 // _____(__NR_persona), // 494
11111 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(495)), // ???
11112 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(496)), // ???
11113 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(497)), // ???
11114 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(498)), // ???
11115 // _____(__NR_work_interval_ctl), // 499
11117 #if DARWIN_VERS >= DARWIN_10_12
11118 // _____(__NR_kdebug_typefilter), // 177
11119 // _____(__NR_clonefileat), // 462
11120 // _____(__NR_renameatx_np), // 488
11121 MACXY(__NR_getentropy
, getentropy
), // 500
11122 MACX_(__NR_necp_open
, necp_open
), // 501
11123 MACX_(__NR_necp_client_action
, necp_client_action
), // 502
11124 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(503)), // ???
11125 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(504)), // ???
11126 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(505)), // ???
11127 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(506)), // ???
11128 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(507)), // ???
11129 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(508)), // ???
11130 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(509)), // ???
11131 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(510)), // ???
11132 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(511)), // ???
11133 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(512)), // ???
11134 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(513)), // ???
11135 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(514)), // ???
11136 MACX_(__NR_ulock_wait
, ulock_wait
), // 515
11137 MACX_(__NR_ulock_wake
, ulock_wake
), // 516
11138 // _____(__NR_fclonefileat), // 517
11139 // _____(__NR_fs_snapshot), // 518
11140 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(519)), // ???
11141 MACX_(__NR_terminate_with_payload
, terminate_with_payload
), // 520
11142 MACX_(__NR_abort_with_payload
, abort_with_payload
), // 521
11144 #if DARWIN_VERS >= DARWIN_10_13
11145 // _____(__NR_thread_selfcounts), // 186
11146 MACXY(__NR_kevent_id
, kevent_id
), // 375
11147 // _____(__NR_necp_session_open), // 522
11148 // _____(__NR_necp_session_action), // 523
11149 // _____(__NR_setattrlistat), // 524
11150 // _____(__NR_net_qos_guideline), // 525
11151 // _____(__NR_fmount), // 526
11152 // _____(__NR_ntp_adjtime), // 527
11153 // _____(__NR_ntp_gettime), // 528
11154 // _____(__NR_os_fault_with_payload), // 529
11156 // _____(__NR_MAXSYSCALL)
11157 MACX_(__NR_DARWIN_FAKE_SIGRETURN
, FAKE_SIGRETURN
)
11161 // Mach traps use negative syscall numbers.
11162 // Use ML_(mach_trap_table)[-mach_trap_number] .
11163 // cf xnu sources osfmk/kern/syscall_sw.c
11165 const SyscallTableEntry
ML_(mach_trap_table
)[] = {
11166 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(0)),
11167 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(1)),
11168 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(2)),
11169 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(3)),
11170 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(4)),
11171 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(5)),
11172 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(6)),
11173 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(7)),
11174 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(8)),
11175 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(9)),
11177 # if DARWIN_VERS >= DARWIN_10_8
11178 MACXY(__NR_kernelrpc_mach_vm_allocate_trap
, kernelrpc_mach_vm_allocate_trap
),
11180 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10)),
11183 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11)),
11185 # if DARWIN_VERS >= DARWIN_10_8
11186 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12), kernelrpc_mach_vm_deallocate_trap
),
11188 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12)),
11191 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(13)),
11193 # if DARWIN_VERS >= DARWIN_10_8
11194 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14), kernelrpc_mach_vm_protect_trap
),
11197 # if DARWIN_VERS >= DARWIN_10_9
11198 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(15), kernelrpc_mach_vm_map_trap
),
11201 # if DARWIN_VERS < DARWIN_10_8
11202 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14)),
11203 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(15)),
11206 # if DARWIN_VERS >= DARWIN_10_8
11207 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16), kernelrpc_mach_port_allocate_trap
),
11208 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17), kernelrpc_mach_port_destroy_trap
),
11209 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18), kernelrpc_mach_port_deallocate_trap
),
11210 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19), kernelrpc_mach_port_mod_refs_trap
),
11211 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20), kernelrpc_mach_port_move_member_trap
),
11212 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21), kernelrpc_mach_port_insert_right_trap
),
11213 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(22), kernelrpc_mach_port_insert_member_trap
),
11214 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(23), kernelrpc_mach_port_extract_member_trap
),
11216 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16)),
11217 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17)),
11218 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18)),
11219 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19)),
11220 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20)),
11221 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21)),
11222 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(22)),
11223 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(23)),
11226 # if DARWIN_VERS >= DARWIN_10_9
11227 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24), kernelrpc_mach_port_construct_trap
),
11228 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(25), kernelrpc_mach_port_destruct_trap
),
11230 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24)),
11231 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(25)),
11234 MACXY(__NR_mach_reply_port
, mach_reply_port
),
11235 MACXY(__NR_thread_self_trap
, mach_thread_self
),
11236 MACXY(__NR_task_self_trap
, mach_task_self
),
11237 MACXY(__NR_host_self_trap
, mach_host_self
),
11238 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(30)),
11239 MACXY(__NR_mach_msg_trap
, mach_msg
),
11240 // _____(__NR_mach_msg_overwrite_trap),
11241 MACX_(__NR_semaphore_signal_trap
, semaphore_signal
),
11242 MACX_(__NR_semaphore_signal_all_trap
, semaphore_signal_all
),
11243 MACX_(__NR_semaphore_signal_thread_trap
, semaphore_signal_thread
),
11244 MACX_(__NR_semaphore_wait_trap
, semaphore_wait
),
11245 MACX_(__NR_semaphore_wait_signal_trap
, semaphore_wait_signal
),
11246 MACX_(__NR_semaphore_timedwait_trap
, semaphore_timedwait
),
11247 MACX_(__NR_semaphore_timedwait_signal_trap
, semaphore_timedwait_signal
),
11248 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(40)), // -40
11250 # if DARWIN_VERS >= DARWIN_10_9
11251 MACX_(__NR_kernelrpc_mach_port_guard_trap
, kernelrpc_mach_port_guard_trap
),
11252 MACX_(__NR_kernelrpc_mach_port_unguard_trap
, kernelrpc_mach_port_unguard_trap
),
11254 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(41)),
11255 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(42)),
11258 # if DARWIN_VERS >= DARWIN_10_12
11259 MACXY(__NR_mach_generate_activity_id
, mach_generate_activity_id
),
11260 # elif DARWIN_VERS >= DARWIN_10_10
11261 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(43)),
11262 # elif defined(VGA_x86) || DARWIN_VERS == DARWIN_10_9
11263 // _____(__NR_map_fd),
11265 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(43)),
11268 // _____(__NR_task_name_for_pid),
11269 MACXY(__NR_task_for_pid
, task_for_pid
),
11270 MACXY(__NR_pid_for_task
, pid_for_task
),
11271 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(47)),
11272 #if defined(VGA_x86)
11273 // _____(__NR_macx_swapon),
11274 // _____(__NR_macx_swapoff),
11276 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(48)),
11277 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(49)),
11279 #if DARWIN_VERS >= DARWIN_10_13
11280 MACXY(__NR_thread_get_special_reply_port
, thread_get_special_reply_port
),
11282 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(50)),
11283 #endif /* DARWIN_VERS >= DARWIN_10_13 */
11284 #if defined(VGA_x86)
11285 // _____(__NR_macx_triggers),
11286 // _____(__NR_macx_backing_store_suspend),
11287 // _____(__NR_macx_backing_store_recovery),
11289 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(51)),
11290 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(52)),
11291 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(53)),
11293 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(54)),
11294 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(55)),
11295 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(56)),
11296 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(57)),
11297 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(58)),
11298 MACX_(__NR_swtch_pri
, swtch_pri
),
11299 MACX_(__NR_swtch
, swtch
), // -60
11300 MACX_(__NR_syscall_thread_switch
, syscall_thread_switch
),
11301 // _____(__NR_clock_sleep_trap),
11302 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(63)),
11303 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(64)),
11304 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(65)),
11305 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(66)),
11306 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(67)),
11307 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(68)),
11308 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(69)),
11309 #if DARWIN_VERS >= DARWIN_10_12
11310 MACXY(__NR_host_create_mach_voucher_trap
, host_create_mach_voucher_trap
),
11312 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(70)),
11314 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(71)),
11315 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(72)),
11316 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(73)),
11317 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(74)),
11318 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(75)),
11319 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(76)),
11320 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(77)),
11321 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(78)),
11322 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(79)),
11323 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(80)), // -80
11324 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(81)),
11325 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(82)),
11326 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(83)),
11327 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(84)),
11328 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(85)),
11329 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(86)),
11330 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(87)),
11331 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(88)),
11332 MACXY(__NR_mach_timebase_info
, mach_timebase_info
),
11333 MACX_(__NR_mach_wait_until
, mach_wait_until
),
11334 MACXY(__NR_mk_timer_create
, mk_timer_create
),
11335 MACXY(__NR_mk_timer_destroy
, mk_timer_destroy
),
11336 MACX_(__NR_mk_timer_arm
, mk_timer_arm
),
11337 MACXY(__NR_mk_timer_cancel
, mk_timer_cancel
),
11338 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(95)),
11339 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(96)),
11340 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(97)),
11341 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(98)),
11342 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(99)),
11343 MACXY(__NR_iokit_user_client_trap
, iokit_user_client_trap
), // -100
11347 // Machine-dependent traps have wacky syscall numbers, and use the Mach trap
11348 // calling convention instead of the syscall convention.
11349 // Use ML_(mdep_trap_table)[syscallno - ML_(mdep_trap_base)] .
11351 #if defined(VGA_x86)
11352 const SyscallTableEntry
ML_(mdep_trap_table
)[] = {
11353 MACX_(__NR_thread_fast_set_cthread_self
, thread_fast_set_cthread_self
),
11355 #elif defined(VGA_amd64)
11356 const SyscallTableEntry
ML_(mdep_trap_table
)[] = {
11357 MACX_(__NR_thread_fast_set_cthread_self
, thread_fast_set_cthread_self
),
11360 #error unknown architecture
11363 const UInt
ML_(syscall_table_size
) =
11364 sizeof(ML_(syscall_table
)) / sizeof(ML_(syscall_table
)[0]);
11366 const UInt
ML_(mach_trap_table_size
) =
11367 sizeof(ML_(mach_trap_table
)) / sizeof(ML_(mach_trap_table
)[0]);
11369 const UInt
ML_(mdep_trap_table_size
) =
11370 sizeof(ML_(mdep_trap_table
)) / sizeof(ML_(mdep_trap_table
)[0]);
11372 #endif // defined(VGO_darwin)
11374 /*--------------------------------------------------------------------*/
11376 /*--------------------------------------------------------------------*/