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