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