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