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