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-2013 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_arch_prctl);
    362 DECL_TEMPLATE(amd64_linux, sys_ptrace);
    363 DECL_TEMPLATE(amd64_linux, sys_fadvise64);
    364 DECL_TEMPLATE(amd64_linux, sys_mmap);
    365 DECL_TEMPLATE(amd64_linux, sys_syscall184);
    366 
    367 
    368 PRE(sys_clone)
    369 {
    370    ULong cloneflags;
    371 
    372    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
    373    PRE_REG_READ2(int, "clone",
    374                  unsigned long, flags,
    375                  void *, child_stack);
    376 
    377    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    378       if (VG_(tdict).track_pre_reg_read) {
    379          PRA3("clone", int *, parent_tidptr);
    380       }
    381       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    382       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
    383          SET_STATUS_Failure( VKI_EFAULT );
    384          return;
    385       }
    386    }
    387    if (ARG1 & VKI_CLONE_SETTLS) {
    388       if (VG_(tdict).track_pre_reg_read) {
    389          PRA4("clone", vki_modify_ldt_t *, tlsinfo);
    390       }
    391       PRE_MEM_READ("clone(tlsinfo)", ARG4, sizeof(vki_modify_ldt_t));
    392       if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
    393                                              VKI_PROT_READ)) {
    394          SET_STATUS_Failure( VKI_EFAULT );
    395          return;
    396       }
    397    }
    398    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    399       if (VG_(tdict).track_pre_reg_read) {
    400          PRA5("clone", int *, child_tidptr);
    401       }
    402       PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
    403       if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
    404          SET_STATUS_Failure( VKI_EFAULT );
    405          return;
    406       }
    407    }
    408 
    409    cloneflags = ARG1;
    410 
    411    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
    412       SET_STATUS_Failure( VKI_EINVAL );
    413       return;
    414    }
    415 
    416    /* Only look at the flags we really care about */
    417    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    418                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    419    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    420       /* thread creation */
    421       SET_STATUS_from_SysRes(
    422          do_clone(tid,
    423                   ARG1,          /* flags */
    424                   (Addr)ARG2,    /* child ESP */
    425                   (Long *)ARG3,  /* parent_tidptr */
    426                   (Long *)ARG4,  /* child_tidptr */
    427                   (Addr)ARG5));  /* set_tls */
    428       break;
    429 
    430    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
    431       /* FALLTHROUGH - assume vfork == fork */
    432       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    433 
    434    case 0: /* plain fork */
    435       SET_STATUS_from_SysRes(
    436          ML_(do_fork_clone)(tid,
    437                        cloneflags,      /* flags */
    438                        (Int *)ARG3,     /* parent_tidptr */
    439                        (Int *)ARG4));   /* child_tidptr */
    440       break;
    441 
    442    default:
    443       /* should we just ENOSYS? */
    444       VG_(message)(Vg_UserMsg,
    445                    "Unsupported clone() flags: 0x%lx\n", ARG1);
    446       VG_(message)(Vg_UserMsg,
    447                    "\n");
    448       VG_(message)(Vg_UserMsg,
    449                    "The only supported clone() uses are:\n");
    450       VG_(message)(Vg_UserMsg,
    451                    " - via a threads library (LinuxThreads or NPTL)\n");
    452       VG_(message)(Vg_UserMsg,
    453                    " - via the implementation of fork or vfork\n");
    454       VG_(unimplemented)
    455          ("Valgrind does not support general clone().");
    456    }
    457 
    458    if (SUCCESS) {
    459       if (ARG1 & VKI_CLONE_PARENT_SETTID)
    460          POST_MEM_WRITE(ARG3, sizeof(Int));
    461       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    462          POST_MEM_WRITE(ARG4, sizeof(Int));
    463 
    464       /* Thread creation was successful; let the child have the chance
    465          to run */
    466       *flags |= SfYieldAfter;
    467    }
    468 }
    469 
    470 PRE(sys_rt_sigreturn)
    471 {
    472    /* This isn't really a syscall at all - it's a misuse of the
    473       syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
    474       return address of the signal frames it creates to be a short
    475       piece of code which does this "syscall".  The only purpose of
    476       the syscall is to call VG_(sigframe_destroy), which restores the
    477       thread's registers from the frame and then removes it.
    478       Consequently we must ask the syswrap driver logic not to write
    479       back the syscall "result" as that would overwrite the
    480       just-restored register state. */
    481 
    482    ThreadState* tst;
    483    PRINT("sys_rt_sigreturn ( )");
    484 
    485    vg_assert(VG_(is_valid_tid)(tid));
    486    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    487    vg_assert(VG_(is_running_thread)(tid));
    488 
    489    /* Adjust RSP to point to start of frame; skip back up over handler
    490       ret addr */
    491    tst = VG_(get_ThreadState)(tid);
    492    tst->arch.vex.guest_RSP -= sizeof(Addr);
    493 
    494    /* This is only so that the RIP is (might be) useful to report if
    495       something goes wrong in the sigreturn.  JRS 20070318: no idea
    496       what this is for */
    497    ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    498 
    499    /* Restore register state from frame and remove it, as
    500       described above */
    501    VG_(sigframe_destroy)(tid, True);
    502 
    503    /* Tell the driver not to update the guest state with the "result",
    504       and set a bogus result to keep it happy. */
    505    *flags |= SfNoWriteResult;
    506    SET_STATUS_Success(0);
    507 
    508    /* Check to see if any signals arose as a result of this. */
    509    *flags |= SfPollAfter;
    510 }
    511 
    512 PRE(sys_arch_prctl)
    513 {
    514    ThreadState* tst;
    515    PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
    516 
    517    vg_assert(VG_(is_valid_tid)(tid));
    518    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    519    vg_assert(VG_(is_running_thread)(tid));
    520 
    521    // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
    522    PRE_REG_READ2(long, "arch_prctl",
    523                  int, option, unsigned long, arg2);
    524    // XXX: totally wrong... we need to look at the 'option' arg, and do
    525    // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
    526 
    527    /* "do" the syscall ourselves; the kernel never sees it */
    528    if (ARG1 == VKI_ARCH_SET_FS) {
    529       tst = VG_(get_ThreadState)(tid);
    530       tst->arch.vex.guest_FS_ZERO = ARG2;
    531    }
    532    else if (ARG1 == VKI_ARCH_GET_FS) {
    533       PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
    534       tst = VG_(get_ThreadState)(tid);
    535       *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_ZERO;
    536       POST_MEM_WRITE(ARG2, sizeof(unsigned long));
    537    }
    538    else {
    539       VG_(core_panic)("Unsupported arch_prtctl option");
    540    }
    541 
    542    /* Note; the Status writeback to guest state that happens after
    543       this wrapper returns does not change guest_FS_ZERO; hence that
    544       direct assignment to the guest state is safe here. */
    545    SET_STATUS_Success( 0 );
    546 }
    547 
    548 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
    549 //
    550 // ARG3 is only used for pointers into the traced process's address
    551 // space and for offsets into the traced process's struct
    552 // user_regs_struct. It is never a pointer into this process's memory
    553 // space, and we should therefore not check anything it points to.
    554 PRE(sys_ptrace)
    555 {
    556    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
    557    PRE_REG_READ4(int, "ptrace",
    558                  long, request, long, pid, long, addr, long, data);
    559    switch (ARG1) {
    560    case VKI_PTRACE_PEEKTEXT:
    561    case VKI_PTRACE_PEEKDATA:
    562    case VKI_PTRACE_PEEKUSR:
    563       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
    564 		     sizeof (long));
    565       break;
    566    case VKI_PTRACE_GETREGS:
    567       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
    568 		     sizeof (struct vki_user_regs_struct));
    569       break;
    570    case VKI_PTRACE_GETFPREGS:
    571       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
    572 		     sizeof (struct vki_user_i387_struct));
    573       break;
    574    case VKI_PTRACE_SETREGS:
    575       PRE_MEM_READ( "ptrace(setregs)", ARG4,
    576 		     sizeof (struct vki_user_regs_struct));
    577       break;
    578    case VKI_PTRACE_SETFPREGS:
    579       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
    580 		     sizeof (struct vki_user_i387_struct));
    581       break;
    582    case VKI_PTRACE_GETEVENTMSG:
    583       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
    584       break;
    585    case VKI_PTRACE_GETSIGINFO:
    586       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
    587       break;
    588    case VKI_PTRACE_SETSIGINFO:
    589       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
    590       break;
    591    case VKI_PTRACE_GETREGSET:
    592       ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
    593       break;
    594    case VKI_PTRACE_SETREGSET:
    595       ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
    596       break;
    597    default:
    598       break;
    599    }
    600 }
    601 
    602 POST(sys_ptrace)
    603 {
    604    switch (ARG1) {
    605    case VKI_PTRACE_PEEKTEXT:
    606    case VKI_PTRACE_PEEKDATA:
    607    case VKI_PTRACE_PEEKUSR:
    608       POST_MEM_WRITE( ARG4, sizeof (long));
    609       break;
    610    case VKI_PTRACE_GETREGS:
    611       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
    612       break;
    613    case VKI_PTRACE_GETFPREGS:
    614       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
    615       break;
    616    case VKI_PTRACE_GETEVENTMSG:
    617       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
    618       break;
    619    case VKI_PTRACE_GETSIGINFO:
    620       /* XXX: This is a simplification. Different parts of the
    621        * siginfo_t are valid depending on the type of signal.
    622        */
    623       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
    624       break;
    625    case VKI_PTRACE_GETREGSET:
    626       ML_(linux_POST_getregset)(tid, ARG3, ARG4);
    627       break;
    628    default:
    629       break;
    630    }
    631 }
    632 
    633 PRE(sys_fadvise64)
    634 {
    635    PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", ARG1,ARG2,ARG3,ARG4);
    636    PRE_REG_READ4(long, "fadvise64",
    637                  int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
    638 }
    639 
    640 PRE(sys_mmap)
    641 {
    642    SysRes r;
    643 
    644    PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %d, %ld )",
    645          ARG1, (ULong)ARG2, ARG3, ARG4, (Int)ARG5, ARG6 );
    646    PRE_REG_READ6(long, "mmap",
    647                  unsigned long, start, unsigned long, length,
    648                  unsigned long, prot,  unsigned long, flags,
    649                  unsigned long, fd,    unsigned long, offset);
    650 
    651    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
    652    SET_STATUS_from_SysRes(r);
    653 }
    654 
    655 
    656 /* ---------------------------------------------------------------
    657    PRE/POST wrappers for AMD64/Linux-variant specific syscalls
    658    ------------------------------------------------------------ */
    659 
    660 PRE(sys_syscall184)
    661 {
    662    Int err;
    663 
    664    /* 184 is used by sys_bproc.  If we're not on a declared bproc
    665       variant, fail in the usual way, since it is otherwise unused. */
    666 
    667    if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
    668       PRINT("non-existent syscall! (syscall 184)");
    669       PRE_REG_READ0(long, "ni_syscall(184)");
    670       SET_STATUS_Failure( VKI_ENOSYS );
    671       return;
    672    }
    673 
    674    err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
    675                                            ARG4, ARG5, ARG6 );
    676    if (err) {
    677       SET_STATUS_Failure( err );
    678       return;
    679    }
    680    /* Let it go through. */
    681    *flags |= SfMayBlock; /* who knows?  play safe. */
    682 }
    683 
    684 POST(sys_syscall184)
    685 {
    686    ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
    687                                       ARG4, ARG5, ARG6 );
    688 }
    689 
    690 #undef PRE
    691 #undef POST
    692 
    693 
    694 /* ---------------------------------------------------------------------
    695    The AMD64/Linux syscall table
    696    ------------------------------------------------------------------ */
    697 
    698 /* Add an amd64-linux specific wrapper to a syscall table. */
    699 #define PLAX_(const, name)    WRAPPER_ENTRY_X_(amd64_linux, const, name)
    700 #define PLAXY(const, name)    WRAPPER_ENTRY_XY(amd64_linux, const, name)
    701 
    702 // This table maps from __NR_xxx syscall numbers (from
    703 // linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
    704 // wrappers on AMD64 (as per sys_call_table in
    705 // linux/arch/x86_64/kernel/entry.S).
    706 //
    707 // When implementing these wrappers, you need to work out if the wrapper is
    708 // generic, Linux-only (but arch-independent), or AMD64/Linux only.
    709 
    710 static SyscallTableEntry syscall_table[] = {
    711    GENXY(__NR_read,              sys_read),           // 0
    712    GENX_(__NR_write,             sys_write),          // 1
    713    GENXY(__NR_open,              sys_open),           // 2
    714    GENXY(__NR_close,             sys_close),          // 3
    715    GENXY(__NR_stat,              sys_newstat),        // 4
    716 
    717    GENXY(__NR_fstat,             sys_newfstat),       // 5
    718    GENXY(__NR_lstat,             sys_newlstat),       // 6
    719    GENXY(__NR_poll,              sys_poll),           // 7
    720    LINX_(__NR_lseek,             sys_lseek),          // 8
    721    PLAX_(__NR_mmap,              sys_mmap),           // 9
    722 
    723    GENXY(__NR_mprotect,          sys_mprotect),       // 10
    724    GENXY(__NR_munmap,            sys_munmap),         // 11
    725    GENX_(__NR_brk,               sys_brk),            // 12
    726    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 13
    727    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 14
    728 
    729    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 15
    730    LINXY(__NR_ioctl,             sys_ioctl),          // 16
    731    GENXY(__NR_pread64,           sys_pread64),        // 17
    732    GENX_(__NR_pwrite64,          sys_pwrite64),       // 18
    733    GENXY(__NR_readv,             sys_readv),          // 19
    734 
    735    GENX_(__NR_writev,            sys_writev),         // 20
    736    GENX_(__NR_access,            sys_access),         // 21
    737    LINXY(__NR_pipe,              sys_pipe),           // 22
    738    GENX_(__NR_select,            sys_select),         // 23
    739    LINX_(__NR_sched_yield,       sys_sched_yield),    // 24
    740 
    741    GENX_(__NR_mremap,            sys_mremap),         // 25
    742    GENX_(__NR_msync,             sys_msync),          // 26
    743    GENXY(__NR_mincore,           sys_mincore),        // 27
    744    GENX_(__NR_madvise,           sys_madvise),        // 28
    745    LINX_(__NR_shmget,            sys_shmget),         // 29
    746 
    747    LINXY(__NR_shmat,             wrap_sys_shmat),     // 30
    748    LINXY(__NR_shmctl,            sys_shmctl),         // 31
    749    GENXY(__NR_dup,               sys_dup),            // 32
    750    GENXY(__NR_dup2,              sys_dup2),           // 33
    751    GENX_(__NR_pause,             sys_pause),          // 34
    752 
    753    GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
    754    GENXY(__NR_getitimer,         sys_getitimer),      // 36
    755    GENX_(__NR_alarm,             sys_alarm),          // 37
    756    GENXY(__NR_setitimer,         sys_setitimer),      // 38
    757    GENX_(__NR_getpid,            sys_getpid),         // 39
    758 
    759    LINXY(__NR_sendfile,          sys_sendfile),       // 40
    760    LINXY(__NR_socket,            sys_socket),         // 41
    761    LINX_(__NR_connect,           sys_connect),        // 42
    762    LINXY(__NR_accept,            sys_accept),         // 43
    763    LINX_(__NR_sendto,            sys_sendto),         // 44
    764 
    765    LINXY(__NR_recvfrom,          sys_recvfrom),       // 45
    766    LINX_(__NR_sendmsg,           sys_sendmsg),        // 46
    767    LINXY(__NR_recvmsg,           sys_recvmsg),        // 47
    768    LINX_(__NR_shutdown,          sys_shutdown),       // 48
    769    LINX_(__NR_bind,              sys_bind),           // 49
    770 
    771    LINX_(__NR_listen,            sys_listen),         // 50
    772    LINXY(__NR_getsockname,       sys_getsockname),    // 51
    773    LINXY(__NR_getpeername,       sys_getpeername),    // 52
    774    LINXY(__NR_socketpair,        sys_socketpair),     // 53
    775    LINX_(__NR_setsockopt,        sys_setsockopt),     // 54
    776 
    777    LINXY(__NR_getsockopt,        sys_getsockopt),     // 55
    778    PLAX_(__NR_clone,             sys_clone),          // 56
    779    GENX_(__NR_fork,              sys_fork),           // 57
    780    GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
    781    GENX_(__NR_execve,            sys_execve),         // 59
    782 
    783    GENX_(__NR_exit,              sys_exit),           // 60
    784    GENXY(__NR_wait4,             sys_wait4),          // 61
    785    GENX_(__NR_kill,              sys_kill),           // 62
    786    GENXY(__NR_uname,             sys_newuname),       // 63
    787    LINX_(__NR_semget,            sys_semget),         // 64
    788 
    789    LINX_(__NR_semop,             sys_semop),          // 65
    790    LINXY(__NR_semctl,            sys_semctl),         // 66
    791    LINXY(__NR_shmdt,             sys_shmdt),          // 67
    792    LINX_(__NR_msgget,            sys_msgget),         // 68
    793    LINX_(__NR_msgsnd,            sys_msgsnd),         // 69
    794 
    795    LINXY(__NR_msgrcv,            sys_msgrcv),         // 70
    796    LINXY(__NR_msgctl,            sys_msgctl),         // 71
    797    LINXY(__NR_fcntl,             sys_fcntl),          // 72
    798    GENX_(__NR_flock,             sys_flock),          // 73
    799    GENX_(__NR_fsync,             sys_fsync),          // 74
    800 
    801    GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
    802    GENX_(__NR_truncate,          sys_truncate),       // 76
    803    GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
    804    GENXY(__NR_getdents,          sys_getdents),       // 78
    805    GENXY(__NR_getcwd,            sys_getcwd),         // 79
    806 
    807    GENX_(__NR_chdir,             sys_chdir),          // 80
    808    GENX_(__NR_fchdir,            sys_fchdir),         // 81
    809    GENX_(__NR_rename,            sys_rename),         // 82
    810    GENX_(__NR_mkdir,             sys_mkdir),          // 83
    811    GENX_(__NR_rmdir,             sys_rmdir),          // 84
    812 
    813    GENXY(__NR_creat,             sys_creat),          // 85
    814    GENX_(__NR_link,              sys_link),           // 86
    815    GENX_(__NR_unlink,            sys_unlink),         // 87
    816    GENX_(__NR_symlink,           sys_symlink),        // 88
    817    GENX_(__NR_readlink,          sys_readlink),       // 89
    818 
    819    GENX_(__NR_chmod,             sys_chmod),          // 90
    820    GENX_(__NR_fchmod,            sys_fchmod),         // 91
    821    GENX_(__NR_chown,             sys_chown),          // 92
    822    GENX_(__NR_fchown,            sys_fchown),         // 93
    823    GENX_(__NR_lchown,            sys_lchown),         // 94
    824 
    825    GENX_(__NR_umask,             sys_umask),          // 95
    826    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
    827    GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
    828    GENXY(__NR_getrusage,         sys_getrusage),      // 98
    829    LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
    830 
    831    GENXY(__NR_times,             sys_times),          // 100
    832    PLAXY(__NR_ptrace,            sys_ptrace),         // 101
    833    GENX_(__NR_getuid,            sys_getuid),         // 102
    834    LINXY(__NR_syslog,            sys_syslog),         // 103
    835    GENX_(__NR_getgid,            sys_getgid),         // 104
    836 
    837    GENX_(__NR_setuid,            sys_setuid),         // 105
    838    GENX_(__NR_setgid,            sys_setgid),         // 106
    839    GENX_(__NR_geteuid,           sys_geteuid),        // 107
    840    GENX_(__NR_getegid,           sys_getegid),        // 108
    841    GENX_(__NR_setpgid,           sys_setpgid),        // 109
    842 
    843    GENX_(__NR_getppid,           sys_getppid),        // 110
    844    GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
    845    GENX_(__NR_setsid,            sys_setsid),         // 112
    846    GENX_(__NR_setreuid,          sys_setreuid),       // 113
    847    GENX_(__NR_setregid,          sys_setregid),       // 114
    848 
    849    GENXY(__NR_getgroups,         sys_getgroups),      // 115
    850    GENX_(__NR_setgroups,         sys_setgroups),      // 116
    851    LINX_(__NR_setresuid,         sys_setresuid),      // 117
    852    LINXY(__NR_getresuid,         sys_getresuid),      // 118
    853    LINX_(__NR_setresgid,         sys_setresgid),      // 119
    854 
    855    LINXY(__NR_getresgid,         sys_getresgid),      // 120
    856    GENX_(__NR_getpgid,           sys_getpgid),        // 121
    857    LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
    858    LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
    859    GENX_(__NR_getsid,            sys_getsid),         // 124
    860 
    861    LINXY(__NR_capget,            sys_capget),         // 125
    862    LINX_(__NR_capset,            sys_capset),         // 126
    863    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
    864    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
    865    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
    866 
    867    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
    868    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
    869    LINX_(__NR_utime,             sys_utime),          // 132
    870    GENX_(__NR_mknod,             sys_mknod),          // 133
    871    //   (__NR_uselib,            sys_uselib),         // 134
    872 
    873    LINX_(__NR_personality,       sys_personality),    // 135
    874    //   (__NR_ustat,             sys_ustat),          // 136
    875    GENXY(__NR_statfs,            sys_statfs),         // 137
    876    GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
    877    //   (__NR_sysfs,             sys_sysfs),          // 139
    878 
    879    GENX_(__NR_getpriority,             sys_getpriority),             // 140
    880    GENX_(__NR_setpriority,             sys_setpriority),             // 141
    881    LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
    882    LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
    883    LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
    884 
    885    LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
    886    LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
    887    LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
    888    LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
    889    GENX_(__NR_mlock,                   sys_mlock),                   // 149
    890 
    891    GENX_(__NR_munlock,           sys_munlock),        // 150
    892    GENX_(__NR_mlockall,          sys_mlockall),       // 151
    893    LINX_(__NR_munlockall,        sys_munlockall),     // 152
    894    LINX_(__NR_vhangup,           sys_vhangup),        // 153
    895    //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
    896 
    897    //   (__NR_pivot_root,        sys_pivot_root),     // 155
    898    LINXY(__NR__sysctl,           sys_sysctl),         // 156
    899    LINXY(__NR_prctl,             sys_prctl),          // 157
    900    PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
    901    LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
    902 
    903    GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
    904    GENX_(__NR_chroot,            sys_chroot),         // 161
    905    GENX_(__NR_sync,              sys_sync),           // 162
    906    //   (__NR_acct,              sys_acct),           // 163
    907    GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
    908 
    909    LINX_(__NR_mount,             sys_mount),          // 165
    910    LINX_(__NR_umount2,           sys_umount),         // 166
    911    //   (__NR_swapon,            sys_swapon),         // 167
    912    //   (__NR_swapoff,           sys_swapoff),        // 168
    913    //   (__NR_reboot,            sys_reboot),         // 169
    914 
    915    GENX_(__NR_sethostname,       sys_sethostname),    // 170
    916    //   (__NR_setdomainname,     sys_setdomainname),  // 171
    917    GENX_(__NR_iopl,              sys_iopl),           // 172
    918    LINX_(__NR_ioperm,            sys_ioperm),         // 173
    919    GENX_(__NR_create_module,     sys_ni_syscall),     // 174
    920 
    921    LINX_(__NR_init_module,       sys_init_module),    // 175
    922    LINX_(__NR_delete_module,     sys_delete_module),  // 176
    923    //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
    924    //   (__NR_query_module,      sys_ni_syscall),     // 178
    925    LINX_(__NR_quotactl,          sys_quotactl),       // 179
    926 
    927    //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
    928    //   (__NR_getpmsg,           sys_ni_syscall),     // 181
    929    //   (__NR_putpmsg,           sys_ni_syscall),     // 182
    930    //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
    931    PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
    932 
    933    //   (__NR_security,          sys_ni_syscall),     // 185
    934    LINX_(__NR_gettid,            sys_gettid),         // 186
    935    LINX_(__NR_readahead,         sys_readahead),      // 187
    936    LINX_(__NR_setxattr,          sys_setxattr),       // 188
    937    LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
    938 
    939    LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
    940    LINXY(__NR_getxattr,          sys_getxattr),       // 191
    941    LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
    942    LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
    943    LINXY(__NR_listxattr,         sys_listxattr),      // 194
    944 
    945    LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
    946    LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
    947    LINX_(__NR_removexattr,       sys_removexattr),    // 197
    948    LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
    949    LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
    950 
    951    LINXY(__NR_tkill,             sys_tkill),             // 200
    952    GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
    953    LINXY(__NR_futex,             sys_futex),             // 202
    954    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
    955    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
    956 
    957    //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
    958    LINXY(__NR_io_setup,          sys_io_setup),       // 206
    959    LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
    960    LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
    961    LINX_(__NR_io_submit,         sys_io_submit),      // 209
    962 
    963    LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
    964    //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
    965    LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
    966    LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
    967    //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
    968 
    969    //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
    970    //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
    971    GENXY(__NR_getdents64,        sys_getdents64),     // 217
    972    LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
    973    //   (__NR_restart_syscall,   sys_restart_syscall),// 219
    974 
    975    LINX_(__NR_semtimedop,        sys_semtimedop),     // 220
    976    PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
    977    LINXY(__NR_timer_create,      sys_timer_create),   // 222
    978    LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
    979    LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
    980 
    981    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
    982    LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
    983    LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
    984    LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
    985    LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
    986 
    987    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
    988    LINX_(__NR_exit_group,        sys_exit_group),     // 231
    989    LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
    990    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
    991    LINXY(__NR_tgkill,            sys_tgkill),         // 234
    992 
    993    GENX_(__NR_utimes,            sys_utimes),         // 235
    994    //   (__NR_vserver,           sys_ni_syscall),     // 236
    995    LINX_(__NR_mbind,             sys_mbind),          // 237
    996    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
    997    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
    998 
    999    LINXY(__NR_mq_open,           sys_mq_open),        // 240
   1000    LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
   1001    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
   1002    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
   1003    LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
   1004 
   1005    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
   1006    //   (__NR_kexec_load,        sys_ni_syscall),     // 246
   1007    LINXY(__NR_waitid,            sys_waitid),         // 247
   1008    LINX_(__NR_add_key,           sys_add_key),        // 248
   1009    LINX_(__NR_request_key,       sys_request_key),    // 249
   1010 
   1011    LINXY(__NR_keyctl,            sys_keyctl),         // 250
   1012    LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
   1013    LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
   1014    LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
   1015    LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
   1016 
   1017    LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
   1018 //   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
   1019    LINXY(__NR_openat,		 sys_openat),           // 257
   1020    LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
   1021    LINX_(__NR_mknodat,		 sys_mknodat),          // 259
   1022 
   1023    LINX_(__NR_fchownat,		 sys_fchownat),         // 260
   1024    LINX_(__NR_futimesat,	 sys_futimesat),        // 261
   1025    LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
   1026    LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
   1027    LINX_(__NR_renameat,		 sys_renameat),         // 264
   1028 
   1029    LINX_(__NR_linkat,		 sys_linkat),           // 265
   1030    LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
   1031    LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
   1032    LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
   1033    LINX_(__NR_faccessat,	 sys_faccessat),        // 269
   1034 
   1035    LINX_(__NR_pselect6,		 sys_pselect6),         // 270
   1036    LINXY(__NR_ppoll,		 sys_ppoll),            // 271
   1037 //   LINX_(__NR_unshare,		 sys_unshare),          // 272
   1038    LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
   1039    LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
   1040 
   1041    LINX_(__NR_splice,            sys_splice),           // 275
   1042    LINX_(__NR_tee,               sys_tee),              // 276
   1043    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
   1044    LINXY(__NR_vmsplice,          sys_vmsplice),         // 278
   1045    LINXY(__NR_move_pages,        sys_move_pages),       // 279
   1046 
   1047    LINX_(__NR_utimensat,         sys_utimensat),        // 280
   1048    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
   1049    LINXY(__NR_signalfd,          sys_signalfd),         // 282
   1050    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
   1051    LINXY(__NR_eventfd,           sys_eventfd),          // 284
   1052 
   1053    LINX_(__NR_fallocate,         sys_fallocate),        // 285
   1054    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
   1055    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
   1056    LINXY(__NR_accept4,           sys_accept4),          // 288
   1057    LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
   1058 
   1059    LINXY(__NR_eventfd2,          sys_eventfd2),         // 290
   1060    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
   1061    LINXY(__NR_dup3,              sys_dup3),             // 292
   1062    LINXY(__NR_pipe2,             sys_pipe2),            // 293
   1063    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
   1064 
   1065    LINXY(__NR_preadv,            sys_preadv),           // 295
   1066    LINX_(__NR_pwritev,           sys_pwritev),          // 296
   1067    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
   1068    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
   1069    LINXY(__NR_recvmmsg,          sys_recvmmsg),         // 299
   1070 
   1071    LINXY(__NR_fanotify_init,     sys_fanotify_init),    // 300
   1072    LINX_(__NR_fanotify_mark,     sys_fanotify_mark),    // 301
   1073    LINXY(__NR_prlimit64,         sys_prlimit64),        // 302
   1074    LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 303
   1075    LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 304
   1076 
   1077    LINXY(__NR_clock_adjtime,     sys_clock_adjtime),    // 305
   1078 //   LINX_(__NR_syncfs,            sys_ni_syscall),       // 306
   1079    LINXY(__NR_sendmmsg,          sys_sendmmsg),         // 307
   1080 //   LINX_(__NR_setns,             sys_ni_syscall),       // 308
   1081    LINXY(__NR_getcpu,            sys_getcpu),           // 309
   1082 
   1083    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 310
   1084    LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 311
   1085 };
   1086 
   1087 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
   1088 {
   1089    const UInt syscall_table_size
   1090       = sizeof(syscall_table) / sizeof(syscall_table[0]);
   1091 
   1092    /* Is it in the contiguous initial section of the table? */
   1093    if (sysno < syscall_table_size) {
   1094       SyscallTableEntry* sys = &syscall_table[sysno];
   1095       if (sys->before == NULL)
   1096          return NULL; /* no entry */
   1097       else
   1098          return sys;
   1099    }
   1100 
   1101    /* Can't find a wrapper */
   1102    return NULL;
   1103 }
   1104 
   1105 #endif // defined(VGP_amd64_linux)
   1106 
   1107 /*--------------------------------------------------------------------*/
   1108 /*--- end                                                          ---*/
   1109 /*--------------------------------------------------------------------*/
   1110