Home | History | Annotate | Download | only in m_syswrap
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Platform-specific syscalls stuff.      syswrap-arm-linux.c -----*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2000-2013 Nicholas Nethercote
     11       njn (at) valgrind.org
     12    Copyright (C) 2008-2013 Evan Geller
     13       gaze (at) bea.ms
     14 
     15    This program is free software; you can redistribute it and/or
     16    modify it under the terms of the GNU General Public License as
     17    published by the Free Software Foundation; either version 2 of the
     18    License, or (at your option) any later version.
     19 
     20    This program is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received a copy of the GNU General Public License
     26    along with this program; if not, write to the Free Software
     27    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     28    02111-1307, USA.
     29 
     30    The GNU General Public License is contained in the file COPYING.
     31 */
     32 
     33 #if defined(VGP_arm_linux)
     34 
     35 #include "pub_core_basics.h"
     36 #include "pub_core_vki.h"
     37 #include "pub_core_vkiscnums.h"
     38 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
     39 #include "pub_core_threadstate.h"
     40 #include "pub_core_aspacemgr.h"
     41 #include "pub_core_debuglog.h"
     42 #include "pub_core_libcbase.h"
     43 #include "pub_core_libcassert.h"
     44 #include "pub_core_libcprint.h"
     45 #include "pub_core_libcproc.h"
     46 #include "pub_core_libcsignal.h"
     47 #include "pub_core_options.h"
     48 #include "pub_core_scheduler.h"
     49 #include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
     50 #include "pub_core_signals.h"
     51 #include "pub_core_syscall.h"
     52 #include "pub_core_syswrap.h"
     53 #include "pub_core_tooliface.h"
     54 #include "pub_core_stacks.h"        // VG_(register_stack)
     55 #include "pub_core_transtab.h"      // VG_(discard_translations)
     56 
     57 #include "priv_types_n_macros.h"
     58 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
     59 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
     60 #include "priv_syswrap-main.h"
     61 
     62 
     63 /* ---------------------------------------------------------------------
     64    clone() handling
     65    ------------------------------------------------------------------ */
     66 
     67 /* Call f(arg1), but first switch stacks, using 'stack' as the new
     68    stack, and use 'retaddr' as f's return-to address.  Also, clear all
     69    the integer registers before entering f.*/
     70 __attribute__((noreturn))
     71 void ML_(call_on_new_stack_0_1) ( Addr stack,
     72                                   Addr retaddr,
     73                                   void (*f)(Word),
     74                                   Word arg1 );
     75 //    r0 = stack
     76 //    r1 = retaddr
     77 //    r2 = f
     78 //    r3 = arg1
     79 asm(
     80 ".text\n"
     81 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
     82 "vgModuleLocal_call_on_new_stack_0_1:\n"
     83 "   mov    sp,r0\n\t" /* Stack pointer */
     84 "   mov    lr,r1\n\t" /* Return address */
     85 "   mov    r0,r3\n\t" /* First argument */
     86 "   push   {r2}\n\t"  /* So we can ret to the new dest */
     87 "   mov    r1, #0\n\t" /* Clear our GPRs */
     88 "   mov    r2, #0\n\t"
     89 "   mov    r3, #0\n\t"
     90 "   mov    r4, #0\n\t"
     91 "   mov    r5, #0\n\t"
     92 "   mov    r6, #0\n\t"
     93 "   mov    r7, #0\n\t"
     94 "   mov    r8, #0\n\t"
     95 "   mov    r9, #0\n\t"
     96 "   mov    r10, #0\n\t"
     97 "   mov    r11, #0\n\t"
     98 "   mov    r12, #0\n\t"
     99 "   pop    {pc}\n\t"  /* Herrre we go! */
    100 ".previous\n"
    101 );
    102 
    103 
    104 #define __NR_CLONE        VG_STRINGIFY(__NR_clone)
    105 #define __NR_EXIT         VG_STRINGIFY(__NR_exit)
    106 
    107 extern
    108 ULong do_syscall_clone_arm_linux   ( Word (*fn)(void *),
    109                                      void* stack,
    110                                      Int   flags,
    111                                      void* arg,
    112                                      Int*  child_tid,
    113                                      Int*  parent_tid,
    114                                      void* tls );
    115 asm(
    116 ".text\n"
    117 ".globl do_syscall_clone_arm_linux\n"
    118 "do_syscall_clone_arm_linux:\n"
    119 
    120 /*Setup child stack */
    121 "   str     r0, [r1, #-4]!\n"
    122 "   str     r3, [r1, #-4]!\n"
    123 "   push {r4,r7}\n"
    124 "   mov r0, r2\n" /* arg1: flags */
    125 /* r1 (arg2) is already our child's stack */
    126 "   ldr r2, [sp, #12]\n" // parent tid
    127 "   ldr r3, [sp, #16]\n" // tls
    128 "   ldr r4, [sp, #8]\n" // Child tid
    129 "   mov r7, #"__NR_CLONE"\n"
    130 "   svc 0x00000000\n"
    131 "   cmp r0, #0\n"
    132 "   beq 1f\n"
    133 
    134 /* Parent */
    135 "   pop {r4,r7}\n"
    136 "   bx lr\n"
    137 
    138 "1:\n" /*child*/
    139 "   mov     lr, pc\n"
    140 "   pop     {r0,pc}\n"
    141 /* Retval from child is already in r0 */
    142 "   mov r7, #"__NR_EXIT"\n"
    143 "   svc 0x00000000\n"
    144 /* Urh.. why did exit return? */
    145 "   .long 0\n"
    146 "   .previous\n"
    147 );
    148 
    149 #undef __NR_CLONE
    150 #undef __NR_EXIT
    151 
    152 // forward declarations
    153 static void setup_child ( ThreadArchState*, ThreadArchState* );
    154 static void assign_guest_tls(ThreadId ctid, Addr tlsptr);
    155 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
    156 
    157 /*
    158    When a client clones, we need to keep track of the new thread.  This means:
    159    1. allocate a ThreadId+ThreadState+stack for the the thread
    160 
    161    2. initialize the thread's new VCPU state
    162 
    163    3. create the thread using the same args as the client requested,
    164    but using the scheduler entrypoint for IP, and a separate stack
    165    for SP.
    166  */
    167 static SysRes do_clone ( ThreadId ptid,
    168                          UInt flags, Addr sp,
    169                          Int *parent_tidptr,
    170                          Int *child_tidptr,
    171                          Addr child_tls)
    172 {
    173    const Bool debug = False;
    174 
    175    ThreadId ctid = VG_(alloc_ThreadState)();
    176    ThreadState* ptst = VG_(get_ThreadState)(ptid);
    177    ThreadState* ctst = VG_(get_ThreadState)(ctid);
    178    UInt r0;
    179    UWord *stack;
    180    NSegment const* seg;
    181    SysRes res;
    182    vki_sigset_t blockall, savedmask;
    183 
    184    VG_(sigfillset)(&blockall);
    185 
    186    vg_assert(VG_(is_running_thread)(ptid));
    187    vg_assert(VG_(is_valid_tid)(ctid));
    188 
    189    stack = (UWord*)ML_(allocstack)(ctid);
    190 
    191    if(stack == NULL) {
    192       res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
    193       goto out;
    194    }
    195 
    196    setup_child( &ctst->arch, &ptst->arch );
    197 
    198    ctst->arch.vex.guest_R0 = 0;
    199    if(sp != 0)
    200       ctst->arch.vex.guest_R13 = sp;
    201 
    202    ctst->os_state.parent = ptid;
    203 
    204    ctst->sig_mask = ptst->sig_mask;
    205    ctst->tmp_sig_mask = ptst->sig_mask;
    206 
    207    /* Start the child with its threadgroup being the same as the
    208       parent's.  This is so that any exit_group calls that happen
    209       after the child is created but before it sets its
    210       os_state.threadgroup field for real (in thread_wrapper in
    211       syswrap-linux.c), really kill the new thread.  a.k.a this avoids
    212       a race condition in which the thread is unkillable (via
    213       exit_group) because its threadgroup is not set.  The race window
    214       is probably only a few hundred or a few thousand cycles long.
    215       See #226116. */
    216    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
    217 
    218    seg = VG_(am_find_nsegment)((Addr)sp);
    219    if (seg && seg->kind != SkResvn) {
    220       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
    221       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
    222 
    223       VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
    224 
    225       if (debug)
    226          VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
    227          ctid, seg->start, VG_PGROUNDUP(sp));
    228    } else {
    229       VG_(message)(Vg_UserMsg, "!? New thread %d starts with sp+%#lx) unmapped\n", ctid, sp);
    230       ctst->client_stack_szB  = 0;
    231    }
    232 
    233    vg_assert(VG_(owns_BigLock_LL)(ptid));
    234    VG_TRACK ( pre_thread_ll_create, ptid, ctid );
    235 
    236    if (flags & VKI_CLONE_SETTLS) {
    237       /* Just assign the tls pointer in the guest TPIDRURO. */
    238       assign_guest_tls(ctid, child_tls);
    239    }
    240 
    241    flags &= ~VKI_CLONE_SETTLS;
    242 
    243    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
    244 
    245    r0 = do_syscall_clone_arm_linux(
    246       ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
    247       child_tidptr, parent_tidptr, NULL
    248    );
    249    //VG_(printf)("AFTER SYSCALL, %x and %x  CHILD: %d PARENT: %d\n",child_tidptr, parent_tidptr,*child_tidptr,*parent_tidptr);
    250 
    251    res = VG_(mk_SysRes_arm_linux)( r0 );
    252 
    253    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
    254 
    255 out:
    256    if (sr_isError(res)) {
    257       VG_(cleanup_thread)(&ctst->arch);
    258       ctst->status = VgTs_Empty;
    259       VG_TRACK( pre_thread_ll_exit, ctid );
    260    }
    261 
    262    return res;
    263 }
    264 
    265 
    266 
    267 /* ---------------------------------------------------------------------
    268    More thread stuff
    269    ------------------------------------------------------------------ */
    270 
    271 // ARM doesn't have any architecture specific thread stuff that
    272 // needs to be cleaned up
    273 void VG_(cleanup_thread) ( ThreadArchState* arch )
    274 {
    275 }
    276 
    277 void setup_child ( /*OUT*/ ThreadArchState *child,
    278                    /*IN*/  ThreadArchState *parent )
    279 {
    280    child->vex = parent->vex;
    281    child->vex_shadow1 = parent->vex_shadow1;
    282    child->vex_shadow2 = parent->vex_shadow2;
    283 }
    284 
    285 static void assign_guest_tls(ThreadId tid, Addr tlsptr)
    286 {
    287    VG_(threads)[tid].arch.vex.guest_TPIDRURO = tlsptr;
    288 }
    289 
    290 /* Assigns tlsptr to the guest TPIDRURO.
    291    If needed for the specific hardware, really executes
    292    the set_tls syscall.
    293 */
    294 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
    295 {
    296    assign_guest_tls(tid, tlsptr);
    297 #if defined(ANDROID_HARDWARE_emulator)
    298    /* Android emulator does not provide an hw tls register.
    299       So, the tls register is emulated by the kernel.
    300       This emulated value is set by the __NR_ARM_set_tls syscall.
    301       The emulated value must be read by the kernel helper function
    302       located at 0xffff0fe0.
    303 
    304       The emulated tlsptr is located at 0xffff0ff0
    305       (so slightly after the kernel helper function).
    306       Note that applications are not supposed to read this directly.
    307 
    308       For compatibility : if there is a hw tls register, the kernel
    309       will put at 0xffff0fe0 the instructions to read it, so
    310       as to have old applications calling the kernel helper
    311       working properly.
    312 
    313       For having emulated guest TLS working correctly with
    314       Valgrind, it is needed to execute the syscall to set
    315       the emulated TLS value in addition to the assignment
    316       of TPIDRURO.
    317 
    318       Note: the below means that if we need thread local storage
    319       for Valgrind host, then there will be a conflict between
    320       the need of the guest tls and of the host tls.
    321       If all the guest code would cleanly call 0xffff0fe0,
    322       then we might maybe intercept this. However, at least
    323       __libc_preinit reads directly 0xffff0ff0.
    324    */
    325    /* ??? might call the below if auxv->u.a_val & VKI_HWCAP_TLS ???
    326       Unclear if real hardware having tls hw register sets
    327       VKI_HWCAP_TLS. */
    328    return VG_(do_syscall1) (__NR_ARM_set_tls, tlsptr);
    329 #else
    330    return VG_(mk_SysRes_Success)( 0 );
    331 #endif
    332 }
    333 
    334 /* ---------------------------------------------------------------------
    335    PRE/POST wrappers for arm/Linux-specific syscalls
    336    ------------------------------------------------------------------ */
    337 
    338 #define PRE(name)       DEFN_PRE_TEMPLATE(arm_linux, name)
    339 #define POST(name)      DEFN_POST_TEMPLATE(arm_linux, name)
    340 
    341 /* Add prototypes for the wrappers declared here, so that gcc doesn't
    342    harass us for not having prototypes.  Really this is a kludge --
    343    the right thing to do is to make these wrappers 'static' since they
    344    aren't visible outside this file, but that requires even more macro
    345    magic. */
    346 
    347 DECL_TEMPLATE(arm_linux, sys_mmap2);
    348 DECL_TEMPLATE(arm_linux, sys_stat64);
    349 DECL_TEMPLATE(arm_linux, sys_lstat64);
    350 DECL_TEMPLATE(arm_linux, sys_fstatat64);
    351 DECL_TEMPLATE(arm_linux, sys_fstat64);
    352 DECL_TEMPLATE(arm_linux, sys_clone);
    353 DECL_TEMPLATE(arm_linux, sys_sigreturn);
    354 DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
    355 DECL_TEMPLATE(arm_linux, sys_sigsuspend);
    356 DECL_TEMPLATE(arm_linux, sys_set_tls);
    357 DECL_TEMPLATE(arm_linux, sys_cacheflush);
    358 DECL_TEMPLATE(arm_linux, sys_ptrace);
    359 
    360 PRE(sys_mmap2)
    361 {
    362    SysRes r;
    363 
    364    // Exactly like old_mmap() except:
    365    //  - all 6 args are passed in regs, rather than in a memory-block.
    366    //  - the file offset is specified in pagesize units rather than bytes,
    367    //    so that it can be used for files bigger than 2^32 bytes.
    368    // pagesize or 4K-size units in offset?  For ppc32/64-linux, this is
    369    // 4K-sized.  Assert that the page size is 4K here for safety.
    370    vg_assert(VKI_PAGE_SIZE == 4096);
    371    PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
    372          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
    373    PRE_REG_READ6(long, "mmap2",
    374                  unsigned long, start, unsigned long, length,
    375                  unsigned long, prot,  unsigned long, flags,
    376                  unsigned long, fd,    unsigned long, offset);
    377 
    378    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
    379                                        4096 * (Off64T)ARG6 );
    380    SET_STATUS_from_SysRes(r);
    381 }
    382 
    383 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
    384 // applicable to every architecture -- I think only to 32-bit archs.
    385 // We're going to need something like linux/core_os32.h for such
    386 // things, eventually, I think.  --njn
    387 PRE(sys_lstat64)
    388 {
    389    PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
    390    PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
    391    PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
    392    PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
    393 }
    394 
    395 POST(sys_lstat64)
    396 {
    397    vg_assert(SUCCESS);
    398    if (RES == 0) {
    399       POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    400    }
    401 }
    402 
    403 PRE(sys_stat64)
    404 {
    405    PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
    406    PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
    407    PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
    408    PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
    409 }
    410 
    411 POST(sys_stat64)
    412 {
    413    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    414 }
    415 
    416 PRE(sys_fstatat64)
    417 {
    418    PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
    419    PRE_REG_READ3(long, "fstatat64",
    420                  int, dfd, char *, file_name, struct stat64 *, buf);
    421    PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
    422    PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
    423 }
    424 
    425 POST(sys_fstatat64)
    426 {
    427    POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
    428 }
    429 
    430 PRE(sys_fstat64)
    431 {
    432    PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
    433    PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
    434    PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
    435 }
    436 
    437 POST(sys_fstat64)
    438 {
    439    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    440 }
    441 
    442 PRE(sys_clone)
    443 {
    444     UInt cloneflags;
    445 
    446    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
    447    PRE_REG_READ5(int, "clone",
    448                  unsigned long, flags,
    449                  void *, child_stack,
    450                  int *, parent_tidptr,
    451                  void *, child_tls,
    452                  int *, child_tidptr);
    453 
    454    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
    455       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
    456       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
    457                                              VKI_PROT_WRITE)) {
    458          SET_STATUS_Failure( VKI_EFAULT );
    459          return;
    460       }
    461    }
    462    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
    463       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
    464       if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
    465                                              VKI_PROT_WRITE)) {
    466          SET_STATUS_Failure( VKI_EFAULT );
    467          return;
    468       }
    469    }
    470    if (ARG1 & VKI_CLONE_SETTLS) {
    471       PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
    472       if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
    473                                              VKI_PROT_READ)) {
    474          SET_STATUS_Failure( VKI_EFAULT );
    475          return;
    476       }
    477    }
    478 
    479    cloneflags = ARG1;
    480 
    481    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
    482       SET_STATUS_Failure( VKI_EINVAL );
    483       return;
    484    }
    485 
    486    /* Only look at the flags we really care about */
    487    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
    488                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    489    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
    490       /* thread creation */
    491       SET_STATUS_from_SysRes(
    492          do_clone(tid,
    493                   ARG1,         /* flags */
    494                   (Addr)ARG2,   /* child ESP */
    495                   (Int *)ARG3,  /* parent_tidptr */
    496                   (Int *)ARG5,  /* child_tidptr */
    497                   (Addr)ARG4)); /* set_tls */
    498       break;
    499 
    500    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
    501       /* FALLTHROUGH - assume vfork == fork */
    502       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
    503 
    504    case 0: /* plain fork */
    505       SET_STATUS_from_SysRes(
    506          ML_(do_fork_clone)(tid,
    507                        cloneflags,      /* flags */
    508                        (Int *)ARG3,     /* parent_tidptr */
    509                        (Int *)ARG5));   /* child_tidptr */
    510       break;
    511 
    512    default:
    513       /* should we just ENOSYS? */
    514       VG_(message)(Vg_UserMsg, "");
    515       VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
    516       VG_(message)(Vg_UserMsg, "");
    517       VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
    518       VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
    519       VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
    520       VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
    521       VG_(unimplemented)
    522          ("Valgrind does not support general clone().");
    523    }
    524 
    525    if (SUCCESS) {
    526       if (ARG1 & VKI_CLONE_PARENT_SETTID)
    527          POST_MEM_WRITE(ARG3, sizeof(Int));
    528       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
    529          POST_MEM_WRITE(ARG5, sizeof(Int));
    530 
    531       /* Thread creation was successful; let the child have the chance
    532          to run */
    533       *flags |= SfYieldAfter;
    534    }
    535 }
    536 
    537 PRE(sys_sigreturn)
    538 {
    539    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
    540      an explanation of what follows. */
    541 
    542    PRINT("sys_sigreturn ( )");
    543 
    544    vg_assert(VG_(is_valid_tid)(tid));
    545    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    546    vg_assert(VG_(is_running_thread)(tid));
    547 
    548    /* Restore register state from frame and remove it */
    549    VG_(sigframe_destroy)(tid, False);
    550 
    551    /* Tell the driver not to update the guest state with the "result",
    552       and set a bogus result to keep it happy. */
    553    *flags |= SfNoWriteResult;
    554    SET_STATUS_Success(0);
    555 
    556    /* Check to see if any signals arose as a result of this. */
    557    *flags |= SfPollAfter;
    558 }
    559 
    560 PRE(sys_rt_sigreturn)
    561 {
    562   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
    563       an explanation of what follows. */
    564 
    565    PRINT("rt_sigreturn ( )");
    566 
    567    vg_assert(VG_(is_valid_tid)(tid));
    568    vg_assert(tid >= 1 && tid < VG_N_THREADS);
    569    vg_assert(VG_(is_running_thread)(tid));
    570 
    571    /* Restore register state from frame and remove it */
    572    VG_(sigframe_destroy)(tid, True);
    573 
    574    /* Tell the driver not to update the guest state with the "result",
    575       and set a bogus result to keep it happy. */
    576    *flags |= SfNoWriteResult;
    577    SET_STATUS_Success(0);
    578 
    579    /* Check to see if any signals arose as a result of this. */
    580    *flags |= SfPollAfter;
    581 }
    582 
    583 /* NB: clone of x86-linux version, and ppc32-linux has an almost
    584    identical one. */
    585 PRE(sys_sigsuspend)
    586 {
    587    /* The C library interface to sigsuspend just takes a pointer to
    588       a signal mask but this system call has three arguments - the first
    589       two don't appear to be used by the kernel and are always passed as
    590       zero by glibc and the third is the first word of the signal mask
    591       so only 32 signals are supported.
    592 
    593       In fact glibc normally uses rt_sigsuspend if it is available as
    594       that takes a pointer to the signal mask so supports more signals.
    595     */
    596    *flags |= SfMayBlock;
    597    PRINT("sys_sigsuspend ( %ld, %ld, %ld )", ARG1,ARG2,ARG3 );
    598    PRE_REG_READ3(int, "sigsuspend",
    599                  int, history0, int, history1,
    600                  vki_old_sigset_t, mask);
    601 }
    602 
    603 /* Very much ARM specific */
    604 
    605 PRE(sys_set_tls)
    606 {
    607    PRINT("set_tls (%lx)",ARG1);
    608    PRE_REG_READ1(long, "set_tls", unsigned long, addr);
    609 
    610    SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
    611 }
    612 
    613 PRE(sys_cacheflush)
    614 {
    615    PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3);
    616    PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags);
    617    VG_(discard_translations)( (Addr64)ARG1,
    618                               ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/,
    619                               "PRE(sys_cacheflush)" );
    620    SET_STATUS_Success(0);
    621 }
    622 
    623 // ARG3 is only used for pointers into the traced process's address
    624 // space and for offsets into the traced process's struct
    625 // user_regs_struct. It is never a pointer into this process's memory
    626 // space, and we should therefore not check anything it points to.
    627 PRE(sys_ptrace)
    628 {
    629    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
    630    PRE_REG_READ4(int, "ptrace",
    631                  long, request, long, pid, long, addr, long, data);
    632    switch (ARG1) {
    633    case VKI_PTRACE_PEEKTEXT:
    634    case VKI_PTRACE_PEEKDATA:
    635    case VKI_PTRACE_PEEKUSR:
    636       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
    637 		     sizeof (long));
    638       break;
    639    case VKI_PTRACE_GETREGS:
    640       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
    641 		     sizeof (struct vki_user_regs_struct));
    642       break;
    643    case VKI_PTRACE_GETFPREGS:
    644       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
    645 		     sizeof (struct vki_user_fp));
    646       break;
    647    case VKI_PTRACE_GETWMMXREGS:
    648       PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4,
    649 		     VKI_IWMMXT_SIZE);
    650       break;
    651    case VKI_PTRACE_GETCRUNCHREGS:
    652       PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4,
    653 		     VKI_CRUNCH_SIZE);
    654       break;
    655    case VKI_PTRACE_GETVFPREGS:
    656       PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4,
    657                      sizeof (struct vki_user_vfp) );
    658       break;
    659    case VKI_PTRACE_GETHBPREGS:
    660       PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4,
    661                      sizeof (unsigned long) );
    662       break;
    663    case VKI_PTRACE_SETREGS:
    664       PRE_MEM_READ( "ptrace(setregs)", ARG4,
    665 		     sizeof (struct vki_user_regs_struct));
    666       break;
    667    case VKI_PTRACE_SETFPREGS:
    668       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
    669 		     sizeof (struct vki_user_fp));
    670       break;
    671    case VKI_PTRACE_SETWMMXREGS:
    672       PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4,
    673 		     VKI_IWMMXT_SIZE);
    674       break;
    675    case VKI_PTRACE_SETCRUNCHREGS:
    676       PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4,
    677 		     VKI_CRUNCH_SIZE);
    678       break;
    679    case VKI_PTRACE_SETVFPREGS:
    680       PRE_MEM_READ( "ptrace(setvfpregs)", ARG4,
    681                      sizeof (struct vki_user_vfp));
    682       break;
    683    case VKI_PTRACE_SETHBPREGS:
    684       PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long));
    685       break;
    686    case VKI_PTRACE_GET_THREAD_AREA:
    687       PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long));
    688       break;
    689    case VKI_PTRACE_GETEVENTMSG:
    690       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
    691       break;
    692    case VKI_PTRACE_GETSIGINFO:
    693       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
    694       break;
    695    case VKI_PTRACE_SETSIGINFO:
    696       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
    697       break;
    698    case VKI_PTRACE_GETREGSET:
    699       ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
    700       break;
    701    case VKI_PTRACE_SETREGSET:
    702       ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
    703       break;
    704    default:
    705       break;
    706    }
    707 }
    708 
    709 POST(sys_ptrace)
    710 {
    711    switch (ARG1) {
    712    case VKI_PTRACE_PEEKTEXT:
    713    case VKI_PTRACE_PEEKDATA:
    714    case VKI_PTRACE_PEEKUSR:
    715       POST_MEM_WRITE( ARG4, sizeof (long));
    716       break;
    717    case VKI_PTRACE_GETREGS:
    718       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
    719       break;
    720    case VKI_PTRACE_GETFPREGS:
    721       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp));
    722       break;
    723    case VKI_PTRACE_GETWMMXREGS:
    724       POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE);
    725       break;
    726    case VKI_PTRACE_GETCRUNCHREGS:
    727       POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE);
    728       break;
    729    case VKI_PTRACE_GETVFPREGS:
    730       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp));
    731       break;
    732    case VKI_PTRACE_GET_THREAD_AREA:
    733    case VKI_PTRACE_GETHBPREGS:
    734    case VKI_PTRACE_GETEVENTMSG:
    735       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
    736       break;
    737    case VKI_PTRACE_GETSIGINFO:
    738       /* XXX: This is a simplification. Different parts of the
    739        * siginfo_t are valid depending on the type of signal.
    740        */
    741       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
    742       break;
    743    case VKI_PTRACE_GETREGSET:
    744       ML_(linux_POST_getregset)(tid, ARG3, ARG4);
    745       break;
    746    default:
    747       break;
    748    }
    749 }
    750 
    751 #undef PRE
    752 #undef POST
    753 
    754 /* ---------------------------------------------------------------------
    755    The arm/Linux syscall table
    756    ------------------------------------------------------------------ */
    757 
    758 #if 0
    759 #define __NR_OABI_SYSCALL_BASE 0x900000
    760 #else
    761 #define __NR_OABI_SYSCALL_BASE 0x0
    762 #endif
    763 
    764 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(arm_linux, sysno, name)
    765 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(arm_linux, sysno, name)
    766 
    767 // This table maps from __NR_xxx syscall numbers (from
    768 // linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo()
    769 // wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S).
    770 //
    771 // For those syscalls not handled by Valgrind, the annotation indicate its
    772 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
    773 // (unknown).
    774 
    775 static SyscallTableEntry syscall_main_table[] = {
    776 //zz    //   (restart_syscall)                             // 0
    777    GENX_(__NR_exit,              sys_exit),           // 1
    778    GENX_(__NR_fork,              sys_fork),           // 2
    779    GENXY(__NR_read,              sys_read),           // 3
    780    GENX_(__NR_write,             sys_write),          // 4
    781 
    782    GENXY(__NR_open,              sys_open),           // 5
    783    GENXY(__NR_close,             sys_close),          // 6
    784 //   GENXY(__NR_waitpid,           sys_waitpid),        // 7
    785    GENXY(__NR_creat,             sys_creat),          // 8
    786    GENX_(__NR_link,              sys_link),           // 9
    787 
    788    GENX_(__NR_unlink,            sys_unlink),         // 10
    789    GENX_(__NR_execve,            sys_execve),         // 11
    790    GENX_(__NR_chdir,             sys_chdir),          // 12
    791    GENXY(__NR_time,              sys_time),           // 13
    792    GENX_(__NR_mknod,             sys_mknod),          // 14
    793 
    794    GENX_(__NR_chmod,             sys_chmod),          // 15
    795 //zz    LINX_(__NR_lchown,            sys_lchown16),       // 16
    796 //   GENX_(__NR_break,             sys_ni_syscall),     // 17
    797 //zz    //   (__NR_oldstat,           sys_stat),           // 18 (obsolete)
    798    LINX_(__NR_lseek,             sys_lseek),          // 19
    799 
    800    GENX_(__NR_getpid,            sys_getpid),         // 20
    801    LINX_(__NR_mount,             sys_mount),          // 21
    802    LINX_(__NR_umount,            sys_oldumount),      // 22
    803    LINX_(__NR_setuid,            sys_setuid16),       // 23 ## P
    804    LINX_(__NR_getuid,            sys_getuid16),       // 24 ## P
    805 //zz
    806 //zz    //   (__NR_stime,             sys_stime),          // 25 * (SVr4,SVID,X/OPEN)
    807    PLAXY(__NR_ptrace,            sys_ptrace),         // 26
    808    GENX_(__NR_alarm,             sys_alarm),          // 27
    809 //zz    //   (__NR_oldfstat,          sys_fstat),          // 28 * L -- obsolete
    810    GENX_(__NR_pause,             sys_pause),          // 29
    811 
    812    LINX_(__NR_utime,             sys_utime),          // 30
    813 //   GENX_(__NR_stty,              sys_ni_syscall),     // 31
    814 //   GENX_(__NR_gtty,              sys_ni_syscall),     // 32
    815    GENX_(__NR_access,            sys_access),         // 33
    816    GENX_(__NR_nice,              sys_nice),           // 34
    817 
    818 //   GENX_(__NR_ftime,             sys_ni_syscall),     // 35
    819    GENX_(__NR_sync,              sys_sync),           // 36
    820    GENX_(__NR_kill,              sys_kill),           // 37
    821    GENX_(__NR_rename,            sys_rename),         // 38
    822    GENX_(__NR_mkdir,             sys_mkdir),          // 39
    823 
    824    GENX_(__NR_rmdir,             sys_rmdir),          // 40
    825    GENXY(__NR_dup,               sys_dup),            // 41
    826    LINXY(__NR_pipe,              sys_pipe),           // 42
    827    GENXY(__NR_times,             sys_times),          // 43
    828 //   GENX_(__NR_prof,              sys_ni_syscall),     // 44
    829 //zz
    830    GENX_(__NR_brk,               sys_brk),            // 45
    831    LINX_(__NR_setgid,            sys_setgid16),       // 46
    832    LINX_(__NR_getgid,            sys_getgid16),       // 47
    833 //zz    //   (__NR_signal,            sys_signal),         // 48 */* (ANSI C)
    834    LINX_(__NR_geteuid,           sys_geteuid16),      // 49
    835 
    836    LINX_(__NR_getegid,           sys_getegid16),      // 50
    837    GENX_(__NR_acct,              sys_acct),           // 51
    838    LINX_(__NR_umount2,           sys_umount),         // 52
    839 //   GENX_(__NR_lock,              sys_ni_syscall),     // 53
    840    LINXY(__NR_ioctl,             sys_ioctl),          // 54
    841 
    842    LINXY(__NR_fcntl,             sys_fcntl),          // 55
    843 //   GENX_(__NR_mpx,               sys_ni_syscall),     // 56
    844    GENX_(__NR_setpgid,           sys_setpgid),        // 57
    845 //   GENX_(__NR_ulimit,            sys_ni_syscall),     // 58
    846 //zz    //   (__NR_oldolduname,       sys_olduname),       // 59 Linux -- obsolete
    847 //zz
    848    GENX_(__NR_umask,             sys_umask),          // 60
    849    GENX_(__NR_chroot,            sys_chroot),         // 61
    850 //zz    //   (__NR_ustat,             sys_ustat)           // 62 SVr4 -- deprecated
    851    GENXY(__NR_dup2,              sys_dup2),           // 63
    852    GENX_(__NR_getppid,           sys_getppid),        // 64
    853 
    854    GENX_(__NR_getpgrp,           sys_getpgrp),        // 65
    855    GENX_(__NR_setsid,            sys_setsid),         // 66
    856    LINXY(__NR_sigaction,         sys_sigaction),      // 67
    857 //zz    //   (__NR_sgetmask,          sys_sgetmask),       // 68 */* (ANSI C)
    858 //zz    //   (__NR_ssetmask,          sys_ssetmask),       // 69 */* (ANSI C)
    859 //zz
    860    LINX_(__NR_setreuid,          sys_setreuid16),     // 70
    861    LINX_(__NR_setregid,          sys_setregid16),     // 71
    862    PLAX_(__NR_sigsuspend,        sys_sigsuspend),     // 72
    863    LINXY(__NR_sigpending,        sys_sigpending),     // 73
    864 //zz    //   (__NR_sethostname,       sys_sethostname),    // 74 */*
    865 //zz
    866    GENX_(__NR_setrlimit,         sys_setrlimit),      // 75
    867    GENXY(__NR_getrlimit,         sys_old_getrlimit),  // 76
    868    GENXY(__NR_getrusage,         sys_getrusage),      // 77
    869    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 78
    870    GENX_(__NR_settimeofday,      sys_settimeofday),   // 79
    871 
    872    LINXY(__NR_getgroups,         sys_getgroups16),    // 80
    873    LINX_(__NR_setgroups,         sys_setgroups16),    // 81
    874 //   PLAX_(__NR_select,            old_select),         // 82
    875    GENX_(__NR_symlink,           sys_symlink),        // 83
    876 //zz    //   (__NR_oldlstat,          sys_lstat),          // 84 -- obsolete
    877 //zz
    878    GENX_(__NR_readlink,          sys_readlink),       // 85
    879 //zz    //   (__NR_uselib,            sys_uselib),         // 86 */Linux
    880 //zz    //   (__NR_swapon,            sys_swapon),         // 87 */Linux
    881 //zz    //   (__NR_reboot,            sys_reboot),         // 88 */Linux
    882 //zz    //   (__NR_readdir,           old_readdir),        // 89 -- superseded
    883 //zz
    884 //   _____(__NR_mmap,              old_mmap),           // 90
    885    GENXY(__NR_munmap,            sys_munmap),         // 91
    886    GENX_(__NR_truncate,          sys_truncate),       // 92
    887    GENX_(__NR_ftruncate,         sys_ftruncate),      // 93
    888    GENX_(__NR_fchmod,            sys_fchmod),         // 94
    889 
    890    LINX_(__NR_fchown,            sys_fchown16),       // 95
    891    GENX_(__NR_getpriority,       sys_getpriority),    // 96
    892    GENX_(__NR_setpriority,       sys_setpriority),    // 97
    893 //   GENX_(__NR_profil,            sys_ni_syscall),     // 98
    894    GENXY(__NR_statfs,            sys_statfs),         // 99
    895 
    896    GENXY(__NR_fstatfs,           sys_fstatfs),        // 100
    897 //   LINX_(__NR_ioperm,            sys_ioperm),         // 101
    898    LINXY(__NR_socketcall,        sys_socketcall),     // 102
    899    LINXY(__NR_syslog,            sys_syslog),         // 103
    900    GENXY(__NR_setitimer,         sys_setitimer),      // 104
    901 
    902    GENXY(__NR_getitimer,         sys_getitimer),      // 105
    903    GENXY(__NR_stat,              sys_newstat),        // 106
    904    GENXY(__NR_lstat,             sys_newlstat),       // 107
    905    GENXY(__NR_fstat,             sys_newfstat),       // 108
    906 //zz    //   (__NR_olduname,          sys_uname),          // 109 -- obsolete
    907 //zz
    908 //   GENX_(__NR_iopl,              sys_iopl),           // 110
    909    LINX_(__NR_vhangup,           sys_vhangup),        // 111
    910 //   GENX_(__NR_idle,              sys_ni_syscall),     // 112
    911 // PLAXY(__NR_vm86old,           sys_vm86old),        // 113 __NR_syscall... weird
    912    GENXY(__NR_wait4,             sys_wait4),          // 114
    913 //zz
    914 //zz    //   (__NR_swapoff,           sys_swapoff),        // 115 */Linux
    915    LINXY(__NR_sysinfo,           sys_sysinfo),        // 116
    916 //   _____(__NR_ipc,               sys_ipc),            // 117
    917    GENX_(__NR_fsync,             sys_fsync),          // 118
    918    PLAX_(__NR_sigreturn,         sys_sigreturn),      // 119 ?/Linux
    919 
    920    PLAX_(__NR_clone,             sys_clone),          // 120
    921 //zz    //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
    922    GENXY(__NR_uname,             sys_newuname),       // 122
    923 //   PLAX_(__NR_modify_ldt,        sys_modify_ldt),     // 123
    924 //zz    LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
    925 //zz
    926    GENXY(__NR_mprotect,          sys_mprotect),       // 125
    927    LINXY(__NR_sigprocmask,       sys_sigprocmask),    // 126
    928 //zz    // Nb: create_module() was removed 2.4-->2.6
    929 //   GENX_(__NR_create_module,     sys_ni_syscall),     // 127
    930    LINX_(__NR_init_module,       sys_init_module),    // 128
    931    LINX_(__NR_delete_module,     sys_delete_module),  // 129
    932 //zz
    933 //zz    // Nb: get_kernel_syms() was removed 2.4-->2.6
    934 //   GENX_(__NR_get_kernel_syms,   sys_ni_syscall),     // 130
    935    LINX_(__NR_quotactl,          sys_quotactl),       // 131
    936    GENX_(__NR_getpgid,           sys_getpgid),        // 132
    937    GENX_(__NR_fchdir,            sys_fchdir),         // 133
    938 //zz    //   (__NR_bdflush,           sys_bdflush),        // 134 */Linux
    939 //zz
    940 //zz    //   (__NR_sysfs,             sys_sysfs),          // 135 SVr4
    941    LINX_(__NR_personality,       sys_personality),    // 136
    942 //   GENX_(__NR_afs_syscall,       sys_ni_syscall),     // 137
    943    LINX_(__NR_setfsuid,          sys_setfsuid16),     // 138
    944    LINX_(__NR_setfsgid,          sys_setfsgid16),     // 139
    945 
    946    LINXY(__NR__llseek,           sys_llseek),         // 140
    947    GENXY(__NR_getdents,          sys_getdents),       // 141
    948    GENX_(__NR__newselect,        sys_select),         // 142
    949    GENX_(__NR_flock,             sys_flock),          // 143
    950    GENX_(__NR_msync,             sys_msync),          // 144
    951 
    952    GENXY(__NR_readv,             sys_readv),          // 145
    953    GENX_(__NR_writev,            sys_writev),         // 146
    954    GENX_(__NR_getsid,            sys_getsid),         // 147
    955    GENX_(__NR_fdatasync,         sys_fdatasync),      // 148
    956    LINXY(__NR__sysctl,           sys_sysctl),         // 149
    957 
    958    GENX_(__NR_mlock,             sys_mlock),          // 150
    959    GENX_(__NR_munlock,           sys_munlock),        // 151
    960    GENX_(__NR_mlockall,          sys_mlockall),       // 152
    961    LINX_(__NR_munlockall,        sys_munlockall),     // 153
    962    LINXY(__NR_sched_setparam,    sys_sched_setparam), // 154
    963 
    964    LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
    965    LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
    966    LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
    967    LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
    968    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
    969 
    970    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
    971 //zz    //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
    972    GENXY(__NR_nanosleep,         sys_nanosleep),      // 162
    973    GENX_(__NR_mremap,            sys_mremap),         // 163
    974    LINX_(__NR_setresuid,         sys_setresuid16),    // 164
    975 
    976    LINXY(__NR_getresuid,         sys_getresuid16),    // 165
    977 //   PLAXY(__NR_vm86,              sys_vm86),           // 166 x86/Linux-only
    978 //   GENX_(__NR_query_module,      sys_ni_syscall),     // 167
    979    GENXY(__NR_poll,              sys_poll),           // 168
    980 //zz    //   (__NR_nfsservctl,        sys_nfsservctl),     // 169 */Linux
    981 //zz
    982    LINX_(__NR_setresgid,         sys_setresgid16),    // 170
    983    LINXY(__NR_getresgid,         sys_getresgid16),    // 171
    984    LINXY(__NR_prctl,             sys_prctl),          // 172
    985    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 173
    986    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 174
    987 
    988    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 175
    989    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 176
    990    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 177
    991    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 178
    992    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 179
    993 
    994    GENXY(__NR_pread64,           sys_pread64),        // 180
    995    GENX_(__NR_pwrite64,          sys_pwrite64),       // 181
    996    LINX_(__NR_chown,             sys_chown16),        // 182
    997    GENXY(__NR_getcwd,            sys_getcwd),         // 183
    998    LINXY(__NR_capget,            sys_capget),         // 184
    999 
   1000    LINX_(__NR_capset,            sys_capset),         // 185
   1001    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 186
   1002    LINXY(__NR_sendfile,          sys_sendfile),       // 187
   1003 //   GENXY(__NR_getpmsg,           sys_getpmsg),        // 188
   1004 //   GENX_(__NR_putpmsg,           sys_putpmsg),        // 189
   1005 
   1006    // Nb: we treat vfork as fork
   1007    GENX_(__NR_vfork,             sys_fork),           // 190
   1008    GENXY(__NR_ugetrlimit,        sys_getrlimit),      // 191
   1009    PLAX_(__NR_mmap2,             sys_mmap2),          // 192
   1010    GENX_(__NR_truncate64,        sys_truncate64),     // 193
   1011    GENX_(__NR_ftruncate64,       sys_ftruncate64),    // 194
   1012 
   1013    PLAXY(__NR_stat64,            sys_stat64),         // 195
   1014    PLAXY(__NR_lstat64,           sys_lstat64),        // 196
   1015    PLAXY(__NR_fstat64,           sys_fstat64),        // 197
   1016    GENX_(__NR_lchown32,          sys_lchown),         // 198
   1017    GENX_(__NR_getuid32,          sys_getuid),         // 199
   1018 
   1019    GENX_(__NR_getgid32,          sys_getgid),         // 200
   1020    GENX_(__NR_geteuid32,         sys_geteuid),        // 201
   1021    GENX_(__NR_getegid32,         sys_getegid),        // 202
   1022    GENX_(__NR_setreuid32,        sys_setreuid),       // 203
   1023    GENX_(__NR_setregid32,        sys_setregid),       // 204
   1024 
   1025    GENXY(__NR_getgroups32,       sys_getgroups),      // 205
   1026    GENX_(__NR_setgroups32,       sys_setgroups),      // 206
   1027    GENX_(__NR_fchown32,          sys_fchown),         // 207
   1028    LINX_(__NR_setresuid32,       sys_setresuid),      // 208
   1029    LINXY(__NR_getresuid32,       sys_getresuid),      // 209
   1030 
   1031    LINX_(__NR_setresgid32,       sys_setresgid),      // 210
   1032    LINXY(__NR_getresgid32,       sys_getresgid),      // 211
   1033    GENX_(__NR_chown32,           sys_chown),          // 212
   1034    GENX_(__NR_setuid32,          sys_setuid),         // 213
   1035    GENX_(__NR_setgid32,          sys_setgid),         // 214
   1036 
   1037    LINX_(__NR_setfsuid32,        sys_setfsuid),       // 215
   1038    LINX_(__NR_setfsgid32,        sys_setfsgid),       // 216
   1039 //zz    //   (__NR_pivot_root,        sys_pivot_root),     // 217 */Linux
   1040    GENXY(__NR_mincore,           sys_mincore),        // 218
   1041    GENX_(__NR_madvise,           sys_madvise),        // 219
   1042 
   1043    GENXY(__NR_getdents64,        sys_getdents64),     // 220
   1044    LINXY(__NR_fcntl64,           sys_fcntl64),        // 221
   1045 //   GENX_(222,                    sys_ni_syscall),     // 222
   1046 //   PLAXY(223,                    sys_syscall223),     // 223 // sys_bproc?
   1047    LINX_(__NR_gettid,            sys_gettid),         // 224
   1048 
   1049    LINX_(__NR_readahead,         sys_readahead),      // 225 */Linux
   1050    LINX_(__NR_setxattr,          sys_setxattr),       // 226
   1051    LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 227
   1052    LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 228
   1053    LINXY(__NR_getxattr,          sys_getxattr),       // 229
   1054 
   1055    LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 230
   1056    LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 231
   1057    LINXY(__NR_listxattr,         sys_listxattr),      // 232
   1058    LINXY(__NR_llistxattr,        sys_llistxattr),     // 233
   1059    LINXY(__NR_flistxattr,        sys_flistxattr),     // 234
   1060 
   1061    LINX_(__NR_removexattr,       sys_removexattr),    // 235
   1062    LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 236
   1063    LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 237
   1064    LINXY(__NR_tkill,             sys_tkill),          // 238 */Linux
   1065    LINXY(__NR_sendfile64,        sys_sendfile64),     // 239
   1066 
   1067    LINXY(__NR_futex,             sys_futex),             // 240
   1068    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
   1069    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
   1070 //   PLAX_(__NR_set_thread_area,   sys_set_thread_area),   // 243
   1071 //   PLAX_(__NR_get_thread_area,   sys_get_thread_area),   // 244
   1072 
   1073    LINXY(__NR_io_setup,          sys_io_setup),       // 245
   1074    LINX_(__NR_io_destroy,        sys_io_destroy),     // 246
   1075    LINXY(__NR_io_getevents,      sys_io_getevents),   // 247
   1076    LINX_(__NR_io_submit,         sys_io_submit),      // 248
   1077    LINXY(__NR_io_cancel,         sys_io_cancel),      // 249
   1078 
   1079 //   LINX_(__NR_fadvise64,         sys_fadvise64),      // 250 */(Linux?)
   1080    GENX_(251,                    sys_ni_syscall),     // 251
   1081    LINX_(__NR_exit_group,        sys_exit_group),     // 252
   1082 //   GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 253
   1083    LINXY(__NR_epoll_create,      sys_epoll_create),   // 254
   1084 
   1085    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 255
   1086    LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 256
   1087 //zz    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 257 */Linux
   1088    LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 258
   1089    LINXY(__NR_timer_create,      sys_timer_create),      // 259
   1090 
   1091    LINXY(__NR_timer_settime,     sys_timer_settime),  // (timer_create+1)
   1092    LINXY(__NR_timer_gettime,     sys_timer_gettime),  // (timer_create+2)
   1093    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),//(timer_create+3)
   1094    LINX_(__NR_timer_delete,      sys_timer_delete),   // (timer_create+4)
   1095    LINX_(__NR_clock_settime,     sys_clock_settime),  // (timer_create+5)
   1096 
   1097    LINXY(__NR_clock_gettime,     sys_clock_gettime),  // (timer_create+6)
   1098    LINXY(__NR_clock_getres,      sys_clock_getres),   // (timer_create+7)
   1099    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// (timer_create+8) */*
   1100    GENXY(__NR_statfs64,          sys_statfs64),       // 268
   1101    GENXY(__NR_fstatfs64,         sys_fstatfs64),      // 269
   1102 
   1103    LINX_(__NR_tgkill,            sys_tgkill),         // 270 */Linux
   1104    GENX_(__NR_utimes,            sys_utimes),         // 271
   1105 //   LINX_(__NR_fadvise64_64,      sys_fadvise64_64),   // 272 */(Linux?)
   1106    GENX_(__NR_vserver,           sys_ni_syscall),     // 273
   1107    LINX_(__NR_mbind,             sys_mbind),          // 274 ?/?
   1108 
   1109    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 275 ?/?
   1110    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 276 ?/?
   1111    LINXY(__NR_mq_open,           sys_mq_open),        // 277
   1112    LINX_(__NR_mq_unlink,         sys_mq_unlink),      // (mq_open+1)
   1113    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // (mq_open+2)
   1114 
   1115    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// (mq_open+3)
   1116    LINX_(__NR_mq_notify,         sys_mq_notify),      // (mq_open+4)
   1117    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // (mq_open+5)
   1118    LINXY(__NR_waitid,            sys_waitid),         // 280
   1119 
   1120    LINXY(__NR_socket,            sys_socket),         // 281
   1121    LINX_(__NR_bind,              sys_bind),           // 282
   1122    LINX_(__NR_connect,           sys_connect),        // 283
   1123    LINX_(__NR_listen,            sys_listen),         // 284
   1124    LINXY(__NR_accept,            sys_accept),         // 285
   1125    LINXY(__NR_getsockname,       sys_getsockname),    // 286
   1126    LINXY(__NR_getpeername,       sys_getpeername),    // 287
   1127    LINXY(__NR_socketpair,        sys_socketpair),     // 288
   1128    LINX_(__NR_send,              sys_send),
   1129    LINX_(__NR_sendto,            sys_sendto),         // 290
   1130    LINXY(__NR_recv,              sys_recv),
   1131    LINXY(__NR_recvfrom,          sys_recvfrom),       // 292
   1132    LINX_(__NR_shutdown,          sys_shutdown),       // 293
   1133    LINX_(__NR_setsockopt,        sys_setsockopt),     // 294
   1134    LINXY(__NR_getsockopt,        sys_getsockopt),     // 295
   1135    LINX_(__NR_sendmsg,           sys_sendmsg),        // 296
   1136    LINXY(__NR_recvmsg,           sys_recvmsg),        // 297
   1137    LINX_(__NR_semop,             sys_semop),          // 298
   1138    LINX_(__NR_semget,            sys_semget),         // 299
   1139    LINXY(__NR_semctl,            sys_semctl),         // 300
   1140    LINX_(__NR_msgget,            sys_msgget),
   1141    LINX_(__NR_msgsnd,            sys_msgsnd),
   1142    LINXY(__NR_msgrcv,            sys_msgrcv),
   1143    LINXY(__NR_msgctl,            sys_msgctl),         // 304
   1144    LINX_(__NR_semtimedop,        sys_semtimedop),     // 312
   1145 
   1146    LINX_(__NR_add_key,           sys_add_key),        // 286
   1147    LINX_(__NR_request_key,       sys_request_key),    // 287
   1148    LINXY(__NR_keyctl,            sys_keyctl),         // not 288...
   1149 //   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 289
   1150 
   1151 //   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 290
   1152    LINX_(__NR_inotify_init,    sys_inotify_init),   // 291
   1153    LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
   1154    LINX_(__NR_inotify_rm_watch,    sys_inotify_rm_watch), // 293
   1155 //   LINX_(__NR_migrate_pages,    sys_migrate_pages),    // 294
   1156 
   1157    LINXY(__NR_openat,       sys_openat),           // 295
   1158    LINX_(__NR_mkdirat,       sys_mkdirat),          // 296
   1159    LINX_(__NR_mknodat,       sys_mknodat),          // 297
   1160    LINX_(__NR_fchownat,       sys_fchownat),         // 298
   1161    LINX_(__NR_futimesat,    sys_futimesat),        // 326 on arm
   1162 
   1163    PLAXY(__NR_fstatat64,    sys_fstatat64),        // 300
   1164    LINX_(__NR_unlinkat,       sys_unlinkat),         // 301
   1165    LINX_(__NR_renameat,       sys_renameat),         // 302
   1166    LINX_(__NR_linkat,       sys_linkat),           // 303
   1167    LINX_(__NR_symlinkat,    sys_symlinkat),        // 304
   1168 
   1169    LINX_(__NR_readlinkat,    sys_readlinkat),       //
   1170    LINX_(__NR_fchmodat,       sys_fchmodat),         //
   1171    LINX_(__NR_faccessat,    sys_faccessat),        //
   1172    LINXY(__NR_shmat,         wrap_sys_shmat),       //305
   1173    LINXY(__NR_shmdt,             sys_shmdt),          //306
   1174    LINX_(__NR_shmget,            sys_shmget),         //307
   1175    LINXY(__NR_shmctl,            sys_shmctl),         // 308
   1176 //   LINX_(__NR_pselect6,       sys_pselect6),         //
   1177 
   1178 //   LINX_(__NR_unshare,       sys_unshare),          // 310
   1179    LINX_(__NR_set_robust_list,    sys_set_robust_list),  // 311
   1180    LINXY(__NR_get_robust_list,    sys_get_robust_list),  // 312
   1181 //   LINX_(__NR_splice,            sys_ni_syscall),       // 313
   1182 //   LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 314
   1183 
   1184 //   LINX_(__NR_tee,               sys_ni_syscall),       // 315
   1185 //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 316
   1186    LINXY(__NR_move_pages,        sys_move_pages),       // 317
   1187 //   LINX_(__NR_getcpu,            sys_ni_syscall),       // 318
   1188 
   1189    LINX_(__NR_utimensat,         sys_utimensat),        // 320
   1190    LINXY(__NR_signalfd,          sys_signalfd),         // 321
   1191    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 322
   1192    LINXY(__NR_eventfd,           sys_eventfd),          // 323
   1193 
   1194    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 325
   1195    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),   // 326
   1196 
   1197    ///////////////
   1198 
   1199    // JRS 2010-Jan-03: I believe that all the numbers listed
   1200    // in comments in the table prior to this point (eg "// 326",
   1201    // etc) are bogus since it looks to me like they are copied
   1202    // verbatim from syswrap-x86-linux.c and they certainly do not
   1203    // correspond to what's in include/vki/vki-scnums-arm-linux.h.
   1204    // From here onwards, please ensure the numbers are correct.
   1205 
   1206    LINX_(__NR_pselect6,          sys_pselect6),         // 335
   1207    LINXY(__NR_ppoll,             sys_ppoll),            // 336
   1208 
   1209    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 346
   1210 
   1211    LINX_(__NR_fallocate,         sys_fallocate),        // 352
   1212 
   1213    LINXY(__NR_signalfd4,         sys_signalfd4),        // 355
   1214    LINXY(__NR_eventfd2,          sys_eventfd2),         // 356
   1215    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 357
   1216    LINXY(__NR_dup3,              sys_dup3),             // 358
   1217    LINXY(__NR_pipe2,             sys_pipe2),            // 359
   1218    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 360
   1219    LINXY(__NR_preadv,            sys_preadv),           // 361
   1220    LINX_(__NR_pwritev,           sys_pwritev),          // 362
   1221    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 363
   1222    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 364
   1223 
   1224    LINXY(__NR_accept4,           sys_accept4),          // 366
   1225    LINXY(__NR_fanotify_init,     sys_fanotify_init),    // 367
   1226    LINX_(__NR_fanotify_mark,     sys_fanotify_mark),    // 368
   1227    LINXY(__NR_prlimit64,         sys_prlimit64),        // 369
   1228    LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 370
   1229    LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 371
   1230    LINXY(__NR_clock_adjtime,     sys_clock_adjtime),    // 372
   1231    LINXY(__NR_sendmmsg,          sys_sendmmsg)          // 374
   1232 };
   1233 
   1234 
   1235 /* These are not in the main table because there indexes are not small
   1236    integers, but rather values close to one million.  So their
   1237    inclusion would force the main table to be huge (about 8 MB). */
   1238 
   1239 static SyscallTableEntry ste___ARM_set_tls
   1240    = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
   1241 
   1242 static SyscallTableEntry ste___ARM_cacheflush
   1243    = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
   1244 
   1245 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
   1246 {
   1247    const UInt syscall_main_table_size
   1248       = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
   1249 
   1250    /* Is it in the contiguous initial section of the table? */
   1251    if (sysno < syscall_main_table_size) {
   1252       SyscallTableEntry* sys = &syscall_main_table[sysno];
   1253       if (sys->before == NULL)
   1254          return NULL; /* no entry */
   1255       else
   1256          return sys;
   1257    }
   1258 
   1259    /* Check if it's one of the out-of-line entries. */
   1260    switch (sysno) {
   1261       case __NR_ARM_set_tls:    return &ste___ARM_set_tls;
   1262       case __NR_ARM_cacheflush: return &ste___ARM_cacheflush;
   1263       default: break;
   1264    }
   1265 
   1266    /* Can't find a wrapper */
   1267    return NULL;
   1268 }
   1269 
   1270 #endif // defined(VGP_arm_linux)
   1271 
   1272 /*--------------------------------------------------------------------*/
   1273 /*--- end                                      syswrap-arm-linux.c ---*/
   1274 /*--------------------------------------------------------------------*/
   1275