Home | History | Annotate | Download | only in m_syswrap
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Platform-specific syscalls stuff.      syswrap-ppc32-linux.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2005-2015 Nicholas Nethercote <njn (at) valgrind.org>
     11    Copyright (C) 2005-2015 Cerion Armour-Brown <cerion (at) open-works.co.uk>
     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_ppc32_linux)
     32 
     33 #include "pub_core_basics.h"
     34 #include "pub_core_vki.h"
     35 #include "pub_core_vkiscnums.h"
     36 #include "pub_core_threadstate.h"
     37 #include "pub_core_aspacemgr.h"
     38 #include "pub_core_debuglog.h"
     39 #include "pub_core_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 
     52 #include "priv_types_n_macros.h"
     53 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
     54 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
     55 #include "priv_syswrap-main.h"
     56 
     57 
     58 /* ---------------------------------------------------------------------
     59    clone() handling
     60    ------------------------------------------------------------------ */
     61 
     62 /* Call f(arg1), but first switch stacks, using 'stack' as the new
     63    stack, and use 'retaddr' as f's return-to address.  Also, clear all
     64    the integer registers before entering f.*/
     65 __attribute__((noreturn))
     66 void ML_(call_on_new_stack_0_1) ( Addr stack,
     67                                   Addr retaddr,
     68                                   void (*f)(Word),
     69                                   Word arg1 );
     70 //    r3 = stack
     71 //    r4 = retaddr
     72 //    r5 = f
     73 //    r6 = arg1
     74 asm(
     75 ".text\n"
     76 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
     77 "vgModuleLocal_call_on_new_stack_0_1:\n"
     78 "   mr    %r1,%r3\n\t"     // stack to %sp
     79 "   mtlr  %r4\n\t"         // retaddr to %lr
     80 "   mtctr %r5\n\t"         // f to count reg
     81 "   mr %r3,%r6\n\t"        // arg1 to %r3
     82 "   li 0,0\n\t"            // zero all GP regs
     83 "   li 4,0\n\t"
     84 "   li 5,0\n\t"
     85 "   li 6,0\n\t"
     86 "   li 7,0\n\t"
     87 "   li 8,0\n\t"
     88 "   li 9,0\n\t"
     89 "   li 10,0\n\t"
     90 "   li 11,0\n\t"
     91 "   li 12,0\n\t"
     92 "   li 13,0\n\t"
     93 "   li 14,0\n\t"
     94 "   li 15,0\n\t"
     95 "   li 16,0\n\t"
     96 "   li 17,0\n\t"
     97 "   li 18,0\n\t"
     98 "   li 19,0\n\t"
     99 "   li 20,0\n\t"
    100 "   li 21,0\n\t"
    101 "   li 22,0\n\t"
    102 "   li 23,0\n\t"
    103 "   li 24,0\n\t"
    104 "   li 25,0\n\t"
    105 "   li 26,0\n\t"
    106 "   li 27,0\n\t"
    107 "   li 28,0\n\t"
    108 "   li 29,0\n\t"
    109 "   li 30,0\n\t"
    110 "   li 31,0\n\t"
    111 "   mtxer 0\n\t"           // CAB: Need this?
    112 "   mtcr 0\n\t"            // CAB: Need this?
    113 "   bctr\n\t"              // jump to dst
    114 "   trap\n"                // should never get here
    115 ".previous\n"
    116 );
    117 
    118 
    119 /*
    120         Perform a clone system call.  clone is strange because it has
    121         fork()-like return-twice semantics, so it needs special
    122         handling here.
    123 
    124         Upon entry, we have:
    125 
    126             int (fn)(void*)     in r3
    127             void* child_stack   in r4
    128             int flags           in r5
    129             void* arg           in r6
    130             pid_t* child_tid    in r7
    131             pid_t* parent_tid   in r8
    132             void* ???           in r9
    133 
    134         System call requires:
    135 
    136             int    $__NR_clone  in r0  (sc number)
    137             int    flags        in r3  (sc arg1)
    138             void*  child_stack  in r4  (sc arg2)
    139             pid_t* parent_tid   in r5  (sc arg3)
    140             ??     child_tls    in r6  (sc arg4)
    141             pid_t* child_tid    in r7  (sc arg5)
    142             void*  ???          in r8  (sc arg6)
    143 
    144         Returns an Int encoded in the linux-ppc32 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 ULong do_syscall_clone_ppc32_linux ( Word (*fn)(void *),
    151                                      void* stack,
    152                                      Int   flags,
    153                                      void* arg,
    154                                      Int*  child_tid,
    155                                      Int*  parent_tid,
    156                                      vki_modify_ldt_t * );
    157 asm(
    158 ".text\n"
    159 ".globl do_syscall_clone_ppc32_linux\n"
    160 "do_syscall_clone_ppc32_linux:\n"
    161 "       stwu    1,-32(1)\n"
    162 "       stw     29,20(1)\n"
    163 "       stw     30,24(1)\n"
    164 "       stw     31,28(1)\n"
    165 "       mr      30,3\n"              // preserve fn
    166 "       mr      31,6\n"              // preserve arg
    167 
    168         // setup child stack
    169 "       rlwinm  4,4,0,~0xf\n"        // trim sp to multiple of 16 bytes
    170 "       li      0,0\n"
    171 "       stwu    0,-16(4)\n"          // make initial stack frame
    172 "       mr      29,4\n"              // preserve sp
    173 
    174         // setup syscall
    175 "       li      0,"__NR_CLONE"\n"    // syscall number
    176 "       mr      3,5\n"               // syscall arg1: flags
    177         // r4 already setup          // syscall arg2: child_stack
    178 "       mr      5,8\n"               // syscall arg3: parent_tid
    179 "       mr      6,2\n"               // syscall arg4: REAL THREAD tls
    180 "       mr      7,7\n"               // syscall arg5: child_tid
    181 "       mr      8,8\n"               // syscall arg6: ????
    182 "       mr      9,9\n"               // syscall arg7: ????
    183 
    184 "       sc\n"                        // clone()
    185 
    186 "       mfcr    4\n"                 // return CR in r4 (low word of ULong)
    187 "       cmpwi   3,0\n"               // child if retval == 0
    188 "       bne     1f\n"                // jump if !child
    189 
    190         /* CHILD - call thread function */
    191         /* Note: 2.4 kernel doesn't set the child stack pointer,
    192            so we do it here.
    193            That does leave a small window for a signal to be delivered
    194            on the wrong stack, unfortunately. */
    195 "       mr      1,29\n"
    196 "       mtctr   30\n"                // ctr reg = fn
    197 "       mr      3,31\n"              // r3 = arg
    198 "       bctrl\n"                     // call fn()
    199 
    200         // exit with result
    201 "       li      0,"__NR_EXIT"\n"
    202 "       sc\n"
    203 
    204         // Exit returned?!
    205 "       .long   0\n"
    206 
    207         // PARENT or ERROR - return
    208 "1:     lwz     29,20(1)\n"
    209 "       lwz     30,24(1)\n"
    210 "       lwz     31,28(1)\n"
    211 "       addi    1,1,32\n"
    212 "       blr\n"
    213 ".previous\n"
    214 );
    215 
    216 #undef __NR_CLONE
    217 #undef __NR_EXIT
    218 
    219 // forward declarations
    220 static void setup_child ( ThreadArchState*, ThreadArchState* );
    221 
    222 /*
    223    When a client clones, we need to keep track of the new thread.  This means:
    224    1. allocate a ThreadId+ThreadState+stack for the thread
    225 
    226    2. initialize the thread's new VCPU state
    227 
    228    3. create the thread using the same args as the client requested,
    229    but using the scheduler entrypoint for IP, and a separate stack
    230    for SP.
    231  */
    232 static SysRes do_clone ( ThreadId ptid,
    233                          UInt flags, Addr sp,
    234                          Int *parent_tidptr,
    235                          Int *child_tidptr,
    236                          Addr child_tls)
    237 {
    238    const Bool debug = False;
    239 
    240    ThreadId     ctid = VG_(alloc_ThreadState)();
    241    ThreadState* ptst = VG_(get_ThreadState)(ptid);
    242    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    243    ULong        word64;
    244    UWord*       stack;
    245    SysRes       res;
    246    vki_sigset_t blockall, savedmask;
    247 
    248    VG_(sigfillset)(&blockall);
    249 
    250    vg_assert(VG_(is_running_thread)(ptid));
    251    vg_assert(VG_(is_valid_tid)(ctid));
    252 
    253    stack = (UWord*)ML_(allocstack)(ctid);
    254    if (stack == NULL) {
    255       res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
    256       goto out;
    257    }
    258 
    259 //?   /* make a stack frame */
    260 //?   stack -= 16;
    261 //?   *(UWord *)stack = 0;
    262 
    263 
    264    /* Copy register state
    265 
    266       Both parent and child return to the same place, and the code
    267       following the clone syscall works out which is which, so we
    268       don't need to worry about it.
    269 
    270       The parent gets the child's new tid returned from clone, but the
    271       child gets 0.
    272 
    273       If the clone call specifies a NULL SP for the new thread, then
    274       it actually gets a copy of the parent's SP.
    275 
    276       The child's TLS register (r2) gets set to the tlsaddr argument
    277       if the CLONE_SETTLS flag is set.
    278    */
    279    setup_child( &ctst->arch, &ptst->arch );
    280 
    281    /* Make sys_clone appear to have returned Success(0) in the
    282       child. */
    283    { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
    284      /* %r3 = 0 */
    285      ctst->arch.vex.guest_GPR3 = 0;
    286      /* %cr0.so = 0 */
    287      LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
    288    }
    289 
    290    if (sp != 0)
    291       ctst->arch.vex.guest_GPR1 = sp;
    292 
    293    ctst->os_state.parent = ptid;
    294 
    295    /* inherit signal mask */
    296    ctst->sig_mask = ptst->sig_mask;
    297    ctst->tmp_sig_mask = ptst->sig_mask;
    298 
    299    /* Start the child with its threadgroup being the same as the
    300       parent's.  This is so that any exit_group calls that happen
    301       after the child is created but before it sets its
    302       os_state.threadgroup field for real (in thread_wrapper in
    303       syswrap-linux.c), really kill the new thread.  a.k.a this avoids
    304       a race condition in which the thread is unkillable (via
    305       exit_group) because its threadgroup is not set.  The race window
    306       is probably only a few hundred or a few thousand cycles long.
    307       See #226116. */
    308    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
    309 
    310    ML_(guess_and_register_stack) (sp, ctst);
    311 
    312    /* Assume the clone will succeed, and tell any tool that wants to
    313       know that this thread has come into existence.  If the clone
    314       fails, we'll send out a ll_exit notification for it at the out:
    315       label below, to clean up. */
    316    vg_assert(VG_(owns_BigLock_LL)(ptid));
    317    VG_TRACK ( pre_thread_ll_create, ptid, ctid );
    318 
    319    if (flags & VKI_CLONE_SETTLS) {
    320       if (debug)
    321          VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
    322       ctst->arch.vex.guest_GPR2 = child_tls;
    323    }
    324 
    325    flags &= ~VKI_CLONE_SETTLS;
    326 
    327    /* start the thread with everything blocked */
    328    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
    329 
    330    /* Create the new thread */
    331    word64 = do_syscall_clone_ppc32_linux(
    332                ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
    333                child_tidptr, parent_tidptr, NULL
    334             );
    335    /* High half word64 is syscall return value.  Low half is
    336       the entire CR, from which we need to extract CR0.SO. */
    337    /* VG_(printf)("word64 = 0x%llx\n", word64); */
    338    res = VG_(mk_SysRes_ppc32_linux)(
    339             /*val*/(UInt)(word64 >> 32),
    340             /*errflag*/ (((UInt)word64) >> 28) & 1
    341          );
    342 
    343    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
    344 
    345   out:
    346    if (sr_isError(res)) {
    347       /* clone failed */
    348       VG_(cleanup_thread)(&ctst->arch);
    349       ctst->status = VgTs_Empty;
    350       /* oops.  Better tell the tool the thread exited in a hurry :-) */
    351       VG_TRACK( pre_thread_ll_exit, ctid );
    352    }
    353 
    354    return res;
    355 }
    356 
    357 
    358 
    359 /* ---------------------------------------------------------------------
    360    More thread stuff
    361    ------------------------------------------------------------------ */
    362 
    363 void VG_(cleanup_thread) ( ThreadArchState* arch )
    364 {
    365 }
    366 
    367 void setup_child ( /*OUT*/ ThreadArchState *child,
    368                    /*IN*/  ThreadArchState *parent )
    369 {
    370    /* We inherit our parent's guest state. */
    371    child->vex = parent->vex;
    372    child->vex_shadow1 = parent->vex_shadow1;
    373    child->vex_shadow2 = parent->vex_shadow2;
    374 }
    375 
    376 
    377 /* ---------------------------------------------------------------------
    378    PRE/POST wrappers for ppc32/Linux-specific syscalls
    379    ------------------------------------------------------------------ */
    380 
    381 #define PRE(name)       DEFN_PRE_TEMPLATE(ppc32_linux, name)
    382 #define POST(name)      DEFN_POST_TEMPLATE(ppc32_linux, name)
    383 
    384 /* Add prototypes for the wrappers declared here, so that gcc doesn't
    385    harass us for not having prototypes.  Really this is a kludge --
    386    the right thing to do is to make these wrappers 'static' since they
    387    aren't visible outside this file, but that requires even more macro
    388    magic. */
    389 
    390 DECL_TEMPLATE(ppc32_linux, sys_mmap);
    391 DECL_TEMPLATE(ppc32_linux, sys_mmap2);
    392 DECL_TEMPLATE(ppc32_linux, sys_stat64);
    393 DECL_TEMPLATE(ppc32_linux, sys_lstat64);
    394 DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
    395 DECL_TEMPLATE(ppc32_linux, sys_fstat64);
    396 DECL_TEMPLATE(ppc32_linux, sys_clone);
    397 DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
    398 DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
    399 DECL_TEMPLATE(ppc32_linux, sys_sigsuspend);
    400 DECL_TEMPLATE(ppc32_linux, sys_spu_create);
    401 DECL_TEMPLATE(ppc32_linux, sys_spu_run);
    402 
    403 PRE(sys_mmap)
    404 {
    405    SysRes r;
    406 
    407    PRINT("sys_mmap ( %#lx, %lu, %lu, %lu, %lu, %lu )",
    408          ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
    409    PRE_REG_READ6(long, "mmap",
    410                  unsigned long, start, unsigned long, length,
    411                  unsigned long, prot,  unsigned long, flags,
    412                  unsigned long, fd,    unsigned long, offset);
    413 
    414    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    415                                        (Off64T)ARG6 );
    416    SET_STATUS_from_SysRes(r);
    417 }
    418 
    419 PRE(sys_mmap2)
    420 {
    421    SysRes r;
    422 
    423    // Exactly like old_mmap() except:
    424    //  - the file offset is specified in 4K units rather than bytes,
    425    //    so that it can be used for files bigger than 2^32 bytes.
    426    PRINT("sys_mmap2 ( %#lx, %lu, %lu, %lu, %lu, %lu )",
    427          ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
    428    PRE_REG_READ6(long, "mmap2",
    429                  unsigned long, start, unsigned long, length,
    430                  unsigned long, prot,  unsigned long, flags,
    431                  unsigned long, fd,    unsigned long, offset);
    432 
    433    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    434                                        4096 * (Off64T)ARG6 );
    435    SET_STATUS_from_SysRes(r);
    436 }
    437 
    438 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
    439 // applicable to every architecture -- I think only to 32-bit archs.
    440 // We're going to need something like linux/core_os32.h for such
    441 // things, eventually, I think.  --njn
    442 PRE(sys_stat64)
    443 {
    444    PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2);
    445    PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
    446    PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
    447    PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
    448 }
    449 
    450 POST(sys_stat64)
    451 {
    452    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    453 }
    454 
    455 PRE(sys_lstat64)
    456 {
    457    PRINT("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (HChar*)ARG1, ARG2);
    458    PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
    459    PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
    460    PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
    461 }
    462 
    463 POST(sys_lstat64)
    464 {
    465    vg_assert(SUCCESS);
    466    if (RES == 0) {
    467       POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    468    }
    469 }
    470 
    471 PRE(sys_fstatat64)
    472 {
    473    PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", SARG1, ARG2, (HChar*)ARG2,
    474          ARG3);
    475    PRE_REG_READ3(long, "fstatat64",
    476                  int, dfd, char *, file_name, struct stat64 *, buf);
    477    PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
    478    PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
    479 }
    480 
    481 POST(sys_fstatat64)
    482 {
    483    POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
    484 }
    485 
    486 PRE(sys_fstat64)
    487 {
    488   PRINT("sys_fstat64 ( %lu, %#lx )", ARG1, ARG2);
    489   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
    490   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
    491 }
    492 
    493 POST(sys_fstat64)
    494 {
    495   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    496 }
    497 
    498 
    499 
    500 //.. PRE(old_select, MayBlock)
    501 //.. {
    502 //..    /* struct sel_arg_struct {
    503 //..       unsigned long n;
    504 //..       fd_set *inp, *outp, *exp;
    505 //..       struct timeval *tvp;
    506 //..       };
    507 //..    */
    508 //..    PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
    509 //..    PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
    510 //..
    511 //..    {
    512 //..       UInt* arg_struct = (UInt*)ARG1;
    513 //..       UInt a1, a2, a3, a4, a5;
    514 //..
    515 //..       a1 = arg_struct[0];
    516 //..       a2 = arg_struct[1];
    517 //..       a3 = arg_struct[2];
    518 //..       a4 = arg_struct[3];
    519 //..       a5 = arg_struct[4];
    520 //..
    521 //..       PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
    522 //..       if (a2 != (Addr)NULL)
    523 //.. 	 PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
    524 //..       if (a3 != (Addr)NULL)
    525 //.. 	 PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
    526 //..       if (a4 != (Addr)NULL)
    527 //.. 	 PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
    528 //..       if (a5 != (Addr)NULL)
    529 //.. 	 PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
    530 //..    }
    531 //.. }
    532 
    533 PRE(sys_clone)
    534 {
    535    UInt cloneflags;
    536 
    537    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
    538    PRE_REG_READ5(int, "clone",
    539                  unsigned long, flags,
    540                  void *,        child_stack,
    541                  int *,         parent_tidptr,
    542                  void *,        child_tls,
    543                  int *,         child_tidptr);
    544 
    545    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    546       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    547       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
    548                                              VKI_PROT_WRITE)) {
    549          SET_STATUS_Failure( VKI_EFAULT );
    550          return;
    551       }
    552    }
    553    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    554       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
    555       if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
    556                                              VKI_PROT_WRITE)) {
    557          SET_STATUS_Failure( VKI_EFAULT );
    558          return;
    559       }
    560    }
    561 
    562    cloneflags = ARG1;
    563 
    564    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
    565       SET_STATUS_Failure( VKI_EINVAL );
    566       return;
    567    }
    568 
    569    /* Only look at the flags we really care about */
    570    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    571                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    572    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    573       /* thread creation */
    574       SET_STATUS_from_SysRes(
    575          do_clone(tid,
    576                   ARG1,         /* flags */
    577                   (Addr)ARG2,   /* child SP */
    578                   (Int *)ARG3,  /* parent_tidptr */
    579                   (Int *)ARG5,  /* child_tidptr */
    580                   (Addr)ARG4)); /* child_tls */
    581       break;
    582 
    583    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
    584       /* FALLTHROUGH - assume vfork == fork */
    585       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    586 
    587    case 0: /* plain fork */
    588       SET_STATUS_from_SysRes(
    589          ML_(do_fork_clone)(tid,
    590                        cloneflags,      /* flags */
    591                        (Int *)ARG3,     /* parent_tidptr */
    592                        (Int *)ARG5));   /* child_tidptr */
    593       break;
    594 
    595    default:
    596       /* should we just ENOSYS? */
    597       VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
    598       VG_(message)(Vg_UserMsg, "\n");
    599       VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
    600       VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
    601       VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
    602       VG_(unimplemented)
    603          ("Valgrind does not support general clone().");
    604    }
    605 
    606    if (SUCCESS) {
    607       if (ARG1 & VKI_CLONE_PARENT_SETTID)
    608          POST_MEM_WRITE(ARG3, sizeof(Int));
    609       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    610          POST_MEM_WRITE(ARG5, sizeof(Int));
    611 
    612       /* Thread creation was successful; let the child have the chance
    613          to run */
    614       *flags |= SfYieldAfter;
    615    }
    616 }
    617 
    618 PRE(sys_sigreturn)
    619 {
    620    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
    621       an explanation of what follows. */
    622 
    623    //ThreadState* tst;
    624    PRINT("sys_sigreturn ( )");
    625 
    626    vg_assert(VG_(is_valid_tid)(tid));
    627    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    628    vg_assert(VG_(is_running_thread)(tid));
    629 
    630    ///* Adjust esp to point to start of frame; skip back up over
    631    //   sigreturn sequence's "popl %eax" and handler ret addr */
    632    //tst = VG_(get_ThreadState)(tid);
    633    //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
    634    // Should we do something equivalent on ppc32?  Who knows.
    635 
    636    ///* This is only so that the EIP is (might be) useful to report if
    637    //   something goes wrong in the sigreturn */
    638    //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    639    // Should we do something equivalent on ppc32?  Who knows.
    640 
    641    /* Restore register state from frame and remove it */
    642    VG_(sigframe_destroy)(tid, False);
    643 
    644    /* Tell the driver not to update the guest state with the "result",
    645       and set a bogus result to keep it happy. */
    646    *flags |= SfNoWriteResult;
    647    SET_STATUS_Success(0);
    648 
    649    /* Check to see if any signals arose as a result of this. */
    650    *flags |= SfPollAfter;
    651 }
    652 
    653 PRE(sys_rt_sigreturn)
    654 {
    655    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
    656       an explanation of what follows. */
    657 
    658    //ThreadState* tst;
    659    PRINT("rt_sigreturn ( )");
    660 
    661    vg_assert(VG_(is_valid_tid)(tid));
    662    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    663    vg_assert(VG_(is_running_thread)(tid));
    664 
    665    ///* Adjust esp to point to start of frame; skip back up over handler
    666    //   ret addr */
    667    //tst = VG_(get_ThreadState)(tid);
    668    //tst->arch.vex.guest_ESP -= sizeof(Addr);
    669    // Should we do something equivalent on ppc32?  Who knows.
    670 
    671    ///* This is only so that the EIP is (might be) useful to report if
    672    //   something goes wrong in the sigreturn */
    673    //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
    674    // Should we do something equivalent on ppc32?  Who knows.
    675 
    676    /* Restore register state from frame and remove it */
    677    VG_(sigframe_destroy)(tid, True);
    678 
    679    /* Tell the driver not to update the guest state with the "result",
    680       and set a bogus result to keep it happy. */
    681    *flags |= SfNoWriteResult;
    682    SET_STATUS_Success(0);
    683 
    684    /* Check to see if any signals arose as a result of this. */
    685    *flags |= SfPollAfter;
    686 }
    687 
    688 
    689 //.. PRE(sys_modify_ldt, Special)
    690 //.. {
    691 //..    PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
    692 //..    PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
    693 //..                  unsigned long, bytecount);
    694 //..
    695 //..    if (ARG1 == 0) {
    696 //..       /* read the LDT into ptr */
    697 //..       PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
    698 //..    }
    699 //..    if (ARG1 == 1 || ARG1 == 0x11) {
    700 //..       /* write the LDT with the entry pointed at by ptr */
    701 //..       PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
    702 //..    }
    703 //..    /* "do" the syscall ourselves; the kernel never sees it */
    704 //..    SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) );
    705 //..
    706 //..    if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
    707 //..       POST_MEM_WRITE( ARG2, RES );
    708 //..    }
    709 //.. }
    710 
    711 //.. PRE(sys_set_thread_area, Special)
    712 //.. {
    713 //..    PRINT("sys_set_thread_area ( %p )", ARG1);
    714 //..    PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
    715 //..    PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
    716 //..
    717 //..    /* "do" the syscall ourselves; the kernel never sees it */
    718 //..    SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) );
    719 //.. }
    720 
    721 //.. PRE(sys_get_thread_area, Special)
    722 //.. {
    723 //..    PRINT("sys_get_thread_area ( %p )", ARG1);
    724 //..    PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
    725 //..    PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
    726 //..
    727 //..    /* "do" the syscall ourselves; the kernel never sees it */
    728 //..    SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) );
    729 //..
    730 //..    if (!VG_(is_kerror)(RES)) {
    731 //..       POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
    732 //..    }
    733 //.. }
    734 
    735 //.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic.
    736 //.. // XXX: Why is the memory pointed to by ARG3 never checked?
    737 //.. PRE(sys_ptrace, 0)
    738 //.. {
    739 //..    PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
    740 //..    PRE_REG_READ4(int, "ptrace",
    741 //..                  long, request, long, pid, long, addr, long, data);
    742 //..    switch (ARG1) {
    743 //..    case VKI_PTRACE_PEEKTEXT:
    744 //..    case VKI_PTRACE_PEEKDATA:
    745 //..    case VKI_PTRACE_PEEKUSR:
    746 //..       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
    747 //.. 		     sizeof (long));
    748 //..       break;
    749 //..    case VKI_PTRACE_GETREGS:
    750 //..       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
    751 //.. 		     sizeof (struct vki_user_regs_struct));
    752 //..       break;
    753 //..    case VKI_PTRACE_GETFPREGS:
    754 //..       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
    755 //.. 		     sizeof (struct vki_user_i387_struct));
    756 //..       break;
    757 //..    case VKI_PTRACE_GETFPXREGS:
    758 //..       PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
    759 //..                      sizeof(struct vki_user_fxsr_struct) );
    760 //..       break;
    761 //..    case VKI_PTRACE_SETREGS:
    762 //..       PRE_MEM_READ( "ptrace(setregs)", ARG4,
    763 //.. 		     sizeof (struct vki_user_regs_struct));
    764 //..       break;
    765 //..    case VKI_PTRACE_SETFPREGS:
    766 //..       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
    767 //.. 		     sizeof (struct vki_user_i387_struct));
    768 //..       break;
    769 //..    case VKI_PTRACE_SETFPXREGS:
    770 //..       PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
    771 //..                      sizeof(struct vki_user_fxsr_struct) );
    772 //..       break;
    773 //..    default:
    774 //..       break;
    775 //..    }
    776 //.. }
    777 
    778 //.. POST(sys_ptrace)
    779 //.. {
    780 //..    switch (ARG1) {
    781 //..    case VKI_PTRACE_PEEKTEXT:
    782 //..    case VKI_PTRACE_PEEKDATA:
    783 //..    case VKI_PTRACE_PEEKUSR:
    784 //..       POST_MEM_WRITE( ARG4, sizeof (long));
    785 //..       break;
    786 //..    case VKI_PTRACE_GETREGS:
    787 //..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
    788 //..       break;
    789 //..    case VKI_PTRACE_GETFPREGS:
    790 //..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
    791 //..       break;
    792 //..    case VKI_PTRACE_GETFPXREGS:
    793 //..       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
    794 //..       break;
    795 //..    default:
    796 //..       break;
    797 //..    }
    798 //.. }
    799 
    800 /* NB: This is an almost identical clone of versions for x86-linux and
    801    arm-linux, which are themselves literally identical. */
    802 PRE(sys_sigsuspend)
    803 {
    804    /* The C library interface to sigsuspend just takes a pointer to
    805       a signal mask but this system call only takes the first word of
    806       the signal mask as an argument so only 32 signals are supported.
    807 
    808       In fact glibc normally uses rt_sigsuspend if it is available as
    809       that takes a pointer to the signal mask so supports more signals.
    810     */
    811    *flags |= SfMayBlock;
    812    PRINT("sys_sigsuspend ( %lu )", ARG1 );
    813    PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask);
    814 }
    815 
    816 PRE(sys_spu_create)
    817 {
    818    PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
    819 }
    820 POST(sys_spu_create)
    821 {
    822    vg_assert(SUCCESS);
    823 }
    824 
    825 PRE(sys_spu_run)
    826 {
    827    *flags |= SfMayBlock;
    828    if (ARG2 != 0)
    829       PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int));
    830    PRE_MEM_READ("event", ARG3, sizeof(unsigned int));
    831 }
    832 POST(sys_spu_run)
    833 {
    834    if (ARG2 != 0)
    835       POST_MEM_WRITE(ARG2, sizeof(unsigned int));
    836 }
    837 
    838 #undef PRE
    839 #undef POST
    840 
    841 /* ---------------------------------------------------------------------
    842    The ppc32/Linux syscall table
    843    ------------------------------------------------------------------ */
    844 
    845 /* Add an ppc32-linux specific wrapper to a syscall table. */
    846 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(ppc32_linux, sysno, name)
    847 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(ppc32_linux, sysno, name)
    848 
    849 // This table maps from __NR_xxx syscall numbers (from
    850 // linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
    851 // wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
    852 //
    853 // For those syscalls not handled by Valgrind, the annotation indicate its
    854 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
    855 // (unknown).
    856 
    857 static SyscallTableEntry syscall_table[] = {
    858 //..   (restart_syscall)                                      // 0
    859    GENX_(__NR_exit,              sys_exit),              // 1
    860    GENX_(__NR_fork,              sys_fork),              // 2
    861    GENXY(__NR_read,              sys_read),              // 3
    862    GENX_(__NR_write,             sys_write),             // 4
    863 
    864    GENXY(__NR_open,              sys_open),              // 5
    865    GENXY(__NR_close,             sys_close),             // 6
    866    GENXY(__NR_waitpid,           sys_waitpid),           // 7
    867    GENXY(__NR_creat,             sys_creat),             // 8
    868    GENX_(__NR_link,              sys_link),              // 9
    869 
    870    GENX_(__NR_unlink,            sys_unlink),            // 10
    871    GENX_(__NR_execve,            sys_execve),            // 11
    872    GENX_(__NR_chdir,             sys_chdir),             // 12
    873    GENXY(__NR_time,              sys_time),              // 13
    874    GENX_(__NR_mknod,             sys_mknod),             // 14
    875 //..
    876    GENX_(__NR_chmod,             sys_chmod),             // 15
    877    GENX_(__NR_lchown,            sys_lchown),          // 16 ## P
    878 //..    GENX_(__NR_break,             sys_ni_syscall),        // 17
    879 //..    //   (__NR_oldstat,           sys_stat),              // 18 (obsolete)
    880    LINX_(__NR_lseek,             sys_lseek),             // 19
    881 //..
    882    GENX_(__NR_getpid,            sys_getpid),            // 20
    883    LINX_(__NR_mount,             sys_mount),             // 21
    884    LINX_(__NR_umount,            sys_oldumount),         // 22
    885    GENX_(__NR_setuid,            sys_setuid),            // 23 ## P
    886    GENX_(__NR_getuid,            sys_getuid),            // 24 ## P
    887 //..
    888 //..    //   (__NR_stime,             sys_stime),             // 25 * (SVr4,SVID,X/OPEN)
    889 //..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
    890    GENX_(__NR_alarm,             sys_alarm),             // 27
    891 //..    //   (__NR_oldfstat,          sys_fstat),             // 28 * L -- obsolete
    892    GENX_(__NR_pause,             sys_pause),             // 29
    893 //..
    894    LINX_(__NR_utime,             sys_utime),                  // 30
    895 //..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
    896 //..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
    897    GENX_(__NR_access,            sys_access),            // 33
    898 //..    GENX_(__NR_nice,              sys_nice),              // 34
    899 //..
    900 //..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
    901    GENX_(__NR_sync,              sys_sync),              // 36
    902    GENX_(__NR_kill,              sys_kill),              // 37
    903    GENX_(__NR_rename,            sys_rename),            // 38
    904    GENX_(__NR_mkdir,             sys_mkdir),             // 39
    905 
    906    GENX_(__NR_rmdir,             sys_rmdir),             // 40
    907    GENXY(__NR_dup,               sys_dup),               // 41
    908    LINXY(__NR_pipe,              sys_pipe),              // 42
    909    GENXY(__NR_times,             sys_times),             // 43
    910 //..    GENX_(__NR_prof,              sys_ni_syscall),        // 44
    911 //..
    912    GENX_(__NR_brk,               sys_brk),               // 45
    913    GENX_(__NR_setgid,            sys_setgid),            // 46
    914    GENX_(__NR_getgid,            sys_getgid),            // 47
    915 //..    //   (__NR_signal,            sys_signal),            // 48 */* (ANSI C)
    916    GENX_(__NR_geteuid,           sys_geteuid),           // 49
    917 
    918    GENX_(__NR_getegid,           sys_getegid),           // 50
    919 //..    GENX_(__NR_acct,              sys_acct),              // 51
    920    LINX_(__NR_umount2,           sys_umount),            // 52
    921 //..    GENX_(__NR_lock,              sys_ni_syscall),        // 53
    922    LINXY(__NR_ioctl,             sys_ioctl),             // 54
    923 //..
    924    LINXY(__NR_fcntl,             sys_fcntl),             // 55
    925 //..    GENX_(__NR_mpx,               sys_ni_syscall),        // 56
    926    GENX_(__NR_setpgid,           sys_setpgid),           // 57
    927 //..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
    928 //..    //   (__NR_oldolduname,       sys_olduname),          // 59 Linux -- obsolete
    929 
    930    GENX_(__NR_umask,             sys_umask),             // 60
    931    GENX_(__NR_chroot,            sys_chroot),            // 61
    932 //..    //   (__NR_ustat,             sys_ustat)              // 62 SVr4 -- deprecated
    933    GENXY(__NR_dup2,              sys_dup2),              // 63
    934    GENX_(__NR_getppid,           sys_getppid),           // 64
    935 
    936    GENX_(__NR_getpgrp,           sys_getpgrp),           // 65
    937    GENX_(__NR_setsid,            sys_setsid),            // 66
    938    LINXY(__NR_sigaction,         sys_sigaction),         // 67
    939 //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68 */* (ANSI C)
    940 //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69 */* (ANSI C)
    941 //..
    942    GENX_(__NR_setreuid,          sys_setreuid),          // 70
    943    GENX_(__NR_setregid,          sys_setregid),          // 71
    944    PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
    945    LINXY(__NR_sigpending,        sys_sigpending),        // 73
    946 //..    //   (__NR_sethostname,       sys_sethostname),       // 74 */*
    947 //..
    948    GENX_(__NR_setrlimit,         sys_setrlimit),              // 75
    949 //..    GENXY(__NR_getrlimit,         sys_old_getrlimit),     // 76
    950    GENXY(__NR_getrusage,         sys_getrusage),         // 77
    951    GENXY(__NR_gettimeofday,      sys_gettimeofday),           // 78
    952 //..    GENX_(__NR_settimeofday,      sys_settimeofday),      // 79
    953 //..
    954    GENXY(__NR_getgroups,         sys_getgroups),         // 80
    955    GENX_(__NR_setgroups,         sys_setgroups),         // 81
    956 //..    PLAX_(__NR_select,            old_select),            // 82
    957    GENX_(__NR_symlink,           sys_symlink),           // 83
    958 //..    //   (__NR_oldlstat,          sys_lstat),             // 84 -- obsolete
    959 //..
    960    GENX_(__NR_readlink,          sys_readlink),          // 85
    961 //..    //   (__NR_uselib,            sys_uselib),            // 86 */Linux
    962 //..    //   (__NR_swapon,            sys_swapon),            // 87 */Linux
    963 //..    //   (__NR_reboot,            sys_reboot),            // 88 */Linux
    964 //..    //   (__NR_readdir,           old_readdir),           // 89 -- superseded
    965 
    966    PLAX_(__NR_mmap,              sys_mmap),                   // 90
    967    GENXY(__NR_munmap,            sys_munmap),                 // 91
    968    GENX_(__NR_truncate,          sys_truncate),          // 92
    969    GENX_(__NR_ftruncate,         sys_ftruncate),         // 93
    970    GENX_(__NR_fchmod,            sys_fchmod),            // 94
    971 
    972    GENX_(__NR_fchown,            sys_fchown),            // 95
    973    GENX_(__NR_getpriority,       sys_getpriority),       // 96
    974    GENX_(__NR_setpriority,       sys_setpriority),       // 97
    975 //..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
    976    GENXY(__NR_statfs,            sys_statfs),            // 99
    977 //..
    978    GENXY(__NR_fstatfs,           sys_fstatfs),           // 100
    979 //..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
    980    LINXY(__NR_socketcall,        sys_socketcall),        // 102
    981    LINXY(__NR_syslog,            sys_syslog),            // 103
    982    GENXY(__NR_setitimer,         sys_setitimer),         // 104
    983 
    984    GENXY(__NR_getitimer,         sys_getitimer),         // 105
    985    GENXY(__NR_stat,              sys_newstat),           // 106
    986    GENXY(__NR_lstat,             sys_newlstat),          // 107
    987    GENXY(__NR_fstat,             sys_newfstat),          // 108
    988 //..    //   (__NR_olduname,          sys_uname),             // 109 -- obsolete
    989 //..
    990 //..    GENX_(__NR_iopl,              sys_iopl),              // 110
    991    LINX_(__NR_vhangup,           sys_vhangup),           // 111
    992 //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
    993 //..    //   (__NR_vm86old,           sys_vm86old),           // 113 x86/Linux-only
    994    GENXY(__NR_wait4,             sys_wait4),             // 114
    995 //..
    996 //..    //   (__NR_swapoff,           sys_swapoff),           // 115 */Linux
    997    LINXY(__NR_sysinfo,           sys_sysinfo),           // 116
    998    LINXY(__NR_ipc,               sys_ipc),               // 117
    999    GENX_(__NR_fsync,             sys_fsync),             // 118
   1000    PLAX_(__NR_sigreturn,         sys_sigreturn),         // 119 ?/Linux
   1001 //..
   1002    PLAX_(__NR_clone,             sys_clone),             // 120
   1003 //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121 */*(?)
   1004    GENXY(__NR_uname,             sys_newuname),          // 122
   1005 //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
   1006    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
   1007 
   1008    GENXY(__NR_mprotect,          sys_mprotect),          // 125
   1009    LINXY(__NR_sigprocmask,       sys_sigprocmask),       // 126
   1010    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
   1011    LINX_(__NR_init_module,       sys_init_module),       // 128
   1012    LINX_(__NR_delete_module,     sys_delete_module),     // 129
   1013 //..
   1014 //..    // Nb: get_kernel_syms() was removed 2.4-->2.6
   1015 //..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
   1016 //..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
   1017    GENX_(__NR_getpgid,           sys_getpgid),           // 132
   1018    GENX_(__NR_fchdir,            sys_fchdir),            // 133
   1019 //..    //   (__NR_bdflush,           sys_bdflush),           // 134 */Linux
   1020 //..
   1021 //..    //   (__NR_sysfs,             sys_sysfs),             // 135 SVr4
   1022    LINX_(__NR_personality,       sys_personality),       // 136
   1023 //..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
   1024    LINX_(__NR_setfsuid,          sys_setfsuid),          // 138
   1025    LINX_(__NR_setfsgid,          sys_setfsgid),          // 139
   1026 
   1027    LINXY(__NR__llseek,           sys_llseek),            // 140
   1028    GENXY(__NR_getdents,          sys_getdents),          // 141
   1029    GENX_(__NR__newselect,        sys_select),            // 142
   1030    GENX_(__NR_flock,             sys_flock),             // 143
   1031    GENX_(__NR_msync,             sys_msync),             // 144
   1032 //..
   1033    GENXY(__NR_readv,             sys_readv),             // 145
   1034    GENX_(__NR_writev,            sys_writev),            // 146
   1035    GENX_(__NR_getsid,            sys_getsid),            // 147
   1036    GENX_(__NR_fdatasync,         sys_fdatasync),         // 148
   1037    LINXY(__NR__sysctl,           sys_sysctl),            // 149
   1038 //..
   1039    GENX_(__NR_mlock,             sys_mlock),             // 150
   1040    GENX_(__NR_munlock,           sys_munlock),           // 151
   1041    GENX_(__NR_mlockall,          sys_mlockall),          // 152
   1042    LINX_(__NR_munlockall,        sys_munlockall),        // 153
   1043    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 154
   1044 //..
   1045    LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
   1046    LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
   1047    LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
   1048    LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
   1049    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
   1050 
   1051    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
   1052    LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
   1053    GENXY(__NR_nanosleep,         sys_nanosleep),         // 162
   1054    GENX_(__NR_mremap,            sys_mremap),            // 163
   1055    LINX_(__NR_setresuid,         sys_setresuid),         // 164
   1056 
   1057    LINXY(__NR_getresuid,         sys_getresuid),         // 165
   1058 
   1059 //..    GENX_(__NR_query_module,      sys_ni_syscall),        // 166
   1060    GENXY(__NR_poll,              sys_poll),              // 167
   1061 //..    //   (__NR_nfsservctl,        sys_nfsservctl),        // 168 */Linux
   1062 //..
   1063    LINX_(__NR_setresgid,         sys_setresgid),         // 169
   1064    LINXY(__NR_getresgid,         sys_getresgid),         // 170
   1065    LINXY(__NR_prctl,             sys_prctl),             // 171
   1066    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),      // 172
   1067    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),      // 173
   1068 
   1069    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask),    // 174
   1070    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),     // 175
   1071    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),   // 176
   1072    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),   // 177
   1073    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),     // 178
   1074 
   1075    GENXY(__NR_pread64,           sys_pread64),           // 179
   1076    GENX_(__NR_pwrite64,          sys_pwrite64),          // 180
   1077    GENX_(__NR_chown,             sys_chown),             // 181
   1078    GENXY(__NR_getcwd,            sys_getcwd),            // 182
   1079    LINXY(__NR_capget,            sys_capget),            // 183
   1080    LINX_(__NR_capset,            sys_capset),            // 184
   1081    GENXY(__NR_sigaltstack,       sys_sigaltstack),       // 185
   1082    LINXY(__NR_sendfile,          sys_sendfile),          // 186
   1083 //..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 187
   1084 //..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 188
   1085 
   1086    // Nb: we treat vfork as fork
   1087    GENX_(__NR_vfork,             sys_fork),              // 189
   1088    GENXY(__NR_ugetrlimit,        sys_getrlimit),         // 190
   1089    LINX_(__NR_readahead,         sys_readahead),         // 191 */Linux
   1090    PLAX_(__NR_mmap2,             sys_mmap2),             // 192
   1091    GENX_(__NR_truncate64,        sys_truncate64),        // 193
   1092    GENX_(__NR_ftruncate64,       sys_ftruncate64),       // 194
   1093 //..
   1094 
   1095    PLAXY(__NR_stat64,            sys_stat64),            // 195
   1096    PLAXY(__NR_lstat64,           sys_lstat64),           // 196
   1097    PLAXY(__NR_fstat64,           sys_fstat64),           // 197
   1098 
   1099 // __NR_pciconfig_read                                        // 198
   1100 // __NR_pciconfig_write                                       // 199
   1101 // __NR_pciconfig_iobase                                      // 200
   1102 // __NR_multiplexer                                           // 201
   1103 
   1104    GENXY(__NR_getdents64,        sys_getdents64),        // 202
   1105    LINX_(__NR_pivot_root,        sys_pivot_root),        // 203
   1106    LINXY(__NR_fcntl64,           sys_fcntl64),           // 204
   1107    GENX_(__NR_madvise,           sys_madvise),           // 205
   1108    GENXY(__NR_mincore,           sys_mincore),           // 206
   1109    LINX_(__NR_gettid,            sys_gettid),            // 207
   1110 //..    LINX_(__NR_tkill,             sys_tkill),             // 208 */Linux
   1111    LINX_(__NR_setxattr,          sys_setxattr),          // 209
   1112    LINX_(__NR_lsetxattr,         sys_lsetxattr),         // 210
   1113    LINX_(__NR_fsetxattr,         sys_fsetxattr),         // 211
   1114    LINXY(__NR_getxattr,          sys_getxattr),          // 212
   1115    LINXY(__NR_lgetxattr,         sys_lgetxattr),         // 213
   1116    LINXY(__NR_fgetxattr,         sys_fgetxattr),         // 214
   1117    LINXY(__NR_listxattr,         sys_listxattr),         // 215
   1118    LINXY(__NR_llistxattr,        sys_llistxattr),        // 216
   1119    LINXY(__NR_flistxattr,        sys_flistxattr),        // 217
   1120    LINX_(__NR_removexattr,       sys_removexattr),       // 218
   1121    LINX_(__NR_lremovexattr,      sys_lremovexattr),      // 219
   1122    LINX_(__NR_fremovexattr,      sys_fremovexattr),      // 220
   1123 
   1124    LINXY(__NR_futex,             sys_futex),                  // 221
   1125    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222
   1126    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223
   1127 /* 224 currently unused */
   1128 
   1129 // __NR_tuxcall                                               // 225
   1130 
   1131    LINXY(__NR_sendfile64,        sys_sendfile64),        // 226
   1132 //..
   1133    LINX_(__NR_io_setup,          sys_io_setup),          // 227
   1134    LINX_(__NR_io_destroy,        sys_io_destroy),        // 228
   1135    LINXY(__NR_io_getevents,      sys_io_getevents),      // 229
   1136    LINX_(__NR_io_submit,         sys_io_submit),         // 230
   1137    LINXY(__NR_io_cancel,         sys_io_cancel),         // 231
   1138 //..
   1139    LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 232
   1140 
   1141    LINX_(__NR_fadvise64,         sys_fadvise64),         // 233 */(Linux?)
   1142    LINX_(__NR_exit_group,        sys_exit_group),        // 234
   1143 //..    GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie),    // 235
   1144    LINXY(__NR_epoll_create,      sys_epoll_create),      // 236
   1145    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 237
   1146    LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 238
   1147 
   1148 //..    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 239 */Linux
   1149    LINXY(__NR_timer_create,      sys_timer_create),      // 240
   1150    LINXY(__NR_timer_settime,     sys_timer_settime),     // 241
   1151    LINXY(__NR_timer_gettime,     sys_timer_gettime),     // 242
   1152    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),  // 243
   1153    LINX_(__NR_timer_delete,      sys_timer_delete),      // 244
   1154    LINX_(__NR_clock_settime,     sys_clock_settime),     // 245
   1155    LINXY(__NR_clock_gettime,     sys_clock_gettime),     // 246
   1156    LINXY(__NR_clock_getres,      sys_clock_getres),      // 247
   1157    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),   // 248
   1158 
   1159 // __NR_swapcontext                                           // 249
   1160 
   1161    LINXY(__NR_tgkill,            sys_tgkill),            // 250 */Linux
   1162 //..    GENX_(__NR_utimes,            sys_utimes),            // 251
   1163    GENXY(__NR_statfs64,          sys_statfs64),          // 252
   1164    GENXY(__NR_fstatfs64,         sys_fstatfs64),         // 253
   1165    LINX_(__NR_fadvise64_64,      sys_fadvise64_64),      // 254 */(Linux?)
   1166 
   1167 // __NR_rtas                                                  // 255
   1168 
   1169 /* Number 256 is reserved for sys_debug_setcontext */
   1170 /* Number 257 is reserved for vserver */
   1171 /* Number 258 is reserved for new sys_remap_file_pages */
   1172    LINX_(__NR_mbind,             sys_mbind),             // 259
   1173    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),          // 260
   1174    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),          // 261
   1175 
   1176    LINXY(__NR_mq_open,           sys_mq_open),           // 262
   1177    LINX_(__NR_mq_unlink,         sys_mq_unlink),         // 263
   1178    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),      // 264
   1179    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),   // 265
   1180    LINX_(__NR_mq_notify,         sys_mq_notify),         // 266
   1181    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),     // 267
   1182 // __NR_kexec_load                                            // 268
   1183 
   1184 /* Number 269 is reserved for sys_add_key */
   1185 /* Number 270 is reserved for sys_request_key */
   1186 /* Number 271 is reserved for sys_keyctl */
   1187 /* Number 272 is reserved for sys_waitid */
   1188    LINX_(__NR_ioprio_set,        sys_ioprio_set),         // 273
   1189    LINX_(__NR_ioprio_get,        sys_ioprio_get),         // 274
   1190 
   1191    LINX_(__NR_inotify_init,  sys_inotify_init),               // 275
   1192    LINX_(__NR_inotify_add_watch,  sys_inotify_add_watch),     // 276
   1193    LINX_(__NR_inotify_rm_watch,   sys_inotify_rm_watch),      // 277
   1194    PLAXY(__NR_spu_run,            sys_spu_run),               // 278
   1195    PLAX_(__NR_spu_create,         sys_spu_create),            // 279
   1196 
   1197    LINX_(__NR_pselect6,          sys_pselect6),          // 280
   1198    LINXY(__NR_ppoll,             sys_ppoll),             // 281
   1199 
   1200    LINXY(__NR_openat,            sys_openat),            // 286
   1201    LINX_(__NR_mkdirat,           sys_mkdirat),           // 287
   1202    LINX_(__NR_mknodat,           sys_mknodat),           // 288
   1203    LINX_(__NR_fchownat,          sys_fchownat),          // 289
   1204    LINX_(__NR_futimesat,         sys_futimesat),         // 290
   1205    PLAXY(__NR_fstatat64,         sys_fstatat64),         // 291
   1206    LINX_(__NR_unlinkat,          sys_unlinkat),          // 292
   1207    LINX_(__NR_renameat,          sys_renameat),          // 293
   1208    LINX_(__NR_linkat,            sys_linkat),            // 294
   1209    LINX_(__NR_symlinkat,         sys_symlinkat),         // 295
   1210    LINX_(__NR_readlinkat,        sys_readlinkat),        // 296
   1211    LINX_(__NR_fchmodat,          sys_fchmodat),          // 297
   1212    LINX_(__NR_faccessat,         sys_faccessat),         // 298
   1213    LINX_(__NR_set_robust_list,   sys_set_robust_list),   // 299
   1214    LINXY(__NR_get_robust_list,   sys_get_robust_list),   // 300
   1215    LINXY(__NR_move_pages,        sys_move_pages),        // 301
   1216    LINXY(__NR_getcpu,            sys_getcpu),            // 302
   1217    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
   1218    LINX_(__NR_utimensat,         sys_utimensat),         // 304
   1219    LINXY(__NR_signalfd,          sys_signalfd),          // 305
   1220    LINXY(__NR_timerfd_create,    sys_timerfd_create),    // 306
   1221    LINXY(__NR_eventfd,           sys_eventfd),           // 307
   1222    LINX_(__NR_sync_file_range2,  sys_sync_file_range2),  // 308
   1223    LINX_(__NR_fallocate,         sys_fallocate),         // 309
   1224 //   LINXY(__NR_subpage_prot,       sys_ni_syscall),       // 310
   1225    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 311
   1226    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 312
   1227    LINXY(__NR_signalfd4,         sys_signalfd4),        // 313
   1228    LINXY(__NR_eventfd2,          sys_eventfd2),         // 314
   1229    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
   1230    LINXY(__NR_dup3,              sys_dup3),             // 316
   1231    LINXY(__NR_pipe2,             sys_pipe2),            // 317
   1232    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
   1233    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 319
   1234    LINXY(__NR_preadv,            sys_preadv),           // 320
   1235    LINX_(__NR_pwritev,           sys_pwritev),          // 321
   1236    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322
   1237 
   1238    LINXY(__NR_socket,            sys_socket),           // 326
   1239    LINX_(__NR_bind,              sys_bind),             // 327
   1240    LINX_(__NR_connect,           sys_connect),          // 328
   1241    LINX_(__NR_listen,            sys_listen),           // 329
   1242    LINXY(__NR_accept,            sys_accept),           // 330
   1243    LINXY(__NR_getsockname,       sys_getsockname),      // 331
   1244    LINXY(__NR_getpeername,       sys_getpeername),      // 332
   1245 
   1246    LINX_(__NR_send,              sys_send),             // 334
   1247    LINX_(__NR_sendto,            sys_sendto),           // 335
   1248    LINXY(__NR_recv,              sys_recv),             // 336
   1249    LINXY(__NR_recvfrom,          sys_recvfrom),         // 337
   1250    LINX_(__NR_shutdown,          sys_shutdown),         // 338
   1251    LINX_(__NR_setsockopt,        sys_setsockopt),       // 339
   1252 
   1253    LINXY(__NR_recvmmsg,          sys_recvmmsg),         // 343
   1254    LINXY(__NR_accept4,           sys_accept4),          // 344
   1255 
   1256    LINX_(__NR_clock_adjtime,     sys_clock_adjtime),    // 347
   1257    LINX_(__NR_syncfs,            sys_syncfs),           // 348
   1258    LINXY(__NR_sendmmsg,          sys_sendmmsg),         // 349
   1259 
   1260    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 351
   1261    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352
   1262 
   1263    LINXY(__NR_getrandom,         sys_getrandom),        // 359
   1264    LINXY(__NR_memfd_create,      sys_memfd_create)      // 360
   1265 };
   1266 
   1267 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
   1268 {
   1269    const UInt syscall_table_size
   1270       = sizeof(syscall_table) / sizeof(syscall_table[0]);
   1271 
   1272    /* Is it in the contiguous initial section of the table? */
   1273    if (sysno < syscall_table_size) {
   1274       SyscallTableEntry* sys = &syscall_table[sysno];
   1275       if (sys->before == NULL)
   1276          return NULL; /* no entry */
   1277       else
   1278          return sys;
   1279    }
   1280 
   1281    /* Can't find a wrapper */
   1282    return NULL;
   1283 }
   1284 
   1285 #endif // defined(VGP_ppc32_linux)
   1286 
   1287 /*--------------------------------------------------------------------*/
   1288 /*--- end                                                          ---*/
   1289 /*--------------------------------------------------------------------*/
   1290