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