1
2/*--------------------------------------------------------------------*/
3/*--- Platform-specific syscalls stuff.      syswrap-amd64-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
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#if defined(VGP_amd64_linux)
32
33#include "pub_core_basics.h"
34#include "pub_core_vki.h"
35#include "pub_core_vkiscnums.h"
36#include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
37#include "pub_core_threadstate.h"
38#include "pub_core_aspacemgr.h"
39#include "pub_core_debuglog.h"
40#include "pub_core_options.h"
41#include "pub_core_libcbase.h"
42#include "pub_core_libcassert.h"
43#include "pub_core_libcprint.h"
44#include "pub_core_libcproc.h"
45#include "pub_core_libcsignal.h"
46#include "pub_core_scheduler.h"
47#include "pub_core_sigframe.h"
48#include "pub_core_signals.h"
49#include "pub_core_syscall.h"
50#include "pub_core_syswrap.h"
51#include "pub_core_tooliface.h"
52#include "pub_core_stacks.h"        // VG_(register_stack)
53
54#include "priv_types_n_macros.h"
55#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
56#include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
57#include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
58#include "priv_syswrap-main.h"
59
60
61/* ---------------------------------------------------------------------
62   clone() handling
63   ------------------------------------------------------------------ */
64
65/* Call f(arg1), but first switch stacks, using 'stack' as the new
66   stack, and use 'retaddr' as f's return-to address.  Also, clear all
67   the integer registers before entering f.  */
68__attribute__((noreturn))
69void ML_(call_on_new_stack_0_1) ( Addr stack,
70			          Addr retaddr,
71			          void (*f)(Word),
72                                  Word arg1 );
73// %rdi == stack
74// %rsi == retaddr
75// %rdx == f
76// %rcx == arg1
77asm(
78".text\n"
79".globl vgModuleLocal_call_on_new_stack_0_1\n"
80"vgModuleLocal_call_on_new_stack_0_1:\n"
81"   movq   %rdi, %rsp\n"   // set stack
82"   pushq  %rsi\n"         // retaddr to stack
83"   pushq  %rdx\n"         // f to stack
84"   pushq  %rcx\n"         // arg1 to stack
85"   movq $0, %rax\n"       // zero all GP regs
86"   movq $0, %rbx\n"
87"   movq $0, %rcx\n"
88"   movq $0, %rdx\n"
89"   movq $0, %rsi\n"
90"   movq $0, %rdi\n"
91"   movq $0, %rbp\n"
92"   movq $0, %r8\n"
93"   movq $0, %r9\n"
94"   movq $0, %r10\n"
95"   movq $0, %r11\n"
96"   movq $0, %r12\n"
97"   movq $0, %r13\n"
98"   movq $0, %r14\n"
99"   movq $0, %r15\n"
100"   popq   %rdi\n"         // arg1 to correct arg reg
101"   ret\n"                 // jump to f
102"   ud2\n"                 // should never get here
103".previous\n"
104);
105
106/*
107        Perform a clone system call.  clone is strange because it has
108        fork()-like return-twice semantics, so it needs special
109        handling here.
110
111	Upon entry, we have:
112
113	    int (*fn)(void*)	in %rdi
114	    void*  child_stack	in %rsi
115	    int    flags	in %rdx
116	    void*  arg		in %rcx
117	    pid_t* child_tid	in %r8
118	    pid_t* parent_tid	in %r9
119	    void*  tls_ptr      at 8(%rsp)
120
121	System call requires:
122
123	    int    $__NR_clone  in %rax
124	    int    flags	in %rdi
125	    void*  child_stack	in %rsi
126	    pid_t* parent_tid	in %rdx
127	    pid_t* child_tid	in %r10
128	    void*  tls_ptr      in %r8
129
130	Returns a Long encoded in the linux-amd64 way, not a SysRes.
131 */
132#define __NR_CLONE        VG_STRINGIFY(__NR_clone)
133#define __NR_EXIT         VG_STRINGIFY(__NR_exit)
134
135extern
136Long do_syscall_clone_amd64_linux ( Word (*fn)(void *),
137                                    void* stack,
138                                    Long  flags,
139                                    void* arg,
140                                    Long* child_tid,
141                                    Long* parent_tid,
142                                    vki_modify_ldt_t * );
143asm(
144".text\n"
145"do_syscall_clone_amd64_linux:\n"
146        // set up child stack, temporarily preserving fn and arg
147"       subq    $16, %rsi\n"            // make space on stack
148"       movq    %rcx, 8(%rsi)\n"        // save arg
149"       movq    %rdi, 0(%rsi)\n"        // save fn
150
151        // setup syscall
152"       movq    $"__NR_CLONE", %rax\n"  // syscall number
153"       movq    %rdx,     %rdi\n"       // syscall arg1: flags
154        // %rsi already setup           // syscall arg2: child_stack
155"       movq    %r9,      %rdx\n"       // syscall arg3: parent_tid
156"       movq    %r8,      %r10\n"       // syscall arg4: child_tid
157"       movq    8(%rsp),  %r8\n"        // syscall arg5: tls_ptr
158
159"       syscall\n"                      // clone()
160
161"       testq   %rax, %rax\n"           // child if retval == 0
162"       jnz     1f\n"
163
164        // CHILD - call thread function
165"       pop     %rax\n"                 // pop fn
166"       pop     %rdi\n"                 // pop fn arg1: arg
167"       call    *%rax\n"                // call fn
168
169        // exit with result
170"       movq    %rax, %rdi\n"           // arg1: return value from fn
171"       movq    $"__NR_EXIT", %rax\n"
172
173"       syscall\n"
174
175        // Exit returned?!
176"       ud2\n"
177
178"1:\n"  // PARENT or ERROR
179"       ret\n"
180".previous\n"
181);
182
183#undef __NR_CLONE
184#undef __NR_EXIT
185
186
187// forward declaration
188static void setup_child ( ThreadArchState*, ThreadArchState* );
189
190/*
191   When a client clones, we need to keep track of the new thread.  This means:
192   1. allocate a ThreadId+ThreadState+stack for the the thread
193
194   2. initialize the thread's new VCPU state
195
196   3. create the thread using the same args as the client requested,
197   but using the scheduler entrypoint for EIP, and a separate stack
198   for ESP.
199 */
200static SysRes do_clone ( ThreadId ptid,
201                         ULong flags, Addr rsp,
202                         Long* parent_tidptr,
203                         Long* child_tidptr,
204                         Addr tlsaddr )
205{
206   static const Bool debug = False;
207
208   ThreadId     ctid = VG_(alloc_ThreadState)();
209   ThreadState* ptst = VG_(get_ThreadState)(ptid);
210   ThreadState* ctst = VG_(get_ThreadState)(ctid);
211   UWord*       stack;
212   NSegment const* seg;
213   SysRes       res;
214   Long         rax;
215   vki_sigset_t blockall, savedmask;
216
217   VG_(sigfillset)(&blockall);
218
219   vg_assert(VG_(is_running_thread)(ptid));
220   vg_assert(VG_(is_valid_tid)(ctid));
221
222   stack = (UWord*)ML_(allocstack)(ctid);
223   if (stack == NULL) {
224      res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
225      goto out;
226   }
227
228   /* Copy register state
229
230      Both parent and child return to the same place, and the code
231      following the clone syscall works out which is which, so we
232      don't need to worry about it.
233
234      The parent gets the child's new tid returned from clone, but the
235      child gets 0.
236
237      If the clone call specifies a NULL rsp for the new thread, then
238      it actually gets a copy of the parent's rsp.
239   */
240   setup_child( &ctst->arch, &ptst->arch );
241
242   /* Make sys_clone appear to have returned Success(0) in the
243      child. */
244   ctst->arch.vex.guest_RAX = 0;
245
246   if (rsp != 0)
247      ctst->arch.vex.guest_RSP = rsp;
248
249   ctst->os_state.parent = ptid;
250
251   /* inherit signal mask */
252   ctst->sig_mask = ptst->sig_mask;
253   ctst->tmp_sig_mask = ptst->sig_mask;
254
255   /* Start the child with its threadgroup being the same as the
256      parent's.  This is so that any exit_group calls that happen
257      after the child is created but before it sets its
258      os_state.threadgroup field for real (in thread_wrapper in
259      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
260      a race condition in which the thread is unkillable (via
261      exit_group) because its threadgroup is not set.  The race window
262      is probably only a few hundred or a few thousand cycles long.
263      See #226116. */
264   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
265
266   /* We don't really know where the client stack is, because its
267      allocated by the client.  The best we can do is look at the
268      memory mappings and try to derive some useful information.  We
269      assume that esp starts near its highest possible value, and can
270      only go down to the start of the mmaped segment. */
271   seg = VG_(am_find_nsegment)((Addr)rsp);
272   if (seg && seg->kind != SkResvn) {
273      ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(rsp);
274      ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
275
276      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
277
278      if (debug)
279	 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
280		     ctid, seg->start, VG_PGROUNDUP(rsp));
281   } else {
282      VG_(message)(Vg_UserMsg,
283                   "!? New thread %d starts with RSP(%#lx) unmapped\n",
284		   ctid, rsp);
285      ctst->client_stack_szB  = 0;
286   }
287
288   /* Assume the clone will succeed, and tell any tool that wants to
289      know that this thread has come into existence.  If the clone
290      fails, we'll send out a ll_exit notification for it at the out:
291      label below, to clean up. */
292   VG_TRACK ( pre_thread_ll_create, ptid, ctid );
293
294   if (flags & VKI_CLONE_SETTLS) {
295      if (debug)
296	 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
297      ctst->arch.vex.guest_FS_ZERO = tlsaddr;
298   }
299
300   flags &= ~VKI_CLONE_SETTLS;
301
302   /* start the thread with everything blocked */
303   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
304
305   /* Create the new thread */
306   rax = do_syscall_clone_amd64_linux(
307            ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
308            child_tidptr, parent_tidptr, NULL
309         );
310   res = VG_(mk_SysRes_amd64_linux)( rax );
311
312   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
313
314  out:
315   if (sr_isError(res)) {
316      /* clone failed */
317      VG_(cleanup_thread)(&ctst->arch);
318      ctst->status = VgTs_Empty;
319      /* oops.  Better tell the tool the thread exited in a hurry :-) */
320      VG_TRACK( pre_thread_ll_exit, ctid );
321   }
322
323   return res;
324}
325
326
327/* ---------------------------------------------------------------------
328   More thread stuff
329   ------------------------------------------------------------------ */
330
331void VG_(cleanup_thread) ( ThreadArchState *arch )
332{
333}
334
335void setup_child ( /*OUT*/ ThreadArchState *child,
336                   /*IN*/  ThreadArchState *parent )
337{
338   /* We inherit our parent's guest state. */
339   child->vex = parent->vex;
340   child->vex_shadow1 = parent->vex_shadow1;
341   child->vex_shadow2 = parent->vex_shadow2;
342}
343
344
345/* ---------------------------------------------------------------------
346   PRE/POST wrappers for AMD64/Linux-specific syscalls
347   ------------------------------------------------------------------ */
348
349#define PRE(name)       DEFN_PRE_TEMPLATE(amd64_linux, name)
350#define POST(name)      DEFN_POST_TEMPLATE(amd64_linux, name)
351
352/* Add prototypes for the wrappers declared here, so that gcc doesn't
353   harass us for not having prototypes.  Really this is a kludge --
354   the right thing to do is to make these wrappers 'static' since they
355   aren't visible outside this file, but that requires even more macro
356   magic. */
357DECL_TEMPLATE(amd64_linux, sys_clone);
358DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
359DECL_TEMPLATE(amd64_linux, sys_socket);
360DECL_TEMPLATE(amd64_linux, sys_setsockopt);
361DECL_TEMPLATE(amd64_linux, sys_getsockopt);
362DECL_TEMPLATE(amd64_linux, sys_connect);
363DECL_TEMPLATE(amd64_linux, sys_accept);
364DECL_TEMPLATE(amd64_linux, sys_accept4);
365DECL_TEMPLATE(amd64_linux, sys_sendto);
366DECL_TEMPLATE(amd64_linux, sys_recvfrom);
367DECL_TEMPLATE(amd64_linux, sys_sendmsg);
368DECL_TEMPLATE(amd64_linux, sys_recvmsg);
369DECL_TEMPLATE(amd64_linux, sys_shutdown);
370DECL_TEMPLATE(amd64_linux, sys_bind);
371DECL_TEMPLATE(amd64_linux, sys_listen);
372DECL_TEMPLATE(amd64_linux, sys_getsockname);
373DECL_TEMPLATE(amd64_linux, sys_getpeername);
374DECL_TEMPLATE(amd64_linux, sys_socketpair);
375DECL_TEMPLATE(amd64_linux, sys_semget);
376DECL_TEMPLATE(amd64_linux, sys_semop);
377DECL_TEMPLATE(amd64_linux, sys_semtimedop);
378DECL_TEMPLATE(amd64_linux, sys_semctl);
379DECL_TEMPLATE(amd64_linux, sys_msgget);
380DECL_TEMPLATE(amd64_linux, sys_msgrcv);
381DECL_TEMPLATE(amd64_linux, sys_msgsnd);
382DECL_TEMPLATE(amd64_linux, sys_msgctl);
383DECL_TEMPLATE(amd64_linux, sys_shmget);
384DECL_TEMPLATE(amd64_linux, wrap_sys_shmat);
385DECL_TEMPLATE(amd64_linux, sys_shmdt);
386DECL_TEMPLATE(amd64_linux, sys_shmdt);
387DECL_TEMPLATE(amd64_linux, sys_shmctl);
388DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
389DECL_TEMPLATE(amd64_linux, sys_ptrace);
390DECL_TEMPLATE(amd64_linux, sys_fadvise64);
391DECL_TEMPLATE(amd64_linux, sys_mmap);
392DECL_TEMPLATE(amd64_linux, sys_syscall184);
393
394
395PRE(sys_clone)
396{
397   ULong cloneflags;
398
399   PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
400   PRE_REG_READ5(int, "clone",
401                 unsigned long, flags,
402                 void *, child_stack,
403                 int *, parent_tidptr,
404                 int *, child_tidptr,
405                 void *, tlsaddr);
406
407   if (ARG1 & VKI_CLONE_PARENT_SETTID) {
408      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
409      if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
410         SET_STATUS_Failure( VKI_EFAULT );
411         return;
412      }
413   }
414   if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
415      PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
416      if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
417         SET_STATUS_Failure( VKI_EFAULT );
418         return;
419      }
420   }
421
422   cloneflags = ARG1;
423
424   if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
425      SET_STATUS_Failure( VKI_EINVAL );
426      return;
427   }
428
429   /* Only look at the flags we really care about */
430   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
431                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
432   case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
433      /* thread creation */
434      SET_STATUS_from_SysRes(
435         do_clone(tid,
436                  ARG1,          /* flags */
437                  (Addr)ARG2,    /* child ESP */
438                  (Long *)ARG3,  /* parent_tidptr */
439                  (Long *)ARG4,  /* child_tidptr */
440                  (Addr)ARG5));  /* set_tls */
441      break;
442
443   case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
444      /* FALLTHROUGH - assume vfork == fork */
445      cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
446
447   case 0: /* plain fork */
448      SET_STATUS_from_SysRes(
449         ML_(do_fork_clone)(tid,
450                       cloneflags,      /* flags */
451                       (Int *)ARG3,     /* parent_tidptr */
452                       (Int *)ARG4));   /* child_tidptr */
453      break;
454
455   default:
456      /* should we just ENOSYS? */
457      VG_(message)(Vg_UserMsg,
458                   "Unsupported clone() flags: 0x%lx\n", ARG1);
459      VG_(message)(Vg_UserMsg,
460                   "\n");
461      VG_(message)(Vg_UserMsg,
462                   "The only supported clone() uses are:\n");
463      VG_(message)(Vg_UserMsg,
464                   " - via a threads library (LinuxThreads or NPTL)\n");
465      VG_(message)(Vg_UserMsg,
466                   " - via the implementation of fork or vfork\n");
467      VG_(unimplemented)
468         ("Valgrind does not support general clone().");
469   }
470
471   if (SUCCESS) {
472      if (ARG1 & VKI_CLONE_PARENT_SETTID)
473         POST_MEM_WRITE(ARG3, sizeof(Int));
474      if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
475         POST_MEM_WRITE(ARG4, sizeof(Int));
476
477      /* Thread creation was successful; let the child have the chance
478         to run */
479      *flags |= SfYieldAfter;
480   }
481}
482
483PRE(sys_rt_sigreturn)
484{
485   /* This isn't really a syscall at all - it's a misuse of the
486      syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
487      return address of the signal frames it creates to be a short
488      piece of code which does this "syscall".  The only purpose of
489      the syscall is to call VG_(sigframe_destroy), which restores the
490      thread's registers from the frame and then removes it.
491      Consequently we must ask the syswrap driver logic not to write
492      back the syscall "result" as that would overwrite the
493      just-restored register state. */
494
495   ThreadState* tst;
496   PRINT("sys_rt_sigreturn ( )");
497
498   vg_assert(VG_(is_valid_tid)(tid));
499   vg_assert(tid >= 1 && tid < VG_N_THREADS);
500   vg_assert(VG_(is_running_thread)(tid));
501
502   /* Adjust RSP to point to start of frame; skip back up over handler
503      ret addr */
504   tst = VG_(get_ThreadState)(tid);
505   tst->arch.vex.guest_RSP -= sizeof(Addr);
506
507   /* This is only so that the RIP is (might be) useful to report if
508      something goes wrong in the sigreturn.  JRS 20070318: no idea
509      what this is for */
510   ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
511
512   /* Restore register state from frame and remove it, as
513      described above */
514   VG_(sigframe_destroy)(tid, True);
515
516   /* Tell the driver not to update the guest state with the "result",
517      and set a bogus result to keep it happy. */
518   *flags |= SfNoWriteResult;
519   SET_STATUS_Success(0);
520
521   /* Check to see if any signals arose as a result of this. */
522   *flags |= SfPollAfter;
523}
524
525PRE(sys_arch_prctl)
526{
527   ThreadState* tst;
528   PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
529
530   vg_assert(VG_(is_valid_tid)(tid));
531   vg_assert(tid >= 1 && tid < VG_N_THREADS);
532   vg_assert(VG_(is_running_thread)(tid));
533
534   // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
535   PRE_REG_READ2(long, "arch_prctl",
536                 int, option, unsigned long, arg2);
537   // XXX: totally wrong... we need to look at the 'option' arg, and do
538   // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
539
540   /* "do" the syscall ourselves; the kernel never sees it */
541   if (ARG1 == VKI_ARCH_SET_FS) {
542      tst = VG_(get_ThreadState)(tid);
543      tst->arch.vex.guest_FS_ZERO = ARG2;
544   }
545   else if (ARG1 == VKI_ARCH_GET_FS) {
546      PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
547      tst = VG_(get_ThreadState)(tid);
548      *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_ZERO;
549      POST_MEM_WRITE(ARG2, sizeof(unsigned long));
550   }
551   else {
552      VG_(core_panic)("Unsupported arch_prtctl option");
553   }
554
555   /* Note; the Status writeback to guest state that happens after
556      this wrapper returns does not change guest_FS_ZERO; hence that
557      direct assignment to the guest state is safe here. */
558   SET_STATUS_Success( 0 );
559}
560
561// Parts of this are amd64-specific, but the *PEEK* cases are generic.
562//
563// ARG3 is only used for pointers into the traced process's address
564// space and for offsets into the traced process's struct
565// user_regs_struct. It is never a pointer into this process's memory
566// space, and we should therefore not check anything it points to.
567PRE(sys_ptrace)
568{
569   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
570   PRE_REG_READ4(int, "ptrace",
571                 long, request, long, pid, long, addr, long, data);
572   switch (ARG1) {
573   case VKI_PTRACE_PEEKTEXT:
574   case VKI_PTRACE_PEEKDATA:
575   case VKI_PTRACE_PEEKUSR:
576      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
577		     sizeof (long));
578      break;
579   case VKI_PTRACE_GETREGS:
580      PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
581		     sizeof (struct vki_user_regs_struct));
582      break;
583   case VKI_PTRACE_GETFPREGS:
584      PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
585		     sizeof (struct vki_user_i387_struct));
586      break;
587   case VKI_PTRACE_SETREGS:
588      PRE_MEM_READ( "ptrace(setregs)", ARG4,
589		     sizeof (struct vki_user_regs_struct));
590      break;
591   case VKI_PTRACE_SETFPREGS:
592      PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
593		     sizeof (struct vki_user_i387_struct));
594      break;
595   case VKI_PTRACE_GETEVENTMSG:
596      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
597      break;
598   case VKI_PTRACE_GETSIGINFO:
599      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
600      break;
601   case VKI_PTRACE_SETSIGINFO:
602      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
603      break;
604   default:
605      break;
606   }
607}
608
609POST(sys_ptrace)
610{
611   switch (ARG1) {
612   case VKI_PTRACE_PEEKTEXT:
613   case VKI_PTRACE_PEEKDATA:
614   case VKI_PTRACE_PEEKUSR:
615      POST_MEM_WRITE( ARG4, sizeof (long));
616      break;
617   case VKI_PTRACE_GETREGS:
618      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
619      break;
620   case VKI_PTRACE_GETFPREGS:
621      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
622      break;
623   case VKI_PTRACE_GETEVENTMSG:
624      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
625      break;
626   case VKI_PTRACE_GETSIGINFO:
627      /* XXX: This is a simplification. Different parts of the
628       * siginfo_t are valid depending on the type of signal.
629       */
630      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
631      break;
632   default:
633      break;
634   }
635}
636
637PRE(sys_socket)
638{
639   PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
640   PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
641}
642POST(sys_socket)
643{
644   SysRes r;
645   vg_assert(SUCCESS);
646   r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
647   SET_STATUS_from_SysRes(r);
648}
649
650PRE(sys_setsockopt)
651{
652   PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
653   PRE_REG_READ5(long, "setsockopt",
654                 int, s, int, level, int, optname,
655                 const void *, optval, int, optlen);
656   ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
657}
658
659PRE(sys_getsockopt)
660{
661   PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
662   PRE_REG_READ5(long, "getsockopt",
663                 int, s, int, level, int, optname,
664                 void *, optval, int, *optlen);
665   ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
666}
667POST(sys_getsockopt)
668{
669   vg_assert(SUCCESS);
670   ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
671                                       ARG1,ARG2,ARG3,ARG4,ARG5);
672}
673
674PRE(sys_connect)
675{
676   *flags |= SfMayBlock;
677   PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
678   PRE_REG_READ3(long, "connect",
679                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
680   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
681}
682
683PRE(sys_accept)
684{
685   *flags |= SfMayBlock;
686   PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
687   PRE_REG_READ3(long, "accept",
688                 int, s, struct sockaddr *, addr, int, *addrlen);
689   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
690}
691POST(sys_accept)
692{
693   SysRes r;
694   vg_assert(SUCCESS);
695   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
696                                         ARG1,ARG2,ARG3);
697   SET_STATUS_from_SysRes(r);
698}
699
700PRE(sys_accept4)
701{
702   *flags |= SfMayBlock;
703   PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
704   PRE_REG_READ4(long, "accept4",
705                 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
706   ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
707}
708POST(sys_accept4)
709{
710   SysRes r;
711   vg_assert(SUCCESS);
712   r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
713                                         ARG1,ARG2,ARG3);
714   SET_STATUS_from_SysRes(r);
715}
716
717PRE(sys_sendto)
718{
719   *flags |= SfMayBlock;
720   PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
721   PRE_REG_READ6(long, "sendto",
722                 int, s, const void *, msg, int, len,
723                 unsigned int, flags,
724                 const struct sockaddr *, to, int, tolen);
725   ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
726}
727
728PRE(sys_recvfrom)
729{
730   *flags |= SfMayBlock;
731   PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
732   PRE_REG_READ6(long, "recvfrom",
733                 int, s, void *, buf, int, len, unsigned int, flags,
734                 struct sockaddr *, from, int *, fromlen);
735   ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
736}
737POST(sys_recvfrom)
738{
739   vg_assert(SUCCESS);
740   ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
741                                       ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
742}
743
744PRE(sys_sendmsg)
745{
746   *flags |= SfMayBlock;
747   PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
748   PRE_REG_READ3(long, "sendmsg",
749                 int, s, const struct msghdr *, msg, int, flags);
750   ML_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
751}
752
753PRE(sys_recvmsg)
754{
755   *flags |= SfMayBlock;
756   PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
757   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
758   ML_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
759}
760POST(sys_recvmsg)
761{
762   ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
763}
764
765PRE(sys_shutdown)
766{
767   *flags |= SfMayBlock;
768   PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
769   PRE_REG_READ2(int, "shutdown", int, s, int, how);
770}
771
772PRE(sys_bind)
773{
774   PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
775   PRE_REG_READ3(long, "bind",
776                 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
777   ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
778}
779
780PRE(sys_listen)
781{
782   PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
783   PRE_REG_READ2(long, "listen", int, s, int, backlog);
784}
785
786PRE(sys_getsockname)
787{
788   PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
789   PRE_REG_READ3(long, "getsockname",
790                 int, s, struct sockaddr *, name, int *, namelen);
791   ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
792}
793POST(sys_getsockname)
794{
795   vg_assert(SUCCESS);
796   ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
797                                          ARG1,ARG2,ARG3);
798}
799
800PRE(sys_getpeername)
801{
802   PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
803   PRE_REG_READ3(long, "getpeername",
804                 int, s, struct sockaddr *, name, int *, namelen);
805   ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
806}
807POST(sys_getpeername)
808{
809   vg_assert(SUCCESS);
810   ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
811                                          ARG1,ARG2,ARG3);
812}
813
814PRE(sys_socketpair)
815{
816   PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
817   PRE_REG_READ4(long, "socketpair",
818                 int, d, int, type, int, protocol, int*, sv);
819   ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
820}
821POST(sys_socketpair)
822{
823   vg_assert(SUCCESS);
824   ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
825                                         ARG1,ARG2,ARG3,ARG4);
826}
827
828PRE(sys_semget)
829{
830   PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
831   PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
832}
833
834PRE(sys_semop)
835{
836   *flags |= SfMayBlock;
837   PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
838   PRE_REG_READ3(long, "semop",
839                 int, semid, struct sembuf *, sops, unsigned, nsoops);
840   ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
841}
842
843PRE(sys_semtimedop)
844{
845   *flags |= SfMayBlock;
846   PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
847   PRE_REG_READ4(long, "semtimedop",
848                 int, semid, struct sembuf *, sops, unsigned, nsoops,
849                 struct timespec *, timeout);
850   ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
851}
852
853PRE(sys_semctl)
854{
855   switch (ARG3 & ~VKI_IPC_64) {
856   case VKI_IPC_INFO:
857   case VKI_SEM_INFO:
858      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
859      PRE_REG_READ4(long, "semctl",
860                    int, semid, int, semnum, int, cmd, struct seminfo *, arg);
861      break;
862   case VKI_IPC_STAT:
863   case VKI_SEM_STAT:
864   case VKI_IPC_SET:
865      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
866      PRE_REG_READ4(long, "semctl",
867                    int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
868      break;
869   case VKI_GETALL:
870   case VKI_SETALL:
871      PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
872      PRE_REG_READ4(long, "semctl",
873                    int, semid, int, semnum, int, cmd, unsigned short *, arg);
874      break;
875   default:
876      PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
877      PRE_REG_READ3(long, "semctl",
878                    int, semid, int, semnum, int, cmd);
879      break;
880   }
881   ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
882}
883POST(sys_semctl)
884{
885   ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
886}
887
888PRE(sys_msgget)
889{
890   PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
891   PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
892}
893
894PRE(sys_msgsnd)
895{
896   PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
897   PRE_REG_READ4(long, "msgsnd",
898                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
899   ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
900   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
901      *flags |= SfMayBlock;
902}
903
904PRE(sys_msgrcv)
905{
906   PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
907   PRE_REG_READ5(long, "msgrcv",
908                 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
909                 long, msgytp, int, msgflg);
910   ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
911   if ((ARG4 & VKI_IPC_NOWAIT) == 0)
912      *flags |= SfMayBlock;
913}
914POST(sys_msgrcv)
915{
916   ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
917}
918
919PRE(sys_msgctl)
920{
921   PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
922   PRE_REG_READ3(long, "msgctl",
923                 int, msqid, int, cmd, struct msqid_ds *, buf);
924   ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
925}
926POST(sys_msgctl)
927{
928   ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
929}
930
931PRE(sys_shmget)
932{
933   PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
934   PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
935}
936
937PRE(wrap_sys_shmat)
938{
939   UWord arg2tmp;
940   PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
941   PRE_REG_READ3(long, "shmat",
942                 int, shmid, const void *, shmaddr, int, shmflg);
943   arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
944   if (arg2tmp == 0)
945      SET_STATUS_Failure( VKI_EINVAL );
946   else
947      ARG2 = arg2tmp;  // used in POST
948}
949POST(wrap_sys_shmat)
950{
951   ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
952}
953
954PRE(sys_shmdt)
955{
956   PRINT("sys_shmdt ( %#lx )",ARG1);
957   PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
958   if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
959      SET_STATUS_Failure( VKI_EINVAL );
960}
961POST(sys_shmdt)
962{
963   ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
964}
965
966PRE(sys_shmctl)
967{
968   PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
969   PRE_REG_READ3(long, "shmctl",
970                 int, shmid, int, cmd, struct shmid_ds *, buf);
971   ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
972}
973POST(sys_shmctl)
974{
975   ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
976}
977
978PRE(sys_fadvise64)
979{
980   PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", ARG1,ARG2,ARG3,ARG4);
981   PRE_REG_READ4(long, "fadvise64",
982                 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
983}
984
985PRE(sys_mmap)
986{
987   SysRes r;
988
989   PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %d, %ld )",
990         ARG1, (ULong)ARG2, ARG3, ARG4, (Int)ARG5, ARG6 );
991   PRE_REG_READ6(long, "mmap",
992                 unsigned long, start, unsigned long, length,
993                 unsigned long, prot,  unsigned long, flags,
994                 unsigned long, fd,    unsigned long, offset);
995
996   r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
997   SET_STATUS_from_SysRes(r);
998}
999
1000
1001/* ---------------------------------------------------------------
1002   PRE/POST wrappers for AMD64/Linux-variant specific syscalls
1003   ------------------------------------------------------------ */
1004
1005PRE(sys_syscall184)
1006{
1007   Int err;
1008
1009   /* 184 is used by sys_bproc.  If we're not on a declared bproc
1010      variant, fail in the usual way, since it is otherwise unused. */
1011
1012   if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
1013      PRINT("non-existent syscall! (syscall 184)");
1014      PRE_REG_READ0(long, "ni_syscall(184)");
1015      SET_STATUS_Failure( VKI_ENOSYS );
1016      return;
1017   }
1018
1019   err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
1020                                           ARG4, ARG5, ARG6 );
1021   if (err) {
1022      SET_STATUS_Failure( err );
1023      return;
1024   }
1025   /* Let it go through. */
1026   *flags |= SfMayBlock; /* who knows?  play safe. */
1027}
1028
1029POST(sys_syscall184)
1030{
1031   ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
1032                                      ARG4, ARG5, ARG6 );
1033}
1034
1035#undef PRE
1036#undef POST
1037
1038
1039/* ---------------------------------------------------------------------
1040   The AMD64/Linux syscall table
1041   ------------------------------------------------------------------ */
1042
1043/* Add an amd64-linux specific wrapper to a syscall table. */
1044#define PLAX_(const, name)    WRAPPER_ENTRY_X_(amd64_linux, const, name)
1045#define PLAXY(const, name)    WRAPPER_ENTRY_XY(amd64_linux, const, name)
1046
1047// This table maps from __NR_xxx syscall numbers (from
1048// linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
1049// wrappers on AMD64 (as per sys_call_table in
1050// linux/arch/x86_64/kernel/entry.S).
1051//
1052// When implementing these wrappers, you need to work out if the wrapper is
1053// generic, Linux-only (but arch-independent), or AMD64/Linux only.
1054
1055static SyscallTableEntry syscall_table[] = {
1056   GENXY(__NR_read,              sys_read),           // 0
1057   GENX_(__NR_write,             sys_write),          // 1
1058   GENXY(__NR_open,              sys_open),           // 2
1059   GENXY(__NR_close,             sys_close),          // 3
1060   GENXY(__NR_stat,              sys_newstat),        // 4
1061
1062   GENXY(__NR_fstat,             sys_newfstat),       // 5
1063   GENXY(__NR_lstat,             sys_newlstat),       // 6
1064   GENXY(__NR_poll,              sys_poll),           // 7
1065   LINX_(__NR_lseek,             sys_lseek),          // 8
1066   PLAX_(__NR_mmap,              sys_mmap),           // 9
1067
1068   GENXY(__NR_mprotect,          sys_mprotect),       // 10
1069   GENXY(__NR_munmap,            sys_munmap),         // 11
1070   GENX_(__NR_brk,               sys_brk),            // 12
1071   LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 13
1072   LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 14
1073
1074   PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 15
1075   LINXY(__NR_ioctl,             sys_ioctl),          // 16
1076   GENXY(__NR_pread64,           sys_pread64),        // 17
1077   GENX_(__NR_pwrite64,          sys_pwrite64),       // 18
1078   GENXY(__NR_readv,             sys_readv),          // 19
1079
1080   GENX_(__NR_writev,            sys_writev),         // 20
1081   GENX_(__NR_access,            sys_access),         // 21
1082   LINXY(__NR_pipe,              sys_pipe),           // 22
1083   GENX_(__NR_select,            sys_select),         // 23
1084   LINX_(__NR_sched_yield,       sys_sched_yield),    // 24
1085
1086   GENX_(__NR_mremap,            sys_mremap),         // 25
1087   GENX_(__NR_msync,             sys_msync),          // 26
1088   GENXY(__NR_mincore,           sys_mincore),        // 27
1089   GENX_(__NR_madvise,           sys_madvise),        // 28
1090   PLAX_(__NR_shmget,            sys_shmget),         // 29
1091
1092   PLAXY(__NR_shmat,             wrap_sys_shmat),     // 30
1093   PLAXY(__NR_shmctl,            sys_shmctl),         // 31
1094   GENXY(__NR_dup,               sys_dup),            // 32
1095   GENXY(__NR_dup2,              sys_dup2),           // 33
1096   GENX_(__NR_pause,             sys_pause),          // 34
1097
1098   GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
1099   GENXY(__NR_getitimer,         sys_getitimer),      // 36
1100   GENX_(__NR_alarm,             sys_alarm),          // 37
1101   GENXY(__NR_setitimer,         sys_setitimer),      // 38
1102   GENX_(__NR_getpid,            sys_getpid),         // 39
1103
1104   LINXY(__NR_sendfile,          sys_sendfile),       // 40
1105   PLAXY(__NR_socket,            sys_socket),         // 41
1106   PLAX_(__NR_connect,           sys_connect),        // 42
1107   PLAXY(__NR_accept,            sys_accept),         // 43
1108   PLAX_(__NR_sendto,            sys_sendto),         // 44
1109
1110   PLAXY(__NR_recvfrom,          sys_recvfrom),       // 45
1111   PLAX_(__NR_sendmsg,           sys_sendmsg),        // 46
1112   PLAXY(__NR_recvmsg,           sys_recvmsg),        // 47
1113   PLAX_(__NR_shutdown,          sys_shutdown),       // 48
1114   PLAX_(__NR_bind,              sys_bind),           // 49
1115
1116   PLAX_(__NR_listen,            sys_listen),         // 50
1117   PLAXY(__NR_getsockname,       sys_getsockname),    // 51
1118   PLAXY(__NR_getpeername,       sys_getpeername),    // 52
1119   PLAXY(__NR_socketpair,        sys_socketpair),     // 53
1120   PLAX_(__NR_setsockopt,        sys_setsockopt),     // 54
1121
1122   PLAXY(__NR_getsockopt,        sys_getsockopt),     // 55
1123   PLAX_(__NR_clone,             sys_clone),          // 56
1124   GENX_(__NR_fork,              sys_fork),           // 57
1125   GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
1126   GENX_(__NR_execve,            sys_execve),         // 59
1127
1128   GENX_(__NR_exit,              sys_exit),           // 60
1129   GENXY(__NR_wait4,             sys_wait4),          // 61
1130   GENX_(__NR_kill,              sys_kill),           // 62
1131   GENXY(__NR_uname,             sys_newuname),       // 63
1132   PLAX_(__NR_semget,            sys_semget),         // 64
1133
1134   PLAX_(__NR_semop,             sys_semop),          // 65
1135   PLAXY(__NR_semctl,            sys_semctl),         // 66
1136   PLAXY(__NR_shmdt,             sys_shmdt),          // 67
1137   PLAX_(__NR_msgget,            sys_msgget),         // 68
1138   PLAX_(__NR_msgsnd,            sys_msgsnd),         // 69
1139
1140   PLAXY(__NR_msgrcv,            sys_msgrcv),         // 70
1141   PLAXY(__NR_msgctl,            sys_msgctl),         // 71
1142   LINXY(__NR_fcntl,             sys_fcntl),          // 72
1143   GENX_(__NR_flock,             sys_flock),          // 73
1144   GENX_(__NR_fsync,             sys_fsync),          // 74
1145
1146   GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
1147   GENX_(__NR_truncate,          sys_truncate),       // 76
1148   GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
1149   GENXY(__NR_getdents,          sys_getdents),       // 78
1150   GENXY(__NR_getcwd,            sys_getcwd),         // 79
1151
1152   GENX_(__NR_chdir,             sys_chdir),          // 80
1153   GENX_(__NR_fchdir,            sys_fchdir),         // 81
1154   GENX_(__NR_rename,            sys_rename),         // 82
1155   GENX_(__NR_mkdir,             sys_mkdir),          // 83
1156   GENX_(__NR_rmdir,             sys_rmdir),          // 84
1157
1158   GENXY(__NR_creat,             sys_creat),          // 85
1159   GENX_(__NR_link,              sys_link),           // 86
1160   GENX_(__NR_unlink,            sys_unlink),         // 87
1161   GENX_(__NR_symlink,           sys_symlink),        // 88
1162   GENX_(__NR_readlink,          sys_readlink),       // 89
1163
1164   GENX_(__NR_chmod,             sys_chmod),          // 90
1165   GENX_(__NR_fchmod,            sys_fchmod),         // 91
1166   GENX_(__NR_chown,             sys_chown),          // 92
1167   GENX_(__NR_fchown,            sys_fchown),         // 93
1168   GENX_(__NR_lchown,            sys_lchown),         // 94
1169
1170   GENX_(__NR_umask,             sys_umask),          // 95
1171   GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
1172   GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
1173   GENXY(__NR_getrusage,         sys_getrusage),      // 98
1174   LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
1175
1176   GENXY(__NR_times,             sys_times),          // 100
1177   PLAXY(__NR_ptrace,            sys_ptrace),         // 101
1178   GENX_(__NR_getuid,            sys_getuid),         // 102
1179   LINXY(__NR_syslog,            sys_syslog),         // 103
1180   GENX_(__NR_getgid,            sys_getgid),         // 104
1181
1182   GENX_(__NR_setuid,            sys_setuid),         // 105
1183   GENX_(__NR_setgid,            sys_setgid),         // 106
1184   GENX_(__NR_geteuid,           sys_geteuid),        // 107
1185   GENX_(__NR_getegid,           sys_getegid),        // 108
1186   GENX_(__NR_setpgid,           sys_setpgid),        // 109
1187
1188   GENX_(__NR_getppid,           sys_getppid),        // 110
1189   GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
1190   GENX_(__NR_setsid,            sys_setsid),         // 112
1191   GENX_(__NR_setreuid,          sys_setreuid),       // 113
1192   GENX_(__NR_setregid,          sys_setregid),       // 114
1193
1194   GENXY(__NR_getgroups,         sys_getgroups),      // 115
1195   GENX_(__NR_setgroups,         sys_setgroups),      // 116
1196   LINX_(__NR_setresuid,         sys_setresuid),      // 117
1197   LINXY(__NR_getresuid,         sys_getresuid),      // 118
1198   LINX_(__NR_setresgid,         sys_setresgid),      // 119
1199
1200   LINXY(__NR_getresgid,         sys_getresgid),      // 120
1201   GENX_(__NR_getpgid,           sys_getpgid),        // 121
1202   LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
1203   LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
1204   GENX_(__NR_getsid,            sys_getsid),         // 124
1205
1206   LINXY(__NR_capget,            sys_capget),         // 125
1207   LINX_(__NR_capset,            sys_capset),         // 126
1208   LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
1209   LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
1210   LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
1211
1212   LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
1213   GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
1214   LINX_(__NR_utime,             sys_utime),          // 132
1215   GENX_(__NR_mknod,             sys_mknod),          // 133
1216   //   (__NR_uselib,            sys_uselib),         // 134
1217
1218   LINX_(__NR_personality,       sys_personality),    // 135
1219   //   (__NR_ustat,             sys_ustat),          // 136
1220   GENXY(__NR_statfs,            sys_statfs),         // 137
1221   GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
1222   //   (__NR_sysfs,             sys_sysfs),          // 139
1223
1224   GENX_(__NR_getpriority,             sys_getpriority),             // 140
1225   GENX_(__NR_setpriority,             sys_setpriority),             // 141
1226   LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
1227   LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
1228   LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
1229
1230   LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
1231   LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
1232   LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
1233   LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
1234   GENX_(__NR_mlock,                   sys_mlock),                   // 149
1235
1236   GENX_(__NR_munlock,           sys_munlock),        // 150
1237   GENX_(__NR_mlockall,          sys_mlockall),       // 151
1238   LINX_(__NR_munlockall,        sys_munlockall),     // 152
1239   LINX_(__NR_vhangup,           sys_vhangup),        // 153
1240   //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
1241
1242   //   (__NR_pivot_root,        sys_pivot_root),     // 155
1243   LINXY(__NR__sysctl,           sys_sysctl),         // 156
1244   LINXY(__NR_prctl,             sys_prctl),          // 157
1245   PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
1246   LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
1247
1248   GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
1249   GENX_(__NR_chroot,            sys_chroot),         // 161
1250   GENX_(__NR_sync,              sys_sync),           // 162
1251   //   (__NR_acct,              sys_acct),           // 163
1252   GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
1253
1254   LINX_(__NR_mount,             sys_mount),          // 165
1255   LINX_(__NR_umount2,           sys_umount),         // 166
1256   //   (__NR_swapon,            sys_swapon),         // 167
1257   //   (__NR_swapoff,           sys_swapoff),        // 168
1258   //   (__NR_reboot,            sys_reboot),         // 169
1259
1260   //   (__NR_sethostname,       sys_sethostname),    // 170
1261   //   (__NR_setdomainname,     sys_setdomainname),  // 171
1262   GENX_(__NR_iopl,              sys_iopl),           // 172
1263   LINX_(__NR_ioperm,            sys_ioperm),         // 173
1264   GENX_(__NR_create_module,     sys_ni_syscall),     // 174
1265
1266   LINX_(__NR_init_module,       sys_init_module),    // 175
1267   LINX_(__NR_delete_module,     sys_delete_module),  // 176
1268   //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
1269   //   (__NR_query_module,      sys_ni_syscall),     // 178
1270   LINX_(__NR_quotactl,          sys_quotactl),       // 179
1271
1272   //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
1273   //   (__NR_getpmsg,           sys_ni_syscall),     // 181
1274   //   (__NR_putpmsg,           sys_ni_syscall),     // 182
1275   //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
1276   PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
1277
1278   //   (__NR_security,          sys_ni_syscall),     // 185
1279   LINX_(__NR_gettid,            sys_gettid),         // 186
1280   LINX_(__NR_readahead,         sys_readahead),      // 187
1281   LINX_(__NR_setxattr,          sys_setxattr),       // 188
1282   LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
1283
1284   LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
1285   LINXY(__NR_getxattr,          sys_getxattr),       // 191
1286   LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
1287   LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
1288   LINXY(__NR_listxattr,         sys_listxattr),      // 194
1289
1290   LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
1291   LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
1292   LINX_(__NR_removexattr,       sys_removexattr),    // 197
1293   LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
1294   LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
1295
1296   LINXY(__NR_tkill,             sys_tkill),             // 200
1297   GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
1298   LINXY(__NR_futex,             sys_futex),             // 202
1299   LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
1300   LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
1301
1302   //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
1303   LINXY(__NR_io_setup,          sys_io_setup),       // 206
1304   LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
1305   LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
1306   LINX_(__NR_io_submit,         sys_io_submit),      // 209
1307
1308   LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
1309   //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
1310   LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
1311   LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
1312   //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
1313
1314   //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
1315   //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
1316   GENXY(__NR_getdents64,        sys_getdents64),     // 217
1317   LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
1318   //   (__NR_restart_syscall,   sys_restart_syscall),// 219
1319
1320   PLAX_(__NR_semtimedop,        sys_semtimedop),     // 220
1321   PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
1322   LINXY(__NR_timer_create,      sys_timer_create),   // 222
1323   LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
1324   LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
1325
1326   LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
1327   LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
1328   LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
1329   LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
1330   LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
1331
1332   LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
1333   LINX_(__NR_exit_group,        sys_exit_group),     // 231
1334   LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
1335   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
1336   LINXY(__NR_tgkill,            sys_tgkill),         // 234
1337
1338   GENX_(__NR_utimes,            sys_utimes),         // 235
1339   //   (__NR_vserver,           sys_ni_syscall),     // 236
1340   LINX_(__NR_mbind,             sys_mbind),          // 237
1341   LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
1342   LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
1343
1344   LINXY(__NR_mq_open,           sys_mq_open),        // 240
1345   LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
1346   LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
1347   LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
1348   LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
1349
1350   LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
1351   //   (__NR_kexec_load,        sys_ni_syscall),     // 246
1352   LINXY(__NR_waitid,            sys_waitid),         // 247
1353   LINX_(__NR_add_key,           sys_add_key),        // 248
1354   LINX_(__NR_request_key,       sys_request_key),    // 249
1355
1356   LINXY(__NR_keyctl,            sys_keyctl),         // 250
1357   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
1358   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
1359   LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
1360   LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
1361
1362   LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
1363//   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
1364   LINXY(__NR_openat,		 sys_openat),           // 257
1365   LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
1366   LINX_(__NR_mknodat,		 sys_mknodat),          // 259
1367
1368   LINX_(__NR_fchownat,		 sys_fchownat),         // 260
1369   LINX_(__NR_futimesat,	 sys_futimesat),        // 261
1370   LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
1371   LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
1372   LINX_(__NR_renameat,		 sys_renameat),         // 264
1373
1374   LINX_(__NR_linkat,		 sys_linkat),           // 265
1375   LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
1376   LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
1377   LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
1378   LINX_(__NR_faccessat,	 sys_faccessat),        // 269
1379
1380   LINX_(__NR_pselect6,		 sys_pselect6),         // 270
1381   LINXY(__NR_ppoll,		 sys_ppoll),            // 271
1382//   LINX_(__NR_unshare,		 sys_unshare),          // 272
1383   LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
1384   LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
1385
1386   LINX_(__NR_splice,            sys_splice),           // 275
1387//   LINX_(__NR_tee,               sys_ni_syscall),       // 276
1388   LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
1389//   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 278
1390//   LINX_(__NR_move_pages,        sys_ni_syscall),       // 279
1391
1392   LINX_(__NR_utimensat,         sys_utimensat),        // 280
1393   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
1394   LINXY(__NR_signalfd,          sys_signalfd),         // 282
1395   LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
1396   LINX_(__NR_eventfd,           sys_eventfd),          // 284
1397
1398   LINX_(__NR_fallocate,         sys_fallocate),        // 285
1399   LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
1400   LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
1401   PLAXY(__NR_accept4,           sys_accept4),          // 288
1402   LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
1403
1404   LINX_(__NR_eventfd2,          sys_eventfd2),         // 290
1405   LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
1406   LINXY(__NR_dup3,              sys_dup3),             // 292
1407   LINXY(__NR_pipe2,             sys_pipe2),            // 293
1408   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
1409
1410   LINXY(__NR_preadv,            sys_preadv),           // 295
1411   LINX_(__NR_pwritev,           sys_pwritev),          // 296
1412   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
1413   LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
1414//   LINX_(__NR_recvmmsg,          sys_ni_syscall),       // 299
1415
1416//   LINX_(__NR_fanotify_init,     sys_ni_syscall),       // 300
1417//   LINX_(__NR_fanotify_mark,     sys_ni_syscall),       // 301
1418   LINXY(__NR_prlimit64,         sys_prlimit64)         // 302
1419//   LINX_(__NR_name_to_handle_at, sys_ni_syscall),       // 303
1420//   LINX_(__NR_open_by_handle_at, sys_ni_syscall),       // 304
1421
1422//   LINX_(__NR_clock_adjtime,     sys_ni_syscall),       // 305
1423//   LINX_(__NR_syncfs,            sys_ni_syscall),       // 306
1424//   LINX_(__NR_sendmmsg,          sys_ni_syscall),       // 307
1425//   LINX_(__NR_setns,             sys_ni_syscall),       // 308
1426};
1427
1428SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1429{
1430   const UInt syscall_table_size
1431      = sizeof(syscall_table) / sizeof(syscall_table[0]);
1432
1433   /* Is it in the contiguous initial section of the table? */
1434   if (sysno < syscall_table_size) {
1435      SyscallTableEntry* sys = &syscall_table[sysno];
1436      if (sys->before == NULL)
1437         return NULL; /* no entry */
1438      else
1439         return sys;
1440   }
1441
1442   /* Can't find a wrapper */
1443   return NULL;
1444}
1445
1446#endif // defined(VGP_amd64_linux)
1447
1448/*--------------------------------------------------------------------*/
1449/*--- end                                                          ---*/
1450/*--------------------------------------------------------------------*/
1451