1 2 /*--------------------------------------------------------------------*/ 3 /*--- Platform-specific syscalls stuff. syswrap-mips32-linux.c ----*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2010-2013 RT-RK 11 mips-valgrind (at) 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_mips32_linux) 32 #include "pub_core_basics.h" 33 #include "pub_core_vki.h" 34 #include "pub_core_vkiscnums.h" 35 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 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 #include "pub_core_transtab.h" // VG_(discard_translations) 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 #include "pub_core_debuginfo.h" // VG_(di_notify_*) 59 #include "pub_core_xarray.h" 60 #include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit) 61 #include "pub_core_errormgr.h" 62 #include "pub_core_gdbserver.h" // VG_(gdbserver) 63 #include "pub_core_libcfile.h" 64 #include "pub_core_machine.h" // VG_(get_SP) 65 #include "pub_core_mallocfree.h" 66 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)() 67 #include "pub_core_ume.h" 68 69 #include "priv_syswrap-generic.h" 70 71 #include "config.h" 72 73 #include <errno.h> 74 75 /* --------------------------------------------------------------------- 76 clone() handling 77 ------------------------------------------------------------------ */ 78 /* Call f(arg1), but first switch stacks, using 'stack' as the new 79 stack, and use 'retaddr' as f's return-to address. Also, clear all 80 the integer registers before entering f.*/ 81 82 __attribute__ ((noreturn)) 83 void ML_ (call_on_new_stack_0_1) (Addr stack, Addr retaddr, 84 void (*f) (Word), Word arg1); 85 // a0 = stack 86 // a1 = retaddr 87 // a2 = f 88 // a3 = arg1 89 asm ( 90 ".text\n" 91 ".globl vgModuleLocal_call_on_new_stack_0_1\n" 92 "vgModuleLocal_call_on_new_stack_0_1:\n" 93 " move $29, $4\n\t" // stack to %sp 94 " move $25, $6\n\t" // f to t9/$25 95 " move $4, $7\n\t" // arg1 to $a0 96 " li $2, 0\n\t" // zero all GP regs 97 " li $3, 0\n\t" 98 " li $5, 0\n\t" 99 " li $6, 0\n\t" 100 " li $7, 0\n\t" 101 102 " li $12, 0\n\t" 103 " li $13, 0\n\t" 104 " li $14, 0\n\t" 105 " li $15, 0\n\t" 106 " li $16, 0\n\t" 107 " li $17, 0\n\t" 108 " li $18, 0\n\t" 109 " li $19, 0\n\t" 110 " li $20, 0\n\t" 111 " li $21, 0\n\t" 112 " li $22, 0\n\t" 113 " li $23, 0\n\t" 114 " li $24, 0\n\t" 115 " jr $25\n\t" // jump to dst 116 " break 0x7\n" // should never get here 117 ".previous\n" 118 ); 119 120 /* 121 Perform a clone system call. clone is strange because it has 122 fork()-like return-twice semantics, so it needs special 123 handling here. 124 Upon entry, we have: 125 int (fn)(void*) in $a0 0 126 void* child_stack in $a1 4 127 int flags in $a2 8 128 void* arg in $a3 12 129 pid_t* child_tid in stack 16 130 pid_t* parent_tid in stack 20 131 void* tls_ptr in stack 24 132 133 System call requires: 134 int $__NR_clone in $v0 135 int flags in $a0 0 136 void* child_stack in $a1 4 137 pid_t* parent_tid in $a2 8 138 void* tls_ptr in $a3 12 139 pid_t* child_tid in stack 16 140 141 int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, 142 void *parent_tidptr, void *tls, void *child_tidptr) 143 144 Returns an Int encoded in the linux-mips way, not a SysRes. 145 */ 146 #define __NR_CLONE VG_STRINGIFY(__NR_clone) 147 #define __NR_EXIT VG_STRINGIFY(__NR_exit) 148 149 //extern 150 UInt do_syscall_clone_mips_linux (Word (*fn) (void *), //a0 0 32 151 void *stack, //a1 4 36 152 Int flags, //a2 8 40 153 void *arg, //a3 12 44 154 Int * child_tid, //stack 16 48 155 Int * parent_tid, //stack 20 52 156 Int tls); //stack 24 56 157 asm ( 158 ".text\n" 159 " .globl do_syscall_clone_mips_linux\n" 160 " do_syscall_clone_mips_linux:\n" 161 " subu $29,$29,32\n\t" 162 " sw $31, 0($29)\n\t" 163 " sw $2, 4($29)\n\t" 164 " sw $3, 8($29)\n\t" 165 " sw $30, 12($29)\n\t" 166 " sw $28, 28($29)\n\t" 167 /* set up child stack with function and arg */ 168 /* syscall arg 2 child_stack is already in a1 */ 169 " subu $5, $5, 32\n\t" /* make space on stack */ 170 " sw $4, 0($5)\n\t" /* fn */ 171 " sw $7, 4($5)\n\t" /* fn arg */ 172 " sw $6, 8($5)\n\t" 173 /* get other args to clone */ 174 175 " move $4, $a2\n\t" /* a0 = flags */ 176 " lw $6, 52($29)\n\t" /* a2 = parent_tid */ 177 " lw $7, 48($29)\n\t" /* a3 = child_tid */ 178 " sw $7, 16($29)\n\t" /* 16(sp) = child_tid */ 179 " lw $7, 56($29)\n\t" /* a3 = tls_ptr */ 180 /* do the system call */ 181 182 " li $2, " __NR_CLONE "\n\t" /* __NR_clone */ 183 " syscall\n\t" 184 " nop\n\t" 185 186 " bnez $7, .Lerror\n\t" 187 " nop\n\t" 188 " beqz $2, .Lstart\n\t" 189 " nop\n\t" 190 191 " lw $31, 0($sp)\n\t" 192 " nop\n\t" 193 " lw $30, 12($sp)\n\t" 194 " nop\n\t" 195 " addu $29,$29,32\n\t" /* free stack */ 196 " nop\n\t" 197 " jr $31\n\t" 198 " nop\n\t" 199 200 ".Lerror:\n\t" 201 " li $31, 5\n\t" 202 " jr $31\n\t" 203 " nop\n\t" 204 205 ".Lstart:\n\t" 206 " lw $4, 4($29)\n\t" 207 " nop\n\t" 208 " lw $25, 0($29)\n\t" 209 " nop\n\t" 210 " jalr $25\n\t" 211 " nop\n\t" 212 213 " move $4, $2\n\t" /* retval from fn is in $v0 */ 214 " li $2, " __NR_EXIT "\n\t" /* NR_exit */ 215 " syscall\n\t" 216 " nop\n\t" 217 " .previous\n" 218 ); 219 220 #undef __NR_CLONE 221 #undef __NR_EXIT 222 223 // forward declarations 224 225 static void setup_child (ThreadArchState *, ThreadArchState *); 226 static SysRes sys_set_tls (ThreadId tid, Addr tlsptr); 227 static SysRes mips_PRE_sys_mmap (ThreadId tid, 228 UWord arg1, UWord arg2, UWord arg3, 229 UWord arg4, UWord arg5, Off64T arg6); 230 /* 231 When a client clones, we need to keep track of the new thread. This means: 232 1. allocate a ThreadId+ThreadState+stack for the the thread 233 2. initialize the thread's new VCPU state 234 3. create the thread using the same args as the client requested, 235 but using the scheduler entrypoint for IP, and a separate stack 236 for SP. 237 */ 238 239 static SysRes do_clone (ThreadId ptid, 240 UInt flags, Addr sp, 241 Int * parent_tidptr, 242 Int * child_tidptr, 243 Addr child_tls) 244 { 245 const Bool debug = False; 246 ThreadId ctid = VG_ (alloc_ThreadState) (); 247 ThreadState * ptst = VG_ (get_ThreadState) (ptid); 248 ThreadState * ctst = VG_ (get_ThreadState) (ctid); 249 UInt ret = 0; 250 UWord * stack; 251 NSegment const *seg; 252 SysRes res; 253 vki_sigset_t blockall, savedmask; 254 255 VG_ (sigfillset) (&blockall); 256 vg_assert (VG_ (is_running_thread) (ptid)); 257 vg_assert (VG_ (is_valid_tid) (ctid)); 258 stack = (UWord *) ML_ (allocstack) (ctid); 259 if (stack == NULL) { 260 res = VG_ (mk_SysRes_Error) (VKI_ENOMEM); 261 goto out; 262 } 263 setup_child (&ctst->arch, &ptst->arch); 264 265 /* on MIPS we need to set V0 and A3 to zero */ 266 ctst->arch.vex.guest_r2 = 0; 267 ctst->arch.vex.guest_r7 = 0; 268 if (sp != 0) 269 ctst->arch.vex.guest_r29 = sp; 270 271 ctst->os_state.parent = ptid; 272 ctst->sig_mask = ptst->sig_mask; 273 ctst->tmp_sig_mask = ptst->sig_mask; 274 275 /* Start the child with its threadgroup being the same as the 276 parent's. This is so that any exit_group calls that happen 277 after the child is created but before it sets its 278 os_state.threadgroup field for real (in thread_wrapper in 279 syswrap-linux.c), really kill the new thread. a.k.a this avoids 280 a race condition in which the thread is unkillable (via 281 exit_group) because its threadgroup is not set. The race window 282 is probably only a few hundred or a few thousand cycles long. 283 See #226116. */ 284 285 ctst->os_state.threadgroup = ptst->os_state.threadgroup; 286 seg = VG_ (am_find_nsegment) ((Addr) sp); 287 288 if (seg && seg->kind != SkResvn) { 289 ctst->client_stack_highest_word = (Addr) VG_PGROUNDUP (sp); 290 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start; 291 VG_ (register_stack) (seg->start, ctst->client_stack_highest_word); 292 if (debug) 293 VG_ (printf) ("tid %d: guessed client stack range %#lx-%#lx\n", 294 295 ctid, seg->start, VG_PGROUNDUP (sp)); 296 } else { 297 VG_ (message) (Vg_UserMsg, 298 "!? New thread %d starts with sp+%#lx) unmapped\n", 299 ctid, sp); 300 ctst->client_stack_szB = 0; 301 } 302 303 VG_TRACK (pre_thread_ll_create, ptid, ctid); 304 if (flags & VKI_CLONE_SETTLS) { 305 if (debug) 306 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls); 307 ctst->arch.vex.guest_r27 = child_tls; 308 res = sys_set_tls(ctid, child_tls); 309 if (sr_isError(res)) 310 goto out; 311 ctst->arch.vex.guest_r27 = child_tls; 312 } 313 314 flags &= ~VKI_CLONE_SETTLS; 315 VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask); 316 /* Create the new thread */ 317 ret = do_syscall_clone_mips_linux (ML_ (start_thread_NORETURN), 318 stack, flags, &VG_ (threads)[ctid], 319 child_tidptr, parent_tidptr, 320 0 /*child_tls*/); 321 322 /* High half word64 is syscall return value. Low half is 323 the entire CR, from which we need to extract CR0.SO. */ 324 if (debug) 325 VG_(printf)("ret: 0x%x\n", ret); 326 327 res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0); 328 329 VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL); 330 331 out: 332 if (sr_isError (res)) { 333 VG_(cleanup_thread) (&ctst->arch); 334 ctst->status = VgTs_Empty; 335 VG_TRACK (pre_thread_ll_exit, ctid); 336 } 337 ptst->arch.vex.guest_r2 = 0; 338 339 return res; 340 } 341 342 /* --------------------------------------------------------------------- 343 More thread stuff 344 ------------------------------------------------------------------ */ 345 346 // MIPS doesn't have any architecture specific thread stuff that 347 // needs to be cleaned up da li ????!!!!??? 348 void 349 VG_ (cleanup_thread) (ThreadArchState * arch) { } 350 351 void 352 setup_child ( /*OUT*/ ThreadArchState * child, 353 /*IN*/ ThreadArchState * parent) 354 { 355 /* We inherit our parent's guest state. */ 356 child->vex = parent->vex; 357 child->vex_shadow1 = parent->vex_shadow1; 358 child->vex_shadow2 = parent->vex_shadow2; 359 } 360 361 SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ) 362 { 363 VG_(threads)[tid].arch.vex.guest_ULR = tlsptr; 364 return VG_(mk_SysRes_Success)( 0 ); 365 } 366 367 /* --------------------------------------------------------------------- 368 mips handler for mmap and mmap2 369 ------------------------------------------------------------------ */ 370 static void notify_core_of_mmap(Addr a, SizeT len, UInt prot, 371 UInt flags, Int fd, Off64T offset) 372 { 373 Bool d; 374 375 /* 'a' is the return value from a real kernel mmap, hence: */ 376 vg_assert(VG_IS_PAGE_ALIGNED(a)); 377 /* whereas len is whatever the syscall supplied. So: */ 378 len = VG_PGROUNDUP(len); 379 380 d = VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset ); 381 382 if (d) 383 VG_(discard_translations)( (Addr64)a, (ULong)len, 384 "notify_core_of_mmap" ); 385 } 386 387 static void notify_tool_of_mmap(Addr a, SizeT len, UInt prot, ULong di_handle) 388 { 389 Bool rr, ww, xx; 390 391 /* 'a' is the return value from a real kernel mmap, hence: */ 392 vg_assert(VG_IS_PAGE_ALIGNED(a)); 393 /* whereas len is whatever the syscall supplied. So: */ 394 len = VG_PGROUNDUP(len); 395 396 rr = toBool(prot & VKI_PROT_READ); 397 ww = toBool(prot & VKI_PROT_WRITE); 398 xx = toBool(prot & VKI_PROT_EXEC); 399 400 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx, di_handle ); 401 } 402 403 /* Based on ML_(generic_PRE_sys_mmap) from syswrap-generic.c. 404 If we are trying to do mmap with VKI_MAP_SHARED flag we need to align the 405 start address on VKI_SHMLBA like we did in 406 VG_(am_mmap_file_float_valgrind_flags) 407 */ 408 static SysRes mips_PRE_sys_mmap(ThreadId tid, 409 UWord arg1, UWord arg2, UWord arg3, 410 UWord arg4, UWord arg5, Off64T arg6) 411 { 412 Addr advised; 413 SysRes sres; 414 MapRequest mreq; 415 Bool mreq_ok; 416 417 if (arg2 == 0) { 418 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping 419 shall be established. */ 420 return VG_(mk_SysRes_Error)( VKI_EINVAL ); 421 } 422 423 if (!VG_IS_PAGE_ALIGNED(arg1)) { 424 /* zap any misaligned addresses. */ 425 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case 426 to fail. Here, we catch them all. */ 427 return VG_(mk_SysRes_Error)( VKI_EINVAL ); 428 } 429 430 if (!VG_IS_PAGE_ALIGNED(arg6)) { 431 /* zap any misaligned offsets. */ 432 /* SuSV3 says: The off argument is constrained to be aligned and 433 sized according to the value returned by sysconf() when 434 passed _SC_PAGESIZE or _SC_PAGE_SIZE. */ 435 return VG_(mk_SysRes_Error)( VKI_EINVAL ); 436 } 437 438 /* Figure out what kind of allocation constraints there are 439 (fixed/hint/any), and ask aspacem what we should do. */ 440 mreq.start = arg1; 441 mreq.len = arg2; 442 if (arg4 & VKI_MAP_FIXED) { 443 mreq.rkind = MFixed; 444 } else 445 if (arg1 != 0) { 446 mreq.rkind = MHint; 447 } else { 448 mreq.rkind = MAny; 449 } 450 451 if ((VKI_SHMLBA > VKI_PAGE_SIZE) && (VKI_MAP_SHARED & arg4) 452 && !(VKI_MAP_FIXED & arg4)) 453 mreq.len = arg2 + VKI_SHMLBA - VKI_PAGE_SIZE; 454 455 /* Enquire ... */ 456 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); 457 458 if ((VKI_SHMLBA > VKI_PAGE_SIZE) && (VKI_MAP_SHARED & arg4) 459 && !(VKI_MAP_FIXED & arg4)) 460 advised = VG_ROUNDUP(advised, VKI_SHMLBA); 461 462 if (!mreq_ok) { 463 /* Our request was bounced, so we'd better fail. */ 464 return VG_(mk_SysRes_Error)( VKI_EINVAL ); 465 } 466 467 /* Otherwise we're OK (so far). Install aspacem's choice of 468 address, and let the mmap go through. */ 469 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3, 470 arg4 | VKI_MAP_FIXED, 471 arg5, arg6); 472 473 /* A refinement: it may be that the kernel refused aspacem's choice 474 of address. If we were originally asked for a hinted mapping, 475 there is still a last chance: try again at any address. 476 Hence: */ 477 if (mreq.rkind == MHint && sr_isError(sres)) { 478 mreq.start = 0; 479 mreq.len = arg2; 480 mreq.rkind = MAny; 481 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); 482 if (!mreq_ok) { 483 /* Our request was bounced, so we'd better fail. */ 484 return VG_(mk_SysRes_Error)( VKI_EINVAL ); 485 } 486 /* and try again with the kernel */ 487 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3, 488 arg4 | VKI_MAP_FIXED, 489 arg5, arg6); 490 } 491 492 if (!sr_isError(sres)) { 493 ULong di_handle; 494 /* Notify aspacem. */ 495 notify_core_of_mmap( 496 (Addr)sr_Res(sres), /* addr kernel actually assigned */ 497 arg2, /* length */ 498 arg3, /* prot */ 499 arg4, /* the original flags value */ 500 arg5, /* fd */ 501 arg6 /* offset */ 502 ); 503 /* Load symbols? */ 504 di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres), 505 False/*allow_SkFileV*/, (Int)arg5 ); 506 /* Notify the tool. */ 507 notify_tool_of_mmap( 508 (Addr)sr_Res(sres), /* addr kernel actually assigned */ 509 arg2, /* length */ 510 arg3, /* prot */ 511 di_handle /* so the tool can refer to the read debuginfo later, 512 if it wants. */ 513 ); 514 } 515 516 /* Stay sane */ 517 if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED)) 518 vg_assert(sr_Res(sres) == arg1); 519 520 return sres; 521 } 522 /* --------------------------------------------------------------------- 523 PRE/POST wrappers for mips/Linux-specific syscalls 524 ------------------------------------------------------------------ */ 525 #define PRE(name) DEFN_PRE_TEMPLATE(mips_linux, name) 526 #define POST(name) DEFN_POST_TEMPLATE(mips_linux, name) 527 528 /* Add prototypes for the wrappers declared here, so that gcc doesn't 529 harass us for not having prototypes. Really this is a kludge -- 530 the right thing to do is to make these wrappers 'static' since they 531 aren't visible outside this file, but that requires even more macro 532 magic. */ 533 //DECL_TEMPLATE (mips_linux, sys_syscall); 534 DECL_TEMPLATE (mips_linux, sys_mmap); 535 DECL_TEMPLATE (mips_linux, sys_mmap2); 536 DECL_TEMPLATE (mips_linux, sys_stat64); 537 DECL_TEMPLATE (mips_linux, sys_lstat64); 538 DECL_TEMPLATE (mips_linux, sys_fstatat64); 539 DECL_TEMPLATE (mips_linux, sys_fstat64); 540 DECL_TEMPLATE (mips_linux, sys_clone); 541 DECL_TEMPLATE (mips_linux, sys_sigreturn); 542 DECL_TEMPLATE (mips_linux, sys_rt_sigreturn); 543 DECL_TEMPLATE (mips_linux, sys_cacheflush); 544 DECL_TEMPLATE (mips_linux, sys_set_thread_area); 545 DECL_TEMPLATE (mips_linux, sys_pipe); 546 547 PRE(sys_mmap2) 548 { 549 /* Exactly like sys_mmap() except the file offset is specified in pagesize 550 units rather than bytes, so that it can be used for files bigger than 551 2^32 bytes. */ 552 SysRes r; 553 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", ARG1, (ULong) ARG2, 554 ARG3, ARG4, ARG5, ARG6); 555 PRE_REG_READ6(long, "mmap2", unsigned long, start, unsigned long, length, 556 unsigned long, prot, unsigned long, flags, 557 unsigned long, fd, unsigned long, offset); 558 r = mips_PRE_sys_mmap(tid, ARG1, ARG2, ARG3, ARG4, ARG5, 559 VKI_PAGE_SIZE * (Off64T) ARG6); 560 SET_STATUS_from_SysRes(r); 561 } 562 563 PRE(sys_mmap) 564 { 565 SysRes r; 566 PRINT("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong) ARG2, 567 ARG3, ARG4, ARG5, ARG6); 568 PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length, 569 int, prot, int, flags, int, fd, unsigned long, offset); 570 r = mips_PRE_sys_mmap(tid, ARG1, ARG2, ARG3, ARG4, ARG5, (Off64T) ARG6); 571 SET_STATUS_from_SysRes(r); 572 } 573 574 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily 575 // applicable to every architecture -- I think only to 32-bit archs. 576 // We're going to need something like linux/core_os32.h for such 577 // things, eventually, I think. --njn 578 579 PRE (sys_lstat64) 580 { 581 PRINT ("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2); 582 PRE_REG_READ2 (long, "lstat64", char *, file_name, struct stat64 *, buf); 583 PRE_MEM_RASCIIZ ("lstat64(file_name)", ARG1); 584 PRE_MEM_WRITE ("lstat64(buf)", ARG2, sizeof (struct vki_stat64)); 585 } 586 587 POST (sys_lstat64) 588 { 589 vg_assert (SUCCESS); 590 if (RES == 0) 591 { 592 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64)); 593 } 594 } 595 596 PRE (sys_stat64) 597 { 598 PRINT ("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2); 599 PRE_REG_READ2 (long, "stat64", char *, file_name, struct stat64 *, buf); 600 PRE_MEM_RASCIIZ ("stat64(file_name)", ARG1); 601 PRE_MEM_WRITE ("stat64(buf)", ARG2, sizeof (struct vki_stat64)); 602 } 603 604 POST (sys_stat64) 605 { 606 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64)); 607 } 608 609 PRE (sys_fstatat64) 610 { 611 PRINT ("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", ARG1, ARG2, (char *) ARG2, 612 ARG3); 613 PRE_REG_READ3 (long, "fstatat64", int, dfd, char *, file_name, 614 struct stat64 *, buf); 615 PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2); 616 PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64)); 617 } 618 619 POST (sys_fstatat64) 620 { 621 POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64)); 622 } 623 624 PRE (sys_fstat64) 625 { 626 PRINT ("sys_fstat64 ( %ld, %#lx )", ARG1, ARG2); 627 PRE_REG_READ2 (long, "fstat64", unsigned long, fd, struct stat64 *, buf); 628 PRE_MEM_WRITE ("fstat64(buf)", ARG2, sizeof (struct vki_stat64)); 629 } 630 631 POST (sys_fstat64) 632 { 633 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64)); 634 } 635 636 PRE (sys_clone) 637 { 638 Bool badarg = False; 639 UInt cloneflags; 640 PRINT ("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3, 641 ARG4, ARG5); 642 PRE_REG_READ2 (int, "clone", unsigned long, flags, void *, child_stack); 643 if (ARG1 & VKI_CLONE_PARENT_SETTID) 644 { 645 if (VG_ (tdict).track_pre_reg_read) 646 { 647 PRA3 ("clone", int *, parent_tidptr); 648 } 649 PRE_MEM_WRITE ("clone(parent_tidptr)", ARG3, sizeof (Int)); 650 if (!VG_ (am_is_valid_for_client)(ARG3, sizeof (Int), VKI_PROT_WRITE)) 651 { 652 badarg = True; 653 } 654 } 655 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 656 { 657 if (VG_ (tdict).track_pre_reg_read) 658 { 659 PRA5 ("clone", int *, child_tidptr); 660 } 661 PRE_MEM_WRITE ("clone(child_tidptr)", ARG5, sizeof (Int)); 662 if (!VG_ (am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE)) 663 { 664 badarg = True; 665 } 666 } 667 if (badarg) 668 { 669 SET_STATUS_Failure (VKI_EFAULT); 670 return; 671 } 672 cloneflags = ARG1; 673 if (!ML_ (client_signal_OK) (ARG1 & VKI_CSIGNAL)) 674 { 675 SET_STATUS_Failure (VKI_EINVAL); 676 return; 677 } 678 /* Only look at the flags we really care about */ 679 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 680 |VKI_CLONE_FILES | VKI_CLONE_VFORK)) 681 { 682 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: 683 /* thread creation */ 684 PRINT ("sys_clone1 ( %#lx, %#lx, %#lx, %#lx, %#lx )", 685 ARG1, ARG2, ARG3, ARG4, ARG5); 686 SET_STATUS_from_SysRes (do_clone (tid, 687 ARG1, /* flags */ 688 (Addr) ARG2, /* child SP */ 689 (Int *) ARG3, /* parent_tidptr */ 690 (Int *) ARG5, /* child_tidptr */ 691 (Addr) ARG4)); /* child_tls */ 692 693 break; 694 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ 695 /* FALLTHROUGH - assume vfork == fork */ 696 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); 697 case 0: /* plain fork */ 698 SET_STATUS_from_SysRes (ML_ (do_fork_clone) (tid, 699 cloneflags, /* flags */ 700 (Int *) ARG3, /* parent_tidptr */ 701 (Int *) ARG5)); /* child_tidptr */ 702 break; 703 default: 704 /* should we just ENOSYS? */ 705 VG_ (message) (Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1); 706 VG_ (message) (Vg_UserMsg, "\n"); 707 VG_ (message) (Vg_UserMsg, "The only supported clone() uses are:\n"); 708 VG_ (message) (Vg_UserMsg, 709 " - via a threads library (LinuxThreads or NPTL)\n"); 710 VG_ (message) (Vg_UserMsg, 711 " - via the implementation of fork or vfork\n"); 712 VG_ (unimplemented)("Valgrind does not support general clone()."); 713 } 714 if (SUCCESS) 715 { 716 if (ARG1 & VKI_CLONE_PARENT_SETTID) 717 POST_MEM_WRITE (ARG3, sizeof (Int)); 718 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 719 POST_MEM_WRITE (ARG5, sizeof (Int)); 720 /* Thread creation was successful; let the child have the chance 721 * to run */ 722 *flags |= SfYieldAfter; 723 } 724 } 725 726 PRE (sys_sigreturn) 727 { 728 PRINT ("sys_sigreturn ( )"); 729 vg_assert (VG_ (is_valid_tid) (tid)); 730 vg_assert (tid >= 1 && tid < VG_N_THREADS); 731 vg_assert (VG_ (is_running_thread) (tid)); 732 VG_ (sigframe_destroy) (tid, False); 733 /* Tell the driver not to update the guest state with the "result", 734 and set a bogus result to keep it happy. */ 735 *flags |= SfNoWriteResult; 736 SET_STATUS_Success (0); 737 /* Check to see if any signals arose as a result of this. */ 738 *flags |= SfPollAfter; 739 } 740 741 PRE (sys_rt_sigreturn) 742 { 743 PRINT ("rt_sigreturn ( )"); 744 vg_assert (VG_ (is_valid_tid) (tid)); 745 vg_assert (tid >= 1 && tid < VG_N_THREADS); 746 vg_assert (VG_ (is_running_thread) (tid)); 747 /* Restore register state from frame and remove it */ 748 VG_ (sigframe_destroy) (tid, True); 749 /* Tell the driver not to update the guest state with the "result", 750 and set a bogus result to keep it happy. */ 751 *flags |= SfNoWriteResult; 752 SET_STATUS_Success (0); 753 /* Check to see if any signals arose as a result of this. */ 754 *flags |= SfPollAfter; 755 } 756 757 PRE (sys_set_thread_area) 758 { 759 PRINT ("set_thread_area (%lx)", ARG1); 760 PRE_REG_READ1(long, "set_thread_area", unsigned long, addr); 761 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) ); 762 } 763 764 /* Very much MIPS specific */ 765 PRE (sys_cacheflush) 766 { 767 PRINT ("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3); 768 PRE_REG_READ3(long, "cacheflush", unsigned long, addr, 769 int, nbytes, int, cache); 770 VG_ (discard_translations) ((Addr64) ARG1, ((ULong) ARG2), 771 "PRE(sys_cacheflush)"); 772 SET_STATUS_Success (0); 773 } 774 775 PRE(sys_pipe) 776 { 777 PRINT("sys_pipe ( %#lx )", ARG1); 778 PRE_REG_READ1(int, "pipe", int *, filedes); 779 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) ); 780 } 781 782 POST(sys_pipe) 783 { 784 Int p0, p1; 785 vg_assert(SUCCESS); 786 p0 = RES; 787 p1 = sr_ResEx(status->sres); 788 789 if (!ML_(fd_allowed)(p0, "pipe", tid, True) || 790 !ML_(fd_allowed)(p1, "pipe", tid, True)) { 791 VG_(close)(p0); 792 VG_(close)(p1); 793 SET_STATUS_Failure( VKI_EMFILE ); 794 } else { 795 if (VG_(clo_track_fds)) { 796 ML_(record_fd_open_nameless)(tid, p0); 797 ML_(record_fd_open_nameless)(tid, p1); 798 } 799 } 800 } 801 802 #undef PRE 803 #undef POST 804 805 /* --------------------------------------------------------------------- 806 The mips/Linux syscall table 807 ------------------------------------------------------------------ */ 808 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(mips_linux, sysno, name) 809 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(mips_linux, sysno, name) 810 811 // This table maps from __NR_xxx syscall numbers (from 812 // linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo() 813 // wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S). 814 // 815 816 // For those syscalls not handled by Valgrind, the annotation indicate its 817 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? 818 // (unknown). 819 820 static SyscallTableEntry syscall_main_table[] = { 821 //.. PLAXY (__NR_syscall, sys_syscall), // 0 822 GENX_ (__NR_exit, sys_exit), // 1 823 GENX_ (__NR_fork, sys_fork), // 2 824 GENXY (__NR_read, sys_read), // 3 825 GENX_ (__NR_write, sys_write), // 4 826 GENXY (__NR_open, sys_open), // 5 827 GENXY (__NR_close, sys_close), // 6 828 GENXY (__NR_waitpid, sys_waitpid), // 7 829 GENXY (__NR_creat, sys_creat), // 8 830 GENX_ (__NR_link, sys_link), // 9 831 GENX_ (__NR_unlink, sys_unlink), // 10 832 GENX_ (__NR_execve, sys_execve), // 11 833 GENX_ (__NR_chdir, sys_chdir), // 12 834 GENXY (__NR_time, sys_time), // 13 835 GENX_ (__NR_mknod, sys_mknod), // 14 836 GENX_ (__NR_chmod, sys_chmod), // 15 837 GENX_ (__NR_lchown, sys_lchown), // 16 838 //.. 839 LINX_ (__NR_lseek, sys_lseek), // 19 840 GENX_ (__NR_getpid, sys_getpid), // 20 841 LINX_ (__NR_mount, sys_mount), // 21 842 LINX_ (__NR_umount, sys_oldumount), // 22 843 GENX_ (__NR_setuid, sys_setuid), // 23 844 GENX_ (__NR_getuid, sys_getuid), // 24 845 LINX_ (__NR_stime, sys_stime), // 25 846 //.. PLAXY(__NR_ptrace, sys_ptrace), // 26 847 GENX_ (__NR_alarm, sys_alarm), // 27 848 //.. // (__NR_oldfstat, sys_fstat), // 28 849 GENX_ (__NR_pause, sys_pause), // 29 850 LINX_ (__NR_utime, sys_utime), // 30 851 //.. GENX_(__NR_stty, sys_ni_syscall), // 31 852 //.. GENX_(__NR_gtty, sys_ni_syscall), // 32 853 GENX_ (__NR_access, sys_access), // 33 854 //.. GENX_(__NR_nice, sys_nice), // 34 855 //.. GENX_(__NR_ftime, sys_ni_syscall), // 35 856 //.. GENX_(__NR_sync, sys_sync), // 36 857 GENX_ (__NR_kill, sys_kill), // 37 858 GENX_ (__NR_rename, sys_rename), // 38 859 GENX_ (__NR_mkdir, sys_mkdir), // 39 860 GENX_ (__NR_rmdir, sys_rmdir), // 40 861 GENXY (__NR_dup, sys_dup), // 41 862 PLAXY (__NR_pipe, sys_pipe), // 42 863 GENXY (__NR_times, sys_times), // 43 864 //.. GENX_(__NR_prof, sys_ni_syscall), // 44 865 GENX_ (__NR_brk, sys_brk), // 45 866 GENX_ (__NR_setgid, sys_setgid), // 46 867 GENX_ (__NR_getgid, sys_getgid), // 47 868 //.. // (__NR_signal, sys_signal), // 48 869 GENX_ (__NR_geteuid, sys_geteuid), // 49 870 GENX_ (__NR_getegid, sys_getegid), // 50 871 //.. GENX_(__NR_acct, sys_acct), // 51 872 LINX_ (__NR_umount2, sys_umount), // 52 873 //.. GENX_(__NR_lock, sys_ni_syscall), // 53 874 LINXY (__NR_ioctl, sys_ioctl), // 54 875 LINXY (__NR_fcntl, sys_fcntl), // 55 876 //.. GENX_(__NR_mpx, sys_ni_syscall), // 56 877 GENX_ (__NR_setpgid, sys_setpgid), // 57 878 //.. GENX_(__NR_ulimit, sys_ni_syscall), // 58 879 //.. // (__NR_oldolduname, sys_olduname), // 59 880 GENX_ (__NR_umask, sys_umask), // 60 881 GENX_ (__NR_chroot, sys_chroot), // 61 882 //.. // (__NR_ustat, sys_ustat) // 62 883 GENXY (__NR_dup2, sys_dup2), // 63 884 GENX_ (__NR_getppid, sys_getppid), // 64 885 GENX_ (__NR_getpgrp, sys_getpgrp), // 65 886 GENX_ (__NR_setsid, sys_setsid), // 66 887 LINXY (__NR_sigaction, sys_sigaction), // 67 888 //.. // (__NR_sgetmask, sys_sgetmask), // 68 889 //.. // (__NR_ssetmask, sys_ssetmask), // 69 890 GENX_ (__NR_setreuid, sys_setreuid), // 70 891 GENX_ (__NR_setregid, sys_setregid), // 71 892 // PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72 893 LINXY (__NR_sigpending, sys_sigpending), // 73 894 //.. // (__NR_sethostname, sys_sethostname), // 74 895 GENX_ (__NR_setrlimit, sys_setrlimit), // 75 896 GENXY (__NR_getrlimit, sys_getrlimit), // 76 897 GENXY (__NR_getrusage, sys_getrusage), // 77 898 GENXY (__NR_gettimeofday, sys_gettimeofday), // 78 899 GENX_ (__NR_settimeofday, sys_settimeofday), // 79 900 GENXY (__NR_getgroups, sys_getgroups), // 80 901 GENX_ (__NR_setgroups, sys_setgroups), // 81 902 //.. PLAX_(__NR_select, old_select), // 82 903 GENX_ (__NR_symlink, sys_symlink), // 83 904 //.. // (__NR_oldlstat, sys_lstat), // 84 905 GENX_ (__NR_readlink, sys_readlink), // 85 906 //.. // (__NR_uselib, sys_uselib), // 86 907 //.. // (__NR_swapon, sys_swapon), // 87 908 //.. // (__NR_reboot, sys_reboot), // 88 909 //.. // (__NR_readdir, old_readdir), // 89 910 PLAX_ (__NR_mmap, sys_mmap), // 90 911 GENXY (__NR_munmap, sys_munmap), // 91 912 GENX_ (__NR_truncate, sys_truncate), // 92 913 GENX_ (__NR_ftruncate, sys_ftruncate), // 93 914 GENX_ (__NR_fchmod, sys_fchmod), // 94 915 GENX_ (__NR_fchown, sys_fchown), // 95 916 GENX_ (__NR_getpriority, sys_getpriority), // 96 917 GENX_ (__NR_setpriority, sys_setpriority), // 97 918 //.. GENX_(__NR_profil, sys_ni_syscall), // 98 919 GENXY (__NR_statfs, sys_statfs), // 99 920 GENXY (__NR_fstatfs, sys_fstatfs), // 100 921 //.. LINX_(__NR_ioperm, sys_ioperm), // 101 922 LINXY (__NR_socketcall, sys_socketcall), // 102 923 LINXY (__NR_syslog, sys_syslog), // 103 924 GENXY (__NR_setitimer, sys_setitimer), // 104 925 //.. GENXY(__NR_getitimer, sys_getitimer), // 105 926 GENXY (__NR_stat, sys_newstat), // 106 927 GENXY (__NR_lstat, sys_newlstat), // 107 928 GENXY (__NR_fstat, sys_newfstat), // 108 929 //.. // (__NR_olduname, sys_uname), // 109 930 //.. GENX_(__NR_iopl, sys_iopl), // 110 931 //.. LINX_(__NR_vhangup, sys_vhangup), // 111 932 //.. GENX_(__NR_idle, sys_ni_syscall), // 112 933 //.. // (__NR_vm86old, sys_vm86old), // 113 934 GENXY (__NR_wait4, sys_wait4), // 114 935 //.. // (__NR_swapoff, sys_swapoff), // 115 936 LINXY (__NR_sysinfo, sys_sysinfo), // 116 937 LINXY (__NR_ipc, sys_ipc), // 117 938 GENX_ (__NR_fsync, sys_fsync), // 118 939 PLAX_ (__NR_sigreturn, sys_sigreturn), // 119 940 PLAX_ (__NR_clone, sys_clone), // 120 941 //.. // (__NR_setdomainname, sys_setdomainname), // 121 942 GENXY (__NR_uname, sys_newuname), // 122 943 //.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123 944 //.. LINXY(__NR_adjtimex, sys_adjtimex), // 124 945 GENXY (__NR_mprotect, sys_mprotect), // 125 946 LINXY (__NR_sigprocmask, sys_sigprocmask), // 126 947 //.. GENX_(__NR_create_module, sys_ni_syscall), // 127 948 //.. GENX_(__NR_init_module, sys_init_module), // 128 949 //.. // (__NR_delete_module, sys_delete_module), // 129 950 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 951 //.. LINX_(__NR_quotactl, sys_quotactl), // 131 952 GENX_ (__NR_getpgid, sys_getpgid), // 132 953 GENX_ (__NR_fchdir, sys_fchdir), // 133 954 //.. // (__NR_bdflush, sys_bdflush), // 134 955 //.. // (__NR_sysfs, sys_sysfs), // 135 956 LINX_ (__NR_personality, sys_personality), // 136 957 //.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137 958 LINX_ (__NR_setfsuid, sys_setfsuid), // 138 959 LINX_ (__NR_setfsgid, sys_setfsgid), // 139 960 LINXY (__NR__llseek, sys_llseek), // 140 961 GENXY (__NR_getdents, sys_getdents), // 141 962 GENX_ (__NR__newselect, sys_select), // 142 963 GENX_ (__NR_flock, sys_flock), // 143 964 GENX_ (__NR_msync, sys_msync), // 144 965 GENXY (__NR_readv, sys_readv), // 145 966 GENX_ (__NR_writev, sys_writev), // 146 967 PLAX_ (__NR_cacheflush, sys_cacheflush), // 147 968 GENX_ (__NR_getsid, sys_getsid), // 151 969 GENX_ (__NR_fdatasync, sys_fdatasync), // 152 970 LINXY (__NR__sysctl, sys_sysctl), // 153 971 GENX_ (__NR_mlock, sys_mlock), // 154 972 GENX_ (__NR_munlock, sys_munlock), // 155 973 GENX_ (__NR_mlockall, sys_mlockall), // 156 974 LINX_ (__NR_munlockall, sys_munlockall), // 157 975 //.. LINXY(__NR_sched_setparam, sys_sched_setparam), // 158 976 LINXY (__NR_sched_getparam, sys_sched_getparam), // 159 977 LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler), // 160 978 LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler), // 161 979 LINX_ (__NR_sched_yield, sys_sched_yield), // 162 980 LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max), // 163 981 LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min), // 164 982 //.. //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 165 983 GENXY (__NR_nanosleep, sys_nanosleep), // 166 984 GENX_ (__NR_mremap, sys_mremap), // 167 985 LINXY (__NR_accept, sys_accept), // 168 986 LINX_ (__NR_bind, sys_bind), // 169 987 LINX_ (__NR_connect, sys_connect), // 170 988 LINXY (__NR_getpeername, sys_getpeername), // 171 989 LINXY (__NR_getsockname, sys_getsockname), // 172 990 LINXY (__NR_getsockopt, sys_getsockopt), // 173 991 LINX_ (__NR_listen, sys_listen), // 174 992 LINXY (__NR_recv, sys_recv), // 175 993 LINXY (__NR_recvfrom, sys_recvfrom), // 176 994 LINXY (__NR_recvmsg, sys_recvmsg), // 177 995 LINX_ (__NR_send, sys_send), // 178 996 LINX_ (__NR_sendmsg, sys_sendmsg), // 179 997 LINX_ (__NR_sendto, sys_sendto), // 180 998 LINX_ (__NR_setsockopt, sys_setsockopt), // 181 999 LINX_ (__NR_shutdown, sys_shutdown), // 182 1000 LINXY (__NR_socket, sys_socket), // 183 1001 LINXY (__NR_socketpair, sys_socketpair), // 184 1002 LINX_ (__NR_setresuid, sys_setresuid), // 185 1003 LINXY (__NR_getresuid, sys_getresuid), // 186 1004 //.. GENX_(__NR_query_module, sys_ni_syscall), // 187 1005 GENXY (__NR_poll, sys_poll), // 188 1006 //.. 1007 LINX_ (__NR_setresgid, sys_setresgid), // 190 1008 LINXY (__NR_getresgid, sys_getresgid), // 191 1009 LINXY (__NR_prctl, sys_prctl), // 192 1010 PLAX_ (__NR_rt_sigreturn, sys_rt_sigreturn), // 193 1011 LINXY (__NR_rt_sigaction, sys_rt_sigaction), // 194 1012 LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask), // 195 1013 LINXY (__NR_rt_sigpending, sys_rt_sigpending), // 196 1014 LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 197 1015 LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 198 1016 LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend), // 199 1017 GENXY (__NR_pread64, sys_pread64), // 200 1018 GENX_ (__NR_pwrite64, sys_pwrite64), // 201 1019 GENX_ (__NR_chown, sys_chown), // 202 1020 GENXY (__NR_getcwd, sys_getcwd), // 203 1021 LINXY (__NR_capget, sys_capget), // 204 1022 //.. LINX_(__NR_capset, sys_capset), // 205 1023 GENXY (__NR_sigaltstack, sys_sigaltstack), // 206 1024 LINXY (__NR_sendfile, sys_sendfile), // 207 1025 //.. GENXY(__NR_getpmsg, sys_getpmsg), // 208 1026 //.. GENX_(__NR_putpmsg, sys_putpmsg), // 209 1027 PLAX_ (__NR_mmap2, sys_mmap2), // 210 1028 // GENX_(__NR_truncate64, sys_truncate64), // 211 1029 GENX_ (__NR_ftruncate64, sys_ftruncate64), // 212 1030 PLAXY (__NR_stat64, sys_stat64), // 213 1031 PLAXY (__NR_lstat64, sys_lstat64), // 214 1032 PLAXY (__NR_fstat64, sys_fstat64), // 215 1033 //.. 1034 GENXY (__NR_mincore, sys_mincore), // 217 1035 GENX_ (__NR_madvise, sys_madvise), // 218 1036 GENXY (__NR_getdents64, sys_getdents64), // 219 1037 LINXY (__NR_fcntl64, sys_fcntl64), // 220 1038 //.. 1039 LINX_ (__NR_gettid, sys_gettid), // 222 1040 //.. 1041 LINXY (__NR_getxattr, sys_getxattr), // 227 1042 LINXY (__NR_lgetxattr, sys_lgetxattr), // 228 1043 LINXY (__NR_fgetxattr, sys_fgetxattr), // 229 1044 LINXY (__NR_listxattr, sys_listxattr), // 230 1045 LINXY (__NR_llistxattr, sys_llistxattr), // 231 1046 LINXY (__NR_flistxattr, sys_flistxattr), // 232 1047 LINX_ (__NR_removexattr, sys_removexattr), // 233 1048 LINX_ (__NR_lremovexattr, sys_lremovexattr), // 234 1049 LINX_ (__NR_fremovexattr, sys_fremovexattr), // 235 1050 //.. 1051 LINXY (__NR_sendfile64, sys_sendfile64), // 237 1052 LINXY (__NR_futex, sys_futex), // 238 1053 LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity), // 239 1054 LINXY (__NR_sched_getaffinity, sys_sched_getaffinity), // 240 1055 LINX_ (__NR_io_setup, sys_io_setup), // 241 1056 LINX_ (__NR_io_destroy, sys_io_destroy), // 242 1057 LINXY (__NR_io_getevents, sys_io_getevents), // 243 1058 LINX_ (__NR_io_submit, sys_io_submit), // 244 1059 LINXY (__NR_io_cancel, sys_io_cancel), // 245 1060 LINX_ (__NR_exit_group, sys_exit_group), // 246 1061 //.. 1062 LINXY (__NR_epoll_create, sys_epoll_create), // 248 1063 LINX_ (__NR_epoll_ctl, sys_epoll_ctl), // 249 1064 LINXY (__NR_epoll_wait, sys_epoll_wait), // 250 1065 //.. 1066 LINX_ (__NR_set_tid_address, sys_set_tid_address), // 252 1067 LINX_ (__NR_fadvise64, sys_fadvise64), // 254 1068 GENXY (__NR_statfs64, sys_statfs64), // 255 1069 GENXY (__NR_fstatfs64, sys_fstatfs64), // 256 1070 //.. 1071 LINXY (__NR_timer_create, sys_timer_create), // 257 1072 LINXY (__NR_timer_settime, sys_timer_settime), // 258 1073 LINXY (__NR_timer_gettime, sys_timer_gettime), // 259 1074 LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun), // 260 1075 LINX_ (__NR_timer_delete, sys_timer_delete), // 261 1076 LINX_ (__NR_clock_settime, sys_clock_settime), // 262 1077 LINXY (__NR_clock_gettime, sys_clock_gettime), // 263 1078 LINXY (__NR_clock_getres, sys_clock_getres), // 264 1079 LINXY (__NR_clock_nanosleep, sys_clock_nanosleep), // 265 1080 LINXY (__NR_tgkill, sys_tgkill), // 266 1081 //.. GENX_(__NR_utimes, sys_utimes), // 267 1082 LINXY (__NR_get_mempolicy, sys_get_mempolicy), // 269 1083 LINX_ (__NR_set_mempolicy, sys_set_mempolicy), // 270 1084 LINXY (__NR_mq_open, sys_mq_open), // 271 1085 LINX_ (__NR_mq_unlink, sys_mq_unlink), // 272 1086 LINX_ (__NR_mq_timedsend, sys_mq_timedsend), // 273 1087 LINXY (__NR_mq_timedreceive, sys_mq_timedreceive), // 274 1088 LINX_ (__NR_mq_notify, sys_mq_notify), // 275 1089 LINXY (__NR_mq_getsetattr, sys_mq_getsetattr), // 276 1090 LINX_ (__NR_inotify_init, sys_inotify_init), // 275 1091 LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch), // 276 1092 LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277 1093 //.. 1094 PLAX_ (__NR_set_thread_area, sys_set_thread_area), // 283 1095 //.. 1096 LINXY (__NR_openat, sys_openat), // 288 1097 LINX_ (__NR_mkdirat, sys_mkdirat), // 289 1098 LINX_ (__NR_mknodat, sys_mknodat), // 290 1099 LINX_ (__NR_fchownat, sys_fchownat), // 291 1100 LINX_ (__NR_futimesat, sys_futimesat), // 292 1101 PLAXY (__NR_fstatat64, sys_fstatat64), // 293 1102 LINX_ (__NR_unlinkat, sys_unlinkat), // 294 1103 LINX_ (__NR_renameat, sys_renameat), // 295 1104 LINX_ (__NR_linkat, sys_linkat), // 296 1105 LINX_ (__NR_symlinkat, sys_symlinkat), // 297 1106 LINX_ (__NR_readlinkat, sys_readlinkat), // 298 1107 LINX_ (__NR_fchmodat, sys_fchmodat), // 299 1108 LINX_ (__NR_faccessat, sys_faccessat), // 300 1109 //.. 1110 LINXY (__NR_ppoll, sys_ppoll), // 302 1111 //.. 1112 LINX_ (__NR_set_robust_list, sys_set_robust_list), // 309 1113 LINXY (__NR_get_robust_list, sys_get_robust_list), // 310 1114 //.. 1115 LINXY (__NR_epoll_pwait, sys_epoll_pwait), // 313 1116 //.. 1117 LINX_ (__NR_utimensat, sys_utimensat), // 316 1118 //.. 1119 LINX_ (__NR_fallocate, sys_fallocate), // 320 1120 LINXY (__NR_timerfd_create, sys_timerfd_create), // 321 1121 LINXY (__NR_timerfd_gettime, sys_timerfd_gettime), // 322 1122 LINXY (__NR_timerfd_settime, sys_timerfd_settime), // 323 1123 LINXY (__NR_signalfd4, sys_signalfd4), // 324 1124 LINXY (__NR_eventfd2, sys_eventfd2), // 325 1125 //.. 1126 LINXY (__NR_pipe2, sys_pipe2), // 328 1127 LINXY (__NR_inotify_init1, sys_inotify_init1), // 329 1128 //.. 1129 LINXY (__NR_prlimit64, sys_prlimit64), // 338 1130 //.. 1131 LINXY (__NR_clock_adjtime, sys_clock_adjtime), // 341 1132 //.. 1133 LINXY (__NR_process_vm_readv, sys_process_vm_readv), // 345 1134 LINX_ (__NR_process_vm_writev, sys_process_vm_writev) // 346 1135 }; 1136 1137 SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno) 1138 { 1139 const UInt syscall_main_table_size 1140 = sizeof (syscall_main_table) / sizeof (syscall_main_table[0]); 1141 /* Is it in the contiguous initial section of the table? */ 1142 if (sysno < syscall_main_table_size) { 1143 SyscallTableEntry * sys = &syscall_main_table[sysno]; 1144 if (sys->before == NULL) 1145 return NULL; /* No entry. */ 1146 else 1147 return sys; 1148 } 1149 /* Can't find a wrapper. */ 1150 return NULL; 1151 } 1152 1153 #endif // defined(VGP_mips32_linux) 1154 1155 /*--------------------------------------------------------------------*/ 1156 /*--- end syswrap-mips-linux.c ---*/ 1157 /*--------------------------------------------------------------------*/ 1158