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