2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-amd64-linux.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2010 Nicholas Nethercote
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
31 #if defined(VGP_amd64_linux)
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)
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"
61 /* ---------------------------------------------------------------------
63 ------------------------------------------------------------------ */
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,
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
100 " popq %rdi\n" // arg1 to correct arg reg
101 " ret\n" // jump to f
102 " ud2\n" // should never get here
107 Perform a clone system call. clone is strange because it has
108 fork()-like return-twice semantics, so it needs special
113 int (*fn)(void*) in %rdi
114 void* child_stack in %rsi
117 pid_t* child_tid in %r8
118 pid_t* parent_tid in %r9
119 void* tls_ptr at 8(%rsp)
121 System call requires:
123 int $__NR_clone in %rax
125 void* child_stack in %rsi
126 pid_t* parent_tid in %rdx
127 pid_t* child_tid in %r10
130 Returns a Long encoded in the linux-amd64 way, not a SysRes.
132 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
133 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
136 Long do_syscall_clone_amd64_linux ( Word (*fn)(void *),
142 vki_modify_ldt_t * );
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
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
159 " syscall\n" // clone()
161 " testq %rax, %rax\n" // child if retval == 0
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
170 " movq %rax, %rdi\n" // arg1: return value from fn
171 " movq $"__NR_EXIT", %rax\n"
178 "1:\n" // PARENT or ERROR
187 // forward declaration
188 static void setup_child ( ThreadArchState*, ThreadArchState* );
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
194 2. initialize the thread's new VCPU state
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
200 static SysRes do_clone ( ThreadId ptid,
201 ULong flags, Addr rsp,
206 static const Bool debug = False;
208 ThreadId ctid = VG_(alloc_ThreadState)();
209 ThreadState* ptst = VG_(get_ThreadState)(ptid);
210 ThreadState* ctst = VG_(get_ThreadState)(ctid);
215 vki_sigset_t blockall, savedmask;
217 VG_(sigfillset)(&blockall);
219 vg_assert(VG_(is_running_thread)(ptid));
220 vg_assert(VG_(is_valid_tid)(ctid));
222 stack = (UWord*)ML_(allocstack)(ctid);
224 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
228 /* Copy register state
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.
234 The parent gets the child's new tid returned from clone, but the
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.
240 setup_child( &ctst->arch, &ptst->arch );
242 /* Make sys_clone appear to have returned Success(0) in the
244 ctst->arch.vex.guest_RAX = 0;
247 ctst->arch.vex.guest_RSP = rsp;
249 ctst->os_state.parent = ptid;
251 /* inherit signal mask */
252 ctst->sig_mask = ptst->sig_mask;
253 ctst->tmp_sig_mask = ptst->sig_mask;
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.
264 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
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;
276 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
279 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
280 ctid, seg->start, VG_PGROUNDUP(rsp));
282 VG_(message)(Vg_UserMsg,
283 "!? New thread %d starts with RSP(%#lx) unmapped\n",
285 ctst->client_stack_szB = 0;
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 );
294 if (flags & VKI_CLONE_SETTLS) {
296 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
297 ctst->arch.vex.guest_FS_ZERO = tlsaddr;
300 flags &= ~VKI_CLONE_SETTLS;
302 /* start the thread with everything blocked */
303 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
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
310 res = VG_(mk_SysRes_amd64_linux)( rax );
312 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
315 if (sr_isError(res)) {
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 );
327 /* ---------------------------------------------------------------------
329 ------------------------------------------------------------------ */
331 void VG_(cleanup_thread) ( ThreadArchState *arch )
335 void setup_child ( /*OUT*/ ThreadArchState *child,
336 /*IN*/ ThreadArchState *parent )
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;
345 /* ---------------------------------------------------------------------
346 PRE/POST wrappers for AMD64/Linux-specific syscalls
347 ------------------------------------------------------------------ */
349 #define PRE(name) DEFN_PRE_TEMPLATE(amd64_linux, name)
350 #define POST(name) DEFN_POST_TEMPLATE(amd64_linux, name)
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
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);
399 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
400 PRE_REG_READ5(int, "clone",
401 unsigned long, flags,
403 int *, parent_tidptr,
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 );
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 );
424 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
425 SET_STATUS_Failure( VKI_EINVAL );
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(
437 (Addr)ARG2, /* child ESP */
438 (Long *)ARG3, /* parent_tidptr */
439 (Long *)ARG4, /* child_tidptr */
440 (Addr)ARG5)); /* set_tls */
443 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
444 /* FALLTHROUGH - assume vfork == fork */
445 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
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 */
456 /* should we just ENOSYS? */
457 VG_(message)(Vg_UserMsg,
458 "Unsupported clone() flags: 0x%lx\n", ARG1);
459 VG_(message)(Vg_UserMsg,
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");
468 ("Valgrind does not support general clone().");
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));
477 /* Thread creation was successful; let the child have the chance
479 *flags |= SfYieldAfter;
483 PRE(sys_rt_sigreturn)
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. */
496 PRINT("sys_rt_sigreturn ( )");
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));
502 /* Adjust RSP to point to start of frame; skip back up over handler
504 tst = VG_(get_ThreadState)(tid);
505 tst->arch.vex.guest_RSP -= sizeof(Addr);
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
510 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
512 /* Restore register state from frame and remove it, as
514 VG_(sigframe_destroy)(tid, True);
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);
521 /* Check to see if any signals arose as a result of this. */
522 *flags |= SfPollAfter;
528 PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
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));
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...
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;
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));
552 VG_(core_panic)("Unsupported arch_prtctl option");
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 );
561 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
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.
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);
573 case VKI_PTRACE_PEEKTEXT:
574 case VKI_PTRACE_PEEKDATA:
575 case VKI_PTRACE_PEEKUSR:
576 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
579 case VKI_PTRACE_GETREGS:
580 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
581 sizeof (struct vki_user_regs_struct));
583 case VKI_PTRACE_GETFPREGS:
584 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
585 sizeof (struct vki_user_i387_struct));
587 case VKI_PTRACE_SETREGS:
588 PRE_MEM_READ( "ptrace(setregs)", ARG4,
589 sizeof (struct vki_user_regs_struct));
591 case VKI_PTRACE_SETFPREGS:
592 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
593 sizeof (struct vki_user_i387_struct));
595 case VKI_PTRACE_GETEVENTMSG:
596 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
598 case VKI_PTRACE_GETSIGINFO:
599 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
601 case VKI_PTRACE_SETSIGINFO:
602 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
612 case VKI_PTRACE_PEEKTEXT:
613 case VKI_PTRACE_PEEKDATA:
614 case VKI_PTRACE_PEEKUSR:
615 POST_MEM_WRITE( ARG4, sizeof (long));
617 case VKI_PTRACE_GETREGS:
618 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
620 case VKI_PTRACE_GETFPREGS:
621 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
623 case VKI_PTRACE_GETEVENTMSG:
624 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
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.
630 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
639 PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
640 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
646 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
647 SET_STATUS_from_SysRes(r);
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);
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);
670 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
671 ARG1,ARG2,ARG3,ARG4,ARG5);
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);
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);
695 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
697 SET_STATUS_from_SysRes(r);
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);
712 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
714 SET_STATUS_from_SysRes(r);
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,
724 const struct sockaddr *, to, int, tolen);
725 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
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);
740 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
741 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
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);
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);
762 ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
767 *flags |= SfMayBlock;
768 PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
769 PRE_REG_READ2(int, "shutdown", int, s, int, how);
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);
782 PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
783 PRE_REG_READ2(long, "listen", int, s, int, backlog);
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);
793 POST(sys_getsockname)
796 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
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);
807 POST(sys_getpeername)
810 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
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);
824 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
825 ARG1,ARG2,ARG3,ARG4);
830 PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
831 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
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);
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);
855 switch (ARG3 & ~VKI_IPC_64) {
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);
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);
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);
876 PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
877 PRE_REG_READ3(long, "semctl",
878 int, semid, int, semnum, int, cmd);
881 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
885 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
890 PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
891 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
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;
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;
916 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
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);
928 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
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);
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);
945 SET_STATUS_Failure( VKI_EINVAL );
947 ARG2 = arg2tmp; // used in POST
951 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
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 );
963 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
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);
975 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
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);
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);
996 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
997 SET_STATUS_from_SysRes(r);
1001 /* ---------------------------------------------------------------
1002 PRE/POST wrappers for AMD64/Linux-variant specific syscalls
1003 ------------------------------------------------------------ */
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. */
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 );
1019 err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
1022 SET_STATUS_Failure( err );
1025 /* Let it go through. */
1026 *flags |= SfMayBlock; /* who knows? play safe. */
1029 POST(sys_syscall184)
1031 ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
1039 /* ---------------------------------------------------------------------
1040 The AMD64/Linux syscall table
1041 ------------------------------------------------------------------ */
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)
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).
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.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1416 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1418 const UInt syscall_table_size
1419 = sizeof(syscall_table) / sizeof(syscall_table[0]);
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 */
1430 /* Can't find a wrapper */
1434 #endif // defined(VGP_amd64_linux)
1436 /*--------------------------------------------------------------------*/
1438 /*--------------------------------------------------------------------*/