1 2/*--------------------------------------------------------------------*/ 3/*--- Platform-specific syscalls stuff. syswrap-mips64-linux.c ----*/ 4/*--------------------------------------------------------------------*/ 5 6/* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2010-2015 RT-RK 11 mips-valgrind@rt-rk.com 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_mips64_linux) 32#include "pub_core_basics.h" 33#include "pub_core_vki.h" 34#include "pub_core_vkiscnums.h" 35#include "pub_core_threadstate.h" 36#include "pub_core_aspacemgr.h" 37#include "pub_core_debuglog.h" 38#include "pub_core_libcbase.h" 39#include "pub_core_libcassert.h" 40#include "pub_core_libcprint.h" 41#include "pub_core_libcproc.h" 42#include "pub_core_libcsignal.h" 43#include "pub_core_options.h" 44#include "pub_core_scheduler.h" 45#include "pub_core_sigframe.h" /* For VG_(sigframe_destroy)() */ 46#include "pub_core_signals.h" 47#include "pub_core_syscall.h" 48#include "pub_core_syswrap.h" 49#include "pub_core_tooliface.h" 50#include "pub_core_transtab.h" /* VG_(discard_translations) */ 51#include "priv_types_n_macros.h" 52#include "priv_syswrap-generic.h" /* for decls of generic wrappers */ 53#include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */ 54#include "priv_syswrap-main.h" 55 56#include "pub_core_debuginfo.h" /* VG_(di_notify_*) */ 57#include "pub_core_xarray.h" 58#include "pub_core_clientstate.h" /* VG_(brk_base), VG_(brk_limit) */ 59#include "pub_core_errormgr.h" 60#include "pub_core_gdbserver.h" /* VG_(gdbserver) */ 61#include "pub_core_libcfile.h" 62#include "pub_core_machine.h" /* VG_(get_SP) */ 63#include "pub_core_mallocfree.h" 64#include "pub_core_stacktrace.h" /* For VG_(get_and_pp_StackTrace)() */ 65#include "pub_core_ume.h" 66 67#include "config.h" 68 69#include <errno.h> 70 71/* --------------------------------------------------------------------- 72 clone() handling 73 ------------------------------------------------------------------ */ 74 75/* Call f(arg1), but first switch stacks, using 'stack' as the new stack, and 76 use 'retaddr' as f's return-to address. Also, clear all the integer registers 77 before entering f. */ 78__attribute__ ((noreturn)) 79void ML_(call_on_new_stack_0_1) ( Addr stack, /* $4 - $a0 */ 80 Addr retaddr, /* $5 - $a1 */ 81 void (*f_desc) (Word), /* $6 - $a2 */ 82 Word arg1 ); /* $7 - $a3 */ 83asm ( 84".text\n" 85".globl vgModuleLocal_call_on_new_stack_0_1\n" 86"vgModuleLocal_call_on_new_stack_0_1:\n" 87" move $29, $4\n" /* set stack */ 88" move $4, $7\n" /* arg1 to $4 */ 89" move $25, $6\n" 90" move $31, $5\n" /* retaddr to $ra */ 91" jr $25\n" /* jump to f */ 92" break 0x7\n" /* should never get here */ 93".previous\n" 94); 95 96/* Perform a clone system call. clone is strange because it has fork()-like 97 return-twice semantics, so it needs special handling here. 98 99 Upon entry, we have: 100 101 word (fn)(void*) in a0 = 4 102 void* child_stack in a1 = 5 103 word flags in a2 = 6 104 void* arg in a3 = 7 105 pid_t* parent_tid in a4 = 8 106 void* tls in a5 = 9 107 pid_t* child_tid in a6 = 10 108 109 System call requires: 110 111 int $__NR_clone in v0 112 int flags in a0 = 4 113 void* child_stack in a1 = 5 114 pid_t* parent_tid in a2 = 6 115 void* tls_ptr in a3 = 7 116 pid_t* child_tid in a4 = 8 */ 117 118#define __NR_CLONE __NR_clone 119#define __NR_EXIT __NR_exit 120 121ULong do_syscall_clone_mips64_linux ( Word (*fn) (void *), /* a0 - 4 */ 122 void* stack, /* a1 - 5 */ 123 Int flags, /* a2 - 6 */ 124 void* arg, /* a3 - 7 */ 125 Int* parent_tid, /* a4 - 8 */ 126 void* /* Int tls */, /* a5 - 9 */ 127 Int* child_tid ); /* a6 - 10 */ 128 129asm( 130".text\n" 131".set noreorder\n" 132".set nomacro\n" 133".globl do_syscall_clone_mips64_linux\n" 134"do_syscall_clone_mips64_linux:\n" 135" daddiu $29, $29, -32\n" 136" sd $31, 0($29)\n" 137" sd $30, 8($29)\n" 138" sd $28, 16($29)\n" 139 140" daddiu $5, $5, -32\n" 141" sd $4, 0($5)\n" /* fn */ 142" sd $7, 8($5)\n" /* arg */ 143" sd $6, 16($5)\n" /* flags */ 144 145/* 1. arg for syscalls */ 146" move $4, $6\n" /* flags */ 147" move $6, $8\n" /* parent */ 148" move $7, $a5\n" /* tls */ 149" move $8, $a6\n" /* child */ 150 151/* 2. do a syscall to clone */ 152" li $2, 5055\n" /* syscall num for clone */ 153" syscall\n" 154 155/* 3. See if we are a child, call fn and after that exit */ 156" bnez $7, p_or_error\n" 157" nop\n" 158 159" bnez $2, p_or_error\n" 160" nop\n" 161 162" ld $25,0($29)\n" 163" jalr $25\n" 164" ld $4,8($29)\n" 165 166" move $4, $2\n\t" /* retval from fn is in $v0 */ 167" li $2, 5058\n\t" /* NR_exit */ 168" syscall\n\t" 169" nop\n\t" 170/* 4. If we are parent or error, just return to caller */ 171" p_or_error:\n" 172" ld $31, 0($29)\n" 173" ld $30, 8($29)\n" 174" ld $28, 16($29)\n" 175" jr $31\n" 176" daddi $29,$29, 32\n" 177".previous\n" 178); 179 180#undef __NR_CLONE 181#undef __NR_EXIT 182 183/* forward declarations */ 184static void setup_child ( ThreadArchState *, ThreadArchState *); 185static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr); 186 187/* When a client clones, we need to keep track of the new thread. This means: 188 1. allocate a ThreadId+ThreadState+stack for the thread 189 190 2. initialize the thread's new VCPU state 191 192 3. create the thread using the same args as the client requested, but using 193 the scheduler entrypoint for IP, and a separate stack for SP. */ 194static SysRes do_clone ( ThreadId ptid, 195 UInt flags, Addr sp, 196 Int* parent_tidptr, 197 Int* child_tidptr, 198 Addr child_tls ) 199{ 200 const Bool debug = False; 201 ThreadId ctid = VG_ (alloc_ThreadState) (); 202 ThreadState * ptst = VG_ (get_ThreadState) (ptid); 203 ThreadState * ctst = VG_ (get_ThreadState) (ctid); 204 UInt ret = 0; 205 UWord * stack; 206 SysRes res; 207 vki_sigset_t blockall, savedmask; 208 209 VG_(sigfillset)(&blockall); 210 vg_assert(VG_(is_running_thread)(ptid)); 211 vg_assert(VG_(is_valid_tid)(ctid)); 212 stack = (UWord *)ML_(allocstack)(ctid); 213 if (stack == NULL) { 214 res = VG_(mk_SysRes_Error)(VKI_ENOMEM); 215 goto out; 216 } 217 setup_child(&ctst->arch, &ptst->arch); 218 219 /* on MIPS we need to set V0 and A3 to zero */ 220 ctst->arch.vex.guest_r2 = 0; 221 ctst->arch.vex.guest_r7 = 0; 222 if (sp != 0) 223 ctst->arch.vex.guest_r29 = sp; 224 225 ctst->os_state.parent = ptid; 226 ctst->sig_mask = ptst->sig_mask; 227 ctst->tmp_sig_mask = ptst->sig_mask; 228 229 ctst->os_state.threadgroup = ptst->os_state.threadgroup; 230 231 ML_(guess_and_register_stack) (sp, ctst); 232 233 VG_TRACK(pre_thread_ll_create, ptid, ctid); 234 if (flags & VKI_CLONE_SETTLS) { 235 if (debug) 236 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls); 237 res = sys_set_tls(ctid, child_tls); 238 if (sr_isError(res)) 239 goto out; 240 ctst->arch.vex.guest_r27 = child_tls; 241 } 242 243 flags &= ~VKI_CLONE_SETTLS; 244 VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask); 245 /* Create the new thread */ 246 ret = do_syscall_clone_mips64_linux(ML_(start_thread_NORETURN), 247 stack, flags, &VG_(threads)[ctid], 248 parent_tidptr, NULL /*child_tls*/, 249 child_tidptr); 250 if (debug) 251 VG_(printf)("ret: 0x%x\n", ret); 252 253 res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0); 254 255 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL); 256 257 out: 258 if (sr_isError (res)) { 259 VG_ (cleanup_thread) (&ctst->arch); 260 ctst->status = VgTs_Empty; 261 VG_TRACK (pre_thread_ll_exit, ctid); 262 } 263 ptst->arch.vex.guest_r2 = 0; 264 265 return res; 266} 267 268/* --------------------------------------------------------------------- 269 More thread stuff 270 ------------------------------------------------------------------ */ 271void VG_(cleanup_thread) ( ThreadArchState * arch ) { }; 272 273void setup_child ( /* OUT */ ThreadArchState * child, 274 /* IN */ ThreadArchState * parent ) 275{ 276 /* We inherit our parent's guest state. */ 277 child->vex = parent->vex; 278 child->vex_shadow1 = parent->vex_shadow1; 279 child->vex_shadow2 = parent->vex_shadow2; 280} 281 282SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ) 283{ 284 VG_(threads)[tid].arch.vex.guest_ULR = tlsptr; 285 return VG_(mk_SysRes_Success)( 0 ); 286} 287 288/* --------------------------------------------------------------------- 289 PRE/POST wrappers for mips/Linux-specific syscalls 290 ------------------------------------------------------------------ */ 291 292#define PRE(name) DEFN_PRE_TEMPLATE(mips_linux, name) 293#define POST(name) DEFN_POST_TEMPLATE(mips_linux, name) 294 295/* Add prototypes for the wrappers declared here, so that gcc doesn't harass us 296 for not having prototypes. Really this is a kludge -- the right thing to do 297 is to make these wrappers 'static' since they aren't visible outside this 298 file, but that requires even more macro magic. */ 299 300DECL_TEMPLATE (mips_linux, sys_set_thread_area); 301DECL_TEMPLATE (mips_linux, sys_clone); 302DECL_TEMPLATE (mips_linux, sys_tee); 303DECL_TEMPLATE (mips_linux, sys_splice); 304DECL_TEMPLATE (mips_linux, sys_vmsplice); 305DECL_TEMPLATE (mips_linux, sys_ustat); 306DECL_TEMPLATE (mips_linux, sys_sysfs); 307DECL_TEMPLATE (mips_linux, sys_swapon); 308DECL_TEMPLATE (mips_linux, sys_swapoff); 309DECL_TEMPLATE (mips_linux, sys_setdomainname); 310DECL_TEMPLATE (mips_linux, sys_sethostname); 311DECL_TEMPLATE (mips_linux, sys_reboot); 312DECL_TEMPLATE (mips_linux, sys_cacheflush); 313DECL_TEMPLATE (mips_linux, sys_sched_rr_get_interval); 314DECL_TEMPLATE (mips_linux, sys_unshare); 315DECL_TEMPLATE (mips_linux, sys_arch_prctl); 316DECL_TEMPLATE (mips_linux, sys_ptrace); 317DECL_TEMPLATE (mips_linux, sys_mmap); 318DECL_TEMPLATE (mips_linux, sys_rt_sigreturn); 319DECL_TEMPLATE (mips_linux, sys_pipe); 320 321PRE(sys_tee) 322{ 323 PRINT("sys_tee ( %ld, %ld, %lu, %#lx )", SARG1, SARG2, ARG3, ARG4); 324 PRE_REG_READ4(long, "sys_tee", int, fdin, int, fdout, vki_size_t, len, 325 int, flags); 326} 327 328PRE(sys_splice) 329{ 330 PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %lu, %#lx )", 331 SARG1, ARG2, SARG3, ARG4, ARG5, ARG6); 332 333 PRE_REG_READ6(long, "sys_splice", int, fdin, vki_loff_t, sizein, int, 334 fdout, vki_loff_t, sizeout, vki_size_t, len, int, flags); 335} 336 337PRE(sys_vmsplice) 338{ 339 PRINT("sys_vmsplice ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4); 340 PRE_REG_READ4(long, "sys_vmsplice", int, fdin, struct vki_iovec *, v, 341 vki_size_t, len, int, flags); 342} 343 344PRE(sys_unshare) 345{ 346 PRINT("sys_unshare ( %lu )", ARG1); 347 PRE_REG_READ1(long, "sys_unshare", unsigned long, flags); 348} 349 350PRE(sys_sched_rr_get_interval) 351{ 352 PRINT("sys_sched_rr_get_interval ( %ld, %#lx)", SARG1, ARG2); 353 PRE_REG_READ2(long, "sched_rr_get_interval", vki_pid_t, pid, 354 struct timespec *, timer); 355 *flags |= SfMayBlock; 356} 357 358PRE(sys_ustat) 359{ 360 PRINT("sys_ustat ( %#lx, %#lx)", ARG1, ARG2); 361 PRE_REG_READ2(long, "ustat", int, flags, const void *, path); 362} 363 364PRE(sys_swapon) 365{ 366 PRINT("sys_swapon ( %#lx, %#lx )", ARG1, ARG2); 367 PRE_REG_READ2(long, "swapon", const void *, path, int, flags); 368} 369 370PRE(sys_swapoff) 371{ 372 PRINT("sys_swapoff ( %#lx )", ARG1); 373 PRE_REG_READ1(long, "swapoff", const void *, path); 374} 375 376PRE(sys_sysfs) 377{ 378 PRINT("sys_sysfs ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3); 379 PRE_REG_READ3(long, "sysfs", int, flags, int, desc, const void *, path); 380} 381 382/* Very much MIPS specific */ 383PRE(sys_cacheflush) 384{ 385 PRINT("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3); 386 PRE_REG_READ3(long, "cacheflush", unsigned long, addr, 387 unsigned long, nbytes, unsigned int, cache); 388 VG_ (discard_translations) ((Addr)ARG1, (ULong) ARG2, 389 "PRE(sys_cacheflush)"); 390 SET_STATUS_Success(0); 391} 392 393PRE(sys_reboot) 394{ 395 PRINT("sys_reboot ( %ld, %ld, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4); 396 // An approximation. ARG4 is only read conditionally by the kernel 397 PRE_REG_READ4(int, "reboot", 398 int, magic1, int, magic2, unsigned int, cmd, 399 void *, arg); 400 401 *flags |= SfMayBlock; 402} 403 404PRE(sys_setdomainname) 405{ 406 PRINT ("sys_setdomainname ( %#lx, %ld )", ARG1, SARG2); 407 PRE_REG_READ2 (long, "setdomainname", const void *, name, int, len); 408} 409 410PRE(sys_sethostname) 411{ 412 PRINT ("sys_sethostname ( %#lx, %ld )", ARG1, SARG2); 413 PRE_REG_READ2 (long, "sethostname", const void *, name, int, len); 414} 415 416PRE(sys_ptrace) 417{ 418 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4); 419 PRE_REG_READ4(int, "ptrace", 420 long, request, long, pid, unsigned long, addr, 421 unsigned long, data); 422 switch (ARG1) { 423 case VKI_PTRACE_PEEKTEXT: 424 case VKI_PTRACE_PEEKDATA: 425 case VKI_PTRACE_PEEKUSR: 426 PRE_MEM_WRITE("ptrace(peek)", ARG4, sizeof(long)); 427 break; 428 case VKI_PTRACE_GETEVENTMSG: 429 PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4, sizeof(unsigned long)); 430 break; 431 case VKI_PTRACE_GETSIGINFO: 432 PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t)); 433 break; 434 case VKI_PTRACE_SETSIGINFO: 435 PRE_MEM_READ("ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t)); 436 break; 437 case VKI_PTRACE_GETREGSET: 438 ML_(linux_PRE_getregset)(tid, ARG3, ARG4); 439 break; 440 default: 441 break; 442 } 443} 444 445POST(sys_ptrace) 446{ 447 switch (ARG1) { 448 case VKI_PTRACE_PEEKTEXT: 449 case VKI_PTRACE_PEEKDATA: 450 case VKI_PTRACE_PEEKUSR: 451 POST_MEM_WRITE (ARG4, sizeof(long)); 452 break; 453 case VKI_PTRACE_GETEVENTMSG: 454 POST_MEM_WRITE (ARG4, sizeof(unsigned long)); 455 break; 456 case VKI_PTRACE_GETSIGINFO: 457 POST_MEM_WRITE (ARG4, sizeof(vki_siginfo_t)); 458 break; 459 case VKI_PTRACE_GETREGSET: 460 ML_(linux_POST_getregset)(tid, ARG3, ARG4); 461 break; 462 default: 463 break; 464 } 465} 466 467PRE (sys_mmap) 468{ 469 SysRes r; 470 PRINT("sys_mmap ( %#lx, %lu, %ld, %ld, %ld, %lu )", 471 ARG1, ARG2, SARG3, SARG4, SARG5, ARG6); 472 PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length, 473 int, prot, int, flags, int, fd, unsigned long, offset); 474 r = ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5, 475 (Off64T) ARG6); 476 SET_STATUS_from_SysRes(r); 477} 478 479PRE(sys_clone) 480{ 481 Bool badarg = False; 482 UInt cloneflags; 483 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3, 484 ARG4, ARG5); 485 PRE_REG_READ2(int, "clone", unsigned long, flags, void *, child_stack); 486 if (ARG1 & VKI_CLONE_PARENT_SETTID) { 487 if (VG_(tdict).track_pre_reg_read) { 488 PRA3("clone", int *, parent_tidptr); 489 } 490 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int)); 491 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) { 492 badarg = True; 493 } 494 } 495 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) { 496 if (VG_(tdict).track_pre_reg_read) { 497 PRA5("clone", int *, child_tidptr); 498 } 499 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof (Int)); 500 if (!VG_(am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE)) 501 badarg = True; 502 } 503 if (badarg) { 504 SET_STATUS_Failure(VKI_EFAULT); 505 return; 506 } 507 cloneflags = ARG1; 508 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) { 509 SET_STATUS_Failure(VKI_EINVAL); 510 return; 511 } 512 /* Only look at the flags we really care about */ 513 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 514 |VKI_CLONE_FILES | VKI_CLONE_VFORK)) { 515 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: 516 /* thread creation */ 517 SET_STATUS_from_SysRes(do_clone(tid, 518 ARG1, /* flags */ 519 (Addr)ARG2, /* child SP */ 520 (Int *)ARG3, /* parent_tidptr */ 521 (Int *)ARG5, /* child_tidptr */ 522 (Addr)ARG4)); /* child_tls */ 523 break; 524 525 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ 526 /* FALLTHROUGH - assume vfork == fork */ 527 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); 528 case 0: /* plain fork */ 529 SET_STATUS_from_SysRes(ML_(do_fork_clone)(tid, 530 cloneflags, /* flags */ 531 (Int *)ARG3, /* parent_tidptr */ 532 (Int *)ARG5)); /* child_tidptr */ 533 break; 534 535 default: 536 /* should we just ENOSYS? */ 537 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1); 538 VG_(message)(Vg_UserMsg, "\n"); 539 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n"); 540 VG_(message)(Vg_UserMsg, 541 " - via a threads library (LinuxThreads or NPTL)\n"); 542 VG_(message)(Vg_UserMsg, 543 " - via the implementation of fork or vfork\n"); 544 VG_(unimplemented)("Valgrind does not support general clone()."); 545 } 546 if (SUCCESS) { 547 if (ARG1 & VKI_CLONE_PARENT_SETTID) 548 POST_MEM_WRITE(ARG3, sizeof(Int)); 549 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 550 POST_MEM_WRITE(ARG5, sizeof(Int)); 551 /* Thread creation was successful; let the child have the chance to run */ 552 *flags |= SfYieldAfter; 553 } 554} 555 556PRE(sys_rt_sigreturn) 557{ 558 /* See comments on PRE(sys_rt_sigreturn) in syswrap-s390x-linux.c for 559 an explanation of what follows. */ 560 ThreadState* tst; 561 PRINT("sys_rt_sigreturn ( )"); 562 563 vg_assert(VG_(is_valid_tid)(tid)); 564 vg_assert(tid >= 1 && tid < VG_N_THREADS); 565 vg_assert(VG_(is_running_thread)(tid)); 566 567 tst = VG_(get_ThreadState)(tid); 568 569 /* This is only so that the IA is (might be) useful to report if 570 something goes wrong in the sigreturn */ 571 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch); 572 573 /* Restore register state from frame and remove it */ 574 VG_(sigframe_destroy)(tid, True); 575 576 /* Tell the driver not to update the guest state with the "result", 577 and set a bogus result to keep it happy. */ 578 *flags |= SfNoWriteResult; 579 SET_STATUS_Success(0); 580 581 /* Check to see if any signals arose as a result of this. */ 582 *flags |= SfPollAfter; 583} 584 585PRE(sys_set_thread_area) 586{ 587 PRINT("set_thread_area (%lx)", ARG1); 588 PRE_REG_READ1(long, "set_thread_area", unsigned long, addr); 589 SET_STATUS_from_SysRes(sys_set_tls(tid, ARG1)); 590} 591 592PRE(sys_pipe) 593{ 594 PRINT("sys_pipe ( %#lx )", ARG1); 595 PRE_REG_READ1(int, "pipe", int *, filedes); 596 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) ); 597} 598 599POST(sys_pipe) 600{ 601 Int p0, p1; 602 vg_assert(SUCCESS); 603 p0 = RES; 604 p1 = sr_ResEx(status->sres); 605 606 if (!ML_(fd_allowed)(p0, "pipe", tid, True) || 607 !ML_(fd_allowed)(p1, "pipe", tid, True)) { 608 VG_(close)(p0); 609 VG_(close)(p1); 610 SET_STATUS_Failure( VKI_EMFILE ); 611 } else { 612 if (VG_(clo_track_fds)) { 613 ML_(record_fd_open_nameless)(tid, p0); 614 ML_(record_fd_open_nameless)(tid, p1); 615 } 616 } 617} 618 619#undef PRE 620#undef POST 621 622/* --------------------------------------------------------------------- 623 The mips64/Linux syscall table 624 ------------------------------------------------------------------ */ 625 626/* Add an mips64-linux specific wrapper to a syscall table. */ 627#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(mips_linux, sysno, name) 628#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(mips_linux, sysno, name) 629 630static SyscallTableEntry syscall_main_table[] = { 631 GENXY (__NR_read, sys_read), /* 5000 */ 632 GENX_ (__NR_write, sys_write), 633 GENXY (__NR_open, sys_open), 634 GENXY (__NR_close, sys_close), 635 GENXY (__NR_stat, sys_newstat), 636 GENXY (__NR_fstat, sys_newfstat), 637 GENXY (__NR_lstat, sys_newlstat), 638 GENXY (__NR_poll, sys_poll), 639 LINX_ (__NR_lseek, sys_lseek), 640 PLAX_ (__NR_mmap, sys_mmap), 641 GENXY (__NR_mprotect, sys_mprotect), 642 GENXY (__NR_munmap, sys_munmap), 643 GENX_ (__NR_brk, sys_brk), 644 LINXY (__NR_rt_sigaction, sys_rt_sigaction), 645 LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask), 646 LINXY (__NR_ioctl, sys_ioctl), 647 LINXY (__NR_eventfd2, sys_eventfd2), 648 LINXY (__NR_signalfd4, sys_signalfd4), 649 GENXY (__NR_pread64, sys_pread64), 650 GENX_ (__NR_pwrite64, sys_pwrite64), 651 GENXY (__NR_readv, sys_readv), 652 GENX_ (__NR_writev, sys_writev), 653 GENX_ (__NR_access, sys_access), 654 PLAXY (__NR_pipe, sys_pipe), 655 LINXY (__NR_pipe2, sys_pipe2), 656 GENX_ (__NR__newselect,sys_select), 657 LINX_ (__NR_sched_yield, sys_sched_yield), 658 GENX_ (__NR_mremap, sys_mremap), 659 GENX_ (__NR_msync, sys_msync), 660 GENXY (__NR_mincore, sys_mincore), 661 GENX_ (__NR_madvise, sys_madvise), 662 LINX_ (__NR_shmget, sys_shmget), 663 LINXY (__NR_shmat, wrap_sys_shmat), 664 LINXY (__NR_shmctl, sys_shmctl), 665 GENXY (__NR_dup, sys_dup), 666 GENXY (__NR_dup2, sys_dup2), 667 LINXY (__NR_dup3, sys_dup3), 668 GENX_ (__NR_pause, sys_pause), 669 GENXY (__NR_nanosleep, sys_nanosleep), 670 GENXY (__NR_getitimer, sys_getitimer), 671 GENXY (__NR_setitimer, sys_setitimer), 672 GENX_ (__NR_alarm, sys_alarm), 673 GENX_ (__NR_getpid, sys_getpid), 674 /* LINX_(__NR_fallocate,sys_fallocate), */ 675 LINXY (__NR_sendfile, sys_sendfile), 676 LINXY (__NR_socket, sys_socket), 677 LINX_ (__NR_connect, sys_connect), 678 LINXY (__NR_accept, sys_accept), 679 LINXY (__NR_accept4, sys_accept4), 680 LINX_ (__NR_sendto, sys_sendto), 681 LINXY (__NR_recvfrom, sys_recvfrom), 682 LINX_ (__NR_sendmsg, sys_sendmsg), 683 LINXY (__NR_recvmsg, sys_recvmsg), 684 LINX_ (__NR_shutdown, sys_shutdown), 685 LINX_ (__NR_bind, sys_bind), 686 LINX_ (__NR_listen, sys_listen), 687 LINXY (__NR_getsockname, sys_getsockname), 688 LINXY (__NR_getpeername, sys_getpeername), 689 LINXY (__NR_socketpair, sys_socketpair), 690 LINX_ (__NR_setsockopt, sys_setsockopt), 691 LINXY (__NR_getsockopt, sys_getsockopt), 692 PLAX_ (__NR_clone, sys_clone), 693 GENX_ (__NR_fork, sys_fork), 694 GENX_ (__NR_execve, sys_execve), 695 GENX_ (__NR_exit, sys_exit), 696 GENXY (__NR_wait4, sys_wait4), 697 GENX_ (__NR_kill, sys_kill), 698 GENXY (__NR_uname, sys_newuname), 699 LINX_ (__NR_semget, sys_semget), 700 LINX_ (__NR_semop, sys_semop), 701 LINXY (__NR_semctl, sys_semctl), 702 LINXY (__NR_shmdt, sys_shmdt), 703 LINX_ (__NR_msgget, sys_msgget), 704 LINX_ (__NR_msgsnd, sys_msgsnd), 705 LINXY (__NR_msgrcv, sys_msgrcv), 706 LINXY (__NR_msgctl, sys_msgctl), 707 LINXY (__NR_fcntl, sys_fcntl), 708 GENX_ (__NR_flock, sys_flock), 709 GENX_ (__NR_fsync, sys_fsync), 710 GENX_ (__NR_fdatasync, sys_fdatasync), 711 GENX_ (__NR_truncate, sys_truncate), 712 GENX_ (__NR_ftruncate, sys_ftruncate), 713 GENXY (__NR_getdents, sys_getdents), 714 GENXY (__NR_getcwd, sys_getcwd), 715 GENX_ (__NR_chdir, sys_chdir), 716 GENX_ (__NR_fchdir, sys_fchdir), 717 GENX_ (__NR_rename, sys_rename), 718 GENX_ (__NR_mkdir, sys_mkdir), 719 GENX_ (__NR_rmdir, sys_rmdir), 720 GENXY (__NR_creat, sys_creat), 721 GENX_ (__NR_link, sys_link), 722 GENX_ (__NR_unlink, sys_unlink), 723 GENX_ (__NR_symlink, sys_symlink), 724 GENX_ (__NR_readlink, sys_readlink), 725 GENX_ (__NR_chmod, sys_chmod), 726 GENX_ (__NR_fchmod, sys_fchmod), 727 GENX_ (__NR_chown, sys_chown), 728 GENX_ (__NR_fchown, sys_fchown), 729 GENX_ (__NR_lchown, sys_lchown), 730 GENX_ (__NR_umask, sys_umask), 731 GENXY (__NR_gettimeofday, sys_gettimeofday), 732 GENXY (__NR_getrlimit, sys_getrlimit), 733 GENXY (__NR_getrusage, sys_getrusage), 734 LINXY (__NR_sysinfo, sys_sysinfo), 735 GENXY (__NR_times, sys_times), 736 PLAXY (__NR_ptrace, sys_ptrace), 737 GENX_ (__NR_getuid, sys_getuid), 738 LINXY (__NR_syslog, sys_syslog), 739 GENX_ (__NR_getgid, sys_getgid), 740 GENX_ (__NR_setuid, sys_setuid), 741 GENX_ (__NR_setgid, sys_setgid), 742 GENX_ (__NR_geteuid, sys_geteuid), 743 GENX_ (__NR_getegid, sys_getegid), 744 GENX_ (__NR_setpgid, sys_setpgid), 745 GENX_ (__NR_getppid, sys_getppid), 746 GENX_ (__NR_getpgrp, sys_getpgrp), 747 GENX_ (__NR_setsid, sys_setsid), 748 GENX_ (__NR_setreuid, sys_setreuid), 749 GENX_ (__NR_setregid, sys_setregid), 750 GENXY (__NR_getgroups, sys_getgroups), 751 GENX_ (__NR_setgroups, sys_setgroups), 752 LINX_ (__NR_setresuid, sys_setresuid), 753 LINXY (__NR_getresuid, sys_getresuid), 754 LINX_ (__NR_setresgid, sys_setresgid), 755 LINXY (__NR_getresgid, sys_getresgid), 756 GENX_ (__NR_getpgid, sys_getpgid), 757 LINX_ (__NR_setfsuid, sys_setfsuid), 758 LINX_ (__NR_setfsgid, sys_setfsgid), 759 GENX_ (__NR_getsid, sys_getsid), 760 LINXY (__NR_capget, sys_capget), 761 LINX_ (__NR_capset, sys_capset), 762 LINXY (__NR_rt_sigpending, sys_rt_sigpending), 763 LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait), 764 LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), 765 LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend), 766 GENXY (__NR_sigaltstack, sys_sigaltstack), 767 LINX_ (__NR_utime, sys_utime), 768 GENX_ (__NR_mknod, sys_mknod), 769 LINX_ (__NR_personality, sys_personality), 770 PLAX_ (__NR_ustat, sys_ustat), 771 GENXY (__NR_statfs, sys_statfs), 772 GENXY (__NR_fstatfs, sys_fstatfs), 773 PLAX_ (__NR_sysfs, sys_sysfs), 774 GENX_ (__NR_getpriority, sys_getpriority), 775 GENX_ (__NR_setpriority, sys_setpriority), 776 LINXY (__NR_sched_setparam, sys_sched_setparam), 777 LINXY (__NR_sched_getparam, sys_sched_getparam), 778 LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler), 779 LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler), 780 LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max), 781 LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min), 782 PLAX_ (__NR_sched_rr_get_interval, sys_sched_rr_get_interval), 783 GENX_ (__NR_mlock, sys_mlock), 784 GENX_ (__NR_munlock, sys_munlock), 785 GENX_ (__NR_mlockall, sys_mlockall), 786 LINX_ (__NR_munlockall, sys_munlockall), 787 LINX_ (__NR_vhangup, sys_vhangup), 788 LINX_ (__NR_pivot_root,sys_pivot_root), 789 LINXY (__NR__sysctl, sys_sysctl), 790 LINXY (__NR_prctl, sys_prctl), 791 LINXY (__NR_adjtimex, sys_adjtimex), 792 GENX_ (__NR_setrlimit, sys_setrlimit), 793 GENX_ (__NR_chroot, sys_chroot), 794 GENX_ (__NR_sync, sys_sync), 795 GENX_ (__NR_acct, sys_acct), 796 GENX_ (__NR_settimeofday, sys_settimeofday), 797 LINX_ (__NR_mount, sys_mount), 798 LINX_ (__NR_umount2, sys_umount), 799 PLAX_ (__NR_swapon, sys_swapon), 800 PLAX_ (__NR_swapoff, sys_swapoff), 801 PLAX_ (__NR_reboot, sys_reboot), 802 PLAX_ (__NR_sethostname, sys_sethostname), 803 PLAX_ (__NR_setdomainname, sys_setdomainname), 804 GENX_ (__NR_create_module, sys_ni_syscall), 805 LINX_ (__NR_init_module, sys_init_module), 806 LINX_ (__NR_delete_module, sys_delete_module), 807 GENX_ (__NR_get_kernel_syms, sys_ni_syscall), 808 GENX_ (__NR_query_module, sys_ni_syscall), 809 LINX_ (__NR_quotactl, sys_quotactl), 810 /* GENX_(__NR_nfsservctl,sys_nfsservctl), */ 811 GENXY (__NR_getpmsg, sys_getpmsg), 812 GENX_ (__NR_putpmsg, sys_putpmsg), 813 GENX_ (__NR_afs_syscall, sys_ni_syscall), 814 /* GENX_(__NR_reserved177,sys_reserved177), */ 815 LINX_ (__NR_gettid, sys_gettid), 816 /* GENX_(__NR_readahead,sys_readahead), */ 817 LINX_ (__NR_setxattr, sys_setxattr), 818 LINX_ (__NR_lsetxattr, sys_lsetxattr), 819 LINX_ (__NR_fsetxattr, sys_fsetxattr), 820 LINXY (__NR_getxattr, sys_getxattr), 821 LINXY (__NR_lgetxattr, sys_lgetxattr), 822 LINXY (__NR_fgetxattr, sys_fgetxattr), 823 LINXY (__NR_listxattr, sys_listxattr), 824 LINXY (__NR_llistxattr, sys_llistxattr), 825 LINXY (__NR_flistxattr, sys_flistxattr), 826 LINX_ (__NR_removexattr, sys_removexattr), 827 LINX_ (__NR_lremovexattr, sys_lremovexattr), 828 LINX_ (__NR_fremovexattr, sys_fremovexattr), 829 LINXY (__NR_tkill, sys_tkill), 830 /* GENX_(__NR_reserved193,sys_reserved193), */ 831 LINXY (__NR_futex, sys_futex), 832 LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity), 833 LINXY (__NR_sched_getaffinity, sys_sched_getaffinity), 834 PLAX_ (__NR_cacheflush, sys_cacheflush), 835 LINXY (__NR_io_setup, sys_io_setup), 836 LINX_ (__NR_io_destroy, sys_io_destroy), 837 LINXY (__NR_io_getevents, sys_io_getevents), 838 LINX_ (__NR_io_submit, sys_io_submit), 839 LINXY (__NR_io_cancel, sys_io_cancel), 840 LINX_ (__NR_exit_group, sys_exit_group), 841 /* LINXY (__NR_lookup_dcookie, sys_lookup_dcookie), */ 842 LINXY (__NR_epoll_create, sys_epoll_create), 843 LINXY (__NR_epoll_create1, sys_epoll_create1), 844 LINX_ (__NR_epoll_ctl, sys_epoll_ctl), 845 LINXY (__NR_epoll_wait, sys_epoll_wait), 846 PLAX_(__NR_rt_sigreturn,sys_rt_sigreturn), 847 /* LINXY(__NR_fcntl64,sys_fcntl64), */ 848 LINX_ (__NR_set_tid_address, sys_set_tid_address), 849 LINX_ (__NR_semtimedop, sys_semtimedop), 850 LINX_ (__NR_fadvise64, sys_fadvise64), 851 LINXY (__NR_timer_create, sys_timer_create), 852 LINXY (__NR_timer_settime, sys_timer_settime), 853 LINXY (__NR_timer_gettime, sys_timer_gettime), 854 LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun), 855 LINX_ (__NR_timer_delete, sys_timer_delete), 856 LINX_ (__NR_clock_settime, sys_clock_settime), 857 LINXY (__NR_clock_gettime, sys_clock_gettime), 858 LINXY (__NR_clock_getres, sys_clock_getres), 859 LINXY (__NR_clock_nanosleep, sys_clock_nanosleep), 860 LINX_ (__NR_tgkill, sys_tgkill), 861 GENX_ (__NR_utimes, sys_utimes), 862 LINX_ (__NR_mbind, sys_mbind), 863 LINXY (__NR_get_mempolicy, sys_get_mempolicy), 864 LINX_ (__NR_set_mempolicy, sys_set_mempolicy), 865 LINXY (__NR_mq_open, sys_mq_open), 866 LINX_ (__NR_mq_unlink, sys_mq_unlink), 867 LINX_ (__NR_mq_timedsend, sys_mq_timedsend), 868 LINXY (__NR_mq_timedreceive, sys_mq_timedreceive), 869 LINX_ (__NR_mq_notify, sys_mq_notify), 870 LINXY (__NR_mq_getsetattr, sys_mq_getsetattr), 871 GENX_ (__NR_vserver, sys_ni_syscall), 872 LINXY (__NR_waitid, sys_waitid), 873 LINX_ (__NR_add_key, sys_add_key), 874 LINX_ (__NR_request_key, sys_request_key), 875 LINXY (__NR_keyctl, sys_keyctl), 876 PLAX_ (__NR_set_thread_area, sys_set_thread_area), 877 LINX_ (__NR_inotify_init, sys_inotify_init), 878 LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch), 879 LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch), 880 LINXY (__NR_openat, sys_openat), 881 LINX_ (__NR_mkdirat, sys_mkdirat), 882 LINX_ (__NR_mknodat, sys_mknodat), 883 LINX_ (__NR_fchownat, sys_fchownat), 884 LINX_ (__NR_futimesat, sys_futimesat), 885 LINX_ (__NR_unlinkat, sys_unlinkat), 886 LINX_ (__NR_renameat, sys_renameat), 887 LINX_ (__NR_linkat, sys_linkat), 888 LINX_ (__NR_symlinkat, sys_symlinkat), 889 LINX_ (__NR_readlinkat, sys_readlinkat), 890 LINX_ (__NR_fchmodat, sys_fchmodat), 891 LINX_ (__NR_faccessat, sys_faccessat), 892 LINX_ (__NR_pselect6, sys_pselect6), 893 LINXY (__NR_ppoll, sys_ppoll), 894 PLAX_ (__NR_unshare, sys_unshare), 895 PLAX_ (__NR_splice, sys_splice), 896 LINX_ (__NR_sync_file_range, sys_sync_file_range), 897 PLAX_ (__NR_tee, sys_tee), 898 PLAX_ (__NR_vmsplice, sys_vmsplice), 899 LINX_ (__NR_set_robust_list, sys_set_robust_list), 900 LINXY (__NR_get_robust_list, sys_get_robust_list), 901 LINXY (__NR_epoll_pwait, sys_epoll_pwait), 902 LINX_ (__NR_ioprio_set, sys_ioprio_set), 903 LINX_ (__NR_ioprio_get, sys_ioprio_get), 904 LINX_ (__NR_utimensat, sys_utimensat), 905 LINXY (__NR_signalfd, sys_signalfd), 906 LINXY (__NR_eventfd, sys_eventfd), 907 LINX_ (__NR_fallocate, sys_fallocate), 908 LINXY (__NR_timerfd_create, sys_timerfd_create), 909 LINXY (__NR_timerfd_gettime, sys_timerfd_gettime), 910 LINXY (__NR_timerfd_settime, sys_timerfd_settime), 911 LINXY (__NR_newfstatat, sys_newfstatat), 912 LINXY (__NR_prlimit64, sys_prlimit64), 913 LINXY (__NR_clock_adjtime, sys_clock_adjtime), 914 LINXY (__NR_process_vm_readv, sys_process_vm_readv), 915 LINX_ (__NR_process_vm_writev, sys_process_vm_writev), 916 LINXY(__NR_getrandom, sys_getrandom), 917 LINXY(__NR_memfd_create, sys_memfd_create), 918 LINX_(__NR_syncfs, sys_syncfs) 919}; 920 921SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno ) 922{ 923 const UInt syscall_main_table_size 924 = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]); 925 926 if (sysno < syscall_main_table_size) { 927 SyscallTableEntry * sys = &syscall_main_table[sysno]; 928 if (sys->before == NULL) 929 return NULL; /* no entry */ 930 else 931 return sys; 932 } 933 /* Can't find a wrapper */ 934 return NULL; 935} 936 937#endif /* defined(VGP_mips64_linux) */ 938 939/*--------------------------------------------------------------------*/ 940/*--- end syswrap-mips64-linux.c ---*/ 941/*--------------------------------------------------------------------*/ 942