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