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