Home | History | Annotate | Download | only in m_syswrap
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Platform-specific syscalls stuff.    syswrap-mips32-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_mips32_linux)
     32 #include "pub_core_basics.h"
     33 #include "pub_core_vki.h"
     34 #include "pub_core_vkiscnums.h"
     35 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
     36 #include "pub_core_threadstate.h"
     37 #include "pub_core_aspacemgr.h"
     38 #include "pub_core_debuglog.h"
     39 #include "pub_core_libcbase.h"
     40 #include "pub_core_libcassert.h"
     41 #include "pub_core_libcprint.h"
     42 #include "pub_core_libcproc.h"
     43 #include "pub_core_libcsignal.h"
     44 #include "pub_core_options.h"
     45 #include "pub_core_scheduler.h"
     46 #include "pub_core_sigframe.h"     // For VG_(sigframe_destroy)()
     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 #include "pub_core_stacks.h"        // VG_(register_stack)
     52 #include "pub_core_transtab.h"      // VG_(discard_translations)
     53 #include "priv_types_n_macros.h"
     54 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
     55 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
     56 #include "priv_syswrap-main.h"
     57 
     58 #include "pub_core_debuginfo.h"     // VG_(di_notify_*)
     59 #include "pub_core_xarray.h"
     60 #include "pub_core_clientstate.h"   // VG_(brk_base), VG_(brk_limit)
     61 #include "pub_core_errormgr.h"
     62 #include "pub_core_gdbserver.h"     // VG_(gdbserver)
     63 #include "pub_core_libcfile.h"
     64 #include "pub_core_machine.h"       // VG_(get_SP)
     65 #include "pub_core_mallocfree.h"
     66 #include "pub_core_stacktrace.h"    // For VG_(get_and_pp_StackTrace)()
     67 #include "pub_core_ume.h"
     68 
     69 #include "priv_syswrap-generic.h"
     70 
     71 #include "config.h"
     72 
     73 #include <errno.h>
     74 
     75 /* ---------------------------------------------------------------------
     76                              clone() handling
     77    ------------------------------------------------------------------ */
     78 /* Call f(arg1), but first switch stacks, using 'stack' as the new
     79    stack, and use 'retaddr' as f's return-to address.  Also, clear all
     80    the integer registers before entering f.*/
     81 
     82 __attribute__ ((noreturn))
     83 void ML_ (call_on_new_stack_0_1) (Addr stack, Addr retaddr,
     84                                   void (*f) (Word), Word arg1);
     85 //    a0 = stack
     86 //    a1 = retaddr
     87 //    a2 = f
     88 //    a3 = arg1
     89 asm (
     90 ".text\n"
     91 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
     92 "vgModuleLocal_call_on_new_stack_0_1:\n"
     93 "   move	$29, $4\n\t"	// stack to %sp
     94 "   move	$25, $6\n\t"	// f to t9/$25
     95 "   move 	$4, $7\n\t"	// arg1 to $a0
     96 "   li 		$2, 0\n\t"	// zero all GP regs
     97 "   li 		$3, 0\n\t"
     98 "   li 		$5, 0\n\t"
     99 "   li 		$6, 0\n\t"
    100 "   li 		$7, 0\n\t"
    101 
    102 "   li 		$12, 0\n\t"
    103 "   li 		$13, 0\n\t"
    104 "   li 		$14, 0\n\t"
    105 "   li 		$15, 0\n\t"
    106 "   li 		$16, 0\n\t"
    107 "   li 		$17, 0\n\t"
    108 "   li 		$18, 0\n\t"
    109 "   li 		$19, 0\n\t"
    110 "   li 		$20, 0\n\t"
    111 "   li 		$21, 0\n\t"
    112 "   li 		$22, 0\n\t"
    113 "   li 		$23, 0\n\t"
    114 "   li 		$24, 0\n\t"
    115 "   jr 		$25\n\t"	// jump to dst
    116 "   break	0x7\n"	// should never get here
    117 ".previous\n"
    118 );
    119 
    120 /*
    121         Perform a clone system call.  clone is strange because it has
    122         fork()-like return-twice semantics, so it needs special
    123         handling here.
    124         Upon entry, we have:
    125             int (fn)(void*)     in  $a0       0
    126             void* child_stack   in  $a1       4
    127             int flags           in  $a2       8
    128             void* arg           in  $a3       12
    129             pid_t* child_tid    in  stack     16
    130             pid_t* parent_tid   in  stack     20
    131             void* tls_ptr       in  stack     24
    132 
    133         System call requires:
    134             int    $__NR_clone  in $v0
    135             int    flags        in $a0   0
    136             void*  child_stack  in $a1   4
    137             pid_t* parent_tid   in $a2   8
    138             void*  tls_ptr      in $a3   12
    139             pid_t* child_tid    in stack 16
    140 
    141    int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
    142              void *parent_tidptr, void *tls, void *child_tidptr)
    143 
    144    Returns an Int encoded in the linux-mips way, not a SysRes.
    145  */
    146 #define __NR_CLONE        VG_STRINGIFY(__NR_clone)
    147 #define __NR_EXIT         VG_STRINGIFY(__NR_exit)
    148 
    149 //extern
    150 UInt do_syscall_clone_mips_linux (Word (*fn) (void *), //a0      0     32
    151                                    void *stack,         //a1      4     36
    152                                    Int flags,           //a2      8     40
    153                                    void *arg,           //a3      12    44
    154                                    Int * child_tid,     //stack   16    48
    155                                    Int * parent_tid,    //stack   20    52
    156                                    Int tls);          //stack   24    56
    157 asm (
    158 ".text\n"
    159 "   .globl   do_syscall_clone_mips_linux\n"
    160 "   do_syscall_clone_mips_linux:\n"
    161 "   subu    $29,$29,32\n\t"
    162 "   sw $31, 0($29)\n\t"
    163 "   sw $2, 4($29)\n\t"
    164 "   sw $3, 8($29)\n\t"
    165 "   sw $30, 12($29)\n\t"
    166 "   sw $28, 28($29)\n\t"
    167     /* set up child stack with function and arg */
    168     /* syscall arg 2 child_stack is already in a1 */
    169 "   subu $5, $5, 32\n\t" /* make space on stack */
    170 "   sw $4, 0($5)\n\t" /* fn  */
    171 "   sw $7, 4($5)\n\t" /* fn arg */
    172 "   sw $6, 8($5)\n\t"
    173     /* get other args to clone */
    174 
    175 "   move $4, $a2\n\t" /* a0 = flags */
    176 "   lw $6,  52($29)\n\t" /* a2 = parent_tid */
    177 "   lw $7,  48($29)\n\t" /* a3 = child_tid */
    178 "   sw $7,  16($29)\n\t" /* 16(sp) = child_tid */
    179 "   lw $7,  56($29)\n\t" /* a3 = tls_ptr */
    180     /* do the system call */
    181 
    182 "   li $2, " __NR_CLONE "\n\t" /* __NR_clone */
    183 "   syscall\n\t"
    184 "   nop\n\t"
    185 
    186 "   bnez    $7, .Lerror\n\t"
    187 "   nop\n\t"
    188 "   beqz    $2, .Lstart\n\t"
    189 "   nop\n\t"
    190 
    191 "   lw      $31, 0($sp)\n\t"
    192 "   nop\n\t"
    193 "   lw      $30, 12($sp)\n\t"
    194 "   nop\n\t"
    195 "   addu    $29,$29,32\n\t" /* free stack */
    196 "   nop\n\t"
    197 "   jr      $31\n\t"
    198 "   nop\n\t"
    199 
    200 ".Lerror:\n\t"
    201 "   li      $31, 5\n\t"
    202 "   jr      $31\n\t"
    203 "   nop\n\t"
    204 
    205 ".Lstart:\n\t"
    206 "   lw      $4,  4($29)\n\t"
    207 "   nop\n\t"
    208 "   lw      $25, 0($29)\n\t"
    209 "   nop\n\t"
    210 "   jalr    $25\n\t"
    211 "   nop\n\t"
    212 
    213 "   move $4, $2\n\t" /* retval from fn is in $v0 */
    214 "   li $2, " __NR_EXIT "\n\t" /* NR_exit */
    215 "   syscall\n\t"
    216 "   nop\n\t"
    217 "   .previous\n"
    218 );
    219 
    220 #undef __NR_CLONE
    221 #undef __NR_EXIT
    222 
    223 // forward declarations
    224 
    225 static void setup_child (ThreadArchState *, ThreadArchState *);
    226 static SysRes sys_set_tls (ThreadId tid, Addr tlsptr);
    227 static SysRes mips_PRE_sys_mmap (ThreadId tid,
    228                                  UWord arg1, UWord arg2, UWord arg3,
    229                                  UWord arg4, UWord arg5, Off64T arg6);
    230 /*
    231    When a client clones, we need to keep track of the new thread.  This means:
    232    1. allocate a ThreadId+ThreadState+stack for the the thread
    233    2. initialize the thread's new VCPU state
    234    3. create the thread using the same args as the client requested,
    235    but using the scheduler entrypoint for IP, and a separate stack
    236    for SP.
    237  */
    238 
    239 static SysRes do_clone (ThreadId ptid,
    240                         UInt flags, Addr sp,
    241                         Int * parent_tidptr,
    242                         Int * child_tidptr,
    243                         Addr child_tls)
    244 {
    245    const Bool debug = False;
    246    ThreadId ctid = VG_ (alloc_ThreadState) ();
    247    ThreadState * ptst = VG_ (get_ThreadState) (ptid);
    248    ThreadState * ctst = VG_ (get_ThreadState) (ctid);
    249    UInt ret = 0;
    250    UWord * stack;
    251    NSegment const *seg;
    252    SysRes res;
    253    vki_sigset_t blockall, savedmask;
    254 
    255    VG_ (sigfillset) (&blockall);
    256    vg_assert (VG_ (is_running_thread) (ptid));
    257    vg_assert (VG_ (is_valid_tid) (ctid));
    258    stack = (UWord *) ML_ (allocstack) (ctid);
    259    if (stack == NULL) {
    260       res = VG_ (mk_SysRes_Error) (VKI_ENOMEM);
    261       goto out;
    262    }
    263    setup_child (&ctst->arch, &ptst->arch);
    264 
    265    /* on MIPS we need to set V0 and A3 to zero */
    266    ctst->arch.vex.guest_r2 = 0;
    267    ctst->arch.vex.guest_r7 = 0;
    268    if (sp != 0)
    269       ctst->arch.vex.guest_r29 = sp;
    270 
    271    ctst->os_state.parent = ptid;
    272    ctst->sig_mask = ptst->sig_mask;
    273    ctst->tmp_sig_mask = ptst->sig_mask;
    274 
    275    /* Start the child with its threadgroup being the same as the
    276       parent's.  This is so that any exit_group calls that happen
    277       after the child is created but before it sets its
    278       os_state.threadgroup field for real (in thread_wrapper in
    279       syswrap-linux.c), really kill the new thread.  a.k.a this avoids
    280       a race condition in which the thread is unkillable (via
    281       exit_group) because its threadgroup is not set.  The race window
    282       is probably only a few hundred or a few thousand cycles long.
    283       See #226116. */
    284 
    285    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
    286    seg = VG_ (am_find_nsegment) ((Addr) sp);
    287 
    288    if (seg && seg->kind != SkResvn) {
    289       ctst->client_stack_highest_word = (Addr) VG_PGROUNDUP (sp);
    290       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
    291       VG_ (register_stack) (seg->start, ctst->client_stack_highest_word);
    292       if (debug)
    293          VG_ (printf) ("tid %d: guessed client stack range %#lx-%#lx\n",
    294 
    295       ctid, seg->start, VG_PGROUNDUP (sp));
    296    } else {
    297       VG_ (message) (Vg_UserMsg,
    298                      "!? New thread %d starts with sp+%#lx) unmapped\n",
    299                      ctid, sp);
    300       ctst->client_stack_szB = 0;
    301    }
    302 
    303    VG_TRACK (pre_thread_ll_create, ptid, ctid);
    304    if (flags & VKI_CLONE_SETTLS) {
    305       if (debug)
    306         VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
    307       ctst->arch.vex.guest_r27 = child_tls;
    308       res = sys_set_tls(ctid, child_tls);
    309       if (sr_isError(res))
    310          goto out;
    311       ctst->arch.vex.guest_r27 = child_tls;
    312   }
    313 
    314    flags &= ~VKI_CLONE_SETTLS;
    315    VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
    316    /* Create the new thread */
    317    ret = do_syscall_clone_mips_linux (ML_ (start_thread_NORETURN),
    318                                     stack, flags, &VG_ (threads)[ctid],
    319                                     child_tidptr, parent_tidptr,
    320                                     0 /*child_tls*/);
    321 
    322    /* High half word64 is syscall return value.  Low half is
    323       the entire CR, from which we need to extract CR0.SO. */
    324    if (debug)
    325       VG_(printf)("ret: 0x%x\n", ret);
    326 
    327    res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
    328 
    329    VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL);
    330 
    331    out:
    332    if (sr_isError (res)) {
    333       VG_(cleanup_thread) (&ctst->arch);
    334       ctst->status = VgTs_Empty;
    335       VG_TRACK (pre_thread_ll_exit, ctid);
    336    }
    337    ptst->arch.vex.guest_r2 = 0;
    338 
    339    return res;
    340 }
    341 
    342 /* ---------------------------------------------------------------------
    343    More thread stuff
    344    ------------------------------------------------------------------ */
    345 
    346 // MIPS doesn't have any architecture specific thread stuff that
    347 // needs to be cleaned up da li ????!!!!???
    348 void
    349 VG_ (cleanup_thread) (ThreadArchState * arch) { }
    350 
    351 void
    352 setup_child ( /*OUT*/ ThreadArchState * child,
    353               /*IN*/ ThreadArchState * parent)
    354 {
    355    /* We inherit our parent's guest state. */
    356    child->vex = parent->vex;
    357    child->vex_shadow1 = parent->vex_shadow1;
    358    child->vex_shadow2 = parent->vex_shadow2;
    359 }
    360 
    361 SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
    362 {
    363    VG_(threads)[tid].arch.vex.guest_ULR = tlsptr;
    364    return VG_(mk_SysRes_Success)( 0 );
    365 }
    366 
    367 /* ---------------------------------------------------------------------
    368    mips handler for mmap and mmap2
    369    ------------------------------------------------------------------ */
    370 static void notify_core_of_mmap(Addr a, SizeT len, UInt prot,
    371                                 UInt flags, Int fd, Off64T offset)
    372 {
    373    Bool d;
    374 
    375    /* 'a' is the return value from a real kernel mmap, hence: */
    376    vg_assert(VG_IS_PAGE_ALIGNED(a));
    377    /* whereas len is whatever the syscall supplied.  So: */
    378    len = VG_PGROUNDUP(len);
    379 
    380    d = VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset );
    381 
    382    if (d)
    383       VG_(discard_translations)( (Addr64)a, (ULong)len,
    384                                  "notify_core_of_mmap" );
    385 }
    386 
    387 static void notify_tool_of_mmap(Addr a, SizeT len, UInt prot, ULong di_handle)
    388 {
    389    Bool rr, ww, xx;
    390 
    391    /* 'a' is the return value from a real kernel mmap, hence: */
    392    vg_assert(VG_IS_PAGE_ALIGNED(a));
    393    /* whereas len is whatever the syscall supplied.  So: */
    394    len = VG_PGROUNDUP(len);
    395 
    396    rr = toBool(prot & VKI_PROT_READ);
    397    ww = toBool(prot & VKI_PROT_WRITE);
    398    xx = toBool(prot & VKI_PROT_EXEC);
    399 
    400    VG_TRACK( new_mem_mmap, a, len, rr, ww, xx, di_handle );
    401 }
    402 
    403 /* Based on ML_(generic_PRE_sys_mmap) from syswrap-generic.c.
    404    If we are trying to do mmap with VKI_MAP_SHARED flag we need to align the
    405    start address on VKI_SHMLBA like we did in
    406    VG_(am_mmap_file_float_valgrind_flags)
    407  */
    408 static SysRes mips_PRE_sys_mmap(ThreadId tid,
    409                                 UWord arg1, UWord arg2, UWord arg3,
    410                                 UWord arg4, UWord arg5, Off64T arg6)
    411 {
    412    Addr       advised;
    413    SysRes     sres;
    414    MapRequest mreq;
    415    Bool       mreq_ok;
    416 
    417    if (arg2 == 0) {
    418       /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
    419          shall be established. */
    420       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    421    }
    422 
    423    if (!VG_IS_PAGE_ALIGNED(arg1)) {
    424       /* zap any misaligned addresses. */
    425       /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
    426          to fail.   Here, we catch them all. */
    427       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    428    }
    429 
    430    if (!VG_IS_PAGE_ALIGNED(arg6)) {
    431       /* zap any misaligned offsets. */
    432       /* SuSV3 says: The off argument is constrained to be aligned and
    433          sized according to the value returned by sysconf() when
    434          passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
    435       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    436    }
    437 
    438    /* Figure out what kind of allocation constraints there are
    439       (fixed/hint/any), and ask aspacem what we should do. */
    440    mreq.start = arg1;
    441    mreq.len   = arg2;
    442    if (arg4 & VKI_MAP_FIXED) {
    443       mreq.rkind = MFixed;
    444    } else
    445    if (arg1 != 0) {
    446       mreq.rkind = MHint;
    447    } else {
    448       mreq.rkind = MAny;
    449    }
    450 
    451    if ((VKI_SHMLBA > VKI_PAGE_SIZE) && (VKI_MAP_SHARED & arg4)
    452        && !(VKI_MAP_FIXED & arg4))
    453       mreq.len = arg2 + VKI_SHMLBA - VKI_PAGE_SIZE;
    454 
    455    /* Enquire ... */
    456    advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
    457 
    458    if ((VKI_SHMLBA > VKI_PAGE_SIZE) && (VKI_MAP_SHARED & arg4)
    459        && !(VKI_MAP_FIXED & arg4))
    460       advised = VG_ROUNDUP(advised, VKI_SHMLBA);
    461 
    462    if (!mreq_ok) {
    463       /* Our request was bounced, so we'd better fail. */
    464       return VG_(mk_SysRes_Error)( VKI_EINVAL );
    465    }
    466 
    467    /* Otherwise we're OK (so far).  Install aspacem's choice of
    468       address, and let the mmap go through.  */
    469    sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
    470                                     arg4 | VKI_MAP_FIXED,
    471                                     arg5, arg6);
    472 
    473    /* A refinement: it may be that the kernel refused aspacem's choice
    474       of address.  If we were originally asked for a hinted mapping,
    475       there is still a last chance: try again at any address.
    476       Hence: */
    477    if (mreq.rkind == MHint && sr_isError(sres)) {
    478       mreq.start = 0;
    479       mreq.len   = arg2;
    480       mreq.rkind = MAny;
    481       advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
    482       if (!mreq_ok) {
    483          /* Our request was bounced, so we'd better fail. */
    484          return VG_(mk_SysRes_Error)( VKI_EINVAL );
    485       }
    486       /* and try again with the kernel */
    487       sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
    488                                        arg4 | VKI_MAP_FIXED,
    489                                        arg5, arg6);
    490    }
    491 
    492    if (!sr_isError(sres)) {
    493       ULong di_handle;
    494       /* Notify aspacem. */
    495       notify_core_of_mmap(
    496          (Addr)sr_Res(sres), /* addr kernel actually assigned */
    497          arg2, /* length */
    498          arg3, /* prot */
    499          arg4, /* the original flags value */
    500          arg5, /* fd */
    501          arg6  /* offset */
    502       );
    503       /* Load symbols? */
    504       di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres),
    505                                        False/*allow_SkFileV*/, (Int)arg5 );
    506       /* Notify the tool. */
    507       notify_tool_of_mmap(
    508          (Addr)sr_Res(sres), /* addr kernel actually assigned */
    509          arg2, /* length */
    510          arg3, /* prot */
    511          di_handle /* so the tool can refer to the read debuginfo later,
    512                       if it wants. */
    513       );
    514    }
    515 
    516    /* Stay sane */
    517    if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED))
    518       vg_assert(sr_Res(sres) == arg1);
    519 
    520    return sres;
    521 }
    522 /* ---------------------------------------------------------------------
    523    PRE/POST wrappers for mips/Linux-specific syscalls
    524    ------------------------------------------------------------------ */
    525 #define PRE(name)       DEFN_PRE_TEMPLATE(mips_linux, name)
    526 #define POST(name)      DEFN_POST_TEMPLATE(mips_linux, name)
    527 
    528 /* Add prototypes for the wrappers declared here, so that gcc doesn't
    529    harass us for not having prototypes.  Really this is a kludge --
    530    the right thing to do is to make these wrappers 'static' since they
    531    aren't visible outside this file, but that requires even more macro
    532    magic. */
    533 //DECL_TEMPLATE (mips_linux, sys_syscall);
    534 DECL_TEMPLATE (mips_linux, sys_mmap);
    535 DECL_TEMPLATE (mips_linux, sys_mmap2);
    536 DECL_TEMPLATE (mips_linux, sys_stat64);
    537 DECL_TEMPLATE (mips_linux, sys_lstat64);
    538 DECL_TEMPLATE (mips_linux, sys_fstatat64);
    539 DECL_TEMPLATE (mips_linux, sys_fstat64);
    540 DECL_TEMPLATE (mips_linux, sys_clone);
    541 DECL_TEMPLATE (mips_linux, sys_sigreturn);
    542 DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
    543 DECL_TEMPLATE (mips_linux, sys_cacheflush);
    544 DECL_TEMPLATE (mips_linux, sys_set_thread_area);
    545 DECL_TEMPLATE (mips_linux, sys_pipe);
    546 
    547 PRE(sys_mmap2)
    548 {
    549   /* Exactly like sys_mmap() except the file offset is specified in pagesize
    550      units rather than bytes, so that it can be used for files bigger than
    551      2^32 bytes. */
    552   SysRes r;
    553   PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", ARG1, (ULong) ARG2,
    554                                                         ARG3, ARG4, ARG5, ARG6);
    555   PRE_REG_READ6(long, "mmap2", unsigned long, start, unsigned long, length,
    556                 unsigned long, prot, unsigned long, flags,
    557                 unsigned long, fd, unsigned long, offset);
    558   r = mips_PRE_sys_mmap(tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    559                         VKI_PAGE_SIZE * (Off64T) ARG6);
    560   SET_STATUS_from_SysRes(r);
    561 }
    562 
    563 PRE(sys_mmap)
    564 {
    565   SysRes r;
    566   PRINT("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong) ARG2,
    567                                                        ARG3, ARG4, ARG5, ARG6);
    568   PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length,
    569                 int, prot, int, flags, int, fd, unsigned long, offset);
    570   r = mips_PRE_sys_mmap(tid, ARG1, ARG2, ARG3, ARG4, ARG5, (Off64T) ARG6);
    571   SET_STATUS_from_SysRes(r);
    572 }
    573 
    574 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
    575 // applicable to every architecture -- I think only to 32-bit archs.
    576 // We're going to need something like linux/core_os32.h for such
    577 // things, eventually, I think.  --njn
    578 
    579 PRE (sys_lstat64)
    580 {
    581   PRINT ("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2);
    582   PRE_REG_READ2 (long, "lstat64", char *, file_name, struct stat64 *, buf);
    583   PRE_MEM_RASCIIZ ("lstat64(file_name)", ARG1);
    584   PRE_MEM_WRITE ("lstat64(buf)", ARG2, sizeof (struct vki_stat64));
    585 }
    586 
    587 POST (sys_lstat64)
    588 {
    589   vg_assert (SUCCESS);
    590   if (RES == 0)
    591     {
    592       POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
    593     }
    594 }
    595 
    596 PRE (sys_stat64)
    597 {
    598   PRINT ("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2);
    599   PRE_REG_READ2 (long, "stat64", char *, file_name, struct stat64 *, buf);
    600   PRE_MEM_RASCIIZ ("stat64(file_name)", ARG1);
    601   PRE_MEM_WRITE ("stat64(buf)", ARG2, sizeof (struct vki_stat64));
    602 }
    603 
    604 POST (sys_stat64)
    605 {
    606   POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
    607 }
    608 
    609 PRE (sys_fstatat64)
    610 {
    611   PRINT ("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", ARG1, ARG2, (char *) ARG2,
    612                                                   ARG3);
    613   PRE_REG_READ3 (long, "fstatat64", int, dfd, char *, file_name,
    614                  struct stat64 *, buf);
    615   PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2);
    616   PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64));
    617 }
    618 
    619 POST (sys_fstatat64)
    620 {
    621   POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64));
    622 }
    623 
    624 PRE (sys_fstat64)
    625 {
    626   PRINT ("sys_fstat64 ( %ld, %#lx )", ARG1, ARG2);
    627   PRE_REG_READ2 (long, "fstat64", unsigned long, fd, struct stat64 *, buf);
    628   PRE_MEM_WRITE ("fstat64(buf)", ARG2, sizeof (struct vki_stat64));
    629 }
    630 
    631 POST (sys_fstat64)
    632 {
    633   POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
    634 }
    635 
    636 PRE (sys_clone)
    637   {
    638     Bool badarg = False;
    639     UInt cloneflags;
    640     PRINT ("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
    641                                                         ARG4, ARG5);
    642     PRE_REG_READ2 (int, "clone", unsigned long, flags,  void *, child_stack);
    643     if (ARG1 & VKI_CLONE_PARENT_SETTID)
    644       {
    645         if (VG_ (tdict).track_pre_reg_read)
    646           {
    647             PRA3 ("clone", int *, parent_tidptr);
    648           }
    649         PRE_MEM_WRITE ("clone(parent_tidptr)", ARG3, sizeof (Int));
    650         if (!VG_ (am_is_valid_for_client)(ARG3, sizeof (Int), VKI_PROT_WRITE))
    651         {
    652           badarg = True;
    653         }
    654       }
    655     if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    656       {
    657         if (VG_ (tdict).track_pre_reg_read)
    658           {
    659             PRA5 ("clone", int *, child_tidptr);
    660           }
    661         PRE_MEM_WRITE ("clone(child_tidptr)", ARG5, sizeof (Int));
    662         if (!VG_ (am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
    663           {
    664             badarg = True;
    665           }
    666       }
    667     if (badarg)
    668       {
    669         SET_STATUS_Failure (VKI_EFAULT);
    670         return;
    671       }
    672     cloneflags = ARG1;
    673     if (!ML_ (client_signal_OK) (ARG1 & VKI_CSIGNAL))
    674       {
    675         SET_STATUS_Failure (VKI_EINVAL);
    676         return;
    677       }
    678     /* Only look at the flags we really care about */
    679     switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    680            |VKI_CLONE_FILES | VKI_CLONE_VFORK))
    681       {
    682         case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    683         /* thread creation */
    684         PRINT ("sys_clone1 ( %#lx, %#lx, %#lx, %#lx, %#lx )",
    685                ARG1, ARG2, ARG3, ARG4, ARG5);
    686         SET_STATUS_from_SysRes (do_clone (tid,
    687                                           ARG1, /* flags */
    688                                           (Addr) ARG2, /* child SP */
    689                                           (Int *) ARG3, /* parent_tidptr */
    690                                           (Int *) ARG5, /* child_tidptr */
    691                                           (Addr) ARG4));	/* child_tls */
    692 
    693         break;
    694         case VKI_CLONE_VFORK | VKI_CLONE_VM:	/* vfork */
    695           /* FALLTHROUGH - assume vfork == fork */
    696           cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    697         case 0:  /* plain fork */
    698           SET_STATUS_from_SysRes (ML_ (do_fork_clone) (tid,
    699                                   cloneflags, /* flags */
    700                                   (Int *) ARG3, /* parent_tidptr */
    701                                   (Int *) ARG5));	/* child_tidptr */
    702         break;
    703         default:
    704           /* should we just ENOSYS? */
    705           VG_ (message) (Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
    706           VG_ (message) (Vg_UserMsg, "\n");
    707           VG_ (message) (Vg_UserMsg, "The only supported clone() uses are:\n");
    708           VG_ (message) (Vg_UserMsg,
    709                           " - via a threads library (LinuxThreads or NPTL)\n");
    710           VG_ (message) (Vg_UserMsg,
    711                           " - via the implementation of fork or vfork\n");
    712           VG_ (unimplemented)("Valgrind does not support general clone().");
    713     }
    714     if (SUCCESS)
    715       {
    716         if (ARG1 & VKI_CLONE_PARENT_SETTID)
    717           POST_MEM_WRITE (ARG3, sizeof (Int));
    718         if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    719           POST_MEM_WRITE (ARG5, sizeof (Int));
    720         /* Thread creation was successful; let the child have the chance
    721          * to run */
    722         *flags |= SfYieldAfter;
    723       }
    724 }
    725 
    726 PRE (sys_sigreturn)
    727 {
    728   PRINT ("sys_sigreturn ( )");
    729   vg_assert (VG_ (is_valid_tid) (tid));
    730   vg_assert (tid >= 1 && tid < VG_N_THREADS);
    731   vg_assert (VG_ (is_running_thread) (tid));
    732   VG_ (sigframe_destroy) (tid, False);
    733   /* Tell the driver not to update the guest state with the "result",
    734      and set a bogus result to keep it happy. */
    735   *flags |= SfNoWriteResult;
    736   SET_STATUS_Success (0);
    737    /* Check to see if any signals arose as a result of this. */
    738   *flags |= SfPollAfter;
    739 }
    740 
    741 PRE (sys_rt_sigreturn)
    742 {
    743   PRINT ("rt_sigreturn ( )");
    744   vg_assert (VG_ (is_valid_tid) (tid));
    745   vg_assert (tid >= 1 && tid < VG_N_THREADS);
    746   vg_assert (VG_ (is_running_thread) (tid));
    747   /* Restore register state from frame and remove it */
    748   VG_ (sigframe_destroy) (tid, True);
    749   /* Tell the driver not to update the guest state with the "result",
    750      and set a bogus result to keep it happy. */
    751   *flags |= SfNoWriteResult;
    752   SET_STATUS_Success (0);
    753   /* Check to see if any signals arose as a result of this. */
    754   *flags |= SfPollAfter;
    755 }
    756 
    757 PRE (sys_set_thread_area)
    758 {
    759    PRINT ("set_thread_area (%lx)", ARG1);
    760    PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
    761    SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
    762 }
    763 
    764 /* Very much MIPS specific */
    765 PRE (sys_cacheflush)
    766 {
    767   PRINT ("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3);
    768   PRE_REG_READ3(long, "cacheflush", unsigned long, addr,
    769                 int, nbytes, int, cache);
    770   VG_ (discard_translations) ((Addr64) ARG1, ((ULong) ARG2),
    771                               "PRE(sys_cacheflush)");
    772   SET_STATUS_Success (0);
    773 }
    774 
    775 PRE(sys_pipe)
    776 {
    777    PRINT("sys_pipe ( %#lx )", ARG1);
    778    PRE_REG_READ1(int, "pipe", int *, filedes);
    779    PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
    780 }
    781 
    782 POST(sys_pipe)
    783 {
    784    Int p0, p1;
    785    vg_assert(SUCCESS);
    786    p0 = RES;
    787    p1 = sr_ResEx(status->sres);
    788 
    789    if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
    790        !ML_(fd_allowed)(p1, "pipe", tid, True)) {
    791       VG_(close)(p0);
    792       VG_(close)(p1);
    793       SET_STATUS_Failure( VKI_EMFILE );
    794    } else {
    795       if (VG_(clo_track_fds)) {
    796          ML_(record_fd_open_nameless)(tid, p0);
    797          ML_(record_fd_open_nameless)(tid, p1);
    798       }
    799    }
    800 }
    801 
    802 #undef PRE
    803 #undef POST
    804 
    805 /* ---------------------------------------------------------------------
    806    The mips/Linux syscall table
    807    ------------------------------------------------------------------ */
    808 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(mips_linux, sysno, name)
    809 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(mips_linux, sysno, name)
    810 
    811 // This table maps from __NR_xxx syscall numbers (from
    812 // linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo()
    813 // wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S).
    814 //
    815 
    816 // For those syscalls not handled by Valgrind, the annotation indicate its
    817 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
    818 // (unknown).
    819 
    820 static SyscallTableEntry syscall_main_table[] = {
    821    //..    PLAXY (__NR_syscall,                sys_syscall),            // 0
    822    GENX_ (__NR_exit,                   sys_exit),                    // 1
    823    GENX_ (__NR_fork,                   sys_fork),                    // 2
    824    GENXY (__NR_read,                   sys_read),                    // 3
    825    GENX_ (__NR_write,                  sys_write),                   // 4
    826    GENXY (__NR_open,                   sys_open),                    // 5
    827    GENXY (__NR_close,                  sys_close),                   // 6
    828    GENXY (__NR_waitpid,                sys_waitpid),                 // 7
    829    GENXY (__NR_creat,                  sys_creat),                   // 8
    830    GENX_ (__NR_link,                   sys_link),                    // 9
    831    GENX_ (__NR_unlink,                 sys_unlink),                  // 10
    832    GENX_ (__NR_execve,                 sys_execve),                  // 11
    833    GENX_ (__NR_chdir,                  sys_chdir),                   // 12
    834    GENXY (__NR_time,                   sys_time),                    // 13
    835    GENX_ (__NR_mknod,                  sys_mknod),                   // 14
    836    GENX_ (__NR_chmod,                  sys_chmod),                   // 15
    837    GENX_ (__NR_lchown,                 sys_lchown),                  // 16
    838    //..
    839    LINX_ (__NR_lseek,                  sys_lseek),                   // 19
    840    GENX_ (__NR_getpid,                 sys_getpid),                  // 20
    841    LINX_ (__NR_mount,                  sys_mount),                   // 21
    842    LINX_ (__NR_umount,                 sys_oldumount),               // 22
    843    GENX_ (__NR_setuid,                 sys_setuid),                  // 23
    844    GENX_ (__NR_getuid,                 sys_getuid),                  // 24
    845    LINX_ (__NR_stime,                  sys_stime),                   // 25
    846    //..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
    847    GENX_ (__NR_alarm,                  sys_alarm),                   // 27
    848    //..    //   (__NR_oldfstat,          sys_fstat),  // 28
    849    GENX_ (__NR_pause,                  sys_pause),                   // 29
    850    LINX_ (__NR_utime,                  sys_utime),                   // 30
    851    //..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
    852    //..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
    853    GENX_ (__NR_access,                 sys_access),                  // 33
    854    //..    GENX_(__NR_nice,              sys_nice),              // 34
    855    //..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
    856    //..    GENX_(__NR_sync,              sys_sync),              // 36
    857    GENX_ (__NR_kill,                   sys_kill),                    // 37
    858    GENX_ (__NR_rename,                 sys_rename),                  // 38
    859    GENX_ (__NR_mkdir,                  sys_mkdir),                   // 39
    860    GENX_ (__NR_rmdir,                  sys_rmdir),                   // 40
    861    GENXY (__NR_dup,                    sys_dup),                     // 41
    862    PLAXY (__NR_pipe,                   sys_pipe),                    // 42
    863    GENXY (__NR_times,                  sys_times),                   // 43
    864    //..    GENX_(__NR_prof,              sys_ni_syscall),   // 44
    865    GENX_ (__NR_brk,                    sys_brk),                     // 45
    866    GENX_ (__NR_setgid,                 sys_setgid),                  // 46
    867    GENX_ (__NR_getgid,                 sys_getgid),                  // 47
    868    //..    //   (__NR_signal,            sys_signal),       // 48
    869    GENX_ (__NR_geteuid,                sys_geteuid),                 // 49
    870    GENX_ (__NR_getegid,                sys_getegid),                 // 50
    871    //..    GENX_(__NR_acct,              sys_acct),         // 51
    872    LINX_ (__NR_umount2,                sys_umount),                  // 52
    873    //..    GENX_(__NR_lock,              sys_ni_syscall),   // 53
    874    LINXY (__NR_ioctl,                  sys_ioctl),                   // 54
    875    LINXY (__NR_fcntl,                  sys_fcntl),                   // 55
    876    //..    GENX_(__NR_mpx,               sys_ni_syscall),   // 56
    877    GENX_ (__NR_setpgid,                sys_setpgid),                 // 57
    878    //..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
    879    //..    //   (__NR_oldolduname,       sys_olduname),          // 59
    880    GENX_ (__NR_umask,                  sys_umask),                   // 60
    881    GENX_ (__NR_chroot,                 sys_chroot),                  // 61
    882    //..    //   (__NR_ustat,             sys_ustat)              // 62
    883    GENXY (__NR_dup2,                   sys_dup2),                    // 63
    884    GENX_ (__NR_getppid,                sys_getppid),                 // 64
    885    GENX_ (__NR_getpgrp,                sys_getpgrp),                 // 65
    886    GENX_ (__NR_setsid,                 sys_setsid),                  // 66
    887    LINXY (__NR_sigaction,              sys_sigaction),               // 67
    888    //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68
    889    //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69
    890    GENX_ (__NR_setreuid,               sys_setreuid),                // 70
    891    GENX_ (__NR_setregid,               sys_setregid),                // 71
    892    //   PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
    893    LINXY (__NR_sigpending,             sys_sigpending),              // 73
    894    //..    //   (__NR_sethostname,       sys_sethostname),       // 74
    895    GENX_ (__NR_setrlimit,              sys_setrlimit),               // 75
    896    GENXY (__NR_getrlimit,              sys_getrlimit),               // 76
    897    GENXY (__NR_getrusage,              sys_getrusage),               // 77
    898    GENXY (__NR_gettimeofday,           sys_gettimeofday),            // 78
    899    GENX_ (__NR_settimeofday,           sys_settimeofday),            // 79
    900    GENXY (__NR_getgroups,              sys_getgroups),               // 80
    901    GENX_ (__NR_setgroups,              sys_setgroups),               // 81
    902    //..    PLAX_(__NR_select,            old_select),            // 82
    903    GENX_ (__NR_symlink,                sys_symlink),                 // 83
    904    //..    //   (__NR_oldlstat,          sys_lstat),             // 84
    905    GENX_ (__NR_readlink,               sys_readlink),                // 85
    906    //..    //   (__NR_uselib,            sys_uselib),            // 86
    907    //..    //   (__NR_swapon,            sys_swapon),            // 87
    908    //..    //   (__NR_reboot,            sys_reboot),            // 88
    909    //..    //   (__NR_readdir,           old_readdir),           // 89
    910    PLAX_ (__NR_mmap,                   sys_mmap),                    // 90
    911    GENXY (__NR_munmap,                 sys_munmap),                  // 91
    912    GENX_ (__NR_truncate,               sys_truncate),                // 92
    913    GENX_ (__NR_ftruncate,              sys_ftruncate),               // 93
    914    GENX_ (__NR_fchmod,                 sys_fchmod),                  // 94
    915    GENX_ (__NR_fchown,                 sys_fchown),                  // 95
    916    GENX_ (__NR_getpriority,            sys_getpriority),             // 96
    917    GENX_ (__NR_setpriority,            sys_setpriority),             // 97
    918    //..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
    919    GENXY (__NR_statfs,                 sys_statfs),                  // 99
    920    GENXY (__NR_fstatfs,                sys_fstatfs),                 // 100
    921    //..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
    922    LINXY (__NR_socketcall,             sys_socketcall),              // 102
    923    LINXY (__NR_syslog,                 sys_syslog),                  // 103
    924    GENXY (__NR_setitimer,              sys_setitimer),               // 104
    925    //..    GENXY(__NR_getitimer,         sys_getitimer),         // 105
    926    GENXY (__NR_stat,                   sys_newstat),                 // 106
    927    GENXY (__NR_lstat,                  sys_newlstat),                // 107
    928    GENXY (__NR_fstat,                  sys_newfstat),                // 108
    929    //..    //   (__NR_olduname,          sys_uname),             // 109
    930    //..    GENX_(__NR_iopl,              sys_iopl),              // 110
    931    //..    LINX_(__NR_vhangup,           sys_vhangup),           // 111
    932    //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
    933    //..    //   (__NR_vm86old,           sys_vm86old),           // 113
    934    GENXY (__NR_wait4,                  sys_wait4),                   // 114
    935    //..    //   (__NR_swapoff,           sys_swapoff),           // 115
    936    LINXY (__NR_sysinfo,                sys_sysinfo),                 // 116
    937    LINXY (__NR_ipc,                    sys_ipc),                     // 117
    938    GENX_ (__NR_fsync,                  sys_fsync),                   // 118
    939    PLAX_ (__NR_sigreturn,              sys_sigreturn),               // 119
    940    PLAX_ (__NR_clone,                  sys_clone),                   // 120
    941    //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121
    942    GENXY (__NR_uname,                  sys_newuname),                // 122
    943    //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
    944    //..    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
    945    GENXY (__NR_mprotect,               sys_mprotect),                // 125
    946    LINXY (__NR_sigprocmask,            sys_sigprocmask),             // 126
    947    //..    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
    948    //..    GENX_(__NR_init_module,       sys_init_module),       // 128
    949    //..    //   (__NR_delete_module,     sys_delete_module),     // 129
    950    //..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
    951    //..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
    952    GENX_ (__NR_getpgid,                sys_getpgid),                 // 132
    953    GENX_ (__NR_fchdir,                 sys_fchdir),                  // 133
    954    //..    //   (__NR_bdflush,           sys_bdflush),           // 134
    955    //..    //   (__NR_sysfs,             sys_sysfs),             // 135
    956    LINX_ (__NR_personality,            sys_personality),            // 136
    957    //..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
    958    LINX_ (__NR_setfsuid,               sys_setfsuid),                // 138
    959    LINX_ (__NR_setfsgid,               sys_setfsgid),                // 139
    960    LINXY (__NR__llseek,                sys_llseek),                  // 140
    961    GENXY (__NR_getdents,               sys_getdents),                // 141
    962    GENX_ (__NR__newselect,             sys_select),                  // 142
    963    GENX_ (__NR_flock,                  sys_flock),                   // 143
    964    GENX_ (__NR_msync,                  sys_msync),                   // 144
    965    GENXY (__NR_readv,                  sys_readv),                   // 145
    966    GENX_ (__NR_writev,                 sys_writev),                  // 146
    967    PLAX_ (__NR_cacheflush,             sys_cacheflush),              // 147
    968    GENX_ (__NR_getsid,                 sys_getsid),                  // 151
    969    GENX_ (__NR_fdatasync,              sys_fdatasync),               // 152
    970    LINXY (__NR__sysctl,                sys_sysctl),                  // 153
    971    GENX_ (__NR_mlock,                  sys_mlock),                   // 154
    972    GENX_ (__NR_munlock,                sys_munlock),                 // 155
    973    GENX_ (__NR_mlockall,               sys_mlockall),                // 156
    974    LINX_ (__NR_munlockall,             sys_munlockall),              // 157
    975    //..    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 158
    976    LINXY (__NR_sched_getparam,         sys_sched_getparam),          // 159
    977    LINX_ (__NR_sched_setscheduler,     sys_sched_setscheduler),      // 160
    978    LINX_ (__NR_sched_getscheduler,     sys_sched_getscheduler),      // 161
    979    LINX_ (__NR_sched_yield,            sys_sched_yield),             // 162
    980    LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),  // 163
    981    LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),  // 164
    982    //.. //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 165
    983    GENXY (__NR_nanosleep,              sys_nanosleep),               // 166
    984    GENX_ (__NR_mremap,                 sys_mremap),                  // 167
    985    LINXY (__NR_accept,                 sys_accept),                  // 168
    986    LINX_ (__NR_bind,                   sys_bind),                    // 169
    987    LINX_ (__NR_connect,                sys_connect),                 // 170
    988    LINXY (__NR_getpeername,            sys_getpeername),             // 171
    989    LINXY (__NR_getsockname,            sys_getsockname),             // 172
    990    LINXY (__NR_getsockopt,             sys_getsockopt),              // 173
    991    LINX_ (__NR_listen,                 sys_listen),                  // 174
    992    LINXY (__NR_recv,                   sys_recv),                    // 175
    993    LINXY (__NR_recvfrom,               sys_recvfrom),                // 176
    994    LINXY (__NR_recvmsg,                sys_recvmsg),                 // 177
    995    LINX_ (__NR_send,                   sys_send),                    // 178
    996    LINX_ (__NR_sendmsg,                sys_sendmsg),                 // 179
    997    LINX_ (__NR_sendto,                 sys_sendto),                  // 180
    998    LINX_ (__NR_setsockopt,             sys_setsockopt),              // 181
    999    LINX_ (__NR_shutdown,               sys_shutdown),                // 182
   1000    LINXY (__NR_socket,                 sys_socket),                  // 183
   1001    LINXY (__NR_socketpair,             sys_socketpair),              // 184
   1002    LINX_ (__NR_setresuid,              sys_setresuid),               // 185
   1003    LINXY (__NR_getresuid,              sys_getresuid),               // 186
   1004    //..    GENX_(__NR_query_module,      sys_ni_syscall),        // 187
   1005    GENXY (__NR_poll,                   sys_poll),                    // 188
   1006    //..
   1007    LINX_ (__NR_setresgid,              sys_setresgid),               // 190
   1008    LINXY (__NR_getresgid,              sys_getresgid),               // 191
   1009    LINXY (__NR_prctl,                  sys_prctl),                   // 192
   1010    PLAX_ (__NR_rt_sigreturn,           sys_rt_sigreturn),            // 193
   1011    LINXY (__NR_rt_sigaction,           sys_rt_sigaction),            // 194
   1012    LINXY (__NR_rt_sigprocmask,         sys_rt_sigprocmask),          // 195
   1013    LINXY (__NR_rt_sigpending,          sys_rt_sigpending),           // 196
   1014    LINXY (__NR_rt_sigtimedwait,        sys_rt_sigtimedwait),         // 197
   1015    LINXY (__NR_rt_sigqueueinfo,        sys_rt_sigqueueinfo),         // 198
   1016    LINX_ (__NR_rt_sigsuspend,          sys_rt_sigsuspend),           // 199
   1017    GENXY (__NR_pread64,                sys_pread64),                 // 200
   1018    GENX_ (__NR_pwrite64,               sys_pwrite64),                // 201
   1019    GENX_ (__NR_chown,                  sys_chown),                   // 202
   1020    GENXY (__NR_getcwd,                 sys_getcwd),                  // 203
   1021    LINXY (__NR_capget,                 sys_capget),                  // 204
   1022    //..    LINX_(__NR_capset,            sys_capset),            // 205
   1023    GENXY (__NR_sigaltstack,            sys_sigaltstack),             // 206
   1024    LINXY (__NR_sendfile,               sys_sendfile),                // 207
   1025    //..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 208
   1026    //..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 209
   1027    PLAX_ (__NR_mmap2,                  sys_mmap2),                   // 210
   1028    //   GENX_(__NR_truncate64,        sys_truncate64),        // 211
   1029    GENX_ (__NR_ftruncate64,            sys_ftruncate64),             // 212
   1030    PLAXY (__NR_stat64,                 sys_stat64),                  // 213
   1031    PLAXY (__NR_lstat64,                sys_lstat64),                 // 214
   1032    PLAXY (__NR_fstat64,                sys_fstat64),                 // 215
   1033    //..
   1034    GENXY (__NR_mincore,                sys_mincore),                 // 217
   1035    GENX_ (__NR_madvise,                sys_madvise),                 // 218
   1036    GENXY (__NR_getdents64,             sys_getdents64),              // 219
   1037    LINXY (__NR_fcntl64,                sys_fcntl64),                 // 220
   1038    //..
   1039    LINX_ (__NR_gettid,                 sys_gettid),                  // 222
   1040    //..
   1041    LINXY (__NR_getxattr,               sys_getxattr),                // 227
   1042    LINXY (__NR_lgetxattr,              sys_lgetxattr),               // 228
   1043    LINXY (__NR_fgetxattr,              sys_fgetxattr),               // 229
   1044    LINXY (__NR_listxattr,              sys_listxattr),               // 230
   1045    LINXY (__NR_llistxattr,             sys_llistxattr),              // 231
   1046    LINXY (__NR_flistxattr,             sys_flistxattr),              // 232
   1047    LINX_ (__NR_removexattr,            sys_removexattr),             // 233
   1048    LINX_ (__NR_lremovexattr,           sys_lremovexattr),            // 234
   1049    LINX_ (__NR_fremovexattr,           sys_fremovexattr),            // 235
   1050    //..
   1051    LINXY (__NR_sendfile64,             sys_sendfile64),              // 237
   1052    LINXY (__NR_futex,                  sys_futex),                   // 238
   1053    LINX_ (__NR_sched_setaffinity,      sys_sched_setaffinity),       // 239
   1054    LINXY (__NR_sched_getaffinity,      sys_sched_getaffinity),       // 240
   1055    LINX_ (__NR_io_setup,               sys_io_setup),                // 241
   1056    LINX_ (__NR_io_destroy,             sys_io_destroy),              // 242
   1057    LINXY (__NR_io_getevents,           sys_io_getevents),            // 243
   1058    LINX_ (__NR_io_submit,              sys_io_submit),               // 244
   1059    LINXY (__NR_io_cancel,              sys_io_cancel),               // 245
   1060    LINX_ (__NR_exit_group,             sys_exit_group),              // 246
   1061    //..
   1062    LINXY (__NR_epoll_create,           sys_epoll_create),            // 248
   1063    LINX_ (__NR_epoll_ctl,              sys_epoll_ctl),               // 249
   1064    LINXY (__NR_epoll_wait,             sys_epoll_wait),              // 250
   1065    //..
   1066    LINX_ (__NR_set_tid_address,        sys_set_tid_address),         // 252
   1067    LINX_ (__NR_fadvise64,              sys_fadvise64),               // 254
   1068    GENXY (__NR_statfs64,               sys_statfs64),                // 255
   1069    GENXY (__NR_fstatfs64,              sys_fstatfs64),               // 256
   1070    //..
   1071    LINXY (__NR_timer_create,           sys_timer_create),            // 257
   1072    LINXY (__NR_timer_settime,          sys_timer_settime),           // 258
   1073    LINXY (__NR_timer_gettime,          sys_timer_gettime),           // 259
   1074    LINX_ (__NR_timer_getoverrun,       sys_timer_getoverrun),        // 260
   1075    LINX_ (__NR_timer_delete,           sys_timer_delete),            // 261
   1076    LINX_ (__NR_clock_settime,          sys_clock_settime),           // 262
   1077    LINXY (__NR_clock_gettime,          sys_clock_gettime),           // 263
   1078    LINXY (__NR_clock_getres,           sys_clock_getres),            // 264
   1079    LINXY (__NR_clock_nanosleep,        sys_clock_nanosleep),         // 265
   1080    LINXY (__NR_tgkill,                 sys_tgkill),                  // 266
   1081    //..    GENX_(__NR_utimes,            sys_utimes),            // 267
   1082    LINXY (__NR_get_mempolicy,          sys_get_mempolicy),           // 269
   1083    LINX_ (__NR_set_mempolicy,          sys_set_mempolicy),           // 270
   1084    LINXY (__NR_mq_open,                sys_mq_open),                 // 271
   1085    LINX_ (__NR_mq_unlink,              sys_mq_unlink),               // 272
   1086    LINX_ (__NR_mq_timedsend,           sys_mq_timedsend),            // 273
   1087    LINXY (__NR_mq_timedreceive,        sys_mq_timedreceive),         // 274
   1088    LINX_ (__NR_mq_notify,              sys_mq_notify),               // 275
   1089    LINXY (__NR_mq_getsetattr,          sys_mq_getsetattr),           // 276
   1090    LINX_ (__NR_inotify_init,           sys_inotify_init),            // 275
   1091    LINX_ (__NR_inotify_add_watch,      sys_inotify_add_watch),       // 276
   1092    LINX_ (__NR_inotify_rm_watch,       sys_inotify_rm_watch),        // 277
   1093    //..
   1094    PLAX_ (__NR_set_thread_area,        sys_set_thread_area),         // 283
   1095    //..
   1096    LINXY (__NR_openat,                 sys_openat),                  // 288
   1097    LINX_ (__NR_mkdirat,                sys_mkdirat),                 // 289
   1098    LINX_ (__NR_mknodat,                sys_mknodat),                 // 290
   1099    LINX_ (__NR_fchownat,               sys_fchownat),                // 291
   1100    LINX_ (__NR_futimesat,              sys_futimesat),               // 292
   1101    PLAXY (__NR_fstatat64,              sys_fstatat64),               // 293
   1102    LINX_ (__NR_unlinkat,               sys_unlinkat),                // 294
   1103    LINX_ (__NR_renameat,               sys_renameat),                // 295
   1104    LINX_ (__NR_linkat,                 sys_linkat),                  // 296
   1105    LINX_ (__NR_symlinkat,              sys_symlinkat),               // 297
   1106    LINX_ (__NR_readlinkat,             sys_readlinkat),              // 298
   1107    LINX_ (__NR_fchmodat,               sys_fchmodat),                // 299
   1108    LINX_ (__NR_faccessat,              sys_faccessat),               // 300
   1109    //..
   1110    LINXY (__NR_ppoll,                  sys_ppoll),                   // 302
   1111    //..
   1112    LINX_ (__NR_set_robust_list,        sys_set_robust_list),         // 309
   1113    LINXY (__NR_get_robust_list,        sys_get_robust_list),         // 310
   1114    //..
   1115    LINXY (__NR_epoll_pwait,            sys_epoll_pwait),             // 313
   1116    //..
   1117    LINX_ (__NR_utimensat,              sys_utimensat),               // 316
   1118    //..
   1119    LINX_ (__NR_fallocate,              sys_fallocate),               // 320
   1120    LINXY (__NR_timerfd_create,         sys_timerfd_create),          // 321
   1121    LINXY (__NR_timerfd_gettime,        sys_timerfd_gettime),         // 322
   1122    LINXY (__NR_timerfd_settime,        sys_timerfd_settime),         // 323
   1123    LINXY (__NR_signalfd4,              sys_signalfd4),               // 324
   1124    LINXY (__NR_eventfd2,               sys_eventfd2),                // 325
   1125    //..
   1126    LINXY (__NR_pipe2,                  sys_pipe2),                   // 328
   1127    LINXY (__NR_inotify_init1,          sys_inotify_init1),           // 329
   1128    //..
   1129    LINXY (__NR_prlimit64,              sys_prlimit64),               // 338
   1130    //..
   1131    LINXY (__NR_clock_adjtime,          sys_clock_adjtime),           // 341
   1132    //..
   1133    LINXY (__NR_process_vm_readv,       sys_process_vm_readv),        // 345
   1134    LINX_ (__NR_process_vm_writev,      sys_process_vm_writev)        // 346
   1135 };
   1136 
   1137 SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno)
   1138 {
   1139    const UInt syscall_main_table_size
   1140                = sizeof (syscall_main_table) / sizeof (syscall_main_table[0]);
   1141    /* Is it in the contiguous initial section of the table? */
   1142    if (sysno < syscall_main_table_size) {
   1143       SyscallTableEntry * sys = &syscall_main_table[sysno];
   1144       if (sys->before == NULL)
   1145          return NULL;  /* No entry. */
   1146       else
   1147          return sys;
   1148    }
   1149    /* Can't find a wrapper. */
   1150    return NULL;
   1151 }
   1152 
   1153 #endif // defined(VGP_mips32_linux)
   1154 
   1155 /*--------------------------------------------------------------------*/
   1156 /*--- end                                     syswrap-mips-linux.c ---*/
   1157 /*--------------------------------------------------------------------*/
   1158