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-2013 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".globl do_syscall_clone_amd64_linux\n"
146"do_syscall_clone_amd64_linux:\n"
147        // set up child stack, temporarily preserving fn and arg
148"       subq    $16, %rsi\n"            // make space on stack
149"       movq    %rcx, 8(%rsi)\n"        // save arg
150"       movq    %rdi, 0(%rsi)\n"        // save fn
151
152        // setup syscall
153"       movq    $"__NR_CLONE", %rax\n"  // syscall number
154"       movq    %rdx,     %rdi\n"       // syscall arg1: flags
155        // %rsi already setup           // syscall arg2: child_stack
156"       movq    %r9,      %rdx\n"       // syscall arg3: parent_tid
157"       movq    %r8,      %r10\n"       // syscall arg4: child_tid
158"       movq    8(%rsp),  %r8\n"        // syscall arg5: tls_ptr
159
160"       syscall\n"                      // clone()
161
162"       testq   %rax, %rax\n"           // child if retval == 0
163"       jnz     1f\n"
164
165        // CHILD - call thread function
166"       pop     %rax\n"                 // pop fn
167"       pop     %rdi\n"                 // pop fn arg1: arg
168"       call    *%rax\n"                // call fn
169
170        // exit with result
171"       movq    %rax, %rdi\n"           // arg1: return value from fn
172"       movq    $"__NR_EXIT", %rax\n"
173
174"       syscall\n"
175
176        // Exit returned?!
177"       ud2\n"
178
179"1:\n"  // PARENT or ERROR
180"       ret\n"
181".previous\n"
182);
183
184#undef __NR_CLONE
185#undef __NR_EXIT
186
187
188// forward declaration
189static void setup_child ( ThreadArchState*, ThreadArchState* );
190
191/*
192   When a client clones, we need to keep track of the new thread.  This means:
193   1. allocate a ThreadId+ThreadState+stack for the the thread
194
195   2. initialize the thread's new VCPU state
196
197   3. create the thread using the same args as the client requested,
198   but using the scheduler entrypoint for EIP, and a separate stack
199   for ESP.
200 */
201static SysRes do_clone ( ThreadId ptid,
202                         ULong flags, Addr rsp,
203                         Long* parent_tidptr,
204                         Long* child_tidptr,
205                         Addr tlsaddr )
206{
207   static const Bool debug = False;
208
209   ThreadId     ctid = VG_(alloc_ThreadState)();
210   ThreadState* ptst = VG_(get_ThreadState)(ptid);
211   ThreadState* ctst = VG_(get_ThreadState)(ctid);
212   UWord*       stack;
213   NSegment const* seg;
214   SysRes       res;
215   Long         rax;
216   vki_sigset_t blockall, savedmask;
217
218   VG_(sigfillset)(&blockall);
219
220   vg_assert(VG_(is_running_thread)(ptid));
221   vg_assert(VG_(is_valid_tid)(ctid));
222
223   stack = (UWord*)ML_(allocstack)(ctid);
224   if (stack == NULL) {
225      res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
226      goto out;
227   }
228
229   /* Copy register state
230
231      Both parent and child return to the same place, and the code
232      following the clone syscall works out which is which, so we
233      don't need to worry about it.
234
235      The parent gets the child's new tid returned from clone, but the
236      child gets 0.
237
238      If the clone call specifies a NULL rsp for the new thread, then
239      it actually gets a copy of the parent's rsp.
240   */
241   setup_child( &ctst->arch, &ptst->arch );
242
243   /* Make sys_clone appear to have returned Success(0) in the
244      child. */
245   ctst->arch.vex.guest_RAX = 0;
246
247   if (rsp != 0)
248      ctst->arch.vex.guest_RSP = rsp;
249
250   ctst->os_state.parent = ptid;
251
252   /* inherit signal mask */
253   ctst->sig_mask = ptst->sig_mask;
254   ctst->tmp_sig_mask = ptst->sig_mask;
255
256   /* Start the child with its threadgroup being the same as the
257      parent's.  This is so that any exit_group calls that happen
258      after the child is created but before it sets its
259      os_state.threadgroup field for real (in thread_wrapper in
260      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
261      a race condition in which the thread is unkillable (via
262      exit_group) because its threadgroup is not set.  The race window
263      is probably only a few hundred or a few thousand cycles long.
264      See #226116. */
265   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
266
267   /* We don't really know where the client stack is, because its
268      allocated by the client.  The best we can do is look at the
269      memory mappings and try to derive some useful information.  We
270      assume that esp starts near its highest possible value, and can
271      only go down to the start of the mmaped segment. */
272   seg = VG_(am_find_nsegment)((Addr)rsp);
273   if (seg && seg->kind != SkResvn) {
274      ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(rsp);
275      ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
276
277      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
278
279      if (debug)
280	 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
281		     ctid, seg->start, VG_PGROUNDUP(rsp));
282   } else {
283      VG_(message)(Vg_UserMsg,
284                   "!? New thread %d starts with RSP(%#lx) unmapped\n",
285		   ctid, rsp);
286      ctst->client_stack_szB  = 0;
287   }
288
289   /* Assume the clone will succeed, and tell any tool that wants to
290      know that this thread has come into existence.  If the clone
291      fails, we'll send out a ll_exit notification for it at the out:
292      label below, to clean up. */
293   vg_assert(VG_(owns_BigLock_LL)(ptid));
294   VG_TRACK ( pre_thread_ll_create, ptid, ctid );
295
296   if (flags & VKI_CLONE_SETTLS) {
297      if (debug)
298	 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
299      ctst->arch.vex.guest_FS_ZERO = tlsaddr;
300   }
301
302   flags &= ~VKI_CLONE_SETTLS;
303
304   /* start the thread with everything blocked */
305   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
306
307   /* Create the new thread */
308   rax = do_syscall_clone_amd64_linux(
309            ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
310            child_tidptr, parent_tidptr, NULL
311         );
312   res = VG_(mk_SysRes_amd64_linux)( rax );
313
314   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
315
316  out:
317   if (sr_isError(res)) {
318      /* clone failed */
319      VG_(cleanup_thread)(&ctst->arch);
320      ctst->status = VgTs_Empty;
321      /* oops.  Better tell the tool the thread exited in a hurry :-) */
322      VG_TRACK( pre_thread_ll_exit, ctid );
323   }
324
325   return res;
326}
327
328
329/* ---------------------------------------------------------------------
330   More thread stuff
331   ------------------------------------------------------------------ */
332
333void VG_(cleanup_thread) ( ThreadArchState *arch )
334{
335}
336
337void setup_child ( /*OUT*/ ThreadArchState *child,
338                   /*IN*/  ThreadArchState *parent )
339{
340   /* We inherit our parent's guest state. */
341   child->vex = parent->vex;
342   child->vex_shadow1 = parent->vex_shadow1;
343   child->vex_shadow2 = parent->vex_shadow2;
344}
345
346
347/* ---------------------------------------------------------------------
348   PRE/POST wrappers for AMD64/Linux-specific syscalls
349   ------------------------------------------------------------------ */
350
351#define PRE(name)       DEFN_PRE_TEMPLATE(amd64_linux, name)
352#define POST(name)      DEFN_POST_TEMPLATE(amd64_linux, name)
353
354/* Add prototypes for the wrappers declared here, so that gcc doesn't
355   harass us for not having prototypes.  Really this is a kludge --
356   the right thing to do is to make these wrappers 'static' since they
357   aren't visible outside this file, but that requires even more macro
358   magic. */
359DECL_TEMPLATE(amd64_linux, sys_clone);
360DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
361DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
362DECL_TEMPLATE(amd64_linux, sys_ptrace);
363DECL_TEMPLATE(amd64_linux, sys_fadvise64);
364DECL_TEMPLATE(amd64_linux, sys_mmap);
365DECL_TEMPLATE(amd64_linux, sys_syscall184);
366
367
368PRE(sys_clone)
369{
370   ULong cloneflags;
371
372   PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
373   PRE_REG_READ2(int, "clone",
374                 unsigned long, flags,
375                 void *, child_stack);
376
377   if (ARG1 & VKI_CLONE_PARENT_SETTID) {
378      if (VG_(tdict).track_pre_reg_read) {
379         PRA3("clone", int *, parent_tidptr);
380      }
381      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
382      if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
383         SET_STATUS_Failure( VKI_EFAULT );
384         return;
385      }
386   }
387   if (ARG1 & VKI_CLONE_SETTLS) {
388      if (VG_(tdict).track_pre_reg_read) {
389         PRA4("clone", vki_modify_ldt_t *, tlsinfo);
390      }
391      PRE_MEM_READ("clone(tlsinfo)", ARG4, sizeof(vki_modify_ldt_t));
392      if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
393                                             VKI_PROT_READ)) {
394         SET_STATUS_Failure( VKI_EFAULT );
395         return;
396      }
397   }
398   if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
399      if (VG_(tdict).track_pre_reg_read) {
400         PRA5("clone", int *, child_tidptr);
401      }
402      PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
403      if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
404         SET_STATUS_Failure( VKI_EFAULT );
405         return;
406      }
407   }
408
409   cloneflags = ARG1;
410
411   if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
412      SET_STATUS_Failure( VKI_EINVAL );
413      return;
414   }
415
416   /* Only look at the flags we really care about */
417   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
418                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
419   case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
420      /* thread creation */
421      SET_STATUS_from_SysRes(
422         do_clone(tid,
423                  ARG1,          /* flags */
424                  (Addr)ARG2,    /* child ESP */
425                  (Long *)ARG3,  /* parent_tidptr */
426                  (Long *)ARG4,  /* child_tidptr */
427                  (Addr)ARG5));  /* set_tls */
428      break;
429
430   case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
431      /* FALLTHROUGH - assume vfork == fork */
432      cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
433
434   case 0: /* plain fork */
435      SET_STATUS_from_SysRes(
436         ML_(do_fork_clone)(tid,
437                       cloneflags,      /* flags */
438                       (Int *)ARG3,     /* parent_tidptr */
439                       (Int *)ARG4));   /* child_tidptr */
440      break;
441
442   default:
443      /* should we just ENOSYS? */
444      VG_(message)(Vg_UserMsg,
445                   "Unsupported clone() flags: 0x%lx\n", ARG1);
446      VG_(message)(Vg_UserMsg,
447                   "\n");
448      VG_(message)(Vg_UserMsg,
449                   "The only supported clone() uses are:\n");
450      VG_(message)(Vg_UserMsg,
451                   " - via a threads library (LinuxThreads or NPTL)\n");
452      VG_(message)(Vg_UserMsg,
453                   " - via the implementation of fork or vfork\n");
454      VG_(unimplemented)
455         ("Valgrind does not support general clone().");
456   }
457
458   if (SUCCESS) {
459      if (ARG1 & VKI_CLONE_PARENT_SETTID)
460         POST_MEM_WRITE(ARG3, sizeof(Int));
461      if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
462         POST_MEM_WRITE(ARG4, sizeof(Int));
463
464      /* Thread creation was successful; let the child have the chance
465         to run */
466      *flags |= SfYieldAfter;
467   }
468}
469
470PRE(sys_rt_sigreturn)
471{
472   /* This isn't really a syscall at all - it's a misuse of the
473      syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
474      return address of the signal frames it creates to be a short
475      piece of code which does this "syscall".  The only purpose of
476      the syscall is to call VG_(sigframe_destroy), which restores the
477      thread's registers from the frame and then removes it.
478      Consequently we must ask the syswrap driver logic not to write
479      back the syscall "result" as that would overwrite the
480      just-restored register state. */
481
482   ThreadState* tst;
483   PRINT("sys_rt_sigreturn ( )");
484
485   vg_assert(VG_(is_valid_tid)(tid));
486   vg_assert(tid >= 1 && tid < VG_N_THREADS);
487   vg_assert(VG_(is_running_thread)(tid));
488
489   /* Adjust RSP to point to start of frame; skip back up over handler
490      ret addr */
491   tst = VG_(get_ThreadState)(tid);
492   tst->arch.vex.guest_RSP -= sizeof(Addr);
493
494   /* This is only so that the RIP is (might be) useful to report if
495      something goes wrong in the sigreturn.  JRS 20070318: no idea
496      what this is for */
497   ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
498
499   /* Restore register state from frame and remove it, as
500      described above */
501   VG_(sigframe_destroy)(tid, True);
502
503   /* Tell the driver not to update the guest state with the "result",
504      and set a bogus result to keep it happy. */
505   *flags |= SfNoWriteResult;
506   SET_STATUS_Success(0);
507
508   /* Check to see if any signals arose as a result of this. */
509   *flags |= SfPollAfter;
510}
511
512PRE(sys_arch_prctl)
513{
514   ThreadState* tst;
515   PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
516
517   vg_assert(VG_(is_valid_tid)(tid));
518   vg_assert(tid >= 1 && tid < VG_N_THREADS);
519   vg_assert(VG_(is_running_thread)(tid));
520
521   // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
522   PRE_REG_READ2(long, "arch_prctl",
523                 int, option, unsigned long, arg2);
524   // XXX: totally wrong... we need to look at the 'option' arg, and do
525   // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
526
527   /* "do" the syscall ourselves; the kernel never sees it */
528   if (ARG1 == VKI_ARCH_SET_FS) {
529      tst = VG_(get_ThreadState)(tid);
530      tst->arch.vex.guest_FS_ZERO = ARG2;
531   }
532   else if (ARG1 == VKI_ARCH_GET_FS) {
533      PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
534      tst = VG_(get_ThreadState)(tid);
535      *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_ZERO;
536      POST_MEM_WRITE(ARG2, sizeof(unsigned long));
537   }
538   else {
539      VG_(core_panic)("Unsupported arch_prtctl option");
540   }
541
542   /* Note; the Status writeback to guest state that happens after
543      this wrapper returns does not change guest_FS_ZERO; hence that
544      direct assignment to the guest state is safe here. */
545   SET_STATUS_Success( 0 );
546}
547
548// Parts of this are amd64-specific, but the *PEEK* cases are generic.
549//
550// ARG3 is only used for pointers into the traced process's address
551// space and for offsets into the traced process's struct
552// user_regs_struct. It is never a pointer into this process's memory
553// space, and we should therefore not check anything it points to.
554PRE(sys_ptrace)
555{
556   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
557   PRE_REG_READ4(int, "ptrace",
558                 long, request, long, pid, long, addr, long, data);
559   switch (ARG1) {
560   case VKI_PTRACE_PEEKTEXT:
561   case VKI_PTRACE_PEEKDATA:
562   case VKI_PTRACE_PEEKUSR:
563      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
564		     sizeof (long));
565      break;
566   case VKI_PTRACE_GETREGS:
567      PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
568		     sizeof (struct vki_user_regs_struct));
569      break;
570   case VKI_PTRACE_GETFPREGS:
571      PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
572		     sizeof (struct vki_user_i387_struct));
573      break;
574   case VKI_PTRACE_SETREGS:
575      PRE_MEM_READ( "ptrace(setregs)", ARG4,
576		     sizeof (struct vki_user_regs_struct));
577      break;
578   case VKI_PTRACE_SETFPREGS:
579      PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
580		     sizeof (struct vki_user_i387_struct));
581      break;
582   case VKI_PTRACE_GETEVENTMSG:
583      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
584      break;
585   case VKI_PTRACE_GETSIGINFO:
586      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
587      break;
588   case VKI_PTRACE_SETSIGINFO:
589      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
590      break;
591   case VKI_PTRACE_GETREGSET:
592      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
593      break;
594   case VKI_PTRACE_SETREGSET:
595      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
596      break;
597   default:
598      break;
599   }
600}
601
602POST(sys_ptrace)
603{
604   switch (ARG1) {
605   case VKI_PTRACE_PEEKTEXT:
606   case VKI_PTRACE_PEEKDATA:
607   case VKI_PTRACE_PEEKUSR:
608      POST_MEM_WRITE( ARG4, sizeof (long));
609      break;
610   case VKI_PTRACE_GETREGS:
611      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
612      break;
613   case VKI_PTRACE_GETFPREGS:
614      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
615      break;
616   case VKI_PTRACE_GETEVENTMSG:
617      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
618      break;
619   case VKI_PTRACE_GETSIGINFO:
620      /* XXX: This is a simplification. Different parts of the
621       * siginfo_t are valid depending on the type of signal.
622       */
623      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
624      break;
625   case VKI_PTRACE_GETREGSET:
626      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
627      break;
628   default:
629      break;
630   }
631}
632
633PRE(sys_fadvise64)
634{
635   PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", ARG1,ARG2,ARG3,ARG4);
636   PRE_REG_READ4(long, "fadvise64",
637                 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
638}
639
640PRE(sys_mmap)
641{
642   SysRes r;
643
644   PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %d, %ld )",
645         ARG1, (ULong)ARG2, ARG3, ARG4, (Int)ARG5, ARG6 );
646   PRE_REG_READ6(long, "mmap",
647                 unsigned long, start, unsigned long, length,
648                 unsigned long, prot,  unsigned long, flags,
649                 unsigned long, fd,    unsigned long, offset);
650
651   r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
652   SET_STATUS_from_SysRes(r);
653}
654
655
656/* ---------------------------------------------------------------
657   PRE/POST wrappers for AMD64/Linux-variant specific syscalls
658   ------------------------------------------------------------ */
659
660PRE(sys_syscall184)
661{
662   Int err;
663
664   /* 184 is used by sys_bproc.  If we're not on a declared bproc
665      variant, fail in the usual way, since it is otherwise unused. */
666
667   if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
668      PRINT("non-existent syscall! (syscall 184)");
669      PRE_REG_READ0(long, "ni_syscall(184)");
670      SET_STATUS_Failure( VKI_ENOSYS );
671      return;
672   }
673
674   err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
675                                           ARG4, ARG5, ARG6 );
676   if (err) {
677      SET_STATUS_Failure( err );
678      return;
679   }
680   /* Let it go through. */
681   *flags |= SfMayBlock; /* who knows?  play safe. */
682}
683
684POST(sys_syscall184)
685{
686   ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
687                                      ARG4, ARG5, ARG6 );
688}
689
690#undef PRE
691#undef POST
692
693
694/* ---------------------------------------------------------------------
695   The AMD64/Linux syscall table
696   ------------------------------------------------------------------ */
697
698/* Add an amd64-linux specific wrapper to a syscall table. */
699#define PLAX_(const, name)    WRAPPER_ENTRY_X_(amd64_linux, const, name)
700#define PLAXY(const, name)    WRAPPER_ENTRY_XY(amd64_linux, const, name)
701
702// This table maps from __NR_xxx syscall numbers (from
703// linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
704// wrappers on AMD64 (as per sys_call_table in
705// linux/arch/x86_64/kernel/entry.S).
706//
707// When implementing these wrappers, you need to work out if the wrapper is
708// generic, Linux-only (but arch-independent), or AMD64/Linux only.
709
710static SyscallTableEntry syscall_table[] = {
711   GENXY(__NR_read,              sys_read),           // 0
712   GENX_(__NR_write,             sys_write),          // 1
713   GENXY(__NR_open,              sys_open),           // 2
714   GENXY(__NR_close,             sys_close),          // 3
715   GENXY(__NR_stat,              sys_newstat),        // 4
716
717   GENXY(__NR_fstat,             sys_newfstat),       // 5
718   GENXY(__NR_lstat,             sys_newlstat),       // 6
719   GENXY(__NR_poll,              sys_poll),           // 7
720   LINX_(__NR_lseek,             sys_lseek),          // 8
721   PLAX_(__NR_mmap,              sys_mmap),           // 9
722
723   GENXY(__NR_mprotect,          sys_mprotect),       // 10
724   GENXY(__NR_munmap,            sys_munmap),         // 11
725   GENX_(__NR_brk,               sys_brk),            // 12
726   LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 13
727   LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 14
728
729   PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 15
730   LINXY(__NR_ioctl,             sys_ioctl),          // 16
731   GENXY(__NR_pread64,           sys_pread64),        // 17
732   GENX_(__NR_pwrite64,          sys_pwrite64),       // 18
733   GENXY(__NR_readv,             sys_readv),          // 19
734
735   GENX_(__NR_writev,            sys_writev),         // 20
736   GENX_(__NR_access,            sys_access),         // 21
737   LINXY(__NR_pipe,              sys_pipe),           // 22
738   GENX_(__NR_select,            sys_select),         // 23
739   LINX_(__NR_sched_yield,       sys_sched_yield),    // 24
740
741   GENX_(__NR_mremap,            sys_mremap),         // 25
742   GENX_(__NR_msync,             sys_msync),          // 26
743   GENXY(__NR_mincore,           sys_mincore),        // 27
744   GENX_(__NR_madvise,           sys_madvise),        // 28
745   LINX_(__NR_shmget,            sys_shmget),         // 29
746
747   LINXY(__NR_shmat,             wrap_sys_shmat),     // 30
748   LINXY(__NR_shmctl,            sys_shmctl),         // 31
749   GENXY(__NR_dup,               sys_dup),            // 32
750   GENXY(__NR_dup2,              sys_dup2),           // 33
751   GENX_(__NR_pause,             sys_pause),          // 34
752
753   GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
754   GENXY(__NR_getitimer,         sys_getitimer),      // 36
755   GENX_(__NR_alarm,             sys_alarm),          // 37
756   GENXY(__NR_setitimer,         sys_setitimer),      // 38
757   GENX_(__NR_getpid,            sys_getpid),         // 39
758
759   LINXY(__NR_sendfile,          sys_sendfile),       // 40
760   LINXY(__NR_socket,            sys_socket),         // 41
761   LINX_(__NR_connect,           sys_connect),        // 42
762   LINXY(__NR_accept,            sys_accept),         // 43
763   LINX_(__NR_sendto,            sys_sendto),         // 44
764
765   LINXY(__NR_recvfrom,          sys_recvfrom),       // 45
766   LINX_(__NR_sendmsg,           sys_sendmsg),        // 46
767   LINXY(__NR_recvmsg,           sys_recvmsg),        // 47
768   LINX_(__NR_shutdown,          sys_shutdown),       // 48
769   LINX_(__NR_bind,              sys_bind),           // 49
770
771   LINX_(__NR_listen,            sys_listen),         // 50
772   LINXY(__NR_getsockname,       sys_getsockname),    // 51
773   LINXY(__NR_getpeername,       sys_getpeername),    // 52
774   LINXY(__NR_socketpair,        sys_socketpair),     // 53
775   LINX_(__NR_setsockopt,        sys_setsockopt),     // 54
776
777   LINXY(__NR_getsockopt,        sys_getsockopt),     // 55
778   PLAX_(__NR_clone,             sys_clone),          // 56
779   GENX_(__NR_fork,              sys_fork),           // 57
780   GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
781   GENX_(__NR_execve,            sys_execve),         // 59
782
783   GENX_(__NR_exit,              sys_exit),           // 60
784   GENXY(__NR_wait4,             sys_wait4),          // 61
785   GENX_(__NR_kill,              sys_kill),           // 62
786   GENXY(__NR_uname,             sys_newuname),       // 63
787   LINX_(__NR_semget,            sys_semget),         // 64
788
789   LINX_(__NR_semop,             sys_semop),          // 65
790   LINXY(__NR_semctl,            sys_semctl),         // 66
791   LINXY(__NR_shmdt,             sys_shmdt),          // 67
792   LINX_(__NR_msgget,            sys_msgget),         // 68
793   LINX_(__NR_msgsnd,            sys_msgsnd),         // 69
794
795   LINXY(__NR_msgrcv,            sys_msgrcv),         // 70
796   LINXY(__NR_msgctl,            sys_msgctl),         // 71
797   LINXY(__NR_fcntl,             sys_fcntl),          // 72
798   GENX_(__NR_flock,             sys_flock),          // 73
799   GENX_(__NR_fsync,             sys_fsync),          // 74
800
801   GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
802   GENX_(__NR_truncate,          sys_truncate),       // 76
803   GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
804   GENXY(__NR_getdents,          sys_getdents),       // 78
805   GENXY(__NR_getcwd,            sys_getcwd),         // 79
806
807   GENX_(__NR_chdir,             sys_chdir),          // 80
808   GENX_(__NR_fchdir,            sys_fchdir),         // 81
809   GENX_(__NR_rename,            sys_rename),         // 82
810   GENX_(__NR_mkdir,             sys_mkdir),          // 83
811   GENX_(__NR_rmdir,             sys_rmdir),          // 84
812
813   GENXY(__NR_creat,             sys_creat),          // 85
814   GENX_(__NR_link,              sys_link),           // 86
815   GENX_(__NR_unlink,            sys_unlink),         // 87
816   GENX_(__NR_symlink,           sys_symlink),        // 88
817   GENX_(__NR_readlink,          sys_readlink),       // 89
818
819   GENX_(__NR_chmod,             sys_chmod),          // 90
820   GENX_(__NR_fchmod,            sys_fchmod),         // 91
821   GENX_(__NR_chown,             sys_chown),          // 92
822   GENX_(__NR_fchown,            sys_fchown),         // 93
823   GENX_(__NR_lchown,            sys_lchown),         // 94
824
825   GENX_(__NR_umask,             sys_umask),          // 95
826   GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
827   GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
828   GENXY(__NR_getrusage,         sys_getrusage),      // 98
829   LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
830
831   GENXY(__NR_times,             sys_times),          // 100
832   PLAXY(__NR_ptrace,            sys_ptrace),         // 101
833   GENX_(__NR_getuid,            sys_getuid),         // 102
834   LINXY(__NR_syslog,            sys_syslog),         // 103
835   GENX_(__NR_getgid,            sys_getgid),         // 104
836
837   GENX_(__NR_setuid,            sys_setuid),         // 105
838   GENX_(__NR_setgid,            sys_setgid),         // 106
839   GENX_(__NR_geteuid,           sys_geteuid),        // 107
840   GENX_(__NR_getegid,           sys_getegid),        // 108
841   GENX_(__NR_setpgid,           sys_setpgid),        // 109
842
843   GENX_(__NR_getppid,           sys_getppid),        // 110
844   GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
845   GENX_(__NR_setsid,            sys_setsid),         // 112
846   GENX_(__NR_setreuid,          sys_setreuid),       // 113
847   GENX_(__NR_setregid,          sys_setregid),       // 114
848
849   GENXY(__NR_getgroups,         sys_getgroups),      // 115
850   GENX_(__NR_setgroups,         sys_setgroups),      // 116
851   LINX_(__NR_setresuid,         sys_setresuid),      // 117
852   LINXY(__NR_getresuid,         sys_getresuid),      // 118
853   LINX_(__NR_setresgid,         sys_setresgid),      // 119
854
855   LINXY(__NR_getresgid,         sys_getresgid),      // 120
856   GENX_(__NR_getpgid,           sys_getpgid),        // 121
857   LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
858   LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
859   GENX_(__NR_getsid,            sys_getsid),         // 124
860
861   LINXY(__NR_capget,            sys_capget),         // 125
862   LINX_(__NR_capset,            sys_capset),         // 126
863   LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
864   LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
865   LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
866
867   LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
868   GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
869   LINX_(__NR_utime,             sys_utime),          // 132
870   GENX_(__NR_mknod,             sys_mknod),          // 133
871   //   (__NR_uselib,            sys_uselib),         // 134
872
873   LINX_(__NR_personality,       sys_personality),    // 135
874   //   (__NR_ustat,             sys_ustat),          // 136
875   GENXY(__NR_statfs,            sys_statfs),         // 137
876   GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
877   //   (__NR_sysfs,             sys_sysfs),          // 139
878
879   GENX_(__NR_getpriority,             sys_getpriority),             // 140
880   GENX_(__NR_setpriority,             sys_setpriority),             // 141
881   LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
882   LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
883   LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
884
885   LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
886   LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
887   LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
888   LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
889   GENX_(__NR_mlock,                   sys_mlock),                   // 149
890
891   GENX_(__NR_munlock,           sys_munlock),        // 150
892   GENX_(__NR_mlockall,          sys_mlockall),       // 151
893   LINX_(__NR_munlockall,        sys_munlockall),     // 152
894   LINX_(__NR_vhangup,           sys_vhangup),        // 153
895   //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
896
897   //   (__NR_pivot_root,        sys_pivot_root),     // 155
898   LINXY(__NR__sysctl,           sys_sysctl),         // 156
899   LINXY(__NR_prctl,             sys_prctl),          // 157
900   PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
901   LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
902
903   GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
904   GENX_(__NR_chroot,            sys_chroot),         // 161
905   GENX_(__NR_sync,              sys_sync),           // 162
906   //   (__NR_acct,              sys_acct),           // 163
907   GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
908
909   LINX_(__NR_mount,             sys_mount),          // 165
910   LINX_(__NR_umount2,           sys_umount),         // 166
911   //   (__NR_swapon,            sys_swapon),         // 167
912   //   (__NR_swapoff,           sys_swapoff),        // 168
913   //   (__NR_reboot,            sys_reboot),         // 169
914
915   GENX_(__NR_sethostname,       sys_sethostname),    // 170
916   //   (__NR_setdomainname,     sys_setdomainname),  // 171
917   GENX_(__NR_iopl,              sys_iopl),           // 172
918   LINX_(__NR_ioperm,            sys_ioperm),         // 173
919   GENX_(__NR_create_module,     sys_ni_syscall),     // 174
920
921   LINX_(__NR_init_module,       sys_init_module),    // 175
922   LINX_(__NR_delete_module,     sys_delete_module),  // 176
923   //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
924   //   (__NR_query_module,      sys_ni_syscall),     // 178
925   LINX_(__NR_quotactl,          sys_quotactl),       // 179
926
927   //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
928   //   (__NR_getpmsg,           sys_ni_syscall),     // 181
929   //   (__NR_putpmsg,           sys_ni_syscall),     // 182
930   //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
931   PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
932
933   //   (__NR_security,          sys_ni_syscall),     // 185
934   LINX_(__NR_gettid,            sys_gettid),         // 186
935   LINX_(__NR_readahead,         sys_readahead),      // 187
936   LINX_(__NR_setxattr,          sys_setxattr),       // 188
937   LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
938
939   LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
940   LINXY(__NR_getxattr,          sys_getxattr),       // 191
941   LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
942   LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
943   LINXY(__NR_listxattr,         sys_listxattr),      // 194
944
945   LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
946   LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
947   LINX_(__NR_removexattr,       sys_removexattr),    // 197
948   LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
949   LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
950
951   LINXY(__NR_tkill,             sys_tkill),             // 200
952   GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
953   LINXY(__NR_futex,             sys_futex),             // 202
954   LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
955   LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
956
957   //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
958   LINXY(__NR_io_setup,          sys_io_setup),       // 206
959   LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
960   LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
961   LINX_(__NR_io_submit,         sys_io_submit),      // 209
962
963   LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
964   //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
965   LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
966   LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
967   //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
968
969   //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
970   //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
971   GENXY(__NR_getdents64,        sys_getdents64),     // 217
972   LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
973   //   (__NR_restart_syscall,   sys_restart_syscall),// 219
974
975   LINX_(__NR_semtimedop,        sys_semtimedop),     // 220
976   PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
977   LINXY(__NR_timer_create,      sys_timer_create),   // 222
978   LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
979   LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
980
981   LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
982   LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
983   LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
984   LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
985   LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
986
987   LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
988   LINX_(__NR_exit_group,        sys_exit_group),     // 231
989   LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
990   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
991   LINXY(__NR_tgkill,            sys_tgkill),         // 234
992
993   GENX_(__NR_utimes,            sys_utimes),         // 235
994   //   (__NR_vserver,           sys_ni_syscall),     // 236
995   LINX_(__NR_mbind,             sys_mbind),          // 237
996   LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
997   LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
998
999   LINXY(__NR_mq_open,           sys_mq_open),        // 240
1000   LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
1001   LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
1002   LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
1003   LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
1004
1005   LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
1006   //   (__NR_kexec_load,        sys_ni_syscall),     // 246
1007   LINXY(__NR_waitid,            sys_waitid),         // 247
1008   LINX_(__NR_add_key,           sys_add_key),        // 248
1009   LINX_(__NR_request_key,       sys_request_key),    // 249
1010
1011   LINXY(__NR_keyctl,            sys_keyctl),         // 250
1012   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
1013   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
1014   LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
1015   LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
1016
1017   LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
1018//   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
1019   LINXY(__NR_openat,		 sys_openat),           // 257
1020   LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
1021   LINX_(__NR_mknodat,		 sys_mknodat),          // 259
1022
1023   LINX_(__NR_fchownat,		 sys_fchownat),         // 260
1024   LINX_(__NR_futimesat,	 sys_futimesat),        // 261
1025   LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
1026   LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
1027   LINX_(__NR_renameat,		 sys_renameat),         // 264
1028
1029   LINX_(__NR_linkat,		 sys_linkat),           // 265
1030   LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
1031   LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
1032   LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
1033   LINX_(__NR_faccessat,	 sys_faccessat),        // 269
1034
1035   LINX_(__NR_pselect6,		 sys_pselect6),         // 270
1036   LINXY(__NR_ppoll,		 sys_ppoll),            // 271
1037//   LINX_(__NR_unshare,		 sys_unshare),          // 272
1038   LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
1039   LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
1040
1041   LINX_(__NR_splice,            sys_splice),           // 275
1042   LINX_(__NR_tee,               sys_tee),              // 276
1043   LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
1044   LINXY(__NR_vmsplice,          sys_vmsplice),         // 278
1045   LINXY(__NR_move_pages,        sys_move_pages),       // 279
1046
1047   LINX_(__NR_utimensat,         sys_utimensat),        // 280
1048   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
1049   LINXY(__NR_signalfd,          sys_signalfd),         // 282
1050   LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
1051   LINXY(__NR_eventfd,           sys_eventfd),          // 284
1052
1053   LINX_(__NR_fallocate,         sys_fallocate),        // 285
1054   LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
1055   LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
1056   LINXY(__NR_accept4,           sys_accept4),          // 288
1057   LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
1058
1059   LINXY(__NR_eventfd2,          sys_eventfd2),         // 290
1060   LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
1061   LINXY(__NR_dup3,              sys_dup3),             // 292
1062   LINXY(__NR_pipe2,             sys_pipe2),            // 293
1063   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
1064
1065   LINXY(__NR_preadv,            sys_preadv),           // 295
1066   LINX_(__NR_pwritev,           sys_pwritev),          // 296
1067   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
1068   LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
1069   LINXY(__NR_recvmmsg,          sys_recvmmsg),         // 299
1070
1071   LINXY(__NR_fanotify_init,     sys_fanotify_init),    // 300
1072   LINX_(__NR_fanotify_mark,     sys_fanotify_mark),    // 301
1073   LINXY(__NR_prlimit64,         sys_prlimit64),        // 302
1074   LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 303
1075   LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 304
1076
1077   LINXY(__NR_clock_adjtime,     sys_clock_adjtime),    // 305
1078//   LINX_(__NR_syncfs,            sys_ni_syscall),       // 306
1079   LINXY(__NR_sendmmsg,          sys_sendmmsg),         // 307
1080//   LINX_(__NR_setns,             sys_ni_syscall),       // 308
1081   LINXY(__NR_getcpu,            sys_getcpu),           // 309
1082
1083   LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 310
1084   LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 311
1085};
1086
1087SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1088{
1089   const UInt syscall_table_size
1090      = sizeof(syscall_table) / sizeof(syscall_table[0]);
1091
1092   /* Is it in the contiguous initial section of the table? */
1093   if (sysno < syscall_table_size) {
1094      SyscallTableEntry* sys = &syscall_table[sysno];
1095      if (sys->before == NULL)
1096         return NULL; /* no entry */
1097      else
1098         return sys;
1099   }
1100
1101   /* Can't find a wrapper */
1102   return NULL;
1103}
1104
1105#endif // defined(VGP_amd64_linux)
1106
1107/*--------------------------------------------------------------------*/
1108/*--- end                                                          ---*/
1109/*--------------------------------------------------------------------*/
1110