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