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