syswrap-arm-linux.c revision b2cd1bc0abb95119df1b9b8e6dcc71e48b828a94
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-2012 Nicholas Nethercote 11 njn@valgrind.org 12 Copyright (C) 2008-2012 Evan Geller 13 gaze@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)) 71void 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 79asm( 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 107extern 108ULong 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 ); 115asm( 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 153static void setup_child ( ThreadArchState*, ThreadArchState* ); 154static void assign_guest_tls(ThreadId ctid, Addr tlsptr); 155static 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 */ 167static 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 255out: 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 273void VG_(cleanup_thread) ( ThreadArchState* arch ) 274{ 275} 276 277void 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 285static 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*/ 294static 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 347DECL_TEMPLATE(arm_linux, sys_socket); 348DECL_TEMPLATE(arm_linux, sys_setsockopt); 349DECL_TEMPLATE(arm_linux, sys_getsockopt); 350DECL_TEMPLATE(arm_linux, sys_connect); 351DECL_TEMPLATE(arm_linux, sys_accept); 352DECL_TEMPLATE(arm_linux, sys_accept4); 353DECL_TEMPLATE(arm_linux, sys_sendto); 354DECL_TEMPLATE(arm_linux, sys_recvfrom); 355//XXX: Semaphore code ripped from AMD64. 356DECL_TEMPLATE(arm_linux, sys_semget); 357DECL_TEMPLATE(arm_linux, sys_semop); 358DECL_TEMPLATE(arm_linux, sys_semctl); 359DECL_TEMPLATE(arm_linux, sys_semtimedop); 360//XXX: Shared memory code ripped from AMD64 361// 362DECL_TEMPLATE(arm_linux, wrap_sys_shmat); 363DECL_TEMPLATE(arm_linux, sys_shmget); 364DECL_TEMPLATE(arm_linux, sys_shmdt); 365DECL_TEMPLATE(arm_linux, sys_shmctl); 366DECL_TEMPLATE(arm_linux, sys_sendmsg); 367DECL_TEMPLATE(arm_linux, sys_recvmsg); 368//msg* code from AMD64 369DECL_TEMPLATE(arm_linux, sys_msgget); 370DECL_TEMPLATE(arm_linux, sys_msgrcv); 371DECL_TEMPLATE(arm_linux, sys_msgsnd); 372DECL_TEMPLATE(arm_linux, sys_msgctl); 373DECL_TEMPLATE(arm_linux, sys_shutdown); 374DECL_TEMPLATE(arm_linux, sys_bind); 375DECL_TEMPLATE(arm_linux, sys_listen); 376DECL_TEMPLATE(arm_linux, sys_getsockname); 377DECL_TEMPLATE(arm_linux, sys_getpeername); 378DECL_TEMPLATE(arm_linux, sys_socketpair); 379DECL_TEMPLATE(arm_linux, sys_send); 380DECL_TEMPLATE(arm_linux, sys_recv); 381DECL_TEMPLATE(arm_linux, sys_mmap2); 382DECL_TEMPLATE(arm_linux, sys_stat64); 383DECL_TEMPLATE(arm_linux, sys_lstat64); 384DECL_TEMPLATE(arm_linux, sys_fstatat64); 385DECL_TEMPLATE(arm_linux, sys_fstat64); 386DECL_TEMPLATE(arm_linux, sys_clone); 387DECL_TEMPLATE(arm_linux, sys_sigreturn); 388DECL_TEMPLATE(arm_linux, sys_rt_sigreturn); 389DECL_TEMPLATE(arm_linux, sys_sigsuspend); 390DECL_TEMPLATE(arm_linux, sys_set_tls); 391DECL_TEMPLATE(arm_linux, sys_cacheflush); 392DECL_TEMPLATE(arm_linux, sys_ptrace); 393 394 395PRE(sys_socket) 396{ 397 PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3); 398 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol); 399} 400POST(sys_socket) 401{ 402 SysRes r; 403 vg_assert(SUCCESS); 404 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES)); 405 SET_STATUS_from_SysRes(r); 406} 407 408PRE(sys_setsockopt) 409{ 410 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5); 411 PRE_REG_READ5(long, "setsockopt", 412 int, s, int, level, int, optname, 413 const void *, optval, int, optlen); 414 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); 415} 416 417PRE(sys_getsockopt) 418{ 419 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5); 420 PRE_REG_READ5(long, "getsockopt", 421 int, s, int, level, int, optname, 422 void *, optval, int, *optlen); 423 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); 424} 425POST(sys_getsockopt) 426{ 427 vg_assert(SUCCESS); 428 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES), 429 ARG1,ARG2,ARG3,ARG4,ARG5); 430} 431 432PRE(sys_connect) 433{ 434 *flags |= SfMayBlock; 435 PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 436 PRE_REG_READ3(long, "connect", 437 int, sockfd, struct sockaddr *, serv_addr, int, addrlen); 438 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3); 439} 440 441PRE(sys_accept) 442{ 443 *flags |= SfMayBlock; 444 PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 445 PRE_REG_READ3(long, "accept", 446 int, s, struct sockaddr *, addr, int, *addrlen); 447 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); 448} 449POST(sys_accept) 450{ 451 SysRes r; 452 vg_assert(SUCCESS); 453 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), 454 ARG1,ARG2,ARG3); 455 SET_STATUS_from_SysRes(r); 456} 457 458PRE(sys_accept4) 459{ 460 *flags |= SfMayBlock; 461 PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4); 462 PRE_REG_READ4(long, "accept4", 463 int, s, struct sockaddr *, addr, int, *addrlen, int, flags); 464 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3); 465} 466POST(sys_accept4) 467{ 468 SysRes r; 469 vg_assert(SUCCESS); 470 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES), 471 ARG1,ARG2,ARG3); 472 SET_STATUS_from_SysRes(r); 473} 474 475PRE(sys_sendto) 476{ 477 *flags |= SfMayBlock; 478 PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 479 PRE_REG_READ6(long, "sendto", 480 int, s, const void *, msg, int, len, 481 unsigned int, flags, 482 const struct sockaddr *, to, int, tolen); 483 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 484} 485 486PRE(sys_recvfrom) 487{ 488 *flags |= SfMayBlock; 489 PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 490 PRE_REG_READ6(long, "recvfrom", 491 int, s, void *, buf, int, len, unsigned int, flags, 492 struct sockaddr *, from, int *, fromlen); 493 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 494} 495POST(sys_recvfrom) 496{ 497 vg_assert(SUCCESS); 498 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES), 499 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6); 500} 501 502PRE(sys_sendmsg) 503{ 504 *flags |= SfMayBlock; 505 PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 506 PRE_REG_READ3(long, "sendmsg", 507 int, s, const struct msghdr *, msg, int, flags); 508 ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2); 509} 510 511PRE(sys_recvmsg) 512{ 513 *flags |= SfMayBlock; 514 PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 515 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags); 516 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2); 517} 518POST(sys_recvmsg) 519{ 520 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES); 521} 522 523//XXX: Semaphore code ripped from AMD64. 524PRE(sys_semget) 525{ 526 PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3); 527 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg); 528} 529 530PRE(sys_semop) 531{ 532 *flags |= SfMayBlock; 533 PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3); 534 PRE_REG_READ3(long, "semop", 535 int, semid, struct sembuf *, sops, unsigned, nsoops); 536 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3); 537} 538 539PRE(sys_semctl) 540{ 541 switch (ARG3 & ~VKI_IPC_64) { 542 case VKI_IPC_INFO: 543 case VKI_SEM_INFO: 544 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4); 545 PRE_REG_READ4(long, "semctl", 546 int, semid, int, semnum, int, cmd, struct seminfo *, arg); 547 break; 548 case VKI_IPC_STAT: 549 case VKI_SEM_STAT: 550 case VKI_IPC_SET: 551 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4); 552 PRE_REG_READ4(long, "semctl", 553 int, semid, int, semnum, int, cmd, struct semid_ds *, arg); 554 break; 555 case VKI_GETALL: 556 case VKI_SETALL: 557 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4); 558 PRE_REG_READ4(long, "semctl", 559 int, semid, int, semnum, int, cmd, unsigned short *, arg); 560 break; 561 default: 562 PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3); 563 PRE_REG_READ3(long, "semctl", 564 int, semid, int, semnum, int, cmd); 565 break; 566 } 567 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4); 568} 569 570POST(sys_semctl) 571{ 572 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4); 573} 574 575PRE(sys_semtimedop) 576{ 577 *flags |= SfMayBlock; 578 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4); 579 PRE_REG_READ4(long, "semtimedop", 580 int, semid, struct sembuf *, sops, unsigned, nsoops, 581 struct timespec *, timeout); 582 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4); 583} 584 585//amd64 586PRE(sys_msgget) 587{ 588 PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2); 589 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg); 590} 591 592PRE(sys_msgsnd) 593{ 594 PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4); 595 PRE_REG_READ4(long, "msgsnd", 596 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg); 597 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4); 598 if ((ARG4 & VKI_IPC_NOWAIT) == 0) 599 *flags |= SfMayBlock; 600} 601 602PRE(sys_msgrcv) 603{ 604 PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5); 605 PRE_REG_READ5(long, "msgrcv", 606 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, 607 long, msgytp, int, msgflg); 608 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); 609 if ((ARG4 & VKI_IPC_NOWAIT) == 0) 610 *flags |= SfMayBlock; 611} 612POST(sys_msgrcv) 613{ 614 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5); 615} 616 617 618PRE(sys_msgctl) 619{ 620 PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3); 621 PRE_REG_READ3(long, "msgctl", 622 int, msqid, int, cmd, struct msqid_ds *, buf); 623 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3); 624} 625POST(sys_msgctl) 626{ 627 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3); 628} 629 630//shared memory code from AMD64 631PRE(sys_shmget) 632{ 633 PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3); 634 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg); 635} 636 637PRE(wrap_sys_shmat) 638{ 639 UWord arg2tmp; 640 PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 641 PRE_REG_READ3(long, "shmat", 642 int, shmid, const void *, shmaddr, int, shmflg); 643 /* Round the attach address down to an VKI_SHMLBA boundary if the 644 client requested rounding. See #222545. This is necessary only 645 on arm-linux because VKI_SHMLBA is 4 * VKI_PAGE size; on all 646 other linux targets it is the same as the page size. */ 647 if (ARG3 & VKI_SHM_RND) 648 ARG2 = VG_ROUNDDN(ARG2, VKI_SHMLBA); 649 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3); 650 if (arg2tmp == 0) 651 SET_STATUS_Failure( VKI_EINVAL ); 652 else 653 ARG2 = arg2tmp; 654} 655 656POST(wrap_sys_shmat) 657{ 658 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3); 659} 660 661PRE(sys_shmdt) 662{ 663 PRINT("sys_shmdt ( %#lx )",ARG1); 664 PRE_REG_READ1(long, "shmdt", const void *, shmaddr); 665 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1)) 666 SET_STATUS_Failure( VKI_EINVAL ); 667} 668 669POST(sys_shmdt) 670{ 671 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1); 672} 673 674PRE(sys_shmctl) 675{ 676 PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3); 677 PRE_REG_READ3(long, "shmctl", 678 int, shmid, int, cmd, struct shmid_ds *, buf); 679 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3); 680} 681 682POST(sys_shmctl) 683{ 684 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3); 685} 686 687PRE(sys_shutdown) 688{ 689 *flags |= SfMayBlock; 690 PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2); 691 PRE_REG_READ2(int, "shutdown", int, s, int, how); 692} 693 694PRE(sys_bind) 695{ 696 PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 697 PRE_REG_READ3(long, "bind", 698 int, sockfd, struct sockaddr *, my_addr, int, addrlen); 699 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3); 700} 701 702PRE(sys_listen) 703{ 704 PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2); 705 PRE_REG_READ2(long, "listen", int, s, int, backlog); 706} 707 708PRE(sys_getsockname) 709{ 710 PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3); 711 PRE_REG_READ3(long, "getsockname", 712 int, s, struct sockaddr *, name, int *, namelen); 713 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3); 714} 715POST(sys_getsockname) 716{ 717 vg_assert(SUCCESS); 718 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES), 719 ARG1,ARG2,ARG3); 720} 721 722PRE(sys_getpeername) 723{ 724 PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3); 725 PRE_REG_READ3(long, "getpeername", 726 int, s, struct sockaddr *, name, int *, namelen); 727 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3); 728} 729POST(sys_getpeername) 730{ 731 vg_assert(SUCCESS); 732 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES), 733 ARG1,ARG2,ARG3); 734} 735 736PRE(sys_socketpair) 737{ 738 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4); 739 PRE_REG_READ4(long, "socketpair", 740 int, d, int, type, int, protocol, int*, sv); 741 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4); 742} 743POST(sys_socketpair) 744{ 745 vg_assert(SUCCESS); 746 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES), 747 ARG1,ARG2,ARG3,ARG4); 748} 749 750PRE(sys_send) 751{ 752 *flags |= SfMayBlock; 753 PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4); 754 PRE_REG_READ4(long, "send", 755 int, s, const void *, msg, int, len, 756 unsigned int, flags); 757 758 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 ); 759} 760 761PRE(sys_recv) 762{ 763 *flags |= SfMayBlock; 764 PRINT("sys_recv ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4); 765 PRE_REG_READ4(long, "recv", 766 int, s, void *, buf, int, len, unsigned int, flags); 767 ML_(generic_PRE_sys_recv)( tid, ARG1, ARG2, ARG3 ); 768} 769 770POST(sys_recv) 771{ 772 ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 ); 773} 774 775PRE(sys_mmap2) 776{ 777 SysRes r; 778 779 // Exactly like old_mmap() except: 780 // - all 6 args are passed in regs, rather than in a memory-block. 781 // - the file offset is specified in pagesize units rather than bytes, 782 // so that it can be used for files bigger than 2^32 bytes. 783 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is 784 // 4K-sized. Assert that the page size is 4K here for safety. 785 vg_assert(VKI_PAGE_SIZE == 4096); 786 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", 787 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 ); 788 PRE_REG_READ6(long, "mmap2", 789 unsigned long, start, unsigned long, length, 790 unsigned long, prot, unsigned long, flags, 791 unsigned long, fd, unsigned long, offset); 792 793 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 794 4096 * (Off64T)ARG6 ); 795 SET_STATUS_from_SysRes(r); 796} 797 798// XXX: lstat64/fstat64/stat64 are generic, but not necessarily 799// applicable to every architecture -- I think only to 32-bit archs. 800// We're going to need something like linux/core_os32.h for such 801// things, eventually, I think. --njn 802PRE(sys_lstat64) 803{ 804 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 805 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf); 806 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 ); 807 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 808} 809 810POST(sys_lstat64) 811{ 812 vg_assert(SUCCESS); 813 if (RES == 0) { 814 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 815 } 816} 817 818PRE(sys_stat64) 819{ 820 PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 821 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf); 822 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 ); 823 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) ); 824} 825 826POST(sys_stat64) 827{ 828 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 829} 830 831PRE(sys_fstatat64) 832{ 833 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3); 834 PRE_REG_READ3(long, "fstatat64", 835 int, dfd, char *, file_name, struct stat64 *, buf); 836 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); 837 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); 838} 839 840POST(sys_fstatat64) 841{ 842 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); 843} 844 845PRE(sys_fstat64) 846{ 847 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2); 848 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf); 849 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) ); 850} 851 852POST(sys_fstat64) 853{ 854 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 855} 856 857PRE(sys_clone) 858{ 859 UInt cloneflags; 860 861 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5); 862 PRE_REG_READ5(int, "clone", 863 unsigned long, flags, 864 void *, child_stack, 865 int *, parent_tidptr, 866 void *, child_tls, 867 int *, child_tidptr); 868 869 if (ARG1 & VKI_CLONE_PARENT_SETTID) { 870 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int)); 871 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 872 VKI_PROT_WRITE)) { 873 SET_STATUS_Failure( VKI_EFAULT ); 874 return; 875 } 876 } 877 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) { 878 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int)); 879 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 880 VKI_PROT_WRITE)) { 881 SET_STATUS_Failure( VKI_EFAULT ); 882 return; 883 } 884 } 885 if (ARG1 & VKI_CLONE_SETTLS) { 886 PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t)); 887 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t), 888 VKI_PROT_READ)) { 889 SET_STATUS_Failure( VKI_EFAULT ); 890 return; 891 } 892 } 893 894 cloneflags = ARG1; 895 896 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) { 897 SET_STATUS_Failure( VKI_EINVAL ); 898 return; 899 } 900 901 /* Only look at the flags we really care about */ 902 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 903 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) { 904 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: 905 /* thread creation */ 906 SET_STATUS_from_SysRes( 907 do_clone(tid, 908 ARG1, /* flags */ 909 (Addr)ARG2, /* child ESP */ 910 (Int *)ARG3, /* parent_tidptr */ 911 (Int *)ARG5, /* child_tidptr */ 912 (Addr)ARG4)); /* set_tls */ 913 break; 914 915 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ 916 /* FALLTHROUGH - assume vfork == fork */ 917 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); 918 919 case 0: /* plain fork */ 920 SET_STATUS_from_SysRes( 921 ML_(do_fork_clone)(tid, 922 cloneflags, /* flags */ 923 (Int *)ARG3, /* parent_tidptr */ 924 (Int *)ARG5)); /* child_tidptr */ 925 break; 926 927 default: 928 /* should we just ENOSYS? */ 929 VG_(message)(Vg_UserMsg, ""); 930 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1); 931 VG_(message)(Vg_UserMsg, ""); 932 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:"); 933 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)"); 934 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork"); 935 VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver"); 936 VG_(unimplemented) 937 ("Valgrind does not support general clone()."); 938 } 939 940 if (SUCCESS) { 941 if (ARG1 & VKI_CLONE_PARENT_SETTID) 942 POST_MEM_WRITE(ARG3, sizeof(Int)); 943 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) 944 POST_MEM_WRITE(ARG5, sizeof(Int)); 945 946 /* Thread creation was successful; let the child have the chance 947 to run */ 948 *flags |= SfYieldAfter; 949 } 950} 951 952PRE(sys_sigreturn) 953{ 954 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 955 an explanation of what follows. */ 956 957 PRINT("sys_sigreturn ( )"); 958 959 vg_assert(VG_(is_valid_tid)(tid)); 960 vg_assert(tid >= 1 && tid < VG_N_THREADS); 961 vg_assert(VG_(is_running_thread)(tid)); 962 963 /* Restore register state from frame and remove it */ 964 VG_(sigframe_destroy)(tid, False); 965 966 /* Tell the driver not to update the guest state with the "result", 967 and set a bogus result to keep it happy. */ 968 *flags |= SfNoWriteResult; 969 SET_STATUS_Success(0); 970 971 /* Check to see if any signals arose as a result of this. */ 972 *flags |= SfPollAfter; 973} 974 975PRE(sys_rt_sigreturn) 976{ 977 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for 978 an explanation of what follows. */ 979 980 PRINT("rt_sigreturn ( )"); 981 982 vg_assert(VG_(is_valid_tid)(tid)); 983 vg_assert(tid >= 1 && tid < VG_N_THREADS); 984 vg_assert(VG_(is_running_thread)(tid)); 985 986 /* Restore register state from frame and remove it */ 987 VG_(sigframe_destroy)(tid, True); 988 989 /* Tell the driver not to update the guest state with the "result", 990 and set a bogus result to keep it happy. */ 991 *flags |= SfNoWriteResult; 992 SET_STATUS_Success(0); 993 994 /* Check to see if any signals arose as a result of this. */ 995 *flags |= SfPollAfter; 996} 997 998/* NB: clone of x86-linux version, and ppc32-linux has an almost 999 identical one. */ 1000PRE(sys_sigsuspend) 1001{ 1002 /* The C library interface to sigsuspend just takes a pointer to 1003 a signal mask but this system call has three arguments - the first 1004 two don't appear to be used by the kernel and are always passed as 1005 zero by glibc and the third is the first word of the signal mask 1006 so only 32 signals are supported. 1007 1008 In fact glibc normally uses rt_sigsuspend if it is available as 1009 that takes a pointer to the signal mask so supports more signals. 1010 */ 1011 *flags |= SfMayBlock; 1012 PRINT("sys_sigsuspend ( %ld, %ld, %ld )", ARG1,ARG2,ARG3 ); 1013 PRE_REG_READ3(int, "sigsuspend", 1014 int, history0, int, history1, 1015 vki_old_sigset_t, mask); 1016} 1017 1018/* Very much ARM specific */ 1019 1020PRE(sys_set_tls) 1021{ 1022 PRINT("set_tls (%lx)",ARG1); 1023 PRE_REG_READ1(long, "set_tls", unsigned long, addr); 1024 1025 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) ); 1026} 1027 1028PRE(sys_cacheflush) 1029{ 1030 PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3); 1031 PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags); 1032 VG_(discard_translations)( (Addr64)ARG1, 1033 ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/, 1034 "PRE(sys_cacheflush)" ); 1035 SET_STATUS_Success(0); 1036} 1037 1038// ARG3 is only used for pointers into the traced process's address 1039// space and for offsets into the traced process's struct 1040// user_regs_struct. It is never a pointer into this process's memory 1041// space, and we should therefore not check anything it points to. 1042PRE(sys_ptrace) 1043{ 1044 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4); 1045 PRE_REG_READ4(int, "ptrace", 1046 long, request, long, pid, long, addr, long, data); 1047 switch (ARG1) { 1048 case VKI_PTRACE_PEEKTEXT: 1049 case VKI_PTRACE_PEEKDATA: 1050 case VKI_PTRACE_PEEKUSR: 1051 PRE_MEM_WRITE( "ptrace(peek)", ARG4, 1052 sizeof (long)); 1053 break; 1054 case VKI_PTRACE_GETREGS: 1055 PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 1056 sizeof (struct vki_user_regs_struct)); 1057 break; 1058 case VKI_PTRACE_GETFPREGS: 1059 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 1060 sizeof (struct vki_user_fp)); 1061 break; 1062 case VKI_PTRACE_GETWMMXREGS: 1063 PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4, 1064 VKI_IWMMXT_SIZE); 1065 break; 1066 case VKI_PTRACE_GETCRUNCHREGS: 1067 PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4, 1068 VKI_CRUNCH_SIZE); 1069 break; 1070 case VKI_PTRACE_GETVFPREGS: 1071 PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4, 1072 sizeof (struct vki_user_vfp) ); 1073 break; 1074 case VKI_PTRACE_GETHBPREGS: 1075 PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4, 1076 sizeof (unsigned long) ); 1077 break; 1078 case VKI_PTRACE_SETREGS: 1079 PRE_MEM_READ( "ptrace(setregs)", ARG4, 1080 sizeof (struct vki_user_regs_struct)); 1081 break; 1082 case VKI_PTRACE_SETFPREGS: 1083 PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 1084 sizeof (struct vki_user_fp)); 1085 break; 1086 case VKI_PTRACE_SETWMMXREGS: 1087 PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4, 1088 VKI_IWMMXT_SIZE); 1089 break; 1090 case VKI_PTRACE_SETCRUNCHREGS: 1091 PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4, 1092 VKI_CRUNCH_SIZE); 1093 break; 1094 case VKI_PTRACE_SETVFPREGS: 1095 PRE_MEM_READ( "ptrace(setvfpregs)", ARG4, 1096 sizeof (struct vki_user_vfp)); 1097 break; 1098 case VKI_PTRACE_SETHBPREGS: 1099 PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long)); 1100 break; 1101 case VKI_PTRACE_GET_THREAD_AREA: 1102 PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long)); 1103 break; 1104 case VKI_PTRACE_GETEVENTMSG: 1105 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long)); 1106 break; 1107 case VKI_PTRACE_GETSIGINFO: 1108 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t)); 1109 break; 1110 case VKI_PTRACE_SETSIGINFO: 1111 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t)); 1112 break; 1113 case VKI_PTRACE_GETREGSET: 1114 ML_(linux_PRE_getregset)(tid, ARG3, ARG4); 1115 break; 1116 case VKI_PTRACE_SETREGSET: 1117 ML_(linux_PRE_setregset)(tid, ARG3, ARG4); 1118 break; 1119 default: 1120 break; 1121 } 1122} 1123 1124POST(sys_ptrace) 1125{ 1126 switch (ARG1) { 1127 case VKI_PTRACE_PEEKTEXT: 1128 case VKI_PTRACE_PEEKDATA: 1129 case VKI_PTRACE_PEEKUSR: 1130 POST_MEM_WRITE( ARG4, sizeof (long)); 1131 break; 1132 case VKI_PTRACE_GETREGS: 1133 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct)); 1134 break; 1135 case VKI_PTRACE_GETFPREGS: 1136 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp)); 1137 break; 1138 case VKI_PTRACE_GETWMMXREGS: 1139 POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE); 1140 break; 1141 case VKI_PTRACE_GETCRUNCHREGS: 1142 POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE); 1143 break; 1144 case VKI_PTRACE_GETVFPREGS: 1145 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp)); 1146 break; 1147 case VKI_PTRACE_GET_THREAD_AREA: 1148 case VKI_PTRACE_GETHBPREGS: 1149 case VKI_PTRACE_GETEVENTMSG: 1150 POST_MEM_WRITE( ARG4, sizeof(unsigned long)); 1151 break; 1152 case VKI_PTRACE_GETSIGINFO: 1153 /* XXX: This is a simplification. Different parts of the 1154 * siginfo_t are valid depending on the type of signal. 1155 */ 1156 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t)); 1157 break; 1158 case VKI_PTRACE_GETREGSET: 1159 ML_(linux_POST_getregset)(tid, ARG3, ARG4); 1160 break; 1161 default: 1162 break; 1163 } 1164} 1165 1166#undef PRE 1167#undef POST 1168 1169/* --------------------------------------------------------------------- 1170 The arm/Linux syscall table 1171 ------------------------------------------------------------------ */ 1172 1173#if 0 1174#define __NR_OABI_SYSCALL_BASE 0x900000 1175#else 1176#define __NR_OABI_SYSCALL_BASE 0x0 1177#endif 1178 1179#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(arm_linux, sysno, name) 1180#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(arm_linux, sysno, name) 1181 1182// This table maps from __NR_xxx syscall numbers (from 1183// linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo() 1184// wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S). 1185// 1186// For those syscalls not handled by Valgrind, the annotation indicate its 1187// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? 1188// (unknown). 1189 1190static SyscallTableEntry syscall_main_table[] = { 1191//zz // (restart_syscall) // 0 1192 GENX_(__NR_exit, sys_exit), // 1 1193 GENX_(__NR_fork, sys_fork), // 2 1194 GENXY(__NR_read, sys_read), // 3 1195 GENX_(__NR_write, sys_write), // 4 1196 1197 GENXY(__NR_open, sys_open), // 5 1198 GENXY(__NR_close, sys_close), // 6 1199// GENXY(__NR_waitpid, sys_waitpid), // 7 1200 GENXY(__NR_creat, sys_creat), // 8 1201 GENX_(__NR_link, sys_link), // 9 1202 1203 GENX_(__NR_unlink, sys_unlink), // 10 1204 GENX_(__NR_execve, sys_execve), // 11 1205 GENX_(__NR_chdir, sys_chdir), // 12 1206 GENXY(__NR_time, sys_time), // 13 1207 GENX_(__NR_mknod, sys_mknod), // 14 1208 1209 GENX_(__NR_chmod, sys_chmod), // 15 1210//zz LINX_(__NR_lchown, sys_lchown16), // 16 1211// GENX_(__NR_break, sys_ni_syscall), // 17 1212//zz // (__NR_oldstat, sys_stat), // 18 (obsolete) 1213 LINX_(__NR_lseek, sys_lseek), // 19 1214 1215 GENX_(__NR_getpid, sys_getpid), // 20 1216 LINX_(__NR_mount, sys_mount), // 21 1217 LINX_(__NR_umount, sys_oldumount), // 22 1218 LINX_(__NR_setuid, sys_setuid16), // 23 ## P 1219 LINX_(__NR_getuid, sys_getuid16), // 24 ## P 1220//zz 1221//zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN) 1222 PLAXY(__NR_ptrace, sys_ptrace), // 26 1223 GENX_(__NR_alarm, sys_alarm), // 27 1224//zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete 1225 GENX_(__NR_pause, sys_pause), // 29 1226 1227 LINX_(__NR_utime, sys_utime), // 30 1228// GENX_(__NR_stty, sys_ni_syscall), // 31 1229// GENX_(__NR_gtty, sys_ni_syscall), // 32 1230 GENX_(__NR_access, sys_access), // 33 1231 GENX_(__NR_nice, sys_nice), // 34 1232 1233// GENX_(__NR_ftime, sys_ni_syscall), // 35 1234 GENX_(__NR_sync, sys_sync), // 36 1235 GENX_(__NR_kill, sys_kill), // 37 1236 GENX_(__NR_rename, sys_rename), // 38 1237 GENX_(__NR_mkdir, sys_mkdir), // 39 1238 1239 GENX_(__NR_rmdir, sys_rmdir), // 40 1240 GENXY(__NR_dup, sys_dup), // 41 1241 LINXY(__NR_pipe, sys_pipe), // 42 1242 GENXY(__NR_times, sys_times), // 43 1243// GENX_(__NR_prof, sys_ni_syscall), // 44 1244//zz 1245 GENX_(__NR_brk, sys_brk), // 45 1246 LINX_(__NR_setgid, sys_setgid16), // 46 1247 LINX_(__NR_getgid, sys_getgid16), // 47 1248//zz // (__NR_signal, sys_signal), // 48 */* (ANSI C) 1249 LINX_(__NR_geteuid, sys_geteuid16), // 49 1250 1251 LINX_(__NR_getegid, sys_getegid16), // 50 1252 GENX_(__NR_acct, sys_acct), // 51 1253 LINX_(__NR_umount2, sys_umount), // 52 1254// GENX_(__NR_lock, sys_ni_syscall), // 53 1255 LINXY(__NR_ioctl, sys_ioctl), // 54 1256 1257 LINXY(__NR_fcntl, sys_fcntl), // 55 1258// GENX_(__NR_mpx, sys_ni_syscall), // 56 1259 GENX_(__NR_setpgid, sys_setpgid), // 57 1260// GENX_(__NR_ulimit, sys_ni_syscall), // 58 1261//zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete 1262//zz 1263 GENX_(__NR_umask, sys_umask), // 60 1264 GENX_(__NR_chroot, sys_chroot), // 61 1265//zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated 1266 GENXY(__NR_dup2, sys_dup2), // 63 1267 GENX_(__NR_getppid, sys_getppid), // 64 1268 1269 GENX_(__NR_getpgrp, sys_getpgrp), // 65 1270 GENX_(__NR_setsid, sys_setsid), // 66 1271 LINXY(__NR_sigaction, sys_sigaction), // 67 1272//zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C) 1273//zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C) 1274//zz 1275 LINX_(__NR_setreuid, sys_setreuid16), // 70 1276 LINX_(__NR_setregid, sys_setregid16), // 71 1277 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72 1278 LINXY(__NR_sigpending, sys_sigpending), // 73 1279//zz // (__NR_sethostname, sys_sethostname), // 74 */* 1280//zz 1281 GENX_(__NR_setrlimit, sys_setrlimit), // 75 1282 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76 1283 GENXY(__NR_getrusage, sys_getrusage), // 77 1284 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78 1285 GENX_(__NR_settimeofday, sys_settimeofday), // 79 1286 1287 LINXY(__NR_getgroups, sys_getgroups16), // 80 1288 LINX_(__NR_setgroups, sys_setgroups16), // 81 1289// PLAX_(__NR_select, old_select), // 82 1290 GENX_(__NR_symlink, sys_symlink), // 83 1291//zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete 1292//zz 1293 GENX_(__NR_readlink, sys_readlink), // 85 1294//zz // (__NR_uselib, sys_uselib), // 86 */Linux 1295//zz // (__NR_swapon, sys_swapon), // 87 */Linux 1296//zz // (__NR_reboot, sys_reboot), // 88 */Linux 1297//zz // (__NR_readdir, old_readdir), // 89 -- superseded 1298//zz 1299// _____(__NR_mmap, old_mmap), // 90 1300 GENXY(__NR_munmap, sys_munmap), // 91 1301 GENX_(__NR_truncate, sys_truncate), // 92 1302 GENX_(__NR_ftruncate, sys_ftruncate), // 93 1303 GENX_(__NR_fchmod, sys_fchmod), // 94 1304 1305 LINX_(__NR_fchown, sys_fchown16), // 95 1306 GENX_(__NR_getpriority, sys_getpriority), // 96 1307 GENX_(__NR_setpriority, sys_setpriority), // 97 1308// GENX_(__NR_profil, sys_ni_syscall), // 98 1309 GENXY(__NR_statfs, sys_statfs), // 99 1310 1311 GENXY(__NR_fstatfs, sys_fstatfs), // 100 1312// LINX_(__NR_ioperm, sys_ioperm), // 101 1313 LINXY(__NR_socketcall, sys_socketcall), // 102 1314 LINXY(__NR_syslog, sys_syslog), // 103 1315 GENXY(__NR_setitimer, sys_setitimer), // 104 1316 1317 GENXY(__NR_getitimer, sys_getitimer), // 105 1318 GENXY(__NR_stat, sys_newstat), // 106 1319 GENXY(__NR_lstat, sys_newlstat), // 107 1320 GENXY(__NR_fstat, sys_newfstat), // 108 1321//zz // (__NR_olduname, sys_uname), // 109 -- obsolete 1322//zz 1323// GENX_(__NR_iopl, sys_iopl), // 110 1324 LINX_(__NR_vhangup, sys_vhangup), // 111 1325// GENX_(__NR_idle, sys_ni_syscall), // 112 1326// PLAXY(__NR_vm86old, sys_vm86old), // 113 __NR_syscall... weird 1327 GENXY(__NR_wait4, sys_wait4), // 114 1328//zz 1329//zz // (__NR_swapoff, sys_swapoff), // 115 */Linux 1330 LINXY(__NR_sysinfo, sys_sysinfo), // 116 1331// _____(__NR_ipc, sys_ipc), // 117 1332 GENX_(__NR_fsync, sys_fsync), // 118 1333 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux 1334 1335 PLAX_(__NR_clone, sys_clone), // 120 1336//zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?) 1337 GENXY(__NR_uname, sys_newuname), // 122 1338// PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123 1339//zz LINXY(__NR_adjtimex, sys_adjtimex), // 124 1340//zz 1341 GENXY(__NR_mprotect, sys_mprotect), // 125 1342 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126 1343//zz // Nb: create_module() was removed 2.4-->2.6 1344// GENX_(__NR_create_module, sys_ni_syscall), // 127 1345 LINX_(__NR_init_module, sys_init_module), // 128 1346 LINX_(__NR_delete_module, sys_delete_module), // 129 1347//zz 1348//zz // Nb: get_kernel_syms() was removed 2.4-->2.6 1349// GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 1350 LINX_(__NR_quotactl, sys_quotactl), // 131 1351 GENX_(__NR_getpgid, sys_getpgid), // 132 1352 GENX_(__NR_fchdir, sys_fchdir), // 133 1353//zz // (__NR_bdflush, sys_bdflush), // 134 */Linux 1354//zz 1355//zz // (__NR_sysfs, sys_sysfs), // 135 SVr4 1356 LINX_(__NR_personality, sys_personality), // 136 1357// GENX_(__NR_afs_syscall, sys_ni_syscall), // 137 1358 LINX_(__NR_setfsuid, sys_setfsuid16), // 138 1359 LINX_(__NR_setfsgid, sys_setfsgid16), // 139 1360 1361 LINXY(__NR__llseek, sys_llseek), // 140 1362 GENXY(__NR_getdents, sys_getdents), // 141 1363 GENX_(__NR__newselect, sys_select), // 142 1364 GENX_(__NR_flock, sys_flock), // 143 1365 GENX_(__NR_msync, sys_msync), // 144 1366 1367 GENXY(__NR_readv, sys_readv), // 145 1368 GENX_(__NR_writev, sys_writev), // 146 1369 GENX_(__NR_getsid, sys_getsid), // 147 1370 GENX_(__NR_fdatasync, sys_fdatasync), // 148 1371 LINXY(__NR__sysctl, sys_sysctl), // 149 1372 1373 GENX_(__NR_mlock, sys_mlock), // 150 1374 GENX_(__NR_munlock, sys_munlock), // 151 1375 GENX_(__NR_mlockall, sys_mlockall), // 152 1376 LINX_(__NR_munlockall, sys_munlockall), // 153 1377 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154 1378 1379 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155 1380 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156 1381 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157 1382 LINX_(__NR_sched_yield, sys_sched_yield), // 158 1383 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159 1384 1385 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160 1386//zz //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */* 1387 GENXY(__NR_nanosleep, sys_nanosleep), // 162 1388 GENX_(__NR_mremap, sys_mremap), // 163 1389 LINX_(__NR_setresuid, sys_setresuid16), // 164 1390 1391 LINXY(__NR_getresuid, sys_getresuid16), // 165 1392// PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only 1393// GENX_(__NR_query_module, sys_ni_syscall), // 167 1394 GENXY(__NR_poll, sys_poll), // 168 1395//zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux 1396//zz 1397 LINX_(__NR_setresgid, sys_setresgid16), // 170 1398 LINXY(__NR_getresgid, sys_getresgid16), // 171 1399 LINXY(__NR_prctl, sys_prctl), // 172 1400 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173 1401 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174 1402 1403 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175 1404 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176 1405 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177 1406 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178 1407 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179 1408 1409 GENXY(__NR_pread64, sys_pread64), // 180 1410 GENX_(__NR_pwrite64, sys_pwrite64), // 181 1411 LINX_(__NR_chown, sys_chown16), // 182 1412 GENXY(__NR_getcwd, sys_getcwd), // 183 1413 LINXY(__NR_capget, sys_capget), // 184 1414 1415 LINX_(__NR_capset, sys_capset), // 185 1416 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186 1417 LINXY(__NR_sendfile, sys_sendfile), // 187 1418// GENXY(__NR_getpmsg, sys_getpmsg), // 188 1419// GENX_(__NR_putpmsg, sys_putpmsg), // 189 1420 1421 // Nb: we treat vfork as fork 1422 GENX_(__NR_vfork, sys_fork), // 190 1423 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191 1424 PLAX_(__NR_mmap2, sys_mmap2), // 192 1425 GENX_(__NR_truncate64, sys_truncate64), // 193 1426 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194 1427 1428 PLAXY(__NR_stat64, sys_stat64), // 195 1429 PLAXY(__NR_lstat64, sys_lstat64), // 196 1430 PLAXY(__NR_fstat64, sys_fstat64), // 197 1431 GENX_(__NR_lchown32, sys_lchown), // 198 1432 GENX_(__NR_getuid32, sys_getuid), // 199 1433 1434 GENX_(__NR_getgid32, sys_getgid), // 200 1435 GENX_(__NR_geteuid32, sys_geteuid), // 201 1436 GENX_(__NR_getegid32, sys_getegid), // 202 1437 GENX_(__NR_setreuid32, sys_setreuid), // 203 1438 GENX_(__NR_setregid32, sys_setregid), // 204 1439 1440 GENXY(__NR_getgroups32, sys_getgroups), // 205 1441 GENX_(__NR_setgroups32, sys_setgroups), // 206 1442 GENX_(__NR_fchown32, sys_fchown), // 207 1443 LINX_(__NR_setresuid32, sys_setresuid), // 208 1444 LINXY(__NR_getresuid32, sys_getresuid), // 209 1445 1446 LINX_(__NR_setresgid32, sys_setresgid), // 210 1447 LINXY(__NR_getresgid32, sys_getresgid), // 211 1448 GENX_(__NR_chown32, sys_chown), // 212 1449 GENX_(__NR_setuid32, sys_setuid), // 213 1450 GENX_(__NR_setgid32, sys_setgid), // 214 1451 1452 LINX_(__NR_setfsuid32, sys_setfsuid), // 215 1453 LINX_(__NR_setfsgid32, sys_setfsgid), // 216 1454//zz // (__NR_pivot_root, sys_pivot_root), // 217 */Linux 1455 GENXY(__NR_mincore, sys_mincore), // 218 1456 GENX_(__NR_madvise, sys_madvise), // 219 1457 1458 GENXY(__NR_getdents64, sys_getdents64), // 220 1459 LINXY(__NR_fcntl64, sys_fcntl64), // 221 1460// GENX_(222, sys_ni_syscall), // 222 1461// PLAXY(223, sys_syscall223), // 223 // sys_bproc? 1462 LINX_(__NR_gettid, sys_gettid), // 224 1463 1464 LINX_(__NR_readahead, sys_readahead), // 225 */Linux 1465 LINX_(__NR_setxattr, sys_setxattr), // 226 1466 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227 1467 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228 1468 LINXY(__NR_getxattr, sys_getxattr), // 229 1469 1470 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230 1471 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231 1472 LINXY(__NR_listxattr, sys_listxattr), // 232 1473 LINXY(__NR_llistxattr, sys_llistxattr), // 233 1474 LINXY(__NR_flistxattr, sys_flistxattr), // 234 1475 1476 LINX_(__NR_removexattr, sys_removexattr), // 235 1477 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236 1478 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237 1479 LINXY(__NR_tkill, sys_tkill), // 238 */Linux 1480 LINXY(__NR_sendfile64, sys_sendfile64), // 239 1481 1482 LINXY(__NR_futex, sys_futex), // 240 1483 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241 1484 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242 1485// PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243 1486// PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244 1487 1488 LINXY(__NR_io_setup, sys_io_setup), // 245 1489 LINX_(__NR_io_destroy, sys_io_destroy), // 246 1490 LINXY(__NR_io_getevents, sys_io_getevents), // 247 1491 LINX_(__NR_io_submit, sys_io_submit), // 248 1492 LINXY(__NR_io_cancel, sys_io_cancel), // 249 1493 1494// LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?) 1495 GENX_(251, sys_ni_syscall), // 251 1496 LINX_(__NR_exit_group, sys_exit_group), // 252 1497// GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253 1498 LINXY(__NR_epoll_create, sys_epoll_create), // 254 1499 1500 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255 1501 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256 1502//zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux 1503 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258 1504 LINXY(__NR_timer_create, sys_timer_create), // 259 1505 1506 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1) 1507 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2) 1508 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3) 1509 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4) 1510 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5) 1511 1512 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6) 1513 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7) 1514 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */* 1515 GENXY(__NR_statfs64, sys_statfs64), // 268 1516 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269 1517 1518 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux 1519 GENX_(__NR_utimes, sys_utimes), // 271 1520// LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?) 1521 GENX_(__NR_vserver, sys_ni_syscall), // 273 1522 LINX_(__NR_mbind, sys_mbind), // 274 ?/? 1523 1524 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/? 1525 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/? 1526 LINXY(__NR_mq_open, sys_mq_open), // 277 1527 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1) 1528 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2) 1529 1530 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3) 1531 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4) 1532 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5) 1533 LINXY(__NR_waitid, sys_waitid), // 280 1534 1535 PLAXY(__NR_socket, sys_socket), // 281 1536 PLAX_(__NR_bind, sys_bind), // 282 1537 PLAX_(__NR_connect, sys_connect), // 283 1538 PLAX_(__NR_listen, sys_listen), // 284 1539 PLAXY(__NR_accept, sys_accept), // 285 1540 PLAXY(__NR_getsockname, sys_getsockname), // 286 1541 PLAXY(__NR_getpeername, sys_getpeername), // 287 1542 PLAXY(__NR_socketpair, sys_socketpair), // 288 1543 PLAX_(__NR_send, sys_send), 1544 PLAX_(__NR_sendto, sys_sendto), // 290 1545 PLAXY(__NR_recv, sys_recv), 1546 PLAXY(__NR_recvfrom, sys_recvfrom), // 292 1547 PLAX_(__NR_shutdown, sys_shutdown), // 293 1548 PLAX_(__NR_setsockopt, sys_setsockopt), // 294 1549 PLAXY(__NR_getsockopt, sys_getsockopt), // 295 1550 PLAX_(__NR_sendmsg, sys_sendmsg), // 296 1551 PLAXY(__NR_recvmsg, sys_recvmsg), // 297 1552 PLAX_(__NR_semop, sys_semop), // 298 1553 PLAX_(__NR_semget, sys_semget), // 299 1554 PLAXY(__NR_semctl, sys_semctl), // 300 1555 PLAX_(__NR_msgget, sys_msgget), 1556 PLAX_(__NR_msgsnd, sys_msgsnd), 1557 PLAXY(__NR_msgrcv, sys_msgrcv), 1558 PLAXY(__NR_msgctl, sys_msgctl), // 304 1559 PLAX_(__NR_semtimedop, sys_semtimedop), // 312 1560 1561 LINX_(__NR_add_key, sys_add_key), // 286 1562 LINX_(__NR_request_key, sys_request_key), // 287 1563 LINXY(__NR_keyctl, sys_keyctl), // not 288... 1564// LINX_(__NR_ioprio_set, sys_ioprio_set), // 289 1565 1566// LINX_(__NR_ioprio_get, sys_ioprio_get), // 290 1567 LINX_(__NR_inotify_init, sys_inotify_init), // 291 1568 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292 1569 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293 1570// LINX_(__NR_migrate_pages, sys_migrate_pages), // 294 1571 1572 LINXY(__NR_openat, sys_openat), // 295 1573 LINX_(__NR_mkdirat, sys_mkdirat), // 296 1574 LINX_(__NR_mknodat, sys_mknodat), // 297 1575 LINX_(__NR_fchownat, sys_fchownat), // 298 1576 LINX_(__NR_futimesat, sys_futimesat), // 326 on arm 1577 1578 PLAXY(__NR_fstatat64, sys_fstatat64), // 300 1579 LINX_(__NR_unlinkat, sys_unlinkat), // 301 1580 LINX_(__NR_renameat, sys_renameat), // 302 1581 LINX_(__NR_linkat, sys_linkat), // 303 1582 LINX_(__NR_symlinkat, sys_symlinkat), // 304 1583 1584 LINX_(__NR_readlinkat, sys_readlinkat), // 1585 LINX_(__NR_fchmodat, sys_fchmodat), // 1586 LINX_(__NR_faccessat, sys_faccessat), // 1587 PLAXY(__NR_shmat, wrap_sys_shmat), //305 1588 PLAXY(__NR_shmdt, sys_shmdt), //306 1589 PLAX_(__NR_shmget, sys_shmget), //307 1590 PLAXY(__NR_shmctl, sys_shmctl), // 308 1591// LINX_(__NR_pselect6, sys_pselect6), // 1592 1593// LINX_(__NR_unshare, sys_unshare), // 310 1594 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311 1595 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312 1596// LINX_(__NR_splice, sys_ni_syscall), // 313 1597// LINX_(__NR_sync_file_range, sys_sync_file_range), // 314 1598 1599// LINX_(__NR_tee, sys_ni_syscall), // 315 1600// LINX_(__NR_vmsplice, sys_ni_syscall), // 316 1601 LINXY(__NR_move_pages, sys_move_pages), // 317 1602// LINX_(__NR_getcpu, sys_ni_syscall), // 318 1603 1604 LINX_(__NR_utimensat, sys_utimensat), // 320 1605 LINXY(__NR_signalfd, sys_signalfd), // 321 1606 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322 1607 LINX_(__NR_eventfd, sys_eventfd), // 323 1608 1609 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325 1610 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326 1611 1612 /////////////// 1613 1614 // JRS 2010-Jan-03: I believe that all the numbers listed 1615 // in comments in the table prior to this point (eg "// 326", 1616 // etc) are bogus since it looks to me like they are copied 1617 // verbatim from syswrap-x86-linux.c and they certainly do not 1618 // correspond to what's in include/vki/vki-scnums-arm-linux.h. 1619 // From here onwards, please ensure the numbers are correct. 1620 1621 LINX_(__NR_pselect6, sys_pselect6), // 335 1622 LINXY(__NR_ppoll, sys_ppoll), // 336 1623 1624 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 346 1625 1626 LINX_(__NR_fallocate, sys_fallocate), // 352 1627 1628 LINXY(__NR_signalfd4, sys_signalfd4), // 355 1629 LINX_(__NR_eventfd2, sys_eventfd2), // 356 1630 LINXY(__NR_epoll_create1, sys_epoll_create1), // 357 1631 LINXY(__NR_dup3, sys_dup3), // 358 1632 LINXY(__NR_pipe2, sys_pipe2), // 359 1633 LINXY(__NR_inotify_init1, sys_inotify_init1), // 360 1634 LINXY(__NR_preadv, sys_preadv), // 361 1635 LINX_(__NR_pwritev, sys_pwritev), // 362 1636 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 363 1637 LINXY(__NR_perf_event_open, sys_perf_event_open), // 364 1638 1639 PLAXY(__NR_accept4, sys_accept4) // 366 1640}; 1641 1642 1643/* These are not in the main table because there indexes are not small 1644 integers, but rather values close to one million. So their 1645 inclusion would force the main table to be huge (about 8 MB). */ 1646 1647static SyscallTableEntry ste___ARM_set_tls 1648 = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL }; 1649 1650static SyscallTableEntry ste___ARM_cacheflush 1651 = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL }; 1652 1653SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) 1654{ 1655 const UInt syscall_main_table_size 1656 = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]); 1657 1658 /* Is it in the contiguous initial section of the table? */ 1659 if (sysno < syscall_main_table_size) { 1660 SyscallTableEntry* sys = &syscall_main_table[sysno]; 1661 if (sys->before == NULL) 1662 return NULL; /* no entry */ 1663 else 1664 return sys; 1665 } 1666 1667 /* Check if it's one of the out-of-line entries. */ 1668 switch (sysno) { 1669 case __NR_ARM_set_tls: return &ste___ARM_set_tls; 1670 case __NR_ARM_cacheflush: return &ste___ARM_cacheflush; 1671 default: break; 1672 } 1673 1674 /* Can't find a wrapper */ 1675 return NULL; 1676} 1677 1678#endif // defined(VGP_arm_linux) 1679 1680/*--------------------------------------------------------------------*/ 1681/*--- end syswrap-arm-linux.c ---*/ 1682/*--------------------------------------------------------------------*/ 1683