1 2 /*--------------------------------------------------------------------*/ 3 /*--- Platform-specific syscalls stuff. syswrap-ppc32-linux.c ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2005-2012 Nicholas Nethercote <njn (at) valgrind.org> 11 Copyright (C) 2005-2012 Cerion Armour-Brown <cerion (at) open-works.co.uk> 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_ppc32_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_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_options.h" 46 #include "pub_core_scheduler.h" 47 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)() 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-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 // r3 = stack 73 // r4 = retaddr 74 // r5 = f 75 // r6 = 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 " mr %r1,%r3\n\t" // stack to %sp 81 " mtlr %r4\n\t" // retaddr to %lr 82 " mtctr %r5\n\t" // f to count reg 83 " mr %r3,%r6\n\t" // arg1 to %r3 84 " li 0,0\n\t" // zero all GP regs 85 " li 4,0\n\t" 86 " li 5,0\n\t" 87 " li 6,0\n\t" 88 " li 7,0\n\t" 89 " li 8,0\n\t" 90 " li 9,0\n\t" 91 " li 10,0\n\t" 92 " li 11,0\n\t" 93 " li 12,0\n\t" 94 " li 13,0\n\t" 95 " li 14,0\n\t" 96 " li 15,0\n\t" 97 " li 16,0\n\t" 98 " li 17,0\n\t" 99 " li 18,0\n\t" 100 " li 19,0\n\t" 101 " li 20,0\n\t" 102 " li 21,0\n\t" 103 " li 22,0\n\t" 104 " li 23,0\n\t" 105 " li 24,0\n\t" 106 " li 25,0\n\t" 107 " li 26,0\n\t" 108 " li 27,0\n\t" 109 " li 28,0\n\t" 110 " li 29,0\n\t" 111 " li 30,0\n\t" 112 " li 31,0\n\t" 113 " mtxer 0\n\t" // CAB: Need this? 114 " mtcr 0\n\t" // CAB: Need this? 115 " bctr\n\t" // jump to dst 116 " trap\n" // should never get here 117 ".previous\n" 118 ); 119 120 121 /* 122 Perform a clone system call. clone is strange because it has 123 fork()-like return-twice semantics, so it needs special 124 handling here. 125 126 Upon entry, we have: 127 128 int (fn)(void*) in r3 129 void* child_stack in r4 130 int flags in r5 131 void* arg in r6 132 pid_t* child_tid in r7 133 pid_t* parent_tid in r8 134 void* ??? in r9 135 136 System call requires: 137 138 int $__NR_clone in r0 (sc number) 139 int flags in r3 (sc arg1) 140 void* child_stack in r4 (sc arg2) 141 pid_t* parent_tid in r5 (sc arg3) 142 ?? child_tls in r6 (sc arg4) 143 pid_t* child_tid in r7 (sc arg5) 144 void* ??? in r8 (sc arg6) 145 146 Returns an Int encoded in the linux-ppc32 way, not a SysRes. 147 */ 148 #define __NR_CLONE VG_STRINGIFY(__NR_clone) 149 #define __NR_EXIT VG_STRINGIFY(__NR_exit) 150 151 extern 152 ULong do_syscall_clone_ppc32_linux ( Word (*fn)(void *), 153 void* stack, 154 Int flags, 155 void* arg, 156 Int* child_tid, 157 Int* parent_tid, 158 vki_modify_ldt_t * ); 159 asm( 160 ".text\n" 161 ".globl do_syscall_clone_ppc32_linux\n" 162 "do_syscall_clone_ppc32_linux:\n" 163 " stwu 1,-32(1)\n" 164 " stw 29,20(1)\n" 165 " stw 30,24(1)\n" 166 " stw 31,28(1)\n" 167 " mr 30,3\n" // preserve fn 168 " mr 31,6\n" // preserve arg 169 170 // setup child stack 171 " rlwinm 4,4,0,~0xf\n" // trim sp to multiple of 16 bytes 172 " li 0,0\n" 173 " stwu 0,-16(4)\n" // make initial stack frame 174 " mr 29,4\n" // preserve sp 175 176 // setup syscall 177 " li 0,"__NR_CLONE"\n" // syscall number 178 " mr 3,5\n" // syscall arg1: flags 179 // r4 already setup // syscall arg2: child_stack 180 " mr 5,8\n" // syscall arg3: parent_tid 181 " mr 6,2\n" // syscall arg4: REAL THREAD tls 182 " mr 7,7\n" // syscall arg5: child_tid 183 " mr 8,8\n" // syscall arg6: ???? 184 " mr 9,9\n" // syscall arg7: ???? 185 186 " sc\n" // clone() 187 188 " mfcr 4\n" // return CR in r4 (low word of ULong) 189 " cmpwi 3,0\n" // child if retval == 0 190 " bne 1f\n" // jump if !child 191 192 /* CHILD - call thread function */ 193 /* Note: 2.4 kernel doesn't set the child stack pointer, 194 so we do it here. 195 That does leave a small window for a signal to be delivered 196 on the wrong stack, unfortunately. */ 197 " mr 1,29\n" 198 " mtctr 30\n" // ctr reg = fn 199 " mr 3,31\n" // r3 = arg 200 " bctrl\n" // call fn() 201 202 // exit with result 203 " li 0,"__NR_EXIT"\n" 204 " sc\n" 205 206 // Exit returned?! 207 " .long 0\n" 208 209 // PARENT or ERROR - return 210 "1: lwz 29,20(1)\n" 211 " lwz 30,24(1)\n" 212 " lwz 31,28(1)\n" 213 " addi 1,1,32\n" 214 " blr\n" 215 ".previous\n" 216 ); 217 218 #undef __NR_CLONE 219 #undef __NR_EXIT 220 221 // forward declarations 222 static void setup_child ( ThreadArchState*, ThreadArchState* ); 223 224 /* 225 When a client clones, we need to keep track of the new thread. This means: 226 1. allocate a ThreadId+ThreadState+stack for the the thread 227 228 2. initialize the thread's new VCPU state 229 230 3. create the thread using the same args as the client requested, 231 but using the scheduler entrypoint for IP, and a separate stack 232 for SP. 233 */ 234 static SysRes do_clone ( ThreadId ptid, 235 UInt flags, Addr sp, 236 Int *parent_tidptr, 237 Int *child_tidptr, 238 Addr child_tls) 239 { 240 const Bool debug = False; 241 242 ThreadId ctid = VG_(alloc_ThreadState)(); 243 ThreadState* ptst = VG_(get_ThreadState)(ptid); 244 ThreadState* ctst = VG_(get_ThreadState)(ctid); 245 ULong word64; 246 UWord* stack; 247 NSegment const* seg; 248 SysRes res; 249 vki_sigset_t blockall, savedmask; 250 251 VG_(sigfillset)(&blockall); 252 253 vg_assert(VG_(is_running_thread)(ptid)); 254 vg_assert(VG_(is_valid_tid)(ctid)); 255 256 stack = (UWord*)ML_(allocstack)(ctid); 257 if (stack == NULL) { 258 res = VG_(mk_SysRes_Error)( VKI_ENOMEM ); 259 goto out; 260 } 261 262 //? /* make a stack frame */ 263 //? stack -= 16; 264 //? *(UWord *)stack = 0; 265 266 267 /* Copy register state 268 269 Both parent and child return to the same place, and the code 270 following the clone syscall works out which is which, so we 271 don't need to worry about it. 272 273 The parent gets the child's new tid returned from clone, but the 274 child gets 0. 275 276 If the clone call specifies a NULL SP for the new thread, then 277 it actually gets a copy of the parent's SP. 278 279 The child's TLS register (r2) gets set to the tlsaddr argument 280 if the CLONE_SETTLS flag is set. 281 */ 282 setup_child( &ctst->arch, &ptst->arch ); 283 284 /* Make sys_clone appear to have returned Success(0) in the 285 child. */ 286 { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex ); 287 /* %r3 = 0 */ 288 ctst->arch.vex.guest_GPR3 = 0; 289 /* %cr0.so = 0 */ 290 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex ); 291 } 292 293 if (sp != 0) 294 ctst->arch.vex.guest_GPR1 = sp; 295 296 ctst->os_state.parent = ptid; 297 298 /* inherit signal mask */ 299 ctst->sig_mask = ptst->sig_mask; 300 ctst->tmp_sig_mask = ptst->sig_mask; 301 302 /* Start the child with its threadgroup being the same as the 303 parent's. This is so that any exit_group calls that happen 304 after the child is created but before it sets its 305 os_state.threadgroup field for real (in thread_wrapper in 306 syswrap-linux.c), really kill the new thread. a.k.a this avoids 307 a race condition in which the thread is unkillable (via 308 exit_group) because its threadgroup is not set. The race window 309 is probably only a few hundred or a few thousand cycles long. 310 See #226116. */ 311 ctst->os_state.threadgroup = ptst->os_state.threadgroup; 312 313 /* We don't really know where the client stack is, because its 314 allocated by the client. The best we can do is look at the 315 memory mappings and try to derive some useful information. We 316 assume that esp starts near its highest possible value, and can 317 only go down to the start of the mmaped segment. */ 318 seg = VG_(am_find_nsegment)(sp); 319 if (seg && seg->kind != SkResvn) { 320 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp); 321 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start; 322 323 VG_(register_stack)(seg->start, ctst->client_stack_highest_word); 324 325 if (debug) 326 VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n", 327 ctid, seg->start, VG_PGROUNDUP(sp)); 328 } else { 329 VG_(message)(Vg_UserMsg, 330 "!? New thread %d starts with R1(%#lx) unmapped\n", 331 ctid, sp); 332 ctst->client_stack_szB = 0; 333 } 334 335 /* Assume the clone will succeed, and tell any tool that wants to 336 know that this thread has come into existence. If the clone 337 fails, we'll send out a ll_exit notification for it at the out: 338 label below, to clean up. */ 339 vg_assert(VG_(owns_BigLock_LL)(ptid)); 340 VG_TRACK ( pre_thread_ll_create, ptid, ctid ); 341 342 if (flags & VKI_CLONE_SETTLS) { 343 if (debug) 344 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls); 345 ctst->arch.vex.guest_GPR2 = child_tls; 346 } 347 348 flags &= ~VKI_CLONE_SETTLS; 349 350 /* start the thread with everything blocked */ 351 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask); 352 353 /* Create the new thread */ 354 word64 = do_syscall_clone_ppc32_linux( 355 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid], 356 child_tidptr, parent_tidptr, NULL 357 ); 358 /* High half word64 is syscall return value. Low half is 359 the entire CR, from which we need to extract CR0.SO. */ 360 /* VG_(printf)("word64 = 0x%llx\n", word64); */ 361 res = VG_(mk_SysRes_ppc32_linux)( 362 /*val*/(UInt)(word64 >> 32), 363 /*errflag*/ (((UInt)word64) >> 28) & 1 364 ); 365 366 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL); 367 368 out: 369 if (sr_isError(res)) { 370 /* clone failed */ 371 VG_(cleanup_thread)(&ctst->arch); 372 ctst->status = VgTs_Empty; 373 /* oops. Better tell the tool the thread exited in a hurry :-) */ 374 VG_TRACK( pre_thread_ll_exit, ctid ); 375 } 376 377 return res; 378 } 379 380 381 382 /* --------------------------------------------------------------------- 383 More thread stuff 384 ------------------------------------------------------------------ */ 385 386 void VG_(cleanup_thread) ( ThreadArchState* arch ) 387 { 388 } 389 390 void setup_child ( /*OUT*/ ThreadArchState *child, 391 /*IN*/ ThreadArchState *parent ) 392 { 393 /* We inherit our parent's guest state. */ 394 child->vex = parent->vex; 395 child->vex_shadow1 = parent->vex_shadow1; 396 child->vex_shadow2 = parent->vex_shadow2; 397 } 398 399 400 /* --------------------------------------------------------------------- 401 PRE/POST wrappers for ppc32/Linux-specific syscalls 402 ------------------------------------------------------------------ */ 403 404 #define PRE(name) DEFN_PRE_TEMPLATE(ppc32_linux, name) 405 #define POST(name) DEFN_POST_TEMPLATE(ppc32_linux, name) 406 407 /* Add prototypes for the wrappers declared here, so that gcc doesn't 408 harass us for not having prototypes. Really this is a kludge -- 409 the right thing to do is to make these wrappers 'static' since they 410 aren't visible outside this file, but that requires even more macro 411 magic. */ 412 413 DECL_TEMPLATE(ppc32_linux, sys_socketcall); 414 DECL_TEMPLATE(ppc32_linux, sys_mmap); 415 DECL_TEMPLATE(ppc32_linux, sys_mmap2); 416 DECL_TEMPLATE(ppc32_linux, sys_stat64); 417 DECL_TEMPLATE(ppc32_linux, sys_lstat64); 418 DECL_TEMPLATE(ppc32_linux, sys_fstatat64); 419 DECL_TEMPLATE(ppc32_linux, sys_fstat64); 420 DECL_TEMPLATE(ppc32_linux, sys_ipc); 421 DECL_TEMPLATE(ppc32_linux, sys_clone); 422 DECL_TEMPLATE(ppc32_linux, sys_sigreturn); 423 DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn); 424 DECL_TEMPLATE(ppc32_linux, sys_sigsuspend); 425 DECL_TEMPLATE(ppc32_linux, sys_spu_create); 426 DECL_TEMPLATE(ppc32_linux, sys_spu_run); 427 428 PRE(sys_socketcall) 429 { 430 # define ARG2_0 (((UWord*)ARG2)[0]) 431 # define ARG2_1 (((UWord*)ARG2)[1]) 432 # define ARG2_2 (((UWord*)ARG2)[2]) 433 # define ARG2_3 (((UWord*)ARG2)[3]) 434 # define ARG2_4 (((UWord*)ARG2)[4]) 435 # define ARG2_5 (((UWord*)ARG2)[5]) 436 437 *flags |= SfMayBlock; 438 PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2); 439 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args); 440 441 switch (ARG1 /* request */) { 442 443 case VKI_SYS_SOCKETPAIR: 444 /* int socketpair(int d, int type, int protocol, int sv[2]); */ 445 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) ); 446 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 ); 447 break; 448 449 case VKI_SYS_SOCKET: 450 /* int socket(int domain, int type, int protocol); */ 451 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) ); 452 break; 453 454 case VKI_SYS_BIND: 455 /* int bind(int sockfd, struct sockaddr *my_addr, 456 int addrlen); */ 457 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) ); 458 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 ); 459 break; 460 461 case VKI_SYS_LISTEN: 462 /* int listen(int s, int backlog); */ 463 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) ); 464 break; 465 466 case VKI_SYS_ACCEPT: { 467 /* int accept(int s, struct sockaddr *addr, int *addrlen); */ 468 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) ); 469 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 ); 470 break; 471 } 472 473 case VKI_SYS_ACCEPT4: { 474 /* int accept(int s, struct sockaddr *addr, int *addrlen, int args); */ 475 PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) ); 476 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 ); 477 break; 478 } 479 480 case VKI_SYS_SENDTO: 481 /* int sendto(int s, const void *msg, int len, 482 unsigned int flags, 483 const struct sockaddr *to, int tolen); */ 484 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) ); 485 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2, 486 ARG2_3, ARG2_4, ARG2_5 ); 487 break; 488 489 case VKI_SYS_SEND: 490 /* int send(int s, const void *msg, size_t len, int flags); */ 491 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) ); 492 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 ); 493 break; 494 495 case VKI_SYS_RECVFROM: 496 /* int recvfrom(int s, void *buf, int len, unsigned int flags, 497 struct sockaddr *from, int *fromlen); */ 498 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) ); 499 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2, 500 ARG2_3, ARG2_4, ARG2_5 ); 501 break; 502 503 case VKI_SYS_RECV: 504 /* int recv(int s, void *buf, int len, unsigned int flags); */ 505 /* man 2 recv says: 506 The recv call is normally used only on a connected socket 507 (see connect(2)) and is identical to recvfrom with a NULL 508 from parameter. 509 */ 510 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) ); 511 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 ); 512 break; 513 514 case VKI_SYS_CONNECT: 515 /* int connect(int sockfd, 516 struct sockaddr *serv_addr, int addrlen ); */ 517 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) ); 518 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 ); 519 break; 520 521 case VKI_SYS_SETSOCKOPT: 522 /* int setsockopt(int s, int level, int optname, 523 const void *optval, int optlen); */ 524 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) ); 525 ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 526 ARG2_3, ARG2_4 ); 527 break; 528 529 case VKI_SYS_GETSOCKOPT: 530 /* int getsockopt(int s, int level, int optname, 531 void *optval, socklen_t *optlen); */ 532 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) ); 533 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 534 ARG2_3, ARG2_4 ); 535 break; 536 537 case VKI_SYS_GETSOCKNAME: 538 /* int getsockname(int s, struct sockaddr* name, int* namelen) */ 539 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) ); 540 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 ); 541 break; 542 543 case VKI_SYS_GETPEERNAME: 544 /* int getpeername(int s, struct sockaddr* name, int* namelen) */ 545 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) ); 546 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 ); 547 break; 548 549 case VKI_SYS_SHUTDOWN: 550 /* int shutdown(int s, int how); */ 551 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) ); 552 break; 553 554 case VKI_SYS_SENDMSG: { 555 /* int sendmsg(int s, const struct msghdr *msg, int flags); */ 556 557 /* this causes warnings, and I don't get why. glibc bug? 558 * (after all it's glibc providing the arguments array) 559 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) ); 560 */ 561 ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 ); 562 break; 563 } 564 565 case VKI_SYS_RECVMSG: { 566 /* int recvmsg(int s, struct msghdr *msg, int flags); */ 567 568 /* this causes warnings, and I don't get why. glibc bug? 569 * (after all it's glibc providing the arguments array) 570 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) ); 571 */ 572 ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 ); 573 break; 574 } 575 576 default: 577 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1); 578 SET_STATUS_Failure( VKI_EINVAL ); 579 break; 580 } 581 # undef ARG2_0 582 # undef ARG2_1 583 # undef ARG2_2 584 # undef ARG2_3 585 # undef ARG2_4 586 # undef ARG2_5 587 } 588 589 POST(sys_socketcall) 590 { 591 # define ARG2_0 (((UWord*)ARG2)[0]) 592 # define ARG2_1 (((UWord*)ARG2)[1]) 593 # define ARG2_2 (((UWord*)ARG2)[2]) 594 # define ARG2_3 (((UWord*)ARG2)[3]) 595 # define ARG2_4 (((UWord*)ARG2)[4]) 596 # define ARG2_5 (((UWord*)ARG2)[5]) 597 598 SysRes r; 599 vg_assert(SUCCESS); 600 switch (ARG1 /* request */) { 601 602 case VKI_SYS_SOCKETPAIR: 603 r = ML_(generic_POST_sys_socketpair)( 604 tid, VG_(mk_SysRes_Success)(RES), 605 ARG2_0, ARG2_1, ARG2_2, ARG2_3 606 ); 607 SET_STATUS_from_SysRes(r); 608 break; 609 610 case VKI_SYS_SOCKET: 611 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) ); 612 SET_STATUS_from_SysRes(r); 613 break; 614 615 case VKI_SYS_BIND: 616 /* int bind(int sockfd, struct sockaddr *my_addr, 617 int addrlen); */ 618 break; 619 620 case VKI_SYS_LISTEN: 621 /* int listen(int s, int backlog); */ 622 break; 623 624 case VKI_SYS_ACCEPT: 625 case VKI_SYS_ACCEPT4: 626 /* int accept(int s, struct sockaddr *addr, int *addrlen); */ 627 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES), 628 ARG2_0, ARG2_1, ARG2_2 ); 629 SET_STATUS_from_SysRes(r); 630 break; 631 632 case VKI_SYS_SENDTO: 633 break; 634 635 case VKI_SYS_SEND: 636 break; 637 638 case VKI_SYS_RECVFROM: 639 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES), 640 ARG2_0, ARG2_1, ARG2_2, 641 ARG2_3, ARG2_4, ARG2_5 ); 642 break; 643 644 case VKI_SYS_RECV: 645 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 ); 646 break; 647 648 case VKI_SYS_CONNECT: 649 break; 650 651 case VKI_SYS_SETSOCKOPT: 652 break; 653 654 case VKI_SYS_GETSOCKOPT: 655 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), 656 ARG2_0, ARG2_1, 657 ARG2_2, ARG2_3, ARG2_4 ); 658 break; 659 660 case VKI_SYS_GETSOCKNAME: 661 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES), 662 ARG2_0, ARG2_1, ARG2_2 ); 663 break; 664 665 case VKI_SYS_GETPEERNAME: 666 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES), 667 ARG2_0, ARG2_1, ARG2_2 ); 668 break; 669 670 case VKI_SYS_SHUTDOWN: 671 break; 672 673 case VKI_SYS_SENDMSG: 674 break; 675 676 case VKI_SYS_RECVMSG: 677 ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES ); 678 break; 679 680 default: 681 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1); 682 VG_(core_panic)("... bye!\n"); 683 break; /*NOTREACHED*/ 684 } 685 # undef ARG2_0 686 # undef ARG2_1 687 # undef ARG2_2 688 # undef ARG2_3 689 # undef ARG2_4 690 # undef ARG2_5 691 } 692 693 PRE(sys_mmap) 694 { 695 SysRes r; 696 697 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )", 698 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 ); 699 PRE_REG_READ6(long, "mmap", 700 unsigned long, start, unsigned long, length, 701 unsigned long, prot, unsigned long, flags, 702 unsigned long, fd, unsigned long, offset); 703 704 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 705 (Off64T)ARG6 ); 706 SET_STATUS_from_SysRes(r); 707 } 708 709 PRE(sys_mmap2) 710 { 711 SysRes r; 712 713 // Exactly like old_mmap() except: 714 // - the file offset is specified in 4K units rather than bytes, 715 // so that it can be used for files bigger than 2^32 bytes. 716 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", 717 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 ); 718 PRE_REG_READ6(long, "mmap2", 719 unsigned long, start, unsigned long, length, 720 unsigned long, prot, unsigned long, flags, 721 unsigned long, fd, unsigned long, offset); 722 723 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 724 4096 * (Off64T)ARG6 ); 725 SET_STATUS_from_SysRes(r); 726 } 727 728 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily 729 // applicable to every architecture -- I think only to 32-bit archs. 730 // We're going to need something like linux/core_os32.h for such 731 // things, eventually, I think. --njn 732 PRE(sys_stat64) 733 { 734 PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2); 735 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf); 736 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 ); 737 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); 738 } 739 740 POST(sys_stat64) 741 { 742 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 743 } 744 745 PRE(sys_lstat64) 746 { 747 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 748 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf); 749 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 ); 750 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 751 } 752 753 POST(sys_lstat64) 754 { 755 vg_assert(SUCCESS); 756 if (RES == 0) { 757 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 758 } 759 } 760 761 PRE(sys_fstatat64) 762 { 763 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3); 764 PRE_REG_READ3(long, "fstatat64", 765 int, dfd, char *, file_name, struct stat64 *, buf); 766 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); 767 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); 768 } 769 770 POST(sys_fstatat64) 771 { 772 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); 773 } 774 775 PRE(sys_fstat64) 776 { 777 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2); 778 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf); 779 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 780 } 781 782 POST(sys_fstat64) 783 { 784 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 785 } 786 787 static Addr deref_Addr ( ThreadId tid, Addr a, Char* s ) 788 { 789 Addr* a_p = (Addr*)a; 790 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) ); 791 return *a_p; 792 } 793 794 PRE(sys_ipc) 795 { 796 PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 797 // XXX: this is simplistic -- some args are not used in all circumstances. 798 PRE_REG_READ6(int, "ipc", 799 vki_uint, call, int, first, int, second, int, third, 800 void *, ptr, long, fifth) 801 802 switch (ARG1 /* call */) { 803 case VKI_SEMOP: 804 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 ); 805 *flags |= SfMayBlock; 806 break; 807 case VKI_SEMGET: 808 break; 809 case VKI_SEMCTL: 810 { 811 UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" ); 812 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg ); 813 break; 814 } 815 case VKI_SEMTIMEDOP: 816 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 ); 817 *flags |= SfMayBlock; 818 break; 819 case VKI_MSGSND: 820 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 ); 821 if ((ARG4 & VKI_IPC_NOWAIT) == 0) 822 *flags |= SfMayBlock; 823 break; 824 case VKI_MSGRCV: 825 { 826 Addr msgp; 827 Word msgtyp; 828 829 msgp = deref_Addr( tid, 830 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp), 831 "msgrcv(msgp)" ); 832 msgtyp = deref_Addr( tid, 833 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp), 834 "msgrcv(msgp)" ); 835 836 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 ); 837 838 if ((ARG4 & VKI_IPC_NOWAIT) == 0) 839 *flags |= SfMayBlock; 840 break; 841 } 842 case VKI_MSGGET: 843 break; 844 case VKI_MSGCTL: 845 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 ); 846 break; 847 case VKI_SHMAT: 848 { 849 UWord w; 850 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) ); 851 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 ); 852 if (w == 0) 853 SET_STATUS_Failure( VKI_EINVAL ); 854 else 855 ARG5 = w; 856 break; 857 } 858 case VKI_SHMDT: 859 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5)) 860 SET_STATUS_Failure( VKI_EINVAL ); 861 break; 862 case VKI_SHMGET: 863 break; 864 case VKI_SHMCTL: /* IPCOP_shmctl */ 865 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 ); 866 break; 867 default: 868 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 ); 869 VG_(core_panic)("... bye!\n"); 870 break; /*NOTREACHED*/ 871 } 872 } 873 874 POST(sys_ipc) 875 { 876 vg_assert(SUCCESS); 877 switch (ARG1 /* call */) { 878 case VKI_SEMOP: 879 case VKI_SEMGET: 880 break; 881 case VKI_SEMCTL: 882 { 883 UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" ); 884 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg ); 885 break; 886 } 887 case VKI_SEMTIMEDOP: 888 case VKI_MSGSND: 889 break; 890 case VKI_MSGRCV: 891 { 892 Addr msgp; 893 Word msgtyp; 894 895 msgp = deref_Addr( tid, 896 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp), 897 "msgrcv(msgp)" ); 898 msgtyp = deref_Addr( tid, 899 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp), 900 "msgrcv(msgp)" ); 901 902 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 ); 903 break; 904 } 905 case VKI_MSGGET: 906 break; 907 case VKI_MSGCTL: 908 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 ); 909 break; 910 case VKI_SHMAT: 911 { 912 Addr addr; 913 914 /* force readability. before the syscall it is 915 * indeed uninitialized, as can be seen in 916 * glibc/sysdeps/unix/sysv/linux/shmat.c */ 917 POST_MEM_WRITE( ARG4, sizeof( Addr ) ); 918 919 addr = deref_Addr ( tid, ARG4, "shmat(addr)" ); 920 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 ); 921 break; 922 } 923 case VKI_SHMDT: 924 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 ); 925 break; 926 case VKI_SHMGET: 927 break; 928 case VKI_SHMCTL: 929 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 ); 930 break; 931 default: 932 VG_(message)(Vg_DebugMsg, 933 "FATAL: unhandled syscall(ipc) %ld\n", 934 ARG1 ); 935 VG_(core_panic)("... bye!\n"); 936 break; /*NOTREACHED*/ 937 } 938 } 939 940 941 942 943 //.. PRE(old_select, MayBlock) 944 //.. { 945 //.. /* struct sel_arg_struct { 946 //.. unsigned long n; 947 //.. fd_set *inp, *outp, *exp; 948 //.. struct timeval *tvp; 949 //.. }; 950 //.. */ 951 //.. PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args); 952 //.. PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) ); 953 //.. 954 //.. { 955 //.. UInt* arg_struct = (UInt*)ARG1; 956 //.. UInt a1, a2, a3, a4, a5; 957 //.. 958 //.. a1 = arg_struct[0]; 959 //.. a2 = arg_struct[1]; 960 //.. a3 = arg_struct[2]; 961 //.. a4 = arg_struct[3]; 962 //.. a5 = arg_struct[4]; 963 //.. 964 //.. PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5); 965 //.. if (a2 != (Addr)NULL) 966 //.. PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ ); 967 //.. if (a3 != (Addr)NULL) 968 //.. PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ ); 969 //.. if (a4 != (Addr)NULL) 970 //.. PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ ); 971 //.. if (a5 != (Addr)NULL) 972 //.. PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) ); 973 //.. } 974 //.. } 975 976 PRE(sys_clone) 977 { 978 UInt cloneflags; 979 980 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5); 981 PRE_REG_READ5(int, "clone", 982 unsigned long, flags, 983 void *, child_stack, 984 int *, parent_tidptr, 985 void *, child_tls, 986 int *, child_tidptr); 987 988 if (ARG1 & VKI_CLONE_PARENT_SETTID) { 989 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int)); 990 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 991 VKI_PROT_WRITE)) { 992 SET_STATUS_Failure( VKI_EFAULT ); 993 return; 994 } 995 } 996 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) { 997 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int)); 998 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 999 VKI_PROT_WRITE)) { 1000 SET_STATUS_Failure( VKI_EFAULT ); 1001 return; 1002 } 1003 } 1004 1005 cloneflags = ARG1; 1006 1007 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) { 1008 SET_STATUS_Failure( VKI_EINVAL ); 1009 return; 1010 } 1011 1012 /* Only look at the flags we really care about */ 1013 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 1014 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) { 1015 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: 1016 /* thread creation */ 1017 SET_STATUS_from_SysRes( 1018 do_clone(tid, 1019 ARG1, /* flags */ 1020 (Addr)ARG2, /* child SP */ 1021 (Int *)ARG3, /* parent_tidptr */ 1022 (Int *)ARG5, /* child_tidptr */ 1023 (Addr)ARG4)); /* child_tls */ 1024 break; 1025 1026 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ 1027 /* FALLTHROUGH - assume vfork == fork */ 1028 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); 1029 1030 case 0: /* plain fork */ 1031 SET_STATUS_from_SysRes( 1032 ML_(do_fork_clone)(tid, 1033 cloneflags, /* flags */ 1034 (Int *)ARG3, /* parent_tidptr */ 1035 (Int *)ARG5)); /* child_tidptr */ 1036 break; 1037 1038 default: 1039 /* should we just ENOSYS? */ 1040 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1); 1041 VG_(message)(Vg_UserMsg, "\n"); 1042 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n"); 1043 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n"); 1044 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n"); 1045 VG_(unimplemented) 1046 ("Valgrind does not support general clone()."); 1047 } 1048 1049 if (SUCCESS) { 1050 if (ARG1 & VKI_CLONE_PARENT_SETTID) 1051 POST_MEM_WRITE(ARG3, sizeof(Int)); 1052 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 1053 POST_MEM_WRITE(ARG5, sizeof(Int)); 1054 1055 /* Thread creation was successful; let the child have the chance 1056 to run */ 1057 *flags |= SfYieldAfter; 1058 } 1059 } 1060 1061 PRE(sys_sigreturn) 1062 { 1063 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 1064 an explanation of what follows. */ 1065 1066 //ThreadState* tst; 1067 PRINT("sys_sigreturn ( )"); 1068 1069 vg_assert(VG_(is_valid_tid)(tid)); 1070 vg_assert(tid >= 1 && tid < VG_N_THREADS); 1071 vg_assert(VG_(is_running_thread)(tid)); 1072 1073 ///* Adjust esp to point to start of frame; skip back up over 1074 // sigreturn sequence's "popl %eax" and handler ret addr */ 1075 //tst = VG_(get_ThreadState)(tid); 1076 //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word); 1077 // Should we do something equivalent on ppc32? Who knows. 1078 1079 ///* This is only so that the EIP is (might be) useful to report if 1080 // something goes wrong in the sigreturn */ 1081 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch); 1082 // Should we do something equivalent on ppc32? Who knows. 1083 1084 /* Restore register state from frame and remove it */ 1085 VG_(sigframe_destroy)(tid, False); 1086 1087 /* Tell the driver not to update the guest state with the "result", 1088 and set a bogus result to keep it happy. */ 1089 *flags |= SfNoWriteResult; 1090 SET_STATUS_Success(0); 1091 1092 /* Check to see if any signals arose as a result of this. */ 1093 *flags |= SfPollAfter; 1094 } 1095 1096 PRE(sys_rt_sigreturn) 1097 { 1098 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 1099 an explanation of what follows. */ 1100 1101 //ThreadState* tst; 1102 PRINT("rt_sigreturn ( )"); 1103 1104 vg_assert(VG_(is_valid_tid)(tid)); 1105 vg_assert(tid >= 1 && tid < VG_N_THREADS); 1106 vg_assert(VG_(is_running_thread)(tid)); 1107 1108 ///* Adjust esp to point to start of frame; skip back up over handler 1109 // ret addr */ 1110 //tst = VG_(get_ThreadState)(tid); 1111 //tst->arch.vex.guest_ESP -= sizeof(Addr); 1112 // Should we do something equivalent on ppc32? Who knows. 1113 1114 ///* This is only so that the EIP is (might be) useful to report if 1115 // something goes wrong in the sigreturn */ 1116 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch); 1117 // Should we do something equivalent on ppc32? Who knows. 1118 1119 /* Restore register state from frame and remove it */ 1120 VG_(sigframe_destroy)(tid, True); 1121 1122 /* Tell the driver not to update the guest state with the "result", 1123 and set a bogus result to keep it happy. */ 1124 *flags |= SfNoWriteResult; 1125 SET_STATUS_Success(0); 1126 1127 /* Check to see if any signals arose as a result of this. */ 1128 *flags |= SfPollAfter; 1129 } 1130 1131 1132 //.. PRE(sys_modify_ldt, Special) 1133 //.. { 1134 //.. PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3); 1135 //.. PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr, 1136 //.. unsigned long, bytecount); 1137 //.. 1138 //.. if (ARG1 == 0) { 1139 //.. /* read the LDT into ptr */ 1140 //.. PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 ); 1141 //.. } 1142 //.. if (ARG1 == 1 || ARG1 == 0x11) { 1143 //.. /* write the LDT with the entry pointed at by ptr */ 1144 //.. PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) ); 1145 //.. } 1146 //.. /* "do" the syscall ourselves; the kernel never sees it */ 1147 //.. SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) ); 1148 //.. 1149 //.. if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) { 1150 //.. POST_MEM_WRITE( ARG2, RES ); 1151 //.. } 1152 //.. } 1153 1154 //.. PRE(sys_set_thread_area, Special) 1155 //.. { 1156 //.. PRINT("sys_set_thread_area ( %p )", ARG1); 1157 //.. PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info) 1158 //.. PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) ); 1159 //.. 1160 //.. /* "do" the syscall ourselves; the kernel never sees it */ 1161 //.. SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) ); 1162 //.. } 1163 1164 //.. PRE(sys_get_thread_area, Special) 1165 //.. { 1166 //.. PRINT("sys_get_thread_area ( %p )", ARG1); 1167 //.. PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info) 1168 //.. PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) ); 1169 //.. 1170 //.. /* "do" the syscall ourselves; the kernel never sees it */ 1171 //.. SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) ); 1172 //.. 1173 //.. if (!VG_(is_kerror)(RES)) { 1174 //.. POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) ); 1175 //.. } 1176 //.. } 1177 1178 //.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic. 1179 //.. // XXX: Why is the memory pointed to by ARG3 never checked? 1180 //.. PRE(sys_ptrace, 0) 1181 //.. { 1182 //.. PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4); 1183 //.. PRE_REG_READ4(int, "ptrace", 1184 //.. long, request, long, pid, long, addr, long, data); 1185 //.. switch (ARG1) { 1186 //.. case VKI_PTRACE_PEEKTEXT: 1187 //.. case VKI_PTRACE_PEEKDATA: 1188 //.. case VKI_PTRACE_PEEKUSR: 1189 //.. PRE_MEM_WRITE( "ptrace(peek)", ARG4, 1190 //.. sizeof (long)); 1191 //.. break; 1192 //.. case VKI_PTRACE_GETREGS: 1193 //.. PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 1194 //.. sizeof (struct vki_user_regs_struct)); 1195 //.. break; 1196 //.. case VKI_PTRACE_GETFPREGS: 1197 //.. PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 1198 //.. sizeof (struct vki_user_i387_struct)); 1199 //.. break; 1200 //.. case VKI_PTRACE_GETFPXREGS: 1201 //.. PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4, 1202 //.. sizeof(struct vki_user_fxsr_struct) ); 1203 //.. break; 1204 //.. case VKI_PTRACE_SETREGS: 1205 //.. PRE_MEM_READ( "ptrace(setregs)", ARG4, 1206 //.. sizeof (struct vki_user_regs_struct)); 1207 //.. break; 1208 //.. case VKI_PTRACE_SETFPREGS: 1209 //.. PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 1210 //.. sizeof (struct vki_user_i387_struct)); 1211 //.. break; 1212 //.. case VKI_PTRACE_SETFPXREGS: 1213 //.. PRE_MEM_READ( "ptrace(setfpxregs)", ARG4, 1214 //.. sizeof(struct vki_user_fxsr_struct) ); 1215 //.. break; 1216 //.. default: 1217 //.. break; 1218 //.. } 1219 //.. } 1220 1221 //.. POST(sys_ptrace) 1222 //.. { 1223 //.. switch (ARG1) { 1224 //.. case VKI_PTRACE_PEEKTEXT: 1225 //.. case VKI_PTRACE_PEEKDATA: 1226 //.. case VKI_PTRACE_PEEKUSR: 1227 //.. POST_MEM_WRITE( ARG4, sizeof (long)); 1228 //.. break; 1229 //.. case VKI_PTRACE_GETREGS: 1230 //.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct)); 1231 //.. break; 1232 //.. case VKI_PTRACE_GETFPREGS: 1233 //.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct)); 1234 //.. break; 1235 //.. case VKI_PTRACE_GETFPXREGS: 1236 //.. POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) ); 1237 //.. break; 1238 //.. default: 1239 //.. break; 1240 //.. } 1241 //.. } 1242 1243 //.. // XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk 1244 //.. static Addr deref_Addr ( ThreadId tid, Addr a, Char* s ) 1245 //.. { 1246 //.. Addr* a_p = (Addr*)a; 1247 //.. PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) ); 1248 //.. return *a_p; 1249 //.. } 1250 1251 //.. // XXX: should use the constants here (eg. SHMAT), not the numbers directly! 1252 //.. PRE(sys_ipc, 0) 1253 //.. { 1254 //.. PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 1255 //.. // XXX: this is simplistic -- some args are not used in all circumstances. 1256 //.. PRE_REG_READ6(int, "ipc", 1257 //.. vki_uint, call, int, first, int, second, int, third, 1258 //.. void *, ptr, long, fifth) 1259 //.. 1260 //.. switch (ARG1 /* call */) { 1261 //.. case VKI_SEMOP: 1262 //.. ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 ); 1263 //.. /* tst->sys_flags |= MayBlock; */ 1264 //.. break; 1265 //.. case VKI_SEMGET: 1266 //.. break; 1267 //.. case VKI_SEMCTL: 1268 //.. { 1269 //.. UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" ); 1270 //.. ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg ); 1271 //.. break; 1272 //.. } 1273 //.. case VKI_SEMTIMEDOP: 1274 //.. ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 ); 1275 //.. /* tst->sys_flags |= MayBlock; */ 1276 //.. break; 1277 //.. case VKI_MSGSND: 1278 //.. ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 ); 1279 //.. /* if ((ARG4 & VKI_IPC_NOWAIT) == 0) 1280 //.. tst->sys_flags |= MayBlock; 1281 //.. */ 1282 //.. break; 1283 //.. case VKI_MSGRCV: 1284 //.. { 1285 //.. Addr msgp; 1286 //.. Word msgtyp; 1287 //.. 1288 //.. msgp = deref_Addr( tid, 1289 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp), 1290 //.. "msgrcv(msgp)" ); 1291 //.. msgtyp = deref_Addr( tid, 1292 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp), 1293 //.. "msgrcv(msgp)" ); 1294 //.. 1295 //.. ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 ); 1296 //.. 1297 //.. /* if ((ARG4 & VKI_IPC_NOWAIT) == 0) 1298 //.. tst->sys_flags |= MayBlock; 1299 //.. */ 1300 //.. break; 1301 //.. } 1302 //.. case VKI_MSGGET: 1303 //.. break; 1304 //.. case VKI_MSGCTL: 1305 //.. ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 ); 1306 //.. break; 1307 //.. case VKI_SHMAT: 1308 //.. PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) ); 1309 //.. ARG5 = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 ); 1310 //.. if (ARG5 == 0) 1311 //.. SET_RESULT( -VKI_EINVAL ); 1312 //.. break; 1313 //.. case VKI_SHMDT: 1314 //.. if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5)) 1315 //.. SET_RESULT( -VKI_EINVAL ); 1316 //.. break; 1317 //.. case VKI_SHMGET: 1318 //.. break; 1319 //.. case VKI_SHMCTL: /* IPCOP_shmctl */ 1320 //.. ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 ); 1321 //.. break; 1322 //.. default: 1323 //.. VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 ); 1324 //.. VG_(core_panic)("... bye!\n"); 1325 //.. break; /*NOTREACHED*/ 1326 //.. } 1327 //.. } 1328 1329 //.. POST(sys_ipc) 1330 //.. { 1331 //.. switch (ARG1 /* call */) { 1332 //.. case VKI_SEMOP: 1333 //.. case VKI_SEMGET: 1334 //.. break; 1335 //.. case VKI_SEMCTL: 1336 //.. { 1337 //.. UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" ); 1338 //.. ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg ); 1339 //.. break; 1340 //.. } 1341 //.. case VKI_SEMTIMEDOP: 1342 //.. case VKI_MSGSND: 1343 //.. break; 1344 //.. case VKI_MSGRCV: 1345 //.. { 1346 //.. Addr msgp; 1347 //.. Word msgtyp; 1348 //.. 1349 //.. msgp = deref_Addr( tid, 1350 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp), 1351 //.. "msgrcv(msgp)" ); 1352 //.. msgtyp = deref_Addr( tid, 1353 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp), 1354 //.. "msgrcv(msgp)" ); 1355 //.. 1356 //.. ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 ); 1357 //.. break; 1358 //.. } 1359 //.. case VKI_MSGGET: 1360 //.. break; 1361 //.. case VKI_MSGCTL: 1362 //.. ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 ); 1363 //.. break; 1364 //.. case VKI_SHMAT: 1365 //.. { 1366 //.. Addr addr; 1367 //.. 1368 //.. /* force readability. before the syscall it is 1369 //.. * indeed uninitialized, as can be seen in 1370 //.. * glibc/sysdeps/unix/sysv/linux/shmat.c */ 1371 //.. POST_MEM_WRITE( ARG4, sizeof( Addr ) ); 1372 //.. 1373 //.. addr = deref_Addr ( tid, ARG4, "shmat(addr)" ); 1374 //.. if ( addr > 0 ) { 1375 //.. ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 ); 1376 //.. } 1377 //.. break; 1378 //.. } 1379 //.. case VKI_SHMDT: 1380 //.. ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 ); 1381 //.. break; 1382 //.. case VKI_SHMGET: 1383 //.. break; 1384 //.. case VKI_SHMCTL: 1385 //.. ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 ); 1386 //.. break; 1387 //.. default: 1388 //.. VG_(message)(Vg_DebugMsg, 1389 //.. "FATAL: unhandled syscall(ipc) %d", 1390 //.. ARG1 ); 1391 //.. VG_(core_panic)("... bye!\n"); 1392 //.. break; /*NOTREACHED*/ 1393 //.. } 1394 //.. } 1395 1396 /* NB: This is an almost identical clone of versions for x86-linux and 1397 arm-linux, which are themselves literally identical. */ 1398 PRE(sys_sigsuspend) 1399 { 1400 /* The C library interface to sigsuspend just takes a pointer to 1401 a signal mask but this system call only takes the first word of 1402 the signal mask as an argument so only 32 signals are supported. 1403 1404 In fact glibc normally uses rt_sigsuspend if it is available as 1405 that takes a pointer to the signal mask so supports more signals. 1406 */ 1407 *flags |= SfMayBlock; 1408 PRINT("sys_sigsuspend ( %ld )", ARG1 ); 1409 PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask); 1410 } 1411 1412 PRE(sys_spu_create) 1413 { 1414 PRE_MEM_RASCIIZ("stat64(filename)", ARG1); 1415 } 1416 POST(sys_spu_create) 1417 { 1418 vg_assert(SUCCESS); 1419 } 1420 1421 PRE(sys_spu_run) 1422 { 1423 *flags |= SfMayBlock; 1424 if (ARG2 != 0) 1425 PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int)); 1426 PRE_MEM_READ("event", ARG3, sizeof(unsigned int)); 1427 } 1428 POST(sys_spu_run) 1429 { 1430 if (ARG2 != 0) 1431 POST_MEM_WRITE(ARG2, sizeof(unsigned int)); 1432 } 1433 1434 #undef PRE 1435 #undef POST 1436 1437 /* --------------------------------------------------------------------- 1438 The ppc32/Linux syscall table 1439 ------------------------------------------------------------------ */ 1440 1441 /* Add an ppc32-linux specific wrapper to a syscall table. */ 1442 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc32_linux, sysno, name) 1443 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(ppc32_linux, sysno, name) 1444 1445 // This table maps from __NR_xxx syscall numbers (from 1446 // linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo() 1447 // wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S). 1448 // 1449 // For those syscalls not handled by Valgrind, the annotation indicate its 1450 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? 1451 // (unknown). 1452 1453 static SyscallTableEntry syscall_table[] = { 1454 //.. (restart_syscall) // 0 1455 GENX_(__NR_exit, sys_exit), // 1 1456 GENX_(__NR_fork, sys_fork), // 2 1457 GENXY(__NR_read, sys_read), // 3 1458 GENX_(__NR_write, sys_write), // 4 1459 1460 GENXY(__NR_open, sys_open), // 5 1461 GENXY(__NR_close, sys_close), // 6 1462 GENXY(__NR_waitpid, sys_waitpid), // 7 1463 GENXY(__NR_creat, sys_creat), // 8 1464 GENX_(__NR_link, sys_link), // 9 1465 1466 GENX_(__NR_unlink, sys_unlink), // 10 1467 GENX_(__NR_execve, sys_execve), // 11 1468 GENX_(__NR_chdir, sys_chdir), // 12 1469 GENXY(__NR_time, sys_time), // 13 1470 GENX_(__NR_mknod, sys_mknod), // 14 1471 //.. 1472 GENX_(__NR_chmod, sys_chmod), // 15 1473 GENX_(__NR_lchown, sys_lchown), // 16 ## P 1474 //.. GENX_(__NR_break, sys_ni_syscall), // 17 1475 //.. // (__NR_oldstat, sys_stat), // 18 (obsolete) 1476 LINX_(__NR_lseek, sys_lseek), // 19 1477 //.. 1478 GENX_(__NR_getpid, sys_getpid), // 20 1479 LINX_(__NR_mount, sys_mount), // 21 1480 LINX_(__NR_umount, sys_oldumount), // 22 1481 GENX_(__NR_setuid, sys_setuid), // 23 ## P 1482 GENX_(__NR_getuid, sys_getuid), // 24 ## P 1483 //.. 1484 //.. // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN) 1485 //.. PLAXY(__NR_ptrace, sys_ptrace), // 26 1486 GENX_(__NR_alarm, sys_alarm), // 27 1487 //.. // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete 1488 GENX_(__NR_pause, sys_pause), // 29 1489 //.. 1490 LINX_(__NR_utime, sys_utime), // 30 1491 //.. GENX_(__NR_stty, sys_ni_syscall), // 31 1492 //.. GENX_(__NR_gtty, sys_ni_syscall), // 32 1493 GENX_(__NR_access, sys_access), // 33 1494 //.. GENX_(__NR_nice, sys_nice), // 34 1495 //.. 1496 //.. GENX_(__NR_ftime, sys_ni_syscall), // 35 1497 //.. GENX_(__NR_sync, sys_sync), // 36 1498 GENX_(__NR_kill, sys_kill), // 37 1499 GENX_(__NR_rename, sys_rename), // 38 1500 GENX_(__NR_mkdir, sys_mkdir), // 39 1501 1502 GENX_(__NR_rmdir, sys_rmdir), // 40 1503 GENXY(__NR_dup, sys_dup), // 41 1504 LINXY(__NR_pipe, sys_pipe), // 42 1505 GENXY(__NR_times, sys_times), // 43 1506 //.. GENX_(__NR_prof, sys_ni_syscall), // 44 1507 //.. 1508 GENX_(__NR_brk, sys_brk), // 45 1509 GENX_(__NR_setgid, sys_setgid), // 46 1510 GENX_(__NR_getgid, sys_getgid), // 47 1511 //.. // (__NR_signal, sys_signal), // 48 */* (ANSI C) 1512 GENX_(__NR_geteuid, sys_geteuid), // 49 1513 1514 GENX_(__NR_getegid, sys_getegid), // 50 1515 //.. GENX_(__NR_acct, sys_acct), // 51 1516 LINX_(__NR_umount2, sys_umount), // 52 1517 //.. GENX_(__NR_lock, sys_ni_syscall), // 53 1518 LINXY(__NR_ioctl, sys_ioctl), // 54 1519 //.. 1520 LINXY(__NR_fcntl, sys_fcntl), // 55 1521 //.. GENX_(__NR_mpx, sys_ni_syscall), // 56 1522 GENX_(__NR_setpgid, sys_setpgid), // 57 1523 //.. GENX_(__NR_ulimit, sys_ni_syscall), // 58 1524 //.. // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete 1525 1526 GENX_(__NR_umask, sys_umask), // 60 1527 GENX_(__NR_chroot, sys_chroot), // 61 1528 //.. // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated 1529 GENXY(__NR_dup2, sys_dup2), // 63 1530 GENX_(__NR_getppid, sys_getppid), // 64 1531 1532 GENX_(__NR_getpgrp, sys_getpgrp), // 65 1533 GENX_(__NR_setsid, sys_setsid), // 66 1534 LINXY(__NR_sigaction, sys_sigaction), // 67 1535 //.. // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C) 1536 //.. // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C) 1537 //.. 1538 GENX_(__NR_setreuid, sys_setreuid), // 70 1539 GENX_(__NR_setregid, sys_setregid), // 71 1540 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72 1541 LINXY(__NR_sigpending, sys_sigpending), // 73 1542 //.. // (__NR_sethostname, sys_sethostname), // 74 */* 1543 //.. 1544 GENX_(__NR_setrlimit, sys_setrlimit), // 75 1545 //.. GENXY(__NR_getrlimit, sys_old_getrlimit), // 76 1546 GENXY(__NR_getrusage, sys_getrusage), // 77 1547 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78 1548 //.. GENX_(__NR_settimeofday, sys_settimeofday), // 79 1549 //.. 1550 GENXY(__NR_getgroups, sys_getgroups), // 80 1551 GENX_(__NR_setgroups, sys_setgroups), // 81 1552 //.. PLAX_(__NR_select, old_select), // 82 1553 GENX_(__NR_symlink, sys_symlink), // 83 1554 //.. // (__NR_oldlstat, sys_lstat), // 84 -- obsolete 1555 //.. 1556 GENX_(__NR_readlink, sys_readlink), // 85 1557 //.. // (__NR_uselib, sys_uselib), // 86 */Linux 1558 //.. // (__NR_swapon, sys_swapon), // 87 */Linux 1559 //.. // (__NR_reboot, sys_reboot), // 88 */Linux 1560 //.. // (__NR_readdir, old_readdir), // 89 -- superseded 1561 1562 PLAX_(__NR_mmap, sys_mmap), // 90 1563 GENXY(__NR_munmap, sys_munmap), // 91 1564 GENX_(__NR_truncate, sys_truncate), // 92 1565 GENX_(__NR_ftruncate, sys_ftruncate), // 93 1566 GENX_(__NR_fchmod, sys_fchmod), // 94 1567 1568 GENX_(__NR_fchown, sys_fchown), // 95 1569 GENX_(__NR_getpriority, sys_getpriority), // 96 1570 GENX_(__NR_setpriority, sys_setpriority), // 97 1571 //.. GENX_(__NR_profil, sys_ni_syscall), // 98 1572 GENXY(__NR_statfs, sys_statfs), // 99 1573 //.. 1574 GENXY(__NR_fstatfs, sys_fstatfs), // 100 1575 //.. LINX_(__NR_ioperm, sys_ioperm), // 101 1576 PLAXY(__NR_socketcall, sys_socketcall), // 102 1577 LINXY(__NR_syslog, sys_syslog), // 103 1578 GENXY(__NR_setitimer, sys_setitimer), // 104 1579 1580 GENXY(__NR_getitimer, sys_getitimer), // 105 1581 GENXY(__NR_stat, sys_newstat), // 106 1582 GENXY(__NR_lstat, sys_newlstat), // 107 1583 GENXY(__NR_fstat, sys_newfstat), // 108 1584 //.. // (__NR_olduname, sys_uname), // 109 -- obsolete 1585 //.. 1586 //.. GENX_(__NR_iopl, sys_iopl), // 110 1587 LINX_(__NR_vhangup, sys_vhangup), // 111 1588 //.. GENX_(__NR_idle, sys_ni_syscall), // 112 1589 //.. // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only 1590 GENXY(__NR_wait4, sys_wait4), // 114 1591 //.. 1592 //.. // (__NR_swapoff, sys_swapoff), // 115 */Linux 1593 LINXY(__NR_sysinfo, sys_sysinfo), // 116 1594 PLAXY(__NR_ipc, sys_ipc), // 117 1595 GENX_(__NR_fsync, sys_fsync), // 118 1596 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux 1597 //.. 1598 PLAX_(__NR_clone, sys_clone), // 120 1599 //.. // (__NR_setdomainname, sys_setdomainname), // 121 */*(?) 1600 GENXY(__NR_uname, sys_newuname), // 122 1601 //.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123 1602 LINXY(__NR_adjtimex, sys_adjtimex), // 124 1603 1604 GENXY(__NR_mprotect, sys_mprotect), // 125 1605 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126 1606 GENX_(__NR_create_module, sys_ni_syscall), // 127 1607 LINX_(__NR_init_module, sys_init_module), // 128 1608 LINX_(__NR_delete_module, sys_delete_module), // 129 1609 //.. 1610 //.. // Nb: get_kernel_syms() was removed 2.4-->2.6 1611 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 1612 //.. LINX_(__NR_quotactl, sys_quotactl), // 131 1613 GENX_(__NR_getpgid, sys_getpgid), // 132 1614 GENX_(__NR_fchdir, sys_fchdir), // 133 1615 //.. // (__NR_bdflush, sys_bdflush), // 134 */Linux 1616 //.. 1617 //.. // (__NR_sysfs, sys_sysfs), // 135 SVr4 1618 LINX_(__NR_personality, sys_personality), // 136 1619 //.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137 1620 LINX_(__NR_setfsuid, sys_setfsuid), // 138 1621 LINX_(__NR_setfsgid, sys_setfsgid), // 139 1622 1623 LINXY(__NR__llseek, sys_llseek), // 140 1624 GENXY(__NR_getdents, sys_getdents), // 141 1625 GENX_(__NR__newselect, sys_select), // 142 1626 GENX_(__NR_flock, sys_flock), // 143 1627 GENX_(__NR_msync, sys_msync), // 144 1628 //.. 1629 GENXY(__NR_readv, sys_readv), // 145 1630 GENX_(__NR_writev, sys_writev), // 146 1631 GENX_(__NR_getsid, sys_getsid), // 147 1632 GENX_(__NR_fdatasync, sys_fdatasync), // 148 1633 LINXY(__NR__sysctl, sys_sysctl), // 149 1634 //.. 1635 GENX_(__NR_mlock, sys_mlock), // 150 1636 GENX_(__NR_munlock, sys_munlock), // 151 1637 GENX_(__NR_mlockall, sys_mlockall), // 152 1638 LINX_(__NR_munlockall, sys_munlockall), // 153 1639 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154 1640 //.. 1641 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155 1642 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156 1643 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157 1644 LINX_(__NR_sched_yield, sys_sched_yield), // 158 1645 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159 1646 1647 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160 1648 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 1649 GENXY(__NR_nanosleep, sys_nanosleep), // 162 1650 GENX_(__NR_mremap, sys_mremap), // 163 1651 LINX_(__NR_setresuid, sys_setresuid), // 164 1652 1653 LINXY(__NR_getresuid, sys_getresuid), // 165 1654 1655 //.. GENX_(__NR_query_module, sys_ni_syscall), // 166 1656 GENXY(__NR_poll, sys_poll), // 167 1657 //.. // (__NR_nfsservctl, sys_nfsservctl), // 168 */Linux 1658 //.. 1659 LINX_(__NR_setresgid, sys_setresgid), // 169 1660 LINXY(__NR_getresgid, sys_getresgid), // 170 1661 LINXY(__NR_prctl, sys_prctl), // 171 1662 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 172 1663 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 173 1664 1665 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 174 1666 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 175 1667 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 176 1668 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 177 1669 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 178 1670 1671 GENXY(__NR_pread64, sys_pread64), // 179 1672 GENX_(__NR_pwrite64, sys_pwrite64), // 180 1673 GENX_(__NR_chown, sys_chown), // 181 1674 GENXY(__NR_getcwd, sys_getcwd), // 182 1675 LINXY(__NR_capget, sys_capget), // 183 1676 LINX_(__NR_capset, sys_capset), // 184 1677 GENXY(__NR_sigaltstack, sys_sigaltstack), // 185 1678 LINXY(__NR_sendfile, sys_sendfile), // 186 1679 //.. GENXY(__NR_getpmsg, sys_getpmsg), // 187 1680 //.. GENX_(__NR_putpmsg, sys_putpmsg), // 188 1681 1682 // Nb: we treat vfork as fork 1683 GENX_(__NR_vfork, sys_fork), // 189 1684 GENXY(__NR_ugetrlimit, sys_getrlimit), // 190 1685 LINX_(__NR_readahead, sys_readahead), // 191 */Linux 1686 PLAX_(__NR_mmap2, sys_mmap2), // 192 1687 GENX_(__NR_truncate64, sys_truncate64), // 193 1688 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194 1689 //.. 1690 1691 PLAXY(__NR_stat64, sys_stat64), // 195 1692 PLAXY(__NR_lstat64, sys_lstat64), // 196 1693 PLAXY(__NR_fstat64, sys_fstat64), // 197 1694 1695 // __NR_pciconfig_read // 198 1696 // __NR_pciconfig_write // 199 1697 // __NR_pciconfig_iobase // 200 1698 // __NR_multiplexer // 201 1699 1700 GENXY(__NR_getdents64, sys_getdents64), // 202 1701 //.. // (__NR_pivot_root, sys_pivot_root), // 203 */Linux 1702 LINXY(__NR_fcntl64, sys_fcntl64), // 204 1703 GENX_(__NR_madvise, sys_madvise), // 205 1704 GENXY(__NR_mincore, sys_mincore), // 206 1705 LINX_(__NR_gettid, sys_gettid), // 207 1706 //.. LINX_(__NR_tkill, sys_tkill), // 208 */Linux 1707 //.. LINX_(__NR_setxattr, sys_setxattr), // 209 1708 //.. LINX_(__NR_lsetxattr, sys_lsetxattr), // 210 1709 //.. LINX_(__NR_fsetxattr, sys_fsetxattr), // 211 1710 LINXY(__NR_getxattr, sys_getxattr), // 212 1711 LINXY(__NR_lgetxattr, sys_lgetxattr), // 213 1712 LINXY(__NR_fgetxattr, sys_fgetxattr), // 214 1713 LINXY(__NR_listxattr, sys_listxattr), // 215 1714 LINXY(__NR_llistxattr, sys_llistxattr), // 216 1715 LINXY(__NR_flistxattr, sys_flistxattr), // 217 1716 LINX_(__NR_removexattr, sys_removexattr), // 218 1717 LINX_(__NR_lremovexattr, sys_lremovexattr), // 219 1718 LINX_(__NR_fremovexattr, sys_fremovexattr), // 220 1719 1720 LINXY(__NR_futex, sys_futex), // 221 1721 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222 1722 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223 1723 /* 224 currently unused */ 1724 1725 // __NR_tuxcall // 225 1726 1727 LINXY(__NR_sendfile64, sys_sendfile64), // 226 1728 //.. 1729 LINX_(__NR_io_setup, sys_io_setup), // 227 1730 LINX_(__NR_io_destroy, sys_io_destroy), // 228 1731 LINXY(__NR_io_getevents, sys_io_getevents), // 229 1732 LINX_(__NR_io_submit, sys_io_submit), // 230 1733 LINXY(__NR_io_cancel, sys_io_cancel), // 231 1734 //.. 1735 LINX_(__NR_set_tid_address, sys_set_tid_address), // 232 1736 1737 LINX_(__NR_fadvise64, sys_fadvise64), // 233 */(Linux?) 1738 LINX_(__NR_exit_group, sys_exit_group), // 234 1739 //.. GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 235 1740 LINXY(__NR_epoll_create, sys_epoll_create), // 236 1741 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 237 1742 LINXY(__NR_epoll_wait, sys_epoll_wait), // 238 1743 1744 //.. // (__NR_remap_file_pages, sys_remap_file_pages), // 239 */Linux 1745 LINXY(__NR_timer_create, sys_timer_create), // 240 1746 LINXY(__NR_timer_settime, sys_timer_settime), // 241 1747 LINXY(__NR_timer_gettime, sys_timer_gettime), // 242 1748 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 243 1749 LINX_(__NR_timer_delete, sys_timer_delete), // 244 1750 LINX_(__NR_clock_settime, sys_clock_settime), // 245 1751 LINXY(__NR_clock_gettime, sys_clock_gettime), // 246 1752 LINXY(__NR_clock_getres, sys_clock_getres), // 247 1753 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 248 1754 1755 // __NR_swapcontext // 249 1756 1757 LINXY(__NR_tgkill, sys_tgkill), // 250 */Linux 1758 //.. GENX_(__NR_utimes, sys_utimes), // 251 1759 GENXY(__NR_statfs64, sys_statfs64), // 252 1760 GENXY(__NR_fstatfs64, sys_fstatfs64), // 253 1761 LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 254 */(Linux?) 1762 1763 // __NR_rtas // 255 1764 1765 /* Number 256 is reserved for sys_debug_setcontext */ 1766 /* Number 257 is reserved for vserver */ 1767 /* Number 258 is reserved for new sys_remap_file_pages */ 1768 /* Number 259 is reserved for new sys_mbind */ 1769 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 260 1770 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 261 1771 1772 LINXY(__NR_mq_open, sys_mq_open), // 262 1773 LINX_(__NR_mq_unlink, sys_mq_unlink), // 263 1774 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 264 1775 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 265 1776 LINX_(__NR_mq_notify, sys_mq_notify), // 266 1777 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 267 1778 // __NR_kexec_load // 268 1779 1780 /* Number 269 is reserved for sys_add_key */ 1781 /* Number 270 is reserved for sys_request_key */ 1782 /* Number 271 is reserved for sys_keyctl */ 1783 /* Number 272 is reserved for sys_waitid */ 1784 LINX_(__NR_ioprio_set, sys_ioprio_set), // 273 1785 LINX_(__NR_ioprio_get, sys_ioprio_get), // 274 1786 1787 LINX_(__NR_inotify_init, sys_inotify_init), // 275 1788 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 276 1789 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277 1790 PLAXY(__NR_spu_run, sys_spu_run), // 278 1791 PLAX_(__NR_spu_create, sys_spu_create), // 279 1792 1793 LINX_(__NR_pselect6, sys_pselect6), // 280 1794 LINXY(__NR_ppoll, sys_ppoll), // 281 1795 1796 LINXY(__NR_openat, sys_openat), // 286 1797 LINX_(__NR_mkdirat, sys_mkdirat), // 287 1798 LINX_(__NR_mknodat, sys_mknodat), // 288 1799 LINX_(__NR_fchownat, sys_fchownat), // 289 1800 LINX_(__NR_futimesat, sys_futimesat), // 290 1801 PLAXY(__NR_fstatat64, sys_fstatat64), // 291 1802 LINX_(__NR_unlinkat, sys_unlinkat), // 292 1803 LINX_(__NR_renameat, sys_renameat), // 293 1804 LINX_(__NR_linkat, sys_linkat), // 294 1805 LINX_(__NR_symlinkat, sys_symlinkat), // 295 1806 LINX_(__NR_readlinkat, sys_readlinkat), // 296 1807 LINX_(__NR_fchmodat, sys_fchmodat), // 297 1808 LINX_(__NR_faccessat, sys_faccessat), // 298 1809 LINX_(__NR_set_robust_list, sys_set_robust_list), // 299 1810 LINXY(__NR_get_robust_list, sys_get_robust_list), // 300 1811 LINXY(__NR_move_pages, sys_move_pages), // 301 1812 LINXY(__NR_getcpu, sys_getcpu), // 302 1813 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 303 1814 LINX_(__NR_utimensat, sys_utimensat), // 304 1815 LINXY(__NR_signalfd, sys_signalfd), // 305 1816 LINXY(__NR_timerfd_create, sys_timerfd_create), // 306 1817 LINX_(__NR_eventfd, sys_eventfd), // 307 1818 LINX_(__NR_sync_file_range2, sys_sync_file_range2), // 308 1819 LINX_(__NR_fallocate, sys_fallocate), // 309 1820 // LINXY(__NR_subpage_prot, sys_ni_syscall), // 310 1821 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 311 1822 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 312 1823 LINXY(__NR_signalfd4, sys_signalfd4), // 313 1824 LINX_(__NR_eventfd2, sys_eventfd2), // 314 1825 LINXY(__NR_epoll_create1, sys_epoll_create1), // 315 1826 LINXY(__NR_dup3, sys_dup3), // 316 1827 LINXY(__NR_pipe2, sys_pipe2), // 317 1828 LINXY(__NR_inotify_init1, sys_inotify_init1), // 318 1829 LINXY(__NR_perf_event_open, sys_perf_event_open), // 319 1830 LINXY(__NR_preadv, sys_preadv), // 320 1831 LINX_(__NR_pwritev, sys_pwritev), // 321 1832 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322 1833 1834 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351 1835 LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352 1836 }; 1837 1838 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) 1839 { 1840 const UInt syscall_table_size 1841 = sizeof(syscall_table) / sizeof(syscall_table[0]); 1842 1843 /* Is it in the contiguous initial section of the table? */ 1844 if (sysno < syscall_table_size) { 1845 SyscallTableEntry* sys = &syscall_table[sysno]; 1846 if (sys->before == NULL) 1847 return NULL; /* no entry */ 1848 else 1849 return sys; 1850 } 1851 1852 /* Can't find a wrapper */ 1853 return NULL; 1854 } 1855 1856 #endif // defined(VGP_ppc32_linux) 1857 1858 /*--------------------------------------------------------------------*/ 1859 /*--- end ---*/ 1860 /*--------------------------------------------------------------------*/ 1861