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