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