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