2 /*--------------------------------------------------------------------*/
3 /*--- Handle system calls. syswrap-main.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2013 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
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_libcsetjmp.h" // to keep _threadstate.h happy
38 #include "pub_core_threadstate.h"
39 #include "pub_core_libcbase.h"
40 #include "pub_core_libcassert.h"
41 #include "pub_core_libcprint.h"
42 #include "pub_core_libcproc.h" // For VG_(getpid)()
43 #include "pub_core_libcsignal.h"
44 #include "pub_core_scheduler.h" // For VG_({acquire,release}_BigLock),
46 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
47 #include "pub_core_tooliface.h"
48 #include "pub_core_options.h"
49 #include "pub_core_signals.h" // For VG_SIGVGKILL, VG_(poll_signals)
50 #include "pub_core_syscall.h"
51 #include "pub_core_machine.h"
52 #include "pub_core_syswrap.h"
54 #include "priv_types_n_macros.h"
55 #include "priv_syswrap-main.h"
57 #if defined(VGO_darwin)
58 #include "priv_syswrap-darwin.h"
61 /* Useful info which needs to be recorded somewhere:
62 Use of registers in syscalls is:
64 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
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??)
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)
83 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
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
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".
94 /* This is the top level of the system-call handler module. All
95 system calls are channelled through here, doing two things:
97 * notify the tool of the events (mem/reg reads, writes) happening
99 * perform the syscall, usually by passing it along to the kernel
102 A magical piece of assembly code, do_syscall_for_client_WRK, in
103 syscall-$PLATFORM.S does the tricky bit of passing a syscall to the
104 kernel, whilst having the simulator retain control.
107 /* The main function is VG_(client_syscall). The simulation calls it
108 whenever a client thread wants to do a syscall. The following is a
109 sketch of what it does.
111 * Ensures the root thread's stack is suitably mapped. Tedious and
112 arcane. See big big comment in VG_(client_syscall).
114 * First, it rounds up the syscall number and args (which is a
115 platform dependent activity) and puts them in a struct ("args")
116 and also a copy in "orig_args".
118 The pre/post wrappers refer to these structs and so no longer
119 need magic macros to access any specific registers. This struct
120 is stored in thread-specific storage.
123 * The pre-wrapper is called, passing it a pointer to struct
127 * The pre-wrapper examines the args and pokes the tool
128 appropriately. It may modify the args; this is why "orig_args"
131 The pre-wrapper may choose to 'do' the syscall itself, and
132 concludes one of three outcomes:
134 Success(N) -- syscall is already complete, with success;
137 Fail(N) -- syscall is already complete, with failure;
140 HandToKernel -- (the usual case): this needs to be given to
141 the kernel to be done, using the values in
142 the possibly-modified "args" struct.
144 In addition, the pre-wrapper may set some flags:
146 MayBlock -- only applicable when outcome==HandToKernel
148 PostOnFail -- only applicable when outcome==HandToKernel or Fail
151 * If the pre-outcome is HandToKernel, the syscall is duly handed
152 off to the kernel (perhaps involving some thread switchery, but
153 that's not important). This reduces the possible set of outcomes
154 to either Success(N) or Fail(N).
157 * The outcome (Success(N) or Fail(N)) is written back to the guest
158 register(s). This is platform specific:
160 x86: Success(N) ==> eax = N
165 ppc32: Success(N) ==> r3 = N, CR0.SO = 0
166 Fail(N) ==> r3 = N, CR0.SO = 1
169 x86: Success(N) ==> edx:eax = N, cc = 0
170 Fail(N) ==> edx:eax = N, cc = 1
172 s390x: Success(N) ==> r2 = N
175 * The post wrapper is called if:
178 - outcome==Success or (outcome==Fail and PostOnFail is set)
180 The post wrapper is passed the adulterated syscall args (struct
181 "args"), and the syscall outcome (viz, Success(N) or Fail(N)).
183 There are several other complications, primarily to do with
184 syscalls getting interrupted, explained in comments in the code.
187 /* CAVEATS for writing wrappers. It is important to follow these!
189 The macros defined in priv_types_n_macros.h are designed to help
190 decouple the wrapper logic from the actual representation of
191 syscall args/results, since these wrappers are designed to work on
194 Sometimes a PRE wrapper will complete the syscall itself, without
195 handing it to the kernel. It will use one of SET_STATUS_Success,
196 SET_STATUS_Failure or SET_STATUS_from_SysRes to set the return
197 value. It is critical to appreciate that use of the macro does not
198 immediately cause the underlying guest state to be updated -- that
199 is done by the driver logic in this file, when the wrapper returns.
201 As a result, PRE wrappers of the following form will malfunction:
206 SET_STATUS_Somehow(...)
208 // do something that assumes guest state is up to date
211 In particular, direct or indirect calls to VG_(poll_signals) after
212 setting STATUS can cause the guest state to be read (in order to
213 build signal frames). Do not do this. If you want a signal poll
214 after the syscall goes through, do "*flags |= SfPollAfter" and the
215 driver logic will do it for you.
219 Another critical requirement following introduction of new address
220 space manager (JRS, 20050923):
222 In a situation where the mappedness of memory has changed, aspacem
223 should be notified BEFORE the tool. Hence the following is
226 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
227 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
229 VG_(discard_translations)(s->start, s->end+1 - s->start);
231 whilst this is wrong:
233 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
234 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
236 VG_(discard_translations)(s->start, s->end+1 - s->start);
238 The reason is that the tool may itself ask aspacem for more shadow
239 memory as a result of the VG_TRACK call. In such a situation it is
240 critical that aspacem's segment array is up to date -- hence the
241 need to notify aspacem first.
245 Also .. take care to call VG_(discard_translations) whenever
246 memory with execute permissions is unmapped.
250 /* ---------------------------------------------------------------------
251 Do potentially blocking syscall for the client, and mess with
252 signal masks at the same time.
253 ------------------------------------------------------------------ */
255 /* Perform a syscall on behalf of a client thread, using a specific
256 signal mask. On completion, the signal mask is set to restore_mask
257 (which presumably blocks almost everything). If a signal happens
258 during the syscall, the handler should call
259 VG_(fixup_guest_state_after_syscall_interrupted) to adjust the
260 thread's context to do the right thing.
262 The _WRK function is handwritten assembly, implemented per-platform
263 in coregrind/m_syswrap/syscall-$PLAT.S. It has some very magic
264 properties. See comments at the top of
265 VG_(fixup_guest_state_after_syscall_interrupted) below for details.
267 This function (these functions) are required to return zero in case
268 of success (even if the syscall itself failed), and nonzero if the
269 sigprocmask-swizzling calls failed. We don't actually care about
270 the failure values from sigprocmask, although most of the assembly
271 implementations do attempt to return that, using the convention
272 0 for success, or 0x8000 | error-code for failure.
274 #if defined(VGO_linux)
276 UWord
ML_(do_syscall_for_client_WRK
)( Word syscallno
,
278 const vki_sigset_t
*syscall_mask
,
279 const vki_sigset_t
*restore_mask
,
281 #elif defined(VGO_darwin)
283 UWord
ML_(do_syscall_for_client_unix_WRK
)( Word syscallno
,
285 const vki_sigset_t
*syscall_mask
,
286 const vki_sigset_t
*restore_mask
,
287 Word sigsetSzB
); /* unused */
289 UWord
ML_(do_syscall_for_client_mach_WRK
)( Word syscallno
,
291 const vki_sigset_t
*syscall_mask
,
292 const vki_sigset_t
*restore_mask
,
293 Word sigsetSzB
); /* unused */
295 UWord
ML_(do_syscall_for_client_mdep_WRK
)( Word syscallno
,
297 const vki_sigset_t
*syscall_mask
,
298 const vki_sigset_t
*restore_mask
,
299 Word sigsetSzB
); /* unused */
306 void do_syscall_for_client ( Int syscallno
,
308 const vki_sigset_t
* syscall_mask
)
312 # if defined(VGO_linux)
313 err
= ML_(do_syscall_for_client_WRK
)(
314 syscallno
, &tst
->arch
.vex
,
315 syscall_mask
, &saved
, sizeof(vki_sigset_t
)
317 # elif defined(VGO_darwin)
318 switch (VG_DARWIN_SYSNO_CLASS(syscallno
)) {
319 case VG_DARWIN_SYSCALL_CLASS_UNIX
:
320 err
= ML_(do_syscall_for_client_unix_WRK
)(
321 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno
), &tst
->arch
.vex
,
322 syscall_mask
, &saved
, 0/*unused:sigsetSzB*/
325 case VG_DARWIN_SYSCALL_CLASS_MACH
:
326 err
= ML_(do_syscall_for_client_mach_WRK
)(
327 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno
), &tst
->arch
.vex
,
328 syscall_mask
, &saved
, 0/*unused:sigsetSzB*/
331 case VG_DARWIN_SYSCALL_CLASS_MDEP
:
332 err
= ML_(do_syscall_for_client_mdep_WRK
)(
333 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno
), &tst
->arch
.vex
,
334 syscall_mask
, &saved
, 0/*unused:sigsetSzB*/
347 "ML_(do_syscall_for_client_WRK): sigprocmask error %d",
353 /* ---------------------------------------------------------------------
354 Impedance matchers and misc helpers
355 ------------------------------------------------------------------ */
358 Bool
eq_SyscallArgs ( SyscallArgs
* a1
, SyscallArgs
* a2
)
360 return a1
->sysno
== a2
->sysno
361 && a1
->arg1
== a2
->arg1
362 && a1
->arg2
== a2
->arg2
363 && a1
->arg3
== a2
->arg3
364 && a1
->arg4
== a2
->arg4
365 && a1
->arg5
== a2
->arg5
366 && a1
->arg6
== a2
->arg6
367 && a1
->arg7
== a2
->arg7
368 && a1
->arg8
== a2
->arg8
;
372 Bool
eq_SyscallStatus ( SyscallStatus
* s1
, SyscallStatus
* s2
)
374 /* was: return s1->what == s2->what && sr_EQ( s1->sres, s2->sres ); */
375 if (s1
->what
== s2
->what
&& sr_EQ( s1
->sres
, s2
->sres
))
377 # if defined(VGO_darwin)
378 /* Darwin-specific debugging guff */
379 vg_assert(s1
->what
== s2
->what
);
380 VG_(printf
)("eq_SyscallStatus:\n");
381 VG_(printf
)(" {%lu %lu %u}\n", s1
->sres
._wLO
, s1
->sres
._wHI
, s1
->sres
._mode
);
382 VG_(printf
)(" {%lu %lu %u}\n", s2
->sres
._wLO
, s2
->sres
._wHI
, s2
->sres
._mode
);
388 /* Convert between SysRes and SyscallStatus, to the extent possible. */
391 SyscallStatus
convert_SysRes_to_SyscallStatus ( SysRes res
)
393 SyscallStatus status
;
394 status
.what
= SsComplete
;
400 /* Impedance matchers. These convert syscall arg or result data from
401 the platform-specific in-guest-state format to the canonical
402 formats, and back. */
405 void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs
* canonical
,
406 /*IN*/ VexGuestArchState
* gst_vanilla
,
409 #if defined(VGP_x86_linux)
410 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
411 canonical
->sysno
= gst
->guest_EAX
;
412 canonical
->arg1
= gst
->guest_EBX
;
413 canonical
->arg2
= gst
->guest_ECX
;
414 canonical
->arg3
= gst
->guest_EDX
;
415 canonical
->arg4
= gst
->guest_ESI
;
416 canonical
->arg5
= gst
->guest_EDI
;
417 canonical
->arg6
= gst
->guest_EBP
;
421 #elif defined(VGP_amd64_linux)
422 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
423 canonical
->sysno
= gst
->guest_RAX
;
424 canonical
->arg1
= gst
->guest_RDI
;
425 canonical
->arg2
= gst
->guest_RSI
;
426 canonical
->arg3
= gst
->guest_RDX
;
427 canonical
->arg4
= gst
->guest_R10
;
428 canonical
->arg5
= gst
->guest_R8
;
429 canonical
->arg6
= gst
->guest_R9
;
433 #elif defined(VGP_ppc32_linux)
434 VexGuestPPC32State
* gst
= (VexGuestPPC32State
*)gst_vanilla
;
435 canonical
->sysno
= gst
->guest_GPR0
;
436 canonical
->arg1
= gst
->guest_GPR3
;
437 canonical
->arg2
= gst
->guest_GPR4
;
438 canonical
->arg3
= gst
->guest_GPR5
;
439 canonical
->arg4
= gst
->guest_GPR6
;
440 canonical
->arg5
= gst
->guest_GPR7
;
441 canonical
->arg6
= gst
->guest_GPR8
;
445 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
446 VexGuestPPC64State
* gst
= (VexGuestPPC64State
*)gst_vanilla
;
447 canonical
->sysno
= gst
->guest_GPR0
;
448 canonical
->arg1
= gst
->guest_GPR3
;
449 canonical
->arg2
= gst
->guest_GPR4
;
450 canonical
->arg3
= gst
->guest_GPR5
;
451 canonical
->arg4
= gst
->guest_GPR6
;
452 canonical
->arg5
= gst
->guest_GPR7
;
453 canonical
->arg6
= gst
->guest_GPR8
;
457 #elif defined(VGP_arm_linux)
458 VexGuestARMState
* gst
= (VexGuestARMState
*)gst_vanilla
;
459 canonical
->sysno
= gst
->guest_R7
;
460 canonical
->arg1
= gst
->guest_R0
;
461 canonical
->arg2
= gst
->guest_R1
;
462 canonical
->arg3
= gst
->guest_R2
;
463 canonical
->arg4
= gst
->guest_R3
;
464 canonical
->arg5
= gst
->guest_R4
;
465 canonical
->arg6
= gst
->guest_R5
;
469 #elif defined(VGP_arm64_linux)
470 VexGuestARM64State
* gst
= (VexGuestARM64State
*)gst_vanilla
;
471 canonical
->sysno
= gst
->guest_X8
;
472 canonical
->arg1
= gst
->guest_X0
;
473 canonical
->arg2
= gst
->guest_X1
;
474 canonical
->arg3
= gst
->guest_X2
;
475 canonical
->arg4
= gst
->guest_X3
;
476 canonical
->arg5
= gst
->guest_X4
;
477 canonical
->arg6
= gst
->guest_X5
;
481 #elif defined(VGP_mips32_linux)
482 VexGuestMIPS32State
* gst
= (VexGuestMIPS32State
*)gst_vanilla
;
483 canonical
->sysno
= gst
->guest_r2
; // v0
484 if (canonical
->sysno
== __NR_exit
) {
485 canonical
->arg1
= gst
->guest_r4
; // a0
492 } else if (canonical
->sysno
!= __NR_syscall
) {
493 canonical
->arg1
= gst
->guest_r4
; // a0
494 canonical
->arg2
= gst
->guest_r5
; // a1
495 canonical
->arg3
= gst
->guest_r6
; // a2
496 canonical
->arg4
= gst
->guest_r7
; // a3
497 canonical
->arg5
= *((UInt
*) (gst
->guest_r29
+ 16)); // 16(guest_SP/sp)
498 canonical
->arg6
= *((UInt
*) (gst
->guest_r29
+ 20)); // 20(sp)
501 // Fixme hack handle syscall()
502 canonical
->sysno
= gst
->guest_r4
; // a0
503 canonical
->arg1
= gst
->guest_r5
; // a1
504 canonical
->arg2
= gst
->guest_r6
; // a2
505 canonical
->arg3
= gst
->guest_r7
; // a3
506 canonical
->arg4
= *((UInt
*) (gst
->guest_r29
+ 16)); // 16(guest_SP/sp)
507 canonical
->arg5
= *((UInt
*) (gst
->guest_r29
+ 20)); // 20(guest_SP/sp)
508 canonical
->arg6
= *((UInt
*) (gst
->guest_r29
+ 24)); // 24(guest_SP/sp)
509 canonical
->arg8
= __NR_syscall
;
512 #elif defined(VGP_mips64_linux)
513 VexGuestMIPS64State
* gst
= (VexGuestMIPS64State
*)gst_vanilla
;
514 canonical
->sysno
= gst
->guest_r2
; // v0
515 canonical
->arg1
= gst
->guest_r4
; // a0
516 canonical
->arg2
= gst
->guest_r5
; // a1
517 canonical
->arg3
= gst
->guest_r6
; // a2
518 canonical
->arg4
= gst
->guest_r7
; // a3
519 canonical
->arg5
= gst
->guest_r8
; // a4
520 canonical
->arg6
= gst
->guest_r9
; // a5
522 #elif defined(VGP_x86_darwin)
523 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
524 UWord
*stack
= (UWord
*)gst
->guest_ESP
;
525 // GrP fixme hope syscalls aren't called with really shallow stacks...
526 canonical
->sysno
= gst
->guest_EAX
;
527 if (canonical
->sysno
!= 0) {
528 // stack[0] is return address
529 canonical
->arg1
= stack
[1];
530 canonical
->arg2
= stack
[2];
531 canonical
->arg3
= stack
[3];
532 canonical
->arg4
= stack
[4];
533 canonical
->arg5
= stack
[5];
534 canonical
->arg6
= stack
[6];
535 canonical
->arg7
= stack
[7];
536 canonical
->arg8
= stack
[8];
538 // GrP fixme hack handle syscall()
539 // GrP fixme what about __syscall() ?
540 // stack[0] is return address
541 // DDD: the tool can't see that the params have been shifted! Can
542 // lead to incorrect checking, I think, because the PRRAn/PSARn
543 // macros will mention the pre-shifted args.
544 canonical
->sysno
= stack
[1];
545 vg_assert(canonical
->sysno
!= 0);
546 canonical
->arg1
= stack
[2];
547 canonical
->arg2
= stack
[3];
548 canonical
->arg3
= stack
[4];
549 canonical
->arg4
= stack
[5];
550 canonical
->arg5
= stack
[6];
551 canonical
->arg6
= stack
[7];
552 canonical
->arg7
= stack
[8];
553 canonical
->arg8
= stack
[9];
555 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
556 VG_(getpid
)(), /*tid,*/
557 VG_SYSNUM_STRING(canonical
->sysno
));
560 // Here we determine what kind of syscall it was by looking at the
561 // interrupt kind, and then encode the syscall number using the 64-bit
562 // encoding for Valgrind's internal use.
564 // DDD: Would it be better to stash the JMP kind into the Darwin
565 // thread state rather than passing in the trc?
567 case VEX_TRC_JMP_SYS_INT128
:
568 // int $0x80 = Unix, 64-bit result
569 vg_assert(canonical
->sysno
>= 0);
570 canonical
->sysno
= VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical
->sysno
);
572 case VEX_TRC_JMP_SYS_SYSENTER
:
573 // syscall = Unix, 32-bit result
574 // OR Mach, 32-bit result
575 if (canonical
->sysno
>= 0) {
576 // GrP fixme hack: 0xffff == I386_SYSCALL_NUMBER_MASK
577 canonical
->sysno
= VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical
->sysno
580 canonical
->sysno
= VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical
->sysno
);
583 case VEX_TRC_JMP_SYS_INT129
:
584 // int $0x81 = Mach, 32-bit result
585 vg_assert(canonical
->sysno
< 0);
586 canonical
->sysno
= VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical
->sysno
);
588 case VEX_TRC_JMP_SYS_INT130
:
589 // int $0x82 = mdep, 32-bit result
590 vg_assert(canonical
->sysno
>= 0);
591 canonical
->sysno
= VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical
->sysno
);
598 #elif defined(VGP_amd64_darwin)
599 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
600 UWord
*stack
= (UWord
*)gst
->guest_RSP
;
602 vg_assert(trc
== VEX_TRC_JMP_SYS_SYSCALL
);
604 // GrP fixme hope syscalls aren't called with really shallow stacks...
605 canonical
->sysno
= gst
->guest_RAX
;
606 if (canonical
->sysno
!= __NR_syscall
) {
607 // stack[0] is return address
608 canonical
->arg1
= gst
->guest_RDI
;
609 canonical
->arg2
= gst
->guest_RSI
;
610 canonical
->arg3
= gst
->guest_RDX
;
611 canonical
->arg4
= gst
->guest_R10
; // not rcx with syscall insn
612 canonical
->arg5
= gst
->guest_R8
;
613 canonical
->arg6
= gst
->guest_R9
;
614 canonical
->arg7
= stack
[1];
615 canonical
->arg8
= stack
[2];
617 // GrP fixme hack handle syscall()
618 // GrP fixme what about __syscall() ?
619 // stack[0] is return address
620 // DDD: the tool can't see that the params have been shifted! Can
621 // lead to incorrect checking, I think, because the PRRAn/PSARn
622 // macros will mention the pre-shifted args.
623 canonical
->sysno
= VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst
->guest_RDI
);
624 vg_assert(canonical
->sysno
!= __NR_syscall
);
625 canonical
->arg1
= gst
->guest_RSI
;
626 canonical
->arg2
= gst
->guest_RDX
;
627 canonical
->arg3
= gst
->guest_R10
; // not rcx with syscall insn
628 canonical
->arg4
= gst
->guest_R8
;
629 canonical
->arg5
= gst
->guest_R9
;
630 canonical
->arg6
= stack
[1];
631 canonical
->arg7
= stack
[2];
632 canonical
->arg8
= stack
[3];
634 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
635 VG_(getpid
)(), /*tid,*/
636 VG_SYSNUM_STRING(canonical
->sysno
));
639 // no canonical->sysno adjustment needed
641 #elif defined(VGP_s390x_linux)
642 VexGuestS390XState
* gst
= (VexGuestS390XState
*)gst_vanilla
;
643 canonical
->sysno
= gst
->guest_SYSNO
;
644 canonical
->arg1
= gst
->guest_r2
;
645 canonical
->arg2
= gst
->guest_r3
;
646 canonical
->arg3
= gst
->guest_r4
;
647 canonical
->arg4
= gst
->guest_r5
;
648 canonical
->arg5
= gst
->guest_r6
;
649 canonical
->arg6
= gst
->guest_r7
;
653 # error "getSyscallArgsFromGuestState: unknown arch"
658 void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs
* canonical
,
659 /*OUT*/VexGuestArchState
* gst_vanilla
)
661 #if defined(VGP_x86_linux)
662 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
663 gst
->guest_EAX
= canonical
->sysno
;
664 gst
->guest_EBX
= canonical
->arg1
;
665 gst
->guest_ECX
= canonical
->arg2
;
666 gst
->guest_EDX
= canonical
->arg3
;
667 gst
->guest_ESI
= canonical
->arg4
;
668 gst
->guest_EDI
= canonical
->arg5
;
669 gst
->guest_EBP
= canonical
->arg6
;
671 #elif defined(VGP_amd64_linux)
672 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
673 gst
->guest_RAX
= canonical
->sysno
;
674 gst
->guest_RDI
= canonical
->arg1
;
675 gst
->guest_RSI
= canonical
->arg2
;
676 gst
->guest_RDX
= canonical
->arg3
;
677 gst
->guest_R10
= canonical
->arg4
;
678 gst
->guest_R8
= canonical
->arg5
;
679 gst
->guest_R9
= canonical
->arg6
;
681 #elif defined(VGP_ppc32_linux)
682 VexGuestPPC32State
* gst
= (VexGuestPPC32State
*)gst_vanilla
;
683 gst
->guest_GPR0
= canonical
->sysno
;
684 gst
->guest_GPR3
= canonical
->arg1
;
685 gst
->guest_GPR4
= canonical
->arg2
;
686 gst
->guest_GPR5
= canonical
->arg3
;
687 gst
->guest_GPR6
= canonical
->arg4
;
688 gst
->guest_GPR7
= canonical
->arg5
;
689 gst
->guest_GPR8
= canonical
->arg6
;
691 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
692 VexGuestPPC64State
* gst
= (VexGuestPPC64State
*)gst_vanilla
;
693 gst
->guest_GPR0
= canonical
->sysno
;
694 gst
->guest_GPR3
= canonical
->arg1
;
695 gst
->guest_GPR4
= canonical
->arg2
;
696 gst
->guest_GPR5
= canonical
->arg3
;
697 gst
->guest_GPR6
= canonical
->arg4
;
698 gst
->guest_GPR7
= canonical
->arg5
;
699 gst
->guest_GPR8
= canonical
->arg6
;
701 #elif defined(VGP_arm_linux)
702 VexGuestARMState
* gst
= (VexGuestARMState
*)gst_vanilla
;
703 gst
->guest_R7
= canonical
->sysno
;
704 gst
->guest_R0
= canonical
->arg1
;
705 gst
->guest_R1
= canonical
->arg2
;
706 gst
->guest_R2
= canonical
->arg3
;
707 gst
->guest_R3
= canonical
->arg4
;
708 gst
->guest_R4
= canonical
->arg5
;
709 gst
->guest_R5
= canonical
->arg6
;
711 #elif defined(VGP_arm64_linux)
712 VexGuestARM64State
* gst
= (VexGuestARM64State
*)gst_vanilla
;
713 gst
->guest_X8
= canonical
->sysno
;
714 gst
->guest_X0
= canonical
->arg1
;
715 gst
->guest_X1
= canonical
->arg2
;
716 gst
->guest_X2
= canonical
->arg3
;
717 gst
->guest_X3
= canonical
->arg4
;
718 gst
->guest_X4
= canonical
->arg5
;
719 gst
->guest_X5
= canonical
->arg6
;
721 #elif defined(VGP_x86_darwin)
722 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
723 UWord
*stack
= (UWord
*)gst
->guest_ESP
;
725 gst
->guest_EAX
= VG_DARWIN_SYSNO_FOR_KERNEL(canonical
->sysno
);
727 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
728 // stack[0] is return address
729 stack
[1] = canonical
->arg1
;
730 stack
[2] = canonical
->arg2
;
731 stack
[3] = canonical
->arg3
;
732 stack
[4] = canonical
->arg4
;
733 stack
[5] = canonical
->arg5
;
734 stack
[6] = canonical
->arg6
;
735 stack
[7] = canonical
->arg7
;
736 stack
[8] = canonical
->arg8
;
738 #elif defined(VGP_amd64_darwin)
739 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
740 UWord
*stack
= (UWord
*)gst
->guest_RSP
;
742 gst
->guest_RAX
= VG_DARWIN_SYSNO_FOR_KERNEL(canonical
->sysno
);
743 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
745 // stack[0] is return address
746 gst
->guest_RDI
= canonical
->arg1
;
747 gst
->guest_RSI
= canonical
->arg2
;
748 gst
->guest_RDX
= canonical
->arg3
;
749 gst
->guest_RCX
= canonical
->arg4
;
750 gst
->guest_R8
= canonical
->arg5
;
751 gst
->guest_R9
= canonical
->arg6
;
752 stack
[1] = canonical
->arg7
;
753 stack
[2] = canonical
->arg8
;
755 #elif defined(VGP_s390x_linux)
756 VexGuestS390XState
* gst
= (VexGuestS390XState
*)gst_vanilla
;
757 gst
->guest_SYSNO
= canonical
->sysno
;
758 gst
->guest_r2
= canonical
->arg1
;
759 gst
->guest_r3
= canonical
->arg2
;
760 gst
->guest_r4
= canonical
->arg3
;
761 gst
->guest_r5
= canonical
->arg4
;
762 gst
->guest_r6
= canonical
->arg5
;
763 gst
->guest_r7
= canonical
->arg6
;
765 #elif defined(VGP_mips32_linux)
766 VexGuestMIPS32State
* gst
= (VexGuestMIPS32State
*)gst_vanilla
;
767 if (canonical
->arg8
!= __NR_syscall
) {
768 gst
->guest_r2
= canonical
->sysno
;
769 gst
->guest_r4
= canonical
->arg1
;
770 gst
->guest_r5
= canonical
->arg2
;
771 gst
->guest_r6
= canonical
->arg3
;
772 gst
->guest_r7
= canonical
->arg4
;
773 *((UInt
*) (gst
->guest_r29
+ 16)) = canonical
->arg5
; // 16(guest_GPR29/sp)
774 *((UInt
*) (gst
->guest_r29
+ 20)) = canonical
->arg6
; // 20(sp)
777 gst
->guest_r2
= __NR_syscall
;
778 gst
->guest_r4
= canonical
->sysno
;
779 gst
->guest_r5
= canonical
->arg1
;
780 gst
->guest_r6
= canonical
->arg2
;
781 gst
->guest_r7
= canonical
->arg3
;
782 *((UInt
*) (gst
->guest_r29
+ 16)) = canonical
->arg4
; // 16(guest_GPR29/sp)
783 *((UInt
*) (gst
->guest_r29
+ 20)) = canonical
->arg5
; // 20(sp)
784 *((UInt
*) (gst
->guest_r29
+ 24)) = canonical
->arg6
; // 24(sp)
787 #elif defined(VGP_mips64_linux)
788 VexGuestMIPS64State
* gst
= (VexGuestMIPS64State
*)gst_vanilla
;
789 gst
->guest_r2
= canonical
->sysno
;
790 gst
->guest_r4
= canonical
->arg1
;
791 gst
->guest_r5
= canonical
->arg2
;
792 gst
->guest_r6
= canonical
->arg3
;
793 gst
->guest_r7
= canonical
->arg4
;
794 gst
->guest_r8
= canonical
->arg5
;
795 gst
->guest_r9
= canonical
->arg6
;
797 # error "putSyscallArgsIntoGuestState: unknown arch"
802 void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus
* canonical
,
803 /*IN*/ VexGuestArchState
* gst_vanilla
)
805 # if defined(VGP_x86_linux)
806 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
807 canonical
->sres
= VG_(mk_SysRes_x86_linux
)( gst
->guest_EAX
);
808 canonical
->what
= SsComplete
;
810 # elif defined(VGP_amd64_linux)
811 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
812 canonical
->sres
= VG_(mk_SysRes_amd64_linux
)( gst
->guest_RAX
);
813 canonical
->what
= SsComplete
;
815 # elif defined(VGP_ppc32_linux)
816 VexGuestPPC32State
* gst
= (VexGuestPPC32State
*)gst_vanilla
;
817 UInt cr
= LibVEX_GuestPPC32_get_CR( gst
);
818 UInt cr0so
= (cr
>> 28) & 1;
819 canonical
->sres
= VG_(mk_SysRes_ppc32_linux
)( gst
->guest_GPR3
, cr0so
);
820 canonical
->what
= SsComplete
;
822 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
823 VexGuestPPC64State
* gst
= (VexGuestPPC64State
*)gst_vanilla
;
824 UInt cr
= LibVEX_GuestPPC64_get_CR( gst
);
825 UInt cr0so
= (cr
>> 28) & 1;
826 canonical
->sres
= VG_(mk_SysRes_ppc64_linux
)( gst
->guest_GPR3
, cr0so
);
827 canonical
->what
= SsComplete
;
829 # elif defined(VGP_arm_linux)
830 VexGuestARMState
* gst
= (VexGuestARMState
*)gst_vanilla
;
831 canonical
->sres
= VG_(mk_SysRes_arm_linux
)( gst
->guest_R0
);
832 canonical
->what
= SsComplete
;
834 # elif defined(VGP_arm64_linux)
835 VexGuestARM64State
* gst
= (VexGuestARM64State
*)gst_vanilla
;
836 canonical
->sres
= VG_(mk_SysRes_arm64_linux
)( gst
->guest_X0
);
837 canonical
->what
= SsComplete
;
839 # elif defined(VGP_mips32_linux)
840 VexGuestMIPS32State
* gst
= (VexGuestMIPS32State
*)gst_vanilla
;
841 UInt v0
= gst
->guest_r2
; // v0
842 UInt v1
= gst
->guest_r3
; // v1
843 UInt a3
= gst
->guest_r7
; // a3
844 canonical
->sres
= VG_(mk_SysRes_mips32_linux
)( v0
, v1
, a3
);
845 canonical
->what
= SsComplete
;
847 # elif defined(VGP_mips64_linux)
848 VexGuestMIPS64State
* gst
= (VexGuestMIPS64State
*)gst_vanilla
;
849 ULong v0
= gst
->guest_r2
; // v0
850 ULong v1
= gst
->guest_r3
; // v1
851 ULong a3
= gst
->guest_r7
; // a3
852 canonical
->sres
= VG_(mk_SysRes_mips64_linux
)(v0
, v1
, a3
);
853 canonical
->what
= SsComplete
;
855 # elif defined(VGP_x86_darwin)
856 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
857 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
858 UInt carry
= 1 & LibVEX_GuestX86_get_eflags(gst
);
862 switch (gst
->guest_SC_CLASS
) {
863 case VG_DARWIN_SYSCALL_CLASS_UNIX
:
864 // int $0x80 = Unix, 64-bit result
866 wLO
= gst
->guest_EAX
;
867 wHI
= gst
->guest_EDX
;
869 case VG_DARWIN_SYSCALL_CLASS_MACH
:
870 // int $0x81 = Mach, 32-bit result
871 wLO
= gst
->guest_EAX
;
873 case VG_DARWIN_SYSCALL_CLASS_MDEP
:
874 // int $0x82 = mdep, 32-bit result
875 wLO
= gst
->guest_EAX
;
881 canonical
->sres
= VG_(mk_SysRes_x86_darwin
)(
882 gst
->guest_SC_CLASS
, err
? True
: False
,
885 canonical
->what
= SsComplete
;
887 # elif defined(VGP_amd64_darwin)
888 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
889 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
890 ULong carry
= 1 & LibVEX_GuestAMD64_get_rflags(gst
);
894 switch (gst
->guest_SC_CLASS
) {
895 case VG_DARWIN_SYSCALL_CLASS_UNIX
:
896 // syscall = Unix, 128-bit result
898 wLO
= gst
->guest_RAX
;
899 wHI
= gst
->guest_RDX
;
901 case VG_DARWIN_SYSCALL_CLASS_MACH
:
902 // syscall = Mach, 64-bit result
903 wLO
= gst
->guest_RAX
;
905 case VG_DARWIN_SYSCALL_CLASS_MDEP
:
906 // syscall = mdep, 64-bit result
907 wLO
= gst
->guest_RAX
;
913 canonical
->sres
= VG_(mk_SysRes_amd64_darwin
)(
914 gst
->guest_SC_CLASS
, err
? True
: False
,
917 canonical
->what
= SsComplete
;
919 # elif defined(VGP_s390x_linux)
920 VexGuestS390XState
* gst
= (VexGuestS390XState
*)gst_vanilla
;
921 canonical
->sres
= VG_(mk_SysRes_s390x_linux
)( gst
->guest_r2
);
922 canonical
->what
= SsComplete
;
925 # error "getSyscallStatusFromGuestState: unknown arch"
930 void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid
,
931 /*IN*/ SyscallStatus
* canonical
,
932 /*OUT*/VexGuestArchState
* gst_vanilla
)
934 # if defined(VGP_x86_linux)
935 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
936 vg_assert(canonical
->what
== SsComplete
);
937 if (sr_isError(canonical
->sres
)) {
938 /* This isn't exactly right, in that really a Failure with res
939 not in the range 1 .. 4095 is unrepresentable in the
940 Linux-x86 scheme. Oh well. */
941 gst
->guest_EAX
= - (Int
)sr_Err(canonical
->sres
);
943 gst
->guest_EAX
= sr_Res(canonical
->sres
);
945 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
946 OFFSET_x86_EAX
, sizeof(UWord
) );
948 # elif defined(VGP_amd64_linux)
949 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
950 vg_assert(canonical
->what
== SsComplete
);
951 if (sr_isError(canonical
->sres
)) {
952 /* This isn't exactly right, in that really a Failure with res
953 not in the range 1 .. 4095 is unrepresentable in the
954 Linux-amd64 scheme. Oh well. */
955 gst
->guest_RAX
= - (Long
)sr_Err(canonical
->sres
);
957 gst
->guest_RAX
= sr_Res(canonical
->sres
);
959 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
960 OFFSET_amd64_RAX
, sizeof(UWord
) );
962 # elif defined(VGP_ppc32_linux)
963 VexGuestPPC32State
* gst
= (VexGuestPPC32State
*)gst_vanilla
;
964 UInt old_cr
= LibVEX_GuestPPC32_get_CR(gst
);
965 vg_assert(canonical
->what
== SsComplete
);
966 if (sr_isError(canonical
->sres
)) {
968 LibVEX_GuestPPC32_put_CR( old_cr
| (1<<28), gst
);
969 gst
->guest_GPR3
= sr_Err(canonical
->sres
);
972 LibVEX_GuestPPC32_put_CR( old_cr
& ~(1<<28), gst
);
973 gst
->guest_GPR3
= sr_Res(canonical
->sres
);
975 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
976 OFFSET_ppc32_GPR3
, sizeof(UWord
) );
977 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
978 OFFSET_ppc32_CR0_0
, sizeof(UChar
) );
980 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
981 VexGuestPPC64State
* gst
= (VexGuestPPC64State
*)gst_vanilla
;
982 UInt old_cr
= LibVEX_GuestPPC64_get_CR(gst
);
983 vg_assert(canonical
->what
== SsComplete
);
984 if (sr_isError(canonical
->sres
)) {
986 LibVEX_GuestPPC64_put_CR( old_cr
| (1<<28), gst
);
987 gst
->guest_GPR3
= sr_Err(canonical
->sres
);
990 LibVEX_GuestPPC64_put_CR( old_cr
& ~(1<<28), gst
);
991 gst
->guest_GPR3
= sr_Res(canonical
->sres
);
993 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
994 OFFSET_ppc64_GPR3
, sizeof(UWord
) );
995 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
996 OFFSET_ppc64_CR0_0
, sizeof(UChar
) );
998 # elif defined(VGP_arm_linux)
999 VexGuestARMState
* gst
= (VexGuestARMState
*)gst_vanilla
;
1000 vg_assert(canonical
->what
== SsComplete
);
1001 if (sr_isError(canonical
->sres
)) {
1002 /* This isn't exactly right, in that really a Failure with res
1003 not in the range 1 .. 4095 is unrepresentable in the
1004 Linux-arm scheme. Oh well. */
1005 gst
->guest_R0
= - (Int
)sr_Err(canonical
->sres
);
1007 gst
->guest_R0
= sr_Res(canonical
->sres
);
1009 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1010 OFFSET_arm_R0
, sizeof(UWord
) );
1012 # elif defined(VGP_arm64_linux)
1013 VexGuestARM64State
* gst
= (VexGuestARM64State
*)gst_vanilla
;
1014 vg_assert(canonical
->what
== SsComplete
);
1015 if (sr_isError(canonical
->sres
)) {
1016 /* This isn't exactly right, in that really a Failure with res
1017 not in the range 1 .. 4095 is unrepresentable in the
1018 Linux-arm64 scheme. Oh well. */
1019 gst
->guest_X0
= - (Long
)sr_Err(canonical
->sres
);
1021 gst
->guest_X0
= sr_Res(canonical
->sres
);
1023 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1024 OFFSET_arm64_X0
, sizeof(UWord
) );
1026 #elif defined(VGP_x86_darwin)
1027 VexGuestX86State
* gst
= (VexGuestX86State
*)gst_vanilla
;
1028 SysRes sres
= canonical
->sres
;
1029 vg_assert(canonical
->what
== SsComplete
);
1030 /* Unfortunately here we have to break abstraction and look
1031 directly inside 'res', in order to decide what to do. */
1032 switch (sres
._mode
) {
1033 case SysRes_MACH
: // int $0x81 = Mach, 32-bit result
1034 case SysRes_MDEP
: // int $0x82 = mdep, 32-bit result
1035 gst
->guest_EAX
= sres
._wLO
;
1036 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1037 OFFSET_x86_EAX
, sizeof(UInt
) );
1039 case SysRes_UNIX_OK
: // int $0x80 = Unix, 64-bit result
1040 case SysRes_UNIX_ERR
: // int $0x80 = Unix, 64-bit error
1041 gst
->guest_EAX
= sres
._wLO
;
1042 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1043 OFFSET_x86_EAX
, sizeof(UInt
) );
1044 gst
->guest_EDX
= sres
._wHI
;
1045 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1046 OFFSET_x86_EDX
, sizeof(UInt
) );
1047 LibVEX_GuestX86_put_eflag_c( sres
._mode
==SysRes_UNIX_ERR
? 1 : 0,
1049 // GrP fixme sets defined for entire eflags, not just bit c
1050 // DDD: this breaks exp-ptrcheck.
1051 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1052 offsetof(VexGuestX86State
, guest_CC_DEP1
), sizeof(UInt
) );
1059 #elif defined(VGP_amd64_darwin)
1060 VexGuestAMD64State
* gst
= (VexGuestAMD64State
*)gst_vanilla
;
1061 SysRes sres
= canonical
->sres
;
1062 vg_assert(canonical
->what
== SsComplete
);
1063 /* Unfortunately here we have to break abstraction and look
1064 directly inside 'res', in order to decide what to do. */
1065 switch (sres
._mode
) {
1066 case SysRes_MACH
: // syscall = Mach, 64-bit result
1067 case SysRes_MDEP
: // syscall = mdep, 64-bit result
1068 gst
->guest_RAX
= sres
._wLO
;
1069 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1070 OFFSET_amd64_RAX
, sizeof(ULong
) );
1072 case SysRes_UNIX_OK
: // syscall = Unix, 128-bit result
1073 case SysRes_UNIX_ERR
: // syscall = Unix, 128-bit error
1074 gst
->guest_RAX
= sres
._wLO
;
1075 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1076 OFFSET_amd64_RAX
, sizeof(ULong
) );
1077 gst
->guest_RDX
= sres
._wHI
;
1078 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1079 OFFSET_amd64_RDX
, sizeof(ULong
) );
1080 LibVEX_GuestAMD64_put_rflag_c( sres
._mode
==SysRes_UNIX_ERR
? 1 : 0,
1082 // GrP fixme sets defined for entire rflags, not just bit c
1083 // DDD: this breaks exp-ptrcheck.
1084 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1085 offsetof(VexGuestAMD64State
, guest_CC_DEP1
), sizeof(ULong
) );
1092 # elif defined(VGP_s390x_linux)
1093 VexGuestS390XState
* gst
= (VexGuestS390XState
*)gst_vanilla
;
1094 vg_assert(canonical
->what
== SsComplete
);
1095 if (sr_isError(canonical
->sres
)) {
1096 gst
->guest_r2
= - (Long
)sr_Err(canonical
->sres
);
1098 gst
->guest_r2
= sr_Res(canonical
->sres
);
1101 # elif defined(VGP_mips32_linux)
1102 VexGuestMIPS32State
* gst
= (VexGuestMIPS32State
*)gst_vanilla
;
1103 vg_assert(canonical
->what
== SsComplete
);
1104 if (sr_isError(canonical
->sres
)) {
1105 gst
->guest_r2
= (Int
)sr_Err(canonical
->sres
);
1106 gst
->guest_r7
= (Int
)sr_Err(canonical
->sres
);
1108 gst
->guest_r2
= sr_Res(canonical
->sres
);
1109 gst
->guest_r3
= sr_ResEx(canonical
->sres
);
1110 gst
->guest_r7
= (Int
)sr_Err(canonical
->sres
);
1112 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1113 OFFSET_mips32_r2
, sizeof(UWord
) );
1114 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1115 OFFSET_mips32_r3
, sizeof(UWord
) );
1116 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1117 OFFSET_mips32_r7
, sizeof(UWord
) );
1119 # elif defined(VGP_mips64_linux)
1120 VexGuestMIPS64State
* gst
= (VexGuestMIPS64State
*)gst_vanilla
;
1121 vg_assert(canonical
->what
== SsComplete
);
1122 if (sr_isError(canonical
->sres
)) {
1123 gst
->guest_r2
= (Int
)sr_Err(canonical
->sres
);
1124 gst
->guest_r7
= (Int
)sr_Err(canonical
->sres
);
1126 gst
->guest_r2
= sr_Res(canonical
->sres
);
1127 gst
->guest_r3
= sr_ResEx(canonical
->sres
);
1128 gst
->guest_r7
= (Int
)sr_Err(canonical
->sres
);
1130 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1131 OFFSET_mips64_r2
, sizeof(UWord
) );
1132 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1133 OFFSET_mips64_r3
, sizeof(UWord
) );
1134 VG_TRACK( post_reg_write
, Vg_CoreSysCall
, tid
,
1135 OFFSET_mips64_r7
, sizeof(UWord
) );
1138 # error "putSyscallStatusIntoGuestState: unknown arch"
1143 /* Tell me the offsets in the guest state of the syscall params, so
1144 that the scalar argument checkers don't have to have this info
1148 void getSyscallArgLayout ( /*OUT*/SyscallArgLayout
* layout
)
1150 VG_(bzero_inline
)(layout
, sizeof(*layout
));
1152 #if defined(VGP_x86_linux)
1153 layout
->o_sysno
= OFFSET_x86_EAX
;
1154 layout
->o_arg1
= OFFSET_x86_EBX
;
1155 layout
->o_arg2
= OFFSET_x86_ECX
;
1156 layout
->o_arg3
= OFFSET_x86_EDX
;
1157 layout
->o_arg4
= OFFSET_x86_ESI
;
1158 layout
->o_arg5
= OFFSET_x86_EDI
;
1159 layout
->o_arg6
= OFFSET_x86_EBP
;
1160 layout
->uu_arg7
= -1; /* impossible value */
1161 layout
->uu_arg8
= -1; /* impossible value */
1163 #elif defined(VGP_amd64_linux)
1164 layout
->o_sysno
= OFFSET_amd64_RAX
;
1165 layout
->o_arg1
= OFFSET_amd64_RDI
;
1166 layout
->o_arg2
= OFFSET_amd64_RSI
;
1167 layout
->o_arg3
= OFFSET_amd64_RDX
;
1168 layout
->o_arg4
= OFFSET_amd64_R10
;
1169 layout
->o_arg5
= OFFSET_amd64_R8
;
1170 layout
->o_arg6
= OFFSET_amd64_R9
;
1171 layout
->uu_arg7
= -1; /* impossible value */
1172 layout
->uu_arg8
= -1; /* impossible value */
1174 #elif defined(VGP_ppc32_linux)
1175 layout
->o_sysno
= OFFSET_ppc32_GPR0
;
1176 layout
->o_arg1
= OFFSET_ppc32_GPR3
;
1177 layout
->o_arg2
= OFFSET_ppc32_GPR4
;
1178 layout
->o_arg3
= OFFSET_ppc32_GPR5
;
1179 layout
->o_arg4
= OFFSET_ppc32_GPR6
;
1180 layout
->o_arg5
= OFFSET_ppc32_GPR7
;
1181 layout
->o_arg6
= OFFSET_ppc32_GPR8
;
1182 layout
->uu_arg7
= -1; /* impossible value */
1183 layout
->uu_arg8
= -1; /* impossible value */
1185 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1186 layout
->o_sysno
= OFFSET_ppc64_GPR0
;
1187 layout
->o_arg1
= OFFSET_ppc64_GPR3
;
1188 layout
->o_arg2
= OFFSET_ppc64_GPR4
;
1189 layout
->o_arg3
= OFFSET_ppc64_GPR5
;
1190 layout
->o_arg4
= OFFSET_ppc64_GPR6
;
1191 layout
->o_arg5
= OFFSET_ppc64_GPR7
;
1192 layout
->o_arg6
= OFFSET_ppc64_GPR8
;
1193 layout
->uu_arg7
= -1; /* impossible value */
1194 layout
->uu_arg8
= -1; /* impossible value */
1196 #elif defined(VGP_arm_linux)
1197 layout
->o_sysno
= OFFSET_arm_R7
;
1198 layout
->o_arg1
= OFFSET_arm_R0
;
1199 layout
->o_arg2
= OFFSET_arm_R1
;
1200 layout
->o_arg3
= OFFSET_arm_R2
;
1201 layout
->o_arg4
= OFFSET_arm_R3
;
1202 layout
->o_arg5
= OFFSET_arm_R4
;
1203 layout
->o_arg6
= OFFSET_arm_R5
;
1204 layout
->uu_arg7
= -1; /* impossible value */
1205 layout
->uu_arg8
= -1; /* impossible value */
1207 #elif defined(VGP_arm64_linux)
1208 layout
->o_sysno
= OFFSET_arm64_X8
;
1209 layout
->o_arg1
= OFFSET_arm64_X0
;
1210 layout
->o_arg2
= OFFSET_arm64_X1
;
1211 layout
->o_arg3
= OFFSET_arm64_X2
;
1212 layout
->o_arg4
= OFFSET_arm64_X3
;
1213 layout
->o_arg5
= OFFSET_arm64_X4
;
1214 layout
->o_arg6
= OFFSET_arm64_X5
;
1215 layout
->uu_arg7
= -1; /* impossible value */
1216 layout
->uu_arg8
= -1; /* impossible value */
1218 #elif defined(VGP_mips32_linux)
1219 layout
->o_sysno
= OFFSET_mips32_r2
;
1220 layout
->o_arg1
= OFFSET_mips32_r4
;
1221 layout
->o_arg2
= OFFSET_mips32_r5
;
1222 layout
->o_arg3
= OFFSET_mips32_r6
;
1223 layout
->o_arg4
= OFFSET_mips32_r7
;
1224 layout
->s_arg5
= sizeof(UWord
) * 4;
1225 layout
->s_arg6
= sizeof(UWord
) * 5;
1226 layout
->uu_arg7
= -1; /* impossible value */
1227 layout
->uu_arg8
= -1; /* impossible value */
1229 #elif defined(VGP_mips64_linux)
1230 layout
->o_sysno
= OFFSET_mips64_r2
;
1231 layout
->o_arg1
= OFFSET_mips64_r4
;
1232 layout
->o_arg2
= OFFSET_mips64_r5
;
1233 layout
->o_arg3
= OFFSET_mips64_r6
;
1234 layout
->o_arg4
= OFFSET_mips64_r7
;
1235 layout
->o_arg5
= OFFSET_mips64_r8
;
1236 layout
->o_arg6
= OFFSET_mips64_r9
;
1237 layout
->uu_arg7
= -1; /* impossible value */
1238 layout
->uu_arg8
= -1; /* impossible value */
1240 #elif defined(VGP_x86_darwin)
1241 layout
->o_sysno
= OFFSET_x86_EAX
;
1242 // syscall parameters are on stack in C convention
1243 layout
->s_arg1
= sizeof(UWord
) * 1;
1244 layout
->s_arg2
= sizeof(UWord
) * 2;
1245 layout
->s_arg3
= sizeof(UWord
) * 3;
1246 layout
->s_arg4
= sizeof(UWord
) * 4;
1247 layout
->s_arg5
= sizeof(UWord
) * 5;
1248 layout
->s_arg6
= sizeof(UWord
) * 6;
1249 layout
->s_arg7
= sizeof(UWord
) * 7;
1250 layout
->s_arg8
= sizeof(UWord
) * 8;
1252 #elif defined(VGP_amd64_darwin)
1253 layout
->o_sysno
= OFFSET_amd64_RAX
;
1254 layout
->o_arg1
= OFFSET_amd64_RDI
;
1255 layout
->o_arg2
= OFFSET_amd64_RSI
;
1256 layout
->o_arg3
= OFFSET_amd64_RDX
;
1257 layout
->o_arg4
= OFFSET_amd64_RCX
;
1258 layout
->o_arg5
= OFFSET_amd64_R8
;
1259 layout
->o_arg6
= OFFSET_amd64_R9
;
1260 layout
->s_arg7
= sizeof(UWord
) * 1;
1261 layout
->s_arg8
= sizeof(UWord
) * 2;
1263 #elif defined(VGP_s390x_linux)
1264 layout
->o_sysno
= OFFSET_s390x_SYSNO
;
1265 layout
->o_arg1
= OFFSET_s390x_r2
;
1266 layout
->o_arg2
= OFFSET_s390x_r3
;
1267 layout
->o_arg3
= OFFSET_s390x_r4
;
1268 layout
->o_arg4
= OFFSET_s390x_r5
;
1269 layout
->o_arg5
= OFFSET_s390x_r6
;
1270 layout
->o_arg6
= OFFSET_s390x_r7
;
1271 layout
->uu_arg7
= -1; /* impossible value */
1272 layout
->uu_arg8
= -1; /* impossible value */
1274 # error "getSyscallLayout: unknown arch"
1279 /* ---------------------------------------------------------------------
1280 The main driver logic
1281 ------------------------------------------------------------------ */
1283 /* Finding the handlers for a given syscall, or faking up one
1284 when no handler is found. */
1287 void bad_before ( ThreadId tid
,
1288 SyscallArgLayout
* layout
,
1289 /*MOD*/SyscallArgs
* args
,
1290 /*OUT*/SyscallStatus
* status
,
1291 /*OUT*/UWord
* flags
)
1293 VG_(dmsg
)("WARNING: unhandled syscall: %s\n",
1294 VG_SYSNUM_STRING(args
->sysno
));
1295 if (VG_(clo_verbosity
) > 1) {
1296 VG_(get_and_pp_StackTrace
)(tid
, VG_(clo_backtrace_size
));
1298 VG_(dmsg
)("You may be able to write your own handler.\n");
1299 VG_(dmsg
)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
1300 VG_(dmsg
)("Nevertheless we consider this a bug. Please report\n");
1301 VG_(dmsg
)("it at http://valgrind.org/support/bug_reports.html.\n");
1303 SET_STATUS_Failure(VKI_ENOSYS
);
1306 static SyscallTableEntry bad_sys
=
1307 { bad_before
, NULL
};
1309 static const SyscallTableEntry
* get_syscall_entry ( Int syscallno
)
1311 const SyscallTableEntry
* sys
= NULL
;
1313 # if defined(VGO_linux)
1314 sys
= ML_(get_linux_syscall_entry
)( syscallno
);
1316 # elif defined(VGO_darwin)
1317 Int idx
= VG_DARWIN_SYSNO_INDEX(syscallno
);
1319 switch (VG_DARWIN_SYSNO_CLASS(syscallno
)) {
1320 case VG_DARWIN_SYSCALL_CLASS_UNIX
:
1321 if (idx
>= 0 && idx
< ML_(syscall_table_size
) &&
1322 ML_(syscall_table
)[idx
].before
!= NULL
)
1323 sys
= &ML_(syscall_table
)[idx
];
1325 case VG_DARWIN_SYSCALL_CLASS_MACH
:
1326 if (idx
>= 0 && idx
< ML_(mach_trap_table_size
) &&
1327 ML_(mach_trap_table
)[idx
].before
!= NULL
)
1328 sys
= &ML_(mach_trap_table
)[idx
];
1330 case VG_DARWIN_SYSCALL_CLASS_MDEP
:
1331 if (idx
>= 0 && idx
< ML_(mdep_trap_table_size
) &&
1332 ML_(mdep_trap_table
)[idx
].before
!= NULL
)
1333 sys
= &ML_(mdep_trap_table
)[idx
];
1344 return sys
== NULL
? &bad_sys
: sys
;
1348 /* Add and remove signals from mask so that we end up telling the
1349 kernel the state we actually want rather than what the client
1351 static void sanitize_client_sigmask(vki_sigset_t
*mask
)
1353 VG_(sigdelset
)(mask
, VKI_SIGKILL
);
1354 VG_(sigdelset
)(mask
, VKI_SIGSTOP
);
1355 VG_(sigdelset
)(mask
, VG_SIGVGKILL
); /* never block */
1360 SyscallArgs orig_args
;
1362 SyscallStatus status
;
1367 SyscallInfo syscallInfo
[VG_N_THREADS
];
1370 /* The scheduler needs to be able to zero out these records after a
1371 fork, hence this is exported from m_syswrap. */
1372 void VG_(clear_syscallInfo
) ( Int tid
)
1374 vg_assert(tid
>= 0 && tid
< VG_N_THREADS
);
1375 VG_(memset
)( & syscallInfo
[tid
], 0, sizeof( syscallInfo
[tid
] ));
1376 syscallInfo
[tid
].status
.what
= SsIdle
;
1379 static void ensure_initialised ( void )
1382 static Bool init_done
= False
;
1386 for (i
= 0; i
< VG_N_THREADS
; i
++) {
1387 VG_(clear_syscallInfo
)( i
);
1391 /* --- This is the main function of this file. --- */
1393 void VG_(client_syscall
) ( ThreadId tid
, UInt trc
)
1397 const SyscallTableEntry
* ent
;
1398 SyscallArgLayout layout
;
1401 ensure_initialised();
1403 vg_assert(VG_(is_valid_tid
)(tid
));
1404 vg_assert(tid
>= 1 && tid
< VG_N_THREADS
);
1405 vg_assert(VG_(is_running_thread
)(tid
));
1407 # if !defined(VGO_darwin)
1408 // Resync filtering is meaningless on non-Darwin targets.
1409 vg_assert(VG_(clo_resync_filter
) == 0);
1412 tst
= VG_(get_ThreadState
)(tid
);
1414 /* BEGIN ensure root thread's stack is suitably mapped */
1415 /* In some rare circumstances, we may do the syscall without the
1416 bottom page of the stack being mapped, because the stack pointer
1417 was moved down just a few instructions before the syscall
1418 instruction, and there have been no memory references since
1419 then, that would cause a call to VG_(extend_stack) to have
1422 In native execution that's OK: the kernel automagically extends
1423 the stack's mapped area down to cover the stack pointer (or sp -
1424 redzone, really). In simulated normal execution that's OK too,
1425 since any signals we get from accessing below the mapped area of
1426 the (guest's) stack lead us to VG_(extend_stack), where we
1427 simulate the kernel's stack extension logic. But that leaves
1428 the problem of entering a syscall with the SP unmapped. Because
1429 the kernel doesn't know that the segment immediately above SP is
1430 supposed to be a grow-down segment, it causes the syscall to
1431 fail, and thereby causes a divergence between native behaviour
1432 (syscall succeeds) and simulated behaviour (syscall fails).
1434 This is quite a rare failure mode. It has only been seen
1435 affecting calls to sys_readlink on amd64-linux, and even then it
1436 requires a certain code sequence around the syscall to trigger
1439 extern int my_readlink ( const char* path );
1442 ".globl my_readlink\n"
1444 "\tsubq $0x1008,%rsp\n"
1445 "\tmovq %rdi,%rdi\n" // path is in rdi
1446 "\tmovq %rsp,%rsi\n" // &buf[0] -> rsi
1447 "\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx
1448 "\tmovl $"__NR_READLINK",%eax\n" // syscall number
1450 "\taddq $0x1008,%rsp\n"
1455 For more details, see bug #156404
1456 (https://bugs.kde.org/show_bug.cgi?id=156404).
1458 The fix is actually very simple. We simply need to call
1459 VG_(extend_stack) for this thread, handing it the lowest
1460 possible valid address for stack (sp - redzone), to ensure the
1461 pages all the way down to that address, are mapped. Because
1462 this is a potentially expensive and frequent operation, we
1465 First, only the main thread (tid=1) has a growdown stack. So
1466 ignore all others. It is conceivable, although highly unlikely,
1467 that the main thread exits, and later another thread is
1468 allocated tid=1, but that's harmless, I believe;
1469 VG_(extend_stack) will do nothing when applied to a non-root
1472 Secondly, first call VG_(am_find_nsegment) directly, to see if
1473 the page holding (sp - redzone) is mapped correctly. If so, do
1474 nothing. This is almost always the case. VG_(extend_stack)
1475 calls VG_(am_find_nsegment) twice, so this optimisation -- and
1476 that's all it is -- more or less halves the number of calls to
1477 VG_(am_find_nsegment) required.
1479 TODO: the test "seg->kind == SkAnonC" is really inadequate,
1480 because although it tests whether the segment is mapped
1481 _somehow_, it doesn't check that it has the right permissions
1482 (r,w, maybe x) ? We could test that here, but it will also be
1483 necessary to fix the corresponding test in VG_(extend_stack).
1485 All this guff is of course Linux-specific. Hence the ifdef.
1487 # if defined(VGO_linux)
1488 if (tid
== 1/*ROOT THREAD*/) {
1489 Addr stackMin
= VG_(get_SP
)(tid
) - VG_STACK_REDZONE_SZB
;
1490 NSegment
const* seg
= VG_(am_find_nsegment
)(stackMin
);
1491 if (seg
&& seg
->kind
== SkAnonC
) {
1492 /* stackMin is already mapped. Nothing to do. */
1494 (void)VG_(extend_stack
)( stackMin
,
1495 tst
->client_stack_szB
);
1499 /* END ensure root thread's stack is suitably mapped */
1501 /* First off, get the syscall args and number. This is a
1502 platform-dependent action. */
1504 sci
= & syscallInfo
[tid
];
1505 vg_assert(sci
->status
.what
== SsIdle
);
1507 getSyscallArgsFromGuestState( &sci
->orig_args
, &tst
->arch
.vex
, trc
);
1509 /* Copy .orig_args to .args. The pre-handler may modify .args, but
1510 we want to keep the originals too, just in case. */
1511 sci
->args
= sci
->orig_args
;
1513 /* Save the syscall number in the thread state in case the syscall
1514 is interrupted by a signal. */
1515 sysno
= sci
->orig_args
.sysno
;
1517 /* It's sometimes useful, as a crude debugging hack, to get a
1518 stack trace at each (or selected) syscalls. */
1519 if (0 && sysno
== __NR_ioctl
) {
1520 VG_(umsg
)("\nioctl:\n");
1521 VG_(get_and_pp_StackTrace
)(tid
, 10);
1525 # if defined(VGO_darwin)
1526 /* Record syscall class. But why? Because the syscall might be
1527 interrupted by a signal, and in the signal handler (which will
1528 be m_signals.async_signalhandler) we will need to build a SysRes
1529 reflecting the syscall return result. In order to do that we
1530 need to know the syscall class. Hence stash it in the guest
1531 state of this thread. This madness is not needed on Linux
1532 because it only has a single syscall return convention and so
1533 there is no ambiguity involved in converting the post-signal
1534 machine state into a SysRes. */
1535 tst
->arch
.vex
.guest_SC_CLASS
= VG_DARWIN_SYSNO_CLASS(sysno
);
1538 /* The default what-to-do-next thing is hand the syscall to the
1539 kernel, so we pre-set that here. Set .sres to something
1540 harmless looking (is irrelevant because .what is not
1542 sci
->status
.what
= SsHandToKernel
;
1543 sci
->status
.sres
= VG_(mk_SysRes_Error
)(0);
1546 /* Fetch the syscall's handlers. If no handlers exist for this
1547 syscall, we are given dummy handlers which force an immediate
1548 return with ENOSYS. */
1549 ent
= get_syscall_entry(sysno
);
1551 /* Fetch the layout information, which tells us where in the guest
1552 state the syscall args reside. This is a platform-dependent
1553 action. This info is needed so that the scalar syscall argument
1554 checks (PRE_REG_READ calls) know which bits of the guest state
1555 they need to inspect. */
1556 getSyscallArgLayout( &layout
);
1558 /* Make sure the tmp signal mask matches the real signal mask;
1559 sigsuspend may change this. */
1560 vg_assert(VG_(iseqsigset
)(&tst
->sig_mask
, &tst
->tmp_sig_mask
));
1562 /* Right, we're finally ready to Party. Call the pre-handler and
1563 see what we get back. At this point:
1565 sci->status.what is Unset (we don't know yet).
1566 sci->orig_args contains the original args.
1567 sci->args is the same as sci->orig_args.
1571 PRINT("SYSCALL[%d,%d](%s) ",
1572 VG_(getpid
)(), tid
, VG_SYSNUM_STRING(sysno
));
1574 /* Do any pre-syscall actions */
1575 if (VG_(needs
).syscall_wrapper
) {
1577 tmpv
[0] = sci
->orig_args
.arg1
;
1578 tmpv
[1] = sci
->orig_args
.arg2
;
1579 tmpv
[2] = sci
->orig_args
.arg3
;
1580 tmpv
[3] = sci
->orig_args
.arg4
;
1581 tmpv
[4] = sci
->orig_args
.arg5
;
1582 tmpv
[5] = sci
->orig_args
.arg6
;
1583 tmpv
[6] = sci
->orig_args
.arg7
;
1584 tmpv
[7] = sci
->orig_args
.arg8
;
1585 VG_TDICT_CALL(tool_pre_syscall
, tid
, sysno
,
1586 &tmpv
[0], sizeof(tmpv
)/sizeof(tmpv
[0]));
1590 vg_assert(ent
->before
);
1593 &sci
->args
, &sci
->status
, &sci
->flags
);
1595 /* The pre-handler may have modified:
1599 All else remains unchanged.
1600 Although the args may be modified, pre handlers are not allowed
1601 to change the syscall number.
1603 /* Now we proceed according to what the pre-handler decided. */
1604 vg_assert(sci
->status
.what
== SsHandToKernel
1605 || sci
->status
.what
== SsComplete
);
1606 vg_assert(sci
->args
.sysno
== sci
->orig_args
.sysno
);
1608 if (sci
->status
.what
== SsComplete
&& !sr_isError(sci
->status
.sres
)) {
1609 /* The pre-handler completed the syscall itself, declaring
1611 if (sci
->flags
& SfNoWriteResult
) {
1612 PRINT(" --> [pre-success] NoWriteResult");
1614 PRINT(" --> [pre-success] Success(0x%llx:0x%llx)",
1615 (ULong
)sr_ResHI(sci
->status
.sres
),
1616 (ULong
)sr_Res(sci
->status
.sres
));
1618 /* In this case the allowable flags are to ask for a signal-poll
1619 and/or a yield after the call. Changing the args isn't
1621 vg_assert(0 == (sci
->flags
1622 & ~(SfPollAfter
| SfYieldAfter
| SfNoWriteResult
)));
1623 vg_assert(eq_SyscallArgs(&sci
->args
, &sci
->orig_args
));
1627 if (sci
->status
.what
== SsComplete
&& sr_isError(sci
->status
.sres
)) {
1628 /* The pre-handler decided to fail syscall itself. */
1629 PRINT(" --> [pre-fail] Failure(0x%llx)", (ULong
)sr_Err(sci
->status
.sres
));
1630 /* In this case, the pre-handler is also allowed to ask for the
1631 post-handler to be run anyway. Changing the args is not
1633 vg_assert(0 == (sci
->flags
& ~(SfMayBlock
| SfPostOnFail
| SfPollAfter
)));
1634 vg_assert(eq_SyscallArgs(&sci
->args
, &sci
->orig_args
));
1638 if (sci
->status
.what
!= SsHandToKernel
) {
1643 else /* (sci->status.what == HandToKernel) */ {
1644 /* Ok, this is the usual case -- and the complicated one. There
1645 are two subcases: sync and async. async is the general case
1646 and is to be used when there is any possibility that the
1647 syscall might block [a fact that the pre-handler must tell us
1648 via the sci->flags field.] Because the tidying-away /
1649 context-switch overhead of the async case could be large, if
1650 we are sure that the syscall will not block, we fast-track it
1651 by doing it directly in this thread, which is a lot
1654 /* Check that the given flags are allowable: MayBlock, PollAfter
1655 and PostOnFail are ok. */
1656 vg_assert(0 == (sci
->flags
& ~(SfMayBlock
| SfPostOnFail
| SfPollAfter
)));
1658 if (sci
->flags
& SfMayBlock
) {
1660 /* Syscall may block, so run it asynchronously */
1663 PRINT(" --> [async] ... \n");
1665 mask
= tst
->sig_mask
;
1666 sanitize_client_sigmask(&mask
);
1668 /* Gack. More impedance matching. Copy the possibly
1669 modified syscall args back into the guest state. */
1670 /* JRS 2009-Mar-16: if the syscall args are possibly modified,
1671 then this assertion is senseless:
1672 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
1673 The case that exposed it was sys_posix_spawn on Darwin,
1674 which heavily modifies its arguments but then lets the call
1675 go through anyway, with SfToBlock set, hence we end up here. */
1676 putSyscallArgsIntoGuestState( &sci
->args
, &tst
->arch
.vex
);
1678 /* Drop the bigLock */
1679 VG_(release_BigLock
)(tid
, VgTs_WaitSys
, "VG_(client_syscall)[async]");
1680 /* Urr. We're now in a race against other threads trying to
1681 acquire the bigLock. I guess that doesn't matter provided
1682 that do_syscall_for_client only touches thread-local
1685 /* Do the call, which operates directly on the guest state,
1686 not on our abstracted copies of the args/result. */
1687 do_syscall_for_client(sysno
, tst
, &mask
);
1689 /* do_syscall_for_client may not return if the syscall was
1690 interrupted by a signal. In that case, flow of control is
1691 first to m_signals.async_sighandler, which calls
1692 VG_(fixup_guest_state_after_syscall_interrupted), which
1693 fixes up the guest state, and possibly calls
1694 VG_(post_syscall). Once that's done, control drops back
1695 to the scheduler. */
1697 /* Darwin: do_syscall_for_client may not return if the
1698 syscall was workq_ops(WQOPS_THREAD_RETURN) and the kernel
1699 responded by starting the thread at wqthread_hijack(reuse=1)
1700 (to run another workqueue item). In that case, wqthread_hijack
1701 calls ML_(wqthread_continue), which is similar to
1702 VG_(fixup_guest_state_after_syscall_interrupted). */
1704 /* Reacquire the lock */
1705 VG_(acquire_BigLock
)(tid
, "VG_(client_syscall)[async]");
1707 /* Even more impedance matching. Extract the syscall status
1708 from the guest state. */
1709 getSyscallStatusFromGuestState( &sci
->status
, &tst
->arch
.vex
);
1710 vg_assert(sci
->status
.what
== SsComplete
);
1712 /* Be decorative, if required. */
1713 if (VG_(clo_trace_syscalls
)) {
1714 Bool failed
= sr_isError(sci
->status
.sres
);
1716 PRINT("SYSCALL[%d,%d](%s) ... [async] --> Failure(0x%llx)",
1717 VG_(getpid
)(), tid
, VG_SYSNUM_STRING(sysno
),
1718 (ULong
)sr_Err(sci
->status
.sres
));
1720 PRINT("SYSCALL[%d,%d](%s) ... [async] --> "
1721 "Success(0x%llx:0x%llx)",
1722 VG_(getpid
)(), tid
, VG_SYSNUM_STRING(sysno
),
1723 (ULong
)sr_ResHI(sci
->status
.sres
),
1724 (ULong
)sr_Res(sci
->status
.sres
) );
1730 /* run the syscall directly */
1731 /* The pre-handler may have modified the syscall args, but
1732 since we're passing values in ->args directly to the
1733 kernel, there's no point in flushing them back to the
1734 guest state. Indeed doing so could be construed as
1737 = VG_(do_syscall
)(sysno
, sci
->args
.arg1
, sci
->args
.arg2
,
1738 sci
->args
.arg3
, sci
->args
.arg4
,
1739 sci
->args
.arg5
, sci
->args
.arg6
,
1740 sci
->args
.arg7
, sci
->args
.arg8
);
1741 sci
->status
= convert_SysRes_to_SyscallStatus(sres
);
1743 /* Be decorative, if required. */
1744 if (VG_(clo_trace_syscalls
)) {
1745 Bool failed
= sr_isError(sci
->status
.sres
);
1747 PRINT("[sync] --> Failure(0x%llx)",
1748 (ULong
)sr_Err(sci
->status
.sres
) );
1750 PRINT("[sync] --> Success(0x%llx:0x%llx)",
1751 (ULong
)sr_ResHI(sci
->status
.sres
),
1752 (ULong
)sr_Res(sci
->status
.sres
) );
1758 vg_assert(sci
->status
.what
== SsComplete
);
1760 vg_assert(VG_(is_running_thread
)(tid
));
1762 /* Dump the syscall result back in the guest state. This is
1763 a platform-specific action. */
1764 if (!(sci
->flags
& SfNoWriteResult
))
1765 putSyscallStatusIntoGuestState( tid
, &sci
->status
, &tst
->arch
.vex
);
1768 - the guest state is now correctly modified following the syscall
1769 - modified args, original args and syscall status are still
1770 available in the syscallInfo[] entry for this syscall.
1772 Now go on to do the post-syscall actions (read on down ..)
1775 VG_(post_syscall
)(tid
);
1780 /* Perform post syscall actions. The expected state on entry is
1781 precisely as at the end of VG_(client_syscall), that is:
1783 - guest state up to date following the syscall
1784 - modified args, original args and syscall status are still
1785 available in the syscallInfo[] entry for this syscall.
1786 - syscall status matches what's in the guest state.
1788 There are two ways to get here: the normal way -- being called by
1789 VG_(client_syscall), and the unusual way, from
1790 VG_(fixup_guest_state_after_syscall_interrupted).
1791 Darwin: there's a third way, ML_(wqthread_continue).
1793 void VG_(post_syscall
) (ThreadId tid
)
1796 const SyscallTableEntry
* ent
;
1797 SyscallStatus test_status
;
1802 vg_assert(VG_(is_valid_tid
)(tid
));
1803 vg_assert(tid
>= 1 && tid
< VG_N_THREADS
);
1804 vg_assert(VG_(is_running_thread
)(tid
));
1806 tst
= VG_(get_ThreadState
)(tid
);
1807 sci
= & syscallInfo
[tid
];
1809 /* m_signals.sigvgkill_handler might call here even when not in
1811 if (sci
->status
.what
== SsIdle
|| sci
->status
.what
== SsHandToKernel
) {
1812 sci
->status
.what
= SsIdle
;
1816 /* Validate current syscallInfo entry. In particular we require
1817 that the current .status matches what's actually in the guest
1818 state. At least in the normal case where we have actually
1819 previously written the result into the guest state. */
1820 vg_assert(sci
->status
.what
== SsComplete
);
1822 getSyscallStatusFromGuestState( &test_status
, &tst
->arch
.vex
);
1823 if (!(sci
->flags
& SfNoWriteResult
))
1824 vg_assert(eq_SyscallStatus( &sci
->status
, &test_status
));
1825 /* Failure of the above assertion on Darwin can indicate a problem
1826 in the syscall wrappers that pre-fail or pre-succeed the
1827 syscall, by calling SET_STATUS_Success or SET_STATUS_Failure,
1828 when they really should call SET_STATUS_from_SysRes. The former
1829 create a UNIX-class syscall result on Darwin, which may not be
1830 correct for the syscall; if that's the case then this assertion
1831 fires. See PRE(thread_fast_set_cthread_self) for an example. On
1832 non-Darwin platforms this assertion is should never fail, and this
1833 comment is completely irrelevant. */
1834 /* Ok, looks sane */
1836 /* Get the system call number. Because the pre-handler isn't
1837 allowed to mess with it, it should be the same for both the
1838 original and potentially-modified args. */
1839 vg_assert(sci
->args
.sysno
== sci
->orig_args
.sysno
);
1840 sysno
= sci
->args
.sysno
;
1841 ent
= get_syscall_entry(sysno
);
1843 /* pre: status == Complete (asserted above) */
1844 /* Consider either success or failure. Now run the post handler if:
1846 - Success or (Failure and PostOnFail is set)
1849 && ((!sr_isError(sci
->status
.sres
))
1850 || (sr_isError(sci
->status
.sres
)
1851 && (sci
->flags
& SfPostOnFail
) ))) {
1853 (ent
->after
)( tid
, &sci
->args
, &sci
->status
);
1856 /* Because the post handler might have changed the status (eg, the
1857 post-handler for sys_open can change the result from success to
1858 failure if the kernel supplied a fd that it doesn't like), once
1859 again dump the syscall result back in the guest state.*/
1860 if (!(sci
->flags
& SfNoWriteResult
))
1861 putSyscallStatusIntoGuestState( tid
, &sci
->status
, &tst
->arch
.vex
);
1863 /* Do any post-syscall actions required by the tool. */
1864 if (VG_(needs
).syscall_wrapper
) {
1866 tmpv
[0] = sci
->orig_args
.arg1
;
1867 tmpv
[1] = sci
->orig_args
.arg2
;
1868 tmpv
[2] = sci
->orig_args
.arg3
;
1869 tmpv
[3] = sci
->orig_args
.arg4
;
1870 tmpv
[4] = sci
->orig_args
.arg5
;
1871 tmpv
[5] = sci
->orig_args
.arg6
;
1872 tmpv
[6] = sci
->orig_args
.arg7
;
1873 tmpv
[7] = sci
->orig_args
.arg8
;
1874 VG_TDICT_CALL(tool_post_syscall
, tid
,
1876 &tmpv
[0], sizeof(tmpv
)/sizeof(tmpv
[0]),
1880 /* The syscall is done. */
1881 vg_assert(sci
->status
.what
== SsComplete
);
1882 sci
->status
.what
= SsIdle
;
1884 /* The pre/post wrappers may have concluded that pending signals
1885 might have been created, and will have set SfPollAfter to
1886 request a poll for them once the syscall is done. */
1887 if (sci
->flags
& SfPollAfter
)
1888 VG_(poll_signals
)(tid
);
1890 /* Similarly, the wrappers might have asked for a yield
1892 if (sci
->flags
& SfYieldAfter
)
1897 /* ---------------------------------------------------------------------
1898 Dealing with syscalls which get interrupted by a signal:
1899 VG_(fixup_guest_state_after_syscall_interrupted)
1900 ------------------------------------------------------------------ */
1902 /* Syscalls done on behalf of the client are finally handed off to the
1903 kernel in VG_(client_syscall) above, either by calling
1904 do_syscall_for_client (the async case), or by calling
1905 VG_(do_syscall6) (the sync case).
1907 If the syscall is not interrupted by a signal (it may block and
1908 later unblock, but that's irrelevant here) then those functions
1909 eventually return and so control is passed to VG_(post_syscall).
1910 NB: not sure if the sync case can actually get interrupted, as it
1911 operates with all signals masked.
1913 However, the syscall may get interrupted by an async-signal. In
1914 that case do_syscall_for_client/VG_(do_syscall6) do not
1915 return. Instead we wind up in m_signals.async_sighandler. We need
1916 to fix up the guest state to make it look like the syscall was
1917 interrupted for guest. So async_sighandler calls here, and this
1918 does the fixup. Note that from here we wind up calling
1919 VG_(post_syscall) too.
1923 /* These are addresses within ML_(do_syscall_for_client_WRK). See
1924 syscall-$PLAT.S for details.
1926 #if defined(VGO_linux)
1927 extern const Addr
ML_(blksys_setup
);
1928 extern const Addr
ML_(blksys_restart
);
1929 extern const Addr
ML_(blksys_complete
);
1930 extern const Addr
ML_(blksys_committed
);
1931 extern const Addr
ML_(blksys_finished
);
1932 #elif defined(VGO_darwin)
1933 /* Darwin requires extra uglyness */
1934 extern const Addr
ML_(blksys_setup_MACH
);
1935 extern const Addr
ML_(blksys_restart_MACH
);
1936 extern const Addr
ML_(blksys_complete_MACH
);
1937 extern const Addr
ML_(blksys_committed_MACH
);
1938 extern const Addr
ML_(blksys_finished_MACH
);
1939 extern const Addr
ML_(blksys_setup_MDEP
);
1940 extern const Addr
ML_(blksys_restart_MDEP
);
1941 extern const Addr
ML_(blksys_complete_MDEP
);
1942 extern const Addr
ML_(blksys_committed_MDEP
);
1943 extern const Addr
ML_(blksys_finished_MDEP
);
1944 extern const Addr
ML_(blksys_setup_UNIX
);
1945 extern const Addr
ML_(blksys_restart_UNIX
);
1946 extern const Addr
ML_(blksys_complete_UNIX
);
1947 extern const Addr
ML_(blksys_committed_UNIX
);
1948 extern const Addr
ML_(blksys_finished_UNIX
);
1950 # error "Unknown OS"
1954 /* Back up guest state to restart a system call. */
1956 void ML_(fixup_guest_state_to_restart_syscall
) ( ThreadArchState
* arch
)
1958 #if defined(VGP_x86_linux)
1959 arch
->vex
.guest_EIP
-= 2; // sizeof(int $0x80)
1961 /* Make sure our caller is actually sane, and we're really backing
1962 back over a syscall.
1967 UChar
*p
= (UChar
*)arch
->vex
.guest_EIP
;
1969 if (p
[0] != 0xcd || p
[1] != 0x80)
1970 VG_(message
)(Vg_DebugMsg
,
1971 "?! restarting over syscall at %#x %02x %02x\n",
1972 arch
->vex
.guest_EIP
, p
[0], p
[1]);
1974 vg_assert(p
[0] == 0xcd && p
[1] == 0x80);
1977 #elif defined(VGP_amd64_linux)
1978 arch
->vex
.guest_RIP
-= 2; // sizeof(syscall)
1980 /* Make sure our caller is actually sane, and we're really backing
1981 back over a syscall.
1986 UChar
*p
= (UChar
*)arch
->vex
.guest_RIP
;
1988 if (p
[0] != 0x0F || p
[1] != 0x05)
1989 VG_(message
)(Vg_DebugMsg
,
1990 "?! restarting over syscall at %#llx %02x %02x\n",
1991 arch
->vex
.guest_RIP
, p
[0], p
[1]);
1993 vg_assert(p
[0] == 0x0F && p
[1] == 0x05);
1996 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux)
1997 arch
->vex
.guest_CIA
-= 4; // sizeof(ppc32 instr)
1999 /* Make sure our caller is actually sane, and we're really backing
2000 back over a syscall.
2005 UChar
*p
= (UChar
*)arch
->vex
.guest_CIA
;
2007 if (p
[0] != 0x44 || p
[1] != 0x0 || p
[2] != 0x0 || p
[3] != 0x02)
2008 VG_(message
)(Vg_DebugMsg
,
2009 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2010 arch
->vex
.guest_CIA
+ 0ULL, p
[0], p
[1], p
[2], p
[3]);
2012 vg_assert(p
[0] == 0x44 && p
[1] == 0x0 && p
[2] == 0x0 && p
[3] == 0x2);
2015 #elif defined(VGP_ppc64le_linux)
2016 arch
->vex
.guest_CIA
-= 4; // sizeof(ppc32 instr)
2018 /* Make sure our caller is actually sane, and we're really backing
2019 back over a syscall.
2024 UChar
*p
= (UChar
*)arch
->vex
.guest_CIA
;
2026 if (p
[3] != 0x44 || p
[2] != 0x0 || p
[1] != 0x0 || p
[0] != 0x02)
2027 VG_(message
)(Vg_DebugMsg
,
2028 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2029 arch
->vex
.guest_CIA
+ 0ULL, p
[3], p
[2], p
[1], p
[0]);
2031 vg_assert(p
[3] == 0x44 && p
[2] == 0x0 && p
[1] == 0x0 && p
[0] == 0x2);
2034 #elif defined(VGP_arm_linux)
2035 if (arch
->vex
.guest_R15T
& 1) {
2036 // Thumb mode. SVC is a encoded as
2038 // where imm8 is the SVC number, and we only accept 0.
2039 arch
->vex
.guest_R15T
-= 2; // sizeof(thumb 16 bit insn)
2040 UChar
* p
= (UChar
*)(arch
->vex
.guest_R15T
- 1);
2041 Bool valid
= p
[0] == 0 && p
[1] == 0xDF;
2043 VG_(message
)(Vg_DebugMsg
,
2044 "?! restarting over (Thumb) syscall that is not syscall "
2045 "at %#llx %02x %02x\n",
2046 arch
->vex
.guest_R15T
- 1ULL, p
[0], p
[1]);
2049 // FIXME: NOTE, this really isn't right. We need to back up
2050 // ITSTATE to what it was before the SVC instruction, but we
2051 // don't know what it was. At least assert that it is now
2052 // zero, because if it is nonzero then it must also have
2053 // been nonzero for the SVC itself, which means it was
2054 // conditional. Urk.
2055 vg_assert(arch
->vex
.guest_ITSTATE
== 0);
2057 // ARM mode. SVC is encoded as
2059 // where imm24 is the SVC number, and we only accept 0.
2060 arch
->vex
.guest_R15T
-= 4; // sizeof(arm instr)
2061 UChar
* p
= (UChar
*)arch
->vex
.guest_R15T
;
2062 Bool valid
= p
[0] == 0 && p
[1] == 0 && p
[2] == 0
2063 && (p
[3] & 0xF) == 0xF;
2065 VG_(message
)(Vg_DebugMsg
,
2066 "?! restarting over (ARM) syscall that is not syscall "
2067 "at %#llx %02x %02x %02x %02x\n",
2068 arch
->vex
.guest_R15T
+ 0ULL, p
[0], p
[1], p
[2], p
[3]);
2073 #elif defined(VGP_arm64_linux)
2074 arch
->vex
.guest_PC
-= 4; // sizeof(arm64 instr)
2076 /* Make sure our caller is actually sane, and we're really backing
2077 back over a syscall.
2079 svc #0 == d4 00 00 01
2082 UChar
*p
= (UChar
*)arch
->vex
.guest_PC
;
2084 if (p
[0] != 0x01 || p
[1] != 0x00 || p
[2] != 0x00 || p
[3] != 0xD4)
2087 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2088 arch
->vex
.guest_PC
+ 0ULL, p
[0], p
[1], p
[2], p
[3]
2091 vg_assert(p
[0] == 0x01 && p
[1] == 0x00 && p
[2] == 0x00 && p
[3] == 0xD4);
2094 #elif defined(VGP_x86_darwin)
2095 arch
->vex
.guest_EIP
= arch
->vex
.guest_IP_AT_SYSCALL
;
2097 /* Make sure our caller is actually sane, and we're really backing
2098 back over a syscall.
2106 UChar
*p
= (UChar
*)arch
->vex
.guest_EIP
;
2107 Bool ok
= (p
[0] == 0xCD && p
[1] == 0x80)
2108 || (p
[0] == 0xCD && p
[1] == 0x81)
2109 || (p
[0] == 0xCD && p
[1] == 0x82)
2110 || (p
[0] == 0x0F && p
[1] == 0x34);
2112 VG_(message
)(Vg_DebugMsg
,
2113 "?! restarting over syscall at %#x %02x %02x\n",
2114 arch
->vex
.guest_EIP
, p
[0], p
[1]);
2118 #elif defined(VGP_amd64_darwin)
2119 // DDD: #warning GrP fixme amd64 restart unimplemented
2122 #elif defined(VGP_s390x_linux)
2123 arch
->vex
.guest_IA
-= 2; // sizeof(syscall)
2125 /* Make sure our caller is actually sane, and we're really backing
2126 back over a syscall.
2131 UChar
*p
= (UChar
*)arch
->vex
.guest_IA
;
2133 VG_(message
)(Vg_DebugMsg
,
2134 "?! restarting over syscall at %#llx %02x %02x\n",
2135 arch
->vex
.guest_IA
, p
[0], p
[1]);
2137 vg_assert(p
[0] == 0x0A);
2140 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
2142 arch
->vex
.guest_PC
-= 4; // sizeof(mips instr)
2144 /* Make sure our caller is actually sane, and we're really backing
2145 back over a syscall.
2147 syscall == 00 00 00 0C
2149 syscall == 0C 00 00 00
2152 UChar
*p
= (UChar
*)(arch
->vex
.guest_PC
);
2153 # if defined (VG_LITTLEENDIAN)
2154 if (p
[0] != 0x0c || p
[1] != 0x00 || p
[2] != 0x00 || p
[3] != 0x00)
2155 VG_(message
)(Vg_DebugMsg
,
2156 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2157 (ULong
)arch
->vex
.guest_PC
, p
[0], p
[1], p
[2], p
[3]);
2159 vg_assert(p
[0] == 0x0c && p
[1] == 0x00 && p
[2] == 0x00 && p
[3] == 0x00);
2160 # elif defined (VG_BIGENDIAN)
2161 if (p
[0] != 0x00 || p
[1] != 0x00 || p
[2] != 0x00 || p
[3] != 0x0c)
2162 VG_(message
)(Vg_DebugMsg
,
2163 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2164 (ULong
)arch
->vex
.guest_PC
, p
[0], p
[1], p
[2], p
[3]);
2166 vg_assert(p
[0] == 0x00 && p
[1] == 0x00 && p
[2] == 0x00 && p
[3] == 0x0c);
2168 # error "Unknown endianness"
2173 # error "ML_(fixup_guest_state_to_restart_syscall): unknown plat"
2179 Fix up the guest state when a syscall is interrupted by a signal
2180 and so has been forced to return 'sysret'.
2182 To do this, we determine the precise state of the syscall by
2183 looking at the (real) IP at the time the signal happened. The
2184 syscall sequence looks like:
2188 3. save result to guest state (EAX, RAX, R3+CR0.SO, R0, V0)
2192 happens at Then Why?
2193 [1-2) restart nothing has happened (restart syscall)
2194 [2] restart syscall hasn't started, or kernel wants to restart
2195 [2-3) save syscall complete, but results not saved
2196 [3-4) syscall complete, results saved
2198 Sometimes we never want to restart an interrupted syscall (because
2199 sigaction says not to), so we only restart if "restart" is True.
2201 This will also call VG_(post_syscall) if the syscall has actually
2202 completed (either because it was interrupted, or because it
2203 actually finished). It will not call VG_(post_syscall) if the
2204 syscall is set up for restart, which means that the pre-wrapper may
2205 get called multiple times.
2209 VG_(fixup_guest_state_after_syscall_interrupted
)( ThreadId tid
,
2214 /* Note that we don't know the syscall number here, since (1) in
2215 general there's no reliable way to get hold of it short of
2216 stashing it in the guest state before the syscall, and (2) in
2217 any case we don't need to know it for the actions done by this
2220 Furthermore, 'sres' is only used in the case where the syscall
2221 is complete, but the result has not been committed to the guest
2222 state yet. In any other situation it will be meaningless and
2223 therefore ignored. */
2226 SyscallStatus canonical
;
2227 ThreadArchState
* th_regs
;
2230 /* Compute some Booleans indicating which range we're in. */
2232 in_setup_to_restart
, // [1,2) in the .S files
2233 at_restart
, // [2] in the .S files
2234 in_complete_to_committed
, // [3,4) in the .S files
2235 in_committed_to_finished
; // [4,5) in the .S files
2237 # if defined(VGO_linux)
2239 = ip
< ML_(blksys_setup
) || ip
>= ML_(blksys_finished
);
2241 = ip
>= ML_(blksys_setup
) && ip
< ML_(blksys_restart
);
2243 = ip
== ML_(blksys_restart
);
2244 in_complete_to_committed
2245 = ip
>= ML_(blksys_complete
) && ip
< ML_(blksys_committed
);
2246 in_committed_to_finished
2247 = ip
>= ML_(blksys_committed
) && ip
< ML_(blksys_finished
);
2248 # elif defined(VGO_darwin)
2250 = (ip
< ML_(blksys_setup_MACH
) || ip
>= ML_(blksys_finished_MACH
))
2251 && (ip
< ML_(blksys_setup_MDEP
) || ip
>= ML_(blksys_finished_MDEP
))
2252 && (ip
< ML_(blksys_setup_UNIX
) || ip
>= ML_(blksys_finished_UNIX
));
2254 = (ip
>= ML_(blksys_setup_MACH
) && ip
< ML_(blksys_restart_MACH
))
2255 || (ip
>= ML_(blksys_setup_MDEP
) && ip
< ML_(blksys_restart_MDEP
))
2256 || (ip
>= ML_(blksys_setup_UNIX
) && ip
< ML_(blksys_restart_UNIX
));
2258 = (ip
== ML_(blksys_restart_MACH
))
2259 || (ip
== ML_(blksys_restart_MDEP
))
2260 || (ip
== ML_(blksys_restart_UNIX
));
2261 in_complete_to_committed
2262 = (ip
>= ML_(blksys_complete_MACH
) && ip
< ML_(blksys_committed_MACH
))
2263 || (ip
>= ML_(blksys_complete_MDEP
) && ip
< ML_(blksys_committed_MDEP
))
2264 || (ip
>= ML_(blksys_complete_UNIX
) && ip
< ML_(blksys_committed_UNIX
));
2265 in_committed_to_finished
2266 = (ip
>= ML_(blksys_committed_MACH
) && ip
< ML_(blksys_finished_MACH
))
2267 || (ip
>= ML_(blksys_committed_MDEP
) && ip
< ML_(blksys_finished_MDEP
))
2268 || (ip
>= ML_(blksys_committed_UNIX
) && ip
< ML_(blksys_finished_UNIX
));
2269 /* Wasn't that just So Much Fun? Does your head hurt yet? Mine does. */
2271 # error "Unknown OS"
2274 if (VG_(clo_trace_signals
))
2275 VG_(message
)( Vg_DebugMsg
,
2276 "interrupted_syscall: tid=%d, ip=0x%llx, "
2277 "restart=%s, sres.isErr=%s, sres.val=%lld\n",
2280 restart
? "True" : "False",
2281 sr_isError(sres
) ? "True" : "False",
2282 (Long
)(sr_isError(sres
) ? sr_Err(sres
) : sr_Res(sres
)) );
2284 vg_assert(VG_(is_valid_tid
)(tid
));
2285 vg_assert(tid
>= 1 && tid
< VG_N_THREADS
);
2286 vg_assert(VG_(is_running_thread
)(tid
));
2288 tst
= VG_(get_ThreadState
)(tid
);
2289 th_regs
= &tst
->arch
;
2290 sci
= & syscallInfo
[tid
];
2292 /* Figure out what the state of the syscall was by examining the
2293 (real) IP at the time of the signal, and act accordingly. */
2294 if (outside_range
) {
2295 if (VG_(clo_trace_signals
))
2296 VG_(message
)( Vg_DebugMsg
,
2297 " not in syscall at all: hmm, very suspicious\n" );
2298 /* Looks like we weren't in a syscall at all. Hmm. */
2299 vg_assert(sci
->status
.what
!= SsIdle
);
2303 /* We should not be here unless this thread had first started up
2304 the machinery for a syscall by calling VG_(client_syscall).
2306 vg_assert(sci
->status
.what
!= SsIdle
);
2308 /* now, do one of four fixup actions, depending on where the IP has
2311 if (in_setup_to_restart
) {
2312 /* syscall hasn't even started; go around again */
2313 if (VG_(clo_trace_signals
))
2314 VG_(message
)( Vg_DebugMsg
, " not started: restarting\n");
2315 vg_assert(sci
->status
.what
== SsHandToKernel
);
2316 ML_(fixup_guest_state_to_restart_syscall
)(th_regs
);
2321 /* We're either about to run the syscall, or it was interrupted
2322 and the kernel restarted it. Restart if asked, otherwise
2325 if (VG_(clo_trace_signals
))
2326 VG_(message
)( Vg_DebugMsg
, " at syscall instr: restarting\n");
2327 ML_(fixup_guest_state_to_restart_syscall
)(th_regs
);
2329 if (VG_(clo_trace_signals
))
2330 VG_(message
)( Vg_DebugMsg
, " at syscall instr: returning EINTR\n");
2331 canonical
= convert_SysRes_to_SyscallStatus(
2332 VG_(mk_SysRes_Error
)( VKI_EINTR
)
2334 if (!(sci
->flags
& SfNoWriteResult
))
2335 putSyscallStatusIntoGuestState( tid
, &canonical
, &th_regs
->vex
);
2336 sci
->status
= canonical
;
2337 VG_(post_syscall
)(tid
);
2342 if (in_complete_to_committed
) {
2343 /* Syscall complete, but result hasn't been written back yet.
2344 Write the SysRes we were supplied with back to the guest
2346 if (VG_(clo_trace_signals
))
2347 VG_(message
)( Vg_DebugMsg
,
2348 " completed, but uncommitted: committing\n");
2349 canonical
= convert_SysRes_to_SyscallStatus( sres
);
2350 if (!(sci
->flags
& SfNoWriteResult
))
2351 putSyscallStatusIntoGuestState( tid
, &canonical
, &th_regs
->vex
);
2352 sci
->status
= canonical
;
2353 VG_(post_syscall
)(tid
);
2357 if (in_committed_to_finished
) {
2358 /* Result committed, but the signal mask has not been restored;
2359 we expect our caller (the signal handler) will have fixed
2361 if (VG_(clo_trace_signals
))
2362 VG_(message
)( Vg_DebugMsg
,
2363 " completed and committed: nothing to do\n");
2364 getSyscallStatusFromGuestState( &sci
->status
, &th_regs
->vex
);
2365 vg_assert(sci
->status
.what
== SsComplete
);
2366 VG_(post_syscall
)(tid
);
2370 VG_(core_panic
)("?? strange syscall interrupt state?");
2372 /* In all cases, the syscall is now finished (even if we called
2373 ML_(fixup_guest_state_to_restart_syscall), since that just
2374 re-positions the guest's IP for another go at it). So we need
2375 to record that fact. */
2376 sci
->status
.what
= SsIdle
;
2380 #if defined(VGO_darwin)
2381 // Clean up after workq_ops(WQOPS_THREAD_RETURN) jumped to wqthread_hijack.
2382 // This is similar to VG_(fixup_guest_state_after_syscall_interrupted).
2383 // This longjmps back to the scheduler.
2384 void ML_(wqthread_continue_NORETURN
)(ThreadId tid
)
2389 VG_(acquire_BigLock
)(tid
, "wqthread_continue_NORETURN");
2391 PRINT("SYSCALL[%d,%d](%s) workq_ops() starting new workqueue item\n",
2392 VG_(getpid
)(), tid
, VG_SYSNUM_STRING(__NR_workq_ops
));
2394 vg_assert(VG_(is_valid_tid
)(tid
));
2395 vg_assert(tid
>= 1 && tid
< VG_N_THREADS
);
2396 vg_assert(VG_(is_running_thread
)(tid
));
2398 tst
= VG_(get_ThreadState
)(tid
);
2399 sci
= & syscallInfo
[tid
];
2400 vg_assert(sci
->status
.what
!= SsIdle
);
2401 vg_assert(tst
->os_state
.wq_jmpbuf_valid
); // check this BEFORE post_syscall
2403 // Pretend the syscall completed normally, but don't touch the thread state.
2404 sci
->status
= convert_SysRes_to_SyscallStatus( VG_(mk_SysRes_Success
)(0) );
2405 sci
->flags
|= SfNoWriteResult
;
2406 VG_(post_syscall
)(tid
);
2408 ML_(sync_mappings
)("in", "ML_(wqthread_continue_NORETURN)", 0);
2410 sci
->status
.what
= SsIdle
;
2412 vg_assert(tst
->sched_jmpbuf_valid
);
2413 VG_MINIMAL_LONGJMP(tst
->sched_jmpbuf
);
2421 /* ---------------------------------------------------------------------
2422 A place to store the where-to-call-when-really-done pointer
2423 ------------------------------------------------------------------ */
2425 // When the final thread is done, where shall I call to shutdown the
2426 // system cleanly? Is set once at startup (in m_main) and never
2427 // changes after that. Is basically a pointer to the exit
2428 // continuation. This is all just a nasty hack to avoid calling
2429 // directly from m_syswrap to m_main at exit, since that would cause
2430 // m_main to become part of a module cycle, which is silly.
2431 void (* VG_(address_of_m_main_shutdown_actions_NORETURN
) )
2432 (ThreadId
,VgSchedReturnCode
)
2435 /*--------------------------------------------------------------------*/
2437 /*--------------------------------------------------------------------*/