1 2 /*--------------------------------------------------------------------*/ 3 /*--- Darwin-specific syscalls, etc. syswrap-darwin.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2005-2017 Apple Inc. 11 Greg Parker gparker (at) apple.com 12 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. 17 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. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #if defined(VGO_darwin) 32 33 #include "pub_core_basics.h" 34 #include "pub_core_vki.h" 35 #include "pub_core_vkiscnums.h" 36 #include "pub_core_threadstate.h" 37 #include "pub_core_aspacemgr.h" 38 #include "pub_core_xarray.h" 39 #include "pub_core_clientstate.h" 40 #include "pub_core_debuglog.h" 41 #include "pub_core_debuginfo.h" // VG_(di_notify_*) 42 #include "pub_core_transtab.h" // VG_(discard_translations) 43 #include "pub_core_libcbase.h" 44 #include "pub_core_libcassert.h" 45 #include "pub_core_libcfile.h" 46 #include "pub_core_libcprint.h" 47 #include "pub_core_libcproc.h" 48 #include "pub_core_libcsignal.h" 49 #include "pub_core_machine.h" // VG_(get_SP) 50 #include "pub_core_mallocfree.h" 51 #include "pub_core_options.h" 52 #include "pub_core_oset.h" 53 #include "pub_core_scheduler.h" 54 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)() 55 #include "pub_core_signals.h" 56 #include "pub_core_stacks.h" 57 #include "pub_core_syscall.h" 58 #include "pub_core_syswrap.h" 59 #include "pub_core_tooliface.h" 60 #include "pub_core_wordfm.h" 61 62 #include "priv_types_n_macros.h" 63 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */ 64 #include "priv_syswrap-darwin.h" /* for decls of darwin-ish wrappers */ 65 #include "priv_syswrap-main.h" 66 67 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ 68 #include <mach/mach.h> 69 #include <mach/mach_vm.h> 70 #include <semaphore.h> 71 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ 72 73 #define msgh_request_port msgh_remote_port 74 #define msgh_reply_port msgh_local_port 75 #define BOOTSTRAP_MAX_NAME_LEN 128 76 typedef HChar name_t[BOOTSTRAP_MAX_NAME_LEN]; 77 78 typedef uint64_t mig_addr_t; 79 80 81 // Saved ports 82 static mach_port_t vg_host_port = 0; 83 static mach_port_t vg_task_port = 0; 84 static mach_port_t vg_bootstrap_port = 0; 85 86 // Run a thread from beginning to end and return the thread's 87 // scheduler-return-code. 88 static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW) 89 { 90 VgSchedReturnCode ret; 91 ThreadId tid = (ThreadId)tidW; 92 ThreadState* tst = VG_(get_ThreadState)(tid); 93 94 VG_(debugLog)(1, "syswrap-darwin", 95 "thread_wrapper(tid=%u): entry\n", 96 tid); 97 98 vg_assert(tst->status == VgTs_Init); 99 100 /* make sure we get the CPU lock before doing anything significant */ 101 VG_(acquire_BigLock)(tid, "thread_wrapper"); 102 103 if (0) 104 VG_(printf)("thread tid %u started: stack = %p\n", 105 tid, (void *)&tid); 106 107 /* Make sure error reporting is enabled in the new thread. */ 108 tst->err_disablement_level = 0; 109 110 VG_TRACK(pre_thread_first_insn, tid); 111 112 tst->os_state.lwpid = VG_(gettid)(); 113 tst->os_state.threadgroup = VG_(getpid)(); 114 115 /* Thread created with all signals blocked; scheduler will set the 116 appropriate mask */ 117 118 ret = VG_(scheduler)(tid); 119 120 vg_assert(VG_(is_exiting)(tid)); 121 122 vg_assert(tst->status == VgTs_Runnable); 123 vg_assert(VG_(is_running_thread)(tid)); 124 125 VG_(debugLog)(1, "syswrap-darwin", 126 "thread_wrapper(tid=%u): done\n", 127 tid); 128 129 /* Return to caller, still holding the lock. */ 130 return ret; 131 } 132 133 134 135 /* Allocate a stack for this thread, if it doesn't already have one. 136 Returns the initial stack pointer value to use, or 0 if allocation 137 failed. */ 138 139 Addr allocstack ( ThreadId tid ) 140 { 141 ThreadState* tst = VG_(get_ThreadState)(tid); 142 VgStack* stack; 143 Addr initial_SP; 144 145 /* Either the stack_base and stack_init_SP are both zero (in which 146 case a stack hasn't been allocated) or they are both non-zero, 147 in which case it has. */ 148 149 if (tst->os_state.valgrind_stack_base == 0) 150 vg_assert(tst->os_state.valgrind_stack_init_SP == 0); 151 152 if (tst->os_state.valgrind_stack_base != 0) 153 vg_assert(tst->os_state.valgrind_stack_init_SP != 0); 154 155 /* If no stack is present, allocate one. */ 156 157 if (tst->os_state.valgrind_stack_base == 0) { 158 stack = VG_(am_alloc_VgStack)( &initial_SP ); 159 if (stack) { 160 tst->os_state.valgrind_stack_base = (Addr)stack; 161 tst->os_state.valgrind_stack_init_SP = initial_SP; 162 } 163 } 164 165 VG_(debugLog)( 2, "syswrap-darwin", "stack for tid %u at %p; init_SP=%p\n", 166 tid, 167 (void*)tst->os_state.valgrind_stack_base, 168 (void*)tst->os_state.valgrind_stack_init_SP ); 169 170 vg_assert(VG_IS_32_ALIGNED(tst->os_state.valgrind_stack_init_SP)); 171 172 return tst->os_state.valgrind_stack_init_SP; 173 } 174 175 176 void find_stack_segment(ThreadId tid, Addr sp) 177 { 178 ML_(guess_and_register_stack) (sp, VG_(get_ThreadState)(tid)); 179 } 180 181 182 /* Run a thread all the way to the end, then do appropriate exit actions 183 (this is the last-one-out-turn-off-the-lights bit). 184 */ 185 static void run_a_thread_NORETURN ( Word tidW ) 186 { 187 Int c; 188 VgSchedReturnCode src; 189 ThreadId tid = (ThreadId)tidW; 190 ThreadState* tst; 191 192 VG_(debugLog)(1, "syswrap-darwin", 193 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n", 194 tid); 195 196 tst = VG_(get_ThreadState)(tid); 197 vg_assert(tst); 198 199 /* Run the thread all the way through. */ 200 src = thread_wrapper(tid); 201 202 VG_(debugLog)(1, "syswrap-darwin", 203 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n", 204 tid); 205 206 c = VG_(count_living_threads)(); 207 vg_assert(c >= 1); /* stay sane */ 208 209 /* Deregister thread's stack. */ 210 if (tst->os_state.stk_id != NULL_STK_ID) 211 VG_(deregister_stack)(tst->os_state.stk_id); 212 213 // Tell the tool this thread is exiting 214 VG_TRACK( pre_thread_ll_exit, tid ); 215 216 /* If the thread is exiting with errors disabled, complain loudly; 217 doing so is bad (does the user know this has happened?) Also, 218 in all cases, be paranoid and clear the flag anyway so that the 219 thread slot is safe in this respect if later reallocated. This 220 should be unnecessary since the flag should be cleared when the 221 slot is reallocated, in thread_wrapper(). */ 222 if (tst->err_disablement_level > 0) { 223 VG_(umsg)( 224 "WARNING: exiting thread has error reporting disabled.\n" 225 "WARNING: possibly as a result of some mistake in the use\n" 226 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n" 227 ); 228 VG_(debugLog)( 229 1, "syswrap-darwin", 230 "run_a_thread_NORETURN(tid=%u): " 231 "WARNING: exiting thread has err_disablement_level = %u\n", 232 tid, tst->err_disablement_level 233 ); 234 } 235 tst->err_disablement_level = 0; 236 237 if (c == 1) { 238 239 VG_(debugLog)(1, "syswrap-darwin", 240 "run_a_thread_NORETURN(tid=%u): " 241 "last one standing\n", 242 tid); 243 244 /* We are the last one standing. Keep hold of the lock and 245 carry on to show final tool results, then exit the entire system. 246 Use the continuation pointer set at startup in m_main. */ 247 ( * VG_(address_of_m_main_shutdown_actions_NORETURN) ) (tid, src); 248 249 } else { 250 251 mach_msg_header_t msg; 252 253 VG_(debugLog)(1, "syswrap-darwin", 254 "run_a_thread_NORETURN(tid=%u): " 255 "not last one standing\n", 256 tid); 257 258 /* OK, thread is dead, but others still exist. Just exit. */ 259 260 /* This releases the run lock */ 261 VG_(exit_thread)(tid); 262 vg_assert(tst->status == VgTs_Zombie); 263 264 /* tid is now invalid. */ 265 266 // GrP fixme exit race 267 msg.msgh_bits = MACH_MSGH_BITS(17, MACH_MSG_TYPE_MAKE_SEND_ONCE); 268 msg.msgh_request_port = VG_(gettid)(); 269 msg.msgh_reply_port = 0; 270 msg.msgh_id = 3600; // thread_terminate 271 272 tst->status = VgTs_Empty; 273 // GrP fixme race here! new thread may claim this V thread stack 274 // before we get out here! 275 // GrP fixme use bsdthread_terminate for safe cleanup? 276 mach_msg(&msg, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, 277 sizeof(msg), 0, 0, MACH_MSG_TIMEOUT_NONE, 0); 278 279 // DDD: This is reached sometimes on none/tests/manythreads, maybe 280 // because of the race above. 281 VG_(core_panic)("Thread exit failed?\n"); 282 } 283 284 /*NOTREACHED*/ 285 vg_assert(0); 286 } 287 288 289 /* Allocate a stack for the main thread, and run it all the way to the 290 end. Although we already have a working VgStack 291 (VG_(interim_stack)) it's better to allocate a new one, so that 292 overflow detection works uniformly for all threads. 293 */ 294 void VG_(main_thread_wrapper_NORETURN)(ThreadId tid) 295 { 296 Addr sp; 297 VG_(debugLog)(1, "syswrap-darwin", 298 "entering VG_(main_thread_wrapper_NORETURN)\n"); 299 300 sp = allocstack(tid); 301 302 /* If we can't even allocate the first thread's stack, we're hosed. 303 Give up. */ 304 vg_assert2(sp != 0, "Cannot allocate main thread's stack."); 305 306 /* shouldn't be any other threads around yet */ 307 vg_assert( VG_(count_living_threads)() == 1 ); 308 309 call_on_new_stack_0_1( 310 (Addr)sp, /* stack */ 311 0, /*bogus return address*/ 312 run_a_thread_NORETURN, /* fn to call */ 313 (Word)tid /* arg to give it */ 314 ); 315 316 /*NOTREACHED*/ 317 vg_assert(0); 318 } 319 320 321 void start_thread_NORETURN ( Word arg ) 322 { 323 ThreadState* tst = (ThreadState*)arg; 324 ThreadId tid = tst->tid; 325 326 run_a_thread_NORETURN ( (Word)tid ); 327 /*NOTREACHED*/ 328 vg_assert(0); 329 } 330 331 332 void VG_(cleanup_thread) ( ThreadArchState* arch ) 333 { 334 } 335 336 337 /* --------------------------------------------------------------------- 338 Message reporting, with duplicate removal 339 ------------------------------------------------------------------ */ 340 341 static WordFM* decaying_string_table = NULL; /* HChar* -> UWord */ 342 343 static Word decaying_string_table_cmp ( UWord s1, UWord s2 ) { 344 return (Word)VG_(strcmp)( (HChar*)s1, (HChar*)s2 ); 345 } 346 347 static void log_decaying ( const HChar* format, ... ) PRINTF_CHECK(1, 2); 348 static void log_decaying ( const HChar* format, ... ) 349 { 350 // get the message into a stack-allocated string. 351 HChar buf[256]; 352 VG_(memset)(buf, 0, sizeof(buf)); 353 va_list vargs; 354 va_start(vargs,format); 355 (void) VG_(vsnprintf)(buf, sizeof(buf), format, vargs); 356 va_end(vargs); 357 buf[sizeof(buf)-1] = 0; 358 359 // Now see if it already exists in the table of strings that we have. 360 if (!decaying_string_table) { 361 decaying_string_table 362 = VG_(newFM)( VG_(malloc), "syswrap-darwin.pd.1", 363 VG_(free), decaying_string_table_cmp ); 364 } 365 366 const HChar* key = NULL; 367 UWord val = 0; 368 if (!VG_(lookupFM)(decaying_string_table, 369 (UWord*)&key, &val, (UWord)&buf[0])) { 370 // We haven't seen this string before, so strdup it and add 371 // it to the table. 372 vg_assert(key == NULL && val == 0); 373 key = VG_(strdup)("syswrap-darwin.pd.2", buf); 374 VG_(addToFM)(decaying_string_table, (UWord)key, (UWord)0); 375 } 376 377 vg_assert(key != NULL && key != &buf[0]); 378 379 // So, finally, |key| is in the tree, and |val| is what it is 380 // currently associated with. Increment that counter. 381 val++; 382 Bool b = VG_(addToFM)(decaying_string_table, (UWord)key, (UWord)val); 383 vg_assert(b); 384 385 if (-1 != VG_(log2)( (UInt)val )) { 386 if (val == 1) 387 VG_(dmsg)("%s\n", key); 388 else 389 VG_(dmsg)("%s (repeated %lu times)\n", key, val); 390 } 391 } 392 393 394 /* --------------------------------------------------------------------- 395 Mach port tracking (based on syswrap-generic's fd tracker) 396 ------------------------------------------------------------------ */ 397 398 /* One of these is allocated for each open port. */ 399 typedef struct OpenPort 400 { 401 mach_port_t port; 402 mach_port_type_t type; /* right type(s) */ 403 Int send_count; /* number of send rights */ 404 HChar *name; /* bootstrap name or NULL */ 405 ExeContext *where; /* first allocation only */ 406 struct OpenPort *next, *prev; 407 } OpenPort; 408 409 // strlen("0x12345678") 410 #define PORT_STRLEN (2+2*sizeof(mach_port_t)) 411 412 /* List of allocated ports. */ 413 static OpenPort *allocated_ports; 414 415 /* Count of open ports. */ 416 static Int allocated_port_count = 0; 417 418 /* Create an entry for |port|, with no other info. Assumes it doesn't 419 already exist. */ 420 static void port_create_vanilla(mach_port_t port) 421 { 422 OpenPort* op 423 = VG_(calloc)("syswrap-darwin.port_create_vanilla", sizeof(OpenPort), 1); 424 op->port = port; 425 /* Add it to the list. */ 426 op->next = allocated_ports; 427 if (allocated_ports) allocated_ports->prev = op; 428 allocated_ports = op; 429 allocated_port_count++; 430 } 431 432 __attribute__((unused)) 433 static Bool port_exists(mach_port_t port) 434 { 435 OpenPort *i; 436 437 /* Check to see if this port is already open. */ 438 i = allocated_ports; 439 while (i) { 440 if (i->port == port) { 441 return True; 442 } 443 i = i->next; 444 } 445 446 return False; 447 } 448 449 static OpenPort *info_for_port(mach_port_t port) 450 { 451 OpenPort *i; 452 if (!port) return NULL; 453 454 i = allocated_ports; 455 while (i) { 456 if (i->port == port) { 457 return i; 458 } 459 i = i->next; 460 } 461 462 return NULL; 463 } 464 465 466 // Give a port a name, without changing its refcount 467 // GrP fixme don't override name if it already has a specific one 468 __private_extern__ void assign_port_name(mach_port_t port, const HChar *name) 469 { 470 OpenPort *i; 471 if (!port) return; 472 vg_assert(name); 473 474 i = info_for_port(port); 475 vg_assert(i); 476 477 if (i->name) VG_(free)(i->name); 478 i->name = 479 VG_(malloc)("syswrap-darwin.mach-port-name", 480 VG_(strlen)(name) + PORT_STRLEN + 1); 481 VG_(sprintf)(i->name, name, port); 482 } 483 484 485 // Return the name of the given port or "UNKNOWN 0x1234" if not known. 486 static const HChar *name_for_port(mach_port_t port) 487 { 488 static HChar buf[8 + PORT_STRLEN + 1]; 489 OpenPort *i; 490 491 // hack 492 if (port == VG_(gettid)()) return "mach_thread_self()"; 493 if (port == 0) return "NULL"; 494 495 i = allocated_ports; 496 while (i) { 497 if (i->port == port) { 498 return i->name; 499 } 500 i = i->next; 501 } 502 503 VG_(sprintf)(buf, "NONPORT-%#x", port); 504 return buf; 505 } 506 507 /* Note the fact that a port was just deallocated. */ 508 509 static 510 void record_port_mod_refs(mach_port_t port, mach_port_type_t right, Int delta) 511 { 512 OpenPort *i = allocated_ports; 513 if (!port) return; 514 515 while(i) { 516 if(i->port == port) { 517 vg_assert(right != MACH_PORT_TYPE_DEAD_NAME); 518 if (right & MACH_PORT_TYPE_SEND) { 519 // send rights are refcounted 520 if (delta == INT_MIN) delta = -i->send_count; // INT_MIN == destroy 521 i->send_count += delta; 522 if (i->send_count > 0) i->type |= MACH_PORT_TYPE_SEND; 523 else i->type &= ~MACH_PORT_TYPE_SEND; 524 } 525 right = right & ~MACH_PORT_TYPE_SEND; 526 if (right) { 527 // other rights are not refcounted 528 if (delta > 0) { 529 i->type |= right; 530 } else if (delta < 0) { 531 i->type &= ~right; 532 } 533 } 534 535 if (i->type != 0) return; 536 537 // Port has no rights left. Kill it. 538 // VG_(printf)("deleting port %p %s", i->port, i->name); 539 if(i->prev) 540 i->prev->next = i->next; 541 else 542 allocated_ports = i->next; 543 if(i->next) 544 i->next->prev = i->prev; 545 if(i->name) 546 VG_(free) (i->name); 547 VG_(free) (i); 548 allocated_port_count--; 549 return; 550 } 551 i = i->next; 552 } 553 554 VG_(printf)("UNKNOWN Mach port modified (port %#x delta %d)\n", port, delta); 555 } 556 557 static 558 void record_port_insert_rights(mach_port_t port, mach_msg_type_name_t type) 559 { 560 switch (type) { 561 case MACH_MSG_TYPE_PORT_NAME: 562 // this task has no rights for the name 563 break; 564 case MACH_MSG_TYPE_PORT_RECEIVE: 565 // this task gets receive rights 566 record_port_mod_refs(port, MACH_PORT_TYPE_RECEIVE, 1); 567 break; 568 case MACH_MSG_TYPE_PORT_SEND: 569 // this task gets a send right 570 record_port_mod_refs(port, MACH_PORT_TYPE_SEND, 1); 571 break; 572 case MACH_MSG_TYPE_PORT_SEND_ONCE: 573 // this task gets send-once rights 574 record_port_mod_refs(port, MACH_PORT_TYPE_SEND_ONCE, 1); 575 break; 576 default: 577 vg_assert(0); 578 break; 579 } 580 } 581 582 static 583 void record_port_dealloc(mach_port_t port) 584 { 585 // deletes 1 send or send-once right (port can't have both) 586 record_port_mod_refs(port, MACH_PORT_TYPE_SEND_RIGHTS, -1); 587 } 588 589 static 590 void record_port_destroy(mach_port_t port) 591 { 592 // deletes all rights to port 593 record_port_mod_refs(port, MACH_PORT_TYPE_ALL_RIGHTS, INT_MIN); 594 } 595 596 597 /* Note the fact that a Mach port was just allocated or transferred. 598 If the port is already known, increment its reference count. */ 599 void record_named_port(ThreadId tid, mach_port_t port, 600 mach_port_right_t right, const HChar *name) 601 { 602 OpenPort *i; 603 if (!port) return; 604 605 /* Check to see if this port is already open. */ 606 i = allocated_ports; 607 while (i) { 608 if (i->port == port) { 609 if (right != -1) record_port_mod_refs(port, MACH_PORT_TYPE(right), 1); 610 return; 611 } 612 i = i->next; 613 } 614 615 /* Not already one: allocate an OpenPort */ 616 if (i == NULL) { 617 i = VG_(malloc)("syswrap-darwin.mach-port", sizeof(OpenPort)); 618 619 i->prev = NULL; 620 i->next = allocated_ports; 621 if(allocated_ports) allocated_ports->prev = i; 622 allocated_ports = i; 623 allocated_port_count++; 624 625 i->port = port; 626 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid, 0); 627 i->name = NULL; 628 if (right != -1) { 629 i->type = MACH_PORT_TYPE(right); 630 i->send_count = (right == MACH_PORT_RIGHT_SEND) ? 1 : 0; 631 } else { 632 i->type = 0; 633 i->send_count = 0; 634 } 635 636 assign_port_name(port, name); 637 } 638 } 639 640 641 // Record opening of a nameless port. 642 static void record_unnamed_port(ThreadId tid, mach_port_t port, mach_port_right_t right) 643 { 644 record_named_port(tid, port, right, "unnamed-%p"); 645 } 646 647 648 /* Dump summary of open Mach ports, like VG_(show_open_fds) */ 649 void VG_(show_open_ports)(void) 650 { 651 OpenPort *i; 652 653 VG_(message)(Vg_UserMsg, 654 "MACH PORTS: %d open at exit.\n", allocated_port_count); 655 656 for (i = allocated_ports; i; i = i->next) { 657 if (i->name) { 658 VG_(message)(Vg_UserMsg, "Open Mach port 0x%x: %s\n", i->port, 659 i->name); 660 } else { 661 VG_(message)(Vg_UserMsg, "Open Mach port 0x%x\n", i->port); 662 } 663 664 if (i->where) { 665 VG_(pp_ExeContext)(i->where); 666 VG_(message)(Vg_UserMsg, "\n"); 667 } 668 } 669 670 VG_(message)(Vg_UserMsg, "\n"); 671 } 672 673 674 /* --------------------------------------------------------------------- 675 sync_mappings 676 ------------------------------------------------------------------ */ 677 678 typedef 679 enum { CheckAlways=1, CheckEvery20, CheckNever } 680 CheckHowOften; 681 682 static const HChar* show_CheckHowOften ( CheckHowOften cho ) { 683 switch (cho) { 684 case CheckAlways: return "Always "; 685 case CheckEvery20: return "Every20"; 686 case CheckNever: return "Never "; 687 default: vg_assert(0); 688 } 689 } 690 691 /* Statistics for one particular resync-call set of arguments, 692 as specified by key1, key2 and key3. */ 693 typedef 694 struct { 695 CheckHowOften cho; 696 const HChar* key1; 697 const HChar* key2; 698 UWord key3; 699 ULong n_checks; 700 ULong n_mappings_added; 701 ULong n_mappings_removed; 702 } 703 SyncStats; 704 705 static Bool cmp_eqkeys_SyncStats ( SyncStats* ss1, SyncStats* ss2 ) { 706 return ss1->key3 == ss2->key3 707 && 0 == VG_(strcmp)(ss1->key1, ss2->key1) 708 && 0 == VG_(strcmp)(ss1->key2, ss2->key2); 709 } 710 711 /* The filter data. */ 712 #define N_SYNCSTATS 1000 713 static Int syncstats_used = 0; 714 static SyncStats syncstats[N_SYNCSTATS]; 715 716 /* Statistics overall, for the filter. */ 717 static ULong n_syncsRequested = 0; // Total number requested 718 static ULong n_syncsPerformed = 0; // Number carried out (the rest skipped) 719 720 721 static 722 void update_syncstats ( CheckHowOften cho, 723 const HChar* key1, const HChar* key2, 724 UWord key3, 725 UInt n_mappings_added, UInt n_mappings_removed ) 726 { 727 SyncStats dummy = { CheckAlways, key1, key2, key3, 0, 0, 0 }; 728 Int i; 729 for (i = 0; i < syncstats_used; i++) { 730 if (cmp_eqkeys_SyncStats(&syncstats[i], &dummy)) 731 break; 732 } 733 vg_assert(i >= 0 && i <= syncstats_used); 734 if (i == syncstats_used) { 735 // alloc new 736 vg_assert(syncstats_used < N_SYNCSTATS); 737 syncstats_used++; 738 syncstats[i] = dummy; 739 syncstats[i].cho = cho; 740 } 741 vg_assert(cmp_eqkeys_SyncStats(&syncstats[i], &dummy)); 742 syncstats[i].n_checks++; 743 syncstats[i].n_mappings_added += (ULong)n_mappings_added; 744 syncstats[i].n_mappings_removed += (ULong)n_mappings_removed; 745 // reorder 746 static UInt reorder_ctr = 0; 747 if (i > 0 && 0 == (1 & reorder_ctr++)) { 748 SyncStats tmp = syncstats[i-1]; 749 syncstats[i-1] = syncstats[i]; 750 syncstats[i] = tmp; 751 } 752 } 753 754 755 static void maybe_show_syncstats ( void ) 756 { 757 Int i; 758 759 // display 760 if (0 == (n_syncsRequested & 0xFF)) { 761 VG_(printf)("Resync filter: %'llu requested, %'llu performed (%llu%%)\n", 762 n_syncsRequested, n_syncsPerformed, 763 (100 * n_syncsPerformed) / 764 (n_syncsRequested == 0 ? 1 : n_syncsRequested)); 765 for (i = 0; i < syncstats_used; i++) { 766 if (i >= 40) break; // just show the top 40 767 VG_(printf)(" [%3d] (%s) upd %6llu diff %4llu+,%3llu-" 768 " %s %s 0x%08llx\n", 769 i, show_CheckHowOften(syncstats[i].cho), 770 syncstats[i].n_checks, 771 syncstats[i].n_mappings_added, 772 syncstats[i].n_mappings_removed, 773 syncstats[i].key1, syncstats[i].key2, 774 (ULong)syncstats[i].key3); 775 } 776 if (i < syncstats_used) { 777 VG_(printf)(" and %d more entries not shown.\n", syncstats_used - i); 778 } 779 VG_(printf)("\n"); 780 } 781 } 782 783 784 Bool ML_(sync_mappings)(const HChar* when, const HChar* where, UWord num) 785 { 786 // If VG(clo_resync_filter) == 0, the filter is disabled, and 787 // we must always honour the resync request. 788 // 789 // If VG(clo_resync_filter) == 1, the filter is enabled, 790 // so we try to avoid doing the sync if possible, but keep 791 // quiet. 792 // 793 // If VG(clo_resync_filter) == 2, the filter is enabled, 794 // so we try to avoid doing the sync if possible, and also 795 // periodically show stats, so that the filter can be updated. 796 // (by hand). 797 798 if (VG_(clo_resync_filter) >= 2) 799 maybe_show_syncstats(); 800 801 n_syncsRequested++; 802 803 // Usually the number of segments added/removed in a single call is very 804 // small e.g. 1. But it sometimes gets up to at least 100 or so (eg. for 805 // Quicktime). So we use a repeat-with-bigger-buffers-until-success model, 806 // because we can't do dynamic allocation within VG_(get_changed_segments), 807 // because it's in m_aspacemgr. 808 ChangedSeg* css = NULL; 809 Int css_size; 810 Int css_used; 811 Int i; 812 Bool ok; 813 814 // -------------- BEGIN resync-filter-kludge -------------- 815 // 816 // Some kludges to try and avoid the worst case cost hit of doing 817 // zillions of resyncs (huge). The idea is that many of the most 818 // common resyncs never appear to cause a delta, so we just ignore 819 // them (CheckNever). Then, a bunch of them also happen a lot, but 820 // only very occasionally cause a delta. We resync after 20 of those 821 // (CheckEvery20). Finally, the rest form a long tail, so we always 822 // resync after those (CheckAlways). 823 // 824 // Assume this is kernel-version and word-size specific, so develop 825 // filters accordingly. This might be overly conservative -- 826 // I don't know. 827 828 # define STREQ(_s1, _s2) (0 == VG_(strcmp)((_s1),(_s2))) 829 Bool when_in = STREQ(when, "in"); 830 Bool when_after = STREQ(when, "after"); 831 Bool where_mmr = STREQ(where, "mach_msg_receive"); 832 Bool where_mmrU = STREQ(where, "mach_msg_receive-UNHANDLED"); 833 Bool where_iuct = STREQ(where, "iokit_user_client_trap"); 834 Bool where_MwcN = STREQ(where, "ML_(wqthread_continue_NORETURN)"); 835 Bool where_woQR = STREQ(where, "workq_ops(QUEUE_REQTHREADS)"); 836 Bool where_woTR = STREQ(where, "workq_ops(THREAD_RETURN)"); 837 Bool where_ke64 = STREQ(where, "kevent64"); 838 # undef STREQ 839 840 vg_assert( 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_woTR ? 1 : 0) 844 + (where_ke64 ? 1 : 0) 845 )); 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); 850 851 CheckHowOften check = CheckAlways; 852 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>" 857 switch (num) { 858 case 0x00000000: // upd 12414 diff 36+,0- 859 check = CheckEvery20; 860 break; 861 default: 862 break; 863 } 864 } 865 else 866 if (when_after && where_mmrU) { 867 // "after mach_msg_receive-UNHANDLED <number>" 868 switch (num) { 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; 878 break; 879 default: 880 break; 881 } 882 } 883 else 884 if (when_in && where_MwcN && num == 0x00000000) { 885 // in ML_(wqthread_continue_NORETURN) 0x00000000 886 // upd 4346 diff 0+,0- 887 check = CheckEvery20; 888 } 889 else 890 if (when_after && where_woQR && num == 0x00000000) { 891 // after workq_ops(QUEUE_REQTHREADS) 0x00000000 892 // upd 14434 diff 102+,0- 893 check = CheckEvery20; 894 } 895 else 896 if (when_after && where_woTR && num == 0x00000000) { 897 // after workq_ops(THREAD_RETURN) 0x00000000 898 // upd 14434 diff 102+,0- 899 check = CheckEvery20; 900 } 901 else 902 if (when_after && where_ke64 && num == 0x00000000) { 903 // after kevent64 0x00000000 904 // upd 1736 diff 78+,0- 905 check = CheckEvery20; 906 } 907 /* ----------- END filter for 64-bit 10.9.x ----------- */ 908 # endif /* DARWIN_VERS == DARWIN_10_9 && VG_WORDSIZE == 8 */ 909 910 # if DARWIN_VERS == DARWIN_10_10 && VG_WORDSIZE == 8 911 /* ---------- BEGIN filter for 64-bit 10.10.x ---------- */ 912 if (when_after && where_mmr) { 913 // "after mach_msg_receive <number>" 914 switch (num) { 915 case 0x00000000: // upd 2380 diff 23+,0- 916 check = CheckEvery20; 917 break; 918 default: 919 break; 920 } 921 } 922 else 923 if (when_after && where_mmrU) { 924 // "after mach_msg_receive-UNHANDLED <number>" 925 switch (num) { 926 case 0x00000000: // upd 2370 diff 93+,1- <==dangerous 927 case 0x0000004f: // upd 212 diff 2+,0- 928 case 0x00000b95: // upd 9826 diff 163+,1- diff scale, dangerous 929 case 0x00000ba5: // upd 304 diff 0+,0- 930 case 0x0000157f: // upd 201 diff 2+,0- 931 case 0x0000157d: // upd 197 diff 1+,0- 932 case 0x0000333d: // upd 112 diff 0+,0- 933 case 0x0000333f: // upd 223 diff 10+,0- 934 case 0x000072cd: // upd 8286 diff 98+,0- diff scale 935 case 0x000072ae: // upd 193 diff 10+,0- 936 case 0x000072ec: // upd 319 diff 7+,0- 937 case 0x77303074: // upd 113 diff 3+,0- 938 case 0x10000000: // upd 314 diff 6+,0- 939 check = CheckEvery20; 940 break; 941 default: 942 break; 943 } 944 } 945 else 946 if (when_in && where_MwcN && num == 0x00000000) { 947 // in ML_(wqthread_continue_NORETURN) 0x00000000 948 // upd 1110 diff 37+,0- 949 check = CheckEvery20; 950 } 951 else 952 if (when_after && where_woQR && num == 0x00000000) { 953 // after workq_ops(QUEUE_REQTHREADS) 0x00000000 954 // upd 1099 diff 37+,0- 955 check = CheckEvery20; 956 } 957 else 958 if (when_after && where_woTR && num == 0x00000000) { 959 // after workq_ops(THREAD_RETURN) 0x00000000 960 // 1239 diff 53+,0- 961 check = CheckEvery20; 962 } 963 else 964 if (when_after && where_ke64 && num == 0x00000000) { 965 // after kevent64 0x00000000 966 // upd 1463 diff 15+,0- 967 check = CheckEvery20; 968 } 969 /* ----------- END filter for 64-bit 10.10.x ----------- */ 970 # endif /* DARWIN_VERS == DARWIN_10_10 && VG_WORDSIZE == 8 */ 971 972 /* Regardless of what the filter says, force a sync every 1 time in 973 1000, to stop things getting too far out of sync. */ 974 { 975 static UInt ctr1k = 0; 976 ctr1k++; 977 if ((ctr1k % 1000) == 0) 978 check = CheckAlways; 979 } 980 981 /* If the filter is disabled, we must always check. */ 982 if (VG_(clo_resync_filter) == 0) 983 check = CheckAlways; 984 985 switch (check) { 986 case CheckAlways: 987 break; 988 case CheckEvery20: { 989 // only resync once every 20th time 990 static UInt ctr10 = 0; 991 ctr10++; 992 if ((ctr10 % 20) != 0) return False; 993 break; 994 } 995 case CheckNever: 996 return False; 997 default: 998 vg_assert(0); 999 } 1000 // 1001 // --------------- END resync-filter-kludge --------------- 1002 1003 if (0 || VG_(clo_trace_syscalls)) { 1004 VG_(debugLog)(0, "syswrap-darwin", 1005 "sync_mappings (%s) (\"%s\", \"%s\", 0x%lx)\n", 1006 show_CheckHowOften(check), when, where, num); 1007 } 1008 1009 // 16 is enough for most cases, but small enough that overflow happens 1010 // occasionally and thus the overflow path gets some test coverage. 1011 css_size = 16; 1012 ok = False; 1013 while (!ok) { 1014 VG_(free)(css); // css is NULL on first iteration; that's ok. 1015 css = VG_(calloc)("sys_wrap.sync_mappings", 1016 css_size, sizeof(ChangedSeg)); 1017 ok = VG_(get_changed_segments)(when, where, css, css_size, &css_used); 1018 css_size *= 2; 1019 } 1020 1021 UInt css_added = 0, css_removed = 0; 1022 1023 // Now add/remove them. 1024 for (i = 0; i < css_used; i++) { 1025 ChangedSeg* cs = &css[i]; 1026 if (cs->is_added) { 1027 css_added++; 1028 ML_(notify_core_and_tool_of_mmap)( 1029 cs->start, cs->end - cs->start + 1, 1030 cs->prot, VKI_MAP_PRIVATE, 0, cs->offset); 1031 // should this call VG_(di_notify_mmap) also? 1032 } else { 1033 css_removed++; 1034 ML_(notify_core_and_tool_of_munmap)( 1035 cs->start, cs->end - cs->start + 1); 1036 } 1037 if (VG_(clo_trace_syscalls)) { 1038 if (cs->is_added) { 1039 VG_(debugLog)(0, "syswrap-darwin", 1040 " added region 0x%010lx..0x%010lx prot %u at %s (%s)\n", 1041 cs->start, cs->end + 1, (UInt)cs->prot, where, when); 1042 } else { 1043 VG_(debugLog)(0, "syswrap-darwin", 1044 " removed region 0x%010lx..0x%010lx at %s (%s)\n", 1045 cs->start, cs->end + 1, where, when); 1046 } 1047 } 1048 } 1049 1050 VG_(free)(css); 1051 1052 if (0) 1053 VG_(debugLog)(0, "syswrap-darwin", "SYNC: %d %s %s\n", 1054 css_used, when, where); 1055 1056 // Update the stats, so we can derive the filter above. 1057 n_syncsPerformed++; 1058 update_syncstats(check, when, where, num, css_added, css_removed); 1059 1060 return css_used > 0; 1061 } 1062 1063 /* --------------------------------------------------------------------- 1064 wrappers 1065 ------------------------------------------------------------------ */ 1066 1067 #define PRE(name) DEFN_PRE_TEMPLATE(darwin, name) 1068 #define POST(name) DEFN_POST_TEMPLATE(darwin, name) 1069 1070 #define PRE_FN(name) vgSysWrap_darwin_##name##_before 1071 #define POST_FN(name) vgSysWrap_darwin_##name##_after 1072 1073 #define CALL_PRE(name) PRE_FN(name)(tid, layout, arrghs, status, flags) 1074 #define CALL_POST(name) POST_FN(name)(tid, arrghs, status) 1075 1076 #if VG_WORDSIZE == 4 1077 // Combine two 32-bit values into a 64-bit value 1078 // Always use with low-numbered arg first (e.g. LOHI64(ARG1,ARG2) ) 1079 # if defined(VGA_x86) 1080 # define LOHI64(lo,hi) ( ((ULong)(UInt)(lo)) | (((ULong)(UInt)(hi)) << 32) ) 1081 # else 1082 # error unknown architecture 1083 # endif 1084 #endif 1085 1086 // Retrieve the current Mach thread 1087 #define MACH_THREAD ((Addr)VG_(get_ThreadState)(tid)->os_state.lwpid) 1088 1089 // Set the POST handler for a mach_msg derivative 1090 #define AFTER VG_(get_ThreadState)(tid)->os_state.post_mach_trap_fn 1091 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 1096 1097 /* --------------------------------------------------------------------- 1098 darwin ioctl wrapper 1099 ------------------------------------------------------------------ */ 1100 1101 PRE(ioctl) 1102 { 1103 *flags |= SfMayBlock; 1104 1105 /* Handle ioctls that don't take an arg first */ 1106 switch (ARG2 /* request */) { 1107 case VKI_TIOCSCTTY: 1108 case VKI_TIOCEXCL: 1109 case VKI_TIOCSBRK: 1110 case VKI_TIOCCBRK: 1111 case VKI_TIOCPTYGRANT: 1112 case VKI_TIOCPTYUNLK: 1113 case VKI_DTRACEHIOC_REMOVE: 1114 case VKI_BIOCFLUSH: 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); 1119 return; 1120 default: 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); 1124 } 1125 1126 switch (ARG2 /* request */) { 1127 case VKI_TIOCGWINSZ: 1128 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) ); 1129 break; 1130 case VKI_TIOCSWINSZ: 1131 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) ); 1132 break; 1133 case VKI_TIOCMBIS: 1134 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) ); 1135 break; 1136 case VKI_TIOCMBIC: 1137 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) ); 1138 break; 1139 case VKI_TIOCMSET: 1140 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) ); 1141 break; 1142 case VKI_TIOCMGET: 1143 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) ); 1144 break; 1145 case VKI_TIOCGPGRP: 1146 /* Get process group ID for foreground processing group. */ 1147 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) ); 1148 break; 1149 case VKI_TIOCSPGRP: 1150 /* Set a process group ID? */ 1151 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) ); 1152 break; 1153 case VKI_FIONBIO: 1154 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) ); 1155 break; 1156 case VKI_FIOASYNC: 1157 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) ); 1158 break; 1159 case VKI_FIONREAD: /* identical to SIOCINQ */ 1160 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) ); 1161 break; 1162 1163 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)); 1170 break; 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)); 1175 break; 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)); 1180 break; 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)); 1185 break; 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)); 1190 break; 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)); 1195 break; 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)); 1200 break; 1201 case VKI_SIOCGIFCONF: /* get iface list */ 1202 /* WAS: 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)); 1207 */ 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)); 1214 if ( ARG3 ) { 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 ); 1220 } 1221 break; 1222 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) ); 1229 break; 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) ); 1239 break; 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) ); 1246 break; 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) ); 1253 break; 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)); 1260 break; 1261 #endif 1262 1263 case VKI_SIOCGPGRP: 1264 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) ); 1265 break; 1266 case VKI_SIOCSPGRP: 1267 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) ); 1268 //tst->sys_flags &= ~SfMayBlock; 1269 break; 1270 1271 case VKI_FIODTYPE: 1272 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) ); 1273 break; 1274 1275 case VKI_DTRACEHIOC_ADDDOF: 1276 break; 1277 1278 // ttycom.h 1279 case VKI_TIOCGETA: 1280 PRE_MEM_WRITE( "ioctl(TIOCGETA)", ARG3, sizeof(struct vki_termios) ); 1281 break; 1282 case VKI_TIOCSETA: 1283 PRE_MEM_READ( "ioctl(TIOCSETA)", ARG3, sizeof(struct vki_termios) ); 1284 break; 1285 case VKI_TIOCGETD: 1286 PRE_MEM_WRITE( "ioctl(TIOCGETD)", ARG3, sizeof(int) ); 1287 break; 1288 case VKI_TIOCSETD: 1289 PRE_MEM_READ( "ioctl(TIOCSETD)", ARG3, sizeof(int) ); 1290 break; 1291 case VKI_TIOCPTYGNAME: 1292 PRE_MEM_WRITE( "ioctl(TIOCPTYGNAME)", ARG3, 128 ); 1293 break; 1294 1295 // filio.h 1296 case VKI_FIOCLEX: 1297 break; 1298 case VKI_FIONCLEX: 1299 break; 1300 1301 // net/bpf.h 1302 case VKI_BIOCSETF: /* set BPF filter */ 1303 /* 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. 1307 * 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. 1310 * 1311 * We then make sure that what bf_insns points to is valid. 1312 */ 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) ); 1319 if ( ARG3 ) { 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) ); 1326 } 1327 break; 1328 case VKI_BIOCSETIF: /* set BPF interface */ 1329 PRE_MEM_RASCIIZ( "ioctl(BIOCSETIF)", 1330 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name ); 1331 break; 1332 case VKI_BIOCSRTIMEOUT: /* set BPF timeout */ 1333 /* 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. 1338 * 1339 * So that we don't bogusly complain about the padding bytes, 1340 * we just report that we read tv_sec and tv_usec. 1341 */ 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) ); 1348 break; 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) ); 1353 if ( ARG3 ) { 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) ); 1363 } 1364 break; 1365 1366 default: 1367 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3); 1368 break; 1369 } 1370 } 1371 1372 1373 POST(ioctl) 1374 { 1375 vg_assert(SUCCESS); 1376 switch (ARG2 /* request */) { 1377 case VKI_TIOCGWINSZ: 1378 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) ); 1379 break; 1380 case VKI_TIOCSWINSZ: 1381 case VKI_TIOCMBIS: 1382 case VKI_TIOCMBIC: 1383 case VKI_TIOCMSET: 1384 break; 1385 case VKI_TIOCMGET: 1386 POST_MEM_WRITE( ARG3, sizeof(unsigned int) ); 1387 break; 1388 case VKI_TIOCGPGRP: 1389 /* Get process group ID for foreground processing group. */ 1390 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) ); 1391 break; 1392 case VKI_TIOCSPGRP: 1393 /* Set a process group ID? */ 1394 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) ); 1395 break; 1396 case VKI_TIOCSCTTY: 1397 break; 1398 case VKI_FIONBIO: 1399 break; 1400 case VKI_FIOASYNC: 1401 break; 1402 case VKI_FIONREAD: /* identical to SIOCINQ */ 1403 POST_MEM_WRITE( ARG3, sizeof(int) ); 1404 break; 1405 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) ); 1410 break; 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) ); 1414 break; 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 */ 1419 POST_MEM_WRITE( 1420 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr, 1421 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) ); 1422 break; 1423 case VKI_SIOCGIFMETRIC: /* get metric */ 1424 POST_MEM_WRITE( 1425 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric, 1426 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) ); 1427 break; 1428 case VKI_SIOCGIFCONF: /* get iface list */ 1429 /* WAS: 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)); 1434 */ 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 ); 1439 } 1440 break; 1441 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 */ 1449 break; 1450 1451 #ifdef VKI_SIOCADDRT 1452 /* Routing table calls. */ 1453 case VKI_SIOCADDRT: /* add routing table entry */ 1454 case VKI_SIOCDELRT: /* delete routing table entry */ 1455 break; 1456 #endif 1457 1458 case VKI_SIOCGPGRP: 1459 POST_MEM_WRITE(ARG3, sizeof(int)); 1460 break; 1461 case VKI_SIOCSPGRP: 1462 break; 1463 1464 case VKI_FIODTYPE: 1465 POST_MEM_WRITE( ARG3, sizeof(int) ); 1466 break; 1467 1468 case VKI_DTRACEHIOC_REMOVE: 1469 case VKI_DTRACEHIOC_ADDDOF: 1470 break; 1471 1472 // ttycom.h 1473 case VKI_TIOCGETA: 1474 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios)); 1475 break; 1476 case VKI_TIOCSETA: 1477 break; 1478 case VKI_TIOCGETD: 1479 POST_MEM_WRITE( ARG3, sizeof(int) ); 1480 break; 1481 case VKI_TIOCSETD: 1482 break; 1483 case VKI_TIOCPTYGNAME: 1484 POST_MEM_WRITE( ARG3, 128); 1485 break; 1486 case VKI_TIOCSBRK: /* set break bit */ 1487 case VKI_TIOCCBRK: /* clear break bit */ 1488 case VKI_TIOCPTYGRANT: 1489 case VKI_TIOCPTYUNLK: 1490 break; 1491 1492 // bpf.h 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) ); 1500 } 1501 break; 1502 1503 default: 1504 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3); 1505 break; 1506 } 1507 } 1508 1509 1510 /* --------------------------------------------------------------------- 1511 darwin fcntl wrapper 1512 ------------------------------------------------------------------ */ 1513 static const HChar *name_for_fcntl(UWord cmd) { 1514 #define F(n) case VKI_##n: return #n 1515 switch (cmd) { 1516 F(F_CHKCLEAN); 1517 F(F_RDAHEAD); 1518 F(F_NOCACHE); 1519 F(F_FULLFSYNC); 1520 F(F_FREEZE_FS); 1521 F(F_THAW_FS); 1522 F(F_GLOBAL_NOCACHE); 1523 F(F_PREALLOCATE); 1524 F(F_SETSIZE); 1525 F(F_RDADVISE); 1526 # if DARWIN_VERS < DARWIN_10_9 1527 F(F_READBOOTSTRAP); 1528 F(F_WRITEBOOTSTRAP); 1529 # endif 1530 F(F_LOG2PHYS); 1531 F(F_GETPATH); 1532 F(F_PATHPKG_CHECK); 1533 F(F_ADDSIGS); 1534 # if DARWIN_VERS >= DARWIN_10_9 1535 F(F_ADDFILESIGS); 1536 # endif 1537 # if DARWIN_VERS >= DARWIN_10_11 1538 F(F_ADDFILESIGS_FOR_DYLD_SIM); 1539 F(F_BARRIERFSYNC); 1540 F(F_ADDFILESIGS_RETURN); 1541 # endif 1542 default: 1543 return "UNKNOWN"; 1544 } 1545 #undef F 1546 } 1547 1548 PRE(fcntl) 1549 { 1550 switch (ARG2) { 1551 // These ones ignore ARG3. 1552 case VKI_F_GETFD: 1553 case VKI_F_GETFL: 1554 case VKI_F_GETOWN: 1555 PRINT("fcntl ( %lu, %lu )", ARG1,ARG2); 1556 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd); 1557 break; 1558 1559 // These ones use ARG3 as "arg". 1560 case VKI_F_DUPFD: 1561 case VKI_F_SETFD: 1562 case VKI_F_SETFL: 1563 case VKI_F_SETOWN: 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); 1567 break; 1568 1569 // These ones use ARG3 as "lock". 1570 case VKI_F_GETLK: 1571 case VKI_F_SETLK: 1572 case VKI_F_SETLKW: 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; 1580 break; 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; 1588 break; 1589 # endif 1590 1591 // none 1592 case VKI_F_CHKCLEAN: 1593 case VKI_F_RDAHEAD: 1594 case VKI_F_NOCACHE: 1595 case VKI_F_FULLFSYNC: 1596 case VKI_F_FREEZE_FS: 1597 case VKI_F_THAW_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); 1601 break; 1602 1603 // struct fstore 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); 1609 { 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); 1621 } 1622 break; 1623 1624 // off_t 1625 case VKI_F_SETSIZE: 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); 1630 break; 1631 1632 // struct radvisory 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); 1638 { 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 ); 1644 } 1645 break; 1646 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) ); 1657 break; 1658 # endif 1659 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) ); 1668 break; 1669 1670 // char[maxpathlen] (out) 1671 case VKI_F_GETPATH: 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, 1675 char *, pathbuf); 1676 PRE_MEM_WRITE( "fcntl(F_GETPATH, pathbuf)", 1677 ARG3, VKI_MAXPATHLEN ); 1678 break; 1679 1680 // char[maxpathlen] (in) 1681 case VKI_F_PATHPKG_CHECK: 1682 PRINT("fcntl ( %lu, %s, %#lx '%s')", ARG1, name_for_fcntl(ARG2), ARG3, 1683 (HChar *)ARG3); 1684 PRE_REG_READ3(long, "fcntl", 1685 unsigned int, fd, unsigned int, cmd, 1686 char *, pathbuf); 1687 PRE_MEM_RASCIIZ( "fcntl(F_PATHPKG_CHECK, pathbuf)", ARG3); 1688 break; 1689 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); 1695 1696 { 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); 1702 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); 1706 } 1707 break; 1708 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); 1714 1715 { 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); 1721 } 1722 break; 1723 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 */ 1727 // FIXME: RK 1728 break; 1729 1730 case VKI_F_BARRIERFSYNC: /* fsync + issue barrier to drive */ 1731 // FIXME: RK 1732 break; 1733 1734 case VKI_F_ADDFILESIGS_RETURN: /* Add signature from same file, return end offset in 1735 structure on success */ 1736 // FIXME: RK 1737 break; 1738 # endif 1739 1740 default: 1741 PRINT("fcntl ( %lu, %lu [??] )", ARG1, ARG2); 1742 log_decaying("UNKNOWN fcntl %lu!", ARG2); 1743 break; 1744 } 1745 } 1746 1747 POST(fcntl) 1748 { 1749 vg_assert(SUCCESS); 1750 switch (ARG2) { 1751 case VKI_F_DUPFD: 1752 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) { 1753 VG_(close)(RES); 1754 SET_STATUS_Failure( VKI_EMFILE ); 1755 } else { 1756 if (VG_(clo_track_fds)) 1757 ML_(record_fd_open_named)(tid, RES); 1758 } 1759 break; 1760 1761 case VKI_F_GETFD: 1762 case VKI_F_GETFL: 1763 case VKI_F_GETOWN: 1764 case VKI_F_SETFD: 1765 case VKI_F_SETFL: 1766 case VKI_F_SETOWN: 1767 case VKI_F_GETLK: 1768 case VKI_F_SETLK: 1769 case VKI_F_SETLKW: 1770 # if DARWIN_VERS >= DARWIN_10_10 1771 case VKI_F_SETLKWTIMEOUT: 1772 break; 1773 # endif 1774 1775 case VKI_F_PREALLOCATE: 1776 { 1777 struct vki_fstore *fstore = (struct vki_fstore *)ARG3; 1778 POST_FIELD_WRITE( fstore->fst_bytesalloc ); 1779 } 1780 break; 1781 1782 case VKI_F_LOG2PHYS: 1783 POST_MEM_WRITE( ARG3, sizeof(struct vki_log2phys) ); 1784 break; 1785 1786 case VKI_F_GETPATH: 1787 POST_MEM_WRITE( ARG3, 1+VG_(strlen)((char *)ARG3) ); 1788 PRINT("\"%s\"", (char*)ARG3); 1789 break; 1790 1791 default: 1792 // DDD: ugh, missing lots of cases here, not nice 1793 break; 1794 } 1795 } 1796 1797 /* --------------------------------------------------------------------- 1798 unix syscalls 1799 ------------------------------------------------------------------ */ 1800 1801 PRE(futimes) 1802 { 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) ); 1810 } 1811 } 1812 1813 PRE(semget) 1814 { 1815 PRINT("semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3); 1816 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg); 1817 } 1818 1819 PRE(semop) 1820 { 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); 1826 } 1827 1828 PRE(semctl) 1829 { 1830 switch (ARG3) { 1831 case VKI_IPC_STAT: 1832 case VKI_IPC_SET: 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); 1836 break; 1837 case VKI_GETALL: 1838 case VKI_SETALL: 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); 1842 break; 1843 case VKI_SETVAL: 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); 1847 break; 1848 default: 1849 PRINT("semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3); 1850 PRE_REG_READ3(long, "semctl", 1851 int, semid, int, semnum, int, cmd); 1852 break; 1853 } 1854 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4); 1855 } 1856 POST(semctl) 1857 { 1858 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4); 1859 } 1860 1861 PRE(sem_open) 1862 { 1863 if (ARG2 & VKI_O_CREAT) { 1864 // 4-arg version 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); 1870 } else { 1871 // 2-arg version 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); 1875 } 1876 PRE_MEM_RASCIIZ( "sem_open(name)", ARG1 ); 1877 1878 /* Otherwise handle normally */ 1879 *flags |= SfMayBlock; 1880 } 1881 1882 PRE(sem_close) 1883 { 1884 PRINT("sem_close( %#lx )", ARG1); 1885 PRE_REG_READ1(int, "sem_close", vki_sem_t *, sem); 1886 } 1887 1888 PRE(sem_unlink) 1889 { 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 ); 1893 } 1894 1895 PRE(sem_post) 1896 { 1897 PRINT("sem_post( %#lx )", ARG1); 1898 PRE_REG_READ1(int, "sem_post", vki_sem_t *, sem); 1899 *flags |= SfMayBlock; 1900 } 1901 1902 PRE(sem_destroy) 1903 { 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)); 1907 } 1908 1909 PRE(sem_init) 1910 { 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)); 1915 } 1916 1917 POST(sem_init) 1918 { 1919 POST_MEM_WRITE(ARG1, sizeof(vki_sem_t)); 1920 } 1921 1922 PRE(sem_wait) 1923 { 1924 PRINT("sem_wait( %#lx )", ARG1); 1925 PRE_REG_READ1(int, "sem_wait", vki_sem_t *, sem); 1926 *flags |= SfMayBlock; 1927 } 1928 1929 PRE(sem_trywait) 1930 { 1931 PRINT("sem_trywait( %#lx )", ARG1); 1932 PRE_REG_READ1(int, "sem_trywait", vki_sem_t *, sem); 1933 *flags |= SfMayBlock; 1934 } 1935 1936 PRE(kqueue) 1937 { 1938 PRINT("kqueue()"); 1939 } 1940 1941 POST(kqueue) 1942 { 1943 if (!ML_(fd_allowed)(RES, "kqueue", tid, True)) { 1944 VG_(close)(RES); 1945 SET_STATUS_Failure( VKI_EMFILE ); 1946 } else { 1947 if (VG_(clo_track_fds)) { 1948 ML_(record_fd_open_with_given_name)(tid, RES, NULL); 1949 } 1950 } 1951 } 1952 1953 PRE(fileport_makeport) 1954 { 1955 PRINT("fileport_makeport(fd:%#lx, portnamep:%#lx) FIXME", 1956 ARG1, ARG2); 1957 } 1958 1959 PRE(guarded_open_np) 1960 { 1961 PRINT("guarded_open_np(path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx) FIXME", 1962 ARG1, (char*)ARG1, ARG2, ARG3, ARG4); 1963 } 1964 1965 PRE(guarded_kqueue_np) 1966 { 1967 PRINT("guarded_kqueue_np(guard:%#lx, guardflags:%#lx) FIXME", 1968 ARG1, ARG2); 1969 } 1970 1971 POST(guarded_kqueue_np) 1972 { 1973 if (!ML_(fd_allowed)(RES, "guarded_kqueue_np", tid, True)) { 1974 VG_(close)(RES); 1975 SET_STATUS_Failure( VKI_EMFILE ); 1976 } else { 1977 if (VG_(clo_track_fds)) { 1978 ML_(record_fd_open_with_given_name)(tid, RES, NULL); 1979 } 1980 } 1981 } 1982 1983 PRE(guarded_close_np) 1984 { 1985 PRINT("guarded_close_np(fd:%#lx, guard:%#lx) FIXME", 1986 ARG1, ARG2); 1987 } 1988 1989 PRE(change_fdguard_np) 1990 { 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); 1993 } 1994 1995 PRE(connectx) 1996 { 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); 1999 } 2000 2001 PRE(disconnectx) 2002 { 2003 PRINT("disconnectx(s:%#lx, aid:%#lx, cid:%#lx) FIXME", 2004 ARG1, ARG2, ARG3); 2005 } 2006 2007 2008 PRE(kevent) 2009 { 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); 2016 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)); 2023 2024 *flags |= SfMayBlock; 2025 } 2026 2027 POST(kevent) 2028 { 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)); 2031 } 2032 2033 2034 PRE(kevent64) 2035 { 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); 2042 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)); 2049 2050 *flags |= SfMayBlock; 2051 } 2052 2053 POST(kevent64) 2054 { 2055 PRINT("kevent64 ret %ld dst %#lx (%zu)", RES, ARG4, sizeof(struct vki_kevent64)); 2056 if (RES > 0) { 2057 ML_(sync_mappings)("after", "kevent64", 0); 2058 POST_MEM_WRITE(ARG4, RES * sizeof(struct vki_kevent64)); 2059 } 2060 } 2061 2062 2063 Addr pthread_starter = 0; 2064 Addr wqthread_starter = 0; 2065 SizeT pthread_structsize = 0; 2066 2067 PRE(bsdthread_register) 2068 { 2069 PRINT("bsdthread_register( %#lx, %#lx, %lu )", ARG1, ARG2, ARG3); 2070 PRE_REG_READ3(int,"__bsdthread_register", void *,"threadstart", 2071 void *,"wqthread", size_t,"pthsize"); 2072 2073 pthread_starter = ARG1; 2074 wqthread_starter = ARG2; 2075 pthread_structsize = ARG3; 2076 ARG1 = (Word)&pthread_hijack_asm; 2077 ARG2 = (Word)&wqthread_hijack_asm; 2078 } 2079 2080 PRE(workq_open) 2081 { 2082 PRINT("workq_open()"); 2083 PRE_REG_READ0(int, "workq_open"); 2084 2085 // This creates lots of threads and thread stacks under the covers, 2086 // but we ignore them all until some work item starts running on it. 2087 } 2088 2089 static const HChar *workqop_name(int op) 2090 { 2091 switch (op) { 2092 case VKI_WQOPS_QUEUE_ADD: return "QUEUE_ADD"; 2093 case VKI_WQOPS_QUEUE_REMOVE: return "QUEUE_REMOVE"; 2094 case VKI_WQOPS_THREAD_RETURN: return "THREAD_RETURN"; 2095 case VKI_WQOPS_THREAD_SETCONC: return "THREAD_SETCONC"; 2096 case VKI_WQOPS_QUEUE_NEWSPISUPP: return "QUEUE_NEWSPISUPP"; 2097 case VKI_WQOPS_QUEUE_REQTHREADS: return "QUEUE_REQTHREADS"; 2098 default: return "?"; 2099 } 2100 } 2101 2102 2103 PRE(workq_ops) 2104 { 2105 PRINT("workq_ops( %ld(%s), %#lx, %ld )", SARG1, workqop_name(ARG1), ARG2, 2106 SARG3); 2107 PRE_REG_READ3(int,"workq_ops", int,"options", void *,"item", 2108 int,"priority"); 2109 2110 switch (ARG1) { 2111 case VKI_WQOPS_QUEUE_ADD: 2112 case VKI_WQOPS_QUEUE_REMOVE: 2113 // GrP fixme need anything here? 2114 // GrP fixme may block? 2115 break; 2116 case VKI_WQOPS_QUEUE_NEWSPISUPP: 2117 // JRS don't think we need to do anything here -- this just checks 2118 // whether some newer functionality is supported 2119 break; 2120 case VKI_WQOPS_QUEUE_REQTHREADS: 2121 // JRS uh, looks like it queues up a bunch of threads, or some such? 2122 *flags |= SfMayBlock; // the kernel sources take a spinlock, so play safe 2123 break; 2124 case VKI_WQOPS_THREAD_RETURN: { 2125 // The interesting case. The kernel will do one of two things: 2126 // 1. Return normally. We continue; libc proceeds to stop the thread. 2127 // V does nothing special here. 2128 // 2. Jump to wqthread_hijack. This wipes the stack and runs a 2129 // new work item, and never returns from workq_ops. 2130 // V handles this by longjmp() from wqthread_hijack back to the 2131 // scheduler, which continues at the new client SP/IP/state. 2132 // This works something like V's signal handling. 2133 // To the tool, this looks like workq_ops() sometimes returns 2134 // to a strange address. 2135 ThreadState *tst = VG_(get_ThreadState)(tid); 2136 tst->os_state.wq_jmpbuf_valid = True; 2137 *flags |= SfMayBlock; // GrP fixme true? 2138 break; 2139 } 2140 default: 2141 VG_(printf)("UNKNOWN workq_ops option %ld\n", ARG1); 2142 break; 2143 } 2144 } 2145 POST(workq_ops) 2146 { 2147 ThreadState *tst = VG_(get_ThreadState)(tid); 2148 tst->os_state.wq_jmpbuf_valid = False; 2149 switch (ARG1) { 2150 case VKI_WQOPS_THREAD_RETURN: 2151 ML_(sync_mappings)("after", "workq_ops(THREAD_RETURN)", 0); 2152 break; 2153 case VKI_WQOPS_QUEUE_REQTHREADS: 2154 ML_(sync_mappings)("after", "workq_ops(QUEUE_REQTHREADS)", 0); 2155 break; 2156 default: 2157 break; 2158 } 2159 } 2160 2161 2162 2163 PRE(__mac_syscall) 2164 { 2165 PRINT("__mac_syscall( %#lx(%s), %ld, %#lx )", 2166 ARG1, (HChar*)ARG1, SARG2, ARG3); 2167 PRE_REG_READ3(int,"__mac_syscall", char *,"policy", 2168 int,"call", void *,"arg"); 2169 2170 // GrP fixme check call's arg? 2171 // GrP fixme check policy? 2172 } 2173 2174 2175 /* Not like syswrap-generic's sys_exit, which exits only one thread. 2176 More like syswrap-generic's sys_exit_group. */ 2177 PRE(exit) 2178 { 2179 ThreadId t; 2180 ThreadState* tst; 2181 2182 PRINT("darwin exit( %ld )", SARG1); 2183 PRE_REG_READ1(void, "exit", int, status); 2184 2185 tst = VG_(get_ThreadState)(tid); 2186 2187 /* A little complex; find all the threads with the same threadgroup 2188 as this one (including this one), and mark them to exit */ 2189 for (t = 1; t < VG_N_THREADS; t++) { 2190 if ( /* not alive */ 2191 VG_(threads)[t].status == VgTs_Empty 2192 /* GrP fixme zombie? */ 2193 ) 2194 continue; 2195 2196 VG_(threads)[t].exitreason = VgSrc_ExitProcess; 2197 VG_(threads)[t].os_state.exitcode = ARG1; 2198 2199 if (t != tid) 2200 VG_(get_thread_out_of_syscall)(t); /* unblock it, if blocked */ 2201 } 2202 2203 /* We have to claim the syscall already succeeded. */ 2204 SET_STATUS_Success(0); 2205 } 2206 2207 2208 PRE(sigaction) 2209 { 2210 PRINT("sigaction ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); 2211 PRE_REG_READ3(long, "sigaction", 2212 int, signum, vki_sigaction_toK_t *, act, 2213 vki_sigaction_fromK_t *, oldact); 2214 2215 if (ARG2 != 0) { 2216 vki_sigaction_toK_t *sa = (vki_sigaction_toK_t *)ARG2; 2217 PRE_MEM_READ( "sigaction(act->sa_handler)", 2218 (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler)); 2219 PRE_MEM_READ( "sigaction(act->sa_mask)", 2220 (Addr)&sa->sa_mask, sizeof(sa->sa_mask)); 2221 PRE_MEM_READ( "sigaction(act->sa_flags)", 2222 (Addr)&sa->sa_flags, sizeof(sa->sa_flags)); 2223 } 2224 if (ARG3 != 0) 2225 PRE_MEM_WRITE( "sigaction(oldact)", 2226 ARG3, sizeof(vki_sigaction_fromK_t)); 2227 2228 SET_STATUS_from_SysRes( 2229 VG_(do_sys_sigaction)(ARG1, (const vki_sigaction_toK_t *)ARG2, 2230 (vki_sigaction_fromK_t *)ARG3) 2231 ); 2232 } 2233 POST(sigaction) 2234 { 2235 vg_assert(SUCCESS); 2236 if (RES == 0 && ARG3 != 0) 2237 POST_MEM_WRITE( ARG3, sizeof(vki_sigaction_fromK_t)); 2238 } 2239 2240 2241 PRE(__pthread_kill) 2242 { 2243 PRINT("__pthread_kill ( %#lx, %ld )", ARG1, SARG2); 2244 PRE_REG_READ2(long, "__pthread_kill", vki_pthread_t*, thread, int, sig); 2245 } 2246 2247 2248 PRE(__pthread_sigmask) 2249 { 2250 // arguments are identical to sigprocmask (how, sigset_t*, sigset_t*). 2251 UWord arg1; 2252 PRINT("__pthread_sigmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); 2253 PRE_REG_READ3(long, "__pthread_sigmask", 2254 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset); 2255 if (ARG2 != 0) 2256 PRE_MEM_READ( "__pthread_sigmask(set)", ARG2, sizeof(vki_sigset_t)); 2257 if (ARG3 != 0) 2258 PRE_MEM_WRITE( "__pthread_sigmask(oldset)", ARG3, sizeof(vki_sigset_t)); 2259 2260 /* Massage ARG1 ('how'). If ARG2 (the new mask) is NULL then the 2261 value of 'how' is irrelevant, and it appears that Darwin's libc 2262 passes zero, which is not equal to any of 2263 SIG_{BLOCK,UNBLOCK,SETMASK}. This causes 2264 VG_(do_sys_sigprocmask) to complain, since it checks the 'how' 2265 value independently of the other args. Solution: in this case, 2266 simply pass a valid (but irrelevant) value for 'how'. */ 2267 /* Also, in this case the new set is passed to the kernel by 2268 reference, not value, as in some other sigmask related Darwin 2269 syscalls. */ 2270 arg1 = ARG1; 2271 if (ARG2 == 0 /* the new-set is NULL */ 2272 && ARG1 != VKI_SIG_BLOCK 2273 && ARG1 != VKI_SIG_UNBLOCK && ARG1 != VKI_SIG_SETMASK) { 2274 arg1 = VKI_SIG_SETMASK; 2275 } 2276 SET_STATUS_from_SysRes( 2277 VG_(do_sys_sigprocmask) ( tid, arg1, (vki_sigset_t*)ARG2, 2278 (vki_sigset_t*)ARG3 ) 2279 ); 2280 2281 if (SUCCESS) 2282 *flags |= SfPollAfter; 2283 } 2284 POST(__pthread_sigmask) 2285 { 2286 vg_assert(SUCCESS); 2287 if (RES == 0 && ARG3 != 0) 2288 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t)); 2289 } 2290 2291 2292 PRE(__pthread_canceled) 2293 { 2294 *flags |= SfMayBlock; /* might kill this thread??? */ 2295 /* I don't think so -- I think it just changes the cancellation 2296 state. But taking no chances. */ 2297 PRINT("__pthread_canceled ( %#lx )", ARG1); 2298 PRE_REG_READ1(long, "__pthread_canceled", void*, arg1); 2299 } 2300 2301 2302 PRE(__pthread_markcancel) 2303 { 2304 *flags |= SfMayBlock; /* might kill this thread??? */ 2305 PRINT("__pthread_markcancel ( %#lx )", ARG1); 2306 PRE_REG_READ1(long, "__pthread_markcancel", void*, arg1); 2307 /* Just let it go through. No idea if this is correct. */ 2308 } 2309 2310 2311 PRE(__disable_threadsignal) 2312 { 2313 vki_sigset_t set; 2314 PRINT("__disable_threadsignal(%ld, %ld, %ld)", SARG1, SARG2, SARG3); 2315 /* I don't think this really looks at its arguments. So don't 2316 bother to check them. */ 2317 2318 VG_(sigfillset)( &set ); 2319 SET_STATUS_from_SysRes( 2320 VG_(do_sys_sigprocmask) ( tid, VKI_SIG_BLOCK, &set, NULL ) 2321 ); 2322 2323 /* We don't expect that blocking all signals for this thread could 2324 cause any more to be delivered (how could it?), but just in case 2325 .. */ 2326 if (SUCCESS) 2327 *flags |= SfPollAfter; 2328 } 2329 2330 2331 PRE(__pthread_chdir) 2332 { 2333 PRINT("__pthread_chdir ( %#lx(%s) )", ARG1, (HChar*)ARG1); 2334 PRE_REG_READ1(long, "__pthread_chdir", const char *, path); 2335 PRE_MEM_RASCIIZ( "__pthread_chdir(path)", ARG1 ); 2336 } 2337 2338 2339 2340 PRE(__pthread_fchdir) 2341 { 2342 PRINT("__pthread_fchdir ( %lu )", ARG1); 2343 PRE_REG_READ1(long, "__pthread_fchdir", unsigned int, fd); 2344 } 2345 2346 2347 PRE(kdebug_trace) 2348 { 2349 PRINT("kdebug_trace(%ld, %ld, %ld, %ld, %ld, %ld)", 2350 SARG1, SARG2, SARG3, SARG4, SARG5, SARG6); 2351 /* 2352 Don't check anything - some clients pass fewer arguments. 2353 PRE_REG_READ6(long, "kdebug_trace", 2354 int,"code", int,"arg1", int,"arg2", 2355 int,"arg3", int,"arg4", int,"arg5"); 2356 */ 2357 } 2358 2359 2360 PRE(seteuid) 2361 { 2362 PRINT("seteuid(%lu)", ARG1); 2363 PRE_REG_READ1(long, "seteuid", vki_uid_t, "uid"); 2364 } 2365 2366 2367 PRE(setegid) 2368 { 2369 PRINT("setegid(%lu)", ARG1); 2370 PRE_REG_READ1(long, "setegid", vki_uid_t, "uid"); 2371 } 2372 2373 PRE(settid) 2374 { 2375 PRINT("settid(%lu, %lu)", ARG1, ARG2); 2376 PRE_REG_READ2(long, "settid", vki_uid_t, "uid", vki_gid_t, "gid"); 2377 } 2378 2379 PRE(gettid) 2380 { 2381 PRINT("gettid()"); 2382 PRE_REG_READ0(long, gettid); 2383 } 2384 2385 /* XXX need to check whether we need POST operations for 2386 * waitevent, watchevent, modwatch -- jpeach 2387 */ 2388 PRE(watchevent) 2389 { 2390 PRINT("watchevent(%#lx, %#lx)", ARG1, ARG2); 2391 PRE_REG_READ2(long, "watchevent", 2392 vki_eventreq *, "event", unsigned int, "eventmask"); 2393 2394 PRE_MEM_READ("watchevent(event)", ARG1, sizeof(vki_eventreq)); 2395 PRE_MEM_READ("watchevent(eventmask)", ARG2, sizeof(unsigned int)); 2396 *flags |= SfMayBlock; 2397 } 2398 2399 #define WAITEVENT_FAST_POLL ((Addr)(struct timeval *)-1) 2400 PRE(waitevent) 2401 { 2402 PRINT("waitevent(%#lx, %#lx)", ARG1, ARG2); 2403 PRE_REG_READ2(long, "waitevent", 2404 vki_eventreq *, "event", struct timeval *, "timeout"); 2405 PRE_MEM_WRITE("waitevent(event)", ARG1, sizeof(vki_eventreq)); 2406 2407 if (ARG2 && ARG2 != WAITEVENT_FAST_POLL) { 2408 PRE_timeval_READ("waitevent(timeout)", ARG2); 2409 } 2410 2411 /* XXX ((timeval*)-1) is valid for ARG2 -- jpeach */ 2412 *flags |= SfMayBlock; 2413 } 2414 2415 POST(waitevent) 2416 { 2417 POST_MEM_WRITE(ARG1, sizeof(vki_eventreq)); 2418 } 2419 2420 PRE(modwatch) 2421 { 2422 PRINT("modwatch(%#lx, %#lx)", ARG1, ARG2); 2423 PRE_REG_READ2(long, "modwatch", 2424 vki_eventreq *, "event", unsigned int, "eventmask"); 2425 2426 PRE_MEM_READ("modwatch(event)", ARG1, sizeof(vki_eventreq)); 2427 PRE_MEM_READ("modwatch(eventmask)", ARG2, sizeof(unsigned int)); 2428 } 2429 2430 PRE(getxattr) 2431 { 2432 PRINT("getxattr(%#lx(%s), %#lx(%s), %#lx, %lu, %lu, %ld)", 2433 ARG1, (HChar *)ARG1, ARG2, (HChar *)ARG2, ARG3, ARG4, ARG5, SARG6); 2434 2435 PRE_REG_READ6(vki_ssize_t, "getxattr", 2436 const char *, path, char *, name, void *, value, 2437 vki_size_t, size, uint32_t, position, int, options); 2438 PRE_MEM_RASCIIZ("getxattr(path)", ARG1); 2439 PRE_MEM_RASCIIZ("getxattr(name)", ARG2); 2440 if (ARG3) 2441 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4); 2442 } 2443 2444 POST(getxattr) 2445 { 2446 vg_assert((vki_ssize_t)RES >= 0); 2447 if (ARG3) 2448 POST_MEM_WRITE(ARG3, (vki_ssize_t)RES); 2449 } 2450 2451 PRE(fgetxattr) 2452 { 2453 PRINT("fgetxattr(%ld, %#lx(%s), %#lx, %lu, %lu, %ld)", 2454 SARG1, ARG2, (HChar *)ARG2, ARG3, ARG4, ARG5, SARG6); 2455 2456 PRE_REG_READ6(vki_ssize_t, "fgetxattr", 2457 int, fd, char *, name, void *, value, 2458 vki_size_t, size, uint32_t, position, int, options); 2459 PRE_MEM_RASCIIZ("getxattr(name)", ARG2); 2460 PRE_MEM_WRITE( "getxattr(value)", ARG3, ARG4); 2461 } 2462 2463 POST(fgetxattr) 2464 { 2465 vg_assert((vki_ssize_t)RES >= 0); 2466 POST_MEM_WRITE(ARG3, (vki_ssize_t)RES); 2467 } 2468 2469 PRE(setxattr) 2470 { 2471 PRINT("setxattr ( %#lx(%s), %#lx(%s), %#lx, %lu, %lu, %ld )", 2472 ARG1, (HChar *)ARG1, ARG2, (HChar*)ARG2, ARG3, ARG4, ARG5, SARG6 ); 2473 PRE_REG_READ6(int, "setxattr", 2474 const char *,"path", char *,"name", void *,"value", 2475 vki_size_t,"size", uint32_t,"position", int,"options" ); 2476 2477 PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 ); 2478 PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 ); 2479 PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 ); 2480 } 2481 2482 2483 PRE(fsetxattr) 2484 { 2485 PRINT( "fsetxattr ( %ld, %#lx(%s), %#lx, %lu, %lu, %ld )", 2486 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4, ARG5, SARG6 ); 2487 PRE_REG_READ6(int, "fsetxattr", 2488 int,"fd", char *,"name", void *,"value", 2489 vki_size_t,"size", uint32_t,"position", int,"options" ); 2490 2491 PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 ); 2492 PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 ); 2493 } 2494 2495 2496 PRE(removexattr) 2497 { 2498 PRINT( "removexattr ( %#lx(%s), %#lx(%s), %ld )", 2499 ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, SARG3 ); 2500 PRE_REG_READ3(int, "removexattr", 2501 const char*, "path", char*, "attrname", int, "options"); 2502 PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 ); 2503 PRE_MEM_RASCIIZ( "removexattr(attrname)", ARG2 ); 2504 } 2505 2506 2507 PRE(fremovexattr) 2508 { 2509 PRINT( "fremovexattr ( %ld, %#lx(%s), %ld )", 2510 SARG1, ARG2, (HChar*)ARG2, SARG3 ); 2511 PRE_REG_READ3(int, "fremovexattr", 2512 int, "fd", char*, "attrname", int, "options"); 2513 PRE_MEM_RASCIIZ( "removexattr(attrname)", ARG2 ); 2514 } 2515 2516 2517 PRE(listxattr) 2518 { 2519 PRINT( "listxattr ( %#lx(%s), %#lx, %lu, %ld )", 2520 ARG1, (HChar *)ARG1, ARG2, ARG3, SARG4 ); 2521 PRE_REG_READ4 (long, "listxattr", 2522 const char *,"path", char *,"namebuf", 2523 vki_size_t,"size", int,"options" ); 2524 2525 PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 ); 2526 PRE_MEM_WRITE( "listxattr(namebuf)", ARG2, ARG3 ); 2527 *flags |= SfMayBlock; 2528 } 2529 POST(listxattr) 2530 { 2531 vg_assert(SUCCESS); 2532 vg_assert((vki_ssize_t)RES >= 0); 2533 POST_MEM_WRITE( ARG2, (vki_ssize_t)RES ); 2534 } 2535 2536 2537 PRE(flistxattr) 2538 { 2539 PRINT( "flistxattr ( %ld, %#lx, %lu, %ld )", 2540 SARG1, ARG2, ARG3, SARG4 ); 2541 PRE_REG_READ4 (long, "flistxattr", 2542 int, "fd", char *,"namebuf", 2543 vki_size_t,"size", int,"options" ); 2544 PRE_MEM_WRITE( "flistxattr(namebuf)", ARG2, ARG3 ); 2545 *flags |= SfMayBlock; 2546 } 2547 POST(flistxattr) 2548 { 2549 vg_assert(SUCCESS); 2550 vg_assert((vki_ssize_t)RES >= 0); 2551 POST_MEM_WRITE( ARG2, (vki_ssize_t)RES ); 2552 } 2553 2554 2555 PRE(shmat) 2556 { 2557 UWord arg2tmp; 2558 PRINT("shmat ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3); 2559 PRE_REG_READ3(long, "shmat", 2560 int, shmid, const void *, shmaddr, int, shmflg); 2561 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3); 2562 if (arg2tmp == 0) 2563 SET_STATUS_Failure( VKI_EINVAL ); 2564 else 2565 ARG2 = arg2tmp; // used in POST 2566 } 2567 POST(shmat) 2568 { 2569 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3); 2570 } 2571 2572 PRE(shmctl) 2573 { 2574 PRINT("shmctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3); 2575 PRE_REG_READ3(long, "shmctl", 2576 int, shmid, int, cmd, struct vki_shmid_ds *, buf); 2577 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3); 2578 } 2579 POST(shmctl) 2580 { 2581 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3); 2582 } 2583 2584 PRE(shmdt) 2585 { 2586 PRINT("shmdt ( %#lx )",ARG1); 2587 PRE_REG_READ1(long, "shmdt", const void *, shmaddr); 2588 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1)) 2589 SET_STATUS_Failure( VKI_EINVAL ); 2590 } 2591 POST(shmdt) 2592 { 2593 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1); 2594 } 2595 2596 PRE(shmget) 2597 { 2598 PRINT("shmget ( %ld, %lu, %ld )", SARG1, ARG2, SARG3); 2599 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg); 2600 } 2601 2602 PRE(shm_open) 2603 { 2604 PRINT("shm_open(%#lx(%s), %ld, %lu)", ARG1, (HChar *)ARG1, SARG2, ARG3); 2605 PRE_REG_READ3(long, "shm_open", 2606 const char *,"name", int,"flags", vki_mode_t,"mode"); 2607 2608 PRE_MEM_RASCIIZ( "shm_open(filename)", ARG1 ); 2609 2610 *flags |= SfMayBlock; 2611 } 2612 POST(shm_open) 2613 { 2614 vg_assert(SUCCESS); 2615 if (!ML_(fd_allowed)(RES, "shm_open", tid, True)) { 2616 VG_(close)(RES); 2617 SET_STATUS_Failure( VKI_EMFILE ); 2618 } else { 2619 if (VG_(clo_track_fds)) 2620 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); 2621 } 2622 } 2623 2624 PRE(shm_unlink) 2625 { 2626 *flags |= SfMayBlock; 2627 PRINT("shm_unlink ( %#lx(%s) )", ARG1, (HChar*)ARG1); 2628 PRE_REG_READ1(long, "shm_unlink", const char *, pathname); 2629 PRE_MEM_RASCIIZ( "shm_unlink(pathname)", ARG1 ); 2630 } 2631 POST(shm_unlink) 2632 { 2633 /* My reading of the man page suggests that a call may cause memory 2634 mappings to change: "if no references exist at the time of the 2635 call to shm_unlink(), the resources are reclaimed immediately". 2636 So we need to resync here, sigh. */ 2637 ML_(sync_mappings)("after", "shm_unlink", 0); 2638 } 2639 2640 PRE(stat_extended) 2641 { 2642 PRINT("stat_extended( %#lx(%s), %#lx, %#lx, %#lx )", 2643 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4); 2644 PRE_REG_READ4(int, "stat_extended", char *, file_name, struct stat *, buf, 2645 void *, fsacl, vki_size_t *, fsacl_size); 2646 PRE_MEM_RASCIIZ( "stat_extended(file_name)", ARG1 ); 2647 PRE_MEM_WRITE( "stat_extended(buf)", ARG2, sizeof(struct vki_stat) ); 2648 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2649 PRE_MEM_WRITE("stat_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); 2650 PRE_MEM_READ( "stat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); 2651 } 2652 POST(stat_extended) 2653 { 2654 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); 2655 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2656 POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 ); 2657 POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); 2658 } 2659 2660 2661 PRE(lstat_extended) 2662 { 2663 PRINT("lstat_extended( %#lx(%s), %#lx, %#lx, %#lx )", 2664 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4); 2665 PRE_REG_READ4(int, "lstat_extended", char *, file_name, struct stat *, buf, 2666 void *, fsacl, vki_size_t *, fsacl_size); 2667 PRE_MEM_RASCIIZ( "lstat_extended(file_name)", ARG1 ); 2668 PRE_MEM_WRITE( "lstat_extended(buf)", ARG2, sizeof(struct vki_stat) ); 2669 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2670 PRE_MEM_WRITE("lstat_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); 2671 PRE_MEM_READ( "lstat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); 2672 } 2673 POST(lstat_extended) 2674 { 2675 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); 2676 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2677 POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 ); 2678 POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); 2679 } 2680 2681 2682 PRE(fstat_extended) 2683 { 2684 PRINT("fstat_extended( %ld, %#lx, %#lx, %#lx )", 2685 SARG1, ARG2, ARG3, ARG4); 2686 PRE_REG_READ4(int, "fstat_extended", int, fd, struct stat *, buf, 2687 void *, fsacl, vki_size_t *, fsacl_size); 2688 PRE_MEM_WRITE( "fstat_extended(buf)", ARG2, sizeof(struct vki_stat) ); 2689 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2690 PRE_MEM_WRITE("fstat_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); 2691 PRE_MEM_READ( "fstat_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); 2692 } 2693 POST(fstat_extended) 2694 { 2695 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); 2696 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2697 POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 ); 2698 POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); 2699 } 2700 2701 2702 PRE(stat64_extended) 2703 { 2704 PRINT("stat64_extended( %#lx(%s), %#lx, %#lx, %#lx )", 2705 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4); 2706 PRE_REG_READ4(int, "stat64_extended", char *, file_name, struct stat64 *, buf, 2707 void *, fsacl, vki_size_t *, fsacl_size); 2708 PRE_MEM_RASCIIZ( "stat64_extended(file_name)", ARG1 ); 2709 PRE_MEM_WRITE( "stat64_extended(buf)", ARG2, sizeof(struct vki_stat64) ); 2710 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2711 PRE_MEM_WRITE("stat64_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); 2712 PRE_MEM_READ( "stat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); 2713 } 2714 POST(stat64_extended) 2715 { 2716 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 2717 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2718 POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 ); 2719 POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); 2720 } 2721 2722 2723 PRE(lstat64_extended) 2724 { 2725 PRINT("lstat64_extended( %#lx(%s), %#lx, %#lx, %#lx )", 2726 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4); 2727 PRE_REG_READ4(int, "lstat64_extended", char *, file_name, struct stat64 *, buf, 2728 void *, fsacl, vki_size_t *, fsacl_size); 2729 PRE_MEM_RASCIIZ( "lstat64_extended(file_name)", ARG1 ); 2730 PRE_MEM_WRITE( "lstat64_extended(buf)", ARG2, sizeof(struct vki_stat64) ); 2731 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2732 PRE_MEM_WRITE( "lstat64_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); 2733 PRE_MEM_READ( "lstat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); 2734 } 2735 POST(lstat64_extended) 2736 { 2737 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 2738 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2739 POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 ); 2740 POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); 2741 } 2742 2743 2744 PRE(fstat64_extended) 2745 { 2746 PRINT("fstat64_extended( %ld, %#lx, %#lx, %#lx )", 2747 SARG1, ARG2, ARG3, ARG4); 2748 PRE_REG_READ4(int, "fstat64_extended", int, fd, struct stat64 *, buf, 2749 void *, fsacl, vki_size_t *, fsacl_size); 2750 PRE_MEM_WRITE( "fstat64_extended(buf)", ARG2, sizeof(struct vki_stat64) ); 2751 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2752 PRE_MEM_WRITE("fstat64_extended(fsacl)", ARG3, *(vki_size_t *)ARG4 ); 2753 PRE_MEM_READ( "fstat64_extended(fsacl_size)", ARG4, sizeof(vki_size_t) ); 2754 } 2755 POST(fstat64_extended) 2756 { 2757 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 2758 if (ML_(safe_to_deref)( (void*)ARG4, sizeof(vki_size_t) )) 2759 POST_MEM_WRITE( ARG3, *(vki_size_t *)ARG4 ); 2760 POST_MEM_WRITE( ARG4, sizeof(vki_size_t) ); 2761 } 2762 2763 2764 PRE(fchmod_extended) 2765 { 2766 /* DDD: Note: this is not really correct. Handling of 2767 chmod_extended is broken in the same way. */ 2768 PRINT("fchmod_extended ( %lu, %lu, %lu, %lu, %#lx )", 2769 ARG1, ARG2, ARG3, ARG4, ARG5); 2770 PRE_REG_READ5(long, "fchmod_extended", 2771 unsigned int, fildes, 2772 uid_t, uid, 2773 gid_t, gid, 2774 vki_mode_t, mode, 2775 void* /*really,user_addr_t*/, xsecurity); 2776 /* DDD: relative to the xnu sources (kauth_copyinfilesec), this 2777 is just way wrong. [The trouble is with the size, which depends on a 2778 non-trival kernel computation] */ 2779 if (ARG5) { 2780 PRE_MEM_READ( "fchmod_extended(xsecurity)", ARG5, 2781 sizeof(struct vki_kauth_filesec) ); 2782 } 2783 } 2784 2785 PRE(chmod_extended) 2786 { 2787 /* DDD: Note: this is not really correct. Handling of 2788 fchmod_extended is broken in the same way. */ 2789 PRINT("chmod_extended ( %#lx(%s), %ld, %ld, %ld, %#lx )", 2790 ARG1, ARG1 ? (HChar*)ARG1 : "(null)", ARG2, ARG3, ARG4, ARG5); 2791 PRE_REG_READ5(long, "chmod_extended", 2792 unsigned int, fildes, 2793 uid_t, uid, 2794 gid_t, gid, 2795 vki_mode_t, mode, 2796 void* /*really,user_addr_t*/, xsecurity); 2797 PRE_MEM_RASCIIZ("chmod_extended(path)", ARG1); 2798 /* DDD: relative to the xnu sources (kauth_copyinfilesec), this 2799 is just way wrong. [The trouble is with the size, which depends on a 2800 non-trival kernel computation] */ 2801 if (ARG5) { 2802 PRE_MEM_READ( "chmod_extended(xsecurity)", ARG5, 2803 sizeof(struct vki_kauth_filesec) ); 2804 } 2805 } 2806 2807 PRE(open_extended) 2808 { 2809 /* DDD: Note: this is not really correct. Handling of 2810 {,f}chmod_extended is broken in the same way. */ 2811 PRINT("open_extended ( %#lx(%s), %ld, %lu, %lu, %lu, %#lx )", 2812 ARG1, ARG1 ? (HChar*)ARG1 : "(null)", 2813 SARG2, ARG3, ARG4, ARG5, ARG6); 2814 PRE_REG_READ6(long, "open_extended", 2815 char*, path, 2816 int, flags, 2817 uid_t, uid, 2818 gid_t, gid, 2819 vki_mode_t, mode, 2820 void* /*really,user_addr_t*/, xsecurity); 2821 PRE_MEM_RASCIIZ("open_extended(path)", ARG1); 2822 /* DDD: relative to the xnu sources (kauth_copyinfilesec), this 2823 is just way wrong. [The trouble is with the size, which depends on a 2824 non-trival kernel computation] */ 2825 if (ARG6) 2826 PRE_MEM_READ( "open_extended(xsecurity)", ARG6, 2827 sizeof(struct vki_kauth_filesec) ); 2828 } 2829 2830 // This is a ridiculous syscall. Specifically, the 'entries' argument points 2831 // to a buffer that contains one or more 'accessx_descriptor' structs followed 2832 // by one or more strings. Each accessx_descriptor contains a field, 2833 // 'ad_name_offset', which points to one of the strings (or it can contain 2834 // zero which means "reuse the string from the previous accessx_descriptor"). 2835 // 2836 // What's really ridiculous is that we are only given the size of the overall 2837 // buffer, not the number of accessx_descriptors, nor the number of strings. 2838 // The kernel determines the number of accessx_descriptors by walking through 2839 // them one by one, checking that the ad_name_offset points within the buffer, 2840 // past the current point (or that it's a zero, unless its the first 2841 // descriptor); if so, we assume that this really is an accessx_descriptor, 2842 // if not, we assume we've hit the strings section. Gah. 2843 // 2844 // This affects us here because number of entries in the 'results' buffer is 2845 // determined by the number of accessx_descriptors. So we have to know that 2846 // number in order to do PRE_MEM_WRITE/POST_MEM_WRITE of 'results'. In 2847 // practice, we skip the PRE_MEM_WRITE step because it's easier to do the 2848 // computation after the syscall has succeeded, because the kernel will have 2849 // checked for all the zillion different ways this syscall can fail, and we'll 2850 // know we have a well-formed 'entries' buffer. This means we might miss some 2851 // uses of unaddressable memory but oh well. 2852 // 2853 PRE(access_extended) 2854 { 2855 PRINT("access_extended( %#lx(%s), %lu, %#lx, %lu )", 2856 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4); 2857 // XXX: the accessx_descriptor struct contains padding, so this can cause 2858 // unnecessary undefined value errors. But you arguably shouldn't be 2859 // passing undefined values to the kernel anyway... 2860 PRE_REG_READ4(int, "access_extended", void *, entries, vki_size_t, size, 2861 vki_errno_t *, results, vki_uid_t *, uid); 2862 PRE_MEM_READ("access_extended(entries)", ARG1, ARG2 ); 2863 2864 // XXX: as mentioned above, this check is too hard to do before the 2865 // syscall. 2866 //PRE_MEM_WRITE("access_extended(results)", ARG3, ??? ); 2867 } 2868 POST(access_extended) 2869 { 2870 // 'n_descs' is the number of descriptors we think are in the buffer. We 2871 // start with the maximum possible value, which occurs if we have the 2872 // shortest possible string section. The shortest string section allowed 2873 // consists of a single one-char string (plus the NUL char). Hence the 2874 // '2'. 2875 struct vki_accessx_descriptor* entries = (struct vki_accessx_descriptor*)ARG1; 2876 SizeT size = ARG2; 2877 Int n_descs = (size - 2) / sizeof(struct accessx_descriptor); 2878 Int i; // Current position in the descriptors section array. 2879 Int u; // Upper bound on the length of the descriptors array 2880 // (recomputed each time around the loop) 2881 vg_assert(n_descs > 0); 2882 2883 // Step through the descriptors, lowering 'n_descs' until we know we've 2884 // reached the string section. 2885 for (i = 0; True; i++) { 2886 // If we're past our estimate, we must be one past the end of the 2887 // descriptors section (ie. at the start of the string section). Stop. 2888 if (i >= n_descs) 2889 break; 2890 2891 // Get the array index for the string, but pretend momentarily that it 2892 // is actually another accessx_descriptor. That gives us an upper bound 2893 // on the length of the descriptors section. (Unless the index is zero, 2894 // in which case we have no new info.) 2895 u = entries[i].ad_name_offset / sizeof(struct vki_accessx_descriptor); 2896 if (u == 0) { 2897 vg_assert(i != 0); 2898 continue; 2899 } 2900 2901 // If the upper bound is below our current estimate, revise that 2902 // estimate downwards. 2903 if (u < n_descs) 2904 n_descs = u; 2905 } 2906 2907 // Sanity check. 2908 vg_assert(n_descs <= VKI_ACCESSX_MAX_DESCRIPTORS); 2909 2910 POST_MEM_WRITE( ARG3, n_descs * sizeof(vki_errno_t) ); 2911 } 2912 2913 2914 PRE(chflags) 2915 { 2916 PRINT("chflags ( %#lx(%s), %lu )", ARG1, (HChar *)ARG1, ARG2); 2917 PRE_REG_READ2(int, "chflags", const char *,path, unsigned int,flags); 2918 PRE_MEM_RASCIIZ("chflags(path)", ARG1); 2919 2920 // GrP fixme sanity-check flags value? 2921 } 2922 2923 PRE(fchflags) 2924 { 2925 PRINT("fchflags ( %ld, %lu )", SARG1, ARG2); 2926 PRE_REG_READ2(int, "fchflags", int,fd, unsigned int,flags); 2927 2928 // GrP fixme sanity-check flags value? 2929 } 2930 2931 PRE(stat64) 2932 { 2933 PRINT("stat64 ( %#lx(%s), %#lx )", ARG1, (HChar *)ARG1, ARG2); 2934 PRE_REG_READ2(long, "stat", const char *,path, struct stat64 *,buf); 2935 PRE_MEM_RASCIIZ("stat64(path)", ARG1); 2936 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); 2937 } 2938 POST(stat64) 2939 { 2940 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 2941 } 2942 2943 PRE(lstat64) 2944 { 2945 PRINT("lstat64 ( %#lx(%s), %#lx )", ARG1, (HChar *)ARG1, ARG2); 2946 PRE_REG_READ2(long, "stat", const char *,path, struct stat64 *,buf); 2947 PRE_MEM_RASCIIZ("lstat64(path)", ARG1); 2948 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 2949 } 2950 POST(lstat64) 2951 { 2952 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 2953 } 2954 2955 PRE(fstat64) 2956 { 2957 PRINT("fstat64 ( %lu, %#lx )", ARG1,ARG2); 2958 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat64 *, buf); 2959 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 2960 } 2961 POST(fstat64) 2962 { 2963 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 2964 } 2965 2966 PRE(getfsstat) 2967 { 2968 PRINT("getfsstat(%#lx, %ld, %ld)", ARG1, SARG2, SARG3); 2969 PRE_REG_READ3(int, "getfsstat", 2970 struct vki_statfs *, buf, int, bufsize, int, flags); 2971 if (ARG1) { 2972 // ARG2 is a BYTE SIZE 2973 PRE_MEM_WRITE("getfsstat(buf)", ARG1, ARG2); 2974 } 2975 } 2976 POST(getfsstat) 2977 { 2978 if (ARG1) { 2979 // RES is a STRUCT COUNT 2980 POST_MEM_WRITE(ARG1, RES * sizeof(struct vki_statfs)); 2981 } 2982 } 2983 2984 PRE(getfsstat64) 2985 { 2986 PRINT("getfsstat64(%#lx, %ld, %ld)", ARG1, SARG2, SARG3); 2987 PRE_REG_READ3(int, "getfsstat64", 2988 struct vki_statfs64 *, buf, int, bufsize, int, flags); 2989 if (ARG1) { 2990 // ARG2 is a BYTE SIZE 2991 PRE_MEM_WRITE("getfsstat64(buf)", ARG1, ARG2); 2992 } 2993 } 2994 POST(getfsstat64) 2995 { 2996 if (ARG1) { 2997 // RES is a STRUCT COUNT 2998 POST_MEM_WRITE(ARG1, RES * sizeof(struct vki_statfs64)); 2999 } 3000 } 3001 3002 PRE(mount) 3003 { 3004 // Nb: depending on 'flags', the 'type' and 'data' args may be ignored. 3005 // We are conservative and check everything, except the memory pointed to 3006 // by 'data'. 3007 *flags |= SfMayBlock; 3008 PRINT("sys_mount( %#lx(%s), %#lx(%s), %#lx, %#lx )", 3009 ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3, ARG4); 3010 PRE_REG_READ4(long, "mount", 3011 const char *, type, const char *, dir, 3012 int, flags, void *, data); 3013 PRE_MEM_RASCIIZ( "mount(type)", ARG1); 3014 PRE_MEM_RASCIIZ( "mount(dir)", ARG2); 3015 } 3016 3017 3018 static void scan_attrlist(ThreadId tid, struct vki_attrlist *attrList, 3019 void *attrBuf, SizeT attrBufSize, 3020 void (*fn)(ThreadId, void *attrData, SizeT size) 3021 ) 3022 { 3023 typedef struct { 3024 uint32_t attrBit; 3025 int32_t attrSize; 3026 } attrspec; 3027 static const attrspec commonattr[] = { 3028 // This order is important. 3029 #if DARWIN_VERS >= DARWIN_10_6 3030 { ATTR_CMN_RETURNED_ATTRS, sizeof(attribute_set_t) }, 3031 #endif 3032 { ATTR_CMN_NAME, -1 }, 3033 { ATTR_CMN_DEVID, sizeof(dev_t) }, 3034 { ATTR_CMN_FSID, sizeof(fsid_t) }, 3035 { ATTR_CMN_OBJTYPE, sizeof(fsobj_type_t) }, 3036 { ATTR_CMN_OBJTAG, sizeof(fsobj_tag_t) }, 3037 { ATTR_CMN_OBJID, sizeof(fsobj_id_t) }, 3038 { ATTR_CMN_OBJPERMANENTID, sizeof(fsobj_id_t) }, 3039 { ATTR_CMN_PAROBJID, sizeof(fsobj_id_t) }, 3040 { ATTR_CMN_SCRIPT, sizeof(text_encoding_t) }, 3041 { ATTR_CMN_CRTIME, sizeof(struct timespec) }, 3042 { ATTR_CMN_MODTIME, sizeof(struct timespec) }, 3043 { ATTR_CMN_CHGTIME, sizeof(struct timespec) }, 3044 { ATTR_CMN_ACCTIME, sizeof(struct timespec) }, 3045 { ATTR_CMN_BKUPTIME, sizeof(struct timespec) }, 3046 { ATTR_CMN_FNDRINFO, 32 /*FileInfo+ExtendedFileInfo, or FolderInfo+ExtendedFolderInfo*/ }, 3047 { ATTR_CMN_OWNERID, sizeof(uid_t) }, 3048 { ATTR_CMN_GRPID, sizeof(gid_t) }, 3049 { ATTR_CMN_ACCESSMASK, sizeof(uint32_t) }, 3050 { ATTR_CMN_NAMEDATTRCOUNT, sizeof(uint32_t) }, 3051 { ATTR_CMN_NAMEDATTRLIST, -1 }, 3052 { ATTR_CMN_FLAGS, sizeof(uint32_t) }, 3053 { ATTR_CMN_USERACCESS, sizeof(uint32_t) }, 3054 { ATTR_CMN_EXTENDED_SECURITY, -1 }, 3055 { ATTR_CMN_UUID, sizeof(guid_t) }, 3056 { ATTR_CMN_GRPUUID, sizeof(guid_t) }, 3057 { ATTR_CMN_FILEID, sizeof(uint64_t) }, 3058 { ATTR_CMN_PARENTID, sizeof(uint64_t) }, 3059 #if DARWIN_VERS >= DARWIN_10_6 3060 { ATTR_CMN_FULLPATH, -1 }, 3061 #endif 3062 #if DARWIN_VERS >= DARWIN_10_8 3063 { ATTR_CMN_ADDEDTIME, -1 }, 3064 #endif 3065 { 0, 0 } 3066 }; 3067 static const attrspec volattr[] = { 3068 // This order is important. 3069 { ATTR_VOL_INFO, 0 }, 3070 { ATTR_VOL_FSTYPE, sizeof(uint32_t) }, 3071 { ATTR_VOL_SIGNATURE, sizeof(uint32_t) }, 3072 { ATTR_VOL_SIZE, sizeof(off_t) }, 3073 { ATTR_VOL_SPACEFREE, sizeof(off_t) }, 3074 { ATTR_VOL_SPACEAVAIL, sizeof(off_t) }, 3075 { ATTR_VOL_MINALLOCATION, sizeof(off_t) }, 3076 { ATTR_VOL_ALLOCATIONCLUMP, sizeof(off_t) }, 3077 { ATTR_VOL_IOBLOCKSIZE, sizeof(uint32_t) }, 3078 { ATTR_VOL_OBJCOUNT, sizeof(uint32_t) }, 3079 { ATTR_VOL_FILECOUNT, sizeof(uint32_t) }, 3080 { ATTR_VOL_DIRCOUNT, sizeof(uint32_t) }, 3081 { ATTR_VOL_MAXOBJCOUNT, sizeof(uint32_t) }, 3082 { ATTR_VOL_MOUNTPOINT, -1 }, 3083 { ATTR_VOL_NAME, -1 }, 3084 { ATTR_VOL_MOUNTFLAGS, sizeof(uint32_t) }, 3085 { ATTR_VOL_MOUNTEDDEVICE, -1 }, 3086 { ATTR_VOL_ENCODINGSUSED, sizeof(uint64_t) }, 3087 { ATTR_VOL_CAPABILITIES, sizeof(vol_capabilities_attr_t) }, 3088 #if DARWIN_VERS >= DARWIN_10_6 3089 { ATTR_VOL_UUID, sizeof(uuid_t) }, 3090 #endif 3091 { ATTR_VOL_ATTRIBUTES, sizeof(vol_attributes_attr_t) }, 3092 { 0, 0 } 3093 }; 3094 static const attrspec dirattr[] = { 3095 // This order is important. 3096 { ATTR_DIR_LINKCOUNT, sizeof(uint32_t) }, 3097 { ATTR_DIR_ENTRYCOUNT, sizeof(uint32_t) }, 3098 { ATTR_DIR_MOUNTSTATUS, sizeof(uint32_t) }, 3099 { 0, 0 } 3100 }; 3101 static const attrspec fileattr[] = { 3102 // This order is important. 3103 { ATTR_FILE_LINKCOUNT, sizeof(uint32_t) }, 3104 { ATTR_FILE_TOTALSIZE, sizeof(off_t) }, 3105 { ATTR_FILE_ALLOCSIZE, sizeof(off_t) }, 3106 { ATTR_FILE_IOBLOCKSIZE, sizeof(uint32_t) }, 3107 { ATTR_FILE_CLUMPSIZE, sizeof(uint32_t) }, 3108 { ATTR_FILE_DEVTYPE, sizeof(uint32_t) }, 3109 { ATTR_FILE_FILETYPE, sizeof(uint32_t) }, 3110 { ATTR_FILE_FORKCOUNT, sizeof(uint32_t) }, 3111 { ATTR_FILE_FORKLIST, -1 }, 3112 { ATTR_FILE_DATALENGTH, sizeof(off_t) }, 3113 { ATTR_FILE_DATAALLOCSIZE, sizeof(off_t) }, 3114 { ATTR_FILE_DATAEXTENTS, sizeof(extentrecord) }, 3115 { ATTR_FILE_RSRCLENGTH, sizeof(off_t) }, 3116 { ATTR_FILE_RSRCALLOCSIZE, sizeof(off_t) }, 3117 { ATTR_FILE_RSRCEXTENTS, sizeof(extentrecord) }, 3118 { 0, 0 } 3119 }; 3120 static const attrspec forkattr[] = { 3121 // This order is important. 3122 { ATTR_FORK_TOTALSIZE, sizeof(off_t) }, 3123 { ATTR_FORK_ALLOCSIZE, sizeof(off_t) }, 3124 { 0, 0 } 3125 }; 3126 3127 static const attrspec *attrdefs[5] = { 3128 commonattr, volattr, dirattr, fileattr, forkattr 3129 }; 3130 attrgroup_t a[5]; 3131 uint8_t *d, *dend; 3132 int g, i; 3133 3134 vg_assert(attrList->bitmapcount == 5); 3135 VG_(memcpy)(a, &attrList->commonattr, sizeof(a)); 3136 d = attrBuf; 3137 dend = d + attrBufSize; 3138 3139 #if DARWIN_VERS >= DARWIN_10_6 3140 // ATTR_CMN_RETURNED_ATTRS tells us what's really here, if set 3141 if (a[0] & ATTR_CMN_RETURNED_ATTRS) { 3142 // fixme range check this? 3143 a[0] &= ~ATTR_CMN_RETURNED_ATTRS; 3144 fn(tid, d, sizeof(attribute_set_t)); 3145 VG_(memcpy)(a, d, sizeof(a)); 3146 } 3147 #endif 3148 3149 for (g = 0; g < 5; g++) { 3150 for (i = 0; attrdefs[g][i].attrBit; i++) { 3151 uint32_t bit = attrdefs[g][i].attrBit; 3152 int32_t size = attrdefs[g][i].attrSize; 3153 3154 if (a[g] & bit) { 3155 a[g] &= ~bit; // clear bit for error check later 3156 if (size == -1) { 3157 attrreference_t *ref = (attrreference_t *)d; 3158 size = MIN(sizeof(attrreference_t), dend - d); 3159 fn(tid, d, size); 3160 if (size >= sizeof(attrreference_t) && 3161 d + ref->attr_dataoffset < dend) 3162 { 3163 fn(tid, d + ref->attr_dataoffset, 3164 MIN(ref->attr_length, dend - (d + ref->attr_dataoffset))); 3165 } 3166 d += size; 3167 } 3168 else { 3169 size = MIN(size, dend - d); 3170 fn(tid, d, size); 3171 d += size; 3172 } 3173 3174 if ((uintptr_t)d % 4) d += 4 - ((uintptr_t)d % 4); 3175 if (d > dend) d = dend; 3176 } 3177 } 3178 3179 // Known bits are cleared. Die if any bits are left. 3180 if (a[g] != 0) { 3181 VG_(message)(Vg_UserMsg, "UNKNOWN attrlist flags %d:0x%x\n", g, a[g]); 3182 } 3183 } 3184 } 3185 3186 static void get1attr(ThreadId tid, void *attrData, SizeT attrDataSize) 3187 { 3188 POST_MEM_WRITE((Addr)attrData, attrDataSize); 3189 } 3190 3191 static void set1attr(ThreadId tid, void *attrData, SizeT attrDataSize) 3192 { 3193 PRE_MEM_READ("setattrlist(attrBuf value)", (Addr)attrData, attrDataSize); 3194 } 3195 3196 PRE(getattrlist) 3197 { 3198 PRINT("getattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)", 3199 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4, ARG5); 3200 PRE_REG_READ5(int, "getattrlist", 3201 const char *,path, struct vki_attrlist *,attrList, 3202 void *,attrBuf, vki_size_t,attrBufSize, unsigned int,options); 3203 PRE_MEM_RASCIIZ("getattrlist(path)", ARG1); 3204 PRE_MEM_READ("getattrlist(attrList)", ARG2, sizeof(struct vki_attrlist)); 3205 PRE_MEM_WRITE("getattrlist(attrBuf)", ARG3, ARG4); 3206 } 3207 3208 POST(getattrlist) 3209 { 3210 if (ARG4 > sizeof(vki_uint32_t)) { 3211 // attrBuf is uint32_t size followed by attr data 3212 vki_uint32_t *sizep = (vki_uint32_t *)ARG3; 3213 POST_MEM_WRITE(ARG3, sizeof(vki_uint32_t)); 3214 if (ARG5 & FSOPT_REPORT_FULLSIZE) { 3215 // *sizep is bytes required for return value, including *sizep 3216 } else { 3217 // *sizep is actual bytes returned, including *sizep 3218 } 3219 scan_attrlist(tid, (struct vki_attrlist *)ARG2, sizep+1, MIN(*sizep, ARG4), &get1attr); 3220 } 3221 } 3222 3223 3224 PRE(setattrlist) 3225 { 3226 PRINT("setattrlist(%#lx(%s), %#lx, %#lx, %lu, %lu)", 3227 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4, ARG5); 3228 PRE_REG_READ5(int, "setattrlist", 3229 const char *,path, struct vki_attrlist *,attrList, 3230 void *,attrBuf, vki_size_t,attrBufSize, unsigned int,options); 3231 PRE_MEM_RASCIIZ("setattrlist(path)", ARG1); 3232 PRE_MEM_READ("setattrlist(attrList)", ARG2, sizeof(struct vki_attrlist)); 3233 scan_attrlist(tid, (struct vki_attrlist *)ARG2, (void*)ARG3, ARG4, &set1attr); 3234 } 3235 3236 3237 PRE(getdirentriesattr) 3238 { 3239 PRINT("getdirentriesattr(%ld, %#lx, %#lx, %lu, %#lx, %#lx, %#lx, %lu)", 3240 SARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); 3241 PRE_REG_READ8(int, "getdirentriesattr", 3242 int,fd, struct vki_attrlist *,attrList, 3243 void *,attrBuf, size_t,attrBufSize, 3244 unsigned int *,count, unsigned int *,basep, 3245 unsigned int *,newState, unsigned int,options); 3246 PRE_MEM_READ("getdirentriesattr(attrList)", 3247 ARG2, sizeof(struct vki_attrlist)); 3248 PRE_MEM_WRITE("getdirentriesattr(attrBuf)", ARG3, ARG4); 3249 PRE_MEM_READ("getdirentriesattr(count)", ARG5, sizeof(unsigned int)); 3250 PRE_MEM_WRITE("getdirentriesattr(count)", ARG5, sizeof(unsigned int)); 3251 PRE_MEM_WRITE("getdirentriesattr(basep)", ARG6, sizeof(unsigned int)); 3252 PRE_MEM_WRITE("getdirentriesattr(newState)", ARG7, sizeof(unsigned int)); 3253 } 3254 POST(getdirentriesattr) 3255 { 3256 char *p, *end; 3257 unsigned int count; 3258 unsigned int i; 3259 3260 POST_MEM_WRITE(ARG5, sizeof(unsigned int)); 3261 POST_MEM_WRITE(ARG6, sizeof(unsigned int)); 3262 POST_MEM_WRITE(ARG7, sizeof(unsigned int)); 3263 3264 // return buffer is concatenation of variable-size structs 3265 count = *(unsigned int *)ARG5; 3266 p = (char *)ARG3; 3267 end = (char *)ARG3 + ARG4; 3268 for (i = 0; i < count; i++) { 3269 vg_assert(p < end); // failure is kernel bug or Valgrind bug 3270 p += *(unsigned int *)p; 3271 } 3272 3273 POST_MEM_WRITE(ARG3, p - (char *)ARG3); 3274 3275 PRINT("got %d records, %ld/%lu bytes\n", 3276 count, (Addr)p-(Addr)ARG3, ARG4); 3277 } 3278 3279 PRE(exchangedata) 3280 { 3281 PRINT("exchangedata(%#lx(%s), %#lx(%s), %lu)", 3282 ARG1, (HChar*)ARG1, ARG2, (HChar*)ARG2, ARG3); 3283 PRE_REG_READ3(int, "exchangedata", 3284 char *, path1, char *, path2, unsigned long, options); 3285 PRE_MEM_RASCIIZ( "exchangedata(path1)", ARG1 ); 3286 PRE_MEM_RASCIIZ( "exchangedata(path2)", ARG2 ); 3287 } 3288 3289 PRE(fsctl) 3290 { 3291 PRINT("fsctl ( %#lx(%s), %lu, %#lx, %lu )", 3292 ARG1, (HChar *)ARG1, ARG2, ARG3, ARG4); 3293 PRE_REG_READ4( long, "fsctl", 3294 char *,"path", unsigned int,"request", 3295 void *,"data", unsigned int,"options"); 3296 3297 PRE_MEM_RASCIIZ( "fsctl(path)", ARG1 ); 3298 3299 switch (ARG2) { 3300 case VKI_afpfsByteRangeLock2FSCTL: { 3301 struct vki_ByteRangeLockPB2 *pb = (struct vki_ByteRangeLockPB2 *)ARG3; 3302 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->offset)", 3303 pb->offset); 3304 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->length)", 3305 pb->length); 3306 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->unLockFlag)", 3307 pb->unLockFlag); 3308 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->startEndFlag)", 3309 pb->startEndFlag); 3310 PRE_FIELD_READ("fsctl(afpfsByteRangeLock2, pb->fd)", 3311 pb->fd); 3312 3313 PRE_FIELD_WRITE("fsctl(afpfsByteRangeLock2, pb->retRangeStart)", 3314 pb->retRangeStart); 3315 3316 // GrP fixme check fd 3317 break; 3318 } 3319 case VKI_FSIOC_SYNC_VOLUME: 3320 PRE_MEM_READ( "fsctl(FSIOC_SYNC_VOLUME)", ARG3, sizeof(int) ); 3321 break; 3322 3323 default: 3324 // fsctl requests use ioctl encoding 3325 ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3); 3326 break; 3327 } 3328 } 3329 3330 POST(fsctl) 3331 { 3332 switch (ARG2) { 3333 case VKI_afpfsByteRangeLock2FSCTL: { 3334 struct vki_ByteRangeLockPB2 *pb = (struct vki_ByteRangeLockPB2 *)ARG3; 3335 POST_FIELD_WRITE(pb->retRangeStart); 3336 break; 3337 } 3338 case VKI_FSIOC_SYNC_VOLUME: 3339 break; 3340 3341 default: 3342 // fsctl requests use ioctl encoding 3343 ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3); 3344 break; 3345 } 3346 } 3347 3348 PRE(initgroups) 3349 { 3350 PRINT("initgroups(%s, %#lx, %lu)", (HChar *)ARG1, ARG2, ARG3); 3351 PRE_REG_READ3(long, "initgroups", 3352 int, setlen, vki_gid_t *, gidset, vki_uid_t, gmuid); 3353 PRE_MEM_READ("gidset", ARG2, ARG1 * sizeof(vki_gid_t)); 3354 } 3355 3356 3357 //--------- posix_spawn ---------// 3358 /* Largely copied from PRE(sys_execve) in syswrap-generic.c, and from 3359 the simpler AIX equivalent (syswrap-aix5.c). */ 3360 // Pre_read a char** argument. 3361 static void pre_argv_envp(Addr a, ThreadId tid, const HChar* s1, const HChar* s2) 3362 { 3363 while (True) { 3364 Addr a_deref; 3365 Addr* a_p = (Addr*)a; 3366 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) ); 3367 a_deref = *a_p; 3368 if (0 == a_deref) 3369 break; 3370 PRE_MEM_RASCIIZ( s2, a_deref ); 3371 a += sizeof(char*); 3372 } 3373 } 3374 static SysRes simple_pre_exec_check ( const HChar* exe_name, 3375 Bool trace_this_child ) 3376 { 3377 Int fd, ret; 3378 SysRes res; 3379 Bool setuid_allowed; 3380 3381 // Check it's readable 3382 res = VG_(open)(exe_name, VKI_O_RDONLY, 0); 3383 if (sr_isError(res)) { 3384 return res; 3385 } 3386 fd = sr_Res(res); 3387 VG_(close)(fd); 3388 3389 // Check we have execute permissions. We allow setuid executables 3390 // to be run only in the case when we are not simulating them, that 3391 // is, they to be run natively. 3392 setuid_allowed = trace_this_child ? False : True; 3393 ret = VG_(check_executable)(NULL/*&is_setuid*/, 3394 exe_name, setuid_allowed); 3395 if (0 != ret) { 3396 return VG_(mk_SysRes_Error)(ret); 3397 } 3398 return VG_(mk_SysRes_Success)(0); 3399 } 3400 PRE(posix_spawn) 3401 { 3402 HChar* path = NULL; /* path to executable */ 3403 HChar** envp = NULL; 3404 HChar** argv = NULL; 3405 HChar** arg2copy; 3406 HChar* launcher_basename = NULL; 3407 Int i, j, tot_args; 3408 SysRes res; 3409 Bool trace_this_child; 3410 3411 /* args: pid_t* pid 3412 char* path 3413 posix_spawn_file_actions_t* file_actions 3414 char** argv 3415 char** envp 3416 */ 3417 PRINT("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )", 3418 ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5 ); 3419 3420 /* Standard pre-syscall checks */ 3421 3422 PRE_REG_READ5(int, "posix_spawn", vki_pid_t*, pid, char*, path, 3423 void*, file_actions, char**, argv, char**, envp ); 3424 PRE_MEM_WRITE("posix_spawn(pid)", ARG1, sizeof(vki_pid_t) ); 3425 PRE_MEM_RASCIIZ("posix_spawn(path)", ARG2); 3426 // DDD: check file_actions 3427 if (ARG4 != 0) 3428 pre_argv_envp( ARG4, tid, "posix_spawn(argv)", 3429 "posix_spawn(argv[i])" ); 3430 if (ARG5 != 0) 3431 pre_argv_envp( ARG5, tid, "posix_spawn(envp)", 3432 "posix_spawn(envp[i])" ); 3433 3434 if (0) 3435 VG_(printf)("posix_spawn( %#lx, %#lx(%s), %#lx, %#lx, %#lx )\n", 3436 ARG1, ARG2, ARG2 ? (HChar*)ARG2 : "(null)", ARG3, ARG4, ARG5 ); 3437 3438 /* Now follows a bunch of logic copied from PRE(sys_execve) in 3439 syswrap-generic.c. */ 3440 3441 /* Check that the name at least begins in client-accessible storage. */ 3442 if (ARG2 == 0 /* obviously bogus */ 3443 || !VG_(am_is_valid_for_client)( ARG2, 1, VKI_PROT_READ )) { 3444 SET_STATUS_Failure( VKI_EFAULT ); 3445 return; 3446 } 3447 3448 // Decide whether or not we want to follow along 3449 { // Make 'child_argv' be a pointer to the child's arg vector 3450 // (skipping the exe name) 3451 const HChar** child_argv = (const HChar**)ARG4; 3452 if (child_argv && child_argv[0] == NULL) 3453 child_argv = NULL; 3454 trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG2, child_argv ); 3455 } 3456 3457 // Do the important checks: it is a file, is executable, permissions are 3458 // ok, etc. We allow setuid executables to run only in the case when 3459 // we are not simulating them, that is, they to be run natively. 3460 res = simple_pre_exec_check( (const HChar*)ARG2, trace_this_child ); 3461 if (sr_isError(res)) { 3462 SET_STATUS_Failure( sr_Err(res) ); 3463 return; 3464 } 3465 3466 /* If we're tracing the child, and the launcher name looks bogus 3467 (possibly because launcher.c couldn't figure it out, see 3468 comments therein) then we have no option but to fail. */ 3469 if (trace_this_child 3470 && (VG_(name_of_launcher) == NULL 3471 || VG_(name_of_launcher)[0] != '/')) { 3472 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */ 3473 return; 3474 } 3475 3476 /* Ok. So let's give it a try. */ 3477 VG_(debugLog)(1, "syswrap", "Posix_spawn of %s\n", (HChar*)ARG2); 3478 3479 /* posix_spawn on Darwin is combining the fork and exec in one syscall. 3480 So, we should not terminate gdbserver : this is still the parent 3481 running, which will terminate its gdbserver when exiting. 3482 If the child process is traced, it will start a fresh gdbserver 3483 after posix_spawn. */ 3484 3485 // Set up the child's exe path. 3486 // 3487 if (trace_this_child) { 3488 3489 // We want to exec the launcher. Get its pre-remembered path. 3490 path = VG_(name_of_launcher); 3491 // VG_(name_of_launcher) should have been acquired by m_main at 3492 // startup. The following two assertions should be assured by 3493 // the "If we're tracking the child .." test just above here. 3494 vg_assert(path); 3495 vg_assert(path[0] == '/'); 3496 launcher_basename = path; 3497 3498 } else { 3499 path = (HChar*)ARG2; 3500 } 3501 3502 // Set up the child's environment. 3503 // 3504 // Remove the valgrind-specific stuff from the environment so the 3505 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc. 3506 // This is done unconditionally, since if we are tracing the child, 3507 // the child valgrind will set up the appropriate client environment. 3508 // Nb: we make a copy of the environment before trying to mangle it 3509 // as it might be in read-only memory (this was bug #101881). 3510 // 3511 // Then, if tracing the child, set VALGRIND_LIB for it. 3512 // 3513 if (ARG5 == 0) { 3514 envp = NULL; 3515 } else { 3516 envp = VG_(env_clone)( (HChar**)ARG5 ); 3517 vg_assert(envp); 3518 VG_(env_remove_valgrind_env_stuff)( envp, /* ro_strings */ False, NULL); 3519 } 3520 3521 if (trace_this_child) { 3522 // Set VALGRIND_LIB in ARG5 (the environment) 3523 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir)); 3524 } 3525 3526 // Set up the child's args. If not tracing it, they are 3527 // simply ARG4. Otherwise, they are 3528 // 3529 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG2] ++ ARG4[1..] 3530 // 3531 // except that the first VG_(args_for_valgrind_noexecpass) args 3532 // are omitted. 3533 // 3534 if (!trace_this_child) { 3535 argv = (HChar**)ARG4; 3536 } else { 3537 vg_assert( VG_(args_for_valgrind) ); 3538 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 ); 3539 vg_assert( VG_(args_for_valgrind_noexecpass) 3540 <= VG_(sizeXA)( VG_(args_for_valgrind) ) ); 3541 /* how many args in total will there be? */ 3542 // launcher basename 3543 tot_args = 1; 3544 // V's args 3545 tot_args += VG_(sizeXA)( VG_(args_for_valgrind) ); 3546 tot_args -= VG_(args_for_valgrind_noexecpass); 3547 // name of client exe 3548 tot_args++; 3549 // args for client exe, skipping [0] 3550 arg2copy = (HChar**)ARG4; 3551 if (arg2copy && arg2copy[0]) { 3552 for (i = 1; arg2copy[i]; i++) 3553 tot_args++; 3554 } 3555 // allocate 3556 argv = VG_(malloc)( "di.syswrap.pre_sys_execve.1", 3557 (tot_args+1) * sizeof(HChar*) ); 3558 // copy 3559 j = 0; 3560 argv[j++] = launcher_basename; 3561 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) { 3562 if (i < VG_(args_for_valgrind_noexecpass)) 3563 continue; 3564 argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ); 3565 } 3566 argv[j++] = (HChar*)ARG2; 3567 if (arg2copy && arg2copy[0]) 3568 for (i = 1; arg2copy[i]; i++) 3569 argv[j++] = arg2copy[i]; 3570 argv[j++] = NULL; 3571 // check 3572 vg_assert(j == tot_args+1); 3573 } 3574 3575 /* DDD: sort out the signal state. What signal 3576 state does the child inherit from the parent? */ 3577 3578 if (0) { 3579 HChar **cpp; 3580 VG_(printf)("posix_spawn: %s\n", path); 3581 for (cpp = argv; cpp && *cpp; cpp++) 3582 VG_(printf)("argv: %s\n", *cpp); 3583 if (1) 3584 for (cpp = envp; cpp && *cpp; cpp++) 3585 VG_(printf)("env: %s\n", *cpp); 3586 } 3587 3588 /* Let the call go through as usual. However, we have to poke 3589 the altered arguments back into the argument slots. */ 3590 ARG2 = (UWord)path; 3591 ARG4 = (UWord)argv; 3592 ARG5 = (UWord)envp; 3593 3594 /* not to mention .. */ 3595 *flags |= SfMayBlock; 3596 } 3597 POST(posix_spawn) 3598 { 3599 vg_assert(SUCCESS); 3600 if (ARG1 != 0) { 3601 POST_MEM_WRITE( ARG1, sizeof(vki_pid_t) ); 3602 } 3603 } 3604 3605 3606 PRE(socket) 3607 { 3608 PRINT("socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3); 3609 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol); 3610 } 3611 3612 POST(socket) 3613 { 3614 SysRes r; 3615 vg_assert(SUCCESS); 3616 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES)); 3617 SET_STATUS_from_SysRes(r); 3618 } 3619 3620 3621 PRE(setsockopt) 3622 { 3623 PRINT("setsockopt ( %ld, %ld, %ld, %#lx, %ld )", 3624 SARG1, SARG2, SARG3, ARG4, SARG5); 3625 PRE_REG_READ5(long, "setsockopt", 3626 int, s, int, level, int, optname, 3627 const void *, optval, vki_socklen_t, optlen); 3628 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); 3629 } 3630 3631 3632 PRE(getsockopt) 3633 { 3634 Addr optval_p = ARG4; 3635 Addr optlen_p = ARG5; 3636 PRINT("getsockopt ( %ld, %ld, %ld, %#lx, %#lx )", 3637 SARG1, SARG2, SARG3, ARG4, ARG5); 3638 PRE_REG_READ5(long, "getsockopt", 3639 int, s, int, level, int, optname, 3640 void *, optval, vki_socklen_t *, optlen); 3641 /* int getsockopt(int socket, int level, int option_name, 3642 void *restrict option_value, 3643 socklen_t *restrict option_len); */ 3644 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */ 3645 if (optval_p != (Addr)NULL) { 3646 ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p, 3647 "socketcall.getsockopt(optval)", 3648 "socketcall.getsockopt(optlen)" ); 3649 } 3650 // DDD: #warning GrP fixme darwin-specific sockopts 3651 } 3652 3653 POST(getsockopt) 3654 { 3655 Addr optval_p = ARG4; 3656 Addr optlen_p = ARG5; 3657 vg_assert(SUCCESS); 3658 if (optval_p != (Addr)NULL) { 3659 ML_(buf_and_len_post_check) ( tid, VG_(mk_SysRes_Success)(RES), 3660 optval_p, optlen_p, 3661 "socketcall.getsockopt(optlen_out)" ); 3662 // DDD: #warning GrP fixme darwin-specific sockopts 3663 } 3664 } 3665 3666 3667 PRE(connect) 3668 { 3669 *flags |= SfMayBlock; 3670 PRINT("connect ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3); 3671 PRE_REG_READ3(long, "connect", 3672 int, sockfd, struct sockaddr *, serv_addr, int, addrlen); 3673 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3); 3674 } 3675 3676 3677 PRE(accept) 3678 { 3679 *flags |= SfMayBlock; 3680 PRINT("accept ( %ld, %#lx, %#lx )", SARG1, ARG2, SARG3); 3681 PRE_REG_READ3(long, "accept", 3682 int, s, struct sockaddr *, addr, int *, addrlen); 3683 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); 3684 } 3685 3686 POST(accept) 3687 { 3688 SysRes r; 3689 vg_assert(SUCCESS); 3690 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), 3691 ARG1,ARG2,ARG3); 3692 SET_STATUS_from_SysRes(r); 3693 } 3694 3695 PRE(mkfifo) 3696 { 3697 *flags |= SfMayBlock; 3698 PRINT("mkfifo ( %#lx(%s), %lx )", ARG1, (HChar *)ARG1, ARG2); 3699 PRE_REG_READ2(long, "mkfifo", const char *, path, vki_mode_t, mode); 3700 PRE_MEM_RASCIIZ( "mkfifo(path)", ARG1 ); 3701 } 3702 3703 POST(mkfifo) 3704 { 3705 vg_assert(SUCCESS); 3706 if (!ML_(fd_allowed)(RES, "mkfifo", tid, True)) { 3707 VG_(close)(RES); 3708 SET_STATUS_Failure( VKI_EMFILE ); 3709 } else { 3710 if (VG_(clo_track_fds)) 3711 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); 3712 } 3713 } 3714 3715 PRE(sendto) 3716 { 3717 *flags |= SfMayBlock; 3718 PRINT("sendto ( %ld, %s, %ld, %lu, %#lx, %ld )", 3719 SARG1, (HChar *)ARG2, SARG3, ARG4, ARG5, SARG6); 3720 PRE_REG_READ6(long, "sendto", 3721 int, s, const void *, msg, int, len, 3722 unsigned int, flags, 3723 const struct sockaddr *, to, int, tolen); 3724 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 3725 } 3726 3727 PRE(sendfile) 3728 { 3729 #if VG_WORDSIZE == 4 3730 PRINT("sendfile(%ld, %ld, %llu, %#lx, %#lx, %ld)", 3731 SARG1, SARG2, LOHI64(ARG3, ARG4), ARG5, ARG6, SARG7); 3732 3733 PRE_REG_READ7(long, "sendfile", 3734 int, fromfd, int, tofd, 3735 vki_uint32_t, offset_low32, vki_uint32_t, offset_high32, 3736 vki_uint64_t *, nwritten, struct sf_hdtr *, sf_header, int, flags); 3737 PRE_MEM_WRITE("sendfile(nwritten)", ARG5, sizeof(vki_uint64_t)); 3738 if (ARG6) PRE_MEM_WRITE("sendfile(sf_header)", ARG6, sizeof(struct sf_hdtr)); 3739 #else 3740 PRINT("sendfile(%ld, %ld, %lu, %#lx, %#lx, %ld)", 3741 SARG1, SARG2, ARG3, ARG4, ARG5, SARG6); 3742 3743 PRE_REG_READ6(long, "sendfile", 3744 int, fromfd, int, tofd, 3745 vki_uint64_t, offset, 3746 vki_uint64_t *, nwritten, struct sf_hdtr *, sf_header, int, flags); 3747 PRE_MEM_WRITE("sendfile(nwritten)", ARG4, sizeof(vki_uint64_t)); 3748 if (ARG5) PRE_MEM_WRITE("sendfile(sf_header)", ARG5, sizeof(struct sf_hdtr)); 3749 #endif 3750 3751 *flags |= SfMayBlock; 3752 } 3753 POST(sendfile) 3754 { 3755 #if VG_WORDSIZE == 4 3756 POST_MEM_WRITE(ARG5, sizeof(vki_uint64_t)); 3757 if (ARG6) POST_MEM_WRITE(ARG6, sizeof(struct sf_hdtr)); 3758 #else 3759 POST_MEM_WRITE(ARG4, sizeof(vki_uint64_t)); 3760 if (ARG5) POST_MEM_WRITE(ARG5, sizeof(struct sf_hdtr)); 3761 #endif 3762 } 3763 3764 PRE(recvfrom) 3765 { 3766 *flags |= SfMayBlock; 3767 PRINT("recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )", 3768 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6); 3769 PRE_REG_READ6(long, "recvfrom", 3770 int, s, void *, buf, int, len, unsigned int, flags, 3771 struct sockaddr *, from, int *, fromlen); 3772 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 3773 } 3774 3775 POST(recvfrom) 3776 { 3777 vg_assert(SUCCESS); 3778 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES), 3779 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 3780 } 3781 3782 3783 PRE(sendmsg) 3784 { 3785 *flags |= SfMayBlock; 3786 PRINT("sendmsg ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3); 3787 PRE_REG_READ3(long, "sendmsg", 3788 int, s, const struct msghdr *, msg, int, flags); 3789 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2); 3790 } 3791 3792 3793 PRE(recvmsg) 3794 { 3795 *flags |= SfMayBlock; 3796 PRINT("recvmsg ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3); 3797 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags); 3798 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2); 3799 } 3800 3801 POST(recvmsg) 3802 { 3803 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES); 3804 } 3805 3806 3807 PRE(shutdown) 3808 { 3809 *flags |= SfMayBlock; 3810 PRINT("shutdown ( %ld, %ld )", SARG1, SARG2); 3811 PRE_REG_READ2(int, "shutdown", int, s, int, how); 3812 } 3813 3814 3815 PRE(bind) 3816 { 3817 PRINT("bind ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3); 3818 PRE_REG_READ3(long, "bind", 3819 int, sockfd, struct sockaddr *, my_addr, int, addrlen); 3820 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3); 3821 } 3822 3823 3824 PRE(listen) 3825 { 3826 PRINT("listen ( %ld, %ld )", SARG1, SARG2); 3827 PRE_REG_READ2(long, "listen", int, s, int, backlog); 3828 } 3829 3830 3831 PRE(getsockname) 3832 { 3833 PRINT("getsockname ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); 3834 PRE_REG_READ3(long, "getsockname", 3835 int, s, struct sockaddr *, name, int *, namelen); 3836 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3); 3837 } 3838 3839 POST(getsockname) 3840 { 3841 vg_assert(SUCCESS); 3842 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES), 3843 ARG1,ARG2,ARG3); 3844 } 3845 3846 3847 PRE(getpeername) 3848 { 3849 PRINT("getpeername ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); 3850 PRE_REG_READ3(long, "getpeername", 3851 int, s, struct sockaddr *, name, int *, namelen); 3852 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3); 3853 } 3854 3855 POST(getpeername) 3856 { 3857 vg_assert(SUCCESS); 3858 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES), 3859 ARG1,ARG2,ARG3); 3860 } 3861 3862 3863 PRE(socketpair) 3864 { 3865 PRINT("socketpair ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4); 3866 PRE_REG_READ4(long, "socketpair", 3867 int, d, int, type, int, protocol, int *, sv); 3868 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4); 3869 } 3870 3871 POST(socketpair) 3872 { 3873 vg_assert(SUCCESS); 3874 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES), 3875 ARG1,ARG2,ARG3,ARG4); 3876 } 3877 3878 3879 PRE(gethostuuid) 3880 { 3881 PRINT("gethostuuid ( %#lx, %#lx )", ARG1, ARG2); 3882 PRE_REG_READ2(int,"gethostuuid", 3883 char *,"uuid_buf", 3884 const struct vki_timespec *,"timeout"); 3885 3886 PRE_MEM_WRITE("uuid_buf", ARG1, 16); 3887 PRE_MEM_READ("timeout", ARG2, sizeof(struct vki_timespec)); 3888 3889 *flags |= SfMayBlock; 3890 } 3891 3892 3893 POST(gethostuuid) 3894 { 3895 POST_MEM_WRITE(ARG1, 16); 3896 } 3897 3898 /* Darwin pipe() returns the two descriptors in two registers. */ 3899 PRE(pipe) 3900 { 3901 PRINT("pipe ( )"); 3902 PRE_REG_READ0(int, "pipe"); 3903 } 3904 3905 POST(pipe) 3906 { 3907 Int p0, p1; 3908 vg_assert(SUCCESS); 3909 p0 = RES; 3910 p1 = RESHI; 3911 3912 if (!ML_(fd_allowed)(p0, "pipe", tid, True) || 3913 !ML_(fd_allowed)(p1, "pipe", tid, True)) { 3914 VG_(close)(p0); 3915 VG_(close)(p1); 3916 SET_STATUS_Failure( VKI_EMFILE ); 3917 } else { 3918 if (VG_(clo_track_fds)) { 3919 ML_(record_fd_open_nameless)(tid, p0); 3920 ML_(record_fd_open_nameless)(tid, p1); 3921 } 3922 } 3923 } 3924 3925 3926 PRE(getlogin) 3927 { 3928 PRINT("getlogin ( %#lx, %lu )", ARG1, ARG2); 3929 PRE_REG_READ2(long, "getlogin", 3930 char *,"namebuf", unsigned int,"namelen"); 3931 3932 PRE_MEM_WRITE("getlogin(namebuf)", ARG1, ARG2); 3933 } 3934 3935 POST(getlogin) 3936 { 3937 POST_MEM_WRITE(ARG1, ARG2); 3938 } 3939 3940 3941 PRE(ptrace) 3942 { 3943 PRINT("ptrace ( %ld, %ld, %#lx, %ld )", SARG1, SARG2, ARG3, SARG4); 3944 PRE_REG_READ4(long, "ptrace", 3945 int,"request", vki_pid_t,"pid", 3946 vki_caddr_t,"addr", int,"data"); 3947 3948 // Note: some code uses ptrace(random, 0, 0, 0) as a profiling mechanism. 3949 3950 // GrP fixme anything needed? 3951 } 3952 3953 3954 PRE(issetugid) 3955 { 3956 PRINT("issetugid ( )"); 3957 PRE_REG_READ0(long, "issetugid"); 3958 } 3959 3960 3961 PRE(getdtablesize) 3962 { 3963 PRINT("getdtablesize ( )"); 3964 PRE_REG_READ0(long, "getdtablesize"); 3965 } 3966 3967 POST(getdtablesize) 3968 { 3969 // Subtract Valgrind's fd range from client's dtable 3970 if (RES > VG_(fd_hard_limit)) SET_STATUS_Success(VG_(fd_hard_limit)); 3971 } 3972 3973 PRE(lseek) 3974 { 3975 PRINT("lseek ( %lu, %ld, %ld )", ARG1, SARG2, SARG3); 3976 PRE_REG_READ4(vki_off_t, "lseek", 3977 unsigned int,fd, int,offset_hi, int,offset_lo, 3978 unsigned int,whence); 3979 } 3980 3981 3982 PRE(pathconf) 3983 { 3984 PRINT("pathconf(%#lx(%s), %ld)", ARG1, (HChar *)ARG1, SARG2); 3985 PRE_REG_READ2(long,"pathconf", const char *,"path", int,"name"); 3986 PRE_MEM_RASCIIZ("pathconf(path)", ARG1); 3987 } 3988 3989 3990 PRE(fpathconf) 3991 { 3992 PRINT("fpathconf(%ld, %ld)", SARG1, SARG2); 3993 PRE_REG_READ2(long,"fpathconf", int,"fd", int,"name"); 3994 3995 if (!ML_(fd_allowed)(ARG1, "fpathconf", tid, False)) 3996 SET_STATUS_Failure( VKI_EBADF ); 3997 } 3998 3999 4000 PRE(getdirentries) 4001 { 4002 PRINT("getdirentries(%ld, %#lx, %ld, %#lx)", SARG1, ARG2, SARG3, ARG4); 4003 PRE_REG_READ4(int, "getdirentries", 4004 int, fd, char *, buf, int, nbytes, long *, basep); 4005 PRE_MEM_WRITE("getdirentries(basep)", ARG4, sizeof(long)); 4006 PRE_MEM_WRITE("getdirentries(buf)", ARG2, ARG3); 4007 } 4008 4009 POST(getdirentries) 4010 { 4011 POST_MEM_WRITE(ARG4, sizeof(long)); 4012 // GrP fixme be specific about d_name? 4013 POST_MEM_WRITE(ARG2, RES); 4014 } 4015 4016 4017 PRE(getdirentries64) 4018 { 4019 PRINT("getdirentries64(%ld, %#lx, %lu, %#lx)", SARG1, ARG2, ARG3, ARG4); 4020 PRE_REG_READ4(vki_ssize_t, "getdirentries", 4021 int,fd, char *,buf, vki_size_t,nbytes, vki_off_t *,basep); 4022 /* JRS 18-Nov-2014: it appears that sometimes |basep| doesn't point 4023 to valid memory and the kernel doesn't modify it. I can't 4024 determine the conditions under which that happens. But it 4025 causes Memcheck to complain, confusingly. So disable this check 4026 for the time being. 4027 4028 PRE_MEM_WRITE("getdirentries64(position)", ARG4, sizeof(vki_off_t)); 4029 */ 4030 PRE_MEM_WRITE("getdirentries64(buf)", ARG2, ARG3); 4031 } 4032 POST(getdirentries64) 4033 { 4034 /* Disabled; see comments in the PRE wrapper. 4035 POST_MEM_WRITE(ARG4, sizeof(vki_off_t)); 4036 */ 4037 // GrP fixme be specific about d_name? (fixme copied from 32 bit version) 4038 POST_MEM_WRITE(ARG2, RES); 4039 } 4040 4041 4042 PRE(statfs64) 4043 { 4044 PRINT("statfs64 ( %#lx(%s), %#lx )", ARG1, (HChar *)ARG1, ARG2); 4045 PRE_REG_READ2(long, "statfs64", const char *, path, struct statfs64 *, buf); 4046 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 ); 4047 PRE_MEM_WRITE( "statfs64(buf)", ARG2, sizeof(struct vki_statfs64) ); 4048 } 4049 POST(statfs64) 4050 { 4051 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs64) ); 4052 } 4053 4054 4055 PRE(fstatfs64) 4056 { 4057 PRINT("fstatfs64 ( %lu, %#lx )", ARG1, ARG2); 4058 PRE_REG_READ2(long, "fstatfs64", 4059 unsigned int, fd, struct statfs *, buf); 4060 PRE_MEM_WRITE( "fstatfs64(buf)", ARG2, sizeof(struct vki_statfs64) ); 4061 } 4062 POST(fstatfs64) 4063 { 4064 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs64) ); 4065 } 4066 4067 PRE(csops) 4068 { 4069 PRINT("csops ( %ld, %#lx, %#lx, %lu )", SARG1, ARG2, ARG3, ARG4); 4070 PRE_REG_READ4(int, "csops", 4071 vki_pid_t, pid, uint32_t, ops, 4072 void *, useraddr, vki_size_t, usersize); 4073 4074 PRE_MEM_WRITE( "csops(useraddr)", ARG3, ARG4 ); 4075 4076 // If the pid is ours, don't mark the program as KILL or HARD 4077 // Maybe we should keep track of this for later calls to STATUS 4078 if (!ARG1 || VG_(getpid)() == ARG1) { 4079 switch (ARG2) { 4080 case VKI_CS_OPS_MARKINVALID: 4081 case VKI_CS_OPS_MARKHARD: 4082 case VKI_CS_OPS_MARKKILL: 4083 SET_STATUS_Success(0); 4084 } 4085 } 4086 } 4087 POST(csops) 4088 { 4089 POST_MEM_WRITE( ARG3, ARG4 ); 4090 } 4091 4092 PRE(auditon) 4093 { 4094 PRINT("auditon ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3); 4095 PRE_REG_READ3(int,"auditon", 4096 int,"cmd", void*,"data", unsigned int,"length"); 4097 4098 switch (ARG1) { 4099 4100 case VKI_A_SETPOLICY: 4101 case VKI_A_SETKMASK: 4102 case VKI_A_SETQCTRL: 4103 case VKI_A_SETCOND: 4104 case VKI_A_SETCLASS: 4105 case VKI_A_SETPMASK: 4106 case VKI_A_SETFSIZE: 4107 #if DARWIN_VERS >= DARWIN_10_6 4108 case VKI_A_SENDTRIGGER: 4109 #endif 4110 // kernel reads data..data+length 4111 PRE_MEM_READ("auditon(data)", ARG2, ARG3); 4112 break; 4113 4114 case VKI_A_GETKMASK: 4115 case VKI_A_GETPOLICY: 4116 case VKI_A_GETQCTRL: 4117 case VKI_A_GETFSIZE: 4118 case VKI_A_GETCOND: 4119 // kernel writes data..data+length 4120 // GrP fixme be precise about what gets written 4121 PRE_MEM_WRITE("auditon(data)", ARG2, ARG3); 4122 break; 4123 4124 4125 case VKI_A_GETCLASS: 4126 case VKI_A_GETPINFO: 4127 case VKI_A_GETPINFO_ADDR: 4128 #if DARWIN_VERS >= DARWIN_10_6 4129 case VKI_A_GETSINFO_ADDR: 4130 #endif 4131 // kernel reads and writes data..data+length 4132 // GrP fixme be precise about what gets read and written 4133 PRE_MEM_READ("auditon(data)", ARG2, ARG3); 4134 PRE_MEM_WRITE("auditon(data)", ARG2, ARG3); 4135 break; 4136 4137 case VKI_A_SETKAUDIT: 4138 case VKI_A_SETSTAT: 4139 case VKI_A_SETUMASK: 4140 case VKI_A_SETSMASK: 4141 case VKI_A_GETKAUDIT: 4142 case VKI_A_GETCWD: 4143 case VKI_A_GETCAR: 4144 case VKI_A_GETSTAT: 4145 // unimplemented on darwin 4146 break; 4147 4148 default: 4149 VG_(message)(Vg_UserMsg, "UNKNOWN auditon cmd %ld\n", ARG1); 4150 break; 4151 } 4152 } 4153 POST(auditon) 4154 { 4155 switch (ARG1) { 4156 4157 case VKI_A_SETPOLICY: 4158 case VKI_A_SETKMASK: 4159 case VKI_A_SETQCTRL: 4160 case VKI_A_SETCOND: 4161 case VKI_A_SETCLASS: 4162 case VKI_A_SETPMASK: 4163 case VKI_A_SETFSIZE: 4164 #if DARWIN_VERS >= DARWIN_10_6 4165 case VKI_A_SENDTRIGGER: 4166 #endif 4167 // kernel reads data..data+length 4168 break; 4169 4170 case VKI_A_GETKMASK: 4171 case VKI_A_GETPOLICY: 4172 case VKI_A_GETQCTRL: 4173 case VKI_A_GETFSIZE: 4174 case VKI_A_GETCOND: 4175 // kernel writes data..data+length 4176 // GrP fixme be precise about what gets written 4177 POST_MEM_WRITE(ARG2, ARG3); 4178 break; 4179 4180 4181 case VKI_A_GETCLASS: 4182 case VKI_A_GETPINFO: 4183 case VKI_A_GETPINFO_ADDR: 4184 #if DARWIN_VERS >= DARWIN_10_6 4185 case VKI_A_GETSINFO_ADDR: 4186 #endif 4187 // kernel reads and writes data..data+length 4188 // GrP fixme be precise about what gets read and written 4189 POST_MEM_WRITE(ARG2, ARG3); 4190 break; 4191 4192 case VKI_A_SETKAUDIT: 4193 case VKI_A_SETSTAT: 4194 case VKI_A_SETUMASK: 4195 case VKI_A_SETSMASK: 4196 case VKI_A_GETKAUDIT: 4197 case VKI_A_GETCWD: 4198 case VKI_A_GETCAR: 4199 case VKI_A_GETSTAT: 4200 // unimplemented on darwin 4201 break; 4202 4203 default: 4204 break; 4205 } 4206 } 4207 4208 PRE(getaudit_addr) 4209 { 4210 PRINT("getaudit_addr(%#lx, %ld)", ARG1, SARG2); 4211 PRE_REG_READ1(void*, "auditinfo_addr", int, "length"); 4212 PRE_MEM_WRITE("getaudit_addr(auditinfo_addr)", ARG1, ARG2); 4213 } 4214 POST(getaudit_addr) 4215 { 4216 POST_MEM_WRITE(ARG1, ARG2); 4217 } 4218 4219 4220 PRE(mmap) 4221 { 4222 // SysRes r; 4223 if (0) VG_(am_do_sync_check)("(PRE_MMAP)",__FILE__,__LINE__); 4224 4225 #if VG_WORDSIZE == 4 4226 PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %llu )", 4227 ARG1, ARG2, SARG3, SARG4, SARG5, LOHI64(ARG6, ARG7) ); 4228 PRE_REG_READ7(Addr, "mmap", 4229 Addr,start, vki_size_t,length, int,prot, int,flags, int,fd, 4230 unsigned long,offset_hi, unsigned long,offset_lo); 4231 // GrP fixme V mmap and kernel mach_msg collided once - don't use 4232 // V's mechanism for now 4233 // r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 4234 // (Off64T)LOHI64(ARG6, ARG7) ); 4235 #else 4236 PRINT("mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )", 4237 ARG1, ARG2, SARG3, SARG4, SARG5, SARG6 ); 4238 PRE_REG_READ6(long, "mmap", 4239 Addr,start, vki_size_t,length, int,prot, int,flags, int,fd, 4240 Off64T,offset); 4241 // r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 ); 4242 4243 #endif 4244 4245 // SET_STATUS_from_SysRes(r); 4246 } 4247 4248 POST(mmap) 4249 { 4250 if (RES != -1) { 4251 ML_(notify_core_and_tool_of_mmap)(RES, ARG2, ARG3, ARG4, ARG5, ARG6); 4252 // Try to load symbols from the region 4253 VG_(di_notify_mmap)( (Addr)RES, False/*allow_SkFileV*/, 4254 -1/*don't use_fd*/ ); 4255 ML_(sync_mappings)("after", "mmap", 0); 4256 } 4257 } 4258 4259 4260 /* This function holds common elements of PRE(__sysctl) and 4261 PRE(sysctlbyname). */ 4262 static void common_PRE_sysctl ( 4263 /*IMPLICIT ARGS*/ 4264 ThreadId tid, /*OUT*/SyscallStatus* status, /*OUT*/UWord* flags, 4265 /*!IMPLICIT ARGS*/ 4266 Bool is_kern_dot_userstack, 4267 UWord oldp, UWord oldlenp, 4268 UWord newp, UWord newlen ) 4269 { 4270 if (oldlenp) { 4271 // writes *oldlenp 4272 PRE_MEM_WRITE("sysctl(oldlenp)", oldlenp, sizeof(size_t)); 4273 if (oldp) { 4274 // also reads *oldlenp, and writes up to oldp[0..(*oldlenp)-1] 4275 PRE_MEM_READ("sysctl(oldlenp)", oldlenp, sizeof(size_t)); 4276 PRE_MEM_WRITE("sysctl(oldp)", oldp, *(size_t*)oldlenp); 4277 } 4278 } 4279 if (newp) { 4280 PRE_MEM_READ("sysctl(newp)", newp, newlen); 4281 } 4282 4283 // GrP fixme intercept KERN_PROCARGS and KERN_PROC_PID for our pid 4284 // (executable path and arguments and environment 4285 4286 if (is_kern_dot_userstack) { 4287 // Intercept sysctl(kern.usrstack). The kernel's reply 4288 // would be Valgrind's stack, not the client's stack. 4289 // GrP fixme kern_usrstack64 */ 4290 if (newp || newlen) { 4291 SET_STATUS_Failure(VKI_EPERM); // USRSTACK is read-only */ 4292 } else { 4293 Addr* t_oldp = (Addr*)oldp; 4294 size_t* t_oldlenp = (size_t*)oldlenp; 4295 if (t_oldlenp) { 4296 // According to some searches on the net, it looks like 4297 // USRSTACK gives the address of the byte following the 4298 // highest byte of the stack. As VG_(clstk_end) is the 4299 // address of the highest addressable byte, we add 1. 4300 Addr stack_end = VG_(clstk_end)+1; 4301 size_t oldlen = *t_oldlenp; 4302 // always return actual size 4303 *t_oldlenp = sizeof(Addr); 4304 if (t_oldp && oldlen >= sizeof(Addr)) { 4305 // oldp is big enough. copy value and return 0 4306 *t_oldp = stack_end; 4307 SET_STATUS_Success(0); 4308 } else { 4309 // oldp isn't big enough. copy as much as possible 4310 // and return ENOMEM 4311 if (t_oldp) VG_(memcpy)(t_oldp, &stack_end, oldlen); 4312 SET_STATUS_Failure(VKI_ENOMEM); 4313 } 4314 } 4315 } 4316 } 4317 4318 if (!SUCCESS && !FAILURE) { 4319 // Don't set SfPostOnFail if we've already handled it locally. 4320 *flags |= SfPostOnFail; 4321 } 4322 } 4323 4324 4325 PRE(__sysctl) 4326 { 4327 UWord name = ARG1; 4328 UWord namelen = ARG2; 4329 UWord oldp = ARG3; 4330 UWord oldlenp = ARG4; 4331 UWord newp = ARG5; 4332 UWord newlen = ARG6; 4333 4334 PRINT( "__sysctl ( %#lx, %lu, %#lx, %#lx, %#lx, %#lx )", 4335 name, namelen, oldp, oldlenp, newp, newlen ); 4336 4337 PRE_REG_READ6(int, "__sysctl", int*, name, unsigned int, namelen, 4338 void*, oldp, vki_size_t *, oldlenp, 4339 void*, newp, vki_size_t *, newlenp); 4340 4341 PRE_MEM_READ("sysctl(name)", name, namelen); // reads name[0..namelen-1] 4342 4343 if (VG_(clo_trace_syscalls)) { 4344 UInt i; 4345 Int* t_name = (Int*)name; 4346 VG_(printf)(" mib: [ "); 4347 for (i = 0; i < namelen; i++) { 4348 VG_(printf)("%d ", t_name[i]); 4349 } 4350 VG_(printf)("]"); 4351 } 4352 4353 Int vKI_KERN_USRSTACKXX 4354 = VG_WORDSIZE == 4 ? VKI_KERN_USRSTACK32 : VKI_KERN_USRSTACK64; 4355 Bool is_kern_dot_userstack 4356 = name && namelen == 2 4357 && ((Int*)name)[0] == VKI_CTL_KERN 4358 && ((Int*)name)[1] == vKI_KERN_USRSTACKXX; 4359 4360 common_PRE_sysctl( /*IMPLICIT ARGS*/tid,status,flags,/*!IMPLICIT_ARGS*/ 4361 is_kern_dot_userstack, oldp, oldlenp, newp, newlen ); 4362 } 4363 4364 POST(__sysctl) 4365 { 4366 UWord oldp = ARG3; 4367 UWord oldlenp = ARG4; 4368 4369 if (SUCCESS || ERR == VKI_ENOMEM) { 4370 // sysctl can write truncated data and return VKI_ENOMEM 4371 if (oldlenp) { 4372 POST_MEM_WRITE(oldlenp, sizeof(size_t)); 4373 } 4374 if (oldp && oldlenp) { 4375 POST_MEM_WRITE(oldp, *(size_t*)oldlenp); 4376 } 4377 } 4378 } 4379 4380 4381 PRE(sigpending) 4382 { 4383 PRINT( "sigpending ( %#lx )", ARG1 ); 4384 PRE_REG_READ1(long, "sigpending", vki_sigset_t *, set); 4385 PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_sigset_t)); 4386 } 4387 POST(sigpending) 4388 { 4389 POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ; 4390 } 4391 4392 4393 PRE(sigprocmask) 4394 { 4395 UWord arg1; 4396 PRINT("sigprocmask ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); 4397 PRE_REG_READ3(long, "sigprocmask", 4398 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset); 4399 if (ARG2 != 0) 4400 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t)); 4401 if (ARG3 != 0) 4402 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t)); 4403 4404 /* Massage ARG1 ('how'). If ARG2 (the new mask) is NULL then the 4405 value of 'how' is irrelevant, and it appears that Darwin's libc 4406 passes zero, which is not equal to any of 4407 SIG_{BLOCK,UNBLOCK,SETMASK}. This causes 4408 VG_(do_sys_sigprocmask) to complain, since it checks the 'how' 4409 value independently of the other args. Solution: in this case, 4410 simply pass a valid (but irrelevant) value for 'how'. */ 4411 /* Also, in this case the new set is passed to the kernel by 4412 reference, not value, as in some other sigmask related Darwin 4413 syscalls. */ 4414 arg1 = ARG1; 4415 if (ARG2 == 0 /* the new-set is NULL */ 4416 && ARG1 != VKI_SIG_BLOCK 4417 && ARG1 != VKI_SIG_UNBLOCK && ARG1 != VKI_SIG_SETMASK) { 4418 arg1 = VKI_SIG_SETMASK; 4419 } 4420 SET_STATUS_from_SysRes( 4421 VG_(do_sys_sigprocmask) ( tid, arg1, (vki_sigset_t*)ARG2, 4422 (vki_sigset_t*)ARG3 ) 4423 ); 4424 4425 if (SUCCESS) 4426 *flags |= SfPollAfter; 4427 } 4428 4429 POST(sigprocmask) 4430 { 4431 vg_assert(SUCCESS); 4432 if (RES == 0 && ARG3 != 0) 4433 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t)); 4434 } 4435 4436 4437 PRE(sigsuspend) 4438 { 4439 /* Just hand this off to the kernel. Is that really correct? And 4440 shouldn't we at least set SfPollAfter? These questions apply to 4441 all the Linux versions too. */ 4442 /* I think the first arg is the 32-bit signal mask (by value), and 4443 the other two args are ignored. */ 4444 *flags |= SfMayBlock; 4445 PRINT("sigsuspend ( mask=0x%08lx )", ARG1 ); 4446 PRE_REG_READ1(int, "sigsuspend", int, sigmask); 4447 } 4448 4449 4450 /* Be careful about the 4th arg, since that is a uint64_t. Hence 64- 4451 and 32-bit wrappers are different. 4452 4453 ARG5 and ARG6 (buffer, buffersize) specify a buffer start and 4454 length in the usual way. I have seen values NULL, 0 passed in some 4455 cases. I left the calls to PRE_MEM_WRITE/READ unconditional on the 4456 basis that they don't do anything if the length is zero, so it's OK 4457 for the buffer pointer to be NULL in that case (meaning they don't 4458 complain). 4459 4460 int proc_info(int32_t callnum, int32_t pid, 4461 uint32_t flavor, uint64_t arg, 4462 user_addr_t buffer, int32_t buffersize) 4463 */ 4464 PRE(proc_info) 4465 { 4466 #if VG_WORDSIZE == 4 4467 PRINT("proc_info(%d, %d, %u, %llu, %#lx, %d)", 4468 (Int)ARG1, (Int)ARG2, (UInt)ARG3, LOHI64(ARG4,ARG5), ARG6, (Int)ARG7); 4469 PRE_REG_READ7(int, "proc_info", 4470 int, callnum, int, pid, unsigned int, flavor, 4471 vki_uint32_t, arg_low32, 4472 vki_uint32_t, arg_high32, 4473 void*, buffer, int, buffersize); 4474 PRE_MEM_WRITE("proc_info(buffer)", ARG6, ARG7); 4475 #else 4476 PRINT("proc_info(%d, %d, %u, %llu, %#lx, %d)", 4477 (Int)ARG1, (Int)ARG2, (UInt)ARG3, (ULong)ARG4, ARG5, (Int)ARG6); 4478 PRE_REG_READ6(int, "proc_info", 4479 int, callnum, int, pid, unsigned int, flavor, 4480 unsigned long long int, arg, 4481 void*, buffer, int, buffersize); 4482 PRE_MEM_WRITE("proc_info(buffer)", ARG5, ARG6); 4483 #endif 4484 } 4485 4486 POST(proc_info) 4487 { 4488 #if VG_WORDSIZE == 4 4489 vg_assert(SUCCESS); 4490 4491 // Intercept internal call to proc_setcontrol() where flavor = 2, arg = 0 4492 if (ARG1 == 5 && ARG3 == 2 && LOHI64(ARG4,ARG5) == 0 ) 4493 { 4494 const HChar* new_name = (const HChar*) ARG6; 4495 if (new_name) { // Paranoia 4496 ThreadState* tst = VG_(get_ThreadState)(tid); 4497 SizeT new_len = VG_(strlen)(new_name); 4498 4499 /* Don't bother reusing the memory. This is a rare event. */ 4500 tst->thread_name = 4501 VG_(realloc)("syscall(proc_info)", tst->thread_name, new_len + 1); 4502 VG_(strcpy)(tst->thread_name, new_name); 4503 } 4504 } 4505 4506 POST_MEM_WRITE(ARG6, ARG7); 4507 #else 4508 vg_assert(SUCCESS); 4509 4510 // Intercept internal call to proc_setcontrol() where flavor = 2, arg = 0 4511 if (ARG1 == 5 && ARG3 == 2 && ARG4 == 0 ) 4512 { 4513 const HChar* new_name = (const HChar*) ARG5; 4514 if (new_name) { // Paranoia 4515 ThreadState* tst = VG_(get_ThreadState)(tid); 4516 SizeT new_len = VG_(strlen)(new_name); 4517 4518 /* Don't bother reusing the memory. This is a rare event. */ 4519 tst->thread_name = 4520 VG_(realloc)("syscall(proc_info)", tst->thread_name, new_len + 1); 4521 VG_(strcpy)(tst->thread_name, new_name); 4522 } 4523 } 4524 4525 POST_MEM_WRITE(ARG5, ARG6); 4526 #endif 4527 } 4528 4529 4530 /* --------------------------------------------------------------------- 4531 aio_* 4532 ------------------------------------------------------------------ */ 4533 4534 // We must record the aiocbp for each aio_read() in a table so that when 4535 // aio_return() is called we can mark the memory written asynchronously by 4536 // aio_read() as having been written. We don't have to do this for 4537 // aio_write(). See bug 197227 for more details. 4538 static OSet* aiocbp_table = NULL; 4539 static Bool aio_init_done = False; 4540 4541 static void aio_init(void) 4542 { 4543 aiocbp_table = VG_(OSetWord_Create)(VG_(malloc), "syswrap.aio", VG_(free)); 4544 aio_init_done = True; 4545 } 4546 4547 static Bool was_a_successful_aio_read = False; 4548 4549 PRE(aio_return) 4550 { 4551 struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1; 4552 // This assumes that the kernel looks at the struct pointer, but not the 4553 // contents of the struct. 4554 PRINT( "aio_return ( %#lx )", ARG1 ); 4555 PRE_REG_READ1(long, "aio_return", struct vki_aiocb*, aiocbp); 4556 4557 if (!aio_init_done) aio_init(); 4558 was_a_successful_aio_read = VG_(OSetWord_Remove)(aiocbp_table, (UWord)aiocbp); 4559 } 4560 POST(aio_return) 4561 { 4562 // If we found the aiocbp in our own table it must have been an aio_read(), 4563 // so mark the buffer as written. If we didn't find it, it must have been 4564 // an aio_write() or a bogus aio_return() (eg. a second one on the same 4565 // aiocbp). Either way, the buffer won't have been written so we don't 4566 // have to mark the buffer as written. 4567 if (was_a_successful_aio_read) { 4568 struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1; 4569 POST_MEM_WRITE((Addr)aiocbp->aio_buf, aiocbp->aio_nbytes); 4570 was_a_successful_aio_read = False; 4571 } 4572 } 4573 4574 PRE(aio_suspend) 4575 { 4576 // This assumes that the kernel looks at the struct pointers in the list, 4577 // but not the contents of the structs. 4578 PRINT( "aio_suspend ( %#lx )", ARG1 ); 4579 PRE_REG_READ3(long, "aio_suspend", 4580 const struct vki_aiocb *, aiocbp, int, nent, 4581 const struct vki_timespec *, timeout); 4582 if (ARG2 > 0) 4583 PRE_MEM_READ("aio_suspend(list)", ARG1, ARG2 * sizeof(struct vki_aiocb *)); 4584 if (ARG3) 4585 PRE_MEM_READ ("aio_suspend(timeout)", ARG3, sizeof(struct vki_timespec)); 4586 } 4587 4588 PRE(aio_error) 4589 { 4590 // This assumes that the kernel looks at the struct pointer, but not the 4591 // contents of the struct. 4592 PRINT( "aio_error ( %#lx )", ARG1 ); 4593 PRE_REG_READ1(long, "aio_error", struct vki_aiocb*, aiocbp); 4594 } 4595 4596 PRE(aio_read) 4597 { 4598 struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1; 4599 4600 PRINT( "aio_read ( %#lx )", ARG1 ); 4601 PRE_REG_READ1(long, "aio_read", struct vki_aiocb*, aiocbp); 4602 PRE_MEM_READ( "aio_read(aiocbp)", ARG1, sizeof(struct vki_aiocb)); 4603 4604 if (ML_(safe_to_deref)(aiocbp, sizeof(struct vki_aiocb))) { 4605 if (ML_(fd_allowed)(aiocbp->aio_fildes, "aio_read", tid, /*isNewFd*/False)) { 4606 PRE_MEM_WRITE("aio_read(aiocbp->aio_buf)", 4607 (Addr)aiocbp->aio_buf, aiocbp->aio_nbytes); 4608 } else { 4609 SET_STATUS_Failure( VKI_EBADF ); 4610 } 4611 } else { 4612 SET_STATUS_Failure( VKI_EINVAL ); 4613 } 4614 } 4615 POST(aio_read) 4616 { 4617 // We have to record the fact that there is an asynchronous read request 4618 // pending. When a successful aio_return() occurs for this aiocb, then we 4619 // will mark the memory as having been defined. 4620 struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1; 4621 if (!aio_init_done) aio_init(); 4622 // aiocbp shouldn't already be in the table -- if it was a dup, the kernel 4623 // should have caused the aio_read() to fail and we shouldn't have reached 4624 // here. 4625 VG_(OSetWord_Insert)(aiocbp_table, (UWord)aiocbp); 4626 } 4627 4628 PRE(aio_write) 4629 { 4630 struct vki_aiocb* aiocbp = (struct vki_aiocb*)ARG1; 4631 4632 PRINT( "aio_write ( %#lx )", ARG1 ); 4633 PRE_REG_READ1(long, "aio_write", struct vki_aiocb*, aiocbp); 4634 PRE_MEM_READ( "aio_write(aiocbp)", ARG1, sizeof(struct vki_aiocb)); 4635 4636 if (ML_(safe_to_deref)(aiocbp, sizeof(struct vki_aiocb))) { 4637 if (ML_(fd_allowed)(aiocbp->aio_fildes, "aio_write", tid, /*isNewFd*/False)) { 4638 PRE_MEM_READ("aio_write(aiocbp->aio_buf)", 4639 (Addr)aiocbp->aio_buf, aiocbp->aio_nbytes); 4640 } else { 4641 SET_STATUS_Failure( VKI_EBADF ); 4642 } 4643 } else { 4644 SET_STATUS_Failure( VKI_EINVAL ); 4645 } 4646 } 4647 4648 /* --------------------------------------------------------------------- 4649 mach_msg: formatted messages 4650 ------------------------------------------------------------------ */ 4651 4652 static size_t desc_size(mach_msg_descriptor_t *desc) 4653 { 4654 switch (desc->type.type) { 4655 case MACH_MSG_PORT_DESCRIPTOR: return sizeof(desc->port); 4656 case MACH_MSG_OOL_DESCRIPTOR: return sizeof(desc->out_of_line); 4657 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: return sizeof(desc->out_of_line); 4658 case MACH_MSG_OOL_PORTS_DESCRIPTOR: return sizeof(desc->ool_ports); 4659 default: 4660 VG_(printf)("UNKNOWN mach message descriptor %d\n", desc->type.type); 4661 return sizeof(desc->type); // guess 4662 } 4663 } 4664 4665 4666 static void assign_port_names(mach_msg_ool_ports_descriptor_t *desc, 4667 const char *name) 4668 { 4669 mach_msg_size_t i; 4670 mach_port_t *ports = (mach_port_t *)desc->address; 4671 for (i = 0; i < desc->count; i++) { 4672 assign_port_name(ports[i], name); 4673 } 4674 } 4675 4676 4677 static void import_complex_message(ThreadId tid, mach_msg_header_t *mh) 4678 { 4679 mach_msg_body_t *body; 4680 mach_msg_size_t count, i; 4681 uint8_t *p; 4682 mach_msg_descriptor_t *desc; 4683 4684 vg_assert(mh->msgh_bits & MACH_MSGH_BITS_COMPLEX); 4685 4686 body = (mach_msg_body_t *)(mh+1); 4687 count = body->msgh_descriptor_count; 4688 p = (uint8_t *)(body+1); 4689 4690 for (i = 0; i < count; i++) { 4691 desc = (mach_msg_descriptor_t *)p; 4692 p += desc_size(desc); 4693 4694 switch (desc->type.type) { 4695 case MACH_MSG_PORT_DESCRIPTOR: 4696 // single port 4697 record_unnamed_port(tid, desc->port.name, -1); 4698 record_port_insert_rights(desc->port.name, desc->port.disposition); 4699 PRINT("got port %s;\n", name_for_port(desc->port.name)); 4700 break; 4701 4702 case MACH_MSG_OOL_DESCRIPTOR: 4703 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 4704 // out-of-line memory - map it 4705 // GrP fixme how is VOLATILE different? do we care? 4706 // GrP fixme do other flags tell us anything? assume shared for now 4707 // GrP fixme more SF_ flags marking mach_msg memory might be nice 4708 // GrP fixme protection 4709 if (desc->out_of_line.size > 0) { 4710 Addr start = VG_PGROUNDDN((Addr)desc->out_of_line.address); 4711 Addr end = VG_PGROUNDUP((Addr)desc->out_of_line.address + 4712 (Addr)desc->out_of_line.size); 4713 PRINT("got ool mem %p..%p;\n", desc->out_of_line.address, 4714 (char*)desc->out_of_line.address+desc->out_of_line.size); 4715 4716 ML_(notify_core_and_tool_of_mmap)( 4717 start, end - start, VKI_PROT_READ|VKI_PROT_WRITE, 4718 VKI_MAP_PRIVATE, -1, 0); 4719 } 4720 // GrP fixme mark only un-rounded part as initialized 4721 break; 4722 4723 case MACH_MSG_OOL_PORTS_DESCRIPTOR: 4724 // out-of-line array of ports - map it 4725 // GrP fixme see fixmes above 4726 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)); 4727 4728 if (desc->ool_ports.count > 0) { 4729 Addr start = VG_PGROUNDDN((Addr)desc->ool_ports.address); 4730 Addr end = VG_PGROUNDUP((Addr)desc->ool_ports.address + desc->ool_ports.count * sizeof(mach_port_t)); 4731 mach_port_t *ports = (mach_port_t *)desc->ool_ports.address; 4732 4733 ML_(notify_core_and_tool_of_mmap)( 4734 start, end - start, VKI_PROT_READ|VKI_PROT_WRITE, 4735 VKI_MAP_PRIVATE, -1, 0); 4736 4737 PRINT(":"); 4738 for (i = 0; i < desc->ool_ports.count; i++) { 4739 record_unnamed_port(tid, ports[i], -1); 4740 record_port_insert_rights(ports[i], desc->port.disposition); 4741 PRINT(" %s", name_for_port(ports[i])); 4742 } 4743 } 4744 PRINT(";\n"); 4745 break; 4746 4747 default: 4748 VG_(printf)("UNKNOWN Mach descriptor type %u!\n", desc->type.type); 4749 break; 4750 } 4751 } 4752 } 4753 4754 4755 static void pre_port_desc_read(ThreadId tid, mach_msg_port_descriptor_t *desc2) 4756 { 4757 #pragma pack(4) 4758 struct { 4759 mach_port_t name; 4760 mach_msg_size_t pad1; 4761 uint16_t pad2; 4762 uint8_t disposition; 4763 uint8_t type; 4764 } *desc = (void*)desc2; 4765 #pragma pack() 4766 4767 PRE_FIELD_READ("msg->desc.port.name", desc->name); 4768 PRE_FIELD_READ("msg->desc.port.disposition", desc->disposition); 4769 PRE_FIELD_READ("msg->desc.port.type", desc->type); 4770 } 4771 4772 4773 static void pre_ool_desc_read(ThreadId tid, mach_msg_ool_descriptor_t *desc2) 4774 { 4775 #pragma pack(4) 4776 struct { 4777 Addr address; 4778 #if VG_WORDSIZE != 8 4779 mach_msg_size_t size; 4780 #endif 4781 uint8_t deallocate; 4782 uint8_t copy; 4783 uint8_t pad1; 4784 uint8_t type; 4785 #if VG_WORDSIZE == 8 4786 mach_msg_size_t size; 4787 #endif 4788 } *desc = (void*)desc2; 4789 #pragma pack() 4790 4791 PRE_FIELD_READ("msg->desc.out_of_line.address", desc->address); 4792 PRE_FIELD_READ("msg->desc.out_of_line.size", desc->size); 4793 PRE_FIELD_READ("msg->desc.out_of_line.deallocate", desc->deallocate); 4794 PRE_FIELD_READ("msg->desc.out_of_line.copy", desc->copy); 4795 PRE_FIELD_READ("msg->desc.out_of_line.type", desc->type); 4796 } 4797 4798 static void pre_oolports_desc_read(ThreadId tid, 4799 mach_msg_ool_ports_descriptor_t *desc2) 4800 { 4801 #pragma pack(4) 4802 struct { 4803 Addr address; 4804 #if VG_WORDSIZE != 8 4805 mach_msg_size_t size; 4806 #endif 4807 uint8_t deallocate; 4808 uint8_t copy; 4809 uint8_t disposition; 4810 uint8_t type; 4811 #if VG_WORDSIZE == 8 4812 mach_msg_size_t size; 4813 #endif 4814 } *desc = (void*)desc2; 4815 #pragma pack() 4816 4817 PRE_FIELD_READ("msg->desc.ool_ports.address", desc->address); 4818 PRE_FIELD_READ("msg->desc.ool_ports.size", desc->size); 4819 PRE_FIELD_READ("msg->desc.ool_ports.deallocate", desc->deallocate); 4820 PRE_FIELD_READ("msg->desc.ool_ports.copy", desc->copy); 4821 PRE_FIELD_READ("msg->desc.ool_ports.disposition", desc->disposition); 4822 PRE_FIELD_READ("msg->desc.ool_ports.type", desc->type); 4823 } 4824 4825 4826 // Returns the size of the descriptor area 4827 // (mach_msg_body_t + any mach_msg_descriptor_t) 4828 static size_t export_complex_message(ThreadId tid, mach_msg_header_t *mh) 4829 { 4830 mach_msg_body_t *body; 4831 mach_msg_size_t count, i; 4832 uint8_t *p; 4833 mach_msg_descriptor_t *desc; 4834 4835 vg_assert(mh->msgh_bits & MACH_MSGH_BITS_COMPLEX); 4836 4837 body = (mach_msg_body_t *)(mh+1); 4838 PRE_MEM_READ("msg->msgh_descriptor_count)", (Addr)body, sizeof(*body)); 4839 4840 count = body->msgh_descriptor_count; 4841 p = (uint8_t *)(body+1); 4842 4843 for (i = 0; i < count; i++) { 4844 desc = (mach_msg_descriptor_t *)p; 4845 p += desc_size(desc); 4846 4847 switch (desc->type.type) { 4848 case MACH_MSG_PORT_DESCRIPTOR: 4849 // single port; no memory map effects 4850 pre_port_desc_read(tid, &desc->port); 4851 break; 4852 4853 case MACH_MSG_OOL_DESCRIPTOR: 4854 case MACH_MSG_OOL_VOLATILE_DESCRIPTOR: 4855 // out-of-line memory - unmap it if it's marked dealloc 4856 // GrP fixme need to remap if message fails? 4857 // GrP fixme how is VOLATILE different? do we care? 4858 // GrP fixme struct is different for lp64 4859 pre_ool_desc_read(tid, &desc->out_of_line); 4860 4861 if (desc->out_of_line.deallocate && desc->out_of_line.size > 0) { 4862 vm_size_t size = desc->out_of_line.size; 4863 Addr start = VG_PGROUNDDN((Addr)desc->out_of_line.address); 4864 Addr end = VG_PGROUNDUP((Addr)desc->out_of_line.address + size); 4865 PRINT("kill ool mem %p..%#lx; ", desc->out_of_line.address, 4866 (Addr)desc->out_of_line.address + size); 4867 ML_(notify_core_and_tool_of_munmap)(start, end - start); 4868 } 4869 break; 4870 4871 case MACH_MSG_OOL_PORTS_DESCRIPTOR: 4872 // out-of-line array of ports - unmap it if it's marked dealloc 4873 // GrP fixme need to remap if message fails? 4874 // GrP fixme struct different for lp64 4875 pre_oolports_desc_read(tid, &desc->ool_ports); 4876 4877 if (desc->ool_ports.deallocate && desc->ool_ports.count > 0) { 4878 vm_size_t size = desc->ool_ports.count * sizeof(mach_port_t); 4879 Addr start = VG_PGROUNDDN((Addr)desc->ool_ports.address); 4880 Addr end = VG_PGROUNDUP((Addr)desc->ool_ports.address + size); 4881 PRINT("kill ool port array %p..%#lx; ", desc->ool_ports.address, 4882 (Addr)desc->ool_ports.address + size); 4883 ML_(notify_core_and_tool_of_munmap)(start, end - start); 4884 } 4885 break; 4886 default: 4887 VG_(printf)("UNKNOWN Mach descriptor type %u!\n", desc->type.type); 4888 break; 4889 } 4890 } 4891 4892 return (size_t)((Addr)p - (Addr)body); 4893 } 4894 4895 4896 /* --------------------------------------------------------------------- 4897 mach_msg: host-related messages 4898 ------------------------------------------------------------------ */ 4899 4900 4901 POST(host_info) 4902 { 4903 #pragma pack(4) 4904 typedef struct { 4905 mach_msg_header_t Head; 4906 NDR_record_t NDR; 4907 kern_return_t RetCode; 4908 mach_msg_type_number_t host_info_outCnt; 4909 integer_t host_info_out[14]; 4910 } Reply; 4911 #pragma pack() 4912 4913 Reply *reply = (Reply *)ARG1; 4914 4915 if (reply->RetCode) PRINT("mig return %d", reply->RetCode); 4916 } 4917 4918 PRE(host_info) 4919 { 4920 #pragma pack(4) 4921 typedef struct { 4922 mach_msg_header_t Head; 4923 NDR_record_t NDR; 4924 host_flavor_t flavor; 4925 mach_msg_type_number_t host_info_outCnt; 4926 } Request; 4927 #pragma pack() 4928 4929 Request *req = (Request *)ARG1; 4930 4931 PRINT("host_info(mach_host_self(), flavor %d)", req->flavor); 4932 4933 AFTER = POST_FN(host_info); 4934 } 4935 4936 4937 POST(host_page_size) 4938 { 4939 #pragma pack(4) 4940 typedef struct { 4941 mach_msg_header_t Head; 4942 NDR_record_t NDR; 4943 kern_return_t RetCode; 4944 vm_size_t out_page_size; 4945 } Reply; 4946 #pragma pack() 4947 4948 Reply *reply = (Reply *)ARG1; 4949 4950 if (!reply->RetCode) { 4951 PRINT("page size %llu", (ULong)reply->out_page_size); 4952 } else { 4953 PRINT("mig return %d", reply->RetCode); 4954 } 4955 } 4956 4957 PRE(host_page_size) 4958 { 4959 PRINT("host_page_size(mach_host_self(), ...)"); 4960 4961 AFTER = POST_FN(host_page_size); 4962 } 4963 4964 4965 POST(host_get_io_master) 4966 { 4967 #pragma pack(4) 4968 typedef struct { 4969 mach_msg_header_t Head; 4970 /* start of the kernel processed data */ 4971 mach_msg_body_t msgh_body; 4972 mach_msg_port_descriptor_t io_master; 4973 /* end of the kernel processed data */ 4974 } Reply; 4975 #pragma pack() 4976 4977 Reply *reply = (Reply *)ARG1; 4978 4979 assign_port_name(reply->io_master.name, "io_master-%p"); 4980 PRINT("%s", name_for_port(reply->io_master.name)); 4981 } 4982 4983 PRE(host_get_io_master) 4984 { 4985 #pragma pack(4) 4986 typedef struct { 4987 mach_msg_header_t Head; 4988 } Request; 4989 #pragma pack() 4990 4991 // Request *req = (Request *)ARG1; 4992 4993 PRINT("host_get_io_master(mach_host_self())"); 4994 4995 AFTER = POST_FN(host_get_io_master); 4996 } 4997 4998 4999 POST(host_get_clock_service) 5000 { 5001 #pragma pack(4) 5002 typedef struct { 5003 mach_msg_header_t Head; 5004 /* start of the kernel processed data */ 5005 mach_msg_body_t msgh_body; 5006 mach_msg_port_descriptor_t clock_serv; 5007 /* end of the kernel processed data */ 5008 } Reply; 5009 #pragma pack() 5010 5011 Reply *reply = (Reply *)ARG1; 5012 5013 assign_port_name(reply->clock_serv.name, "clock-%p"); 5014 PRINT("%s", name_for_port(reply->clock_serv.name)); 5015 } 5016 5017 PRE(host_get_clock_service) 5018 { 5019 #pragma pack(4) 5020 typedef struct { 5021 mach_msg_header_t Head; 5022 NDR_record_t NDR; 5023 clock_id_t clock_id; 5024 } Request; 5025 #pragma pack() 5026 5027 Request *req = (Request *)ARG1; 5028 5029 PRINT("host_get_clock_service(mach_host_self(), %d)", req->clock_id); 5030 5031 AFTER = POST_FN(host_get_clock_service); 5032 } 5033 5034 5035 PRE(host_request_notification) 5036 { 5037 #pragma pack(4) 5038 typedef struct { 5039 mach_msg_header_t Head; 5040 /* start of the kernel processed data */ 5041 mach_msg_body_t msgh_body; 5042 mach_msg_port_descriptor_t notify_port; 5043 /* end of the kernel processed data */ 5044 NDR_record_t NDR; 5045 host_flavor_t notify_type; 5046 } Request; 5047 #pragma pack() 5048 5049 Request *req = (Request *)ARG1; 5050 5051 if (MACH_REMOTE == mach_task_self()) { 5052 if (req->notify_type == 0) { 5053 PRINT("host_request_notification(mach_host_self(), %s, %s)", 5054 "HOST_NOTIFY_CALENDAR_CHANGE", 5055 name_for_port(req->notify_port.name)); 5056 } else { 5057 PRINT("host_request_notification(mach_host_self(), %d, %s)", 5058 req->notify_type, 5059 name_for_port(req->notify_port.name)); 5060 } 5061 } else { 5062 PRINT("host_request_notification(%s, %d, %s)", 5063 name_for_port(MACH_REMOTE), 5064 req->notify_type, 5065 name_for_port(req->notify_port.name)); 5066 } 5067 5068 // GrP fixme only do this on success 5069 assign_port_name(req->notify_port.name, "host_notify-%p"); 5070 } 5071 5072 5073 PRE(host_create_mach_voucher) 5074 { 5075 #pragma pack(4) 5076 typedef struct { 5077 mach_msg_header_t Head; 5078 NDR_record_t NDR; 5079 mach_msg_type_number_t recipesCnt; 5080 uint8_t recipes[5120]; 5081 } Request; 5082 #pragma pack() 5083 5084 Request *req = (Request *)ARG1; 5085 5086 PRINT("host_create_mach_voucher(count %u)", 5087 req->recipesCnt); 5088 5089 AFTER = POST_FN(host_create_mach_voucher); 5090 } 5091 5092 5093 POST(host_create_mach_voucher) 5094 { 5095 #pragma pack(4) 5096 typedef struct { 5097 mach_msg_header_t Head; 5098 /* start of the kernel processed data */ 5099 mach_msg_body_t msgh_body; 5100 mach_msg_port_descriptor_t voucher; 5101 /* end of the kernel processed data */ 5102 } Reply; 5103 #pragma pack() 5104 5105 Reply *reply = (Reply *)ARG1; 5106 5107 // RK fixme properly parse this return type 5108 PRINT("got voucher %#x ", reply->voucher.name); 5109 } 5110 5111 5112 PRE(host_get_special_port) 5113 { 5114 #pragma pack(4) 5115 typedef struct { 5116 mach_msg_header_t Head; 5117 NDR_record_t NDR; 5118 int node; 5119 int which; 5120 } Request; 5121 #pragma pack() 5122 5123 Request *req = (Request *)ARG1; 5124 5125 PRINT("host_get_special_port(node %d)", req->node); 5126 5127 switch (req->which) { 5128 case HOST_PORT: 5129 PRINT("host_get_special_port(%s, HOST_PORT)", 5130 name_for_port(MACH_REMOTE)); 5131 break; 5132 case HOST_PRIV_PORT: 5133 PRINT("host_get_special_port(%s, HOST_PRIV_PORT)", 5134 name_for_port(MACH_REMOTE)); 5135 break; 5136 case HOST_IO_MASTER_PORT: 5137 PRINT("host_get_special_port(%s, HOST_IO_MASTER_PORT)", 5138 name_for_port(MACH_REMOTE)); 5139 break; 5140 // Not provided by kernel 5141 case HOST_DYNAMIC_PAGER_PORT: 5142 PRINT("host_get_special_port(%s, HOST_DYNAMIC_PAGER_PORT)", 5143 name_for_port(MACH_REMOTE)); 5144 break; 5145 case HOST_AUDIT_CONTROL_PORT: 5146 PRINT("host_get_special_port(%s, HOST_AUDIT_CONTROL_PORT)", 5147 name_for_port(MACH_REMOTE)); 5148 break; 5149 case HOST_USER_NOTIFICATION_PORT: 5150 PRINT("host_get_special_port(%s, HOST_USER_NOTIFICATION_PORT)", 5151 name_for_port(MACH_REMOTE)); 5152 break; 5153 // ... 5154 5155 default: 5156 PRINT("host_get_special_port(%s, %d)", 5157 name_for_port(MACH_REMOTE), req->which); 5158 break; 5159 } 5160 5161 MACH_ARG(host_get_special_port.which) = req->which; 5162 5163 AFTER = POST_FN(host_get_special_port); 5164 } 5165 5166 5167 POST(host_get_special_port) 5168 { 5169 #pragma pack(4) 5170 typedef struct { 5171 mach_msg_header_t Head; 5172 /* start of the kernel processed data */ 5173 mach_msg_body_t msgh_body; 5174 mach_msg_port_descriptor_t port; 5175 /* end of the kernel processed data */ 5176 } Reply; 5177 #pragma pack() 5178 5179 Reply *reply = (Reply *)ARG1; 5180 5181 PRINT("got port %#x ", reply->port.name); 5182 5183 /* The required entry in the allocated_ports list (mapping) might 5184 not exist, due perhaps to broken syscall wrappers (mach__N etc). 5185 Create a minimal entry so that assign_port_name below doesn't 5186 cause an assertion. */ 5187 if (!port_exists(reply->port.name)) { 5188 port_create_vanilla(reply->port.name); 5189 } 5190 5191 switch (MACH_ARG(host_get_special_port.which)) { 5192 case HOST_PORT: 5193 assign_port_name(reply->port.name, "port-%p"); 5194 break; 5195 case HOST_PRIV_PORT: 5196 assign_port_name(reply->port.name, "priv-%p"); 5197 break; 5198 case HOST_IO_MASTER_PORT: 5199 assign_port_name(reply->port.name, "io-master-%p"); 5200 break; 5201 // Not provided by kernel 5202 case HOST_DYNAMIC_PAGER_PORT: 5203 assign_port_name(reply->port.name, "dynamic-pager-%p"); 5204 break; 5205 case HOST_AUDIT_CONTROL_PORT: 5206 assign_port_name(reply->port.name, "audit-control-%p"); 5207 break; 5208 case HOST_USER_NOTIFICATION_PORT: 5209 assign_port_name(reply->port.name, "user-notification-%p"); 5210 break; 5211 // ... 5212 5213 default: 5214 assign_port_name(reply->port.name, "special-%p"); 5215 break; 5216 } 5217 5218 PRINT("%s", name_for_port(reply->port.name)); 5219 } 5220 5221 /* --------------------------------------------------------------------- 5222 mach_msg: messages to a task 5223 ------------------------------------------------------------------ */ 5224 5225 // JRS 2011-Aug-25: just guessing here. I have no clear idea how 5226 // these structs are derived. They obviously relate to the various 5227 // .def files in the xnu sources, and can also be found in some 5228 // form in /usr/include/mach/*.h, but not sure how these all 5229 // relate to each other. 5230 5231 PRE(mach_port_set_context) 5232 { 5233 #pragma pack(4) 5234 typedef struct { 5235 mach_msg_header_t Head; 5236 NDR_record_t NDR; 5237 mach_port_name_t name; 5238 mach_vm_address_t context; 5239 } Request; 5240 #pragma pack() 5241 5242 Request *req = (Request *)ARG1; 5243 5244 PRINT("mach_port_set_context(%s, %s, 0x%llx)", 5245 name_for_port(MACH_REMOTE), 5246 name_for_port(req->name), req->context); 5247 5248 AFTER = POST_FN(mach_port_set_context); 5249 } 5250 5251 POST(mach_port_set_context) 5252 { 5253 #pragma pack(4) 5254 typedef struct { 5255 mach_msg_header_t Head; 5256 NDR_record_t NDR; 5257 kern_return_t RetCode; 5258 } Reply; 5259 #pragma pack() 5260 } 5261 5262 5263 // JRS 2011-Aug-25 FIXME completely bogus 5264 PRE(task_get_exception_ports) 5265 { 5266 #pragma pack(4) 5267 typedef struct { 5268 mach_msg_header_t Head; 5269 NDR_record_t NDR; 5270 exception_mask_t exception_mask; 5271 } Request; 5272 #pragma pack() 5273 5274 PRINT("task_get_exception_ports(BOGUS)"); 5275 AFTER = POST_FN(task_get_exception_ports); 5276 } 5277 5278 POST(task_get_exception_ports) 5279 { 5280 #pragma pack(4) 5281 typedef struct { 5282 mach_msg_header_t Head; 5283 /* start of the kernel processed data */ 5284 mach_msg_body_t msgh_body; 5285 mach_msg_port_descriptor_t old_handlers[32]; 5286 /* end of the kernel processed data */ 5287 NDR_record_t NDR; 5288 mach_msg_type_number_t masksCnt; 5289 exception_mask_t masks[32]; 5290 exception_behavior_t old_behaviors[32]; 5291 thread_state_flavor_t old_flavors[32]; 5292 } Reply; 5293 #pragma pack() 5294 } 5295 5296 5297 /////////////////////////////////////////////////// 5298 5299 PRE(mach_port_type) 5300 { 5301 #pragma pack(4) 5302 typedef struct { 5303 mach_msg_header_t Head; 5304 NDR_record_t NDR; 5305 mach_port_name_t name; 5306 } Request; 5307 #pragma pack() 5308 5309 Request *req = (Request *)ARG1; 5310 5311 PRINT("mach_port_type(%s, %s, ...)", 5312 name_for_port(MACH_REMOTE), name_for_port(req->name)); 5313 5314 AFTER = POST_FN(mach_port_type); 5315 } 5316 5317 POST(mach_port_type) 5318 { 5319 } 5320 5321 5322 PRE(mach_port_extract_member) 5323 { 5324 #pragma pack(4) 5325 typedef struct { 5326 mach_msg_header_t Head; 5327 NDR_record_t NDR; 5328 mach_port_name_t name; 5329 mach_port_name_t pset; 5330 } Request; 5331 #pragma pack() 5332 5333 Request *req = (Request *)ARG1; 5334 5335 PRINT("mach_port_extract_member(%s, 0x%x, 0x%x)", 5336 name_for_port(MACH_REMOTE), 5337 req->name, req->pset); 5338 5339 AFTER = POST_FN(mach_port_extract_member); 5340 5341 // GrP fixme port tracker? 5342 } 5343 5344 POST(mach_port_extract_member) 5345 { 5346 #pragma pack(4) 5347 typedef struct { 5348 mach_msg_header_t Head; 5349 NDR_record_t NDR; 5350 kern_return_t RetCode; 5351 } Reply; 5352 #pragma pack() 5353 5354 Reply *reply = (Reply *)ARG1; 5355 5356 if (reply->RetCode) PRINT("mig return %d", reply->RetCode); 5357 } 5358 5359 5360 PRE(mach_port_allocate) 5361 { 5362 #pragma pack(4) 5363 typedef struct { 5364 mach_msg_header_t Head; 5365 NDR_record_t NDR; 5366 mach_port_right_t right; 5367 } Request; 5368 #pragma pack() 5369 5370 Request *req = (Request *)ARG1; 5371 5372 PRINT("mach_port_allocate(mach_task_self(), %d, ...)", req->right); 5373 5374 MACH_ARG(mach_port_allocate.right) = req->right; 5375 5376 AFTER = POST_FN(mach_port_allocate); 5377 } 5378 5379 POST(mach_port_allocate) 5380 { 5381 #pragma pack(4) 5382 typedef struct { 5383 mach_msg_header_t Head; 5384 NDR_record_t NDR; 5385 kern_return_t RetCode; 5386 mach_port_name_t name; 5387 } Reply; 5388 #pragma pack() 5389 5390 Reply *reply = (Reply *)ARG1; 5391 5392 if (!reply->RetCode) { 5393 if (MACH_REMOTE == vg_task_port) { 5394 // GrP fixme port tracking is too imprecise 5395 // vg_assert(!port_exists(reply->name)); 5396 record_unnamed_port(tid, reply->name, MACH_ARG(mach_port_allocate.right)); 5397 PRINT("got port 0x%x", reply->name); 5398 } else { 5399 VG_(printf)("UNKNOWN inserted port 0x%x into remote task\n", reply->name); 5400 } 5401 } else { 5402 PRINT("mig return %d", reply->RetCode); 5403 } 5404 } 5405 5406 5407 PRE(mach_port_deallocate) 5408 { 5409 #pragma pack(4) 5410 typedef struct { 5411 mach_msg_header_t Head; 5412 NDR_record_t NDR; 5413 mach_port_name_t name; 5414 } Request; 5415 #pragma pack() 5416 5417 Request *req = (Request *)ARG1; 5418 5419 PRINT("mach_port_deallocate(%s, %s)", 5420 name_for_port(MACH_REMOTE), 5421 name_for_port(req->name)); 5422 5423 MACH_ARG(mach_port.port) = req->name; 5424 5425 AFTER = POST_FN(mach_port_deallocate); 5426 5427 // Must block to prevent race (other thread allocates and 5428 // notifies after we deallocate but before we notify) 5429 *flags &= ~SfMayBlock; 5430 } 5431 5432 POST(mach_port_deallocate) 5433 { 5434 #pragma pack(4) 5435 typedef struct { 5436 mach_msg_header_t Head; 5437 NDR_record_t NDR; 5438 kern_return_t RetCode; 5439 } Reply; 5440 #pragma pack() 5441 5442 Reply *reply = (Reply *)ARG1; 5443 5444 if (!reply->RetCode) { 5445 if (MACH_REMOTE == vg_task_port) { 5446 // Must have cleared SfMayBlock in PRE to prevent race 5447 record_port_dealloc(MACH_ARG(mach_port.port)); 5448 } else { 5449 VG_(printf)("UNKNOWN remote port dealloc\n"); 5450 } 5451 } else { 5452 PRINT("mig return %d", reply->RetCode); 5453 } 5454 } 5455 5456 5457 PRE(mach_port_get_refs) 5458 { 5459 #pragma pack(4) 5460 typedef struct { 5461 mach_msg_header_t Head; 5462 NDR_record_t NDR; 5463 mach_port_name_t name; 5464 mach_port_right_t right; 5465 } Request; 5466 #pragma pack() 5467 5468 Request *req = (Request *)ARG1; 5469 5470 PRINT("mach_port_get_refs(%s, %s, 0x%x)", 5471 name_for_port(MACH_REMOTE), 5472 name_for_port(req->name), req->right); 5473 5474 MACH_ARG(mach_port_mod_refs.port) = req->name; 5475 MACH_ARG(mach_port_mod_refs.right) = req->right; 5476 5477 AFTER = POST_FN(mach_port_get_refs); 5478 } 5479 5480 POST(mach_port_get_refs) 5481 { 5482 #pragma pack(4) 5483 typedef struct { 5484 mach_msg_header_t Head; 5485 NDR_record_t NDR; 5486 kern_return_t RetCode; 5487 mach_port_urefs_t refs; 5488 } Reply; 5489 #pragma pack() 5490 5491 Reply *reply = (Reply *)ARG1; 5492 5493 if (!reply->RetCode) { 5494 PRINT("got refs=%d", reply->refs); 5495 } else { 5496 PRINT("mig return %d", reply->RetCode); 5497 } 5498 } 5499 5500 5501 PRE(mach_port_mod_refs) 5502 { 5503 #pragma pack(4) 5504 typedef struct { 5505 mach_msg_header_t Head; 5506 NDR_record_t NDR; 5507 mach_port_name_t name; 5508 mach_port_right_t right; 5509 mach_port_delta_t delta; 5510 } Request; 5511 #pragma pack() 5512 5513 Request *req = (Request *)ARG1; 5514 5515 PRINT("mach_port_mod_refs(%s, %s, 0x%x, 0x%x)", 5516 name_for_port(MACH_REMOTE), 5517 name_for_port(req->name), req->right, req->delta); 5518 5519 MACH_ARG(mach_port_mod_refs.port) = req->name; 5520 MACH_ARG(mach_port_mod_refs.right) = req->right; 5521 MACH_ARG(mach_port_mod_refs.delta) = req->delta; 5522 5523 AFTER = POST_FN(mach_port_mod_refs); 5524 5525 // Must block to prevent race (other thread allocates and 5526 // notifies after we deallocate but before we notify) 5527 *flags &= ~SfMayBlock; 5528 } 5529 5530 POST(mach_port_mod_refs) 5531 { 5532 #pragma pack(4) 5533 typedef struct { 5534 mach_msg_header_t Head; 5535 NDR_record_t NDR; 5536 kern_return_t RetCode; 5537 } Reply; 5538 #pragma pack() 5539 5540 Reply *reply = (Reply *)ARG1; 5541 5542 if (!reply->RetCode) { 5543 if (MACH_REMOTE == vg_task_port) { 5544 // Must have cleared SfMayBlock in PRE to prevent race 5545 record_port_mod_refs(MACH_ARG(mach_port_mod_refs.port), 5546 MACH_PORT_TYPE(MACH_ARG(mach_port_mod_refs.right)), 5547 MACH_ARG(mach_port_mod_refs.delta)); 5548 } else { 5549 VG_(printf)("UNKNOWN remote port mod refs\n"); 5550 } 5551 } else { 5552 PRINT("mig return %d", reply->RetCode); 5553 } 5554 } 5555 5556 5557 PRE(mach_port_get_set_status) 5558 { 5559 #pragma pack(4) 5560 typedef struct { 5561 mach_msg_header_t Head; 5562 NDR_record_t NDR; 5563 mach_port_name_t name; 5564 } Request; 5565 #pragma pack() 5566 5567 Request *req = (Request *)ARG1; 5568 5569 PRINT("mach_port_get_set_status(%s, %s)", 5570 name_for_port(MACH_REMOTE), 5571 name_for_port(req->name)); 5572 5573 AFTER = POST_FN(mach_port_get_set_status); 5574 } 5575 5576 POST(mach_port_get_set_status) 5577 { 5578 #pragma pack(4) 5579 typedef struct { 5580 mach_msg_header_t Head; 5581 /* start of the kernel processed data */ 5582 mach_msg_body_t msgh_body; 5583 mach_msg_ool_descriptor_t members; 5584 /* end of the kernel processed data */ 5585 NDR_record_t NDR; 5586 mach_msg_type_number_t membersCnt; 5587 mach_msg_trailer_t trailer; 5588 } Reply; 5589 #pragma pack() 5590 5591 // Reply *reply = (Reply *)ARG1; 5592 5593 // GrP fixme nothing to do? 5594 } 5595 5596 5597 PRE(mach_port_move_member) 5598 { 5599 #pragma pack(4) 5600 typedef struct { 5601 mach_msg_header_t Head; 5602 NDR_record_t NDR; 5603 mach_port_name_t member; 5604 mach_port_name_t after; 5605 } Request; 5606 #pragma pack() 5607 5608 Request *req = (Request *)ARG1; 5609 5610 PRINT("mach_port_move_member(%s, %s, %s)", 5611 name_for_port(MACH_REMOTE), 5612 name_for_port(req->member), 5613 name_for_port(req->after)); 5614 /* 5615 MACH_ARG(mach_port_move_member.member) = req->member; 5616 MACH_ARG(mach_port_move_member.after) = req->after; 5617 */ 5618 AFTER = POST_FN(mach_port_move_member); 5619 } 5620 5621 POST(mach_port_move_member) 5622 { 5623 #pragma pack(4) 5624 typedef struct { 5625 mach_msg_header_t Head; 5626 NDR_record_t NDR; 5627 kern_return_t RetCode; 5628 mach_msg_trailer_t trailer; 5629 } Reply; 5630 #pragma pack() 5631 5632 Reply *reply = (Reply *)ARG1; 5633 5634 if (!reply->RetCode) { 5635 // fixme port set tracker? 5636 } else { 5637 PRINT("mig return %d", reply->RetCode); 5638 } 5639 } 5640 5641 5642 PRE(mach_port_destroy) 5643 { 5644 #pragma pack(4) 5645 typedef struct { 5646 mach_msg_header_t Head; 5647 NDR_record_t NDR; 5648 mach_port_name_t name; 5649 } Request; 5650 #pragma pack() 5651 5652 Request *req = (Request *)ARG1; 5653 5654 PRINT("mach_port_destroy(%s, %s)", 5655 name_for_port(MACH_REMOTE), 5656 name_for_port(req->name)); 5657 5658 MACH_ARG(mach_port.port) = req->name; 5659 5660 AFTER = POST_FN(mach_port_destroy); 5661 5662 // Must block to prevent race (other thread allocates and 5663 // notifies after we deallocate but before we notify) 5664 *flags &= ~SfMayBlock; 5665 } 5666 5667 POST(mach_port_destroy) 5668 { 5669 #pragma pack(4) 5670 typedef struct { 5671 mach_msg_header_t Head; 5672 NDR_record_t NDR; 5673 kern_return_t RetCode; 5674 } Reply; 5675 #pragma pack() 5676 5677 Reply *reply = (Reply *)ARG1; 5678 5679 if (!reply->RetCode) { 5680 if (MACH_REMOTE == vg_task_port) { 5681 // Must have cleared SfMayBlock in PRE to prevent race 5682 record_port_destroy(MACH_ARG(mach_port.port)); 5683 } else { 5684 VG_(printf)("UNKNOWN remote port destroy\n"); 5685 } 5686 } else { 5687 PRINT("mig return %d", reply->RetCode); 5688 } 5689 } 5690 5691 5692 PRE(mach_port_request_notification) 5693 { 5694 #pragma pack(4) 5695 typedef struct { 5696 mach_msg_header_t Head; 5697 /* start of the kernel processed data */ 5698 mach_msg_body_t msgh_body; 5699 mach_msg_port_descriptor_t notify; 5700 /* end of the kernel processed data */ 5701 NDR_record_t NDR; 5702 mach_port_name_t name; 5703 mach_msg_id_t msgid; 5704 mach_port_mscount_t sync; 5705 } Request; 5706 #pragma pack() 5707 5708 Request *req = (Request *)ARG1; 5709 5710 PRINT("mach_port_request_notification(%s, %s, %d, %d, %d, %d, ...)", 5711 name_for_port(MACH_REMOTE), 5712 name_for_port(req->name), req->msgid, req->sync, 5713 req->notify.name, req->notify.disposition); 5714 5715 AFTER = POST_FN(mach_port_request_notification); 5716 } 5717 5718 POST(mach_port_request_notification) 5719 { 5720 // GrP fixme port tracker? not sure 5721 } 5722 5723 5724 PRE(mach_port_insert_right) 5725 { 5726 #pragma pack(4) 5727 typedef struct { 5728 mach_msg_header_t Head; 5729 /* start of the kernel processed data */ 5730 mach_msg_body_t msgh_body; 5731 mach_msg_port_descriptor_t poly; 5732 /* end of the kernel processed data */ 5733 NDR_record_t NDR; 5734 mach_port_name_t name; 5735 } Request; 5736 #pragma pack() 5737 5738 Request *req = (Request *)ARG1; 5739 5740 PRINT("mach_port_insert_right(%s, %s, %d, %d)", 5741 name_for_port(MACH_REMOTE), 5742 name_for_port(req->name), req->poly.name, req->poly.disposition); 5743 5744 AFTER = POST_FN(mach_port_insert_right); 5745 5746 if (MACH_REMOTE == mach_task_self()) { 5747 // GrP fixme import_complex_message handles everything? 5748 // what about export_complex_message for MOVE variants? 5749 } else { 5750 VG_(printf)("UNKNOWN mach_port_insert_right into remote task!\n"); 5751 // GrP fixme also may remove rights from this task? 5752 } 5753 5754 // GrP fixme port tracker? 5755 } 5756 5757 POST(mach_port_insert_right) 5758 { 5759 } 5760 5761 5762 PRE(mach_port_extract_right) 5763 { 5764 #pragma pack(4) 5765 typedef struct { 5766 mach_msg_header_t Head; 5767 NDR_record_t NDR; 5768 mach_port_name_t name; 5769 mach_msg_type_name_t msgt_name; 5770 } Request; 5771 #pragma pack() 5772 5773 Request *req = (Request *)ARG1; 5774 5775 PRINT("mach_port_extract_right(%s, %s, %d)", 5776 name_for_port(MACH_REMOTE), 5777 name_for_port(req->name), req->msgt_name); 5778 5779 AFTER = POST_FN(mach_port_extract_right); 5780 5781 // fixme port tracker? 5782 } 5783 5784 POST(mach_port_extract_right) 5785 { 5786 // fixme import_complex_message handles the returned result, right? 5787 } 5788 5789 5790 PRE(mach_port_get_attributes) 5791 { 5792 #pragma pack(4) 5793 typedef struct { 5794 mach_msg_header_t Head; 5795 NDR_record_t NDR; 5796 mach_port_name_t name; 5797 mach_port_flavor_t flavor; 5798 mach_msg_type_number_t port_info_outCnt; 5799 } Request; 5800 #pragma pack() 5801 5802 Request *req = (Request *)ARG1; 5803 5804 PRINT("mach_port_get_attributes(%s, %s, %d, ..., %d)", 5805 name_for_port(MACH_REMOTE), 5806 name_for_port(req->name), req->flavor, req->port_info_outCnt); 5807 5808 AFTER = POST_FN(mach_port_get_attributes); 5809 } 5810 5811 POST(mach_port_get_attributes) 5812 { 5813 } 5814 5815 5816 PRE(mach_port_set_attributes) 5817 { 5818 #pragma pack(4) 5819 typedef struct { 5820 mach_msg_header_t Head; 5821 NDR_record_t NDR; 5822 mach_port_name_t name; 5823 mach_port_flavor_t flavor; 5824 mach_msg_type_number_t port_infoCnt; 5825 integer_t port_info[10]; 5826 } Request; 5827 #pragma pack() 5828 5829 Request *req = (Request *)ARG1; 5830 5831 PRINT("mach_port_set_attributes(%s, %s, %d, ..., %d)", 5832 name_for_port(MACH_REMOTE), 5833 name_for_port(req->name), req->flavor, req->port_infoCnt); 5834 5835 AFTER = POST_FN(mach_port_set_attributes); 5836 } 5837 5838 POST(mach_port_set_attributes) 5839 { 5840 } 5841 5842 5843 PRE(mach_port_insert_member) 5844 { 5845 #pragma pack(4) 5846 typedef struct { 5847 mach_msg_header_t Head; 5848 NDR_record_t NDR; 5849 mach_port_name_t name; 5850 mach_port_name_t pset; 5851 } Request; 5852 #pragma pack() 5853 5854 Request *req = (Request *)ARG1; 5855 5856 PRINT("mach_port_insert_member(%s, 0x%x, 0x%x)", 5857 name_for_port(MACH_REMOTE), req->name, req->pset); 5858 5859 AFTER = POST_FN(mach_port_insert_member); 5860 5861 // GrP fixme port tracker? 5862 } 5863 5864 POST(mach_port_insert_member) 5865 { 5866 } 5867 5868 5869 PRE(task_get_special_port) 5870 { 5871 #pragma pack(4) 5872 typedef struct { 5873 mach_msg_header_t Head; 5874 NDR_record_t NDR; 5875 int which_port; 5876 } Request; 5877 #pragma pack() 5878 5879 Request *req = (Request *)ARG1; 5880 5881 switch (req->which_port) { 5882 case TASK_KERNEL_PORT: 5883 PRINT("task_get_special_port(%s, TASK_KERNEL_PORT)", 5884 name_for_port(MACH_REMOTE)); 5885 break; 5886 case TASK_HOST_PORT: 5887 PRINT("task_get_special_port(%s, TASK_HOST_PORT)", 5888 name_for_port(MACH_REMOTE)); 5889 break; 5890 case TASK_BOOTSTRAP_PORT: 5891 PRINT("task_get_special_port(%s, TASK_BOOTSTRAP_PORT)", 5892 name_for_port(MACH_REMOTE)); 5893 break; 5894 #if DARWIN_VERS < DARWIN_10_8 5895 /* These disappeared in 10.8 */ 5896 case TASK_WIRED_LEDGER_PORT: 5897 PRINT("task_get_special_port(%s, TASK_WIRED_LEDGER_PORT)", 5898 name_for_port(MACH_REMOTE)); 5899 break; 5900 case TASK_PAGED_LEDGER_PORT: 5901 PRINT("task_get_special_port(%s, TASK_PAGED_LEDGER_PORT)", 5902 name_for_port(MACH_REMOTE)); 5903 break; 5904 #endif 5905 default: 5906 PRINT("task_get_special_port(%s, %d)", 5907 name_for_port(MACH_REMOTE), req->which_port); 5908 break; 5909 } 5910 5911 MACH_ARG(task_get_special_port.which_port) = req->which_port; 5912 5913 AFTER = POST_FN(task_get_special_port); 5914 } 5915 5916 POST(task_get_special_port) 5917 { 5918 #pragma pack(4) 5919 typedef struct { 5920 mach_msg_header_t Head; 5921 /* start of the kernel processed data */ 5922 mach_msg_body_t msgh_body; 5923 mach_msg_port_descriptor_t special_port; 5924 /* end of the kernel processed data */ 5925 } Reply; 5926 #pragma pack() 5927 5928 Reply *reply = (Reply *)ARG1; 5929 5930 PRINT("got port %#x ", reply->special_port.name); 5931 5932 switch (MACH_ARG(task_get_special_port.which_port)) { 5933 case TASK_BOOTSTRAP_PORT: 5934 vg_bootstrap_port = reply->special_port.name; 5935 assign_port_name(reply->special_port.name, "bootstrap"); 5936 break; 5937 case TASK_KERNEL_PORT: 5938 assign_port_name(reply->special_port.name, "kernel"); 5939 break; 5940 case TASK_HOST_PORT: 5941 assign_port_name(reply->special_port.name, "host"); 5942 break; 5943 #if DARWIN_VERS < DARWIN_10_8 5944 /* These disappeared in 10.8 */ 5945 case TASK_WIRED_LEDGER_PORT: 5946 assign_port_name(reply->special_port.name, "wired-ledger"); 5947 break; 5948 case TASK_PAGED_LEDGER_PORT: 5949 assign_port_name(reply->special_port.name, "paged-ledger"); 5950 break; 5951 #endif 5952 default: 5953 assign_port_name(reply->special_port.name, "special-%p"); 5954 break; 5955 } 5956 5957 PRINT("%s", name_for_port(reply->special_port.name)); 5958 } 5959 5960 5961 PRE(task_set_special_port) 5962 { 5963 #pragma pack(4) 5964 typedef struct { 5965 mach_msg_header_t Head; 5966 /* start of the kernel processed data */ 5967 mach_msg_body_t msgh_body; 5968 mach_msg_port_descriptor_t special_port; 5969 /* end of the kernel processed data */ 5970 NDR_record_t NDR; 5971 int which_port; 5972 } Request; 5973 #pragma pack() 5974 5975 Request *req = (Request *)ARG1; 5976 5977 PRINT("got port %#x ", req->special_port.name); 5978 5979 // MACH_ARG(task_set_special_port.which_port) = req->which_port; 5980 PRINT("%s", name_for_port(req->special_port.name)); 5981 5982 AFTER = POST_FN(task_set_special_port); 5983 } 5984 5985 POST(task_set_special_port) 5986 { 5987 #pragma pack(4) 5988 typedef struct { 5989 mach_msg_header_t Head; 5990 NDR_record_t NDR; 5991 kern_return_t RetCode; 5992 } Reply; 5993 #pragma pack() 5994 5995 Reply *reply = (Reply *)ARG1; 5996 if (!reply->RetCode) { 5997 } else { 5998 PRINT("mig return %d", reply->RetCode); 5999 } 6000 } 6001 6002 6003 PRE(semaphore_create) 6004 { 6005 #pragma pack(4) 6006 typedef struct { 6007 mach_msg_header_t Head; 6008 NDR_record_t NDR; 6009 int policy; 6010 int value; 6011 } Request; 6012 #pragma pack() 6013 6014 Request *req = (Request *)ARG1; 6015 6016 PRINT("semaphore_create(%s, ..., %d, %d)", 6017 name_for_port(MACH_REMOTE), req->policy, req->value); 6018 6019 AFTER = POST_FN(semaphore_create); 6020 } 6021 6022 POST(semaphore_create) 6023 { 6024 #pragma pack(4) 6025 typedef struct { 6026 mach_msg_header_t Head; 6027 /* start of the kernel processed data */ 6028 mach_msg_body_t msgh_body; 6029 mach_msg_port_descriptor_t semaphore; 6030 /* end of the kernel processed data */ 6031 mach_msg_trailer_t trailer; 6032 } Reply; 6033 #pragma pack() 6034 6035 Reply *reply = (Reply *)ARG1; 6036 6037 assign_port_name(reply->semaphore.name, "semaphore-%p"); 6038 PRINT("%s", name_for_port(reply->semaphore.name)); 6039 } 6040 6041 6042 PRE(semaphore_destroy) 6043 { 6044 #pragma pack(4) 6045 typedef struct { 6046 mach_msg_header_t Head; 6047 /* start of the kernel processed data */ 6048 mach_msg_body_t msgh_body; 6049 mach_msg_port_descriptor_t semaphore; 6050 /* end of the kernel processed data */ 6051 mach_msg_trailer_t trailer; 6052 } Request; 6053 #pragma pack() 6054 6055 Request *req = (Request *)ARG1; 6056 6057 PRINT("semaphore_destroy(%s, %s)", 6058 name_for_port(MACH_REMOTE), name_for_port(req->semaphore.name)); 6059 6060 record_port_destroy(req->semaphore.name); 6061 6062 AFTER = POST_FN(semaphore_destroy); 6063 } 6064 6065 POST(semaphore_destroy) 6066 { 6067 #pragma pack(4) 6068 typedef struct { 6069 mach_msg_header_t Head; 6070 NDR_record_t NDR; 6071 kern_return_t RetCode; 6072 mach_msg_trailer_t trailer; 6073 } Reply; 6074 #pragma pack() 6075 6076 Reply *reply = (Reply *)ARG1; 6077 if (!reply->RetCode) { 6078 } else { 6079 PRINT("mig return %d", reply->RetCode); 6080 } 6081 } 6082 6083 PRE(task_policy_set) 6084 { 6085 #pragma pack(4) 6086 typedef struct { 6087 mach_msg_header_t Head; 6088 NDR_record_t NDR; 6089 task_policy_flavor_t flavor; 6090 mach_msg_type_number_t policy_infoCnt; 6091 integer_t policy_info[16]; 6092 } Request; 6093 #pragma pack() 6094 6095 Request *req = (Request *)ARG1; 6096 6097 PRINT("task_policy_set(%s) flavor:%d", name_for_port(MACH_REMOTE), req->flavor); 6098 6099 AFTER = POST_FN(task_policy_set); 6100 } 6101 6102 POST(task_policy_set) 6103 { 6104 #pragma pack(4) 6105 typedef struct { 6106 mach_msg_header_t Head; 6107 NDR_record_t NDR; 6108 kern_return_t RetCode; 6109 } Reply; 6110 #pragma pack() 6111 6112 Reply *reply = (Reply *)ARG1; 6113 if (!reply->RetCode) { 6114 } else { 6115 PRINT("mig return %d", reply->RetCode); 6116 } 6117 } 6118 6119 6120 PRE(mach_ports_register) 6121 { 6122 #pragma pack(4) 6123 typedef struct { 6124 mach_msg_header_t Head; 6125 /* start of the kernel processed data */ 6126 mach_msg_body_t msgh_body; 6127 mach_msg_ool_ports_descriptor_t init_port_set; 6128 /* end of the kernel processed data */ 6129 NDR_record_t NDR; 6130 mach_msg_type_number_t init_port_setCnt; 6131 } Request; 6132 #pragma pack() 6133 6134 // Request *req = (Request *)ARG1; 6135 6136 PRINT("mach_ports_register(%s)", name_for_port(MACH_REMOTE)); 6137 6138 AFTER = POST_FN(mach_ports_register); 6139 } 6140 6141 POST(mach_ports_register) 6142 { 6143 #pragma pack(4) 6144 typedef struct { 6145 mach_msg_header_t Head; 6146 NDR_record_t NDR; 6147 kern_return_t RetCode; 6148 } Reply; 6149 #pragma pack() 6150 6151 Reply *reply = (Reply *)ARG1; 6152 if (!reply->RetCode) { 6153 } else { 6154 PRINT("mig return %d", reply->RetCode); 6155 } 6156 } 6157 6158 6159 PRE(mach_ports_lookup) 6160 { 6161 #pragma pack(4) 6162 typedef struct { 6163 mach_msg_header_t Head; 6164 } Request; 6165 #pragma pack() 6166 6167 // Request *req = (Request *)ARG1; 6168 6169 PRINT("mach_ports_lookup(%s)", name_for_port(MACH_REMOTE)); 6170 6171 AFTER = POST_FN(mach_ports_lookup); 6172 } 6173 6174 POST(mach_ports_lookup) 6175 { 6176 #pragma pack(4) 6177 typedef struct { 6178 mach_msg_header_t Head; 6179 /* start of the kernel processed data */ 6180 mach_msg_body_t msgh_body; 6181 mach_msg_ool_ports_descriptor_t init_port_set; 6182 /* end of the kernel processed data */ 6183 NDR_record_t NDR; 6184 mach_msg_type_number_t init_port_setCnt; 6185 } Reply; 6186 #pragma pack() 6187 6188 // Reply *reply = (Reply *)ARG1; 6189 } 6190 6191 6192 PRE(task_info) 6193 { 6194 #pragma pack(4) 6195 typedef struct { 6196 mach_msg_header_t Head; 6197 NDR_record_t NDR; 6198 task_flavor_t flavor; 6199 mach_msg_type_number_t task_info_outCnt; 6200 } Request; 6201 #pragma pack() 6202 6203 Request *req = (Request *)ARG1; 6204 6205 PRINT("task_info(%s) flavor:%d", name_for_port(MACH_REMOTE), req->flavor); 6206 6207 AFTER = POST_FN(task_info); 6208 } 6209 6210 POST(task_info) 6211 { 6212 #pragma pack(4) 6213 typedef struct { 6214 mach_msg_header_t Head; 6215 NDR_record_t NDR; 6216 kern_return_t RetCode; 6217 mach_msg_type_number_t task_info_outCnt; 6218 integer_t task_info_out[52]; 6219 } Reply; 6220 #pragma pack() 6221 6222 Reply *reply = (Reply *)ARG1; 6223 if (!reply->RetCode) { 6224 } else { 6225 PRINT("mig return %d", reply->RetCode); 6226 } 6227 } 6228 6229 6230 PRE(task_set_info) 6231 { 6232 #pragma pack(4) 6233 typedef struct { 6234 mach_msg_header_t Head; 6235 NDR_record_t NDR; 6236 task_flavor_t flavor; 6237 mach_msg_type_number_t task_info_inCnt; 6238 integer_t task_info_in[52]; 6239 } Request; 6240 #pragma pack() 6241 6242 Request *req = (Request *)ARG1; 6243 6244 PRINT("task_set_info(%s) flavor:%d", name_for_port(MACH_REMOTE), req->flavor); 6245 6246 AFTER = POST_FN(task_set_info); 6247 } 6248 6249 POST(task_set_info) 6250 { 6251 #pragma pack(4) 6252 typedef struct { 6253 mach_msg_header_t Head; 6254 NDR_record_t NDR; 6255 kern_return_t RetCode; 6256 } Reply; 6257 #pragma pack() 6258 6259 Reply *reply = (Reply *)ARG1; 6260 if (!reply->RetCode) { 6261 } else { 6262 PRINT("mig return %d", reply->RetCode); 6263 } 6264 } 6265 6266 PRE(task_threads) 6267 { 6268 #pragma pack(4) 6269 typedef struct { 6270 mach_msg_header_t Head; 6271 } Request; 6272 #pragma pack() 6273 6274 // Request *req = (Request *)ARG1; 6275 6276 PRINT("task_threads(%s)", name_for_port(MACH_REMOTE)); 6277 6278 AFTER = POST_FN(task_threads); 6279 } 6280 6281 POST(task_threads) 6282 { 6283 #pragma pack(4) 6284 typedef struct { 6285 mach_msg_header_t Head; 6286 /* start of the kernel processed data */ 6287 mach_msg_body_t msgh_body; 6288 mach_msg_ool_ports_descriptor_t act_list; 6289 /* end of the kernel processed data */ 6290 NDR_record_t NDR; 6291 mach_msg_type_number_t act_listCnt; 6292 mach_msg_trailer_t trailer; 6293 } Reply; 6294 #pragma pack() 6295 6296 Reply *reply = (Reply *)ARG1; 6297 6298 if (MACH_REMOTE == vg_task_port) { 6299 assign_port_names(&reply->act_list, "thread-%p"); 6300 } else { 6301 assign_port_names(&reply->act_list, "remote-thread-%p"); 6302 } 6303 } 6304 6305 6306 PRE(task_suspend) 6307 { 6308 PRINT("task_suspend(%s)", name_for_port(MACH_REMOTE)); 6309 6310 if (MACH_REMOTE == vg_task_port) { 6311 // GrP fixme self-suspend 6312 vg_assert(0); 6313 } else { 6314 // suspend other - no problem 6315 } 6316 6317 AFTER = POST_FN(task_suspend); 6318 } 6319 6320 POST(task_suspend) 6321 { 6322 } 6323 6324 6325 PRE(task_resume) 6326 { 6327 PRINT("task_resume(%s)", name_for_port(MACH_REMOTE)); 6328 6329 if (MACH_REMOTE == vg_task_port) { 6330 // GrP fixme self-resume 6331 vg_assert(0); 6332 } else { 6333 // resume other - no problem 6334 } 6335 6336 AFTER = POST_FN(task_resume); 6337 } 6338 6339 POST(task_resume) 6340 { 6341 } 6342 6343 6344 PRE(vm_allocate) 6345 { 6346 #pragma pack(4) 6347 typedef struct { 6348 mach_msg_header_t Head; 6349 NDR_record_t NDR; 6350 vm_address_t address; 6351 vm_size_t size; 6352 int flags; 6353 } Request; 6354 #pragma pack() 6355 6356 Request *req = (Request *)ARG1; 6357 6358 PRINT("vm_allocate (%s, at %#llx, size %llu, flags %#x)", 6359 name_for_port(MACH_REMOTE), 6360 (ULong)req->address, (ULong)req->size, req->flags); 6361 6362 MACH_ARG(vm_allocate.size) = req->size; 6363 MACH_ARG(vm_allocate.flags) = req->flags; 6364 6365 AFTER = POST_FN(vm_allocate); 6366 } 6367 6368 POST(vm_allocate) 6369 { 6370 #pragma pack(4) 6371 typedef struct { 6372 mach_msg_header_t Head; 6373 NDR_record_t NDR; 6374 kern_return_t RetCode; 6375 vm_address_t address; 6376 mach_msg_trailer_t trailer; 6377 } Reply; 6378 #pragma pack() 6379 6380 Reply *reply = (Reply *)ARG1; 6381 6382 if (!reply->RetCode) { 6383 if (MACH_REMOTE == vg_task_port) { 6384 PRINT("allocated at %#llx", (ULong)reply->address); 6385 // requesting 0 bytes returns address 0 with no error 6386 if (MACH_ARG(vm_allocate.size)) { 6387 ML_(notify_core_and_tool_of_mmap)( 6388 reply->address, MACH_ARG(vm_allocate.size), 6389 VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_ANON, -1, 0); 6390 } 6391 } else { 6392 PRINT("allocated at %#llx in remote task %s", 6393 (ULong)reply->address, 6394 name_for_port(MACH_REMOTE)); 6395 } 6396 } else { 6397 PRINT("mig return %d", reply->RetCode); 6398 } 6399 } 6400 6401 6402 PRE(vm_deallocate) 6403 { 6404 #pragma pack(4) 6405 typedef struct { 6406 mach_msg_header_t Head; 6407 NDR_record_t NDR; 6408 vm_address_t address; 6409 vm_size_t size; 6410 } Request; 6411 #pragma pack() 6412 6413 Request *req = (Request *)ARG1; 6414 6415 PRINT("vm_deallocate(%s, at %#llx, size %llu)", 6416 name_for_port(MACH_REMOTE), 6417 (ULong)req->address, (ULong)req->size); 6418 6419 MACH_ARG(vm_deallocate.address) = req->address; 6420 MACH_ARG(vm_deallocate.size) = req->size; 6421 6422 AFTER = POST_FN(vm_deallocate); 6423 6424 // Must block to prevent race (other thread allocates and 6425 // notifies after we deallocate but before we notify) 6426 *flags &= ~SfMayBlock; 6427 } 6428 6429 POST(vm_deallocate) 6430 { 6431 #pragma pack(4) 6432 typedef struct { 6433 mach_msg_header_t Head; 6434 NDR_record_t NDR; 6435 kern_return_t RetCode; 6436 mach_msg_trailer_t trailer; 6437 } Reply; 6438 #pragma pack() 6439 6440 Reply *reply = (Reply *)ARG1; 6441 6442 if (!reply->RetCode) { 6443 if (MACH_REMOTE == vg_task_port) { 6444 if (MACH_ARG(vm_deallocate.size)) { 6445 Addr start = VG_PGROUNDDN(MACH_ARG(vm_deallocate.address)); 6446 Addr end = VG_PGROUNDUP(MACH_ARG(vm_deallocate.address) + 6447 MACH_ARG(vm_deallocate.size)); 6448 // Must have cleared SfMayBlock in PRE to prevent race 6449 ML_(notify_core_and_tool_of_munmap)(start, end - start); 6450 } 6451 } 6452 } else { 6453 PRINT("mig return %d", reply->RetCode); 6454 } 6455 } 6456 6457 6458 PRE(vm_protect) 6459 { 6460 #pragma pack(4) 6461 typedef struct { 6462 mach_msg_header_t Head; 6463 NDR_record_t NDR; 6464 vm_address_t address; 6465 vm_size_t size; 6466 boolean_t set_maximum; 6467 vm_prot_t new_protection; 6468 } Request; 6469 #pragma pack() 6470 6471 Request *req = (Request *)ARG1; 6472 6473 PRINT("vm_protect(%s, at %#llx, size %llu, set_max %d, prot %d)", 6474 name_for_port(MACH_REMOTE), 6475 (ULong)req->address, (ULong)req->size, 6476 req->set_maximum, req->new_protection); 6477 6478 MACH_ARG(vm_protect.address) = req->address; 6479 MACH_ARG(vm_protect.size) = req->size; 6480 MACH_ARG(vm_protect.set_maximum) = req->set_maximum; 6481 MACH_ARG(vm_protect.new_protection) = req->new_protection; 6482 6483 AFTER = POST_FN(vm_protect); 6484 } 6485 6486 POST(vm_protect) 6487 { 6488 #pragma pack(4) 6489 typedef struct { 6490 mach_msg_header_t Head; 6491 NDR_record_t NDR; 6492 kern_return_t RetCode; 6493 mach_msg_trailer_t trailer; 6494 } Reply; 6495 #pragma pack() 6496 6497 Reply *reply = (Reply *)ARG1; 6498 6499 if (!reply->RetCode) { 6500 if (MACH_REMOTE == vg_task_port) { 6501 Addr start = VG_PGROUNDDN(MACH_ARG(vm_protect.address)); 6502 Addr end = VG_PGROUNDUP(MACH_ARG(vm_protect.address) + 6503 MACH_ARG(vm_protect.size)); 6504 UInt prot = MACH_ARG(vm_protect.new_protection); 6505 if (MACH_ARG(vm_protect.set_maximum)) { 6506 // GrP fixme mprotect max 6507 VG_(printf)("UNKNOWN vm_protect set maximum"); 6508 //VG_(mprotect_max_range)(start, end-start, prot); 6509 } else { 6510 ML_(notify_core_and_tool_of_mprotect)(start, end-start, prot); 6511 VG_(di_notify_vm_protect)(start, end-start, prot); 6512 } 6513 } 6514 } else { 6515 PRINT("mig return %d", reply->RetCode); 6516 } 6517 } 6518 6519 6520 PRE(vm_inherit) 6521 { 6522 #pragma pack(4) 6523 typedef struct { 6524 mach_msg_header_t Head; 6525 NDR_record_t NDR; 6526 vm_address_t address; 6527 vm_size_t size; 6528 vm_inherit_t new_inheritance; 6529 } Request; 6530 #pragma pack() 6531 6532 Request *req = (Request *)ARG1; 6533 6534 PRINT("vm_inherit(%s, at %#llx, size %llu, value %d)", 6535 name_for_port(MACH_REMOTE), 6536 (ULong)req->address, (ULong)req->size, 6537 req->new_inheritance); 6538 6539 AFTER = POST_FN(vm_inherit); 6540 } 6541 6542 POST(vm_inherit) 6543 { 6544 #pragma pack(4) 6545 typedef struct { 6546 mach_msg_header_t Head; 6547 NDR_record_t NDR; 6548 kern_return_t RetCode; 6549 mach_msg_trailer_t trailer; 6550 } Reply; 6551 #pragma pack() 6552 6553 Reply *reply = (Reply *)ARG1; 6554 6555 if (!reply->RetCode) { 6556 if (MACH_REMOTE == vg_task_port) { 6557 // GrP fixme do something? 6558 } 6559 } else { 6560 PRINT("mig return %d", reply->RetCode); 6561 } 6562 } 6563 6564 6565 PRE(vm_read) 6566 { 6567 #pragma pack(4) 6568 typedef struct { 6569 mach_msg_header_t Head; 6570 NDR_record_t NDR; 6571 vm_address_t address; 6572 vm_size_t size; 6573 } Request; 6574 #pragma pack() 6575 6576 Request *req = (Request *)ARG1; 6577 6578 PRINT("vm_read(from %s at %#llx size %llu)", 6579 name_for_port(MACH_REMOTE), 6580 (ULong)req->address, (ULong)req->size); 6581 6582 MACH_ARG(vm_read.addr) = req->address; 6583 MACH_ARG(vm_read.size) = req->size; 6584 6585 AFTER = POST_FN(vm_read); 6586 } 6587 6588 POST(vm_read) 6589 { 6590 #pragma pack(4) 6591 typedef struct { 6592 mach_msg_header_t Head; 6593 /* start of the kernel processed data */ 6594 mach_msg_body_t msgh_body; 6595 mach_msg_ool_descriptor_t data; 6596 /* end of the kernel processed data */ 6597 NDR_record_t NDR; 6598 mach_msg_type_number_t dataCnt; 6599 } Reply; 6600 #pragma pack() 6601 6602 // Reply *reply = (Reply *)ARG1; 6603 6604 if (MACH_REMOTE == vg_task_port) { 6605 // vm_read from self 6606 // GrP fixme copy initialized state 6607 } 6608 } 6609 6610 6611 6612 PRE(mach_vm_read) 6613 { 6614 #pragma pack(4) 6615 typedef struct { 6616 mach_msg_header_t Head; 6617 NDR_record_t NDR; 6618 mach_vm_address_t address; 6619 mach_vm_size_t size; 6620 } Request; 6621 #pragma pack() 6622 6623 Request *req = (Request *)ARG1; 6624 6625 PRINT("mach_vm_read(from %s at 0x%llx size %llu)", 6626 name_for_port(MACH_REMOTE), req->address, req->size); 6627 6628 MACH_ARG(mach_vm_read.addr) = req->address; 6629 MACH_ARG(mach_vm_read.size) = req->size; 6630 6631 AFTER = POST_FN(mach_vm_read); 6632 } 6633 6634 POST(mach_vm_read) 6635 { 6636 #pragma pack(4) 6637 typedef struct { 6638 mach_msg_header_t Head; 6639 /* start of the kernel processed data */ 6640 mach_msg_body_t msgh_body; 6641 mach_msg_ool_descriptor_t data; 6642 /* end of the kernel processed data */ 6643 NDR_record_t NDR; 6644 mach_msg_type_number_t dataCnt; 6645 } Reply; 6646 #pragma pack() 6647 6648 // Reply *reply = (Reply *)ARG1; 6649 6650 if (MACH_REMOTE == vg_task_port) { 6651 // vm_read from self 6652 // GrP fixme copy initialized state 6653 } 6654 } 6655 6656 6657 PRE(vm_read_overwrite) 6658 { 6659 #pragma pack(4) 6660 typedef struct { 6661 mach_msg_header_t Head; 6662 NDR_record_t NDR; 6663 vm_address_t address; 6664 vm_size_t size; 6665 vm_address_t data; 6666 } Request; 6667 #pragma pack() 6668 6669 Request *req = (Request *)ARG1; 6670 6671 PRINT("vm_read_overwrite(from %s at %#llx size %llu to %#llx)", 6672 name_for_port(MACH_REMOTE), 6673 (ULong)req->address, (ULong)req->size, (ULong)req->data); 6674 6675 MACH_ARG(vm_read_overwrite.addr) = req->address; 6676 MACH_ARG(vm_read_overwrite.size) = req->size; 6677 MACH_ARG(vm_read_overwrite.data) = req->data; 6678 6679 PRE_MEM_WRITE("vm_read_overwrite(data)", req->data, req->size); 6680 6681 AFTER = POST_FN(vm_read_overwrite); 6682 } 6683 6684 POST(vm_read_overwrite) 6685 { 6686 #pragma pack(4) 6687 typedef struct { 6688 mach_msg_header_t Head; 6689 NDR_record_t NDR; 6690 kern_return_t RetCode; 6691 vm_size_t outsize; 6692 } Reply; 6693 #pragma pack() 6694 6695 Reply *reply = (Reply *)ARG1; 6696 6697 if (reply->RetCode) { 6698 PRINT("mig return %d", reply->RetCode); 6699 } else { 6700 PRINT("read %llu bytes", (unsigned long long)reply->outsize); 6701 if (MACH_REMOTE == vg_task_port) { 6702 // vm_read_overwrite from self 6703 // GrP fixme copy initialized state 6704 POST_MEM_WRITE(MACH_ARG(vm_read_overwrite.data), reply->outsize); 6705 } else { 6706 // vm_read_overwrite from remote 6707 POST_MEM_WRITE(MACH_ARG(vm_read_overwrite.data), reply->outsize); 6708 } 6709 } 6710 } 6711 6712 6713 PRE(vm_copy) 6714 { 6715 #pragma pack(4) 6716 typedef struct { 6717 mach_msg_header_t Head; 6718 NDR_record_t NDR; 6719 vm_address_t source_address; 6720 vm_size_t size; 6721 vm_address_t dest_address; 6722 } Request; 6723 #pragma pack() 6724 6725 Request *req = (Request *)ARG1; 6726 6727 PRINT("vm_copy(%s, %#llx, %lld, %#llx)", 6728 name_for_port(MACH_REMOTE), 6729 (ULong)req->source_address, 6730 (ULong)req->size, (ULong)req->dest_address); 6731 6732 MACH_ARG(vm_copy.src) = req->source_address; 6733 MACH_ARG(vm_copy.dst) = req->dest_address; 6734 MACH_ARG(vm_copy.size) = req->size; 6735 6736 AFTER = POST_FN(vm_copy); 6737 } 6738 6739 POST(vm_copy) 6740 { 6741 #pragma pack(4) 6742 typedef struct { 6743 mach_msg_header_t Head; 6744 NDR_record_t NDR; 6745 kern_return_t RetCode; 6746 mach_msg_trailer_t trailer; 6747 } Reply; 6748 #pragma pack() 6749 6750 Reply *reply = (Reply *)ARG1; 6751 6752 if (!reply->RetCode) { 6753 if (MACH_REMOTE == vg_task_port) { 6754 // GrP fixme set dst's initialization equal to src's 6755 // and wipe any symbols or translations in dst 6756 } 6757 } else { 6758 PRINT("mig return %d", reply->RetCode); 6759 } 6760 } 6761 6762 6763 PRE(vm_map) 6764 { 6765 #pragma pack(4) 6766 typedef struct { 6767 mach_msg_header_t Head; 6768 /* start of the kernel processed data */ 6769 mach_msg_body_t msgh_body; 6770 mach_msg_port_descriptor_t object; 6771 /* end of the kernel processed data */ 6772 NDR_record_t NDR; 6773 vm_address_t address; 6774 vm_size_t size; 6775 vm_address_t mask; 6776 int flags; 6777 vm_offset_t offset; 6778 boolean_t copy; 6779 vm_prot_t cur_protection; 6780 vm_prot_t max_protection; 6781 vm_inherit_t inheritance; 6782 } Request; 6783 #pragma pack() 6784 6785 Request *req = (Request *)ARG1; 6786 6787 // GrP fixme check these 6788 PRINT("vm_map(in %s, at %#llx, size %llu, from %s ...)", 6789 name_for_port(MACH_REMOTE), 6790 (ULong)req->address, (ULong)req->size, 6791 name_for_port(req->object.name)); 6792 6793 MACH_ARG(vm_map.size) = req->size; 6794 MACH_ARG(vm_map.copy) = req->copy; 6795 MACH_ARG(vm_map.protection) = (req->cur_protection & req->max_protection); 6796 6797 AFTER = POST_FN(vm_map); 6798 } 6799 6800 POST(vm_map) 6801 { 6802 #pragma pack(4) 6803 typedef struct { 6804 mach_msg_header_t Head; 6805 NDR_record_t NDR; 6806 kern_return_t RetCode; 6807 vm_address_t address; 6808 mach_msg_trailer_t trailer; 6809 } Reply; 6810 #pragma pack() 6811 6812 Reply *reply = (Reply *)ARG1; 6813 6814 if (!reply->RetCode) { 6815 // GrP fixme check src and dest tasks 6816 PRINT("mapped at %#llx", (ULong)reply->address); 6817 // GrP fixme max prot 6818 ML_(notify_core_and_tool_of_mmap)( 6819 reply->address, VG_PGROUNDUP(MACH_ARG(vm_map.size)), 6820 MACH_ARG(vm_map.protection), VKI_MAP_SHARED, -1, 0); 6821 // GrP fixme VKI_MAP_PRIVATE if !copy? 6822 } else { 6823 PRINT("mig return %d", reply->RetCode); 6824 } 6825 } 6826 6827 6828 PRE(vm_remap) 6829 { 6830 #pragma pack(4) 6831 typedef struct { 6832 mach_msg_header_t Head; 6833 /* start of the kernel processed data */ 6834 mach_msg_body_t msgh_body; 6835 mach_msg_port_descriptor_t src_task; 6836 /* end of the kernel processed data */ 6837 NDR_record_t NDR; 6838 vm_address_t target_address; 6839 vm_size_t size; 6840 vm_address_t mask; 6841 boolean_t anywhere; 6842 vm_address_t src_address; 6843 boolean_t copy; 6844 vm_inherit_t inheritance; 6845 } Request; 6846 #pragma pack() 6847 6848 Request *req = (Request *)ARG1; 6849 6850 // GrP fixme check src and dest tasks 6851 6852 if (VG_(clo_trace_syscalls)) { 6853 mach_port_name_t source_task = req->src_task.name; 6854 if (source_task == mach_task_self()) { 6855 PRINT("vm_remap(mach_task_self(), " 6856 "to %#llx size %llu, from mach_task_self() at %#llx, ...)", 6857 (ULong)req->target_address, 6858 (ULong)req->size, (ULong)req->src_address); 6859 } else { 6860 PRINT("vm_remap(mach_task_self(), " 6861 "to %#llx size %llu, from task %u at %#llx, ...)", 6862 (ULong)req->target_address, (ULong)req->size, 6863 source_task, (ULong)req->src_address); 6864 } 6865 } 6866 6867 // arg1 is task 6868 // vt->syscall_arg2 = req->target_address; 6869 MACH_ARG(vm_remap.size) = req->size; 6870 // vt->syscall_arg4 = req->copy; 6871 6872 AFTER = POST_FN(vm_remap); 6873 } 6874 6875 POST(vm_remap) 6876 { 6877 #pragma pack(4) 6878 typedef struct { 6879 mach_msg_header_t Head; 6880 NDR_record_t NDR; 6881 kern_return_t RetCode; 6882 vm_address_t target_address; 6883 vm_prot_t cur_protection; 6884 vm_prot_t max_protection; 6885 mach_msg_trailer_t trailer; 6886 } Reply; 6887 #pragma pack() 6888 6889 Reply *reply = (Reply *)ARG1; 6890 6891 if (!reply->RetCode) { 6892 // GrP fixme check src and dest tasks 6893 UInt prot = reply->cur_protection & reply->max_protection; 6894 // GrP fixme max prot 6895 PRINT("mapped at %#llx", (ULong)reply->target_address); 6896 ML_(notify_core_and_tool_of_mmap)( 6897 reply->target_address, VG_PGROUNDUP(MACH_ARG(vm_remap.size)), 6898 prot, VKI_MAP_SHARED, -1, 0); 6899 // GrP fixme VKI_MAP_FIXED if !copy? 6900 // GrP fixme copy initialized bits from source to dest if source_task is also mach_task_self 6901 } else { 6902 PRINT("mig return %d", reply->RetCode); 6903 } 6904 } 6905 6906 6907 PRE(mach_make_memory_entry_64) 6908 { 6909 #pragma pack(4) 6910 typedef struct { 6911 mach_msg_header_t Head; 6912 /* start of the kernel processed data */ 6913 mach_msg_body_t msgh_body; 6914 mach_msg_port_descriptor_t parent_entry; 6915 /* end of the kernel processed data */ 6916 NDR_record_t NDR; 6917 memory_object_size_t size; 6918 memory_object_offset_t offset; 6919 vm_prot_t permission; 6920 } Request; 6921 #pragma pack() 6922 6923 Request *req = (Request *)ARG1; 6924 6925 PRINT("mach_make_memory_entry_64(%s, %llu, %llu, %d, ..., %u)", 6926 name_for_port(MACH_REMOTE), 6927 req->size, req->offset, req->permission, req->parent_entry.type); 6928 6929 AFTER = POST_FN(mach_make_memory_entry_64); 6930 } 6931 6932 POST(mach_make_memory_entry_64) 6933 { 6934 #pragma pack(4) 6935 typedef struct { 6936 mach_msg_header_t Head; 6937 mach_msg_body_t msgh_body; 6938 mach_msg_port_descriptor_t object; 6939 NDR_record_t NDR; 6940 memory_object_size_t size; 6941 } Reply; 6942 #pragma pack() 6943 6944 Reply *reply = (Reply *)ARG1; 6945 6946 if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) { 6947 assign_port_name(reply->object.name, "memory-%p"); 6948 PRINT("%s", name_for_port(reply->object.name)); 6949 } 6950 } 6951 6952 6953 PRE(vm_purgable_control) 6954 { 6955 #pragma pack(4) 6956 typedef struct { 6957 mach_msg_header_t Head; 6958 NDR_record_t NDR; 6959 vm_address_t address; 6960 vm_purgable_t control; 6961 int state; 6962 } Request; 6963 #pragma pack() 6964 6965 Request *req = (Request *)ARG1; 6966 6967 PRINT("vm_purgable_control(%s, %#llx, %d, %d)", 6968 name_for_port(MACH_REMOTE), 6969 (ULong)req->address, req->control, req->state); 6970 6971 // GrP fixme verify address? 6972 6973 AFTER = POST_FN(vm_purgable_control); 6974 } 6975 6976 POST(vm_purgable_control) 6977 { 6978 #pragma pack(4) 6979 typedef struct { 6980 mach_msg_header_t Head; 6981 NDR_record_t NDR; 6982 kern_return_t RetCode; 6983 int state; 6984 } Reply; 6985 #pragma pack() 6986 6987 Reply *reply = (Reply *)ARG1; 6988 6989 if (!reply->RetCode) { 6990 } else { 6991 PRINT("mig return %d", reply->RetCode); 6992 } 6993 } 6994 6995 6996 PRE(mach_vm_purgable_control) 6997 { 6998 #pragma pack(4) 6999 typedef struct { 7000 mach_msg_header_t Head; 7001 NDR_record_t NDR; 7002 mach_vm_address_t address; 7003 vm_purgable_t control; 7004 int state; 7005 } Request; 7006 #pragma pack() 7007 7008 Request *req = (Request *)ARG1; 7009 7010 PRINT("mach_vm_purgable_control(%s, 0x%llx, %d, %d)", 7011 name_for_port(MACH_REMOTE), 7012 (ULong)req->address, req->control, req->state); 7013 7014 // GrP fixme verify address? 7015 7016 AFTER = POST_FN(mach_vm_purgable_control); 7017 } 7018 7019 POST(mach_vm_purgable_control) 7020 { 7021 #pragma pack(4) 7022 typedef struct { 7023 mach_msg_header_t Head; 7024 NDR_record_t NDR; 7025 kern_return_t RetCode; 7026 int state; 7027 } Reply; 7028 #pragma pack() 7029 7030 Reply *reply = (Reply *)ARG1; 7031 7032 if (!reply->RetCode) { 7033 } else { 7034 PRINT("mig return %d", reply->RetCode); 7035 } 7036 } 7037 7038 7039 PRE(mach_vm_allocate) 7040 { 7041 #pragma pack(4) 7042 typedef struct { 7043 mach_msg_header_t Head; 7044 NDR_record_t NDR; 7045 mach_vm_address_t address; 7046 mach_vm_size_t size; 7047 int flags; 7048 } Request; 7049 #pragma pack() 7050 7051 Request *req = (Request *)ARG1; 7052 7053 PRINT("mach_vm_allocate (%s, at 0x%llx, size %llu, flags 0x%x)", 7054 name_for_port(MACH_REMOTE), 7055 req->address, req->size, req->flags); 7056 7057 MACH_ARG(mach_vm_allocate.size) = req->size; 7058 MACH_ARG(mach_vm_allocate.flags) = req->flags; 7059 7060 AFTER = POST_FN(mach_vm_allocate); 7061 } 7062 7063 POST(mach_vm_allocate) 7064 { 7065 #pragma pack(4) 7066 typedef struct { 7067 mach_msg_header_t Head; 7068 NDR_record_t NDR; 7069 kern_return_t RetCode; 7070 mach_vm_address_t address; 7071 mach_msg_trailer_t trailer; 7072 } Reply; 7073 #pragma pack() 7074 7075 Reply *reply = (Reply *)ARG1; 7076 7077 if (!reply->RetCode) { 7078 if (MACH_REMOTE == vg_task_port) { 7079 PRINT("allocated at 0x%llx", reply->address); 7080 // requesting 0 bytes returns address 0 with no error 7081 if (MACH_ARG(mach_vm_allocate.size)) { 7082 ML_(notify_core_and_tool_of_mmap)( 7083 reply->address, MACH_ARG(mach_vm_allocate.size), 7084 VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_ANON, -1, 0); 7085 } 7086 } else { 7087 PRINT("allocated at 0x%llx in remote task %s", reply->address, 7088 name_for_port(MACH_REMOTE)); 7089 } 7090 } else { 7091 PRINT("mig return %d", reply->RetCode); 7092 } 7093 } 7094 7095 7096 PRE(mach_vm_deallocate) 7097 { 7098 #pragma pack(4) 7099 typedef struct { 7100 mach_msg_header_t Head; 7101 NDR_record_t NDR; 7102 mach_vm_address_t address; 7103 mach_vm_size_t size; 7104 } Request; 7105 #pragma pack() 7106 7107 Request *req = (Request *)ARG1; 7108 7109 PRINT("mach_vm_deallocate(%s, at 0x%llx, size %llu)", 7110 name_for_port(MACH_REMOTE), 7111 req->address, req->size); 7112 7113 MACH_ARG(mach_vm_deallocate.address) = req->address; 7114 MACH_ARG(mach_vm_deallocate.size) = req->size; 7115 7116 AFTER = POST_FN(mach_vm_deallocate); 7117 7118 // Must block to prevent race (other thread allocates and 7119 // notifies after we deallocate but before we notify) 7120 *flags &= ~SfMayBlock; 7121 } 7122 7123 POST(mach_vm_deallocate) 7124 { 7125 #pragma pack(4) 7126 typedef struct { 7127 mach_msg_header_t Head; 7128 NDR_record_t NDR; 7129 kern_return_t RetCode; 7130 mach_msg_trailer_t trailer; 7131 } Reply; 7132 #pragma pack() 7133 7134 Reply *reply = (Reply *)ARG1; 7135 7136 if (!reply->RetCode) { 7137 if (MACH_REMOTE == vg_task_port) { 7138 if (MACH_ARG(mach_vm_deallocate.size)) { 7139 Addr start = VG_PGROUNDDN(MACH_ARG(mach_vm_deallocate.address)); 7140 Addr end = VG_PGROUNDUP(MACH_ARG(mach_vm_deallocate.address) + 7141 MACH_ARG(mach_vm_deallocate.size)); 7142 // Must have cleared SfMayBlock in PRE to prevent race 7143 ML_(notify_core_and_tool_of_munmap)(start, end - start); 7144 } 7145 } 7146 } else { 7147 PRINT("mig return %d", reply->RetCode); 7148 } 7149 } 7150 7151 7152 PRE(mach_vm_protect) 7153 { 7154 #pragma pack(4) 7155 typedef struct { 7156 mach_msg_header_t Head; 7157 NDR_record_t NDR; 7158 mach_vm_address_t address; 7159 mach_vm_size_t size; 7160 boolean_t set_maximum; 7161 vm_prot_t new_protection; 7162 } Request; 7163 #pragma pack() 7164 7165 Request *req = (Request *)ARG1; 7166 7167 PRINT("mach_vm_protect(%s, at 0x%llx, size %llu, set_max %d, prot %d)", 7168 name_for_port(MACH_REMOTE), req->address, req->size, 7169 req->set_maximum, req->new_protection); 7170 7171 MACH_ARG(mach_vm_protect.address) = req->address; 7172 MACH_ARG(mach_vm_protect.size) = req->size; 7173 MACH_ARG(mach_vm_protect.set_maximum) = req->set_maximum; 7174 MACH_ARG(mach_vm_protect.new_protection) = req->new_protection; 7175 7176 AFTER = POST_FN(mach_vm_protect); 7177 } 7178 7179 POST(mach_vm_protect) 7180 { 7181 #pragma pack(4) 7182 typedef struct { 7183 mach_msg_header_t Head; 7184 NDR_record_t NDR; 7185 kern_return_t RetCode; 7186 mach_msg_trailer_t trailer; 7187 } Reply; 7188 #pragma pack() 7189 7190 Reply *reply = (Reply *)ARG1; 7191 7192 if (!reply->RetCode) { 7193 if (MACH_REMOTE == vg_task_port) { 7194 Addr start = VG_PGROUNDDN(MACH_ARG(mach_vm_protect.address)); 7195 Addr end = VG_PGROUNDUP(MACH_ARG(mach_vm_protect.address) + 7196 MACH_ARG(mach_vm_protect.size)); 7197 UInt prot = MACH_ARG(mach_vm_protect.new_protection); 7198 if (MACH_ARG(mach_vm_protect.set_maximum)) { 7199 // DDD: #warning GrP fixme mprotect max 7200 //VG_(mprotect_max_range)(start, end-start, prot); 7201 } else { 7202 ML_(notify_core_and_tool_of_mprotect)(start, end-start, prot); 7203 } 7204 } 7205 } else { 7206 PRINT("mig return %d", reply->RetCode); 7207 } 7208 } 7209 7210 7211 PRE(mach_vm_inherit) 7212 { 7213 #pragma pack(4) 7214 typedef struct { 7215 mach_msg_header_t Head; 7216 NDR_record_t NDR; 7217 mach_vm_address_t address; 7218 mach_vm_size_t size; 7219 vm_inherit_t new_inheritance; 7220 } Request; 7221 #pragma pack() 7222 7223 Request *req = (Request *)ARG1; 7224 7225 PRINT("mach_vm_inherit(to %s, at 0x%llx, size %llu, value %u)", 7226 name_for_port(MACH_REMOTE), 7227 req->address, req->size, req->new_inheritance); 7228 7229 AFTER = POST_FN(mach_vm_inherit); 7230 } 7231 7232 POST(mach_vm_inherit) 7233 { 7234 #pragma pack(4) 7235 typedef struct { 7236 mach_msg_header_t Head; 7237 NDR_record_t NDR; 7238 kern_return_t RetCode; 7239 mach_msg_trailer_t trailer; 7240 } Reply; 7241 #pragma pack() 7242 7243 Reply *reply = (Reply *)ARG1; 7244 7245 if (!reply->RetCode) { 7246 // no V-visible side effects 7247 // GrP fixme except maybe fork/exec 7248 } else { 7249 PRINT("mig return %d", reply->RetCode); 7250 } 7251 } 7252 7253 7254 PRE(mach_vm_copy) 7255 { 7256 #pragma pack(4) 7257 typedef struct { 7258 mach_msg_header_t Head; 7259 NDR_record_t NDR; 7260 mach_vm_address_t source_address; 7261 mach_vm_size_t size; 7262 mach_vm_address_t dest_address; 7263 } Request; 7264 #pragma pack() 7265 7266 Request *req = (Request *)ARG1; 7267 7268 PRINT("mach_vm_copy(%s, 0x%llx, %llu, 0x%llx)", 7269 name_for_port(MACH_REMOTE), 7270 req->source_address, req->size, req->dest_address); 7271 7272 // arg1 is task 7273 // vt->syscall_arg2 = req->source_address; 7274 // vt->syscall_arg3 = req->size; 7275 // vt->syscall_arg4 = req->dest_address; 7276 7277 AFTER = POST_FN(mach_vm_copy); 7278 } 7279 7280 POST(mach_vm_copy) 7281 { 7282 #pragma pack(4) 7283 typedef struct { 7284 mach_msg_header_t Head; 7285 NDR_record_t NDR; 7286 kern_return_t RetCode; 7287 mach_msg_trailer_t trailer; 7288 } Reply; 7289 #pragma pack() 7290 7291 Reply *reply = (Reply *)ARG1; 7292 7293 if (!reply->RetCode) { 7294 if (MACH_REMOTE == vg_task_port) { 7295 // GrP fixme set dest's initialization equal to src's 7296 // BUT vm_copy allocates no memory 7297 } 7298 } else { 7299 PRINT("mig return %d", reply->RetCode); 7300 } 7301 } 7302 7303 PRE(mach_vm_read_overwrite) 7304 { 7305 #pragma pack(4) 7306 typedef struct { 7307 mach_msg_header_t Head; 7308 NDR_record_t NDR; 7309 mach_vm_address_t address; 7310 mach_vm_size_t size; 7311 mach_vm_address_t data; 7312 } Request; 7313 #pragma pack() 7314 7315 Request *req = (Request *)ARG1; 7316 7317 PRINT("mach_vm_read_overwrite(%s, 0x%llx, %llu, 0x%llx)", 7318 name_for_port(MACH_REMOTE), 7319 req->address, req->size, req->data); 7320 7321 AFTER = POST_FN(mach_vm_read_overwrite); 7322 } 7323 7324 POST(mach_vm_read_overwrite) 7325 { 7326 #pragma pack(4) 7327 typedef struct { 7328 mach_msg_header_t Head; 7329 NDR_record_t NDR; 7330 kern_return_t RetCode; 7331 mach_vm_size_t outsize; 7332 } Reply; 7333 #pragma pack() 7334 7335 Reply *reply = (Reply *)ARG1; 7336 7337 if (!reply->RetCode) { 7338 if (MACH_REMOTE == vg_task_port) { 7339 // GrP fixme set dest's initialization equal to src's 7340 // BUT vm_copy allocates no memory 7341 } 7342 } else { 7343 PRINT("mig return %d", reply->RetCode); 7344 } 7345 } 7346 7347 PRE(mach_vm_map) 7348 { 7349 #pragma pack(4) 7350 typedef struct { 7351 mach_msg_header_t Head; 7352 /* start of the kernel processed data */ 7353 mach_msg_body_t msgh_body; 7354 mach_msg_port_descriptor_t object; 7355 /* end of the kernel processed data */ 7356 NDR_record_t NDR; 7357 mach_vm_address_t address; 7358 mach_vm_size_t size; 7359 mach_vm_address_t mask; 7360 int flags; 7361 memory_object_offset_t offset; 7362 boolean_t copy; 7363 vm_prot_t cur_protection; 7364 vm_prot_t max_protection; 7365 vm_inherit_t inheritance; 7366 } Request; 7367 #pragma pack() 7368 7369 Request *req = (Request *)ARG1; 7370 7371 // GrP fixme check these 7372 PRINT("mach_vm_map(in %s->%s at 0x%llx, size %llu, cur_prot:%x max_prot:%x ...)", 7373 name_for_port(req->Head.msgh_remote_port), 7374 name_for_port(req->object.name), 7375 req->address, req->size, 7376 req->cur_protection, 7377 req->max_protection); 7378 7379 MACH_ARG(mach_vm_map.size) = req->size; 7380 MACH_ARG(mach_vm_map.copy) = req->copy; 7381 MACH_ARG(mach_vm_map.protection) = 7382 (req->cur_protection & req->max_protection); 7383 7384 AFTER = POST_FN(mach_vm_map); 7385 } 7386 7387 POST(mach_vm_map) 7388 { 7389 #pragma pack(4) 7390 typedef struct { 7391 mach_msg_header_t Head; 7392 NDR_record_t NDR; 7393 kern_return_t RetCode; 7394 mach_vm_address_t address; 7395 mach_msg_trailer_t trailer; 7396 } Reply; 7397 #pragma pack() 7398 7399 Reply *reply = (Reply *)ARG1; 7400 7401 if (!reply->RetCode) { 7402 // GrP fixme check src and dest tasks 7403 PRINT("mapped at 0x%llx", reply->address); 7404 # if 0 7405 // GrP fixme max prot 7406 ML_(notify_core_and_tool_of_mmap)( 7407 reply->address, VG_PGROUNDUP(MACH_ARG(mach_vm_map.size)), 7408 MACH_ARG(mach_vm_map.protection), VKI_MAP_SHARED, -1, 0); 7409 // GrP fixme VKI_MAP_PRIVATE if !copy? 7410 # else 7411 ML_(sync_mappings)("after", "mach_vm_map", 0); 7412 # endif 7413 } else { 7414 PRINT("mig return %d", reply->RetCode); 7415 } 7416 } 7417 7418 7419 PRE(mach_vm_remap) 7420 { 7421 #pragma pack(4) 7422 typedef struct { 7423 mach_msg_header_t Head; 7424 /* start of the kernel processed data */ 7425 mach_msg_body_t msgh_body; 7426 mach_msg_port_descriptor_t src_task; 7427 /* end of the kernel processed data */ 7428 NDR_record_t NDR; 7429 mach_vm_address_t target_address; 7430 mach_vm_size_t size; 7431 mach_vm_offset_t mask; 7432 int flags; 7433 mach_vm_address_t src_address; 7434 boolean_t copy; 7435 vm_inherit_t inheritance; 7436 } Request; 7437 #pragma pack() 7438 7439 Request *req = (Request *)ARG1; 7440 7441 // GrP fixme check these 7442 PRINT("mach_vm_remap(in %s, at 0x%llx, size %llu, from %s ...)", 7443 name_for_port(MACH_REMOTE), 7444 req->target_address, req->size, 7445 name_for_port(req->src_task.name)); 7446 7447 MACH_ARG(mach_vm_remap.size) = req->size; 7448 MACH_ARG(mach_vm_remap.copy) = req->copy; 7449 7450 AFTER = POST_FN(mach_vm_remap); 7451 } 7452 7453 POST(mach_vm_remap) 7454 { 7455 #pragma pack(4) 7456 typedef struct { 7457 mach_msg_header_t Head; 7458 NDR_record_t NDR; 7459 kern_return_t RetCode; 7460 mach_vm_address_t target_address; 7461 vm_prot_t cur_protection; 7462 vm_prot_t max_protection; 7463 } Reply; 7464 #pragma pack() 7465 7466 Reply *reply = (Reply *)ARG1; 7467 7468 if (!reply->RetCode) { 7469 // GrP fixme check src and dest tasks 7470 PRINT("mapped at 0x%llx", reply->target_address); 7471 // GrP fixme max prot 7472 ML_(notify_core_and_tool_of_mmap)( 7473 reply->target_address, VG_PGROUNDUP(MACH_ARG(mach_vm_remap.size)), 7474 reply->cur_protection, VKI_MAP_SHARED, -1, 0); 7475 // GrP fixme VKI_MAP_PRIVATE if !copy? 7476 } else { 7477 PRINT("mig return %d", reply->RetCode); 7478 } 7479 } 7480 7481 7482 PRE(mach_vm_region_recurse) 7483 { 7484 #pragma pack(4) 7485 typedef struct { 7486 mach_msg_header_t Head; 7487 NDR_record_t NDR; 7488 mach_vm_address_t address; 7489 natural_t nesting_depth; 7490 mach_msg_type_number_t infoCnt; 7491 } Request; 7492 #pragma pack() 7493 7494 Request *req = (Request *)ARG1; 7495 7496 PRINT("mach_vm_region_recurse(in %s, at 0x%llx, depth %u, count %u)", 7497 name_for_port(MACH_REMOTE), 7498 req->address, req->nesting_depth, req->infoCnt); 7499 7500 AFTER = POST_FN(mach_vm_region_recurse); 7501 } 7502 7503 POST(mach_vm_region_recurse) 7504 { 7505 #pragma pack(4) 7506 typedef struct { 7507 mach_msg_header_t Head; 7508 NDR_record_t NDR; 7509 kern_return_t RetCode; 7510 mach_vm_address_t address; 7511 mach_vm_size_t size; 7512 natural_t nesting_depth; 7513 mach_msg_type_number_t infoCnt; 7514 int info[19]; 7515 } Reply; 7516 #pragma pack() 7517 7518 Reply *reply = (Reply *)ARG1; 7519 7520 if (!reply->RetCode) { 7521 PRINT("got region at 0x%llx, size %llu, depth %u, count %u", 7522 reply->address, reply->size, 7523 reply->nesting_depth, reply->infoCnt); 7524 // GrP fixme mark info contents beyond infoCnt as bogus 7525 } else { 7526 PRINT("mig return %d", reply->RetCode); 7527 } 7528 } 7529 7530 7531 /* --------------------------------------------------------------------- 7532 mach_msg: messages to thread 7533 ------------------------------------------------------------------ */ 7534 7535 7536 7537 POST(thread_terminate) 7538 { 7539 } 7540 7541 7542 PRE(thread_terminate) 7543 { 7544 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 7545 Bool self_terminate = (mh->msgh_request_port == MACH_THREAD); 7546 7547 PRINT("thread_terminate(%s)", name_for_port(mh->msgh_request_port)); 7548 7549 AFTER = POST_FN(thread_terminate); 7550 7551 if (self_terminate) { 7552 // Terminating this thread. 7553 // Copied from sys_exit. 7554 ThreadState *tst = VG_(get_ThreadState)(tid); 7555 tst->exitreason = VgSrc_ExitThread; 7556 tst->os_state.exitcode = 0; // GrP fixme anything better? 7557 // What we would like to do is: 7558 // SET_STATUS_Success(0); 7559 // but that doesn't work, because this is a MACH-class syscall, 7560 // and SET_STATUS_Success creates a UNIX-class syscall result. 7561 // Hence we have to laboriously construct the full SysRes "by hand" 7562 // and use that to set the syscall return status. 7563 #if defined(VGA_x86) 7564 SET_STATUS_from_SysRes( 7565 VG_(mk_SysRes_x86_darwin)( 7566 VG_DARWIN_SYSCALL_CLASS_MACH, 7567 False/*success*/, 0, 0 7568 ) 7569 ); 7570 #elif defined(VGA_amd64) 7571 SET_STATUS_from_SysRes( 7572 VG_(mk_SysRes_amd64_darwin)( 7573 VG_DARWIN_SYSCALL_CLASS_MACH, 7574 False/*success*/, 0, 0 7575 ) 7576 ); 7577 #else 7578 #error unknown architecture 7579 #endif 7580 *flags &= ~SfMayBlock; // clear flag set by PRE(mach_msg) 7581 } else { 7582 // Terminating some other thread. 7583 // Do keep the scheduler lock while terminating any other thread. 7584 // Otherwise we might halt the other thread while it holds the lock, 7585 // which would deadlock the process. 7586 // GrP fixme good enough? 7587 // GrP fixme need to clean up other thread's valgrind data? 7588 } 7589 } 7590 7591 7592 POST(thread_create) 7593 { 7594 } 7595 7596 7597 PRE(thread_create) 7598 { 7599 PRINT("thread_create(mach_task_self(), ...)"); 7600 7601 AFTER = POST_FN(thread_create); 7602 7603 // GrP fixme 7604 VG_(core_panic)("thread_create() unimplemented"); 7605 } 7606 7607 7608 PRE(thread_create_running) 7609 { 7610 #pragma pack(4) 7611 typedef struct { 7612 mach_msg_header_t Head; 7613 NDR_record_t NDR; 7614 thread_state_flavor_t flavor; 7615 mach_msg_type_number_t new_stateCnt; 7616 natural_t new_state[144]; 7617 } Request; 7618 #pragma pack() 7619 7620 Request *req; 7621 thread_state_t regs; 7622 ThreadState *new_thread; 7623 7624 PRINT("thread_create_running(mach_task_self(), ...)"); 7625 7626 // The new thread will immediately begin execution, 7627 // so we need to hijack the register state here. 7628 7629 req = (Request *)ARG1; 7630 regs = (thread_state_t)req->new_state; 7631 7632 // Build virtual thread. 7633 new_thread = build_thread(regs, req->flavor, req->new_stateCnt); 7634 7635 // Edit the thread state to send to the real kernel. 7636 hijack_thread_state(regs, req->flavor, req->new_stateCnt, new_thread); 7637 7638 AFTER = POST_FN(thread_create_running); 7639 } 7640 7641 7642 POST(thread_create_running) 7643 { 7644 #pragma pack(4) 7645 typedef struct { 7646 mach_msg_header_t Head; 7647 /* start of the kernel processed data */ 7648 mach_msg_body_t msgh_body; 7649 mach_msg_port_descriptor_t child_act; 7650 /* end of the kernel processed data */ 7651 } Reply; 7652 #pragma pack() 7653 7654 Reply *reply = (Reply *)ARG1; 7655 7656 assign_port_name(reply->child_act.name, "thread-%p"); 7657 PRINT("%s", name_for_port(reply->child_act.name)); 7658 } 7659 7660 7661 PRE(bsdthread_create) 7662 { 7663 ThreadState *tst; 7664 7665 PRINT("bsdthread_create( %#lx, %#lx, %#lx, %#lx, %#lx )", 7666 ARG1, ARG2, ARG3, ARG4, ARG5); 7667 PRE_REG_READ5(pthread_t,"bsdthread_create", 7668 void *,"func", void *,"func_arg", void *,"stack", 7669 pthread_t,"thread", unsigned int,"flags"); 7670 7671 // The kernel will call V's pthread_hijack() to launch the thread. 7672 // Here we allocate the thread state and pass it to pthread_hijack() 7673 // via the func_arg parameter. 7674 7675 tst = VG_(get_ThreadState)(VG_(alloc_ThreadState)()); 7676 allocstack(tst->tid); 7677 7678 tst->os_state.func_arg = (Addr)ARG2; 7679 ARG2 = (Word)tst; 7680 7681 // Create a semaphore that pthread_hijack will signal once it starts 7682 // POST(bsdthread_create) needs to wait for the new memory map to appear 7683 semaphore_create(mach_task_self(), &tst->os_state.child_go, 7684 SYNC_POLICY_FIFO, 0); 7685 semaphore_create(mach_task_self(), &tst->os_state.child_done, 7686 SYNC_POLICY_FIFO, 0); 7687 } 7688 7689 POST(bsdthread_create) 7690 { 7691 // Tell new thread's pthread_hijack to proceed, and wait for it to finish. 7692 // We hold V's lock on the child's behalf. 7693 // If we return before letting pthread_hijack do its thing, V thinks 7694 // the new pthread struct is still unmapped when we return to libc, 7695 // causing false errors. 7696 7697 ThreadState *tst = (ThreadState *)ARG2; 7698 semaphore_signal(tst->os_state.child_go); 7699 semaphore_wait(tst->os_state.child_done); 7700 semaphore_destroy(mach_task_self(), tst->os_state.child_go); 7701 semaphore_destroy(mach_task_self(), tst->os_state.child_done); 7702 7703 // GrP fixme semaphore destroy needed when thread creation fails 7704 // GrP fixme probably other cleanup too 7705 // GrP fixme spinlocks might be good enough? 7706 7707 // DDD: I'm not at all sure this is the right spot for this. It probably 7708 // should be in pthread_hijack instead, just before the call to 7709 // start_thread_NORETURN(), call_on_new_stack_0_1(), but we don't have the 7710 // parent tid value there... 7711 vg_assert(VG_(owns_BigLock_LL)(tid)); 7712 VG_TRACK ( pre_thread_ll_create, tid, tst->tid ); 7713 } 7714 7715 7716 PRE(bsdthread_terminate) 7717 { 7718 ThreadState *tst; 7719 7720 PRINT("bsdthread_terminate( %#lx, %lx, %s, %s )", 7721 ARG1, ARG2, name_for_port(ARG3), name_for_port(ARG4)); 7722 PRE_REG_READ4(int,"bsdthread_terminate", 7723 void *,"freeaddr", size_t,"freesize", 7724 mach_port_t,"kport", mach_port_t,"joinsem"); 7725 7726 // Free memory and signal semaphore. 7727 // GrP fixme errors? 7728 if (ARG4) semaphore_signal((semaphore_t)ARG4); 7729 if (ARG1 && ARG2) { 7730 ML_(notify_core_and_tool_of_munmap)(ARG1, ARG2); 7731 # if DARWIN_VERS >= DARWIN_10_8 7732 /* JRS 2012 Aug 02: ugly hack: vm_deallocate disappeared from 7733 the mig output. Work around it for the time being. */ 7734 VG_(do_syscall2)(__NR_munmap, ARG1, ARG2); 7735 # else 7736 vm_deallocate(mach_task_self(), (vm_address_t)ARG1, (vm_size_t)ARG2); 7737 # endif 7738 } 7739 7740 // Tell V to terminate the thread. 7741 // Copied from sys_exit. 7742 tst = VG_(get_ThreadState)(tid); 7743 tst->exitreason = VgSrc_ExitThread; 7744 tst->os_state.exitcode = 0; // GrP fixme anything better? 7745 SET_STATUS_Success(0); 7746 } 7747 7748 7749 POST(thread_suspend) 7750 { 7751 } 7752 7753 PRE(thread_suspend) 7754 { 7755 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 7756 Bool self_suspend = (mh->msgh_request_port == MACH_THREAD); 7757 7758 PRINT("thread_suspend(%s)", name_for_port(mh->msgh_request_port)); 7759 7760 AFTER = POST_FN(thread_suspend); 7761 7762 if (self_suspend) { 7763 // Don't keep the scheduler lock while self-suspending. 7764 // Otherwise we might halt while still holding the lock, 7765 // which would deadlock the process. 7766 *flags |= SfMayBlock; 7767 } else { 7768 // Do keep the scheduler lock while suspending any other thread. 7769 // Otherwise we might halt the other thread while it holds the lock, 7770 // which would deadlock the process. 7771 *flags &= ~SfMayBlock; 7772 } 7773 } 7774 7775 7776 POST(thread_resume) 7777 { 7778 } 7779 7780 PRE(thread_resume) 7781 { 7782 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 7783 Bool self_resume = (mh->msgh_request_port == MACH_THREAD); 7784 7785 PRINT("thread_resume(%s)", name_for_port(mh->msgh_request_port)); 7786 7787 AFTER = POST_FN(thread_resume); 7788 7789 if (self_resume) { 7790 // This doesn't make much sense. If we are resuming ourself, we can't 7791 // already be running. So I don't see how we can ever get here. 7792 vg_assert(0); 7793 } else { 7794 // Resuming some other thread. It might not yet come back to life 7795 // (if the suspend count is still above zero) so make sure we keep 7796 // holding the lock. 7797 *flags &= ~SfMayBlock; 7798 } 7799 } 7800 7801 7802 POST(thread_get_state) 7803 { 7804 #pragma pack(4) 7805 typedef struct { 7806 mach_msg_header_t Head; 7807 NDR_record_t NDR; 7808 kern_return_t RetCode; 7809 mach_msg_type_number_t old_stateCnt; 7810 natural_t old_state[144]; 7811 mach_msg_trailer_t trailer; 7812 } Reply; 7813 #pragma pack() 7814 7815 Reply *reply = (Reply *)ARG1; 7816 // mach_port_t thread = MACH_ARG(thread_get_state.thread); 7817 thread_state_flavor_t flavor = MACH_ARG(thread_get_state.flavor); 7818 7819 if (!reply->RetCode) { 7820 thread_state_from_vex((thread_state_t)reply->old_state, 7821 flavor, reply->old_stateCnt, 7822 &VG_(get_ThreadState)(tid)->arch.vex); 7823 } else { 7824 PRINT("mig return %d", reply->RetCode); 7825 } 7826 } 7827 7828 PRE(thread_get_state) 7829 { 7830 #pragma pack(4) 7831 typedef struct { 7832 mach_msg_header_t Head; 7833 NDR_record_t NDR; 7834 thread_state_flavor_t flavor; 7835 mach_msg_type_number_t old_stateCnt; 7836 } Request; 7837 #pragma pack() 7838 7839 Request *req = (Request *)ARG1; 7840 // Bool self = (req->Head.msgh_request_port == MACH_THREAD); 7841 7842 // GrP fixme if (self) { 7843 PRINT("thread_get_state(%s, %d)", 7844 name_for_port(req->Head.msgh_request_port), req->flavor); 7845 /*} else { 7846 PRINT("thread_get_state(0x%x, %d)", 7847 req->Head.msgh_request_port, req->flavor); 7848 }*/ 7849 7850 // Hack the thread state after making the real call. 7851 MACH_ARG(thread_get_state.thread) = req->Head.msgh_request_port; 7852 MACH_ARG(thread_get_state.flavor) = req->flavor; 7853 7854 AFTER = POST_FN(thread_get_state); 7855 } 7856 7857 7858 PRE(thread_policy) 7859 { 7860 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 7861 // Bool self = (mh->msgh_request_port == MACH_THREAD); 7862 7863 // GrP fixme if (self) { 7864 PRINT("thread_policy(%s, ...)", name_for_port(mh->msgh_request_port)); 7865 /*} else { 7866 PRINT("thread_policy(thread 0x%x, ...)", mh->msgh_request_port); 7867 }*/ 7868 7869 AFTER = POST_FN(thread_policy); 7870 } 7871 7872 POST(thread_policy) 7873 { 7874 } 7875 7876 7877 PRE(thread_policy_set) 7878 { 7879 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 7880 7881 PRINT("thread_policy_set(%s, ...)", name_for_port(mh->msgh_request_port)); 7882 7883 AFTER = POST_FN(thread_policy_set); 7884 } 7885 7886 POST(thread_policy_set) 7887 { 7888 } 7889 7890 7891 PRE(thread_info) 7892 { 7893 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 7894 7895 PRINT("thread_info(%s, ...)", name_for_port(mh->msgh_request_port)); 7896 // GrP fixme does any thread info need to be hijacked? 7897 7898 AFTER = POST_FN(thread_info); 7899 } 7900 7901 POST(thread_info) 7902 { 7903 // GrP fixme mark unused parts of thread_info_out as uninitialized? 7904 } 7905 7906 7907 7908 /* --------------------------------------------------------------------- 7909 mach_msg: messages to bootstrap port 7910 ------------------------------------------------------------------ */ 7911 7912 7913 POST(bootstrap_register) 7914 { 7915 #pragma pack(4) 7916 typedef struct { 7917 mach_msg_header_t Head; 7918 NDR_record_t NDR; 7919 kern_return_t RetCode; 7920 mach_msg_trailer_t trailer; 7921 } Reply; 7922 #pragma pack() 7923 7924 Reply *reply = (Reply *)ARG1; 7925 7926 if (reply->RetCode) PRINT("mig return %d", reply->RetCode); 7927 } 7928 7929 PRE(bootstrap_register) 7930 { 7931 #pragma pack(4) 7932 typedef struct { 7933 mach_msg_header_t Head; 7934 /* start of the kernel processed data */ 7935 mach_msg_body_t msgh_body; 7936 mach_msg_port_descriptor_t service_port; 7937 /* end of the kernel processed data */ 7938 NDR_record_t NDR; 7939 name_t service_name; 7940 } Request; 7941 #pragma pack() 7942 7943 Request *req = (Request *)ARG1; 7944 7945 PRINT("bootstrap_register(port 0x%x, \"%s\")", 7946 req->service_port.name, req->service_name); 7947 7948 /* The required entry in the allocated_ports list (mapping) might 7949 not exist, due perhaps to broken syscall wrappers (mach__N etc). 7950 Create a minimal entry so that assign_port_name below doesn't 7951 cause an assertion. */ 7952 if (!port_exists(req->service_port.name)) { 7953 port_create_vanilla(req->service_port.name); 7954 } 7955 7956 assign_port_name(req->service_port.name, req->service_name); 7957 7958 AFTER = POST_FN(bootstrap_register); 7959 } 7960 7961 7962 POST(bootstrap_look_up) 7963 { 7964 #pragma pack(4) 7965 typedef struct { 7966 mach_msg_header_t Head; 7967 /* start of the kernel processed data */ 7968 mach_msg_body_t msgh_body; 7969 mach_msg_port_descriptor_t service_port; 7970 /* end of the kernel processed data */ 7971 mach_msg_trailer_t trailer; 7972 } Reply; 7973 #pragma pack() 7974 7975 Reply *reply = (Reply *)ARG1; 7976 7977 if ((reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) && 7978 reply->service_port.name) 7979 { 7980 assign_port_name(reply->service_port.name, 7981 MACH_ARG(bootstrap_look_up.service_name)); 7982 PRINT("%s", name_for_port(reply->service_port.name)); 7983 } else { 7984 PRINT("not found"); 7985 } 7986 VG_(free)(MACH_ARG(bootstrap_look_up.service_name)); 7987 } 7988 7989 PRE(bootstrap_look_up) 7990 { 7991 #pragma pack(4) 7992 typedef struct { 7993 mach_msg_header_t Head; 7994 NDR_record_t NDR; 7995 name_t service_name; 7996 } Request; 7997 #pragma pack() 7998 7999 Request *req = (Request *)ARG1; 8000 8001 PRINT("bootstrap_look_up(\"%s\")", req->service_name); 8002 8003 MACH_ARG(bootstrap_look_up.service_name) = 8004 VG_(strdup)("syswrap-darwin.bootstrap-name", req->service_name); 8005 8006 AFTER = POST_FN(bootstrap_look_up); 8007 } 8008 8009 8010 /* --------------------------------------------------------------------- 8011 mach_msg: receiver-specific handlers 8012 ------------------------------------------------------------------ */ 8013 8014 8015 POST(mach_msg_receive) 8016 { 8017 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8018 8019 // GrP fixme don't know of anything interesting here currently 8020 // import_complex_message handles everything 8021 // PRINT("UNHANDLED reply %d", mh->msgh_id); 8022 8023 // Assume the call may have mapped or unmapped memory 8024 ML_(sync_mappings)("after", "mach_msg_receive", mh->msgh_id); 8025 } 8026 8027 PRE(mach_msg_receive) 8028 { 8029 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8030 8031 PRINT("mach_msg_receive(port %s)", name_for_port(mh->msgh_reply_port)); 8032 8033 AFTER = POST_FN(mach_msg_receive); 8034 8035 // no message sent, only listening for a reply 8036 // assume message may block 8037 *flags |= SfMayBlock; 8038 } 8039 8040 8041 PRE(mach_msg_bootstrap) 8042 { 8043 // message to bootstrap port 8044 8045 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8046 8047 switch (mh->msgh_id) { 8048 case 403: 8049 CALL_PRE(bootstrap_register); 8050 return; 8051 case 404: 8052 CALL_PRE(bootstrap_look_up); 8053 return; 8054 8055 default: 8056 PRINT("UNHANDLED bootstrap message [id %d, to %s, reply 0x%x]\n", 8057 mh->msgh_id, name_for_port(mh->msgh_request_port), 8058 mh->msgh_reply_port); 8059 return; 8060 } 8061 } 8062 8063 8064 PRE(mach_msg_host) 8065 { 8066 // message to host self - check for host-level kernel calls 8067 8068 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8069 8070 switch (mh->msgh_id) { 8071 case 200: 8072 CALL_PRE(host_info); 8073 return; 8074 case 202: 8075 CALL_PRE(host_page_size); 8076 return; 8077 case 205: 8078 CALL_PRE(host_get_io_master); 8079 return; 8080 case 206: 8081 CALL_PRE(host_get_clock_service); 8082 return; 8083 case 217: 8084 CALL_PRE(host_request_notification); 8085 return; 8086 case 222: 8087 CALL_PRE(host_create_mach_voucher); 8088 return; 8089 8090 case 412: 8091 CALL_PRE(host_get_special_port); 8092 return; 8093 8094 default: 8095 // unknown message to host self 8096 log_decaying("UNKNOWN host message [id %d, to %s, reply 0x%x]", 8097 mh->msgh_id, name_for_port(mh->msgh_request_port), 8098 mh->msgh_reply_port); 8099 return; 8100 } 8101 } 8102 8103 // JRS 2011-Aug-25: these magic numbers (3201 etc) come from 8104 // /usr/include/mach/mach_port.h et al (grep in /usr/include 8105 // for them) 8106 PRE(mach_msg_task) 8107 { 8108 // message to a task port 8109 8110 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8111 8112 switch (mh->msgh_id) { 8113 case 3201: 8114 CALL_PRE(mach_port_type); 8115 return; 8116 case 3204: 8117 CALL_PRE(mach_port_allocate); 8118 return; 8119 case 3205: 8120 CALL_PRE(mach_port_destroy); 8121 return; 8122 case 3206: 8123 CALL_PRE(mach_port_deallocate); 8124 return; 8125 case 3207: 8126 CALL_PRE(mach_port_get_refs); 8127 return; 8128 case 3208: 8129 CALL_PRE(mach_port_mod_refs); 8130 return; 8131 case 3211: 8132 CALL_PRE(mach_port_get_set_status); 8133 return; 8134 case 3212: 8135 CALL_PRE(mach_port_move_member); 8136 return; 8137 case 3213: 8138 CALL_PRE(mach_port_request_notification); 8139 return; 8140 case 3214: 8141 CALL_PRE(mach_port_insert_right); 8142 return; 8143 case 3215: 8144 CALL_PRE(mach_port_extract_right); 8145 return; 8146 case 3217: 8147 CALL_PRE(mach_port_get_attributes); 8148 return; 8149 case 3218: 8150 CALL_PRE(mach_port_set_attributes); 8151 return; 8152 case 3226: 8153 CALL_PRE(mach_port_insert_member); 8154 return; 8155 case 3227: 8156 CALL_PRE(mach_port_extract_member); 8157 return; 8158 8159 case 3229: 8160 CALL_PRE(mach_port_set_context); 8161 return; 8162 8163 case 3402: 8164 CALL_PRE(task_threads); 8165 return; 8166 case 3403: 8167 CALL_PRE(mach_ports_register); 8168 return; 8169 case 3404: 8170 CALL_PRE(mach_ports_lookup); 8171 return; 8172 case 3405: 8173 CALL_PRE(task_info); 8174 return; 8175 case 3406: 8176 CALL_PRE(task_set_info); 8177 return; 8178 case 3407: 8179 CALL_PRE(task_suspend); 8180 return; 8181 case 3408: 8182 CALL_PRE(task_resume); 8183 return; 8184 case 3409: 8185 CALL_PRE(task_get_special_port); 8186 return; 8187 case 3410: 8188 CALL_PRE(task_set_special_port); 8189 return; 8190 case 3411: 8191 CALL_PRE(thread_create); 8192 return; 8193 case 3412: 8194 CALL_PRE(thread_create_running); 8195 return; 8196 8197 case 3414: 8198 CALL_PRE(task_get_exception_ports); 8199 return; 8200 8201 case 3418: 8202 CALL_PRE(semaphore_create); 8203 return; 8204 case 3419: 8205 CALL_PRE(semaphore_destroy); 8206 return; 8207 case 3420: 8208 CALL_PRE(task_policy_set); 8209 return; 8210 8211 #if DARWIN_VERS >= DARWIN_10_12 8212 case 3444: 8213 CALL_PRE(task_register_dyld_image_infos); 8214 return; 8215 8216 case 3447: 8217 CALL_PRE(task_register_dyld_shared_cache_image_info); 8218 return; 8219 #endif /* DARWIN_VERS >= DARWIN_10_12 */ 8220 8221 case 3801: 8222 CALL_PRE(vm_allocate); 8223 return; 8224 case 3802: 8225 CALL_PRE(vm_deallocate); 8226 return; 8227 case 3803: 8228 CALL_PRE(vm_protect); 8229 return; 8230 case 3804: 8231 CALL_PRE(vm_inherit); 8232 return; 8233 case 3805: 8234 CALL_PRE(vm_read); 8235 return; 8236 case 3808: 8237 CALL_PRE(vm_copy); 8238 return; 8239 case 3809: 8240 CALL_PRE(vm_read_overwrite); 8241 return; 8242 case 3812: 8243 CALL_PRE(vm_map); 8244 return; 8245 case 3814: 8246 CALL_PRE(vm_remap); 8247 return; 8248 case 3825: 8249 CALL_PRE(mach_make_memory_entry_64); 8250 return; 8251 case 3830: 8252 CALL_PRE(vm_purgable_control); 8253 return; 8254 8255 case 4800: 8256 CALL_PRE(mach_vm_allocate); 8257 return; 8258 case 4801: 8259 CALL_PRE(mach_vm_deallocate); 8260 return; 8261 case 4802: 8262 CALL_PRE(mach_vm_protect); 8263 return; 8264 case 4803: 8265 CALL_PRE(mach_vm_inherit); 8266 return; 8267 case 4804: 8268 CALL_PRE(mach_vm_read); 8269 return; 8270 case 4807: 8271 CALL_PRE(mach_vm_copy); 8272 return; 8273 case 4808: 8274 CALL_PRE(mach_vm_read_overwrite); 8275 return; 8276 case 4811: 8277 CALL_PRE(mach_vm_map); 8278 return; 8279 case 4813: 8280 CALL_PRE(mach_vm_remap); 8281 return; 8282 case 4815: 8283 CALL_PRE(mach_vm_region_recurse); 8284 return; 8285 case 4817: 8286 CALL_PRE(mach_make_memory_entry_64); 8287 return; 8288 case 4818: 8289 CALL_PRE(mach_vm_purgable_control); 8290 return; 8291 8292 default: 8293 // unknown message to task self 8294 log_decaying("UNKNOWN task message [id %d, to %s, reply 0x%x]", 8295 mh->msgh_id, name_for_port(mh->msgh_remote_port), 8296 mh->msgh_reply_port); 8297 return; 8298 } 8299 } 8300 8301 8302 PRE(mach_msg_thread) 8303 { 8304 // message to local thread - check for thread-level kernel calls 8305 8306 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8307 8308 switch (mh->msgh_id) { 8309 case 3600: 8310 CALL_PRE(thread_terminate); 8311 return; 8312 case 3603: 8313 CALL_PRE(thread_get_state); 8314 return; 8315 case 3605: 8316 CALL_PRE(thread_suspend); 8317 return; 8318 case 3606: 8319 CALL_PRE(thread_resume); 8320 return; 8321 case 3612: 8322 CALL_PRE(thread_info); 8323 return; 8324 case 3616: 8325 CALL_PRE(thread_policy); 8326 return; 8327 case 3617: 8328 CALL_PRE(thread_policy_set); 8329 return; 8330 default: 8331 // unknown message to a thread 8332 VG_(printf)("UNKNOWN thread message [id %d, to %s, reply 0x%x]\n", 8333 mh->msgh_id, name_for_port(mh->msgh_request_port), 8334 mh->msgh_reply_port); 8335 return; 8336 } 8337 } 8338 8339 8340 static int is_thread_port(mach_port_t port) 8341 { 8342 if (port == 0) return False; 8343 8344 return VG_(lwpid_to_vgtid)(port) != VG_INVALID_THREADID; 8345 } 8346 8347 8348 static int is_task_port(mach_port_t port) 8349 { 8350 if (port == 0) return False; 8351 8352 if (port == vg_task_port) return True; 8353 8354 return (0 == VG_(strncmp)("task-", name_for_port(port), 5)); 8355 } 8356 8357 8358 /* --------------------------------------------------------------------- 8359 mach_msg: base handlers 8360 ------------------------------------------------------------------ */ 8361 8362 PRE(mach_msg) 8363 { 8364 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8365 mach_msg_option_t option = (mach_msg_option_t)ARG2; 8366 // mach_msg_size_t send_size = (mach_msg_size_t)ARG3; 8367 mach_msg_size_t rcv_size = (mach_msg_size_t)ARG4; 8368 // mach_port_t rcv_name = (mach_port_t)ARG5; 8369 size_t complex_header_size = 0; 8370 8371 PRE_REG_READ7(long, "mach_msg", 8372 mach_msg_header_t*,"msg", mach_msg_option_t,"option", 8373 mach_msg_size_t,"send_size", mach_msg_size_t,"rcv_size", 8374 mach_port_t,"rcv_name", mach_msg_timeout_t,"timeout", 8375 mach_port_t,"notify"); 8376 8377 // Assume default POST handler until specified otherwise 8378 AFTER = NULL; 8379 8380 // Assume call may block unless specified otherwise 8381 *flags |= SfMayBlock; 8382 8383 if (option & MACH_SEND_MSG) { 8384 // Validate outgoing message header 8385 PRE_MEM_READ("mach_msg(msg.msgh_bits)", 8386 (Addr)&mh->msgh_bits, sizeof(mh->msgh_bits)); 8387 // msgh_size not required, use parameter instead 8388 PRE_MEM_READ("mach_msg(msg.msgh_remote_port)", 8389 (Addr)&mh->msgh_remote_port, sizeof(mh->msgh_remote_port)); 8390 PRE_MEM_READ("mach_msg(msg.msgh_local_port)", 8391 (Addr)&mh->msgh_local_port, sizeof(mh->msgh_local_port)); 8392 // msgh_reserved not required 8393 PRE_MEM_READ("mach_msg(msg.msgh_id)", 8394 (Addr)&mh->msgh_id, sizeof(mh->msgh_id)); 8395 8396 if (mh->msgh_bits & MACH_MSGH_BITS_COMPLEX) { 8397 // Validate typed message data and handle memory map changes. 8398 complex_header_size = export_complex_message(tid, mh); 8399 } 8400 8401 // GrP fixme handle sender-specified message trailer 8402 // (but is this only for too-secure processes?) 8403 // JRS 11 Nov 2014: this assertion is OK for <= 10.9 but fails on 10.10 8404 # if DARWIN_VERS >= DARWIN_10_10 8405 if (mh->msgh_bits & MACH_SEND_TRAILER) { 8406 log_decaying("UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option"); 8407 } 8408 # else 8409 vg_assert(! (mh->msgh_bits & MACH_SEND_TRAILER)); 8410 # endif 8411 8412 MACH_REMOTE = mh->msgh_remote_port; 8413 MACH_MSGH_ID = mh->msgh_id; 8414 } 8415 8416 if (option & MACH_RCV_MSG) { 8417 // Pre-validate receive buffer 8418 PRE_MEM_WRITE("mach_msg(receive buffer)", (Addr)mh, rcv_size); 8419 } 8420 8421 // Call a PRE handler. The PRE handler may set an AFTER handler. 8422 8423 if (!(option & MACH_SEND_MSG)) { 8424 // no message sent, receive only 8425 CALL_PRE(mach_msg_receive); 8426 return; 8427 } 8428 else if (mh->msgh_request_port == vg_host_port) { 8429 // message sent to mach_host_self() 8430 CALL_PRE(mach_msg_host); 8431 return; 8432 } 8433 else if (is_task_port(mh->msgh_request_port)) { 8434 // message sent to a task 8435 CALL_PRE(mach_msg_task); 8436 return; 8437 } 8438 else if (mh->msgh_request_port == vg_bootstrap_port) { 8439 // message sent to bootstrap port 8440 CALL_PRE(mach_msg_bootstrap); 8441 return; 8442 } 8443 else if (is_thread_port(mh->msgh_request_port)) { 8444 // message sent to one of this process's threads 8445 CALL_PRE(mach_msg_thread); 8446 return; 8447 } 8448 else { 8449 // this is an attempt to optimize mapping sync 8450 // but there are always some cases hard to find 8451 #if 0 8452 Bool do_mapping_update = False; 8453 // sorted by msgh_id, we suppose that msgh_id are different for each service, 8454 // which is obviously not true... 8455 switch (mh->msgh_id) { 8456 // com.apple.windowserver.active 8457 case 29008: // this one opens a port type 'a' 8458 8459 // com.apple.windowserver.active 'a' port 8460 case 29000: 8461 case 29822: 8462 case 29820: // adds a vm mapping 8463 case 29809: // contains a ool mem 8464 case 29800: // opens a port type 'b' 8465 case 29873: 8466 case 29876: // adds a vm mapping 8467 8468 // com.apple.windowserver.active 'b' port 8469 case 29624: 8470 case 29625: 8471 case 29506: 8472 case 29504: 8473 case 29509: 8474 case 29315: 8475 case 29236: 8476 case 29473: 8477 case 29268: 8478 case 29237: // contains a ool mem 8479 case 29360: 8480 case 29301: 8481 case 29287: 8482 case 29568: 8483 case 29570: // contains a ool mem 8484 case 29211: 8485 case 29569: // contains a ool mem 8486 case 29374: 8487 case 29246: 8488 case 29239: 8489 case 29272: 8490 if (mh->msgh_id == 29820 || 8491 mh->msgh_id == 29876) 8492 do_mapping_update = True; 8493 8494 PRINT("com.apple.windowserver.active service mach_msg [id %d, to %s, reply 0x%x]", 8495 mh->msgh_id, name_for_port(mh->msgh_request_port), 8496 mh->msgh_reply_port); 8497 break; 8498 8499 // com.apple.FontServer 8500 case 13024: 8501 PRINT("com.apple.FontServerservice mach_msg [id %d, to %s, reply 0x%x]", 8502 mh->msgh_id, name_for_port(mh->msgh_request_port), 8503 mh->msgh_reply_port); 8504 break; 8505 8506 // com.apple.system.notification_center 8507 case 78945698: 8508 case 78945701: 8509 case 78945695: // contains a ool mem 8510 case 78945694: 8511 case 78945700: 8512 if (mh->msgh_id == 78945695) 8513 do_mapping_update = False; 8514 PRINT("com.apple.system.notification_center mach_msg [id %d, to %s, reply 0x%x]", 8515 mh->msgh_id, name_for_port(mh->msgh_request_port), 8516 mh->msgh_reply_port); 8517 break; 8518 8519 // com.apple.CoreServices.coreservicesd 8520 case 10000: 8521 case 10019: 8522 case 10002: // adds vm mappings 8523 case 10003: // adds vm mappings 8524 case 14007: 8525 case 13000: 8526 case 13001: 8527 case 13011: 8528 case 13016: // contains a ool mem 8529 if (mh->msgh_id == 10002|| 8530 mh->msgh_id == 10003) 8531 do_mapping_update = True; 8532 PRINT("com.apple.CoreServices.coreservicesd mach_msg [id %d, to %s, reply 0x%x]", 8533 mh->msgh_id, name_for_port(mh->msgh_request_port), 8534 mh->msgh_reply_port); 8535 break; 8536 8537 // com.apple.system.logger 8538 case 118: 8539 PRINT("com.apple.system.logger mach_msg [id %d, to %s, reply 0x%x]", 8540 mh->msgh_id, name_for_port(mh->msgh_request_port), 8541 mh->msgh_reply_port); 8542 break; 8543 8544 // com.apple.coreservices.launchservicesd, and others 8545 case 1999646836: // might adds vm mapping 8546 if (mh->msgh_id == 1999646836) 8547 do_mapping_update = True; 8548 PRINT("om.apple.coreservices.launchservicesd mach_msg [id %d, to %s, reply 0x%x]", 8549 mh->msgh_id, name_for_port(mh->msgh_request_port), 8550 mh->msgh_reply_port); 8551 break; 8552 8553 // com.apple.ocspd 8554 case 33012: 8555 PRINT("com.apple.ocspd mach_msg [id %d, to %s, reply 0x%x]", 8556 mh->msgh_id, name_for_port(mh->msgh_request_port), 8557 mh->msgh_reply_port); 8558 8559 default: 8560 // arbitrary message to arbitrary port 8561 do_mapping_update = True; 8562 PRINT("UNHANDLED mach_msg [id %d, to %s, reply 0x%x]", 8563 mh->msgh_id, name_for_port(mh->msgh_request_port), 8564 mh->msgh_reply_port); 8565 } 8566 8567 // this is an optimization, don't check mapping on known mach_msg 8568 if (do_mapping_update) 8569 AFTER = POST_FN(mach_msg_unhandled); 8570 else 8571 AFTER = POST_FN(mach_msg_unhandled_check); 8572 #else 8573 AFTER = POST_FN(mach_msg_unhandled); 8574 #endif 8575 8576 // Assume the entire message body may be read. 8577 // GrP fixme generates false positives for unknown protocols 8578 /* 8579 PRE_MEM_READ("mach_msg(payload)", 8580 (Addr)((char*)mh + sizeof(mach_msg_header_t) + complex_header_size), 8581 send_size - sizeof(mach_msg_header_t) - complex_header_size); 8582 */ 8583 return; 8584 } 8585 } 8586 8587 POST(mach_msg) 8588 { 8589 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8590 mach_msg_option_t option = (mach_msg_option_t)ARG2; 8591 8592 if (option & MACH_RCV_MSG) { 8593 if (RES != 0) { 8594 // error during send or receive 8595 // GrP fixme need to clean up port rights? 8596 } else { 8597 mach_msg_trailer_t *mt = 8598 (mach_msg_trailer_t *)((Addr)mh + round_msg(mh->msgh_size)); 8599 8600 // Assume the entire received message and trailer is initialized 8601 // GrP fixme would being more specific catch any bugs? 8602 POST_MEM_WRITE((Addr)mh, 8603 round_msg(mh->msgh_size) + mt->msgh_trailer_size); 8604 8605 if (mh->msgh_bits & MACH_MSGH_BITS_COMPLEX) { 8606 // Update memory map for out-of-line message data 8607 import_complex_message(tid, mh); 8608 } 8609 } 8610 } 8611 8612 // Call handler chosen by PRE(mach_msg) 8613 if (AFTER) { 8614 (*AFTER)(tid, arrghs, status); 8615 } 8616 } 8617 8618 8619 POST(mach_msg_unhandled) 8620 { 8621 mach_msg_header_t *mh = (mach_msg_header_t *)ARG1; 8622 ML_(sync_mappings)("after", "mach_msg_receive-UNHANDLED", mh->msgh_id); 8623 } 8624 8625 POST(mach_msg_unhandled_check) 8626 { 8627 if (ML_(sync_mappings)("after", "mach_msg_receive (unhandled_check)", 0)) 8628 PRINT("mach_msg_unhandled_check tid:%d missed mapping change()", tid); 8629 } 8630 8631 8632 /* --------------------------------------------------------------------- 8633 other Mach traps 8634 ------------------------------------------------------------------ */ 8635 8636 PRE(mach_reply_port) 8637 { 8638 PRINT("mach_reply_port()"); 8639 } 8640 8641 POST(mach_reply_port) 8642 { 8643 record_named_port(tid, RES, MACH_PORT_RIGHT_RECEIVE, "reply-%p"); 8644 PRINT("reply port %s", name_for_port(RES)); 8645 } 8646 8647 8648 PRE(mach_thread_self) 8649 { 8650 PRINT("mach_thread_self()"); 8651 } 8652 8653 POST(mach_thread_self) 8654 { 8655 record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "thread-%p"); 8656 PRINT("thread %#lx", RES); 8657 } 8658 8659 8660 PRE(mach_host_self) 8661 { 8662 PRINT("mach_host_self()"); 8663 } 8664 8665 POST(mach_host_self) 8666 { 8667 vg_host_port = RES; 8668 record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "mach_host_self()"); 8669 PRINT("host %#lx", RES); 8670 } 8671 8672 8673 PRE(mach_task_self) 8674 { 8675 PRINT("mach_task_self()"); 8676 } 8677 8678 POST(mach_task_self) 8679 { 8680 vg_task_port = RES; 8681 record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "mach_task_self()"); 8682 PRINT("task %#lx", RES); 8683 } 8684 8685 8686 PRE(syscall_thread_switch) 8687 { 8688 PRINT("syscall_thread_switch(%s, %ld, %ld)", 8689 name_for_port(ARG1), SARG2, SARG3); 8690 PRE_REG_READ3(long, "syscall_thread_switch", 8691 mach_port_t,"thread", int,"option", natural_t,"timeout"); 8692 8693 *flags |= SfMayBlock; 8694 } 8695 8696 8697 PRE(semaphore_signal) 8698 { 8699 PRINT("semaphore_signal(%s)", name_for_port(ARG1)); 8700 PRE_REG_READ1(long, "semaphore_signal", semaphore_t,"semaphore"); 8701 } 8702 8703 8704 PRE(semaphore_signal_all) 8705 { 8706 PRINT("semaphore_signal_all(%s)", name_for_port(ARG1)); 8707 PRE_REG_READ1(long, "semaphore_signal_all", semaphore_t,"semaphore"); 8708 } 8709 8710 8711 PRE(semaphore_signal_thread) 8712 { 8713 PRINT("semaphore_signal_thread(%s, %s)", 8714 name_for_port(ARG1), name_for_port(ARG2)); 8715 PRE_REG_READ2(long, "semaphore_signal_thread", 8716 semaphore_t,"semaphore", mach_port_t,"thread"); 8717 } 8718 8719 8720 PRE(semaphore_wait) 8721 { 8722 PRINT("semaphore_wait(%s)", name_for_port(ARG1)); 8723 PRE_REG_READ1(long, "semaphore_signal", semaphore_t,"semaphore"); 8724 8725 *flags |= SfMayBlock; 8726 } 8727 8728 8729 PRE(semaphore_wait_signal) 8730 { 8731 PRINT("semaphore_wait_signal(%s, %s)", 8732 name_for_port(ARG1), name_for_port(ARG2)); 8733 PRE_REG_READ2(long, "semaphore_wait_signal", 8734 semaphore_t,"wait_semaphore", 8735 semaphore_t,"signal_semaphore"); 8736 8737 *flags |= SfMayBlock; 8738 } 8739 8740 8741 PRE(semaphore_timedwait) 8742 { 8743 PRINT("semaphore_timedwait(%s, %g seconds)", 8744 name_for_port(ARG1), ARG2+ARG3/1000000000.0); 8745 PRE_REG_READ3(long, "semaphore_wait_signal", 8746 semaphore_t,"semaphore", 8747 int,"wait_time_hi", 8748 int,"wait_time_lo"); 8749 8750 *flags |= SfMayBlock; 8751 } 8752 8753 8754 PRE(semaphore_timedwait_signal) 8755 { 8756 PRINT("semaphore_wait_signal(wait %s, signal %s, %g seconds)", 8757 name_for_port(ARG1), name_for_port(ARG2), ARG3+ARG4/1000000000.0); 8758 PRE_REG_READ4(long, "semaphore_wait_signal", 8759 semaphore_t,"wait_semaphore", 8760 semaphore_t,"signal_semaphore", 8761 int,"wait_time_hi", 8762 int,"wait_time_lo"); 8763 8764 *flags |= SfMayBlock; 8765 } 8766 8767 8768 PRE(__semwait_signal) 8769 { 8770 /* 10.5 args: int cond_sem, int mutex_sem, 8771 int timeout, int relative, 8772 time_t tv_sec, time_t tv_nsec */ 8773 PRINT("__semwait_signal(wait %s, signal %s, %ld, %ld, %lds:%ldns)", 8774 name_for_port(ARG1), name_for_port(ARG2), SARG3, SARG4, SARG5, SARG6); 8775 PRE_REG_READ6(long, "__semwait_signal", 8776 int,"cond_sem", int,"mutex_sem", 8777 int,"timeout", int,"relative", 8778 vki_time_t,"tv_sec", int,"tv_nsec"); 8779 8780 *flags |= SfMayBlock; 8781 } 8782 // GrP provided this alternative version for 10.6, but NjN 8783 // reckons the 10.5 is is still correct for 10.6. So, retaining 8784 // Greg's version as a comment just in case we need it later. 8785 //PRE(__old_semwait_signal) 8786 //{ 8787 // /* 10.5 args: int cond_sem, int mutex_sem, 8788 // int timeout, int relative, 8789 // const timespec *ts */ 8790 // PRINT("__old_semwait_signal(wait %s, signal %s, %ld, %ld, %#lx)", 8791 // name_for_port(ARG1), name_for_port(ARG2), ARG3, ARG4, ARG5); 8792 // PRE_REG_READ5(int, "__old_semwait_signal", 8793 // int,cond_sem, int,mutex_sem, 8794 // int,timeout, int,relative, 8795 // const struct vki_timespec *,ts); 8796 // 8797 // if (ARG5) PRE_MEM_READ ("__old_semwait_signal(ts)", 8798 // ARG5, sizeof(struct vki_timespec)); 8799 // 8800 // *flags |= SfMayBlock; 8801 //} 8802 8803 8804 PRE(task_for_pid) 8805 { 8806 PRINT("task_for_pid(%s, %ld, %#lx)", name_for_port(ARG1), SARG2, ARG3); 8807 PRE_REG_READ3(long, "task_for_pid", 8808 mach_port_t,"target", 8809 vki_pid_t, "pid", mach_port_t *,"task"); 8810 PRE_MEM_WRITE("task_for_pid(task)", ARG3, sizeof(mach_port_t)); 8811 } 8812 8813 POST(task_for_pid) 8814 { 8815 mach_port_t task; 8816 8817 POST_MEM_WRITE(ARG3, sizeof(mach_port_t)); 8818 8819 task = *(mach_port_t *)ARG3; 8820 record_named_port(tid, task, MACH_PORT_RIGHT_SEND, "task-%p"); 8821 PRINT("task 0x%x", task); 8822 } 8823 8824 8825 PRE(pid_for_task) 8826 { 8827 PRINT("pid_for_task(%s, %#lx)", name_for_port(ARG1), ARG2); 8828 PRE_REG_READ2(long, "task_for_pid", mach_port_t,"task", vki_pid_t *,"pid"); 8829 PRE_MEM_WRITE("task_for_pid(pid)", ARG2, sizeof(vki_pid_t)); 8830 } 8831 8832 POST(pid_for_task) 8833 { 8834 vki_pid_t pid; 8835 8836 POST_MEM_WRITE(ARG2, sizeof(vki_pid_t)); 8837 8838 pid = *(vki_pid_t *)ARG2; 8839 PRINT("pid %u", pid); 8840 } 8841 8842 8843 PRE(mach_timebase_info) 8844 { 8845 PRINT("mach_timebase_info(%#lx)", ARG1); 8846 PRE_REG_READ1(long, "mach_timebase_info", void *,"info"); 8847 PRE_MEM_WRITE("mach_timebase_info(info)", ARG1, sizeof(struct vki_mach_timebase_info)); 8848 } 8849 8850 POST(mach_timebase_info) 8851 { 8852 POST_MEM_WRITE(ARG1, sizeof(struct vki_mach_timebase_info)); 8853 } 8854 8855 8856 PRE(mach_wait_until) 8857 { 8858 #if VG_WORDSIZE == 8 8859 PRINT("mach_wait_until(%lu)", ARG1); 8860 PRE_REG_READ1(long, "mach_wait_until", 8861 unsigned long long,"deadline"); 8862 #else 8863 PRINT("mach_wait_until(%llu)", LOHI64(ARG1, ARG2)); 8864 PRE_REG_READ2(long, "mach_wait_until", 8865 int,"deadline_hi", int,"deadline_lo"); 8866 #endif 8867 *flags |= SfMayBlock; 8868 } 8869 8870 8871 PRE(mk_timer_create) 8872 { 8873 PRINT("mk_timer_create()"); 8874 PRE_REG_READ0(long, "mk_timer_create"); 8875 } 8876 8877 POST(mk_timer_create) 8878 { 8879 record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "mk_timer-%p"); 8880 } 8881 8882 8883 PRE(mk_timer_destroy) 8884 { 8885 PRINT("mk_timer_destroy(%s)", name_for_port(ARG1)); 8886 PRE_REG_READ1(long, "mk_timer_destroy", mach_port_t,"name"); 8887 8888 // Must block to prevent race (other thread allocates and 8889 // notifies after we deallocate but before we notify) 8890 *flags &= ~SfMayBlock; 8891 } 8892 8893 POST(mk_timer_destroy) 8894 { 8895 // Must have cleared SfMayBlock in PRE to prevent race 8896 record_port_destroy(ARG1); 8897 } 8898 8899 8900 PRE(mk_timer_arm) 8901 { 8902 #if VG_WORDSIZE == 8 8903 PRINT("mk_timer_arm(%s, %lu)", name_for_port(ARG1), ARG2); 8904 PRE_REG_READ2(long, "mk_timer_arm", mach_port_t,"name", 8905 unsigned long,"expire_time"); 8906 #else 8907 PRINT("mk_timer_arm(%s, %llu)", name_for_port(ARG1), LOHI64(ARG2, ARG3)); 8908 PRE_REG_READ3(long, "mk_timer_arm", mach_port_t,"name", 8909 int,"expire_time_hi", int,"expire_time_lo"); 8910 #endif 8911 } 8912 8913 8914 PRE(mk_timer_cancel) 8915 { 8916 PRINT("mk_timer_cancel(%s, %#lx)", name_for_port(ARG1), ARG2); 8917 PRE_REG_READ2(long, "mk_timer_cancel", 8918 mach_port_t,"name", Addr,"result_time"); 8919 if (ARG2) { 8920 PRE_MEM_WRITE("mk_timer_cancel(result_time)", ARG2,sizeof(vki_uint64_t)); 8921 } 8922 } 8923 8924 POST(mk_timer_cancel) 8925 { 8926 if (ARG2) { 8927 POST_MEM_WRITE(ARG2, sizeof(vki_uint64_t)); 8928 } 8929 } 8930 8931 8932 PRE(iokit_user_client_trap) 8933 { 8934 PRINT("iokit_user_client_trap(%s, %ld, %lx, %lx, %lx, %lx, %lx, %lx)", 8935 name_for_port(ARG1), ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); 8936 PRE_REG_READ8(kern_return_t, "iokit_user_client_trap", 8937 mach_port_t,connect, unsigned int,index, 8938 uintptr_t,p1, uintptr_t,p2, uintptr_t,p3, 8939 uintptr_t,p4, uintptr_t,p5, uintptr_t,p6); 8940 8941 // can't do anything else with this in general 8942 // might be able to use connect+index to choose something sometimes 8943 } 8944 8945 POST(iokit_user_client_trap) 8946 { 8947 ML_(sync_mappings)("after", "iokit_user_client_trap", ARG2); 8948 } 8949 8950 8951 PRE(swtch) 8952 { 8953 PRINT("swtch ( )"); 8954 PRE_REG_READ0(long, "swtch"); 8955 8956 *flags |= SfMayBlock; 8957 } 8958 8959 8960 PRE(swtch_pri) 8961 { 8962 PRINT("swtch_pri ( %ld )", SARG1); 8963 PRE_REG_READ1(long, "swtch_pri", int,"pri"); 8964 8965 *flags |= SfMayBlock; 8966 } 8967 8968 8969 PRE(FAKE_SIGRETURN) 8970 { 8971 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 8972 an explanation of what follows. */ 8973 /* This handles the fake signal-return system call created by 8974 sigframe-x86-darwin.c. */ 8975 /* See also comments just below on PRE(sigreturn). */ 8976 8977 PRINT("FAKE_SIGRETURN ( )"); 8978 8979 vg_assert(VG_(is_valid_tid)(tid)); 8980 vg_assert(tid >= 1 && tid < VG_N_THREADS); 8981 vg_assert(VG_(is_running_thread)(tid)); 8982 8983 /* Remove the signal frame from this thread's (guest) stack, 8984 in the process restoring the pre-signal guest state. */ 8985 VG_(sigframe_destroy)(tid, True); 8986 8987 /* Tell the driver not to update the guest state with the "result", 8988 and set a bogus result to keep it happy. */ 8989 *flags |= SfNoWriteResult; 8990 SET_STATUS_Success(0); 8991 8992 /* Check to see if any signals arose as a result of this. */ 8993 *flags |= SfPollAfter; 8994 } 8995 8996 8997 PRE(sigreturn) 8998 { 8999 /* This is the "real" sigreturn. But because we construct all the 9000 signal frames ourselves (of course, in m_sigframe), this cannot 9001 happen as a result of normal signal delivery. I think it 9002 happens only when doing siglongjmp, in which case Darwin's Libc 9003 appears to use it for two different purposes: to mess with the 9004 per-thread sigaltstack flags (as per arg 2), or to restore the 9005 thread's state from a ucontext* (as per arg 1). */ 9006 9007 PRINT("sigreturn ( uctx=%#lx, infostyle=%#lx )", ARG1, ARG2); 9008 9009 vg_assert(VG_(is_valid_tid)(tid)); 9010 vg_assert(tid >= 1 && tid < VG_N_THREADS); 9011 vg_assert(VG_(is_running_thread)(tid)); 9012 9013 if (ARG2 == VKI_UC_SET_ALT_STACK) { 9014 /* This is confusing .. the darwin kernel sources imply there is 9015 a per-thread on-altstack/not-on-altstack flag, which is set 9016 by this flag. Just ignore it and claim success for the time 9017 being. */ 9018 VG_(debugLog)(0, "syswrap-darwin", 9019 "WARNING: Ignoring sigreturn( ..., " 9020 "UC_SET_ALT_STACK );\n"); 9021 SET_STATUS_Success(0); 9022 return; 9023 } 9024 if (ARG2 == VKI_UC_RESET_ALT_STACK) { 9025 /* Ditto */ 9026 VG_(debugLog)(0, "syswrap-darwin", 9027 "WARNING: Ignoring sigreturn( ..., " 9028 "UC_RESET_ALT_STACK );\n"); 9029 SET_STATUS_Success(0); 9030 return; 9031 } 9032 9033 /* Otherwise claim this isn't supported. (Could be 9034 catastrophic). 9035 9036 What do we have to do if we do need to support it? 9037 9038 1. Change the second argument of VG_(sigframe_destroy) from 9039 "Bool isRT" to "UInt sysno", so we can pass the syscall 9040 number, so it can distinguish this case from the 9041 __NR_DARWIN_FAKE_SIGRETURN case. 9042 9043 2. In VG_(sigframe_destroy), look at sysno to distinguish the 9044 cases. For __NR_DARWIN_FAKE_SIGRETURN, behave as at present. 9045 For this case, restore the thread's CPU state (or at least 9046 the integer regs) from the ucontext in ARG1 (and do all the 9047 other "signal-returns" stuff too). 9048 9049 3. For (2), how do we know where the ucontext is? One way is to 9050 temporarily copy ARG1 into this thread's guest_EBX (or any 9051 other int reg), and have VG_(sigframe_destroy) read 9052 guest_EBX. Why is it ok to trash guest_EBX (or any other int 9053 reg)? Because VG_(sigframe_destroy) is just about to 9054 overwrite all the regs anyway -- since the primary purpose of 9055 calling it is to restore the register state from the ucontext 9056 pointed to by ARG1. 9057 9058 Hey, it's uggerly. But at least it's documented. 9059 */ 9060 /* But in the meantime ... */ 9061 VG_(debugLog)(0, "syswrap-darwin", 9062 "WARNING: Ignoring sigreturn( uctx=..., 0 );\n"); 9063 VG_(debugLog)(0, "syswrap-darwin", 9064 "WARNING: Thread/program/Valgrind " 9065 "will likely segfault now.\n"); 9066 VG_(debugLog)(0, "syswrap-darwin", 9067 "WARNING: Please file a bug report at " 9068 "http://www.valgrind.org.\n"); 9069 SET_STATUS_Failure( VKI_ENOSYS ); 9070 } 9071 9072 9073 /* --------------------------------------------------------------------- 9074 machine-dependent traps 9075 ------------------------------------------------------------------ */ 9076 9077 #if defined(VGA_x86) 9078 static VexGuestX86SegDescr* alloc_zeroed_x86_LDT ( void ) 9079 { 9080 Int nbytes = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr); 9081 return VG_(calloc)("syswrap-darwin.ldt", nbytes, 1); 9082 } 9083 #endif 9084 9085 PRE(thread_fast_set_cthread_self) 9086 { 9087 PRINT("thread_fast_set_cthread_self ( %#lx )", ARG1); 9088 PRE_REG_READ1(void, "thread_fast_set_cthread_self", struct pthread_t *, self); 9089 9090 #if defined(VGA_x86) 9091 // Point the USER_CTHREAD ldt entry (slot 6, reg 0x37) at this pthread 9092 { 9093 VexGuestX86SegDescr *ldt; 9094 ThreadState *tst = VG_(get_ThreadState)(tid); 9095 ldt = (VexGuestX86SegDescr *)tst->arch.vex.guest_LDT; 9096 if (!ldt) { 9097 ldt = alloc_zeroed_x86_LDT(); 9098 tst->arch.vex.guest_LDT = (HWord)ldt; 9099 } 9100 VG_(memset)(&ldt[6], 0, sizeof(ldt[6])); 9101 ldt[6].LdtEnt.Bits.LimitLow = 1; 9102 ldt[6].LdtEnt.Bits.LimitHi = 0; 9103 ldt[6].LdtEnt.Bits.BaseLow = ARG1 & 0xffff; 9104 ldt[6].LdtEnt.Bits.BaseMid = (ARG1 >> 16) & 0xff; 9105 ldt[6].LdtEnt.Bits.BaseHi = (ARG1 >> 24) & 0xff; 9106 ldt[6].LdtEnt.Bits.Pres = 1; // ACC_P 9107 ldt[6].LdtEnt.Bits.Dpl = 3; // ACC_PL_U 9108 ldt[6].LdtEnt.Bits.Type = 0x12; // ACC_DATA_W 9109 ldt[6].LdtEnt.Bits.Granularity = 1; // SZ_G 9110 ldt[6].LdtEnt.Bits.Default_Big = 1; // SZ_32 9111 9112 tst->os_state.pthread = ARG1; 9113 tst->arch.vex.guest_GS = 0x37; 9114 9115 // What we would like to do is: 9116 // SET_STATUS_Success(0x37); 9117 // but that doesn't work, because this is a MDEP-class syscall, 9118 // and SET_STATUS_Success creates a UNIX-class syscall result. 9119 // Hence we have to laboriously construct the full SysRes "by hand" 9120 // and use that to set the syscall return status. 9121 SET_STATUS_from_SysRes( 9122 VG_(mk_SysRes_x86_darwin)( 9123 VG_DARWIN_SYSNO_CLASS(__NR_thread_fast_set_cthread_self), 9124 False, 0, 0x37 9125 ) 9126 ); 9127 } 9128 9129 #elif defined(VGA_amd64) 9130 // GrP fixme bigger hack than x86 9131 { 9132 ThreadState *tst = VG_(get_ThreadState)(tid); 9133 tst->os_state.pthread = ARG1; 9134 tst->arch.vex.guest_GS_CONST = ARG1; 9135 // SET_STATUS_Success(0x60); 9136 // see comments on x86 case just above 9137 SET_STATUS_from_SysRes( 9138 VG_(mk_SysRes_amd64_darwin)( 9139 VG_DARWIN_SYSNO_CLASS(__NR_thread_fast_set_cthread_self), 9140 False, 0, 0x60 9141 ) 9142 ); 9143 } 9144 9145 #else 9146 #error unknown architecture 9147 #endif 9148 } 9149 9150 9151 /* --------------------------------------------------------------------- 9152 Added for OSX 10.6 (Snow Leopard) 9153 ------------------------------------------------------------------ */ 9154 9155 #if DARWIN_VERS >= DARWIN_10_6 9156 9157 PRE(psynch_mutexwait) 9158 { 9159 PRINT("psynch_mutexwait(BOGUS)"); 9160 *flags |= SfMayBlock; 9161 } 9162 POST(psynch_mutexwait) 9163 { 9164 } 9165 9166 PRE(psynch_mutexdrop) 9167 { 9168 PRINT("psynch_mutexdrop(BOGUS)"); 9169 *flags |= SfMayBlock; 9170 } 9171 POST(psynch_mutexdrop) 9172 { 9173 } 9174 9175 PRE(psynch_cvbroad) 9176 { 9177 PRINT("psynch_cvbroad(BOGUS)"); 9178 } 9179 POST(psynch_cvbroad) 9180 { 9181 } 9182 9183 PRE(psynch_cvsignal) 9184 { 9185 PRINT("psynch_cvsignal(BOGUS)"); 9186 } 9187 POST(psynch_cvsignal) 9188 { 9189 } 9190 9191 PRE(psynch_cvwait) 9192 { 9193 PRINT("psynch_cvwait(BOGUS)"); 9194 *flags |= SfMayBlock; 9195 } 9196 POST(psynch_cvwait) 9197 { 9198 } 9199 9200 PRE(psynch_rw_rdlock) 9201 { 9202 PRINT("psynch_rw_rdlock(BOGUS)"); 9203 *flags |= SfMayBlock; 9204 } 9205 POST(psynch_rw_rdlock) 9206 { 9207 } 9208 9209 PRE(psynch_rw_wrlock) 9210 { 9211 PRINT("psynch_rw_wrlock(BOGUS)"); 9212 *flags |= SfMayBlock; 9213 } 9214 POST(psynch_rw_wrlock) 9215 { 9216 } 9217 9218 PRE(psynch_rw_unlock) 9219 { 9220 PRINT("psynch_rw_unlock(BOGUS)"); 9221 } 9222 POST(psynch_rw_unlock) 9223 { 9224 } 9225 9226 PRE(__thread_selfid) 9227 { 9228 PRINT("__thread_selfid ()"); 9229 PRE_REG_READ0(vki_uint64_t, "__thread_selfid"); 9230 } 9231 9232 PRE(fsgetpath) 9233 { 9234 #if VG_WORDSIZE == 4 9235 PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %llu)", 9236 ARG1, ARG2, ARG3, 9237 ((unsigned int *)ARG3)[0], ((unsigned int *)ARG3)[1], 9238 LOHI64(ARG4, ARG5)); 9239 PRE_REG_READ5(ssize_t, "fsgetpath", 9240 void*,"buf", size_t,"bufsize", 9241 fsid_t *,"fsid", 9242 vki_uint32_t, "objid_low32", vki_uint32_t, "objid_high32"); 9243 #else 9244 PRINT("fsgetpath(%#lx, %ld, %#lx {%u,%u}, %lu)", 9245 ARG1, ARG2, ARG3, 9246 ((unsigned int *)ARG3)[0], 9247 ((unsigned int *)ARG3)[1], ARG4); 9248 PRE_REG_READ4(ssize_t, "fsgetpath", 9249 void*,"buf", size_t,"bufsize", 9250 fsid_t *,"fsid", uint64_t,"objid"); 9251 #endif 9252 PRE_MEM_READ("fsgetpath(fsid)", ARG3, sizeof(fsid_t)); 9253 PRE_MEM_WRITE("fsgetpath(buf)", ARG1, ARG2); 9254 } 9255 9256 POST(fsgetpath) 9257 { 9258 POST_MEM_WRITE(ARG1, RES); 9259 } 9260 9261 PRE(audit_session_self) 9262 { 9263 PRINT("audit_session_self()"); 9264 } 9265 POST(audit_session_self) 9266 { 9267 record_named_port(tid, RES, MACH_PORT_RIGHT_SEND, "audit-session-%p"); 9268 PRINT("audit-session %#lx", RES); 9269 } 9270 9271 #endif /* DARWIN_VERS >= DARWIN_10_6 */ 9272 9273 9274 /* --------------------------------------------------------------------- 9275 Added for OSX 10.7 (Lion) 9276 ------------------------------------------------------------------ */ 9277 9278 #if DARWIN_VERS >= DARWIN_10_7 9279 9280 PRE(psynch_cvclrprepost) 9281 { 9282 PRINT("psynch_cvclrprepost(BOGUS)"); 9283 *flags |= SfMayBlock; 9284 } 9285 POST(psynch_cvclrprepost) 9286 { 9287 } 9288 9289 #endif /* DARWIN_VERS >= DARWIN_10_7 */ 9290 9291 9292 /* --------------------------------------------------------------------- 9293 Added for OSX 10.8 (Mountain Lion) 9294 ------------------------------------------------------------------ */ 9295 9296 /* About munge tags, eg munge_wllww. 9297 9298 Means the syscall takes 5 args. For a 64 bit process each arg 9299 occupies one 64-bit value and so the mapping to ARGn macros is 9300 direct. For a 32 bit process, this is more complex: 'w' denotes a 9301 32-bit word and 'l' a 64-bit word. Hence the wllww denotation 9302 indicates that, in a 64 bit process, the args are: ARG1 ARG2 ARG3 9303 ARG4 ARG5, but in a 32 bit process they are: ARG1 ARG3:ARG2 9304 ARG5:ARG4 ARG6 ARG7. And we have to laboriously reconstruct them 9305 in order to get sane values for the arguments in 32-bit 9306 processes. */ 9307 9308 static void munge_wwl(UWord* a1, UWord* a2, ULong* a3, 9309 UWord aRG1, UWord aRG2, UWord aRG3, UWord aRG4) 9310 { 9311 # if defined(VGA_x86) 9312 *a1 = aRG1; *a2 = aRG2; *a3 = LOHI64(aRG3,aRG4); 9313 # else 9314 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; 9315 # endif 9316 } 9317 9318 static void munge_wll(UWord* a1, ULong* a2, ULong* a3, 9319 UWord aRG1, UWord aRG2, UWord aRG3, 9320 UWord aRG4, UWord aRG5) 9321 { 9322 # if defined(VGA_x86) 9323 *a1 = aRG1; *a2 = LOHI64(aRG2,aRG3); *a3 = LOHI64(aRG4,aRG5); 9324 # else 9325 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; 9326 # endif 9327 } 9328 9329 static void munge_wwlw(UWord* a1, UWord* a2, ULong* a3, UWord* a4, 9330 UWord aRG1, UWord aRG2, UWord aRG3, 9331 UWord aRG4, UWord aRG5) 9332 { 9333 # if defined(VGA_x86) 9334 *a1 = aRG1; *a2 = aRG2; *a3 = LOHI64(aRG3,aRG4); *a4 = aRG5; 9335 # else 9336 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; *a4 = aRG4; 9337 # endif 9338 } 9339 9340 static void munge_wwwl(UWord* a1, UWord* a2, UWord* a3, ULong* a4, 9341 UWord aRG1, UWord aRG2, UWord aRG3, 9342 UWord aRG4, UWord aRG5) 9343 { 9344 # if defined(VGA_x86) 9345 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; *a4 = LOHI64(aRG4,aRG5); 9346 # else 9347 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; *a4 = aRG4; 9348 # endif 9349 } 9350 9351 static void munge_wllww(UWord* a1, ULong* a2, ULong* a3, UWord* a4, UWord* a5, 9352 UWord aRG1, UWord aRG2, UWord aRG3, 9353 UWord aRG4, UWord aRG5, UWord aRG6, UWord aRG7) 9354 { 9355 # if defined(VGA_x86) 9356 *a1 = aRG1; *a2 = LOHI64(aRG2,aRG3); *a3 = LOHI64(aRG4,aRG5); 9357 *a4 = aRG6; *a5 = aRG7; 9358 # else 9359 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; *a4 = aRG4; *a5 = aRG5; 9360 # endif 9361 } 9362 9363 static void munge_wwllww(UWord* a1, UWord* a2, ULong* a3, 9364 ULong* a4, UWord* a5, UWord* a6, 9365 UWord aRG1, UWord aRG2, UWord aRG3, UWord aRG4, 9366 UWord aRG5, UWord aRG6, UWord aRG7, UWord aRG8) 9367 { 9368 # if defined(VGA_x86) 9369 *a1 = aRG1; *a2 = aRG2; 9370 *a3 = LOHI64(aRG3,aRG4); *a4 = LOHI64(aRG5,aRG6); 9371 *a5 = aRG7; *a6 = aRG8; 9372 # else 9373 *a1 = aRG1; *a2 = aRG2; *a3 = aRG3; *a4 = aRG4; *a5 = aRG5; *a6 = aRG6; 9374 # endif 9375 } 9376 9377 #if DARWIN_VERS >= DARWIN_10_8 9378 9379 PRE(kernelrpc_mach_vm_allocate_trap) 9380 { 9381 UWord a1; UWord a2; ULong a3; UWord a4; 9382 munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); 9383 PRINT("kernelrpc_mach_vm_allocate_trap" 9384 "(target:%s, address:%p, size:%#llx, flags:%#lx)", 9385 name_for_port(a1), *(void**)a2, a3, a4); 9386 PRE_MEM_WRITE("kernelrpc_mach_vm_allocate_trap(address)", 9387 a2, sizeof(void*)); 9388 } 9389 POST(kernelrpc_mach_vm_allocate_trap) 9390 { 9391 UWord a1; UWord a2; ULong a3; UWord a4; 9392 munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); 9393 PRINT("address:%p size:%#llx", *(void**)a2, a3); 9394 if (ML_(safe_to_deref)((void*)a2, sizeof(void*))) { 9395 POST_MEM_WRITE(a2, sizeof(void*)); 9396 } 9397 if (a1 == mach_task_self()) { 9398 # if 1 9399 ML_(sync_mappings)("POST(kernelrpc_mach_vm_allocate_trap)", "??", 0); 9400 # else 9401 /* This is nearly right, but not always -- sometimes the mapping 9402 appears to be r--, for some reason. Hence resync. */ 9403 ML_(notify_core_and_tool_of_mmap)( 9404 *(UWord*)a2, a3, 9405 VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_ANON, -1, 0); 9406 # endif 9407 } 9408 } 9409 9410 PRE(kernelrpc_mach_vm_deallocate_trap) 9411 { 9412 UWord a1; ULong a2; ULong a3; 9413 munge_wll(&a1, &a2, &a3, ARG1, ARG2, ARG3, ARG4, ARG5); 9414 PRINT("kernelrpc_mach_vm_deallocate_trap" 9415 "(target:%#lx, address:%#llx, size:%#llx)", a1, a2, a3); 9416 } 9417 POST(kernelrpc_mach_vm_deallocate_trap) 9418 { 9419 UWord a1; ULong a2; ULong a3; 9420 munge_wll(&a1, &a2, &a3, ARG1, ARG2, ARG3, ARG4, ARG5); 9421 // kernelrpc_mach_vm_deallocate_trap could be call with 9422 // address ==0 && size == 0, 9423 // we shall not notify any unmap then 9424 if (a3) 9425 ML_(notify_core_and_tool_of_munmap)(a2, a3); 9426 } 9427 9428 PRE(kernelrpc_mach_vm_protect_trap) 9429 { 9430 UWord a1; ULong a2; ULong a3; UWord a4; UWord a5; 9431 munge_wllww(&a1, &a2, &a3, &a4, &a5, 9432 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); 9433 PRINT("kernelrpc_mach_vm_protect_trap" 9434 "(task:%#lx, address:%#llx, size:%#llx," 9435 " set_maximum:%#lx, new_prot:%#lx)", a1, a2, a3, a4, a5); 9436 } 9437 POST(kernelrpc_mach_vm_protect_trap) 9438 { 9439 UWord a1; ULong a2; ULong a3; UWord a4; UWord a5; 9440 munge_wllww(&a1, &a2, &a3, &a4, &a5, 9441 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); 9442 if (/*a4 set_maximum == 0 && */a1 == mach_task_self()) { 9443 ML_(notify_core_and_tool_of_mprotect)((Addr)a2, (SizeT)a3, (Int)a5); 9444 VG_(di_notify_vm_protect)((Addr)a2, (SizeT)a3, (UInt)a5); 9445 } 9446 } 9447 9448 PRE(kernelrpc_mach_port_allocate_trap) 9449 { 9450 // munge_www -- no need to call helper 9451 PRINT("kernelrpc_mach_port_allocate_trap(task:%#lx, mach_port_right_t:%#lx)", 9452 ARG1, ARG2); 9453 PRE_MEM_WRITE("kernelrpc_mach_port_allocate_trap(name)", 9454 ARG3, sizeof(mach_port_name_t)); 9455 } 9456 POST(kernelrpc_mach_port_allocate_trap) 9457 { 9458 // munge_www -- no need to call helper 9459 POST_MEM_WRITE(ARG3, sizeof(mach_port_name_t)); 9460 PRINT(", name:%#x", *(mach_port_name_t*)ARG3); 9461 record_unnamed_port(tid, *(mach_port_name_t *)ARG3, ARG2); 9462 } 9463 9464 PRE(kernelrpc_mach_port_destroy_trap) 9465 { 9466 // munge_ww -- no need to call helper 9467 PRINT("kernelrpc_mach_port_destroy_trap(task:%#lx, name:%#lx)", ARG1, ARG2); 9468 record_port_destroy(ARG2); 9469 } 9470 9471 PRE(kernelrpc_mach_port_deallocate_trap) 9472 { 9473 // munge_ww -- no need to call helper 9474 PRINT("kernelrpc_mach_port_deallocate_trap(task:%#lx, name:%#lx ) FIXME", 9475 ARG1, ARG2); 9476 } 9477 POST(kernelrpc_mach_port_deallocate_trap) 9478 { 9479 // munge_ww -- no need to call helper 9480 } 9481 9482 PRE(kernelrpc_mach_port_mod_refs_trap) 9483 { 9484 // munge_wwww -- no need to call helper 9485 PRINT("kernelrpc_mach_port_mod_refs_trap" 9486 "(task:%#lx, name:%#lx, right:%#lx refs:%#lx) FIXME", 9487 ARG1, ARG2, ARG3, ARG4); 9488 } 9489 9490 PRE(kernelrpc_mach_port_move_member_trap) 9491 { 9492 // munge_www -- no need to call helper 9493 PRINT("kernelrpc_mach_port_move_member_trap" 9494 "(task:%#lx, name:%#lx, after:%#lx ) FIXME", 9495 ARG1, ARG2, ARG3); 9496 } 9497 9498 PRE(kernelrpc_mach_port_insert_right_trap) 9499 { 9500 //munge_wwww -- no need to call helper 9501 PRINT("kernelrpc_mach_port_insert_right_trap(FIXME)" 9502 "(%lx,%lx,%lx,%lx)", ARG1, ARG2, ARG3, ARG4); 9503 } 9504 9505 PRE(kernelrpc_mach_port_insert_member_trap) 9506 { 9507 // munge_www -- no need to call helper 9508 PRINT("kernelrpc_mach_port_insert_member_trap(FIXME)" 9509 "(%lx,%lx,%lx)", ARG1, ARG2, ARG3); 9510 } 9511 9512 PRE(kernelrpc_mach_port_extract_member_trap) 9513 { 9514 // munge_www -- no need to call helper 9515 PRINT("kernelrpc_mach_port_extract_member_trap(FIXME)" 9516 "(%lx,%lx,%lx)", ARG1, ARG2, ARG3); 9517 } 9518 9519 PRE(iopolicysys) 9520 { 9521 // munge_??? 9522 PRINT("iopolicysys(FIXME)(0x%lx, 0x%lx, 0x%lx)", ARG1, ARG2, ARG3); 9523 /* mem effects unknown */ 9524 } 9525 POST(iopolicysys) 9526 { 9527 // munge_??? 9528 } 9529 9530 PRE(process_policy) 9531 { 9532 // munge_??? 9533 PRINT("process_policy(FIXME)(" 9534 "scope:0x%lx, action:0x%lx, policy:0x%lx, policy_subtype:0x%lx," 9535 " attr:%lx, target_pid:%lx, target_threadid:%lx)", 9536 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); 9537 /* mem effects unknown */ 9538 } 9539 POST(process_policy) 9540 { 9541 // munge_??? 9542 } 9543 9544 #endif /* DARWIN_VERS >= DARWIN_10_8 */ 9545 9546 9547 /* --------------------------------------------------------------------- 9548 Added for OSX 10.9 (Mavericks) 9549 ------------------------------------------------------------------ */ 9550 9551 #if DARWIN_VERS >= DARWIN_10_9 9552 9553 PRE(kernelrpc_mach_vm_map_trap) 9554 { 9555 UWord a1; UWord a2; ULong a3; ULong a4; UWord a5; UWord a6; 9556 munge_wwllww(&a1, &a2, &a3, &a4, &a5, &a6, 9557 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); 9558 PRINT("kernelrpc_mach_vm_map_trap" 9559 "(target:%#lx, address:%p, size:%#llx," 9560 " mask:%#llx, flags:%#lx, cur_prot:%#lx)", 9561 a1, *(void**)a2, a3, a4, a5, a6); 9562 PRE_MEM_WRITE("kernelrpc_mach_vm_map_trap(address)", a2, sizeof(void*)); 9563 } 9564 POST(kernelrpc_mach_vm_map_trap) 9565 { 9566 UWord a1; UWord a2; ULong a3; ULong a4; UWord a5; UWord a6; 9567 munge_wwllww(&a1, &a2, &a3, &a4, &a5, &a6, 9568 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8); 9569 PRINT("-> address:%p", *(void**)a2); 9570 if (ML_(safe_to_deref)((void*)a2, sizeof(void*))) { 9571 POST_MEM_WRITE(a2, sizeof(void*)); 9572 } 9573 ML_(notify_core_and_tool_of_mmap)( 9574 *(mach_vm_address_t*)a2, a3, 9575 VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_ANON, -1, 0); 9576 // ML_(sync_mappings)("after", "kernelrpc_mach_vm_map_trap", 0); 9577 } 9578 9579 PRE(kernelrpc_mach_port_construct_trap) 9580 { 9581 UWord a1; UWord a2; ULong a3; UWord a4; 9582 munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); 9583 PRINT("kernelrpc_mach_port_construct_trap(FIXME)" 9584 "(%lx,%lx,%llx,%lx)", a1, a2, a3, a4); 9585 } 9586 9587 PRE(kernelrpc_mach_port_destruct_trap) 9588 { 9589 UWord a1; UWord a2; UWord a3; ULong a4; 9590 munge_wwwl(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); 9591 PRINT("kernelrpc_mach_port_destruct_trap(FIXME)" 9592 "(%lx,%lx,%lx,%llx)", a1, a2, a3, a4); 9593 } 9594 9595 PRE(kernelrpc_mach_port_guard_trap) 9596 { 9597 UWord a1; UWord a2; ULong a3; UWord a4; 9598 munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); 9599 PRINT("kernelrpc_mach_port_guard_trap(FIXME)" 9600 "(%lx,%lx,%llx,%lx)", a1, a2, a3, a4); 9601 } 9602 9603 PRE(kernelrpc_mach_port_unguard_trap) 9604 { 9605 // munge_wwl 9606 UWord a1; UWord a2; ULong a3; 9607 munge_wwl(&a1, &a2, &a3, ARG1, ARG2, ARG3, ARG4); 9608 PRINT("kernelrpc_mach_port_unguard_trap(FIXME)" 9609 "(%lx,%lx,%llx)", a1, a2, a3); 9610 } 9611 9612 #endif /* DARWIN_VERS >= DARWIN_10_9 */ 9613 9614 9615 /* --------------------------------------------------------------------- 9616 Added for OSX 10.10 (Yosemite) 9617 ------------------------------------------------------------------ */ 9618 9619 #if DARWIN_VERS >= DARWIN_10_10 9620 9621 PRE(necp_match_policy) 9622 { 9623 // int necp_match_policy(uint8_t *parameters, size_t parameters_size, 9624 // struct necp_aggregate_result *returned_result) 9625 PRINT("necp_match_policy(FIXME)(%lx,%lu, %lx)", ARG1, ARG2, ARG3); 9626 PRE_REG_READ3(int, "necp_match_policy", uint8_t*, parameters, 9627 size_t, parameters_size, struct necp_aggregate_result*, 9628 returned_result); 9629 PRE_MEM_READ("necp_match_policy(returned_result)", ARG1, ARG2); 9630 } 9631 POST(necp_match_policy) 9632 { 9633 POST_MEM_WRITE(ARG3, sizeof(struct vki_necp_aggregate_result)); 9634 } 9635 9636 PRE(sysctlbyname) 9637 { 9638 UWord name = ARG1; 9639 UWord namelen = ARG2; 9640 UWord oldp = ARG3; 9641 UWord oldlenp = ARG4; 9642 UWord newp = ARG5; 9643 UWord newlen = ARG6; // FIXME: or newlenp ?? 9644 9645 PRINT( "sysctlbyname ( %#lx,%lu, %#lx,%#lx, %#lx,%lu )", 9646 name, namelen, oldp, oldlenp, newp, newlen ); 9647 9648 PRE_REG_READ6(int, "sysctlbyname", char*, name, size_t, namelen, 9649 void*, oldp, vki_size_t *, oldlenp, 9650 void*, newp, vki_size_t *, newlenp); // <---<< 9651 9652 // reads name[0..namelen-1] 9653 PRE_MEM_READ("sysctlbyname(name)", name, namelen); 9654 9655 if (VG_(clo_trace_syscalls)) { 9656 UInt i; 9657 const HChar* t_name = (const HChar*)name; 9658 VG_(printf)(" name: "); 9659 for (i = 0; i < namelen; i++) { 9660 VG_(printf)("%c", t_name[i]); 9661 } 9662 VG_(printf)(" "); 9663 } 9664 9665 Bool is_kern_dot_userstack 9666 = False; 9667 9668 common_PRE_sysctl( /*IMPLICIT ARGS*/tid,status,flags,/*!IMPLICIT_ARGS*/ 9669 is_kern_dot_userstack, oldp, oldlenp, newp, newlen ); 9670 } 9671 POST(sysctlbyname) 9672 { 9673 UWord oldp = ARG3; 9674 UWord oldlenp = ARG4; 9675 9676 if (SUCCESS || ERR == VKI_ENOMEM) { 9677 // sysctl can write truncated data and return VKI_ENOMEM 9678 if (oldlenp) { 9679 POST_MEM_WRITE(oldlenp, sizeof(size_t)); 9680 } 9681 if (oldp && oldlenp) { 9682 POST_MEM_WRITE(oldp, *(size_t*)oldlenp); 9683 } 9684 } 9685 } 9686 9687 PRE(getattrlistbulk) 9688 { 9689 // int getattrlistbulk(int dirfd, struct attrlist *alist, 9690 // void *attributeBuffer, size_t bufferSize, 9691 // uint64_t options); 9692 // Presumably the last arg is value-pair in the 32 bit case. 9693 PRINT("getattrlistbulk(FIXME)(%ld, %lx, %lx,%lu, %lu)", 9694 SARG1, ARG2, ARG3, ARG4, ARG5); 9695 PRE_REG_READ5(int, "getattrlistbulk", int, dirfd, void*, list, 9696 void*, attributeBuffer, size_t, bufferSize, 9697 uint32_t, options_lo32); 9698 PRE_MEM_READ("getattrlistbulk(alist)", ARG2, sizeof(struct vki_attrlist)); 9699 PRE_MEM_WRITE("getattrlistbulk(attributeBuffer)", ARG3, ARG4); 9700 } 9701 POST(getattrlistbulk) 9702 { 9703 // FIXME: this isn't right. It seems as if what is returned is a 9704 // set of variable-length records -- see complication in 9705 // POST(getattrlist). For now, just paint the entire result buffer 9706 // as defined. Sigh. 9707 vg_assert(SUCCESS); 9708 if (ARG3 && /* "at least one output element was written" */RES > 0) 9709 POST_MEM_WRITE(ARG3, ARG4); 9710 } 9711 9712 PRE(faccessat) 9713 { 9714 PRINT("faccessat(FIXME)(fd:%ld, path:%#lx(%s), amode:%#lx, flag:%#lx)", 9715 ARG1, ARG2, (HChar*)ARG2, ARG3, ARG4); 9716 PRE_REG_READ4(int, "faccessat", 9717 int, fd, user_addr_t, path, int, amode, int, flag); 9718 } 9719 9720 PRE(fstatat64) 9721 { 9722 PRINT("fstatat64(FIXME)(fd:%ld, path:%#lx(%s), ub:%#lx, flag:%#lx)", 9723 ARG1, ARG2, (HChar*)ARG2, ARG3, ARG4); 9724 PRE_REG_READ4(int, "fstatat64", 9725 int, fd, user_addr_t, path, user_addr_t, ub, int, flag); 9726 } 9727 9728 PRE(readlinkat) 9729 { 9730 Word saved = SYSNO; 9731 9732 PRINT("readlinkat ( %ld, %#lx(%s), %#lx, %ld )", 9733 SARG1, ARG2, (HChar*)ARG2, ARG3, SARG4); 9734 PRE_REG_READ4(long, "readlinkat", 9735 int, dfd, const char *, path, char *, buf, int, bufsiz); 9736 PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 ); 9737 PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 ); 9738 9739 /* 9740 * Refer to coregrind/m_syswrap/syswrap-linux.c 9741 */ 9742 { 9743 /* Normal case */ 9744 SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4)); 9745 } 9746 9747 if (SUCCESS && RES > 0) 9748 POST_MEM_WRITE( ARG3, RES ); 9749 } 9750 9751 PRE(bsdthread_ctl) 9752 { 9753 // int bsdthread_ctl(user_addr_t cmd, user_addr_t arg1, 9754 // user_addr_t arg2, user_addr_t arg3) 9755 PRINT("bsdthread_ctl(FIXME)(%lx,%lx,%lx,%lx)", ARG1, ARG2, ARG3, ARG4); 9756 PRE_REG_READ4(int, "bsdthreadctl", 9757 void*, cmd, void*, arg1, void*, arg2, void*, arg3); 9758 } 9759 9760 PRE(csrctl) 9761 { 9762 PRINT("csrctl(op:%ld, useraddr:%#lx, usersize:%#lx) FIXME", ARG1, ARG2, ARG3); 9763 PRE_REG_READ3(int, "csrctl", 9764 uint32_t, op, user_addr_t, useraddr, user_addr_t, usersize); 9765 } 9766 9767 PRE(guarded_open_dprotected_np) 9768 { 9769 PRINT("guarded_open_dprotected_np(" 9770 "path:%#lx(%s), guard:%#lx, guardflags:%#lx, flags:%#lx, " 9771 "dpclass:%#lx, dpflags: %#lx) FIXME", 9772 ARG1, (HChar*)ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); 9773 } 9774 9775 PRE(guarded_write_np) 9776 { 9777 PRINT("guarded_write_np(fd:%ld, guard:%#lx, cbuf:%#lx, nbyte:%llu) FIXME", 9778 ARG1, ARG2, ARG3, (ULong)ARG4); 9779 } 9780 9781 PRE(guarded_pwrite_np) 9782 { 9783 PRINT("guarded_pwrite_np(fd:%ld, guard:%#lx, buf:%#lx, nbyte:%llu, offset:%lld) FIXME", 9784 ARG1, ARG2, ARG3, (ULong)ARG4, (Long)ARG5); 9785 } 9786 9787 PRE(guarded_writev_np) 9788 { 9789 PRINT("guarded_writev_np(fd:%ld, guard:%#lx, iovp:%#lx, iovcnt:%llu) FIXME", 9790 ARG1, ARG2, ARG3, (ULong)ARG4); 9791 } 9792 9793 #endif /* DARWIN_VERS >= DARWIN_10_10 */ 9794 9795 9796 /* --------------------------------------------------------------------- 9797 Added for macOS 10.12 (Sierra) 9798 ------------------------------------------------------------------ */ 9799 9800 #if DARWIN_VERS >= DARWIN_10_12 9801 9802 PRE(getentropy) 9803 { 9804 PRINT("getentropy(buffer:%#lx, size:%ld) FIXME", ARG1, ARG2); 9805 PRE_REG_READ2(int, "getentropy", 9806 void*, buffer, size_t, size); 9807 } 9808 9809 PRE(ulock_wake) 9810 { 9811 PRINT("ulock_wake(operation:%ld, addr:%#lx, wake_value:%ld) FIXME", 9812 ARG1, ARG2, ARG3); 9813 PRE_REG_READ3(int, "ulock_wake", 9814 uint32_t, operation, void*, addr, uint64_t, wake_value); 9815 } 9816 9817 PRE(host_create_mach_voucher_trap) 9818 { 9819 // munge_wwww -- no need to call helper 9820 PRINT("host_create_mach_voucher_trap" 9821 "(host:%#lx, recipes:%#lx, recipes_size:%ld, voucher:%#lx) FIXME", 9822 ARG1, ARG2, ARG3, ARG4); 9823 } 9824 9825 PRE(task_register_dyld_image_infos) 9826 { 9827 #pragma pack(4) 9828 typedef struct { 9829 mach_msg_header_t Head; 9830 /* start of the kernel processed data */ 9831 mach_msg_body_t msgh_body; 9832 mach_msg_ool_descriptor_t dyld_images; 9833 /* end of the kernel processed data */ 9834 NDR_record_t NDR; 9835 mach_msg_type_number_t dyld_imagesCnt; 9836 } Request; 9837 #pragma pack() 9838 9839 // Request *req = (Request *)ARG1; 9840 9841 PRINT("task_register_dyld_image_infos(%s)", name_for_port(MACH_REMOTE)); 9842 9843 AFTER = POST_FN(task_register_dyld_image_infos); 9844 } 9845 9846 POST(task_register_dyld_image_infos) 9847 { 9848 #pragma pack(4) 9849 typedef struct { 9850 mach_msg_header_t Head; 9851 NDR_record_t NDR; 9852 kern_return_t RetCode; 9853 } Reply; 9854 #pragma pack() 9855 9856 Reply *reply = (Reply *)ARG1; 9857 if (!reply->RetCode) { 9858 } else { 9859 PRINT("mig return %d", reply->RetCode); 9860 } 9861 } 9862 9863 PRE(task_register_dyld_shared_cache_image_info) 9864 { 9865 #pragma pack(4) 9866 typedef struct { 9867 mach_msg_header_t Head; 9868 NDR_record_t NDR; 9869 dyld_kernel_image_info_t dyld_cache_image; 9870 boolean_t no_cache; 9871 boolean_t private_cache; 9872 } Request; 9873 #pragma pack() 9874 9875 // Request *req = (Request *)ARG1; 9876 9877 PRINT("task_register_dyld_shared_cache_image_info(%s)", 9878 name_for_port(MACH_REMOTE)); 9879 9880 AFTER = POST_FN(task_register_dyld_shared_cache_image_info); 9881 } 9882 9883 POST(task_register_dyld_shared_cache_image_info) 9884 { 9885 #pragma pack(4) 9886 typedef struct { 9887 mach_msg_header_t Head; 9888 NDR_record_t NDR; 9889 kern_return_t RetCode; 9890 } Reply; 9891 #pragma pack() 9892 9893 Reply *reply = (Reply *)ARG1; 9894 if (!reply->RetCode) { 9895 } else { 9896 PRINT("mig return %d", reply->RetCode); 9897 } 9898 } 9899 9900 #endif /* DARWIN_VERS >= DARWIN_10_12 */ 9901 9902 9903 /* --------------------------------------------------------------------- 9904 syscall tables 9905 ------------------------------------------------------------------ */ 9906 9907 /* Add a Darwin-specific, arch-independent wrapper to a syscall table. */ 9908 9909 #define MACX_(sysno, name) \ 9910 WRAPPER_ENTRY_X_(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name) 9911 9912 #define MACXY(sysno, name) \ 9913 WRAPPER_ENTRY_XY(darwin, VG_DARWIN_SYSNO_INDEX(sysno), name) 9914 9915 #define _____(sysno) GENX_(sysno, sys_ni_syscall) /* UNIX style only */ 9916 9917 /* 9918 _____ : unsupported by the kernel (sys_ni_syscall) (UNIX-style only) 9919 unfortunately misused for Mach too, causing assertion failures 9920 // _____ : unimplemented in valgrind 9921 GEN : handlers are in syswrap-generic.c 9922 MAC : handlers are in this file 9923 X_ : PRE handler only 9924 XY : PRE and POST handlers 9925 */ 9926 const SyscallTableEntry ML_(syscall_table)[] = { 9927 // _____(__NR_syscall), // 0 9928 MACX_(__NR_exit, exit), 9929 GENX_(__NR_fork, sys_fork), 9930 GENXY(__NR_read, sys_read), 9931 GENX_(__NR_write, sys_write), 9932 GENXY(__NR_open, sys_open), 9933 GENXY(__NR_close, sys_close), 9934 GENXY(__NR_wait4, sys_wait4), 9935 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(8)), // old creat 9936 GENX_(__NR_link, sys_link), 9937 GENX_(__NR_unlink, sys_unlink), 9938 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(11)), // old execv 9939 GENX_(__NR_chdir, sys_chdir), 9940 GENX_(__NR_fchdir, sys_fchdir), 9941 GENX_(__NR_mknod, sys_mknod), 9942 GENX_(__NR_chmod, sys_chmod), 9943 GENX_(__NR_chown, sys_chown), 9944 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(17)), // old break 9945 MACXY(__NR_getfsstat, getfsstat), 9946 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(19)), // old lseek 9947 GENX_(__NR_getpid, sys_getpid), // 20 9948 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(21)), // old mount 9949 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(22)), // old umount 9950 GENX_(__NR_setuid, sys_setuid), 9951 GENX_(__NR_getuid, sys_getuid), 9952 GENX_(__NR_geteuid, sys_geteuid), 9953 MACX_(__NR_ptrace, ptrace), 9954 MACXY(__NR_recvmsg, recvmsg), 9955 MACX_(__NR_sendmsg, sendmsg), 9956 MACXY(__NR_recvfrom, recvfrom), 9957 MACXY(__NR_accept, accept), 9958 MACXY(__NR_getpeername, getpeername), 9959 MACXY(__NR_getsockname, getsockname), 9960 GENX_(__NR_access, sys_access), 9961 MACX_(__NR_chflags, chflags), 9962 MACX_(__NR_fchflags, fchflags), 9963 GENX_(__NR_sync, sys_sync), 9964 GENX_(__NR_kill, sys_kill), 9965 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(38)), // old stat 9966 GENX_(__NR_getppid, sys_getppid), 9967 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(40)), // old lstat 9968 GENXY(__NR_dup, sys_dup), 9969 MACXY(__NR_pipe, pipe), 9970 GENX_(__NR_getegid, sys_getegid), 9971 #if DARWIN_VERS >= DARWIN_10_7 9972 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(44)), // old profil 9973 #else 9974 // _____(__NR_profil), 9975 #endif 9976 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(45)), // old ktrace 9977 MACXY(__NR_sigaction, sigaction), 9978 GENX_(__NR_getgid, sys_getgid), 9979 MACXY(__NR_sigprocmask, sigprocmask), 9980 MACXY(__NR_getlogin, getlogin), 9981 // _____(__NR_setlogin), 9982 // _____(__NR_acct), 9983 MACXY(__NR_sigpending, sigpending), 9984 GENXY(__NR_sigaltstack, sys_sigaltstack), 9985 MACXY(__NR_ioctl, ioctl), 9986 // _____(__NR_reboot), 9987 // _____(__NR_revoke), 9988 GENX_(__NR_symlink, sys_symlink), // 57 9989 GENX_(__NR_readlink, sys_readlink), 9990 GENX_(__NR_execve, sys_execve), 9991 GENX_(__NR_umask, sys_umask), // 60 9992 GENX_(__NR_chroot, sys_chroot), 9993 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(62)), // old fstat 9994 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(63)), // used internally, reserved 9995 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(64)), // old getpagesize 9996 GENX_(__NR_msync, sys_msync), 9997 GENX_(__NR_vfork, sys_fork), // (We treat vfork as fork.) 9998 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(67)), // old vread 9999 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(68)), // old vwrite 10000 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(69)), // old sbrk 10001 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(70)), // old sstk 10002 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(71)), // old mmap 10003 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(72)), // old vadvise 10004 GENXY(__NR_munmap, sys_munmap), 10005 GENXY(__NR_mprotect, sys_mprotect), 10006 GENX_(__NR_madvise, sys_madvise), 10007 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(76)), // old vhangup 10008 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(77)), // old vlimit 10009 GENXY(__NR_mincore, sys_mincore), 10010 GENXY(__NR_getgroups, sys_getgroups), 10011 // _____(__NR_setgroups), // 80 10012 GENX_(__NR_getpgrp, sys_getpgrp), 10013 GENX_(__NR_setpgid, sys_setpgid), 10014 GENXY(__NR_setitimer, sys_setitimer), 10015 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(84)), // old wait 10016 // _____(__NR_swapon), 10017 GENXY(__NR_getitimer, sys_getitimer), 10018 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(87)), // old gethostname 10019 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(88)), // old sethostname 10020 MACXY(__NR_getdtablesize, getdtablesize), 10021 GENXY(__NR_dup2, sys_dup2), 10022 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(91)), // old getdopt 10023 MACXY(__NR_fcntl, fcntl), 10024 GENX_(__NR_select, sys_select), 10025 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(94)), // old setdopt 10026 GENX_(__NR_fsync, sys_fsync), 10027 GENX_(__NR_setpriority, sys_setpriority), 10028 MACXY(__NR_socket, socket), 10029 MACX_(__NR_connect, connect), 10030 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(99)), // old accept 10031 GENX_(__NR_getpriority, sys_getpriority), // 100 10032 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(101)), // old send 10033 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(102)), // old recv 10034 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(103)), // old sigreturn 10035 MACX_(__NR_bind, bind), 10036 MACX_(__NR_setsockopt, setsockopt), 10037 MACX_(__NR_listen, listen), 10038 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(107)), // old vtimes 10039 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(108)), // old sigvec 10040 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(109)), // old sigblock 10041 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(110)), // old sigsetmask 10042 MACX_(__NR_sigsuspend, sigsuspend), // old sigsuspend 10043 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(112)), // old sigstack 10044 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(113)), // old recvmsg 10045 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(114)), // old sendmsg 10046 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(115)), // old vtrace 10047 GENXY(__NR_gettimeofday, sys_gettimeofday), 10048 GENXY(__NR_getrusage, sys_getrusage), 10049 MACXY(__NR_getsockopt, getsockopt), 10050 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(119)), // old resuba 10051 GENXY(__NR_readv, sys_readv), // 120 10052 GENX_(__NR_writev, sys_writev), 10053 // _____(__NR_settimeofday), 10054 GENX_(__NR_fchown, sys_fchown), 10055 GENX_(__NR_fchmod, sys_fchmod), 10056 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(125)), // old recvfrom 10057 // _____(__NR_setreuid), 10058 // _____(__NR_setregid), 10059 GENX_(__NR_rename, sys_rename), 10060 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(129)), // old truncate 10061 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(130)), // old ftruncate 10062 GENX_(__NR_flock, sys_flock), 10063 MACXY(__NR_mkfifo, mkfifo), 10064 MACX_(__NR_sendto, sendto), 10065 MACX_(__NR_shutdown, shutdown), 10066 MACXY(__NR_socketpair, socketpair), 10067 GENX_(__NR_mkdir, sys_mkdir), 10068 GENX_(__NR_rmdir, sys_rmdir), 10069 GENX_(__NR_utimes, sys_utimes), 10070 MACX_(__NR_futimes, futimes), 10071 // _____(__NR_adjtime), // 140 10072 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(141)), // old getpeername 10073 MACXY(__NR_gethostuuid, gethostuuid), 10074 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(143)), // old sethostid 10075 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(144)), // old getrlimit 10076 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(145)), // old setrlimit 10077 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(146)), // old killpg 10078 GENX_(__NR_setsid, sys_setsid), 10079 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(148)), // old setquota 10080 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(149)), // old qquota 10081 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(150)), // old getsockname 10082 // _____(__NR_getpgid), 10083 // _____(__NR_setprivexec), 10084 GENXY(__NR_pread, sys_pread64), 10085 GENX_(__NR_pwrite, sys_pwrite64), 10086 // _____(__NR_nfssvc), 10087 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(156)), // old getdirentries 10088 GENXY(__NR_statfs, sys_statfs), 10089 GENXY(__NR_fstatfs, sys_fstatfs), 10090 // _____(__NR_unmount), 10091 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(160)), // old async_daemon 10092 // _____(__NR_getfh), 10093 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(162)), // old getdomainname 10094 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(163)), // old setdomainname 10095 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(164)), // ??? 10096 // _____(__NR_quotactl), 10097 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(166)), // old exportfs 10098 MACX_(__NR_mount, mount), 10099 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(168)), // old ustat 10100 MACXY(__NR_csops, csops), // code-signing ops 10101 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(170)), // old table 10102 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(171)), // old wait3 10103 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(172)), // old rpause 10104 // _____(__NR_waitid), 10105 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(174)), // old getdents 10106 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(175)), // old gc_control 10107 // _____(__NR_add_profil), 10108 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(177)), // ??? 10109 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(178)), // ??? 10110 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(179)), // ??? 10111 MACX_(__NR_kdebug_trace, kdebug_trace), // 180 10112 GENX_(__NR_setgid, sys_setgid), 10113 MACX_(__NR_setegid, setegid), 10114 MACX_(__NR_seteuid, seteuid), 10115 MACX_(__NR_sigreturn, sigreturn), 10116 // _____(__NR_chud), 10117 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(186)), // ??? 10118 #if DARWIN_VERS >= DARWIN_10_6 10119 // _____(__NR_fdatasync), 10120 #else 10121 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(187)), // ??? 10122 #endif 10123 GENXY(__NR_stat, sys_newstat), 10124 GENXY(__NR_fstat, sys_newfstat), 10125 GENXY(__NR_lstat, sys_newlstat), 10126 MACX_(__NR_pathconf, pathconf), 10127 MACX_(__NR_fpathconf, fpathconf), 10128 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(193)), // ??? 10129 GENXY(__NR_getrlimit, sys_getrlimit), 10130 GENX_(__NR_setrlimit, sys_setrlimit), 10131 MACXY(__NR_getdirentries, getdirentries), 10132 MACXY(__NR_mmap, mmap), 10133 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(198)), // __syscall 10134 MACX_(__NR_lseek, lseek), 10135 GENX_(__NR_truncate, sys_truncate64), // 200 10136 GENX_(__NR_ftruncate, sys_ftruncate64), 10137 MACXY(__NR___sysctl, __sysctl), 10138 GENX_(__NR_mlock, sys_mlock), 10139 GENX_(__NR_munlock, sys_munlock), 10140 // _____(__NR_undelete), 10141 // _____(__NR_ATsocket), 10142 // _____(__NR_ATgetmsg), 10143 // _____(__NR_ATputmsg), 10144 // _____(__NR_ATPsndreq), 10145 // _____(__NR_ATPsndrsp), 10146 // _____(__NR_ATPgetreq), 10147 // _____(__NR_ATPgetrsp), 10148 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(213)), // Reserved for AppleTalk 10149 #if DARWIN_VERS >= DARWIN_10_6 10150 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(214)), // old kqueue_from_portset_np 10151 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(215)), // old kqueue_portset_np 10152 #else 10153 // _____(__NR_kqueue_from_portset_np), 10154 // _____(__NR_kqueue_portset_np), 10155 #endif 10156 // _____(__NR_mkcomplex), 10157 // _____(__NR_statv), 10158 // _____(__NR_lstatv), 10159 // _____(__NR_fstatv), 10160 MACXY(__NR_getattrlist, getattrlist), // 220 10161 MACX_(__NR_setattrlist, setattrlist), 10162 MACXY(__NR_getdirentriesattr, getdirentriesattr), 10163 MACX_(__NR_exchangedata, exchangedata), 10164 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(224)), // checkuseraccess 10165 // _____(__NR_searchfs), 10166 GENX_(__NR_delete, sys_unlink), 10167 // _____(__NR_copyfile), 10168 #if DARWIN_VERS >= DARWIN_10_6 10169 // _____(__NR_fgetattrlist), 10170 // _____(__NR_fsetattrlist), 10171 #else 10172 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(228)), // ?? 10173 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(229)), // ?? 10174 #endif 10175 GENXY(__NR_poll, sys_poll), 10176 MACX_(__NR_watchevent, watchevent), 10177 MACXY(__NR_waitevent, waitevent), 10178 MACX_(__NR_modwatch, modwatch), 10179 MACXY(__NR_getxattr, getxattr), 10180 MACXY(__NR_fgetxattr, fgetxattr), 10181 MACX_(__NR_setxattr, setxattr), 10182 MACX_(__NR_fsetxattr, fsetxattr), 10183 MACX_(__NR_removexattr, removexattr), 10184 MACX_(__NR_fremovexattr, fremovexattr), 10185 MACXY(__NR_listxattr, listxattr), // 240 10186 MACXY(__NR_flistxattr, flistxattr), 10187 MACXY(__NR_fsctl, fsctl), 10188 MACX_(__NR_initgroups, initgroups), 10189 MACXY(__NR_posix_spawn, posix_spawn), 10190 #if DARWIN_VERS >= DARWIN_10_6 10191 // _____(__NR_ffsctl), 10192 #else 10193 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(245)), // ??? 10194 #endif 10195 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(246)), // ??? 10196 // _____(__NR_nfsclnt), 10197 // _____(__NR_fhopen), 10198 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(249)), // ??? 10199 // _____(__NR_minherit), 10200 // _____(__NR_semsys), 10201 // _____(__NR_msgsys), 10202 // _____(__NR_shmsys), 10203 MACXY(__NR_semctl, semctl), 10204 MACX_(__NR_semget, semget), 10205 MACX_(__NR_semop, semop), 10206 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(257)), // ??? 10207 // _____(__NR_msgctl), 10208 // _____(__NR_msgget), 10209 // _____(__NR_msgsnd), // 260 10210 // _____(__NR_msgrcv), 10211 MACXY(__NR_shmat, shmat), 10212 MACXY(__NR_shmctl, shmctl), 10213 MACXY(__NR_shmdt, shmdt), 10214 MACX_(__NR_shmget, shmget), 10215 MACXY(__NR_shm_open, shm_open), 10216 MACXY(__NR_shm_unlink, shm_unlink), 10217 MACX_(__NR_sem_open, sem_open), 10218 MACX_(__NR_sem_close, sem_close), 10219 MACX_(__NR_sem_unlink, sem_unlink), 10220 MACX_(__NR_sem_wait, sem_wait), 10221 MACX_(__NR_sem_trywait, sem_trywait), 10222 MACX_(__NR_sem_post, sem_post), 10223 // 274 seems to have been repurposed for 10.10. Was sem_getvalue, 10224 // has become sysctlbyname. See below. 10225 MACXY(__NR_sem_init, sem_init), 10226 MACX_(__NR_sem_destroy, sem_destroy), 10227 MACX_(__NR_open_extended, open_extended), // 277 10228 // _____(__NR_umask_extended), 10229 MACXY(__NR_stat_extended, stat_extended), 10230 MACXY(__NR_lstat_extended, lstat_extended), // 280 10231 MACXY(__NR_fstat_extended, fstat_extended), 10232 MACX_(__NR_chmod_extended, chmod_extended), 10233 MACX_(__NR_fchmod_extended,fchmod_extended), 10234 MACXY(__NR_access_extended,access_extended), 10235 MACX_(__NR_settid, settid), 10236 #if DARWIN_VERS >= DARWIN_10_8 10237 MACX_(__NR_gettid, gettid), // 286 10238 #endif 10239 // _____(__NR_setsgroups), 10240 // _____(__NR_getsgroups), 10241 // _____(__NR_setwgroups), 10242 // _____(__NR_getwgroups), 10243 // _____(__NR_mkfifo_extended), 10244 // _____(__NR_mkdir_extended), 10245 // _____(__NR_identitysvc), 10246 // _____(__NR_shared_region_check_np), 10247 // _____(__NR_shared_region_map_np), 10248 #if DARWIN_VERS >= DARWIN_10_6 10249 // _____(__NR_vm_pressure_monitor), 10250 // _____(__NR_psynch_rw_longrdlock), 10251 // _____(__NR_psynch_rw_yieldwrlock), 10252 // _____(__NR_psynch_rw_downgrade), 10253 // _____(__NR_psynch_rw_upgrade), 10254 MACXY(__NR_psynch_mutexwait, psynch_mutexwait), // 301 10255 MACXY(__NR_psynch_mutexdrop, psynch_mutexdrop), // 302 10256 MACXY(__NR_psynch_cvbroad, psynch_cvbroad), // 303 10257 MACXY(__NR_psynch_cvsignal, psynch_cvsignal), // 304 10258 MACXY(__NR_psynch_cvwait, psynch_cvwait), // 305 10259 MACXY(__NR_psynch_rw_rdlock, psynch_rw_rdlock), // 306 10260 MACXY(__NR_psynch_rw_wrlock, psynch_rw_wrlock), // 307 10261 MACXY(__NR_psynch_rw_unlock, psynch_rw_unlock), // 308 10262 // _____(__NR_psynch_rw_unlock2), 10263 #else 10264 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(296)), // old load_shared_file 10265 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(297)), // old reset_shared_file 10266 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(298)), // old new_system_shared_regions 10267 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(299)), // old shared_region_map_file_np 10268 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(300)), // old shared_region_make_private_np 10269 // _____(__NR___pthread_mutex_destroy), 10270 // _____(__NR___pthread_mutex_init), 10271 // _____(__NR___pthread_mutex_lock), 10272 // _____(__NR___pthread_mutex_trylock), 10273 // _____(__NR___pthread_mutex_unlock), 10274 // _____(__NR___pthread_cond_init), 10275 // _____(__NR___pthread_cond_destroy), 10276 // _____(__NR___pthread_cond_broadcast), 10277 // _____(__NR___pthread_cond_signal), 10278 #endif 10279 // _____(__NR_getsid), 10280 // _____(__NR_settid_with_pid), 10281 #if DARWIN_VERS >= DARWIN_10_7 10282 MACXY(__NR_psynch_cvclrprepost, psynch_cvclrprepost), // 312 10283 #else 10284 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(308)), // old __pthread_cond_timedwait 10285 #endif 10286 // _____(__NR_aio_fsync), 10287 MACXY(__NR_aio_return, aio_return), 10288 MACX_(__NR_aio_suspend, aio_suspend), 10289 // _____(__NR_aio_cancel), 10290 MACX_(__NR_aio_error, aio_error), 10291 MACXY(__NR_aio_read, aio_read), 10292 MACX_(__NR_aio_write, aio_write), 10293 // _____(__NR_lio_listio), // 320 10294 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(321)), // ??? 10295 10296 #if DARWIN_VERS >= DARWIN_10_8 10297 MACXY(__NR_iopolicysys, iopolicysys), 10298 MACXY(__NR_process_policy, process_policy), 10299 #else 10300 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(322)), // ??? 10301 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(323)), // ??? 10302 #endif 10303 // _____(__NR_mlockall), 10304 // _____(__NR_munlockall), 10305 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(326)), // ??? 10306 MACX_(__NR_issetugid, issetugid), 10307 MACX_(__NR___pthread_kill, __pthread_kill), 10308 MACX_(__NR___pthread_sigmask, __pthread_sigmask), 10309 // _____(__NR___sigwait), 10310 MACX_(__NR___disable_threadsignal, __disable_threadsignal), 10311 MACX_(__NR___pthread_markcancel, __pthread_markcancel), 10312 MACX_(__NR___pthread_canceled, __pthread_canceled), 10313 MACX_(__NR___semwait_signal, __semwait_signal), 10314 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(335)), // old utrace 10315 MACXY(__NR_proc_info, proc_info), // 336 10316 MACXY(__NR_sendfile, sendfile), 10317 MACXY(__NR_stat64, stat64), 10318 MACXY(__NR_fstat64, fstat64), 10319 MACXY(__NR_lstat64, lstat64), // 340 10320 MACXY(__NR_stat64_extended, stat64_extended), 10321 MACXY(__NR_lstat64_extended, lstat64_extended), 10322 MACXY(__NR_fstat64_extended, fstat64_extended), 10323 MACXY(__NR_getdirentries64, getdirentries64), 10324 MACXY(__NR_statfs64, statfs64), 10325 MACXY(__NR_fstatfs64, fstatfs64), 10326 MACXY(__NR_getfsstat64, getfsstat64), 10327 MACX_(__NR___pthread_chdir, __pthread_chdir), 10328 MACX_(__NR___pthread_fchdir, __pthread_fchdir), 10329 // _____(__NR_audit), 10330 MACXY(__NR_auditon, auditon), 10331 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(352)), // ??? 10332 // _____(__NR_getauid), 10333 // _____(__NR_setauid), 10334 // _____(__NR_getaudit), 10335 // _____(__NR_setaudit), 10336 MACXY(__NR_getaudit_addr, getaudit_addr), 10337 // _____(__NR_setaudit_addr), 10338 // _____(__NR_auditctl), 10339 MACXY(__NR_bsdthread_create, bsdthread_create), // 360 10340 MACX_(__NR_bsdthread_terminate, bsdthread_terminate), 10341 MACXY(__NR_kqueue, kqueue), 10342 MACXY(__NR_kevent, kevent), 10343 GENX_(__NR_lchown, sys_lchown), 10344 // _____(__NR_stack_snapshot), 10345 MACX_(__NR_bsdthread_register, bsdthread_register), 10346 MACX_(__NR_workq_open, workq_open), 10347 MACXY(__NR_workq_ops, workq_ops), 10348 #if DARWIN_VERS >= DARWIN_10_6 10349 MACXY(__NR_kevent64, kevent64), 10350 #else 10351 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(369)), // ??? 10352 #endif 10353 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(370)), // old semwait_signal 10354 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(371)), // old semwait_signal_nocancel 10355 #if DARWIN_VERS >= DARWIN_10_6 10356 MACX_(__NR___thread_selfid, __thread_selfid), 10357 #else 10358 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(372)), // ??? 10359 #endif 10360 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(373)), // ??? 10361 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(374)), // ??? 10362 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(375)), // ??? 10363 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(376)), // ??? 10364 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(377)), // ??? 10365 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(378)), // ??? 10366 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(379)), // ??? 10367 // _____(__NR___mac_execve), // 380 10368 MACX_(__NR___mac_syscall, __mac_syscall), 10369 // _____(__NR___mac_get_file), 10370 // _____(__NR___mac_set_file), 10371 // _____(__NR___mac_get_link), 10372 // _____(__NR___mac_set_link), 10373 // _____(__NR___mac_get_proc), 10374 // _____(__NR___mac_set_proc), 10375 // _____(__NR___mac_get_fd), 10376 // _____(__NR___mac_set_fd), 10377 // _____(__NR___mac_get_pid), 10378 // _____(__NR___mac_get_lcid), 10379 // _____(__NR___mac_get_lctx), 10380 // _____(__NR___mac_set_lctx), 10381 // _____(__NR_setlcid), 10382 // _____(__NR_getlcid), 10383 // GrP fixme need any special nocancel handling? 10384 GENXY(__NR_read_nocancel, sys_read), 10385 GENX_(__NR_write_nocancel, sys_write), 10386 GENXY(__NR_open_nocancel, sys_open), 10387 GENXY(__NR_close_nocancel, sys_close), 10388 GENXY(__NR_wait4_nocancel, sys_wait4), // 400 10389 MACXY(__NR_recvmsg_nocancel, recvmsg), 10390 MACX_(__NR_sendmsg_nocancel, sendmsg), 10391 MACXY(__NR_recvfrom_nocancel, recvfrom), 10392 MACXY(__NR_accept_nocancel, accept), 10393 GENX_(__NR_msync_nocancel, sys_msync), 10394 MACXY(__NR_fcntl_nocancel, fcntl), 10395 GENX_(__NR_select_nocancel, sys_select), 10396 GENX_(__NR_fsync_nocancel, sys_fsync), 10397 MACX_(__NR_connect_nocancel, connect), 10398 MACX_(__NR_sigsuspend_nocancel, sigsuspend), 10399 GENXY(__NR_readv_nocancel, sys_readv), 10400 GENX_(__NR_writev_nocancel, sys_writev), 10401 MACX_(__NR_sendto_nocancel, sendto), 10402 GENXY(__NR_pread_nocancel, sys_pread64), 10403 GENX_(__NR_pwrite_nocancel, sys_pwrite64), 10404 // _____(__NR_waitid_nocancel), 10405 GENXY(__NR_poll_nocancel, sys_poll), 10406 // _____(__NR_msgsnd_nocancel), 10407 // _____(__NR_msgrcv_nocancel), 10408 MACX_(__NR_sem_wait_nocancel, sem_wait), // 420 10409 // _____(__NR_aio_suspend_nocancel), 10410 // _____(__NR___sigwait_nocancel), 10411 MACX_(__NR___semwait_signal_nocancel, __semwait_signal), 10412 // _____(__NR___mac_mount), 10413 // _____(__NR___mac_get_mount), 10414 // _____(__NR___mac_getfsstat), 10415 #if DARWIN_VERS >= DARWIN_10_6 10416 MACXY(__NR_fsgetpath, fsgetpath), 10417 MACXY(__NR_audit_session_self, audit_session_self), 10418 // _____(__NR_audit_session_join), 10419 #endif 10420 #if DARWIN_VERS >= DARWIN_10_9 10421 MACX_(__NR_fileport_makeport, fileport_makeport), 10422 // _____(__NR_fileport_makefd), // 431 10423 // _____(__NR_audit_session_port), // 432 10424 // _____(__NR_pid_suspend), // 433 10425 // _____(__NR_pid_resume), // 434 10426 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(435)), // ??? 10427 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(436)), // ??? 10428 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(437)), // ??? 10429 // _____(__NR_shared_region_map_and_slide_np), // 438 10430 // _____(__NR_kas_info), // 439 10431 // _____(__NR_memorystatus_control), // 440 10432 MACX_(__NR_guarded_open_np, guarded_open_np), 10433 MACX_(__NR_guarded_close_np, guarded_close_np), 10434 MACX_(__NR_guarded_kqueue_np, guarded_kqueue_np), 10435 MACX_(__NR_change_fdguard_np, change_fdguard_np), 10436 MACX_(__NR_connectx, connectx), 10437 MACX_(__NR_disconnectx, disconnectx), 10438 #endif 10439 #if DARWIN_VERS >= DARWIN_10_10 10440 MACXY(__NR_sysctlbyname, sysctlbyname), // 274 10441 MACXY(__NR_necp_match_policy, necp_match_policy), // 460 10442 MACXY(__NR_getattrlistbulk, getattrlistbulk), // 461 10443 MACX_(__NR_faccessat, faccessat), // 466 10444 MACX_(__NR_fstatat64, fstatat64), // 470 10445 MACX_(__NR_readlinkat, readlinkat), // 473 10446 MACX_(__NR_bsdthread_ctl, bsdthread_ctl), // 478 10447 MACX_(__NR_csrctl, csrctl), // 483 10448 MACX_(__NR_guarded_open_dprotected_np, guarded_open_dprotected_np), // 484 10449 MACX_(__NR_guarded_write_np, guarded_write_np), // 485 10450 MACX_(__NR_guarded_pwrite_np, guarded_pwrite_np), // 486 10451 MACX_(__NR_guarded_writev_np, guarded_writev_np), // 487 10452 // _____(__NR___mremap_encrypted), // 489 10453 #endif 10454 #if DARWIN_VERS >= DARWIN_10_11 10455 // _____(__NR_kdebug_trace_string), // 178 10456 // _____(__NR_kevent_qos), // 374 10457 // _____(__NR_netagent_trigger), // 490 10458 // _____(__NR_stack_snapshot_with_config), // 491 10459 // _____(__NR_microstackshot), // 492 10460 // _____(__NR_grab_pgo_data), // 493 10461 // _____(__NR_persona), // 494 10462 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(495)), // ??? 10463 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(496)), // ??? 10464 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(497)), // ??? 10465 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(498)), // ??? 10466 // _____(__NR_work_interval_ctl), // 499 10467 #endif 10468 #if DARWIN_VERS >= DARWIN_10_12 10469 // _____(__NR_kdebug_typefilter), // 177 10470 // _____(__NR_clonefileat), // 462 10471 // _____(__NR_renameatx_np), // 488 10472 MACX_(__NR_getentropy, getentropy), // 500 10473 // _____(__NR_necp_open), // 501 10474 // _____(__NR_necp_client_action), // 502 10475 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(503)), // ??? 10476 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(504)), // ??? 10477 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(505)), // ??? 10478 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(506)), // ??? 10479 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(507)), // ??? 10480 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(508)), // ??? 10481 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(509)), // ??? 10482 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(510)), // ??? 10483 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(511)), // ??? 10484 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(512)), // ??? 10485 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(513)), // ??? 10486 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(514)), // ??? 10487 // _____(__NR_ulock_wait), // 515 10488 MACX_(__NR_ulock_wake, ulock_wake), // 516 10489 // _____(__NR_fclonefileat), // 517 10490 // _____(__NR_fs_snapshot), // 518 10491 _____(VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(519)), // ??? 10492 // _____(__NR_terminate_with_payload), // 520 10493 // _____(__NR_abort_with_payload), // 521 10494 #endif 10495 // _____(__NR_MAXSYSCALL) 10496 MACX_(__NR_DARWIN_FAKE_SIGRETURN, FAKE_SIGRETURN) 10497 }; 10498 10499 10500 // Mach traps use negative syscall numbers. 10501 // Use ML_(mach_trap_table)[-mach_trap_number] . 10502 // cf xnu sources osfmk/kern/syscall_sw.c 10503 10504 const SyscallTableEntry ML_(mach_trap_table)[] = { 10505 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(0)), 10506 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(1)), 10507 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(2)), 10508 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(3)), 10509 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(4)), 10510 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(5)), 10511 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(6)), 10512 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(7)), 10513 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(8)), 10514 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(9)), 10515 10516 # if DARWIN_VERS >= DARWIN_10_8 10517 MACXY(__NR_kernelrpc_mach_vm_allocate_trap, kernelrpc_mach_vm_allocate_trap), 10518 # else 10519 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(10)), 10520 # endif 10521 10522 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(11)), 10523 10524 # if DARWIN_VERS >= DARWIN_10_8 10525 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12), kernelrpc_mach_vm_deallocate_trap), 10526 # else 10527 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(12)), 10528 # endif 10529 10530 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(13)), 10531 10532 # if DARWIN_VERS >= DARWIN_10_8 10533 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14), kernelrpc_mach_vm_protect_trap), 10534 # endif 10535 10536 # if DARWIN_VERS >= DARWIN_10_9 10537 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(15), kernelrpc_mach_vm_map_trap), 10538 # endif 10539 10540 # if DARWIN_VERS < DARWIN_10_8 10541 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(14)), 10542 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(15)), 10543 # endif 10544 10545 # if DARWIN_VERS >= DARWIN_10_8 10546 MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16), kernelrpc_mach_port_allocate_trap), 10547 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17), kernelrpc_mach_port_destroy_trap), 10548 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18), kernelrpc_mach_port_deallocate_trap), 10549 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19), kernelrpc_mach_port_mod_refs_trap), 10550 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20), kernelrpc_mach_port_move_member_trap), 10551 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21), kernelrpc_mach_port_insert_right_trap), 10552 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(22), kernelrpc_mach_port_insert_member_trap), 10553 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(23), kernelrpc_mach_port_extract_member_trap), 10554 # else 10555 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(16)), 10556 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(17)), 10557 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(18)), 10558 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(19)), 10559 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(20)), 10560 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(21)), 10561 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(22)), 10562 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(23)), 10563 # endif 10564 10565 # if DARWIN_VERS >= DARWIN_10_9 10566 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24), kernelrpc_mach_port_construct_trap), 10567 MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(25), kernelrpc_mach_port_destruct_trap), 10568 # else 10569 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24)), 10570 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(25)), 10571 # endif 10572 10573 MACXY(__NR_mach_reply_port, mach_reply_port), 10574 MACXY(__NR_thread_self_trap, mach_thread_self), 10575 MACXY(__NR_task_self_trap, mach_task_self), 10576 MACXY(__NR_host_self_trap, mach_host_self), 10577 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(30)), 10578 MACXY(__NR_mach_msg_trap, mach_msg), 10579 // _____(__NR_mach_msg_overwrite_trap), 10580 MACX_(__NR_semaphore_signal_trap, semaphore_signal), 10581 MACX_(__NR_semaphore_signal_all_trap, semaphore_signal_all), 10582 MACX_(__NR_semaphore_signal_thread_trap, semaphore_signal_thread), 10583 MACX_(__NR_semaphore_wait_trap, semaphore_wait), 10584 MACX_(__NR_semaphore_wait_signal_trap, semaphore_wait_signal), 10585 MACX_(__NR_semaphore_timedwait_trap, semaphore_timedwait), 10586 MACX_(__NR_semaphore_timedwait_signal_trap, semaphore_timedwait_signal), 10587 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(40)), // -40 10588 10589 # if DARWIN_VERS >= DARWIN_10_9 10590 MACX_(__NR_kernelrpc_mach_port_guard_trap, kernelrpc_mach_port_guard_trap), 10591 MACX_(__NR_kernelrpc_mach_port_unguard_trap, kernelrpc_mach_port_unguard_trap), 10592 # else 10593 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(41)), 10594 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(42)), 10595 # endif 10596 10597 # if DARWIN_VERS >= DARWIN_10_10 10598 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(43)), 10599 # else 10600 # if DARWIN_VERS == DARWIN_10_9 10601 // _____(__NR_map_fd), 10602 # else 10603 # if defined(VGA_x86) 10604 // _____(__NR_map_fd), 10605 # else 10606 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(43)), 10607 # endif 10608 # endif 10609 # endif 10610 10611 // _____(__NR_task_name_for_pid), 10612 MACXY(__NR_task_for_pid, task_for_pid), 10613 MACXY(__NR_pid_for_task, pid_for_task), 10614 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(47)), 10615 #if defined(VGA_x86) 10616 // _____(__NR_macx_swapon), 10617 // _____(__NR_macx_swapoff), 10618 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(50)), 10619 // _____(__NR_macx_triggers), 10620 // _____(__NR_macx_backing_store_suspend), 10621 // _____(__NR_macx_backing_store_recovery), 10622 #else 10623 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(48)), 10624 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(49)), 10625 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(50)), 10626 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(51)), 10627 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(52)), 10628 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(53)), 10629 #endif 10630 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(54)), 10631 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(55)), 10632 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(56)), 10633 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(57)), 10634 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(58)), 10635 MACX_(__NR_swtch_pri, swtch_pri), 10636 MACX_(__NR_swtch, swtch), // -60 10637 MACX_(__NR_syscall_thread_switch, syscall_thread_switch), 10638 // _____(__NR_clock_sleep_trap), 10639 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(63)), 10640 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(64)), 10641 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(65)), 10642 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(66)), 10643 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(67)), 10644 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(68)), 10645 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(69)), 10646 #if DARWIN_VERS >= DARWIN_10_12 10647 MACX_(__NR_host_create_mach_voucher_trap, host_create_mach_voucher_trap), 10648 #else 10649 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(70)), 10650 #endif 10651 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(71)), 10652 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(72)), 10653 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(73)), 10654 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(74)), 10655 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(75)), 10656 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(76)), 10657 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(77)), 10658 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(78)), 10659 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(79)), 10660 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(80)), // -80 10661 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(81)), 10662 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(82)), 10663 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(83)), 10664 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(84)), 10665 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(85)), 10666 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(86)), 10667 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(87)), 10668 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(88)), 10669 MACXY(__NR_mach_timebase_info, mach_timebase_info), 10670 MACX_(__NR_mach_wait_until, mach_wait_until), 10671 MACXY(__NR_mk_timer_create, mk_timer_create), 10672 MACXY(__NR_mk_timer_destroy, mk_timer_destroy), 10673 MACX_(__NR_mk_timer_arm, mk_timer_arm), 10674 MACXY(__NR_mk_timer_cancel, mk_timer_cancel), 10675 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(95)), 10676 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(96)), 10677 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(97)), 10678 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(98)), 10679 _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(99)), 10680 MACXY(__NR_iokit_user_client_trap, iokit_user_client_trap), // -100 10681 }; 10682 10683 10684 // Machine-dependent traps have wacky syscall numbers, and use the Mach trap 10685 // calling convention instead of the syscall convention. 10686 // Use ML_(mdep_trap_table)[syscallno - ML_(mdep_trap_base)] . 10687 10688 #if defined(VGA_x86) 10689 const SyscallTableEntry ML_(mdep_trap_table)[] = { 10690 MACX_(__NR_thread_fast_set_cthread_self, thread_fast_set_cthread_self), 10691 }; 10692 #elif defined(VGA_amd64) 10693 const SyscallTableEntry ML_(mdep_trap_table)[] = { 10694 MACX_(__NR_thread_fast_set_cthread_self, thread_fast_set_cthread_self), 10695 }; 10696 #else 10697 #error unknown architecture 10698 #endif 10699 10700 const UInt ML_(syscall_table_size) = 10701 sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]); 10702 10703 const UInt ML_(mach_trap_table_size) = 10704 sizeof(ML_(mach_trap_table)) / sizeof(ML_(mach_trap_table)[0]); 10705 10706 const UInt ML_(mdep_trap_table_size) = 10707 sizeof(ML_(mdep_trap_table)) / sizeof(ML_(mdep_trap_table)[0]); 10708 10709 #endif // defined(VGO_darwin) 10710 10711 /*--------------------------------------------------------------------*/ 10712 /*--- end ---*/ 10713 /*--------------------------------------------------------------------*/ 10714