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