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