• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff.      syswrap-amd64-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2000-2011 Nicholas Nethercote
11       njn@valgrind.org
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 #if defined(VGP_amd64_linux)
32 
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
37 #include "pub_core_threadstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_debuglog.h"
40 #include "pub_core_options.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcprint.h"
44 #include "pub_core_libcproc.h"
45 #include "pub_core_libcsignal.h"
46 #include "pub_core_scheduler.h"
47 #include "pub_core_sigframe.h"
48 #include "pub_core_signals.h"
49 #include "pub_core_syscall.h"
50 #include "pub_core_syswrap.h"
51 #include "pub_core_tooliface.h"
52 #include "pub_core_stacks.h"        // VG_(register_stack)
53 
54 #include "priv_types_n_macros.h"
55 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
56 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
57 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
58 #include "priv_syswrap-main.h"
59 
60 
61 /* ---------------------------------------------------------------------
62    clone() handling
63    ------------------------------------------------------------------ */
64 
65 /* Call f(arg1), but first switch stacks, using 'stack' as the new
66    stack, and use 'retaddr' as f's return-to address.  Also, clear all
67    the integer registers before entering f.  */
68 __attribute__((noreturn))
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  */
do_clone(ThreadId ptid,ULong flags,Addr rsp,Long * parent_tidptr,Long * child_tidptr,Addr tlsaddr)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 
VG_(cleanup_thread)331 void VG_(cleanup_thread) ( ThreadArchState *arch )
332 {
333 }
334 
setup_child(ThreadArchState * child,ThreadArchState * parent)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 
PRE(sys_clone)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 
PRE(sys_rt_sigreturn)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 
PRE(sys_arch_prctl)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.
PRE(sys_ptrace)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 
POST(sys_ptrace)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 
PRE(sys_socket)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 }
POST(sys_socket)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 
PRE(sys_setsockopt)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 
PRE(sys_getsockopt)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 }
POST(sys_getsockopt)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 
PRE(sys_connect)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 
PRE(sys_accept)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 }
POST(sys_accept)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 
PRE(sys_accept4)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 }
POST(sys_accept4)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 
PRE(sys_sendto)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 
PRE(sys_recvfrom)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 }
POST(sys_recvfrom)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 
PRE(sys_sendmsg)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 
PRE(sys_recvmsg)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 }
POST(sys_recvmsg)760 POST(sys_recvmsg)
761 {
762    ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
763 }
764 
PRE(sys_shutdown)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 
PRE(sys_bind)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 
PRE(sys_listen)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 
PRE(sys_getsockname)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 }
POST(sys_getsockname)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 
PRE(sys_getpeername)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 }
POST(sys_getpeername)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 
PRE(sys_socketpair)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 }
POST(sys_socketpair)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 
PRE(sys_semget)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 
PRE(sys_semop)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 
PRE(sys_semtimedop)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 
PRE(sys_semctl)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 }
POST(sys_semctl)883 POST(sys_semctl)
884 {
885    ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
886 }
887 
PRE(sys_msgget)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 
PRE(sys_msgsnd)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 
PRE(sys_msgrcv)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 }
POST(sys_msgrcv)914 POST(sys_msgrcv)
915 {
916    ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
917 }
918 
PRE(sys_msgctl)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 }
POST(sys_msgctl)926 POST(sys_msgctl)
927 {
928    ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
929 }
930 
PRE(sys_shmget)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 
PRE(wrap_sys_shmat)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 }
POST(wrap_sys_shmat)949 POST(wrap_sys_shmat)
950 {
951    ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
952 }
953 
PRE(sys_shmdt)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 }
POST(sys_shmdt)961 POST(sys_shmdt)
962 {
963    ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
964 }
965 
PRE(sys_shmctl)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 }
POST(sys_shmctl)973 POST(sys_shmctl)
974 {
975    ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
976 }
977 
PRE(sys_fadvise64)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 
PRE(sys_mmap)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 
PRE(sys_syscall184)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 
POST(sys_syscall184)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    GENXY(__NR_mincore,           sys_mincore),        // 27
1089    GENX_(__NR_madvise,           sys_madvise),        // 28
1090    PLAX_(__NR_shmget,            sys_shmget),         // 29
1091 
1092    PLAXY(__NR_shmat,             wrap_sys_shmat),     // 30
1093    PLAXY(__NR_shmctl,            sys_shmctl),         // 31
1094    GENXY(__NR_dup,               sys_dup),            // 32
1095    GENXY(__NR_dup2,              sys_dup2),           // 33
1096    GENX_(__NR_pause,             sys_pause),          // 34
1097 
1098    GENXY(__NR_nanosleep,         sys_nanosleep),      // 35
1099    GENXY(__NR_getitimer,         sys_getitimer),      // 36
1100    GENX_(__NR_alarm,             sys_alarm),          // 37
1101    GENXY(__NR_setitimer,         sys_setitimer),      // 38
1102    GENX_(__NR_getpid,            sys_getpid),         // 39
1103 
1104    LINXY(__NR_sendfile,          sys_sendfile),       // 40
1105    PLAXY(__NR_socket,            sys_socket),         // 41
1106    PLAX_(__NR_connect,           sys_connect),        // 42
1107    PLAXY(__NR_accept,            sys_accept),         // 43
1108    PLAX_(__NR_sendto,            sys_sendto),         // 44
1109 
1110    PLAXY(__NR_recvfrom,          sys_recvfrom),       // 45
1111    PLAX_(__NR_sendmsg,           sys_sendmsg),        // 46
1112    PLAXY(__NR_recvmsg,           sys_recvmsg),        // 47
1113    PLAX_(__NR_shutdown,          sys_shutdown),       // 48
1114    PLAX_(__NR_bind,              sys_bind),           // 49
1115 
1116    PLAX_(__NR_listen,            sys_listen),         // 50
1117    PLAXY(__NR_getsockname,       sys_getsockname),    // 51
1118    PLAXY(__NR_getpeername,       sys_getpeername),    // 52
1119    PLAXY(__NR_socketpair,        sys_socketpair),     // 53
1120    PLAX_(__NR_setsockopt,        sys_setsockopt),     // 54
1121 
1122    PLAXY(__NR_getsockopt,        sys_getsockopt),     // 55
1123    PLAX_(__NR_clone,             sys_clone),          // 56
1124    GENX_(__NR_fork,              sys_fork),           // 57
1125    GENX_(__NR_vfork,             sys_fork),           // 58 treat as fork
1126    GENX_(__NR_execve,            sys_execve),         // 59
1127 
1128    GENX_(__NR_exit,              sys_exit),           // 60
1129    GENXY(__NR_wait4,             sys_wait4),          // 61
1130    GENX_(__NR_kill,              sys_kill),           // 62
1131    GENXY(__NR_uname,             sys_newuname),       // 63
1132    PLAX_(__NR_semget,            sys_semget),         // 64
1133 
1134    PLAX_(__NR_semop,             sys_semop),          // 65
1135    PLAXY(__NR_semctl,            sys_semctl),         // 66
1136    PLAXY(__NR_shmdt,             sys_shmdt),          // 67
1137    PLAX_(__NR_msgget,            sys_msgget),         // 68
1138    PLAX_(__NR_msgsnd,            sys_msgsnd),         // 69
1139 
1140    PLAXY(__NR_msgrcv,            sys_msgrcv),         // 70
1141    PLAXY(__NR_msgctl,            sys_msgctl),         // 71
1142    LINXY(__NR_fcntl,             sys_fcntl),          // 72
1143    GENX_(__NR_flock,             sys_flock),          // 73
1144    GENX_(__NR_fsync,             sys_fsync),          // 74
1145 
1146    GENX_(__NR_fdatasync,         sys_fdatasync),      // 75
1147    GENX_(__NR_truncate,          sys_truncate),       // 76
1148    GENX_(__NR_ftruncate,         sys_ftruncate),      // 77
1149    GENXY(__NR_getdents,          sys_getdents),       // 78
1150    GENXY(__NR_getcwd,            sys_getcwd),         // 79
1151 
1152    GENX_(__NR_chdir,             sys_chdir),          // 80
1153    GENX_(__NR_fchdir,            sys_fchdir),         // 81
1154    GENX_(__NR_rename,            sys_rename),         // 82
1155    GENX_(__NR_mkdir,             sys_mkdir),          // 83
1156    GENX_(__NR_rmdir,             sys_rmdir),          // 84
1157 
1158    GENXY(__NR_creat,             sys_creat),          // 85
1159    GENX_(__NR_link,              sys_link),           // 86
1160    GENX_(__NR_unlink,            sys_unlink),         // 87
1161    GENX_(__NR_symlink,           sys_symlink),        // 88
1162    GENX_(__NR_readlink,          sys_readlink),       // 89
1163 
1164    GENX_(__NR_chmod,             sys_chmod),          // 90
1165    GENX_(__NR_fchmod,            sys_fchmod),         // 91
1166    GENX_(__NR_chown,             sys_chown),          // 92
1167    GENX_(__NR_fchown,            sys_fchown),         // 93
1168    GENX_(__NR_lchown,            sys_lchown),         // 94
1169 
1170    GENX_(__NR_umask,             sys_umask),          // 95
1171    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 96
1172    GENXY(__NR_getrlimit,         sys_getrlimit),      // 97
1173    GENXY(__NR_getrusage,         sys_getrusage),      // 98
1174    LINXY(__NR_sysinfo,           sys_sysinfo),        // 99
1175 
1176    GENXY(__NR_times,             sys_times),          // 100
1177    PLAXY(__NR_ptrace,            sys_ptrace),         // 101
1178    GENX_(__NR_getuid,            sys_getuid),         // 102
1179    LINXY(__NR_syslog,            sys_syslog),         // 103
1180    GENX_(__NR_getgid,            sys_getgid),         // 104
1181 
1182    GENX_(__NR_setuid,            sys_setuid),         // 105
1183    GENX_(__NR_setgid,            sys_setgid),         // 106
1184    GENX_(__NR_geteuid,           sys_geteuid),        // 107
1185    GENX_(__NR_getegid,           sys_getegid),        // 108
1186    GENX_(__NR_setpgid,           sys_setpgid),        // 109
1187 
1188    GENX_(__NR_getppid,           sys_getppid),        // 110
1189    GENX_(__NR_getpgrp,           sys_getpgrp),        // 111
1190    GENX_(__NR_setsid,            sys_setsid),         // 112
1191    GENX_(__NR_setreuid,          sys_setreuid),       // 113
1192    GENX_(__NR_setregid,          sys_setregid),       // 114
1193 
1194    GENXY(__NR_getgroups,         sys_getgroups),      // 115
1195    GENX_(__NR_setgroups,         sys_setgroups),      // 116
1196    LINX_(__NR_setresuid,         sys_setresuid),      // 117
1197    LINXY(__NR_getresuid,         sys_getresuid),      // 118
1198    LINX_(__NR_setresgid,         sys_setresgid),      // 119
1199 
1200    LINXY(__NR_getresgid,         sys_getresgid),      // 120
1201    GENX_(__NR_getpgid,           sys_getpgid),        // 121
1202    LINX_(__NR_setfsuid,          sys_setfsuid),       // 122
1203    LINX_(__NR_setfsgid,          sys_setfsgid),       // 123
1204    GENX_(__NR_getsid,            sys_getsid),         // 124
1205 
1206    LINXY(__NR_capget,            sys_capget),         // 125
1207    LINX_(__NR_capset,            sys_capset),         // 126
1208    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 127
1209    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 128
1210    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 129
1211 
1212    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 130
1213    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 131
1214    LINX_(__NR_utime,             sys_utime),          // 132
1215    GENX_(__NR_mknod,             sys_mknod),          // 133
1216    //   (__NR_uselib,            sys_uselib),         // 134
1217 
1218    LINX_(__NR_personality,       sys_personality),    // 135
1219    //   (__NR_ustat,             sys_ustat),          // 136
1220    GENXY(__NR_statfs,            sys_statfs),         // 137
1221    GENXY(__NR_fstatfs,           sys_fstatfs),        // 138
1222    //   (__NR_sysfs,             sys_sysfs),          // 139
1223 
1224    GENX_(__NR_getpriority,             sys_getpriority),             // 140
1225    GENX_(__NR_setpriority,             sys_setpriority),             // 141
1226    LINXY(__NR_sched_setparam,          sys_sched_setparam),          // 142
1227    LINXY(__NR_sched_getparam,          sys_sched_getparam),          // 143
1228    LINX_(__NR_sched_setscheduler,      sys_sched_setscheduler),      // 144
1229 
1230    LINX_(__NR_sched_getscheduler,      sys_sched_getscheduler),      // 145
1231    LINX_(__NR_sched_get_priority_max,  sys_sched_get_priority_max),  // 146
1232    LINX_(__NR_sched_get_priority_min,  sys_sched_get_priority_min),  // 147
1233    LINXY(__NR_sched_rr_get_interval,   sys_sched_rr_get_interval),   // 148
1234    GENX_(__NR_mlock,                   sys_mlock),                   // 149
1235 
1236    GENX_(__NR_munlock,           sys_munlock),        // 150
1237    GENX_(__NR_mlockall,          sys_mlockall),       // 151
1238    LINX_(__NR_munlockall,        sys_munlockall),     // 152
1239    LINX_(__NR_vhangup,           sys_vhangup),        // 153
1240    //   (__NR_modify_ldt,        sys_modify_ldt),     // 154
1241 
1242    //   (__NR_pivot_root,        sys_pivot_root),     // 155
1243    LINXY(__NR__sysctl,           sys_sysctl),         // 156
1244    LINXY(__NR_prctl,             sys_prctl),          // 157
1245    PLAX_(__NR_arch_prctl,	 sys_arch_prctl),     // 158
1246    LINXY(__NR_adjtimex,          sys_adjtimex),       // 159
1247 
1248    GENX_(__NR_setrlimit,         sys_setrlimit),      // 160
1249    GENX_(__NR_chroot,            sys_chroot),         // 161
1250    GENX_(__NR_sync,              sys_sync),           // 162
1251    //   (__NR_acct,              sys_acct),           // 163
1252    GENX_(__NR_settimeofday,      sys_settimeofday),   // 164
1253 
1254    LINX_(__NR_mount,             sys_mount),          // 165
1255    LINX_(__NR_umount2,           sys_umount),         // 166
1256    //   (__NR_swapon,            sys_swapon),         // 167
1257    //   (__NR_swapoff,           sys_swapoff),        // 168
1258    //   (__NR_reboot,            sys_reboot),         // 169
1259 
1260    //   (__NR_sethostname,       sys_sethostname),    // 170
1261    //   (__NR_setdomainname,     sys_setdomainname),  // 171
1262    GENX_(__NR_iopl,              sys_iopl),           // 172
1263    LINX_(__NR_ioperm,            sys_ioperm),         // 173
1264    GENX_(__NR_create_module,     sys_ni_syscall),     // 174
1265 
1266    LINX_(__NR_init_module,       sys_init_module),    // 175
1267    LINX_(__NR_delete_module,     sys_delete_module),  // 176
1268    //   (__NR_get_kernel_syms,   sys_ni_syscall),     // 177
1269    //   (__NR_query_module,      sys_ni_syscall),     // 178
1270    LINX_(__NR_quotactl,          sys_quotactl),       // 179
1271 
1272    //   (__NR_nfsservctl,        sys_nfsservctl),     // 180
1273    //   (__NR_getpmsg,           sys_ni_syscall),     // 181
1274    //   (__NR_putpmsg,           sys_ni_syscall),     // 182
1275    //   (__NR_afs_syscall,       sys_ni_syscall),     // 183
1276    PLAXY(184,                    sys_syscall184),     // 184 // sys_bproc?
1277 
1278    //   (__NR_security,          sys_ni_syscall),     // 185
1279    LINX_(__NR_gettid,            sys_gettid),         // 186
1280    LINX_(__NR_readahead,         sys_readahead),      // 187
1281    LINX_(__NR_setxattr,          sys_setxattr),       // 188
1282    LINX_(__NR_lsetxattr,         sys_lsetxattr),      // 189
1283 
1284    LINX_(__NR_fsetxattr,         sys_fsetxattr),      // 190
1285    LINXY(__NR_getxattr,          sys_getxattr),       // 191
1286    LINXY(__NR_lgetxattr,         sys_lgetxattr),      // 192
1287    LINXY(__NR_fgetxattr,         sys_fgetxattr),      // 193
1288    LINXY(__NR_listxattr,         sys_listxattr),      // 194
1289 
1290    LINXY(__NR_llistxattr,        sys_llistxattr),     // 195
1291    LINXY(__NR_flistxattr,        sys_flistxattr),     // 196
1292    LINX_(__NR_removexattr,       sys_removexattr),    // 197
1293    LINX_(__NR_lremovexattr,      sys_lremovexattr),   // 198
1294    LINX_(__NR_fremovexattr,      sys_fremovexattr),   // 199
1295 
1296    LINXY(__NR_tkill,             sys_tkill),             // 200
1297    GENXY(__NR_time,              sys_time), /*was sys_time64*/ // 201
1298    LINXY(__NR_futex,             sys_futex),             // 202
1299    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
1300    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
1301 
1302    //   (__NR_set_thread_area,   sys_ni_syscall),     // 205
1303    LINXY(__NR_io_setup,          sys_io_setup),       // 206
1304    LINX_(__NR_io_destroy,        sys_io_destroy),     // 207
1305    LINXY(__NR_io_getevents,      sys_io_getevents),   // 208
1306    LINX_(__NR_io_submit,         sys_io_submit),      // 209
1307 
1308    LINXY(__NR_io_cancel,         sys_io_cancel),      // 210
1309    //   (__NR_get_thread_area,   sys_ni_syscall),     // 211
1310    LINXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 212
1311    LINXY(__NR_epoll_create,      sys_epoll_create),   // 213
1312    //   (__NR_epoll_ctl_old,     sys_ni_syscall),     // 214
1313 
1314    //   (__NR_epoll_wait_old,    sys_ni_syscall),     // 215
1315    //   (__NR_remap_file_pages,  sys_remap_file_pages)// 216
1316    GENXY(__NR_getdents64,        sys_getdents64),     // 217
1317    LINX_(__NR_set_tid_address,   sys_set_tid_address),// 218
1318    //   (__NR_restart_syscall,   sys_restart_syscall),// 219
1319 
1320    PLAX_(__NR_semtimedop,        sys_semtimedop),     // 220
1321    PLAX_(__NR_fadvise64,         sys_fadvise64),      // 221
1322    LINXY(__NR_timer_create,      sys_timer_create),   // 222
1323    LINXY(__NR_timer_settime,     sys_timer_settime),  // 223
1324    LINXY(__NR_timer_gettime,     sys_timer_gettime),  // 224
1325 
1326    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun), // 225
1327    LINX_(__NR_timer_delete,      sys_timer_delete),   // 226
1328    LINX_(__NR_clock_settime,     sys_clock_settime),  // 227
1329    LINXY(__NR_clock_gettime,     sys_clock_gettime),  // 228
1330    LINXY(__NR_clock_getres,      sys_clock_getres),   // 229
1331 
1332    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// 230
1333    LINX_(__NR_exit_group,        sys_exit_group),     // 231
1334    LINXY(__NR_epoll_wait,        sys_epoll_wait),     // 232
1335    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),      // 233
1336    LINXY(__NR_tgkill,            sys_tgkill),         // 234
1337 
1338    GENX_(__NR_utimes,            sys_utimes),         // 235
1339    //   (__NR_vserver,           sys_ni_syscall),     // 236
1340    LINX_(__NR_mbind,             sys_mbind),          // 237
1341    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 238
1342    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 239
1343 
1344    LINXY(__NR_mq_open,           sys_mq_open),        // 240
1345    LINX_(__NR_mq_unlink,         sys_mq_unlink),      // 241
1346    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // 242
1347    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// 243
1348    LINX_(__NR_mq_notify,         sys_mq_notify),      // 244
1349 
1350    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // 245
1351    //   (__NR_kexec_load,        sys_ni_syscall),     // 246
1352    LINXY(__NR_waitid,            sys_waitid),         // 247
1353    LINX_(__NR_add_key,           sys_add_key),        // 248
1354    LINX_(__NR_request_key,       sys_request_key),    // 249
1355 
1356    LINXY(__NR_keyctl,            sys_keyctl),         // 250
1357    LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 251
1358    LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 252
1359    LINX_(__NR_inotify_init,	 sys_inotify_init),   // 253
1360    LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
1361 
1362    LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 255
1363 //   LINX_(__NR_migrate_pages,	 sys_migrate_pages),    // 256
1364    LINXY(__NR_openat,		 sys_openat),           // 257
1365    LINX_(__NR_mkdirat,		 sys_mkdirat),          // 258
1366    LINX_(__NR_mknodat,		 sys_mknodat),          // 259
1367 
1368    LINX_(__NR_fchownat,		 sys_fchownat),         // 260
1369    LINX_(__NR_futimesat,	 sys_futimesat),        // 261
1370    LINXY(__NR_newfstatat,	 sys_newfstatat),       // 262
1371    LINX_(__NR_unlinkat,		 sys_unlinkat),         // 263
1372    LINX_(__NR_renameat,		 sys_renameat),         // 264
1373 
1374    LINX_(__NR_linkat,		 sys_linkat),           // 265
1375    LINX_(__NR_symlinkat,	 sys_symlinkat),        // 266
1376    LINX_(__NR_readlinkat,	 sys_readlinkat),       // 267
1377    LINX_(__NR_fchmodat,		 sys_fchmodat),         // 268
1378    LINX_(__NR_faccessat,	 sys_faccessat),        // 269
1379 
1380    LINX_(__NR_pselect6,		 sys_pselect6),         // 270
1381    LINXY(__NR_ppoll,		 sys_ppoll),            // 271
1382 //   LINX_(__NR_unshare,		 sys_unshare),          // 272
1383    LINX_(__NR_set_robust_list,	 sys_set_robust_list),  // 273
1384    LINXY(__NR_get_robust_list,	 sys_get_robust_list),  // 274
1385 
1386    LINX_(__NR_splice,            sys_splice),           // 275
1387 //   LINX_(__NR_tee,               sys_ni_syscall),       // 276
1388    LINX_(__NR_sync_file_range,   sys_sync_file_range),  // 277
1389 //   LINX_(__NR_vmsplice,          sys_ni_syscall),       // 278
1390 //   LINX_(__NR_move_pages,        sys_ni_syscall),       // 279
1391 
1392    LINX_(__NR_utimensat,         sys_utimensat),        // 280
1393    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 281
1394    LINXY(__NR_signalfd,          sys_signalfd),         // 282
1395    LINXY(__NR_timerfd_create,    sys_timerfd_create),   // 283
1396    LINX_(__NR_eventfd,           sys_eventfd),          // 284
1397 
1398    LINX_(__NR_fallocate,         sys_fallocate),        // 285
1399    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 286
1400    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 287
1401    PLAXY(__NR_accept4,           sys_accept4),          // 288
1402    LINXY(__NR_signalfd4,         sys_signalfd4),        // 289
1403 
1404    LINX_(__NR_eventfd2,          sys_eventfd2),         // 290
1405    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 291
1406    LINXY(__NR_dup3,              sys_dup3),             // 292
1407    LINXY(__NR_pipe2,             sys_pipe2),            // 293
1408    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 294
1409 
1410    LINXY(__NR_preadv,            sys_preadv),           // 295
1411    LINX_(__NR_pwritev,           sys_pwritev),          // 296
1412    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
1413    LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 298
1414 //   LINX_(__NR_recvmmsg,          sys_ni_syscall),       // 299
1415 
1416 //   LINX_(__NR_fanotify_init,     sys_ni_syscall),       // 300
1417 //   LINX_(__NR_fanotify_mark,     sys_ni_syscall),       // 301
1418    LINXY(__NR_prlimit64,         sys_prlimit64)         // 302
1419 //   LINX_(__NR_name_to_handle_at, sys_ni_syscall),       // 303
1420 //   LINX_(__NR_open_by_handle_at, sys_ni_syscall),       // 304
1421 
1422 //   LINX_(__NR_clock_adjtime,     sys_ni_syscall),       // 305
1423 //   LINX_(__NR_syncfs,            sys_ni_syscall),       // 306
1424 //   LINX_(__NR_sendmmsg,          sys_ni_syscall),       // 307
1425 //   LINX_(__NR_setns,             sys_ni_syscall),       // 308
1426 };
1427 
ML_(get_linux_syscall_entry)1428 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1429 {
1430    const UInt syscall_table_size
1431       = sizeof(syscall_table) / sizeof(syscall_table[0]);
1432 
1433    /* Is it in the contiguous initial section of the table? */
1434    if (sysno < syscall_table_size) {
1435       SyscallTableEntry* sys = &syscall_table[sysno];
1436       if (sys->before == NULL)
1437          return NULL; /* no entry */
1438       else
1439          return sys;
1440    }
1441 
1442    /* Can't find a wrapper */
1443    return NULL;
1444 }
1445 
1446 #endif // defined(VGP_amd64_linux)
1447 
1448 /*--------------------------------------------------------------------*/
1449 /*--- end                                                          ---*/
1450 /*--------------------------------------------------------------------*/
1451