]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/m_syswrap/syswrap-arm-linux.c
d550469c04f1f0ae6072b883d1919a5a9385dbdc
[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_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))
70 void 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
78 asm(
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
106 extern
107 ULong 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 );
114 asm(
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
151 static void setup_child ( ThreadArchState*, ThreadArchState* );
152 static 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  */
164 static 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
252 out:
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
270 void VG_(cleanup_thread) ( ThreadArchState* arch )
271 {
272 }  
273
274 void 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
282 static 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
301 DECL_TEMPLATE(arm_linux, sys_socketcall);
302 DECL_TEMPLATE(arm_linux, sys_socket);
303 DECL_TEMPLATE(arm_linux, sys_setsockopt);
304 DECL_TEMPLATE(arm_linux, sys_getsockopt);
305 DECL_TEMPLATE(arm_linux, sys_connect);
306 DECL_TEMPLATE(arm_linux, sys_accept);
307 DECL_TEMPLATE(arm_linux, sys_sendto);
308 DECL_TEMPLATE(arm_linux, sys_recvfrom);
309 //XXX: Semaphore code ripped from AMD64.
310 DECL_TEMPLATE(arm_linux, sys_semget);
311 DECL_TEMPLATE(arm_linux, sys_semop);
312 DECL_TEMPLATE(arm_linux, sys_semctl);
313 DECL_TEMPLATE(arm_linux, sys_semtimedop);
314 //XXX: Shared memory code ripped from AMD64
315 //
316 DECL_TEMPLATE(arm_linux, wrap_sys_shmat);
317 DECL_TEMPLATE(arm_linux, sys_shmget);
318 DECL_TEMPLATE(arm_linux, sys_shmdt);
319 DECL_TEMPLATE(arm_linux, sys_shmctl);
320 DECL_TEMPLATE(arm_linux, sys_sendmsg);
321 DECL_TEMPLATE(arm_linux, sys_recvmsg);
322 //msg* code from AMD64
323 DECL_TEMPLATE(arm_linux, sys_msgget);
324 DECL_TEMPLATE(arm_linux, sys_msgrcv);
325 DECL_TEMPLATE(arm_linux, sys_msgsnd);
326 DECL_TEMPLATE(arm_linux, sys_msgctl);
327 DECL_TEMPLATE(arm_linux, sys_shutdown);
328 DECL_TEMPLATE(arm_linux, sys_bind);
329 DECL_TEMPLATE(arm_linux, sys_listen);
330 DECL_TEMPLATE(arm_linux, sys_getsockname);
331 DECL_TEMPLATE(arm_linux, sys_getpeername);
332 DECL_TEMPLATE(arm_linux, sys_socketpair);
333 DECL_TEMPLATE(arm_linux, sys_send);
334 DECL_TEMPLATE(arm_linux, sys_recv);
335 DECL_TEMPLATE(arm_linux, sys_mmap2);
336 DECL_TEMPLATE(arm_linux, sys_stat64);
337 DECL_TEMPLATE(arm_linux, sys_lstat64);
338 DECL_TEMPLATE(arm_linux, sys_fstatat64);
339 DECL_TEMPLATE(arm_linux, sys_fstat64);
340 DECL_TEMPLATE(arm_linux, sys_clone);
341 DECL_TEMPLATE(arm_linux, sys_sigreturn);
342 DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
343 DECL_TEMPLATE(arm_linux, sys_set_tls);
344 DECL_TEMPLATE(arm_linux, sys_cacheflush);
345
346 PRE(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
500 POST(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
603 PRE(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 }
608 POST(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
616 PRE(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
625 PRE(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 }
633 POST(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
640 PRE(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
649 PRE(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 }
657 POST(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
666 PRE(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
677 PRE(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 }
686 POST(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
693 PRE(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
702 PRE(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 }
709 POST(sys_recvmsg)
710 {
711    ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
712 }
713
714 //XXX: Semaphore code ripped from AMD64.
715 PRE(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
721 PRE(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
730 PRE(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
761 POST(sys_semctl)
762 {
763    ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
764 }
765
766 PRE(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
777 PRE(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
783 PRE(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
793 PRE(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 }
803 POST(sys_msgrcv)
804 {
805    ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
806 }
807
808
809 PRE(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 }
816 POST(sys_msgctl)
817 {
818    ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
819 }
820
821 //shared memory code from AMD64
822 PRE(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
828 PRE(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    arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
835    if (arg2tmp == 0)
836       SET_STATUS_Failure( VKI_EINVAL );
837    else
838       ARG2 = arg2tmp;
839 }
840
841 POST(wrap_sys_shmat)
842 {
843    ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
844 }
845
846 PRE(sys_shmdt)
847 {
848    PRINT("sys_shmdt ( %#lx )",ARG1);
849    PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
850    if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
851       SET_STATUS_Failure( VKI_EINVAL );
852 }
853
854 POST(sys_shmdt)
855 {
856    ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
857 }
858
859 PRE(sys_shmctl)
860 {
861    PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
862    PRE_REG_READ3(long, "shmctl",
863                  int, shmid, int, cmd, struct shmid_ds *, buf);
864    ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
865 }
866
867 POST(sys_shmctl)
868 {
869    ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
870 }
871
872 PRE(sys_shutdown)
873 {
874    *flags |= SfMayBlock;
875    PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
876    PRE_REG_READ2(int, "shutdown", int, s, int, how);
877 }
878
879 PRE(sys_bind)
880 {
881    PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
882    PRE_REG_READ3(long, "bind",
883                  int, sockfd, struct sockaddr *, my_addr, int, addrlen);
884    ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
885 }
886
887 PRE(sys_listen)
888 {
889    PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
890    PRE_REG_READ2(long, "listen", int, s, int, backlog);
891 }
892
893 PRE(sys_getsockname)
894 {
895    PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
896    PRE_REG_READ3(long, "getsockname",
897                  int, s, struct sockaddr *, name, int *, namelen);
898    ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
899 }
900 POST(sys_getsockname)
901 {
902    vg_assert(SUCCESS);
903    ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
904                                           ARG1,ARG2,ARG3);
905 }
906
907 PRE(sys_getpeername)
908 {
909    PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
910    PRE_REG_READ3(long, "getpeername",
911                  int, s, struct sockaddr *, name, int *, namelen);
912    ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
913 }
914 POST(sys_getpeername)
915 {
916    vg_assert(SUCCESS);
917    ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
918                                           ARG1,ARG2,ARG3);
919 }
920
921 PRE(sys_socketpair)
922 {
923    PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
924    PRE_REG_READ4(long, "socketpair",
925                  int, d, int, type, int, protocol, int*, sv);
926    ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
927 }
928 POST(sys_socketpair)
929 {
930    vg_assert(SUCCESS);
931    ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
932                                          ARG1,ARG2,ARG3,ARG4);
933 }
934
935 PRE(sys_send)
936 {
937    *flags |= SfMayBlock;
938    PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
939    PRE_REG_READ4(long, "send",
940                  int, s, const void *, msg, int, len, 
941                  unsigned int, flags);
942
943    ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
944 }
945
946 PRE(sys_recv)
947 {
948    *flags |= SfMayBlock;
949    PRINT("sys_recv ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
950    PRE_REG_READ4(long, "recv",
951                  int, s, void *, buf, int, len, unsigned int, flags);
952    ML_(generic_PRE_sys_recv)( tid, ARG1, ARG2, ARG3 );
953 }
954
955 POST(sys_recv)
956 {
957    ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 );
958 }
959
960 PRE(sys_mmap2)
961 {
962    SysRes r;
963
964    // Exactly like old_mmap() except:
965    //  - all 6 args are passed in regs, rather than in a memory-block.
966    //  - the file offset is specified in pagesize units rather than bytes,
967    //    so that it can be used for files bigger than 2^32 bytes.
968    // pagesize or 4K-size units in offset?  For ppc32/64-linux, this is
969    // 4K-sized.  Assert that the page size is 4K here for safety.
970    vg_assert(VKI_PAGE_SIZE == 4096);
971    PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
972          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
973    PRE_REG_READ6(long, "mmap2",
974                  unsigned long, start, unsigned long, length,
975                  unsigned long, prot,  unsigned long, flags,
976                  unsigned long, fd,    unsigned long, offset);
977
978    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 
979                                        4096 * (Off64T)ARG6 );
980    SET_STATUS_from_SysRes(r);
981 }
982
983 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
984 // applicable to every architecture -- I think only to 32-bit archs.
985 // We're going to need something like linux/core_os32.h for such
986 // things, eventually, I think.  --njn
987 PRE(sys_lstat64)
988 {
989    PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
990    PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
991    PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
992    PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
993 }
994
995 POST(sys_lstat64)
996 {
997    vg_assert(SUCCESS);
998    if (RES == 0) {
999       POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1000    }
1001 }
1002
1003 PRE(sys_stat64)
1004 {
1005    PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
1006    PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
1007    PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
1008    PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
1009 }
1010
1011 POST(sys_stat64)
1012 {
1013    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1014 }
1015
1016 PRE(sys_fstatat64)
1017 {
1018    PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
1019    PRE_REG_READ3(long, "fstatat64",
1020                  int, dfd, char *, file_name, struct stat64 *, buf);
1021    PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
1022    PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
1023 }
1024
1025 POST(sys_fstatat64)
1026 {
1027    POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
1028 }
1029
1030 PRE(sys_fstat64)
1031 {
1032    PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
1033    PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
1034    PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1035 }
1036
1037 POST(sys_fstat64)
1038 {
1039    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1040 }
1041
1042 PRE(sys_clone)
1043 {
1044     UInt cloneflags;
1045
1046    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
1047    PRE_REG_READ5(int, "clone",
1048                  unsigned long, flags,
1049                  void *, child_stack,
1050                  int *, parent_tidptr,
1051                  void *, child_tls,
1052                  int *, child_tidptr);
1053
1054    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
1055       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
1056       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 
1057                                              VKI_PROT_WRITE)) {
1058          SET_STATUS_Failure( VKI_EFAULT );
1059          return;
1060       }
1061    }
1062    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
1063       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
1064       if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 
1065                                              VKI_PROT_WRITE)) {
1066          SET_STATUS_Failure( VKI_EFAULT );
1067          return;
1068       }
1069    }
1070    if (ARG1 & VKI_CLONE_SETTLS) {
1071       PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
1072       if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t), 
1073                                              VKI_PROT_READ)) {
1074          SET_STATUS_Failure( VKI_EFAULT );
1075          return;
1076       }
1077    }
1078
1079    cloneflags = ARG1;
1080
1081    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
1082       SET_STATUS_Failure( VKI_EINVAL );
1083       return;
1084    }
1085
1086    /* Only look at the flags we really care about */
1087    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 
1088                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
1089    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
1090       /* thread creation */
1091       SET_STATUS_from_SysRes(
1092          do_clone(tid,
1093                   ARG1,         /* flags */
1094                   (Addr)ARG2,   /* child ESP */
1095                   (Int *)ARG3,  /* parent_tidptr */
1096                   (Int *)ARG5,  /* child_tidptr */
1097                   (Addr)ARG4)); /* set_tls */
1098       break;
1099
1100    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
1101       /* FALLTHROUGH - assume vfork == fork */
1102       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
1103
1104    case 0: /* plain fork */
1105       SET_STATUS_from_SysRes(
1106          ML_(do_fork_clone)(tid,
1107                        cloneflags,      /* flags */
1108                        (Int *)ARG3,     /* parent_tidptr */
1109                        (Int *)ARG5));   /* child_tidptr */
1110       break;
1111
1112    default:
1113       /* should we just ENOSYS? */
1114       VG_(message)(Vg_UserMsg, "");
1115       VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
1116       VG_(message)(Vg_UserMsg, "");
1117       VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
1118       VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
1119       VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
1120       VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
1121       VG_(unimplemented)
1122          ("Valgrind does not support general clone().");
1123    }
1124
1125    if (SUCCESS) {
1126       if (ARG1 & VKI_CLONE_PARENT_SETTID)
1127          POST_MEM_WRITE(ARG3, sizeof(Int));
1128       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1129          POST_MEM_WRITE(ARG5, sizeof(Int));
1130
1131       /* Thread creation was successful; let the child have the chance
1132          to run */
1133       *flags |= SfYieldAfter;
1134    }
1135 }
1136
1137 PRE(sys_sigreturn)
1138 {
1139    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1140      an explanation of what follows. */
1141
1142    PRINT("sys_sigreturn ( )");
1143
1144    vg_assert(VG_(is_valid_tid)(tid));
1145    vg_assert(tid >= 1 && tid < VG_N_THREADS);
1146    vg_assert(VG_(is_running_thread)(tid));
1147
1148    /* Restore register state from frame and remove it */
1149    VG_(sigframe_destroy)(tid, False);
1150
1151    /* Tell the driver not to update the guest state with the "result",
1152       and set a bogus result to keep it happy. */
1153    *flags |= SfNoWriteResult;
1154    SET_STATUS_Success(0);
1155
1156    /* Check to see if any signals arose as a result of this. */
1157    *flags |= SfPollAfter;
1158 }
1159
1160 PRE(sys_rt_sigreturn)
1161 {
1162   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1163       an explanation of what follows. */
1164
1165    PRINT("rt_sigreturn ( )");
1166
1167    vg_assert(VG_(is_valid_tid)(tid));
1168    vg_assert(tid >= 1 && tid < VG_N_THREADS);
1169    vg_assert(VG_(is_running_thread)(tid));
1170
1171    /* Restore register state from frame and remove it */
1172    VG_(sigframe_destroy)(tid, True);
1173
1174    /* Tell the driver not to update the guest state with the "result",
1175       and set a bogus result to keep it happy. */
1176    *flags |= SfNoWriteResult;
1177    SET_STATUS_Success(0);
1178
1179    /* Check to see if any signals arose as a result of this. */
1180    *flags |= SfPollAfter;
1181 }
1182
1183 /* Very much ARM specific */
1184
1185 PRE(sys_set_tls)
1186 {
1187    PRE_REG_READ1(long, "set_tls", unsigned long, addr);
1188
1189    SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
1190 }
1191
1192 PRE(sys_cacheflush)
1193 {
1194    PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3);
1195    PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags);
1196    VG_(discard_translations)( (Addr64)ARG1,
1197                               ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/,
1198                               "PRE(sys_cacheflush)" );
1199    SET_STATUS_Success(0);
1200 }
1201
1202
1203 #undef PRE
1204 #undef POST
1205
1206 /* ---------------------------------------------------------------------
1207    The arm/Linux syscall table
1208    ------------------------------------------------------------------ */
1209
1210 #if 0
1211 #define __NR_OABI_SYSCALL_BASE 0x900000
1212 #else
1213 #define __NR_OABI_SYSCALL_BASE 0x0
1214 #endif
1215
1216 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(arm_linux, sysno, name) 
1217 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(arm_linux, sysno, name)
1218
1219 // This table maps from __NR_xxx syscall numbers (from
1220 // linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo()
1221 // wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S).
1222 //
1223 // For those syscalls not handled by Valgrind, the annotation indicate its
1224 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1225 // (unknown).
1226
1227 static SyscallTableEntry syscall_main_table[] = {
1228 //zz    //   (restart_syscall)                             // 0
1229    GENX_(__NR_exit,              sys_exit),           // 1
1230    GENX_(__NR_fork,              sys_fork),           // 2
1231    GENXY(__NR_read,              sys_read),           // 3
1232    GENX_(__NR_write,             sys_write),          // 4
1233
1234    GENXY(__NR_open,              sys_open),           // 5
1235    GENXY(__NR_close,             sys_close),          // 6
1236 //   GENXY(__NR_waitpid,           sys_waitpid),        // 7
1237    GENXY(__NR_creat,             sys_creat),          // 8
1238    GENX_(__NR_link,              sys_link),           // 9
1239
1240    GENX_(__NR_unlink,            sys_unlink),         // 10
1241    GENX_(__NR_execve,            sys_execve),         // 11
1242    GENX_(__NR_chdir,             sys_chdir),          // 12
1243    GENXY(__NR_time,              sys_time),           // 13
1244    GENX_(__NR_mknod,             sys_mknod),          // 14
1245
1246    GENX_(__NR_chmod,             sys_chmod),          // 15
1247 //zz    LINX_(__NR_lchown,            sys_lchown16),       // 16
1248 //   GENX_(__NR_break,             sys_ni_syscall),     // 17
1249 //zz    //   (__NR_oldstat,           sys_stat),           // 18 (obsolete)
1250    LINX_(__NR_lseek,             sys_lseek),          // 19
1251
1252    GENX_(__NR_getpid,            sys_getpid),         // 20
1253    LINX_(__NR_mount,             sys_mount),          // 21
1254    LINX_(__NR_umount,            sys_oldumount),      // 22
1255    LINX_(__NR_setuid,            sys_setuid16),       // 23 ## P
1256    LINX_(__NR_getuid,            sys_getuid16),       // 24 ## P
1257 //zz 
1258 //zz    //   (__NR_stime,             sys_stime),          // 25 * (SVr4,SVID,X/OPEN)
1259 //   PLAXY(__NR_ptrace,            sys_ptrace),         // 26
1260    GENX_(__NR_alarm,             sys_alarm),          // 27
1261 //zz    //   (__NR_oldfstat,          sys_fstat),          // 28 * L -- obsolete
1262    GENX_(__NR_pause,             sys_pause),          // 29
1263
1264    LINX_(__NR_utime,             sys_utime),          // 30
1265 //   GENX_(__NR_stty,              sys_ni_syscall),     // 31
1266 //   GENX_(__NR_gtty,              sys_ni_syscall),     // 32
1267    GENX_(__NR_access,            sys_access),         // 33
1268    GENX_(__NR_nice,              sys_nice),           // 34
1269
1270 //   GENX_(__NR_ftime,             sys_ni_syscall),     // 35
1271    GENX_(__NR_sync,              sys_sync),           // 36
1272    GENX_(__NR_kill,              sys_kill),           // 37
1273    GENX_(__NR_rename,            sys_rename),         // 38
1274    GENX_(__NR_mkdir,             sys_mkdir),          // 39
1275
1276    GENX_(__NR_rmdir,             sys_rmdir),          // 40
1277    GENXY(__NR_dup,               sys_dup),            // 41
1278    LINXY(__NR_pipe,              sys_pipe),           // 42
1279    GENXY(__NR_times,             sys_times),          // 43
1280 //   GENX_(__NR_prof,              sys_ni_syscall),     // 44
1281 //zz 
1282    GENX_(__NR_brk,               sys_brk),            // 45
1283    LINX_(__NR_setgid,            sys_setgid16),       // 46
1284    LINX_(__NR_getgid,            sys_getgid16),       // 47
1285 //zz    //   (__NR_signal,            sys_signal),         // 48 */* (ANSI C)
1286    LINX_(__NR_geteuid,           sys_geteuid16),      // 49
1287
1288    LINX_(__NR_getegid,           sys_getegid16),      // 50
1289    GENX_(__NR_acct,              sys_acct),           // 51
1290    LINX_(__NR_umount2,           sys_umount),         // 52
1291 //   GENX_(__NR_lock,              sys_ni_syscall),     // 53
1292    LINXY(__NR_ioctl,             sys_ioctl),          // 54
1293
1294    LINXY(__NR_fcntl,             sys_fcntl),          // 55
1295 //   GENX_(__NR_mpx,               sys_ni_syscall),     // 56
1296    GENX_(__NR_setpgid,           sys_setpgid),        // 57
1297 //   GENX_(__NR_ulimit,            sys_ni_syscall),     // 58
1298 //zz    //   (__NR_oldolduname,       sys_olduname),       // 59 Linux -- obsolete
1299 //zz 
1300    GENX_(__NR_umask,             sys_umask),          // 60
1301    GENX_(__NR_chroot,            sys_chroot),         // 61
1302 //zz    //   (__NR_ustat,             sys_ustat)           // 62 SVr4 -- deprecated
1303    GENXY(__NR_dup2,              sys_dup2),           // 63
1304    GENX_(__NR_getppid,           sys_getppid),        // 64
1305
1306    GENX_(__NR_getpgrp,           sys_getpgrp),        // 65
1307    GENX_(__NR_setsid,            sys_setsid),         // 66
1308 //      _____(__NR_sigaction,         sys_sigaction),      // 67
1309 //zz    //   (__NR_sgetmask,          sys_sgetmask),       // 68 */* (ANSI C)
1310 //zz    //   (__NR_ssetmask,          sys_ssetmask),       // 69 */* (ANSI C)
1311 //zz 
1312    LINX_(__NR_setreuid,          sys_setreuid16),     // 70
1313    LINX_(__NR_setregid,          sys_setregid16),     // 71
1314 //   _____(__NR_sigsuspend,        sys_sigsuspend),     // 72
1315    LINXY(__NR_sigpending,        sys_sigpending),     // 73
1316 //zz    //   (__NR_sethostname,       sys_sethostname),    // 74 */*
1317 //zz 
1318    GENX_(__NR_setrlimit,         sys_setrlimit),      // 75
1319    GENXY(__NR_getrlimit,         sys_old_getrlimit),  // 76
1320    GENXY(__NR_getrusage,         sys_getrusage),      // 77
1321    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 78
1322    GENX_(__NR_settimeofday,      sys_settimeofday),   // 79
1323
1324    LINXY(__NR_getgroups,         sys_getgroups16),    // 80
1325    LINX_(__NR_setgroups,         sys_setgroups16),    // 81
1326 //   PLAX_(__NR_select,            old_select),         // 82
1327    GENX_(__NR_symlink,           sys_symlink),        // 83
1328 //zz    //   (__NR_oldlstat,          sys_lstat),          // 84 -- obsolete
1329 //zz 
1330    GENX_(__NR_readlink,          sys_readlink),       // 85
1331 //zz    //   (__NR_uselib,            sys_uselib),         // 86 */Linux
1332 //zz    //   (__NR_swapon,            sys_swapon),         // 87 */Linux
1333 //zz    //   (__NR_reboot,            sys_reboot),         // 88 */Linux
1334 //zz    //   (__NR_readdir,           old_readdir),        // 89 -- superseded
1335 //zz 
1336 //   _____(__NR_mmap,              old_mmap),           // 90
1337    GENXY(__NR_munmap,            sys_munmap),         // 91
1338    GENX_(__NR_truncate,          sys_truncate),       // 92
1339    GENX_(__NR_ftruncate,         sys_ftruncate),      // 93
1340    GENX_(__NR_fchmod,            sys_fchmod),         // 94
1341
1342    LINX_(__NR_fchown,            sys_fchown16),       // 95
1343    GENX_(__NR_getpriority,       sys_getpriority),    // 96
1344    GENX_(__NR_setpriority,       sys_setpriority),    // 97
1345 //   GENX_(__NR_profil,            sys_ni_syscall),     // 98
1346    GENXY(__NR_statfs,            sys_statfs),         // 99
1347
1348    GENXY(__NR_fstatfs,           sys_fstatfs),        // 100
1349 //   LINX_(__NR_ioperm,            sys_ioperm),         // 101
1350    PLAXY(__NR_socketcall,        sys_socketcall),     // 102
1351    LINXY(__NR_syslog,            sys_syslog),         // 103
1352    GENXY(__NR_setitimer,         sys_setitimer),      // 104
1353
1354    GENXY(__NR_getitimer,         sys_getitimer),      // 105
1355    GENXY(__NR_stat,              sys_newstat),        // 106
1356    GENXY(__NR_lstat,             sys_newlstat),       // 107
1357    GENXY(__NR_fstat,             sys_newfstat),       // 108
1358 //zz    //   (__NR_olduname,          sys_uname),          // 109 -- obsolete
1359 //zz 
1360 //   GENX_(__NR_iopl,              sys_iopl),           // 110
1361    LINX_(__NR_vhangup,           sys_vhangup),        // 111
1362 //   GENX_(__NR_idle,              sys_ni_syscall),     // 112
1363 // PLAXY(__NR_vm86old,           sys_vm86old),        // 113 __NR_syscall... weird
1364    GENXY(__NR_wait4,             sys_wait4),          // 114
1365 //zz 
1366 //zz    //   (__NR_swapoff,           sys_swapoff),        // 115 */Linux 
1367    LINXY(__NR_sysinfo,           sys_sysinfo),        // 116
1368 //   _____(__NR_ipc,               sys_ipc),            // 117
1369    GENX_(__NR_fsync,             sys_fsync),          // 118
1370    PLAX_(__NR_sigreturn,         sys_sigreturn),      // 119 ?/Linux
1371
1372    PLAX_(__NR_clone,             sys_clone),          // 120
1373 //zz    //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
1374    GENXY(__NR_uname,             sys_newuname),       // 122
1375 //   PLAX_(__NR_modify_ldt,        sys_modify_ldt),     // 123
1376 //zz    LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
1377 //zz 
1378    GENXY(__NR_mprotect,          sys_mprotect),       // 125
1379    //   LINXY(__NR_sigprocmask,       sys_sigprocmask),    // 126
1380 //zz    // Nb: create_module() was removed 2.4-->2.6
1381 //   GENX_(__NR_create_module,     sys_ni_syscall),     // 127
1382    LINX_(__NR_init_module,       sys_init_module),    // 128
1383    LINX_(__NR_delete_module,     sys_delete_module),  // 129
1384 //zz 
1385 //zz    // Nb: get_kernel_syms() was removed 2.4-->2.6
1386 //   GENX_(__NR_get_kernel_syms,   sys_ni_syscall),     // 130
1387    LINX_(__NR_quotactl,          sys_quotactl),       // 131
1388    GENX_(__NR_getpgid,           sys_getpgid),        // 132
1389    GENX_(__NR_fchdir,            sys_fchdir),         // 133
1390 //zz    //   (__NR_bdflush,           sys_bdflush),        // 134 */Linux
1391 //zz 
1392 //zz    //   (__NR_sysfs,             sys_sysfs),          // 135 SVr4
1393    LINX_(__NR_personality,       sys_personality),    // 136
1394 //   GENX_(__NR_afs_syscall,       sys_ni_syscall),     // 137
1395    LINX_(__NR_setfsuid,          sys_setfsuid16),     // 138
1396    LINX_(__NR_setfsgid,          sys_setfsgid16),     // 139
1397  
1398    LINXY(__NR__llseek,           sys_llseek),         // 140
1399    GENXY(__NR_getdents,          sys_getdents),       // 141
1400    GENX_(__NR__newselect,        sys_select),         // 142
1401    GENX_(__NR_flock,             sys_flock),          // 143
1402    GENX_(__NR_msync,             sys_msync),          // 144
1403
1404    GENXY(__NR_readv,             sys_readv),          // 145
1405    GENX_(__NR_writev,            sys_writev),         // 146
1406    GENX_(__NR_getsid,            sys_getsid),         // 147
1407    GENX_(__NR_fdatasync,         sys_fdatasync),      // 148
1408    LINXY(__NR__sysctl,           sys_sysctl),         // 149
1409
1410    GENX_(__NR_mlock,             sys_mlock),          // 150
1411    GENX_(__NR_munlock,           sys_munlock),        // 151
1412    GENX_(__NR_mlockall,          sys_mlockall),       // 152
1413    LINX_(__NR_munlockall,        sys_munlockall),     // 153
1414    LINXY(__NR_sched_setparam,    sys_sched_setparam), // 154
1415
1416    LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
1417    LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
1418    LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
1419    LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
1420    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1421
1422    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1423 //zz    //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
1424    GENXY(__NR_nanosleep,         sys_nanosleep),      // 162
1425    GENX_(__NR_mremap,            sys_mremap),         // 163
1426    LINX_(__NR_setresuid,         sys_setresuid16),    // 164
1427
1428    LINXY(__NR_getresuid,         sys_getresuid16),    // 165
1429 //   PLAXY(__NR_vm86,              sys_vm86),           // 166 x86/Linux-only
1430 //   GENX_(__NR_query_module,      sys_ni_syscall),     // 167
1431    GENXY(__NR_poll,              sys_poll),           // 168
1432 //zz    //   (__NR_nfsservctl,        sys_nfsservctl),     // 169 */Linux
1433 //zz 
1434    LINX_(__NR_setresgid,         sys_setresgid16),    // 170
1435    LINXY(__NR_getresgid,         sys_getresgid16),    // 171
1436    LINXY(__NR_prctl,             sys_prctl),          // 172
1437    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 173 
1438    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 174
1439
1440    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 175
1441    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 176
1442    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 177
1443    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 178
1444    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 179
1445
1446    GENXY(__NR_pread64,           sys_pread64),        // 180
1447    //GENX_(__NR_pwrite64,          sys_pwrite64_on32bitplat),       // 181
1448    LINX_(__NR_chown,             sys_chown16),        // 182
1449    GENXY(__NR_getcwd,            sys_getcwd),         // 183
1450    LINXY(__NR_capget,            sys_capget),         // 184
1451
1452    LINX_(__NR_capset,            sys_capset),         // 185
1453    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 186
1454    LINXY(__NR_sendfile,          sys_sendfile),       // 187
1455 //   GENXY(__NR_getpmsg,           sys_getpmsg),        // 188
1456 //   GENX_(__NR_putpmsg,           sys_putpmsg),        // 189
1457
1458    // Nb: we treat vfork as fork
1459    GENX_(__NR_vfork,             sys_fork),           // 190
1460    GENXY(__NR_ugetrlimit,        sys_getrlimit),      // 191
1461    PLAX_(__NR_mmap2,             sys_mmap2),          // 192
1462    GENX_(__NR_truncate64,        sys_truncate64),     // 193
1463    GENX_(__NR_ftruncate64,       sys_ftruncate64),    // 194
1464    
1465    PLAXY(__NR_stat64,            sys_stat64),         // 195
1466    PLAXY(__NR_lstat64,           sys_lstat64),        // 196
1467    PLAXY(__NR_fstat64,           sys_fstat64),        // 197
1468    GENX_(__NR_lchown32,          sys_lchown),         // 198
1469    GENX_(__NR_getuid32,          sys_getuid),         // 199
1470
1471    GENX_(__NR_getgid32,          sys_getgid),         // 200
1472    GENX_(__NR_geteuid32,         sys_geteuid),        // 201
1473    GENX_(__NR_getegid32,         sys_getegid),        // 202
1474    GENX_(__NR_setreuid32,        sys_setreuid),       // 203
1475    GENX_(__NR_setregid32,        sys_setregid),       // 204
1476
1477    GENXY(__NR_getgroups32,       sys_getgroups),      // 205
1478    GENX_(__NR_setgroups32,       sys_setgroups),      // 206
1479    GENX_(__NR_fchown32,          sys_fchown),         // 207
1480    LINX_(__NR_setresuid32,       sys_setresuid),      // 208
1481    LINXY(__NR_getresuid32,       sys_getresuid),      // 209
1482
1483    LINX_(__NR_setresgid32,       sys_setresgid),      // 210
1484    LINXY(__NR_getresgid32,       sys_getresgid),      // 211
1485    GENX_(__NR_chown32,           sys_chown),          // 212
1486    GENX_(__NR_setuid32,          sys_setuid),         // 213
1487    GENX_(__NR_setgid32,          sys_setgid),         // 214
1488
1489    LINX_(__NR_setfsuid32,        sys_setfsuid),       // 215
1490    LINX_(__NR_setfsgid32,        sys_setfsgid),       // 216
1491 //zz    //   (__NR_pivot_root,        sys_pivot_root),     // 217 */Linux
1492    GENXY(__NR_mincore,           sys_mincore),        // 218
1493    GENX_(__NR_madvise,           sys_madvise),        // 219
1494
1495    GENXY(__NR_getdents64,        sys_getdents64),     // 220
1496    LINXY(__NR_fcntl64,           sys_fcntl64),        // 221
1497 //   GENX_(222,                    sys_ni_syscall),     // 222
1498 //   PLAXY(223,                    sys_syscall223),     // 223 // sys_bproc?
1499    LINX_(__NR_gettid,            sys_gettid),         // 224
1500
1501 //zz    //   (__NR_readahead,         sys_readahead),      // 225 */(Linux?)
1502    LINX_(__NR_setxattr,          sys_setxattr),       // 226
1503    LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 227
1504    LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 228
1505    LINXY(__NR_getxattr,          sys_getxattr),       // 229
1506
1507    LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 230
1508    LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 231
1509    LINXY(__NR_listxattr,         sys_listxattr),      // 232
1510    LINXY(__NR_llistxattr,        sys_llistxattr),     // 233
1511    LINXY(__NR_flistxattr,        sys_flistxattr),     // 234
1512
1513    LINX_(__NR_removexattr,       sys_removexattr),    // 235
1514    LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 236
1515    LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 237
1516    LINXY(__NR_tkill,             sys_tkill),          // 238 */Linux
1517    LINXY(__NR_sendfile64,        sys_sendfile64),     // 239
1518
1519    LINXY(__NR_futex,             sys_futex),             // 240
1520    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1521    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1522 //   PLAX_(__NR_set_thread_area,   sys_set_thread_area),   // 243
1523 //   PLAX_(__NR_get_thread_area,   sys_get_thread_area),   // 244
1524
1525    LINXY(__NR_io_setup,          sys_io_setup),       // 245
1526    LINX_(__NR_io_destroy,        sys_io_destroy),     // 246
1527    LINXY(__NR_io_getevents,      sys_io_getevents),   // 247
1528    LINX_(__NR_io_submit,         sys_io_submit),      // 248
1529    LINXY(__NR_io_cancel,         sys_io_cancel),      // 249
1530
1531 //   LINX_(__NR_fadvise64,         sys_fadvise64),      // 250 */(Linux?)
1532    GENX_(251,                    sys_ni_syscall),     // 251
1533    LINX_(__NR_exit_group,        sys_exit_group),     // 252
1534 //   GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 253
1535    LINXY(__NR_epoll_create,      sys_epoll_create),   // 254
1536
1537    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 255
1538    LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 256
1539 //zz    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 257 */Linux
1540    LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 258
1541    LINXY(__NR_timer_create,      sys_timer_create),      // 259
1542
1543    LINXY(__NR_timer_settime,     sys_timer_settime),  // (timer_create+1)
1544    LINXY(__NR_timer_gettime,     sys_timer_gettime),  // (timer_create+2)
1545    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),//(timer_create+3)
1546    LINX_(__NR_timer_delete,      sys_timer_delete),   // (timer_create+4)
1547    LINX_(__NR_clock_settime,     sys_clock_settime),  // (timer_create+5)
1548
1549    LINXY(__NR_clock_gettime,     sys_clock_gettime),  // (timer_create+6)
1550    LINXY(__NR_clock_getres,      sys_clock_getres),   // (timer_create+7)
1551    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// (timer_create+8) */*
1552    GENXY(__NR_statfs64,          sys_statfs64),       // 268
1553    GENXY(__NR_fstatfs64,         sys_fstatfs64),      // 269
1554
1555    LINX_(__NR_tgkill,            sys_tgkill),         // 270 */Linux
1556    GENX_(__NR_utimes,            sys_utimes),         // 271
1557 //   LINX_(__NR_fadvise64_64,      sys_fadvise64_64),   // 272 */(Linux?)
1558    GENX_(__NR_vserver,           sys_ni_syscall),     // 273
1559    LINX_(__NR_mbind,             sys_mbind),          // 274 ?/?
1560
1561    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 275 ?/?
1562    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 276 ?/?
1563    LINXY(__NR_mq_open,           sys_mq_open),        // 277
1564    LINX_(__NR_mq_unlink,         sys_mq_unlink),      // (mq_open+1)
1565    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // (mq_open+2)
1566
1567    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// (mq_open+3)
1568    LINX_(__NR_mq_notify,         sys_mq_notify),      // (mq_open+4)
1569    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // (mq_open+5)
1570    LINXY(__NR_waitid,            sys_waitid),         // 280
1571
1572    PLAXY(__NR_socket,            sys_socket),         // 281
1573    PLAX_(__NR_bind,              sys_bind),           // 282
1574    PLAX_(__NR_connect,           sys_connect),        // 283
1575    PLAX_(__NR_listen,            sys_listen),         // 284
1576    PLAXY(__NR_accept,            sys_accept),         // 285
1577    PLAXY(__NR_getsockname,       sys_getsockname),    // 286
1578    PLAXY(__NR_getpeername,       sys_getpeername),    // 287
1579    PLAXY(__NR_socketpair,        sys_socketpair),     // 288
1580    PLAX_(__NR_send,              sys_send),
1581    PLAX_(__NR_sendto,            sys_sendto),         // 290
1582    PLAXY(__NR_recv,              sys_recv),
1583    PLAXY(__NR_recvfrom,          sys_recvfrom),       // 292
1584    PLAX_(__NR_shutdown,          sys_shutdown),       // 293
1585    PLAX_(__NR_setsockopt,        sys_setsockopt),     // 294
1586    PLAXY(__NR_getsockopt,        sys_getsockopt),     // 295
1587    PLAX_(__NR_sendmsg,           sys_sendmsg),        // 296
1588    PLAXY(__NR_recvmsg,           sys_recvmsg),        // 297
1589    PLAX_(__NR_semop,             sys_semop),          // 298 
1590    PLAX_(__NR_semget,            sys_semget),         // 299
1591    PLAXY(__NR_semctl,            sys_semctl),         // 300
1592    PLAX_(__NR_msgget,            sys_msgget),         
1593    PLAX_(__NR_msgsnd,            sys_msgsnd),          
1594    PLAXY(__NR_msgrcv,            sys_msgrcv),         
1595    PLAXY(__NR_msgctl,            sys_msgctl),         // 304
1596    PLAX_(__NR_semtimedop,        sys_semtimedop),     // 312
1597
1598    LINX_(__NR_add_key,           sys_add_key),        // 286
1599    LINX_(__NR_request_key,       sys_request_key),    // 287
1600    LINXY(__NR_keyctl,            sys_keyctl),         // not 288...
1601 //   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 289
1602
1603 //   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 290
1604    LINX_(__NR_inotify_init,    sys_inotify_init),   // 291
1605    LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1606    LINX_(__NR_inotify_rm_watch,    sys_inotify_rm_watch), // 293
1607 //   LINX_(__NR_migrate_pages,    sys_migrate_pages),    // 294
1608
1609    LINXY(__NR_openat,       sys_openat),           // 295
1610    LINX_(__NR_mkdirat,       sys_mkdirat),          // 296
1611    LINX_(__NR_mknodat,       sys_mknodat),          // 297
1612    LINX_(__NR_fchownat,       sys_fchownat),         // 298
1613    LINX_(__NR_futimesat,    sys_futimesat),        // 326 on arm
1614
1615    PLAXY(__NR_fstatat64,    sys_fstatat64),        // 300
1616    LINX_(__NR_unlinkat,       sys_unlinkat),         // 301
1617    LINX_(__NR_renameat,       sys_renameat),         // 302
1618    LINX_(__NR_linkat,       sys_linkat),           // 303
1619    LINX_(__NR_symlinkat,    sys_symlinkat),        // 304
1620
1621    LINX_(__NR_readlinkat,    sys_readlinkat),       // 
1622    LINX_(__NR_fchmodat,       sys_fchmodat),         //
1623    LINX_(__NR_faccessat,    sys_faccessat),        //
1624    PLAXY(__NR_shmat,         wrap_sys_shmat),       //305
1625    PLAXY(__NR_shmdt,             sys_shmdt),          //306 
1626    PLAX_(__NR_shmget,            sys_shmget),         //307 
1627    PLAXY(__NR_shmctl,            sys_shmctl),         // 308 
1628 //   LINX_(__NR_pselect6,       sys_pselect6),         //
1629 //   LINXY(__NR_ppoll,       sys_ppoll),            // 309
1630
1631 //   LINX_(__NR_unshare,       sys_unshare),          // 310
1632    LINX_(__NR_set_robust_list,    sys_set_robust_list),  // 311
1633    LINXY(__NR_get_robust_list,    sys_get_robust_list),  // 312
1634 //   LINX_(__NR_splice,            sys_ni_syscall),       // 313
1635 //   LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 314
1636
1637 //   LINX_(__NR_tee,               sys_ni_syscall),       // 315
1638 //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 316
1639 //   LINX_(__NR_move_pages,        sys_ni_syscall),       // 317
1640 //   LINX_(__NR_getcpu,            sys_ni_syscall),       // 318
1641 //   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 319
1642
1643    LINX_(__NR_utimensat,         sys_utimensat),        // 320
1644    LINXY(__NR_signalfd,          sys_signalfd),         // 321
1645    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 322
1646    LINX_(__NR_eventfd,           sys_eventfd),          // 323
1647 //   LINX_(__NR_fallocate,        sys_ni_syscall),        // 324
1648    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 325
1649    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),   // 326
1650
1651    ///////////////
1652
1653    // JRS 2010-Jan-03: I believe that all the numbers listed 
1654    // in comments in the table prior to this point (eg "// 326",
1655    // etc) are bogus since it looks to me like they are copied
1656    // verbatim from syswrap-x86-linux.c and they certainly do not
1657    // correspond to what's in include/vki/vki-scnums-arm-linux.h.
1658    // From here onwards, please ensure the numbers are correct.
1659
1660    LINXY(__NR_signalfd4,         sys_signalfd4),        // 355
1661    LINX_(__NR_eventfd2,          sys_eventfd2),         // 356
1662
1663    LINXY(__NR_pipe2,             sys_pipe2)             // 359
1664 };
1665
1666
1667 /* These are not in the main table because there indexes are not small
1668    integers, but rather values close to one million.  So their
1669    inclusion would force the main table to be huge (about 8 MB). */
1670
1671 static SyscallTableEntry ste___ARM_set_tls
1672    = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
1673
1674 static SyscallTableEntry ste___ARM_cacheflush
1675    = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
1676
1677 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1678 {
1679    const UInt syscall_main_table_size
1680       = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
1681
1682    /* Is it in the contiguous initial section of the table? */
1683    if (sysno < syscall_main_table_size) {
1684       SyscallTableEntry* sys = &syscall_main_table[sysno];
1685       if (sys->before == NULL)
1686          return NULL; /* no entry */
1687       else
1688          return sys;
1689    }
1690
1691    /* Check if it's one of the out-of-line entries. */
1692    switch (sysno) {
1693       case __NR_ARM_set_tls:    return &ste___ARM_set_tls;
1694       case __NR_ARM_cacheflush: return &ste___ARM_cacheflush;
1695       default: break;
1696    }
1697
1698    /* Can't find a wrapper */
1699    return NULL;
1700 }
1701
1702 #endif // defined(VGP_arm_linux)
1703
1704 /*--------------------------------------------------------------------*/
1705 /*--- end                                      syswrap-arm-linux.c ---*/
1706 /*--------------------------------------------------------------------*/