syswrap-arm-linux.c revision 3a7c5ad5ac99454ae15caadf67defdfaa6395292
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-2009 Nicholas Nethercote
11      njn@valgrind.org
12   Copyright (C) 2008-2009 Evan Geller
13      gaze@bea.ms
14
15   This program is free software; you can redistribute it and/or
16   modify it under the terms of the GNU General Public License as
17   published by the Free Software Foundation; either version 2 of the
18   License, or (at your option) any later version.
19
20   This program is distributed in the hope that it will be useful, but
21   WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   General Public License for more details.
24
25   You should have received a copy of the GNU General Public License
26   along with this program; if not, write to the Free Software
27   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28   02111-1307, USA.
29
30   The GNU General Public License is contained in the file COPYING.
31*/
32
33#if defined(VGP_arm_linux)
34
35#include "pub_core_basics.h"
36#include "pub_core_vki.h"
37#include "pub_core_vkiscnums.h"
38#include "pub_core_threadstate.h"
39#include "pub_core_aspacemgr.h"
40#include "pub_core_debuglog.h"
41#include "pub_core_libcbase.h"
42#include "pub_core_libcassert.h"
43#include "pub_core_libcprint.h"
44#include "pub_core_libcproc.h"
45#include "pub_core_libcsignal.h"
46#include "pub_core_options.h"
47#include "pub_core_scheduler.h"
48#include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
49#include "pub_core_signals.h"
50#include "pub_core_syscall.h"
51#include "pub_core_syswrap.h"
52#include "pub_core_tooliface.h"
53#include "pub_core_stacks.h"        // VG_(register_stack)
54#include "pub_core_transtab.h"      // VG_(discard_translations)
55
56#include "priv_types_n_macros.h"
57#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
58#include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
59#include "priv_syswrap-main.h"
60
61
62/* ---------------------------------------------------------------------
63   clone() handling
64   ------------------------------------------------------------------ */
65
66/* Call f(arg1), but first switch stacks, using 'stack' as the new
67   stack, and use 'retaddr' as f's return-to address.  Also, clear all
68   the integer registers before entering f.*/
69__attribute__((noreturn))
70void ML_(call_on_new_stack_0_1) ( Addr stack,
71                                  Addr retaddr,
72                                  void (*f)(Word),
73                                  Word arg1 );
74//    r0 = stack
75//    r1 = retaddr
76//    r2 = f
77//    r3 = arg1
78asm(
79".text\n"
80".globl vgModuleLocal_call_on_new_stack_0_1\n"
81"vgModuleLocal_call_on_new_stack_0_1:\n"
82"   mov    sp,r0\n\t" /* Stack pointer */
83"   mov    lr,r1\n\t" /* Return address */
84"   mov    r0,r3\n\t" /* First argument */
85"   push   {r2}\n\t"  /* So we can ret to the new dest */
86"   mov    r1, #0\n\t" /* Clear our GPRs */
87"   mov    r2, #0\n\t"
88"   mov    r3, #0\n\t"
89"   mov    r4, #0\n\t"
90"   mov    r5, #0\n\t"
91"   mov    r6, #0\n\t"
92"   mov    r7, #0\n\t"
93"   mov    r8, #0\n\t"
94"   mov    r9, #0\n\t"
95"   mov    r10, #0\n\t"
96"   mov    r11, #0\n\t"
97"   mov    r12, #0\n\t"
98"   pop    {pc}\n\t"  /* Herrre we go! */
99".previous\n"
100);
101
102
103#define __NR_CLONE        VG_STRINGIFY(__NR_clone)
104#define __NR_EXIT         VG_STRINGIFY(__NR_exit)
105
106extern
107ULong do_syscall_clone_arm_linux   ( Word (*fn)(void *),
108                                     void* stack,
109                                     Int   flags,
110                                     void* arg,
111                                     Int*  child_tid,
112                                     Int*  parent_tid,
113                                     void* tls );
114asm(
115".text\n"
116"do_syscall_clone_arm_linux:\n"
117
118/*Setup child stack */
119"   str     r0, [r1, #-4]!\n"
120"   str     r3, [r1, #-4]!\n"
121"   push {r4,r7}\n"
122"   mov r0, r2\n" /* arg1: flags */
123/* r1 (arg2) is already our child's stack */
124"   ldr r2, [sp, #12]\n" // parent tid
125"   ldr r3, [sp, #16]\n" // tls
126"   ldr r4, [sp, #8]\n" // Child tid
127"   mov r7, #"__NR_CLONE"\n"
128"   svc 0x00000000\n"
129"   cmp r0, #0\n"
130"   beq 1f\n"
131
132/* Parent */
133"   pop {r4,r7}\n"
134"   bx lr\n"
135
136"1:\n" /*child*/
137"   mov     lr, pc\n"
138"   pop     {r0,pc}\n"
139/* Retval from child is already in r0 */
140"   mov r7, #"__NR_EXIT"\n"
141"   svc 0x00000000\n"
142/* Urh.. why did exit return? */
143"   .long 0\n"
144"   .previous\n"
145);
146
147#undef __NR_CLONE
148#undef __NR_EXIT
149
150// forward declarations
151static void setup_child ( ThreadArchState*, ThreadArchState* );
152static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
153
154/*
155   When a client clones, we need to keep track of the new thread.  This means:
156   1. allocate a ThreadId+ThreadState+stack for the the thread
157
158   2. initialize the thread's new VCPU state
159
160   3. create the thread using the same args as the client requested,
161   but using the scheduler entrypoint for IP, and a separate stack
162   for SP.
163 */
164static SysRes do_clone ( ThreadId ptid,
165                         UInt flags, Addr sp,
166                         Int *parent_tidptr,
167                         Int *child_tidptr,
168                         Addr child_tls)
169{
170   const Bool debug = False;
171
172   ThreadId ctid = VG_(alloc_ThreadState)();
173   ThreadState* ptst = VG_(get_ThreadState)(ptid);
174   ThreadState* ctst = VG_(get_ThreadState)(ctid);
175   UInt r0;
176   UWord *stack;
177   NSegment const* seg;
178   SysRes res;
179   vki_sigset_t blockall, savedmask;
180
181   VG_(sigfillset)(&blockall);
182
183   vg_assert(VG_(is_running_thread)(ptid));
184   vg_assert(VG_(is_valid_tid)(ctid));
185
186   stack = (UWord*)ML_(allocstack)(ctid);
187
188   if(stack == NULL) {
189      res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
190      goto out;
191   }
192
193   setup_child( &ctst->arch, &ptst->arch );
194
195   ctst->arch.vex.guest_R0 = 0;
196   if(sp != 0)
197      ctst->arch.vex.guest_R13 = sp;
198
199   ctst->os_state.parent = ptid;
200
201   ctst->sig_mask = ptst->sig_mask;
202   ctst->tmp_sig_mask = ptst->sig_mask;
203
204   /* Start the child with its threadgroup being the same as the
205      parent's.  This is so that any exit_group calls that happen
206      after the child is created but before it sets its
207      os_state.threadgroup field for real (in thread_wrapper in
208      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
209      a race condition in which the thread is unkillable (via
210      exit_group) because its threadgroup is not set.  The race window
211      is probably only a few hundred or a few thousand cycles long.
212      See #226116. */
213   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
214
215   seg = VG_(am_find_nsegment)((Addr)sp);
216   if (seg && seg->kind != SkResvn) {
217      ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
218      ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
219
220      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
221
222      if (debug)
223         VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
224         ctid, seg->start, VG_PGROUNDUP(sp));
225   } else {
226      VG_(message)(Vg_UserMsg, "!? New thread %d starts with sp+%#lx) unmapped\n", ctid, sp);
227      ctst->client_stack_szB  = 0;
228   }
229
230   VG_TRACK ( pre_thread_ll_create, ptid, ctid );
231
232   if (flags & VKI_CLONE_SETTLS) {
233      res = sys_set_tls(ctid, child_tls);
234      if (sr_isError(res))
235         goto out;
236   }
237
238   flags &= ~VKI_CLONE_SETTLS;
239
240   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
241
242   r0 = do_syscall_clone_arm_linux(
243      ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
244      child_tidptr, parent_tidptr, NULL
245   );
246   //VG_(printf)("AFTER SYSCALL, %x and %x  CHILD: %d PARENT: %d\n",child_tidptr, parent_tidptr,*child_tidptr,*parent_tidptr);
247
248   res = VG_(mk_SysRes_arm_linux)( r0 );
249
250   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
251
252out:
253   if (sr_isError(res)) {
254      VG_(cleanup_thread)(&ctst->arch);
255      ctst->status = VgTs_Empty;
256      VG_TRACK( pre_thread_ll_exit, ctid );
257   }
258
259   return res;
260}
261
262
263
264/* ---------------------------------------------------------------------
265   More thread stuff
266   ------------------------------------------------------------------ */
267
268// ARM doesn't have any architecture specific thread stuff that
269// needs to be cleaned up
270void VG_(cleanup_thread) ( ThreadArchState* arch )
271{
272}
273
274void setup_child ( /*OUT*/ ThreadArchState *child,
275                   /*IN*/  ThreadArchState *parent )
276{
277   child->vex = parent->vex;
278   child->vex_shadow1 = parent->vex_shadow1;
279   child->vex_shadow2 = parent->vex_shadow2;
280}
281
282static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
283{
284   VG_(threads)[tid].arch.vex.guest_TPIDRURO = tlsptr;
285   return VG_(mk_SysRes_Success)( 0 );
286}
287
288/* ---------------------------------------------------------------------
289   PRE/POST wrappers for arm/Linux-specific syscalls
290   ------------------------------------------------------------------ */
291
292#define PRE(name)       DEFN_PRE_TEMPLATE(arm_linux, name)
293#define POST(name)      DEFN_POST_TEMPLATE(arm_linux, name)
294
295/* Add prototypes for the wrappers declared here, so that gcc doesn't
296   harass us for not having prototypes.  Really this is a kludge --
297   the right thing to do is to make these wrappers 'static' since they
298   aren't visible outside this file, but that requires even more macro
299   magic. */
300
301DECL_TEMPLATE(arm_linux, sys_socketcall);
302DECL_TEMPLATE(arm_linux, sys_socket);
303DECL_TEMPLATE(arm_linux, sys_setsockopt);
304DECL_TEMPLATE(arm_linux, sys_getsockopt);
305DECL_TEMPLATE(arm_linux, sys_connect);
306DECL_TEMPLATE(arm_linux, sys_accept);
307DECL_TEMPLATE(arm_linux, sys_sendto);
308DECL_TEMPLATE(arm_linux, sys_recvfrom);
309//XXX: Semaphore code ripped from AMD64.
310DECL_TEMPLATE(arm_linux, sys_semget);
311DECL_TEMPLATE(arm_linux, sys_semop);
312DECL_TEMPLATE(arm_linux, sys_semctl);
313DECL_TEMPLATE(arm_linux, sys_semtimedop);
314//XXX: Shared memory code ripped from AMD64
315//
316DECL_TEMPLATE(arm_linux, wrap_sys_shmat);
317DECL_TEMPLATE(arm_linux, sys_shmget);
318DECL_TEMPLATE(arm_linux, sys_shmdt);
319DECL_TEMPLATE(arm_linux, sys_shmctl);
320DECL_TEMPLATE(arm_linux, sys_sendmsg);
321DECL_TEMPLATE(arm_linux, sys_recvmsg);
322//msg* code from AMD64
323DECL_TEMPLATE(arm_linux, sys_msgget);
324DECL_TEMPLATE(arm_linux, sys_msgrcv);
325DECL_TEMPLATE(arm_linux, sys_msgsnd);
326DECL_TEMPLATE(arm_linux, sys_msgctl);
327DECL_TEMPLATE(arm_linux, sys_shutdown);
328DECL_TEMPLATE(arm_linux, sys_bind);
329DECL_TEMPLATE(arm_linux, sys_listen);
330DECL_TEMPLATE(arm_linux, sys_getsockname);
331DECL_TEMPLATE(arm_linux, sys_getpeername);
332DECL_TEMPLATE(arm_linux, sys_socketpair);
333DECL_TEMPLATE(arm_linux, sys_send);
334DECL_TEMPLATE(arm_linux, sys_recv);
335DECL_TEMPLATE(arm_linux, sys_mmap2);
336DECL_TEMPLATE(arm_linux, sys_stat64);
337DECL_TEMPLATE(arm_linux, sys_lstat64);
338DECL_TEMPLATE(arm_linux, sys_fstatat64);
339DECL_TEMPLATE(arm_linux, sys_fstat64);
340DECL_TEMPLATE(arm_linux, sys_clone);
341DECL_TEMPLATE(arm_linux, sys_sigreturn);
342DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
343DECL_TEMPLATE(arm_linux, sys_set_tls);
344DECL_TEMPLATE(arm_linux, sys_cacheflush);
345
346PRE(sys_socketcall)
347{
348#  define ARG2_0  (((UWord*)ARG2)[0])
349#  define ARG2_1  (((UWord*)ARG2)[1])
350#  define ARG2_2  (((UWord*)ARG2)[2])
351#  define ARG2_3  (((UWord*)ARG2)[3])
352#  define ARG2_4  (((UWord*)ARG2)[4])
353#  define ARG2_5  (((UWord*)ARG2)[5])
354
355   *flags |= SfMayBlock;
356   PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
357   PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
358
359   switch (ARG1 /* request */) {
360
361   case VKI_SYS_SOCKETPAIR:
362     /* int socketpair(int d, int type, int protocol, int sv[2]); */
363      PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
364      ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
365      break;
366
367   case VKI_SYS_SOCKET:
368     /* int socket(int domain, int type, int protocol); */
369      PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
370      break;
371
372   case VKI_SYS_BIND:
373     /* int bind(int sockfd, struct sockaddr *my_addr,
374   int addrlen); */
375      PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
376      ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
377      break;
378
379   case VKI_SYS_LISTEN:
380     /* int listen(int s, int backlog); */
381      PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
382      break;
383
384   case VKI_SYS_ACCEPT: {
385     /* int accept(int s, struct sockaddr *addr, int *addrlen); */
386      PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
387      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
388      break;
389   }
390
391   case VKI_SYS_SENDTO:
392     /* int sendto(int s, const void *msg, int len,
393                    unsigned int flags,
394                    const struct sockaddr *to, int tolen); */
395     PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
396     ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
397              ARG2_3, ARG2_4, ARG2_5 );
398     break;
399
400   case VKI_SYS_SEND:
401     /* int send(int s, const void *msg, size_t len, int flags); */
402     PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
403     ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
404     break;
405
406   case VKI_SYS_RECVFROM:
407     /* int recvfrom(int s, void *buf, int len, unsigned int flags,
408   struct sockaddr *from, int *fromlen); */
409     PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
410     ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
411                ARG2_3, ARG2_4, ARG2_5 );
412     break;
413
414   case VKI_SYS_RECV:
415     /* int recv(int s, void *buf, int len, unsigned int flags); */
416     /* man 2 recv says:
417         The  recv call is normally used only on a connected socket
418         (see connect(2)) and is identical to recvfrom with a  NULL
419         from parameter.
420     */
421     PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
422     ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
423     break;
424
425   case VKI_SYS_CONNECT:
426     /* int connect(int sockfd,
427   struct sockaddr *serv_addr, int addrlen ); */
428     PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
429     ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
430     break;
431
432   case VKI_SYS_SETSOCKOPT:
433     /* int setsockopt(int s, int level, int optname,
434   const void *optval, int optlen); */
435     PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
436     ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
437                  ARG2_3, ARG2_4 );
438     break;
439
440   case VKI_SYS_GETSOCKOPT:
441     /* int getsockopt(int s, int level, int optname,
442   void *optval, socklen_t *optlen); */
443     PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
444     ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
445                  ARG2_3, ARG2_4 );
446     break;
447
448   case VKI_SYS_GETSOCKNAME:
449     /* int getsockname(int s, struct sockaddr* name, int* namelen) */
450     PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
451     ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
452     break;
453
454   case VKI_SYS_GETPEERNAME:
455     /* int getpeername(int s, struct sockaddr* name, int* namelen) */
456     PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
457     ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
458     break;
459
460   case VKI_SYS_SHUTDOWN:
461     /* int shutdown(int s, int how); */
462     PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
463     break;
464
465   case VKI_SYS_SENDMSG: {
466     /* int sendmsg(int s, const struct msghdr *msg, int flags); */
467
468     /* this causes warnings, and I don't get why. glibc bug?
469      * (after all it's glibc providing the arguments array)
470       PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
471     */
472     ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
473     break;
474   }
475
476   case VKI_SYS_RECVMSG: {
477     /* int recvmsg(int s, struct msghdr *msg, int flags); */
478
479     /* this causes warnings, and I don't get why. glibc bug?
480      * (after all it's glibc providing the arguments array)
481       PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
482     */
483     ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
484     break;
485   }
486
487   default:
488     VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx",ARG1);
489     SET_STATUS_Failure( VKI_EINVAL );
490     break;
491   }
492#  undef ARG2_0
493#  undef ARG2_1
494#  undef ARG2_2
495#  undef ARG2_3
496#  undef ARG2_4
497#  undef ARG2_5
498}
499
500POST(sys_socketcall)
501{
502#  define ARG2_0  (((UWord*)ARG2)[0])
503#  define ARG2_1  (((UWord*)ARG2)[1])
504#  define ARG2_2  (((UWord*)ARG2)[2])
505#  define ARG2_3  (((UWord*)ARG2)[3])
506#  define ARG2_4  (((UWord*)ARG2)[4])
507#  define ARG2_5  (((UWord*)ARG2)[5])
508
509  SysRes r;
510  vg_assert(SUCCESS);
511  switch (ARG1 /* request */) {
512
513  case VKI_SYS_SOCKETPAIR:
514    r = ML_(generic_POST_sys_socketpair)(
515                tid, VG_(mk_SysRes_Success)(RES),
516                ARG2_0, ARG2_1, ARG2_2, ARG2_3
517                );
518    SET_STATUS_from_SysRes(r);
519    break;
520
521  case VKI_SYS_SOCKET:
522    r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
523    SET_STATUS_from_SysRes(r);
524    break;
525
526  case VKI_SYS_BIND:
527    /* int bind(int sockfd, struct sockaddr *my_addr,
528       int addrlen); */
529    break;
530
531  case VKI_SYS_LISTEN:
532    /* int listen(int s, int backlog); */
533    break;
534
535  case VKI_SYS_ACCEPT:
536    /* int accept(int s, struct sockaddr *addr, int *addrlen); */
537    r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
538                  ARG2_0, ARG2_1, ARG2_2 );
539    SET_STATUS_from_SysRes(r);
540    break;
541
542  case VKI_SYS_SENDTO:
543    break;
544
545  case VKI_SYS_SEND:
546    break;
547
548  case VKI_SYS_RECVFROM:
549    ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
550                ARG2_0, ARG2_1, ARG2_2,
551                ARG2_3, ARG2_4, ARG2_5 );
552    break;
553
554  case VKI_SYS_RECV:
555    ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
556    break;
557
558  case VKI_SYS_CONNECT:
559    break;
560
561  case VKI_SYS_SETSOCKOPT:
562    break;
563
564  case VKI_SYS_GETSOCKOPT:
565    ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
566                  ARG2_0, ARG2_1,
567                  ARG2_2, ARG2_3, ARG2_4 );
568    break;
569
570  case VKI_SYS_GETSOCKNAME:
571    ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
572                   ARG2_0, ARG2_1, ARG2_2 );
573    break;
574
575  case VKI_SYS_GETPEERNAME:
576    ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
577                   ARG2_0, ARG2_1, ARG2_2 );
578    break;
579
580  case VKI_SYS_SHUTDOWN:
581    break;
582
583  case VKI_SYS_SENDMSG:
584    break;
585
586  case VKI_SYS_RECVMSG:
587    ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
588    break;
589
590  default:
591    VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx",ARG1);
592    VG_(core_panic)("... bye!\n");
593    break; /*NOTREACHED*/
594  }
595#  undef ARG2_0
596#  undef ARG2_1
597#  undef ARG2_2
598#  undef ARG2_3
599#  undef ARG2_4
600#  undef ARG2_5
601}
602
603PRE(sys_socket)
604{
605   PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
606   PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
607}
608POST(sys_socket)
609{
610   SysRes r;
611   vg_assert(SUCCESS);
612   r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
613   SET_STATUS_from_SysRes(r);
614}
615
616PRE(sys_setsockopt)
617{
618   PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
619   PRE_REG_READ5(long, "setsockopt",
620                 int, s, int, level, int, optname,
621                 const void *, optval, int, optlen);
622   ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
623}
624
625PRE(sys_getsockopt)
626{
627   PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
628   PRE_REG_READ5(long, "getsockopt",
629                 int, s, int, level, int, optname,
630                 void *, optval, int, *optlen);
631   ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
632}
633POST(sys_getsockopt)
634{
635   vg_assert(SUCCESS);
636   ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
637                                         ARG1,ARG2,ARG3,ARG4,ARG5);
638}
639
640PRE(sys_connect)
641{
642   *flags |= SfMayBlock;
643   PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
644   PRE_REG_READ3(long, "connect",
645                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
646   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
647}
648
649PRE(sys_accept)
650{
651   *flags |= SfMayBlock;
652   PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
653   PRE_REG_READ3(long, "accept",
654                 int, s, struct sockaddr *, addr, int, *addrlen);
655   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
656}
657POST(sys_accept)
658{
659   SysRes r;
660   vg_assert(SUCCESS);
661   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
662                                         ARG1,ARG2,ARG3);
663   SET_STATUS_from_SysRes(r);
664}
665
666PRE(sys_sendto)
667{
668   *flags |= SfMayBlock;
669   PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
670   PRE_REG_READ6(long, "sendto",
671                 int, s, const void *, msg, int, len,
672                 unsigned int, flags,
673                 const struct sockaddr *, to, int, tolen);
674   ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
675}
676
677PRE(sys_recvfrom)
678{
679   *flags |= SfMayBlock;
680   PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
681   PRE_REG_READ6(long, "recvfrom",
682                 int, s, void *, buf, int, len, unsigned int, flags,
683                 struct sockaddr *, from, int *, fromlen);
684   ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
685}
686POST(sys_recvfrom)
687{
688   vg_assert(SUCCESS);
689   ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
690                                       ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
691}
692
693PRE(sys_sendmsg)
694{
695   *flags |= SfMayBlock;
696   PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
697   PRE_REG_READ3(long, "sendmsg",
698                 int, s, const struct msghdr *, msg, int, flags);
699   ML_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
700}
701
702PRE(sys_recvmsg)
703{
704   *flags |= SfMayBlock;
705   PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
706   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
707   ML_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
708}
709POST(sys_recvmsg)
710{
711   ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
712}
713
714//XXX: Semaphore code ripped from AMD64.
715PRE(sys_semget)
716{
717   PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
718   PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
719}
720
721PRE(sys_semop)
722{
723   *flags |= SfMayBlock;
724   PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
725   PRE_REG_READ3(long, "semop",
726                 int, semid, struct sembuf *, sops, unsigned, nsoops);
727   ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
728}
729
730PRE(sys_semctl)
731{
732   switch (ARG3 & ~VKI_IPC_64) {
733   case VKI_IPC_INFO:
734   case VKI_SEM_INFO:
735      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
736      PRE_REG_READ4(long, "semctl",
737                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
738      break;
739   case VKI_IPC_STAT:
740   case VKI_SEM_STAT:
741   case VKI_IPC_SET:
742      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
743      PRE_REG_READ4(long, "semctl",
744                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
745      break;
746   case VKI_GETALL:
747   case VKI_SETALL:
748      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
749      PRE_REG_READ4(long, "semctl",
750                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
751      break;
752   default:
753      PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
754      PRE_REG_READ3(long, "semctl",
755                    int, semid, int, semnum, int, cmd);
756      break;
757   }
758   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
759}
760
761POST(sys_semctl)
762{
763   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
764}
765
766PRE(sys_semtimedop)
767{
768   *flags |= SfMayBlock;
769   PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
770   PRE_REG_READ4(long, "semtimedop",
771                 int, semid, struct sembuf *, sops, unsigned, nsoops,
772                 struct timespec *, timeout);
773   ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
774}
775
776//amd64
777PRE(sys_msgget)
778{
779   PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
780   PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
781}
782
783PRE(sys_msgsnd)
784{
785   PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
786   PRE_REG_READ4(long, "msgsnd",
787                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
788   ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
789   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
790      *flags |= SfMayBlock;
791}
792
793PRE(sys_msgrcv)
794{
795   PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
796   PRE_REG_READ5(long, "msgrcv",
797                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
798                 long, msgytp, int, msgflg);
799   ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
800   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
801      *flags |= SfMayBlock;
802}
803POST(sys_msgrcv)
804{
805   ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
806}
807
808
809PRE(sys_msgctl)
810{
811   PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
812   PRE_REG_READ3(long, "msgctl",
813                 int, msqid, int, cmd, struct msqid_ds *, buf);
814   ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
815}
816POST(sys_msgctl)
817{
818   ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
819}
820
821//shared memory code from AMD64
822PRE(sys_shmget)
823{
824   PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
825   PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
826}
827
828PRE(wrap_sys_shmat)
829{
830   UWord arg2tmp;
831   PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
832   PRE_REG_READ3(long, "shmat",
833                 int, shmid, const void *, shmaddr, int, shmflg);
834   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
841POST(wrap_sys_shmat)
842{
843   ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
844}
845
846PRE(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
854POST(sys_shmdt)
855{
856   ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
857}
858
859PRE(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
867POST(sys_shmctl)
868{
869   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
870}
871
872PRE(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
879PRE(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
887PRE(sys_listen)
888{
889   PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
890   PRE_REG_READ2(long, "listen", int, s, int, backlog);
891}
892
893PRE(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}
900POST(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
907PRE(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}
914POST(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
921PRE(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}
928POST(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
935PRE(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
946PRE(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
955POST(sys_recv)
956{
957   ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 );
958}
959
960PRE(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
987PRE(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
995POST(sys_lstat64)
996{
997   vg_assert(SUCCESS);
998   if (RES == 0) {
999      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1000   }
1001}
1002
1003PRE(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
1011POST(sys_stat64)
1012{
1013   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1014}
1015
1016PRE(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
1025POST(sys_fstatat64)
1026{
1027   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
1028}
1029
1030PRE(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
1037POST(sys_fstat64)
1038{
1039   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1040}
1041
1042PRE(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
1137PRE(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
1160PRE(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
1185PRE(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
1192PRE(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
1227static 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
1671static SyscallTableEntry ste___ARM_set_tls
1672   = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
1673
1674static SyscallTableEntry ste___ARM_cacheflush
1675   = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
1676
1677SyscallTableEntry* 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/*--------------------------------------------------------------------*/
1707