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