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