1 2 /*--------------------------------------------------------------------*/ 3 /*--- Platform-specific syscalls stuff. syswrap-arm-linux.c -----*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2013 Nicholas Nethercote 11 njn (at) valgrind.org 12 Copyright (C) 2008-2013 Evan Geller 13 gaze (at) bea.ms 14 15 This program is free software; you can redistribute it and/or 16 modify it under the terms of the GNU General Public License as 17 published by the Free Software Foundation; either version 2 of the 18 License, or (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, but 21 WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program; if not, write to the Free Software 27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28 02111-1307, USA. 29 30 The GNU General Public License is contained in the file COPYING. 31 */ 32 33 #if defined(VGP_arm_linux) 34 35 #include "pub_core_basics.h" 36 #include "pub_core_vki.h" 37 #include "pub_core_vkiscnums.h" 38 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 39 #include "pub_core_threadstate.h" 40 #include "pub_core_aspacemgr.h" 41 #include "pub_core_debuglog.h" 42 #include "pub_core_libcbase.h" 43 #include "pub_core_libcassert.h" 44 #include "pub_core_libcprint.h" 45 #include "pub_core_libcproc.h" 46 #include "pub_core_libcsignal.h" 47 #include "pub_core_options.h" 48 #include "pub_core_scheduler.h" 49 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)() 50 #include "pub_core_signals.h" 51 #include "pub_core_syscall.h" 52 #include "pub_core_syswrap.h" 53 #include "pub_core_tooliface.h" 54 #include "pub_core_stacks.h" // VG_(register_stack) 55 #include "pub_core_transtab.h" // VG_(discard_translations) 56 57 #include "priv_types_n_macros.h" 58 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */ 59 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */ 60 #include "priv_syswrap-main.h" 61 62 63 /* --------------------------------------------------------------------- 64 clone() handling 65 ------------------------------------------------------------------ */ 66 67 /* Call f(arg1), but first switch stacks, using 'stack' as the new 68 stack, and use 'retaddr' as f's return-to address. Also, clear all 69 the integer registers before entering f.*/ 70 __attribute__((noreturn)) 71 void ML_(call_on_new_stack_0_1) ( Addr stack, 72 Addr retaddr, 73 void (*f)(Word), 74 Word arg1 ); 75 // r0 = stack 76 // r1 = retaddr 77 // r2 = f 78 // r3 = arg1 79 asm( 80 ".text\n" 81 ".globl vgModuleLocal_call_on_new_stack_0_1\n" 82 "vgModuleLocal_call_on_new_stack_0_1:\n" 83 " mov sp,r0\n\t" /* Stack pointer */ 84 " mov lr,r1\n\t" /* Return address */ 85 " mov r0,r3\n\t" /* First argument */ 86 " push {r2}\n\t" /* So we can ret to the new dest */ 87 " mov r1, #0\n\t" /* Clear our GPRs */ 88 " mov r2, #0\n\t" 89 " mov r3, #0\n\t" 90 " mov r4, #0\n\t" 91 " mov r5, #0\n\t" 92 " mov r6, #0\n\t" 93 " mov r7, #0\n\t" 94 " mov r8, #0\n\t" 95 " mov r9, #0\n\t" 96 " mov r10, #0\n\t" 97 " mov r11, #0\n\t" 98 " mov r12, #0\n\t" 99 " pop {pc}\n\t" /* Herrre we go! */ 100 ".previous\n" 101 ); 102 103 104 #define __NR_CLONE VG_STRINGIFY(__NR_clone) 105 #define __NR_EXIT VG_STRINGIFY(__NR_exit) 106 107 extern 108 ULong do_syscall_clone_arm_linux ( Word (*fn)(void *), 109 void* stack, 110 Int flags, 111 void* arg, 112 Int* child_tid, 113 Int* parent_tid, 114 void* tls ); 115 asm( 116 ".text\n" 117 ".globl do_syscall_clone_arm_linux\n" 118 "do_syscall_clone_arm_linux:\n" 119 120 /*Setup child stack */ 121 " str r0, [r1, #-4]!\n" 122 " str r3, [r1, #-4]!\n" 123 " push {r4,r7}\n" 124 " mov r0, r2\n" /* arg1: flags */ 125 /* r1 (arg2) is already our child's stack */ 126 " ldr r2, [sp, #12]\n" // parent tid 127 " ldr r3, [sp, #16]\n" // tls 128 " ldr r4, [sp, #8]\n" // Child tid 129 " mov r7, #"__NR_CLONE"\n" 130 " svc 0x00000000\n" 131 " cmp r0, #0\n" 132 " beq 1f\n" 133 134 /* Parent */ 135 " pop {r4,r7}\n" 136 " bx lr\n" 137 138 "1:\n" /*child*/ 139 " mov lr, pc\n" 140 " pop {r0,pc}\n" 141 /* Retval from child is already in r0 */ 142 " mov r7, #"__NR_EXIT"\n" 143 " svc 0x00000000\n" 144 /* Urh.. why did exit return? */ 145 " .long 0\n" 146 " .previous\n" 147 ); 148 149 #undef __NR_CLONE 150 #undef __NR_EXIT 151 152 // forward declarations 153 static void setup_child ( ThreadArchState*, ThreadArchState* ); 154 static void assign_guest_tls(ThreadId ctid, Addr tlsptr); 155 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ); 156 157 /* 158 When a client clones, we need to keep track of the new thread. This means: 159 1. allocate a ThreadId+ThreadState+stack for the the thread 160 161 2. initialize the thread's new VCPU state 162 163 3. create the thread using the same args as the client requested, 164 but using the scheduler entrypoint for IP, and a separate stack 165 for SP. 166 */ 167 static SysRes do_clone ( ThreadId ptid, 168 UInt flags, Addr sp, 169 Int *parent_tidptr, 170 Int *child_tidptr, 171 Addr child_tls) 172 { 173 const Bool debug = False; 174 175 ThreadId ctid = VG_(alloc_ThreadState)(); 176 ThreadState* ptst = VG_(get_ThreadState)(ptid); 177 ThreadState* ctst = VG_(get_ThreadState)(ctid); 178 UInt r0; 179 UWord *stack; 180 NSegment const* seg; 181 SysRes res; 182 vki_sigset_t blockall, savedmask; 183 184 VG_(sigfillset)(&blockall); 185 186 vg_assert(VG_(is_running_thread)(ptid)); 187 vg_assert(VG_(is_valid_tid)(ctid)); 188 189 stack = (UWord*)ML_(allocstack)(ctid); 190 191 if(stack == NULL) { 192 res = VG_(mk_SysRes_Error)( VKI_ENOMEM ); 193 goto out; 194 } 195 196 setup_child( &ctst->arch, &ptst->arch ); 197 198 ctst->arch.vex.guest_R0 = 0; 199 if(sp != 0) 200 ctst->arch.vex.guest_R13 = sp; 201 202 ctst->os_state.parent = ptid; 203 204 ctst->sig_mask = ptst->sig_mask; 205 ctst->tmp_sig_mask = ptst->sig_mask; 206 207 /* Start the child with its threadgroup being the same as the 208 parent's. This is so that any exit_group calls that happen 209 after the child is created but before it sets its 210 os_state.threadgroup field for real (in thread_wrapper in 211 syswrap-linux.c), really kill the new thread. a.k.a this avoids 212 a race condition in which the thread is unkillable (via 213 exit_group) because its threadgroup is not set. The race window 214 is probably only a few hundred or a few thousand cycles long. 215 See #226116. */ 216 ctst->os_state.threadgroup = ptst->os_state.threadgroup; 217 218 seg = VG_(am_find_nsegment)((Addr)sp); 219 if (seg && seg->kind != SkResvn) { 220 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp); 221 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start; 222 223 VG_(register_stack)(seg->start, ctst->client_stack_highest_word); 224 225 if (debug) 226 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n", 227 ctid, seg->start, VG_PGROUNDUP(sp)); 228 } else { 229 VG_(message)(Vg_UserMsg, "!? New thread %d starts with sp+%#lx) unmapped\n", ctid, sp); 230 ctst->client_stack_szB = 0; 231 } 232 233 vg_assert(VG_(owns_BigLock_LL)(ptid)); 234 VG_TRACK ( pre_thread_ll_create, ptid, ctid ); 235 236 if (flags & VKI_CLONE_SETTLS) { 237 /* Just assign the tls pointer in the guest TPIDRURO. */ 238 assign_guest_tls(ctid, child_tls); 239 } 240 241 flags &= ~VKI_CLONE_SETTLS; 242 243 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask); 244 245 r0 = do_syscall_clone_arm_linux( 246 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid], 247 child_tidptr, parent_tidptr, NULL 248 ); 249 //VG_(printf)("AFTER SYSCALL, %x and %x CHILD: %d PARENT: %d\n",child_tidptr, parent_tidptr,*child_tidptr,*parent_tidptr); 250 251 res = VG_(mk_SysRes_arm_linux)( r0 ); 252 253 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL); 254 255 out: 256 if (sr_isError(res)) { 257 VG_(cleanup_thread)(&ctst->arch); 258 ctst->status = VgTs_Empty; 259 VG_TRACK( pre_thread_ll_exit, ctid ); 260 } 261 262 return res; 263 } 264 265 266 267 /* --------------------------------------------------------------------- 268 More thread stuff 269 ------------------------------------------------------------------ */ 270 271 // ARM doesn't have any architecture specific thread stuff that 272 // needs to be cleaned up 273 void VG_(cleanup_thread) ( ThreadArchState* arch ) 274 { 275 } 276 277 void setup_child ( /*OUT*/ ThreadArchState *child, 278 /*IN*/ ThreadArchState *parent ) 279 { 280 child->vex = parent->vex; 281 child->vex_shadow1 = parent->vex_shadow1; 282 child->vex_shadow2 = parent->vex_shadow2; 283 } 284 285 static void assign_guest_tls(ThreadId tid, Addr tlsptr) 286 { 287 VG_(threads)[tid].arch.vex.guest_TPIDRURO = tlsptr; 288 } 289 290 /* Assigns tlsptr to the guest TPIDRURO. 291 If needed for the specific hardware, really executes 292 the set_tls syscall. 293 */ 294 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ) 295 { 296 assign_guest_tls(tid, tlsptr); 297 #if defined(ANDROID_HARDWARE_emulator) 298 /* Android emulator does not provide an hw tls register. 299 So, the tls register is emulated by the kernel. 300 This emulated value is set by the __NR_ARM_set_tls syscall. 301 The emulated value must be read by the kernel helper function 302 located at 0xffff0fe0. 303 304 The emulated tlsptr is located at 0xffff0ff0 305 (so slightly after the kernel helper function). 306 Note that applications are not supposed to read this directly. 307 308 For compatibility : if there is a hw tls register, the kernel 309 will put at 0xffff0fe0 the instructions to read it, so 310 as to have old applications calling the kernel helper 311 working properly. 312 313 For having emulated guest TLS working correctly with 314 Valgrind, it is needed to execute the syscall to set 315 the emulated TLS value in addition to the assignment 316 of TPIDRURO. 317 318 Note: the below means that if we need thread local storage 319 for Valgrind host, then there will be a conflict between 320 the need of the guest tls and of the host tls. 321 If all the guest code would cleanly call 0xffff0fe0, 322 then we might maybe intercept this. However, at least 323 __libc_preinit reads directly 0xffff0ff0. 324 */ 325 /* ??? might call the below if auxv->u.a_val & VKI_HWCAP_TLS ??? 326 Unclear if real hardware having tls hw register sets 327 VKI_HWCAP_TLS. */ 328 return VG_(do_syscall1) (__NR_ARM_set_tls, tlsptr); 329 #else 330 return VG_(mk_SysRes_Success)( 0 ); 331 #endif 332 } 333 334 /* --------------------------------------------------------------------- 335 PRE/POST wrappers for arm/Linux-specific syscalls 336 ------------------------------------------------------------------ */ 337 338 #define PRE(name) DEFN_PRE_TEMPLATE(arm_linux, name) 339 #define POST(name) DEFN_POST_TEMPLATE(arm_linux, name) 340 341 /* Add prototypes for the wrappers declared here, so that gcc doesn't 342 harass us for not having prototypes. Really this is a kludge -- 343 the right thing to do is to make these wrappers 'static' since they 344 aren't visible outside this file, but that requires even more macro 345 magic. */ 346 347 DECL_TEMPLATE(arm_linux, sys_mmap2); 348 DECL_TEMPLATE(arm_linux, sys_stat64); 349 DECL_TEMPLATE(arm_linux, sys_lstat64); 350 DECL_TEMPLATE(arm_linux, sys_fstatat64); 351 DECL_TEMPLATE(arm_linux, sys_fstat64); 352 DECL_TEMPLATE(arm_linux, sys_clone); 353 DECL_TEMPLATE(arm_linux, sys_sigreturn); 354 DECL_TEMPLATE(arm_linux, sys_rt_sigreturn); 355 DECL_TEMPLATE(arm_linux, sys_sigsuspend); 356 DECL_TEMPLATE(arm_linux, sys_set_tls); 357 DECL_TEMPLATE(arm_linux, sys_cacheflush); 358 DECL_TEMPLATE(arm_linux, sys_ptrace); 359 360 PRE(sys_mmap2) 361 { 362 SysRes r; 363 364 // Exactly like old_mmap() except: 365 // - all 6 args are passed in regs, rather than in a memory-block. 366 // - the file offset is specified in pagesize units rather than bytes, 367 // so that it can be used for files bigger than 2^32 bytes. 368 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is 369 // 4K-sized. Assert that the page size is 4K here for safety. 370 vg_assert(VKI_PAGE_SIZE == 4096); 371 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", 372 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 ); 373 PRE_REG_READ6(long, "mmap2", 374 unsigned long, start, unsigned long, length, 375 unsigned long, prot, unsigned long, flags, 376 unsigned long, fd, unsigned long, offset); 377 378 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 379 4096 * (Off64T)ARG6 ); 380 SET_STATUS_from_SysRes(r); 381 } 382 383 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily 384 // applicable to every architecture -- I think only to 32-bit archs. 385 // We're going to need something like linux/core_os32.h for such 386 // things, eventually, I think. --njn 387 PRE(sys_lstat64) 388 { 389 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 390 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf); 391 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 ); 392 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 393 } 394 395 POST(sys_lstat64) 396 { 397 vg_assert(SUCCESS); 398 if (RES == 0) { 399 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 400 } 401 } 402 403 PRE(sys_stat64) 404 { 405 PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 406 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf); 407 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 ); 408 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); 409 } 410 411 POST(sys_stat64) 412 { 413 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 414 } 415 416 PRE(sys_fstatat64) 417 { 418 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3); 419 PRE_REG_READ3(long, "fstatat64", 420 int, dfd, char *, file_name, struct stat64 *, buf); 421 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); 422 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); 423 } 424 425 POST(sys_fstatat64) 426 { 427 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); 428 } 429 430 PRE(sys_fstat64) 431 { 432 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2); 433 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf); 434 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 435 } 436 437 POST(sys_fstat64) 438 { 439 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 440 } 441 442 PRE(sys_clone) 443 { 444 UInt cloneflags; 445 446 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5); 447 PRE_REG_READ5(int, "clone", 448 unsigned long, flags, 449 void *, child_stack, 450 int *, parent_tidptr, 451 void *, child_tls, 452 int *, child_tidptr); 453 454 if (ARG1 & VKI_CLONE_PARENT_SETTID) { 455 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int)); 456 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 457 VKI_PROT_WRITE)) { 458 SET_STATUS_Failure( VKI_EFAULT ); 459 return; 460 } 461 } 462 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) { 463 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int)); 464 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 465 VKI_PROT_WRITE)) { 466 SET_STATUS_Failure( VKI_EFAULT ); 467 return; 468 } 469 } 470 if (ARG1 & VKI_CLONE_SETTLS) { 471 PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t)); 472 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t), 473 VKI_PROT_READ)) { 474 SET_STATUS_Failure( VKI_EFAULT ); 475 return; 476 } 477 } 478 479 cloneflags = ARG1; 480 481 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) { 482 SET_STATUS_Failure( VKI_EINVAL ); 483 return; 484 } 485 486 /* Only look at the flags we really care about */ 487 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 488 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) { 489 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: 490 /* thread creation */ 491 SET_STATUS_from_SysRes( 492 do_clone(tid, 493 ARG1, /* flags */ 494 (Addr)ARG2, /* child ESP */ 495 (Int *)ARG3, /* parent_tidptr */ 496 (Int *)ARG5, /* child_tidptr */ 497 (Addr)ARG4)); /* set_tls */ 498 break; 499 500 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ 501 /* FALLTHROUGH - assume vfork == fork */ 502 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); 503 504 case 0: /* plain fork */ 505 SET_STATUS_from_SysRes( 506 ML_(do_fork_clone)(tid, 507 cloneflags, /* flags */ 508 (Int *)ARG3, /* parent_tidptr */ 509 (Int *)ARG5)); /* child_tidptr */ 510 break; 511 512 default: 513 /* should we just ENOSYS? */ 514 VG_(message)(Vg_UserMsg, ""); 515 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1); 516 VG_(message)(Vg_UserMsg, ""); 517 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:"); 518 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)"); 519 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork"); 520 VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver"); 521 VG_(unimplemented) 522 ("Valgrind does not support general clone()."); 523 } 524 525 if (SUCCESS) { 526 if (ARG1 & VKI_CLONE_PARENT_SETTID) 527 POST_MEM_WRITE(ARG3, sizeof(Int)); 528 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 529 POST_MEM_WRITE(ARG5, sizeof(Int)); 530 531 /* Thread creation was successful; let the child have the chance 532 to run */ 533 *flags |= SfYieldAfter; 534 } 535 } 536 537 PRE(sys_sigreturn) 538 { 539 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 540 an explanation of what follows. */ 541 542 PRINT("sys_sigreturn ( )"); 543 544 vg_assert(VG_(is_valid_tid)(tid)); 545 vg_assert(tid >= 1 && tid < VG_N_THREADS); 546 vg_assert(VG_(is_running_thread)(tid)); 547 548 /* Restore register state from frame and remove it */ 549 VG_(sigframe_destroy)(tid, False); 550 551 /* Tell the driver not to update the guest state with the "result", 552 and set a bogus result to keep it happy. */ 553 *flags |= SfNoWriteResult; 554 SET_STATUS_Success(0); 555 556 /* Check to see if any signals arose as a result of this. */ 557 *flags |= SfPollAfter; 558 } 559 560 PRE(sys_rt_sigreturn) 561 { 562 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 563 an explanation of what follows. */ 564 565 PRINT("rt_sigreturn ( )"); 566 567 vg_assert(VG_(is_valid_tid)(tid)); 568 vg_assert(tid >= 1 && tid < VG_N_THREADS); 569 vg_assert(VG_(is_running_thread)(tid)); 570 571 /* Restore register state from frame and remove it */ 572 VG_(sigframe_destroy)(tid, True); 573 574 /* Tell the driver not to update the guest state with the "result", 575 and set a bogus result to keep it happy. */ 576 *flags |= SfNoWriteResult; 577 SET_STATUS_Success(0); 578 579 /* Check to see if any signals arose as a result of this. */ 580 *flags |= SfPollAfter; 581 } 582 583 /* NB: clone of x86-linux version, and ppc32-linux has an almost 584 identical one. */ 585 PRE(sys_sigsuspend) 586 { 587 /* The C library interface to sigsuspend just takes a pointer to 588 a signal mask but this system call has three arguments - the first 589 two don't appear to be used by the kernel and are always passed as 590 zero by glibc and the third is the first word of the signal mask 591 so only 32 signals are supported. 592 593 In fact glibc normally uses rt_sigsuspend if it is available as 594 that takes a pointer to the signal mask so supports more signals. 595 */ 596 *flags |= SfMayBlock; 597 PRINT("sys_sigsuspend ( %ld, %ld, %ld )", ARG1,ARG2,ARG3 ); 598 PRE_REG_READ3(int, "sigsuspend", 599 int, history0, int, history1, 600 vki_old_sigset_t, mask); 601 } 602 603 /* Very much ARM specific */ 604 605 PRE(sys_set_tls) 606 { 607 PRINT("set_tls (%lx)",ARG1); 608 PRE_REG_READ1(long, "set_tls", unsigned long, addr); 609 610 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) ); 611 } 612 613 PRE(sys_cacheflush) 614 { 615 PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3); 616 PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags); 617 VG_(discard_translations)( (Addr64)ARG1, 618 ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/, 619 "PRE(sys_cacheflush)" ); 620 SET_STATUS_Success(0); 621 } 622 623 // ARG3 is only used for pointers into the traced process's address 624 // space and for offsets into the traced process's struct 625 // user_regs_struct. It is never a pointer into this process's memory 626 // space, and we should therefore not check anything it points to. 627 PRE(sys_ptrace) 628 { 629 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4); 630 PRE_REG_READ4(int, "ptrace", 631 long, request, long, pid, long, addr, long, data); 632 switch (ARG1) { 633 case VKI_PTRACE_PEEKTEXT: 634 case VKI_PTRACE_PEEKDATA: 635 case VKI_PTRACE_PEEKUSR: 636 PRE_MEM_WRITE( "ptrace(peek)", ARG4, 637 sizeof (long)); 638 break; 639 case VKI_PTRACE_GETREGS: 640 PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 641 sizeof (struct vki_user_regs_struct)); 642 break; 643 case VKI_PTRACE_GETFPREGS: 644 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 645 sizeof (struct vki_user_fp)); 646 break; 647 case VKI_PTRACE_GETWMMXREGS: 648 PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4, 649 VKI_IWMMXT_SIZE); 650 break; 651 case VKI_PTRACE_GETCRUNCHREGS: 652 PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4, 653 VKI_CRUNCH_SIZE); 654 break; 655 case VKI_PTRACE_GETVFPREGS: 656 PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4, 657 sizeof (struct vki_user_vfp) ); 658 break; 659 case VKI_PTRACE_GETHBPREGS: 660 PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4, 661 sizeof (unsigned long) ); 662 break; 663 case VKI_PTRACE_SETREGS: 664 PRE_MEM_READ( "ptrace(setregs)", ARG4, 665 sizeof (struct vki_user_regs_struct)); 666 break; 667 case VKI_PTRACE_SETFPREGS: 668 PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 669 sizeof (struct vki_user_fp)); 670 break; 671 case VKI_PTRACE_SETWMMXREGS: 672 PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4, 673 VKI_IWMMXT_SIZE); 674 break; 675 case VKI_PTRACE_SETCRUNCHREGS: 676 PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4, 677 VKI_CRUNCH_SIZE); 678 break; 679 case VKI_PTRACE_SETVFPREGS: 680 PRE_MEM_READ( "ptrace(setvfpregs)", ARG4, 681 sizeof (struct vki_user_vfp)); 682 break; 683 case VKI_PTRACE_SETHBPREGS: 684 PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long)); 685 break; 686 case VKI_PTRACE_GET_THREAD_AREA: 687 PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long)); 688 break; 689 case VKI_PTRACE_GETEVENTMSG: 690 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long)); 691 break; 692 case VKI_PTRACE_GETSIGINFO: 693 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t)); 694 break; 695 case VKI_PTRACE_SETSIGINFO: 696 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t)); 697 break; 698 case VKI_PTRACE_GETREGSET: 699 ML_(linux_PRE_getregset)(tid, ARG3, ARG4); 700 break; 701 case VKI_PTRACE_SETREGSET: 702 ML_(linux_PRE_setregset)(tid, ARG3, ARG4); 703 break; 704 default: 705 break; 706 } 707 } 708 709 POST(sys_ptrace) 710 { 711 switch (ARG1) { 712 case VKI_PTRACE_PEEKTEXT: 713 case VKI_PTRACE_PEEKDATA: 714 case VKI_PTRACE_PEEKUSR: 715 POST_MEM_WRITE( ARG4, sizeof (long)); 716 break; 717 case VKI_PTRACE_GETREGS: 718 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct)); 719 break; 720 case VKI_PTRACE_GETFPREGS: 721 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp)); 722 break; 723 case VKI_PTRACE_GETWMMXREGS: 724 POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE); 725 break; 726 case VKI_PTRACE_GETCRUNCHREGS: 727 POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE); 728 break; 729 case VKI_PTRACE_GETVFPREGS: 730 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp)); 731 break; 732 case VKI_PTRACE_GET_THREAD_AREA: 733 case VKI_PTRACE_GETHBPREGS: 734 case VKI_PTRACE_GETEVENTMSG: 735 POST_MEM_WRITE( ARG4, sizeof(unsigned long)); 736 break; 737 case VKI_PTRACE_GETSIGINFO: 738 /* XXX: This is a simplification. Different parts of the 739 * siginfo_t are valid depending on the type of signal. 740 */ 741 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t)); 742 break; 743 case VKI_PTRACE_GETREGSET: 744 ML_(linux_POST_getregset)(tid, ARG3, ARG4); 745 break; 746 default: 747 break; 748 } 749 } 750 751 #undef PRE 752 #undef POST 753 754 /* --------------------------------------------------------------------- 755 The arm/Linux syscall table 756 ------------------------------------------------------------------ */ 757 758 #if 0 759 #define __NR_OABI_SYSCALL_BASE 0x900000 760 #else 761 #define __NR_OABI_SYSCALL_BASE 0x0 762 #endif 763 764 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(arm_linux, sysno, name) 765 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(arm_linux, sysno, name) 766 767 // This table maps from __NR_xxx syscall numbers (from 768 // linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo() 769 // wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S). 770 // 771 // For those syscalls not handled by Valgrind, the annotation indicate its 772 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? 773 // (unknown). 774 775 static SyscallTableEntry syscall_main_table[] = { 776 //zz // (restart_syscall) // 0 777 GENX_(__NR_exit, sys_exit), // 1 778 GENX_(__NR_fork, sys_fork), // 2 779 GENXY(__NR_read, sys_read), // 3 780 GENX_(__NR_write, sys_write), // 4 781 782 GENXY(__NR_open, sys_open), // 5 783 GENXY(__NR_close, sys_close), // 6 784 // GENXY(__NR_waitpid, sys_waitpid), // 7 785 GENXY(__NR_creat, sys_creat), // 8 786 GENX_(__NR_link, sys_link), // 9 787 788 GENX_(__NR_unlink, sys_unlink), // 10 789 GENX_(__NR_execve, sys_execve), // 11 790 GENX_(__NR_chdir, sys_chdir), // 12 791 GENXY(__NR_time, sys_time), // 13 792 GENX_(__NR_mknod, sys_mknod), // 14 793 794 GENX_(__NR_chmod, sys_chmod), // 15 795 //zz LINX_(__NR_lchown, sys_lchown16), // 16 796 // GENX_(__NR_break, sys_ni_syscall), // 17 797 //zz // (__NR_oldstat, sys_stat), // 18 (obsolete) 798 LINX_(__NR_lseek, sys_lseek), // 19 799 800 GENX_(__NR_getpid, sys_getpid), // 20 801 LINX_(__NR_mount, sys_mount), // 21 802 LINX_(__NR_umount, sys_oldumount), // 22 803 LINX_(__NR_setuid, sys_setuid16), // 23 ## P 804 LINX_(__NR_getuid, sys_getuid16), // 24 ## P 805 //zz 806 //zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN) 807 PLAXY(__NR_ptrace, sys_ptrace), // 26 808 GENX_(__NR_alarm, sys_alarm), // 27 809 //zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete 810 GENX_(__NR_pause, sys_pause), // 29 811 812 LINX_(__NR_utime, sys_utime), // 30 813 // GENX_(__NR_stty, sys_ni_syscall), // 31 814 // GENX_(__NR_gtty, sys_ni_syscall), // 32 815 GENX_(__NR_access, sys_access), // 33 816 GENX_(__NR_nice, sys_nice), // 34 817 818 // GENX_(__NR_ftime, sys_ni_syscall), // 35 819 GENX_(__NR_sync, sys_sync), // 36 820 GENX_(__NR_kill, sys_kill), // 37 821 GENX_(__NR_rename, sys_rename), // 38 822 GENX_(__NR_mkdir, sys_mkdir), // 39 823 824 GENX_(__NR_rmdir, sys_rmdir), // 40 825 GENXY(__NR_dup, sys_dup), // 41 826 LINXY(__NR_pipe, sys_pipe), // 42 827 GENXY(__NR_times, sys_times), // 43 828 // GENX_(__NR_prof, sys_ni_syscall), // 44 829 //zz 830 GENX_(__NR_brk, sys_brk), // 45 831 LINX_(__NR_setgid, sys_setgid16), // 46 832 LINX_(__NR_getgid, sys_getgid16), // 47 833 //zz // (__NR_signal, sys_signal), // 48 */* (ANSI C) 834 LINX_(__NR_geteuid, sys_geteuid16), // 49 835 836 LINX_(__NR_getegid, sys_getegid16), // 50 837 GENX_(__NR_acct, sys_acct), // 51 838 LINX_(__NR_umount2, sys_umount), // 52 839 // GENX_(__NR_lock, sys_ni_syscall), // 53 840 LINXY(__NR_ioctl, sys_ioctl), // 54 841 842 LINXY(__NR_fcntl, sys_fcntl), // 55 843 // GENX_(__NR_mpx, sys_ni_syscall), // 56 844 GENX_(__NR_setpgid, sys_setpgid), // 57 845 // GENX_(__NR_ulimit, sys_ni_syscall), // 58 846 //zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete 847 //zz 848 GENX_(__NR_umask, sys_umask), // 60 849 GENX_(__NR_chroot, sys_chroot), // 61 850 //zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated 851 GENXY(__NR_dup2, sys_dup2), // 63 852 GENX_(__NR_getppid, sys_getppid), // 64 853 854 GENX_(__NR_getpgrp, sys_getpgrp), // 65 855 GENX_(__NR_setsid, sys_setsid), // 66 856 LINXY(__NR_sigaction, sys_sigaction), // 67 857 //zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C) 858 //zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C) 859 //zz 860 LINX_(__NR_setreuid, sys_setreuid16), // 70 861 LINX_(__NR_setregid, sys_setregid16), // 71 862 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72 863 LINXY(__NR_sigpending, sys_sigpending), // 73 864 //zz // (__NR_sethostname, sys_sethostname), // 74 */* 865 //zz 866 GENX_(__NR_setrlimit, sys_setrlimit), // 75 867 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76 868 GENXY(__NR_getrusage, sys_getrusage), // 77 869 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78 870 GENX_(__NR_settimeofday, sys_settimeofday), // 79 871 872 LINXY(__NR_getgroups, sys_getgroups16), // 80 873 LINX_(__NR_setgroups, sys_setgroups16), // 81 874 // PLAX_(__NR_select, old_select), // 82 875 GENX_(__NR_symlink, sys_symlink), // 83 876 //zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete 877 //zz 878 GENX_(__NR_readlink, sys_readlink), // 85 879 //zz // (__NR_uselib, sys_uselib), // 86 */Linux 880 //zz // (__NR_swapon, sys_swapon), // 87 */Linux 881 //zz // (__NR_reboot, sys_reboot), // 88 */Linux 882 //zz // (__NR_readdir, old_readdir), // 89 -- superseded 883 //zz 884 // _____(__NR_mmap, old_mmap), // 90 885 GENXY(__NR_munmap, sys_munmap), // 91 886 GENX_(__NR_truncate, sys_truncate), // 92 887 GENX_(__NR_ftruncate, sys_ftruncate), // 93 888 GENX_(__NR_fchmod, sys_fchmod), // 94 889 890 LINX_(__NR_fchown, sys_fchown16), // 95 891 GENX_(__NR_getpriority, sys_getpriority), // 96 892 GENX_(__NR_setpriority, sys_setpriority), // 97 893 // GENX_(__NR_profil, sys_ni_syscall), // 98 894 GENXY(__NR_statfs, sys_statfs), // 99 895 896 GENXY(__NR_fstatfs, sys_fstatfs), // 100 897 // LINX_(__NR_ioperm, sys_ioperm), // 101 898 LINXY(__NR_socketcall, sys_socketcall), // 102 899 LINXY(__NR_syslog, sys_syslog), // 103 900 GENXY(__NR_setitimer, sys_setitimer), // 104 901 902 GENXY(__NR_getitimer, sys_getitimer), // 105 903 GENXY(__NR_stat, sys_newstat), // 106 904 GENXY(__NR_lstat, sys_newlstat), // 107 905 GENXY(__NR_fstat, sys_newfstat), // 108 906 //zz // (__NR_olduname, sys_uname), // 109 -- obsolete 907 //zz 908 // GENX_(__NR_iopl, sys_iopl), // 110 909 LINX_(__NR_vhangup, sys_vhangup), // 111 910 // GENX_(__NR_idle, sys_ni_syscall), // 112 911 // PLAXY(__NR_vm86old, sys_vm86old), // 113 __NR_syscall... weird 912 GENXY(__NR_wait4, sys_wait4), // 114 913 //zz 914 //zz // (__NR_swapoff, sys_swapoff), // 115 */Linux 915 LINXY(__NR_sysinfo, sys_sysinfo), // 116 916 // _____(__NR_ipc, sys_ipc), // 117 917 GENX_(__NR_fsync, sys_fsync), // 118 918 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux 919 920 PLAX_(__NR_clone, sys_clone), // 120 921 //zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?) 922 GENXY(__NR_uname, sys_newuname), // 122 923 // PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123 924 //zz LINXY(__NR_adjtimex, sys_adjtimex), // 124 925 //zz 926 GENXY(__NR_mprotect, sys_mprotect), // 125 927 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126 928 //zz // Nb: create_module() was removed 2.4-->2.6 929 // GENX_(__NR_create_module, sys_ni_syscall), // 127 930 LINX_(__NR_init_module, sys_init_module), // 128 931 LINX_(__NR_delete_module, sys_delete_module), // 129 932 //zz 933 //zz // Nb: get_kernel_syms() was removed 2.4-->2.6 934 // GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 935 LINX_(__NR_quotactl, sys_quotactl), // 131 936 GENX_(__NR_getpgid, sys_getpgid), // 132 937 GENX_(__NR_fchdir, sys_fchdir), // 133 938 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux 939 //zz 940 //zz // (__NR_sysfs, sys_sysfs), // 135 SVr4 941 LINX_(__NR_personality, sys_personality), // 136 942 // GENX_(__NR_afs_syscall, sys_ni_syscall), // 137 943 LINX_(__NR_setfsuid, sys_setfsuid16), // 138 944 LINX_(__NR_setfsgid, sys_setfsgid16), // 139 945 946 LINXY(__NR__llseek, sys_llseek), // 140 947 GENXY(__NR_getdents, sys_getdents), // 141 948 GENX_(__NR__newselect, sys_select), // 142 949 GENX_(__NR_flock, sys_flock), // 143 950 GENX_(__NR_msync, sys_msync), // 144 951 952 GENXY(__NR_readv, sys_readv), // 145 953 GENX_(__NR_writev, sys_writev), // 146 954 GENX_(__NR_getsid, sys_getsid), // 147 955 GENX_(__NR_fdatasync, sys_fdatasync), // 148 956 LINXY(__NR__sysctl, sys_sysctl), // 149 957 958 GENX_(__NR_mlock, sys_mlock), // 150 959 GENX_(__NR_munlock, sys_munlock), // 151 960 GENX_(__NR_mlockall, sys_mlockall), // 152 961 LINX_(__NR_munlockall, sys_munlockall), // 153 962 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154 963 964 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155 965 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156 966 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157 967 LINX_(__NR_sched_yield, sys_sched_yield), // 158 968 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159 969 970 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160 971 //zz //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */* 972 GENXY(__NR_nanosleep, sys_nanosleep), // 162 973 GENX_(__NR_mremap, sys_mremap), // 163 974 LINX_(__NR_setresuid, sys_setresuid16), // 164 975 976 LINXY(__NR_getresuid, sys_getresuid16), // 165 977 // PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only 978 // GENX_(__NR_query_module, sys_ni_syscall), // 167 979 GENXY(__NR_poll, sys_poll), // 168 980 //zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux 981 //zz 982 LINX_(__NR_setresgid, sys_setresgid16), // 170 983 LINXY(__NR_getresgid, sys_getresgid16), // 171 984 LINXY(__NR_prctl, sys_prctl), // 172 985 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173 986 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174 987 988 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175 989 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176 990 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177 991 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178 992 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179 993 994 GENXY(__NR_pread64, sys_pread64), // 180 995 GENX_(__NR_pwrite64, sys_pwrite64), // 181 996 LINX_(__NR_chown, sys_chown16), // 182 997 GENXY(__NR_getcwd, sys_getcwd), // 183 998 LINXY(__NR_capget, sys_capget), // 184 999 1000 LINX_(__NR_capset, sys_capset), // 185 1001 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186 1002 LINXY(__NR_sendfile, sys_sendfile), // 187 1003 // GENXY(__NR_getpmsg, sys_getpmsg), // 188 1004 // GENX_(__NR_putpmsg, sys_putpmsg), // 189 1005 1006 // Nb: we treat vfork as fork 1007 GENX_(__NR_vfork, sys_fork), // 190 1008 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191 1009 PLAX_(__NR_mmap2, sys_mmap2), // 192 1010 GENX_(__NR_truncate64, sys_truncate64), // 193 1011 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194 1012 1013 PLAXY(__NR_stat64, sys_stat64), // 195 1014 PLAXY(__NR_lstat64, sys_lstat64), // 196 1015 PLAXY(__NR_fstat64, sys_fstat64), // 197 1016 GENX_(__NR_lchown32, sys_lchown), // 198 1017 GENX_(__NR_getuid32, sys_getuid), // 199 1018 1019 GENX_(__NR_getgid32, sys_getgid), // 200 1020 GENX_(__NR_geteuid32, sys_geteuid), // 201 1021 GENX_(__NR_getegid32, sys_getegid), // 202 1022 GENX_(__NR_setreuid32, sys_setreuid), // 203 1023 GENX_(__NR_setregid32, sys_setregid), // 204 1024 1025 GENXY(__NR_getgroups32, sys_getgroups), // 205 1026 GENX_(__NR_setgroups32, sys_setgroups), // 206 1027 GENX_(__NR_fchown32, sys_fchown), // 207 1028 LINX_(__NR_setresuid32, sys_setresuid), // 208 1029 LINXY(__NR_getresuid32, sys_getresuid), // 209 1030 1031 LINX_(__NR_setresgid32, sys_setresgid), // 210 1032 LINXY(__NR_getresgid32, sys_getresgid), // 211 1033 GENX_(__NR_chown32, sys_chown), // 212 1034 GENX_(__NR_setuid32, sys_setuid), // 213 1035 GENX_(__NR_setgid32, sys_setgid), // 214 1036 1037 LINX_(__NR_setfsuid32, sys_setfsuid), // 215 1038 LINX_(__NR_setfsgid32, sys_setfsgid), // 216 1039 //zz // (__NR_pivot_root, sys_pivot_root), // 217 */Linux 1040 GENXY(__NR_mincore, sys_mincore), // 218 1041 GENX_(__NR_madvise, sys_madvise), // 219 1042 1043 GENXY(__NR_getdents64, sys_getdents64), // 220 1044 LINXY(__NR_fcntl64, sys_fcntl64), // 221 1045 // GENX_(222, sys_ni_syscall), // 222 1046 // PLAXY(223, sys_syscall223), // 223 // sys_bproc? 1047 LINX_(__NR_gettid, sys_gettid), // 224 1048 1049 LINX_(__NR_readahead, sys_readahead), // 225 */Linux 1050 LINX_(__NR_setxattr, sys_setxattr), // 226 1051 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227 1052 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228 1053 LINXY(__NR_getxattr, sys_getxattr), // 229 1054 1055 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230 1056 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231 1057 LINXY(__NR_listxattr, sys_listxattr), // 232 1058 LINXY(__NR_llistxattr, sys_llistxattr), // 233 1059 LINXY(__NR_flistxattr, sys_flistxattr), // 234 1060 1061 LINX_(__NR_removexattr, sys_removexattr), // 235 1062 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236 1063 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237 1064 LINXY(__NR_tkill, sys_tkill), // 238 */Linux 1065 LINXY(__NR_sendfile64, sys_sendfile64), // 239 1066 1067 LINXY(__NR_futex, sys_futex), // 240 1068 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241 1069 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242 1070 // PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243 1071 // PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244 1072 1073 LINXY(__NR_io_setup, sys_io_setup), // 245 1074 LINX_(__NR_io_destroy, sys_io_destroy), // 246 1075 LINXY(__NR_io_getevents, sys_io_getevents), // 247 1076 LINX_(__NR_io_submit, sys_io_submit), // 248 1077 LINXY(__NR_io_cancel, sys_io_cancel), // 249 1078 1079 // LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?) 1080 GENX_(251, sys_ni_syscall), // 251 1081 LINX_(__NR_exit_group, sys_exit_group), // 252 1082 // GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253 1083 LINXY(__NR_epoll_create, sys_epoll_create), // 254 1084 1085 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255 1086 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256 1087 //zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux 1088 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258 1089 LINXY(__NR_timer_create, sys_timer_create), // 259 1090 1091 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1) 1092 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2) 1093 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3) 1094 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4) 1095 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5) 1096 1097 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6) 1098 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7) 1099 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */* 1100 GENXY(__NR_statfs64, sys_statfs64), // 268 1101 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269 1102 1103 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux 1104 GENX_(__NR_utimes, sys_utimes), // 271 1105 // LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?) 1106 GENX_(__NR_vserver, sys_ni_syscall), // 273 1107 LINX_(__NR_mbind, sys_mbind), // 274 ?/? 1108 1109 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/? 1110 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/? 1111 LINXY(__NR_mq_open, sys_mq_open), // 277 1112 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1) 1113 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2) 1114 1115 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3) 1116 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4) 1117 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5) 1118 LINXY(__NR_waitid, sys_waitid), // 280 1119 1120 LINXY(__NR_socket, sys_socket), // 281 1121 LINX_(__NR_bind, sys_bind), // 282 1122 LINX_(__NR_connect, sys_connect), // 283 1123 LINX_(__NR_listen, sys_listen), // 284 1124 LINXY(__NR_accept, sys_accept), // 285 1125 LINXY(__NR_getsockname, sys_getsockname), // 286 1126 LINXY(__NR_getpeername, sys_getpeername), // 287 1127 LINXY(__NR_socketpair, sys_socketpair), // 288 1128 LINX_(__NR_send, sys_send), 1129 LINX_(__NR_sendto, sys_sendto), // 290 1130 LINXY(__NR_recv, sys_recv), 1131 LINXY(__NR_recvfrom, sys_recvfrom), // 292 1132 LINX_(__NR_shutdown, sys_shutdown), // 293 1133 LINX_(__NR_setsockopt, sys_setsockopt), // 294 1134 LINXY(__NR_getsockopt, sys_getsockopt), // 295 1135 LINX_(__NR_sendmsg, sys_sendmsg), // 296 1136 LINXY(__NR_recvmsg, sys_recvmsg), // 297 1137 LINX_(__NR_semop, sys_semop), // 298 1138 LINX_(__NR_semget, sys_semget), // 299 1139 LINXY(__NR_semctl, sys_semctl), // 300 1140 LINX_(__NR_msgget, sys_msgget), 1141 LINX_(__NR_msgsnd, sys_msgsnd), 1142 LINXY(__NR_msgrcv, sys_msgrcv), 1143 LINXY(__NR_msgctl, sys_msgctl), // 304 1144 LINX_(__NR_semtimedop, sys_semtimedop), // 312 1145 1146 LINX_(__NR_add_key, sys_add_key), // 286 1147 LINX_(__NR_request_key, sys_request_key), // 287 1148 LINXY(__NR_keyctl, sys_keyctl), // not 288... 1149 // LINX_(__NR_ioprio_set, sys_ioprio_set), // 289 1150 1151 // LINX_(__NR_ioprio_get, sys_ioprio_get), // 290 1152 LINX_(__NR_inotify_init, sys_inotify_init), // 291 1153 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292 1154 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293 1155 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 294 1156 1157 LINXY(__NR_openat, sys_openat), // 295 1158 LINX_(__NR_mkdirat, sys_mkdirat), // 296 1159 LINX_(__NR_mknodat, sys_mknodat), // 297 1160 LINX_(__NR_fchownat, sys_fchownat), // 298 1161 LINX_(__NR_futimesat, sys_futimesat), // 326 on arm 1162 1163 PLAXY(__NR_fstatat64, sys_fstatat64), // 300 1164 LINX_(__NR_unlinkat, sys_unlinkat), // 301 1165 LINX_(__NR_renameat, sys_renameat), // 302 1166 LINX_(__NR_linkat, sys_linkat), // 303 1167 LINX_(__NR_symlinkat, sys_symlinkat), // 304 1168 1169 LINX_(__NR_readlinkat, sys_readlinkat), // 1170 LINX_(__NR_fchmodat, sys_fchmodat), // 1171 LINX_(__NR_faccessat, sys_faccessat), // 1172 LINXY(__NR_shmat, wrap_sys_shmat), //305 1173 LINXY(__NR_shmdt, sys_shmdt), //306 1174 LINX_(__NR_shmget, sys_shmget), //307 1175 LINXY(__NR_shmctl, sys_shmctl), // 308 1176 // LINX_(__NR_pselect6, sys_pselect6), // 1177 1178 // LINX_(__NR_unshare, sys_unshare), // 310 1179 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311 1180 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312 1181 // LINX_(__NR_splice, sys_ni_syscall), // 313 1182 // LINX_(__NR_sync_file_range, sys_sync_file_range), // 314 1183 1184 // LINX_(__NR_tee, sys_ni_syscall), // 315 1185 // LINX_(__NR_vmsplice, sys_ni_syscall), // 316 1186 LINXY(__NR_move_pages, sys_move_pages), // 317 1187 // LINX_(__NR_getcpu, sys_ni_syscall), // 318 1188 1189 LINX_(__NR_utimensat, sys_utimensat), // 320 1190 LINXY(__NR_signalfd, sys_signalfd), // 321 1191 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322 1192 LINXY(__NR_eventfd, sys_eventfd), // 323 1193 1194 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325 1195 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326 1196 1197 /////////////// 1198 1199 // JRS 2010-Jan-03: I believe that all the numbers listed 1200 // in comments in the table prior to this point (eg "// 326", 1201 // etc) are bogus since it looks to me like they are copied 1202 // verbatim from syswrap-x86-linux.c and they certainly do not 1203 // correspond to what's in include/vki/vki-scnums-arm-linux.h. 1204 // From here onwards, please ensure the numbers are correct. 1205 1206 LINX_(__NR_pselect6, sys_pselect6), // 335 1207 LINXY(__NR_ppoll, sys_ppoll), // 336 1208 1209 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 346 1210 1211 LINX_(__NR_fallocate, sys_fallocate), // 352 1212 1213 LINXY(__NR_signalfd4, sys_signalfd4), // 355 1214 LINXY(__NR_eventfd2, sys_eventfd2), // 356 1215 LINXY(__NR_epoll_create1, sys_epoll_create1), // 357 1216 LINXY(__NR_dup3, sys_dup3), // 358 1217 LINXY(__NR_pipe2, sys_pipe2), // 359 1218 LINXY(__NR_inotify_init1, sys_inotify_init1), // 360 1219 LINXY(__NR_preadv, sys_preadv), // 361 1220 LINX_(__NR_pwritev, sys_pwritev), // 362 1221 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 363 1222 LINXY(__NR_perf_event_open, sys_perf_event_open), // 364 1223 1224 LINXY(__NR_accept4, sys_accept4), // 366 1225 LINXY(__NR_fanotify_init, sys_fanotify_init), // 367 1226 LINX_(__NR_fanotify_mark, sys_fanotify_mark), // 368 1227 LINXY(__NR_prlimit64, sys_prlimit64), // 369 1228 LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 370 1229 LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 371 1230 LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 372 1231 LINXY(__NR_sendmmsg, sys_sendmmsg) // 374 1232 }; 1233 1234 1235 /* These are not in the main table because there indexes are not small 1236 integers, but rather values close to one million. So their 1237 inclusion would force the main table to be huge (about 8 MB). */ 1238 1239 static SyscallTableEntry ste___ARM_set_tls 1240 = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL }; 1241 1242 static SyscallTableEntry ste___ARM_cacheflush 1243 = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL }; 1244 1245 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) 1246 { 1247 const UInt syscall_main_table_size 1248 = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]); 1249 1250 /* Is it in the contiguous initial section of the table? */ 1251 if (sysno < syscall_main_table_size) { 1252 SyscallTableEntry* sys = &syscall_main_table[sysno]; 1253 if (sys->before == NULL) 1254 return NULL; /* no entry */ 1255 else 1256 return sys; 1257 } 1258 1259 /* Check if it's one of the out-of-line entries. */ 1260 switch (sysno) { 1261 case __NR_ARM_set_tls: return &ste___ARM_set_tls; 1262 case __NR_ARM_cacheflush: return &ste___ARM_cacheflush; 1263 default: break; 1264 } 1265 1266 /* Can't find a wrapper */ 1267 return NULL; 1268 } 1269 1270 #endif // defined(VGP_arm_linux) 1271 1272 /*--------------------------------------------------------------------*/ 1273 /*--- end syswrap-arm-linux.c ---*/ 1274 /*--------------------------------------------------------------------*/ 1275