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