Home | History | Annotate | Download | only in m_syswrap
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Platform-specific syscalls stuff.      syswrap-amd64-linux.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2000-2012 Nicholas Nethercote
     11       njn (at) valgrind.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 #if defined(VGP_amd64_linux)
     32 
     33 #include "pub_core_basics.h"
     34 #include "pub_core_vki.h"
     35 #include "pub_core_vkiscnums.h"
     36 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
     37 #include "pub_core_threadstate.h"
     38 #include "pub_core_aspacemgr.h"
     39 #include "pub_core_debuglog.h"
     40 #include "pub_core_options.h"
     41 #include "pub_core_libcbase.h"
     42 #include "pub_core_libcassert.h"
     43 #include "pub_core_libcprint.h"
     44 #include "pub_core_libcproc.h"
     45 #include "pub_core_libcsignal.h"
     46 #include "pub_core_scheduler.h"
     47 #include "pub_core_sigframe.h"
     48 #include "pub_core_signals.h"
     49 #include "pub_core_syscall.h"
     50 #include "pub_core_syswrap.h"
     51 #include "pub_core_tooliface.h"
     52 #include "pub_core_stacks.h"        // VG_(register_stack)
     53 
     54 #include "priv_types_n_macros.h"
     55 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
     56 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
     57 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
     58 #include "priv_syswrap-main.h"
     59 
     60 
     61 /* ---------------------------------------------------------------------
     62    clone() handling
     63    ------------------------------------------------------------------ */
     64 
     65 /* Call f(arg1), but first switch stacks, using 'stack' as the new
     66    stack, and use 'retaddr' as f's return-to address.  Also, clear all
     67    the integer registers before entering f.  */
     68 __attribute__((noreturn))
     69 void ML_(call_on_new_stack_0_1) ( Addr stack,
     70 			          Addr retaddr,
     71 			          void (*f)(Word),
     72                                   Word arg1 );
     73 // %rdi == stack
     74 // %rsi == retaddr
     75 // %rdx == f
     76 // %rcx == arg1
     77 asm(
     78 ".text\n"
     79 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
     80 "vgModuleLocal_call_on_new_stack_0_1:\n"
     81 "   movq   %rdi, %rsp\n"   // set stack
     82 "   pushq  %rsi\n"         // retaddr to stack
     83 "   pushq  %rdx\n"         // f to stack
     84 "   pushq  %rcx\n"         // arg1 to stack
     85 "   movq $0, %rax\n"       // zero all GP regs
     86 "   movq $0, %rbx\n"
     87 "   movq $0, %rcx\n"
     88 "   movq $0, %rdx\n"
     89 "   movq $0, %rsi\n"
     90 "   movq $0, %rdi\n"
     91 "   movq $0, %rbp\n"
     92 "   movq $0, %r8\n"
     93 "   movq $0, %r9\n"
     94 "   movq $0, %r10\n"
     95 "   movq $0, %r11\n"
     96 "   movq $0, %r12\n"
     97 "   movq $0, %r13\n"
     98 "   movq $0, %r14\n"
     99 "   movq $0, %r15\n"
    100 "   popq   %rdi\n"         // arg1 to correct arg reg
    101 "   ret\n"                 // jump to f
    102 "   ud2\n"                 // should never get here
    103 ".previous\n"
    104 );
    105 
    106 /*
    107         Perform a clone system call.  clone is strange because it has
    108         fork()-like return-twice semantics, so it needs special
    109         handling here.
    110 
    111 	Upon entry, we have:
    112 
    113 	    int (*fn)(void*)	in %rdi
    114 	    void*  child_stack	in %rsi
    115 	    int    flags	in %rdx
    116 	    void*  arg		in %rcx
    117 	    pid_t* child_tid	in %r8
    118 	    pid_t* parent_tid	in %r9
    119 	    void*  tls_ptr      at 8(%rsp)
    120 
    121 	System call requires:
    122 
    123 	    int    $__NR_clone  in %rax
    124 	    int    flags	in %rdi
    125 	    void*  child_stack	in %rsi
    126 	    pid_t* parent_tid	in %rdx
    127 	    pid_t* child_tid	in %r10
    128 	    void*  tls_ptr      in %r8
    129 
    130 	Returns a Long encoded in the linux-amd64 way, not a SysRes.
    131  */
    132 #define __NR_CLONE        VG_STRINGIFY(__NR_clone)
    133 #define __NR_EXIT         VG_STRINGIFY(__NR_exit)
    134 
    135 extern
    136 Long do_syscall_clone_amd64_linux ( Word (*fn)(void *),
    137                                     void* stack,
    138                                     Long  flags,
    139                                     void* arg,
    140                                     Long* child_tid,
    141                                     Long* parent_tid,
    142                                     vki_modify_ldt_t * );
    143 asm(
    144 ".text\n"
    145 ".globl do_syscall_clone_amd64_linux\n"
    146 "do_syscall_clone_amd64_linux:\n"
    147         // set up child stack, temporarily preserving fn and arg
    148 "       subq    $16, %rsi\n"            // make space on stack
    149 "       movq    %rcx, 8(%rsi)\n"        // save arg
    150 "       movq    %rdi, 0(%rsi)\n"        // save fn
    151 
    152         // setup syscall
    153 "       movq    $"__NR_CLONE", %rax\n"  // syscall number
    154 "       movq    %rdx,     %rdi\n"       // syscall arg1: flags
    155         // %rsi already setup           // syscall arg2: child_stack
    156 "       movq    %r9,      %rdx\n"       // syscall arg3: parent_tid
    157 "       movq    %r8,      %r10\n"       // syscall arg4: child_tid
    158 "       movq    8(%rsp),  %r8\n"        // syscall arg5: tls_ptr
    159 
    160 "       syscall\n"                      // clone()
    161 
    162 "       testq   %rax, %rax\n"           // child if retval == 0
    163 "       jnz     1f\n"
    164 
    165         // CHILD - call thread function
    166 "       pop     %rax\n"                 // pop fn
    167 "       pop     %rdi\n"                 // pop fn arg1: arg
    168 "       call    *%rax\n"                // call fn
    169 
    170         // exit with result
    171 "       movq    %rax, %rdi\n"           // arg1: return value from fn
    172 "       movq    $"__NR_EXIT", %rax\n"
    173 
    174 "       syscall\n"
    175 
    176         // Exit returned?!
    177 "       ud2\n"
    178 
    179 "1:\n"  // PARENT or ERROR
    180 "       ret\n"
    181 ".previous\n"
    182 );
    183 
    184 #undef __NR_CLONE
    185 #undef __NR_EXIT
    186 
    187 
    188 // forward declaration
    189 static void setup_child ( ThreadArchState*, ThreadArchState* );
    190 
    191 /*
    192    When a client clones, we need to keep track of the new thread.  This means:
    193    1. allocate a ThreadId+ThreadState+stack for the the thread
    194 
    195    2. initialize the thread's new VCPU state
    196 
    197    3. create the thread using the same args as the client requested,
    198    but using the scheduler entrypoint for EIP, and a separate stack
    199    for ESP.
    200  */
    201 static SysRes do_clone ( ThreadId ptid,
    202                          ULong flags, Addr rsp,
    203                          Long* parent_tidptr,
    204                          Long* child_tidptr,
    205                          Addr tlsaddr )
    206 {
    207    static const Bool debug = False;
    208 
    209    ThreadId     ctid = VG_(alloc_ThreadState)();
    210    ThreadState* ptst = VG_(get_ThreadState)(ptid);
    211    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    212    UWord*       stack;
    213    NSegment const* seg;
    214    SysRes       res;
    215    Long         rax;
    216    vki_sigset_t blockall, savedmask;
    217 
    218    VG_(sigfillset)(&blockall);
    219 
    220    vg_assert(VG_(is_running_thread)(ptid));
    221    vg_assert(VG_(is_valid_tid)(ctid));
    222 
    223    stack = (UWord*)ML_(allocstack)(ctid);
    224    if (stack == NULL) {
    225       res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
    226       goto out;
    227    }
    228 
    229    /* Copy register state
    230 
    231       Both parent and child return to the same place, and the code
    232       following the clone syscall works out which is which, so we
    233       don't need to worry about it.
    234 
    235       The parent gets the child's new tid returned from clone, but the
    236       child gets 0.
    237 
    238       If the clone call specifies a NULL rsp for the new thread, then
    239       it actually gets a copy of the parent's rsp.
    240    */
    241    setup_child( &ctst->arch, &ptst->arch );
    242 
    243    /* Make sys_clone appear to have returned Success(0) in the
    244       child. */
    245    ctst->arch.vex.guest_RAX = 0;
    246 
    247    if (rsp != 0)
    248       ctst->arch.vex.guest_RSP = rsp;
    249 
    250    ctst->os_state.parent = ptid;
    251 
    252    /* inherit signal mask */
    253    ctst->sig_mask = ptst->sig_mask;
    254    ctst->tmp_sig_mask = ptst->sig_mask;
    255 
    256    /* Start the child with its threadgroup being the same as the
    257       parent's.  This is so that any exit_group calls that happen
    258       after the child is created but before it sets its
    259       os_state.threadgroup field for real (in thread_wrapper in
    260       syswrap-linux.c), really kill the new thread.  a.k.a this avoids
    261       a race condition in which the thread is unkillable (via
    262       exit_group) because its threadgroup is not set.  The race window
    263       is probably only a few hundred or a few thousand cycles long.
    264       See #226116. */
    265    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
    266 
    267    /* We don't really know where the client stack is, because its
    268       allocated by the client.  The best we can do is look at the
    269       memory mappings and try to derive some useful information.  We
    270       assume that esp starts near its highest possible value, and can
    271       only go down to the start of the mmaped segment. */
    272    seg = VG_(am_find_nsegment)((Addr)rsp);
    273    if (seg && seg->kind != SkResvn) {
    274       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(rsp);
    275       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
    276 
    277       VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
    278 
    279       if (debug)
    280 	 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
    281 		     ctid, seg->start, VG_PGROUNDUP(rsp));
    282    } else {
    283       VG_(message)(Vg_UserMsg,
    284                    "!? New thread %d starts with RSP(%#lx) unmapped\n",
    285 		   ctid, rsp);
    286       ctst->client_stack_szB  = 0;
    287    }
    288 
    289    /* Assume the clone will succeed, and tell any tool that wants to
    290       know that this thread has come into existence.  If the clone
    291       fails, we'll send out a ll_exit notification for it at the out:
    292       label below, to clean up. */
    293    vg_assert(VG_(owns_BigLock_LL)(ptid));
    294    VG_TRACK ( pre_thread_ll_create, ptid, ctid );
    295 
    296    if (flags & VKI_CLONE_SETTLS) {
    297       if (debug)
    298 	 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
    299       ctst->arch.vex.guest_FS_ZERO = tlsaddr;
    300    }
    301 
    302    flags &= ~VKI_CLONE_SETTLS;
    303 
    304    /* start the thread with everything blocked */
    305    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
    306 
    307    /* Create the new thread */
    308    rax = do_syscall_clone_amd64_linux(
    309             ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
    310             child_tidptr, parent_tidptr, NULL
    311          );
    312    res = VG_(mk_SysRes_amd64_linux)( rax );
    313 
    314    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
    315 
    316   out:
    317    if (sr_isError(res)) {
    318       /* clone failed */
    319       VG_(cleanup_thread)(&ctst->arch);
    320       ctst->status = VgTs_Empty;
    321       /* oops.  Better tell the tool the thread exited in a hurry :-) */
    322       VG_TRACK( pre_thread_ll_exit, ctid );
    323    }
    324 
    325    return res;
    326 }
    327 
    328 
    329 /* ---------------------------------------------------------------------
    330    More thread stuff
    331    ------------------------------------------------------------------ */
    332 
    333 void VG_(cleanup_thread) ( ThreadArchState *arch )
    334 {
    335 }
    336 
    337 void setup_child ( /*OUT*/ ThreadArchState *child,
    338                    /*IN*/  ThreadArchState *parent )
    339 {
    340    /* We inherit our parent's guest state. */
    341    child->vex = parent->vex;
    342    child->vex_shadow1 = parent->vex_shadow1;
    343    child->vex_shadow2 = parent->vex_shadow2;
    344 }
    345 
    346 
    347 /* ---------------------------------------------------------------------
    348    PRE/POST wrappers for AMD64/Linux-specific syscalls
    349    ------------------------------------------------------------------ */
    350 
    351 #define PRE(name)       DEFN_PRE_TEMPLATE(amd64_linux, name)
    352 #define POST(name)      DEFN_POST_TEMPLATE(amd64_linux, name)
    353 
    354 /* Add prototypes for the wrappers declared here, so that gcc doesn't
    355    harass us for not having prototypes.  Really this is a kludge --
    356    the right thing to do is to make these wrappers 'static' since they
    357    aren't visible outside this file, but that requires even more macro
    358    magic. */
    359 DECL_TEMPLATE(amd64_linux, sys_clone);
    360 DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
    361 DECL_TEMPLATE(amd64_linux, sys_socket);
    362 DECL_TEMPLATE(amd64_linux, sys_setsockopt);
    363 DECL_TEMPLATE(amd64_linux, sys_getsockopt);
    364 DECL_TEMPLATE(amd64_linux, sys_connect);
    365 DECL_TEMPLATE(amd64_linux, sys_accept);
    366 DECL_TEMPLATE(amd64_linux, sys_accept4);
    367 DECL_TEMPLATE(amd64_linux, sys_sendto);
    368 DECL_TEMPLATE(amd64_linux, sys_recvfrom);
    369 DECL_TEMPLATE(amd64_linux, sys_sendmsg);
    370 DECL_TEMPLATE(amd64_linux, sys_recvmsg);
    371 DECL_TEMPLATE(amd64_linux, sys_shutdown);
    372 DECL_TEMPLATE(amd64_linux, sys_bind);
    373 DECL_TEMPLATE(amd64_linux, sys_listen);
    374 DECL_TEMPLATE(amd64_linux, sys_getsockname);
    375 DECL_TEMPLATE(amd64_linux, sys_getpeername);
    376 DECL_TEMPLATE(amd64_linux, sys_socketpair);
    377 DECL_TEMPLATE(amd64_linux, sys_semget);
    378 DECL_TEMPLATE(amd64_linux, sys_semop);
    379 DECL_TEMPLATE(amd64_linux, sys_semtimedop);
    380 DECL_TEMPLATE(amd64_linux, sys_semctl);
    381 DECL_TEMPLATE(amd64_linux, sys_msgget);
    382 DECL_TEMPLATE(amd64_linux, sys_msgrcv);
    383 DECL_TEMPLATE(amd64_linux, sys_msgsnd);
    384 DECL_TEMPLATE(amd64_linux, sys_msgctl);
    385 DECL_TEMPLATE(amd64_linux, sys_shmget);
    386 DECL_TEMPLATE(amd64_linux, wrap_sys_shmat);
    387 DECL_TEMPLATE(amd64_linux, sys_shmdt);
    388 DECL_TEMPLATE(amd64_linux, sys_shmdt);
    389 DECL_TEMPLATE(amd64_linux, sys_shmctl);
    390 DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
    391 DECL_TEMPLATE(amd64_linux, sys_ptrace);
    392 DECL_TEMPLATE(amd64_linux, sys_fadvise64);
    393 DECL_TEMPLATE(amd64_linux, sys_mmap);
    394 DECL_TEMPLATE(amd64_linux, sys_syscall184);
    395 
    396 
    397 PRE(sys_clone)
    398 {
    399    ULong cloneflags;
    400 
    401    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
    402    PRE_REG_READ2(int, "clone",
    403                  unsigned long, flags,
    404                  void *, child_stack);
    405 
    406    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    407       if (VG_(tdict).track_pre_reg_read) {
    408          PRA3("clone", int *, parent_tidptr);
    409       }
    410       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    411       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
    412          SET_STATUS_Failure( VKI_EFAULT );
    413          return;
    414       }
    415    }
    416    if (ARG1 & VKI_CLONE_SETTLS) {
    417       if (VG_(tdict).track_pre_reg_read) {
    418          PRA4("clone", vki_modify_ldt_t *, tlsinfo);
    419       }
    420       PRE_MEM_READ("clone(tlsinfo)", ARG4, sizeof(vki_modify_ldt_t));
    421       if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
    422                                              VKI_PROT_READ)) {
    423          SET_STATUS_Failure( VKI_EFAULT );
    424          return;
    425       }
    426    }
    427    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    428       if (VG_(tdict).track_pre_reg_read) {
    429          PRA5("clone", int *, child_tidptr);
    430       }
    431       PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
    432       if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
    433          SET_STATUS_Failure( VKI_EFAULT );
    434          return;
    435       }
    436    }
    437 
    438    cloneflags = ARG1;
    439 
    440    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
    441       SET_STATUS_Failure( VKI_EINVAL );
    442       return;
    443    }
    444 
    445    /* Only look at the flags we really care about */
    446    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    447                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    448    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    449       /* thread creation */
    450       SET_STATUS_from_SysRes(
    451          do_clone(tid,
    452                   ARG1,          /* flags */
    453                   (Addr)ARG2,    /* child ESP */
    454                   (Long *)ARG3,  /* parent_tidptr */
    455                   (Long *)ARG4,  /* child_tidptr */
    456                   (Addr)ARG5));  /* set_tls */
    457       break;
    458 
    459    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
    460       /* FALLTHROUGH - assume vfork == fork */
    461       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    462 
    463    case 0: /* plain fork */
    464       SET_STATUS_from_SysRes(
    465          ML_(do_fork_clone)(tid,
    466                        cloneflags,      /* flags */
    467                        (Int *)ARG3,     /* parent_tidptr */
    468                        (Int *)ARG4));   /* child_tidptr */
    469       break;
    470 
    471    default:
    472       /* should we just ENOSYS? */
    473       VG_(message)(Vg_UserMsg,
    474                    "Unsupported clone() flags: 0x%lx\n", ARG1);
    475       VG_(message)(Vg_UserMsg,
    476                    "\n");
    477       VG_(message)(Vg_UserMsg,
    478                    "The only supported clone() uses are:\n");
    479       VG_(message)(Vg_UserMsg,
    480                    " - via a threads library (LinuxThreads or NPTL)\n");
    481       VG_(message)(Vg_UserMsg,
    482                    " - via the implementation of fork or vfork\n");
    483       VG_(unimplemented)
    484          ("Valgrind does not support general clone().");
    485    }
    486 
    487    if (SUCCESS) {
    488       if (ARG1 & VKI_CLONE_PARENT_SETTID)
    489          POST_MEM_WRITE(ARG3, sizeof(Int));
    490       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    491          POST_MEM_WRITE(ARG4, sizeof(Int));
    492 
    493       /* Thread creation was successful; let the child have the chance
    494          to run */
    495       *flags |= SfYieldAfter;
    496    }
    497 }
    498 
    499 PRE(sys_rt_sigreturn)
    500 {
    501    /* This isn't really a syscall at all - it's a misuse of the
    502       syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
    503       return address of the signal frames it creates to be a short
    504       piece of code which does this "syscall".  The only purpose of
    505       the syscall is to call VG_(sigframe_destroy), which restores the
    506       thread's registers from the frame and then removes it.
    507       Consequently we must ask the syswrap driver logic not to write
    508       back the syscall "result" as that would overwrite the
    509       just-restored register state. */
    510 
    511    ThreadState* tst;
    512    PRINT("sys_rt_sigreturn ( )");
    513 
    514    vg_assert(VG_(is_valid_tid)(tid));
    515    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    516    vg_assert(VG_(is_running_thread)(tid));
    517 
    518    /* Adjust RSP to point to start of frame; skip back up over handler
    519       ret addr */
    520    tst = VG_(get_ThreadState)(tid);
    521    tst->arch.vex.guest_RSP -= sizeof(Addr);
    522 
    523    /* This is only so that the RIP is (might be) useful to report if
    524       something goes wrong in the sigreturn.  JRS 20070318: no idea
    525       what this is for */
    526    ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    527 
    528    /* Restore register state from frame and remove it, as
    529       described above */
    530    VG_(sigframe_destroy)(tid, True);
    531 
    532    /* Tell the driver not to update the guest state with the "result",
    533       and set a bogus result to keep it happy. */
    534    *flags |= SfNoWriteResult;
    535    SET_STATUS_Success(0);
    536 
    537    /* Check to see if any signals arose as a result of this. */
    538    *flags |= SfPollAfter;
    539 }
    540 
    541 PRE(sys_arch_prctl)
    542 {
    543    ThreadState* tst;
    544    PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
    545 
    546    vg_assert(VG_(is_valid_tid)(tid));
    547    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    548    vg_assert(VG_(is_running_thread)(tid));
    549 
    550    // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
    551    PRE_REG_READ2(long, "arch_prctl",
    552                  int, option, unsigned long, arg2);
    553    // XXX: totally wrong... we need to look at the 'option' arg, and do
    554    // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
    555 
    556    /* "do" the syscall ourselves; the kernel never sees it */
    557    if (ARG1 == VKI_ARCH_SET_FS) {
    558       tst = VG_(get_ThreadState)(tid);
    559       tst->arch.vex.guest_FS_ZERO = ARG2;
    560    }
    561    else if (ARG1 == VKI_ARCH_GET_FS) {
    562       PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
    563       tst = VG_(get_ThreadState)(tid);
    564       *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_ZERO;
    565       POST_MEM_WRITE(ARG2, sizeof(unsigned long));
    566    }
    567    else {
    568       VG_(core_panic)("Unsupported arch_prtctl option");
    569    }
    570 
    571    /* Note; the Status writeback to guest state that happens after
    572       this wrapper returns does not change guest_FS_ZERO; hence that
    573       direct assignment to the guest state is safe here. */
    574    SET_STATUS_Success( 0 );
    575 }
    576 
    577 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
    578 //
    579 // ARG3 is only used for pointers into the traced process's address
    580 // space and for offsets into the traced process's struct
    581 // user_regs_struct. It is never a pointer into this process's memory
    582 // space, and we should therefore not check anything it points to.
    583 PRE(sys_ptrace)
    584 {
    585    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
    586    PRE_REG_READ4(int, "ptrace",
    587                  long, request, long, pid, long, addr, long, data);
    588    switch (ARG1) {
    589    case VKI_PTRACE_PEEKTEXT:
    590    case VKI_PTRACE_PEEKDATA:
    591    case VKI_PTRACE_PEEKUSR:
    592       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
    593 		     sizeof (long));
    594       break;
    595    case VKI_PTRACE_GETREGS:
    596       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
    597 		     sizeof (struct vki_user_regs_struct));
    598       break;
    599    case VKI_PTRACE_GETFPREGS:
    600       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
    601 		     sizeof (struct vki_user_i387_struct));
    602       break;
    603    case VKI_PTRACE_SETREGS:
    604       PRE_MEM_READ( "ptrace(setregs)", ARG4,
    605 		     sizeof (struct vki_user_regs_struct));
    606       break;
    607    case VKI_PTRACE_SETFPREGS:
    608       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
    609 		     sizeof (struct vki_user_i387_struct));
    610       break;
    611    case VKI_PTRACE_GETEVENTMSG:
    612       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
    613       break;
    614    case VKI_PTRACE_GETSIGINFO:
    615       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
    616       break;
    617    case VKI_PTRACE_SETSIGINFO:
    618       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
    619       break;
    620    default:
    621       break;
    622    }
    623 }
    624 
    625 POST(sys_ptrace)
    626 {
    627    switch (ARG1) {
    628    case VKI_PTRACE_PEEKTEXT:
    629    case VKI_PTRACE_PEEKDATA:
    630    case VKI_PTRACE_PEEKUSR:
    631       POST_MEM_WRITE( ARG4, sizeof (long));
    632       break;
    633    case VKI_PTRACE_GETREGS:
    634       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
    635       break;
    636    case VKI_PTRACE_GETFPREGS:
    637       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
    638       break;
    639    case VKI_PTRACE_GETEVENTMSG:
    640       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
    641       break;
    642    case VKI_PTRACE_GETSIGINFO:
    643       /* XXX: This is a simplification. Different parts of the
    644        * siginfo_t are valid depending on the type of signal.
    645        */
    646       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
    647       break;
    648    default:
    649       break;
    650    }
    651 }
    652 
    653 PRE(sys_socket)
    654 {
    655    PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
    656    PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
    657 }
    658 POST(sys_socket)
    659 {
    660    SysRes r;
    661    vg_assert(SUCCESS);
    662    r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
    663    SET_STATUS_from_SysRes(r);
    664 }
    665 
    666 PRE(sys_setsockopt)
    667 {
    668    PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
    669    PRE_REG_READ5(long, "setsockopt",
    670                  int, s, int, level, int, optname,
    671                  const void *, optval, int, optlen);
    672    ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
    673 }
    674 
    675 PRE(sys_getsockopt)
    676 {
    677    PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
    678    PRE_REG_READ5(long, "getsockopt",
    679                  int, s, int, level, int, optname,
    680                  void *, optval, int, *optlen);
    681    ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
    682 }
    683 POST(sys_getsockopt)
    684 {
    685    vg_assert(SUCCESS);
    686    ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
    687                                        ARG1,ARG2,ARG3,ARG4,ARG5);
    688 }
    689 
    690 PRE(sys_connect)
    691 {
    692    *flags |= SfMayBlock;
    693    PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    694    PRE_REG_READ3(long, "connect",
    695                  int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
    696    ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
    697 }
    698 
    699 PRE(sys_accept)
    700 {
    701    *flags |= SfMayBlock;
    702    PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    703    PRE_REG_READ3(long, "accept",
    704                  int, s, struct sockaddr *, addr, int, *addrlen);
    705    ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
    706 }
    707 POST(sys_accept)
    708 {
    709    SysRes r;
    710    vg_assert(SUCCESS);
    711    r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
    712                                          ARG1,ARG2,ARG3);
    713    SET_STATUS_from_SysRes(r);
    714 }
    715 
    716 PRE(sys_accept4)
    717 {
    718    *flags |= SfMayBlock;
    719    PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
    720    PRE_REG_READ4(long, "accept4",
    721                  int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
    722    ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
    723 }
    724 POST(sys_accept4)
    725 {
    726    SysRes r;
    727    vg_assert(SUCCESS);
    728    r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
    729                                          ARG1,ARG2,ARG3);
    730    SET_STATUS_from_SysRes(r);
    731 }
    732 
    733 PRE(sys_sendto)
    734 {
    735    *flags |= SfMayBlock;
    736    PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    737    PRE_REG_READ6(long, "sendto",
    738                  int, s, const void *, msg, int, len,
    739                  unsigned int, flags,
    740                  const struct sockaddr *, to, int, tolen);
    741    ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    742 }
    743 
    744 PRE(sys_recvfrom)
    745 {
    746    *flags |= SfMayBlock;
    747    PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    748    PRE_REG_READ6(long, "recvfrom",
    749                  int, s, void *, buf, int, len, unsigned int, flags,
    750                  struct sockaddr *, from, int *, fromlen);
    751    ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    752 }
    753 POST(sys_recvfrom)
    754 {
    755    vg_assert(SUCCESS);
    756    ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
    757                                        ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    758 }
    759 
    760 PRE(sys_sendmsg)
    761 {
    762    *flags |= SfMayBlock;
    763    PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    764    PRE_REG_READ3(long, "sendmsg",
    765                  int, s, const struct msghdr *, msg, int, flags);
    766    ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
    767 }
    768 
    769 PRE(sys_recvmsg)
    770 {
    771    *flags |= SfMayBlock;
    772    PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    773    PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
    774    ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
    775 }
    776 POST(sys_recvmsg)
    777 {
    778    ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
    779 }
    780 
    781 PRE(sys_shutdown)
    782 {
    783    *flags |= SfMayBlock;
    784    PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
    785    PRE_REG_READ2(int, "shutdown", int, s, int, how);
    786 }
    787 
    788 PRE(sys_bind)
    789 {
    790    PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    791    PRE_REG_READ3(long, "bind",
    792                  int, sockfd, struct sockaddr *, my_addr, int, addrlen);
    793    ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
    794 }
    795 
    796 PRE(sys_listen)
    797 {
    798    PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
    799    PRE_REG_READ2(long, "listen", int, s, int, backlog);
    800 }
    801 
    802 PRE(sys_getsockname)
    803 {
    804    PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
    805    PRE_REG_READ3(long, "getsockname",
    806                  int, s, struct sockaddr *, name, int *, namelen);
    807    ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
    808 }
    809 POST(sys_getsockname)
    810 {
    811    vg_assert(SUCCESS);
    812    ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
    813                                           ARG1,ARG2,ARG3);
    814 }
    815 
    816 PRE(sys_getpeername)
    817 {
    818    PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
    819    PRE_REG_READ3(long, "getpeername",
    820                  int, s, struct sockaddr *, name, int *, namelen);
    821    ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
    822 }
    823 POST(sys_getpeername)
    824 {
    825    vg_assert(SUCCESS);
    826    ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
    827                                           ARG1,ARG2,ARG3);
    828 }
    829 
    830 PRE(sys_socketpair)
    831 {
    832    PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
    833    PRE_REG_READ4(long, "socketpair",
    834                  int, d, int, type, int, protocol, int*, sv);
    835    ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
    836 }
    837 POST(sys_socketpair)
    838 {
    839    vg_assert(SUCCESS);
    840    ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
    841                                          ARG1,ARG2,ARG3,ARG4);
    842 }
    843 
    844 PRE(sys_semget)
    845 {
    846    PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
    847    PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
    848 }
    849 
    850 PRE(sys_semop)
    851 {
    852    *flags |= SfMayBlock;
    853    PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
    854    PRE_REG_READ3(long, "semop",
    855                  int, semid, struct sembuf *, sops, unsigned, nsoops);
    856    ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
    857 }
    858 
    859 PRE(sys_semtimedop)
    860 {
    861    *flags |= SfMayBlock;
    862    PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
    863    PRE_REG_READ4(long, "semtimedop",
    864                  int, semid, struct sembuf *, sops, unsigned, nsoops,
    865                  struct timespec *, timeout);
    866    ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
    867 }
    868 
    869 PRE(sys_semctl)
    870 {
    871    switch (ARG3 & ~VKI_IPC_64) {
    872    case VKI_IPC_INFO:
    873    case VKI_SEM_INFO:
    874       PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
    875       PRE_REG_READ4(long, "semctl",
    876                     int, semid, int, semnum, int, cmd, struct seminfo *, arg);
    877       break;
    878    case VKI_IPC_STAT:
    879    case VKI_SEM_STAT:
    880    case VKI_IPC_SET:
    881       PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
    882       PRE_REG_READ4(long, "semctl",
    883                     int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
    884       break;
    885    case VKI_GETALL:
    886    case VKI_SETALL:
    887       PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
    888       PRE_REG_READ4(long, "semctl",
    889                     int, semid, int, semnum, int, cmd, unsigned short *, arg);
    890       break;
    891    default:
    892       PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
    893       PRE_REG_READ3(long, "semctl",
    894                     int, semid, int, semnum, int, cmd);
    895       break;
    896    }
    897    ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
    898 }
    899 POST(sys_semctl)
    900 {
    901    ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
    902 }
    903 
    904 PRE(sys_msgget)
    905 {
    906    PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
    907    PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
    908 }
    909 
    910 PRE(sys_msgsnd)
    911 {
    912    PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
    913    PRE_REG_READ4(long, "msgsnd",
    914                  int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
    915    ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
    916    if ((ARG4 & VKI_IPC_NOWAIT) == 0)
    917       *flags |= SfMayBlock;
    918 }
    919 
    920 PRE(sys_msgrcv)
    921 {
    922    PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
    923    PRE_REG_READ5(long, "msgrcv",
    924                  int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
    925                  long, msgytp, int, msgflg);
    926    ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
    927    if ((ARG4 & VKI_IPC_NOWAIT) == 0)
    928       *flags |= SfMayBlock;
    929 }
    930 POST(sys_msgrcv)
    931 {
    932    ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
    933 }
    934 
    935 PRE(sys_msgctl)
    936 {
    937    PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
    938    PRE_REG_READ3(long, "msgctl",
    939                  int, msqid, int, cmd, struct msqid_ds *, buf);
    940    ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
    941 }
    942 POST(sys_msgctl)
    943 {
    944    ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
    945 }
    946 
    947 PRE(sys_shmget)
    948 {
    949    PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
    950    PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
    951 }
    952 
    953 PRE(wrap_sys_shmat)
    954 {
    955    UWord arg2tmp;
    956    PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
    957    PRE_REG_READ3(long, "shmat",
    958                  int, shmid, const void *, shmaddr, int, shmflg);
    959    arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
    960    if (arg2tmp == 0)
    961       SET_STATUS_Failure( VKI_EINVAL );
    962    else
    963       ARG2 = arg2tmp;  // used in POST
    964 }
    965 POST(wrap_sys_shmat)
    966 {
    967    ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
    968 }
    969 
    970 PRE(sys_shmdt)
    971 {
    972    PRINT("sys_shmdt ( %#lx )",ARG1);
    973    PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
    974    if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
    975       SET_STATUS_Failure( VKI_EINVAL );
    976 }
    977 POST(sys_shmdt)
    978 {
    979    ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
    980 }
    981 
    982 PRE(sys_shmctl)
    983 {
    984    PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
    985    PRE_REG_READ3(long, "shmctl",
    986                  int, shmid, int, cmd, struct shmid_ds *, buf);
    987    ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
    988 }
    989 POST(sys_shmctl)
    990 {
    991    ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
    992 }
    993 
    994 PRE(sys_fadvise64)
    995 {
    996    PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", ARG1,ARG2,ARG3,ARG4);
    997    PRE_REG_READ4(long, "fadvise64",
    998                  int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
    999 }
   1000 
   1001 PRE(sys_mmap)
   1002 {
   1003    SysRes r;
   1004 
   1005    PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %d, %ld )",
   1006          ARG1, (ULong)ARG2, ARG3, ARG4, (Int)ARG5, ARG6 );
   1007    PRE_REG_READ6(long, "mmap",
   1008                  unsigned long, start, unsigned long, length,
   1009                  unsigned long, prot,  unsigned long, flags,
   1010                  unsigned long, fd,    unsigned long, offset);
   1011 
   1012    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
   1013    SET_STATUS_from_SysRes(r);
   1014 }
   1015 
   1016 
   1017 /* ---------------------------------------------------------------
   1018    PRE/POST wrappers for AMD64/Linux-variant specific syscalls
   1019    ------------------------------------------------------------ */
   1020 
   1021 PRE(sys_syscall184)
   1022 {
   1023    Int err;
   1024 
   1025    /* 184 is used by sys_bproc.  If we're not on a declared bproc
   1026       variant, fail in the usual way, since it is otherwise unused. */
   1027 
   1028    if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
   1029       PRINT("non-existent syscall! (syscall 184)");
   1030       PRE_REG_READ0(long, "ni_syscall(184)");
   1031       SET_STATUS_Failure( VKI_ENOSYS );
   1032       return;
   1033    }
   1034 
   1035    err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
   1036                                            ARG4, ARG5, ARG6 );
   1037    if (err) {
   1038       SET_STATUS_Failure( err );
   1039       return;
   1040    }
   1041    /* Let it go through. */
   1042    *flags |= SfMayBlock; /* who knows?  play safe. */
   1043 }
   1044 
   1045 POST(sys_syscall184)
   1046 {
   1047    ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
   1048                                       ARG4, ARG5, ARG6 );
   1049 }
   1050 
   1051 #undef PRE
   1052 #undef POST
   1053 
   1054 
   1055 /* ---------------------------------------------------------------------
   1056    The AMD64/Linux syscall table
   1057    ------------------------------------------------------------------ */
   1058 
   1059 /* Add an amd64-linux specific wrapper to a syscall table. */
   1060 #define PLAX_(const, name)    WRAPPER_ENTRY_X_(amd64_linux, const, name)
   1061 #define PLAXY(const, name)    WRAPPER_ENTRY_XY(amd64_linux, const, name)
   1062 
   1063 // This table maps from __NR_xxx syscall numbers (from
   1064 // linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
   1065 // wrappers on AMD64 (as per sys_call_table in
   1066 // linux/arch/x86_64/kernel/entry.S).
   1067 //
   1068 // When implementing these wrappers, you need to work out if the wrapper is
   1069 // generic, Linux-only (but arch-independent), or AMD64/Linux only.
   1070 
   1071 static SyscallTableEntry syscall_table[] = {
   1072    GENXY(__NR_read,              sys_read),           // 0
   1073    GENX_(__NR_write,             sys_write),          // 1
   1074    GENXY(__NR_open,              sys_open),           // 2
   1075    GENXY(__NR_close,             sys_close),          // 3
   1076    GENXY(__NR_stat,              sys_newstat),        // 4
   1077 
   1078    GENXY(__NR_fstat,             sys_newfstat),       // 5
   1079    GENXY(__NR_lstat,             sys_newlstat),       // 6
   1080    GENXY(__NR_poll,              sys_poll),           // 7
   1081    LINX_(__NR_lseek,             sys_lseek),          // 8
   1082    PLAX_(__NR_mmap,              sys_mmap),           // 9
   1083 
   1084    GENXY(__NR_mprotect,          sys_mprotect),       // 10
   1085    GENXY(__NR_munmap,            sys_munmap),         // 11
   1086    GENX_(__NR_brk,               sys_brk),            // 12
   1087    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 13
   1088    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 14
   1089 
   1090    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 15
   1091    LINXY(__NR_ioctl,             sys_ioctl),          // 16
   1092    GENXY(__NR_pread64,           sys_pread64),        // 17
   1093    GENX_(__NR_pwrite64,          sys_pwrite64),       // 18
   1094    GENXY(__NR_readv,             sys_readv),          // 19
   1095 
   1096    GENX_(__NR_writev,            sys_writev),         // 20
   1097    GENX_(__NR_access,            sys_access),         // 21
   1098    LINXY(__NR_pipe,              sys_pipe),           // 22
   1099    GENX_(__NR_select,            sys_select),         // 23
   1100    LINX_(__NR_sched_yield,       sys_sched_yield),    // 24
   1101 
   1102    GENX_(__NR_mremap,            sys_mremap),         // 25
   1103    GENX_(__NR_msync,             sys_msync),          // 26
   1104    GENXY(__NR_mincore,           sys_mincore),        // 27
   1105    GENX_(__NR_madvise,           sys_madvise),        // 28
   1106    PLAX_(__NR_shmget,            sys_shmget),         // 29
   1107 
   1108    PLAXY(__NR_shmat,             wrap_sys_shmat),     // 30
   1109    PLAXY(__NR_shmctl,            sys_shmctl),         // 31
   1110    GENXY(__NR_dup,               sys_dup),            // 32
   1111    GENXY(__NR_dup2,              sys_dup2),           // 33
   1112    GENX_(__NR_pause,             sys_pause),          // 34
   1113 
   1114    GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
   1115    GENXY(__NR_getitimer,         sys_getitimer),      // 36
   1116    GENX_(__NR_alarm,             sys_alarm),          // 37
   1117    GENXY(__NR_setitimer,         sys_setitimer),      // 38
   1118    GENX_(__NR_getpid,            sys_getpid),         // 39
   1119 
   1120    LINXY(__NR_sendfile,          sys_sendfile),       // 40
   1121    PLAXY(__NR_socket,            sys_socket),         // 41
   1122    PLAX_(__NR_connect,           sys_connect),        // 42
   1123    PLAXY(__NR_accept,            sys_accept),         // 43
   1124    PLAX_(__NR_sendto,            sys_sendto),         // 44
   1125 
   1126    PLAXY(__NR_recvfrom,          sys_recvfrom),       // 45
   1127    PLAX_(__NR_sendmsg,           sys_sendmsg),        // 46
   1128    PLAXY(__NR_recvmsg,           sys_recvmsg),        // 47
   1129    PLAX_(__NR_shutdown,          sys_shutdown),       // 48
   1130    PLAX_(__NR_bind,              sys_bind),           // 49
   1131 
   1132    PLAX_(__NR_listen,            sys_listen),         // 50
   1133    PLAXY(__NR_getsockname,       sys_getsockname),    // 51
   1134    PLAXY(__NR_getpeername,       sys_getpeername),    // 52
   1135    PLAXY(__NR_socketpair,        sys_socketpair),     // 53
   1136    PLAX_(__NR_setsockopt,        sys_setsockopt),     // 54
   1137 
   1138    PLAXY(__NR_getsockopt,        sys_getsockopt),     // 55
   1139    PLAX_(__NR_clone,             sys_clone),          // 56
   1140    GENX_(__NR_fork,              sys_fork),           // 57
   1141    GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
   1142    GENX_(__NR_execve,            sys_execve),         // 59
   1143 
   1144    GENX_(__NR_exit,              sys_exit),           // 60
   1145    GENXY(__NR_wait4,             sys_wait4),          // 61
   1146    GENX_(__NR_kill,              sys_kill),           // 62
   1147    GENXY(__NR_uname,             sys_newuname),       // 63
   1148    PLAX_(__NR_semget,            sys_semget),         // 64
   1149 
   1150    PLAX_(__NR_semop,             sys_semop),          // 65
   1151    PLAXY(__NR_semctl,            sys_semctl),         // 66
   1152    PLAXY(__NR_shmdt,             sys_shmdt),          // 67
   1153    PLAX_(__NR_msgget,            sys_msgget),         // 68
   1154    PLAX_(__NR_msgsnd,            sys_msgsnd),         // 69
   1155 
   1156    PLAXY(__NR_msgrcv,            sys_msgrcv),         // 70
   1157    PLAXY(__NR_msgctl,            sys_msgctl),         // 71
   1158    LINXY(__NR_fcntl,             sys_fcntl),          // 72
   1159    GENX_(__NR_flock,             sys_flock),          // 73
   1160    GENX_(__NR_fsync,             sys_fsync),          // 74
   1161 
   1162    GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
   1163    GENX_(__NR_truncate,          sys_truncate),       // 76
   1164    GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
   1165    GENXY(__NR_getdents,          sys_getdents),       // 78
   1166    GENXY(__NR_getcwd,            sys_getcwd),         // 79
   1167 
   1168    GENX_(__NR_chdir,             sys_chdir),          // 80
   1169    GENX_(__NR_fchdir,            sys_fchdir),         // 81
   1170    GENX_(__NR_rename,            sys_rename),         // 82
   1171    GENX_(__NR_mkdir,             sys_mkdir),          // 83
   1172    GENX_(__NR_rmdir,             sys_rmdir),          // 84
   1173 
   1174    GENXY(__NR_creat,             sys_creat),          // 85
   1175    GENX_(__NR_link,              sys_link),           // 86
   1176    GENX_(__NR_unlink,            sys_unlink),         // 87
   1177    GENX_(__NR_symlink,           sys_symlink),        // 88
   1178    GENX_(__NR_readlink,          sys_readlink),       // 89
   1179 
   1180    GENX_(__NR_chmod,             sys_chmod),          // 90
   1181    GENX_(__NR_fchmod,            sys_fchmod),         // 91
   1182    GENX_(__NR_chown,             sys_chown),          // 92
   1183    GENX_(__NR_fchown,            sys_fchown),         // 93
   1184    GENX_(__NR_lchown,            sys_lchown),         // 94
   1185 
   1186    GENX_(__NR_umask,             sys_umask),          // 95
   1187    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
   1188    GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
   1189    GENXY(__NR_getrusage,         sys_getrusage),      // 98
   1190    LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
   1191 
   1192    GENXY(__NR_times,             sys_times),          // 100
   1193    PLAXY(__NR_ptrace,            sys_ptrace),         // 101
   1194    GENX_(__NR_getuid,            sys_getuid),         // 102
   1195    LINXY(__NR_syslog,            sys_syslog),         // 103
   1196    GENX_(__NR_getgid,            sys_getgid),         // 104
   1197 
   1198    GENX_(__NR_setuid,            sys_setuid),         // 105
   1199    GENX_(__NR_setgid,            sys_setgid),         // 106
   1200    GENX_(__NR_geteuid,           sys_geteuid),        // 107
   1201    GENX_(__NR_getegid,           sys_getegid),        // 108
   1202    GENX_(__NR_setpgid,           sys_setpgid),        // 109
   1203 
   1204    GENX_(__NR_getppid,           sys_getppid),        // 110
   1205    GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
   1206    GENX_(__NR_setsid,            sys_setsid),         // 112
   1207    GENX_(__NR_setreuid,          sys_setreuid),       // 113
   1208    GENX_(__NR_setregid,          sys_setregid),       // 114
   1209 
   1210    GENXY(__NR_getgroups,         sys_getgroups),      // 115
   1211    GENX_(__NR_setgroups,         sys_setgroups),      // 116
   1212    LINX_(__NR_setresuid,         sys_setresuid),      // 117
   1213    LINXY(__NR_getresuid,         sys_getresuid),      // 118
   1214    LINX_(__NR_setresgid,         sys_setresgid),      // 119
   1215 
   1216    LINXY(__NR_getresgid,         sys_getresgid),      // 120
   1217    GENX_(__NR_getpgid,           sys_getpgid),        // 121
   1218    LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
   1219    LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
   1220    GENX_(__NR_getsid,            sys_getsid),         // 124
   1221 
   1222    LINXY(__NR_capget,            sys_capget),         // 125
   1223    LINX_(__NR_capset,            sys_capset),         // 126
   1224    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
   1225    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
   1226    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
   1227 
   1228    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
   1229    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
   1230    LINX_(__NR_utime,             sys_utime),          // 132
   1231    GENX_(__NR_mknod,             sys_mknod),          // 133
   1232    //   (__NR_uselib,            sys_uselib),         // 134
   1233 
   1234    LINX_(__NR_personality,       sys_personality),    // 135
   1235    //   (__NR_ustat,             sys_ustat),          // 136
   1236    GENXY(__NR_statfs,            sys_statfs),         // 137
   1237    GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
   1238    //   (__NR_sysfs,             sys_sysfs),          // 139
   1239 
   1240    GENX_(__NR_getpriority,             sys_getpriority),             // 140
   1241    GENX_(__NR_setpriority,             sys_setpriority),             // 141
   1242    LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
   1243    LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
   1244    LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
   1245 
   1246    LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
   1247    LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
   1248    LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
   1249    LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
   1250    GENX_(__NR_mlock,                   sys_mlock),                   // 149
   1251 
   1252    GENX_(__NR_munlock,           sys_munlock),        // 150
   1253    GENX_(__NR_mlockall,          sys_mlockall),       // 151
   1254    LINX_(__NR_munlockall,        sys_munlockall),     // 152
   1255    LINX_(__NR_vhangup,           sys_vhangup),        // 153
   1256    //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
   1257 
   1258    //   (__NR_pivot_root,        sys_pivot_root),     // 155
   1259    LINXY(__NR__sysctl,           sys_sysctl),         // 156
   1260    LINXY(__NR_prctl,             sys_prctl),          // 157
   1261    PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
   1262    LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
   1263 
   1264    GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
   1265    GENX_(__NR_chroot,            sys_chroot),         // 161
   1266    GENX_(__NR_sync,              sys_sync),           // 162
   1267    //   (__NR_acct,              sys_acct),           // 163
   1268    GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
   1269 
   1270    LINX_(__NR_mount,             sys_mount),          // 165
   1271    LINX_(__NR_umount2,           sys_umount),         // 166
   1272    //   (__NR_swapon,            sys_swapon),         // 167
   1273    //   (__NR_swapoff,           sys_swapoff),        // 168
   1274    //   (__NR_reboot,            sys_reboot),         // 169
   1275 
   1276    //   (__NR_sethostname,       sys_sethostname),    // 170
   1277    //   (__NR_setdomainname,     sys_setdomainname),  // 171
   1278    GENX_(__NR_iopl,              sys_iopl),           // 172
   1279    LINX_(__NR_ioperm,            sys_ioperm),         // 173
   1280    GENX_(__NR_create_module,     sys_ni_syscall),     // 174
   1281 
   1282    LINX_(__NR_init_module,       sys_init_module),    // 175
   1283    LINX_(__NR_delete_module,     sys_delete_module),  // 176
   1284    //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
   1285    //   (__NR_query_module,      sys_ni_syscall),     // 178
   1286    LINX_(__NR_quotactl,          sys_quotactl),       // 179
   1287 
   1288    //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
   1289    //   (__NR_getpmsg,           sys_ni_syscall),     // 181
   1290    //   (__NR_putpmsg,           sys_ni_syscall),     // 182
   1291    //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
   1292    PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
   1293 
   1294    //   (__NR_security,          sys_ni_syscall),     // 185
   1295    LINX_(__NR_gettid,            sys_gettid),         // 186
   1296    LINX_(__NR_readahead,         sys_readahead),      // 187
   1297    LINX_(__NR_setxattr,          sys_setxattr),       // 188
   1298    LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
   1299 
   1300    LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
   1301    LINXY(__NR_getxattr,          sys_getxattr),       // 191
   1302    LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
   1303    LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
   1304    LINXY(__NR_listxattr,         sys_listxattr),      // 194
   1305 
   1306    LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
   1307    LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
   1308    LINX_(__NR_removexattr,       sys_removexattr),    // 197
   1309    LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
   1310    LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
   1311 
   1312    LINXY(__NR_tkill,             sys_tkill),             // 200
   1313    GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
   1314    LINXY(__NR_futex,             sys_futex),             // 202
   1315    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
   1316    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
   1317 
   1318    //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
   1319    LINXY(__NR_io_setup,          sys_io_setup),       // 206
   1320    LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
   1321    LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
   1322    LINX_(__NR_io_submit,         sys_io_submit),      // 209
   1323 
   1324    LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
   1325    //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
   1326    LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
   1327    LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
   1328    //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
   1329 
   1330    //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
   1331    //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
   1332    GENXY(__NR_getdents64,        sys_getdents64),     // 217
   1333    LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
   1334    //   (__NR_restart_syscall,   sys_restart_syscall),// 219
   1335 
   1336    PLAX_(__NR_semtimedop,        sys_semtimedop),     // 220
   1337    PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
   1338    LINXY(__NR_timer_create,      sys_timer_create),   // 222
   1339    LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
   1340    LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
   1341 
   1342    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
   1343    LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
   1344    LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
   1345    LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
   1346    LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
   1347 
   1348    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
   1349    LINX_(__NR_exit_group,        sys_exit_group),     // 231
   1350    LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
   1351    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
   1352    LINXY(__NR_tgkill,            sys_tgkill),         // 234
   1353 
   1354    GENX_(__NR_utimes,            sys_utimes),         // 235
   1355    //   (__NR_vserver,           sys_ni_syscall),     // 236
   1356    LINX_(__NR_mbind,             sys_mbind),          // 237
   1357    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
   1358    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
   1359 
   1360    LINXY(__NR_mq_open,           sys_mq_open),        // 240
   1361    LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
   1362    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
   1363    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
   1364    LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
   1365 
   1366    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
   1367    //   (__NR_kexec_load,        sys_ni_syscall),     // 246
   1368    LINXY(__NR_waitid,            sys_waitid),         // 247
   1369    LINX_(__NR_add_key,           sys_add_key),        // 248
   1370    LINX_(__NR_request_key,       sys_request_key),    // 249
   1371 
   1372    LINXY(__NR_keyctl,            sys_keyctl),         // 250
   1373    LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
   1374    LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
   1375    LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
   1376    LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
   1377 
   1378    LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
   1379 //   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
   1380    LINXY(__NR_openat,		 sys_openat),           // 257
   1381    LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
   1382    LINX_(__NR_mknodat,		 sys_mknodat),          // 259
   1383 
   1384    LINX_(__NR_fchownat,		 sys_fchownat),         // 260
   1385    LINX_(__NR_futimesat,	 sys_futimesat),        // 261
   1386    LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
   1387    LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
   1388    LINX_(__NR_renameat,		 sys_renameat),         // 264
   1389 
   1390    LINX_(__NR_linkat,		 sys_linkat),           // 265
   1391    LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
   1392    LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
   1393    LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
   1394    LINX_(__NR_faccessat,	 sys_faccessat),        // 269
   1395 
   1396    LINX_(__NR_pselect6,		 sys_pselect6),         // 270
   1397    LINXY(__NR_ppoll,		 sys_ppoll),            // 271
   1398 //   LINX_(__NR_unshare,		 sys_unshare),          // 272
   1399    LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
   1400    LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
   1401 
   1402    LINX_(__NR_splice,            sys_splice),           // 275
   1403    LINX_(__NR_tee,               sys_tee),              // 276
   1404    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
   1405    LINXY(__NR_vmsplice,          sys_vmsplice),         // 278
   1406    LINXY(__NR_move_pages,        sys_move_pages),       // 279
   1407 
   1408    LINX_(__NR_utimensat,         sys_utimensat),        // 280
   1409    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
   1410    LINXY(__NR_signalfd,          sys_signalfd),         // 282
   1411    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
   1412    LINX_(__NR_eventfd,           sys_eventfd),          // 284
   1413 
   1414    LINX_(__NR_fallocate,         sys_fallocate),        // 285
   1415    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
   1416    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
   1417    PLAXY(__NR_accept4,           sys_accept4),          // 288
   1418    LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
   1419 
   1420    LINX_(__NR_eventfd2,          sys_eventfd2),         // 290
   1421    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
   1422    LINXY(__NR_dup3,              sys_dup3),             // 292
   1423    LINXY(__NR_pipe2,             sys_pipe2),            // 293
   1424    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
   1425 
   1426    LINXY(__NR_preadv,            sys_preadv),           // 295
   1427    LINX_(__NR_pwritev,           sys_pwritev),          // 296
   1428    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
   1429    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
   1430    LINXY(__NR_recvmmsg,          sys_recvmmsg),         // 299
   1431 
   1432 //   LINX_(__NR_fanotify_init,     sys_ni_syscall),       // 300
   1433 //   LINX_(__NR_fanotify_mark,     sys_ni_syscall),       // 301
   1434    LINXY(__NR_prlimit64,         sys_prlimit64),        // 302
   1435 //   LINX_(__NR_name_to_handle_at, sys_ni_syscall),       // 303
   1436 //   LINX_(__NR_open_by_handle_at, sys_ni_syscall),       // 304
   1437 
   1438 //   LINX_(__NR_clock_adjtime,     sys_ni_syscall),       // 305
   1439 //   LINX_(__NR_syncfs,            sys_ni_syscall),       // 306
   1440    LINXY(__NR_sendmmsg,          sys_sendmmsg),         // 307
   1441 //   LINX_(__NR_setns,             sys_ni_syscall),       // 308
   1442    LINXY(__NR_getcpu,            sys_getcpu),           // 309
   1443 
   1444    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 310
   1445    LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 311
   1446 };
   1447 
   1448 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
   1449 {
   1450    const UInt syscall_table_size
   1451       = sizeof(syscall_table) / sizeof(syscall_table[0]);
   1452 
   1453    /* Is it in the contiguous initial section of the table? */
   1454    if (sysno < syscall_table_size) {
   1455       SyscallTableEntry* sys = &syscall_table[sysno];
   1456       if (sys->before == NULL)
   1457          return NULL; /* no entry */
   1458       else
   1459          return sys;
   1460    }
   1461 
   1462    /* Can't find a wrapper */
   1463    return NULL;
   1464 }
   1465 
   1466 #endif // defined(VGP_amd64_linux)
   1467 
   1468 /*--------------------------------------------------------------------*/
   1469 /*--- end                                                          ---*/
   1470 /*--------------------------------------------------------------------*/
   1471