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-2013 Nicholas Nethercote <njn@valgrind.org> 11 Copyright (C) 2005-2013 Cerion Armour-Brown <cerion@open-works.co.uk> 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29*/ 30 31#if defined(VGP_ppc32_linux) 32 33#include "pub_core_basics.h" 34#include "pub_core_vki.h" 35#include "pub_core_vkiscnums.h" 36#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 37#include "pub_core_threadstate.h" 38#include "pub_core_aspacemgr.h" 39#include "pub_core_debuglog.h" 40#include "pub_core_libcbase.h" 41#include "pub_core_libcassert.h" 42#include "pub_core_libcprint.h" 43#include "pub_core_libcproc.h" 44#include "pub_core_libcsignal.h" 45#include "pub_core_options.h" 46#include "pub_core_scheduler.h" 47#include "pub_core_sigframe.h" // For VG_(sigframe_destroy)() 48#include "pub_core_signals.h" 49#include "pub_core_syscall.h" 50#include "pub_core_syswrap.h" 51#include "pub_core_tooliface.h" 52#include "pub_core_stacks.h" // VG_(register_stack) 53 54#include "priv_types_n_macros.h" 55#include "priv_syswrap-generic.h" /* for decls of generic wrappers */ 56#include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */ 57#include "priv_syswrap-main.h" 58 59 60/* --------------------------------------------------------------------- 61 clone() handling 62 ------------------------------------------------------------------ */ 63 64/* Call f(arg1), but first switch stacks, using 'stack' as the new 65 stack, and use 'retaddr' as f's return-to address. Also, clear all 66 the integer registers before entering f.*/ 67__attribute__((noreturn)) 68void ML_(call_on_new_stack_0_1) ( Addr stack, 69 Addr retaddr, 70 void (*f)(Word), 71 Word arg1 ); 72// r3 = stack 73// r4 = retaddr 74// r5 = f 75// r6 = arg1 76asm( 77".text\n" 78".globl vgModuleLocal_call_on_new_stack_0_1\n" 79"vgModuleLocal_call_on_new_stack_0_1:\n" 80" mr %r1,%r3\n\t" // stack to %sp 81" mtlr %r4\n\t" // retaddr to %lr 82" mtctr %r5\n\t" // f to count reg 83" mr %r3,%r6\n\t" // arg1 to %r3 84" li 0,0\n\t" // zero all GP regs 85" li 4,0\n\t" 86" li 5,0\n\t" 87" li 6,0\n\t" 88" li 7,0\n\t" 89" li 8,0\n\t" 90" li 9,0\n\t" 91" li 10,0\n\t" 92" li 11,0\n\t" 93" li 12,0\n\t" 94" li 13,0\n\t" 95" li 14,0\n\t" 96" li 15,0\n\t" 97" li 16,0\n\t" 98" li 17,0\n\t" 99" li 18,0\n\t" 100" li 19,0\n\t" 101" li 20,0\n\t" 102" li 21,0\n\t" 103" li 22,0\n\t" 104" li 23,0\n\t" 105" li 24,0\n\t" 106" li 25,0\n\t" 107" li 26,0\n\t" 108" li 27,0\n\t" 109" li 28,0\n\t" 110" li 29,0\n\t" 111" li 30,0\n\t" 112" li 31,0\n\t" 113" mtxer 0\n\t" // CAB: Need this? 114" mtcr 0\n\t" // CAB: Need this? 115" bctr\n\t" // jump to dst 116" trap\n" // should never get here 117".previous\n" 118); 119 120 121/* 122 Perform a clone system call. clone is strange because it has 123 fork()-like return-twice semantics, so it needs special 124 handling here. 125 126 Upon entry, we have: 127 128 int (fn)(void*) in r3 129 void* child_stack in r4 130 int flags in r5 131 void* arg in r6 132 pid_t* child_tid in r7 133 pid_t* parent_tid in r8 134 void* ??? in r9 135 136 System call requires: 137 138 int $__NR_clone in r0 (sc number) 139 int flags in r3 (sc arg1) 140 void* child_stack in r4 (sc arg2) 141 pid_t* parent_tid in r5 (sc arg3) 142 ?? child_tls in r6 (sc arg4) 143 pid_t* child_tid in r7 (sc arg5) 144 void* ??? in r8 (sc arg6) 145 146 Returns an Int encoded in the linux-ppc32 way, not a SysRes. 147 */ 148#define __NR_CLONE VG_STRINGIFY(__NR_clone) 149#define __NR_EXIT VG_STRINGIFY(__NR_exit) 150 151extern 152ULong do_syscall_clone_ppc32_linux ( Word (*fn)(void *), 153 void* stack, 154 Int flags, 155 void* arg, 156 Int* child_tid, 157 Int* parent_tid, 158 vki_modify_ldt_t * ); 159asm( 160".text\n" 161".globl do_syscall_clone_ppc32_linux\n" 162"do_syscall_clone_ppc32_linux:\n" 163" stwu 1,-32(1)\n" 164" stw 29,20(1)\n" 165" stw 30,24(1)\n" 166" stw 31,28(1)\n" 167" mr 30,3\n" // preserve fn 168" mr 31,6\n" // preserve arg 169 170 // setup child stack 171" rlwinm 4,4,0,~0xf\n" // trim sp to multiple of 16 bytes 172" li 0,0\n" 173" stwu 0,-16(4)\n" // make initial stack frame 174" mr 29,4\n" // preserve sp 175 176 // setup syscall 177" li 0,"__NR_CLONE"\n" // syscall number 178" mr 3,5\n" // syscall arg1: flags 179 // r4 already setup // syscall arg2: child_stack 180" mr 5,8\n" // syscall arg3: parent_tid 181" mr 6,2\n" // syscall arg4: REAL THREAD tls 182" mr 7,7\n" // syscall arg5: child_tid 183" mr 8,8\n" // syscall arg6: ???? 184" mr 9,9\n" // syscall arg7: ???? 185 186" sc\n" // clone() 187 188" mfcr 4\n" // return CR in r4 (low word of ULong) 189" cmpwi 3,0\n" // child if retval == 0 190" bne 1f\n" // jump if !child 191 192 /* CHILD - call thread function */ 193 /* Note: 2.4 kernel doesn't set the child stack pointer, 194 so we do it here. 195 That does leave a small window for a signal to be delivered 196 on the wrong stack, unfortunately. */ 197" mr 1,29\n" 198" mtctr 30\n" // ctr reg = fn 199" mr 3,31\n" // r3 = arg 200" bctrl\n" // call fn() 201 202 // exit with result 203" li 0,"__NR_EXIT"\n" 204" sc\n" 205 206 // Exit returned?! 207" .long 0\n" 208 209 // PARENT or ERROR - return 210"1: lwz 29,20(1)\n" 211" lwz 30,24(1)\n" 212" lwz 31,28(1)\n" 213" addi 1,1,32\n" 214" blr\n" 215".previous\n" 216); 217 218#undef __NR_CLONE 219#undef __NR_EXIT 220 221// forward declarations 222static void setup_child ( ThreadArchState*, ThreadArchState* ); 223 224/* 225 When a client clones, we need to keep track of the new thread. This means: 226 1. allocate a ThreadId+ThreadState+stack for the the thread 227 228 2. initialize the thread's new VCPU state 229 230 3. create the thread using the same args as the client requested, 231 but using the scheduler entrypoint for IP, and a separate stack 232 for SP. 233 */ 234static SysRes do_clone ( ThreadId ptid, 235 UInt flags, Addr sp, 236 Int *parent_tidptr, 237 Int *child_tidptr, 238 Addr child_tls) 239{ 240 const Bool debug = False; 241 242 ThreadId ctid = VG_(alloc_ThreadState)(); 243 ThreadState* ptst = VG_(get_ThreadState)(ptid); 244 ThreadState* ctst = VG_(get_ThreadState)(ctid); 245 ULong word64; 246 UWord* stack; 247 NSegment const* seg; 248 SysRes res; 249 vki_sigset_t blockall, savedmask; 250 251 VG_(sigfillset)(&blockall); 252 253 vg_assert(VG_(is_running_thread)(ptid)); 254 vg_assert(VG_(is_valid_tid)(ctid)); 255 256 stack = (UWord*)ML_(allocstack)(ctid); 257 if (stack == NULL) { 258 res = VG_(mk_SysRes_Error)( VKI_ENOMEM ); 259 goto out; 260 } 261 262//? /* make a stack frame */ 263//? stack -= 16; 264//? *(UWord *)stack = 0; 265 266 267 /* Copy register state 268 269 Both parent and child return to the same place, and the code 270 following the clone syscall works out which is which, so we 271 don't need to worry about it. 272 273 The parent gets the child's new tid returned from clone, but the 274 child gets 0. 275 276 If the clone call specifies a NULL SP for the new thread, then 277 it actually gets a copy of the parent's SP. 278 279 The child's TLS register (r2) gets set to the tlsaddr argument 280 if the CLONE_SETTLS flag is set. 281 */ 282 setup_child( &ctst->arch, &ptst->arch ); 283 284 /* Make sys_clone appear to have returned Success(0) in the 285 child. */ 286 { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex ); 287 /* %r3 = 0 */ 288 ctst->arch.vex.guest_GPR3 = 0; 289 /* %cr0.so = 0 */ 290 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex ); 291 } 292 293 if (sp != 0) 294 ctst->arch.vex.guest_GPR1 = sp; 295 296 ctst->os_state.parent = ptid; 297 298 /* inherit signal mask */ 299 ctst->sig_mask = ptst->sig_mask; 300 ctst->tmp_sig_mask = ptst->sig_mask; 301 302 /* Start the child with its threadgroup being the same as the 303 parent's. This is so that any exit_group calls that happen 304 after the child is created but before it sets its 305 os_state.threadgroup field for real (in thread_wrapper in 306 syswrap-linux.c), really kill the new thread. a.k.a this avoids 307 a race condition in which the thread is unkillable (via 308 exit_group) because its threadgroup is not set. The race window 309 is probably only a few hundred or a few thousand cycles long. 310 See #226116. */ 311 ctst->os_state.threadgroup = ptst->os_state.threadgroup; 312 313 /* We don't really know where the client stack is, because its 314 allocated by the client. The best we can do is look at the 315 memory mappings and try to derive some useful information. We 316 assume that esp starts near its highest possible value, and can 317 only go down to the start of the mmaped segment. */ 318 seg = VG_(am_find_nsegment)(sp); 319 if (seg && seg->kind != SkResvn) { 320 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp); 321 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start; 322 323 VG_(register_stack)(seg->start, ctst->client_stack_highest_word); 324 325 if (debug) 326 VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n", 327 ctid, seg->start, VG_PGROUNDUP(sp)); 328 } else { 329 VG_(message)(Vg_UserMsg, 330 "!? New thread %d starts with R1(%#lx) unmapped\n", 331 ctid, sp); 332 ctst->client_stack_szB = 0; 333 } 334 335 /* Assume the clone will succeed, and tell any tool that wants to 336 know that this thread has come into existence. If the clone 337 fails, we'll send out a ll_exit notification for it at the out: 338 label below, to clean up. */ 339 vg_assert(VG_(owns_BigLock_LL)(ptid)); 340 VG_TRACK ( pre_thread_ll_create, ptid, ctid ); 341 342 if (flags & VKI_CLONE_SETTLS) { 343 if (debug) 344 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls); 345 ctst->arch.vex.guest_GPR2 = child_tls; 346 } 347 348 flags &= ~VKI_CLONE_SETTLS; 349 350 /* start the thread with everything blocked */ 351 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask); 352 353 /* Create the new thread */ 354 word64 = do_syscall_clone_ppc32_linux( 355 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid], 356 child_tidptr, parent_tidptr, NULL 357 ); 358 /* High half word64 is syscall return value. Low half is 359 the entire CR, from which we need to extract CR0.SO. */ 360 /* VG_(printf)("word64 = 0x%llx\n", word64); */ 361 res = VG_(mk_SysRes_ppc32_linux)( 362 /*val*/(UInt)(word64 >> 32), 363 /*errflag*/ (((UInt)word64) >> 28) & 1 364 ); 365 366 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL); 367 368 out: 369 if (sr_isError(res)) { 370 /* clone failed */ 371 VG_(cleanup_thread)(&ctst->arch); 372 ctst->status = VgTs_Empty; 373 /* oops. Better tell the tool the thread exited in a hurry :-) */ 374 VG_TRACK( pre_thread_ll_exit, ctid ); 375 } 376 377 return res; 378} 379 380 381 382/* --------------------------------------------------------------------- 383 More thread stuff 384 ------------------------------------------------------------------ */ 385 386void VG_(cleanup_thread) ( ThreadArchState* arch ) 387{ 388} 389 390void setup_child ( /*OUT*/ ThreadArchState *child, 391 /*IN*/ ThreadArchState *parent ) 392{ 393 /* We inherit our parent's guest state. */ 394 child->vex = parent->vex; 395 child->vex_shadow1 = parent->vex_shadow1; 396 child->vex_shadow2 = parent->vex_shadow2; 397} 398 399 400/* --------------------------------------------------------------------- 401 PRE/POST wrappers for ppc32/Linux-specific syscalls 402 ------------------------------------------------------------------ */ 403 404#define PRE(name) DEFN_PRE_TEMPLATE(ppc32_linux, name) 405#define POST(name) DEFN_POST_TEMPLATE(ppc32_linux, name) 406 407/* Add prototypes for the wrappers declared here, so that gcc doesn't 408 harass us for not having prototypes. Really this is a kludge -- 409 the right thing to do is to make these wrappers 'static' since they 410 aren't visible outside this file, but that requires even more macro 411 magic. */ 412 413DECL_TEMPLATE(ppc32_linux, sys_mmap); 414DECL_TEMPLATE(ppc32_linux, sys_mmap2); 415DECL_TEMPLATE(ppc32_linux, sys_stat64); 416DECL_TEMPLATE(ppc32_linux, sys_lstat64); 417DECL_TEMPLATE(ppc32_linux, sys_fstatat64); 418DECL_TEMPLATE(ppc32_linux, sys_fstat64); 419DECL_TEMPLATE(ppc32_linux, sys_clone); 420DECL_TEMPLATE(ppc32_linux, sys_sigreturn); 421DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn); 422DECL_TEMPLATE(ppc32_linux, sys_sigsuspend); 423DECL_TEMPLATE(ppc32_linux, sys_spu_create); 424DECL_TEMPLATE(ppc32_linux, sys_spu_run); 425 426PRE(sys_mmap) 427{ 428 SysRes r; 429 430 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )", 431 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 ); 432 PRE_REG_READ6(long, "mmap", 433 unsigned long, start, unsigned long, length, 434 unsigned long, prot, unsigned long, flags, 435 unsigned long, fd, unsigned long, offset); 436 437 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 438 (Off64T)ARG6 ); 439 SET_STATUS_from_SysRes(r); 440} 441 442PRE(sys_mmap2) 443{ 444 SysRes r; 445 446 // Exactly like old_mmap() except: 447 // - the file offset is specified in 4K units rather than bytes, 448 // so that it can be used for files bigger than 2^32 bytes. 449 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", 450 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 ); 451 PRE_REG_READ6(long, "mmap2", 452 unsigned long, start, unsigned long, length, 453 unsigned long, prot, unsigned long, flags, 454 unsigned long, fd, unsigned long, offset); 455 456 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 457 4096 * (Off64T)ARG6 ); 458 SET_STATUS_from_SysRes(r); 459} 460 461// XXX: lstat64/fstat64/stat64 are generic, but not necessarily 462// applicable to every architecture -- I think only to 32-bit archs. 463// We're going to need something like linux/core_os32.h for such 464// things, eventually, I think. --njn 465PRE(sys_stat64) 466{ 467 PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2); 468 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf); 469 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 ); 470 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); 471} 472 473POST(sys_stat64) 474{ 475 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 476} 477 478PRE(sys_lstat64) 479{ 480 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 481 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf); 482 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 ); 483 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 484} 485 486POST(sys_lstat64) 487{ 488 vg_assert(SUCCESS); 489 if (RES == 0) { 490 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 491 } 492} 493 494PRE(sys_fstatat64) 495{ 496 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3); 497 PRE_REG_READ3(long, "fstatat64", 498 int, dfd, char *, file_name, struct stat64 *, buf); 499 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); 500 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); 501} 502 503POST(sys_fstatat64) 504{ 505 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); 506} 507 508PRE(sys_fstat64) 509{ 510 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2); 511 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf); 512 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 513} 514 515POST(sys_fstat64) 516{ 517 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 518} 519 520 521 522//.. PRE(old_select, MayBlock) 523//.. { 524//.. /* struct sel_arg_struct { 525//.. unsigned long n; 526//.. fd_set *inp, *outp, *exp; 527//.. struct timeval *tvp; 528//.. }; 529//.. */ 530//.. PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args); 531//.. PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) ); 532//.. 533//.. { 534//.. UInt* arg_struct = (UInt*)ARG1; 535//.. UInt a1, a2, a3, a4, a5; 536//.. 537//.. a1 = arg_struct[0]; 538//.. a2 = arg_struct[1]; 539//.. a3 = arg_struct[2]; 540//.. a4 = arg_struct[3]; 541//.. a5 = arg_struct[4]; 542//.. 543//.. PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5); 544//.. if (a2 != (Addr)NULL) 545//.. PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ ); 546//.. if (a3 != (Addr)NULL) 547//.. PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ ); 548//.. if (a4 != (Addr)NULL) 549//.. PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ ); 550//.. if (a5 != (Addr)NULL) 551//.. PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) ); 552//.. } 553//.. } 554 555PRE(sys_clone) 556{ 557 UInt cloneflags; 558 559 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5); 560 PRE_REG_READ5(int, "clone", 561 unsigned long, flags, 562 void *, child_stack, 563 int *, parent_tidptr, 564 void *, child_tls, 565 int *, child_tidptr); 566 567 if (ARG1 & VKI_CLONE_PARENT_SETTID) { 568 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int)); 569 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 570 VKI_PROT_WRITE)) { 571 SET_STATUS_Failure( VKI_EFAULT ); 572 return; 573 } 574 } 575 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) { 576 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int)); 577 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 578 VKI_PROT_WRITE)) { 579 SET_STATUS_Failure( VKI_EFAULT ); 580 return; 581 } 582 } 583 584 cloneflags = ARG1; 585 586 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) { 587 SET_STATUS_Failure( VKI_EINVAL ); 588 return; 589 } 590 591 /* Only look at the flags we really care about */ 592 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 593 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) { 594 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: 595 /* thread creation */ 596 SET_STATUS_from_SysRes( 597 do_clone(tid, 598 ARG1, /* flags */ 599 (Addr)ARG2, /* child SP */ 600 (Int *)ARG3, /* parent_tidptr */ 601 (Int *)ARG5, /* child_tidptr */ 602 (Addr)ARG4)); /* child_tls */ 603 break; 604 605 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ 606 /* FALLTHROUGH - assume vfork == fork */ 607 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); 608 609 case 0: /* plain fork */ 610 SET_STATUS_from_SysRes( 611 ML_(do_fork_clone)(tid, 612 cloneflags, /* flags */ 613 (Int *)ARG3, /* parent_tidptr */ 614 (Int *)ARG5)); /* child_tidptr */ 615 break; 616 617 default: 618 /* should we just ENOSYS? */ 619 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1); 620 VG_(message)(Vg_UserMsg, "\n"); 621 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n"); 622 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n"); 623 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n"); 624 VG_(unimplemented) 625 ("Valgrind does not support general clone()."); 626 } 627 628 if (SUCCESS) { 629 if (ARG1 & VKI_CLONE_PARENT_SETTID) 630 POST_MEM_WRITE(ARG3, sizeof(Int)); 631 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 632 POST_MEM_WRITE(ARG5, sizeof(Int)); 633 634 /* Thread creation was successful; let the child have the chance 635 to run */ 636 *flags |= SfYieldAfter; 637 } 638} 639 640PRE(sys_sigreturn) 641{ 642 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 643 an explanation of what follows. */ 644 645 //ThreadState* tst; 646 PRINT("sys_sigreturn ( )"); 647 648 vg_assert(VG_(is_valid_tid)(tid)); 649 vg_assert(tid >= 1 && tid < VG_N_THREADS); 650 vg_assert(VG_(is_running_thread)(tid)); 651 652 ///* Adjust esp to point to start of frame; skip back up over 653 // sigreturn sequence's "popl %eax" and handler ret addr */ 654 //tst = VG_(get_ThreadState)(tid); 655 //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word); 656 // Should we do something equivalent on ppc32? Who knows. 657 658 ///* This is only so that the EIP is (might be) useful to report if 659 // something goes wrong in the sigreturn */ 660 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch); 661 // Should we do something equivalent on ppc32? Who knows. 662 663 /* Restore register state from frame and remove it */ 664 VG_(sigframe_destroy)(tid, False); 665 666 /* Tell the driver not to update the guest state with the "result", 667 and set a bogus result to keep it happy. */ 668 *flags |= SfNoWriteResult; 669 SET_STATUS_Success(0); 670 671 /* Check to see if any signals arose as a result of this. */ 672 *flags |= SfPollAfter; 673} 674 675PRE(sys_rt_sigreturn) 676{ 677 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 678 an explanation of what follows. */ 679 680 //ThreadState* tst; 681 PRINT("rt_sigreturn ( )"); 682 683 vg_assert(VG_(is_valid_tid)(tid)); 684 vg_assert(tid >= 1 && tid < VG_N_THREADS); 685 vg_assert(VG_(is_running_thread)(tid)); 686 687 ///* Adjust esp to point to start of frame; skip back up over handler 688 // ret addr */ 689 //tst = VG_(get_ThreadState)(tid); 690 //tst->arch.vex.guest_ESP -= sizeof(Addr); 691 // Should we do something equivalent on ppc32? Who knows. 692 693 ///* This is only so that the EIP is (might be) useful to report if 694 // something goes wrong in the sigreturn */ 695 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch); 696 // Should we do something equivalent on ppc32? Who knows. 697 698 /* Restore register state from frame and remove it */ 699 VG_(sigframe_destroy)(tid, True); 700 701 /* Tell the driver not to update the guest state with the "result", 702 and set a bogus result to keep it happy. */ 703 *flags |= SfNoWriteResult; 704 SET_STATUS_Success(0); 705 706 /* Check to see if any signals arose as a result of this. */ 707 *flags |= SfPollAfter; 708} 709 710 711//.. PRE(sys_modify_ldt, Special) 712//.. { 713//.. PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3); 714//.. PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr, 715//.. unsigned long, bytecount); 716//.. 717//.. if (ARG1 == 0) { 718//.. /* read the LDT into ptr */ 719//.. PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 ); 720//.. } 721//.. if (ARG1 == 1 || ARG1 == 0x11) { 722//.. /* write the LDT with the entry pointed at by ptr */ 723//.. PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) ); 724//.. } 725//.. /* "do" the syscall ourselves; the kernel never sees it */ 726//.. SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) ); 727//.. 728//.. if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) { 729//.. POST_MEM_WRITE( ARG2, RES ); 730//.. } 731//.. } 732 733//.. PRE(sys_set_thread_area, Special) 734//.. { 735//.. PRINT("sys_set_thread_area ( %p )", ARG1); 736//.. PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info) 737//.. PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) ); 738//.. 739//.. /* "do" the syscall ourselves; the kernel never sees it */ 740//.. SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) ); 741//.. } 742 743//.. PRE(sys_get_thread_area, Special) 744//.. { 745//.. PRINT("sys_get_thread_area ( %p )", ARG1); 746//.. PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info) 747//.. PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) ); 748//.. 749//.. /* "do" the syscall ourselves; the kernel never sees it */ 750//.. SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) ); 751//.. 752//.. if (!VG_(is_kerror)(RES)) { 753//.. POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) ); 754//.. } 755//.. } 756 757//.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic. 758//.. // XXX: Why is the memory pointed to by ARG3 never checked? 759//.. PRE(sys_ptrace, 0) 760//.. { 761//.. PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4); 762//.. PRE_REG_READ4(int, "ptrace", 763//.. long, request, long, pid, long, addr, long, data); 764//.. switch (ARG1) { 765//.. case VKI_PTRACE_PEEKTEXT: 766//.. case VKI_PTRACE_PEEKDATA: 767//.. case VKI_PTRACE_PEEKUSR: 768//.. PRE_MEM_WRITE( "ptrace(peek)", ARG4, 769//.. sizeof (long)); 770//.. break; 771//.. case VKI_PTRACE_GETREGS: 772//.. PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 773//.. sizeof (struct vki_user_regs_struct)); 774//.. break; 775//.. case VKI_PTRACE_GETFPREGS: 776//.. PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 777//.. sizeof (struct vki_user_i387_struct)); 778//.. break; 779//.. case VKI_PTRACE_GETFPXREGS: 780//.. PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4, 781//.. sizeof(struct vki_user_fxsr_struct) ); 782//.. break; 783//.. case VKI_PTRACE_SETREGS: 784//.. PRE_MEM_READ( "ptrace(setregs)", ARG4, 785//.. sizeof (struct vki_user_regs_struct)); 786//.. break; 787//.. case VKI_PTRACE_SETFPREGS: 788//.. PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 789//.. sizeof (struct vki_user_i387_struct)); 790//.. break; 791//.. case VKI_PTRACE_SETFPXREGS: 792//.. PRE_MEM_READ( "ptrace(setfpxregs)", ARG4, 793//.. sizeof(struct vki_user_fxsr_struct) ); 794//.. break; 795//.. default: 796//.. break; 797//.. } 798//.. } 799 800//.. POST(sys_ptrace) 801//.. { 802//.. switch (ARG1) { 803//.. case VKI_PTRACE_PEEKTEXT: 804//.. case VKI_PTRACE_PEEKDATA: 805//.. case VKI_PTRACE_PEEKUSR: 806//.. POST_MEM_WRITE( ARG4, sizeof (long)); 807//.. break; 808//.. case VKI_PTRACE_GETREGS: 809//.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct)); 810//.. break; 811//.. case VKI_PTRACE_GETFPREGS: 812//.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct)); 813//.. break; 814//.. case VKI_PTRACE_GETFPXREGS: 815//.. POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) ); 816//.. break; 817//.. default: 818//.. break; 819//.. } 820//.. } 821 822/* NB: This is an almost identical clone of versions for x86-linux and 823 arm-linux, which are themselves literally identical. */ 824PRE(sys_sigsuspend) 825{ 826 /* The C library interface to sigsuspend just takes a pointer to 827 a signal mask but this system call only takes the first word of 828 the signal mask as an argument so only 32 signals are supported. 829 830 In fact glibc normally uses rt_sigsuspend if it is available as 831 that takes a pointer to the signal mask so supports more signals. 832 */ 833 *flags |= SfMayBlock; 834 PRINT("sys_sigsuspend ( %ld )", ARG1 ); 835 PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask); 836} 837 838PRE(sys_spu_create) 839{ 840 PRE_MEM_RASCIIZ("stat64(filename)", ARG1); 841} 842POST(sys_spu_create) 843{ 844 vg_assert(SUCCESS); 845} 846 847PRE(sys_spu_run) 848{ 849 *flags |= SfMayBlock; 850 if (ARG2 != 0) 851 PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int)); 852 PRE_MEM_READ("event", ARG3, sizeof(unsigned int)); 853} 854POST(sys_spu_run) 855{ 856 if (ARG2 != 0) 857 POST_MEM_WRITE(ARG2, sizeof(unsigned int)); 858} 859 860#undef PRE 861#undef POST 862 863/* --------------------------------------------------------------------- 864 The ppc32/Linux syscall table 865 ------------------------------------------------------------------ */ 866 867/* Add an ppc32-linux specific wrapper to a syscall table. */ 868#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc32_linux, sysno, name) 869#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(ppc32_linux, sysno, name) 870 871// This table maps from __NR_xxx syscall numbers (from 872// linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo() 873// wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S). 874// 875// For those syscalls not handled by Valgrind, the annotation indicate its 876// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? 877// (unknown). 878 879static SyscallTableEntry syscall_table[] = { 880//.. (restart_syscall) // 0 881 GENX_(__NR_exit, sys_exit), // 1 882 GENX_(__NR_fork, sys_fork), // 2 883 GENXY(__NR_read, sys_read), // 3 884 GENX_(__NR_write, sys_write), // 4 885 886 GENXY(__NR_open, sys_open), // 5 887 GENXY(__NR_close, sys_close), // 6 888 GENXY(__NR_waitpid, sys_waitpid), // 7 889 GENXY(__NR_creat, sys_creat), // 8 890 GENX_(__NR_link, sys_link), // 9 891 892 GENX_(__NR_unlink, sys_unlink), // 10 893 GENX_(__NR_execve, sys_execve), // 11 894 GENX_(__NR_chdir, sys_chdir), // 12 895 GENXY(__NR_time, sys_time), // 13 896 GENX_(__NR_mknod, sys_mknod), // 14 897//.. 898 GENX_(__NR_chmod, sys_chmod), // 15 899 GENX_(__NR_lchown, sys_lchown), // 16 ## P 900//.. GENX_(__NR_break, sys_ni_syscall), // 17 901//.. // (__NR_oldstat, sys_stat), // 18 (obsolete) 902 LINX_(__NR_lseek, sys_lseek), // 19 903//.. 904 GENX_(__NR_getpid, sys_getpid), // 20 905 LINX_(__NR_mount, sys_mount), // 21 906 LINX_(__NR_umount, sys_oldumount), // 22 907 GENX_(__NR_setuid, sys_setuid), // 23 ## P 908 GENX_(__NR_getuid, sys_getuid), // 24 ## P 909//.. 910//.. // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN) 911//.. PLAXY(__NR_ptrace, sys_ptrace), // 26 912 GENX_(__NR_alarm, sys_alarm), // 27 913//.. // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete 914 GENX_(__NR_pause, sys_pause), // 29 915//.. 916 LINX_(__NR_utime, sys_utime), // 30 917//.. GENX_(__NR_stty, sys_ni_syscall), // 31 918//.. GENX_(__NR_gtty, sys_ni_syscall), // 32 919 GENX_(__NR_access, sys_access), // 33 920//.. GENX_(__NR_nice, sys_nice), // 34 921//.. 922//.. GENX_(__NR_ftime, sys_ni_syscall), // 35 923//.. GENX_(__NR_sync, sys_sync), // 36 924 GENX_(__NR_kill, sys_kill), // 37 925 GENX_(__NR_rename, sys_rename), // 38 926 GENX_(__NR_mkdir, sys_mkdir), // 39 927 928 GENX_(__NR_rmdir, sys_rmdir), // 40 929 GENXY(__NR_dup, sys_dup), // 41 930 LINXY(__NR_pipe, sys_pipe), // 42 931 GENXY(__NR_times, sys_times), // 43 932//.. GENX_(__NR_prof, sys_ni_syscall), // 44 933//.. 934 GENX_(__NR_brk, sys_brk), // 45 935 GENX_(__NR_setgid, sys_setgid), // 46 936 GENX_(__NR_getgid, sys_getgid), // 47 937//.. // (__NR_signal, sys_signal), // 48 */* (ANSI C) 938 GENX_(__NR_geteuid, sys_geteuid), // 49 939 940 GENX_(__NR_getegid, sys_getegid), // 50 941//.. GENX_(__NR_acct, sys_acct), // 51 942 LINX_(__NR_umount2, sys_umount), // 52 943//.. GENX_(__NR_lock, sys_ni_syscall), // 53 944 LINXY(__NR_ioctl, sys_ioctl), // 54 945//.. 946 LINXY(__NR_fcntl, sys_fcntl), // 55 947//.. GENX_(__NR_mpx, sys_ni_syscall), // 56 948 GENX_(__NR_setpgid, sys_setpgid), // 57 949//.. GENX_(__NR_ulimit, sys_ni_syscall), // 58 950//.. // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete 951 952 GENX_(__NR_umask, sys_umask), // 60 953 GENX_(__NR_chroot, sys_chroot), // 61 954//.. // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated 955 GENXY(__NR_dup2, sys_dup2), // 63 956 GENX_(__NR_getppid, sys_getppid), // 64 957 958 GENX_(__NR_getpgrp, sys_getpgrp), // 65 959 GENX_(__NR_setsid, sys_setsid), // 66 960 LINXY(__NR_sigaction, sys_sigaction), // 67 961//.. // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C) 962//.. // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C) 963//.. 964 GENX_(__NR_setreuid, sys_setreuid), // 70 965 GENX_(__NR_setregid, sys_setregid), // 71 966 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72 967 LINXY(__NR_sigpending, sys_sigpending), // 73 968//.. // (__NR_sethostname, sys_sethostname), // 74 */* 969//.. 970 GENX_(__NR_setrlimit, sys_setrlimit), // 75 971//.. GENXY(__NR_getrlimit, sys_old_getrlimit), // 76 972 GENXY(__NR_getrusage, sys_getrusage), // 77 973 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78 974//.. GENX_(__NR_settimeofday, sys_settimeofday), // 79 975//.. 976 GENXY(__NR_getgroups, sys_getgroups), // 80 977 GENX_(__NR_setgroups, sys_setgroups), // 81 978//.. PLAX_(__NR_select, old_select), // 82 979 GENX_(__NR_symlink, sys_symlink), // 83 980//.. // (__NR_oldlstat, sys_lstat), // 84 -- obsolete 981//.. 982 GENX_(__NR_readlink, sys_readlink), // 85 983//.. // (__NR_uselib, sys_uselib), // 86 */Linux 984//.. // (__NR_swapon, sys_swapon), // 87 */Linux 985//.. // (__NR_reboot, sys_reboot), // 88 */Linux 986//.. // (__NR_readdir, old_readdir), // 89 -- superseded 987 988 PLAX_(__NR_mmap, sys_mmap), // 90 989 GENXY(__NR_munmap, sys_munmap), // 91 990 GENX_(__NR_truncate, sys_truncate), // 92 991 GENX_(__NR_ftruncate, sys_ftruncate), // 93 992 GENX_(__NR_fchmod, sys_fchmod), // 94 993 994 GENX_(__NR_fchown, sys_fchown), // 95 995 GENX_(__NR_getpriority, sys_getpriority), // 96 996 GENX_(__NR_setpriority, sys_setpriority), // 97 997//.. GENX_(__NR_profil, sys_ni_syscall), // 98 998 GENXY(__NR_statfs, sys_statfs), // 99 999//.. 1000 GENXY(__NR_fstatfs, sys_fstatfs), // 100 1001//.. LINX_(__NR_ioperm, sys_ioperm), // 101 1002 LINXY(__NR_socketcall, sys_socketcall), // 102 1003 LINXY(__NR_syslog, sys_syslog), // 103 1004 GENXY(__NR_setitimer, sys_setitimer), // 104 1005 1006 GENXY(__NR_getitimer, sys_getitimer), // 105 1007 GENXY(__NR_stat, sys_newstat), // 106 1008 GENXY(__NR_lstat, sys_newlstat), // 107 1009 GENXY(__NR_fstat, sys_newfstat), // 108 1010//.. // (__NR_olduname, sys_uname), // 109 -- obsolete 1011//.. 1012//.. GENX_(__NR_iopl, sys_iopl), // 110 1013 LINX_(__NR_vhangup, sys_vhangup), // 111 1014//.. GENX_(__NR_idle, sys_ni_syscall), // 112 1015//.. // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only 1016 GENXY(__NR_wait4, sys_wait4), // 114 1017//.. 1018//.. // (__NR_swapoff, sys_swapoff), // 115 */Linux 1019 LINXY(__NR_sysinfo, sys_sysinfo), // 116 1020 LINXY(__NR_ipc, sys_ipc), // 117 1021 GENX_(__NR_fsync, sys_fsync), // 118 1022 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux 1023//.. 1024 PLAX_(__NR_clone, sys_clone), // 120 1025//.. // (__NR_setdomainname, sys_setdomainname), // 121 */*(?) 1026 GENXY(__NR_uname, sys_newuname), // 122 1027//.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123 1028 LINXY(__NR_adjtimex, sys_adjtimex), // 124 1029 1030 GENXY(__NR_mprotect, sys_mprotect), // 125 1031 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126 1032 GENX_(__NR_create_module, sys_ni_syscall), // 127 1033 LINX_(__NR_init_module, sys_init_module), // 128 1034 LINX_(__NR_delete_module, sys_delete_module), // 129 1035//.. 1036//.. // Nb: get_kernel_syms() was removed 2.4-->2.6 1037//.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 1038//.. LINX_(__NR_quotactl, sys_quotactl), // 131 1039 GENX_(__NR_getpgid, sys_getpgid), // 132 1040 GENX_(__NR_fchdir, sys_fchdir), // 133 1041//.. // (__NR_bdflush, sys_bdflush), // 134 */Linux 1042//.. 1043//.. // (__NR_sysfs, sys_sysfs), // 135 SVr4 1044 LINX_(__NR_personality, sys_personality), // 136 1045//.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137 1046 LINX_(__NR_setfsuid, sys_setfsuid), // 138 1047 LINX_(__NR_setfsgid, sys_setfsgid), // 139 1048 1049 LINXY(__NR__llseek, sys_llseek), // 140 1050 GENXY(__NR_getdents, sys_getdents), // 141 1051 GENX_(__NR__newselect, sys_select), // 142 1052 GENX_(__NR_flock, sys_flock), // 143 1053 GENX_(__NR_msync, sys_msync), // 144 1054//.. 1055 GENXY(__NR_readv, sys_readv), // 145 1056 GENX_(__NR_writev, sys_writev), // 146 1057 GENX_(__NR_getsid, sys_getsid), // 147 1058 GENX_(__NR_fdatasync, sys_fdatasync), // 148 1059 LINXY(__NR__sysctl, sys_sysctl), // 149 1060//.. 1061 GENX_(__NR_mlock, sys_mlock), // 150 1062 GENX_(__NR_munlock, sys_munlock), // 151 1063 GENX_(__NR_mlockall, sys_mlockall), // 152 1064 LINX_(__NR_munlockall, sys_munlockall), // 153 1065 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154 1066//.. 1067 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155 1068 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156 1069 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157 1070 LINX_(__NR_sched_yield, sys_sched_yield), // 158 1071 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159 1072 1073 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160 1074 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 1075 GENXY(__NR_nanosleep, sys_nanosleep), // 162 1076 GENX_(__NR_mremap, sys_mremap), // 163 1077 LINX_(__NR_setresuid, sys_setresuid), // 164 1078 1079 LINXY(__NR_getresuid, sys_getresuid), // 165 1080 1081//.. GENX_(__NR_query_module, sys_ni_syscall), // 166 1082 GENXY(__NR_poll, sys_poll), // 167 1083//.. // (__NR_nfsservctl, sys_nfsservctl), // 168 */Linux 1084//.. 1085 LINX_(__NR_setresgid, sys_setresgid), // 169 1086 LINXY(__NR_getresgid, sys_getresgid), // 170 1087 LINXY(__NR_prctl, sys_prctl), // 171 1088 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 172 1089 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 173 1090 1091 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 174 1092 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 175 1093 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 176 1094 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 177 1095 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 178 1096 1097 GENXY(__NR_pread64, sys_pread64), // 179 1098 GENX_(__NR_pwrite64, sys_pwrite64), // 180 1099 GENX_(__NR_chown, sys_chown), // 181 1100 GENXY(__NR_getcwd, sys_getcwd), // 182 1101 LINXY(__NR_capget, sys_capget), // 183 1102 LINX_(__NR_capset, sys_capset), // 184 1103 GENXY(__NR_sigaltstack, sys_sigaltstack), // 185 1104 LINXY(__NR_sendfile, sys_sendfile), // 186 1105//.. GENXY(__NR_getpmsg, sys_getpmsg), // 187 1106//.. GENX_(__NR_putpmsg, sys_putpmsg), // 188 1107 1108 // Nb: we treat vfork as fork 1109 GENX_(__NR_vfork, sys_fork), // 189 1110 GENXY(__NR_ugetrlimit, sys_getrlimit), // 190 1111 LINX_(__NR_readahead, sys_readahead), // 191 */Linux 1112 PLAX_(__NR_mmap2, sys_mmap2), // 192 1113 GENX_(__NR_truncate64, sys_truncate64), // 193 1114 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194 1115//.. 1116 1117 PLAXY(__NR_stat64, sys_stat64), // 195 1118 PLAXY(__NR_lstat64, sys_lstat64), // 196 1119 PLAXY(__NR_fstat64, sys_fstat64), // 197 1120 1121// __NR_pciconfig_read // 198 1122// __NR_pciconfig_write // 199 1123// __NR_pciconfig_iobase // 200 1124// __NR_multiplexer // 201 1125 1126 GENXY(__NR_getdents64, sys_getdents64), // 202 1127//.. // (__NR_pivot_root, sys_pivot_root), // 203 */Linux 1128 LINXY(__NR_fcntl64, sys_fcntl64), // 204 1129 GENX_(__NR_madvise, sys_madvise), // 205 1130 GENXY(__NR_mincore, sys_mincore), // 206 1131 LINX_(__NR_gettid, sys_gettid), // 207 1132//.. LINX_(__NR_tkill, sys_tkill), // 208 */Linux 1133 LINX_(__NR_setxattr, sys_setxattr), // 209 1134 LINX_(__NR_lsetxattr, sys_lsetxattr), // 210 1135 LINX_(__NR_fsetxattr, sys_fsetxattr), // 211 1136 LINXY(__NR_getxattr, sys_getxattr), // 212 1137 LINXY(__NR_lgetxattr, sys_lgetxattr), // 213 1138 LINXY(__NR_fgetxattr, sys_fgetxattr), // 214 1139 LINXY(__NR_listxattr, sys_listxattr), // 215 1140 LINXY(__NR_llistxattr, sys_llistxattr), // 216 1141 LINXY(__NR_flistxattr, sys_flistxattr), // 217 1142 LINX_(__NR_removexattr, sys_removexattr), // 218 1143 LINX_(__NR_lremovexattr, sys_lremovexattr), // 219 1144 LINX_(__NR_fremovexattr, sys_fremovexattr), // 220 1145 1146 LINXY(__NR_futex, sys_futex), // 221 1147 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222 1148 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223 1149/* 224 currently unused */ 1150 1151// __NR_tuxcall // 225 1152 1153 LINXY(__NR_sendfile64, sys_sendfile64), // 226 1154//.. 1155 LINX_(__NR_io_setup, sys_io_setup), // 227 1156 LINX_(__NR_io_destroy, sys_io_destroy), // 228 1157 LINXY(__NR_io_getevents, sys_io_getevents), // 229 1158 LINX_(__NR_io_submit, sys_io_submit), // 230 1159 LINXY(__NR_io_cancel, sys_io_cancel), // 231 1160//.. 1161 LINX_(__NR_set_tid_address, sys_set_tid_address), // 232 1162 1163 LINX_(__NR_fadvise64, sys_fadvise64), // 233 */(Linux?) 1164 LINX_(__NR_exit_group, sys_exit_group), // 234 1165//.. GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 235 1166 LINXY(__NR_epoll_create, sys_epoll_create), // 236 1167 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 237 1168 LINXY(__NR_epoll_wait, sys_epoll_wait), // 238 1169 1170//.. // (__NR_remap_file_pages, sys_remap_file_pages), // 239 */Linux 1171 LINXY(__NR_timer_create, sys_timer_create), // 240 1172 LINXY(__NR_timer_settime, sys_timer_settime), // 241 1173 LINXY(__NR_timer_gettime, sys_timer_gettime), // 242 1174 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 243 1175 LINX_(__NR_timer_delete, sys_timer_delete), // 244 1176 LINX_(__NR_clock_settime, sys_clock_settime), // 245 1177 LINXY(__NR_clock_gettime, sys_clock_gettime), // 246 1178 LINXY(__NR_clock_getres, sys_clock_getres), // 247 1179 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 248 1180 1181// __NR_swapcontext // 249 1182 1183 LINXY(__NR_tgkill, sys_tgkill), // 250 */Linux 1184//.. GENX_(__NR_utimes, sys_utimes), // 251 1185 GENXY(__NR_statfs64, sys_statfs64), // 252 1186 GENXY(__NR_fstatfs64, sys_fstatfs64), // 253 1187 LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 254 */(Linux?) 1188 1189// __NR_rtas // 255 1190 1191/* Number 256 is reserved for sys_debug_setcontext */ 1192/* Number 257 is reserved for vserver */ 1193/* Number 258 is reserved for new sys_remap_file_pages */ 1194 LINX_(__NR_mbind, sys_mbind), // 259 1195 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 260 1196 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 261 1197 1198 LINXY(__NR_mq_open, sys_mq_open), // 262 1199 LINX_(__NR_mq_unlink, sys_mq_unlink), // 263 1200 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 264 1201 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 265 1202 LINX_(__NR_mq_notify, sys_mq_notify), // 266 1203 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 267 1204// __NR_kexec_load // 268 1205 1206/* Number 269 is reserved for sys_add_key */ 1207/* Number 270 is reserved for sys_request_key */ 1208/* Number 271 is reserved for sys_keyctl */ 1209/* Number 272 is reserved for sys_waitid */ 1210 LINX_(__NR_ioprio_set, sys_ioprio_set), // 273 1211 LINX_(__NR_ioprio_get, sys_ioprio_get), // 274 1212 1213 LINX_(__NR_inotify_init, sys_inotify_init), // 275 1214 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 276 1215 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277 1216 PLAXY(__NR_spu_run, sys_spu_run), // 278 1217 PLAX_(__NR_spu_create, sys_spu_create), // 279 1218 1219 LINX_(__NR_pselect6, sys_pselect6), // 280 1220 LINXY(__NR_ppoll, sys_ppoll), // 281 1221 1222 LINXY(__NR_openat, sys_openat), // 286 1223 LINX_(__NR_mkdirat, sys_mkdirat), // 287 1224 LINX_(__NR_mknodat, sys_mknodat), // 288 1225 LINX_(__NR_fchownat, sys_fchownat), // 289 1226 LINX_(__NR_futimesat, sys_futimesat), // 290 1227 PLAXY(__NR_fstatat64, sys_fstatat64), // 291 1228 LINX_(__NR_unlinkat, sys_unlinkat), // 292 1229 LINX_(__NR_renameat, sys_renameat), // 293 1230 LINX_(__NR_linkat, sys_linkat), // 294 1231 LINX_(__NR_symlinkat, sys_symlinkat), // 295 1232 LINX_(__NR_readlinkat, sys_readlinkat), // 296 1233 LINX_(__NR_fchmodat, sys_fchmodat), // 297 1234 LINX_(__NR_faccessat, sys_faccessat), // 298 1235 LINX_(__NR_set_robust_list, sys_set_robust_list), // 299 1236 LINXY(__NR_get_robust_list, sys_get_robust_list), // 300 1237 LINXY(__NR_move_pages, sys_move_pages), // 301 1238 LINXY(__NR_getcpu, sys_getcpu), // 302 1239 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 303 1240 LINX_(__NR_utimensat, sys_utimensat), // 304 1241 LINXY(__NR_signalfd, sys_signalfd), // 305 1242 LINXY(__NR_timerfd_create, sys_timerfd_create), // 306 1243 LINXY(__NR_eventfd, sys_eventfd), // 307 1244 LINX_(__NR_sync_file_range2, sys_sync_file_range2), // 308 1245 LINX_(__NR_fallocate, sys_fallocate), // 309 1246// LINXY(__NR_subpage_prot, sys_ni_syscall), // 310 1247 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 311 1248 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 312 1249 LINXY(__NR_signalfd4, sys_signalfd4), // 313 1250 LINXY(__NR_eventfd2, sys_eventfd2), // 314 1251 LINXY(__NR_epoll_create1, sys_epoll_create1), // 315 1252 LINXY(__NR_dup3, sys_dup3), // 316 1253 LINXY(__NR_pipe2, sys_pipe2), // 317 1254 LINXY(__NR_inotify_init1, sys_inotify_init1), // 318 1255 LINXY(__NR_perf_event_open, sys_perf_event_open), // 319 1256 LINXY(__NR_preadv, sys_preadv), // 320 1257 LINX_(__NR_pwritev, sys_pwritev), // 321 1258 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322 1259 1260 LINX_(__NR_clock_adjtime, sys_clock_adjtime), // 347 1261 1262 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351 1263 LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352 1264}; 1265 1266SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) 1267{ 1268 const UInt syscall_table_size 1269 = sizeof(syscall_table) / sizeof(syscall_table[0]); 1270 1271 /* Is it in the contiguous initial section of the table? */ 1272 if (sysno < syscall_table_size) { 1273 SyscallTableEntry* sys = &syscall_table[sysno]; 1274 if (sys->before == NULL) 1275 return NULL; /* no entry */ 1276 else 1277 return sys; 1278 } 1279 1280 /* Can't find a wrapper */ 1281 return NULL; 1282} 1283 1284#endif // defined(VGP_ppc32_linux) 1285 1286/*--------------------------------------------------------------------*/ 1287/*--- end ---*/ 1288/*--------------------------------------------------------------------*/ 1289