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