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-2017 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_threadstate.h"
     37 #include "pub_core_aspacemgr.h"
     38 #include "pub_core_debuglog.h"
     39 #include "pub_core_options.h"
     40 #include "pub_core_libcbase.h"
     41 #include "pub_core_libcassert.h"
     42 #include "pub_core_libcprint.h"
     43 #include "pub_core_libcproc.h"
     44 #include "pub_core_libcsignal.h"
     45 #include "pub_core_scheduler.h"
     46 #include "pub_core_sigframe.h"
     47 #include "pub_core_signals.h"
     48 #include "pub_core_syscall.h"
     49 #include "pub_core_syswrap.h"
     50 #include "pub_core_tooliface.h"
     51 
     52 #include "priv_types_n_macros.h"
     53 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
     54 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
     55 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
     56 #include "priv_syswrap-main.h"
     57 
     58 
     59 /* ---------------------------------------------------------------------
     60    clone() handling
     61    ------------------------------------------------------------------ */
     62 
     63 /* Call f(arg1), but first switch stacks, using 'stack' as the new
     64    stack, and use 'retaddr' as f's return-to address.  Also, clear all
     65    the integer registers before entering f.  */
     66 __attribute__((noreturn))
     67 void ML_(call_on_new_stack_0_1) ( Addr stack,
     68 			          Addr retaddr,
     69 			          void (*f)(Word),
     70                                   Word arg1 );
     71 // %rdi == stack
     72 // %rsi == retaddr
     73 // %rdx == f
     74 // %rcx == arg1
     75 asm(
     76 ".text\n"
     77 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
     78 "vgModuleLocal_call_on_new_stack_0_1:\n"
     79 "   movq   %rdi, %rsp\n"   // set stack
     80 "   pushq  %rsi\n"         // retaddr to stack
     81 "   pushq  %rdx\n"         // f to stack
     82 "   pushq  %rcx\n"         // arg1 to stack
     83 "   movq $0, %rax\n"       // zero all GP regs
     84 "   movq $0, %rbx\n"
     85 "   movq $0, %rcx\n"
     86 "   movq $0, %rdx\n"
     87 "   movq $0, %rsi\n"
     88 "   movq $0, %rdi\n"
     89 "   movq $0, %rbp\n"
     90 "   movq $0, %r8\n"
     91 "   movq $0, %r9\n"
     92 "   movq $0, %r10\n"
     93 "   movq $0, %r11\n"
     94 "   movq $0, %r12\n"
     95 "   movq $0, %r13\n"
     96 "   movq $0, %r14\n"
     97 "   movq $0, %r15\n"
     98 "   popq   %rdi\n"         // arg1 to correct arg reg
     99 "   ret\n"                 // jump to f
    100 "   ud2\n"                 // should never get here
    101 ".previous\n"
    102 );
    103 
    104 /*
    105         Perform a clone system call.  clone is strange because it has
    106         fork()-like return-twice semantics, so it needs special
    107         handling here.
    108 
    109 	Upon entry, we have:
    110 
    111 	    int (*fn)(void*)	in %rdi
    112 	    void*  child_stack	in %rsi
    113 	    int    flags	in %rdx
    114 	    void*  arg		in %rcx
    115 	    pid_t* child_tid	in %r8
    116 	    pid_t* parent_tid	in %r9
    117 	    void*  tls_ptr      at 8(%rsp)
    118 
    119 	System call requires:
    120 
    121 	    int    $__NR_clone  in %rax
    122 	    int    flags	in %rdi
    123 	    void*  child_stack	in %rsi
    124 	    pid_t* parent_tid	in %rdx
    125 	    pid_t* child_tid	in %r10
    126 	    void*  tls_ptr      in %r8
    127 
    128 	Returns a Long encoded in the linux-amd64 way, not a SysRes.
    129  */
    130 #define __NR_CLONE        VG_STRINGIFY(__NR_clone)
    131 #define __NR_EXIT         VG_STRINGIFY(__NR_exit)
    132 
    133 // See priv_syswrap-linux.h for arg profile.
    134 asm(
    135 ".text\n"
    136 ".globl do_syscall_clone_amd64_linux\n"
    137 "do_syscall_clone_amd64_linux:\n"
    138         // set up child stack, temporarily preserving fn and arg
    139 "       subq    $16, %rsi\n"            // make space on stack
    140 "       movq    %rcx, 8(%rsi)\n"        // save arg
    141 "       movq    %rdi, 0(%rsi)\n"        // save fn
    142 
    143         // setup syscall
    144 "       movq    $"__NR_CLONE", %rax\n"  // syscall number
    145 "       movq    %rdx,     %rdi\n"       // syscall arg1: flags
    146         // %rsi already setup           // syscall arg2: child_stack
    147 "       movq    %r9,      %rdx\n"       // syscall arg3: parent_tid
    148 "       movq    %r8,      %r10\n"       // syscall arg4: child_tid
    149 "       movq    8(%rsp),  %r8\n"        // syscall arg5: tls_ptr
    150 
    151 "       syscall\n"                      // clone()
    152 
    153 "       testq   %rax, %rax\n"           // child if retval == 0
    154 "       jnz     1f\n"
    155 
    156         // CHILD - call thread function
    157 "       pop     %rax\n"                 // pop fn
    158 "       pop     %rdi\n"                 // pop fn arg1: arg
    159 "       call    *%rax\n"                // call fn
    160 
    161         // exit with result
    162 "       movq    %rax, %rdi\n"           // arg1: return value from fn
    163 "       movq    $"__NR_EXIT", %rax\n"
    164 
    165 "       syscall\n"
    166 
    167         // Exit returned?!
    168 "       ud2\n"
    169 
    170 "1:\n"  // PARENT or ERROR
    171 "       ret\n"
    172 ".previous\n"
    173 );
    174 
    175 #undef __NR_CLONE
    176 #undef __NR_EXIT
    177 
    178 
    179 /* ---------------------------------------------------------------------
    180    More thread stuff
    181    ------------------------------------------------------------------ */
    182 
    183 void VG_(cleanup_thread) ( ThreadArchState *arch )
    184 {
    185 }
    186 
    187 /* ---------------------------------------------------------------------
    188    PRE/POST wrappers for AMD64/Linux-specific syscalls
    189    ------------------------------------------------------------------ */
    190 
    191 #define PRE(name)       DEFN_PRE_TEMPLATE(amd64_linux, name)
    192 #define POST(name)      DEFN_POST_TEMPLATE(amd64_linux, name)
    193 
    194 /* Add prototypes for the wrappers declared here, so that gcc doesn't
    195    harass us for not having prototypes.  Really this is a kludge --
    196    the right thing to do is to make these wrappers 'static' since they
    197    aren't visible outside this file, but that requires even more macro
    198    magic. */
    199 DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
    200 DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
    201 DECL_TEMPLATE(amd64_linux, sys_ptrace);
    202 DECL_TEMPLATE(amd64_linux, sys_fadvise64);
    203 DECL_TEMPLATE(amd64_linux, sys_mmap);
    204 DECL_TEMPLATE(amd64_linux, sys_syscall184);
    205 
    206 
    207 PRE(sys_rt_sigreturn)
    208 {
    209    /* This isn't really a syscall at all - it's a misuse of the
    210       syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
    211       return address of the signal frames it creates to be a short
    212       piece of code which does this "syscall".  The only purpose of
    213       the syscall is to call VG_(sigframe_destroy), which restores the
    214       thread's registers from the frame and then removes it.
    215       Consequently we must ask the syswrap driver logic not to write
    216       back the syscall "result" as that would overwrite the
    217       just-restored register state. */
    218 
    219    ThreadState* tst;
    220    PRINT("sys_rt_sigreturn ( )");
    221 
    222    vg_assert(VG_(is_valid_tid)(tid));
    223    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    224    vg_assert(VG_(is_running_thread)(tid));
    225 
    226    /* Adjust RSP to point to start of frame; skip back up over handler
    227       ret addr */
    228    tst = VG_(get_ThreadState)(tid);
    229    tst->arch.vex.guest_RSP -= sizeof(Addr);
    230 
    231    /* This is only so that the RIP is (might be) useful to report if
    232       something goes wrong in the sigreturn.  JRS 20070318: no idea
    233       what this is for */
    234    ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    235 
    236    /* Restore register state from frame and remove it, as
    237       described above */
    238    VG_(sigframe_destroy)(tid, True);
    239 
    240    /* Tell the driver not to update the guest state with the "result",
    241       and set a bogus result to keep it happy. */
    242    *flags |= SfNoWriteResult;
    243    SET_STATUS_Success(0);
    244 
    245    /* Check to see if any signals arose as a result of this. */
    246    *flags |= SfPollAfter;
    247 }
    248 
    249 PRE(sys_arch_prctl)
    250 {
    251    ThreadState* tst;
    252    PRINT( "arch_prctl ( %ld, %lx )", SARG1, ARG2 );
    253 
    254    vg_assert(VG_(is_valid_tid)(tid));
    255    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    256    vg_assert(VG_(is_running_thread)(tid));
    257 
    258    // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
    259    PRE_REG_READ2(long, "arch_prctl",
    260                  int, option, unsigned long, arg2);
    261    // XXX: totally wrong... we need to look at the 'option' arg, and do
    262    // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
    263 
    264    /* "do" the syscall ourselves; the kernel never sees it */
    265    if (ARG1 == VKI_ARCH_SET_FS) {
    266       tst = VG_(get_ThreadState)(tid);
    267       tst->arch.vex.guest_FS_CONST = ARG2;
    268    }
    269    else if (ARG1 == VKI_ARCH_GET_FS) {
    270       PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
    271       tst = VG_(get_ThreadState)(tid);
    272       *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_CONST;
    273       POST_MEM_WRITE(ARG2, sizeof(unsigned long));
    274    }
    275    else if (ARG1 == VKI_ARCH_SET_GS) {
    276       tst = VG_(get_ThreadState)(tid);
    277       tst->arch.vex.guest_GS_CONST = ARG2;
    278    }
    279    else if (ARG1 == VKI_ARCH_GET_GS) {
    280       PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
    281       tst = VG_(get_ThreadState)(tid);
    282       *(unsigned long *)ARG2 = tst->arch.vex.guest_GS_CONST;
    283       POST_MEM_WRITE(ARG2, sizeof(unsigned long));
    284    }
    285    else {
    286       VG_(core_panic)("Unsupported arch_prctl option");
    287    }
    288 
    289    /* Note; the Status writeback to guest state that happens after
    290       this wrapper returns does not change guest_FS_CONST or guest_GS_CONST;
    291       hence that direct assignment to the guest state is safe here. */
    292    SET_STATUS_Success( 0 );
    293 }
    294 
    295 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
    296 //
    297 // ARG3 is only used for pointers into the traced process's address
    298 // space and for offsets into the traced process's struct
    299 // user_regs_struct. It is never a pointer into this process's memory
    300 // space, and we should therefore not check anything it points to.
    301 PRE(sys_ptrace)
    302 {
    303    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
    304    PRE_REG_READ4(int, "ptrace",
    305                  long, request, long, pid, long, addr, long, data);
    306    switch (ARG1) {
    307    case VKI_PTRACE_PEEKTEXT:
    308    case VKI_PTRACE_PEEKDATA:
    309    case VKI_PTRACE_PEEKUSR:
    310       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
    311 		     sizeof (long));
    312       break;
    313    case VKI_PTRACE_GETREGS:
    314       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
    315 		     sizeof (struct vki_user_regs_struct));
    316       break;
    317    case VKI_PTRACE_GETFPREGS:
    318       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
    319 		     sizeof (struct vki_user_i387_struct));
    320       break;
    321    case VKI_PTRACE_SETREGS:
    322       PRE_MEM_READ( "ptrace(setregs)", ARG4,
    323 		     sizeof (struct vki_user_regs_struct));
    324       break;
    325    case VKI_PTRACE_SETFPREGS:
    326       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
    327 		     sizeof (struct vki_user_i387_struct));
    328       break;
    329    case VKI_PTRACE_GETEVENTMSG:
    330       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
    331       break;
    332    case VKI_PTRACE_GETSIGINFO:
    333       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
    334       break;
    335    case VKI_PTRACE_SETSIGINFO:
    336       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
    337       break;
    338    case VKI_PTRACE_GETREGSET:
    339       ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
    340       break;
    341    case VKI_PTRACE_SETREGSET:
    342       ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
    343       break;
    344    default:
    345       break;
    346    }
    347 }
    348 
    349 POST(sys_ptrace)
    350 {
    351    switch (ARG1) {
    352    case VKI_PTRACE_TRACEME:
    353          ML_(linux_POST_traceme)(tid);
    354          break;
    355    case VKI_PTRACE_PEEKTEXT:
    356    case VKI_PTRACE_PEEKDATA:
    357    case VKI_PTRACE_PEEKUSR:
    358       POST_MEM_WRITE( ARG4, sizeof (long));
    359       break;
    360    case VKI_PTRACE_GETREGS:
    361       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
    362       break;
    363    case VKI_PTRACE_GETFPREGS:
    364       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
    365       break;
    366    case VKI_PTRACE_GETEVENTMSG:
    367       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
    368       break;
    369    case VKI_PTRACE_GETSIGINFO:
    370       /* XXX: This is a simplification. Different parts of the
    371        * siginfo_t are valid depending on the type of signal.
    372        */
    373       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
    374       break;
    375    case VKI_PTRACE_GETREGSET:
    376       ML_(linux_POST_getregset)(tid, ARG3, ARG4);
    377       break;
    378    default:
    379       break;
    380    }
    381 }
    382 
    383 PRE(sys_fadvise64)
    384 {
    385    PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", SARG1, SARG2, ARG3, SARG4);
    386    PRE_REG_READ4(long, "fadvise64",
    387                  int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
    388 }
    389 
    390 PRE(sys_mmap)
    391 {
    392    SysRes r;
    393 
    394    PRINT("sys_mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )",
    395          ARG1, ARG2, SARG3, SARG4, SARG5, SARG6 );
    396    PRE_REG_READ6(long, "mmap",
    397                  unsigned long, start, unsigned long, length,
    398                  int, prot, int, flags, int, fd, vki_off_t, offset);
    399 
    400    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
    401    SET_STATUS_from_SysRes(r);
    402 }
    403 
    404 
    405 /* ---------------------------------------------------------------
    406    PRE/POST wrappers for AMD64/Linux-variant specific syscalls
    407    ------------------------------------------------------------ */
    408 
    409 PRE(sys_syscall184)
    410 {
    411    Int err;
    412 
    413    /* 184 is used by sys_bproc.  If we're not on a declared bproc
    414       variant, fail in the usual way, since it is otherwise unused. */
    415 
    416    if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
    417       PRINT("non-existent syscall! (syscall 184)");
    418       PRE_REG_READ0(long, "ni_syscall(184)");
    419       SET_STATUS_Failure( VKI_ENOSYS );
    420       return;
    421    }
    422 
    423    err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
    424                                            ARG4, ARG5, ARG6 );
    425    if (err) {
    426       SET_STATUS_Failure( err );
    427       return;
    428    }
    429    /* Let it go through. */
    430    *flags |= SfMayBlock; /* who knows?  play safe. */
    431 }
    432 
    433 POST(sys_syscall184)
    434 {
    435    ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
    436                                       ARG4, ARG5, ARG6 );
    437 }
    438 
    439 #undef PRE
    440 #undef POST
    441 
    442 
    443 /* ---------------------------------------------------------------------
    444    The AMD64/Linux syscall table
    445    ------------------------------------------------------------------ */
    446 
    447 /* Add an amd64-linux specific wrapper to a syscall table. */
    448 #define PLAX_(const, name)    WRAPPER_ENTRY_X_(amd64_linux, const, name)
    449 #define PLAXY(const, name)    WRAPPER_ENTRY_XY(amd64_linux, const, name)
    450 
    451 // This table maps from __NR_xxx syscall numbers (from
    452 // linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
    453 // wrappers on AMD64 (as per sys_call_table in
    454 // linux/arch/x86_64/kernel/entry.S).
    455 //
    456 // When implementing these wrappers, you need to work out if the wrapper is
    457 // generic, Linux-only (but arch-independent), or AMD64/Linux only.
    458 
    459 static SyscallTableEntry syscall_table[] = {
    460    GENXY(__NR_read,              sys_read),           // 0
    461    GENX_(__NR_write,             sys_write),          // 1
    462    GENXY(__NR_open,              sys_open),           // 2
    463    GENXY(__NR_close,             sys_close),          // 3
    464    GENXY(__NR_stat,              sys_newstat),        // 4
    465 
    466    GENXY(__NR_fstat,             sys_newfstat),       // 5
    467    GENXY(__NR_lstat,             sys_newlstat),       // 6
    468    GENXY(__NR_poll,              sys_poll),           // 7
    469    LINX_(__NR_lseek,             sys_lseek),          // 8
    470    PLAX_(__NR_mmap,              sys_mmap),           // 9
    471 
    472    GENXY(__NR_mprotect,          sys_mprotect),       // 10
    473    GENXY(__NR_munmap,            sys_munmap),         // 11
    474    GENX_(__NR_brk,               sys_brk),            // 12
    475    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 13
    476    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 14
    477 
    478    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 15
    479    LINXY(__NR_ioctl,             sys_ioctl),          // 16
    480    GENXY(__NR_pread64,           sys_pread64),        // 17
    481    GENX_(__NR_pwrite64,          sys_pwrite64),       // 18
    482    GENXY(__NR_readv,             sys_readv),          // 19
    483 
    484    GENX_(__NR_writev,            sys_writev),         // 20
    485    GENX_(__NR_access,            sys_access),         // 21
    486    LINXY(__NR_pipe,              sys_pipe),           // 22
    487    GENX_(__NR_select,            sys_select),         // 23
    488    LINX_(__NR_sched_yield,       sys_sched_yield),    // 24
    489 
    490    GENX_(__NR_mremap,            sys_mremap),         // 25
    491    GENX_(__NR_msync,             sys_msync),          // 26
    492    GENXY(__NR_mincore,           sys_mincore),        // 27
    493    GENX_(__NR_madvise,           sys_madvise),        // 28
    494    LINX_(__NR_shmget,            sys_shmget),         // 29
    495 
    496    LINXY(__NR_shmat,             sys_shmat),          // 30
    497    LINXY(__NR_shmctl,            sys_shmctl),         // 31
    498    GENXY(__NR_dup,               sys_dup),            // 32
    499    GENXY(__NR_dup2,              sys_dup2),           // 33
    500    GENX_(__NR_pause,             sys_pause),          // 34
    501 
    502    GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
    503    GENXY(__NR_getitimer,         sys_getitimer),      // 36
    504    GENX_(__NR_alarm,             sys_alarm),          // 37
    505    GENXY(__NR_setitimer,         sys_setitimer),      // 38
    506    GENX_(__NR_getpid,            sys_getpid),         // 39
    507 
    508    LINXY(__NR_sendfile,          sys_sendfile),       // 40
    509    LINXY(__NR_socket,            sys_socket),         // 41
    510    LINX_(__NR_connect,           sys_connect),        // 42
    511    LINXY(__NR_accept,            sys_accept),         // 43
    512    LINX_(__NR_sendto,            sys_sendto),         // 44
    513 
    514    LINXY(__NR_recvfrom,          sys_recvfrom),       // 45
    515    LINX_(__NR_sendmsg,           sys_sendmsg),        // 46
    516    LINXY(__NR_recvmsg,           sys_recvmsg),        // 47
    517    LINX_(__NR_shutdown,          sys_shutdown),       // 48
    518    LINX_(__NR_bind,              sys_bind),           // 49
    519 
    520    LINX_(__NR_listen,            sys_listen),         // 50
    521    LINXY(__NR_getsockname,       sys_getsockname),    // 51
    522    LINXY(__NR_getpeername,       sys_getpeername),    // 52
    523    LINXY(__NR_socketpair,        sys_socketpair),     // 53
    524    LINX_(__NR_setsockopt,        sys_setsockopt),     // 54
    525 
    526    LINXY(__NR_getsockopt,        sys_getsockopt),     // 55
    527    LINX_(__NR_clone,             sys_clone),          // 56
    528    GENX_(__NR_fork,              sys_fork),           // 57
    529    GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
    530    GENX_(__NR_execve,            sys_execve),         // 59
    531 
    532    GENX_(__NR_exit,              sys_exit),           // 60
    533    GENXY(__NR_wait4,             sys_wait4),          // 61
    534    GENX_(__NR_kill,              sys_kill),           // 62
    535    GENXY(__NR_uname,             sys_newuname),       // 63
    536    LINX_(__NR_semget,            sys_semget),         // 64
    537 
    538    LINX_(__NR_semop,             sys_semop),          // 65
    539    LINXY(__NR_semctl,            sys_semctl),         // 66
    540    LINXY(__NR_shmdt,             sys_shmdt),          // 67
    541    LINX_(__NR_msgget,            sys_msgget),         // 68
    542    LINX_(__NR_msgsnd,            sys_msgsnd),         // 69
    543 
    544    LINXY(__NR_msgrcv,            sys_msgrcv),         // 70
    545    LINXY(__NR_msgctl,            sys_msgctl),         // 71
    546    LINXY(__NR_fcntl,             sys_fcntl),          // 72
    547    GENX_(__NR_flock,             sys_flock),          // 73
    548    GENX_(__NR_fsync,             sys_fsync),          // 74
    549 
    550    GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
    551    GENX_(__NR_truncate,          sys_truncate),       // 76
    552    GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
    553    GENXY(__NR_getdents,          sys_getdents),       // 78
    554    GENXY(__NR_getcwd,            sys_getcwd),         // 79
    555 
    556    GENX_(__NR_chdir,             sys_chdir),          // 80
    557    GENX_(__NR_fchdir,            sys_fchdir),         // 81
    558    GENX_(__NR_rename,            sys_rename),         // 82
    559    GENX_(__NR_mkdir,             sys_mkdir),          // 83
    560    GENX_(__NR_rmdir,             sys_rmdir),          // 84
    561 
    562    GENXY(__NR_creat,             sys_creat),          // 85
    563    GENX_(__NR_link,              sys_link),           // 86
    564    GENX_(__NR_unlink,            sys_unlink),         // 87
    565    GENX_(__NR_symlink,           sys_symlink),        // 88
    566    GENX_(__NR_readlink,          sys_readlink),       // 89
    567 
    568    GENX_(__NR_chmod,             sys_chmod),          // 90
    569    GENX_(__NR_fchmod,            sys_fchmod),         // 91
    570    GENX_(__NR_chown,             sys_chown),          // 92
    571    GENX_(__NR_fchown,            sys_fchown),         // 93
    572    GENX_(__NR_lchown,            sys_lchown),         // 94
    573 
    574    GENX_(__NR_umask,             sys_umask),          // 95
    575    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
    576    GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
    577    GENXY(__NR_getrusage,         sys_getrusage),      // 98
    578    LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
    579 
    580    GENXY(__NR_times,             sys_times),          // 100
    581    PLAXY(__NR_ptrace,            sys_ptrace),         // 101
    582    GENX_(__NR_getuid,            sys_getuid),         // 102
    583    LINXY(__NR_syslog,            sys_syslog),         // 103
    584    GENX_(__NR_getgid,            sys_getgid),         // 104
    585 
    586    GENX_(__NR_setuid,            sys_setuid),         // 105
    587    GENX_(__NR_setgid,            sys_setgid),         // 106
    588    GENX_(__NR_geteuid,           sys_geteuid),        // 107
    589    GENX_(__NR_getegid,           sys_getegid),        // 108
    590    GENX_(__NR_setpgid,           sys_setpgid),        // 109
    591 
    592    GENX_(__NR_getppid,           sys_getppid),        // 110
    593    GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
    594    GENX_(__NR_setsid,            sys_setsid),         // 112
    595    GENX_(__NR_setreuid,          sys_setreuid),       // 113
    596    GENX_(__NR_setregid,          sys_setregid),       // 114
    597 
    598    GENXY(__NR_getgroups,         sys_getgroups),      // 115
    599    GENX_(__NR_setgroups,         sys_setgroups),      // 116
    600    LINX_(__NR_setresuid,         sys_setresuid),      // 117
    601    LINXY(__NR_getresuid,         sys_getresuid),      // 118
    602    LINX_(__NR_setresgid,         sys_setresgid),      // 119
    603 
    604    LINXY(__NR_getresgid,         sys_getresgid),      // 120
    605    GENX_(__NR_getpgid,           sys_getpgid),        // 121
    606    LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
    607    LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
    608    GENX_(__NR_getsid,            sys_getsid),         // 124
    609 
    610    LINXY(__NR_capget,            sys_capget),         // 125
    611    LINX_(__NR_capset,            sys_capset),         // 126
    612    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
    613    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
    614    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
    615 
    616    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
    617    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
    618    LINX_(__NR_utime,             sys_utime),          // 132
    619    GENX_(__NR_mknod,             sys_mknod),          // 133
    620    //   (__NR_uselib,            sys_uselib),         // 134
    621 
    622    LINX_(__NR_personality,       sys_personality),    // 135
    623    //   (__NR_ustat,             sys_ustat),          // 136
    624    GENXY(__NR_statfs,            sys_statfs),         // 137
    625    GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
    626    //   (__NR_sysfs,             sys_sysfs),          // 139
    627 
    628    GENX_(__NR_getpriority,             sys_getpriority),             // 140
    629    GENX_(__NR_setpriority,             sys_setpriority),             // 141
    630    LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
    631    LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
    632    LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
    633 
    634    LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
    635    LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
    636    LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
    637    LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
    638    GENX_(__NR_mlock,                   sys_mlock),                   // 149
    639 
    640    GENX_(__NR_munlock,           sys_munlock),        // 150
    641    GENX_(__NR_mlockall,          sys_mlockall),       // 151
    642    LINX_(__NR_munlockall,        sys_munlockall),     // 152
    643    LINX_(__NR_vhangup,           sys_vhangup),        // 153
    644    //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
    645 
    646    LINX_(__NR_pivot_root,        sys_pivot_root),     // 155
    647    LINXY(__NR__sysctl,           sys_sysctl),         // 156
    648    LINXY(__NR_prctl,             sys_prctl),          // 157
    649    PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
    650    LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
    651 
    652    GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
    653    GENX_(__NR_chroot,            sys_chroot),         // 161
    654    GENX_(__NR_sync,              sys_sync),           // 162
    655    //   (__NR_acct,              sys_acct),           // 163
    656    GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
    657 
    658    LINX_(__NR_mount,             sys_mount),          // 165
    659    LINX_(__NR_umount2,           sys_umount),         // 166
    660    //   (__NR_swapon,            sys_swapon),         // 167
    661    //   (__NR_swapoff,           sys_swapoff),        // 168
    662    //   (__NR_reboot,            sys_reboot),         // 169
    663 
    664    GENX_(__NR_sethostname,       sys_sethostname),    // 170
    665    //   (__NR_setdomainname,     sys_setdomainname),  // 171
    666    GENX_(__NR_iopl,              sys_iopl),           // 172
    667    LINX_(__NR_ioperm,            sys_ioperm),         // 173
    668    GENX_(__NR_create_module,     sys_ni_syscall),     // 174
    669 
    670    LINX_(__NR_init_module,       sys_init_module),    // 175
    671    LINX_(__NR_delete_module,     sys_delete_module),  // 176
    672    //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
    673    //   (__NR_query_module,      sys_ni_syscall),     // 178
    674    LINX_(__NR_quotactl,          sys_quotactl),       // 179
    675 
    676    //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
    677    //   (__NR_getpmsg,           sys_ni_syscall),     // 181
    678    //   (__NR_putpmsg,           sys_ni_syscall),     // 182
    679    //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
    680    PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
    681 
    682    //   (__NR_security,          sys_ni_syscall),     // 185
    683    LINX_(__NR_gettid,            sys_gettid),         // 186
    684    LINX_(__NR_readahead,         sys_readahead),      // 187
    685    LINX_(__NR_setxattr,          sys_setxattr),       // 188
    686    LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
    687 
    688    LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
    689    LINXY(__NR_getxattr,          sys_getxattr),       // 191
    690    LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
    691    LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
    692    LINXY(__NR_listxattr,         sys_listxattr),      // 194
    693 
    694    LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
    695    LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
    696    LINX_(__NR_removexattr,       sys_removexattr),    // 197
    697    LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
    698    LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
    699 
    700    LINXY(__NR_tkill,             sys_tkill),             // 200
    701    GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
    702    LINXY(__NR_futex,             sys_futex),             // 202
    703    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
    704    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
    705 
    706    //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
    707    LINXY(__NR_io_setup,          sys_io_setup),       // 206
    708    LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
    709    LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
    710    LINX_(__NR_io_submit,         sys_io_submit),      // 209
    711 
    712    LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
    713    //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
    714    LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
    715    LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
    716    //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
    717 
    718    //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
    719    //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
    720    GENXY(__NR_getdents64,        sys_getdents64),     // 217
    721    LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
    722    //   (__NR_restart_syscall,   sys_restart_syscall),// 219
    723 
    724    LINX_(__NR_semtimedop,        sys_semtimedop),     // 220
    725    PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
    726    LINXY(__NR_timer_create,      sys_timer_create),   // 222
    727    LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
    728    LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
    729 
    730    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
    731    LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
    732    LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
    733    LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
    734    LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
    735 
    736    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
    737    LINX_(__NR_exit_group,        sys_exit_group),     // 231
    738    LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
    739    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
    740    LINXY(__NR_tgkill,            sys_tgkill),         // 234
    741 
    742    GENX_(__NR_utimes,            sys_utimes),         // 235
    743    //   (__NR_vserver,           sys_ni_syscall),     // 236
    744    LINX_(__NR_mbind,             sys_mbind),          // 237
    745    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
    746    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
    747 
    748    LINXY(__NR_mq_open,           sys_mq_open),        // 240
    749    LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
    750    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
    751    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
    752    LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
    753 
    754    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
    755    //   (__NR_kexec_load,        sys_ni_syscall),     // 246
    756    LINXY(__NR_waitid,            sys_waitid),         // 247
    757    LINX_(__NR_add_key,           sys_add_key),        // 248
    758    LINX_(__NR_request_key,       sys_request_key),    // 249
    759 
    760    LINXY(__NR_keyctl,            sys_keyctl),         // 250
    761    LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
    762    LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
    763    LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
    764    LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
    765 
    766    LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
    767 //   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
    768    LINXY(__NR_openat,		 sys_openat),           // 257
    769    LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
    770    LINX_(__NR_mknodat,		 sys_mknodat),          // 259
    771 
    772    LINX_(__NR_fchownat,		 sys_fchownat),         // 260
    773    LINX_(__NR_futimesat,	 sys_futimesat),        // 261
    774    LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
    775    LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
    776    LINX_(__NR_renameat,		 sys_renameat),         // 264
    777 
    778    LINX_(__NR_linkat,		 sys_linkat),           // 265
    779    LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
    780    LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
    781    LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
    782    LINX_(__NR_faccessat,	 sys_faccessat),        // 269
    783 
    784    LINXY(__NR_pselect6,		 sys_pselect6),         // 270
    785    LINXY(__NR_ppoll,		 sys_ppoll),            // 271
    786    LINX_(__NR_unshare,		 sys_unshare),          // 272
    787    LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
    788    LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
    789 
    790    LINX_(__NR_splice,            sys_splice),           // 275
    791    LINX_(__NR_tee,               sys_tee),              // 276
    792    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
    793    LINXY(__NR_vmsplice,          sys_vmsplice),         // 278
    794    LINXY(__NR_move_pages,        sys_move_pages),       // 279
    795 
    796    LINX_(__NR_utimensat,         sys_utimensat),        // 280
    797    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
    798    LINXY(__NR_signalfd,          sys_signalfd),         // 282
    799    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
    800    LINXY(__NR_eventfd,           sys_eventfd),          // 284
    801 
    802    LINX_(__NR_fallocate,         sys_fallocate),        // 285
    803    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
    804    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
    805    LINXY(__NR_accept4,           sys_accept4),          // 288
    806    LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
    807 
    808    LINXY(__NR_eventfd2,          sys_eventfd2),         // 290
    809    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
    810    LINXY(__NR_dup3,              sys_dup3),             // 292
    811    LINXY(__NR_pipe2,             sys_pipe2),            // 293
    812    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
    813 
    814    LINXY(__NR_preadv,            sys_preadv),           // 295
    815    LINX_(__NR_pwritev,           sys_pwritev),          // 296
    816    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
    817    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
    818    LINXY(__NR_recvmmsg,          sys_recvmmsg),         // 299
    819 
    820    LINXY(__NR_fanotify_init,     sys_fanotify_init),    // 300
    821    LINX_(__NR_fanotify_mark,     sys_fanotify_mark),    // 301
    822    LINXY(__NR_prlimit64,         sys_prlimit64),        // 302
    823    LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 303
    824    LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 304
    825 
    826    LINXY(__NR_clock_adjtime,     sys_clock_adjtime),    // 305
    827    LINX_(__NR_syncfs,            sys_syncfs),           // 306
    828    LINXY(__NR_sendmmsg,          sys_sendmmsg),         // 307
    829 //   LINX_(__NR_setns,             sys_ni_syscall),       // 308
    830    LINXY(__NR_getcpu,            sys_getcpu),           // 309
    831 
    832    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 310
    833    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 311
    834    LINX_(__NR_kcmp,              sys_kcmp),             // 312
    835    LINX_(__NR_finit_module,      sys_finit_module),     // 313
    836 //   LIN__(__NR_sched_setattr,     sys_ni_syscall),       // 314
    837 
    838 //   LIN__(__NR_sched_getattr,     sys_ni_syscall),       // 315
    839    LINX_(__NR_renameat2,         sys_renameat2),        // 316
    840 //   LIN__(__NR_seccomp,           sys_ni_syscall),       // 317
    841    LINXY(__NR_getrandom,         sys_getrandom),        // 318
    842    LINXY(__NR_memfd_create,      sys_memfd_create)      // 319
    843 
    844 //   LIN__(__NR_kexec_file_load,   sys_ni_syscall),       // 320
    845 //   LIN__(__NR_bpf,               sys_ni_syscall)        // 321
    846 };
    847 
    848 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
    849 {
    850    const UInt syscall_table_size
    851       = sizeof(syscall_table) / sizeof(syscall_table[0]);
    852 
    853    /* Is it in the contiguous initial section of the table? */
    854    if (sysno < syscall_table_size) {
    855       SyscallTableEntry* sys = &syscall_table[sysno];
    856       if (sys->before == NULL)
    857          return NULL; /* no entry */
    858       else
    859          return sys;
    860    }
    861 
    862    /* Can't find a wrapper */
    863    return NULL;
    864 }
    865 
    866 #endif // defined(VGP_amd64_linux)
    867 
    868 /*--------------------------------------------------------------------*/
    869 /*--- end                                                          ---*/
    870 /*--------------------------------------------------------------------*/
    871