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