syswrap-arm-linux.c revision b2cd1bc0abb95119df1b9b8e6dcc71e48b828a94
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-2012 Nicholas Nethercote
11      njn@valgrind.org
12   Copyright (C) 2008-2012 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_socket);
348DECL_TEMPLATE(arm_linux, sys_setsockopt);
349DECL_TEMPLATE(arm_linux, sys_getsockopt);
350DECL_TEMPLATE(arm_linux, sys_connect);
351DECL_TEMPLATE(arm_linux, sys_accept);
352DECL_TEMPLATE(arm_linux, sys_accept4);
353DECL_TEMPLATE(arm_linux, sys_sendto);
354DECL_TEMPLATE(arm_linux, sys_recvfrom);
355//XXX: Semaphore code ripped from AMD64.
356DECL_TEMPLATE(arm_linux, sys_semget);
357DECL_TEMPLATE(arm_linux, sys_semop);
358DECL_TEMPLATE(arm_linux, sys_semctl);
359DECL_TEMPLATE(arm_linux, sys_semtimedop);
360//XXX: Shared memory code ripped from AMD64
361//
362DECL_TEMPLATE(arm_linux, wrap_sys_shmat);
363DECL_TEMPLATE(arm_linux, sys_shmget);
364DECL_TEMPLATE(arm_linux, sys_shmdt);
365DECL_TEMPLATE(arm_linux, sys_shmctl);
366DECL_TEMPLATE(arm_linux, sys_sendmsg);
367DECL_TEMPLATE(arm_linux, sys_recvmsg);
368//msg* code from AMD64
369DECL_TEMPLATE(arm_linux, sys_msgget);
370DECL_TEMPLATE(arm_linux, sys_msgrcv);
371DECL_TEMPLATE(arm_linux, sys_msgsnd);
372DECL_TEMPLATE(arm_linux, sys_msgctl);
373DECL_TEMPLATE(arm_linux, sys_shutdown);
374DECL_TEMPLATE(arm_linux, sys_bind);
375DECL_TEMPLATE(arm_linux, sys_listen);
376DECL_TEMPLATE(arm_linux, sys_getsockname);
377DECL_TEMPLATE(arm_linux, sys_getpeername);
378DECL_TEMPLATE(arm_linux, sys_socketpair);
379DECL_TEMPLATE(arm_linux, sys_send);
380DECL_TEMPLATE(arm_linux, sys_recv);
381DECL_TEMPLATE(arm_linux, sys_mmap2);
382DECL_TEMPLATE(arm_linux, sys_stat64);
383DECL_TEMPLATE(arm_linux, sys_lstat64);
384DECL_TEMPLATE(arm_linux, sys_fstatat64);
385DECL_TEMPLATE(arm_linux, sys_fstat64);
386DECL_TEMPLATE(arm_linux, sys_clone);
387DECL_TEMPLATE(arm_linux, sys_sigreturn);
388DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
389DECL_TEMPLATE(arm_linux, sys_sigsuspend);
390DECL_TEMPLATE(arm_linux, sys_set_tls);
391DECL_TEMPLATE(arm_linux, sys_cacheflush);
392DECL_TEMPLATE(arm_linux, sys_ptrace);
393
394
395PRE(sys_socket)
396{
397   PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
398   PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
399}
400POST(sys_socket)
401{
402   SysRes r;
403   vg_assert(SUCCESS);
404   r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
405   SET_STATUS_from_SysRes(r);
406}
407
408PRE(sys_setsockopt)
409{
410   PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
411   PRE_REG_READ5(long, "setsockopt",
412                 int, s, int, level, int, optname,
413                 const void *, optval, int, optlen);
414   ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
415}
416
417PRE(sys_getsockopt)
418{
419   PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
420   PRE_REG_READ5(long, "getsockopt",
421                 int, s, int, level, int, optname,
422                 void *, optval, int, *optlen);
423   ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
424}
425POST(sys_getsockopt)
426{
427   vg_assert(SUCCESS);
428   ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
429                                         ARG1,ARG2,ARG3,ARG4,ARG5);
430}
431
432PRE(sys_connect)
433{
434   *flags |= SfMayBlock;
435   PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
436   PRE_REG_READ3(long, "connect",
437                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
438   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
439}
440
441PRE(sys_accept)
442{
443   *flags |= SfMayBlock;
444   PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
445   PRE_REG_READ3(long, "accept",
446                 int, s, struct sockaddr *, addr, int, *addrlen);
447   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
448}
449POST(sys_accept)
450{
451   SysRes r;
452   vg_assert(SUCCESS);
453   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
454                                         ARG1,ARG2,ARG3);
455   SET_STATUS_from_SysRes(r);
456}
457
458PRE(sys_accept4)
459{
460   *flags |= SfMayBlock;
461   PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
462   PRE_REG_READ4(long, "accept4",
463                 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
464   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
465}
466POST(sys_accept4)
467{
468   SysRes r;
469   vg_assert(SUCCESS);
470   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
471                                         ARG1,ARG2,ARG3);
472   SET_STATUS_from_SysRes(r);
473}
474
475PRE(sys_sendto)
476{
477   *flags |= SfMayBlock;
478   PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
479   PRE_REG_READ6(long, "sendto",
480                 int, s, const void *, msg, int, len,
481                 unsigned int, flags,
482                 const struct sockaddr *, to, int, tolen);
483   ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
484}
485
486PRE(sys_recvfrom)
487{
488   *flags |= SfMayBlock;
489   PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
490   PRE_REG_READ6(long, "recvfrom",
491                 int, s, void *, buf, int, len, unsigned int, flags,
492                 struct sockaddr *, from, int *, fromlen);
493   ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
494}
495POST(sys_recvfrom)
496{
497   vg_assert(SUCCESS);
498   ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
499                                       ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
500}
501
502PRE(sys_sendmsg)
503{
504   *flags |= SfMayBlock;
505   PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
506   PRE_REG_READ3(long, "sendmsg",
507                 int, s, const struct msghdr *, msg, int, flags);
508   ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
509}
510
511PRE(sys_recvmsg)
512{
513   *flags |= SfMayBlock;
514   PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
515   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
516   ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
517}
518POST(sys_recvmsg)
519{
520   ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
521}
522
523//XXX: Semaphore code ripped from AMD64.
524PRE(sys_semget)
525{
526   PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
527   PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
528}
529
530PRE(sys_semop)
531{
532   *flags |= SfMayBlock;
533   PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
534   PRE_REG_READ3(long, "semop",
535                 int, semid, struct sembuf *, sops, unsigned, nsoops);
536   ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
537}
538
539PRE(sys_semctl)
540{
541   switch (ARG3 & ~VKI_IPC_64) {
542   case VKI_IPC_INFO:
543   case VKI_SEM_INFO:
544      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
545      PRE_REG_READ4(long, "semctl",
546                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
547      break;
548   case VKI_IPC_STAT:
549   case VKI_SEM_STAT:
550   case VKI_IPC_SET:
551      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
552      PRE_REG_READ4(long, "semctl",
553                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
554      break;
555   case VKI_GETALL:
556   case VKI_SETALL:
557      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
558      PRE_REG_READ4(long, "semctl",
559                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
560      break;
561   default:
562      PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
563      PRE_REG_READ3(long, "semctl",
564                    int, semid, int, semnum, int, cmd);
565      break;
566   }
567   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
568}
569
570POST(sys_semctl)
571{
572   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
573}
574
575PRE(sys_semtimedop)
576{
577   *flags |= SfMayBlock;
578   PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
579   PRE_REG_READ4(long, "semtimedop",
580                 int, semid, struct sembuf *, sops, unsigned, nsoops,
581                 struct timespec *, timeout);
582   ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
583}
584
585//amd64
586PRE(sys_msgget)
587{
588   PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
589   PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
590}
591
592PRE(sys_msgsnd)
593{
594   PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
595   PRE_REG_READ4(long, "msgsnd",
596                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
597   ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
598   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
599      *flags |= SfMayBlock;
600}
601
602PRE(sys_msgrcv)
603{
604   PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
605   PRE_REG_READ5(long, "msgrcv",
606                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
607                 long, msgytp, int, msgflg);
608   ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
609   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
610      *flags |= SfMayBlock;
611}
612POST(sys_msgrcv)
613{
614   ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
615}
616
617
618PRE(sys_msgctl)
619{
620   PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
621   PRE_REG_READ3(long, "msgctl",
622                 int, msqid, int, cmd, struct msqid_ds *, buf);
623   ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
624}
625POST(sys_msgctl)
626{
627   ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
628}
629
630//shared memory code from AMD64
631PRE(sys_shmget)
632{
633   PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
634   PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
635}
636
637PRE(wrap_sys_shmat)
638{
639   UWord arg2tmp;
640   PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
641   PRE_REG_READ3(long, "shmat",
642                 int, shmid, const void *, shmaddr, int, shmflg);
643   /* Round the attach address down to an VKI_SHMLBA boundary if the
644      client requested rounding.  See #222545.  This is necessary only
645      on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all
646      other linux targets it is the same as the page size. */
647   if (ARG3 & VKI_SHM_RND)
648      ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA);
649   arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
650   if (arg2tmp == 0)
651      SET_STATUS_Failure( VKI_EINVAL );
652   else
653      ARG2 = arg2tmp;
654}
655
656POST(wrap_sys_shmat)
657{
658   ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
659}
660
661PRE(sys_shmdt)
662{
663   PRINT("sys_shmdt ( %#lx )",ARG1);
664   PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
665   if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
666      SET_STATUS_Failure( VKI_EINVAL );
667}
668
669POST(sys_shmdt)
670{
671   ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
672}
673
674PRE(sys_shmctl)
675{
676   PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
677   PRE_REG_READ3(long, "shmctl",
678                 int, shmid, int, cmd, struct shmid_ds *, buf);
679   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
680}
681
682POST(sys_shmctl)
683{
684   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
685}
686
687PRE(sys_shutdown)
688{
689   *flags |= SfMayBlock;
690   PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
691   PRE_REG_READ2(int, "shutdown", int, s, int, how);
692}
693
694PRE(sys_bind)
695{
696   PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
697   PRE_REG_READ3(long, "bind",
698                 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
699   ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
700}
701
702PRE(sys_listen)
703{
704   PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
705   PRE_REG_READ2(long, "listen", int, s, int, backlog);
706}
707
708PRE(sys_getsockname)
709{
710   PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
711   PRE_REG_READ3(long, "getsockname",
712                 int, s, struct sockaddr *, name, int *, namelen);
713   ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
714}
715POST(sys_getsockname)
716{
717   vg_assert(SUCCESS);
718   ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
719                                          ARG1,ARG2,ARG3);
720}
721
722PRE(sys_getpeername)
723{
724   PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
725   PRE_REG_READ3(long, "getpeername",
726                 int, s, struct sockaddr *, name, int *, namelen);
727   ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
728}
729POST(sys_getpeername)
730{
731   vg_assert(SUCCESS);
732   ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
733                                          ARG1,ARG2,ARG3);
734}
735
736PRE(sys_socketpair)
737{
738   PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
739   PRE_REG_READ4(long, "socketpair",
740                 int, d, int, type, int, protocol, int*, sv);
741   ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
742}
743POST(sys_socketpair)
744{
745   vg_assert(SUCCESS);
746   ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
747                                         ARG1,ARG2,ARG3,ARG4);
748}
749
750PRE(sys_send)
751{
752   *flags |= SfMayBlock;
753   PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
754   PRE_REG_READ4(long, "send",
755                 int, s, const void *, msg, int, len,
756                 unsigned int, flags);
757
758   ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
759}
760
761PRE(sys_recv)
762{
763   *flags |= SfMayBlock;
764   PRINT("sys_recv ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
765   PRE_REG_READ4(long, "recv",
766                 int, s, void *, buf, int, len, unsigned int, flags);
767   ML_(generic_PRE_sys_recv)( tid, ARG1, ARG2, ARG3 );
768}
769
770POST(sys_recv)
771{
772   ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 );
773}
774
775PRE(sys_mmap2)
776{
777   SysRes r;
778
779   // Exactly like old_mmap() except:
780   //  - all 6 args are passed in regs, rather than in a memory-block.
781   //  - the file offset is specified in pagesize units rather than bytes,
782   //    so that it can be used for files bigger than 2^32 bytes.
783   // pagesize or 4K-size units in offset?  For ppc32/64-linux, this is
784   // 4K-sized.  Assert that the page size is 4K here for safety.
785   vg_assert(VKI_PAGE_SIZE == 4096);
786   PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
787         ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
788   PRE_REG_READ6(long, "mmap2",
789                 unsigned long, start, unsigned long, length,
790                 unsigned long, prot,  unsigned long, flags,
791                 unsigned long, fd,    unsigned long, offset);
792
793   r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
794                                       4096 * (Off64T)ARG6 );
795   SET_STATUS_from_SysRes(r);
796}
797
798// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
799// applicable to every architecture -- I think only to 32-bit archs.
800// We're going to need something like linux/core_os32.h for such
801// things, eventually, I think.  --njn
802PRE(sys_lstat64)
803{
804   PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
805   PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
806   PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
807   PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
808}
809
810POST(sys_lstat64)
811{
812   vg_assert(SUCCESS);
813   if (RES == 0) {
814      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
815   }
816}
817
818PRE(sys_stat64)
819{
820   PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
821   PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
822   PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
823   PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
824}
825
826POST(sys_stat64)
827{
828   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
829}
830
831PRE(sys_fstatat64)
832{
833   PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
834   PRE_REG_READ3(long, "fstatat64",
835                 int, dfd, char *, file_name, struct stat64 *, buf);
836   PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
837   PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
838}
839
840POST(sys_fstatat64)
841{
842   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
843}
844
845PRE(sys_fstat64)
846{
847   PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
848   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
849   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
850}
851
852POST(sys_fstat64)
853{
854   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
855}
856
857PRE(sys_clone)
858{
859    UInt cloneflags;
860
861   PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
862   PRE_REG_READ5(int, "clone",
863                 unsigned long, flags,
864                 void *, child_stack,
865                 int *, parent_tidptr,
866                 void *, child_tls,
867                 int *, child_tidptr);
868
869   if (ARG1 & VKI_CLONE_PARENT_SETTID) {
870      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
871      if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
872                                             VKI_PROT_WRITE)) {
873         SET_STATUS_Failure( VKI_EFAULT );
874         return;
875      }
876   }
877   if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
878      PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
879      if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
880                                             VKI_PROT_WRITE)) {
881         SET_STATUS_Failure( VKI_EFAULT );
882         return;
883      }
884   }
885   if (ARG1 & VKI_CLONE_SETTLS) {
886      PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
887      if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
888                                             VKI_PROT_READ)) {
889         SET_STATUS_Failure( VKI_EFAULT );
890         return;
891      }
892   }
893
894   cloneflags = ARG1;
895
896   if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
897      SET_STATUS_Failure( VKI_EINVAL );
898      return;
899   }
900
901   /* Only look at the flags we really care about */
902   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
903                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
904   case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
905      /* thread creation */
906      SET_STATUS_from_SysRes(
907         do_clone(tid,
908                  ARG1,         /* flags */
909                  (Addr)ARG2,   /* child ESP */
910                  (Int *)ARG3,  /* parent_tidptr */
911                  (Int *)ARG5,  /* child_tidptr */
912                  (Addr)ARG4)); /* set_tls */
913      break;
914
915   case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
916      /* FALLTHROUGH - assume vfork == fork */
917      cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
918
919   case 0: /* plain fork */
920      SET_STATUS_from_SysRes(
921         ML_(do_fork_clone)(tid,
922                       cloneflags,      /* flags */
923                       (Int *)ARG3,     /* parent_tidptr */
924                       (Int *)ARG5));   /* child_tidptr */
925      break;
926
927   default:
928      /* should we just ENOSYS? */
929      VG_(message)(Vg_UserMsg, "");
930      VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
931      VG_(message)(Vg_UserMsg, "");
932      VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
933      VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
934      VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
935      VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
936      VG_(unimplemented)
937         ("Valgrind does not support general clone().");
938   }
939
940   if (SUCCESS) {
941      if (ARG1 & VKI_CLONE_PARENT_SETTID)
942         POST_MEM_WRITE(ARG3, sizeof(Int));
943      if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
944         POST_MEM_WRITE(ARG5, sizeof(Int));
945
946      /* Thread creation was successful; let the child have the chance
947         to run */
948      *flags |= SfYieldAfter;
949   }
950}
951
952PRE(sys_sigreturn)
953{
954   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
955     an explanation of what follows. */
956
957   PRINT("sys_sigreturn ( )");
958
959   vg_assert(VG_(is_valid_tid)(tid));
960   vg_assert(tid >= 1 && tid < VG_N_THREADS);
961   vg_assert(VG_(is_running_thread)(tid));
962
963   /* Restore register state from frame and remove it */
964   VG_(sigframe_destroy)(tid, False);
965
966   /* Tell the driver not to update the guest state with the "result",
967      and set a bogus result to keep it happy. */
968   *flags |= SfNoWriteResult;
969   SET_STATUS_Success(0);
970
971   /* Check to see if any signals arose as a result of this. */
972   *flags |= SfPollAfter;
973}
974
975PRE(sys_rt_sigreturn)
976{
977  /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
978      an explanation of what follows. */
979
980   PRINT("rt_sigreturn ( )");
981
982   vg_assert(VG_(is_valid_tid)(tid));
983   vg_assert(tid >= 1 && tid < VG_N_THREADS);
984   vg_assert(VG_(is_running_thread)(tid));
985
986   /* Restore register state from frame and remove it */
987   VG_(sigframe_destroy)(tid, True);
988
989   /* Tell the driver not to update the guest state with the "result",
990      and set a bogus result to keep it happy. */
991   *flags |= SfNoWriteResult;
992   SET_STATUS_Success(0);
993
994   /* Check to see if any signals arose as a result of this. */
995   *flags |= SfPollAfter;
996}
997
998/* NB: clone of x86-linux version, and ppc32-linux has an almost
999   identical one. */
1000PRE(sys_sigsuspend)
1001{
1002   /* The C library interface to sigsuspend just takes a pointer to
1003      a signal mask but this system call has three arguments - the first
1004      two don't appear to be used by the kernel and are always passed as
1005      zero by glibc and the third is the first word of the signal mask
1006      so only 32 signals are supported.
1007
1008      In fact glibc normally uses rt_sigsuspend if it is available as
1009      that takes a pointer to the signal mask so supports more signals.
1010    */
1011   *flags |= SfMayBlock;
1012   PRINT("sys_sigsuspend ( %ld, %ld, %ld )", ARG1,ARG2,ARG3 );
1013   PRE_REG_READ3(int, "sigsuspend",
1014                 int, history0, int, history1,
1015                 vki_old_sigset_t, mask);
1016}
1017
1018/* Very much ARM specific */
1019
1020PRE(sys_set_tls)
1021{
1022   PRINT("set_tls (%lx)",ARG1);
1023   PRE_REG_READ1(long, "set_tls", unsigned long, addr);
1024
1025   SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
1026}
1027
1028PRE(sys_cacheflush)
1029{
1030   PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3);
1031   PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags);
1032   VG_(discard_translations)( (Addr64)ARG1,
1033                              ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/,
1034                              "PRE(sys_cacheflush)" );
1035   SET_STATUS_Success(0);
1036}
1037
1038// ARG3 is only used for pointers into the traced process's address
1039// space and for offsets into the traced process's struct
1040// user_regs_struct. It is never a pointer into this process's memory
1041// space, and we should therefore not check anything it points to.
1042PRE(sys_ptrace)
1043{
1044   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
1045   PRE_REG_READ4(int, "ptrace",
1046                 long, request, long, pid, long, addr, long, data);
1047   switch (ARG1) {
1048   case VKI_PTRACE_PEEKTEXT:
1049   case VKI_PTRACE_PEEKDATA:
1050   case VKI_PTRACE_PEEKUSR:
1051      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
1052		     sizeof (long));
1053      break;
1054   case VKI_PTRACE_GETREGS:
1055      PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
1056		     sizeof (struct vki_user_regs_struct));
1057      break;
1058   case VKI_PTRACE_GETFPREGS:
1059      PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
1060		     sizeof (struct vki_user_fp));
1061      break;
1062   case VKI_PTRACE_GETWMMXREGS:
1063      PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4,
1064		     VKI_IWMMXT_SIZE);
1065      break;
1066   case VKI_PTRACE_GETCRUNCHREGS:
1067      PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4,
1068		     VKI_CRUNCH_SIZE);
1069      break;
1070   case VKI_PTRACE_GETVFPREGS:
1071      PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4,
1072                     sizeof (struct vki_user_vfp) );
1073      break;
1074   case VKI_PTRACE_GETHBPREGS:
1075      PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4,
1076                     sizeof (unsigned long) );
1077      break;
1078   case VKI_PTRACE_SETREGS:
1079      PRE_MEM_READ( "ptrace(setregs)", ARG4,
1080		     sizeof (struct vki_user_regs_struct));
1081      break;
1082   case VKI_PTRACE_SETFPREGS:
1083      PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
1084		     sizeof (struct vki_user_fp));
1085      break;
1086   case VKI_PTRACE_SETWMMXREGS:
1087      PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4,
1088		     VKI_IWMMXT_SIZE);
1089      break;
1090   case VKI_PTRACE_SETCRUNCHREGS:
1091      PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4,
1092		     VKI_CRUNCH_SIZE);
1093      break;
1094   case VKI_PTRACE_SETVFPREGS:
1095      PRE_MEM_READ( "ptrace(setvfpregs)", ARG4,
1096                     sizeof (struct vki_user_vfp));
1097      break;
1098   case VKI_PTRACE_SETHBPREGS:
1099      PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long));
1100      break;
1101   case VKI_PTRACE_GET_THREAD_AREA:
1102      PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long));
1103      break;
1104   case VKI_PTRACE_GETEVENTMSG:
1105      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
1106      break;
1107   case VKI_PTRACE_GETSIGINFO:
1108      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
1109      break;
1110   case VKI_PTRACE_SETSIGINFO:
1111      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
1112      break;
1113   case VKI_PTRACE_GETREGSET:
1114      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
1115      break;
1116   case VKI_PTRACE_SETREGSET:
1117      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
1118      break;
1119   default:
1120      break;
1121   }
1122}
1123
1124POST(sys_ptrace)
1125{
1126   switch (ARG1) {
1127   case VKI_PTRACE_PEEKTEXT:
1128   case VKI_PTRACE_PEEKDATA:
1129   case VKI_PTRACE_PEEKUSR:
1130      POST_MEM_WRITE( ARG4, sizeof (long));
1131      break;
1132   case VKI_PTRACE_GETREGS:
1133      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
1134      break;
1135   case VKI_PTRACE_GETFPREGS:
1136      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp));
1137      break;
1138   case VKI_PTRACE_GETWMMXREGS:
1139      POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE);
1140      break;
1141   case VKI_PTRACE_GETCRUNCHREGS:
1142      POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE);
1143      break;
1144   case VKI_PTRACE_GETVFPREGS:
1145      POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp));
1146      break;
1147   case VKI_PTRACE_GET_THREAD_AREA:
1148   case VKI_PTRACE_GETHBPREGS:
1149   case VKI_PTRACE_GETEVENTMSG:
1150      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
1151      break;
1152   case VKI_PTRACE_GETSIGINFO:
1153      /* XXX: This is a simplification. Different parts of the
1154       * siginfo_t are valid depending on the type of signal.
1155       */
1156      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
1157      break;
1158   case VKI_PTRACE_GETREGSET:
1159      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
1160      break;
1161   default:
1162      break;
1163   }
1164}
1165
1166#undef PRE
1167#undef POST
1168
1169/* ---------------------------------------------------------------------
1170   The arm/Linux syscall table
1171   ------------------------------------------------------------------ */
1172
1173#if 0
1174#define __NR_OABI_SYSCALL_BASE 0x900000
1175#else
1176#define __NR_OABI_SYSCALL_BASE 0x0
1177#endif
1178
1179#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(arm_linux, sysno, name)
1180#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(arm_linux, sysno, name)
1181
1182// This table maps from __NR_xxx syscall numbers (from
1183// linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo()
1184// wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S).
1185//
1186// For those syscalls not handled by Valgrind, the annotation indicate its
1187// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1188// (unknown).
1189
1190static SyscallTableEntry syscall_main_table[] = {
1191//zz    //   (restart_syscall)                             // 0
1192   GENX_(__NR_exit,              sys_exit),           // 1
1193   GENX_(__NR_fork,              sys_fork),           // 2
1194   GENXY(__NR_read,              sys_read),           // 3
1195   GENX_(__NR_write,             sys_write),          // 4
1196
1197   GENXY(__NR_open,              sys_open),           // 5
1198   GENXY(__NR_close,             sys_close),          // 6
1199//   GENXY(__NR_waitpid,           sys_waitpid),        // 7
1200   GENXY(__NR_creat,             sys_creat),          // 8
1201   GENX_(__NR_link,              sys_link),           // 9
1202
1203   GENX_(__NR_unlink,            sys_unlink),         // 10
1204   GENX_(__NR_execve,            sys_execve),         // 11
1205   GENX_(__NR_chdir,             sys_chdir),          // 12
1206   GENXY(__NR_time,              sys_time),           // 13
1207   GENX_(__NR_mknod,             sys_mknod),          // 14
1208
1209   GENX_(__NR_chmod,             sys_chmod),          // 15
1210//zz    LINX_(__NR_lchown,            sys_lchown16),       // 16
1211//   GENX_(__NR_break,             sys_ni_syscall),     // 17
1212//zz    //   (__NR_oldstat,           sys_stat),           // 18 (obsolete)
1213   LINX_(__NR_lseek,             sys_lseek),          // 19
1214
1215   GENX_(__NR_getpid,            sys_getpid),         // 20
1216   LINX_(__NR_mount,             sys_mount),          // 21
1217   LINX_(__NR_umount,            sys_oldumount),      // 22
1218   LINX_(__NR_setuid,            sys_setuid16),       // 23 ## P
1219   LINX_(__NR_getuid,            sys_getuid16),       // 24 ## P
1220//zz
1221//zz    //   (__NR_stime,             sys_stime),          // 25 * (SVr4,SVID,X/OPEN)
1222   PLAXY(__NR_ptrace,            sys_ptrace),         // 26
1223   GENX_(__NR_alarm,             sys_alarm),          // 27
1224//zz    //   (__NR_oldfstat,          sys_fstat),          // 28 * L -- obsolete
1225   GENX_(__NR_pause,             sys_pause),          // 29
1226
1227   LINX_(__NR_utime,             sys_utime),          // 30
1228//   GENX_(__NR_stty,              sys_ni_syscall),     // 31
1229//   GENX_(__NR_gtty,              sys_ni_syscall),     // 32
1230   GENX_(__NR_access,            sys_access),         // 33
1231   GENX_(__NR_nice,              sys_nice),           // 34
1232
1233//   GENX_(__NR_ftime,             sys_ni_syscall),     // 35
1234   GENX_(__NR_sync,              sys_sync),           // 36
1235   GENX_(__NR_kill,              sys_kill),           // 37
1236   GENX_(__NR_rename,            sys_rename),         // 38
1237   GENX_(__NR_mkdir,             sys_mkdir),          // 39
1238
1239   GENX_(__NR_rmdir,             sys_rmdir),          // 40
1240   GENXY(__NR_dup,               sys_dup),            // 41
1241   LINXY(__NR_pipe,              sys_pipe),           // 42
1242   GENXY(__NR_times,             sys_times),          // 43
1243//   GENX_(__NR_prof,              sys_ni_syscall),     // 44
1244//zz
1245   GENX_(__NR_brk,               sys_brk),            // 45
1246   LINX_(__NR_setgid,            sys_setgid16),       // 46
1247   LINX_(__NR_getgid,            sys_getgid16),       // 47
1248//zz    //   (__NR_signal,            sys_signal),         // 48 */* (ANSI C)
1249   LINX_(__NR_geteuid,           sys_geteuid16),      // 49
1250
1251   LINX_(__NR_getegid,           sys_getegid16),      // 50
1252   GENX_(__NR_acct,              sys_acct),           // 51
1253   LINX_(__NR_umount2,           sys_umount),         // 52
1254//   GENX_(__NR_lock,              sys_ni_syscall),     // 53
1255   LINXY(__NR_ioctl,             sys_ioctl),          // 54
1256
1257   LINXY(__NR_fcntl,             sys_fcntl),          // 55
1258//   GENX_(__NR_mpx,               sys_ni_syscall),     // 56
1259   GENX_(__NR_setpgid,           sys_setpgid),        // 57
1260//   GENX_(__NR_ulimit,            sys_ni_syscall),     // 58
1261//zz    //   (__NR_oldolduname,       sys_olduname),       // 59 Linux -- obsolete
1262//zz
1263   GENX_(__NR_umask,             sys_umask),          // 60
1264   GENX_(__NR_chroot,            sys_chroot),         // 61
1265//zz    //   (__NR_ustat,             sys_ustat)           // 62 SVr4 -- deprecated
1266   GENXY(__NR_dup2,              sys_dup2),           // 63
1267   GENX_(__NR_getppid,           sys_getppid),        // 64
1268
1269   GENX_(__NR_getpgrp,           sys_getpgrp),        // 65
1270   GENX_(__NR_setsid,            sys_setsid),         // 66
1271   LINXY(__NR_sigaction,         sys_sigaction),      // 67
1272//zz    //   (__NR_sgetmask,          sys_sgetmask),       // 68 */* (ANSI C)
1273//zz    //   (__NR_ssetmask,          sys_ssetmask),       // 69 */* (ANSI C)
1274//zz
1275   LINX_(__NR_setreuid,          sys_setreuid16),     // 70
1276   LINX_(__NR_setregid,          sys_setregid16),     // 71
1277   PLAX_(__NR_sigsuspend,        sys_sigsuspend),     // 72
1278   LINXY(__NR_sigpending,        sys_sigpending),     // 73
1279//zz    //   (__NR_sethostname,       sys_sethostname),    // 74 */*
1280//zz
1281   GENX_(__NR_setrlimit,         sys_setrlimit),      // 75
1282   GENXY(__NR_getrlimit,         sys_old_getrlimit),  // 76
1283   GENXY(__NR_getrusage,         sys_getrusage),      // 77
1284   GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 78
1285   GENX_(__NR_settimeofday,      sys_settimeofday),   // 79
1286
1287   LINXY(__NR_getgroups,         sys_getgroups16),    // 80
1288   LINX_(__NR_setgroups,         sys_setgroups16),    // 81
1289//   PLAX_(__NR_select,            old_select),         // 82
1290   GENX_(__NR_symlink,           sys_symlink),        // 83
1291//zz    //   (__NR_oldlstat,          sys_lstat),          // 84 -- obsolete
1292//zz
1293   GENX_(__NR_readlink,          sys_readlink),       // 85
1294//zz    //   (__NR_uselib,            sys_uselib),         // 86 */Linux
1295//zz    //   (__NR_swapon,            sys_swapon),         // 87 */Linux
1296//zz    //   (__NR_reboot,            sys_reboot),         // 88 */Linux
1297//zz    //   (__NR_readdir,           old_readdir),        // 89 -- superseded
1298//zz
1299//   _____(__NR_mmap,              old_mmap),           // 90
1300   GENXY(__NR_munmap,            sys_munmap),         // 91
1301   GENX_(__NR_truncate,          sys_truncate),       // 92
1302   GENX_(__NR_ftruncate,         sys_ftruncate),      // 93
1303   GENX_(__NR_fchmod,            sys_fchmod),         // 94
1304
1305   LINX_(__NR_fchown,            sys_fchown16),       // 95
1306   GENX_(__NR_getpriority,       sys_getpriority),    // 96
1307   GENX_(__NR_setpriority,       sys_setpriority),    // 97
1308//   GENX_(__NR_profil,            sys_ni_syscall),     // 98
1309   GENXY(__NR_statfs,            sys_statfs),         // 99
1310
1311   GENXY(__NR_fstatfs,           sys_fstatfs),        // 100
1312//   LINX_(__NR_ioperm,            sys_ioperm),         // 101
1313   LINXY(__NR_socketcall,        sys_socketcall),     // 102
1314   LINXY(__NR_syslog,            sys_syslog),         // 103
1315   GENXY(__NR_setitimer,         sys_setitimer),      // 104
1316
1317   GENXY(__NR_getitimer,         sys_getitimer),      // 105
1318   GENXY(__NR_stat,              sys_newstat),        // 106
1319   GENXY(__NR_lstat,             sys_newlstat),       // 107
1320   GENXY(__NR_fstat,             sys_newfstat),       // 108
1321//zz    //   (__NR_olduname,          sys_uname),          // 109 -- obsolete
1322//zz
1323//   GENX_(__NR_iopl,              sys_iopl),           // 110
1324   LINX_(__NR_vhangup,           sys_vhangup),        // 111
1325//   GENX_(__NR_idle,              sys_ni_syscall),     // 112
1326// PLAXY(__NR_vm86old,           sys_vm86old),        // 113 __NR_syscall... weird
1327   GENXY(__NR_wait4,             sys_wait4),          // 114
1328//zz
1329//zz    //   (__NR_swapoff,           sys_swapoff),        // 115 */Linux
1330   LINXY(__NR_sysinfo,           sys_sysinfo),        // 116
1331//   _____(__NR_ipc,               sys_ipc),            // 117
1332   GENX_(__NR_fsync,             sys_fsync),          // 118
1333   PLAX_(__NR_sigreturn,         sys_sigreturn),      // 119 ?/Linux
1334
1335   PLAX_(__NR_clone,             sys_clone),          // 120
1336//zz    //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
1337   GENXY(__NR_uname,             sys_newuname),       // 122
1338//   PLAX_(__NR_modify_ldt,        sys_modify_ldt),     // 123
1339//zz    LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
1340//zz
1341   GENXY(__NR_mprotect,          sys_mprotect),       // 125
1342   LINXY(__NR_sigprocmask,       sys_sigprocmask),    // 126
1343//zz    // Nb: create_module() was removed 2.4-->2.6
1344//   GENX_(__NR_create_module,     sys_ni_syscall),     // 127
1345   LINX_(__NR_init_module,       sys_init_module),    // 128
1346   LINX_(__NR_delete_module,     sys_delete_module),  // 129
1347//zz
1348//zz    // Nb: get_kernel_syms() was removed 2.4-->2.6
1349//   GENX_(__NR_get_kernel_syms,   sys_ni_syscall),     // 130
1350   LINX_(__NR_quotactl,          sys_quotactl),       // 131
1351   GENX_(__NR_getpgid,           sys_getpgid),        // 132
1352   GENX_(__NR_fchdir,            sys_fchdir),         // 133
1353//zz    //   (__NR_bdflush,           sys_bdflush),        // 134 */Linux
1354//zz
1355//zz    //   (__NR_sysfs,             sys_sysfs),          // 135 SVr4
1356   LINX_(__NR_personality,       sys_personality),    // 136
1357//   GENX_(__NR_afs_syscall,       sys_ni_syscall),     // 137
1358   LINX_(__NR_setfsuid,          sys_setfsuid16),     // 138
1359   LINX_(__NR_setfsgid,          sys_setfsgid16),     // 139
1360
1361   LINXY(__NR__llseek,           sys_llseek),         // 140
1362   GENXY(__NR_getdents,          sys_getdents),       // 141
1363   GENX_(__NR__newselect,        sys_select),         // 142
1364   GENX_(__NR_flock,             sys_flock),          // 143
1365   GENX_(__NR_msync,             sys_msync),          // 144
1366
1367   GENXY(__NR_readv,             sys_readv),          // 145
1368   GENX_(__NR_writev,            sys_writev),         // 146
1369   GENX_(__NR_getsid,            sys_getsid),         // 147
1370   GENX_(__NR_fdatasync,         sys_fdatasync),      // 148
1371   LINXY(__NR__sysctl,           sys_sysctl),         // 149
1372
1373   GENX_(__NR_mlock,             sys_mlock),          // 150
1374   GENX_(__NR_munlock,           sys_munlock),        // 151
1375   GENX_(__NR_mlockall,          sys_mlockall),       // 152
1376   LINX_(__NR_munlockall,        sys_munlockall),     // 153
1377   LINXY(__NR_sched_setparam,    sys_sched_setparam), // 154
1378
1379   LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
1380   LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
1381   LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
1382   LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
1383   LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1384
1385   LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1386//zz    //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
1387   GENXY(__NR_nanosleep,         sys_nanosleep),      // 162
1388   GENX_(__NR_mremap,            sys_mremap),         // 163
1389   LINX_(__NR_setresuid,         sys_setresuid16),    // 164
1390
1391   LINXY(__NR_getresuid,         sys_getresuid16),    // 165
1392//   PLAXY(__NR_vm86,              sys_vm86),           // 166 x86/Linux-only
1393//   GENX_(__NR_query_module,      sys_ni_syscall),     // 167
1394   GENXY(__NR_poll,              sys_poll),           // 168
1395//zz    //   (__NR_nfsservctl,        sys_nfsservctl),     // 169 */Linux
1396//zz
1397   LINX_(__NR_setresgid,         sys_setresgid16),    // 170
1398   LINXY(__NR_getresgid,         sys_getresgid16),    // 171
1399   LINXY(__NR_prctl,             sys_prctl),          // 172
1400   PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 173
1401   LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 174
1402
1403   LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 175
1404   LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 176
1405   LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 177
1406   LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 178
1407   LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 179
1408
1409   GENXY(__NR_pread64,           sys_pread64),        // 180
1410   GENX_(__NR_pwrite64,          sys_pwrite64),       // 181
1411   LINX_(__NR_chown,             sys_chown16),        // 182
1412   GENXY(__NR_getcwd,            sys_getcwd),         // 183
1413   LINXY(__NR_capget,            sys_capget),         // 184
1414
1415   LINX_(__NR_capset,            sys_capset),         // 185
1416   GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 186
1417   LINXY(__NR_sendfile,          sys_sendfile),       // 187
1418//   GENXY(__NR_getpmsg,           sys_getpmsg),        // 188
1419//   GENX_(__NR_putpmsg,           sys_putpmsg),        // 189
1420
1421   // Nb: we treat vfork as fork
1422   GENX_(__NR_vfork,             sys_fork),           // 190
1423   GENXY(__NR_ugetrlimit,        sys_getrlimit),      // 191
1424   PLAX_(__NR_mmap2,             sys_mmap2),          // 192
1425   GENX_(__NR_truncate64,        sys_truncate64),     // 193
1426   GENX_(__NR_ftruncate64,       sys_ftruncate64),    // 194
1427
1428   PLAXY(__NR_stat64,            sys_stat64),         // 195
1429   PLAXY(__NR_lstat64,           sys_lstat64),        // 196
1430   PLAXY(__NR_fstat64,           sys_fstat64),        // 197
1431   GENX_(__NR_lchown32,          sys_lchown),         // 198
1432   GENX_(__NR_getuid32,          sys_getuid),         // 199
1433
1434   GENX_(__NR_getgid32,          sys_getgid),         // 200
1435   GENX_(__NR_geteuid32,         sys_geteuid),        // 201
1436   GENX_(__NR_getegid32,         sys_getegid),        // 202
1437   GENX_(__NR_setreuid32,        sys_setreuid),       // 203
1438   GENX_(__NR_setregid32,        sys_setregid),       // 204
1439
1440   GENXY(__NR_getgroups32,       sys_getgroups),      // 205
1441   GENX_(__NR_setgroups32,       sys_setgroups),      // 206
1442   GENX_(__NR_fchown32,          sys_fchown),         // 207
1443   LINX_(__NR_setresuid32,       sys_setresuid),      // 208
1444   LINXY(__NR_getresuid32,       sys_getresuid),      // 209
1445
1446   LINX_(__NR_setresgid32,       sys_setresgid),      // 210
1447   LINXY(__NR_getresgid32,       sys_getresgid),      // 211
1448   GENX_(__NR_chown32,           sys_chown),          // 212
1449   GENX_(__NR_setuid32,          sys_setuid),         // 213
1450   GENX_(__NR_setgid32,          sys_setgid),         // 214
1451
1452   LINX_(__NR_setfsuid32,        sys_setfsuid),       // 215
1453   LINX_(__NR_setfsgid32,        sys_setfsgid),       // 216
1454//zz    //   (__NR_pivot_root,        sys_pivot_root),     // 217 */Linux
1455   GENXY(__NR_mincore,           sys_mincore),        // 218
1456   GENX_(__NR_madvise,           sys_madvise),        // 219
1457
1458   GENXY(__NR_getdents64,        sys_getdents64),     // 220
1459   LINXY(__NR_fcntl64,           sys_fcntl64),        // 221
1460//   GENX_(222,                    sys_ni_syscall),     // 222
1461//   PLAXY(223,                    sys_syscall223),     // 223 // sys_bproc?
1462   LINX_(__NR_gettid,            sys_gettid),         // 224
1463
1464   LINX_(__NR_readahead,         sys_readahead),      // 225 */Linux
1465   LINX_(__NR_setxattr,          sys_setxattr),       // 226
1466   LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 227
1467   LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 228
1468   LINXY(__NR_getxattr,          sys_getxattr),       // 229
1469
1470   LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 230
1471   LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 231
1472   LINXY(__NR_listxattr,         sys_listxattr),      // 232
1473   LINXY(__NR_llistxattr,        sys_llistxattr),     // 233
1474   LINXY(__NR_flistxattr,        sys_flistxattr),     // 234
1475
1476   LINX_(__NR_removexattr,       sys_removexattr),    // 235
1477   LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 236
1478   LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 237
1479   LINXY(__NR_tkill,             sys_tkill),          // 238 */Linux
1480   LINXY(__NR_sendfile64,        sys_sendfile64),     // 239
1481
1482   LINXY(__NR_futex,             sys_futex),             // 240
1483   LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1484   LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1485//   PLAX_(__NR_set_thread_area,   sys_set_thread_area),   // 243
1486//   PLAX_(__NR_get_thread_area,   sys_get_thread_area),   // 244
1487
1488   LINXY(__NR_io_setup,          sys_io_setup),       // 245
1489   LINX_(__NR_io_destroy,        sys_io_destroy),     // 246
1490   LINXY(__NR_io_getevents,      sys_io_getevents),   // 247
1491   LINX_(__NR_io_submit,         sys_io_submit),      // 248
1492   LINXY(__NR_io_cancel,         sys_io_cancel),      // 249
1493
1494//   LINX_(__NR_fadvise64,         sys_fadvise64),      // 250 */(Linux?)
1495   GENX_(251,                    sys_ni_syscall),     // 251
1496   LINX_(__NR_exit_group,        sys_exit_group),     // 252
1497//   GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 253
1498   LINXY(__NR_epoll_create,      sys_epoll_create),   // 254
1499
1500   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 255
1501   LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 256
1502//zz    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 257 */Linux
1503   LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 258
1504   LINXY(__NR_timer_create,      sys_timer_create),      // 259
1505
1506   LINXY(__NR_timer_settime,     sys_timer_settime),  // (timer_create+1)
1507   LINXY(__NR_timer_gettime,     sys_timer_gettime),  // (timer_create+2)
1508   LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),//(timer_create+3)
1509   LINX_(__NR_timer_delete,      sys_timer_delete),   // (timer_create+4)
1510   LINX_(__NR_clock_settime,     sys_clock_settime),  // (timer_create+5)
1511
1512   LINXY(__NR_clock_gettime,     sys_clock_gettime),  // (timer_create+6)
1513   LINXY(__NR_clock_getres,      sys_clock_getres),   // (timer_create+7)
1514   LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// (timer_create+8) */*
1515   GENXY(__NR_statfs64,          sys_statfs64),       // 268
1516   GENXY(__NR_fstatfs64,         sys_fstatfs64),      // 269
1517
1518   LINX_(__NR_tgkill,            sys_tgkill),         // 270 */Linux
1519   GENX_(__NR_utimes,            sys_utimes),         // 271
1520//   LINX_(__NR_fadvise64_64,      sys_fadvise64_64),   // 272 */(Linux?)
1521   GENX_(__NR_vserver,           sys_ni_syscall),     // 273
1522   LINX_(__NR_mbind,             sys_mbind),          // 274 ?/?
1523
1524   LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 275 ?/?
1525   LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 276 ?/?
1526   LINXY(__NR_mq_open,           sys_mq_open),        // 277
1527   LINX_(__NR_mq_unlink,         sys_mq_unlink),      // (mq_open+1)
1528   LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // (mq_open+2)
1529
1530   LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// (mq_open+3)
1531   LINX_(__NR_mq_notify,         sys_mq_notify),      // (mq_open+4)
1532   LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // (mq_open+5)
1533   LINXY(__NR_waitid,            sys_waitid),         // 280
1534
1535   PLAXY(__NR_socket,            sys_socket),         // 281
1536   PLAX_(__NR_bind,              sys_bind),           // 282
1537   PLAX_(__NR_connect,           sys_connect),        // 283
1538   PLAX_(__NR_listen,            sys_listen),         // 284
1539   PLAXY(__NR_accept,            sys_accept),         // 285
1540   PLAXY(__NR_getsockname,       sys_getsockname),    // 286
1541   PLAXY(__NR_getpeername,       sys_getpeername),    // 287
1542   PLAXY(__NR_socketpair,        sys_socketpair),     // 288
1543   PLAX_(__NR_send,              sys_send),
1544   PLAX_(__NR_sendto,            sys_sendto),         // 290
1545   PLAXY(__NR_recv,              sys_recv),
1546   PLAXY(__NR_recvfrom,          sys_recvfrom),       // 292
1547   PLAX_(__NR_shutdown,          sys_shutdown),       // 293
1548   PLAX_(__NR_setsockopt,        sys_setsockopt),     // 294
1549   PLAXY(__NR_getsockopt,        sys_getsockopt),     // 295
1550   PLAX_(__NR_sendmsg,           sys_sendmsg),        // 296
1551   PLAXY(__NR_recvmsg,           sys_recvmsg),        // 297
1552   PLAX_(__NR_semop,             sys_semop),          // 298
1553   PLAX_(__NR_semget,            sys_semget),         // 299
1554   PLAXY(__NR_semctl,            sys_semctl),         // 300
1555   PLAX_(__NR_msgget,            sys_msgget),
1556   PLAX_(__NR_msgsnd,            sys_msgsnd),
1557   PLAXY(__NR_msgrcv,            sys_msgrcv),
1558   PLAXY(__NR_msgctl,            sys_msgctl),         // 304
1559   PLAX_(__NR_semtimedop,        sys_semtimedop),     // 312
1560
1561   LINX_(__NR_add_key,           sys_add_key),        // 286
1562   LINX_(__NR_request_key,       sys_request_key),    // 287
1563   LINXY(__NR_keyctl,            sys_keyctl),         // not 288...
1564//   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 289
1565
1566//   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 290
1567   LINX_(__NR_inotify_init,    sys_inotify_init),   // 291
1568   LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1569   LINX_(__NR_inotify_rm_watch,    sys_inotify_rm_watch), // 293
1570//   LINX_(__NR_migrate_pages,    sys_migrate_pages),    // 294
1571
1572   LINXY(__NR_openat,       sys_openat),           // 295
1573   LINX_(__NR_mkdirat,       sys_mkdirat),          // 296
1574   LINX_(__NR_mknodat,       sys_mknodat),          // 297
1575   LINX_(__NR_fchownat,       sys_fchownat),         // 298
1576   LINX_(__NR_futimesat,    sys_futimesat),        // 326 on arm
1577
1578   PLAXY(__NR_fstatat64,    sys_fstatat64),        // 300
1579   LINX_(__NR_unlinkat,       sys_unlinkat),         // 301
1580   LINX_(__NR_renameat,       sys_renameat),         // 302
1581   LINX_(__NR_linkat,       sys_linkat),           // 303
1582   LINX_(__NR_symlinkat,    sys_symlinkat),        // 304
1583
1584   LINX_(__NR_readlinkat,    sys_readlinkat),       //
1585   LINX_(__NR_fchmodat,       sys_fchmodat),         //
1586   LINX_(__NR_faccessat,    sys_faccessat),        //
1587   PLAXY(__NR_shmat,         wrap_sys_shmat),       //305
1588   PLAXY(__NR_shmdt,             sys_shmdt),          //306
1589   PLAX_(__NR_shmget,            sys_shmget),         //307
1590   PLAXY(__NR_shmctl,            sys_shmctl),         // 308
1591//   LINX_(__NR_pselect6,       sys_pselect6),         //
1592
1593//   LINX_(__NR_unshare,       sys_unshare),          // 310
1594   LINX_(__NR_set_robust_list,    sys_set_robust_list),  // 311
1595   LINXY(__NR_get_robust_list,    sys_get_robust_list),  // 312
1596//   LINX_(__NR_splice,            sys_ni_syscall),       // 313
1597//   LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 314
1598
1599//   LINX_(__NR_tee,               sys_ni_syscall),       // 315
1600//   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 316
1601   LINXY(__NR_move_pages,        sys_move_pages),       // 317
1602//   LINX_(__NR_getcpu,            sys_ni_syscall),       // 318
1603
1604   LINX_(__NR_utimensat,         sys_utimensat),        // 320
1605   LINXY(__NR_signalfd,          sys_signalfd),         // 321
1606   LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 322
1607   LINX_(__NR_eventfd,           sys_eventfd),          // 323
1608
1609   LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 325
1610   LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),   // 326
1611
1612   ///////////////
1613
1614   // JRS 2010-Jan-03: I believe that all the numbers listed
1615   // in comments in the table prior to this point (eg "// 326",
1616   // etc) are bogus since it looks to me like they are copied
1617   // verbatim from syswrap-x86-linux.c and they certainly do not
1618   // correspond to what's in include/vki/vki-scnums-arm-linux.h.
1619   // From here onwards, please ensure the numbers are correct.
1620
1621   LINX_(__NR_pselect6,          sys_pselect6),         // 335
1622   LINXY(__NR_ppoll,             sys_ppoll),            // 336
1623
1624   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 346
1625
1626   LINX_(__NR_fallocate,         sys_fallocate),        // 352
1627
1628   LINXY(__NR_signalfd4,         sys_signalfd4),        // 355
1629   LINX_(__NR_eventfd2,          sys_eventfd2),         // 356
1630   LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 357
1631   LINXY(__NR_dup3,              sys_dup3),             // 358
1632   LINXY(__NR_pipe2,             sys_pipe2),            // 359
1633   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 360
1634   LINXY(__NR_preadv,            sys_preadv),           // 361
1635   LINX_(__NR_pwritev,           sys_pwritev),          // 362
1636   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 363
1637   LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 364
1638
1639   PLAXY(__NR_accept4,           sys_accept4)           // 366
1640};
1641
1642
1643/* These are not in the main table because there indexes are not small
1644   integers, but rather values close to one million.  So their
1645   inclusion would force the main table to be huge (about 8 MB). */
1646
1647static SyscallTableEntry ste___ARM_set_tls
1648   = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
1649
1650static SyscallTableEntry ste___ARM_cacheflush
1651   = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
1652
1653SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1654{
1655   const UInt syscall_main_table_size
1656      = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
1657
1658   /* Is it in the contiguous initial section of the table? */
1659   if (sysno < syscall_main_table_size) {
1660      SyscallTableEntry* sys = &syscall_main_table[sysno];
1661      if (sys->before == NULL)
1662         return NULL; /* no entry */
1663      else
1664         return sys;
1665   }
1666
1667   /* Check if it's one of the out-of-line entries. */
1668   switch (sysno) {
1669      case __NR_ARM_set_tls:    return &ste___ARM_set_tls;
1670      case __NR_ARM_cacheflush: return &ste___ARM_cacheflush;
1671      default: break;
1672   }
1673
1674   /* Can't find a wrapper */
1675   return NULL;
1676}
1677
1678#endif // defined(VGP_arm_linux)
1679
1680/*--------------------------------------------------------------------*/
1681/*--- end                                      syswrap-arm-linux.c ---*/
1682/*--------------------------------------------------------------------*/
1683