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-2012 Nicholas Nethercote <njn (at) valgrind.org>
     11    Copyright (C) 2005-2012 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_socketcall);
    414 DECL_TEMPLATE(ppc32_linux, sys_mmap);
    415 DECL_TEMPLATE(ppc32_linux, sys_mmap2);
    416 DECL_TEMPLATE(ppc32_linux, sys_stat64);
    417 DECL_TEMPLATE(ppc32_linux, sys_lstat64);
    418 DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
    419 DECL_TEMPLATE(ppc32_linux, sys_fstat64);
    420 DECL_TEMPLATE(ppc32_linux, sys_ipc);
    421 DECL_TEMPLATE(ppc32_linux, sys_clone);
    422 DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
    423 DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
    424 DECL_TEMPLATE(ppc32_linux, sys_sigsuspend);
    425 DECL_TEMPLATE(ppc32_linux, sys_spu_create);
    426 DECL_TEMPLATE(ppc32_linux, sys_spu_run);
    427 
    428 PRE(sys_socketcall)
    429 {
    430 #  define ARG2_0  (((UWord*)ARG2)[0])
    431 #  define ARG2_1  (((UWord*)ARG2)[1])
    432 #  define ARG2_2  (((UWord*)ARG2)[2])
    433 #  define ARG2_3  (((UWord*)ARG2)[3])
    434 #  define ARG2_4  (((UWord*)ARG2)[4])
    435 #  define ARG2_5  (((UWord*)ARG2)[5])
    436 
    437    *flags |= SfMayBlock;
    438    PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
    439    PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
    440 
    441    switch (ARG1 /* request */) {
    442 
    443    case VKI_SYS_SOCKETPAIR:
    444      /* int socketpair(int d, int type, int protocol, int sv[2]); */
    445       PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
    446       ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
    447       break;
    448 
    449    case VKI_SYS_SOCKET:
    450      /* int socket(int domain, int type, int protocol); */
    451       PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
    452       break;
    453 
    454    case VKI_SYS_BIND:
    455      /* int bind(int sockfd, struct sockaddr *my_addr,
    456 	int addrlen); */
    457       PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
    458       ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
    459       break;
    460 
    461    case VKI_SYS_LISTEN:
    462      /* int listen(int s, int backlog); */
    463       PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
    464       break;
    465 
    466    case VKI_SYS_ACCEPT: {
    467      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
    468       PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
    469       ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
    470       break;
    471    }
    472 
    473    case VKI_SYS_ACCEPT4: {
    474      /* int accept(int s, struct sockaddr *addr, int *addrlen, int args); */
    475       PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
    476       ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
    477       break;
    478    }
    479 
    480    case VKI_SYS_SENDTO:
    481      /* int sendto(int s, const void *msg, int len,
    482                     unsigned int flags,
    483                     const struct sockaddr *to, int tolen); */
    484      PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
    485      ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
    486 				  ARG2_3, ARG2_4, ARG2_5 );
    487      break;
    488 
    489    case VKI_SYS_SEND:
    490      /* int send(int s, const void *msg, size_t len, int flags); */
    491      PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
    492      ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
    493      break;
    494 
    495    case VKI_SYS_RECVFROM:
    496      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
    497 	struct sockaddr *from, int *fromlen); */
    498      PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
    499      ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
    500 				    ARG2_3, ARG2_4, ARG2_5 );
    501      break;
    502 
    503    case VKI_SYS_RECV:
    504      /* int recv(int s, void *buf, int len, unsigned int flags); */
    505      /* man 2 recv says:
    506          The  recv call is normally used only on a connected socket
    507          (see connect(2)) and is identical to recvfrom with a  NULL
    508          from parameter.
    509      */
    510      PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
    511      ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
    512      break;
    513 
    514    case VKI_SYS_CONNECT:
    515      /* int connect(int sockfd,
    516 	struct sockaddr *serv_addr, int addrlen ); */
    517      PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
    518      ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
    519      break;
    520 
    521    case VKI_SYS_SETSOCKOPT:
    522      /* int setsockopt(int s, int level, int optname,
    523 	const void *optval, int optlen); */
    524      PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
    525      ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
    526 				      ARG2_3, ARG2_4 );
    527      break;
    528 
    529    case VKI_SYS_GETSOCKOPT:
    530      /* int getsockopt(int s, int level, int optname,
    531 	void *optval, socklen_t *optlen); */
    532      PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
    533      ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
    534 				    ARG2_3, ARG2_4 );
    535      break;
    536 
    537    case VKI_SYS_GETSOCKNAME:
    538      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
    539      PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
    540      ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
    541      break;
    542 
    543    case VKI_SYS_GETPEERNAME:
    544      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
    545      PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
    546      ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
    547      break;
    548 
    549    case VKI_SYS_SHUTDOWN:
    550      /* int shutdown(int s, int how); */
    551      PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
    552      break;
    553 
    554    case VKI_SYS_SENDMSG: {
    555      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
    556 
    557      /* this causes warnings, and I don't get why. glibc bug?
    558       * (after all it's glibc providing the arguments array)
    559        PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
    560      */
    561      ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
    562      break;
    563    }
    564 
    565    case VKI_SYS_RECVMSG: {
    566      /* int recvmsg(int s, struct msghdr *msg, int flags); */
    567 
    568      /* this causes warnings, and I don't get why. glibc bug?
    569       * (after all it's glibc providing the arguments array)
    570        PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
    571      */
    572      ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
    573      break;
    574    }
    575 
    576    default:
    577      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
    578      SET_STATUS_Failure( VKI_EINVAL );
    579      break;
    580    }
    581 #  undef ARG2_0
    582 #  undef ARG2_1
    583 #  undef ARG2_2
    584 #  undef ARG2_3
    585 #  undef ARG2_4
    586 #  undef ARG2_5
    587 }
    588 
    589 POST(sys_socketcall)
    590 {
    591 #  define ARG2_0  (((UWord*)ARG2)[0])
    592 #  define ARG2_1  (((UWord*)ARG2)[1])
    593 #  define ARG2_2  (((UWord*)ARG2)[2])
    594 #  define ARG2_3  (((UWord*)ARG2)[3])
    595 #  define ARG2_4  (((UWord*)ARG2)[4])
    596 #  define ARG2_5  (((UWord*)ARG2)[5])
    597 
    598   SysRes r;
    599   vg_assert(SUCCESS);
    600   switch (ARG1 /* request */) {
    601 
    602   case VKI_SYS_SOCKETPAIR:
    603     r = ML_(generic_POST_sys_socketpair)(
    604 					 tid, VG_(mk_SysRes_Success)(RES),
    605 					 ARG2_0, ARG2_1, ARG2_2, ARG2_3
    606 					 );
    607     SET_STATUS_from_SysRes(r);
    608     break;
    609 
    610   case VKI_SYS_SOCKET:
    611     r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
    612     SET_STATUS_from_SysRes(r);
    613     break;
    614 
    615   case VKI_SYS_BIND:
    616     /* int bind(int sockfd, struct sockaddr *my_addr,
    617        int addrlen); */
    618     break;
    619 
    620   case VKI_SYS_LISTEN:
    621     /* int listen(int s, int backlog); */
    622     break;
    623 
    624   case VKI_SYS_ACCEPT:
    625   case VKI_SYS_ACCEPT4:
    626     /* int accept(int s, struct sockaddr *addr, int *addrlen); */
    627     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
    628 				      ARG2_0, ARG2_1, ARG2_2 );
    629     SET_STATUS_from_SysRes(r);
    630     break;
    631 
    632   case VKI_SYS_SENDTO:
    633     break;
    634 
    635   case VKI_SYS_SEND:
    636     break;
    637 
    638   case VKI_SYS_RECVFROM:
    639     ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
    640 				    ARG2_0, ARG2_1, ARG2_2,
    641 				    ARG2_3, ARG2_4, ARG2_5 );
    642     break;
    643 
    644   case VKI_SYS_RECV:
    645     ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
    646     break;
    647 
    648   case VKI_SYS_CONNECT:
    649     break;
    650 
    651   case VKI_SYS_SETSOCKOPT:
    652     break;
    653 
    654   case VKI_SYS_GETSOCKOPT:
    655     ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
    656 				    ARG2_0, ARG2_1,
    657 				    ARG2_2, ARG2_3, ARG2_4 );
    658     break;
    659 
    660   case VKI_SYS_GETSOCKNAME:
    661     ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
    662 				       ARG2_0, ARG2_1, ARG2_2 );
    663     break;
    664 
    665   case VKI_SYS_GETPEERNAME:
    666     ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
    667 				       ARG2_0, ARG2_1, ARG2_2 );
    668     break;
    669 
    670   case VKI_SYS_SHUTDOWN:
    671     break;
    672 
    673   case VKI_SYS_SENDMSG:
    674     break;
    675 
    676   case VKI_SYS_RECVMSG:
    677     ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
    678     break;
    679 
    680   default:
    681     VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
    682     VG_(core_panic)("... bye!\n");
    683     break; /*NOTREACHED*/
    684   }
    685 #  undef ARG2_0
    686 #  undef ARG2_1
    687 #  undef ARG2_2
    688 #  undef ARG2_3
    689 #  undef ARG2_4
    690 #  undef ARG2_5
    691 }
    692 
    693 PRE(sys_mmap)
    694 {
    695    SysRes r;
    696 
    697    PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
    698          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
    699    PRE_REG_READ6(long, "mmap",
    700                  unsigned long, start, unsigned long, length,
    701                  unsigned long, prot,  unsigned long, flags,
    702                  unsigned long, fd,    unsigned long, offset);
    703 
    704    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    705                                        (Off64T)ARG6 );
    706    SET_STATUS_from_SysRes(r);
    707 }
    708 
    709 PRE(sys_mmap2)
    710 {
    711    SysRes r;
    712 
    713    // Exactly like old_mmap() except:
    714    //  - the file offset is specified in 4K units rather than bytes,
    715    //    so that it can be used for files bigger than 2^32 bytes.
    716    PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
    717          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
    718    PRE_REG_READ6(long, "mmap2",
    719                  unsigned long, start, unsigned long, length,
    720                  unsigned long, prot,  unsigned long, flags,
    721                  unsigned long, fd,    unsigned long, offset);
    722 
    723    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    724                                        4096 * (Off64T)ARG6 );
    725    SET_STATUS_from_SysRes(r);
    726 }
    727 
    728 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
    729 // applicable to every architecture -- I think only to 32-bit archs.
    730 // We're going to need something like linux/core_os32.h for such
    731 // things, eventually, I think.  --njn
    732 PRE(sys_stat64)
    733 {
    734    PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2);
    735    PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
    736    PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
    737    PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
    738 }
    739 
    740 POST(sys_stat64)
    741 {
    742    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    743 }
    744 
    745 PRE(sys_lstat64)
    746 {
    747    PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
    748    PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
    749    PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
    750    PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
    751 }
    752 
    753 POST(sys_lstat64)
    754 {
    755    vg_assert(SUCCESS);
    756    if (RES == 0) {
    757       POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    758    }
    759 }
    760 
    761 PRE(sys_fstatat64)
    762 {
    763   PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
    764    PRE_REG_READ3(long, "fstatat64",
    765                  int, dfd, char *, file_name, struct stat64 *, buf);
    766    PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
    767    PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
    768 }
    769 
    770 POST(sys_fstatat64)
    771 {
    772    POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
    773 }
    774 
    775 PRE(sys_fstat64)
    776 {
    777   PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
    778   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
    779   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
    780 }
    781 
    782 POST(sys_fstat64)
    783 {
    784   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    785 }
    786 
    787 static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
    788 {
    789    Addr* a_p = (Addr*)a;
    790    PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
    791    return *a_p;
    792 }
    793 
    794 PRE(sys_ipc)
    795 {
    796   PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    797   // XXX: this is simplistic -- some args are not used in all circumstances.
    798   PRE_REG_READ6(int, "ipc",
    799 		vki_uint, call, int, first, int, second, int, third,
    800 		void *, ptr, long, fifth)
    801 
    802     switch (ARG1 /* call */) {
    803     case VKI_SEMOP:
    804       ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
    805       *flags |= SfMayBlock;
    806       break;
    807     case VKI_SEMGET:
    808       break;
    809     case VKI_SEMCTL:
    810       {
    811 	UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
    812 	ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
    813 	break;
    814       }
    815     case VKI_SEMTIMEDOP:
    816       ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
    817       *flags |= SfMayBlock;
    818       break;
    819     case VKI_MSGSND:
    820       ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
    821       if ((ARG4 & VKI_IPC_NOWAIT) == 0)
    822 	*flags |= SfMayBlock;
    823       break;
    824     case VKI_MSGRCV:
    825       {
    826 	Addr msgp;
    827 	Word msgtyp;
    828 
    829 	msgp = deref_Addr( tid,
    830 			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
    831 			   "msgrcv(msgp)" );
    832 	msgtyp = deref_Addr( tid,
    833 			     (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
    834 			     "msgrcv(msgp)" );
    835 
    836 	ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
    837 
    838 	if ((ARG4 & VKI_IPC_NOWAIT) == 0)
    839 	  *flags |= SfMayBlock;
    840 	break;
    841       }
    842     case VKI_MSGGET:
    843       break;
    844     case VKI_MSGCTL:
    845       ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
    846       break;
    847     case VKI_SHMAT:
    848       {
    849 	UWord w;
    850 	PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
    851 	w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
    852 	if (w == 0)
    853 	  SET_STATUS_Failure( VKI_EINVAL );
    854 	else
    855 	  ARG5 = w;
    856 	break;
    857       }
    858     case VKI_SHMDT:
    859       if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
    860 	SET_STATUS_Failure( VKI_EINVAL );
    861       break;
    862     case VKI_SHMGET:
    863       break;
    864     case VKI_SHMCTL: /* IPCOP_shmctl */
    865       ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
    866       break;
    867     default:
    868       VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
    869       VG_(core_panic)("... bye!\n");
    870       break; /*NOTREACHED*/
    871     }
    872 }
    873 
    874 POST(sys_ipc)
    875 {
    876   vg_assert(SUCCESS);
    877   switch (ARG1 /* call */) {
    878   case VKI_SEMOP:
    879   case VKI_SEMGET:
    880     break;
    881   case VKI_SEMCTL:
    882     {
    883       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
    884       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
    885       break;
    886     }
    887   case VKI_SEMTIMEDOP:
    888   case VKI_MSGSND:
    889     break;
    890   case VKI_MSGRCV:
    891     {
    892       Addr msgp;
    893       Word msgtyp;
    894 
    895       msgp = deref_Addr( tid,
    896                          (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
    897                          "msgrcv(msgp)" );
    898       msgtyp = deref_Addr( tid,
    899                            (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
    900                            "msgrcv(msgp)" );
    901 
    902       ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
    903       break;
    904     }
    905   case VKI_MSGGET:
    906     break;
    907   case VKI_MSGCTL:
    908     ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
    909     break;
    910   case VKI_SHMAT:
    911     {
    912       Addr addr;
    913 
    914       /* force readability. before the syscall it is
    915        * indeed uninitialized, as can be seen in
    916        * glibc/sysdeps/unix/sysv/linux/shmat.c */
    917       POST_MEM_WRITE( ARG4, sizeof( Addr ) );
    918 
    919       addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
    920       ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
    921       break;
    922     }
    923   case VKI_SHMDT:
    924     ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
    925     break;
    926   case VKI_SHMGET:
    927     break;
    928   case VKI_SHMCTL:
    929     ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
    930     break;
    931   default:
    932     VG_(message)(Vg_DebugMsg,
    933 		 "FATAL: unhandled syscall(ipc) %ld\n",
    934 		 ARG1 );
    935     VG_(core_panic)("... bye!\n");
    936     break; /*NOTREACHED*/
    937   }
    938 }
    939 
    940 
    941 
    942 
    943 //.. PRE(old_select, MayBlock)
    944 //.. {
    945 //..    /* struct sel_arg_struct {
    946 //..       unsigned long n;
    947 //..       fd_set *inp, *outp, *exp;
    948 //..       struct timeval *tvp;
    949 //..       };
    950 //..    */
    951 //..    PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
    952 //..    PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
    953 //..
    954 //..    {
    955 //..       UInt* arg_struct = (UInt*)ARG1;
    956 //..       UInt a1, a2, a3, a4, a5;
    957 //..
    958 //..       a1 = arg_struct[0];
    959 //..       a2 = arg_struct[1];
    960 //..       a3 = arg_struct[2];
    961 //..       a4 = arg_struct[3];
    962 //..       a5 = arg_struct[4];
    963 //..
    964 //..       PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
    965 //..       if (a2 != (Addr)NULL)
    966 //.. 	 PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
    967 //..       if (a3 != (Addr)NULL)
    968 //.. 	 PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
    969 //..       if (a4 != (Addr)NULL)
    970 //.. 	 PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
    971 //..       if (a5 != (Addr)NULL)
    972 //.. 	 PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
    973 //..    }
    974 //.. }
    975 
    976 PRE(sys_clone)
    977 {
    978    UInt cloneflags;
    979 
    980    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
    981    PRE_REG_READ5(int, "clone",
    982                  unsigned long, flags,
    983                  void *,        child_stack,
    984                  int *,         parent_tidptr,
    985                  void *,        child_tls,
    986                  int *,         child_tidptr);
    987 
    988    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    989       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    990       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
    991                                              VKI_PROT_WRITE)) {
    992          SET_STATUS_Failure( VKI_EFAULT );
    993          return;
    994       }
    995    }
    996    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    997       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
    998       if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
    999                                              VKI_PROT_WRITE)) {
   1000          SET_STATUS_Failure( VKI_EFAULT );
   1001          return;
   1002       }
   1003    }
   1004 
   1005    cloneflags = ARG1;
   1006 
   1007    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
   1008       SET_STATUS_Failure( VKI_EINVAL );
   1009       return;
   1010    }
   1011 
   1012    /* Only look at the flags we really care about */
   1013    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
   1014                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
   1015    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
   1016       /* thread creation */
   1017       SET_STATUS_from_SysRes(
   1018          do_clone(tid,
   1019                   ARG1,         /* flags */
   1020                   (Addr)ARG2,   /* child SP */
   1021                   (Int *)ARG3,  /* parent_tidptr */
   1022                   (Int *)ARG5,  /* child_tidptr */
   1023                   (Addr)ARG4)); /* child_tls */
   1024       break;
   1025 
   1026    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
   1027       /* FALLTHROUGH - assume vfork == fork */
   1028       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
   1029 
   1030    case 0: /* plain fork */
   1031       SET_STATUS_from_SysRes(
   1032          ML_(do_fork_clone)(tid,
   1033                        cloneflags,      /* flags */
   1034                        (Int *)ARG3,     /* parent_tidptr */
   1035                        (Int *)ARG5));   /* child_tidptr */
   1036       break;
   1037 
   1038    default:
   1039       /* should we just ENOSYS? */
   1040       VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
   1041       VG_(message)(Vg_UserMsg, "\n");
   1042       VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
   1043       VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
   1044       VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
   1045       VG_(unimplemented)
   1046          ("Valgrind does not support general clone().");
   1047    }
   1048 
   1049    if (SUCCESS) {
   1050       if (ARG1 & VKI_CLONE_PARENT_SETTID)
   1051          POST_MEM_WRITE(ARG3, sizeof(Int));
   1052       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
   1053          POST_MEM_WRITE(ARG5, sizeof(Int));
   1054 
   1055       /* Thread creation was successful; let the child have the chance
   1056          to run */
   1057       *flags |= SfYieldAfter;
   1058    }
   1059 }
   1060 
   1061 PRE(sys_sigreturn)
   1062 {
   1063    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
   1064       an explanation of what follows. */
   1065 
   1066    //ThreadState* tst;
   1067    PRINT("sys_sigreturn ( )");
   1068 
   1069    vg_assert(VG_(is_valid_tid)(tid));
   1070    vg_assert(tid >= 1 && tid < VG_N_THREADS);
   1071    vg_assert(VG_(is_running_thread)(tid));
   1072 
   1073    ///* Adjust esp to point to start of frame; skip back up over
   1074    //   sigreturn sequence's "popl %eax" and handler ret addr */
   1075    //tst = VG_(get_ThreadState)(tid);
   1076    //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
   1077    // Should we do something equivalent on ppc32?  Who knows.
   1078 
   1079    ///* This is only so that the EIP is (might be) useful to report if
   1080    //   something goes wrong in the sigreturn */
   1081    //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
   1082    // Should we do something equivalent on ppc32?  Who knows.
   1083 
   1084    /* Restore register state from frame and remove it */
   1085    VG_(sigframe_destroy)(tid, False);
   1086 
   1087    /* Tell the driver not to update the guest state with the "result",
   1088       and set a bogus result to keep it happy. */
   1089    *flags |= SfNoWriteResult;
   1090    SET_STATUS_Success(0);
   1091 
   1092    /* Check to see if any signals arose as a result of this. */
   1093    *flags |= SfPollAfter;
   1094 }
   1095 
   1096 PRE(sys_rt_sigreturn)
   1097 {
   1098    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
   1099       an explanation of what follows. */
   1100 
   1101    //ThreadState* tst;
   1102    PRINT("rt_sigreturn ( )");
   1103 
   1104    vg_assert(VG_(is_valid_tid)(tid));
   1105    vg_assert(tid >= 1 && tid < VG_N_THREADS);
   1106    vg_assert(VG_(is_running_thread)(tid));
   1107 
   1108    ///* Adjust esp to point to start of frame; skip back up over handler
   1109    //   ret addr */
   1110    //tst = VG_(get_ThreadState)(tid);
   1111    //tst->arch.vex.guest_ESP -= sizeof(Addr);
   1112    // Should we do something equivalent on ppc32?  Who knows.
   1113 
   1114    ///* This is only so that the EIP is (might be) useful to report if
   1115    //   something goes wrong in the sigreturn */
   1116    //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
   1117    // Should we do something equivalent on ppc32?  Who knows.
   1118 
   1119    /* Restore register state from frame and remove it */
   1120    VG_(sigframe_destroy)(tid, True);
   1121 
   1122    /* Tell the driver not to update the guest state with the "result",
   1123       and set a bogus result to keep it happy. */
   1124    *flags |= SfNoWriteResult;
   1125    SET_STATUS_Success(0);
   1126 
   1127    /* Check to see if any signals arose as a result of this. */
   1128    *flags |= SfPollAfter;
   1129 }
   1130 
   1131 
   1132 //.. PRE(sys_modify_ldt, Special)
   1133 //.. {
   1134 //..    PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
   1135 //..    PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
   1136 //..                  unsigned long, bytecount);
   1137 //..
   1138 //..    if (ARG1 == 0) {
   1139 //..       /* read the LDT into ptr */
   1140 //..       PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
   1141 //..    }
   1142 //..    if (ARG1 == 1 || ARG1 == 0x11) {
   1143 //..       /* write the LDT with the entry pointed at by ptr */
   1144 //..       PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
   1145 //..    }
   1146 //..    /* "do" the syscall ourselves; the kernel never sees it */
   1147 //..    SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) );
   1148 //..
   1149 //..    if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
   1150 //..       POST_MEM_WRITE( ARG2, RES );
   1151 //..    }
   1152 //.. }
   1153 
   1154 //.. PRE(sys_set_thread_area, Special)
   1155 //.. {
   1156 //..    PRINT("sys_set_thread_area ( %p )", ARG1);
   1157 //..    PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
   1158 //..    PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
   1159 //..
   1160 //..    /* "do" the syscall ourselves; the kernel never sees it */
   1161 //..    SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) );
   1162 //.. }
   1163 
   1164 //.. PRE(sys_get_thread_area, Special)
   1165 //.. {
   1166 //..    PRINT("sys_get_thread_area ( %p )", ARG1);
   1167 //..    PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
   1168 //..    PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
   1169 //..
   1170 //..    /* "do" the syscall ourselves; the kernel never sees it */
   1171 //..    SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) );
   1172 //..
   1173 //..    if (!VG_(is_kerror)(RES)) {
   1174 //..       POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
   1175 //..    }
   1176 //.. }
   1177 
   1178 //.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic.
   1179 //.. // XXX: Why is the memory pointed to by ARG3 never checked?
   1180 //.. PRE(sys_ptrace, 0)
   1181 //.. {
   1182 //..    PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
   1183 //..    PRE_REG_READ4(int, "ptrace",
   1184 //..                  long, request, long, pid, long, addr, long, data);
   1185 //..    switch (ARG1) {
   1186 //..    case VKI_PTRACE_PEEKTEXT:
   1187 //..    case VKI_PTRACE_PEEKDATA:
   1188 //..    case VKI_PTRACE_PEEKUSR:
   1189 //..       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
   1190 //.. 		     sizeof (long));
   1191 //..       break;
   1192 //..    case VKI_PTRACE_GETREGS:
   1193 //..       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
   1194 //.. 		     sizeof (struct vki_user_regs_struct));
   1195 //..       break;
   1196 //..    case VKI_PTRACE_GETFPREGS:
   1197 //..       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
   1198 //.. 		     sizeof (struct vki_user_i387_struct));
   1199 //..       break;
   1200 //..    case VKI_PTRACE_GETFPXREGS:
   1201 //..       PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
   1202 //..                      sizeof(struct vki_user_fxsr_struct) );
   1203 //..       break;
   1204 //..    case VKI_PTRACE_SETREGS:
   1205 //..       PRE_MEM_READ( "ptrace(setregs)", ARG4,
   1206 //.. 		     sizeof (struct vki_user_regs_struct));
   1207 //..       break;
   1208 //..    case VKI_PTRACE_SETFPREGS:
   1209 //..       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
   1210 //.. 		     sizeof (struct vki_user_i387_struct));
   1211 //..       break;
   1212 //..    case VKI_PTRACE_SETFPXREGS:
   1213 //..       PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
   1214 //..                      sizeof(struct vki_user_fxsr_struct) );
   1215 //..       break;
   1216 //..    default:
   1217 //..       break;
   1218 //..    }
   1219 //.. }
   1220 
   1221 //.. POST(sys_ptrace)
   1222 //.. {
   1223 //..    switch (ARG1) {
   1224 //..    case VKI_PTRACE_PEEKTEXT:
   1225 //..    case VKI_PTRACE_PEEKDATA:
   1226 //..    case VKI_PTRACE_PEEKUSR:
   1227 //..       POST_MEM_WRITE( ARG4, sizeof (long));
   1228 //..       break;
   1229 //..    case VKI_PTRACE_GETREGS:
   1230 //..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
   1231 //..       break;
   1232 //..    case VKI_PTRACE_GETFPREGS:
   1233 //..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
   1234 //..       break;
   1235 //..    case VKI_PTRACE_GETFPXREGS:
   1236 //..       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
   1237 //..       break;
   1238 //..    default:
   1239 //..       break;
   1240 //..    }
   1241 //.. }
   1242 
   1243 //.. // XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk
   1244 //.. static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
   1245 //.. {
   1246 //..    Addr* a_p = (Addr*)a;
   1247 //..    PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
   1248 //..    return *a_p;
   1249 //.. }
   1250 
   1251 //.. // XXX: should use the constants here (eg. SHMAT), not the numbers directly!
   1252 //.. PRE(sys_ipc, 0)
   1253 //.. {
   1254 //..    PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
   1255 //..    // XXX: this is simplistic -- some args are not used in all circumstances.
   1256 //..    PRE_REG_READ6(int, "ipc",
   1257 //..                  vki_uint, call, int, first, int, second, int, third,
   1258 //..                  void *, ptr, long, fifth)
   1259 //..
   1260 //..    switch (ARG1 /* call */) {
   1261 //..    case VKI_SEMOP:
   1262 //..       ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
   1263 //..       /* tst->sys_flags |= MayBlock; */
   1264 //..       break;
   1265 //..    case VKI_SEMGET:
   1266 //..       break;
   1267 //..    case VKI_SEMCTL:
   1268 //..    {
   1269 //..       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
   1270 //..       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
   1271 //..       break;
   1272 //..    }
   1273 //..    case VKI_SEMTIMEDOP:
   1274 //..       ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
   1275 //..       /* tst->sys_flags |= MayBlock; */
   1276 //..       break;
   1277 //..    case VKI_MSGSND:
   1278 //..       ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
   1279 //..       /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
   1280 //..             tst->sys_flags |= MayBlock;
   1281 //..       */
   1282 //..       break;
   1283 //..    case VKI_MSGRCV:
   1284 //..    {
   1285 //..       Addr msgp;
   1286 //..       Word msgtyp;
   1287 //..
   1288 //..       msgp = deref_Addr( tid,
   1289 //.. 			 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
   1290 //.. 			 "msgrcv(msgp)" );
   1291 //..       msgtyp = deref_Addr( tid,
   1292 //.. 			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
   1293 //.. 			   "msgrcv(msgp)" );
   1294 //..
   1295 //..       ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
   1296 //..
   1297 //..       /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
   1298 //..             tst->sys_flags |= MayBlock;
   1299 //..       */
   1300 //..       break;
   1301 //..    }
   1302 //..    case VKI_MSGGET:
   1303 //..       break;
   1304 //..    case VKI_MSGCTL:
   1305 //..       ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
   1306 //..       break;
   1307 //..    case VKI_SHMAT:
   1308 //..       PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
   1309 //..       ARG5 = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
   1310 //..       if (ARG5 == 0)
   1311 //..          SET_RESULT( -VKI_EINVAL );
   1312 //..       break;
   1313 //..    case VKI_SHMDT:
   1314 //..       if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
   1315 //.. 	 SET_RESULT( -VKI_EINVAL );
   1316 //..       break;
   1317 //..    case VKI_SHMGET:
   1318 //..       break;
   1319 //..    case VKI_SHMCTL: /* IPCOP_shmctl */
   1320 //..       ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
   1321 //..       break;
   1322 //..    default:
   1323 //..       VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 );
   1324 //..       VG_(core_panic)("... bye!\n");
   1325 //..       break; /*NOTREACHED*/
   1326 //..    }
   1327 //.. }
   1328 
   1329 //.. POST(sys_ipc)
   1330 //.. {
   1331 //..    switch (ARG1 /* call */) {
   1332 //..    case VKI_SEMOP:
   1333 //..    case VKI_SEMGET:
   1334 //..       break;
   1335 //..    case VKI_SEMCTL:
   1336 //..    {
   1337 //..       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
   1338 //..       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
   1339 //..       break;
   1340 //..    }
   1341 //..    case VKI_SEMTIMEDOP:
   1342 //..    case VKI_MSGSND:
   1343 //..       break;
   1344 //..    case VKI_MSGRCV:
   1345 //..    {
   1346 //..       Addr msgp;
   1347 //..       Word msgtyp;
   1348 //..
   1349 //..       msgp = deref_Addr( tid,
   1350 //.. 			 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
   1351 //.. 			 "msgrcv(msgp)" );
   1352 //..       msgtyp = deref_Addr( tid,
   1353 //.. 			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
   1354 //.. 			   "msgrcv(msgp)" );
   1355 //..
   1356 //..       ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
   1357 //..       break;
   1358 //..    }
   1359 //..    case VKI_MSGGET:
   1360 //..       break;
   1361 //..    case VKI_MSGCTL:
   1362 //..       ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
   1363 //..       break;
   1364 //..    case VKI_SHMAT:
   1365 //..    {
   1366 //..       Addr addr;
   1367 //..
   1368 //..       /* force readability. before the syscall it is
   1369 //..        * indeed uninitialized, as can be seen in
   1370 //..        * glibc/sysdeps/unix/sysv/linux/shmat.c */
   1371 //..       POST_MEM_WRITE( ARG4, sizeof( Addr ) );
   1372 //..
   1373 //..       addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
   1374 //..       if ( addr > 0 ) {
   1375 //..          ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
   1376 //..       }
   1377 //..       break;
   1378 //..    }
   1379 //..    case VKI_SHMDT:
   1380 //..       ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
   1381 //..       break;
   1382 //..    case VKI_SHMGET:
   1383 //..       break;
   1384 //..    case VKI_SHMCTL:
   1385 //..       ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
   1386 //..       break;
   1387 //..    default:
   1388 //..       VG_(message)(Vg_DebugMsg,
   1389 //.. 		   "FATAL: unhandled syscall(ipc) %d",
   1390 //.. 		   ARG1 );
   1391 //..       VG_(core_panic)("... bye!\n");
   1392 //..       break; /*NOTREACHED*/
   1393 //..    }
   1394 //.. }
   1395 
   1396 /* NB: This is an almost identical clone of versions for x86-linux and
   1397    arm-linux, which are themselves literally identical. */
   1398 PRE(sys_sigsuspend)
   1399 {
   1400    /* The C library interface to sigsuspend just takes a pointer to
   1401       a signal mask but this system call only takes the first word of
   1402       the signal mask as an argument so only 32 signals are supported.
   1403 
   1404       In fact glibc normally uses rt_sigsuspend if it is available as
   1405       that takes a pointer to the signal mask so supports more signals.
   1406     */
   1407    *flags |= SfMayBlock;
   1408    PRINT("sys_sigsuspend ( %ld )", ARG1 );
   1409    PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask);
   1410 }
   1411 
   1412 PRE(sys_spu_create)
   1413 {
   1414    PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
   1415 }
   1416 POST(sys_spu_create)
   1417 {
   1418    vg_assert(SUCCESS);
   1419 }
   1420 
   1421 PRE(sys_spu_run)
   1422 {
   1423    *flags |= SfMayBlock;
   1424    if (ARG2 != 0)
   1425       PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int));
   1426    PRE_MEM_READ("event", ARG3, sizeof(unsigned int));
   1427 }
   1428 POST(sys_spu_run)
   1429 {
   1430    if (ARG2 != 0)
   1431       POST_MEM_WRITE(ARG2, sizeof(unsigned int));
   1432 }
   1433 
   1434 #undef PRE
   1435 #undef POST
   1436 
   1437 /* ---------------------------------------------------------------------
   1438    The ppc32/Linux syscall table
   1439    ------------------------------------------------------------------ */
   1440 
   1441 /* Add an ppc32-linux specific wrapper to a syscall table. */
   1442 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(ppc32_linux, sysno, name)
   1443 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(ppc32_linux, sysno, name)
   1444 
   1445 // This table maps from __NR_xxx syscall numbers (from
   1446 // linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
   1447 // wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
   1448 //
   1449 // For those syscalls not handled by Valgrind, the annotation indicate its
   1450 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
   1451 // (unknown).
   1452 
   1453 static SyscallTableEntry syscall_table[] = {
   1454 //..   (restart_syscall)                                      // 0
   1455    GENX_(__NR_exit,              sys_exit),              // 1
   1456    GENX_(__NR_fork,              sys_fork),              // 2
   1457    GENXY(__NR_read,              sys_read),              // 3
   1458    GENX_(__NR_write,             sys_write),             // 4
   1459 
   1460    GENXY(__NR_open,              sys_open),              // 5
   1461    GENXY(__NR_close,             sys_close),             // 6
   1462    GENXY(__NR_waitpid,           sys_waitpid),           // 7
   1463    GENXY(__NR_creat,             sys_creat),             // 8
   1464    GENX_(__NR_link,              sys_link),              // 9
   1465 
   1466    GENX_(__NR_unlink,            sys_unlink),            // 10
   1467    GENX_(__NR_execve,            sys_execve),            // 11
   1468    GENX_(__NR_chdir,             sys_chdir),             // 12
   1469    GENXY(__NR_time,              sys_time),              // 13
   1470    GENX_(__NR_mknod,             sys_mknod),             // 14
   1471 //..
   1472    GENX_(__NR_chmod,             sys_chmod),             // 15
   1473    GENX_(__NR_lchown,            sys_lchown),          // 16 ## P
   1474 //..    GENX_(__NR_break,             sys_ni_syscall),        // 17
   1475 //..    //   (__NR_oldstat,           sys_stat),              // 18 (obsolete)
   1476    LINX_(__NR_lseek,             sys_lseek),             // 19
   1477 //..
   1478    GENX_(__NR_getpid,            sys_getpid),            // 20
   1479    LINX_(__NR_mount,             sys_mount),             // 21
   1480    LINX_(__NR_umount,            sys_oldumount),         // 22
   1481    GENX_(__NR_setuid,            sys_setuid),            // 23 ## P
   1482    GENX_(__NR_getuid,            sys_getuid),            // 24 ## P
   1483 //..
   1484 //..    //   (__NR_stime,             sys_stime),             // 25 * (SVr4,SVID,X/OPEN)
   1485 //..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
   1486    GENX_(__NR_alarm,             sys_alarm),             // 27
   1487 //..    //   (__NR_oldfstat,          sys_fstat),             // 28 * L -- obsolete
   1488    GENX_(__NR_pause,             sys_pause),             // 29
   1489 //..
   1490    LINX_(__NR_utime,             sys_utime),                  // 30
   1491 //..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
   1492 //..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
   1493    GENX_(__NR_access,            sys_access),            // 33
   1494 //..    GENX_(__NR_nice,              sys_nice),              // 34
   1495 //..
   1496 //..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
   1497 //..    GENX_(__NR_sync,              sys_sync),              // 36
   1498    GENX_(__NR_kill,              sys_kill),              // 37
   1499    GENX_(__NR_rename,            sys_rename),            // 38
   1500    GENX_(__NR_mkdir,             sys_mkdir),             // 39
   1501 
   1502    GENX_(__NR_rmdir,             sys_rmdir),             // 40
   1503    GENXY(__NR_dup,               sys_dup),               // 41
   1504    LINXY(__NR_pipe,              sys_pipe),              // 42
   1505    GENXY(__NR_times,             sys_times),             // 43
   1506 //..    GENX_(__NR_prof,              sys_ni_syscall),        // 44
   1507 //..
   1508    GENX_(__NR_brk,               sys_brk),               // 45
   1509    GENX_(__NR_setgid,            sys_setgid),            // 46
   1510    GENX_(__NR_getgid,            sys_getgid),            // 47
   1511 //..    //   (__NR_signal,            sys_signal),            // 48 */* (ANSI C)
   1512    GENX_(__NR_geteuid,           sys_geteuid),           // 49
   1513 
   1514    GENX_(__NR_getegid,           sys_getegid),           // 50
   1515 //..    GENX_(__NR_acct,              sys_acct),              // 51
   1516    LINX_(__NR_umount2,           sys_umount),            // 52
   1517 //..    GENX_(__NR_lock,              sys_ni_syscall),        // 53
   1518    LINXY(__NR_ioctl,             sys_ioctl),             // 54
   1519 //..
   1520    LINXY(__NR_fcntl,             sys_fcntl),             // 55
   1521 //..    GENX_(__NR_mpx,               sys_ni_syscall),        // 56
   1522    GENX_(__NR_setpgid,           sys_setpgid),           // 57
   1523 //..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
   1524 //..    //   (__NR_oldolduname,       sys_olduname),          // 59 Linux -- obsolete
   1525 
   1526    GENX_(__NR_umask,             sys_umask),             // 60
   1527    GENX_(__NR_chroot,            sys_chroot),            // 61
   1528 //..    //   (__NR_ustat,             sys_ustat)              // 62 SVr4 -- deprecated
   1529    GENXY(__NR_dup2,              sys_dup2),              // 63
   1530    GENX_(__NR_getppid,           sys_getppid),           // 64
   1531 
   1532    GENX_(__NR_getpgrp,           sys_getpgrp),           // 65
   1533    GENX_(__NR_setsid,            sys_setsid),            // 66
   1534    LINXY(__NR_sigaction,         sys_sigaction),         // 67
   1535 //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68 */* (ANSI C)
   1536 //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69 */* (ANSI C)
   1537 //..
   1538    GENX_(__NR_setreuid,          sys_setreuid),          // 70
   1539    GENX_(__NR_setregid,          sys_setregid),          // 71
   1540    PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
   1541    LINXY(__NR_sigpending,        sys_sigpending),        // 73
   1542 //..    //   (__NR_sethostname,       sys_sethostname),       // 74 */*
   1543 //..
   1544    GENX_(__NR_setrlimit,         sys_setrlimit),              // 75
   1545 //..    GENXY(__NR_getrlimit,         sys_old_getrlimit),     // 76
   1546    GENXY(__NR_getrusage,         sys_getrusage),         // 77
   1547    GENXY(__NR_gettimeofday,      sys_gettimeofday),           // 78
   1548 //..    GENX_(__NR_settimeofday,      sys_settimeofday),      // 79
   1549 //..
   1550    GENXY(__NR_getgroups,         sys_getgroups),         // 80
   1551    GENX_(__NR_setgroups,         sys_setgroups),         // 81
   1552 //..    PLAX_(__NR_select,            old_select),            // 82
   1553    GENX_(__NR_symlink,           sys_symlink),           // 83
   1554 //..    //   (__NR_oldlstat,          sys_lstat),             // 84 -- obsolete
   1555 //..
   1556    GENX_(__NR_readlink,          sys_readlink),          // 85
   1557 //..    //   (__NR_uselib,            sys_uselib),            // 86 */Linux
   1558 //..    //   (__NR_swapon,            sys_swapon),            // 87 */Linux
   1559 //..    //   (__NR_reboot,            sys_reboot),            // 88 */Linux
   1560 //..    //   (__NR_readdir,           old_readdir),           // 89 -- superseded
   1561 
   1562    PLAX_(__NR_mmap,              sys_mmap),                   // 90
   1563    GENXY(__NR_munmap,            sys_munmap),                 // 91
   1564    GENX_(__NR_truncate,          sys_truncate),          // 92
   1565    GENX_(__NR_ftruncate,         sys_ftruncate),         // 93
   1566    GENX_(__NR_fchmod,            sys_fchmod),            // 94
   1567 
   1568    GENX_(__NR_fchown,            sys_fchown),            // 95
   1569    GENX_(__NR_getpriority,       sys_getpriority),       // 96
   1570    GENX_(__NR_setpriority,       sys_setpriority),       // 97
   1571 //..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
   1572    GENXY(__NR_statfs,            sys_statfs),            // 99
   1573 //..
   1574    GENXY(__NR_fstatfs,           sys_fstatfs),           // 100
   1575 //..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
   1576    PLAXY(__NR_socketcall,        sys_socketcall),        // 102
   1577    LINXY(__NR_syslog,            sys_syslog),            // 103
   1578    GENXY(__NR_setitimer,         sys_setitimer),         // 104
   1579 
   1580    GENXY(__NR_getitimer,         sys_getitimer),         // 105
   1581    GENXY(__NR_stat,              sys_newstat),           // 106
   1582    GENXY(__NR_lstat,             sys_newlstat),          // 107
   1583    GENXY(__NR_fstat,             sys_newfstat),          // 108
   1584 //..    //   (__NR_olduname,          sys_uname),             // 109 -- obsolete
   1585 //..
   1586 //..    GENX_(__NR_iopl,              sys_iopl),              // 110
   1587    LINX_(__NR_vhangup,           sys_vhangup),           // 111
   1588 //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
   1589 //..    //   (__NR_vm86old,           sys_vm86old),           // 113 x86/Linux-only
   1590    GENXY(__NR_wait4,             sys_wait4),             // 114
   1591 //..
   1592 //..    //   (__NR_swapoff,           sys_swapoff),           // 115 */Linux
   1593    LINXY(__NR_sysinfo,           sys_sysinfo),           // 116
   1594    PLAXY(__NR_ipc,               sys_ipc),               // 117
   1595    GENX_(__NR_fsync,             sys_fsync),             // 118
   1596    PLAX_(__NR_sigreturn,         sys_sigreturn),         // 119 ?/Linux
   1597 //..
   1598    PLAX_(__NR_clone,             sys_clone),             // 120
   1599 //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121 */*(?)
   1600    GENXY(__NR_uname,             sys_newuname),          // 122
   1601 //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
   1602    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
   1603 
   1604    GENXY(__NR_mprotect,          sys_mprotect),          // 125
   1605    LINXY(__NR_sigprocmask,       sys_sigprocmask),       // 126
   1606    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
   1607    LINX_(__NR_init_module,       sys_init_module),       // 128
   1608    LINX_(__NR_delete_module,     sys_delete_module),     // 129
   1609 //..
   1610 //..    // Nb: get_kernel_syms() was removed 2.4-->2.6
   1611 //..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
   1612 //..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
   1613    GENX_(__NR_getpgid,           sys_getpgid),           // 132
   1614    GENX_(__NR_fchdir,            sys_fchdir),            // 133
   1615 //..    //   (__NR_bdflush,           sys_bdflush),           // 134 */Linux
   1616 //..
   1617 //..    //   (__NR_sysfs,             sys_sysfs),             // 135 SVr4
   1618    LINX_(__NR_personality,       sys_personality),       // 136
   1619 //..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
   1620    LINX_(__NR_setfsuid,          sys_setfsuid),          // 138
   1621    LINX_(__NR_setfsgid,          sys_setfsgid),          // 139
   1622 
   1623    LINXY(__NR__llseek,           sys_llseek),            // 140
   1624    GENXY(__NR_getdents,          sys_getdents),          // 141
   1625    GENX_(__NR__newselect,        sys_select),            // 142
   1626    GENX_(__NR_flock,             sys_flock),             // 143
   1627    GENX_(__NR_msync,             sys_msync),             // 144
   1628 //..
   1629    GENXY(__NR_readv,             sys_readv),             // 145
   1630    GENX_(__NR_writev,            sys_writev),            // 146
   1631    GENX_(__NR_getsid,            sys_getsid),            // 147
   1632    GENX_(__NR_fdatasync,         sys_fdatasync),         // 148
   1633    LINXY(__NR__sysctl,           sys_sysctl),            // 149
   1634 //..
   1635    GENX_(__NR_mlock,             sys_mlock),             // 150
   1636    GENX_(__NR_munlock,           sys_munlock),           // 151
   1637    GENX_(__NR_mlockall,          sys_mlockall),          // 152
   1638    LINX_(__NR_munlockall,        sys_munlockall),        // 153
   1639    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 154
   1640 //..
   1641    LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
   1642    LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
   1643    LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
   1644    LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
   1645    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
   1646 
   1647    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
   1648    LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
   1649    GENXY(__NR_nanosleep,         sys_nanosleep),         // 162
   1650    GENX_(__NR_mremap,            sys_mremap),            // 163
   1651    LINX_(__NR_setresuid,         sys_setresuid),         // 164
   1652 
   1653    LINXY(__NR_getresuid,         sys_getresuid),         // 165
   1654 
   1655 //..    GENX_(__NR_query_module,      sys_ni_syscall),        // 166
   1656    GENXY(__NR_poll,              sys_poll),              // 167
   1657 //..    //   (__NR_nfsservctl,        sys_nfsservctl),        // 168 */Linux
   1658 //..
   1659    LINX_(__NR_setresgid,         sys_setresgid),         // 169
   1660    LINXY(__NR_getresgid,         sys_getresgid),         // 170
   1661    LINXY(__NR_prctl,             sys_prctl),             // 171
   1662    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),      // 172
   1663    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),      // 173
   1664 
   1665    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask),    // 174
   1666    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),     // 175
   1667    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),   // 176
   1668    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),   // 177
   1669    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),     // 178
   1670 
   1671    GENXY(__NR_pread64,           sys_pread64),           // 179
   1672    GENX_(__NR_pwrite64,          sys_pwrite64),          // 180
   1673    GENX_(__NR_chown,             sys_chown),             // 181
   1674    GENXY(__NR_getcwd,            sys_getcwd),            // 182
   1675    LINXY(__NR_capget,            sys_capget),            // 183
   1676    LINX_(__NR_capset,            sys_capset),            // 184
   1677    GENXY(__NR_sigaltstack,       sys_sigaltstack),       // 185
   1678    LINXY(__NR_sendfile,          sys_sendfile),          // 186
   1679 //..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 187
   1680 //..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 188
   1681 
   1682    // Nb: we treat vfork as fork
   1683    GENX_(__NR_vfork,             sys_fork),              // 189
   1684    GENXY(__NR_ugetrlimit,        sys_getrlimit),         // 190
   1685    LINX_(__NR_readahead,         sys_readahead),         // 191 */Linux
   1686    PLAX_(__NR_mmap2,             sys_mmap2),             // 192
   1687    GENX_(__NR_truncate64,        sys_truncate64),        // 193
   1688    GENX_(__NR_ftruncate64,       sys_ftruncate64),       // 194
   1689 //..
   1690 
   1691    PLAXY(__NR_stat64,            sys_stat64),            // 195
   1692    PLAXY(__NR_lstat64,           sys_lstat64),           // 196
   1693    PLAXY(__NR_fstat64,           sys_fstat64),           // 197
   1694 
   1695 // __NR_pciconfig_read                                        // 198
   1696 // __NR_pciconfig_write                                       // 199
   1697 // __NR_pciconfig_iobase                                      // 200
   1698 // __NR_multiplexer                                           // 201
   1699 
   1700    GENXY(__NR_getdents64,        sys_getdents64),        // 202
   1701 //..    //   (__NR_pivot_root,        sys_pivot_root),        // 203 */Linux
   1702    LINXY(__NR_fcntl64,           sys_fcntl64),           // 204
   1703    GENX_(__NR_madvise,           sys_madvise),           // 205
   1704    GENXY(__NR_mincore,           sys_mincore),           // 206
   1705    LINX_(__NR_gettid,            sys_gettid),            // 207
   1706 //..    LINX_(__NR_tkill,             sys_tkill),             // 208 */Linux
   1707 //..    LINX_(__NR_setxattr,          sys_setxattr),          // 209
   1708 //..    LINX_(__NR_lsetxattr,         sys_lsetxattr),         // 210
   1709 //..    LINX_(__NR_fsetxattr,         sys_fsetxattr),         // 211
   1710    LINXY(__NR_getxattr,          sys_getxattr),          // 212
   1711    LINXY(__NR_lgetxattr,         sys_lgetxattr),         // 213
   1712    LINXY(__NR_fgetxattr,         sys_fgetxattr),         // 214
   1713    LINXY(__NR_listxattr,         sys_listxattr),         // 215
   1714    LINXY(__NR_llistxattr,        sys_llistxattr),        // 216
   1715    LINXY(__NR_flistxattr,        sys_flistxattr),        // 217
   1716    LINX_(__NR_removexattr,       sys_removexattr),       // 218
   1717    LINX_(__NR_lremovexattr,      sys_lremovexattr),      // 219
   1718    LINX_(__NR_fremovexattr,      sys_fremovexattr),      // 220
   1719 
   1720    LINXY(__NR_futex,             sys_futex),                  // 221
   1721    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222
   1722    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223
   1723 /* 224 currently unused */
   1724 
   1725 // __NR_tuxcall                                               // 225
   1726 
   1727    LINXY(__NR_sendfile64,        sys_sendfile64),        // 226
   1728 //..
   1729    LINX_(__NR_io_setup,          sys_io_setup),          // 227
   1730    LINX_(__NR_io_destroy,        sys_io_destroy),        // 228
   1731    LINXY(__NR_io_getevents,      sys_io_getevents),      // 229
   1732    LINX_(__NR_io_submit,         sys_io_submit),         // 230
   1733    LINXY(__NR_io_cancel,         sys_io_cancel),         // 231
   1734 //..
   1735    LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 232
   1736 
   1737    LINX_(__NR_fadvise64,         sys_fadvise64),         // 233 */(Linux?)
   1738    LINX_(__NR_exit_group,        sys_exit_group),        // 234
   1739 //..    GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie),    // 235
   1740    LINXY(__NR_epoll_create,      sys_epoll_create),      // 236
   1741    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 237
   1742    LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 238
   1743 
   1744 //..    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 239 */Linux
   1745    LINXY(__NR_timer_create,      sys_timer_create),      // 240
   1746    LINXY(__NR_timer_settime,     sys_timer_settime),     // 241
   1747    LINXY(__NR_timer_gettime,     sys_timer_gettime),     // 242
   1748    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),  // 243
   1749    LINX_(__NR_timer_delete,      sys_timer_delete),      // 244
   1750    LINX_(__NR_clock_settime,     sys_clock_settime),     // 245
   1751    LINXY(__NR_clock_gettime,     sys_clock_gettime),     // 246
   1752    LINXY(__NR_clock_getres,      sys_clock_getres),      // 247
   1753    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),   // 248
   1754 
   1755 // __NR_swapcontext                                           // 249
   1756 
   1757    LINXY(__NR_tgkill,            sys_tgkill),            // 250 */Linux
   1758 //..    GENX_(__NR_utimes,            sys_utimes),            // 251
   1759    GENXY(__NR_statfs64,          sys_statfs64),          // 252
   1760    GENXY(__NR_fstatfs64,         sys_fstatfs64),         // 253
   1761    LINX_(__NR_fadvise64_64,      sys_fadvise64_64),      // 254 */(Linux?)
   1762 
   1763 // __NR_rtas                                                  // 255
   1764 
   1765 /* Number 256 is reserved for sys_debug_setcontext */
   1766 /* Number 257 is reserved for vserver */
   1767 /* Number 258 is reserved for new sys_remap_file_pages */
   1768 /* Number 259 is reserved for new sys_mbind */
   1769    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),          // 260
   1770    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),          // 261
   1771 
   1772    LINXY(__NR_mq_open,           sys_mq_open),           // 262
   1773    LINX_(__NR_mq_unlink,         sys_mq_unlink),         // 263
   1774    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),      // 264
   1775    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),   // 265
   1776    LINX_(__NR_mq_notify,         sys_mq_notify),         // 266
   1777    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),     // 267
   1778 // __NR_kexec_load                                            // 268
   1779 
   1780 /* Number 269 is reserved for sys_add_key */
   1781 /* Number 270 is reserved for sys_request_key */
   1782 /* Number 271 is reserved for sys_keyctl */
   1783 /* Number 272 is reserved for sys_waitid */
   1784    LINX_(__NR_ioprio_set,        sys_ioprio_set),         // 273
   1785    LINX_(__NR_ioprio_get,        sys_ioprio_get),         // 274
   1786 
   1787    LINX_(__NR_inotify_init,  sys_inotify_init),               // 275
   1788    LINX_(__NR_inotify_add_watch,  sys_inotify_add_watch),     // 276
   1789    LINX_(__NR_inotify_rm_watch,   sys_inotify_rm_watch),      // 277
   1790    PLAXY(__NR_spu_run,            sys_spu_run),               // 278
   1791    PLAX_(__NR_spu_create,         sys_spu_create),            // 279
   1792 
   1793    LINX_(__NR_pselect6,          sys_pselect6),          // 280
   1794    LINXY(__NR_ppoll,             sys_ppoll),             // 281
   1795 
   1796    LINXY(__NR_openat,            sys_openat),            // 286
   1797    LINX_(__NR_mkdirat,           sys_mkdirat),           // 287
   1798    LINX_(__NR_mknodat,           sys_mknodat),           // 288
   1799    LINX_(__NR_fchownat,          sys_fchownat),          // 289
   1800    LINX_(__NR_futimesat,         sys_futimesat),         // 290
   1801    PLAXY(__NR_fstatat64,         sys_fstatat64),         // 291
   1802    LINX_(__NR_unlinkat,          sys_unlinkat),          // 292
   1803    LINX_(__NR_renameat,          sys_renameat),          // 293
   1804    LINX_(__NR_linkat,            sys_linkat),            // 294
   1805    LINX_(__NR_symlinkat,         sys_symlinkat),         // 295
   1806    LINX_(__NR_readlinkat,        sys_readlinkat),        // 296
   1807    LINX_(__NR_fchmodat,          sys_fchmodat),          // 297
   1808    LINX_(__NR_faccessat,         sys_faccessat),         // 298
   1809    LINX_(__NR_set_robust_list,   sys_set_robust_list),   // 299
   1810    LINXY(__NR_get_robust_list,   sys_get_robust_list),   // 300
   1811    LINXY(__NR_move_pages,        sys_move_pages),        // 301
   1812    LINXY(__NR_getcpu,            sys_getcpu),            // 302
   1813    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
   1814    LINX_(__NR_utimensat,         sys_utimensat),         // 304
   1815    LINXY(__NR_signalfd,          sys_signalfd),          // 305
   1816    LINXY(__NR_timerfd_create,    sys_timerfd_create),    // 306
   1817    LINX_(__NR_eventfd,           sys_eventfd),           // 307
   1818    LINX_(__NR_sync_file_range2,  sys_sync_file_range2),  // 308
   1819    LINX_(__NR_fallocate,         sys_fallocate),         // 309
   1820 //   LINXY(__NR_subpage_prot,       sys_ni_syscall),       // 310
   1821    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 311
   1822    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 312
   1823    LINXY(__NR_signalfd4,         sys_signalfd4),        // 313
   1824    LINX_(__NR_eventfd2,          sys_eventfd2),         // 314
   1825    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
   1826    LINXY(__NR_dup3,              sys_dup3),             // 316
   1827    LINXY(__NR_pipe2,             sys_pipe2),            // 317
   1828    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
   1829    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 319
   1830    LINXY(__NR_preadv,            sys_preadv),           // 320
   1831    LINX_(__NR_pwritev,           sys_pwritev),          // 321
   1832    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322
   1833 
   1834    LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 351
   1835    LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352
   1836 };
   1837 
   1838 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
   1839 {
   1840    const UInt syscall_table_size
   1841       = sizeof(syscall_table) / sizeof(syscall_table[0]);
   1842 
   1843    /* Is it in the contiguous initial section of the table? */
   1844    if (sysno < syscall_table_size) {
   1845       SyscallTableEntry* sys = &syscall_table[sysno];
   1846       if (sys->before == NULL)
   1847          return NULL; /* no entry */
   1848       else
   1849          return sys;
   1850    }
   1851 
   1852    /* Can't find a wrapper */
   1853    return NULL;
   1854 }
   1855 
   1856 #endif // defined(VGP_ppc32_linux)
   1857 
   1858 /*--------------------------------------------------------------------*/
   1859 /*--- end                                                          ---*/
   1860 /*--------------------------------------------------------------------*/
   1861