Home | History | Annotate | Download | only in m_syswrap
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Platform-specific syscalls stuff.    syswrap-mips64-linux.c ----*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2010-2015 RT-RK
     11       mips-valgrind (at) rt-rk.com
     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_mips64_linux)
     32 #include "pub_core_basics.h"
     33 #include "pub_core_vki.h"
     34 #include "pub_core_vkiscnums.h"
     35 #include "pub_core_threadstate.h"
     36 #include "pub_core_aspacemgr.h"
     37 #include "pub_core_debuglog.h"
     38 #include "pub_core_libcbase.h"
     39 #include "pub_core_libcassert.h"
     40 #include "pub_core_libcprint.h"
     41 #include "pub_core_libcproc.h"
     42 #include "pub_core_libcsignal.h"
     43 #include "pub_core_options.h"
     44 #include "pub_core_scheduler.h"
     45 #include "pub_core_sigframe.h"     /* For VG_(sigframe_destroy)() */
     46 #include "pub_core_signals.h"
     47 #include "pub_core_syscall.h"
     48 #include "pub_core_syswrap.h"
     49 #include "pub_core_tooliface.h"
     50 #include "pub_core_transtab.h"     /* VG_(discard_translations) */
     51 #include "priv_types_n_macros.h"
     52 #include "priv_syswrap-generic.h"  /* for decls of generic wrappers */
     53 #include "priv_syswrap-linux.h"    /* for decls of linux-ish wrappers */
     54 #include "priv_syswrap-main.h"
     55 
     56 #include "pub_core_debuginfo.h"    /* VG_(di_notify_*) */
     57 #include "pub_core_xarray.h"
     58 #include "pub_core_clientstate.h"  /* VG_(brk_base), VG_(brk_limit) */
     59 #include "pub_core_errormgr.h"
     60 #include "pub_core_gdbserver.h"    /* VG_(gdbserver) */
     61 #include "pub_core_libcfile.h"
     62 #include "pub_core_machine.h"      /* VG_(get_SP) */
     63 #include "pub_core_mallocfree.h"
     64 #include "pub_core_stacktrace.h"   /* For VG_(get_and_pp_StackTrace)() */
     65 #include "pub_core_ume.h"
     66 
     67 #include "config.h"
     68 
     69 #include <errno.h>
     70 
     71 /* ---------------------------------------------------------------------
     72                              clone() handling
     73    ------------------------------------------------------------------ */
     74 
     75 /* Call f(arg1), but first switch stacks, using 'stack' as the new stack, and
     76    use 'retaddr' as f's return-to address. Also, clear all the integer registers
     77    before entering f. */
     78 __attribute__ ((noreturn))
     79 void ML_(call_on_new_stack_0_1) ( Addr stack,             /* $4 - $a0 */
     80                                   Addr retaddr,           /* $5 - $a1 */
     81                                   void (*f_desc) (Word),  /* $6 - $a2 */
     82                                   Word arg1 );            /* $7 - $a3 */
     83 asm (
     84 ".text\n"
     85 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
     86 "vgModuleLocal_call_on_new_stack_0_1:\n"
     87 "   move $29, $4\n"  /* set stack */
     88 "   move $4,  $7\n"  /* arg1 to $4 */
     89 "   move $25, $6\n"
     90 "   move $31, $5\n"  /* retaddr to $ra */
     91 "   jr $25\n"        /* jump to f */
     92 "   break 0x7\n"     /* should never get here */
     93 ".previous\n"
     94 );
     95 
     96 /* Perform a clone system call.  clone is strange because it has fork()-like
     97    return-twice semantics, so it needs special handling here.
     98 
     99    Upon entry, we have:
    100 
    101       word (fn)(void*)    in a0 = 4
    102       void* child_stack   in a1 = 5
    103       word flags          in a2 = 6
    104       void* arg           in a3 = 7
    105       pid_t* parent_tid   in a4 = 8
    106       void* tls           in a5 = 9
    107       pid_t* child_tid    in a6 = 10
    108 
    109    System call requires:
    110 
    111       int    $__NR_clone  in v0
    112       int    flags        in a0 = 4
    113       void*  child_stack  in a1 = 5
    114       pid_t* parent_tid   in a2 = 6
    115       void*  tls_ptr      in a3 = 7
    116       pid_t* child_tid    in a4 = 8 */
    117 
    118 #define __NR_CLONE        __NR_clone
    119 #define __NR_EXIT         __NR_exit
    120 
    121 ULong do_syscall_clone_mips64_linux ( Word (*fn) (void *),  /* a0 - 4 */
    122                                       void* stack,          /* a1 - 5 */
    123                                       Int   flags,          /* a2 - 6 */
    124                                       void* arg,            /* a3 - 7 */
    125                                       Int*  parent_tid,     /* a4 - 8 */
    126                                       void* /* Int tls */,  /* a5 - 9 */
    127                                       Int*  child_tid );    /* a6 - 10 */
    128 
    129 asm(
    130 ".text\n"
    131 ".set noreorder\n"
    132 ".set nomacro\n"
    133 ".globl do_syscall_clone_mips64_linux\n"
    134 "do_syscall_clone_mips64_linux:\n"
    135 "   daddiu $29, $29, -32\n"
    136 "   sd $31, 0($29)\n"
    137 "   sd $30, 8($29)\n"
    138 "   sd $28, 16($29)\n"
    139 
    140 "   daddiu  $5, $5, -32\n"
    141 "   sd $4, 0($5)\n"   /* fn */
    142 "   sd $7, 8($5)\n"   /* arg */
    143 "   sd $6, 16($5)\n"  /* flags */
    144 
    145 /* 1. arg for syscalls */
    146 "   move $4, $6\n"   /* flags */
    147 "   move $6, $8\n"   /* parent */
    148 "   move $7, $a5\n"  /* tls */
    149 "   move $8, $a6\n"  /* child */
    150 
    151 /* 2. do a syscall to clone */
    152 "   li  $2, 5055\n"  /* syscall num for clone */
    153 "   syscall\n"
    154 
    155 /* 3. See if we are a child, call fn and after that exit */
    156 "   bnez $7, p_or_error\n"
    157 "   nop\n"
    158 
    159 "   bnez $2, p_or_error\n"
    160 "   nop\n"
    161 
    162 "   ld $25,0($29)\n"
    163 "   jalr $25\n"
    164 "   ld $4,8($29)\n"
    165 
    166 "   move $4, $2\n\t"  /* retval from fn is in $v0 */
    167 "   li $2, 5058\n\t"  /* NR_exit */
    168 "   syscall\n\t"
    169 "   nop\n\t"
    170 /* 4. If we are parent or error, just return to caller */
    171 "   p_or_error:\n"
    172 "   ld $31, 0($29)\n"
    173 "   ld $30, 8($29)\n"
    174 "   ld $28, 16($29)\n"
    175 "   jr $31\n"
    176 "   daddi $29,$29, 32\n"
    177 ".previous\n"
    178 );
    179 
    180 #undef __NR_CLONE
    181 #undef __NR_EXIT
    182 
    183 /* forward declarations */
    184 static void setup_child ( ThreadArchState *, ThreadArchState *);
    185 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr);
    186 
    187 /* When a client clones, we need to keep track of the new thread. This means:
    188    1. allocate a ThreadId+ThreadState+stack for the thread
    189 
    190    2. initialize the thread's new VCPU state
    191 
    192    3. create the thread using the same args as the client requested, but using
    193       the scheduler entrypoint for IP, and a separate stack for SP. */
    194 static SysRes do_clone ( ThreadId ptid,
    195                          UInt flags, Addr sp,
    196                          Int* parent_tidptr,
    197                          Int* child_tidptr,
    198                          Addr child_tls )
    199 {
    200    const Bool debug = False;
    201    ThreadId ctid = VG_ (alloc_ThreadState) ();
    202    ThreadState * ptst = VG_ (get_ThreadState) (ptid);
    203    ThreadState * ctst = VG_ (get_ThreadState) (ctid);
    204    UInt ret = 0;
    205    UWord * stack;
    206    SysRes res;
    207    vki_sigset_t blockall, savedmask;
    208 
    209    VG_(sigfillset)(&blockall);
    210    vg_assert(VG_(is_running_thread)(ptid));
    211    vg_assert(VG_(is_valid_tid)(ctid));
    212    stack = (UWord *)ML_(allocstack)(ctid);
    213    if (stack == NULL) {
    214       res = VG_(mk_SysRes_Error)(VKI_ENOMEM);
    215       goto out;
    216    }
    217    setup_child(&ctst->arch, &ptst->arch);
    218 
    219    /* on MIPS we need to set V0 and A3 to zero */
    220    ctst->arch.vex.guest_r2 = 0;
    221    ctst->arch.vex.guest_r7 = 0;
    222    if (sp != 0)
    223       ctst->arch.vex.guest_r29 = sp;
    224 
    225    ctst->os_state.parent = ptid;
    226    ctst->sig_mask = ptst->sig_mask;
    227    ctst->tmp_sig_mask = ptst->sig_mask;
    228 
    229    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
    230 
    231    ML_(guess_and_register_stack) (sp, ctst);
    232 
    233    VG_TRACK(pre_thread_ll_create, ptid, ctid);
    234    if (flags & VKI_CLONE_SETTLS) {
    235        if (debug)
    236          VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
    237        res = sys_set_tls(ctid, child_tls);
    238        if (sr_isError(res))
    239           goto out;
    240        ctst->arch.vex.guest_r27 = child_tls;
    241    }
    242 
    243    flags &= ~VKI_CLONE_SETTLS;
    244    VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
    245    /* Create the new thread */
    246    ret = do_syscall_clone_mips64_linux(ML_(start_thread_NORETURN),
    247                                        stack, flags, &VG_(threads)[ctid],
    248                                        parent_tidptr, NULL /*child_tls*/,
    249                                        child_tidptr);
    250    if (debug)
    251      VG_(printf)("ret: 0x%x\n", ret);
    252 
    253    res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
    254 
    255    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
    256 
    257    out:
    258    if (sr_isError (res)) {
    259       VG_ (cleanup_thread) (&ctst->arch);
    260       ctst->status = VgTs_Empty;
    261       VG_TRACK (pre_thread_ll_exit, ctid);
    262    }
    263    ptst->arch.vex.guest_r2 = 0;
    264 
    265    return res;
    266 }
    267 
    268 /* ---------------------------------------------------------------------
    269                           More thread stuff
    270    ------------------------------------------------------------------ */
    271 void VG_(cleanup_thread) ( ThreadArchState * arch ) { };
    272 
    273 void setup_child ( /* OUT */ ThreadArchState * child,
    274                    /* IN  */ ThreadArchState * parent )
    275 {
    276    /* We inherit our parent's guest state. */
    277    child->vex = parent->vex;
    278    child->vex_shadow1 = parent->vex_shadow1;
    279    child->vex_shadow2 = parent->vex_shadow2;
    280 }
    281 
    282 SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
    283 {
    284    VG_(threads)[tid].arch.vex.guest_ULR = tlsptr;
    285    return VG_(mk_SysRes_Success)( 0 );
    286 }
    287 
    288 /* ---------------------------------------------------------------------
    289            PRE/POST wrappers for mips/Linux-specific syscalls
    290    ------------------------------------------------------------------ */
    291 
    292 #define PRE(name)       DEFN_PRE_TEMPLATE(mips_linux, name)
    293 #define POST(name)      DEFN_POST_TEMPLATE(mips_linux, name)
    294 
    295 /* Add prototypes for the wrappers declared here, so that gcc doesn't harass us
    296    for not having prototypes. Really this is a kludge -- the right thing to do
    297    is to make these wrappers 'static' since they aren't visible outside this
    298    file, but that requires even more macro magic. */
    299 
    300 DECL_TEMPLATE (mips_linux, sys_set_thread_area);
    301 DECL_TEMPLATE (mips_linux, sys_clone);
    302 DECL_TEMPLATE (mips_linux, sys_tee);
    303 DECL_TEMPLATE (mips_linux, sys_splice);
    304 DECL_TEMPLATE (mips_linux, sys_vmsplice);
    305 DECL_TEMPLATE (mips_linux, sys_ustat);
    306 DECL_TEMPLATE (mips_linux, sys_sysfs);
    307 DECL_TEMPLATE (mips_linux, sys_swapon);
    308 DECL_TEMPLATE (mips_linux, sys_swapoff);
    309 DECL_TEMPLATE (mips_linux, sys_setdomainname);
    310 DECL_TEMPLATE (mips_linux, sys_sethostname);
    311 DECL_TEMPLATE (mips_linux, sys_reboot);
    312 DECL_TEMPLATE (mips_linux, sys_cacheflush);
    313 DECL_TEMPLATE (mips_linux, sys_sched_rr_get_interval);
    314 DECL_TEMPLATE (mips_linux, sys_unshare);
    315 DECL_TEMPLATE (mips_linux, sys_arch_prctl);
    316 DECL_TEMPLATE (mips_linux, sys_ptrace);
    317 DECL_TEMPLATE (mips_linux, sys_mmap);
    318 DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
    319 DECL_TEMPLATE (mips_linux, sys_pipe);
    320 
    321 PRE(sys_tee)
    322 {
    323    PRINT("sys_tee ( %ld, %ld, %lu, %#lx )", SARG1, SARG2, ARG3, ARG4);
    324    PRE_REG_READ4(long, "sys_tee", int, fdin, int, fdout, vki_size_t, len,
    325                  int, flags);
    326 }
    327 
    328 PRE(sys_splice)
    329 {
    330    PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %lu, %#lx )",
    331          SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
    332 
    333    PRE_REG_READ6(long, "sys_splice", int, fdin, vki_loff_t, sizein, int,
    334                  fdout, vki_loff_t, sizeout, vki_size_t, len, int, flags);
    335 }
    336 
    337 PRE(sys_vmsplice)
    338 {
    339    PRINT("sys_vmsplice ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
    340    PRE_REG_READ4(long, "sys_vmsplice", int, fdin, struct vki_iovec *, v,
    341                  vki_size_t, len, int, flags);
    342 }
    343 
    344 PRE(sys_unshare)
    345 {
    346    PRINT("sys_unshare ( %lu )", ARG1);
    347    PRE_REG_READ1(long, "sys_unshare", unsigned long, flags);
    348 }
    349 
    350 PRE(sys_sched_rr_get_interval)
    351 {
    352    PRINT("sys_sched_rr_get_interval ( %ld, %#lx)", SARG1, ARG2);
    353    PRE_REG_READ2(long, "sched_rr_get_interval", vki_pid_t, pid,
    354                  struct timespec *, timer);
    355    *flags |= SfMayBlock;
    356 }
    357 
    358 PRE(sys_ustat)
    359 {
    360    PRINT("sys_ustat ( %#lx, %#lx)", ARG1, ARG2);
    361    PRE_REG_READ2(long, "ustat", int, flags, const void *, path);
    362 }
    363 
    364 PRE(sys_swapon)
    365 {
    366    PRINT("sys_swapon ( %#lx, %#lx )", ARG1, ARG2);
    367    PRE_REG_READ2(long, "swapon", const void *, path, int, flags);
    368 }
    369 
    370 PRE(sys_swapoff)
    371 {
    372    PRINT("sys_swapoff ( %#lx )", ARG1);
    373    PRE_REG_READ1(long, "swapoff", const void *, path);
    374 }
    375 
    376 PRE(sys_sysfs)
    377 {
    378    PRINT("sys_sysfs ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
    379    PRE_REG_READ3(long, "sysfs", int, flags, int, desc, const void *, path);
    380 }
    381 
    382 /* Very much MIPS specific */
    383 PRE(sys_cacheflush)
    384 {
    385    PRINT("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3);
    386    PRE_REG_READ3(long, "cacheflush", unsigned long, addr,
    387                  unsigned long, nbytes, unsigned int, cache);
    388    VG_ (discard_translations) ((Addr)ARG1, (ULong) ARG2,
    389                                "PRE(sys_cacheflush)");
    390    SET_STATUS_Success(0);
    391 }
    392 
    393 PRE(sys_reboot)
    394 {
    395    PRINT("sys_reboot ( %ld, %ld, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
    396    // An approximation. ARG4 is only read conditionally by the kernel
    397    PRE_REG_READ4(int, "reboot",
    398                  int, magic1, int, magic2, unsigned int, cmd,
    399                  void *, arg);
    400 
    401    *flags |= SfMayBlock;
    402 }
    403 
    404 PRE(sys_setdomainname)
    405 {
    406    PRINT ("sys_setdomainname ( %#lx, %ld )", ARG1, SARG2);
    407    PRE_REG_READ2 (long, "setdomainname", const void *, name, int, len);
    408 }
    409 
    410 PRE(sys_sethostname)
    411 {
    412    PRINT ("sys_sethostname ( %#lx, %ld )", ARG1, SARG2);
    413    PRE_REG_READ2 (long, "sethostname", const void *, name, int, len);
    414 }
    415 
    416 PRE(sys_ptrace)
    417 {
    418    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
    419    PRE_REG_READ4(int, "ptrace",
    420                  long, request, long, pid, unsigned long, addr,
    421                  unsigned long, data);
    422    switch (ARG1) {
    423       case VKI_PTRACE_PEEKTEXT:
    424       case VKI_PTRACE_PEEKDATA:
    425       case VKI_PTRACE_PEEKUSR:
    426          PRE_MEM_WRITE("ptrace(peek)", ARG4, sizeof(long));
    427          break;
    428       case VKI_PTRACE_GETEVENTMSG:
    429          PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
    430          break;
    431       case VKI_PTRACE_GETSIGINFO:
    432          PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
    433          break;
    434       case VKI_PTRACE_SETSIGINFO:
    435          PRE_MEM_READ("ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
    436          break;
    437       case VKI_PTRACE_GETREGSET:
    438          ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
    439          break;
    440       default:
    441         break;
    442    }
    443 }
    444 
    445 POST(sys_ptrace)
    446 {
    447    switch (ARG1) {
    448       case VKI_PTRACE_PEEKTEXT:
    449       case VKI_PTRACE_PEEKDATA:
    450       case VKI_PTRACE_PEEKUSR:
    451          POST_MEM_WRITE (ARG4, sizeof(long));
    452          break;
    453       case VKI_PTRACE_GETEVENTMSG:
    454          POST_MEM_WRITE (ARG4, sizeof(unsigned long));
    455       break;
    456       case VKI_PTRACE_GETSIGINFO:
    457          POST_MEM_WRITE (ARG4, sizeof(vki_siginfo_t));
    458          break;
    459       case VKI_PTRACE_GETREGSET:
    460          ML_(linux_POST_getregset)(tid, ARG3, ARG4);
    461          break;
    462       default:
    463       break;
    464    }
    465 }
    466 
    467 PRE (sys_mmap)
    468 {
    469    SysRes r;
    470    PRINT("sys_mmap ( %#lx, %lu, %ld, %ld, %ld, %lu )",
    471          ARG1, ARG2, SARG3, SARG4, SARG5, ARG6);
    472    PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length,
    473                  int, prot, int, flags, int, fd, unsigned long, offset);
    474    r = ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    475                                  (Off64T) ARG6);
    476    SET_STATUS_from_SysRes(r);
    477 }
    478 
    479 PRE(sys_clone)
    480 {
    481    Bool badarg = False;
    482    UInt cloneflags;
    483    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
    484                                                       ARG4, ARG5);
    485    PRE_REG_READ2(int, "clone", unsigned long, flags, void *, child_stack);
    486    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    487       if (VG_(tdict).track_pre_reg_read) {
    488          PRA3("clone", int *, parent_tidptr);
    489       }
    490       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    491       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
    492          badarg = True;
    493       }
    494    }
    495    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    496       if (VG_(tdict).track_pre_reg_read) {
    497          PRA5("clone", int *, child_tidptr);
    498       }
    499       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof (Int));
    500       if (!VG_(am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
    501          badarg = True;
    502    }
    503    if (badarg) {
    504       SET_STATUS_Failure(VKI_EFAULT);
    505       return;
    506    }
    507    cloneflags = ARG1;
    508    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
    509       SET_STATUS_Failure(VKI_EINVAL);
    510       return;
    511    }
    512    /* Only look at the flags we really care about */
    513    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    514            |VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    515       case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    516          /* thread creation */
    517          SET_STATUS_from_SysRes(do_clone(tid,
    518                                          ARG1,          /* flags */
    519                                          (Addr)ARG2,    /* child SP */
    520                                          (Int *)ARG3,   /* parent_tidptr */
    521                                          (Int *)ARG5,   /* child_tidptr */
    522                                          (Addr)ARG4));  /* child_tls */
    523          break;
    524 
    525       case VKI_CLONE_VFORK | VKI_CLONE_VM:  /* vfork */
    526          /* FALLTHROUGH - assume vfork == fork */
    527          cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    528       case 0:  /* plain fork */
    529          SET_STATUS_from_SysRes(ML_(do_fork_clone)(tid,
    530                                 cloneflags,     /* flags */
    531                                 (Int *)ARG3,    /* parent_tidptr */
    532                                 (Int *)ARG5));  /* child_tidptr */
    533          break;
    534 
    535       default:
    536          /* should we just ENOSYS? */
    537          VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
    538          VG_(message)(Vg_UserMsg, "\n");
    539          VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
    540          VG_(message)(Vg_UserMsg,
    541                        " - via a threads library (LinuxThreads or NPTL)\n");
    542          VG_(message)(Vg_UserMsg,
    543                        " - via the implementation of fork or vfork\n");
    544          VG_(unimplemented)("Valgrind does not support general clone().");
    545    }
    546    if (SUCCESS) {
    547       if (ARG1 & VKI_CLONE_PARENT_SETTID)
    548          POST_MEM_WRITE(ARG3, sizeof(Int));
    549       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    550          POST_MEM_WRITE(ARG5, sizeof(Int));
    551       /* Thread creation was successful; let the child have the chance to run */
    552       *flags |= SfYieldAfter;
    553    }
    554 }
    555 
    556 PRE(sys_rt_sigreturn)
    557 {
    558    /* See comments on PRE(sys_rt_sigreturn) in syswrap-s390x-linux.c for
    559       an explanation of what follows. */
    560    ThreadState* tst;
    561    PRINT("sys_rt_sigreturn ( )");
    562 
    563    vg_assert(VG_(is_valid_tid)(tid));
    564    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    565    vg_assert(VG_(is_running_thread)(tid));
    566 
    567    tst = VG_(get_ThreadState)(tid);
    568 
    569    /* This is only so that the IA is (might be) useful to report if
    570       something goes wrong in the sigreturn */
    571    ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    572 
    573    /* Restore register state from frame and remove it */
    574    VG_(sigframe_destroy)(tid, True);
    575 
    576    /* Tell the driver not to update the guest state with the "result",
    577       and set a bogus result to keep it happy. */
    578    *flags |= SfNoWriteResult;
    579    SET_STATUS_Success(0);
    580 
    581    /* Check to see if any signals arose as a result of this. */
    582    *flags |= SfPollAfter;
    583 }
    584 
    585 PRE(sys_set_thread_area)
    586 {
    587    PRINT("set_thread_area (%lx)", ARG1);
    588    PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
    589    SET_STATUS_from_SysRes(sys_set_tls(tid, ARG1));
    590 }
    591 
    592 PRE(sys_pipe)
    593 {
    594    PRINT("sys_pipe ( %#lx )", ARG1);
    595    PRE_REG_READ1(int, "pipe", int *, filedes);
    596    PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
    597 }
    598 
    599 POST(sys_pipe)
    600 {
    601    Int p0, p1;
    602    vg_assert(SUCCESS);
    603    p0 = RES;
    604    p1 = sr_ResEx(status->sres);
    605 
    606    if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
    607        !ML_(fd_allowed)(p1, "pipe", tid, True)) {
    608       VG_(close)(p0);
    609       VG_(close)(p1);
    610       SET_STATUS_Failure( VKI_EMFILE );
    611    } else {
    612       if (VG_(clo_track_fds)) {
    613          ML_(record_fd_open_nameless)(tid, p0);
    614          ML_(record_fd_open_nameless)(tid, p1);
    615       }
    616    }
    617 }
    618 
    619 #undef PRE
    620 #undef POST
    621 
    622 /* ---------------------------------------------------------------------
    623    The mips64/Linux syscall table
    624    ------------------------------------------------------------------ */
    625 
    626 /* Add an mips64-linux specific wrapper to a syscall table. */
    627 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(mips_linux, sysno, name)
    628 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(mips_linux, sysno, name)
    629 
    630 static SyscallTableEntry syscall_main_table[] = {
    631    GENXY (__NR_read, sys_read),  /* 5000 */
    632    GENX_ (__NR_write, sys_write),
    633    GENXY (__NR_open, sys_open),
    634    GENXY (__NR_close, sys_close),
    635    GENXY (__NR_stat, sys_newstat),
    636    GENXY (__NR_fstat, sys_newfstat),
    637    GENXY (__NR_lstat, sys_newlstat),
    638    GENXY (__NR_poll, sys_poll),
    639    LINX_ (__NR_lseek, sys_lseek),
    640    PLAX_ (__NR_mmap, sys_mmap),
    641    GENXY (__NR_mprotect, sys_mprotect),
    642    GENXY (__NR_munmap, sys_munmap),
    643    GENX_ (__NR_brk, sys_brk),
    644    LINXY (__NR_rt_sigaction, sys_rt_sigaction),
    645    LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask),
    646    LINXY (__NR_ioctl, sys_ioctl),
    647    LINXY (__NR_eventfd2, sys_eventfd2),
    648    LINXY (__NR_signalfd4, sys_signalfd4),
    649    GENXY (__NR_pread64, sys_pread64),
    650    GENX_ (__NR_pwrite64, sys_pwrite64),
    651    GENXY (__NR_readv, sys_readv),
    652    GENX_ (__NR_writev, sys_writev),
    653    GENX_ (__NR_access, sys_access),
    654    PLAXY (__NR_pipe, sys_pipe),
    655    LINXY (__NR_pipe2, sys_pipe2),
    656    GENX_ (__NR__newselect,sys_select),
    657    LINX_ (__NR_sched_yield, sys_sched_yield),
    658    GENX_ (__NR_mremap, sys_mremap),
    659    GENX_ (__NR_msync, sys_msync),
    660    GENXY (__NR_mincore, sys_mincore),
    661    GENX_ (__NR_madvise, sys_madvise),
    662    LINX_ (__NR_shmget, sys_shmget),
    663    LINXY (__NR_shmat, wrap_sys_shmat),
    664    LINXY (__NR_shmctl, sys_shmctl),
    665    GENXY (__NR_dup, sys_dup),
    666    GENXY (__NR_dup2, sys_dup2),
    667    LINXY (__NR_dup3, sys_dup3),
    668    GENX_ (__NR_pause, sys_pause),
    669    GENXY (__NR_nanosleep, sys_nanosleep),
    670    GENXY (__NR_getitimer, sys_getitimer),
    671    GENXY (__NR_setitimer, sys_setitimer),
    672    GENX_ (__NR_alarm, sys_alarm),
    673    GENX_ (__NR_getpid, sys_getpid),
    674    /* LINX_(__NR_fallocate,sys_fallocate), */
    675    LINXY (__NR_sendfile, sys_sendfile),
    676    LINXY (__NR_socket, sys_socket),
    677    LINX_ (__NR_connect, sys_connect),
    678    LINXY (__NR_accept, sys_accept),
    679    LINXY (__NR_accept4, sys_accept4),
    680    LINX_ (__NR_sendto, sys_sendto),
    681    LINXY (__NR_recvfrom, sys_recvfrom),
    682    LINX_ (__NR_sendmsg, sys_sendmsg),
    683    LINXY (__NR_recvmsg, sys_recvmsg),
    684    LINX_ (__NR_shutdown, sys_shutdown),
    685    LINX_ (__NR_bind, sys_bind),
    686    LINX_ (__NR_listen, sys_listen),
    687    LINXY (__NR_getsockname, sys_getsockname),
    688    LINXY (__NR_getpeername, sys_getpeername),
    689    LINXY (__NR_socketpair, sys_socketpair),
    690    LINX_ (__NR_setsockopt, sys_setsockopt),
    691    LINXY (__NR_getsockopt, sys_getsockopt),
    692    PLAX_ (__NR_clone, sys_clone),
    693    GENX_ (__NR_fork, sys_fork),
    694    GENX_ (__NR_execve, sys_execve),
    695    GENX_ (__NR_exit, sys_exit),
    696    GENXY (__NR_wait4, sys_wait4),
    697    GENX_ (__NR_kill, sys_kill),
    698    GENXY (__NR_uname, sys_newuname),
    699    LINX_ (__NR_semget, sys_semget),
    700    LINX_ (__NR_semop, sys_semop),
    701    LINXY (__NR_semctl, sys_semctl),
    702    LINXY (__NR_shmdt, sys_shmdt),
    703    LINX_ (__NR_msgget, sys_msgget),
    704    LINX_ (__NR_msgsnd, sys_msgsnd),
    705    LINXY (__NR_msgrcv, sys_msgrcv),
    706    LINXY (__NR_msgctl, sys_msgctl),
    707    LINXY (__NR_fcntl, sys_fcntl),
    708    GENX_ (__NR_flock, sys_flock),
    709    GENX_ (__NR_fsync, sys_fsync),
    710    GENX_ (__NR_fdatasync, sys_fdatasync),
    711    GENX_ (__NR_truncate, sys_truncate),
    712    GENX_ (__NR_ftruncate, sys_ftruncate),
    713    GENXY (__NR_getdents, sys_getdents),
    714    GENXY (__NR_getcwd, sys_getcwd),
    715    GENX_ (__NR_chdir, sys_chdir),
    716    GENX_ (__NR_fchdir, sys_fchdir),
    717    GENX_ (__NR_rename, sys_rename),
    718    GENX_ (__NR_mkdir, sys_mkdir),
    719    GENX_ (__NR_rmdir, sys_rmdir),
    720    GENXY (__NR_creat, sys_creat),
    721    GENX_ (__NR_link, sys_link),
    722    GENX_ (__NR_unlink, sys_unlink),
    723    GENX_ (__NR_symlink, sys_symlink),
    724    GENX_ (__NR_readlink, sys_readlink),
    725    GENX_ (__NR_chmod, sys_chmod),
    726    GENX_ (__NR_fchmod, sys_fchmod),
    727    GENX_ (__NR_chown, sys_chown),
    728    GENX_ (__NR_fchown, sys_fchown),
    729    GENX_ (__NR_lchown, sys_lchown),
    730    GENX_ (__NR_umask, sys_umask),
    731    GENXY (__NR_gettimeofday, sys_gettimeofday),
    732    GENXY (__NR_getrlimit, sys_getrlimit),
    733    GENXY (__NR_getrusage, sys_getrusage),
    734    LINXY (__NR_sysinfo, sys_sysinfo),
    735    GENXY (__NR_times, sys_times),
    736    PLAXY (__NR_ptrace, sys_ptrace),
    737    GENX_ (__NR_getuid, sys_getuid),
    738    LINXY (__NR_syslog, sys_syslog),
    739    GENX_ (__NR_getgid, sys_getgid),
    740    GENX_ (__NR_setuid, sys_setuid),
    741    GENX_ (__NR_setgid, sys_setgid),
    742    GENX_ (__NR_geteuid, sys_geteuid),
    743    GENX_ (__NR_getegid, sys_getegid),
    744    GENX_ (__NR_setpgid, sys_setpgid),
    745    GENX_ (__NR_getppid, sys_getppid),
    746    GENX_ (__NR_getpgrp, sys_getpgrp),
    747    GENX_ (__NR_setsid, sys_setsid),
    748    GENX_ (__NR_setreuid, sys_setreuid),
    749    GENX_ (__NR_setregid, sys_setregid),
    750    GENXY (__NR_getgroups, sys_getgroups),
    751    GENX_ (__NR_setgroups, sys_setgroups),
    752    LINX_ (__NR_setresuid, sys_setresuid),
    753    LINXY (__NR_getresuid, sys_getresuid),
    754    LINX_ (__NR_setresgid, sys_setresgid),
    755    LINXY (__NR_getresgid, sys_getresgid),
    756    GENX_ (__NR_getpgid, sys_getpgid),
    757    LINX_ (__NR_setfsuid, sys_setfsuid),
    758    LINX_ (__NR_setfsgid, sys_setfsgid),
    759    GENX_ (__NR_getsid, sys_getsid),
    760    LINXY (__NR_capget, sys_capget),
    761    LINX_ (__NR_capset, sys_capset),
    762    LINXY (__NR_rt_sigpending, sys_rt_sigpending),
    763    LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait),
    764    LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),
    765    LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend),
    766    GENXY (__NR_sigaltstack, sys_sigaltstack),
    767    LINX_ (__NR_utime, sys_utime),
    768    GENX_ (__NR_mknod, sys_mknod),
    769    LINX_ (__NR_personality, sys_personality),
    770    PLAX_ (__NR_ustat, sys_ustat),
    771    GENXY (__NR_statfs, sys_statfs),
    772    GENXY (__NR_fstatfs, sys_fstatfs),
    773    PLAX_ (__NR_sysfs, sys_sysfs),
    774    GENX_ (__NR_getpriority, sys_getpriority),
    775    GENX_ (__NR_setpriority, sys_setpriority),
    776    LINXY (__NR_sched_setparam, sys_sched_setparam),
    777    LINXY (__NR_sched_getparam, sys_sched_getparam),
    778    LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler),
    779    LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler),
    780    LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),
    781    LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),
    782    PLAX_ (__NR_sched_rr_get_interval, sys_sched_rr_get_interval),
    783    GENX_ (__NR_mlock, sys_mlock),
    784    GENX_ (__NR_munlock, sys_munlock),
    785    GENX_ (__NR_mlockall, sys_mlockall),
    786    LINX_ (__NR_munlockall, sys_munlockall),
    787    LINX_ (__NR_vhangup, sys_vhangup),
    788    LINX_ (__NR_pivot_root,sys_pivot_root),
    789    LINXY (__NR__sysctl, sys_sysctl),
    790    LINXY (__NR_prctl, sys_prctl),
    791    LINXY (__NR_adjtimex, sys_adjtimex),
    792    GENX_ (__NR_setrlimit, sys_setrlimit),
    793    GENX_ (__NR_chroot, sys_chroot),
    794    GENX_ (__NR_sync, sys_sync),
    795    GENX_ (__NR_acct, sys_acct),
    796    GENX_ (__NR_settimeofday, sys_settimeofday),
    797    LINX_ (__NR_mount, sys_mount),
    798    LINX_ (__NR_umount2, sys_umount),
    799    PLAX_ (__NR_swapon, sys_swapon),
    800    PLAX_ (__NR_swapoff, sys_swapoff),
    801    PLAX_ (__NR_reboot, sys_reboot),
    802    PLAX_ (__NR_sethostname, sys_sethostname),
    803    PLAX_ (__NR_setdomainname, sys_setdomainname),
    804    GENX_ (__NR_create_module, sys_ni_syscall),
    805    LINX_ (__NR_init_module, sys_init_module),
    806    LINX_ (__NR_delete_module, sys_delete_module),
    807    GENX_ (__NR_get_kernel_syms, sys_ni_syscall),
    808    GENX_ (__NR_query_module, sys_ni_syscall),
    809    LINX_ (__NR_quotactl, sys_quotactl),
    810    /* GENX_(__NR_nfsservctl,sys_nfsservctl), */
    811    GENXY (__NR_getpmsg, sys_getpmsg),
    812    GENX_ (__NR_putpmsg, sys_putpmsg),
    813    GENX_ (__NR_afs_syscall, sys_ni_syscall),
    814    /* GENX_(__NR_reserved177,sys_reserved177), */
    815    LINX_ (__NR_gettid, sys_gettid),
    816    /* GENX_(__NR_readahead,sys_readahead), */
    817    LINX_ (__NR_setxattr, sys_setxattr),
    818    LINX_ (__NR_lsetxattr, sys_lsetxattr),
    819    LINX_ (__NR_fsetxattr, sys_fsetxattr),
    820    LINXY (__NR_getxattr, sys_getxattr),
    821    LINXY (__NR_lgetxattr, sys_lgetxattr),
    822    LINXY (__NR_fgetxattr, sys_fgetxattr),
    823    LINXY (__NR_listxattr, sys_listxattr),
    824    LINXY (__NR_llistxattr, sys_llistxattr),
    825    LINXY (__NR_flistxattr, sys_flistxattr),
    826    LINX_ (__NR_removexattr, sys_removexattr),
    827    LINX_ (__NR_lremovexattr, sys_lremovexattr),
    828    LINX_ (__NR_fremovexattr, sys_fremovexattr),
    829    LINXY (__NR_tkill, sys_tkill),
    830    /* GENX_(__NR_reserved193,sys_reserved193), */
    831    LINXY (__NR_futex, sys_futex),
    832    LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity),
    833    LINXY (__NR_sched_getaffinity, sys_sched_getaffinity),
    834    PLAX_ (__NR_cacheflush, sys_cacheflush),
    835    LINXY (__NR_io_setup, sys_io_setup),
    836    LINX_ (__NR_io_destroy, sys_io_destroy),
    837    LINXY (__NR_io_getevents, sys_io_getevents),
    838    LINX_ (__NR_io_submit, sys_io_submit),
    839    LINXY (__NR_io_cancel, sys_io_cancel),
    840    LINX_ (__NR_exit_group, sys_exit_group),
    841    /* LINXY (__NR_lookup_dcookie, sys_lookup_dcookie), */
    842    LINXY (__NR_epoll_create, sys_epoll_create),
    843    LINXY (__NR_epoll_create1, sys_epoll_create1),
    844    LINX_ (__NR_epoll_ctl, sys_epoll_ctl),
    845    LINXY (__NR_epoll_wait, sys_epoll_wait),
    846    PLAX_(__NR_rt_sigreturn,sys_rt_sigreturn),
    847    /* LINXY(__NR_fcntl64,sys_fcntl64), */
    848    LINX_ (__NR_set_tid_address, sys_set_tid_address),
    849    LINX_ (__NR_semtimedop, sys_semtimedop),
    850    LINX_ (__NR_fadvise64, sys_fadvise64),
    851    LINXY (__NR_timer_create, sys_timer_create),
    852    LINXY (__NR_timer_settime, sys_timer_settime),
    853    LINXY (__NR_timer_gettime, sys_timer_gettime),
    854    LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun),
    855    LINX_ (__NR_timer_delete, sys_timer_delete),
    856    LINX_ (__NR_clock_settime, sys_clock_settime),
    857    LINXY (__NR_clock_gettime, sys_clock_gettime),
    858    LINXY (__NR_clock_getres, sys_clock_getres),
    859    LINXY (__NR_clock_nanosleep, sys_clock_nanosleep),
    860    LINX_ (__NR_tgkill, sys_tgkill),
    861    GENX_ (__NR_utimes, sys_utimes),
    862    LINX_ (__NR_mbind, sys_mbind),
    863    LINXY (__NR_get_mempolicy, sys_get_mempolicy),
    864    LINX_ (__NR_set_mempolicy, sys_set_mempolicy),
    865    LINXY (__NR_mq_open, sys_mq_open),
    866    LINX_ (__NR_mq_unlink, sys_mq_unlink),
    867    LINX_ (__NR_mq_timedsend, sys_mq_timedsend),
    868    LINXY (__NR_mq_timedreceive, sys_mq_timedreceive),
    869    LINX_ (__NR_mq_notify, sys_mq_notify),
    870    LINXY (__NR_mq_getsetattr, sys_mq_getsetattr),
    871    GENX_ (__NR_vserver, sys_ni_syscall),
    872    LINXY (__NR_waitid, sys_waitid),
    873    LINX_ (__NR_add_key, sys_add_key),
    874    LINX_ (__NR_request_key, sys_request_key),
    875    LINXY (__NR_keyctl, sys_keyctl),
    876    PLAX_ (__NR_set_thread_area, sys_set_thread_area),
    877    LINX_ (__NR_inotify_init, sys_inotify_init),
    878    LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch),
    879    LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch),
    880    LINXY (__NR_openat, sys_openat),
    881    LINX_ (__NR_mkdirat, sys_mkdirat),
    882    LINX_ (__NR_mknodat, sys_mknodat),
    883    LINX_ (__NR_fchownat, sys_fchownat),
    884    LINX_ (__NR_futimesat, sys_futimesat),
    885    LINX_ (__NR_unlinkat, sys_unlinkat),
    886    LINX_ (__NR_renameat, sys_renameat),
    887    LINX_ (__NR_linkat, sys_linkat),
    888    LINX_ (__NR_symlinkat, sys_symlinkat),
    889    LINX_ (__NR_readlinkat, sys_readlinkat),
    890    LINX_ (__NR_fchmodat, sys_fchmodat),
    891    LINX_ (__NR_faccessat, sys_faccessat),
    892    LINX_ (__NR_pselect6, sys_pselect6),
    893    LINXY (__NR_ppoll, sys_ppoll),
    894    PLAX_ (__NR_unshare, sys_unshare),
    895    PLAX_ (__NR_splice, sys_splice),
    896    LINX_ (__NR_sync_file_range, sys_sync_file_range),
    897    PLAX_ (__NR_tee, sys_tee),
    898    PLAX_ (__NR_vmsplice, sys_vmsplice),
    899    LINX_ (__NR_set_robust_list, sys_set_robust_list),
    900    LINXY (__NR_get_robust_list, sys_get_robust_list),
    901    LINXY (__NR_epoll_pwait, sys_epoll_pwait),
    902    LINX_ (__NR_ioprio_set, sys_ioprio_set),
    903    LINX_ (__NR_ioprio_get, sys_ioprio_get),
    904    LINX_ (__NR_utimensat, sys_utimensat),
    905    LINXY (__NR_signalfd, sys_signalfd),
    906    LINXY (__NR_eventfd, sys_eventfd),
    907    LINX_ (__NR_fallocate, sys_fallocate),
    908    LINXY (__NR_timerfd_create, sys_timerfd_create),
    909    LINXY (__NR_timerfd_gettime, sys_timerfd_gettime),
    910    LINXY (__NR_timerfd_settime, sys_timerfd_settime),
    911    LINXY (__NR_newfstatat, sys_newfstatat),
    912    LINXY (__NR_prlimit64, sys_prlimit64),
    913    LINXY (__NR_clock_adjtime, sys_clock_adjtime),
    914    LINXY (__NR_process_vm_readv, sys_process_vm_readv),
    915    LINX_ (__NR_process_vm_writev, sys_process_vm_writev),
    916    LINXY(__NR_getrandom, sys_getrandom),
    917    LINXY(__NR_memfd_create, sys_memfd_create),
    918    LINX_(__NR_syncfs, sys_syncfs)
    919 };
    920 
    921 SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno )
    922 {
    923    const UInt syscall_main_table_size
    924       = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
    925 
    926    if (sysno < syscall_main_table_size) {
    927       SyscallTableEntry * sys = &syscall_main_table[sysno];
    928       if (sys->before == NULL)
    929          return NULL;  /* no entry */
    930       else
    931          return sys;
    932    }
    933    /* Can't find a wrapper */
    934    return NULL;
    935 }
    936 
    937 #endif  /* defined(VGP_mips64_linux) */
    938 
    939 /*--------------------------------------------------------------------*/
    940 /*--- end                                   syswrap-mips64-linux.c ---*/
    941 /*--------------------------------------------------------------------*/
    942