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-2013 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 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, %ld, %ld )", ARG1, ARG2, 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, %ld, %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3,
    331                                                         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, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
    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 ( %ld )", ARG1);
    347    PRE_REG_READ1(long, "sys_unshare", int, flags);
    348 }
    349 
    350 PRE(sys_sched_rr_get_interval)
    351 {
    352    PRINT("sys_sched_rr_get_interval ( %ld, %#lx)", ARG1, ARG2);
    353    PRE_REG_READ2(long, "sched_rr_get_interval", int, flags,
    354                  struct timespec *, timer);
    355    *flags |= SfMayBlock;
    356 }
    357 
    358 PRE(sys_ustat)
    359 {
    360    PRINT("sys_ustat ( %ld, %#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, %ld )", 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, %ld, %#lx )", ARG1, 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                  int, nbytes, 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 )", ARG1);
    396    PRE_REG_READ1(int, "reboot", int, flags);
    397    *flags |= SfMayBlock;
    398 }
    399 
    400 PRE(sys_setdomainname)
    401 {
    402    PRINT ("sys_setdomainname ( %#lx, %ld )", ARG1, ARG2);
    403    PRE_REG_READ2 (long, "setdomainname", const void *, name, int, len);
    404 }
    405 
    406 PRE(sys_sethostname)
    407 {
    408    PRINT ("sys_sethostname ( %ld, %ld )", ARG1, ARG2);
    409    PRE_REG_READ2 (long, "sethostname", const void *, name, int, len);
    410 }
    411 
    412 PRE(sys_ptrace)
    413 {
    414    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
    415    PRE_REG_READ4(int, "ptrace", long, request, long, pid, long, addr,
    416                  long, data);
    417    switch (ARG1) {
    418       case VKI_PTRACE_PEEKTEXT:
    419       case VKI_PTRACE_PEEKDATA:
    420       case VKI_PTRACE_PEEKUSR:
    421          PRE_MEM_WRITE("ptrace(peek)", ARG4, sizeof(long));
    422          break;
    423       case VKI_PTRACE_GETEVENTMSG:
    424          PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
    425          break;
    426       case VKI_PTRACE_GETSIGINFO:
    427          PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
    428          break;
    429       case VKI_PTRACE_SETSIGINFO:
    430          PRE_MEM_READ("ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
    431          break;
    432       case VKI_PTRACE_GETREGSET:
    433          ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
    434          break;
    435       default:
    436         break;
    437    }
    438 }
    439 
    440 POST(sys_ptrace)
    441 {
    442    switch (ARG1) {
    443       case VKI_PTRACE_PEEKTEXT:
    444       case VKI_PTRACE_PEEKDATA:
    445       case VKI_PTRACE_PEEKUSR:
    446          POST_MEM_WRITE (ARG4, sizeof(long));
    447          break;
    448       case VKI_PTRACE_GETEVENTMSG:
    449          POST_MEM_WRITE (ARG4, sizeof(unsigned long));
    450       break;
    451       case VKI_PTRACE_GETSIGINFO:
    452          POST_MEM_WRITE (ARG4, sizeof(vki_siginfo_t));
    453          break;
    454       case VKI_PTRACE_GETREGSET:
    455          ML_(linux_POST_getregset)(tid, ARG3, ARG4);
    456          break;
    457       default:
    458       break;
    459    }
    460 }
    461 
    462 PRE (sys_mmap)
    463 {
    464    SysRes r;
    465    PRINT("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong)ARG2,
    466                                                         ARG3, ARG4, ARG5, ARG6);
    467    PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length,
    468                  int, prot, int, flags, int, fd, unsigned long, offset);
    469    r = ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    470                                  (Off64T) ARG6);
    471    SET_STATUS_from_SysRes(r);
    472 }
    473 
    474 PRE(sys_clone)
    475 {
    476    Bool badarg = False;
    477    UInt cloneflags;
    478    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
    479                                                       ARG4, ARG5);
    480    PRE_REG_READ2(int, "clone", unsigned long, flags, void *, child_stack);
    481    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    482       if (VG_(tdict).track_pre_reg_read) {
    483          PRA3("clone", int *, parent_tidptr);
    484       }
    485       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    486       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
    487          badarg = True;
    488       }
    489    }
    490    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    491       if (VG_(tdict).track_pre_reg_read) {
    492          PRA5("clone", int *, child_tidptr);
    493       }
    494       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof (Int));
    495       if (!VG_(am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
    496          badarg = True;
    497    }
    498    if (badarg) {
    499       SET_STATUS_Failure(VKI_EFAULT);
    500       return;
    501    }
    502    cloneflags = ARG1;
    503    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
    504       SET_STATUS_Failure(VKI_EINVAL);
    505       return;
    506    }
    507    /* Only look at the flags we really care about */
    508    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    509            |VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    510       case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    511          /* thread creation */
    512          SET_STATUS_from_SysRes(do_clone(tid,
    513                                          ARG1,          /* flags */
    514                                          (Addr)ARG2,    /* child SP */
    515                                          (Int *)ARG3,   /* parent_tidptr */
    516                                          (Int *)ARG5,   /* child_tidptr */
    517                                          (Addr)ARG4));  /* child_tls */
    518          break;
    519 
    520       case VKI_CLONE_VFORK | VKI_CLONE_VM:  /* vfork */
    521          /* FALLTHROUGH - assume vfork == fork */
    522          cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    523       case 0:  /* plain fork */
    524          SET_STATUS_from_SysRes(ML_(do_fork_clone)(tid,
    525                                 cloneflags,     /* flags */
    526                                 (Int *)ARG3,    /* parent_tidptr */
    527                                 (Int *)ARG5));  /* child_tidptr */
    528          break;
    529 
    530       default:
    531          /* should we just ENOSYS? */
    532          VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
    533          VG_(message)(Vg_UserMsg, "\n");
    534          VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
    535          VG_(message)(Vg_UserMsg,
    536                        " - via a threads library (LinuxThreads or NPTL)\n");
    537          VG_(message)(Vg_UserMsg,
    538                        " - via the implementation of fork or vfork\n");
    539          VG_(unimplemented)("Valgrind does not support general clone().");
    540    }
    541    if (SUCCESS) {
    542       if (ARG1 & VKI_CLONE_PARENT_SETTID)
    543          POST_MEM_WRITE(ARG3, sizeof(Int));
    544       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    545          POST_MEM_WRITE(ARG5, sizeof(Int));
    546       /* Thread creation was successful; let the child have the chance to run */
    547       *flags |= SfYieldAfter;
    548    }
    549 }
    550 
    551 PRE(sys_rt_sigreturn)
    552 {
    553    /* See comments on PRE(sys_rt_sigreturn) in syswrap-s390x-linux.c for
    554       an explanation of what follows. */
    555    ThreadState* tst;
    556    PRINT("sys_rt_sigreturn ( )");
    557 
    558    vg_assert(VG_(is_valid_tid)(tid));
    559    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    560    vg_assert(VG_(is_running_thread)(tid));
    561 
    562    tst = VG_(get_ThreadState)(tid);
    563 
    564    /* This is only so that the IA is (might be) useful to report if
    565       something goes wrong in the sigreturn */
    566    ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    567 
    568    /* Restore register state from frame and remove it */
    569    VG_(sigframe_destroy)(tid, True);
    570 
    571    /* Tell the driver not to update the guest state with the "result",
    572       and set a bogus result to keep it happy. */
    573    *flags |= SfNoWriteResult;
    574    SET_STATUS_Success(0);
    575 
    576    /* Check to see if any signals arose as a result of this. */
    577    *flags |= SfPollAfter;
    578 }
    579 
    580 PRE(sys_set_thread_area)
    581 {
    582    PRINT("set_thread_area (%lx)", ARG1);
    583    PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
    584    SET_STATUS_from_SysRes(sys_set_tls(tid, ARG1));
    585 }
    586 
    587 PRE(sys_pipe)
    588 {
    589    PRINT("sys_pipe ( %#lx )", ARG1);
    590    PRE_REG_READ1(int, "pipe", int *, filedes);
    591    PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
    592 }
    593 
    594 POST(sys_pipe)
    595 {
    596    Int p0, p1;
    597    vg_assert(SUCCESS);
    598    p0 = RES;
    599    p1 = sr_ResEx(status->sres);
    600 
    601    if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
    602        !ML_(fd_allowed)(p1, "pipe", tid, True)) {
    603       VG_(close)(p0);
    604       VG_(close)(p1);
    605       SET_STATUS_Failure( VKI_EMFILE );
    606    } else {
    607       if (VG_(clo_track_fds)) {
    608          ML_(record_fd_open_nameless)(tid, p0);
    609          ML_(record_fd_open_nameless)(tid, p1);
    610       }
    611    }
    612 }
    613 
    614 #undef PRE
    615 #undef POST
    616 
    617 /* ---------------------------------------------------------------------
    618    The mips64/Linux syscall table
    619    ------------------------------------------------------------------ */
    620 
    621 /* Add an mips64-linux specific wrapper to a syscall table. */
    622 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(mips_linux, sysno, name)
    623 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(mips_linux, sysno, name)
    624 
    625 static SyscallTableEntry syscall_main_table[] = {
    626    GENXY (__NR_read, sys_read),  /* 5000 */
    627    GENX_ (__NR_write, sys_write),
    628    GENXY (__NR_open, sys_open),
    629    GENXY (__NR_close, sys_close),
    630    GENXY (__NR_stat, sys_newstat),
    631    GENXY (__NR_fstat, sys_newfstat),
    632    GENXY (__NR_lstat, sys_newlstat),
    633    GENXY (__NR_poll, sys_poll),
    634    LINX_ (__NR_lseek, sys_lseek),
    635    PLAX_ (__NR_mmap, sys_mmap),
    636    GENXY (__NR_mprotect, sys_mprotect),
    637    GENXY (__NR_munmap, sys_munmap),
    638    GENX_ (__NR_brk, sys_brk),
    639    LINXY (__NR_rt_sigaction, sys_rt_sigaction),
    640    LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask),
    641    LINXY (__NR_ioctl, sys_ioctl),
    642    LINXY (__NR_eventfd2, sys_eventfd2),
    643    LINXY (__NR_signalfd4, sys_signalfd4),
    644    GENXY (__NR_pread64, sys_pread64),
    645    GENX_ (__NR_pwrite64, sys_pwrite64),
    646    GENXY (__NR_readv, sys_readv),
    647    GENX_ (__NR_writev, sys_writev),
    648    GENX_ (__NR_access, sys_access),
    649    PLAXY (__NR_pipe, sys_pipe),
    650    LINXY (__NR_pipe2, sys_pipe2),
    651    GENX_ (__NR__newselect,sys_select),
    652    LINX_ (__NR_sched_yield, sys_sched_yield),
    653    GENX_ (__NR_mremap, sys_mremap),
    654    GENX_ (__NR_msync, sys_msync),
    655    GENXY (__NR_mincore, sys_mincore),
    656    GENX_ (__NR_madvise, sys_madvise),
    657    LINX_ (__NR_shmget, sys_shmget),
    658    LINXY (__NR_shmat, wrap_sys_shmat),
    659    LINXY (__NR_shmctl, sys_shmctl),
    660    GENXY (__NR_dup, sys_dup),
    661    GENXY (__NR_dup2, sys_dup2),
    662    LINXY (__NR_dup3, sys_dup3),
    663    GENX_ (__NR_pause, sys_pause),
    664    GENXY (__NR_nanosleep, sys_nanosleep),
    665    GENXY (__NR_getitimer, sys_getitimer),
    666    GENXY (__NR_setitimer, sys_setitimer),
    667    GENX_ (__NR_alarm, sys_alarm),
    668    GENX_ (__NR_getpid, sys_getpid),
    669    /* LINX_(__NR_fallocate,sys_fallocate), */
    670    LINXY (__NR_sendfile, sys_sendfile),
    671    LINXY (__NR_socket, sys_socket),
    672    LINX_ (__NR_connect, sys_connect),
    673    LINXY (__NR_accept, sys_accept),
    674    LINXY (__NR_accept4, sys_accept4),
    675    LINX_ (__NR_sendto, sys_sendto),
    676    LINXY (__NR_recvfrom, sys_recvfrom),
    677    LINX_ (__NR_sendmsg, sys_sendmsg),
    678    LINXY (__NR_recvmsg, sys_recvmsg),
    679    LINX_ (__NR_shutdown, sys_shutdown),
    680    LINX_ (__NR_bind, sys_bind),
    681    LINX_ (__NR_listen, sys_listen),
    682    LINXY (__NR_getsockname, sys_getsockname),
    683    LINXY (__NR_getpeername, sys_getpeername),
    684    LINXY (__NR_socketpair, sys_socketpair),
    685    LINX_ (__NR_setsockopt, sys_setsockopt),
    686    LINXY (__NR_getsockopt, sys_getsockopt),
    687    PLAX_ (__NR_clone, sys_clone),
    688    GENX_ (__NR_fork, sys_fork),
    689    GENX_ (__NR_execve, sys_execve),
    690    GENX_ (__NR_exit, sys_exit),
    691    GENXY (__NR_wait4, sys_wait4),
    692    GENX_ (__NR_kill, sys_kill),
    693    GENXY (__NR_uname, sys_newuname),
    694    LINX_ (__NR_semget, sys_semget),
    695    LINX_ (__NR_semop, sys_semop),
    696    LINXY (__NR_semctl, sys_semctl),
    697    LINXY (__NR_shmdt, sys_shmdt),
    698    LINX_ (__NR_msgget, sys_msgget),
    699    LINX_ (__NR_msgsnd, sys_msgsnd),
    700    LINXY (__NR_msgrcv, sys_msgrcv),
    701    LINXY (__NR_msgctl, sys_msgctl),
    702    LINXY (__NR_fcntl, sys_fcntl),
    703    GENX_ (__NR_flock, sys_flock),
    704    GENX_ (__NR_fsync, sys_fsync),
    705    GENX_ (__NR_fdatasync, sys_fdatasync),
    706    GENX_ (__NR_truncate, sys_truncate),
    707    GENX_ (__NR_ftruncate, sys_ftruncate),
    708    GENXY (__NR_getdents, sys_getdents),
    709    GENXY (__NR_getcwd, sys_getcwd),
    710    GENX_ (__NR_chdir, sys_chdir),
    711    GENX_ (__NR_fchdir, sys_fchdir),
    712    GENX_ (__NR_rename, sys_rename),
    713    GENX_ (__NR_mkdir, sys_mkdir),
    714    GENX_ (__NR_rmdir, sys_rmdir),
    715    GENXY (__NR_creat, sys_creat),
    716    GENX_ (__NR_link, sys_link),
    717    GENX_ (__NR_unlink, sys_unlink),
    718    GENX_ (__NR_symlink, sys_symlink),
    719    GENX_ (__NR_readlink, sys_readlink),
    720    GENX_ (__NR_chmod, sys_chmod),
    721    GENX_ (__NR_fchmod, sys_fchmod),
    722    GENX_ (__NR_chown, sys_chown),
    723    GENX_ (__NR_fchown, sys_fchown),
    724    GENX_ (__NR_lchown, sys_lchown),
    725    GENX_ (__NR_umask, sys_umask),
    726    GENXY (__NR_gettimeofday, sys_gettimeofday),
    727    GENXY (__NR_getrlimit, sys_getrlimit),
    728    GENXY (__NR_getrusage, sys_getrusage),
    729    LINXY (__NR_sysinfo, sys_sysinfo),
    730    GENXY (__NR_times, sys_times),
    731    PLAXY (__NR_ptrace, sys_ptrace),
    732    GENX_ (__NR_getuid, sys_getuid),
    733    LINXY (__NR_syslog, sys_syslog),
    734    GENX_ (__NR_getgid, sys_getgid),
    735    GENX_ (__NR_setuid, sys_setuid),
    736    GENX_ (__NR_setgid, sys_setgid),
    737    GENX_ (__NR_geteuid, sys_geteuid),
    738    GENX_ (__NR_getegid, sys_getegid),
    739    GENX_ (__NR_setpgid, sys_setpgid),
    740    GENX_ (__NR_getppid, sys_getppid),
    741    GENX_ (__NR_getpgrp, sys_getpgrp),
    742    GENX_ (__NR_setsid, sys_setsid),
    743    GENX_ (__NR_setreuid, sys_setreuid),
    744    GENX_ (__NR_setregid, sys_setregid),
    745    GENXY (__NR_getgroups, sys_getgroups),
    746    GENX_ (__NR_setgroups, sys_setgroups),
    747    LINX_ (__NR_setresuid, sys_setresuid),
    748    LINXY (__NR_getresuid, sys_getresuid),
    749    LINX_ (__NR_setresgid, sys_setresgid),
    750    LINXY (__NR_getresgid, sys_getresgid),
    751    GENX_ (__NR_getpgid, sys_getpgid),
    752    LINX_ (__NR_setfsuid, sys_setfsuid),
    753    LINX_ (__NR_setfsgid, sys_setfsgid),
    754    GENX_ (__NR_getsid, sys_getsid),
    755    LINXY (__NR_capget, sys_capget),
    756    LINX_ (__NR_capset, sys_capset),
    757    LINXY (__NR_rt_sigpending, sys_rt_sigpending),
    758    LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait),
    759    LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),
    760    LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend),
    761    GENXY (__NR_sigaltstack, sys_sigaltstack),
    762    LINX_ (__NR_utime, sys_utime),
    763    GENX_ (__NR_mknod, sys_mknod),
    764    LINX_ (__NR_personality, sys_personality),
    765    PLAX_ (__NR_ustat, sys_ustat),
    766    GENXY (__NR_statfs, sys_statfs),
    767    GENXY (__NR_fstatfs, sys_fstatfs),
    768    PLAX_ (__NR_sysfs, sys_sysfs),
    769    GENX_ (__NR_getpriority, sys_getpriority),
    770    GENX_ (__NR_setpriority, sys_setpriority),
    771    LINXY (__NR_sched_setparam, sys_sched_setparam),
    772    LINXY (__NR_sched_getparam, sys_sched_getparam),
    773    LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler),
    774    LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler),
    775    LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),
    776    LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),
    777    PLAX_ (__NR_sched_rr_get_interval, sys_sched_rr_get_interval),
    778    GENX_ (__NR_mlock, sys_mlock),
    779    GENX_ (__NR_munlock, sys_munlock),
    780    GENX_ (__NR_mlockall, sys_mlockall),
    781    LINX_ (__NR_munlockall, sys_munlockall),
    782    LINX_ (__NR_vhangup, sys_vhangup),
    783    LINX_ (__NR_pivot_root,sys_pivot_root),
    784    LINXY (__NR__sysctl, sys_sysctl),
    785    LINXY (__NR_prctl, sys_prctl),
    786    LINXY (__NR_adjtimex, sys_adjtimex),
    787    GENX_ (__NR_setrlimit, sys_setrlimit),
    788    GENX_ (__NR_chroot, sys_chroot),
    789    GENX_ (__NR_sync, sys_sync),
    790    GENX_ (__NR_acct, sys_acct),
    791    GENX_ (__NR_settimeofday, sys_settimeofday),
    792    LINX_ (__NR_mount, sys_mount),
    793    LINX_ (__NR_umount2, sys_umount),
    794    PLAX_ (__NR_swapon, sys_swapon),
    795    PLAX_ (__NR_swapoff, sys_swapoff),
    796    PLAX_ (__NR_reboot, sys_reboot),
    797    PLAX_ (__NR_sethostname, sys_sethostname),
    798    PLAX_ (__NR_setdomainname, sys_setdomainname),
    799    GENX_ (__NR_create_module, sys_ni_syscall),
    800    LINX_ (__NR_init_module, sys_init_module),
    801    LINX_ (__NR_delete_module, sys_delete_module),
    802    GENX_ (__NR_get_kernel_syms, sys_ni_syscall),
    803    GENX_ (__NR_query_module, sys_ni_syscall),
    804    LINX_ (__NR_quotactl, sys_quotactl),
    805    /* GENX_(__NR_nfsservctl,sys_nfsservctl), */
    806    GENXY (__NR_getpmsg, sys_getpmsg),
    807    GENX_ (__NR_putpmsg, sys_putpmsg),
    808    GENX_ (__NR_afs_syscall, sys_ni_syscall),
    809    /* GENX_(__NR_reserved177,sys_reserved177), */
    810    LINX_ (__NR_gettid, sys_gettid),
    811    /* GENX_(__NR_readahead,sys_readahead), */
    812    LINX_ (__NR_setxattr, sys_setxattr),
    813    LINX_ (__NR_lsetxattr, sys_lsetxattr),
    814    LINX_ (__NR_fsetxattr, sys_fsetxattr),
    815    LINXY (__NR_getxattr, sys_getxattr),
    816    LINXY (__NR_lgetxattr, sys_lgetxattr),
    817    LINXY (__NR_fgetxattr, sys_fgetxattr),
    818    LINXY (__NR_listxattr, sys_listxattr),
    819    LINXY (__NR_llistxattr, sys_llistxattr),
    820    LINXY (__NR_flistxattr, sys_flistxattr),
    821    LINX_ (__NR_removexattr, sys_removexattr),
    822    LINX_ (__NR_lremovexattr, sys_lremovexattr),
    823    LINX_ (__NR_fremovexattr, sys_fremovexattr),
    824    LINXY (__NR_tkill, sys_tkill),
    825    /* GENX_(__NR_reserved193,sys_reserved193), */
    826    LINXY (__NR_futex, sys_futex),
    827    LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity),
    828    LINXY (__NR_sched_getaffinity, sys_sched_getaffinity),
    829    PLAX_ (__NR_cacheflush, sys_cacheflush),
    830    LINXY (__NR_io_setup, sys_io_setup),
    831    LINX_ (__NR_io_destroy, sys_io_destroy),
    832    LINXY (__NR_io_getevents, sys_io_getevents),
    833    LINX_ (__NR_io_submit, sys_io_submit),
    834    LINXY (__NR_io_cancel, sys_io_cancel),
    835    LINX_ (__NR_exit_group, sys_exit_group),
    836    /* LINXY (__NR_lookup_dcookie, sys_lookup_dcookie), */
    837    LINXY (__NR_epoll_create, sys_epoll_create),
    838    LINXY (__NR_epoll_create1, sys_epoll_create1),
    839    LINX_ (__NR_epoll_ctl, sys_epoll_ctl),
    840    LINXY (__NR_epoll_wait, sys_epoll_wait),
    841    PLAX_(__NR_rt_sigreturn,sys_rt_sigreturn),
    842    /* LINXY(__NR_fcntl64,sys_fcntl64), */
    843    LINX_ (__NR_set_tid_address, sys_set_tid_address),
    844    LINX_ (__NR_semtimedop, sys_semtimedop),
    845    LINX_ (__NR_fadvise64, sys_fadvise64),
    846    LINXY (__NR_timer_create, sys_timer_create),
    847    LINXY (__NR_timer_settime, sys_timer_settime),
    848    LINXY (__NR_timer_gettime, sys_timer_gettime),
    849    LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun),
    850    LINX_ (__NR_timer_delete, sys_timer_delete),
    851    LINX_ (__NR_clock_settime, sys_clock_settime),
    852    LINXY (__NR_clock_gettime, sys_clock_gettime),
    853    LINXY (__NR_clock_getres, sys_clock_getres),
    854    LINXY (__NR_clock_nanosleep, sys_clock_nanosleep),
    855    LINX_ (__NR_tgkill, sys_tgkill),
    856    GENX_ (__NR_utimes, sys_utimes),
    857    LINX_ (__NR_mbind, sys_mbind),
    858    LINXY (__NR_get_mempolicy, sys_get_mempolicy),
    859    LINX_ (__NR_set_mempolicy, sys_set_mempolicy),
    860    LINXY (__NR_mq_open, sys_mq_open),
    861    LINX_ (__NR_mq_unlink, sys_mq_unlink),
    862    LINX_ (__NR_mq_timedsend, sys_mq_timedsend),
    863    LINXY (__NR_mq_timedreceive, sys_mq_timedreceive),
    864    LINX_ (__NR_mq_notify, sys_mq_notify),
    865    LINXY (__NR_mq_getsetattr, sys_mq_getsetattr),
    866    GENX_ (__NR_vserver, sys_ni_syscall),
    867    LINXY (__NR_waitid, sys_waitid),
    868    LINX_ (__NR_add_key, sys_add_key),
    869    LINX_ (__NR_request_key, sys_request_key),
    870    LINXY (__NR_keyctl, sys_keyctl),
    871    PLAX_ (__NR_set_thread_area, sys_set_thread_area),
    872    LINX_ (__NR_inotify_init, sys_inotify_init),
    873    LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch),
    874    LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch),
    875    LINXY (__NR_openat, sys_openat),
    876    LINX_ (__NR_mkdirat, sys_mkdirat),
    877    LINX_ (__NR_mknodat, sys_mknodat),
    878    LINX_ (__NR_fchownat, sys_fchownat),
    879    LINX_ (__NR_futimesat, sys_futimesat),
    880    LINX_ (__NR_unlinkat, sys_unlinkat),
    881    LINX_ (__NR_renameat, sys_renameat),
    882    LINX_ (__NR_linkat, sys_linkat),
    883    LINX_ (__NR_symlinkat, sys_symlinkat),
    884    LINX_ (__NR_readlinkat, sys_readlinkat),
    885    LINX_ (__NR_fchmodat, sys_fchmodat),
    886    LINX_ (__NR_faccessat, sys_faccessat),
    887    LINX_ (__NR_pselect6, sys_pselect6),
    888    LINXY (__NR_ppoll, sys_ppoll),
    889    PLAX_ (__NR_unshare, sys_unshare),
    890    PLAX_ (__NR_splice, sys_splice),
    891    LINX_ (__NR_sync_file_range, sys_sync_file_range),
    892    PLAX_ (__NR_tee, sys_tee),
    893    PLAX_ (__NR_vmsplice, sys_vmsplice),
    894    LINX_ (__NR_set_robust_list, sys_set_robust_list),
    895    LINXY (__NR_get_robust_list, sys_get_robust_list),
    896    LINXY (__NR_epoll_pwait, sys_epoll_pwait),
    897    LINX_ (__NR_ioprio_set, sys_ioprio_set),
    898    LINX_ (__NR_ioprio_get, sys_ioprio_get),
    899    LINX_ (__NR_utimensat, sys_utimensat),
    900    LINXY (__NR_signalfd, sys_signalfd),
    901    LINXY (__NR_eventfd, sys_eventfd),
    902    LINX_ (__NR_fallocate, sys_fallocate),
    903    LINXY (__NR_timerfd_create, sys_timerfd_create),
    904    LINXY (__NR_timerfd_gettime, sys_timerfd_gettime),
    905    LINXY (__NR_timerfd_settime, sys_timerfd_settime),
    906    LINXY (__NR_newfstatat, sys_newfstatat),
    907    LINXY (__NR_prlimit64, sys_prlimit64),
    908    LINXY (__NR_clock_adjtime, sys_clock_adjtime),
    909    LINXY (__NR_process_vm_readv, sys_process_vm_readv),
    910    LINX_ (__NR_process_vm_writev, sys_process_vm_writev),
    911    LINXY(__NR_getrandom, sys_getrandom),
    912    LINXY(__NR_memfd_create, sys_memfd_create),
    913    LINX_(__NR_syncfs, sys_syncfs)
    914 };
    915 
    916 SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno )
    917 {
    918    const UInt syscall_main_table_size
    919       = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
    920 
    921    if (sysno < syscall_main_table_size) {
    922       SyscallTableEntry * sys = &syscall_main_table[sysno];
    923       if (sys->before == NULL)
    924          return NULL;  /* no entry */
    925       else
    926          return sys;
    927    }
    928    /* Can't find a wrapper */
    929    return NULL;
    930 }
    931 
    932 #endif  /* defined(VGP_mips64_linux) */
    933 
    934 /*--------------------------------------------------------------------*/
    935 /*--- end                                   syswrap-mips64-linux.c ---*/
    936 /*--------------------------------------------------------------------*/
    937