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