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