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