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