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-2017 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_threadstate.h"
37#include "pub_core_aspacemgr.h"
38#include "pub_core_debuglog.h"
39#include "pub_core_options.h"
40#include "pub_core_libcbase.h"
41#include "pub_core_libcassert.h"
42#include "pub_core_libcprint.h"
43#include "pub_core_libcproc.h"
44#include "pub_core_libcsignal.h"
45#include "pub_core_scheduler.h"
46#include "pub_core_sigframe.h"
47#include "pub_core_signals.h"
48#include "pub_core_syscall.h"
49#include "pub_core_syswrap.h"
50#include "pub_core_tooliface.h"
51
52#include "priv_types_n_macros.h"
53#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
54#include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
55#include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
56#include "priv_syswrap-main.h"
57
58
59/* ---------------------------------------------------------------------
60   clone() handling
61   ------------------------------------------------------------------ */
62
63/* Call f(arg1), but first switch stacks, using 'stack' as the new
64   stack, and use 'retaddr' as f's return-to address.  Also, clear all
65   the integer registers before entering f.  */
66__attribute__((noreturn))
67void ML_(call_on_new_stack_0_1) ( Addr stack,
68			          Addr retaddr,
69			          void (*f)(Word),
70                                  Word arg1 );
71// %rdi == stack
72// %rsi == retaddr
73// %rdx == f
74// %rcx == arg1
75asm(
76".text\n"
77".globl vgModuleLocal_call_on_new_stack_0_1\n"
78"vgModuleLocal_call_on_new_stack_0_1:\n"
79"   movq   %rdi, %rsp\n"   // set stack
80"   pushq  %rsi\n"         // retaddr to stack
81"   pushq  %rdx\n"         // f to stack
82"   pushq  %rcx\n"         // arg1 to stack
83"   movq $0, %rax\n"       // zero all GP regs
84"   movq $0, %rbx\n"
85"   movq $0, %rcx\n"
86"   movq $0, %rdx\n"
87"   movq $0, %rsi\n"
88"   movq $0, %rdi\n"
89"   movq $0, %rbp\n"
90"   movq $0, %r8\n"
91"   movq $0, %r9\n"
92"   movq $0, %r10\n"
93"   movq $0, %r11\n"
94"   movq $0, %r12\n"
95"   movq $0, %r13\n"
96"   movq $0, %r14\n"
97"   movq $0, %r15\n"
98"   popq   %rdi\n"         // arg1 to correct arg reg
99"   ret\n"                 // jump to f
100"   ud2\n"                 // should never get here
101".previous\n"
102);
103
104/*
105        Perform a clone system call.  clone is strange because it has
106        fork()-like return-twice semantics, so it needs special
107        handling here.
108
109	Upon entry, we have:
110
111	    int (*fn)(void*)	in %rdi
112	    void*  child_stack	in %rsi
113	    int    flags	in %rdx
114	    void*  arg		in %rcx
115	    pid_t* child_tid	in %r8
116	    pid_t* parent_tid	in %r9
117	    void*  tls_ptr      at 8(%rsp)
118
119	System call requires:
120
121	    int    $__NR_clone  in %rax
122	    int    flags	in %rdi
123	    void*  child_stack	in %rsi
124	    pid_t* parent_tid	in %rdx
125	    pid_t* child_tid	in %r10
126	    void*  tls_ptr      in %r8
127
128	Returns a Long encoded in the linux-amd64 way, not a SysRes.
129 */
130#define __NR_CLONE        VG_STRINGIFY(__NR_clone)
131#define __NR_EXIT         VG_STRINGIFY(__NR_exit)
132
133// See priv_syswrap-linux.h for arg profile.
134asm(
135".text\n"
136".globl do_syscall_clone_amd64_linux\n"
137"do_syscall_clone_amd64_linux:\n"
138        // set up child stack, temporarily preserving fn and arg
139"       subq    $16, %rsi\n"            // make space on stack
140"       movq    %rcx, 8(%rsi)\n"        // save arg
141"       movq    %rdi, 0(%rsi)\n"        // save fn
142
143        // setup syscall
144"       movq    $"__NR_CLONE", %rax\n"  // syscall number
145"       movq    %rdx,     %rdi\n"       // syscall arg1: flags
146        // %rsi already setup           // syscall arg2: child_stack
147"       movq    %r9,      %rdx\n"       // syscall arg3: parent_tid
148"       movq    %r8,      %r10\n"       // syscall arg4: child_tid
149"       movq    8(%rsp),  %r8\n"        // syscall arg5: tls_ptr
150
151"       syscall\n"                      // clone()
152
153"       testq   %rax, %rax\n"           // child if retval == 0
154"       jnz     1f\n"
155
156        // CHILD - call thread function
157"       pop     %rax\n"                 // pop fn
158"       pop     %rdi\n"                 // pop fn arg1: arg
159"       call    *%rax\n"                // call fn
160
161        // exit with result
162"       movq    %rax, %rdi\n"           // arg1: return value from fn
163"       movq    $"__NR_EXIT", %rax\n"
164
165"       syscall\n"
166
167        // Exit returned?!
168"       ud2\n"
169
170"1:\n"  // PARENT or ERROR
171"       ret\n"
172".previous\n"
173);
174
175#undef __NR_CLONE
176#undef __NR_EXIT
177
178
179/* ---------------------------------------------------------------------
180   More thread stuff
181   ------------------------------------------------------------------ */
182
183void VG_(cleanup_thread) ( ThreadArchState *arch )
184{
185}
186
187/* ---------------------------------------------------------------------
188   PRE/POST wrappers for AMD64/Linux-specific syscalls
189   ------------------------------------------------------------------ */
190
191#define PRE(name)       DEFN_PRE_TEMPLATE(amd64_linux, name)
192#define POST(name)      DEFN_POST_TEMPLATE(amd64_linux, name)
193
194/* Add prototypes for the wrappers declared here, so that gcc doesn't
195   harass us for not having prototypes.  Really this is a kludge --
196   the right thing to do is to make these wrappers 'static' since they
197   aren't visible outside this file, but that requires even more macro
198   magic. */
199DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
200DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
201DECL_TEMPLATE(amd64_linux, sys_ptrace);
202DECL_TEMPLATE(amd64_linux, sys_fadvise64);
203DECL_TEMPLATE(amd64_linux, sys_mmap);
204DECL_TEMPLATE(amd64_linux, sys_syscall184);
205
206
207PRE(sys_rt_sigreturn)
208{
209   /* This isn't really a syscall at all - it's a misuse of the
210      syscall mechanism by m_sigframe.  VG_(sigframe_create) sets the
211      return address of the signal frames it creates to be a short
212      piece of code which does this "syscall".  The only purpose of
213      the syscall is to call VG_(sigframe_destroy), which restores the
214      thread's registers from the frame and then removes it.
215      Consequently we must ask the syswrap driver logic not to write
216      back the syscall "result" as that would overwrite the
217      just-restored register state. */
218
219   ThreadState* tst;
220   PRINT("sys_rt_sigreturn ( )");
221
222   vg_assert(VG_(is_valid_tid)(tid));
223   vg_assert(tid >= 1 && tid < VG_N_THREADS);
224   vg_assert(VG_(is_running_thread)(tid));
225
226   /* Adjust RSP to point to start of frame; skip back up over handler
227      ret addr */
228   tst = VG_(get_ThreadState)(tid);
229   tst->arch.vex.guest_RSP -= sizeof(Addr);
230
231   /* This is only so that the RIP is (might be) useful to report if
232      something goes wrong in the sigreturn.  JRS 20070318: no idea
233      what this is for */
234   ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
235
236   /* Restore register state from frame and remove it, as
237      described above */
238   VG_(sigframe_destroy)(tid, True);
239
240   /* Tell the driver not to update the guest state with the "result",
241      and set a bogus result to keep it happy. */
242   *flags |= SfNoWriteResult;
243   SET_STATUS_Success(0);
244
245   /* Check to see if any signals arose as a result of this. */
246   *flags |= SfPollAfter;
247}
248
249PRE(sys_arch_prctl)
250{
251   ThreadState* tst;
252   PRINT( "arch_prctl ( %ld, %lx )", SARG1, ARG2 );
253
254   vg_assert(VG_(is_valid_tid)(tid));
255   vg_assert(tid >= 1 && tid < VG_N_THREADS);
256   vg_assert(VG_(is_running_thread)(tid));
257
258   // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
259   PRE_REG_READ2(long, "arch_prctl",
260                 int, option, unsigned long, arg2);
261   // XXX: totally wrong... we need to look at the 'option' arg, and do
262   // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
263
264   /* "do" the syscall ourselves; the kernel never sees it */
265   if (ARG1 == VKI_ARCH_SET_FS) {
266      tst = VG_(get_ThreadState)(tid);
267      tst->arch.vex.guest_FS_CONST = ARG2;
268   }
269   else if (ARG1 == VKI_ARCH_GET_FS) {
270      PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
271      tst = VG_(get_ThreadState)(tid);
272      *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_CONST;
273      POST_MEM_WRITE(ARG2, sizeof(unsigned long));
274   }
275   else if (ARG1 == VKI_ARCH_SET_GS) {
276      tst = VG_(get_ThreadState)(tid);
277      tst->arch.vex.guest_GS_CONST = ARG2;
278   }
279   else if (ARG1 == VKI_ARCH_GET_GS) {
280      PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
281      tst = VG_(get_ThreadState)(tid);
282      *(unsigned long *)ARG2 = tst->arch.vex.guest_GS_CONST;
283      POST_MEM_WRITE(ARG2, sizeof(unsigned long));
284   }
285   else {
286      VG_(core_panic)("Unsupported arch_prctl option");
287   }
288
289   /* Note; the Status writeback to guest state that happens after
290      this wrapper returns does not change guest_FS_CONST or guest_GS_CONST;
291      hence that direct assignment to the guest state is safe here. */
292   SET_STATUS_Success( 0 );
293}
294
295// Parts of this are amd64-specific, but the *PEEK* cases are generic.
296//
297// ARG3 is only used for pointers into the traced process's address
298// space and for offsets into the traced process's struct
299// user_regs_struct. It is never a pointer into this process's memory
300// space, and we should therefore not check anything it points to.
301PRE(sys_ptrace)
302{
303   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
304   PRE_REG_READ4(int, "ptrace",
305                 long, request, long, pid, long, addr, long, data);
306   switch (ARG1) {
307   case VKI_PTRACE_PEEKTEXT:
308   case VKI_PTRACE_PEEKDATA:
309   case VKI_PTRACE_PEEKUSR:
310      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
311		     sizeof (long));
312      break;
313   case VKI_PTRACE_GETREGS:
314      PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
315		     sizeof (struct vki_user_regs_struct));
316      break;
317   case VKI_PTRACE_GETFPREGS:
318      PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
319		     sizeof (struct vki_user_i387_struct));
320      break;
321   case VKI_PTRACE_SETREGS:
322      PRE_MEM_READ( "ptrace(setregs)", ARG4,
323		     sizeof (struct vki_user_regs_struct));
324      break;
325   case VKI_PTRACE_SETFPREGS:
326      PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
327		     sizeof (struct vki_user_i387_struct));
328      break;
329   case VKI_PTRACE_GETEVENTMSG:
330      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
331      break;
332   case VKI_PTRACE_GETSIGINFO:
333      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
334      break;
335   case VKI_PTRACE_SETSIGINFO:
336      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
337      break;
338   case VKI_PTRACE_GETREGSET:
339      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
340      break;
341   case VKI_PTRACE_SETREGSET:
342      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
343      break;
344   default:
345      break;
346   }
347}
348
349POST(sys_ptrace)
350{
351   switch (ARG1) {
352   case VKI_PTRACE_TRACEME:
353         ML_(linux_POST_traceme)(tid);
354         break;
355   case VKI_PTRACE_PEEKTEXT:
356   case VKI_PTRACE_PEEKDATA:
357   case VKI_PTRACE_PEEKUSR:
358      POST_MEM_WRITE( ARG4, sizeof (long));
359      break;
360   case VKI_PTRACE_GETREGS:
361      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
362      break;
363   case VKI_PTRACE_GETFPREGS:
364      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
365      break;
366   case VKI_PTRACE_GETEVENTMSG:
367      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
368      break;
369   case VKI_PTRACE_GETSIGINFO:
370      /* XXX: This is a simplification. Different parts of the
371       * siginfo_t are valid depending on the type of signal.
372       */
373      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
374      break;
375   case VKI_PTRACE_GETREGSET:
376      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
377      break;
378   default:
379      break;
380   }
381}
382
383PRE(sys_fadvise64)
384{
385   PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", SARG1, SARG2, ARG3, SARG4);
386   PRE_REG_READ4(long, "fadvise64",
387                 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
388}
389
390PRE(sys_mmap)
391{
392   SysRes r;
393
394   PRINT("sys_mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )",
395         ARG1, ARG2, SARG3, SARG4, SARG5, SARG6 );
396   PRE_REG_READ6(long, "mmap",
397                 unsigned long, start, unsigned long, length,
398                 int, prot, int, flags, int, fd, vki_off_t, offset);
399
400   r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
401   SET_STATUS_from_SysRes(r);
402}
403
404
405/* ---------------------------------------------------------------
406   PRE/POST wrappers for AMD64/Linux-variant specific syscalls
407   ------------------------------------------------------------ */
408
409PRE(sys_syscall184)
410{
411   Int err;
412
413   /* 184 is used by sys_bproc.  If we're not on a declared bproc
414      variant, fail in the usual way, since it is otherwise unused. */
415
416   if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
417      PRINT("non-existent syscall! (syscall 184)");
418      PRE_REG_READ0(long, "ni_syscall(184)");
419      SET_STATUS_Failure( VKI_ENOSYS );
420      return;
421   }
422
423   err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
424                                           ARG4, ARG5, ARG6 );
425   if (err) {
426      SET_STATUS_Failure( err );
427      return;
428   }
429   /* Let it go through. */
430   *flags |= SfMayBlock; /* who knows?  play safe. */
431}
432
433POST(sys_syscall184)
434{
435   ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
436                                      ARG4, ARG5, ARG6 );
437}
438
439#undef PRE
440#undef POST
441
442
443/* ---------------------------------------------------------------------
444   The AMD64/Linux syscall table
445   ------------------------------------------------------------------ */
446
447/* Add an amd64-linux specific wrapper to a syscall table. */
448#define PLAX_(const, name)    WRAPPER_ENTRY_X_(amd64_linux, const, name)
449#define PLAXY(const, name)    WRAPPER_ENTRY_XY(amd64_linux, const, name)
450
451// This table maps from __NR_xxx syscall numbers (from
452// linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
453// wrappers on AMD64 (as per sys_call_table in
454// linux/arch/x86_64/kernel/entry.S).
455//
456// When implementing these wrappers, you need to work out if the wrapper is
457// generic, Linux-only (but arch-independent), or AMD64/Linux only.
458
459static SyscallTableEntry syscall_table[] = {
460   GENXY(__NR_read,              sys_read),           // 0
461   GENX_(__NR_write,             sys_write),          // 1
462   GENXY(__NR_open,              sys_open),           // 2
463   GENXY(__NR_close,             sys_close),          // 3
464   GENXY(__NR_stat,              sys_newstat),        // 4
465
466   GENXY(__NR_fstat,             sys_newfstat),       // 5
467   GENXY(__NR_lstat,             sys_newlstat),       // 6
468   GENXY(__NR_poll,              sys_poll),           // 7
469   LINX_(__NR_lseek,             sys_lseek),          // 8
470   PLAX_(__NR_mmap,              sys_mmap),           // 9
471
472   GENXY(__NR_mprotect,          sys_mprotect),       // 10
473   GENXY(__NR_munmap,            sys_munmap),         // 11
474   GENX_(__NR_brk,               sys_brk),            // 12
475   LINXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 13
476   LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 14
477
478   PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 15
479   LINXY(__NR_ioctl,             sys_ioctl),          // 16
480   GENXY(__NR_pread64,           sys_pread64),        // 17
481   GENX_(__NR_pwrite64,          sys_pwrite64),       // 18
482   GENXY(__NR_readv,             sys_readv),          // 19
483
484   GENX_(__NR_writev,            sys_writev),         // 20
485   GENX_(__NR_access,            sys_access),         // 21
486   LINXY(__NR_pipe,              sys_pipe),           // 22
487   GENX_(__NR_select,            sys_select),         // 23
488   LINX_(__NR_sched_yield,       sys_sched_yield),    // 24
489
490   GENX_(__NR_mremap,            sys_mremap),         // 25
491   GENX_(__NR_msync,             sys_msync),          // 26
492   GENXY(__NR_mincore,           sys_mincore),        // 27
493   GENX_(__NR_madvise,           sys_madvise),        // 28
494   LINX_(__NR_shmget,            sys_shmget),         // 29
495
496   LINXY(__NR_shmat,             sys_shmat),          // 30
497   LINXY(__NR_shmctl,            sys_shmctl),         // 31
498   GENXY(__NR_dup,               sys_dup),            // 32
499   GENXY(__NR_dup2,              sys_dup2),           // 33
500   GENX_(__NR_pause,             sys_pause),          // 34
501
502   GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
503   GENXY(__NR_getitimer,         sys_getitimer),      // 36
504   GENX_(__NR_alarm,             sys_alarm),          // 37
505   GENXY(__NR_setitimer,         sys_setitimer),      // 38
506   GENX_(__NR_getpid,            sys_getpid),         // 39
507
508   LINXY(__NR_sendfile,          sys_sendfile),       // 40
509   LINXY(__NR_socket,            sys_socket),         // 41
510   LINX_(__NR_connect,           sys_connect),        // 42
511   LINXY(__NR_accept,            sys_accept),         // 43
512   LINX_(__NR_sendto,            sys_sendto),         // 44
513
514   LINXY(__NR_recvfrom,          sys_recvfrom),       // 45
515   LINX_(__NR_sendmsg,           sys_sendmsg),        // 46
516   LINXY(__NR_recvmsg,           sys_recvmsg),        // 47
517   LINX_(__NR_shutdown,          sys_shutdown),       // 48
518   LINX_(__NR_bind,              sys_bind),           // 49
519
520   LINX_(__NR_listen,            sys_listen),         // 50
521   LINXY(__NR_getsockname,       sys_getsockname),    // 51
522   LINXY(__NR_getpeername,       sys_getpeername),    // 52
523   LINXY(__NR_socketpair,        sys_socketpair),     // 53
524   LINX_(__NR_setsockopt,        sys_setsockopt),     // 54
525
526   LINXY(__NR_getsockopt,        sys_getsockopt),     // 55
527   LINX_(__NR_clone,             sys_clone),          // 56
528   GENX_(__NR_fork,              sys_fork),           // 57
529   GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
530   GENX_(__NR_execve,            sys_execve),         // 59
531
532   GENX_(__NR_exit,              sys_exit),           // 60
533   GENXY(__NR_wait4,             sys_wait4),          // 61
534   GENX_(__NR_kill,              sys_kill),           // 62
535   GENXY(__NR_uname,             sys_newuname),       // 63
536   LINX_(__NR_semget,            sys_semget),         // 64
537
538   LINX_(__NR_semop,             sys_semop),          // 65
539   LINXY(__NR_semctl,            sys_semctl),         // 66
540   LINXY(__NR_shmdt,             sys_shmdt),          // 67
541   LINX_(__NR_msgget,            sys_msgget),         // 68
542   LINX_(__NR_msgsnd,            sys_msgsnd),         // 69
543
544   LINXY(__NR_msgrcv,            sys_msgrcv),         // 70
545   LINXY(__NR_msgctl,            sys_msgctl),         // 71
546   LINXY(__NR_fcntl,             sys_fcntl),          // 72
547   GENX_(__NR_flock,             sys_flock),          // 73
548   GENX_(__NR_fsync,             sys_fsync),          // 74
549
550   GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
551   GENX_(__NR_truncate,          sys_truncate),       // 76
552   GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
553   GENXY(__NR_getdents,          sys_getdents),       // 78
554   GENXY(__NR_getcwd,            sys_getcwd),         // 79
555
556   GENX_(__NR_chdir,             sys_chdir),          // 80
557   GENX_(__NR_fchdir,            sys_fchdir),         // 81
558   GENX_(__NR_rename,            sys_rename),         // 82
559   GENX_(__NR_mkdir,             sys_mkdir),          // 83
560   GENX_(__NR_rmdir,             sys_rmdir),          // 84
561
562   GENXY(__NR_creat,             sys_creat),          // 85
563   GENX_(__NR_link,              sys_link),           // 86
564   GENX_(__NR_unlink,            sys_unlink),         // 87
565   GENX_(__NR_symlink,           sys_symlink),        // 88
566   GENX_(__NR_readlink,          sys_readlink),       // 89
567
568   GENX_(__NR_chmod,             sys_chmod),          // 90
569   GENX_(__NR_fchmod,            sys_fchmod),         // 91
570   GENX_(__NR_chown,             sys_chown),          // 92
571   GENX_(__NR_fchown,            sys_fchown),         // 93
572   GENX_(__NR_lchown,            sys_lchown),         // 94
573
574   GENX_(__NR_umask,             sys_umask),          // 95
575   GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
576   GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
577   GENXY(__NR_getrusage,         sys_getrusage),      // 98
578   LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
579
580   GENXY(__NR_times,             sys_times),          // 100
581   PLAXY(__NR_ptrace,            sys_ptrace),         // 101
582   GENX_(__NR_getuid,            sys_getuid),         // 102
583   LINXY(__NR_syslog,            sys_syslog),         // 103
584   GENX_(__NR_getgid,            sys_getgid),         // 104
585
586   GENX_(__NR_setuid,            sys_setuid),         // 105
587   GENX_(__NR_setgid,            sys_setgid),         // 106
588   GENX_(__NR_geteuid,           sys_geteuid),        // 107
589   GENX_(__NR_getegid,           sys_getegid),        // 108
590   GENX_(__NR_setpgid,           sys_setpgid),        // 109
591
592   GENX_(__NR_getppid,           sys_getppid),        // 110
593   GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
594   GENX_(__NR_setsid,            sys_setsid),         // 112
595   GENX_(__NR_setreuid,          sys_setreuid),       // 113
596   GENX_(__NR_setregid,          sys_setregid),       // 114
597
598   GENXY(__NR_getgroups,         sys_getgroups),      // 115
599   GENX_(__NR_setgroups,         sys_setgroups),      // 116
600   LINX_(__NR_setresuid,         sys_setresuid),      // 117
601   LINXY(__NR_getresuid,         sys_getresuid),      // 118
602   LINX_(__NR_setresgid,         sys_setresgid),      // 119
603
604   LINXY(__NR_getresgid,         sys_getresgid),      // 120
605   GENX_(__NR_getpgid,           sys_getpgid),        // 121
606   LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
607   LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
608   GENX_(__NR_getsid,            sys_getsid),         // 124
609
610   LINXY(__NR_capget,            sys_capget),         // 125
611   LINX_(__NR_capset,            sys_capset),         // 126
612   LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
613   LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
614   LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
615
616   LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
617   GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
618   LINX_(__NR_utime,             sys_utime),          // 132
619   GENX_(__NR_mknod,             sys_mknod),          // 133
620   //   (__NR_uselib,            sys_uselib),         // 134
621
622   LINX_(__NR_personality,       sys_personality),    // 135
623   //   (__NR_ustat,             sys_ustat),          // 136
624   GENXY(__NR_statfs,            sys_statfs),         // 137
625   GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
626   //   (__NR_sysfs,             sys_sysfs),          // 139
627
628   GENX_(__NR_getpriority,             sys_getpriority),             // 140
629   GENX_(__NR_setpriority,             sys_setpriority),             // 141
630   LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
631   LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
632   LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
633
634   LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
635   LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
636   LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
637   LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
638   GENX_(__NR_mlock,                   sys_mlock),                   // 149
639
640   GENX_(__NR_munlock,           sys_munlock),        // 150
641   GENX_(__NR_mlockall,          sys_mlockall),       // 151
642   LINX_(__NR_munlockall,        sys_munlockall),     // 152
643   LINX_(__NR_vhangup,           sys_vhangup),        // 153
644   //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
645
646   LINX_(__NR_pivot_root,        sys_pivot_root),     // 155
647   LINXY(__NR__sysctl,           sys_sysctl),         // 156
648   LINXY(__NR_prctl,             sys_prctl),          // 157
649   PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
650   LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
651
652   GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
653   GENX_(__NR_chroot,            sys_chroot),         // 161
654   GENX_(__NR_sync,              sys_sync),           // 162
655   //   (__NR_acct,              sys_acct),           // 163
656   GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
657
658   LINX_(__NR_mount,             sys_mount),          // 165
659   LINX_(__NR_umount2,           sys_umount),         // 166
660   //   (__NR_swapon,            sys_swapon),         // 167
661   //   (__NR_swapoff,           sys_swapoff),        // 168
662   //   (__NR_reboot,            sys_reboot),         // 169
663
664   GENX_(__NR_sethostname,       sys_sethostname),    // 170
665   //   (__NR_setdomainname,     sys_setdomainname),  // 171
666   GENX_(__NR_iopl,              sys_iopl),           // 172
667   LINX_(__NR_ioperm,            sys_ioperm),         // 173
668   GENX_(__NR_create_module,     sys_ni_syscall),     // 174
669
670   LINX_(__NR_init_module,       sys_init_module),    // 175
671   LINX_(__NR_delete_module,     sys_delete_module),  // 176
672   //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
673   //   (__NR_query_module,      sys_ni_syscall),     // 178
674   LINX_(__NR_quotactl,          sys_quotactl),       // 179
675
676   //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
677   //   (__NR_getpmsg,           sys_ni_syscall),     // 181
678   //   (__NR_putpmsg,           sys_ni_syscall),     // 182
679   //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
680   PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
681
682   //   (__NR_security,          sys_ni_syscall),     // 185
683   LINX_(__NR_gettid,            sys_gettid),         // 186
684   LINX_(__NR_readahead,         sys_readahead),      // 187
685   LINX_(__NR_setxattr,          sys_setxattr),       // 188
686   LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
687
688   LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
689   LINXY(__NR_getxattr,          sys_getxattr),       // 191
690   LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
691   LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
692   LINXY(__NR_listxattr,         sys_listxattr),      // 194
693
694   LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
695   LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
696   LINX_(__NR_removexattr,       sys_removexattr),    // 197
697   LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
698   LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
699
700   LINXY(__NR_tkill,             sys_tkill),             // 200
701   GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
702   LINXY(__NR_futex,             sys_futex),             // 202
703   LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
704   LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
705
706   //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
707   LINXY(__NR_io_setup,          sys_io_setup),       // 206
708   LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
709   LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
710   LINX_(__NR_io_submit,         sys_io_submit),      // 209
711
712   LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
713   //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
714   LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
715   LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
716   //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
717
718   //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
719   //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
720   GENXY(__NR_getdents64,        sys_getdents64),     // 217
721   LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
722   //   (__NR_restart_syscall,   sys_restart_syscall),// 219
723
724   LINX_(__NR_semtimedop,        sys_semtimedop),     // 220
725   PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
726   LINXY(__NR_timer_create,      sys_timer_create),   // 222
727   LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
728   LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
729
730   LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
731   LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
732   LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
733   LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
734   LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
735
736   LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
737   LINX_(__NR_exit_group,        sys_exit_group),     // 231
738   LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
739   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
740   LINXY(__NR_tgkill,            sys_tgkill),         // 234
741
742   GENX_(__NR_utimes,            sys_utimes),         // 235
743   //   (__NR_vserver,           sys_ni_syscall),     // 236
744   LINX_(__NR_mbind,             sys_mbind),          // 237
745   LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
746   LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
747
748   LINXY(__NR_mq_open,           sys_mq_open),        // 240
749   LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
750   LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
751   LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
752   LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
753
754   LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
755   //   (__NR_kexec_load,        sys_ni_syscall),     // 246
756   LINXY(__NR_waitid,            sys_waitid),         // 247
757   LINX_(__NR_add_key,           sys_add_key),        // 248
758   LINX_(__NR_request_key,       sys_request_key),    // 249
759
760   LINXY(__NR_keyctl,            sys_keyctl),         // 250
761   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
762   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
763   LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
764   LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
765
766   LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
767//   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
768   LINXY(__NR_openat,		 sys_openat),           // 257
769   LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
770   LINX_(__NR_mknodat,		 sys_mknodat),          // 259
771
772   LINX_(__NR_fchownat,		 sys_fchownat),         // 260
773   LINX_(__NR_futimesat,	 sys_futimesat),        // 261
774   LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
775   LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
776   LINX_(__NR_renameat,		 sys_renameat),         // 264
777
778   LINX_(__NR_linkat,		 sys_linkat),           // 265
779   LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
780   LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
781   LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
782   LINX_(__NR_faccessat,	 sys_faccessat),        // 269
783
784   LINXY(__NR_pselect6,		 sys_pselect6),         // 270
785   LINXY(__NR_ppoll,		 sys_ppoll),            // 271
786   LINX_(__NR_unshare,		 sys_unshare),          // 272
787   LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
788   LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
789
790   LINX_(__NR_splice,            sys_splice),           // 275
791   LINX_(__NR_tee,               sys_tee),              // 276
792   LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
793   LINXY(__NR_vmsplice,          sys_vmsplice),         // 278
794   LINXY(__NR_move_pages,        sys_move_pages),       // 279
795
796   LINX_(__NR_utimensat,         sys_utimensat),        // 280
797   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
798   LINXY(__NR_signalfd,          sys_signalfd),         // 282
799   LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
800   LINXY(__NR_eventfd,           sys_eventfd),          // 284
801
802   LINX_(__NR_fallocate,         sys_fallocate),        // 285
803   LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
804   LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
805   LINXY(__NR_accept4,           sys_accept4),          // 288
806   LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
807
808   LINXY(__NR_eventfd2,          sys_eventfd2),         // 290
809   LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
810   LINXY(__NR_dup3,              sys_dup3),             // 292
811   LINXY(__NR_pipe2,             sys_pipe2),            // 293
812   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
813
814   LINXY(__NR_preadv,            sys_preadv),           // 295
815   LINX_(__NR_pwritev,           sys_pwritev),          // 296
816   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
817   LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
818   LINXY(__NR_recvmmsg,          sys_recvmmsg),         // 299
819
820   LINXY(__NR_fanotify_init,     sys_fanotify_init),    // 300
821   LINX_(__NR_fanotify_mark,     sys_fanotify_mark),    // 301
822   LINXY(__NR_prlimit64,         sys_prlimit64),        // 302
823   LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 303
824   LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 304
825
826   LINXY(__NR_clock_adjtime,     sys_clock_adjtime),    // 305
827   LINX_(__NR_syncfs,            sys_syncfs),           // 306
828   LINXY(__NR_sendmmsg,          sys_sendmmsg),         // 307
829//   LINX_(__NR_setns,             sys_ni_syscall),       // 308
830   LINXY(__NR_getcpu,            sys_getcpu),           // 309
831
832   LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 310
833   LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 311
834   LINX_(__NR_kcmp,              sys_kcmp),             // 312
835   LINX_(__NR_finit_module,      sys_finit_module),     // 313
836//   LIN__(__NR_sched_setattr,     sys_ni_syscall),       // 314
837
838//   LIN__(__NR_sched_getattr,     sys_ni_syscall),       // 315
839   LINX_(__NR_renameat2,         sys_renameat2),        // 316
840//   LIN__(__NR_seccomp,           sys_ni_syscall),       // 317
841   LINXY(__NR_getrandom,         sys_getrandom),        // 318
842   LINXY(__NR_memfd_create,      sys_memfd_create)      // 319
843
844//   LIN__(__NR_kexec_file_load,   sys_ni_syscall),       // 320
845//   LIN__(__NR_bpf,               sys_ni_syscall)        // 321
846};
847
848SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
849{
850   const UInt syscall_table_size
851      = sizeof(syscall_table) / sizeof(syscall_table[0]);
852
853   /* Is it in the contiguous initial section of the table? */
854   if (sysno < syscall_table_size) {
855      SyscallTableEntry* sys = &syscall_table[sysno];
856      if (sys->before == NULL)
857         return NULL; /* no entry */
858      else
859         return sys;
860   }
861
862   /* Can't find a wrapper */
863   return NULL;
864}
865
866#endif // defined(VGP_amd64_linux)
867
868/*--------------------------------------------------------------------*/
869/*--- end                                                          ---*/
870/*--------------------------------------------------------------------*/
871