FreeBSD: add file descriptor tracking for _umtx_op
[valgrind.git] / coregrind / m_syswrap / syswrap-main.c
blobbe4ac0f08143aeb0d257e40a434f73684239061d
2 /*--------------------------------------------------------------------*/
3 /*--- Handle system calls. syswrap-main.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Julian Seward
11 jseward@acm.org
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #include "libvex_guest_offsets.h"
30 #include "libvex_trc_values.h"
31 #include "pub_core_basics.h"
32 #include "pub_core_aspacemgr.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_threadstate.h"
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcassert.h"
38 #include "pub_core_libcprint.h"
39 #include "pub_core_libcproc.h" // For VG_(getpid)()
40 #include "pub_core_libcsignal.h"
41 #include "pub_core_scheduler.h" // For VG_({acquire,release}_BigLock),
42 // and VG_(vg_yield)
43 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
44 #include "pub_core_tooliface.h"
45 #include "pub_core_options.h"
46 #include "pub_core_signals.h" // For VG_SIGVGKILL, VG_(poll_signals)
47 #include "pub_core_syscall.h"
48 #include "pub_core_machine.h"
49 #include "pub_core_mallocfree.h"
50 #include "pub_core_syswrap.h"
51 #include "pub_core_gdbserver.h" // VG_(gdbserver_report_syscall)
53 #include "priv_types_n_macros.h"
54 #include "priv_syswrap-main.h"
56 #if defined(VGO_darwin)
57 #include "priv_syswrap-darwin.h"
58 #endif
60 /* Useful info which needs to be recorded somewhere:
61 Use of registers in syscalls is:
63 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
64 LINUX:
65 x86 eax ebx ecx edx esi edi ebp n/a n/a eax (== NUM)
66 amd64 rax rdi rsi rdx r10 r8 r9 n/a n/a rax (== NUM)
67 ppc32 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1)
68 ppc64 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1)
69 arm r7 r0 r1 r2 r3 r4 r5 n/a n/a r0 (== ARG1)
70 mips32 v0 a0 a1 a2 a3 stack stack n/a n/a v0 (== NUM)
71 mips64 v0 a0 a1 a2 a3 a4 a5 a6 a7 v0 (== NUM)
72 arm64 x8 x0 x1 x2 x3 x4 x5 n/a n/a x0 ?? (== ARG1??)
74 FreeBSD:
75 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c
76 amd64 rax rdi rsi rdx rcx r8 r9 +8 +16 rdx:rax, rflags.c
78 On s390x the svc instruction is used for system calls. The system call
79 number is encoded in the instruction (8 bit immediate field). Since Linux
80 2.6 it is also allowed to use svc 0 with the system call number in r1.
81 This was introduced for system calls >255, but works for all. It is
82 also possible to see the svc 0 together with an EXecute instruction, that
83 fills in the immediate field.
84 s390x r1/SVC r2 r3 r4 r5 r6 r7 n/a n/a r2 (== ARG1)
86 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
87 DARWIN:
88 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c
89 amd64 rax rdi rsi rdx rcx r8 r9 +8 +16 rdx:rax, rflags.c
91 For x86-darwin and x86-freebsd, "+N" denotes "in memory at N(%esp)";
92 ditto amd64-darwin/amd64-freebsd. Apparently 0(%esp) is some kind of return address
93 (perhaps for syscalls done with "sysenter"?) I don't think it is
94 relevant for syscalls done with "int $0x80/1/2".
96 SOLARIS:
97 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c
98 amd64 rax rdi rsi rdx r10 r8 r9 +8 +16 rdx:rax, rflags.c
100 "+N" denotes "in memory at N(%esp)". Solaris also supports fasttrap
101 syscalls. Fasttraps do not take any parameters (except of the sysno in eax)
102 and never fail (if the sysno is valid).
105 /* This is the top level of the system-call handler module. All
106 system calls are channelled through here, doing two things:
108 * notify the tool of the events (mem/reg reads, writes) happening
110 * perform the syscall, usually by passing it along to the kernel
111 unmodified.
113 A magical piece of assembly code, do_syscall_for_client_WRK, in
114 syscall-$PLATFORM.S does the tricky bit of passing a syscall to the
115 kernel, whilst having the simulator retain control.
118 /* The main function is VG_(client_syscall). The simulation calls it
119 whenever a client thread wants to do a syscall. The following is a
120 sketch of what it does.
122 * Ensures the root thread's stack is suitably mapped. Tedious and
123 arcane. See big big comment in VG_(client_syscall).
125 * First, it rounds up the syscall number and args (which is a
126 platform dependent activity) and puts them in a struct ("args")
127 and also a copy in "orig_args".
129 The pre/post wrappers refer to these structs and so no longer
130 need magic macros to access any specific registers. This struct
131 is stored in thread-specific storage.
134 * The pre-wrapper is called, passing it a pointer to struct
135 "args".
138 * The pre-wrapper examines the args and pokes the tool
139 appropriately. It may modify the args; this is why "orig_args"
140 is also stored.
142 The pre-wrapper may choose to 'do' the syscall itself, and
143 concludes one of three outcomes:
145 Success(N) -- syscall is already complete, with success;
146 result is N
148 Fail(N) -- syscall is already complete, with failure;
149 error code is N
151 HandToKernel -- (the usual case): this needs to be given to
152 the kernel to be done, using the values in
153 the possibly-modified "args" struct.
155 In addition, the pre-wrapper may set some flags:
157 MayBlock -- only applicable when outcome==HandToKernel
159 PostOnFail -- only applicable when outcome==HandToKernel or Fail
162 * If the pre-outcome is HandToKernel, the syscall is duly handed
163 off to the kernel (perhaps involving some thread switchery, but
164 that's not important). This reduces the possible set of outcomes
165 to either Success(N) or Fail(N).
168 * The outcome (Success(N) or Fail(N)) is written back to the guest
169 register(s). This is platform specific:
171 x86: Success(N) ==> eax = N
172 Fail(N) ==> eax = -N
174 ditto amd64
176 ppc32: Success(N) ==> r3 = N, CR0.SO = 0
177 Fail(N) ==> r3 = N, CR0.SO = 1
179 FreeBSD:
180 x86: Success(N) ==> edx:eax = N, cc = 0
181 Fail(N) ==> edx:eax = N, cc = 1
183 ditto amd64
185 Darwin:
186 x86: Success(N) ==> edx:eax = N, cc = 0
187 Fail(N) ==> edx:eax = N, cc = 1
189 s390x: Success(N) ==> r2 = N
190 Fail(N) ==> r2 = -N
192 Solaris:
193 x86: Success(N) ==> edx:eax = N, cc = 0
194 Fail(N) ==> eax = N, cc = 1
195 Same applies for fasttraps except they never fail.
197 * The post wrapper is called if:
199 - it exists, and
200 - outcome==Success or (outcome==Fail and PostOnFail is set)
202 The post wrapper is passed the adulterated syscall args (struct
203 "args"), and the syscall outcome (viz, Success(N) or Fail(N)).
205 There are several other complications, primarily to do with
206 syscalls getting interrupted, explained in comments in the code.
209 /* CAVEATS for writing wrappers. It is important to follow these!
211 The macros defined in priv_types_n_macros.h are designed to help
212 decouple the wrapper logic from the actual representation of
213 syscall args/results, since these wrappers are designed to work on
214 multiple platforms.
216 Sometimes a PRE wrapper will complete the syscall itself, without
217 handing it to the kernel. It will use one of SET_STATUS_Success,
218 SET_STATUS_Failure or SET_STATUS_from_SysRes to set the return
219 value. It is critical to appreciate that use of the macro does not
220 immediately cause the underlying guest state to be updated -- that
221 is done by the driver logic in this file, when the wrapper returns.
223 As a result, PRE wrappers of the following form will malfunction:
225 PRE(fooble)
227 ... do stuff ...
228 SET_STATUS_Somehow(...)
230 // do something that assumes guest state is up to date
233 In particular, direct or indirect calls to VG_(poll_signals) after
234 setting STATUS can cause the guest state to be read (in order to
235 build signal frames). Do not do this. If you want a signal poll
236 after the syscall goes through, do "*flags |= SfPollAfter" and the
237 driver logic will do it for you.
239 -----------
241 Another critical requirement following introduction of new address
242 space manager (JRS, 20050923):
244 In a situation where the mappedness of memory has changed, aspacem
245 should be notified BEFORE the tool. Hence the following is
246 correct:
248 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
249 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
250 if (d)
251 VG_(discard_translations)(s->start, s->end+1 - s->start);
253 whilst this is wrong:
255 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
256 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
257 if (d)
258 VG_(discard_translations)(s->start, s->end+1 - s->start);
260 The reason is that the tool may itself ask aspacem for more shadow
261 memory as a result of the VG_TRACK call. In such a situation it is
262 critical that aspacem's segment array is up to date -- hence the
263 need to notify aspacem first.
265 -----------
267 Also .. take care to call VG_(discard_translations) whenever
268 memory with execute permissions is unmapped.
272 /* ---------------------------------------------------------------------
273 Do potentially blocking syscall for the client, and mess with
274 signal masks at the same time.
275 ------------------------------------------------------------------ */
277 /* Perform a syscall on behalf of a client thread, using a specific
278 signal mask. On completion, the signal mask is set to restore_mask
279 (which presumably blocks almost everything). If a signal happens
280 during the syscall, the handler should call
281 VG_(fixup_guest_state_after_syscall_interrupted) to adjust the
282 thread's context to do the right thing.
284 The _WRK function is handwritten assembly, implemented per-platform
285 in coregrind/m_syswrap/syscall-$PLAT.S. It has some very magic
286 properties. See comments at the top of
287 VG_(fixup_guest_state_after_syscall_interrupted) below for details.
289 This function (these functions) are required to return zero in case
290 of success (even if the syscall itself failed), and nonzero if the
291 sigprocmask-swizzling calls failed. We don't actually care about
292 the failure values from sigprocmask, although most of the assembly
293 implementations do attempt to return that, using the convention
294 0 for success, or 0x8000 | error-code for failure.
296 #if defined(VGO_linux)
297 extern
298 UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
299 void* guest_state,
300 const vki_sigset_t *syscall_mask,
301 const vki_sigset_t *restore_mask,
302 Word sigsetSzB );
303 #elif defined(VGO_freebsd)
304 extern
305 UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
306 void* guest_state,
307 const vki_sigset_t *syscall_mask,
308 const vki_sigset_t *restore_mask,
309 Word sigsetSzB );
310 #elif defined(VGO_darwin)
311 extern
312 UWord ML_(do_syscall_for_client_unix_WRK)( Word syscallno,
313 void* guest_state,
314 const vki_sigset_t *syscall_mask,
315 const vki_sigset_t *restore_mask,
316 Word sigsetSzB ); /* unused */
317 extern
318 UWord ML_(do_syscall_for_client_mach_WRK)( Word syscallno,
319 void* guest_state,
320 const vki_sigset_t *syscall_mask,
321 const vki_sigset_t *restore_mask,
322 Word sigsetSzB ); /* unused */
323 extern
324 UWord ML_(do_syscall_for_client_mdep_WRK)( Word syscallno,
325 void* guest_state,
326 const vki_sigset_t *syscall_mask,
327 const vki_sigset_t *restore_mask,
328 Word sigsetSzB ); /* unused */
329 #elif defined(VGO_solaris)
330 extern
331 UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
332 void* guest_state,
333 const vki_sigset_t *syscall_mask,
334 const vki_sigset_t *restore_mask,
335 UChar *cflag);
336 UWord ML_(do_syscall_for_client_dret_WRK)( Word syscallno,
337 void* guest_state,
338 const vki_sigset_t *syscall_mask,
339 const vki_sigset_t *restore_mask,
340 UChar *cflag);
341 #else
342 # error "Unknown OS"
343 #endif
346 static
347 void do_syscall_for_client ( Int syscallno,
348 ThreadState* tst,
349 const vki_sigset_t* syscall_mask )
351 vki_sigset_t saved;
352 UWord err;
353 # if defined(VGO_freebsd)
354 Word real_syscallno;
355 # endif
356 # if defined(VGO_linux)
357 err = ML_(do_syscall_for_client_WRK)(
358 syscallno, &tst->arch.vex,
359 syscall_mask, &saved, sizeof(vki_sigset_t)
361 # elif defined(VGO_freebsd)
362 if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL0)
363 real_syscallno = __NR_syscall;
364 else if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL198)
365 real_syscallno = __NR___syscall;
366 else
367 real_syscallno = syscallno;
368 err = ML_(do_syscall_for_client_WRK)(
369 real_syscallno, &tst->arch.vex,
370 syscall_mask, &saved, sizeof(vki_sigset_t)
372 # elif defined(VGO_darwin)
373 switch (VG_DARWIN_SYSNO_CLASS(syscallno)) {
374 case VG_DARWIN_SYSCALL_CLASS_UNIX:
375 err = ML_(do_syscall_for_client_unix_WRK)(
376 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
377 syscall_mask, &saved, 0/*unused:sigsetSzB*/
379 break;
380 case VG_DARWIN_SYSCALL_CLASS_MACH:
381 err = ML_(do_syscall_for_client_mach_WRK)(
382 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
383 syscall_mask, &saved, 0/*unused:sigsetSzB*/
385 break;
386 case VG_DARWIN_SYSCALL_CLASS_MDEP:
387 err = ML_(do_syscall_for_client_mdep_WRK)(
388 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
389 syscall_mask, &saved, 0/*unused:sigsetSzB*/
391 break;
392 default:
393 vg_assert(0);
394 /*NOTREACHED*/
395 break;
397 # elif defined(VGO_solaris)
398 UChar cflag;
400 /* Fasttraps or anything else cannot go through this path. */
401 vg_assert(VG_SOLARIS_SYSNO_CLASS(syscallno)
402 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
404 /* If the syscall is a door_return call then it has to be handled very
405 differently. */
406 if (tst->os_state.in_door_return)
407 err = ML_(do_syscall_for_client_dret_WRK)(
408 syscallno, &tst->arch.vex,
409 syscall_mask, &saved, &cflag
411 else
412 err = ML_(do_syscall_for_client_WRK)(
413 syscallno, &tst->arch.vex,
414 syscall_mask, &saved, &cflag
417 /* Save the carry flag. */
418 # if defined(VGP_x86_solaris)
419 LibVEX_GuestX86_put_eflag_c(cflag, &tst->arch.vex);
420 # elif defined(VGP_amd64_solaris)
421 LibVEX_GuestAMD64_put_rflag_c(cflag, &tst->arch.vex);
422 # else
423 # error "Unknown platform"
424 # endif
426 # else
427 # error "Unknown OS"
428 # endif
429 vg_assert2(
430 err == 0,
431 "ML_(do_syscall_for_client_WRK): sigprocmask error %lu",
432 err & 0xFFF
437 /* ---------------------------------------------------------------------
438 Impedance matchers and misc helpers
439 ------------------------------------------------------------------ */
441 static
442 Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
444 return a1->sysno == a2->sysno
445 && a1->arg1 == a2->arg1
446 && a1->arg2 == a2->arg2
447 && a1->arg3 == a2->arg3
448 && a1->arg4 == a2->arg4
449 && a1->arg5 == a2->arg5
450 && a1->arg6 == a2->arg6
451 && a1->arg7 == a2->arg7
452 && a1->arg8 == a2->arg8;
455 static
456 Bool eq_SyscallStatus ( UInt sysno, SyscallStatus* s1, SyscallStatus* s2 )
458 /* was: return s1->what == s2->what && sr_EQ( s1->sres, s2->sres ); */
459 if (s1->what == s2->what && sr_EQ( sysno, s1->sres, s2->sres ))
460 return True;
461 # if defined(VGO_darwin)
462 /* Darwin-specific debugging guff */
463 vg_assert(s1->what == s2->what);
464 VG_(printf)("eq_SyscallStatus:\n");
465 VG_(printf)(" {%lu %lu %u}\n", s1->sres._wLO, s1->sres._wHI, s1->sres._mode);
466 VG_(printf)(" {%lu %lu %u}\n", s2->sres._wLO, s2->sres._wHI, s2->sres._mode);
467 vg_assert(0);
468 # endif
469 return False;
472 /* Convert between SysRes and SyscallStatus, to the extent possible. */
474 static
475 SyscallStatus convert_SysRes_to_SyscallStatus ( SysRes res )
477 SyscallStatus status;
478 status.what = SsComplete;
479 status.sres = res;
480 return status;
484 /* Impedance matchers. These convert syscall arg or result data from
485 the platform-specific in-guest-state format to the canonical
486 formats, and back. */
488 static
489 void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical,
490 /*IN*/ VexGuestArchState* gst_vanilla,
491 /*IN*/ UInt trc )
493 #if defined(VGP_x86_linux)
494 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
495 canonical->sysno = gst->guest_EAX;
496 canonical->arg1 = gst->guest_EBX;
497 canonical->arg2 = gst->guest_ECX;
498 canonical->arg3 = gst->guest_EDX;
499 canonical->arg4 = gst->guest_ESI;
500 canonical->arg5 = gst->guest_EDI;
501 canonical->arg6 = gst->guest_EBP;
502 canonical->arg7 = 0;
503 canonical->arg8 = 0;
505 #elif defined(VGP_amd64_linux)
506 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
507 canonical->sysno = gst->guest_RAX;
508 canonical->arg1 = gst->guest_RDI;
509 canonical->arg2 = gst->guest_RSI;
510 canonical->arg3 = gst->guest_RDX;
511 canonical->arg4 = gst->guest_R10;
512 canonical->arg5 = gst->guest_R8;
513 canonical->arg6 = gst->guest_R9;
514 canonical->arg7 = 0;
515 canonical->arg8 = 0;
517 #elif defined(VGP_ppc32_linux)
518 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
519 canonical->sysno = gst->guest_GPR0;
520 canonical->arg1 = gst->guest_GPR3;
521 canonical->arg2 = gst->guest_GPR4;
522 canonical->arg3 = gst->guest_GPR5;
523 canonical->arg4 = gst->guest_GPR6;
524 canonical->arg5 = gst->guest_GPR7;
525 canonical->arg6 = gst->guest_GPR8;
526 canonical->arg7 = 0;
527 canonical->arg8 = 0;
529 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
530 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
531 canonical->sysno = gst->guest_GPR0;
532 canonical->arg1 = gst->guest_GPR3;
533 canonical->arg2 = gst->guest_GPR4;
534 canonical->arg3 = gst->guest_GPR5;
535 canonical->arg4 = gst->guest_GPR6;
536 canonical->arg5 = gst->guest_GPR7;
537 canonical->arg6 = gst->guest_GPR8;
538 /* ISA 3.0 adds the scv system call instruction.
539 The PPC syscalls have at most 6 args. Arg 7 is being used to pass a
540 flag to indicate which system call instruction is to be used.
541 Arg7 = SC_FLAG for the sc instruction; Arg7 = SCV_FLAG for the scv
542 instruction. The guest register guest_syscall_flag was created to pass
543 the flag so the actual guest state would not be changed. */
544 canonical->arg7 = gst->guest_syscall_flag;
545 canonical->arg8 = 0;
547 #elif defined(VGP_x86_freebsd)
548 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
549 UWord *stack = (UWord *)gst->guest_ESP;
551 // FreeBSD supports different calling conventions
552 switch (gst->guest_EAX) {
553 case __NR_syscall:
554 canonical->klass = VG_FREEBSD_SYSCALL0;
555 canonical->sysno = stack[1];
556 stack += 1;
557 break;
558 case __NR___syscall:
559 canonical->klass = VG_FREEBSD_SYSCALL198;
560 canonical->sysno = stack[1];
561 stack += 2;
562 break;
563 default:
564 canonical->klass = 0;
565 canonical->sysno = gst->guest_EAX;
566 break;
568 // stack[0] is a (fake) return address
569 canonical->arg1 = stack[1];
570 canonical->arg2 = stack[2];
571 canonical->arg3 = stack[3];
572 canonical->arg4 = stack[4];
573 canonical->arg5 = stack[5];
574 canonical->arg6 = stack[6];
575 canonical->arg7 = stack[7];
576 canonical->arg8 = stack[8];
578 #elif defined(VGP_amd64_freebsd)
579 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
580 UWord *stack = (UWord *)gst->guest_RSP;
582 // FreeBSD supports different calling conventions
583 // @todo PJF this all seems over complicated to me
584 // SYSCALL_STD is OK but for the other
585 // two here we overwrite canonical->sysno with
586 // the final syscall number but then in do_syscall_for_client
587 // we switch real_syscallno back to __NR_syscall or __NR___syscall
588 switch (gst->guest_RAX) {
589 case __NR_syscall:
590 canonical->klass = VG_FREEBSD_SYSCALL0;
591 canonical->sysno = gst->guest_RDI;
592 break;
593 case __NR___syscall:
594 canonical->klass = VG_FREEBSD_SYSCALL198;
595 canonical->sysno = gst->guest_RDI;
596 break;
597 default:
598 canonical->klass = VG_FREEBSD_SYSCALL_STD;
599 canonical->sysno = gst->guest_RAX;
600 break;
603 // stack[0] is a (fake) return address
604 if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
605 // stack[0] is return address
606 canonical->arg1 = gst->guest_RSI;
607 canonical->arg2 = gst->guest_RDX;
608 canonical->arg3 = gst->guest_R10;
609 canonical->arg4 = gst->guest_R8;
610 canonical->arg5 = gst->guest_R9;
611 canonical->arg6 = stack[1];
612 canonical->arg7 = stack[2];
613 canonical->arg8 = stack[3];
614 } else {
615 // stack[0] is return address
616 canonical->arg1 = gst->guest_RDI;
617 canonical->arg2 = gst->guest_RSI;
618 canonical->arg3 = gst->guest_RDX;
619 canonical->arg4 = gst->guest_R10;
620 canonical->arg5 = gst->guest_R8;
621 canonical->arg6 = gst->guest_R9;
622 canonical->arg7 = stack[1];
623 canonical->arg8 = stack[2];
626 #elif defined(VGP_arm64_freebsd)
627 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
628 switch (gst->guest_X8) {
629 case __NR_syscall:
630 canonical->klass = VG_FREEBSD_SYSCALL0;
631 canonical->sysno = gst->guest_X0;
632 break;
633 case __NR___syscall:
634 canonical->klass = VG_FREEBSD_SYSCALL198;
635 canonical->sysno = gst->guest_X0;
636 break;
637 default:
638 canonical->klass = 0;
639 canonical->sysno = gst->guest_X8;
640 break;
642 if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
643 canonical->arg1 = gst->guest_X1;
644 canonical->arg2 = gst->guest_X2;
645 canonical->arg3 = gst->guest_X3;
646 canonical->arg4 = gst->guest_X4;
647 canonical->arg5 = gst->guest_X5;
648 canonical->arg6 = gst->guest_X6;
649 canonical->arg7 = gst->guest_X7;
650 } else {
651 canonical->arg1 = gst->guest_X0;
652 canonical->arg2 = gst->guest_X1;
653 canonical->arg3 = gst->guest_X2;
654 canonical->arg4 = gst->guest_X3;
655 canonical->arg5 = gst->guest_X4;
656 canonical->arg6 = gst->guest_X5;
657 canonical->arg7 = gst->guest_X6;
660 #elif defined(VGP_arm_linux)
661 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
662 canonical->sysno = gst->guest_R7;
663 canonical->arg1 = gst->guest_R0;
664 canonical->arg2 = gst->guest_R1;
665 canonical->arg3 = gst->guest_R2;
666 canonical->arg4 = gst->guest_R3;
667 canonical->arg5 = gst->guest_R4;
668 canonical->arg6 = gst->guest_R5;
669 canonical->arg7 = 0;
670 canonical->arg8 = 0;
672 #elif defined(VGP_arm64_linux)
673 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
674 canonical->sysno = gst->guest_X8;
675 canonical->arg1 = gst->guest_X0;
676 canonical->arg2 = gst->guest_X1;
677 canonical->arg3 = gst->guest_X2;
678 canonical->arg4 = gst->guest_X3;
679 canonical->arg5 = gst->guest_X4;
680 canonical->arg6 = gst->guest_X5;
681 canonical->arg7 = 0;
682 canonical->arg8 = 0;
684 #elif defined(VGP_mips32_linux)
685 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
686 canonical->sysno = gst->guest_r2; // v0
687 if (canonical->sysno == __NR_exit) {
688 canonical->arg1 = gst->guest_r4; // a0
689 canonical->arg2 = 0;
690 canonical->arg3 = 0;
691 canonical->arg4 = 0;
692 canonical->arg5 = 0;
693 canonical->arg6 = 0;
694 canonical->arg8 = 0;
695 } else if (canonical->sysno != __NR_syscall) {
696 canonical->arg1 = gst->guest_r4; // a0
697 canonical->arg2 = gst->guest_r5; // a1
698 canonical->arg3 = gst->guest_r6; // a2
699 canonical->arg4 = gst->guest_r7; // a3
700 canonical->arg5 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP)
701 canonical->arg6 = *((UInt*) (gst->guest_r29 + 20)); // 20(guest_SP)
702 canonical->arg7 = *((UInt*) (gst->guest_r29 + 24)); // 24(guest_SP)
703 canonical->arg8 = 0;
704 } else {
705 // Fixme hack handle syscall()
706 canonical->sysno = gst->guest_r4; // a0
707 canonical->arg1 = gst->guest_r5; // a1
708 canonical->arg2 = gst->guest_r6; // a2
709 canonical->arg3 = gst->guest_r7; // a3
710 canonical->arg4 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP/sp)
711 canonical->arg5 = *((UInt*) (gst->guest_r29 + 20)); // 20(guest_SP/sp)
712 canonical->arg6 = *((UInt*) (gst->guest_r29 + 24)); // 24(guest_SP/sp)
713 canonical->arg7 = *((UInt*) (gst->guest_r29 + 28)); // 28(guest_SP/sp)
714 canonical->arg8 = __NR_syscall;
717 #elif defined(VGP_mips64_linux)
718 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
719 canonical->sysno = gst->guest_r2; // v0
720 canonical->arg1 = gst->guest_r4; // a0
721 canonical->arg2 = gst->guest_r5; // a1
722 canonical->arg3 = gst->guest_r6; // a2
723 canonical->arg4 = gst->guest_r7; // a3
724 canonical->arg5 = gst->guest_r8; // a4
725 canonical->arg6 = gst->guest_r9; // a5
726 canonical->arg7 = gst->guest_r10; // a6
727 canonical->arg8 = gst->guest_r11; // a7
729 #elif defined(VGP_nanomips_linux)
730 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
731 canonical->sysno = gst->guest_r2; // t4
732 canonical->arg1 = gst->guest_r4; // a0
733 canonical->arg2 = gst->guest_r5; // a1
734 canonical->arg3 = gst->guest_r6; // a2
735 canonical->arg4 = gst->guest_r7; // a3
736 canonical->arg5 = gst->guest_r8; // a4
737 canonical->arg6 = gst->guest_r9; // a5
738 canonical->arg7 = gst->guest_r10; // a6
739 canonical->arg8 = gst->guest_r11; // a7
740 #elif defined(VGP_x86_darwin)
741 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
742 UWord *stack = (UWord *)gst->guest_ESP;
743 // GrP fixme hope syscalls aren't called with really shallow stacks...
744 canonical->sysno = gst->guest_EAX;
745 if (canonical->sysno != 0) {
746 // stack[0] is return address
747 canonical->arg1 = stack[1];
748 canonical->arg2 = stack[2];
749 canonical->arg3 = stack[3];
750 canonical->arg4 = stack[4];
751 canonical->arg5 = stack[5];
752 canonical->arg6 = stack[6];
753 canonical->arg7 = stack[7];
754 canonical->arg8 = stack[8];
755 } else {
756 // GrP fixme hack handle syscall()
757 // GrP fixme what about __syscall() ?
758 // stack[0] is return address
759 // DDD: the tool can't see that the params have been shifted! Can
760 // lead to incorrect checking, I think, because the PRRAn/PSARn
761 // macros will mention the pre-shifted args.
762 canonical->sysno = stack[1];
763 vg_assert(canonical->sysno != 0);
764 canonical->arg1 = stack[2];
765 canonical->arg2 = stack[3];
766 canonical->arg3 = stack[4];
767 canonical->arg4 = stack[5];
768 canonical->arg5 = stack[6];
769 canonical->arg6 = stack[7];
770 canonical->arg7 = stack[8];
771 canonical->arg8 = stack[9];
773 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
774 VG_(getpid)(), /*tid,*/
775 VG_SYSNUM_STRING(canonical->sysno));
778 // Here we determine what kind of syscall it was by looking at the
779 // interrupt kind, and then encode the syscall number using the 64-bit
780 // encoding for Valgrind's internal use.
782 // DDD: Would it be better to stash the JMP kind into the Darwin
783 // thread state rather than passing in the trc?
784 switch (trc) {
785 case VEX_TRC_JMP_SYS_INT128:
786 // int $0x80 = Unix, 64-bit result
787 vg_assert(canonical->sysno >= 0);
788 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno);
789 break;
790 case VEX_TRC_JMP_SYS_SYSENTER:
791 // syscall = Unix, 32-bit result
792 // OR Mach, 32-bit result
793 if (canonical->sysno >= 0) {
794 // GrP fixme hack: 0xffff == I386_SYSCALL_NUMBER_MASK
795 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno
796 & 0xffff);
797 } else {
798 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno);
800 break;
801 case VEX_TRC_JMP_SYS_INT129:
802 // int $0x81 = Mach, 32-bit result
803 vg_assert(canonical->sysno < 0);
804 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno);
805 break;
806 case VEX_TRC_JMP_SYS_INT130:
807 // int $0x82 = mdep, 32-bit result
808 vg_assert(canonical->sysno >= 0);
809 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->sysno);
810 break;
811 default:
812 vg_assert(0);
813 break;
816 #elif defined(VGP_amd64_darwin)
817 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
818 UWord *stack = (UWord *)gst->guest_RSP;
820 vg_assert(trc == VEX_TRC_JMP_SYS_SYSCALL);
822 // GrP fixme hope syscalls aren't called with really shallow stacks...
823 canonical->sysno = gst->guest_RAX;
824 if (canonical->sysno != __NR_syscall) {
825 // stack[0] is return address
826 canonical->arg1 = gst->guest_RDI;
827 canonical->arg2 = gst->guest_RSI;
828 canonical->arg3 = gst->guest_RDX;
829 canonical->arg4 = gst->guest_R10; // not rcx with syscall insn
830 canonical->arg5 = gst->guest_R8;
831 canonical->arg6 = gst->guest_R9;
832 canonical->arg7 = stack[1];
833 canonical->arg8 = stack[2];
834 } else {
835 // GrP fixme hack handle syscall()
836 // GrP fixme what about __syscall() ?
837 // stack[0] is return address
838 // DDD: the tool can't see that the params have been shifted! Can
839 // lead to incorrect checking, I think, because the PRRAn/PSARn
840 // macros will mention the pre-shifted args.
841 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI);
842 vg_assert(canonical->sysno != __NR_syscall);
843 canonical->arg1 = gst->guest_RSI;
844 canonical->arg2 = gst->guest_RDX;
845 canonical->arg3 = gst->guest_R10; // not rcx with syscall insn
846 canonical->arg4 = gst->guest_R8;
847 canonical->arg5 = gst->guest_R9;
848 canonical->arg6 = stack[1];
849 canonical->arg7 = stack[2];
850 canonical->arg8 = stack[3];
852 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
853 VG_(getpid)(), /*tid,*/
854 VG_SYSNUM_STRING(canonical->sysno));
857 // no canonical->sysno adjustment needed
859 #elif defined(VGP_s390x_linux)
860 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
861 canonical->sysno = gst->guest_SYSNO;
862 canonical->arg1 = gst->guest_r2;
863 canonical->arg2 = gst->guest_r3;
864 canonical->arg3 = gst->guest_r4;
865 canonical->arg4 = gst->guest_r5;
866 canonical->arg5 = gst->guest_r6;
867 canonical->arg6 = gst->guest_r7;
868 canonical->arg7 = 0;
869 canonical->arg8 = 0;
871 #elif defined(VGP_x86_solaris)
872 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
873 UWord *stack = (UWord *)gst->guest_ESP;
874 canonical->sysno = gst->guest_EAX;
875 /* stack[0] is a return address. */
876 canonical->arg1 = stack[1];
877 canonical->arg2 = stack[2];
878 canonical->arg3 = stack[3];
879 canonical->arg4 = stack[4];
880 canonical->arg5 = stack[5];
881 canonical->arg6 = stack[6];
882 canonical->arg7 = stack[7];
883 canonical->arg8 = stack[8];
885 switch (trc) {
886 case VEX_TRC_JMP_SYS_INT145:
887 case VEX_TRC_JMP_SYS_SYSENTER:
888 case VEX_TRC_JMP_SYS_SYSCALL:
889 /* These three are not actually valid syscall instructions on Solaris.
890 Pretend for now that we handle them as normal syscalls. */
891 case VEX_TRC_JMP_SYS_INT128:
892 case VEX_TRC_JMP_SYS_INT129:
893 case VEX_TRC_JMP_SYS_INT130:
894 /* int $0x91, sysenter, syscall = normal syscall */
895 break;
896 case VEX_TRC_JMP_SYS_INT210:
897 /* int $0xD2 = fasttrap */
898 canonical->sysno
899 = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno);
900 break;
901 default:
902 vg_assert(0);
903 break;
906 #elif defined(VGP_amd64_solaris)
907 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
908 UWord *stack = (UWord *)gst->guest_RSP;
909 canonical->sysno = gst->guest_RAX;
910 /* stack[0] is a return address. */
911 canonical->arg1 = gst->guest_RDI;
912 canonical->arg2 = gst->guest_RSI;
913 canonical->arg3 = gst->guest_RDX;
914 canonical->arg4 = gst->guest_R10; /* Not RCX with syscall. */
915 canonical->arg5 = gst->guest_R8;
916 canonical->arg6 = gst->guest_R9;
917 canonical->arg7 = stack[1];
918 canonical->arg8 = stack[2];
920 switch (trc) {
921 case VEX_TRC_JMP_SYS_SYSCALL:
922 /* syscall = normal syscall */
923 break;
924 case VEX_TRC_JMP_SYS_INT210:
925 /* int $0xD2 = fasttrap */
926 canonical->sysno
927 = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno);
928 break;
929 default:
930 vg_assert(0);
931 break;
934 #else
935 # error "getSyscallArgsFromGuestState: unknown arch"
936 #endif
939 static
940 void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical,
941 /*OUT*/VexGuestArchState* gst_vanilla )
943 #if defined(VGP_x86_linux)
944 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
945 gst->guest_EAX = canonical->sysno;
946 gst->guest_EBX = canonical->arg1;
947 gst->guest_ECX = canonical->arg2;
948 gst->guest_EDX = canonical->arg3;
949 gst->guest_ESI = canonical->arg4;
950 gst->guest_EDI = canonical->arg5;
951 gst->guest_EBP = canonical->arg6;
953 #elif defined(VGP_amd64_linux)
954 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
955 gst->guest_RAX = canonical->sysno;
956 gst->guest_RDI = canonical->arg1;
957 gst->guest_RSI = canonical->arg2;
958 gst->guest_RDX = canonical->arg3;
959 gst->guest_R10 = canonical->arg4;
960 gst->guest_R8 = canonical->arg5;
961 gst->guest_R9 = canonical->arg6;
963 #elif defined(VGP_ppc32_linux)
964 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
965 gst->guest_GPR0 = canonical->sysno;
966 gst->guest_GPR3 = canonical->arg1;
967 gst->guest_GPR4 = canonical->arg2;
968 gst->guest_GPR5 = canonical->arg3;
969 gst->guest_GPR6 = canonical->arg4;
970 gst->guest_GPR7 = canonical->arg5;
971 gst->guest_GPR8 = canonical->arg6;
973 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
974 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
975 gst->guest_GPR0 = canonical->sysno;
976 gst->guest_GPR3 = canonical->arg1;
977 gst->guest_GPR4 = canonical->arg2;
978 gst->guest_GPR5 = canonical->arg3;
979 gst->guest_GPR6 = canonical->arg4;
980 gst->guest_GPR7 = canonical->arg5;
981 gst->guest_GPR8 = canonical->arg6;
982 gst->guest_GPR9 = canonical->arg7;
984 #elif defined(VGP_x86_freebsd)
985 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
986 UWord *stack = (UWord *)gst->guest_ESP;
988 // stack[0] is a (fake) return address
989 switch (canonical->klass) {
990 case VG_FREEBSD_SYSCALL0:
991 gst->guest_EAX = __NR_syscall;
992 stack[1] = canonical->sysno;
993 stack++;
994 break;
995 case VG_FREEBSD_SYSCALL198:
996 gst->guest_EAX = __NR___syscall;
997 stack[1] = canonical->sysno;
998 stack += 2;
999 break;
1000 default:
1001 gst->guest_EAX = canonical->sysno;
1002 break;
1005 stack[1] = canonical->arg1;
1006 stack[2] = canonical->arg2;
1007 stack[3] = canonical->arg3;
1008 stack[4] = canonical->arg4;
1009 stack[5] = canonical->arg5;
1010 stack[6] = canonical->arg6;
1011 stack[7] = canonical->arg7;
1012 stack[8] = canonical->arg8;
1014 #elif defined(VGP_amd64_freebsd)
1015 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1016 UWord *stack = (UWord *)gst->guest_RSP;
1018 // stack[0] is a (fake) return address
1019 switch (canonical->klass) {
1020 case VG_FREEBSD_SYSCALL0:
1021 gst->guest_RAX = __NR_syscall;
1022 break;
1023 case VG_FREEBSD_SYSCALL198:
1024 gst->guest_RAX = __NR___syscall;
1025 break;
1026 default:
1027 gst->guest_RAX = canonical->sysno;
1028 break;
1031 if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
1032 gst->guest_RDI = canonical->sysno;
1033 gst->guest_RSI = canonical->arg1;
1034 gst->guest_RDX = canonical->arg2;
1035 gst->guest_R10 = canonical->arg3;
1036 gst->guest_R8 = canonical->arg4;
1037 gst->guest_R9 = canonical->arg5;
1038 stack[1] = canonical->arg6;
1039 stack[2] = canonical->arg7;
1040 stack[3] = canonical->arg8;
1041 } else {
1042 gst->guest_RDI = canonical->arg1;
1043 gst->guest_RSI = canonical->arg2;
1044 gst->guest_RDX = canonical->arg3;
1045 gst->guest_R10 = canonical->arg4;
1046 gst->guest_R8 = canonical->arg5;
1047 gst->guest_R9 = canonical->arg6;
1048 stack[1] = canonical->arg7;
1049 stack[2] = canonical->arg8;
1052 #elif defined(VGP_arm64_freebsd)
1053 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1054 switch (canonical->klass) {
1055 case VG_FREEBSD_SYSCALL0:
1056 gst->guest_X8 = __NR_syscall;
1057 break;
1058 case VG_FREEBSD_SYSCALL198:
1059 gst->guest_X8 = __NR___syscall;
1060 break;
1061 default:
1062 gst->guest_X8 = canonical->sysno;
1063 break;
1065 if (canonical->klass == VG_FREEBSD_SYSCALL0 || canonical->klass == VG_FREEBSD_SYSCALL198) {
1066 gst->guest_X0 = canonical->sysno;
1067 gst->guest_X1 = canonical->arg1;
1068 gst->guest_X2 = canonical->arg2;
1069 gst->guest_X3 = canonical->arg3;
1070 gst->guest_X4 = canonical->arg4;
1071 gst->guest_X5 = canonical->arg5;
1072 gst->guest_X6 = canonical->arg6;
1073 gst->guest_X7 = canonical->arg7;
1074 } else {
1075 gst->guest_X0 = canonical->arg1;
1076 gst->guest_X1 = canonical->arg2;
1077 gst->guest_X2 = canonical->arg3;
1078 gst->guest_X3 = canonical->arg4;
1079 gst->guest_X4 = canonical->arg5;
1080 gst->guest_X5 = canonical->arg6;
1081 gst->guest_X6 = canonical->arg7;
1084 #elif defined(VGP_arm_linux)
1085 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
1086 gst->guest_R7 = canonical->sysno;
1087 gst->guest_R0 = canonical->arg1;
1088 gst->guest_R1 = canonical->arg2;
1089 gst->guest_R2 = canonical->arg3;
1090 gst->guest_R3 = canonical->arg4;
1091 gst->guest_R4 = canonical->arg5;
1092 gst->guest_R5 = canonical->arg6;
1094 #elif defined(VGP_arm64_linux)
1095 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1096 gst->guest_X8 = canonical->sysno;
1097 gst->guest_X0 = canonical->arg1;
1098 gst->guest_X1 = canonical->arg2;
1099 gst->guest_X2 = canonical->arg3;
1100 gst->guest_X3 = canonical->arg4;
1101 gst->guest_X4 = canonical->arg5;
1102 gst->guest_X5 = canonical->arg6;
1104 #elif defined(VGP_x86_darwin)
1105 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1106 UWord *stack = (UWord *)gst->guest_ESP;
1108 gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
1110 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
1111 // stack[0] is return address
1112 stack[1] = canonical->arg1;
1113 stack[2] = canonical->arg2;
1114 stack[3] = canonical->arg3;
1115 stack[4] = canonical->arg4;
1116 stack[5] = canonical->arg5;
1117 stack[6] = canonical->arg6;
1118 stack[7] = canonical->arg7;
1119 stack[8] = canonical->arg8;
1121 #elif defined(VGP_amd64_darwin)
1122 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1123 UWord *stack = (UWord *)gst->guest_RSP;
1125 gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
1126 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
1128 // stack[0] is return address
1129 gst->guest_RDI = canonical->arg1;
1130 gst->guest_RSI = canonical->arg2;
1131 gst->guest_RDX = canonical->arg3;
1132 gst->guest_RCX = canonical->arg4;
1133 gst->guest_R8 = canonical->arg5;
1134 gst->guest_R9 = canonical->arg6;
1135 stack[1] = canonical->arg7;
1136 stack[2] = canonical->arg8;
1138 #elif defined(VGP_s390x_linux)
1139 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
1140 gst->guest_SYSNO = canonical->sysno;
1141 gst->guest_r2 = canonical->arg1;
1142 gst->guest_r3 = canonical->arg2;
1143 gst->guest_r4 = canonical->arg3;
1144 gst->guest_r5 = canonical->arg4;
1145 gst->guest_r6 = canonical->arg5;
1146 gst->guest_r7 = canonical->arg6;
1148 #elif defined(VGP_mips32_linux)
1149 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1150 if (canonical->arg8 != __NR_syscall) {
1151 gst->guest_r2 = canonical->sysno;
1152 gst->guest_r4 = canonical->arg1;
1153 gst->guest_r5 = canonical->arg2;
1154 gst->guest_r6 = canonical->arg3;
1155 gst->guest_r7 = canonical->arg4;
1156 *((UInt*) (gst->guest_r29 + 16)) = canonical->arg5; // 16(guest_GPR29/sp)
1157 *((UInt*) (gst->guest_r29 + 20)) = canonical->arg6; // 20(sp)
1158 *((UInt*) (gst->guest_r29 + 24)) = canonical->arg7; // 24(sp)
1159 } else {
1160 canonical->arg8 = 0;
1161 gst->guest_r2 = __NR_syscall;
1162 gst->guest_r4 = canonical->sysno;
1163 gst->guest_r5 = canonical->arg1;
1164 gst->guest_r6 = canonical->arg2;
1165 gst->guest_r7 = canonical->arg3;
1166 *((UInt*) (gst->guest_r29 + 16)) = canonical->arg4; // 16(guest_GPR29/sp)
1167 *((UInt*) (gst->guest_r29 + 20)) = canonical->arg5; // 20(sp)
1168 *((UInt*) (gst->guest_r29 + 24)) = canonical->arg6; // 24(sp)
1169 *((UInt*) (gst->guest_r29 + 28)) = canonical->arg7; // 28(sp)
1172 #elif defined(VGP_nanomips_linux)
1173 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1174 gst->guest_r2 = canonical->sysno;
1175 gst->guest_r4 = canonical->arg1;
1176 gst->guest_r5 = canonical->arg2;
1177 gst->guest_r6 = canonical->arg3;
1178 gst->guest_r7 = canonical->arg4;
1179 gst->guest_r8 = canonical->arg5;
1180 gst->guest_r9 = canonical->arg6;
1181 gst->guest_r10 = canonical->arg7;
1182 gst->guest_r11 = canonical->arg8;
1183 #elif defined(VGP_mips64_linux)
1184 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
1185 gst->guest_r2 = canonical->sysno;
1186 gst->guest_r4 = canonical->arg1;
1187 gst->guest_r5 = canonical->arg2;
1188 gst->guest_r6 = canonical->arg3;
1189 gst->guest_r7 = canonical->arg4;
1190 gst->guest_r8 = canonical->arg5;
1191 gst->guest_r9 = canonical->arg6;
1192 gst->guest_r10 = canonical->arg7;
1193 gst->guest_r11 = canonical->arg8;
1195 #elif defined(VGP_x86_solaris)
1196 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1197 UWord *stack = (UWord *)gst->guest_ESP;
1199 /* Fasttraps or anything else cannot go through this way. */
1200 vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno)
1201 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
1202 gst->guest_EAX = canonical->sysno;
1203 /* stack[0] is a return address. */
1204 stack[1] = canonical->arg1;
1205 stack[2] = canonical->arg2;
1206 stack[3] = canonical->arg3;
1207 stack[4] = canonical->arg4;
1208 stack[5] = canonical->arg5;
1209 stack[6] = canonical->arg6;
1210 stack[7] = canonical->arg7;
1211 stack[8] = canonical->arg8;
1213 #elif defined(VGP_amd64_solaris)
1214 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1215 UWord *stack = (UWord *)gst->guest_RSP;
1217 /* Fasttraps or anything else cannot go through this way. */
1218 vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno)
1219 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
1220 gst->guest_RAX = canonical->sysno;
1221 /* stack[0] is a return address. */
1222 gst->guest_RDI = canonical->arg1;
1223 gst->guest_RSI = canonical->arg2;
1224 gst->guest_RDX = canonical->arg3;
1225 gst->guest_R10 = canonical->arg4;
1226 gst->guest_R8 = canonical->arg5;
1227 gst->guest_R9 = canonical->arg6;
1228 stack[1] = canonical->arg7;
1229 stack[2] = canonical->arg8;
1231 #else
1232 # error "putSyscallArgsIntoGuestState: unknown arch"
1233 #endif
1236 static
1237 void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus* canonical,
1238 /*IN*/ VexGuestArchState* gst_vanilla )
1240 # if defined(VGP_x86_linux)
1241 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1242 canonical->sres = VG_(mk_SysRes_x86_linux)( gst->guest_EAX );
1243 canonical->what = SsComplete;
1245 # elif defined(VGP_amd64_linux)
1246 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1247 canonical->sres = VG_(mk_SysRes_amd64_linux)( gst->guest_RAX );
1248 canonical->what = SsComplete;
1250 # elif defined(VGP_ppc32_linux)
1251 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
1252 UInt cr = LibVEX_GuestPPC32_get_CR( gst );
1253 UInt cr0so = (cr >> 28) & 1;
1254 canonical->sres = VG_(mk_SysRes_ppc32_linux)( gst->guest_GPR3, cr0so );
1255 canonical->what = SsComplete;
1257 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1258 /* There is a Valgrind specific guest state register guest_syscall_flag
1259 that is set to zero to indicate if the sc instruction was used or one
1260 if the scv instruction was used for the system call. */
1261 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
1262 UInt cr = LibVEX_GuestPPC64_get_CR( gst );
1263 UInt cr0so = (cr >> 28) & 1;
1264 UInt flag = gst->guest_syscall_flag;
1266 canonical->sres = VG_(mk_SysRes_ppc64_linux)( gst->guest_GPR3, cr0so, flag );
1267 canonical->what = SsComplete;
1269 # elif defined(VGP_x86_freebsd)
1270 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1271 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1272 UInt flags = LibVEX_GuestX86_get_eflags(gst);
1274 canonical->sres = VG_(mk_SysRes_x86_freebsd)(gst->guest_EAX, gst->guest_EDX,
1275 (flags & 1) != 0 ? True : False);
1276 canonical->what = SsComplete;
1278 # elif defined(VGP_arm_linux)
1279 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
1280 canonical->sres = VG_(mk_SysRes_arm_linux)( gst->guest_R0 );
1281 canonical->what = SsComplete;
1283 # elif defined(VGP_arm64_linux)
1284 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1285 canonical->sres = VG_(mk_SysRes_arm64_linux)( gst->guest_X0 );
1286 canonical->what = SsComplete;
1288 # elif defined(VGP_mips32_linux)
1289 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1290 UInt v0 = gst->guest_r2; // v0
1291 UInt v1 = gst->guest_r3; // v1
1292 UInt a3 = gst->guest_r7; // a3
1293 canonical->sres = VG_(mk_SysRes_mips32_linux)( v0, v1, a3 );
1294 canonical->what = SsComplete;
1296 # elif defined(VGP_mips64_linux)
1297 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
1298 ULong v0 = gst->guest_r2; // v0
1299 ULong v1 = gst->guest_r3; // v1
1300 ULong a3 = gst->guest_r7; // a3
1301 canonical->sres = VG_(mk_SysRes_mips64_linux)(v0, v1, a3);
1302 canonical->what = SsComplete;
1304 # elif defined(VGP_nanomips_linux)
1305 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1306 RegWord a0 = gst->guest_r4; // a0
1307 canonical->sres = VG_(mk_SysRes_nanomips_linux)(a0);
1308 canonical->what = SsComplete;
1310 # elif defined(VGP_amd64_freebsd)
1311 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1312 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1313 ULong flags = LibVEX_GuestAMD64_get_rflags(gst);
1314 canonical->sres = VG_(mk_SysRes_amd64_freebsd)(gst->guest_RAX, gst->guest_RDX,
1315 (flags & 1) != 0 ? True : False);
1316 canonical->what = SsComplete;
1318 # elif defined(VGP_arm64_freebsd)
1319 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1320 ULong flags = LibVEX_GuestARM64_get_nzcv(gst);
1321 canonical->sres = VG_(mk_SysRes_arm64_freebsd)(gst->guest_X0, gst->guest_X1,
1322 (flags & VKI_PSR_C) != 0 ? True : False);
1323 canonical->what = SsComplete;
1325 # elif defined(VGP_x86_darwin)
1326 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1327 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1328 UInt carry = 1 & LibVEX_GuestX86_get_eflags(gst);
1329 UInt err = 0;
1330 UInt wLO = 0;
1331 UInt wHI = 0;
1332 switch (gst->guest_SC_CLASS) {
1333 case VG_DARWIN_SYSCALL_CLASS_UNIX:
1334 // int $0x80 = Unix, 64-bit result
1335 err = carry;
1336 wLO = gst->guest_EAX;
1337 wHI = gst->guest_EDX;
1338 break;
1339 case VG_DARWIN_SYSCALL_CLASS_MACH:
1340 // int $0x81 = Mach, 32-bit result
1341 wLO = gst->guest_EAX;
1342 break;
1343 case VG_DARWIN_SYSCALL_CLASS_MDEP:
1344 // int $0x82 = mdep, 32-bit result
1345 wLO = gst->guest_EAX;
1346 break;
1347 default:
1348 vg_assert(0);
1349 break;
1351 canonical->sres = VG_(mk_SysRes_x86_darwin)(
1352 gst->guest_SC_CLASS, err ? True : False,
1353 wHI, wLO
1355 canonical->what = SsComplete;
1357 # elif defined(VGP_amd64_darwin)
1358 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1359 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1360 ULong carry = 1 & LibVEX_GuestAMD64_get_rflags(gst);
1361 ULong err = 0;
1362 ULong wLO = 0;
1363 ULong wHI = 0;
1364 switch (gst->guest_SC_CLASS) {
1365 case VG_DARWIN_SYSCALL_CLASS_UNIX:
1366 // syscall = Unix, 128-bit result
1367 err = carry;
1368 wLO = gst->guest_RAX;
1369 wHI = gst->guest_RDX;
1370 break;
1371 case VG_DARWIN_SYSCALL_CLASS_MACH:
1372 // syscall = Mach, 64-bit result
1373 wLO = gst->guest_RAX;
1374 break;
1375 case VG_DARWIN_SYSCALL_CLASS_MDEP:
1376 // syscall = mdep, 64-bit result
1377 wLO = gst->guest_RAX;
1378 break;
1379 default:
1380 vg_assert(0);
1381 break;
1383 canonical->sres = VG_(mk_SysRes_amd64_darwin)(
1384 gst->guest_SC_CLASS, err ? True : False,
1385 wHI, wLO
1387 canonical->what = SsComplete;
1389 # elif defined(VGP_s390x_linux)
1390 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
1391 canonical->sres = VG_(mk_SysRes_s390x_linux)( gst->guest_r2 );
1392 canonical->what = SsComplete;
1394 # elif defined(VGP_x86_solaris)
1395 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1396 UInt carry = 1 & LibVEX_GuestX86_get_eflags(gst);
1398 canonical->sres = VG_(mk_SysRes_x86_solaris)(carry ? True : False,
1399 gst->guest_EAX,
1400 carry ? 0 : gst->guest_EDX);
1401 canonical->what = SsComplete;
1403 # elif defined(VGP_amd64_solaris)
1404 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1405 UInt carry = 1 & LibVEX_GuestAMD64_get_rflags(gst);
1407 canonical->sres = VG_(mk_SysRes_amd64_solaris)(carry ? True : False,
1408 gst->guest_RAX,
1409 carry ? 0 : gst->guest_RDX);
1410 canonical->what = SsComplete;
1412 # else
1413 # error "getSyscallStatusFromGuestState: unknown arch"
1414 # endif
1417 static
1418 void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid,
1419 /*IN*/ SyscallStatus* canonical,
1420 /*OUT*/VexGuestArchState* gst_vanilla )
1422 # if defined(VGP_x86_linux)
1423 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1424 vg_assert(canonical->what == SsComplete);
1425 if (sr_isError(canonical->sres)) {
1426 /* This isn't exactly right, in that really a Failure with res
1427 not in the range 1 .. 4095 is unrepresentable in the
1428 Linux-x86 scheme. Oh well. */
1429 gst->guest_EAX = - (Int)sr_Err(canonical->sres);
1430 } else {
1431 gst->guest_EAX = sr_Res(canonical->sres);
1433 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1434 OFFSET_x86_EAX, sizeof(UWord) );
1436 # elif defined(VGP_amd64_linux)
1437 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1438 vg_assert(canonical->what == SsComplete);
1439 if (sr_isError(canonical->sres)) {
1440 /* This isn't exactly right, in that really a Failure with res
1441 not in the range 1 .. 4095 is unrepresentable in the
1442 Linux-amd64 scheme. Oh well. */
1443 gst->guest_RAX = - (Long)sr_Err(canonical->sres);
1444 } else {
1445 gst->guest_RAX = sr_Res(canonical->sres);
1447 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1448 OFFSET_amd64_RAX, sizeof(UWord) );
1450 # elif defined(VGP_ppc32_linux)
1451 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
1452 UInt old_cr = LibVEX_GuestPPC32_get_CR(gst);
1453 vg_assert(canonical->what == SsComplete);
1454 if (sr_isError(canonical->sres)) {
1455 /* set CR0.SO */
1456 LibVEX_GuestPPC32_put_CR( old_cr | (1<<28), gst );
1457 gst->guest_GPR3 = sr_Err(canonical->sres);
1458 } else {
1459 /* clear CR0.SO */
1460 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), gst );
1461 gst->guest_GPR3 = sr_Res(canonical->sres);
1463 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1464 OFFSET_ppc32_GPR3, sizeof(UWord) );
1465 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1466 OFFSET_ppc32_CR0_0, sizeof(UChar) );
1468 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1469 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
1470 UInt old_cr = LibVEX_GuestPPC64_get_CR(gst);
1471 UInt flag = gst->guest_syscall_flag;
1473 vg_assert(canonical->what == SsComplete);
1474 if (flag == SC_FLAG) {
1475 /* sc syscall */
1476 if (sr_isError(canonical->sres)) {
1477 /* set CR0.SO */
1478 LibVEX_GuestPPC64_put_CR( old_cr | (1<<28), gst );
1479 gst->guest_GPR3 = sr_Err(canonical->sres);
1480 } else {
1481 /* clear CR0.SO */
1482 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), gst );
1483 gst->guest_GPR3 = sr_Res(canonical->sres);
1485 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1486 OFFSET_ppc64_GPR3, sizeof(UWord) );
1487 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1488 OFFSET_ppc64_CR0_0, sizeof(UChar) );
1489 } else {
1490 /* scv system call instruction */
1491 if (sr_isError(canonical->sres))
1492 gst->guest_GPR3 = - (Long)canonical->sres._val;
1493 else
1494 gst->guest_GPR3 = canonical->sres._val;
1496 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1497 OFFSET_ppc64_GPR3, sizeof(UWord) );
1500 # elif defined(VGP_arm_linux)
1501 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
1502 vg_assert(canonical->what == SsComplete);
1503 if (sr_isError(canonical->sres)) {
1504 /* This isn't exactly right, in that really a Failure with res
1505 not in the range 1 .. 4095 is unrepresentable in the
1506 Linux-arm scheme. Oh well. */
1507 gst->guest_R0 = - (Int)sr_Err(canonical->sres);
1508 } else {
1509 gst->guest_R0 = sr_Res(canonical->sres);
1511 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1512 OFFSET_arm_R0, sizeof(UWord) );
1514 # elif defined(VGP_arm64_linux)
1515 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1516 vg_assert(canonical->what == SsComplete);
1517 if (sr_isError(canonical->sres)) {
1518 /* This isn't exactly right, in that really a Failure with res
1519 not in the range 1 .. 4095 is unrepresentable in the
1520 Linux-arm64 scheme. Oh well. */
1521 gst->guest_X0 = - (Long)sr_Err(canonical->sres);
1522 } else {
1523 gst->guest_X0 = sr_Res(canonical->sres);
1525 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1526 OFFSET_arm64_X0, sizeof(UWord) );
1528 #elif defined(VGP_x86_freebsd)
1529 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1530 vg_assert(canonical->what == SsComplete);
1531 if (sr_isError(canonical->sres)) {
1532 gst->guest_EAX = sr_Err(canonical->sres);
1533 LibVEX_GuestX86_put_eflag_c(1, gst);
1534 } else {
1535 gst->guest_EAX = sr_Res(canonical->sres);
1536 gst->guest_EDX = sr_ResHI(canonical->sres);
1537 LibVEX_GuestX86_put_eflag_c(0, gst);
1539 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1540 OFFSET_x86_EAX, sizeof(UInt) );
1541 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1542 OFFSET_x86_EDX, sizeof(UInt) );
1543 // GrP fixme sets defined for entire eflags, not just bit c
1544 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1545 offsetof(VexGuestX86State, guest_CC_DEP1), sizeof(UInt) );
1547 #elif defined(VGP_amd64_freebsd)
1548 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1549 vg_assert(canonical->what == SsComplete);
1550 if (sr_isError(canonical->sres)) {
1551 gst->guest_RAX = sr_Err(canonical->sres);
1552 LibVEX_GuestAMD64_put_rflag_c(1, gst);
1553 } else {
1554 gst->guest_RAX = sr_Res(canonical->sres);
1555 gst->guest_RDX = sr_ResHI(canonical->sres);
1556 LibVEX_GuestAMD64_put_rflag_c(0, gst);
1558 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1559 OFFSET_amd64_RAX, sizeof(ULong) );
1560 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1561 OFFSET_amd64_RDX, sizeof(ULong) );
1562 // GrP fixme sets defined for entire eflags, not just bit c
1563 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1564 offsetof(VexGuestAMD64State, guest_CC_DEP1), sizeof(ULong) );
1566 # elif defined(VGP_arm64_freebsd)
1567 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1568 vg_assert(canonical->what == SsComplete);
1569 if (sr_isError(canonical->sres)) {
1570 gst->guest_X0 = sr_Err(canonical->sres);
1571 LibVEX_GuestARM64_put_nzcv_c(1, gst);
1572 } else {
1573 gst->guest_X0 = sr_Res(canonical->sres);
1574 gst->guest_X1 = sr_ResHI(canonical->sres);
1575 LibVEX_GuestARM64_put_nzcv_c(0, gst);
1578 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1579 OFFSET_arm64_X0, sizeof(ULong) );
1580 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1581 OFFSET_arm64_X1, sizeof(ULong) );
1582 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1583 offsetof(VexGuestARM64State, guest_CC_DEP1), sizeof(ULong) );
1585 #elif defined(VGP_x86_darwin)
1586 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1587 SysRes sres = canonical->sres;
1588 vg_assert(canonical->what == SsComplete);
1589 /* Unfortunately here we have to break abstraction and look
1590 directly inside 'res', in order to decide what to do. */
1591 switch (sres._mode) {
1592 case SysRes_MACH: // int $0x81 = Mach, 32-bit result
1593 case SysRes_MDEP: // int $0x82 = mdep, 32-bit result
1594 gst->guest_EAX = sres._wLO;
1595 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1596 OFFSET_x86_EAX, sizeof(UInt) );
1597 break;
1598 case SysRes_UNIX_OK: // int $0x80 = Unix, 64-bit result
1599 case SysRes_UNIX_ERR: // int $0x80 = Unix, 64-bit error
1600 gst->guest_EAX = sres._wLO;
1601 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1602 OFFSET_x86_EAX, sizeof(UInt) );
1603 gst->guest_EDX = sres._wHI;
1604 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1605 OFFSET_x86_EDX, sizeof(UInt) );
1606 LibVEX_GuestX86_put_eflag_c( sres._mode==SysRes_UNIX_ERR ? 1 : 0,
1607 gst );
1608 // GrP fixme sets defined for entire eflags, not just bit c
1609 // DDD: this breaks exp-ptrcheck.
1610 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1611 offsetof(VexGuestX86State, guest_CC_DEP1), sizeof(UInt) );
1612 break;
1613 default:
1614 vg_assert(0);
1615 break;
1618 #elif defined(VGP_amd64_darwin)
1619 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1620 SysRes sres = canonical->sres;
1621 vg_assert(canonical->what == SsComplete);
1622 /* Unfortunately here we have to break abstraction and look
1623 directly inside 'res', in order to decide what to do. */
1624 switch (sres._mode) {
1625 case SysRes_MACH: // syscall = Mach, 64-bit result
1626 case SysRes_MDEP: // syscall = mdep, 64-bit result
1627 gst->guest_RAX = sres._wLO;
1628 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1629 OFFSET_amd64_RAX, sizeof(ULong) );
1630 break;
1631 case SysRes_UNIX_OK: // syscall = Unix, 128-bit result
1632 case SysRes_UNIX_ERR: // syscall = Unix, 128-bit error
1633 gst->guest_RAX = sres._wLO;
1634 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1635 OFFSET_amd64_RAX, sizeof(ULong) );
1636 gst->guest_RDX = sres._wHI;
1637 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1638 OFFSET_amd64_RDX, sizeof(ULong) );
1639 LibVEX_GuestAMD64_put_rflag_c( sres._mode==SysRes_UNIX_ERR ? 1 : 0,
1640 gst );
1641 // GrP fixme sets defined for entire rflags, not just bit c
1642 // DDD: this breaks exp-ptrcheck.
1643 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1644 offsetof(VexGuestAMD64State, guest_CC_DEP1), sizeof(ULong) );
1645 break;
1646 default:
1647 vg_assert(0);
1648 break;
1651 # elif defined(VGP_s390x_linux)
1652 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
1653 vg_assert(canonical->what == SsComplete);
1654 if (sr_isError(canonical->sres)) {
1655 gst->guest_r2 = - (Long)sr_Err(canonical->sres);
1656 } else {
1657 gst->guest_r2 = sr_Res(canonical->sres);
1659 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1660 OFFSET_s390x_r2, sizeof(UWord) );
1662 # elif defined(VGP_mips32_linux)
1663 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1664 vg_assert(canonical->what == SsComplete);
1665 if (sr_isError(canonical->sres)) {
1666 gst->guest_r2 = (Int)sr_Err(canonical->sres);
1667 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1668 } else {
1669 gst->guest_r2 = sr_Res(canonical->sres);
1670 gst->guest_r3 = sr_ResEx(canonical->sres);
1671 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1673 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1674 OFFSET_mips32_r2, sizeof(UWord) );
1675 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1676 OFFSET_mips32_r3, sizeof(UWord) );
1677 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1678 OFFSET_mips32_r7, sizeof(UWord) );
1680 # elif defined(VGP_mips64_linux)
1681 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
1682 vg_assert(canonical->what == SsComplete);
1683 if (sr_isError(canonical->sres)) {
1684 gst->guest_r2 = (Int)sr_Err(canonical->sres);
1685 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1686 } else {
1687 gst->guest_r2 = sr_Res(canonical->sres);
1688 gst->guest_r3 = sr_ResEx(canonical->sres);
1689 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1691 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1692 OFFSET_mips64_r2, sizeof(UWord) );
1693 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1694 OFFSET_mips64_r3, sizeof(UWord) );
1695 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1696 OFFSET_mips64_r7, sizeof(UWord) );
1698 # elif defined(VGP_nanomips_linux)
1699 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1700 vg_assert(canonical->what == SsComplete);
1701 gst->guest_r4 = canonical->sres._val;
1702 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1703 OFFSET_mips32_r4, sizeof(UWord) );
1705 # elif defined(VGP_x86_solaris)
1706 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1707 SysRes sres = canonical->sres;
1708 vg_assert(canonical->what == SsComplete);
1710 if (sr_isError(sres)) {
1711 gst->guest_EAX = sr_Err(sres);
1712 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EAX,
1713 sizeof(UInt));
1714 LibVEX_GuestX86_put_eflag_c(1, gst);
1716 else {
1717 gst->guest_EAX = sr_Res(sres);
1718 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EAX,
1719 sizeof(UInt));
1720 gst->guest_EDX = sr_ResHI(sres);
1721 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EDX,
1722 sizeof(UInt));
1723 LibVEX_GuestX86_put_eflag_c(0, gst);
1725 /* Make CC_DEP1 and CC_DEP2 defined. This is inaccurate because it makes
1726 other eflags defined too (see README.solaris). */
1727 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestX86State,
1728 guest_CC_DEP1), sizeof(UInt));
1729 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestX86State,
1730 guest_CC_DEP2), sizeof(UInt));
1732 # elif defined(VGP_amd64_solaris)
1733 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1734 SysRes sres = canonical->sres;
1735 vg_assert(canonical->what == SsComplete);
1737 if (sr_isError(sres)) {
1738 gst->guest_RAX = sr_Err(sres);
1739 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RAX,
1740 sizeof(ULong));
1741 LibVEX_GuestAMD64_put_rflag_c(1, gst);
1743 else {
1744 gst->guest_RAX = sr_Res(sres);
1745 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RAX,
1746 sizeof(ULong));
1747 gst->guest_RDX = sr_ResHI(sres);
1748 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RDX,
1749 sizeof(ULong));
1750 LibVEX_GuestAMD64_put_rflag_c(0, gst);
1752 /* Make CC_DEP1 and CC_DEP2 defined. This is inaccurate because it makes
1753 other eflags defined too (see README.solaris). */
1754 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestAMD64State,
1755 guest_CC_DEP1), sizeof(ULong));
1756 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestAMD64State,
1757 guest_CC_DEP2), sizeof(ULong));
1759 # else
1760 # error "putSyscallStatusIntoGuestState: unknown arch"
1761 # endif
1765 /* Tell me the offsets in the guest state of the syscall params, so
1766 that the scalar argument checkers don't have to have this info
1767 hardwired. */
1769 static
1770 void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
1772 VG_(bzero_inline)(layout, sizeof(*layout));
1774 #if defined(VGP_x86_linux)
1775 layout->o_sysno = OFFSET_x86_EAX;
1776 layout->o_arg1 = OFFSET_x86_EBX;
1777 layout->o_arg2 = OFFSET_x86_ECX;
1778 layout->o_arg3 = OFFSET_x86_EDX;
1779 layout->o_arg4 = OFFSET_x86_ESI;
1780 layout->o_arg5 = OFFSET_x86_EDI;
1781 layout->o_arg6 = OFFSET_x86_EBP;
1782 layout->uu_arg7 = -1; /* impossible value */
1783 layout->uu_arg8 = -1; /* impossible value */
1785 #elif defined(VGP_amd64_linux)
1786 layout->o_sysno = OFFSET_amd64_RAX;
1787 layout->o_arg1 = OFFSET_amd64_RDI;
1788 layout->o_arg2 = OFFSET_amd64_RSI;
1789 layout->o_arg3 = OFFSET_amd64_RDX;
1790 layout->o_arg4 = OFFSET_amd64_R10;
1791 layout->o_arg5 = OFFSET_amd64_R8;
1792 layout->o_arg6 = OFFSET_amd64_R9;
1793 layout->uu_arg7 = -1; /* impossible value */
1794 layout->uu_arg8 = -1; /* impossible value */
1796 #elif defined(VGP_ppc32_linux)
1797 layout->o_sysno = OFFSET_ppc32_GPR0;
1798 layout->o_arg1 = OFFSET_ppc32_GPR3;
1799 layout->o_arg2 = OFFSET_ppc32_GPR4;
1800 layout->o_arg3 = OFFSET_ppc32_GPR5;
1801 layout->o_arg4 = OFFSET_ppc32_GPR6;
1802 layout->o_arg5 = OFFSET_ppc32_GPR7;
1803 layout->o_arg6 = OFFSET_ppc32_GPR8;
1804 layout->uu_arg7 = -1; /* impossible value */
1805 layout->uu_arg8 = -1; /* impossible value */
1807 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1808 layout->o_sysno = OFFSET_ppc64_GPR0;
1809 layout->o_arg1 = OFFSET_ppc64_GPR3;
1810 layout->o_arg2 = OFFSET_ppc64_GPR4;
1811 layout->o_arg3 = OFFSET_ppc64_GPR5;
1812 layout->o_arg4 = OFFSET_ppc64_GPR6;
1813 layout->o_arg5 = OFFSET_ppc64_GPR7;
1814 layout->o_arg6 = OFFSET_ppc64_GPR8;
1815 layout->o_arg7 = OFFSET_ppc64_GPR9;
1816 layout->uu_arg8 = -1; /* impossible value */
1818 #elif defined(VGP_x86_freebsd)
1819 layout->o_sysno = OFFSET_x86_EAX;
1820 // syscall parameters are on stack in C convention
1821 layout->s_arg1 = sizeof(UWord) * 1;
1822 layout->s_arg2 = sizeof(UWord) * 2;
1823 layout->s_arg3 = sizeof(UWord) * 3;
1824 layout->s_arg4 = sizeof(UWord) * 4;
1825 layout->s_arg5 = sizeof(UWord) * 5;
1826 layout->s_arg6 = sizeof(UWord) * 6;
1827 layout->s_arg7 = sizeof(UWord) * 7;
1828 layout->s_arg8 = sizeof(UWord) * 8;
1830 #elif defined(VGP_amd64_freebsd)
1831 layout->o_sysno = OFFSET_amd64_RAX;
1832 layout->o_arg1 = OFFSET_amd64_RDI;
1833 layout->o_arg2 = OFFSET_amd64_RSI;
1834 layout->o_arg3 = OFFSET_amd64_RDX;
1835 layout->o_arg4 = OFFSET_amd64_R10;
1836 layout->o_arg5 = OFFSET_amd64_R8;
1837 layout->o_arg6 = OFFSET_amd64_R9;
1838 layout->s_arg7 = sizeof(UWord) * 1;
1839 layout->s_arg8 = sizeof(UWord) * 2;
1840 layout->arg6_is_reg = True;
1842 #elif defined(VGP_arm64_freebsd)
1843 layout->o_sysno = OFFSET_arm64_X8;
1844 layout->o_arg1 = OFFSET_arm64_X0;
1845 layout->o_arg2 = OFFSET_arm64_X1;
1846 layout->o_arg3 = OFFSET_arm64_X2;
1847 layout->o_arg4 = OFFSET_arm64_X3;
1848 layout->o_arg5 = OFFSET_arm64_X4;
1849 layout->o_arg6 = OFFSET_arm64_X5;
1850 layout->o_arg7 = OFFSET_arm64_X6;
1851 layout->o_arg8 = OFFSET_arm64_X7;
1853 #elif defined(VGP_arm_linux)
1854 layout->o_sysno = OFFSET_arm_R7;
1855 layout->o_arg1 = OFFSET_arm_R0;
1856 layout->o_arg2 = OFFSET_arm_R1;
1857 layout->o_arg3 = OFFSET_arm_R2;
1858 layout->o_arg4 = OFFSET_arm_R3;
1859 layout->o_arg5 = OFFSET_arm_R4;
1860 layout->o_arg6 = OFFSET_arm_R5;
1861 layout->uu_arg7 = -1; /* impossible value */
1862 layout->uu_arg8 = -1; /* impossible value */
1864 #elif defined(VGP_arm64_linux)
1865 layout->o_sysno = OFFSET_arm64_X8;
1866 layout->o_arg1 = OFFSET_arm64_X0;
1867 layout->o_arg2 = OFFSET_arm64_X1;
1868 layout->o_arg3 = OFFSET_arm64_X2;
1869 layout->o_arg4 = OFFSET_arm64_X3;
1870 layout->o_arg5 = OFFSET_arm64_X4;
1871 layout->o_arg6 = OFFSET_arm64_X5;
1872 layout->uu_arg7 = -1; /* impossible value */
1873 layout->uu_arg8 = -1; /* impossible value */
1875 #elif defined(VGP_mips32_linux)
1876 layout->o_sysno = OFFSET_mips32_r2;
1877 layout->o_arg1 = OFFSET_mips32_r4;
1878 layout->o_arg2 = OFFSET_mips32_r5;
1879 layout->o_arg3 = OFFSET_mips32_r6;
1880 layout->o_arg4 = OFFSET_mips32_r7;
1881 layout->s_arg5 = sizeof(UWord) * 4;
1882 layout->s_arg6 = sizeof(UWord) * 5;
1883 layout->s_arg7 = sizeof(UWord) * 6;
1884 layout->uu_arg8 = -1; /* impossible value */
1886 #elif defined(VGP_nanomips_linux)
1887 layout->o_sysno = OFFSET_mips32_r2;
1888 layout->o_arg1 = OFFSET_mips32_r4;
1889 layout->o_arg2 = OFFSET_mips32_r5;
1890 layout->o_arg3 = OFFSET_mips32_r6;
1891 layout->o_arg4 = OFFSET_mips32_r7;
1892 layout->o_arg5 = OFFSET_mips32_r8;
1893 layout->o_arg6 = OFFSET_mips32_r9;
1894 layout->uu_arg7 = -1; /* impossible value */
1895 layout->uu_arg8 = -1; /* impossible value */
1897 #elif defined(VGP_mips64_linux)
1898 layout->o_sysno = OFFSET_mips64_r2;
1899 layout->o_arg1 = OFFSET_mips64_r4;
1900 layout->o_arg2 = OFFSET_mips64_r5;
1901 layout->o_arg3 = OFFSET_mips64_r6;
1902 layout->o_arg4 = OFFSET_mips64_r7;
1903 layout->o_arg5 = OFFSET_mips64_r8;
1904 layout->o_arg6 = OFFSET_mips64_r9;
1905 layout->o_arg7 = OFFSET_mips64_r10;
1906 layout->o_arg8 = OFFSET_mips64_r11;
1908 #elif defined(VGP_x86_darwin)
1909 layout->o_sysno = OFFSET_x86_EAX;
1910 // syscall parameters are on stack in C convention
1911 layout->s_arg1 = sizeof(UWord) * 1;
1912 layout->s_arg2 = sizeof(UWord) * 2;
1913 layout->s_arg3 = sizeof(UWord) * 3;
1914 layout->s_arg4 = sizeof(UWord) * 4;
1915 layout->s_arg5 = sizeof(UWord) * 5;
1916 layout->s_arg6 = sizeof(UWord) * 6;
1917 layout->s_arg7 = sizeof(UWord) * 7;
1918 layout->s_arg8 = sizeof(UWord) * 8;
1920 #elif defined(VGP_amd64_darwin)
1921 layout->o_sysno = OFFSET_amd64_RAX;
1922 layout->o_arg1 = OFFSET_amd64_RDI;
1923 layout->o_arg2 = OFFSET_amd64_RSI;
1924 layout->o_arg3 = OFFSET_amd64_RDX;
1925 layout->o_arg4 = OFFSET_amd64_RCX;
1926 layout->o_arg5 = OFFSET_amd64_R8;
1927 layout->o_arg6 = OFFSET_amd64_R9;
1928 layout->s_arg7 = sizeof(UWord) * 1;
1929 layout->s_arg8 = sizeof(UWord) * 2;
1931 #elif defined(VGP_s390x_linux)
1932 layout->o_sysno = OFFSET_s390x_SYSNO;
1933 layout->o_arg1 = OFFSET_s390x_r2;
1934 layout->o_arg2 = OFFSET_s390x_r3;
1935 layout->o_arg3 = OFFSET_s390x_r4;
1936 layout->o_arg4 = OFFSET_s390x_r5;
1937 layout->o_arg5 = OFFSET_s390x_r6;
1938 layout->o_arg6 = OFFSET_s390x_r7;
1939 layout->uu_arg7 = -1; /* impossible value */
1940 layout->uu_arg8 = -1; /* impossible value */
1942 #elif defined(VGP_x86_solaris)
1943 layout->o_sysno = OFFSET_x86_EAX;
1944 /* Syscall parameters are on the stack. */
1945 layout->s_arg1 = sizeof(UWord) * 1;
1946 layout->s_arg2 = sizeof(UWord) * 2;
1947 layout->s_arg3 = sizeof(UWord) * 3;
1948 layout->s_arg4 = sizeof(UWord) * 4;
1949 layout->s_arg5 = sizeof(UWord) * 5;
1950 layout->s_arg6 = sizeof(UWord) * 6;
1951 layout->s_arg7 = sizeof(UWord) * 7;
1952 layout->s_arg8 = sizeof(UWord) * 8;
1954 #elif defined(VGP_amd64_solaris)
1955 layout->o_sysno = OFFSET_amd64_RAX;
1956 layout->o_arg1 = OFFSET_amd64_RDI;
1957 layout->o_arg2 = OFFSET_amd64_RSI;
1958 layout->o_arg3 = OFFSET_amd64_RDX;
1959 layout->o_arg4 = OFFSET_amd64_R10;
1960 layout->o_arg5 = OFFSET_amd64_R8;
1961 layout->o_arg6 = OFFSET_amd64_R9;
1962 layout->s_arg7 = sizeof(UWord) * 1;
1963 layout->s_arg8 = sizeof(UWord) * 2;
1965 #else
1966 # error "getSyscallLayout: unknown arch"
1967 #endif
1970 #if defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd)
1971 static
1972 void getSyscallArgLayout_0_198 ( /*OUT*/SyscallArgLayout* layout )
1974 #if defined(VGP_amd64_freebsd)
1975 VG_(bzero_inline)(layout, sizeof(*layout));
1976 layout->o_sysno = OFFSET_amd64_RDI;
1977 layout->o_arg1 = OFFSET_amd64_RSI;
1978 layout->o_arg2 = OFFSET_amd64_RDX;
1979 layout->o_arg3 = OFFSET_amd64_R10;
1980 layout->o_arg4 = OFFSET_amd64_R8;
1981 layout->o_arg5 = OFFSET_amd64_R9;
1982 layout->s_arg6 = sizeof(UWord) * 1;
1983 layout->s_arg7 = sizeof(UWord) * 2;
1984 layout->s_arg8 = sizeof(UWord) * 3;
1985 layout->arg6_is_reg = False;
1986 #else
1987 layout->o_sysno = OFFSET_arm64_X0;
1988 layout->o_arg1 = OFFSET_arm64_X1;
1989 layout->o_arg2 = OFFSET_arm64_X2;
1990 layout->o_arg3 = OFFSET_arm64_X3;
1991 layout->o_arg4 = OFFSET_arm64_X4;
1992 layout->o_arg5 = OFFSET_arm64_X5;
1993 layout->o_arg6 = OFFSET_arm64_X6;
1994 layout->o_arg7 = OFFSET_arm64_X7;
1995 #endif
1997 #endif
2000 /* ---------------------------------------------------------------------
2001 The main driver logic
2002 ------------------------------------------------------------------ */
2004 /* Finding the handlers for a given syscall, or faking up one
2005 when no handler is found. */
2007 static
2008 void bad_before ( ThreadId tid,
2009 SyscallArgLayout* layout,
2010 /*MOD*/SyscallArgs* args,
2011 /*OUT*/SyscallStatus* status,
2012 /*OUT*/UWord* flags )
2014 VG_(dmsg)("WARNING: unhandled %s syscall: %s\n",
2015 VG_PLATFORM, VG_SYSNUM_STRING(args->sysno));
2016 if (VG_(clo_verbosity) > 1) {
2017 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
2019 VG_(dmsg)("You may be able to write your own handler.\n");
2020 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
2021 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
2022 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html.\n");
2024 SET_STATUS_Failure(VKI_ENOSYS);
2026 # if defined(VGO_solaris)
2027 VG_(exit)(1);
2028 # endif
2031 static SyscallTableEntry bad_sys =
2032 { bad_before, NULL };
2034 static const SyscallTableEntry* get_syscall_entry ( Int syscallno )
2036 const SyscallTableEntry* sys = NULL;
2038 # if defined(VGO_linux)
2039 sys = ML_(get_linux_syscall_entry)( syscallno );
2041 # elif defined(VGO_freebsd)
2042 sys = ML_(get_freebsd_syscall_entry)( syscallno );
2044 # elif defined(VGO_darwin)
2045 Int idx = VG_DARWIN_SYSNO_INDEX(syscallno);
2047 switch (VG_DARWIN_SYSNO_CLASS(syscallno)) {
2048 case VG_DARWIN_SYSCALL_CLASS_UNIX:
2049 if (idx >= 0 && idx < ML_(syscall_table_size) &&
2050 ML_(syscall_table)[idx].before != NULL)
2051 sys = &ML_(syscall_table)[idx];
2052 break;
2053 case VG_DARWIN_SYSCALL_CLASS_MACH:
2054 if (idx >= 0 && idx < ML_(mach_trap_table_size) &&
2055 ML_(mach_trap_table)[idx].before != NULL)
2056 sys = &ML_(mach_trap_table)[idx];
2057 break;
2058 case VG_DARWIN_SYSCALL_CLASS_MDEP:
2059 if (idx >= 0 && idx < ML_(mdep_trap_table_size) &&
2060 ML_(mdep_trap_table)[idx].before != NULL)
2061 sys = &ML_(mdep_trap_table)[idx];
2062 break;
2063 default:
2064 vg_assert(0);
2065 break;
2068 # elif defined(VGO_solaris)
2069 sys = ML_(get_solaris_syscall_entry)(syscallno);
2071 # else
2072 # error Unknown OS
2073 # endif
2075 return sys == NULL ? &bad_sys : sys;
2079 /* Add and remove signals from mask so that we end up telling the
2080 kernel the state we actually want rather than what the client
2081 wants. */
2082 void VG_(sanitize_client_sigmask)(vki_sigset_t *mask)
2084 VG_(sigdelset)(mask, VKI_SIGKILL);
2085 VG_(sigdelset)(mask, VKI_SIGSTOP);
2086 VG_(sigdelset)(mask, VG_SIGVGKILL); /* never block */
2089 typedef
2090 struct {
2091 SyscallArgs orig_args;
2092 SyscallArgs args;
2093 SyscallStatus status;
2094 UWord flags;
2096 SyscallInfo;
2098 SyscallInfo *syscallInfo;
2100 /* The scheduler needs to be able to zero out these records after a
2101 fork, hence this is exported from m_syswrap. */
2102 void VG_(clear_syscallInfo) ( ThreadId tid )
2104 vg_assert(syscallInfo);
2105 vg_assert(tid < VG_N_THREADS);
2106 VG_(memset)( & syscallInfo[tid], 0, sizeof( syscallInfo[tid] ));
2107 syscallInfo[tid].status.what = SsIdle;
2110 Bool VG_(is_in_syscall) ( ThreadId tid )
2112 vg_assert(tid < VG_N_THREADS);
2113 return (syscallInfo && syscallInfo[tid].status.what != SsIdle);
2116 Bool VG_(is_in_kernel_restart_syscall) ( ThreadId tid )
2118 vg_assert(tid < VG_N_THREADS);
2119 return (syscallInfo && ((syscallInfo[tid].flags & SfKernelRestart) != 0));
2122 Word VG_(is_in_syscall_no) (ThreadId tid )
2124 vg_assert(tid < VG_N_THREADS);
2125 return syscallInfo[tid].orig_args.sysno;
2128 static void ensure_initialised ( void )
2130 Int i;
2131 static Bool init_done = False;
2132 if (init_done)
2133 return;
2134 init_done = True;
2136 syscallInfo = VG_(malloc)("scinfo", VG_N_THREADS * sizeof syscallInfo[0]);
2138 for (i = 0; i < VG_N_THREADS; i++) {
2139 VG_(clear_syscallInfo)( i );
2143 /* --- This is the main function of this file. --- */
2145 void VG_(client_syscall) ( ThreadId tid, UInt trc )
2147 Word sysno;
2148 ThreadState* tst;
2149 const SyscallTableEntry* ent;
2150 SyscallArgLayout layout;
2151 SyscallInfo* sci;
2153 ensure_initialised();
2155 vg_assert(VG_(is_valid_tid)(tid));
2156 vg_assert(tid >= 1 && tid < VG_N_THREADS);
2157 vg_assert(VG_(is_running_thread)(tid));
2159 # if !defined(VGO_darwin)
2160 // Resync filtering is meaningless on non-Darwin targets.
2161 vg_assert(VG_(clo_resync_filter) == 0);
2162 # endif
2164 tst = VG_(get_ThreadState)(tid);
2166 /* BEGIN ensure root thread's stack is suitably mapped */
2167 /* In some rare circumstances, we may do the syscall without the
2168 bottom page of the stack being mapped, because the stack pointer
2169 was moved down just a few instructions before the syscall
2170 instruction, and there have been no memory references since
2171 then, that would cause a call to VG_(extend_stack) to have
2172 happened.
2174 In native execution that's OK: the kernel automagically extends
2175 the stack's mapped area down to cover the stack pointer (or sp -
2176 redzone, really). In simulated normal execution that's OK too,
2177 since any signals we get from accessing below the mapped area of
2178 the (guest's) stack lead us to VG_(extend_stack), where we
2179 simulate the kernel's stack extension logic. But that leaves
2180 the problem of entering a syscall with the SP unmapped. Because
2181 the kernel doesn't know that the segment immediately above SP is
2182 supposed to be a grow-down segment, it causes the syscall to
2183 fail, and thereby causes a divergence between native behaviour
2184 (syscall succeeds) and simulated behaviour (syscall fails).
2186 This is quite a rare failure mode. It has only been seen
2187 affecting calls to sys_readlink on amd64-linux, and even then it
2188 requires a certain code sequence around the syscall to trigger
2189 it. Here is one:
2191 extern int my_readlink ( const char* path );
2192 asm(
2193 ".text\n"
2194 ".globl my_readlink\n"
2195 "my_readlink:\n"
2196 "\tsubq $0x1008,%rsp\n"
2197 "\tmovq %rdi,%rdi\n" // path is in rdi
2198 "\tmovq %rsp,%rsi\n" // &buf[0] -> rsi
2199 "\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx
2200 "\tmovl $"__NR_READLINK",%eax\n" // syscall number
2201 "\tsyscall\n"
2202 "\taddq $0x1008,%rsp\n"
2203 "\tret\n"
2204 ".previous\n"
2207 For more details, see bug #156404
2208 (https://bugs.kde.org/show_bug.cgi?id=156404).
2210 The fix is actually very simple. We simply need to call
2211 VG_(extend_stack) for this thread, handing it the lowest
2212 possible valid address for stack (sp - redzone), to ensure the
2213 pages all the way down to that address, are mapped. Because
2214 this is a potentially expensive and frequent operation, we
2215 do the following:
2217 Only the main thread (tid=1) has a growdown stack. So
2218 ignore all others. It is conceivable, although highly unlikely,
2219 that the main thread exits, and later another thread is
2220 allocated tid=1, but that's harmless, I believe;
2221 VG_(extend_stack) will do nothing when applied to a non-root
2222 thread.
2224 All this guff is of course Linux-specific. Hence the ifdef.
2226 # if defined(VGO_linux)
2227 if (tid == 1/*ROOT THREAD*/) {
2228 Addr stackMin = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
2230 /* The precise thing to do here would be to extend the stack only
2231 if the system call can be proven to access unmapped user stack
2232 memory. That is an enormous amount of work even if a proper
2233 spec of system calls was available.
2235 In the case where the system call does not access user memory
2236 the stack pointer here can have any value. A legitimate testcase
2237 that exercises this is none/tests/s390x/stmg.c:
2238 The stack pointer happens to be in the reservation segment near
2239 the end of the addressable memory and there is no SkAnonC segment
2240 above.
2242 So the approximation we're taking here is to extend the stack only
2243 if the client stack pointer does not look bogus. */
2244 if (VG_(am_addr_is_in_extensible_client_stack)(stackMin))
2245 VG_(extend_stack)( tid, stackMin );
2247 # endif
2248 /* END ensure root thread's stack is suitably mapped */
2250 /* First off, get the syscall args and number. This is a
2251 platform-dependent action. */
2253 sci = & syscallInfo[tid];
2254 vg_assert(sci->status.what == SsIdle);
2256 getSyscallArgsFromGuestState( &sci->orig_args, &tst->arch.vex, trc );
2258 /* Copy .orig_args to .args. The pre-handler may modify .args, but
2259 we want to keep the originals too, just in case. */
2260 sci->args = sci->orig_args;
2262 /* Save the syscall number in the thread state in case the syscall
2263 is interrupted by a signal. */
2264 sysno = sci->orig_args.sysno;
2266 # if defined(VGO_freebsd)
2267 tst->arch.vex.guest_SC_CLASS = sci->orig_args.klass;
2268 # endif
2269 /* It's sometimes useful, as a crude debugging hack, to get a
2270 stack trace at each (or selected) syscalls. */
2271 if (0 && sysno == __NR_ioctl) {
2272 VG_(umsg)("\nioctl:\n");
2273 VG_(get_and_pp_StackTrace)(tid, 10);
2274 VG_(umsg)("\n");
2277 # if defined(VGO_darwin)
2278 /* Record syscall class. But why? Because the syscall might be
2279 interrupted by a signal, and in the signal handler (which will
2280 be m_signals.async_signalhandler) we will need to build a SysRes
2281 reflecting the syscall return result. In order to do that we
2282 need to know the syscall class. Hence stash it in the guest
2283 state of this thread. This madness is not needed on Linux
2284 because it only has a single syscall return convention and so
2285 there is no ambiguity involved in converting the post-signal
2286 machine state into a SysRes. */
2287 tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(sysno);
2288 # endif
2290 /* The default what-to-do-next thing is hand the syscall to the
2291 kernel, so we pre-set that here. Set .sres to something
2292 harmless looking (is irrelevant because .what is not
2293 SsComplete.) */
2294 sci->status.what = SsHandToKernel;
2295 sci->status.sres = VG_(mk_SysRes_Error)(0);
2296 sci->flags = 0;
2298 /* Fetch the syscall's handlers. If no handlers exist for this
2299 syscall, we are given dummy handlers which force an immediate
2300 return with ENOSYS. */
2301 ent = get_syscall_entry(sysno);
2303 /* Fetch the layout information, which tells us where in the guest
2304 state the syscall args reside. This is a platform-dependent
2305 action. This info is needed so that the scalar syscall argument
2306 checks (PRE_REG_READ calls) know which bits of the guest state
2307 they need to inspect. */
2308 #if defined(VGP_amd64_freebsd) || defined (VGP_arm64_freebsd)
2309 // PJF - somewhat unfortunate uglificaton of the code, but the current code handles two
2310 // types of syscall with different register use. Mixing them up is not good.
2311 // I've avoided modifying the existing function (I could have added
2312 // a FreeBSD amd64-only flag to it for this purpose).
2313 if (sci->orig_args.klass == VG_FREEBSD_SYSCALL0 || sci->orig_args.klass == VG_FREEBSD_SYSCALL198) {
2314 getSyscallArgLayout_0_198( &layout );
2315 } else {
2316 #endif
2318 getSyscallArgLayout( &layout );
2320 #if defined(VGP_amd64_freebsd) || defined(VGP_arm64_freebsd)
2322 #endif
2325 /* Make sure the tmp signal mask matches the real signal mask;
2326 sigsuspend may change this. */
2327 vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
2329 /* Right, we're finally ready to Party. Call the pre-handler and
2330 see what we get back. At this point:
2332 sci->status.what is Unset (we don't know yet).
2333 sci->orig_args contains the original args.
2334 sci->args is the same as sci->orig_args.
2335 sci->flags is zero.
2338 PRINT("SYSCALL[%d,%u](%s) ",
2339 VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno));
2341 /* Do any pre-syscall actions */
2342 if (VG_(needs).syscall_wrapper) {
2343 UWord tmpv[8];
2344 tmpv[0] = sci->orig_args.arg1;
2345 tmpv[1] = sci->orig_args.arg2;
2346 tmpv[2] = sci->orig_args.arg3;
2347 tmpv[3] = sci->orig_args.arg4;
2348 tmpv[4] = sci->orig_args.arg5;
2349 tmpv[5] = sci->orig_args.arg6;
2350 tmpv[6] = sci->orig_args.arg7;
2351 tmpv[7] = sci->orig_args.arg8;
2352 VG_TDICT_CALL(tool_pre_syscall, tid, sysno,
2353 &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]));
2356 vg_assert(ent);
2357 vg_assert(ent->before);
2358 (ent->before)( tid,
2359 &layout,
2360 &sci->args, &sci->status, &sci->flags );
2362 /* If needed, gdbserver will report syscall entry to GDB */
2363 VG_(gdbserver_report_syscall)(True, sysno, tid);
2365 /* The pre-handler may have modified:
2366 sci->args
2367 sci->status
2368 sci->flags
2369 All else remains unchanged.
2370 Although the args may be modified, pre handlers are not allowed
2371 to change the syscall number.
2373 /* Now we proceed according to what the pre-handler decided. */
2374 vg_assert(sci->status.what == SsHandToKernel
2375 || sci->status.what == SsComplete);
2376 vg_assert(sci->args.sysno == sci->orig_args.sysno);
2378 if (sci->status.what == SsComplete && !sr_isError(sci->status.sres)) {
2379 /* The pre-handler completed the syscall itself, declaring
2380 success. */
2381 if (sci->flags & SfNoWriteResult) {
2382 PRINT(" --> [pre-success] NoWriteResult");
2383 } else {
2384 PRINT(" --> [pre-success] %s", VG_(sr_as_string)(sci->status.sres));
2386 /* In this case the allowable flags are to ask for a signal-poll
2387 and/or a yield after the call. Changing the args isn't
2388 allowed. */
2389 vg_assert(0 == (sci->flags
2390 & ~(SfPollAfter | SfYieldAfter | SfNoWriteResult)));
2391 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
2394 else
2395 if (sci->status.what == SsComplete && sr_isError(sci->status.sres)) {
2396 /* The pre-handler decided to fail syscall itself. */
2397 PRINT(" --> [pre-fail] %s", VG_(sr_as_string)(sci->status.sres));
2398 /* In this case, the pre-handler is also allowed to ask for the
2399 post-handler to be run anyway. Changing the args is not
2400 allowed. */
2401 vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter)));
2402 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
2405 else
2406 if (sci->status.what != SsHandToKernel) {
2407 /* huh?! */
2408 vg_assert(0);
2411 else /* (sci->status.what == HandToKernel) */ {
2412 /* Ok, this is the usual case -- and the complicated one. There
2413 are two subcases: sync and async. async is the general case
2414 and is to be used when there is any possibility that the
2415 syscall might block [a fact that the pre-handler must tell us
2416 via the sci->flags field.] Because the tidying-away /
2417 context-switch overhead of the async case could be large, if
2418 we are sure that the syscall will not block, we fast-track it
2419 by doing it directly in this thread, which is a lot
2420 simpler. */
2422 /* Check that the given flags are allowable: MayBlock, PollAfter
2423 and PostOnFail are ok. */
2424 vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter | SfKernelRestart)));
2426 if (sci->flags & SfMayBlock) {
2428 /* Syscall may block, so run it asynchronously */
2429 vki_sigset_t mask;
2431 PRINT(" --> [async] ... \n");
2433 mask = tst->sig_mask;
2434 VG_(sanitize_client_sigmask)(&mask);
2436 /* Gack. More impedance matching. Copy the possibly
2437 modified syscall args back into the guest state. */
2438 /* JRS 2009-Mar-16: if the syscall args are possibly modified,
2439 then this assertion is senseless:
2440 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
2441 The case that exposed it was sys_posix_spawn on Darwin,
2442 which heavily modifies its arguments but then lets the call
2443 go through anyway, with SfToBlock set, hence we end up here. */
2444 putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex );
2446 /* SfNoWriteResult flag is invalid for blocking signals because
2447 do_syscall_for_client() directly modifies the guest state. */
2448 vg_assert(!(sci->flags & SfNoWriteResult));
2450 /* Drop the bigLock */
2451 VG_(release_BigLock)(tid, VgTs_WaitSys, "VG_(client_syscall)[async]");
2452 /* Urr. We're now in a race against other threads trying to
2453 acquire the bigLock. I guess that doesn't matter provided
2454 that do_syscall_for_client only touches thread-local
2455 state. */
2457 /* Do the call, which operates directly on the guest state,
2458 not on our abstracted copies of the args/result. */
2459 do_syscall_for_client(sysno, tst, &mask);
2461 /* do_syscall_for_client may not return if the syscall was
2462 interrupted by a signal. In that case, flow of control is
2463 first to m_signals.async_sighandler, which calls
2464 VG_(fixup_guest_state_after_syscall_interrupted), which
2465 fixes up the guest state, and possibly calls
2466 VG_(post_syscall). Once that's done, control drops back
2467 to the scheduler. */
2469 /* Darwin: do_syscall_for_client may not return if the
2470 syscall was workq_ops(WQOPS_THREAD_RETURN) and the kernel
2471 responded by starting the thread at wqthread_hijack(reuse=1)
2472 (to run another workqueue item). In that case, wqthread_hijack
2473 calls ML_(wqthread_continue), which is similar to
2474 VG_(fixup_guest_state_after_syscall_interrupted). */
2476 /* Reacquire the lock */
2477 VG_(acquire_BigLock)(tid, "VG_(client_syscall)[async]");
2479 /* Even more impedance matching. Extract the syscall status
2480 from the guest state. */
2481 getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex );
2482 vg_assert(sci->status.what == SsComplete);
2484 /* Be decorative, if required. */
2485 if (VG_(clo_trace_syscalls)) {
2486 PRINT("SYSCALL[%d,%u](%s) ... [async] --> %s",
2487 VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno),
2488 VG_(sr_as_string)(sci->status.sres));
2491 } else {
2493 /* run the syscall directly */
2494 /* The pre-handler may have modified the syscall args, but
2495 since we're passing values in ->args directly to the
2496 kernel, there's no point in flushing them back to the
2497 guest state. Indeed doing so could be construed as
2498 incorrect. */
2499 SysRes sres
2500 = VG_(do_syscall)(sysno, sci->args.arg1, sci->args.arg2,
2501 sci->args.arg3, sci->args.arg4,
2502 sci->args.arg5, sci->args.arg6,
2503 sci->args.arg7, sci->args.arg8 );
2504 sci->status = convert_SysRes_to_SyscallStatus(sres);
2506 /* Be decorative, if required. */
2507 if (VG_(clo_trace_syscalls)) {
2508 PRINT("[sync] --> %s", VG_(sr_as_string)(sci->status.sres));
2513 vg_assert(sci->status.what == SsComplete);
2515 vg_assert(VG_(is_running_thread)(tid));
2517 /* Dump the syscall result back in the guest state. This is
2518 a platform-specific action. */
2519 if (!(sci->flags & SfNoWriteResult))
2520 putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex );
2522 /* If needed, gdbserver will report syscall return to GDB */
2523 VG_(gdbserver_report_syscall)(False, sysno, tid);
2525 /* Situation now:
2526 - the guest state is now correctly modified following the syscall
2527 - modified args, original args and syscall status are still
2528 available in the syscallInfo[] entry for this syscall.
2530 Now go on to do the post-syscall actions (read on down ..)
2532 PRINT(" ");
2533 VG_(post_syscall)(tid);
2534 PRINT("\n");
2538 /* Perform post syscall actions. The expected state on entry is
2539 precisely as at the end of VG_(client_syscall), that is:
2541 - guest state up to date following the syscall
2542 - modified args, original args and syscall status are still
2543 available in the syscallInfo[] entry for this syscall.
2544 - syscall status matches what's in the guest state.
2546 There are two ways to get here: the normal way -- being called by
2547 VG_(client_syscall), and the unusual way, from
2548 VG_(fixup_guest_state_after_syscall_interrupted).
2549 Darwin: there's a third way, ML_(wqthread_continue).
2551 void VG_(post_syscall) (ThreadId tid)
2553 SyscallInfo* sci;
2554 const SyscallTableEntry* ent;
2555 SyscallStatus test_status;
2556 ThreadState* tst;
2557 Word sysno;
2559 /* Preliminaries */
2560 vg_assert(VG_(is_valid_tid)(tid));
2561 vg_assert(tid >= 1 && tid < VG_N_THREADS);
2562 vg_assert(VG_(is_running_thread)(tid));
2564 tst = VG_(get_ThreadState)(tid);
2565 sci = & syscallInfo[tid];
2567 /* m_signals.sigvgkill_handler might call here even when not in
2568 a syscall. */
2569 if (sci->status.what == SsIdle || sci->status.what == SsHandToKernel) {
2570 sci->status.what = SsIdle;
2571 return;
2574 /* Validate current syscallInfo entry. In particular we require
2575 that the current .status matches what's actually in the guest
2576 state. At least in the normal case where we have actually
2577 previously written the result into the guest state. */
2578 vg_assert(sci->status.what == SsComplete);
2580 /* Get the system call number. Because the pre-handler isn't
2581 allowed to mess with it, it should be the same for both the
2582 original and potentially-modified args. */
2583 vg_assert(sci->args.sysno == sci->orig_args.sysno);
2584 sysno = sci->args.sysno;
2586 getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
2587 if (!(sci->flags & SfNoWriteResult)) {
2588 vg_assert(eq_SyscallStatus( sysno, &sci->status, &test_status ));
2590 /* Failure of the above assertion on Darwin can indicate a problem
2591 in the syscall wrappers that pre-fail or pre-succeed the
2592 syscall, by calling SET_STATUS_Success or SET_STATUS_Failure,
2593 when they really should call SET_STATUS_from_SysRes. The former
2594 create a UNIX-class syscall result on Darwin, which may not be
2595 correct for the syscall; if that's the case then this assertion
2596 fires. See PRE(thread_fast_set_cthread_self) for an example. On
2597 non-Darwin platforms this assertion is should never fail, and this
2598 comment is completely irrelevant. */
2599 /* Ok, looks sane */
2601 /* pre: status == Complete (asserted above) */
2602 /* Consider either success or failure. Now run the post handler if:
2603 - it exists, and
2604 - Success or (Failure and PostOnFail is set)
2606 ent = get_syscall_entry(sysno);
2607 if (ent->after
2608 && ((!sr_isError(sci->status.sres))
2609 || (sr_isError(sci->status.sres)
2610 && (sci->flags & SfPostOnFail) ))) {
2612 (ent->after)( tid, &sci->args, &sci->status );
2615 /* Because the post handler might have changed the status (eg, the
2616 post-handler for sys_open can change the result from success to
2617 failure if the kernel supplied a fd that it doesn't like), once
2618 again dump the syscall result back in the guest state.*/
2619 if (!(sci->flags & SfNoWriteResult))
2620 putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex );
2622 /* Do any post-syscall actions required by the tool. */
2623 if (VG_(needs).syscall_wrapper) {
2624 UWord tmpv[8];
2625 tmpv[0] = sci->orig_args.arg1;
2626 tmpv[1] = sci->orig_args.arg2;
2627 tmpv[2] = sci->orig_args.arg3;
2628 tmpv[3] = sci->orig_args.arg4;
2629 tmpv[4] = sci->orig_args.arg5;
2630 tmpv[5] = sci->orig_args.arg6;
2631 tmpv[6] = sci->orig_args.arg7;
2632 tmpv[7] = sci->orig_args.arg8;
2633 VG_TDICT_CALL(tool_post_syscall, tid,
2634 sysno,
2635 &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]),
2636 sci->status.sres);
2639 /* The syscall is done. */
2640 vg_assert(sci->status.what == SsComplete);
2641 sci->status.what = SsIdle;
2643 /* The pre/post wrappers may have concluded that pending signals
2644 might have been created, and will have set SfPollAfter to
2645 request a poll for them once the syscall is done. */
2646 if (sci->flags & SfPollAfter)
2647 VG_(poll_signals)(tid);
2649 /* Similarly, the wrappers might have asked for a yield
2650 afterwards. */
2651 if (sci->flags & SfYieldAfter)
2652 VG_(vg_yield)();
2656 /* ---------------------------------------------------------------------
2657 Dealing with syscalls which get interrupted by a signal:
2658 VG_(fixup_guest_state_after_syscall_interrupted)
2659 ------------------------------------------------------------------ */
2661 /* Syscalls done on behalf of the client are finally handed off to the
2662 kernel in VG_(client_syscall) above, either by calling
2663 do_syscall_for_client (the async case), or by calling
2664 VG_(do_syscall6) (the sync case).
2666 If the syscall is not interrupted by a signal (it may block and
2667 later unblock, but that's irrelevant here) then those functions
2668 eventually return and so control is passed to VG_(post_syscall).
2669 NB: not sure if the sync case can actually get interrupted, as it
2670 operates with all signals masked.
2672 However, the syscall may get interrupted by an async-signal. In
2673 that case do_syscall_for_client/VG_(do_syscall6) do not
2674 return. Instead we wind up in m_signals.async_sighandler. We need
2675 to fix up the guest state to make it look like the syscall was
2676 interrupted for guest. So async_sighandler calls here, and this
2677 does the fixup. Note that from here we wind up calling
2678 VG_(post_syscall) too.
2682 /* These are addresses within ML_(do_syscall_for_client_WRK). See
2683 syscall-$PLAT.S for details.
2685 #if defined(VGO_linux) || defined(VGO_freebsd)
2686 extern const Addr ML_(blksys_setup);
2687 extern const Addr ML_(blksys_restart);
2688 extern const Addr ML_(blksys_complete);
2689 extern const Addr ML_(blksys_committed);
2690 extern const Addr ML_(blksys_finished);
2691 #elif defined(VGO_darwin)
2692 /* Darwin requires extra uglyness */
2693 extern const Addr ML_(blksys_setup_MACH);
2694 extern const Addr ML_(blksys_restart_MACH);
2695 extern const Addr ML_(blksys_complete_MACH);
2696 extern const Addr ML_(blksys_committed_MACH);
2697 extern const Addr ML_(blksys_finished_MACH);
2698 extern const Addr ML_(blksys_setup_MDEP);
2699 extern const Addr ML_(blksys_restart_MDEP);
2700 extern const Addr ML_(blksys_complete_MDEP);
2701 extern const Addr ML_(blksys_committed_MDEP);
2702 extern const Addr ML_(blksys_finished_MDEP);
2703 extern const Addr ML_(blksys_setup_UNIX);
2704 extern const Addr ML_(blksys_restart_UNIX);
2705 extern const Addr ML_(blksys_complete_UNIX);
2706 extern const Addr ML_(blksys_committed_UNIX);
2707 extern const Addr ML_(blksys_finished_UNIX);
2708 #elif defined(VGO_solaris)
2709 extern const Addr ML_(blksys_setup);
2710 extern const Addr ML_(blksys_complete);
2711 extern const Addr ML_(blksys_committed);
2712 extern const Addr ML_(blksys_finished);
2713 extern const Addr ML_(blksys_setup_DRET);
2714 extern const Addr ML_(blksys_complete_DRET);
2715 extern const Addr ML_(blksys_committed_DRET);
2716 extern const Addr ML_(blksys_finished_DRET);
2717 #else
2718 # error "Unknown OS"
2719 #endif
2722 /* Back up guest state to restart a system call. */
2724 void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
2726 #if defined(VGP_x86_linux)
2727 arch->vex.guest_EIP -= 2; // sizeof(int $0x80)
2729 /* Make sure our caller is actually sane, and we're really backing
2730 back over a syscall.
2732 int $0x80 == CD 80
2735 UChar *p = (UChar *)arch->vex.guest_EIP;
2737 if (p[0] != 0xcd || p[1] != 0x80)
2738 VG_(message)(Vg_DebugMsg,
2739 "?! restarting over syscall at %#x %02x %02x\n",
2740 arch->vex.guest_EIP, p[0], p[1]);
2742 vg_assert(p[0] == 0xcd && p[1] == 0x80);
2745 #elif defined(VGP_amd64_linux)
2746 arch->vex.guest_RIP -= 2; // sizeof(syscall)
2748 /* Make sure our caller is actually sane, and we're really backing
2749 back over a syscall.
2751 syscall == 0F 05
2754 UChar *p = (UChar *)arch->vex.guest_RIP;
2756 if (p[0] != 0x0F || p[1] != 0x05)
2757 VG_(message)(Vg_DebugMsg,
2758 "?! restarting over syscall at %#llx %02x %02x\n",
2759 arch->vex.guest_RIP, p[0], p[1]);
2761 vg_assert(p[0] == 0x0F && p[1] == 0x05);
2764 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux)
2765 arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr)
2767 /* Make sure our caller is actually sane, and we're really backing
2768 back over a syscall.
2770 sc == 44 00 00 02
2773 UChar *p = (UChar *)arch->vex.guest_CIA;
2775 if (p[0] != 0x44 || p[1] != 0x0 || p[2] != 0x0 || p[3] != 0x02)
2776 VG_(message)(Vg_DebugMsg,
2777 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2778 (ULong)arch->vex.guest_CIA, p[0], p[1], p[2], p[3]);
2780 vg_assert(p[0] == 0x44 && p[1] == 0x0 && p[2] == 0x0 && p[3] == 0x2);
2783 #elif defined(VGP_ppc64le_linux)
2784 arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr)
2786 /* Make sure our caller is actually sane, and we're really backing
2787 back over a syscall.
2789 sc == 44 00 00 02
2791 scv == 44 00 00 01
2794 UChar *p = (UChar *)arch->vex.guest_CIA;
2796 if (!(p[3] == 0x44 && p[2] == 0x0 && p[1] == 0x0
2797 && (p[0] == 0x01 || p[0] == 0x02)))
2798 VG_(message)(Vg_DebugMsg,
2799 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2800 arch->vex.guest_CIA, p[3], p[2], p[1], p[0]);
2802 vg_assert(p[3] == 0x44 && p[2] == 0x0 && p[1] == 0x0
2803 && (p[0] == 0x1 || p[0] == 0x2));
2806 #elif defined(VGP_arm_linux)
2807 if (arch->vex.guest_R15T & 1) {
2808 // Thumb mode. SVC is a encoded as
2809 // 1101 1111 imm8
2810 // where imm8 is the SVC number, and we only accept 0.
2811 arch->vex.guest_R15T -= 2; // sizeof(thumb 16 bit insn)
2812 UChar* p = (UChar*)(arch->vex.guest_R15T - 1);
2813 Bool valid = p[0] == 0 && p[1] == 0xDF;
2814 if (!valid) {
2815 VG_(message)(Vg_DebugMsg,
2816 "?! restarting over (Thumb) syscall that is not syscall "
2817 "at %#x %02x %02x\n",
2818 arch->vex.guest_R15T - 1, p[0], p[1]);
2820 vg_assert(valid);
2821 // FIXME: NOTE, this really isn't right. We need to back up
2822 // ITSTATE to what it was before the SVC instruction, but we
2823 // don't know what it was. At least assert that it is now
2824 // zero, because if it is nonzero then it must also have
2825 // been nonzero for the SVC itself, which means it was
2826 // conditional. Urk.
2827 vg_assert(arch->vex.guest_ITSTATE == 0);
2828 } else {
2829 // ARM mode. SVC is encoded as
2830 // cond 1111 imm24
2831 // where imm24 is the SVC number, and we only accept 0.
2832 arch->vex.guest_R15T -= 4; // sizeof(arm instr)
2833 UChar* p = (UChar*)arch->vex.guest_R15T;
2834 Bool valid = p[0] == 0 && p[1] == 0 && p[2] == 0
2835 && (p[3] & 0xF) == 0xF;
2836 if (!valid) {
2837 VG_(message)(Vg_DebugMsg,
2838 "?! restarting over (ARM) syscall that is not syscall "
2839 "at %#x %02x %02x %02x %02x\n",
2840 arch->vex.guest_R15T, p[0], p[1], p[2], p[3]);
2842 vg_assert(valid);
2845 #elif defined(VGP_arm64_linux)
2846 arch->vex.guest_PC -= 4; // sizeof(arm64 instr)
2848 /* Make sure our caller is actually sane, and we're really backing
2849 back over a syscall.
2851 svc #0 == d4 00 00 01
2854 UChar *p = (UChar *)arch->vex.guest_PC;
2856 if (p[0] != 0x01 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0xD4)
2857 VG_(message)(
2858 Vg_DebugMsg,
2859 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2860 arch->vex.guest_PC, p[0], p[1], p[2], p[3]
2863 vg_assert(p[0] == 0x01 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0xD4);
2866 #elif defined(VGP_x86_freebsd)
2867 /* XXX: we support different syscall methods. */
2868 arch->vex.guest_EIP -= 2; // sizeof(int $0x80)
2870 /* Make sure our caller is actually sane, and we're really backing
2871 back over a syscall.
2873 int $0x80 == CD 80
2876 UChar *p = (UChar *)arch->vex.guest_EIP;
2878 if (p[0] != 0xcd || p[1] != 0x80)
2879 VG_(message)(Vg_DebugMsg,
2880 "?! restarting over syscall at %#x %02x %02x\n",
2881 arch->vex.guest_EIP, p[0], p[1]);
2883 vg_assert(p[0] == 0xcd && p[1] == 0x80);
2886 #elif defined(VGP_amd64_freebsd)
2887 /* XXX: we support different syscall methods. */
2888 arch->vex.guest_RIP -= 2; // sizeof(syscall)
2890 /* Make sure our caller is actually sane, and we're really backing
2891 back over a syscall.
2893 syscall == 0F 05
2896 UChar *p = (UChar *)arch->vex.guest_RIP;
2898 if (p[0] != 0x0F || p[1] != 0x05)
2899 VG_(message)(Vg_DebugMsg,
2900 "?! restarting over syscall at %#llx %02x %02x\n",
2901 arch->vex.guest_RIP, p[0], p[1]);
2903 vg_assert(p[0] == 0x0F && p[1] == 0x05);
2906 #elif defined(VGP_arm64_freebsd)
2907 arch->vex.guest_PC -= 4; // sizeof(arm64 instr)
2909 /* Make sure our caller is actually sane, and we're really backing
2910 back over a syscall.
2912 svc #0 == d4 00 00 01
2915 UChar *p = (UChar *)arch->vex.guest_PC;
2917 if (p[0] != 0x01 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0xD4)
2918 VG_(message)(
2919 Vg_DebugMsg,
2920 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2921 arch->vex.guest_PC, p[0], p[1], p[2], p[3]
2924 vg_assert(p[0] == 0x01 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0xD4);
2927 #elif defined(VGP_x86_darwin)
2928 arch->vex.guest_EIP = arch->vex.guest_IP_AT_SYSCALL;
2930 /* Make sure our caller is actually sane, and we're really backing
2931 back over a syscall.
2933 int $0x80 == CD 80 // Used to communicate with BSD syscalls
2934 int $0x81 == CD 81 // Used to communicate with Mach traps
2935 int $0x82 == CD 82 // Used to communicate with "thread" ?
2936 sysenter == 0F 34 // Used to communicate with Unix syscalls
2939 UChar *p = (UChar *)arch->vex.guest_EIP;
2940 Bool ok = (p[0] == 0xCD && p[1] == 0x80)
2941 || (p[0] == 0xCD && p[1] == 0x81)
2942 || (p[0] == 0xCD && p[1] == 0x82)
2943 || (p[0] == 0x0F && p[1] == 0x34);
2944 if (!ok)
2945 VG_(message)(Vg_DebugMsg,
2946 "?! restarting over syscall at %#x %02x %02x\n",
2947 arch->vex.guest_EIP, p[0], p[1]);
2948 vg_assert(ok);
2951 #elif defined(VGP_amd64_darwin)
2952 arch->vex.guest_RIP = arch->vex.guest_IP_AT_SYSCALL;
2954 /* Make sure our caller is actually sane, and we're really backing
2955 back over a syscall.
2957 syscall == 0F 05
2960 UChar *p = (UChar *)arch->vex.guest_RIP;
2962 Bool ok = (p[0] == 0x0F && p[1] == 0x05);
2963 if (!ok)
2964 VG_(message)(Vg_DebugMsg,
2965 "?! restarting over syscall at %#llx %02x %02x\n",
2966 arch->vex.guest_RIP, p[0], p[1]);
2967 vg_assert(ok);
2970 #elif defined(VGP_s390x_linux)
2971 arch->vex.guest_IA -= 2; // sizeof(syscall)
2973 /* Make sure our caller is actually sane, and we're really backing
2974 back over a syscall.
2976 syscall == 0A <num>
2979 UChar *p = (UChar *)arch->vex.guest_IA;
2980 if (p[0] != 0x0A)
2981 VG_(message)(Vg_DebugMsg,
2982 "?! restarting over syscall at %#llx %02x %02x\n",
2983 arch->vex.guest_IA, p[0], p[1]);
2985 vg_assert(p[0] == 0x0A);
2988 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
2990 arch->vex.guest_PC -= 4; // sizeof(mips instr)
2992 /* Make sure our caller is actually sane, and we're really backing
2993 back over a syscall.
2995 syscall == 00 00 00 0C
2996 big endian
2997 syscall == 0C 00 00 00
3000 UChar *p = (UChar *)(Addr)(arch->vex.guest_PC);
3001 # if defined (VG_LITTLEENDIAN)
3002 if (p[0] != 0x0c || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x00)
3003 VG_(message)(Vg_DebugMsg,
3004 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
3005 (ULong)arch->vex.guest_PC, p[0], p[1], p[2], p[3]);
3007 vg_assert(p[0] == 0x0c && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x00);
3008 # elif defined (VG_BIGENDIAN)
3009 if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x0c)
3010 VG_(message)(Vg_DebugMsg,
3011 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
3012 (ULong)arch->vex.guest_PC, p[0], p[1], p[2], p[3]);
3014 vg_assert(p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x0c);
3015 # else
3016 # error "Unknown endianness"
3017 # endif
3020 #elif defined(VGP_nanomips_linux)
3022 /* Make sure our caller is actually sane, and we're really backing
3023 back over a syscall.
3025 arch->vex.guest_PC -= 2;
3026 /* PC has to be 16-bit aligned. */
3027 vg_assert((arch->vex.guest_PC & 1) == 0);
3029 UShort *p = ASSUME_ALIGNED(UShort *, (Addr)(arch->vex.guest_PC));
3031 if (((*p) & 0xFFFD) != 0x1008) {
3032 if (((*(p - 1)) & 0xFFFD) != 0x0008) {
3033 VG_(message)(Vg_DebugMsg,
3034 "?! restarting over syscall at %#x %08lx\n",
3035 arch->vex.guest_PC, (UWord)(*p));
3036 vg_assert(0);
3038 arch->vex.guest_PC -= 2;
3041 #elif defined(VGP_x86_solaris)
3042 arch->vex.guest_EIP -= 2; // sizeof(int $0x91) or sizeof(syscall)
3044 /* Make sure our caller is actually sane, and we're really backing
3045 back over a syscall.
3047 int $0x91 == CD 91
3048 syscall == 0F 05
3049 sysenter == 0F 34
3051 Handle also other syscall instructions because we also handle them in
3052 the scheduler.
3053 int $0x80 == CD 80
3054 int $0x81 == CD 81
3055 int $0x82 == CD 82
3058 UChar *p = (UChar *)arch->vex.guest_EIP;
3060 Bool ok = (p[0] == 0xCD && p[1] == 0x91)
3061 || (p[0] == 0x0F && p[1] == 0x05)
3062 || (p[0] == 0x0F && p[1] == 0x34)
3063 || (p[0] == 0xCD && p[1] == 0x80)
3064 || (p[0] == 0xCD && p[1] == 0x81)
3065 || (p[0] == 0xCD && p[1] == 0x82);
3066 if (!ok)
3067 VG_(message)(Vg_DebugMsg,
3068 "?! restarting over syscall at %#x %02x %02x\n",
3069 arch->vex.guest_EIP, p[0], p[1]);
3070 vg_assert(ok);
3073 #elif defined(VGP_amd64_solaris)
3074 arch->vex.guest_RIP -= 2; // sizeof(syscall)
3076 /* Make sure our caller is actually sane, and we're really backing
3077 back over a syscall.
3079 syscall == 0F 05
3082 UChar *p = (UChar *)arch->vex.guest_RIP;
3084 Bool ok = (p[0] == 0x0F && p[1] == 0x05);
3085 if (!ok)
3086 VG_(message)(Vg_DebugMsg,
3087 "?! restarting over syscall at %#llx %02x %02x\n",
3088 arch->vex.guest_RIP, p[0], p[1]);
3089 vg_assert(ok);
3092 #else
3093 # error "ML_(fixup_guest_state_to_restart_syscall): unknown plat"
3094 #endif
3099 Fix up the guest state when a syscall is interrupted by a signal
3100 and so has been forced to return 'sysret'.
3102 To do this, we determine the precise state of the syscall by
3103 looking at the (real) IP at the time the signal happened. The
3104 syscall sequence looks like:
3106 1. unblock signals
3107 2. perform syscall
3108 3. save result to guest state (EAX, RAX, R3+CR0.SO, R0, V0)
3109 4. re-block signals
3111 If a signal
3112 happens at Then Why?
3113 [1-2) restart nothing has happened (restart syscall)
3114 [2] restart syscall hasn't started, or kernel wants to restart
3115 [2-3) save syscall complete, but results not saved
3116 [3-4) syscall complete, results saved
3118 Sometimes we never want to restart an interrupted syscall (because
3119 sigaction says not to), so we only restart if "restart" is True.
3121 This will also call VG_(post_syscall) if the syscall has actually
3122 completed (either because it was interrupted, or because it
3123 actually finished). It will not call VG_(post_syscall) if the
3124 syscall is set up for restart, which means that the pre-wrapper may
3125 get called multiple times.
3128 void
3129 VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
3130 Addr ip,
3131 SysRes sres,
3132 Bool restart,
3133 struct vki_ucontext *uc)
3135 /* Note that we don't know the syscall number here, since (1) in
3136 general there's no reliable way to get hold of it short of
3137 stashing it in the guest state before the syscall, and (2) in
3138 any case we don't need to know it for the actions done by this
3139 routine.
3141 Furthermore, 'sres' is only used in the case where the syscall
3142 is complete, but the result has not been committed to the guest
3143 state yet. In any other situation it will be meaningless and
3144 therefore ignored. */
3146 ThreadState* tst;
3147 SyscallStatus canonical;
3148 ThreadArchState* th_regs;
3149 SyscallInfo* sci;
3151 /* Compute some Booleans indicating which range we're in. */
3152 Bool outside_range,
3153 in_setup_to_restart, // [1,2) in the .S files
3154 at_restart, // [2] in the .S files
3155 in_complete_to_committed, // [3,4) in the .S files
3156 in_committed_to_finished; // [4,5) in the .S files
3158 if (VG_(clo_trace_signals))
3159 VG_(message)( Vg_DebugMsg,
3160 "interrupted_syscall: tid=%u, ip=%#lx, "
3161 "restart=%s, sres.isErr=%s, sres.val=%" FMT_REGWORD "u\n",
3162 tid,
3164 restart ? "True" : "False",
3165 sr_isError(sres) ? "True" : "False",
3166 sr_isError(sres) ? (RegWord)sr_Err(sres) :
3167 (RegWord)sr_Res(sres));
3169 vg_assert(VG_(is_valid_tid)(tid));
3170 vg_assert(tid >= 1 && tid < VG_N_THREADS);
3171 vg_assert(VG_(is_running_thread)(tid));
3173 tst = VG_(get_ThreadState)(tid);
3174 th_regs = &tst->arch;
3175 sci = & syscallInfo[tid];
3177 # if defined(VGO_linux) || defined(VGO_freebsd)
3178 outside_range
3179 = ip < ML_(blksys_setup) || ip >= ML_(blksys_finished);
3180 in_setup_to_restart
3181 = ip >= ML_(blksys_setup) && ip < ML_(blksys_restart);
3183 #if defined(VGP_ppc64le_linux)
3184 /* Starting with ISA 3.0, Power supports two system call instructions sc
3185 and scv. The code in file syscall-ppc64[be|le]-linux.S uses an input
3186 to call the requested system call. The definitions for blksys_restart
3187 and blksys_complete must account for being at either of the two system
3188 calls and account for the branch to lable 3 if the sc instruction was
3189 called. at_restart is true if the ip is at either system call
3190 instruction. in_complete_to_committed is true if the ip is between
3191 blksys_complete and blksys_committed OR at the branch after the sc
3192 instruction. The scv instruction is currently only supported on LE. */
3193 at_restart
3194 = (ip == ML_(blksys_restart)) || ((ip-8) == ML_(blksys_restart));
3195 in_complete_to_committed
3196 = (ip >= ML_(blksys_complete) && ip < ML_(blksys_committed)) ||
3197 ((ip+8) == ML_(blksys_complete));
3198 #else
3199 at_restart
3200 = ip == ML_(blksys_restart);
3201 in_complete_to_committed
3202 = ip >= ML_(blksys_complete) && ip < ML_(blksys_committed);
3203 #endif
3205 in_committed_to_finished
3206 = ip >= ML_(blksys_committed) && ip < ML_(blksys_finished);
3207 # elif defined(VGO_darwin)
3208 outside_range
3209 = (ip < ML_(blksys_setup_MACH) || ip >= ML_(blksys_finished_MACH))
3210 && (ip < ML_(blksys_setup_MDEP) || ip >= ML_(blksys_finished_MDEP))
3211 && (ip < ML_(blksys_setup_UNIX) || ip >= ML_(blksys_finished_UNIX));
3212 in_setup_to_restart
3213 = (ip >= ML_(blksys_setup_MACH) && ip < ML_(blksys_restart_MACH))
3214 || (ip >= ML_(blksys_setup_MDEP) && ip < ML_(blksys_restart_MDEP))
3215 || (ip >= ML_(blksys_setup_UNIX) && ip < ML_(blksys_restart_UNIX));
3216 at_restart
3217 = (ip == ML_(blksys_restart_MACH))
3218 || (ip == ML_(blksys_restart_MDEP))
3219 || (ip == ML_(blksys_restart_UNIX));
3220 in_complete_to_committed
3221 = (ip >= ML_(blksys_complete_MACH) && ip < ML_(blksys_committed_MACH))
3222 || (ip >= ML_(blksys_complete_MDEP) && ip < ML_(blksys_committed_MDEP))
3223 || (ip >= ML_(blksys_complete_UNIX) && ip < ML_(blksys_committed_UNIX));
3224 in_committed_to_finished
3225 = (ip >= ML_(blksys_committed_MACH) && ip < ML_(blksys_finished_MACH))
3226 || (ip >= ML_(blksys_committed_MDEP) && ip < ML_(blksys_finished_MDEP))
3227 || (ip >= ML_(blksys_committed_UNIX) && ip < ML_(blksys_finished_UNIX));
3228 /* Wasn't that just So Much Fun? Does your head hurt yet? Mine does. */
3229 # elif defined(VGO_solaris)
3230 /* The solaris port is never outside the range. */
3231 outside_range = False;
3232 /* The Solaris kernel never restarts syscalls directly! */
3233 at_restart = False;
3234 if (tst->os_state.in_door_return) {
3235 vg_assert(ip >= ML_(blksys_setup_DRET)
3236 && ip < ML_(blksys_finished_DRET));
3238 in_setup_to_restart
3239 = ip >= ML_(blksys_setup_DRET) && ip < ML_(blksys_complete_DRET);
3240 in_complete_to_committed
3241 = ip >= ML_(blksys_complete_DRET) && ip < ML_(blksys_committed_DRET);
3242 in_committed_to_finished
3243 = ip >= ML_(blksys_committed_DRET) && ip < ML_(blksys_finished_DRET);
3245 else {
3246 vg_assert(ip >= ML_(blksys_setup) && ip < ML_(blksys_finished));
3248 in_setup_to_restart
3249 = ip >= ML_(blksys_setup) && ip < ML_(blksys_complete);
3250 in_complete_to_committed
3251 = ip >= ML_(blksys_complete) && ip < ML_(blksys_committed);
3252 in_committed_to_finished
3253 = ip >= ML_(blksys_committed) && ip < ML_(blksys_finished);
3255 # else
3256 # error "Unknown OS"
3257 # endif
3259 #if defined(VGO_freebsd) || defined(VGO_darwin)
3260 if (outside_range)
3262 if (th_regs->vex.guest_SETC)
3264 outside_range = False;
3265 in_complete_to_committed = True;
3268 #endif
3271 /* Figure out what the state of the syscall was by examining the
3272 (real) IP at the time of the signal, and act accordingly. */
3273 if (outside_range) {
3274 if (VG_(clo_trace_signals))
3275 VG_(message)( Vg_DebugMsg,
3276 " not in syscall at all: hmm, very suspicious\n" );
3277 /* Looks like we weren't in a syscall at all. Hmm. */
3278 vg_assert(sci->status.what != SsIdle);
3279 return;
3282 /* We should not be here unless this thread had first started up
3283 the machinery for a syscall by calling VG_(client_syscall).
3284 Hence: */
3285 vg_assert(sci->status.what != SsIdle);
3287 /* now, do one of four fixup actions, depending on where the IP has
3288 got to. */
3290 if (in_setup_to_restart) {
3291 /* syscall hasn't even started; go around again */
3292 if (VG_(clo_trace_signals))
3293 VG_(message)( Vg_DebugMsg, " not started: restarting\n");
3294 vg_assert(sci->status.what == SsHandToKernel);
3295 ML_(fixup_guest_state_to_restart_syscall)(th_regs);
3298 else
3299 if (at_restart) {
3300 # if defined(VGO_solaris)
3301 /* We should never hit this branch on Solaris, see the comment above. */
3302 vg_assert(0);
3303 # endif
3305 /* We're either about to run the syscall, or it was interrupted
3306 and the kernel restarted it. Restart if asked, otherwise
3307 EINTR it. */
3308 if (restart) {
3309 if (VG_(clo_trace_signals))
3310 VG_(message)( Vg_DebugMsg, " at syscall instr: restarting\n");
3311 ML_(fixup_guest_state_to_restart_syscall)(th_regs);
3312 } else {
3313 if (VG_(clo_trace_signals))
3314 VG_(message)( Vg_DebugMsg, " at syscall instr: returning EINTR\n");
3315 canonical = convert_SysRes_to_SyscallStatus(
3316 VG_(mk_SysRes_Error)( VKI_EINTR )
3318 if (!(sci->flags & SfNoWriteResult))
3319 putSyscallStatusIntoGuestState( tid, &canonical, &th_regs->vex );
3320 sci->status = canonical;
3321 VG_(post_syscall)(tid);
3325 else
3326 if (in_complete_to_committed) {
3327 /* Syscall complete, but result hasn't been written back yet.
3328 Write the SysRes we were supplied with back to the guest
3329 state. */
3330 if (VG_(clo_trace_signals))
3331 VG_(message)( Vg_DebugMsg,
3332 " completed, but uncommitted: committing\n");
3333 canonical = convert_SysRes_to_SyscallStatus( sres );
3334 vg_assert(!(sci->flags & SfNoWriteResult));
3335 putSyscallStatusIntoGuestState( tid, &canonical, &th_regs->vex );
3336 # if defined(VGO_solaris)
3337 if (tst->os_state.in_door_return) {
3338 # if defined(VGP_x86_solaris)
3339 /* Registers %esp and %ebp were also modified by the syscall. */
3340 tst->arch.vex.guest_ESP = uc->uc_mcontext.gregs[VKI_UESP];
3341 tst->arch.vex.guest_EBP = uc->uc_mcontext.gregs[VKI_EBP];
3342 # elif defined(VGP_amd64_solaris)
3343 tst->arch.vex.guest_RSP = uc->uc_mcontext.gregs[VKI_REG_RSP];
3344 tst->arch.vex.guest_RBP = uc->uc_mcontext.gregs[VKI_REG_RBP];
3345 # endif
3347 # endif
3348 sci->status = canonical;
3349 VG_(post_syscall)(tid);
3352 else
3353 if (in_committed_to_finished) {
3354 /* Result committed, but the signal mask has not been restored;
3355 we expect our caller (the signal handler) will have fixed
3356 this up. */
3357 /* XXX: needed? */
3358 #if defined(VGP_x86_freebsd)
3359 /* On FreeBSD, the success/fail status is returned to the caller
3360 and still has to be fixed up here. */
3361 if (!(sci->flags & SfNoWriteResult)) {
3362 if (sr_isError(sres))
3363 LibVEX_GuestX86_put_eflag_c(1, &th_regs->vex);
3364 else
3365 LibVEX_GuestX86_put_eflag_c(0, &th_regs->vex);
3367 #elif defined(VGP_amd64_freebsd)
3368 if (!(sci->flags & SfNoWriteResult)) {
3369 if (sr_isError(sres))
3370 LibVEX_GuestAMD64_put_rflag_c(1, &th_regs->vex);
3371 else
3372 LibVEX_GuestAMD64_put_rflag_c(0, &th_regs->vex);
3374 #elif defined(VGP_arm64_freebsd)
3375 if (!(sci->flags & SfNoWriteResult)) {
3376 if (sr_isError(sres))
3377 LibVEX_GuestARM64_put_nzcv_c(1, &th_regs->vex);
3378 else
3379 LibVEX_GuestARM64_put_nzcv_c(0, &th_regs->vex);
3381 #endif
3382 if (VG_(clo_trace_signals))
3383 VG_(message)( Vg_DebugMsg,
3384 " completed and committed: nothing to do\n");
3385 # if defined(VGP_x86_solaris)
3386 /* The %eax and %edx values are committed but the carry flag is still
3387 uncommitted. Save it now. */
3388 LibVEX_GuestX86_put_eflag_c(sr_isError(sres), &th_regs->vex);
3389 # elif defined(VGP_amd64_solaris)
3390 LibVEX_GuestAMD64_put_rflag_c(sr_isError(sres), &th_regs->vex);
3391 # endif
3392 getSyscallStatusFromGuestState( &sci->status, &th_regs->vex );
3393 vg_assert(sci->status.what == SsComplete);
3394 VG_(post_syscall)(tid);
3397 else
3398 VG_(core_panic)("?? strange syscall interrupt state?");
3400 /* In all cases, the syscall is now finished (even if we called
3401 ML_(fixup_guest_state_to_restart_syscall), since that just
3402 re-positions the guest's IP for another go at it). So we need
3403 to record that fact. */
3404 sci->status.what = SsIdle;
3408 #if defined(VGO_solaris)
3409 /* Returns True if ip is inside a fixable syscall code in syscall-*-*.S. This
3410 function can be called by a 'non-running' thread! */
3411 Bool VG_(is_ip_in_blocking_syscall)(ThreadId tid, Addr ip)
3413 ThreadState *tst = VG_(get_ThreadState)(tid);
3415 if (tst->os_state.in_door_return)
3416 return ip >= ML_(blksys_setup_DRET) && ip < ML_(blksys_finished_DRET);
3417 else
3418 return ip >= ML_(blksys_setup) && ip < ML_(blksys_finished);
3420 #endif
3423 #if defined(VGO_darwin)
3424 // Clean up after workq_ops(WQOPS_THREAD_RETURN) jumped to wqthread_hijack.
3425 // This is similar to VG_(fixup_guest_state_after_syscall_interrupted).
3426 // This longjmps back to the scheduler.
3427 void ML_(wqthread_continue_NORETURN)(ThreadId tid)
3429 ThreadState* tst;
3430 SyscallInfo* sci;
3432 VG_(acquire_BigLock)(tid, "wqthread_continue_NORETURN");
3434 PRINT("SYSCALL[%d,%u](%s) workq_ops() starting new workqueue item\n",
3435 VG_(getpid)(), tid, VG_SYSNUM_STRING(__NR_workq_ops));
3437 vg_assert(VG_(is_valid_tid)(tid));
3438 vg_assert(tid >= 1 && tid < VG_N_THREADS);
3439 vg_assert(VG_(is_running_thread)(tid));
3441 tst = VG_(get_ThreadState)(tid);
3442 sci = & syscallInfo[tid];
3443 vg_assert(sci->status.what != SsIdle);
3444 vg_assert(tst->os_state.wq_jmpbuf_valid); // check this BEFORE post_syscall
3446 // Pretend the syscall completed normally, but don't touch the thread state.
3447 sci->status = convert_SysRes_to_SyscallStatus( VG_(mk_SysRes_Success)(0) );
3448 sci->flags |= SfNoWriteResult;
3449 VG_(post_syscall)(tid);
3451 ML_(sync_mappings)("in", "ML_(wqthread_continue_NORETURN)", 0);
3453 sci->status.what = SsIdle;
3455 vg_assert(tst->sched_jmpbuf_valid);
3456 VG_MINIMAL_LONGJMP(tst->sched_jmpbuf);
3458 /* NOTREACHED */
3459 vg_assert(0);
3461 #endif
3464 /* ---------------------------------------------------------------------
3465 A place to store the where-to-call-when-really-done pointer
3466 ------------------------------------------------------------------ */
3468 // When the final thread is done, where shall I call to shutdown the
3469 // system cleanly? Is set once at startup (in m_main) and never
3470 // changes after that. Is basically a pointer to the exit
3471 // continuation. This is all just a nasty hack to avoid calling
3472 // directly from m_syswrap to m_main at exit, since that would cause
3473 // m_main to become part of a module cycle, which is silly.
3474 void (* VG_(address_of_m_main_shutdown_actions_NORETURN) )
3475 (ThreadId,VgSchedReturnCode)
3476 = NULL;
3478 /*--------------------------------------------------------------------*/
3479 /*--- end ---*/
3480 /*--------------------------------------------------------------------*/