1 2 /*--------------------------------------------------------------------*/ 3 /*--- Handle system calls. syswrap-main.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2015 Julian Seward 11 jseward (at) acm.org 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 #include "libvex_guest_offsets.h" 32 #include "libvex_trc_values.h" 33 #include "pub_core_basics.h" 34 #include "pub_core_aspacemgr.h" 35 #include "pub_core_vki.h" 36 #include "pub_core_vkiscnums.h" 37 #include "pub_core_threadstate.h" 38 #include "pub_core_libcbase.h" 39 #include "pub_core_libcassert.h" 40 #include "pub_core_libcprint.h" 41 #include "pub_core_libcproc.h" // For VG_(getpid)() 42 #include "pub_core_libcsignal.h" 43 #include "pub_core_scheduler.h" // For VG_({acquire,release}_BigLock), 44 // and VG_(vg_yield) 45 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)() 46 #include "pub_core_tooliface.h" 47 #include "pub_core_options.h" 48 #include "pub_core_signals.h" // For VG_SIGVGKILL, VG_(poll_signals) 49 #include "pub_core_syscall.h" 50 #include "pub_core_machine.h" 51 #include "pub_core_mallocfree.h" 52 #include "pub_core_syswrap.h" 53 54 #include "priv_types_n_macros.h" 55 #include "priv_syswrap-main.h" 56 57 #if defined(VGO_darwin) 58 #include "priv_syswrap-darwin.h" 59 #endif 60 61 /* Useful info which needs to be recorded somewhere: 62 Use of registers in syscalls is: 63 64 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT 65 LINUX: 66 x86 eax ebx ecx edx esi edi ebp n/a n/a eax (== NUM) 67 amd64 rax rdi rsi rdx r10 r8 r9 n/a n/a rax (== NUM) 68 ppc32 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1) 69 ppc64 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1) 70 arm r7 r0 r1 r2 r3 r4 r5 n/a n/a r0 (== ARG1) 71 mips32 v0 a0 a1 a2 a3 stack stack n/a n/a v0 (== NUM) 72 mips64 v0 a0 a1 a2 a3 a4 a5 a6 a7 v0 (== NUM) 73 arm64 x8 x0 x1 x2 x3 x4 x5 n/a n/a x0 ?? (== ARG1??) 74 75 On s390x the svc instruction is used for system calls. The system call 76 number is encoded in the instruction (8 bit immediate field). Since Linux 77 2.6 it is also allowed to use svc 0 with the system call number in r1. 78 This was introduced for system calls >255, but works for all. It is 79 also possible to see the svc 0 together with an EXecute instruction, that 80 fills in the immediate field. 81 s390x r1/SVC r2 r3 r4 r5 r6 r7 n/a n/a r2 (== ARG1) 82 83 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT 84 DARWIN: 85 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c 86 amd64 rax rdi rsi rdx rcx r8 r9 +8 +16 rdx:rax, rflags.c 87 88 For x86-darwin, "+N" denotes "in memory at N(%esp)"; ditto 89 amd64-darwin. Apparently 0(%esp) is some kind of return address 90 (perhaps for syscalls done with "sysenter"?) I don't think it is 91 relevant for syscalls done with "int $0x80/1/2". 92 93 SOLARIS: 94 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c 95 amd64 rax rdi rsi rdx r10 r8 r9 +8 +16 rdx:rax, rflags.c 96 97 "+N" denotes "in memory at N(%esp)". Solaris also supports fasttrap 98 syscalls. Fasttraps do not take any parameters (except of the sysno in eax) 99 and never fail (if the sysno is valid). 100 */ 101 102 /* This is the top level of the system-call handler module. All 103 system calls are channelled through here, doing two things: 104 105 * notify the tool of the events (mem/reg reads, writes) happening 106 107 * perform the syscall, usually by passing it along to the kernel 108 unmodified. 109 110 A magical piece of assembly code, do_syscall_for_client_WRK, in 111 syscall-$PLATFORM.S does the tricky bit of passing a syscall to the 112 kernel, whilst having the simulator retain control. 113 */ 114 115 /* The main function is VG_(client_syscall). The simulation calls it 116 whenever a client thread wants to do a syscall. The following is a 117 sketch of what it does. 118 119 * Ensures the root thread's stack is suitably mapped. Tedious and 120 arcane. See big big comment in VG_(client_syscall). 121 122 * First, it rounds up the syscall number and args (which is a 123 platform dependent activity) and puts them in a struct ("args") 124 and also a copy in "orig_args". 125 126 The pre/post wrappers refer to these structs and so no longer 127 need magic macros to access any specific registers. This struct 128 is stored in thread-specific storage. 129 130 131 * The pre-wrapper is called, passing it a pointer to struct 132 "args". 133 134 135 * The pre-wrapper examines the args and pokes the tool 136 appropriately. It may modify the args; this is why "orig_args" 137 is also stored. 138 139 The pre-wrapper may choose to 'do' the syscall itself, and 140 concludes one of three outcomes: 141 142 Success(N) -- syscall is already complete, with success; 143 result is N 144 145 Fail(N) -- syscall is already complete, with failure; 146 error code is N 147 148 HandToKernel -- (the usual case): this needs to be given to 149 the kernel to be done, using the values in 150 the possibly-modified "args" struct. 151 152 In addition, the pre-wrapper may set some flags: 153 154 MayBlock -- only applicable when outcome==HandToKernel 155 156 PostOnFail -- only applicable when outcome==HandToKernel or Fail 157 158 159 * If the pre-outcome is HandToKernel, the syscall is duly handed 160 off to the kernel (perhaps involving some thread switchery, but 161 that's not important). This reduces the possible set of outcomes 162 to either Success(N) or Fail(N). 163 164 165 * The outcome (Success(N) or Fail(N)) is written back to the guest 166 register(s). This is platform specific: 167 168 x86: Success(N) ==> eax = N 169 Fail(N) ==> eax = -N 170 171 ditto amd64 172 173 ppc32: Success(N) ==> r3 = N, CR0.SO = 0 174 Fail(N) ==> r3 = N, CR0.SO = 1 175 176 Darwin: 177 x86: Success(N) ==> edx:eax = N, cc = 0 178 Fail(N) ==> edx:eax = N, cc = 1 179 180 s390x: Success(N) ==> r2 = N 181 Fail(N) ==> r2 = -N 182 183 Solaris: 184 x86: Success(N) ==> edx:eax = N, cc = 0 185 Fail(N) ==> eax = N, cc = 1 186 Same applies for fasttraps except they never fail. 187 188 * The post wrapper is called if: 189 190 - it exists, and 191 - outcome==Success or (outcome==Fail and PostOnFail is set) 192 193 The post wrapper is passed the adulterated syscall args (struct 194 "args"), and the syscall outcome (viz, Success(N) or Fail(N)). 195 196 There are several other complications, primarily to do with 197 syscalls getting interrupted, explained in comments in the code. 198 */ 199 200 /* CAVEATS for writing wrappers. It is important to follow these! 201 202 The macros defined in priv_types_n_macros.h are designed to help 203 decouple the wrapper logic from the actual representation of 204 syscall args/results, since these wrappers are designed to work on 205 multiple platforms. 206 207 Sometimes a PRE wrapper will complete the syscall itself, without 208 handing it to the kernel. It will use one of SET_STATUS_Success, 209 SET_STATUS_Failure or SET_STATUS_from_SysRes to set the return 210 value. It is critical to appreciate that use of the macro does not 211 immediately cause the underlying guest state to be updated -- that 212 is done by the driver logic in this file, when the wrapper returns. 213 214 As a result, PRE wrappers of the following form will malfunction: 215 216 PRE(fooble) 217 { 218 ... do stuff ... 219 SET_STATUS_Somehow(...) 220 221 // do something that assumes guest state is up to date 222 } 223 224 In particular, direct or indirect calls to VG_(poll_signals) after 225 setting STATUS can cause the guest state to be read (in order to 226 build signal frames). Do not do this. If you want a signal poll 227 after the syscall goes through, do "*flags |= SfPollAfter" and the 228 driver logic will do it for you. 229 230 ----------- 231 232 Another critical requirement following introduction of new address 233 space manager (JRS, 20050923): 234 235 In a situation where the mappedness of memory has changed, aspacem 236 should be notified BEFORE the tool. Hence the following is 237 correct: 238 239 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start); 240 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start ); 241 if (d) 242 VG_(discard_translations)(s->start, s->end+1 - s->start); 243 244 whilst this is wrong: 245 246 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start ); 247 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start); 248 if (d) 249 VG_(discard_translations)(s->start, s->end+1 - s->start); 250 251 The reason is that the tool may itself ask aspacem for more shadow 252 memory as a result of the VG_TRACK call. In such a situation it is 253 critical that aspacem's segment array is up to date -- hence the 254 need to notify aspacem first. 255 256 ----------- 257 258 Also .. take care to call VG_(discard_translations) whenever 259 memory with execute permissions is unmapped. 260 */ 261 262 263 /* --------------------------------------------------------------------- 264 Do potentially blocking syscall for the client, and mess with 265 signal masks at the same time. 266 ------------------------------------------------------------------ */ 267 268 /* Perform a syscall on behalf of a client thread, using a specific 269 signal mask. On completion, the signal mask is set to restore_mask 270 (which presumably blocks almost everything). If a signal happens 271 during the syscall, the handler should call 272 VG_(fixup_guest_state_after_syscall_interrupted) to adjust the 273 thread's context to do the right thing. 274 275 The _WRK function is handwritten assembly, implemented per-platform 276 in coregrind/m_syswrap/syscall-$PLAT.S. It has some very magic 277 properties. See comments at the top of 278 VG_(fixup_guest_state_after_syscall_interrupted) below for details. 279 280 This function (these functions) are required to return zero in case 281 of success (even if the syscall itself failed), and nonzero if the 282 sigprocmask-swizzling calls failed. We don't actually care about 283 the failure values from sigprocmask, although most of the assembly 284 implementations do attempt to return that, using the convention 285 0 for success, or 0x8000 | error-code for failure. 286 */ 287 #if defined(VGO_linux) 288 extern 289 UWord ML_(do_syscall_for_client_WRK)( Word syscallno, 290 void* guest_state, 291 const vki_sigset_t *syscall_mask, 292 const vki_sigset_t *restore_mask, 293 Word sigsetSzB ); 294 #elif defined(VGO_darwin) 295 extern 296 UWord ML_(do_syscall_for_client_unix_WRK)( Word syscallno, 297 void* guest_state, 298 const vki_sigset_t *syscall_mask, 299 const vki_sigset_t *restore_mask, 300 Word sigsetSzB ); /* unused */ 301 extern 302 UWord ML_(do_syscall_for_client_mach_WRK)( Word syscallno, 303 void* guest_state, 304 const vki_sigset_t *syscall_mask, 305 const vki_sigset_t *restore_mask, 306 Word sigsetSzB ); /* unused */ 307 extern 308 UWord ML_(do_syscall_for_client_mdep_WRK)( Word syscallno, 309 void* guest_state, 310 const vki_sigset_t *syscall_mask, 311 const vki_sigset_t *restore_mask, 312 Word sigsetSzB ); /* unused */ 313 #elif defined(VGO_solaris) 314 extern 315 UWord ML_(do_syscall_for_client_WRK)( Word syscallno, 316 void* guest_state, 317 const vki_sigset_t *syscall_mask, 318 const vki_sigset_t *restore_mask, 319 UChar *cflag); 320 UWord ML_(do_syscall_for_client_dret_WRK)( Word syscallno, 321 void* guest_state, 322 const vki_sigset_t *syscall_mask, 323 const vki_sigset_t *restore_mask, 324 UChar *cflag); 325 #else 326 # error "Unknown OS" 327 #endif 328 329 330 static 331 void do_syscall_for_client ( Int syscallno, 332 ThreadState* tst, 333 const vki_sigset_t* syscall_mask ) 334 { 335 vki_sigset_t saved; 336 UWord err; 337 # if defined(VGO_linux) 338 err = ML_(do_syscall_for_client_WRK)( 339 syscallno, &tst->arch.vex, 340 syscall_mask, &saved, sizeof(vki_sigset_t) 341 ); 342 # elif defined(VGO_darwin) 343 switch (VG_DARWIN_SYSNO_CLASS(syscallno)) { 344 case VG_DARWIN_SYSCALL_CLASS_UNIX: 345 err = ML_(do_syscall_for_client_unix_WRK)( 346 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex, 347 syscall_mask, &saved, 0/*unused:sigsetSzB*/ 348 ); 349 break; 350 case VG_DARWIN_SYSCALL_CLASS_MACH: 351 err = ML_(do_syscall_for_client_mach_WRK)( 352 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex, 353 syscall_mask, &saved, 0/*unused:sigsetSzB*/ 354 ); 355 break; 356 case VG_DARWIN_SYSCALL_CLASS_MDEP: 357 err = ML_(do_syscall_for_client_mdep_WRK)( 358 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex, 359 syscall_mask, &saved, 0/*unused:sigsetSzB*/ 360 ); 361 break; 362 default: 363 vg_assert(0); 364 /*NOTREACHED*/ 365 break; 366 } 367 # elif defined(VGO_solaris) 368 UChar cflag; 369 370 /* Fasttraps or anything else cannot go through this path. */ 371 vg_assert(VG_SOLARIS_SYSNO_CLASS(syscallno) 372 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC); 373 374 /* If the syscall is a door_return call then it has to be handled very 375 differently. */ 376 if (tst->os_state.in_door_return) 377 err = ML_(do_syscall_for_client_dret_WRK)( 378 syscallno, &tst->arch.vex, 379 syscall_mask, &saved, &cflag 380 ); 381 else 382 err = ML_(do_syscall_for_client_WRK)( 383 syscallno, &tst->arch.vex, 384 syscall_mask, &saved, &cflag 385 ); 386 387 /* Save the carry flag. */ 388 # if defined(VGP_x86_solaris) 389 LibVEX_GuestX86_put_eflag_c(cflag, &tst->arch.vex); 390 # elif defined(VGP_amd64_solaris) 391 LibVEX_GuestAMD64_put_rflag_c(cflag, &tst->arch.vex); 392 # else 393 # error "Unknown platform" 394 # endif 395 396 # else 397 # error "Unknown OS" 398 # endif 399 vg_assert2( 400 err == 0, 401 "ML_(do_syscall_for_client_WRK): sigprocmask error %lu", 402 err & 0xFFF 403 ); 404 } 405 406 407 /* --------------------------------------------------------------------- 408 Impedance matchers and misc helpers 409 ------------------------------------------------------------------ */ 410 411 static 412 Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 ) 413 { 414 return a1->sysno == a2->sysno 415 && a1->arg1 == a2->arg1 416 && a1->arg2 == a2->arg2 417 && a1->arg3 == a2->arg3 418 && a1->arg4 == a2->arg4 419 && a1->arg5 == a2->arg5 420 && a1->arg6 == a2->arg6 421 && a1->arg7 == a2->arg7 422 && a1->arg8 == a2->arg8; 423 } 424 425 static 426 Bool eq_SyscallStatus ( UInt sysno, SyscallStatus* s1, SyscallStatus* s2 ) 427 { 428 /* was: return s1->what == s2->what && sr_EQ( s1->sres, s2->sres ); */ 429 if (s1->what == s2->what && sr_EQ( sysno, s1->sres, s2->sres )) 430 return True; 431 # if defined(VGO_darwin) 432 /* Darwin-specific debugging guff */ 433 vg_assert(s1->what == s2->what); 434 VG_(printf)("eq_SyscallStatus:\n"); 435 VG_(printf)(" {%lu %lu %u}\n", s1->sres._wLO, s1->sres._wHI, s1->sres._mode); 436 VG_(printf)(" {%lu %lu %u}\n", s2->sres._wLO, s2->sres._wHI, s2->sres._mode); 437 vg_assert(0); 438 # endif 439 return False; 440 } 441 442 /* Convert between SysRes and SyscallStatus, to the extent possible. */ 443 444 static 445 SyscallStatus convert_SysRes_to_SyscallStatus ( SysRes res ) 446 { 447 SyscallStatus status; 448 status.what = SsComplete; 449 status.sres = res; 450 return status; 451 } 452 453 454 /* Impedance matchers. These convert syscall arg or result data from 455 the platform-specific in-guest-state format to the canonical 456 formats, and back. */ 457 458 static 459 void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, 460 /*IN*/ VexGuestArchState* gst_vanilla, 461 /*IN*/ UInt trc ) 462 { 463 #if defined(VGP_x86_linux) 464 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 465 canonical->sysno = gst->guest_EAX; 466 canonical->arg1 = gst->guest_EBX; 467 canonical->arg2 = gst->guest_ECX; 468 canonical->arg3 = gst->guest_EDX; 469 canonical->arg4 = gst->guest_ESI; 470 canonical->arg5 = gst->guest_EDI; 471 canonical->arg6 = gst->guest_EBP; 472 canonical->arg7 = 0; 473 canonical->arg8 = 0; 474 475 #elif defined(VGP_amd64_linux) 476 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 477 canonical->sysno = gst->guest_RAX; 478 canonical->arg1 = gst->guest_RDI; 479 canonical->arg2 = gst->guest_RSI; 480 canonical->arg3 = gst->guest_RDX; 481 canonical->arg4 = gst->guest_R10; 482 canonical->arg5 = gst->guest_R8; 483 canonical->arg6 = gst->guest_R9; 484 canonical->arg7 = 0; 485 canonical->arg8 = 0; 486 487 #elif defined(VGP_ppc32_linux) 488 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; 489 canonical->sysno = gst->guest_GPR0; 490 canonical->arg1 = gst->guest_GPR3; 491 canonical->arg2 = gst->guest_GPR4; 492 canonical->arg3 = gst->guest_GPR5; 493 canonical->arg4 = gst->guest_GPR6; 494 canonical->arg5 = gst->guest_GPR7; 495 canonical->arg6 = gst->guest_GPR8; 496 canonical->arg7 = 0; 497 canonical->arg8 = 0; 498 499 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 500 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla; 501 canonical->sysno = gst->guest_GPR0; 502 canonical->arg1 = gst->guest_GPR3; 503 canonical->arg2 = gst->guest_GPR4; 504 canonical->arg3 = gst->guest_GPR5; 505 canonical->arg4 = gst->guest_GPR6; 506 canonical->arg5 = gst->guest_GPR7; 507 canonical->arg6 = gst->guest_GPR8; 508 canonical->arg7 = 0; 509 canonical->arg8 = 0; 510 511 #elif defined(VGP_arm_linux) 512 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla; 513 canonical->sysno = gst->guest_R7; 514 canonical->arg1 = gst->guest_R0; 515 canonical->arg2 = gst->guest_R1; 516 canonical->arg3 = gst->guest_R2; 517 canonical->arg4 = gst->guest_R3; 518 canonical->arg5 = gst->guest_R4; 519 canonical->arg6 = gst->guest_R5; 520 canonical->arg7 = 0; 521 canonical->arg8 = 0; 522 523 #elif defined(VGP_arm64_linux) 524 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; 525 canonical->sysno = gst->guest_X8; 526 canonical->arg1 = gst->guest_X0; 527 canonical->arg2 = gst->guest_X1; 528 canonical->arg3 = gst->guest_X2; 529 canonical->arg4 = gst->guest_X3; 530 canonical->arg5 = gst->guest_X4; 531 canonical->arg6 = gst->guest_X5; 532 canonical->arg7 = 0; 533 canonical->arg8 = 0; 534 535 #elif defined(VGP_mips32_linux) 536 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; 537 canonical->sysno = gst->guest_r2; // v0 538 if (canonical->sysno == __NR_exit) { 539 canonical->arg1 = gst->guest_r4; // a0 540 canonical->arg2 = 0; 541 canonical->arg3 = 0; 542 canonical->arg4 = 0; 543 canonical->arg5 = 0; 544 canonical->arg6 = 0; 545 canonical->arg8 = 0; 546 } else if (canonical->sysno != __NR_syscall) { 547 canonical->arg1 = gst->guest_r4; // a0 548 canonical->arg2 = gst->guest_r5; // a1 549 canonical->arg3 = gst->guest_r6; // a2 550 canonical->arg4 = gst->guest_r7; // a3 551 canonical->arg5 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP/sp) 552 canonical->arg6 = *((UInt*) (gst->guest_r29 + 20)); // 20(sp) 553 canonical->arg8 = 0; 554 } else { 555 // Fixme hack handle syscall() 556 canonical->sysno = gst->guest_r4; // a0 557 canonical->arg1 = gst->guest_r5; // a1 558 canonical->arg2 = gst->guest_r6; // a2 559 canonical->arg3 = gst->guest_r7; // a3 560 canonical->arg4 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP/sp) 561 canonical->arg5 = *((UInt*) (gst->guest_r29 + 20)); // 20(guest_SP/sp) 562 canonical->arg6 = *((UInt*) (gst->guest_r29 + 24)); // 24(guest_SP/sp) 563 canonical->arg8 = __NR_syscall; 564 } 565 566 #elif defined(VGP_mips64_linux) 567 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla; 568 canonical->sysno = gst->guest_r2; // v0 569 canonical->arg1 = gst->guest_r4; // a0 570 canonical->arg2 = gst->guest_r5; // a1 571 canonical->arg3 = gst->guest_r6; // a2 572 canonical->arg4 = gst->guest_r7; // a3 573 canonical->arg5 = gst->guest_r8; // a4 574 canonical->arg6 = gst->guest_r9; // a5 575 576 #elif defined(VGP_x86_darwin) 577 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 578 UWord *stack = (UWord *)gst->guest_ESP; 579 // GrP fixme hope syscalls aren't called with really shallow stacks... 580 canonical->sysno = gst->guest_EAX; 581 if (canonical->sysno != 0) { 582 // stack[0] is return address 583 canonical->arg1 = stack[1]; 584 canonical->arg2 = stack[2]; 585 canonical->arg3 = stack[3]; 586 canonical->arg4 = stack[4]; 587 canonical->arg5 = stack[5]; 588 canonical->arg6 = stack[6]; 589 canonical->arg7 = stack[7]; 590 canonical->arg8 = stack[8]; 591 } else { 592 // GrP fixme hack handle syscall() 593 // GrP fixme what about __syscall() ? 594 // stack[0] is return address 595 // DDD: the tool can't see that the params have been shifted! Can 596 // lead to incorrect checking, I think, because the PRRAn/PSARn 597 // macros will mention the pre-shifted args. 598 canonical->sysno = stack[1]; 599 vg_assert(canonical->sysno != 0); 600 canonical->arg1 = stack[2]; 601 canonical->arg2 = stack[3]; 602 canonical->arg3 = stack[4]; 603 canonical->arg4 = stack[5]; 604 canonical->arg5 = stack[6]; 605 canonical->arg6 = stack[7]; 606 canonical->arg7 = stack[8]; 607 canonical->arg8 = stack[9]; 608 609 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n", 610 VG_(getpid)(), /*tid,*/ 611 VG_SYSNUM_STRING(canonical->sysno)); 612 } 613 614 // Here we determine what kind of syscall it was by looking at the 615 // interrupt kind, and then encode the syscall number using the 64-bit 616 // encoding for Valgrind's internal use. 617 // 618 // DDD: Would it be better to stash the JMP kind into the Darwin 619 // thread state rather than passing in the trc? 620 switch (trc) { 621 case VEX_TRC_JMP_SYS_INT128: 622 // int $0x80 = Unix, 64-bit result 623 vg_assert(canonical->sysno >= 0); 624 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno); 625 break; 626 case VEX_TRC_JMP_SYS_SYSENTER: 627 // syscall = Unix, 32-bit result 628 // OR Mach, 32-bit result 629 if (canonical->sysno >= 0) { 630 // GrP fixme hack: 0xffff == I386_SYSCALL_NUMBER_MASK 631 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno 632 & 0xffff); 633 } else { 634 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno); 635 } 636 break; 637 case VEX_TRC_JMP_SYS_INT129: 638 // int $0x81 = Mach, 32-bit result 639 vg_assert(canonical->sysno < 0); 640 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno); 641 break; 642 case VEX_TRC_JMP_SYS_INT130: 643 // int $0x82 = mdep, 32-bit result 644 vg_assert(canonical->sysno >= 0); 645 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->sysno); 646 break; 647 default: 648 vg_assert(0); 649 break; 650 } 651 652 #elif defined(VGP_amd64_darwin) 653 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 654 UWord *stack = (UWord *)gst->guest_RSP; 655 656 vg_assert(trc == VEX_TRC_JMP_SYS_SYSCALL); 657 658 // GrP fixme hope syscalls aren't called with really shallow stacks... 659 canonical->sysno = gst->guest_RAX; 660 if (canonical->sysno != __NR_syscall) { 661 // stack[0] is return address 662 canonical->arg1 = gst->guest_RDI; 663 canonical->arg2 = gst->guest_RSI; 664 canonical->arg3 = gst->guest_RDX; 665 canonical->arg4 = gst->guest_R10; // not rcx with syscall insn 666 canonical->arg5 = gst->guest_R8; 667 canonical->arg6 = gst->guest_R9; 668 canonical->arg7 = stack[1]; 669 canonical->arg8 = stack[2]; 670 } else { 671 // GrP fixme hack handle syscall() 672 // GrP fixme what about __syscall() ? 673 // stack[0] is return address 674 // DDD: the tool can't see that the params have been shifted! Can 675 // lead to incorrect checking, I think, because the PRRAn/PSARn 676 // macros will mention the pre-shifted args. 677 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI); 678 vg_assert(canonical->sysno != __NR_syscall); 679 canonical->arg1 = gst->guest_RSI; 680 canonical->arg2 = gst->guest_RDX; 681 canonical->arg3 = gst->guest_R10; // not rcx with syscall insn 682 canonical->arg4 = gst->guest_R8; 683 canonical->arg5 = gst->guest_R9; 684 canonical->arg6 = stack[1]; 685 canonical->arg7 = stack[2]; 686 canonical->arg8 = stack[3]; 687 688 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n", 689 VG_(getpid)(), /*tid,*/ 690 VG_SYSNUM_STRING(canonical->sysno)); 691 } 692 693 // no canonical->sysno adjustment needed 694 695 #elif defined(VGP_s390x_linux) 696 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla; 697 canonical->sysno = gst->guest_SYSNO; 698 canonical->arg1 = gst->guest_r2; 699 canonical->arg2 = gst->guest_r3; 700 canonical->arg3 = gst->guest_r4; 701 canonical->arg4 = gst->guest_r5; 702 canonical->arg5 = gst->guest_r6; 703 canonical->arg6 = gst->guest_r7; 704 canonical->arg7 = 0; 705 canonical->arg8 = 0; 706 707 #elif defined(VGP_tilegx_linux) 708 VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla; 709 canonical->sysno = gst->guest_r10; 710 canonical->arg1 = gst->guest_r0; 711 canonical->arg2 = gst->guest_r1; 712 canonical->arg3 = gst->guest_r2; 713 canonical->arg4 = gst->guest_r3; 714 canonical->arg5 = gst->guest_r4; 715 canonical->arg6 = gst->guest_r5; 716 canonical->arg7 = 0; 717 canonical->arg8 = 0; 718 719 #elif defined(VGP_x86_solaris) 720 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 721 UWord *stack = (UWord *)gst->guest_ESP; 722 canonical->sysno = gst->guest_EAX; 723 /* stack[0] is a return address. */ 724 canonical->arg1 = stack[1]; 725 canonical->arg2 = stack[2]; 726 canonical->arg3 = stack[3]; 727 canonical->arg4 = stack[4]; 728 canonical->arg5 = stack[5]; 729 canonical->arg6 = stack[6]; 730 canonical->arg7 = stack[7]; 731 canonical->arg8 = stack[8]; 732 733 switch (trc) { 734 case VEX_TRC_JMP_SYS_INT145: 735 case VEX_TRC_JMP_SYS_SYSENTER: 736 case VEX_TRC_JMP_SYS_SYSCALL: 737 /* These three are not actually valid syscall instructions on Solaris. 738 Pretend for now that we handle them as normal syscalls. */ 739 case VEX_TRC_JMP_SYS_INT128: 740 case VEX_TRC_JMP_SYS_INT129: 741 case VEX_TRC_JMP_SYS_INT130: 742 /* int $0x91, sysenter, syscall = normal syscall */ 743 break; 744 case VEX_TRC_JMP_SYS_INT210: 745 /* int $0xD2 = fasttrap */ 746 canonical->sysno 747 = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno); 748 break; 749 default: 750 vg_assert(0); 751 break; 752 } 753 754 #elif defined(VGP_amd64_solaris) 755 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 756 UWord *stack = (UWord *)gst->guest_RSP; 757 canonical->sysno = gst->guest_RAX; 758 /* stack[0] is a return address. */ 759 canonical->arg1 = gst->guest_RDI; 760 canonical->arg2 = gst->guest_RSI; 761 canonical->arg3 = gst->guest_RDX; 762 canonical->arg4 = gst->guest_R10; /* Not RCX with syscall. */ 763 canonical->arg5 = gst->guest_R8; 764 canonical->arg6 = gst->guest_R9; 765 canonical->arg7 = stack[1]; 766 canonical->arg8 = stack[2]; 767 768 switch (trc) { 769 case VEX_TRC_JMP_SYS_SYSCALL: 770 /* syscall = normal syscall */ 771 break; 772 case VEX_TRC_JMP_SYS_INT210: 773 /* int $0xD2 = fasttrap */ 774 canonical->sysno 775 = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno); 776 break; 777 default: 778 vg_assert(0); 779 break; 780 } 781 782 #else 783 # error "getSyscallArgsFromGuestState: unknown arch" 784 #endif 785 } 786 787 static 788 void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical, 789 /*OUT*/VexGuestArchState* gst_vanilla ) 790 { 791 #if defined(VGP_x86_linux) 792 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 793 gst->guest_EAX = canonical->sysno; 794 gst->guest_EBX = canonical->arg1; 795 gst->guest_ECX = canonical->arg2; 796 gst->guest_EDX = canonical->arg3; 797 gst->guest_ESI = canonical->arg4; 798 gst->guest_EDI = canonical->arg5; 799 gst->guest_EBP = canonical->arg6; 800 801 #elif defined(VGP_amd64_linux) 802 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 803 gst->guest_RAX = canonical->sysno; 804 gst->guest_RDI = canonical->arg1; 805 gst->guest_RSI = canonical->arg2; 806 gst->guest_RDX = canonical->arg3; 807 gst->guest_R10 = canonical->arg4; 808 gst->guest_R8 = canonical->arg5; 809 gst->guest_R9 = canonical->arg6; 810 811 #elif defined(VGP_ppc32_linux) 812 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; 813 gst->guest_GPR0 = canonical->sysno; 814 gst->guest_GPR3 = canonical->arg1; 815 gst->guest_GPR4 = canonical->arg2; 816 gst->guest_GPR5 = canonical->arg3; 817 gst->guest_GPR6 = canonical->arg4; 818 gst->guest_GPR7 = canonical->arg5; 819 gst->guest_GPR8 = canonical->arg6; 820 821 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 822 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla; 823 gst->guest_GPR0 = canonical->sysno; 824 gst->guest_GPR3 = canonical->arg1; 825 gst->guest_GPR4 = canonical->arg2; 826 gst->guest_GPR5 = canonical->arg3; 827 gst->guest_GPR6 = canonical->arg4; 828 gst->guest_GPR7 = canonical->arg5; 829 gst->guest_GPR8 = canonical->arg6; 830 831 #elif defined(VGP_arm_linux) 832 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla; 833 gst->guest_R7 = canonical->sysno; 834 gst->guest_R0 = canonical->arg1; 835 gst->guest_R1 = canonical->arg2; 836 gst->guest_R2 = canonical->arg3; 837 gst->guest_R3 = canonical->arg4; 838 gst->guest_R4 = canonical->arg5; 839 gst->guest_R5 = canonical->arg6; 840 841 #elif defined(VGP_arm64_linux) 842 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; 843 gst->guest_X8 = canonical->sysno; 844 gst->guest_X0 = canonical->arg1; 845 gst->guest_X1 = canonical->arg2; 846 gst->guest_X2 = canonical->arg3; 847 gst->guest_X3 = canonical->arg4; 848 gst->guest_X4 = canonical->arg5; 849 gst->guest_X5 = canonical->arg6; 850 851 #elif defined(VGP_x86_darwin) 852 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 853 UWord *stack = (UWord *)gst->guest_ESP; 854 855 gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno); 856 857 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0; 858 // stack[0] is return address 859 stack[1] = canonical->arg1; 860 stack[2] = canonical->arg2; 861 stack[3] = canonical->arg3; 862 stack[4] = canonical->arg4; 863 stack[5] = canonical->arg5; 864 stack[6] = canonical->arg6; 865 stack[7] = canonical->arg7; 866 stack[8] = canonical->arg8; 867 868 #elif defined(VGP_amd64_darwin) 869 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 870 UWord *stack = (UWord *)gst->guest_RSP; 871 872 gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno); 873 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0; 874 875 // stack[0] is return address 876 gst->guest_RDI = canonical->arg1; 877 gst->guest_RSI = canonical->arg2; 878 gst->guest_RDX = canonical->arg3; 879 gst->guest_RCX = canonical->arg4; 880 gst->guest_R8 = canonical->arg5; 881 gst->guest_R9 = canonical->arg6; 882 stack[1] = canonical->arg7; 883 stack[2] = canonical->arg8; 884 885 #elif defined(VGP_s390x_linux) 886 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla; 887 gst->guest_SYSNO = canonical->sysno; 888 gst->guest_r2 = canonical->arg1; 889 gst->guest_r3 = canonical->arg2; 890 gst->guest_r4 = canonical->arg3; 891 gst->guest_r5 = canonical->arg4; 892 gst->guest_r6 = canonical->arg5; 893 gst->guest_r7 = canonical->arg6; 894 895 #elif defined(VGP_mips32_linux) 896 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; 897 if (canonical->arg8 != __NR_syscall) { 898 gst->guest_r2 = canonical->sysno; 899 gst->guest_r4 = canonical->arg1; 900 gst->guest_r5 = canonical->arg2; 901 gst->guest_r6 = canonical->arg3; 902 gst->guest_r7 = canonical->arg4; 903 *((UInt*) (gst->guest_r29 + 16)) = canonical->arg5; // 16(guest_GPR29/sp) 904 *((UInt*) (gst->guest_r29 + 20)) = canonical->arg6; // 20(sp) 905 } else { 906 canonical->arg8 = 0; 907 gst->guest_r2 = __NR_syscall; 908 gst->guest_r4 = canonical->sysno; 909 gst->guest_r5 = canonical->arg1; 910 gst->guest_r6 = canonical->arg2; 911 gst->guest_r7 = canonical->arg3; 912 *((UInt*) (gst->guest_r29 + 16)) = canonical->arg4; // 16(guest_GPR29/sp) 913 *((UInt*) (gst->guest_r29 + 20)) = canonical->arg5; // 20(sp) 914 *((UInt*) (gst->guest_r29 + 24)) = canonical->arg6; // 24(sp) 915 } 916 917 #elif defined(VGP_mips64_linux) 918 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla; 919 gst->guest_r2 = canonical->sysno; 920 gst->guest_r4 = canonical->arg1; 921 gst->guest_r5 = canonical->arg2; 922 gst->guest_r6 = canonical->arg3; 923 gst->guest_r7 = canonical->arg4; 924 gst->guest_r8 = canonical->arg5; 925 gst->guest_r9 = canonical->arg6; 926 927 #elif defined(VGP_tilegx_linux) 928 VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla; 929 gst->guest_r10 = canonical->sysno; 930 gst->guest_r0 = canonical->arg1; 931 gst->guest_r1 = canonical->arg2; 932 gst->guest_r2 = canonical->arg3; 933 gst->guest_r3 = canonical->arg4; 934 gst->guest_r4 = canonical->arg5; 935 gst->guest_r5 = canonical->arg6; 936 937 #elif defined(VGP_x86_solaris) 938 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 939 UWord *stack = (UWord *)gst->guest_ESP; 940 941 /* Fasttraps or anything else cannot go through this way. */ 942 vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno) 943 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC); 944 gst->guest_EAX = canonical->sysno; 945 /* stack[0] is a return address. */ 946 stack[1] = canonical->arg1; 947 stack[2] = canonical->arg2; 948 stack[3] = canonical->arg3; 949 stack[4] = canonical->arg4; 950 stack[5] = canonical->arg5; 951 stack[6] = canonical->arg6; 952 stack[7] = canonical->arg7; 953 stack[8] = canonical->arg8; 954 955 #elif defined(VGP_amd64_solaris) 956 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 957 UWord *stack = (UWord *)gst->guest_RSP; 958 959 /* Fasttraps or anything else cannot go through this way. */ 960 vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno) 961 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC); 962 gst->guest_RAX = canonical->sysno; 963 /* stack[0] is a return address. */ 964 gst->guest_RDI = canonical->arg1; 965 gst->guest_RSI = canonical->arg2; 966 gst->guest_RDX = canonical->arg3; 967 gst->guest_R10 = canonical->arg4; 968 gst->guest_R8 = canonical->arg5; 969 gst->guest_R9 = canonical->arg6; 970 stack[1] = canonical->arg7; 971 stack[2] = canonical->arg8; 972 973 #else 974 # error "putSyscallArgsIntoGuestState: unknown arch" 975 #endif 976 } 977 978 static 979 void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus* canonical, 980 /*IN*/ VexGuestArchState* gst_vanilla ) 981 { 982 # if defined(VGP_x86_linux) 983 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 984 canonical->sres = VG_(mk_SysRes_x86_linux)( gst->guest_EAX ); 985 canonical->what = SsComplete; 986 987 # elif defined(VGP_amd64_linux) 988 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 989 canonical->sres = VG_(mk_SysRes_amd64_linux)( gst->guest_RAX ); 990 canonical->what = SsComplete; 991 992 # elif defined(VGP_ppc32_linux) 993 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; 994 UInt cr = LibVEX_GuestPPC32_get_CR( gst ); 995 UInt cr0so = (cr >> 28) & 1; 996 canonical->sres = VG_(mk_SysRes_ppc32_linux)( gst->guest_GPR3, cr0so ); 997 canonical->what = SsComplete; 998 999 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1000 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla; 1001 UInt cr = LibVEX_GuestPPC64_get_CR( gst ); 1002 UInt cr0so = (cr >> 28) & 1; 1003 canonical->sres = VG_(mk_SysRes_ppc64_linux)( gst->guest_GPR3, cr0so ); 1004 canonical->what = SsComplete; 1005 1006 # elif defined(VGP_arm_linux) 1007 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla; 1008 canonical->sres = VG_(mk_SysRes_arm_linux)( gst->guest_R0 ); 1009 canonical->what = SsComplete; 1010 1011 # elif defined(VGP_arm64_linux) 1012 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; 1013 canonical->sres = VG_(mk_SysRes_arm64_linux)( gst->guest_X0 ); 1014 canonical->what = SsComplete; 1015 1016 # elif defined(VGP_mips32_linux) 1017 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; 1018 UInt v0 = gst->guest_r2; // v0 1019 UInt v1 = gst->guest_r3; // v1 1020 UInt a3 = gst->guest_r7; // a3 1021 canonical->sres = VG_(mk_SysRes_mips32_linux)( v0, v1, a3 ); 1022 canonical->what = SsComplete; 1023 1024 # elif defined(VGP_mips64_linux) 1025 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla; 1026 ULong v0 = gst->guest_r2; // v0 1027 ULong v1 = gst->guest_r3; // v1 1028 ULong a3 = gst->guest_r7; // a3 1029 canonical->sres = VG_(mk_SysRes_mips64_linux)(v0, v1, a3); 1030 canonical->what = SsComplete; 1031 1032 # elif defined(VGP_x86_darwin) 1033 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */ 1034 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 1035 UInt carry = 1 & LibVEX_GuestX86_get_eflags(gst); 1036 UInt err = 0; 1037 UInt wLO = 0; 1038 UInt wHI = 0; 1039 switch (gst->guest_SC_CLASS) { 1040 case VG_DARWIN_SYSCALL_CLASS_UNIX: 1041 // int $0x80 = Unix, 64-bit result 1042 err = carry; 1043 wLO = gst->guest_EAX; 1044 wHI = gst->guest_EDX; 1045 break; 1046 case VG_DARWIN_SYSCALL_CLASS_MACH: 1047 // int $0x81 = Mach, 32-bit result 1048 wLO = gst->guest_EAX; 1049 break; 1050 case VG_DARWIN_SYSCALL_CLASS_MDEP: 1051 // int $0x82 = mdep, 32-bit result 1052 wLO = gst->guest_EAX; 1053 break; 1054 default: 1055 vg_assert(0); 1056 break; 1057 } 1058 canonical->sres = VG_(mk_SysRes_x86_darwin)( 1059 gst->guest_SC_CLASS, err ? True : False, 1060 wHI, wLO 1061 ); 1062 canonical->what = SsComplete; 1063 1064 # elif defined(VGP_amd64_darwin) 1065 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */ 1066 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 1067 ULong carry = 1 & LibVEX_GuestAMD64_get_rflags(gst); 1068 ULong err = 0; 1069 ULong wLO = 0; 1070 ULong wHI = 0; 1071 switch (gst->guest_SC_CLASS) { 1072 case VG_DARWIN_SYSCALL_CLASS_UNIX: 1073 // syscall = Unix, 128-bit result 1074 err = carry; 1075 wLO = gst->guest_RAX; 1076 wHI = gst->guest_RDX; 1077 break; 1078 case VG_DARWIN_SYSCALL_CLASS_MACH: 1079 // syscall = Mach, 64-bit result 1080 wLO = gst->guest_RAX; 1081 break; 1082 case VG_DARWIN_SYSCALL_CLASS_MDEP: 1083 // syscall = mdep, 64-bit result 1084 wLO = gst->guest_RAX; 1085 break; 1086 default: 1087 vg_assert(0); 1088 break; 1089 } 1090 canonical->sres = VG_(mk_SysRes_amd64_darwin)( 1091 gst->guest_SC_CLASS, err ? True : False, 1092 wHI, wLO 1093 ); 1094 canonical->what = SsComplete; 1095 1096 # elif defined(VGP_s390x_linux) 1097 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla; 1098 canonical->sres = VG_(mk_SysRes_s390x_linux)( gst->guest_r2 ); 1099 canonical->what = SsComplete; 1100 1101 # elif defined(VGP_tilegx_linux) 1102 VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla; 1103 canonical->sres = VG_(mk_SysRes_tilegx_linux)( gst->guest_r0 ); 1104 canonical->what = SsComplete; 1105 1106 # elif defined(VGP_x86_solaris) 1107 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 1108 UInt carry = 1 & LibVEX_GuestX86_get_eflags(gst); 1109 1110 canonical->sres = VG_(mk_SysRes_x86_solaris)(carry ? True : False, 1111 gst->guest_EAX, 1112 carry ? 0 : gst->guest_EDX); 1113 canonical->what = SsComplete; 1114 1115 # elif defined(VGP_amd64_solaris) 1116 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 1117 UInt carry = 1 & LibVEX_GuestAMD64_get_rflags(gst); 1118 1119 canonical->sres = VG_(mk_SysRes_amd64_solaris)(carry ? True : False, 1120 gst->guest_RAX, 1121 carry ? 0 : gst->guest_RDX); 1122 canonical->what = SsComplete; 1123 1124 # else 1125 # error "getSyscallStatusFromGuestState: unknown arch" 1126 # endif 1127 } 1128 1129 static 1130 void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid, 1131 /*IN*/ SyscallStatus* canonical, 1132 /*OUT*/VexGuestArchState* gst_vanilla ) 1133 { 1134 # if defined(VGP_x86_linux) 1135 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 1136 vg_assert(canonical->what == SsComplete); 1137 if (sr_isError(canonical->sres)) { 1138 /* This isn't exactly right, in that really a Failure with res 1139 not in the range 1 .. 4095 is unrepresentable in the 1140 Linux-x86 scheme. Oh well. */ 1141 gst->guest_EAX = - (Int)sr_Err(canonical->sres); 1142 } else { 1143 gst->guest_EAX = sr_Res(canonical->sres); 1144 } 1145 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1146 OFFSET_x86_EAX, sizeof(UWord) ); 1147 1148 # elif defined(VGP_amd64_linux) 1149 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 1150 vg_assert(canonical->what == SsComplete); 1151 if (sr_isError(canonical->sres)) { 1152 /* This isn't exactly right, in that really a Failure with res 1153 not in the range 1 .. 4095 is unrepresentable in the 1154 Linux-amd64 scheme. Oh well. */ 1155 gst->guest_RAX = - (Long)sr_Err(canonical->sres); 1156 } else { 1157 gst->guest_RAX = sr_Res(canonical->sres); 1158 } 1159 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1160 OFFSET_amd64_RAX, sizeof(UWord) ); 1161 1162 # elif defined(VGP_ppc32_linux) 1163 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla; 1164 UInt old_cr = LibVEX_GuestPPC32_get_CR(gst); 1165 vg_assert(canonical->what == SsComplete); 1166 if (sr_isError(canonical->sres)) { 1167 /* set CR0.SO */ 1168 LibVEX_GuestPPC32_put_CR( old_cr | (1<<28), gst ); 1169 gst->guest_GPR3 = sr_Err(canonical->sres); 1170 } else { 1171 /* clear CR0.SO */ 1172 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), gst ); 1173 gst->guest_GPR3 = sr_Res(canonical->sres); 1174 } 1175 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1176 OFFSET_ppc32_GPR3, sizeof(UWord) ); 1177 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1178 OFFSET_ppc32_CR0_0, sizeof(UChar) ); 1179 1180 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1181 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla; 1182 UInt old_cr = LibVEX_GuestPPC64_get_CR(gst); 1183 vg_assert(canonical->what == SsComplete); 1184 if (sr_isError(canonical->sres)) { 1185 /* set CR0.SO */ 1186 LibVEX_GuestPPC64_put_CR( old_cr | (1<<28), gst ); 1187 gst->guest_GPR3 = sr_Err(canonical->sres); 1188 } else { 1189 /* clear CR0.SO */ 1190 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), gst ); 1191 gst->guest_GPR3 = sr_Res(canonical->sres); 1192 } 1193 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1194 OFFSET_ppc64_GPR3, sizeof(UWord) ); 1195 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1196 OFFSET_ppc64_CR0_0, sizeof(UChar) ); 1197 1198 # elif defined(VGP_arm_linux) 1199 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla; 1200 vg_assert(canonical->what == SsComplete); 1201 if (sr_isError(canonical->sres)) { 1202 /* This isn't exactly right, in that really a Failure with res 1203 not in the range 1 .. 4095 is unrepresentable in the 1204 Linux-arm scheme. Oh well. */ 1205 gst->guest_R0 = - (Int)sr_Err(canonical->sres); 1206 } else { 1207 gst->guest_R0 = sr_Res(canonical->sres); 1208 } 1209 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1210 OFFSET_arm_R0, sizeof(UWord) ); 1211 1212 # elif defined(VGP_arm64_linux) 1213 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla; 1214 vg_assert(canonical->what == SsComplete); 1215 if (sr_isError(canonical->sres)) { 1216 /* This isn't exactly right, in that really a Failure with res 1217 not in the range 1 .. 4095 is unrepresentable in the 1218 Linux-arm64 scheme. Oh well. */ 1219 gst->guest_X0 = - (Long)sr_Err(canonical->sres); 1220 } else { 1221 gst->guest_X0 = sr_Res(canonical->sres); 1222 } 1223 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1224 OFFSET_arm64_X0, sizeof(UWord) ); 1225 1226 #elif defined(VGP_x86_darwin) 1227 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 1228 SysRes sres = canonical->sres; 1229 vg_assert(canonical->what == SsComplete); 1230 /* Unfortunately here we have to break abstraction and look 1231 directly inside 'res', in order to decide what to do. */ 1232 switch (sres._mode) { 1233 case SysRes_MACH: // int $0x81 = Mach, 32-bit result 1234 case SysRes_MDEP: // int $0x82 = mdep, 32-bit result 1235 gst->guest_EAX = sres._wLO; 1236 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1237 OFFSET_x86_EAX, sizeof(UInt) ); 1238 break; 1239 case SysRes_UNIX_OK: // int $0x80 = Unix, 64-bit result 1240 case SysRes_UNIX_ERR: // int $0x80 = Unix, 64-bit error 1241 gst->guest_EAX = sres._wLO; 1242 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1243 OFFSET_x86_EAX, sizeof(UInt) ); 1244 gst->guest_EDX = sres._wHI; 1245 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1246 OFFSET_x86_EDX, sizeof(UInt) ); 1247 LibVEX_GuestX86_put_eflag_c( sres._mode==SysRes_UNIX_ERR ? 1 : 0, 1248 gst ); 1249 // GrP fixme sets defined for entire eflags, not just bit c 1250 // DDD: this breaks exp-ptrcheck. 1251 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1252 offsetof(VexGuestX86State, guest_CC_DEP1), sizeof(UInt) ); 1253 break; 1254 default: 1255 vg_assert(0); 1256 break; 1257 } 1258 1259 #elif defined(VGP_amd64_darwin) 1260 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 1261 SysRes sres = canonical->sres; 1262 vg_assert(canonical->what == SsComplete); 1263 /* Unfortunately here we have to break abstraction and look 1264 directly inside 'res', in order to decide what to do. */ 1265 switch (sres._mode) { 1266 case SysRes_MACH: // syscall = Mach, 64-bit result 1267 case SysRes_MDEP: // syscall = mdep, 64-bit result 1268 gst->guest_RAX = sres._wLO; 1269 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1270 OFFSET_amd64_RAX, sizeof(ULong) ); 1271 break; 1272 case SysRes_UNIX_OK: // syscall = Unix, 128-bit result 1273 case SysRes_UNIX_ERR: // syscall = Unix, 128-bit error 1274 gst->guest_RAX = sres._wLO; 1275 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1276 OFFSET_amd64_RAX, sizeof(ULong) ); 1277 gst->guest_RDX = sres._wHI; 1278 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1279 OFFSET_amd64_RDX, sizeof(ULong) ); 1280 LibVEX_GuestAMD64_put_rflag_c( sres._mode==SysRes_UNIX_ERR ? 1 : 0, 1281 gst ); 1282 // GrP fixme sets defined for entire rflags, not just bit c 1283 // DDD: this breaks exp-ptrcheck. 1284 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1285 offsetof(VexGuestAMD64State, guest_CC_DEP1), sizeof(ULong) ); 1286 break; 1287 default: 1288 vg_assert(0); 1289 break; 1290 } 1291 1292 # elif defined(VGP_s390x_linux) 1293 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla; 1294 vg_assert(canonical->what == SsComplete); 1295 if (sr_isError(canonical->sres)) { 1296 gst->guest_r2 = - (Long)sr_Err(canonical->sres); 1297 } else { 1298 gst->guest_r2 = sr_Res(canonical->sres); 1299 } 1300 1301 # elif defined(VGP_mips32_linux) 1302 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; 1303 vg_assert(canonical->what == SsComplete); 1304 if (sr_isError(canonical->sres)) { 1305 gst->guest_r2 = (Int)sr_Err(canonical->sres); 1306 gst->guest_r7 = (Int)sr_Err(canonical->sres); 1307 } else { 1308 gst->guest_r2 = sr_Res(canonical->sres); 1309 gst->guest_r3 = sr_ResEx(canonical->sres); 1310 gst->guest_r7 = (Int)sr_Err(canonical->sres); 1311 } 1312 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1313 OFFSET_mips32_r2, sizeof(UWord) ); 1314 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1315 OFFSET_mips32_r3, sizeof(UWord) ); 1316 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1317 OFFSET_mips32_r7, sizeof(UWord) ); 1318 1319 # elif defined(VGP_mips64_linux) 1320 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla; 1321 vg_assert(canonical->what == SsComplete); 1322 if (sr_isError(canonical->sres)) { 1323 gst->guest_r2 = (Int)sr_Err(canonical->sres); 1324 gst->guest_r7 = (Int)sr_Err(canonical->sres); 1325 } else { 1326 gst->guest_r2 = sr_Res(canonical->sres); 1327 gst->guest_r3 = sr_ResEx(canonical->sres); 1328 gst->guest_r7 = (Int)sr_Err(canonical->sres); 1329 } 1330 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1331 OFFSET_mips64_r2, sizeof(UWord) ); 1332 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1333 OFFSET_mips64_r3, sizeof(UWord) ); 1334 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, 1335 OFFSET_mips64_r7, sizeof(UWord) ); 1336 1337 # elif defined(VGP_tilegx_linux) 1338 VexGuestTILEGXState* gst = (VexGuestTILEGXState*)gst_vanilla; 1339 vg_assert(canonical->what == SsComplete); 1340 if (sr_isError(canonical->sres)) { 1341 gst->guest_r0 = - (Long)sr_Err(canonical->sres); 1342 // r1 hold errno 1343 gst->guest_r1 = (Long)sr_Err(canonical->sres); 1344 } else { 1345 gst->guest_r0 = sr_Res(canonical->sres); 1346 gst->guest_r1 = 0; 1347 } 1348 1349 # elif defined(VGP_x86_solaris) 1350 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; 1351 SysRes sres = canonical->sres; 1352 vg_assert(canonical->what == SsComplete); 1353 1354 if (sr_isError(sres)) { 1355 gst->guest_EAX = sr_Err(sres); 1356 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EAX, 1357 sizeof(UInt)); 1358 LibVEX_GuestX86_put_eflag_c(1, gst); 1359 } 1360 else { 1361 gst->guest_EAX = sr_Res(sres); 1362 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EAX, 1363 sizeof(UInt)); 1364 gst->guest_EDX = sr_ResHI(sres); 1365 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EDX, 1366 sizeof(UInt)); 1367 LibVEX_GuestX86_put_eflag_c(0, gst); 1368 } 1369 /* Make CC_DEP1 and CC_DEP2 defined. This is inaccurate because it makes 1370 other eflags defined too (see README.solaris). */ 1371 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestX86State, 1372 guest_CC_DEP1), sizeof(UInt)); 1373 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestX86State, 1374 guest_CC_DEP2), sizeof(UInt)); 1375 1376 # elif defined(VGP_amd64_solaris) 1377 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; 1378 SysRes sres = canonical->sres; 1379 vg_assert(canonical->what == SsComplete); 1380 1381 if (sr_isError(sres)) { 1382 gst->guest_RAX = sr_Err(sres); 1383 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RAX, 1384 sizeof(ULong)); 1385 LibVEX_GuestAMD64_put_rflag_c(1, gst); 1386 } 1387 else { 1388 gst->guest_RAX = sr_Res(sres); 1389 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RAX, 1390 sizeof(ULong)); 1391 gst->guest_RDX = sr_ResHI(sres); 1392 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RDX, 1393 sizeof(ULong)); 1394 LibVEX_GuestAMD64_put_rflag_c(0, gst); 1395 } 1396 /* Make CC_DEP1 and CC_DEP2 defined. This is inaccurate because it makes 1397 other eflags defined too (see README.solaris). */ 1398 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestAMD64State, 1399 guest_CC_DEP1), sizeof(ULong)); 1400 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestAMD64State, 1401 guest_CC_DEP2), sizeof(ULong)); 1402 1403 # else 1404 # error "putSyscallStatusIntoGuestState: unknown arch" 1405 # endif 1406 } 1407 1408 1409 /* Tell me the offsets in the guest state of the syscall params, so 1410 that the scalar argument checkers don't have to have this info 1411 hardwired. */ 1412 1413 static 1414 void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout ) 1415 { 1416 VG_(bzero_inline)(layout, sizeof(*layout)); 1417 1418 #if defined(VGP_x86_linux) 1419 layout->o_sysno = OFFSET_x86_EAX; 1420 layout->o_arg1 = OFFSET_x86_EBX; 1421 layout->o_arg2 = OFFSET_x86_ECX; 1422 layout->o_arg3 = OFFSET_x86_EDX; 1423 layout->o_arg4 = OFFSET_x86_ESI; 1424 layout->o_arg5 = OFFSET_x86_EDI; 1425 layout->o_arg6 = OFFSET_x86_EBP; 1426 layout->uu_arg7 = -1; /* impossible value */ 1427 layout->uu_arg8 = -1; /* impossible value */ 1428 1429 #elif defined(VGP_amd64_linux) 1430 layout->o_sysno = OFFSET_amd64_RAX; 1431 layout->o_arg1 = OFFSET_amd64_RDI; 1432 layout->o_arg2 = OFFSET_amd64_RSI; 1433 layout->o_arg3 = OFFSET_amd64_RDX; 1434 layout->o_arg4 = OFFSET_amd64_R10; 1435 layout->o_arg5 = OFFSET_amd64_R8; 1436 layout->o_arg6 = OFFSET_amd64_R9; 1437 layout->uu_arg7 = -1; /* impossible value */ 1438 layout->uu_arg8 = -1; /* impossible value */ 1439 1440 #elif defined(VGP_ppc32_linux) 1441 layout->o_sysno = OFFSET_ppc32_GPR0; 1442 layout->o_arg1 = OFFSET_ppc32_GPR3; 1443 layout->o_arg2 = OFFSET_ppc32_GPR4; 1444 layout->o_arg3 = OFFSET_ppc32_GPR5; 1445 layout->o_arg4 = OFFSET_ppc32_GPR6; 1446 layout->o_arg5 = OFFSET_ppc32_GPR7; 1447 layout->o_arg6 = OFFSET_ppc32_GPR8; 1448 layout->uu_arg7 = -1; /* impossible value */ 1449 layout->uu_arg8 = -1; /* impossible value */ 1450 1451 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1452 layout->o_sysno = OFFSET_ppc64_GPR0; 1453 layout->o_arg1 = OFFSET_ppc64_GPR3; 1454 layout->o_arg2 = OFFSET_ppc64_GPR4; 1455 layout->o_arg3 = OFFSET_ppc64_GPR5; 1456 layout->o_arg4 = OFFSET_ppc64_GPR6; 1457 layout->o_arg5 = OFFSET_ppc64_GPR7; 1458 layout->o_arg6 = OFFSET_ppc64_GPR8; 1459 layout->uu_arg7 = -1; /* impossible value */ 1460 layout->uu_arg8 = -1; /* impossible value */ 1461 1462 #elif defined(VGP_arm_linux) 1463 layout->o_sysno = OFFSET_arm_R7; 1464 layout->o_arg1 = OFFSET_arm_R0; 1465 layout->o_arg2 = OFFSET_arm_R1; 1466 layout->o_arg3 = OFFSET_arm_R2; 1467 layout->o_arg4 = OFFSET_arm_R3; 1468 layout->o_arg5 = OFFSET_arm_R4; 1469 layout->o_arg6 = OFFSET_arm_R5; 1470 layout->uu_arg7 = -1; /* impossible value */ 1471 layout->uu_arg8 = -1; /* impossible value */ 1472 1473 #elif defined(VGP_arm64_linux) 1474 layout->o_sysno = OFFSET_arm64_X8; 1475 layout->o_arg1 = OFFSET_arm64_X0; 1476 layout->o_arg2 = OFFSET_arm64_X1; 1477 layout->o_arg3 = OFFSET_arm64_X2; 1478 layout->o_arg4 = OFFSET_arm64_X3; 1479 layout->o_arg5 = OFFSET_arm64_X4; 1480 layout->o_arg6 = OFFSET_arm64_X5; 1481 layout->uu_arg7 = -1; /* impossible value */ 1482 layout->uu_arg8 = -1; /* impossible value */ 1483 1484 #elif defined(VGP_mips32_linux) 1485 layout->o_sysno = OFFSET_mips32_r2; 1486 layout->o_arg1 = OFFSET_mips32_r4; 1487 layout->o_arg2 = OFFSET_mips32_r5; 1488 layout->o_arg3 = OFFSET_mips32_r6; 1489 layout->o_arg4 = OFFSET_mips32_r7; 1490 layout->s_arg5 = sizeof(UWord) * 4; 1491 layout->s_arg6 = sizeof(UWord) * 5; 1492 layout->uu_arg7 = -1; /* impossible value */ 1493 layout->uu_arg8 = -1; /* impossible value */ 1494 1495 #elif defined(VGP_mips64_linux) 1496 layout->o_sysno = OFFSET_mips64_r2; 1497 layout->o_arg1 = OFFSET_mips64_r4; 1498 layout->o_arg2 = OFFSET_mips64_r5; 1499 layout->o_arg3 = OFFSET_mips64_r6; 1500 layout->o_arg4 = OFFSET_mips64_r7; 1501 layout->o_arg5 = OFFSET_mips64_r8; 1502 layout->o_arg6 = OFFSET_mips64_r9; 1503 layout->uu_arg7 = -1; /* impossible value */ 1504 layout->uu_arg8 = -1; /* impossible value */ 1505 1506 #elif defined(VGP_x86_darwin) 1507 layout->o_sysno = OFFSET_x86_EAX; 1508 // syscall parameters are on stack in C convention 1509 layout->s_arg1 = sizeof(UWord) * 1; 1510 layout->s_arg2 = sizeof(UWord) * 2; 1511 layout->s_arg3 = sizeof(UWord) * 3; 1512 layout->s_arg4 = sizeof(UWord) * 4; 1513 layout->s_arg5 = sizeof(UWord) * 5; 1514 layout->s_arg6 = sizeof(UWord) * 6; 1515 layout->s_arg7 = sizeof(UWord) * 7; 1516 layout->s_arg8 = sizeof(UWord) * 8; 1517 1518 #elif defined(VGP_amd64_darwin) 1519 layout->o_sysno = OFFSET_amd64_RAX; 1520 layout->o_arg1 = OFFSET_amd64_RDI; 1521 layout->o_arg2 = OFFSET_amd64_RSI; 1522 layout->o_arg3 = OFFSET_amd64_RDX; 1523 layout->o_arg4 = OFFSET_amd64_RCX; 1524 layout->o_arg5 = OFFSET_amd64_R8; 1525 layout->o_arg6 = OFFSET_amd64_R9; 1526 layout->s_arg7 = sizeof(UWord) * 1; 1527 layout->s_arg8 = sizeof(UWord) * 2; 1528 1529 #elif defined(VGP_s390x_linux) 1530 layout->o_sysno = OFFSET_s390x_SYSNO; 1531 layout->o_arg1 = OFFSET_s390x_r2; 1532 layout->o_arg2 = OFFSET_s390x_r3; 1533 layout->o_arg3 = OFFSET_s390x_r4; 1534 layout->o_arg4 = OFFSET_s390x_r5; 1535 layout->o_arg5 = OFFSET_s390x_r6; 1536 layout->o_arg6 = OFFSET_s390x_r7; 1537 layout->uu_arg7 = -1; /* impossible value */ 1538 layout->uu_arg8 = -1; /* impossible value */ 1539 1540 #elif defined(VGP_tilegx_linux) 1541 layout->o_sysno = OFFSET_tilegx_r(10); 1542 layout->o_arg1 = OFFSET_tilegx_r(0); 1543 layout->o_arg2 = OFFSET_tilegx_r(1); 1544 layout->o_arg3 = OFFSET_tilegx_r(2); 1545 layout->o_arg4 = OFFSET_tilegx_r(3); 1546 layout->o_arg5 = OFFSET_tilegx_r(4); 1547 layout->o_arg6 = OFFSET_tilegx_r(5); 1548 layout->uu_arg7 = -1; /* impossible value */ 1549 layout->uu_arg8 = -1; /* impossible value */ 1550 1551 #elif defined(VGP_x86_solaris) 1552 layout->o_sysno = OFFSET_x86_EAX; 1553 /* Syscall parameters are on the stack. */ 1554 layout->s_arg1 = sizeof(UWord) * 1; 1555 layout->s_arg2 = sizeof(UWord) * 2; 1556 layout->s_arg3 = sizeof(UWord) * 3; 1557 layout->s_arg4 = sizeof(UWord) * 4; 1558 layout->s_arg5 = sizeof(UWord) * 5; 1559 layout->s_arg6 = sizeof(UWord) * 6; 1560 layout->s_arg7 = sizeof(UWord) * 7; 1561 layout->s_arg8 = sizeof(UWord) * 8; 1562 1563 #elif defined(VGP_amd64_solaris) 1564 layout->o_sysno = OFFSET_amd64_RAX; 1565 layout->o_arg1 = OFFSET_amd64_RDI; 1566 layout->o_arg2 = OFFSET_amd64_RSI; 1567 layout->o_arg3 = OFFSET_amd64_RDX; 1568 layout->o_arg4 = OFFSET_amd64_R10; 1569 layout->o_arg5 = OFFSET_amd64_R8; 1570 layout->o_arg6 = OFFSET_amd64_R9; 1571 layout->s_arg7 = sizeof(UWord) * 1; 1572 layout->s_arg8 = sizeof(UWord) * 2; 1573 1574 #else 1575 # error "getSyscallLayout: unknown arch" 1576 #endif 1577 } 1578 1579 1580 /* --------------------------------------------------------------------- 1581 The main driver logic 1582 ------------------------------------------------------------------ */ 1583 1584 /* Finding the handlers for a given syscall, or faking up one 1585 when no handler is found. */ 1586 1587 static 1588 void bad_before ( ThreadId tid, 1589 SyscallArgLayout* layout, 1590 /*MOD*/SyscallArgs* args, 1591 /*OUT*/SyscallStatus* status, 1592 /*OUT*/UWord* flags ) 1593 { 1594 VG_(dmsg)("WARNING: unhandled %s syscall: %s\n", 1595 VG_PLATFORM, VG_SYSNUM_STRING(args->sysno)); 1596 if (VG_(clo_verbosity) > 1) { 1597 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 1598 } 1599 VG_(dmsg)("You may be able to write your own handler.\n"); 1600 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n"); 1601 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n"); 1602 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html.\n"); 1603 1604 SET_STATUS_Failure(VKI_ENOSYS); 1605 1606 # if defined(VGO_solaris) 1607 VG_(exit)(1); 1608 # endif 1609 } 1610 1611 static SyscallTableEntry bad_sys = 1612 { bad_before, NULL }; 1613 1614 static const SyscallTableEntry* get_syscall_entry ( Int syscallno ) 1615 { 1616 const SyscallTableEntry* sys = NULL; 1617 1618 # if defined(VGO_linux) 1619 sys = ML_(get_linux_syscall_entry)( syscallno ); 1620 1621 # elif defined(VGO_darwin) 1622 Int idx = VG_DARWIN_SYSNO_INDEX(syscallno); 1623 1624 switch (VG_DARWIN_SYSNO_CLASS(syscallno)) { 1625 case VG_DARWIN_SYSCALL_CLASS_UNIX: 1626 if (idx >= 0 && idx < ML_(syscall_table_size) && 1627 ML_(syscall_table)[idx].before != NULL) 1628 sys = &ML_(syscall_table)[idx]; 1629 break; 1630 case VG_DARWIN_SYSCALL_CLASS_MACH: 1631 if (idx >= 0 && idx < ML_(mach_trap_table_size) && 1632 ML_(mach_trap_table)[idx].before != NULL) 1633 sys = &ML_(mach_trap_table)[idx]; 1634 break; 1635 case VG_DARWIN_SYSCALL_CLASS_MDEP: 1636 if (idx >= 0 && idx < ML_(mdep_trap_table_size) && 1637 ML_(mdep_trap_table)[idx].before != NULL) 1638 sys = &ML_(mdep_trap_table)[idx]; 1639 break; 1640 default: 1641 vg_assert(0); 1642 break; 1643 } 1644 1645 # elif defined(VGO_solaris) 1646 sys = ML_(get_solaris_syscall_entry)(syscallno); 1647 1648 # else 1649 # error Unknown OS 1650 # endif 1651 1652 return sys == NULL ? &bad_sys : sys; 1653 } 1654 1655 1656 /* Add and remove signals from mask so that we end up telling the 1657 kernel the state we actually want rather than what the client 1658 wants. */ 1659 static void sanitize_client_sigmask(vki_sigset_t *mask) 1660 { 1661 VG_(sigdelset)(mask, VKI_SIGKILL); 1662 VG_(sigdelset)(mask, VKI_SIGSTOP); 1663 VG_(sigdelset)(mask, VG_SIGVGKILL); /* never block */ 1664 } 1665 1666 typedef 1667 struct { 1668 SyscallArgs orig_args; 1669 SyscallArgs args; 1670 SyscallStatus status; 1671 UWord flags; 1672 } 1673 SyscallInfo; 1674 1675 SyscallInfo *syscallInfo; 1676 1677 /* The scheduler needs to be able to zero out these records after a 1678 fork, hence this is exported from m_syswrap. */ 1679 void VG_(clear_syscallInfo) ( Int tid ) 1680 { 1681 vg_assert(syscallInfo); 1682 vg_assert(tid >= 0 && tid < VG_N_THREADS); 1683 VG_(memset)( & syscallInfo[tid], 0, sizeof( syscallInfo[tid] )); 1684 syscallInfo[tid].status.what = SsIdle; 1685 } 1686 1687 Bool VG_(is_in_syscall) ( Int tid ) 1688 { 1689 vg_assert(tid >= 0 && tid < VG_N_THREADS); 1690 return (syscallInfo[tid].status.what != SsIdle); 1691 } 1692 1693 static void ensure_initialised ( void ) 1694 { 1695 Int i; 1696 static Bool init_done = False; 1697 if (init_done) 1698 return; 1699 init_done = True; 1700 1701 syscallInfo = VG_(malloc)("scinfo", VG_N_THREADS * sizeof syscallInfo[0]); 1702 1703 for (i = 0; i < VG_N_THREADS; i++) { 1704 VG_(clear_syscallInfo)( i ); 1705 } 1706 } 1707 1708 /* --- This is the main function of this file. --- */ 1709 1710 void VG_(client_syscall) ( ThreadId tid, UInt trc ) 1711 { 1712 Word sysno; 1713 ThreadState* tst; 1714 const SyscallTableEntry* ent; 1715 SyscallArgLayout layout; 1716 SyscallInfo* sci; 1717 1718 ensure_initialised(); 1719 1720 vg_assert(VG_(is_valid_tid)(tid)); 1721 vg_assert(tid >= 1 && tid < VG_N_THREADS); 1722 vg_assert(VG_(is_running_thread)(tid)); 1723 1724 # if !defined(VGO_darwin) 1725 // Resync filtering is meaningless on non-Darwin targets. 1726 vg_assert(VG_(clo_resync_filter) == 0); 1727 # endif 1728 1729 tst = VG_(get_ThreadState)(tid); 1730 1731 /* BEGIN ensure root thread's stack is suitably mapped */ 1732 /* In some rare circumstances, we may do the syscall without the 1733 bottom page of the stack being mapped, because the stack pointer 1734 was moved down just a few instructions before the syscall 1735 instruction, and there have been no memory references since 1736 then, that would cause a call to VG_(extend_stack) to have 1737 happened. 1738 1739 In native execution that's OK: the kernel automagically extends 1740 the stack's mapped area down to cover the stack pointer (or sp - 1741 redzone, really). In simulated normal execution that's OK too, 1742 since any signals we get from accessing below the mapped area of 1743 the (guest's) stack lead us to VG_(extend_stack), where we 1744 simulate the kernel's stack extension logic. But that leaves 1745 the problem of entering a syscall with the SP unmapped. Because 1746 the kernel doesn't know that the segment immediately above SP is 1747 supposed to be a grow-down segment, it causes the syscall to 1748 fail, and thereby causes a divergence between native behaviour 1749 (syscall succeeds) and simulated behaviour (syscall fails). 1750 1751 This is quite a rare failure mode. It has only been seen 1752 affecting calls to sys_readlink on amd64-linux, and even then it 1753 requires a certain code sequence around the syscall to trigger 1754 it. Here is one: 1755 1756 extern int my_readlink ( const char* path ); 1757 asm( 1758 ".text\n" 1759 ".globl my_readlink\n" 1760 "my_readlink:\n" 1761 "\tsubq $0x1008,%rsp\n" 1762 "\tmovq %rdi,%rdi\n" // path is in rdi 1763 "\tmovq %rsp,%rsi\n" // &buf[0] -> rsi 1764 "\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx 1765 "\tmovl $"__NR_READLINK",%eax\n" // syscall number 1766 "\tsyscall\n" 1767 "\taddq $0x1008,%rsp\n" 1768 "\tret\n" 1769 ".previous\n" 1770 ); 1771 1772 For more details, see bug #156404 1773 (https://bugs.kde.org/show_bug.cgi?id=156404). 1774 1775 The fix is actually very simple. We simply need to call 1776 VG_(extend_stack) for this thread, handing it the lowest 1777 possible valid address for stack (sp - redzone), to ensure the 1778 pages all the way down to that address, are mapped. Because 1779 this is a potentially expensive and frequent operation, we 1780 do the following: 1781 1782 Only the main thread (tid=1) has a growdown stack. So 1783 ignore all others. It is conceivable, although highly unlikely, 1784 that the main thread exits, and later another thread is 1785 allocated tid=1, but that's harmless, I believe; 1786 VG_(extend_stack) will do nothing when applied to a non-root 1787 thread. 1788 1789 All this guff is of course Linux-specific. Hence the ifdef. 1790 */ 1791 # if defined(VGO_linux) 1792 if (tid == 1/*ROOT THREAD*/) { 1793 Addr stackMin = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB; 1794 1795 /* The precise thing to do here would be to extend the stack only 1796 if the system call can be proven to access unmapped user stack 1797 memory. That is an enormous amount of work even if a proper 1798 spec of system calls was available. 1799 1800 In the case where the system call does not access user memory 1801 the stack pointer here can have any value. A legitimate testcase 1802 that exercises this is none/tests/s390x/stmg.c: 1803 The stack pointer happens to be in the reservation segment near 1804 the end of the addressable memory and there is no SkAnonC segment 1805 above. 1806 1807 So the approximation we're taking here is to extend the stack only 1808 if the client stack pointer does not look bogus. */ 1809 if (VG_(am_addr_is_in_extensible_client_stack)(stackMin)) 1810 VG_(extend_stack)( tid, stackMin ); 1811 } 1812 # endif 1813 /* END ensure root thread's stack is suitably mapped */ 1814 1815 /* First off, get the syscall args and number. This is a 1816 platform-dependent action. */ 1817 1818 sci = & syscallInfo[tid]; 1819 vg_assert(sci->status.what == SsIdle); 1820 1821 getSyscallArgsFromGuestState( &sci->orig_args, &tst->arch.vex, trc ); 1822 1823 /* Copy .orig_args to .args. The pre-handler may modify .args, but 1824 we want to keep the originals too, just in case. */ 1825 sci->args = sci->orig_args; 1826 1827 /* Save the syscall number in the thread state in case the syscall 1828 is interrupted by a signal. */ 1829 sysno = sci->orig_args.sysno; 1830 1831 /* It's sometimes useful, as a crude debugging hack, to get a 1832 stack trace at each (or selected) syscalls. */ 1833 if (0 && sysno == __NR_ioctl) { 1834 VG_(umsg)("\nioctl:\n"); 1835 VG_(get_and_pp_StackTrace)(tid, 10); 1836 VG_(umsg)("\n"); 1837 } 1838 1839 # if defined(VGO_darwin) 1840 /* Record syscall class. But why? Because the syscall might be 1841 interrupted by a signal, and in the signal handler (which will 1842 be m_signals.async_signalhandler) we will need to build a SysRes 1843 reflecting the syscall return result. In order to do that we 1844 need to know the syscall class. Hence stash it in the guest 1845 state of this thread. This madness is not needed on Linux 1846 because it only has a single syscall return convention and so 1847 there is no ambiguity involved in converting the post-signal 1848 machine state into a SysRes. */ 1849 tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(sysno); 1850 # endif 1851 1852 /* The default what-to-do-next thing is hand the syscall to the 1853 kernel, so we pre-set that here. Set .sres to something 1854 harmless looking (is irrelevant because .what is not 1855 SsComplete.) */ 1856 sci->status.what = SsHandToKernel; 1857 sci->status.sres = VG_(mk_SysRes_Error)(0); 1858 sci->flags = 0; 1859 1860 /* Fetch the syscall's handlers. If no handlers exist for this 1861 syscall, we are given dummy handlers which force an immediate 1862 return with ENOSYS. */ 1863 ent = get_syscall_entry(sysno); 1864 1865 /* Fetch the layout information, which tells us where in the guest 1866 state the syscall args reside. This is a platform-dependent 1867 action. This info is needed so that the scalar syscall argument 1868 checks (PRE_REG_READ calls) know which bits of the guest state 1869 they need to inspect. */ 1870 getSyscallArgLayout( &layout ); 1871 1872 /* Make sure the tmp signal mask matches the real signal mask; 1873 sigsuspend may change this. */ 1874 vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask)); 1875 1876 /* Right, we're finally ready to Party. Call the pre-handler and 1877 see what we get back. At this point: 1878 1879 sci->status.what is Unset (we don't know yet). 1880 sci->orig_args contains the original args. 1881 sci->args is the same as sci->orig_args. 1882 sci->flags is zero. 1883 */ 1884 1885 PRINT("SYSCALL[%d,%u](%s) ", 1886 VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno)); 1887 1888 /* Do any pre-syscall actions */ 1889 if (VG_(needs).syscall_wrapper) { 1890 UWord tmpv[8]; 1891 tmpv[0] = sci->orig_args.arg1; 1892 tmpv[1] = sci->orig_args.arg2; 1893 tmpv[2] = sci->orig_args.arg3; 1894 tmpv[3] = sci->orig_args.arg4; 1895 tmpv[4] = sci->orig_args.arg5; 1896 tmpv[5] = sci->orig_args.arg6; 1897 tmpv[6] = sci->orig_args.arg7; 1898 tmpv[7] = sci->orig_args.arg8; 1899 VG_TDICT_CALL(tool_pre_syscall, tid, sysno, 1900 &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0])); 1901 } 1902 1903 vg_assert(ent); 1904 vg_assert(ent->before); 1905 (ent->before)( tid, 1906 &layout, 1907 &sci->args, &sci->status, &sci->flags ); 1908 1909 /* The pre-handler may have modified: 1910 sci->args 1911 sci->status 1912 sci->flags 1913 All else remains unchanged. 1914 Although the args may be modified, pre handlers are not allowed 1915 to change the syscall number. 1916 */ 1917 /* Now we proceed according to what the pre-handler decided. */ 1918 vg_assert(sci->status.what == SsHandToKernel 1919 || sci->status.what == SsComplete); 1920 vg_assert(sci->args.sysno == sci->orig_args.sysno); 1921 1922 if (sci->status.what == SsComplete && !sr_isError(sci->status.sres)) { 1923 /* The pre-handler completed the syscall itself, declaring 1924 success. */ 1925 if (sci->flags & SfNoWriteResult) { 1926 PRINT(" --> [pre-success] NoWriteResult"); 1927 } else { 1928 PRINT(" --> [pre-success] %s", VG_(sr_as_string)(sci->status.sres)); 1929 } 1930 /* In this case the allowable flags are to ask for a signal-poll 1931 and/or a yield after the call. Changing the args isn't 1932 allowed. */ 1933 vg_assert(0 == (sci->flags 1934 & ~(SfPollAfter | SfYieldAfter | SfNoWriteResult))); 1935 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args)); 1936 } 1937 1938 else 1939 if (sci->status.what == SsComplete && sr_isError(sci->status.sres)) { 1940 /* The pre-handler decided to fail syscall itself. */ 1941 PRINT(" --> [pre-fail] %s", VG_(sr_as_string)(sci->status.sres)); 1942 /* In this case, the pre-handler is also allowed to ask for the 1943 post-handler to be run anyway. Changing the args is not 1944 allowed. */ 1945 vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter))); 1946 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args)); 1947 } 1948 1949 else 1950 if (sci->status.what != SsHandToKernel) { 1951 /* huh?! */ 1952 vg_assert(0); 1953 } 1954 1955 else /* (sci->status.what == HandToKernel) */ { 1956 /* Ok, this is the usual case -- and the complicated one. There 1957 are two subcases: sync and async. async is the general case 1958 and is to be used when there is any possibility that the 1959 syscall might block [a fact that the pre-handler must tell us 1960 via the sci->flags field.] Because the tidying-away / 1961 context-switch overhead of the async case could be large, if 1962 we are sure that the syscall will not block, we fast-track it 1963 by doing it directly in this thread, which is a lot 1964 simpler. */ 1965 1966 /* Check that the given flags are allowable: MayBlock, PollAfter 1967 and PostOnFail are ok. */ 1968 vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter))); 1969 1970 if (sci->flags & SfMayBlock) { 1971 1972 /* Syscall may block, so run it asynchronously */ 1973 vki_sigset_t mask; 1974 1975 PRINT(" --> [async] ... \n"); 1976 1977 mask = tst->sig_mask; 1978 sanitize_client_sigmask(&mask); 1979 1980 /* Gack. More impedance matching. Copy the possibly 1981 modified syscall args back into the guest state. */ 1982 /* JRS 2009-Mar-16: if the syscall args are possibly modified, 1983 then this assertion is senseless: 1984 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args)); 1985 The case that exposed it was sys_posix_spawn on Darwin, 1986 which heavily modifies its arguments but then lets the call 1987 go through anyway, with SfToBlock set, hence we end up here. */ 1988 putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex ); 1989 1990 /* SfNoWriteResult flag is invalid for blocking signals because 1991 do_syscall_for_client() directly modifies the guest state. */ 1992 vg_assert(!(sci->flags & SfNoWriteResult)); 1993 1994 /* Drop the bigLock */ 1995 VG_(release_BigLock)(tid, VgTs_WaitSys, "VG_(client_syscall)[async]"); 1996 /* Urr. We're now in a race against other threads trying to 1997 acquire the bigLock. I guess that doesn't matter provided 1998 that do_syscall_for_client only touches thread-local 1999 state. */ 2000 2001 /* Do the call, which operates directly on the guest state, 2002 not on our abstracted copies of the args/result. */ 2003 do_syscall_for_client(sysno, tst, &mask); 2004 2005 /* do_syscall_for_client may not return if the syscall was 2006 interrupted by a signal. In that case, flow of control is 2007 first to m_signals.async_sighandler, which calls 2008 VG_(fixup_guest_state_after_syscall_interrupted), which 2009 fixes up the guest state, and possibly calls 2010 VG_(post_syscall). Once that's done, control drops back 2011 to the scheduler. */ 2012 2013 /* Darwin: do_syscall_for_client may not return if the 2014 syscall was workq_ops(WQOPS_THREAD_RETURN) and the kernel 2015 responded by starting the thread at wqthread_hijack(reuse=1) 2016 (to run another workqueue item). In that case, wqthread_hijack 2017 calls ML_(wqthread_continue), which is similar to 2018 VG_(fixup_guest_state_after_syscall_interrupted). */ 2019 2020 /* Reacquire the lock */ 2021 VG_(acquire_BigLock)(tid, "VG_(client_syscall)[async]"); 2022 2023 /* Even more impedance matching. Extract the syscall status 2024 from the guest state. */ 2025 getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex ); 2026 vg_assert(sci->status.what == SsComplete); 2027 2028 /* Be decorative, if required. */ 2029 if (VG_(clo_trace_syscalls)) { 2030 PRINT("SYSCALL[%d,%u](%s) ... [async] --> %s", 2031 VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno), 2032 VG_(sr_as_string)(sci->status.sres)); 2033 } 2034 2035 } else { 2036 2037 /* run the syscall directly */ 2038 /* The pre-handler may have modified the syscall args, but 2039 since we're passing values in ->args directly to the 2040 kernel, there's no point in flushing them back to the 2041 guest state. Indeed doing so could be construed as 2042 incorrect. */ 2043 SysRes sres 2044 = VG_(do_syscall)(sysno, sci->args.arg1, sci->args.arg2, 2045 sci->args.arg3, sci->args.arg4, 2046 sci->args.arg5, sci->args.arg6, 2047 sci->args.arg7, sci->args.arg8 ); 2048 sci->status = convert_SysRes_to_SyscallStatus(sres); 2049 2050 /* Be decorative, if required. */ 2051 if (VG_(clo_trace_syscalls)) { 2052 PRINT("[sync] --> %s", VG_(sr_as_string)(sci->status.sres)); 2053 } 2054 } 2055 } 2056 2057 vg_assert(sci->status.what == SsComplete); 2058 2059 vg_assert(VG_(is_running_thread)(tid)); 2060 2061 /* Dump the syscall result back in the guest state. This is 2062 a platform-specific action. */ 2063 if (!(sci->flags & SfNoWriteResult)) 2064 putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex ); 2065 2066 /* Situation now: 2067 - the guest state is now correctly modified following the syscall 2068 - modified args, original args and syscall status are still 2069 available in the syscallInfo[] entry for this syscall. 2070 2071 Now go on to do the post-syscall actions (read on down ..) 2072 */ 2073 PRINT(" "); 2074 VG_(post_syscall)(tid); 2075 PRINT("\n"); 2076 } 2077 2078 2079 /* Perform post syscall actions. The expected state on entry is 2080 precisely as at the end of VG_(client_syscall), that is: 2081 2082 - guest state up to date following the syscall 2083 - modified args, original args and syscall status are still 2084 available in the syscallInfo[] entry for this syscall. 2085 - syscall status matches what's in the guest state. 2086 2087 There are two ways to get here: the normal way -- being called by 2088 VG_(client_syscall), and the unusual way, from 2089 VG_(fixup_guest_state_after_syscall_interrupted). 2090 Darwin: there's a third way, ML_(wqthread_continue). 2091 */ 2092 void VG_(post_syscall) (ThreadId tid) 2093 { 2094 SyscallInfo* sci; 2095 const SyscallTableEntry* ent; 2096 SyscallStatus test_status; 2097 ThreadState* tst; 2098 Word sysno; 2099 2100 /* Preliminaries */ 2101 vg_assert(VG_(is_valid_tid)(tid)); 2102 vg_assert(tid >= 1 && tid < VG_N_THREADS); 2103 vg_assert(VG_(is_running_thread)(tid)); 2104 2105 tst = VG_(get_ThreadState)(tid); 2106 sci = & syscallInfo[tid]; 2107 2108 /* m_signals.sigvgkill_handler might call here even when not in 2109 a syscall. */ 2110 if (sci->status.what == SsIdle || sci->status.what == SsHandToKernel) { 2111 sci->status.what = SsIdle; 2112 return; 2113 } 2114 2115 /* Validate current syscallInfo entry. In particular we require 2116 that the current .status matches what's actually in the guest 2117 state. At least in the normal case where we have actually 2118 previously written the result into the guest state. */ 2119 vg_assert(sci->status.what == SsComplete); 2120 2121 /* Get the system call number. Because the pre-handler isn't 2122 allowed to mess with it, it should be the same for both the 2123 original and potentially-modified args. */ 2124 vg_assert(sci->args.sysno == sci->orig_args.sysno); 2125 sysno = sci->args.sysno; 2126 2127 getSyscallStatusFromGuestState( &test_status, &tst->arch.vex ); 2128 if (!(sci->flags & SfNoWriteResult)) 2129 vg_assert(eq_SyscallStatus( sysno, &sci->status, &test_status )); 2130 /* Failure of the above assertion on Darwin can indicate a problem 2131 in the syscall wrappers that pre-fail or pre-succeed the 2132 syscall, by calling SET_STATUS_Success or SET_STATUS_Failure, 2133 when they really should call SET_STATUS_from_SysRes. The former 2134 create a UNIX-class syscall result on Darwin, which may not be 2135 correct for the syscall; if that's the case then this assertion 2136 fires. See PRE(thread_fast_set_cthread_self) for an example. On 2137 non-Darwin platforms this assertion is should never fail, and this 2138 comment is completely irrelevant. */ 2139 /* Ok, looks sane */ 2140 2141 /* pre: status == Complete (asserted above) */ 2142 /* Consider either success or failure. Now run the post handler if: 2143 - it exists, and 2144 - Success or (Failure and PostOnFail is set) 2145 */ 2146 ent = get_syscall_entry(sysno); 2147 if (ent->after 2148 && ((!sr_isError(sci->status.sres)) 2149 || (sr_isError(sci->status.sres) 2150 && (sci->flags & SfPostOnFail) ))) { 2151 2152 (ent->after)( tid, &sci->args, &sci->status ); 2153 } 2154 2155 /* Because the post handler might have changed the status (eg, the 2156 post-handler for sys_open can change the result from success to 2157 failure if the kernel supplied a fd that it doesn't like), once 2158 again dump the syscall result back in the guest state.*/ 2159 if (!(sci->flags & SfNoWriteResult)) 2160 putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex ); 2161 2162 /* Do any post-syscall actions required by the tool. */ 2163 if (VG_(needs).syscall_wrapper) { 2164 UWord tmpv[8]; 2165 tmpv[0] = sci->orig_args.arg1; 2166 tmpv[1] = sci->orig_args.arg2; 2167 tmpv[2] = sci->orig_args.arg3; 2168 tmpv[3] = sci->orig_args.arg4; 2169 tmpv[4] = sci->orig_args.arg5; 2170 tmpv[5] = sci->orig_args.arg6; 2171 tmpv[6] = sci->orig_args.arg7; 2172 tmpv[7] = sci->orig_args.arg8; 2173 VG_TDICT_CALL(tool_post_syscall, tid, 2174 sysno, 2175 &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]), 2176 sci->status.sres); 2177 } 2178 2179 /* The syscall is done. */ 2180 vg_assert(sci->status.what == SsComplete); 2181 sci->status.what = SsIdle; 2182 2183 /* The pre/post wrappers may have concluded that pending signals 2184 might have been created, and will have set SfPollAfter to 2185 request a poll for them once the syscall is done. */ 2186 if (sci->flags & SfPollAfter) 2187 VG_(poll_signals)(tid); 2188 2189 /* Similarly, the wrappers might have asked for a yield 2190 afterwards. */ 2191 if (sci->flags & SfYieldAfter) 2192 VG_(vg_yield)(); 2193 } 2194 2195 2196 /* --------------------------------------------------------------------- 2197 Dealing with syscalls which get interrupted by a signal: 2198 VG_(fixup_guest_state_after_syscall_interrupted) 2199 ------------------------------------------------------------------ */ 2200 2201 /* Syscalls done on behalf of the client are finally handed off to the 2202 kernel in VG_(client_syscall) above, either by calling 2203 do_syscall_for_client (the async case), or by calling 2204 VG_(do_syscall6) (the sync case). 2205 2206 If the syscall is not interrupted by a signal (it may block and 2207 later unblock, but that's irrelevant here) then those functions 2208 eventually return and so control is passed to VG_(post_syscall). 2209 NB: not sure if the sync case can actually get interrupted, as it 2210 operates with all signals masked. 2211 2212 However, the syscall may get interrupted by an async-signal. In 2213 that case do_syscall_for_client/VG_(do_syscall6) do not 2214 return. Instead we wind up in m_signals.async_sighandler. We need 2215 to fix up the guest state to make it look like the syscall was 2216 interrupted for guest. So async_sighandler calls here, and this 2217 does the fixup. Note that from here we wind up calling 2218 VG_(post_syscall) too. 2219 */ 2220 2221 2222 /* These are addresses within ML_(do_syscall_for_client_WRK). See 2223 syscall-$PLAT.S for details. 2224 */ 2225 #if defined(VGO_linux) 2226 extern const Addr ML_(blksys_setup); 2227 extern const Addr ML_(blksys_restart); 2228 extern const Addr ML_(blksys_complete); 2229 extern const Addr ML_(blksys_committed); 2230 extern const Addr ML_(blksys_finished); 2231 #elif defined(VGO_darwin) 2232 /* Darwin requires extra uglyness */ 2233 extern const Addr ML_(blksys_setup_MACH); 2234 extern const Addr ML_(blksys_restart_MACH); 2235 extern const Addr ML_(blksys_complete_MACH); 2236 extern const Addr ML_(blksys_committed_MACH); 2237 extern const Addr ML_(blksys_finished_MACH); 2238 extern const Addr ML_(blksys_setup_MDEP); 2239 extern const Addr ML_(blksys_restart_MDEP); 2240 extern const Addr ML_(blksys_complete_MDEP); 2241 extern const Addr ML_(blksys_committed_MDEP); 2242 extern const Addr ML_(blksys_finished_MDEP); 2243 extern const Addr ML_(blksys_setup_UNIX); 2244 extern const Addr ML_(blksys_restart_UNIX); 2245 extern const Addr ML_(blksys_complete_UNIX); 2246 extern const Addr ML_(blksys_committed_UNIX); 2247 extern const Addr ML_(blksys_finished_UNIX); 2248 #elif defined(VGO_solaris) 2249 extern const Addr ML_(blksys_setup); 2250 extern const Addr ML_(blksys_complete); 2251 extern const Addr ML_(blksys_committed); 2252 extern const Addr ML_(blksys_finished); 2253 extern const Addr ML_(blksys_setup_DRET); 2254 extern const Addr ML_(blksys_complete_DRET); 2255 extern const Addr ML_(blksys_committed_DRET); 2256 extern const Addr ML_(blksys_finished_DRET); 2257 #else 2258 # error "Unknown OS" 2259 #endif 2260 2261 2262 /* Back up guest state to restart a system call. */ 2263 2264 void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch ) 2265 { 2266 #if defined(VGP_x86_linux) 2267 arch->vex.guest_EIP -= 2; // sizeof(int $0x80) 2268 2269 /* Make sure our caller is actually sane, and we're really backing 2270 back over a syscall. 2271 2272 int $0x80 == CD 80 2273 */ 2274 { 2275 UChar *p = (UChar *)arch->vex.guest_EIP; 2276 2277 if (p[0] != 0xcd || p[1] != 0x80) 2278 VG_(message)(Vg_DebugMsg, 2279 "?! restarting over syscall at %#x %02x %02x\n", 2280 arch->vex.guest_EIP, p[0], p[1]); 2281 2282 vg_assert(p[0] == 0xcd && p[1] == 0x80); 2283 } 2284 2285 #elif defined(VGP_amd64_linux) 2286 arch->vex.guest_RIP -= 2; // sizeof(syscall) 2287 2288 /* Make sure our caller is actually sane, and we're really backing 2289 back over a syscall. 2290 2291 syscall == 0F 05 2292 */ 2293 { 2294 UChar *p = (UChar *)arch->vex.guest_RIP; 2295 2296 if (p[0] != 0x0F || p[1] != 0x05) 2297 VG_(message)(Vg_DebugMsg, 2298 "?! restarting over syscall at %#llx %02x %02x\n", 2299 arch->vex.guest_RIP, p[0], p[1]); 2300 2301 vg_assert(p[0] == 0x0F && p[1] == 0x05); 2302 } 2303 2304 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) 2305 arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr) 2306 2307 /* Make sure our caller is actually sane, and we're really backing 2308 back over a syscall. 2309 2310 sc == 44 00 00 02 2311 */ 2312 { 2313 UChar *p = (UChar *)arch->vex.guest_CIA; 2314 2315 if (p[0] != 0x44 || p[1] != 0x0 || p[2] != 0x0 || p[3] != 0x02) 2316 VG_(message)(Vg_DebugMsg, 2317 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n", 2318 (ULong)arch->vex.guest_CIA, p[0], p[1], p[2], p[3]); 2319 2320 vg_assert(p[0] == 0x44 && p[1] == 0x0 && p[2] == 0x0 && p[3] == 0x2); 2321 } 2322 2323 #elif defined(VGP_ppc64le_linux) 2324 arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr) 2325 2326 /* Make sure our caller is actually sane, and we're really backing 2327 back over a syscall. 2328 2329 sc == 44 00 00 02 2330 */ 2331 { 2332 UChar *p = (UChar *)arch->vex.guest_CIA; 2333 2334 if (p[3] != 0x44 || p[2] != 0x0 || p[1] != 0x0 || p[0] != 0x02) 2335 VG_(message)(Vg_DebugMsg, 2336 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n", 2337 arch->vex.guest_CIA, p[3], p[2], p[1], p[0]); 2338 2339 vg_assert(p[3] == 0x44 && p[2] == 0x0 && p[1] == 0x0 && p[0] == 0x2); 2340 } 2341 2342 #elif defined(VGP_arm_linux) 2343 if (arch->vex.guest_R15T & 1) { 2344 // Thumb mode. SVC is a encoded as 2345 // 1101 1111 imm8 2346 // where imm8 is the SVC number, and we only accept 0. 2347 arch->vex.guest_R15T -= 2; // sizeof(thumb 16 bit insn) 2348 UChar* p = (UChar*)(arch->vex.guest_R15T - 1); 2349 Bool valid = p[0] == 0 && p[1] == 0xDF; 2350 if (!valid) { 2351 VG_(message)(Vg_DebugMsg, 2352 "?! restarting over (Thumb) syscall that is not syscall " 2353 "at %#x %02x %02x\n", 2354 arch->vex.guest_R15T - 1, p[0], p[1]); 2355 } 2356 vg_assert(valid); 2357 // FIXME: NOTE, this really isn't right. We need to back up 2358 // ITSTATE to what it was before the SVC instruction, but we 2359 // don't know what it was. At least assert that it is now 2360 // zero, because if it is nonzero then it must also have 2361 // been nonzero for the SVC itself, which means it was 2362 // conditional. Urk. 2363 vg_assert(arch->vex.guest_ITSTATE == 0); 2364 } else { 2365 // ARM mode. SVC is encoded as 2366 // cond 1111 imm24 2367 // where imm24 is the SVC number, and we only accept 0. 2368 arch->vex.guest_R15T -= 4; // sizeof(arm instr) 2369 UChar* p = (UChar*)arch->vex.guest_R15T; 2370 Bool valid = p[0] == 0 && p[1] == 0 && p[2] == 0 2371 && (p[3] & 0xF) == 0xF; 2372 if (!valid) { 2373 VG_(message)(Vg_DebugMsg, 2374 "?! restarting over (ARM) syscall that is not syscall " 2375 "at %#x %02x %02x %02x %02x\n", 2376 arch->vex.guest_R15T, p[0], p[1], p[2], p[3]); 2377 } 2378 vg_assert(valid); 2379 } 2380 2381 #elif defined(VGP_arm64_linux) 2382 arch->vex.guest_PC -= 4; // sizeof(arm64 instr) 2383 2384 /* Make sure our caller is actually sane, and we're really backing 2385 back over a syscall. 2386 2387 svc #0 == d4 00 00 01 2388 */ 2389 { 2390 UChar *p = (UChar *)arch->vex.guest_PC; 2391 2392 if (p[0] != 0x01 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0xD4) 2393 VG_(message)( 2394 Vg_DebugMsg, 2395 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n", 2396 arch->vex.guest_PC, p[0], p[1], p[2], p[3] 2397 ); 2398 2399 vg_assert(p[0] == 0x01 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0xD4); 2400 } 2401 2402 #elif defined(VGP_x86_darwin) 2403 arch->vex.guest_EIP = arch->vex.guest_IP_AT_SYSCALL; 2404 2405 /* Make sure our caller is actually sane, and we're really backing 2406 back over a syscall. 2407 2408 int $0x80 == CD 80 // Used to communicate with BSD syscalls 2409 int $0x81 == CD 81 // Used to communicate with Mach traps 2410 int $0x82 == CD 82 // Used to communicate with "thread" ? 2411 sysenter == 0F 34 // Used to communicate with Unix syscalls 2412 */ 2413 { 2414 UChar *p = (UChar *)arch->vex.guest_EIP; 2415 Bool ok = (p[0] == 0xCD && p[1] == 0x80) 2416 || (p[0] == 0xCD && p[1] == 0x81) 2417 || (p[0] == 0xCD && p[1] == 0x82) 2418 || (p[0] == 0x0F && p[1] == 0x34); 2419 if (!ok) 2420 VG_(message)(Vg_DebugMsg, 2421 "?! restarting over syscall at %#x %02x %02x\n", 2422 arch->vex.guest_EIP, p[0], p[1]); 2423 vg_assert(ok); 2424 } 2425 2426 #elif defined(VGP_amd64_darwin) 2427 arch->vex.guest_RIP = arch->vex.guest_IP_AT_SYSCALL; 2428 2429 /* Make sure our caller is actually sane, and we're really backing 2430 back over a syscall. 2431 2432 syscall == 0F 05 2433 */ 2434 { 2435 UChar *p = (UChar *)arch->vex.guest_RIP; 2436 2437 Bool ok = (p[0] == 0x0F && p[1] == 0x05); 2438 if (!ok) 2439 VG_(message)(Vg_DebugMsg, 2440 "?! restarting over syscall at %#llx %02x %02x\n", 2441 arch->vex.guest_RIP, p[0], p[1]); 2442 vg_assert(ok); 2443 } 2444 2445 #elif defined(VGP_s390x_linux) 2446 arch->vex.guest_IA -= 2; // sizeof(syscall) 2447 2448 /* Make sure our caller is actually sane, and we're really backing 2449 back over a syscall. 2450 2451 syscall == 0A <num> 2452 */ 2453 { 2454 UChar *p = (UChar *)arch->vex.guest_IA; 2455 if (p[0] != 0x0A) 2456 VG_(message)(Vg_DebugMsg, 2457 "?! restarting over syscall at %#llx %02x %02x\n", 2458 arch->vex.guest_IA, p[0], p[1]); 2459 2460 vg_assert(p[0] == 0x0A); 2461 } 2462 2463 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux) 2464 2465 arch->vex.guest_PC -= 4; // sizeof(mips instr) 2466 2467 /* Make sure our caller is actually sane, and we're really backing 2468 back over a syscall. 2469 2470 syscall == 00 00 00 0C 2471 big endian 2472 syscall == 0C 00 00 00 2473 */ 2474 { 2475 UChar *p = (UChar *)(arch->vex.guest_PC); 2476 # if defined (VG_LITTLEENDIAN) 2477 if (p[0] != 0x0c || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x00) 2478 VG_(message)(Vg_DebugMsg, 2479 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n", 2480 (ULong)arch->vex.guest_PC, p[0], p[1], p[2], p[3]); 2481 2482 vg_assert(p[0] == 0x0c && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x00); 2483 # elif defined (VG_BIGENDIAN) 2484 if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x0c) 2485 VG_(message)(Vg_DebugMsg, 2486 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n", 2487 (ULong)arch->vex.guest_PC, p[0], p[1], p[2], p[3]); 2488 2489 vg_assert(p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x0c); 2490 # else 2491 # error "Unknown endianness" 2492 # endif 2493 } 2494 #elif defined(VGP_tilegx_linux) 2495 arch->vex.guest_pc -= 8; // sizeof({ swint1 }) 2496 2497 /* Make sure our caller is actually sane, and we're really backing 2498 back over a syscall. no other instruction in same bundle. 2499 */ 2500 { 2501 unsigned long *p = (unsigned long *)arch->vex.guest_pc; 2502 2503 if (p[0] != 0x286b180051485000ULL ) // "swint1", little enidan only 2504 VG_(message)(Vg_DebugMsg, 2505 "?! restarting over syscall at 0x%lx %lx\n", 2506 arch->vex.guest_pc, p[0]); 2507 vg_assert(p[0] == 0x286b180051485000ULL); 2508 } 2509 2510 #elif defined(VGP_x86_solaris) 2511 arch->vex.guest_EIP -= 2; // sizeof(int $0x91) or sizeof(syscall) 2512 2513 /* Make sure our caller is actually sane, and we're really backing 2514 back over a syscall. 2515 2516 int $0x91 == CD 91 2517 syscall == 0F 05 2518 sysenter == 0F 34 2519 2520 Handle also other syscall instructions because we also handle them in 2521 the scheduler. 2522 int $0x80 == CD 80 2523 int $0x81 == CD 81 2524 int $0x82 == CD 82 2525 */ 2526 { 2527 UChar *p = (UChar *)arch->vex.guest_EIP; 2528 2529 Bool ok = (p[0] == 0xCD && p[1] == 0x91) 2530 || (p[0] == 0x0F && p[1] == 0x05) 2531 || (p[0] == 0x0F && p[1] == 0x34) 2532 || (p[0] == 0xCD && p[1] == 0x80) 2533 || (p[0] == 0xCD && p[1] == 0x81) 2534 || (p[0] == 0xCD && p[1] == 0x82); 2535 if (!ok) 2536 VG_(message)(Vg_DebugMsg, 2537 "?! restarting over syscall at %#x %02x %02x\n", 2538 arch->vex.guest_EIP, p[0], p[1]); 2539 vg_assert(ok); 2540 } 2541 2542 #elif defined(VGP_amd64_solaris) 2543 arch->vex.guest_RIP -= 2; // sizeof(syscall) 2544 2545 /* Make sure our caller is actually sane, and we're really backing 2546 back over a syscall. 2547 2548 syscall == 0F 05 2549 */ 2550 { 2551 UChar *p = (UChar *)arch->vex.guest_RIP; 2552 2553 Bool ok = (p[0] == 0x0F && p[1] == 0x05); 2554 if (!ok) 2555 VG_(message)(Vg_DebugMsg, 2556 "?! restarting over syscall at %#llx %02x %02x\n", 2557 arch->vex.guest_RIP, p[0], p[1]); 2558 vg_assert(ok); 2559 } 2560 2561 #else 2562 # error "ML_(fixup_guest_state_to_restart_syscall): unknown plat" 2563 #endif 2564 } 2565 2566 2567 /* 2568 Fix up the guest state when a syscall is interrupted by a signal 2569 and so has been forced to return 'sysret'. 2570 2571 To do this, we determine the precise state of the syscall by 2572 looking at the (real) IP at the time the signal happened. The 2573 syscall sequence looks like: 2574 2575 1. unblock signals 2576 2. perform syscall 2577 3. save result to guest state (EAX, RAX, R3+CR0.SO, R0, V0) 2578 4. re-block signals 2579 2580 If a signal 2581 happens at Then Why? 2582 [1-2) restart nothing has happened (restart syscall) 2583 [2] restart syscall hasn't started, or kernel wants to restart 2584 [2-3) save syscall complete, but results not saved 2585 [3-4) syscall complete, results saved 2586 2587 Sometimes we never want to restart an interrupted syscall (because 2588 sigaction says not to), so we only restart if "restart" is True. 2589 2590 This will also call VG_(post_syscall) if the syscall has actually 2591 completed (either because it was interrupted, or because it 2592 actually finished). It will not call VG_(post_syscall) if the 2593 syscall is set up for restart, which means that the pre-wrapper may 2594 get called multiple times. 2595 */ 2596 2597 void 2598 VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid, 2599 Addr ip, 2600 SysRes sres, 2601 Bool restart, 2602 struct vki_ucontext *uc) 2603 { 2604 /* Note that we don't know the syscall number here, since (1) in 2605 general there's no reliable way to get hold of it short of 2606 stashing it in the guest state before the syscall, and (2) in 2607 any case we don't need to know it for the actions done by this 2608 routine. 2609 2610 Furthermore, 'sres' is only used in the case where the syscall 2611 is complete, but the result has not been committed to the guest 2612 state yet. In any other situation it will be meaningless and 2613 therefore ignored. */ 2614 2615 ThreadState* tst; 2616 SyscallStatus canonical; 2617 ThreadArchState* th_regs; 2618 SyscallInfo* sci; 2619 2620 /* Compute some Booleans indicating which range we're in. */ 2621 Bool outside_range, 2622 in_setup_to_restart, // [1,2) in the .S files 2623 at_restart, // [2] in the .S files 2624 in_complete_to_committed, // [3,4) in the .S files 2625 in_committed_to_finished; // [4,5) in the .S files 2626 2627 if (VG_(clo_trace_signals)) 2628 VG_(message)( Vg_DebugMsg, 2629 "interrupted_syscall: tid=%u, ip=%#lx, " 2630 "restart=%s, sres.isErr=%s, sres.val=%lu\n", 2631 tid, 2632 ip, 2633 restart ? "True" : "False", 2634 sr_isError(sres) ? "True" : "False", 2635 sr_isError(sres) ? sr_Err(sres) : sr_Res(sres)); 2636 2637 vg_assert(VG_(is_valid_tid)(tid)); 2638 vg_assert(tid >= 1 && tid < VG_N_THREADS); 2639 vg_assert(VG_(is_running_thread)(tid)); 2640 2641 tst = VG_(get_ThreadState)(tid); 2642 th_regs = &tst->arch; 2643 sci = & syscallInfo[tid]; 2644 2645 # if defined(VGO_linux) 2646 outside_range 2647 = ip < ML_(blksys_setup) || ip >= ML_(blksys_finished); 2648 in_setup_to_restart 2649 = ip >= ML_(blksys_setup) && ip < ML_(blksys_restart); 2650 at_restart 2651 = ip == ML_(blksys_restart); 2652 in_complete_to_committed 2653 = ip >= ML_(blksys_complete) && ip < ML_(blksys_committed); 2654 in_committed_to_finished 2655 = ip >= ML_(blksys_committed) && ip < ML_(blksys_finished); 2656 # elif defined(VGO_darwin) 2657 outside_range 2658 = (ip < ML_(blksys_setup_MACH) || ip >= ML_(blksys_finished_MACH)) 2659 && (ip < ML_(blksys_setup_MDEP) || ip >= ML_(blksys_finished_MDEP)) 2660 && (ip < ML_(blksys_setup_UNIX) || ip >= ML_(blksys_finished_UNIX)); 2661 in_setup_to_restart 2662 = (ip >= ML_(blksys_setup_MACH) && ip < ML_(blksys_restart_MACH)) 2663 || (ip >= ML_(blksys_setup_MDEP) && ip < ML_(blksys_restart_MDEP)) 2664 || (ip >= ML_(blksys_setup_UNIX) && ip < ML_(blksys_restart_UNIX)); 2665 at_restart 2666 = (ip == ML_(blksys_restart_MACH)) 2667 || (ip == ML_(blksys_restart_MDEP)) 2668 || (ip == ML_(blksys_restart_UNIX)); 2669 in_complete_to_committed 2670 = (ip >= ML_(blksys_complete_MACH) && ip < ML_(blksys_committed_MACH)) 2671 || (ip >= ML_(blksys_complete_MDEP) && ip < ML_(blksys_committed_MDEP)) 2672 || (ip >= ML_(blksys_complete_UNIX) && ip < ML_(blksys_committed_UNIX)); 2673 in_committed_to_finished 2674 = (ip >= ML_(blksys_committed_MACH) && ip < ML_(blksys_finished_MACH)) 2675 || (ip >= ML_(blksys_committed_MDEP) && ip < ML_(blksys_finished_MDEP)) 2676 || (ip >= ML_(blksys_committed_UNIX) && ip < ML_(blksys_finished_UNIX)); 2677 /* Wasn't that just So Much Fun? Does your head hurt yet? Mine does. */ 2678 # elif defined(VGO_solaris) 2679 /* The solaris port is never outside the range. */ 2680 outside_range = False; 2681 /* The Solaris kernel never restarts syscalls directly! */ 2682 at_restart = False; 2683 if (tst->os_state.in_door_return) { 2684 vg_assert(ip >= ML_(blksys_setup_DRET) 2685 && ip < ML_(blksys_finished_DRET)); 2686 2687 in_setup_to_restart 2688 = ip >= ML_(blksys_setup_DRET) && ip < ML_(blksys_complete_DRET); 2689 in_complete_to_committed 2690 = ip >= ML_(blksys_complete_DRET) && ip < ML_(blksys_committed_DRET); 2691 in_committed_to_finished 2692 = ip >= ML_(blksys_committed_DRET) && ip < ML_(blksys_finished_DRET); 2693 } 2694 else { 2695 vg_assert(ip >= ML_(blksys_setup) && ip < ML_(blksys_finished)); 2696 2697 in_setup_to_restart 2698 = ip >= ML_(blksys_setup) && ip < ML_(blksys_complete); 2699 in_complete_to_committed 2700 = ip >= ML_(blksys_complete) && ip < ML_(blksys_committed); 2701 in_committed_to_finished 2702 = ip >= ML_(blksys_committed) && ip < ML_(blksys_finished); 2703 } 2704 # else 2705 # error "Unknown OS" 2706 # endif 2707 2708 /* Figure out what the state of the syscall was by examining the 2709 (real) IP at the time of the signal, and act accordingly. */ 2710 if (outside_range) { 2711 if (VG_(clo_trace_signals)) 2712 VG_(message)( Vg_DebugMsg, 2713 " not in syscall at all: hmm, very suspicious\n" ); 2714 /* Looks like we weren't in a syscall at all. Hmm. */ 2715 vg_assert(sci->status.what != SsIdle); 2716 return; 2717 } 2718 2719 /* We should not be here unless this thread had first started up 2720 the machinery for a syscall by calling VG_(client_syscall). 2721 Hence: */ 2722 vg_assert(sci->status.what != SsIdle); 2723 2724 /* now, do one of four fixup actions, depending on where the IP has 2725 got to. */ 2726 2727 if (in_setup_to_restart) { 2728 /* syscall hasn't even started; go around again */ 2729 if (VG_(clo_trace_signals)) 2730 VG_(message)( Vg_DebugMsg, " not started: restarting\n"); 2731 vg_assert(sci->status.what == SsHandToKernel); 2732 ML_(fixup_guest_state_to_restart_syscall)(th_regs); 2733 } 2734 2735 else 2736 if (at_restart) { 2737 # if defined(VGO_solaris) 2738 /* We should never hit this branch on Solaris, see the comment above. */ 2739 vg_assert(0); 2740 # endif 2741 2742 /* We're either about to run the syscall, or it was interrupted 2743 and the kernel restarted it. Restart if asked, otherwise 2744 EINTR it. */ 2745 if (restart) { 2746 if (VG_(clo_trace_signals)) 2747 VG_(message)( Vg_DebugMsg, " at syscall instr: restarting\n"); 2748 ML_(fixup_guest_state_to_restart_syscall)(th_regs); 2749 } else { 2750 if (VG_(clo_trace_signals)) 2751 VG_(message)( Vg_DebugMsg, " at syscall instr: returning EINTR\n"); 2752 canonical = convert_SysRes_to_SyscallStatus( 2753 VG_(mk_SysRes_Error)( VKI_EINTR ) 2754 ); 2755 if (!(sci->flags & SfNoWriteResult)) 2756 putSyscallStatusIntoGuestState( tid, &canonical, &th_regs->vex ); 2757 sci->status = canonical; 2758 VG_(post_syscall)(tid); 2759 } 2760 } 2761 2762 else 2763 if (in_complete_to_committed) { 2764 /* Syscall complete, but result hasn't been written back yet. 2765 Write the SysRes we were supplied with back to the guest 2766 state. */ 2767 if (VG_(clo_trace_signals)) 2768 VG_(message)( Vg_DebugMsg, 2769 " completed, but uncommitted: committing\n"); 2770 canonical = convert_SysRes_to_SyscallStatus( sres ); 2771 vg_assert(!(sci->flags & SfNoWriteResult)); 2772 putSyscallStatusIntoGuestState( tid, &canonical, &th_regs->vex ); 2773 # if defined(VGO_solaris) 2774 if (tst->os_state.in_door_return) { 2775 # if defined(VGP_x86_solaris) 2776 /* Registers %esp and %ebp were also modified by the syscall. */ 2777 tst->arch.vex.guest_ESP = uc->uc_mcontext.gregs[VKI_UESP]; 2778 tst->arch.vex.guest_EBP = uc->uc_mcontext.gregs[VKI_EBP]; 2779 # elif defined(VGP_amd64_solaris) 2780 tst->arch.vex.guest_RSP = uc->uc_mcontext.gregs[VKI_REG_RSP]; 2781 tst->arch.vex.guest_RBP = uc->uc_mcontext.gregs[VKI_REG_RBP]; 2782 # endif 2783 } 2784 # endif 2785 sci->status = canonical; 2786 VG_(post_syscall)(tid); 2787 } 2788 2789 else 2790 if (in_committed_to_finished) { 2791 /* Result committed, but the signal mask has not been restored; 2792 we expect our caller (the signal handler) will have fixed 2793 this up. */ 2794 if (VG_(clo_trace_signals)) 2795 VG_(message)( Vg_DebugMsg, 2796 " completed and committed: nothing to do\n"); 2797 # if defined(VGP_x86_solaris) 2798 /* The %eax and %edx values are committed but the carry flag is still 2799 uncommitted. Save it now. */ 2800 LibVEX_GuestX86_put_eflag_c(sr_isError(sres), &th_regs->vex); 2801 # elif defined(VGP_amd64_solaris) 2802 LibVEX_GuestAMD64_put_rflag_c(sr_isError(sres), &th_regs->vex); 2803 # endif 2804 getSyscallStatusFromGuestState( &sci->status, &th_regs->vex ); 2805 vg_assert(sci->status.what == SsComplete); 2806 VG_(post_syscall)(tid); 2807 } 2808 2809 else 2810 VG_(core_panic)("?? strange syscall interrupt state?"); 2811 2812 /* In all cases, the syscall is now finished (even if we called 2813 ML_(fixup_guest_state_to_restart_syscall), since that just 2814 re-positions the guest's IP for another go at it). So we need 2815 to record that fact. */ 2816 sci->status.what = SsIdle; 2817 } 2818 2819 2820 #if defined(VGO_solaris) 2821 /* Returns True if ip is inside a fixable syscall code in syscall-*-*.S. This 2822 function can be called by a 'non-running' thread! */ 2823 Bool VG_(is_ip_in_blocking_syscall)(ThreadId tid, Addr ip) 2824 { 2825 ThreadState *tst = VG_(get_ThreadState)(tid); 2826 2827 if (tst->os_state.in_door_return) 2828 return ip >= ML_(blksys_setup_DRET) && ip < ML_(blksys_finished_DRET); 2829 else 2830 return ip >= ML_(blksys_setup) && ip < ML_(blksys_finished); 2831 } 2832 #endif 2833 2834 2835 #if defined(VGO_darwin) 2836 // Clean up after workq_ops(WQOPS_THREAD_RETURN) jumped to wqthread_hijack. 2837 // This is similar to VG_(fixup_guest_state_after_syscall_interrupted). 2838 // This longjmps back to the scheduler. 2839 void ML_(wqthread_continue_NORETURN)(ThreadId tid) 2840 { 2841 ThreadState* tst; 2842 SyscallInfo* sci; 2843 2844 VG_(acquire_BigLock)(tid, "wqthread_continue_NORETURN"); 2845 2846 PRINT("SYSCALL[%d,%u](%s) workq_ops() starting new workqueue item\n", 2847 VG_(getpid)(), tid, VG_SYSNUM_STRING(__NR_workq_ops)); 2848 2849 vg_assert(VG_(is_valid_tid)(tid)); 2850 vg_assert(tid >= 1 && tid < VG_N_THREADS); 2851 vg_assert(VG_(is_running_thread)(tid)); 2852 2853 tst = VG_(get_ThreadState)(tid); 2854 sci = & syscallInfo[tid]; 2855 vg_assert(sci->status.what != SsIdle); 2856 vg_assert(tst->os_state.wq_jmpbuf_valid); // check this BEFORE post_syscall 2857 2858 // Pretend the syscall completed normally, but don't touch the thread state. 2859 sci->status = convert_SysRes_to_SyscallStatus( VG_(mk_SysRes_Success)(0) ); 2860 sci->flags |= SfNoWriteResult; 2861 VG_(post_syscall)(tid); 2862 2863 ML_(sync_mappings)("in", "ML_(wqthread_continue_NORETURN)", 0); 2864 2865 sci->status.what = SsIdle; 2866 2867 vg_assert(tst->sched_jmpbuf_valid); 2868 VG_MINIMAL_LONGJMP(tst->sched_jmpbuf); 2869 2870 /* NOTREACHED */ 2871 vg_assert(0); 2872 } 2873 #endif 2874 2875 2876 /* --------------------------------------------------------------------- 2877 A place to store the where-to-call-when-really-done pointer 2878 ------------------------------------------------------------------ */ 2879 2880 // When the final thread is done, where shall I call to shutdown the 2881 // system cleanly? Is set once at startup (in m_main) and never 2882 // changes after that. Is basically a pointer to the exit 2883 // continuation. This is all just a nasty hack to avoid calling 2884 // directly from m_syswrap to m_main at exit, since that would cause 2885 // m_main to become part of a module cycle, which is silly. 2886 void (* VG_(address_of_m_main_shutdown_actions_NORETURN) ) 2887 (ThreadId,VgSchedReturnCode) 2888 = NULL; 2889 2890 /*--------------------------------------------------------------------*/ 2891 /*--- end ---*/ 2892 /*--------------------------------------------------------------------*/ 2893