2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-arm-linux.c -----*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2010 Nicholas Nethercote
12 Copyright (C) 2008-2010 Evan Geller
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.
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.
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
30 The GNU General Public License is contained in the file COPYING.
33 #if defined(VGP_arm_linux)
35 #include "pub_core_basics.h"
36 #include "pub_core_vki.h"
37 #include "pub_core_vkiscnums.h"
38 #include "pub_core_threadstate.h"
39 #include "pub_core_aspacemgr.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcprint.h"
44 #include "pub_core_libcproc.h"
45 #include "pub_core_libcsignal.h"
46 #include "pub_core_options.h"
47 #include "pub_core_scheduler.h"
48 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
49 #include "pub_core_signals.h"
50 #include "pub_core_syscall.h"
51 #include "pub_core_syswrap.h"
52 #include "pub_core_tooliface.h"
53 #include "pub_core_stacks.h" // VG_(register_stack)
54 #include "pub_core_transtab.h" // VG_(discard_translations)
56 #include "priv_types_n_macros.h"
57 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
58 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
59 #include "priv_syswrap-main.h"
62 /* ---------------------------------------------------------------------
64 ------------------------------------------------------------------ */
66 /* Call f(arg1), but first switch stacks, using 'stack' as the new
67 stack, and use 'retaddr' as f's return-to address. Also, clear all
68 the integer registers before entering f.*/
69 __attribute__((noreturn))
70 void ML_(call_on_new_stack_0_1) ( Addr stack,
80 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
81 "vgModuleLocal_call_on_new_stack_0_1:\n"
82 " mov sp,r0\n\t" /* Stack pointer */
83 " mov lr,r1\n\t" /* Return address */
84 " mov r0,r3\n\t" /* First argument */
85 " push {r2}\n\t" /* So we can ret to the new dest */
86 " mov r1, #0\n\t" /* Clear our GPRs */
98 " pop {pc}\n\t" /* Herrre we go! */
103 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
104 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
107 ULong do_syscall_clone_arm_linux ( Word (*fn)(void *),
116 "do_syscall_clone_arm_linux:\n"
118 /*Setup child stack */
119 " str r0, [r1, #-4]!\n"
120 " str r3, [r1, #-4]!\n"
122 " mov r0, r2\n" /* arg1: flags */
123 /* r1 (arg2) is already our child's stack */
124 " ldr r2, [sp, #12]\n" // parent tid
125 " ldr r3, [sp, #16]\n" // tls
126 " ldr r4, [sp, #8]\n" // Child tid
127 " mov r7, #"__NR_CLONE"\n"
139 /* Retval from child is already in r0 */
140 " mov r7, #"__NR_EXIT"\n"
142 /* Urh.. why did exit return? */
150 // forward declarations
151 static void setup_child ( ThreadArchState*, ThreadArchState* );
152 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
155 When a client clones, we need to keep track of the new thread. This means:
156 1. allocate a ThreadId+ThreadState+stack for the the thread
158 2. initialize the thread's new VCPU state
160 3. create the thread using the same args as the client requested,
161 but using the scheduler entrypoint for IP, and a separate stack
164 static SysRes do_clone ( ThreadId ptid,
170 const Bool debug = False;
172 ThreadId ctid = VG_(alloc_ThreadState)();
173 ThreadState* ptst = VG_(get_ThreadState)(ptid);
174 ThreadState* ctst = VG_(get_ThreadState)(ctid);
179 vki_sigset_t blockall, savedmask;
181 VG_(sigfillset)(&blockall);
183 vg_assert(VG_(is_running_thread)(ptid));
184 vg_assert(VG_(is_valid_tid)(ctid));
186 stack = (UWord*)ML_(allocstack)(ctid);
189 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
193 setup_child( &ctst->arch, &ptst->arch );
195 ctst->arch.vex.guest_R0 = 0;
197 ctst->arch.vex.guest_R13 = sp;
199 ctst->os_state.parent = ptid;
201 ctst->sig_mask = ptst->sig_mask;
202 ctst->tmp_sig_mask = ptst->sig_mask;
204 /* Start the child with its threadgroup being the same as the
205 parent's. This is so that any exit_group calls that happen
206 after the child is created but before it sets its
207 os_state.threadgroup field for real (in thread_wrapper in
208 syswrap-linux.c), really kill the new thread. a.k.a this avoids
209 a race condition in which the thread is unkillable (via
210 exit_group) because its threadgroup is not set. The race window
211 is probably only a few hundred or a few thousand cycles long.
213 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
215 seg = VG_(am_find_nsegment)((Addr)sp);
216 if (seg && seg->kind != SkResvn) {
217 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
218 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
220 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
223 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
224 ctid, seg->start, VG_PGROUNDUP(sp));
226 VG_(message)(Vg_UserMsg, "!? New thread %d starts with sp+%#lx) unmapped\n", ctid, sp);
227 ctst->client_stack_szB = 0;
230 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
232 if (flags & VKI_CLONE_SETTLS) {
233 res = sys_set_tls(ctid, child_tls);
238 flags &= ~VKI_CLONE_SETTLS;
240 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
242 r0 = do_syscall_clone_arm_linux(
243 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
244 child_tidptr, parent_tidptr, NULL
246 //VG_(printf)("AFTER SYSCALL, %x and %x CHILD: %d PARENT: %d\n",child_tidptr, parent_tidptr,*child_tidptr,*parent_tidptr);
248 res = VG_(mk_SysRes_arm_linux)( r0 );
250 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
253 if (sr_isError(res)) {
254 VG_(cleanup_thread)(&ctst->arch);
255 ctst->status = VgTs_Empty;
256 VG_TRACK( pre_thread_ll_exit, ctid );
264 /* ---------------------------------------------------------------------
266 ------------------------------------------------------------------ */
268 // ARM doesn't have any architecture specific thread stuff that
269 // needs to be cleaned up
270 void VG_(cleanup_thread) ( ThreadArchState* arch )
274 void setup_child ( /*OUT*/ ThreadArchState *child,
275 /*IN*/ ThreadArchState *parent )
277 child->vex = parent->vex;
278 child->vex_shadow1 = parent->vex_shadow1;
279 child->vex_shadow2 = parent->vex_shadow2;
282 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
284 VG_(threads)[tid].arch.vex.guest_TPIDRURO = tlsptr;
285 return VG_(mk_SysRes_Success)( 0 );
288 /* ---------------------------------------------------------------------
289 PRE/POST wrappers for arm/Linux-specific syscalls
290 ------------------------------------------------------------------ */
292 #define PRE(name) DEFN_PRE_TEMPLATE(arm_linux, name)
293 #define POST(name) DEFN_POST_TEMPLATE(arm_linux, name)
295 /* Add prototypes for the wrappers declared here, so that gcc doesn't
296 harass us for not having prototypes. Really this is a kludge --
297 the right thing to do is to make these wrappers 'static' since they
298 aren't visible outside this file, but that requires even more macro
301 DECL_TEMPLATE(arm_linux, sys_socketcall);
302 DECL_TEMPLATE(arm_linux, sys_socket);
303 DECL_TEMPLATE(arm_linux, sys_setsockopt);
304 DECL_TEMPLATE(arm_linux, sys_getsockopt);
305 DECL_TEMPLATE(arm_linux, sys_connect);
306 DECL_TEMPLATE(arm_linux, sys_accept);
307 DECL_TEMPLATE(arm_linux, sys_sendto);
308 DECL_TEMPLATE(arm_linux, sys_recvfrom);
309 //XXX: Semaphore code ripped from AMD64.
310 DECL_TEMPLATE(arm_linux, sys_semget);
311 DECL_TEMPLATE(arm_linux, sys_semop);
312 DECL_TEMPLATE(arm_linux, sys_semctl);
313 DECL_TEMPLATE(arm_linux, sys_semtimedop);
314 //XXX: Shared memory code ripped from AMD64
316 DECL_TEMPLATE(arm_linux, wrap_sys_shmat);
317 DECL_TEMPLATE(arm_linux, sys_shmget);
318 DECL_TEMPLATE(arm_linux, sys_shmdt);
319 DECL_TEMPLATE(arm_linux, sys_shmctl);
320 DECL_TEMPLATE(arm_linux, sys_sendmsg);
321 DECL_TEMPLATE(arm_linux, sys_recvmsg);
322 //msg* code from AMD64
323 DECL_TEMPLATE(arm_linux, sys_msgget);
324 DECL_TEMPLATE(arm_linux, sys_msgrcv);
325 DECL_TEMPLATE(arm_linux, sys_msgsnd);
326 DECL_TEMPLATE(arm_linux, sys_msgctl);
327 DECL_TEMPLATE(arm_linux, sys_shutdown);
328 DECL_TEMPLATE(arm_linux, sys_bind);
329 DECL_TEMPLATE(arm_linux, sys_listen);
330 DECL_TEMPLATE(arm_linux, sys_getsockname);
331 DECL_TEMPLATE(arm_linux, sys_getpeername);
332 DECL_TEMPLATE(arm_linux, sys_socketpair);
333 DECL_TEMPLATE(arm_linux, sys_send);
334 DECL_TEMPLATE(arm_linux, sys_recv);
335 DECL_TEMPLATE(arm_linux, sys_mmap2);
336 DECL_TEMPLATE(arm_linux, sys_stat64);
337 DECL_TEMPLATE(arm_linux, sys_lstat64);
338 DECL_TEMPLATE(arm_linux, sys_fstatat64);
339 DECL_TEMPLATE(arm_linux, sys_fstat64);
340 DECL_TEMPLATE(arm_linux, sys_clone);
341 DECL_TEMPLATE(arm_linux, sys_sigreturn);
342 DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
343 DECL_TEMPLATE(arm_linux, sys_set_tls);
344 DECL_TEMPLATE(arm_linux, sys_cacheflush);
348 # define ARG2_0 (((UWord*)ARG2)[0])
349 # define ARG2_1 (((UWord*)ARG2)[1])
350 # define ARG2_2 (((UWord*)ARG2)[2])
351 # define ARG2_3 (((UWord*)ARG2)[3])
352 # define ARG2_4 (((UWord*)ARG2)[4])
353 # define ARG2_5 (((UWord*)ARG2)[5])
355 *flags |= SfMayBlock;
356 PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
357 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
359 switch (ARG1 /* request */) {
361 case VKI_SYS_SOCKETPAIR:
362 /* int socketpair(int d, int type, int protocol, int sv[2]); */
363 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
364 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
368 /* int socket(int domain, int type, int protocol); */
369 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
373 /* int bind(int sockfd, struct sockaddr *my_addr,
375 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
376 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
380 /* int listen(int s, int backlog); */
381 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
384 case VKI_SYS_ACCEPT: {
385 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
386 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
387 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
392 /* int sendto(int s, const void *msg, int len,
394 const struct sockaddr *to, int tolen); */
395 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
396 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
397 ARG2_3, ARG2_4, ARG2_5 );
401 /* int send(int s, const void *msg, size_t len, int flags); */
402 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
403 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
406 case VKI_SYS_RECVFROM:
407 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
408 struct sockaddr *from, int *fromlen); */
409 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
410 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
411 ARG2_3, ARG2_4, ARG2_5 );
415 /* int recv(int s, void *buf, int len, unsigned int flags); */
417 The recv call is normally used only on a connected socket
418 (see connect(2)) and is identical to recvfrom with a NULL
421 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
422 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
425 case VKI_SYS_CONNECT:
426 /* int connect(int sockfd,
427 struct sockaddr *serv_addr, int addrlen ); */
428 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
429 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
432 case VKI_SYS_SETSOCKOPT:
433 /* int setsockopt(int s, int level, int optname,
434 const void *optval, int optlen); */
435 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
436 ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
440 case VKI_SYS_GETSOCKOPT:
441 /* int getsockopt(int s, int level, int optname,
442 void *optval, socklen_t *optlen); */
443 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
444 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
448 case VKI_SYS_GETSOCKNAME:
449 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
450 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
451 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
454 case VKI_SYS_GETPEERNAME:
455 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
456 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
457 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
460 case VKI_SYS_SHUTDOWN:
461 /* int shutdown(int s, int how); */
462 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
465 case VKI_SYS_SENDMSG: {
466 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
468 /* this causes warnings, and I don't get why. glibc bug?
469 * (after all it's glibc providing the arguments array)
470 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
472 ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
476 case VKI_SYS_RECVMSG: {
477 /* int recvmsg(int s, struct msghdr *msg, int flags); */
479 /* this causes warnings, and I don't get why. glibc bug?
480 * (after all it's glibc providing the arguments array)
481 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
483 ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
488 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx",ARG1);
489 SET_STATUS_Failure( VKI_EINVAL );
502 # define ARG2_0 (((UWord*)ARG2)[0])
503 # define ARG2_1 (((UWord*)ARG2)[1])
504 # define ARG2_2 (((UWord*)ARG2)[2])
505 # define ARG2_3 (((UWord*)ARG2)[3])
506 # define ARG2_4 (((UWord*)ARG2)[4])
507 # define ARG2_5 (((UWord*)ARG2)[5])
511 switch (ARG1 /* request */) {
513 case VKI_SYS_SOCKETPAIR:
514 r = ML_(generic_POST_sys_socketpair)(
515 tid, VG_(mk_SysRes_Success)(RES),
516 ARG2_0, ARG2_1, ARG2_2, ARG2_3
518 SET_STATUS_from_SysRes(r);
522 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
523 SET_STATUS_from_SysRes(r);
527 /* int bind(int sockfd, struct sockaddr *my_addr,
532 /* int listen(int s, int backlog); */
536 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
537 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
538 ARG2_0, ARG2_1, ARG2_2 );
539 SET_STATUS_from_SysRes(r);
548 case VKI_SYS_RECVFROM:
549 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
550 ARG2_0, ARG2_1, ARG2_2,
551 ARG2_3, ARG2_4, ARG2_5 );
555 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
558 case VKI_SYS_CONNECT:
561 case VKI_SYS_SETSOCKOPT:
564 case VKI_SYS_GETSOCKOPT:
565 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
567 ARG2_2, ARG2_3, ARG2_4 );
570 case VKI_SYS_GETSOCKNAME:
571 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
572 ARG2_0, ARG2_1, ARG2_2 );
575 case VKI_SYS_GETPEERNAME:
576 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
577 ARG2_0, ARG2_1, ARG2_2 );
580 case VKI_SYS_SHUTDOWN:
583 case VKI_SYS_SENDMSG:
586 case VKI_SYS_RECVMSG:
587 ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
591 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx",ARG1);
592 VG_(core_panic)("... bye!\n");
593 break; /*NOTREACHED*/
605 PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
606 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
612 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
613 SET_STATUS_from_SysRes(r);
618 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
619 PRE_REG_READ5(long, "setsockopt",
620 int, s, int, level, int, optname,
621 const void *, optval, int, optlen);
622 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
627 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
628 PRE_REG_READ5(long, "getsockopt",
629 int, s, int, level, int, optname,
630 void *, optval, int, *optlen);
631 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
636 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
637 ARG1,ARG2,ARG3,ARG4,ARG5);
642 *flags |= SfMayBlock;
643 PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
644 PRE_REG_READ3(long, "connect",
645 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
646 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
651 *flags |= SfMayBlock;
652 PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
653 PRE_REG_READ3(long, "accept",
654 int, s, struct sockaddr *, addr, int, *addrlen);
655 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
661 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
663 SET_STATUS_from_SysRes(r);
668 *flags |= SfMayBlock;
669 PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
670 PRE_REG_READ6(long, "sendto",
671 int, s, const void *, msg, int, len,
673 const struct sockaddr *, to, int, tolen);
674 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
679 *flags |= SfMayBlock;
680 PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
681 PRE_REG_READ6(long, "recvfrom",
682 int, s, void *, buf, int, len, unsigned int, flags,
683 struct sockaddr *, from, int *, fromlen);
684 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
689 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
690 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
695 *flags |= SfMayBlock;
696 PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
697 PRE_REG_READ3(long, "sendmsg",
698 int, s, const struct msghdr *, msg, int, flags);
699 ML_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
704 *flags |= SfMayBlock;
705 PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
706 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
707 ML_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
711 ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
714 //XXX: Semaphore code ripped from AMD64.
717 PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
718 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
723 *flags |= SfMayBlock;
724 PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
725 PRE_REG_READ3(long, "semop",
726 int, semid, struct sembuf *, sops, unsigned, nsoops);
727 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
732 switch (ARG3 & ~VKI_IPC_64) {
735 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
736 PRE_REG_READ4(long, "semctl",
737 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
742 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
743 PRE_REG_READ4(long, "semctl",
744 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
748 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
749 PRE_REG_READ4(long, "semctl",
750 int, semid, int, semnum, int, cmd, unsigned short *, arg);
753 PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
754 PRE_REG_READ3(long, "semctl",
755 int, semid, int, semnum, int, cmd);
758 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3,ARG4);
763 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3,ARG4);
768 *flags |= SfMayBlock;
769 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
770 PRE_REG_READ4(long, "semtimedop",
771 int, semid, struct sembuf *, sops, unsigned, nsoops,
772 struct timespec *, timeout);
773 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
779 PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
780 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
785 PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
786 PRE_REG_READ4(long, "msgsnd",
787 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
788 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
789 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
790 *flags |= SfMayBlock;
795 PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
796 PRE_REG_READ5(long, "msgrcv",
797 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
798 long, msgytp, int, msgflg);
799 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
800 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
801 *flags |= SfMayBlock;
805 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
811 PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
812 PRE_REG_READ3(long, "msgctl",
813 int, msqid, int, cmd, struct msqid_ds *, buf);
814 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
818 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
821 //shared memory code from AMD64
824 PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
825 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
831 PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
832 PRE_REG_READ3(long, "shmat",
833 int, shmid, const void *, shmaddr, int, shmflg);
834 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
836 SET_STATUS_Failure( VKI_EINVAL );
843 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
848 PRINT("sys_shmdt ( %#lx )",ARG1);
849 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
850 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
851 SET_STATUS_Failure( VKI_EINVAL );
856 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
861 PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
862 PRE_REG_READ3(long, "shmctl",
863 int, shmid, int, cmd, struct shmid_ds *, buf);
864 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3);
869 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3);
874 *flags |= SfMayBlock;
875 PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
876 PRE_REG_READ2(int, "shutdown", int, s, int, how);
881 PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
882 PRE_REG_READ3(long, "bind",
883 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
884 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
889 PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
890 PRE_REG_READ2(long, "listen", int, s, int, backlog);
895 PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
896 PRE_REG_READ3(long, "getsockname",
897 int, s, struct sockaddr *, name, int *, namelen);
898 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
900 POST(sys_getsockname)
903 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
909 PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
910 PRE_REG_READ3(long, "getpeername",
911 int, s, struct sockaddr *, name, int *, namelen);
912 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
914 POST(sys_getpeername)
917 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
923 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
924 PRE_REG_READ4(long, "socketpair",
925 int, d, int, type, int, protocol, int*, sv);
926 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
931 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
932 ARG1,ARG2,ARG3,ARG4);
937 *flags |= SfMayBlock;
938 PRINT("sys_send ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
939 PRE_REG_READ4(long, "send",
940 int, s, const void *, msg, int, len,
941 unsigned int, flags);
943 ML_(generic_PRE_sys_send)( tid, ARG1, ARG2, ARG3 );
948 *flags |= SfMayBlock;
949 PRINT("sys_recv ( %ld, %#lx, %ld, %lu )",ARG1,ARG2,ARG3,ARG4);
950 PRE_REG_READ4(long, "recv",
951 int, s, void *, buf, int, len, unsigned int, flags);
952 ML_(generic_PRE_sys_recv)( tid, ARG1, ARG2, ARG3 );
957 ML_(generic_POST_sys_recv)( tid, RES, ARG1, ARG2, ARG3 );
964 // Exactly like old_mmap() except:
965 // - all 6 args are passed in regs, rather than in a memory-block.
966 // - the file offset is specified in pagesize units rather than bytes,
967 // so that it can be used for files bigger than 2^32 bytes.
968 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is
969 // 4K-sized. Assert that the page size is 4K here for safety.
970 vg_assert(VKI_PAGE_SIZE == 4096);
971 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
972 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
973 PRE_REG_READ6(long, "mmap2",
974 unsigned long, start, unsigned long, length,
975 unsigned long, prot, unsigned long, flags,
976 unsigned long, fd, unsigned long, offset);
978 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
979 4096 * (Off64T)ARG6 );
980 SET_STATUS_from_SysRes(r);
983 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
984 // applicable to every architecture -- I think only to 32-bit archs.
985 // We're going to need something like linux/core_os32.h for such
986 // things, eventually, I think. --njn
989 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
990 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
991 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
992 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
999 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1005 PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
1006 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
1007 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
1008 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
1013 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1018 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
1019 PRE_REG_READ3(long, "fstatat64",
1020 int, dfd, char *, file_name, struct stat64 *, buf);
1021 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
1022 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
1027 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
1032 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
1033 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
1034 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1039 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1046 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
1047 PRE_REG_READ5(int, "clone",
1048 unsigned long, flags,
1049 void *, child_stack,
1050 int *, parent_tidptr,
1052 int *, child_tidptr);
1054 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
1055 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
1056 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
1058 SET_STATUS_Failure( VKI_EFAULT );
1062 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
1063 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
1064 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
1066 SET_STATUS_Failure( VKI_EFAULT );
1070 if (ARG1 & VKI_CLONE_SETTLS) {
1071 PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
1072 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
1074 SET_STATUS_Failure( VKI_EFAULT );
1081 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
1082 SET_STATUS_Failure( VKI_EINVAL );
1086 /* Only look at the flags we really care about */
1087 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
1088 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
1089 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
1090 /* thread creation */
1091 SET_STATUS_from_SysRes(
1094 (Addr)ARG2, /* child ESP */
1095 (Int *)ARG3, /* parent_tidptr */
1096 (Int *)ARG5, /* child_tidptr */
1097 (Addr)ARG4)); /* set_tls */
1100 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
1101 /* FALLTHROUGH - assume vfork == fork */
1102 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
1104 case 0: /* plain fork */
1105 SET_STATUS_from_SysRes(
1106 ML_(do_fork_clone)(tid,
1107 cloneflags, /* flags */
1108 (Int *)ARG3, /* parent_tidptr */
1109 (Int *)ARG5)); /* child_tidptr */
1113 /* should we just ENOSYS? */
1114 VG_(message)(Vg_UserMsg, "");
1115 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG1);
1116 VG_(message)(Vg_UserMsg, "");
1117 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
1118 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
1119 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
1120 VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
1122 ("Valgrind does not support general clone().");
1126 if (ARG1 & VKI_CLONE_PARENT_SETTID)
1127 POST_MEM_WRITE(ARG3, sizeof(Int));
1128 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1129 POST_MEM_WRITE(ARG5, sizeof(Int));
1131 /* Thread creation was successful; let the child have the chance
1133 *flags |= SfYieldAfter;
1139 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1140 an explanation of what follows. */
1142 PRINT("sys_sigreturn ( )");
1144 vg_assert(VG_(is_valid_tid)(tid));
1145 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1146 vg_assert(VG_(is_running_thread)(tid));
1148 /* Restore register state from frame and remove it */
1149 VG_(sigframe_destroy)(tid, False);
1151 /* Tell the driver not to update the guest state with the "result",
1152 and set a bogus result to keep it happy. */
1153 *flags |= SfNoWriteResult;
1154 SET_STATUS_Success(0);
1156 /* Check to see if any signals arose as a result of this. */
1157 *flags |= SfPollAfter;
1160 PRE(sys_rt_sigreturn)
1162 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1163 an explanation of what follows. */
1165 PRINT("rt_sigreturn ( )");
1167 vg_assert(VG_(is_valid_tid)(tid));
1168 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1169 vg_assert(VG_(is_running_thread)(tid));
1171 /* Restore register state from frame and remove it */
1172 VG_(sigframe_destroy)(tid, True);
1174 /* Tell the driver not to update the guest state with the "result",
1175 and set a bogus result to keep it happy. */
1176 *flags |= SfNoWriteResult;
1177 SET_STATUS_Success(0);
1179 /* Check to see if any signals arose as a result of this. */
1180 *flags |= SfPollAfter;
1183 /* Very much ARM specific */
1187 PRE_REG_READ1(long, "set_tls", unsigned long, addr);
1189 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
1194 PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3);
1195 PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags);
1196 VG_(discard_translations)( (Addr64)ARG1,
1197 ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/,
1198 "PRE(sys_cacheflush)" );
1199 SET_STATUS_Success(0);
1206 /* ---------------------------------------------------------------------
1207 The arm/Linux syscall table
1208 ------------------------------------------------------------------ */
1211 #define __NR_OABI_SYSCALL_BASE 0x900000
1213 #define __NR_OABI_SYSCALL_BASE 0x0
1216 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(arm_linux, sysno, name)
1217 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(arm_linux, sysno, name)
1219 // This table maps from __NR_xxx syscall numbers (from
1220 // linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo()
1221 // wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S).
1223 // For those syscalls not handled by Valgrind, the annotation indicate its
1224 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1227 static SyscallTableEntry syscall_main_table[] = {
1228 //zz // (restart_syscall) // 0
1229 GENX_(__NR_exit, sys_exit), // 1
1230 GENX_(__NR_fork, sys_fork), // 2
1231 GENXY(__NR_read, sys_read), // 3
1232 GENX_(__NR_write, sys_write), // 4
1234 GENXY(__NR_open, sys_open), // 5
1235 GENXY(__NR_close, sys_close), // 6
1236 // GENXY(__NR_waitpid, sys_waitpid), // 7
1237 GENXY(__NR_creat, sys_creat), // 8
1238 GENX_(__NR_link, sys_link), // 9
1240 GENX_(__NR_unlink, sys_unlink), // 10
1241 GENX_(__NR_execve, sys_execve), // 11
1242 GENX_(__NR_chdir, sys_chdir), // 12
1243 GENXY(__NR_time, sys_time), // 13
1244 GENX_(__NR_mknod, sys_mknod), // 14
1246 GENX_(__NR_chmod, sys_chmod), // 15
1247 //zz LINX_(__NR_lchown, sys_lchown16), // 16
1248 // GENX_(__NR_break, sys_ni_syscall), // 17
1249 //zz // (__NR_oldstat, sys_stat), // 18 (obsolete)
1250 LINX_(__NR_lseek, sys_lseek), // 19
1252 GENX_(__NR_getpid, sys_getpid), // 20
1253 LINX_(__NR_mount, sys_mount), // 21
1254 LINX_(__NR_umount, sys_oldumount), // 22
1255 LINX_(__NR_setuid, sys_setuid16), // 23 ## P
1256 LINX_(__NR_getuid, sys_getuid16), // 24 ## P
1258 //zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
1259 // PLAXY(__NR_ptrace, sys_ptrace), // 26
1260 GENX_(__NR_alarm, sys_alarm), // 27
1261 //zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
1262 GENX_(__NR_pause, sys_pause), // 29
1264 LINX_(__NR_utime, sys_utime), // 30
1265 // GENX_(__NR_stty, sys_ni_syscall), // 31
1266 // GENX_(__NR_gtty, sys_ni_syscall), // 32
1267 GENX_(__NR_access, sys_access), // 33
1268 GENX_(__NR_nice, sys_nice), // 34
1270 // GENX_(__NR_ftime, sys_ni_syscall), // 35
1271 GENX_(__NR_sync, sys_sync), // 36
1272 GENX_(__NR_kill, sys_kill), // 37
1273 GENX_(__NR_rename, sys_rename), // 38
1274 GENX_(__NR_mkdir, sys_mkdir), // 39
1276 GENX_(__NR_rmdir, sys_rmdir), // 40
1277 GENXY(__NR_dup, sys_dup), // 41
1278 LINXY(__NR_pipe, sys_pipe), // 42
1279 GENXY(__NR_times, sys_times), // 43
1280 // GENX_(__NR_prof, sys_ni_syscall), // 44
1282 GENX_(__NR_brk, sys_brk), // 45
1283 LINX_(__NR_setgid, sys_setgid16), // 46
1284 LINX_(__NR_getgid, sys_getgid16), // 47
1285 //zz // (__NR_signal, sys_signal), // 48 */* (ANSI C)
1286 LINX_(__NR_geteuid, sys_geteuid16), // 49
1288 LINX_(__NR_getegid, sys_getegid16), // 50
1289 GENX_(__NR_acct, sys_acct), // 51
1290 LINX_(__NR_umount2, sys_umount), // 52
1291 // GENX_(__NR_lock, sys_ni_syscall), // 53
1292 LINXY(__NR_ioctl, sys_ioctl), // 54
1294 LINXY(__NR_fcntl, sys_fcntl), // 55
1295 // GENX_(__NR_mpx, sys_ni_syscall), // 56
1296 GENX_(__NR_setpgid, sys_setpgid), // 57
1297 // GENX_(__NR_ulimit, sys_ni_syscall), // 58
1298 //zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
1300 GENX_(__NR_umask, sys_umask), // 60
1301 GENX_(__NR_chroot, sys_chroot), // 61
1302 //zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
1303 GENXY(__NR_dup2, sys_dup2), // 63
1304 GENX_(__NR_getppid, sys_getppid), // 64
1306 GENX_(__NR_getpgrp, sys_getpgrp), // 65
1307 GENX_(__NR_setsid, sys_setsid), // 66
1308 // _____(__NR_sigaction, sys_sigaction), // 67
1309 //zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
1310 //zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
1312 LINX_(__NR_setreuid, sys_setreuid16), // 70
1313 LINX_(__NR_setregid, sys_setregid16), // 71
1314 // _____(__NR_sigsuspend, sys_sigsuspend), // 72
1315 LINXY(__NR_sigpending, sys_sigpending), // 73
1316 //zz // (__NR_sethostname, sys_sethostname), // 74 */*
1318 GENX_(__NR_setrlimit, sys_setrlimit), // 75
1319 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
1320 GENXY(__NR_getrusage, sys_getrusage), // 77
1321 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
1322 GENX_(__NR_settimeofday, sys_settimeofday), // 79
1324 LINXY(__NR_getgroups, sys_getgroups16), // 80
1325 LINX_(__NR_setgroups, sys_setgroups16), // 81
1326 // PLAX_(__NR_select, old_select), // 82
1327 GENX_(__NR_symlink, sys_symlink), // 83
1328 //zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
1330 GENX_(__NR_readlink, sys_readlink), // 85
1331 //zz // (__NR_uselib, sys_uselib), // 86 */Linux
1332 //zz // (__NR_swapon, sys_swapon), // 87 */Linux
1333 //zz // (__NR_reboot, sys_reboot), // 88 */Linux
1334 //zz // (__NR_readdir, old_readdir), // 89 -- superseded
1336 // _____(__NR_mmap, old_mmap), // 90
1337 GENXY(__NR_munmap, sys_munmap), // 91
1338 GENX_(__NR_truncate, sys_truncate), // 92
1339 GENX_(__NR_ftruncate, sys_ftruncate), // 93
1340 GENX_(__NR_fchmod, sys_fchmod), // 94
1342 LINX_(__NR_fchown, sys_fchown16), // 95
1343 GENX_(__NR_getpriority, sys_getpriority), // 96
1344 GENX_(__NR_setpriority, sys_setpriority), // 97
1345 // GENX_(__NR_profil, sys_ni_syscall), // 98
1346 GENXY(__NR_statfs, sys_statfs), // 99
1348 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1349 // LINX_(__NR_ioperm, sys_ioperm), // 101
1350 PLAXY(__NR_socketcall, sys_socketcall), // 102
1351 LINXY(__NR_syslog, sys_syslog), // 103
1352 GENXY(__NR_setitimer, sys_setitimer), // 104
1354 GENXY(__NR_getitimer, sys_getitimer), // 105
1355 GENXY(__NR_stat, sys_newstat), // 106
1356 GENXY(__NR_lstat, sys_newlstat), // 107
1357 GENXY(__NR_fstat, sys_newfstat), // 108
1358 //zz // (__NR_olduname, sys_uname), // 109 -- obsolete
1360 // GENX_(__NR_iopl, sys_iopl), // 110
1361 LINX_(__NR_vhangup, sys_vhangup), // 111
1362 // GENX_(__NR_idle, sys_ni_syscall), // 112
1363 // PLAXY(__NR_vm86old, sys_vm86old), // 113 __NR_syscall... weird
1364 GENXY(__NR_wait4, sys_wait4), // 114
1366 //zz // (__NR_swapoff, sys_swapoff), // 115 */Linux
1367 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1368 // _____(__NR_ipc, sys_ipc), // 117
1369 GENX_(__NR_fsync, sys_fsync), // 118
1370 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
1372 PLAX_(__NR_clone, sys_clone), // 120
1373 //zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
1374 GENXY(__NR_uname, sys_newuname), // 122
1375 // PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
1376 //zz LINXY(__NR_adjtimex, sys_adjtimex), // 124
1378 GENXY(__NR_mprotect, sys_mprotect), // 125
1379 // LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1380 //zz // Nb: create_module() was removed 2.4-->2.6
1381 // GENX_(__NR_create_module, sys_ni_syscall), // 127
1382 LINX_(__NR_init_module, sys_init_module), // 128
1383 LINX_(__NR_delete_module, sys_delete_module), // 129
1385 //zz // Nb: get_kernel_syms() was removed 2.4-->2.6
1386 // GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
1387 LINX_(__NR_quotactl, sys_quotactl), // 131
1388 GENX_(__NR_getpgid, sys_getpgid), // 132
1389 GENX_(__NR_fchdir, sys_fchdir), // 133
1390 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux
1392 //zz // (__NR_sysfs, sys_sysfs), // 135 SVr4
1393 LINX_(__NR_personality, sys_personality), // 136
1394 // GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
1395 LINX_(__NR_setfsuid, sys_setfsuid16), // 138
1396 LINX_(__NR_setfsgid, sys_setfsgid16), // 139
1398 LINXY(__NR__llseek, sys_llseek), // 140
1399 GENXY(__NR_getdents, sys_getdents), // 141
1400 GENX_(__NR__newselect, sys_select), // 142
1401 GENX_(__NR_flock, sys_flock), // 143
1402 GENX_(__NR_msync, sys_msync), // 144
1404 GENXY(__NR_readv, sys_readv), // 145
1405 GENX_(__NR_writev, sys_writev), // 146
1406 GENX_(__NR_getsid, sys_getsid), // 147
1407 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1408 LINXY(__NR__sysctl, sys_sysctl), // 149
1410 GENX_(__NR_mlock, sys_mlock), // 150
1411 GENX_(__NR_munlock, sys_munlock), // 151
1412 GENX_(__NR_mlockall, sys_mlockall), // 152
1413 LINX_(__NR_munlockall, sys_munlockall), // 153
1414 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1416 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1417 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1418 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1419 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1420 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1422 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1423 //zz //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */*
1424 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1425 GENX_(__NR_mremap, sys_mremap), // 163
1426 LINX_(__NR_setresuid, sys_setresuid16), // 164
1428 LINXY(__NR_getresuid, sys_getresuid16), // 165
1429 // PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only
1430 // GENX_(__NR_query_module, sys_ni_syscall), // 167
1431 GENXY(__NR_poll, sys_poll), // 168
1432 //zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
1434 LINX_(__NR_setresgid, sys_setresgid16), // 170
1435 LINXY(__NR_getresgid, sys_getresgid16), // 171
1436 LINXY(__NR_prctl, sys_prctl), // 172
1437 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173
1438 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
1440 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
1441 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
1442 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177
1443 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
1444 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
1446 GENXY(__NR_pread64, sys_pread64), // 180
1447 //GENX_(__NR_pwrite64, sys_pwrite64_on32bitplat), // 181
1448 LINX_(__NR_chown, sys_chown16), // 182
1449 GENXY(__NR_getcwd, sys_getcwd), // 183
1450 LINXY(__NR_capget, sys_capget), // 184
1452 LINX_(__NR_capset, sys_capset), // 185
1453 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
1454 LINXY(__NR_sendfile, sys_sendfile), // 187
1455 // GENXY(__NR_getpmsg, sys_getpmsg), // 188
1456 // GENX_(__NR_putpmsg, sys_putpmsg), // 189
1458 // Nb: we treat vfork as fork
1459 GENX_(__NR_vfork, sys_fork), // 190
1460 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
1461 PLAX_(__NR_mmap2, sys_mmap2), // 192
1462 GENX_(__NR_truncate64, sys_truncate64), // 193
1463 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
1465 PLAXY(__NR_stat64, sys_stat64), // 195
1466 PLAXY(__NR_lstat64, sys_lstat64), // 196
1467 PLAXY(__NR_fstat64, sys_fstat64), // 197
1468 GENX_(__NR_lchown32, sys_lchown), // 198
1469 GENX_(__NR_getuid32, sys_getuid), // 199
1471 GENX_(__NR_getgid32, sys_getgid), // 200
1472 GENX_(__NR_geteuid32, sys_geteuid), // 201
1473 GENX_(__NR_getegid32, sys_getegid), // 202
1474 GENX_(__NR_setreuid32, sys_setreuid), // 203
1475 GENX_(__NR_setregid32, sys_setregid), // 204
1477 GENXY(__NR_getgroups32, sys_getgroups), // 205
1478 GENX_(__NR_setgroups32, sys_setgroups), // 206
1479 GENX_(__NR_fchown32, sys_fchown), // 207
1480 LINX_(__NR_setresuid32, sys_setresuid), // 208
1481 LINXY(__NR_getresuid32, sys_getresuid), // 209
1483 LINX_(__NR_setresgid32, sys_setresgid), // 210
1484 LINXY(__NR_getresgid32, sys_getresgid), // 211
1485 GENX_(__NR_chown32, sys_chown), // 212
1486 GENX_(__NR_setuid32, sys_setuid), // 213
1487 GENX_(__NR_setgid32, sys_setgid), // 214
1489 LINX_(__NR_setfsuid32, sys_setfsuid), // 215
1490 LINX_(__NR_setfsgid32, sys_setfsgid), // 216
1491 //zz // (__NR_pivot_root, sys_pivot_root), // 217 */Linux
1492 GENXY(__NR_mincore, sys_mincore), // 218
1493 GENX_(__NR_madvise, sys_madvise), // 219
1495 GENXY(__NR_getdents64, sys_getdents64), // 220
1496 LINXY(__NR_fcntl64, sys_fcntl64), // 221
1497 // GENX_(222, sys_ni_syscall), // 222
1498 // PLAXY(223, sys_syscall223), // 223 // sys_bproc?
1499 LINX_(__NR_gettid, sys_gettid), // 224
1501 //zz // (__NR_readahead, sys_readahead), // 225 */(Linux?)
1502 LINX_(__NR_setxattr, sys_setxattr), // 226
1503 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227
1504 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228
1505 LINXY(__NR_getxattr, sys_getxattr), // 229
1507 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230
1508 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231
1509 LINXY(__NR_listxattr, sys_listxattr), // 232
1510 LINXY(__NR_llistxattr, sys_llistxattr), // 233
1511 LINXY(__NR_flistxattr, sys_flistxattr), // 234
1513 LINX_(__NR_removexattr, sys_removexattr), // 235
1514 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236
1515 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237
1516 LINXY(__NR_tkill, sys_tkill), // 238 */Linux
1517 LINXY(__NR_sendfile64, sys_sendfile64), // 239
1519 LINXY(__NR_futex, sys_futex), // 240
1520 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1521 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1522 // PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
1523 // PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
1525 LINXY(__NR_io_setup, sys_io_setup), // 245
1526 LINX_(__NR_io_destroy, sys_io_destroy), // 246
1527 LINXY(__NR_io_getevents, sys_io_getevents), // 247
1528 LINX_(__NR_io_submit, sys_io_submit), // 248
1529 LINXY(__NR_io_cancel, sys_io_cancel), // 249
1531 // LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
1532 GENX_(251, sys_ni_syscall), // 251
1533 LINX_(__NR_exit_group, sys_exit_group), // 252
1534 // GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
1535 LINXY(__NR_epoll_create, sys_epoll_create), // 254
1537 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
1538 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
1539 //zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
1540 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258
1541 LINXY(__NR_timer_create, sys_timer_create), // 259
1543 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
1544 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
1545 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
1546 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
1547 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
1549 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6)
1550 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
1551 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
1552 GENXY(__NR_statfs64, sys_statfs64), // 268
1553 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
1555 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
1556 GENX_(__NR_utimes, sys_utimes), // 271
1557 // LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?)
1558 GENX_(__NR_vserver, sys_ni_syscall), // 273
1559 LINX_(__NR_mbind, sys_mbind), // 274 ?/?
1561 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
1562 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
1563 LINXY(__NR_mq_open, sys_mq_open), // 277
1564 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
1565 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
1567 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
1568 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
1569 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
1570 LINXY(__NR_waitid, sys_waitid), // 280
1572 PLAXY(__NR_socket, sys_socket), // 281
1573 PLAX_(__NR_bind, sys_bind), // 282
1574 PLAX_(__NR_connect, sys_connect), // 283
1575 PLAX_(__NR_listen, sys_listen), // 284
1576 PLAXY(__NR_accept, sys_accept), // 285
1577 PLAXY(__NR_getsockname, sys_getsockname), // 286
1578 PLAXY(__NR_getpeername, sys_getpeername), // 287
1579 PLAXY(__NR_socketpair, sys_socketpair), // 288
1580 PLAX_(__NR_send, sys_send),
1581 PLAX_(__NR_sendto, sys_sendto), // 290
1582 PLAXY(__NR_recv, sys_recv),
1583 PLAXY(__NR_recvfrom, sys_recvfrom), // 292
1584 PLAX_(__NR_shutdown, sys_shutdown), // 293
1585 PLAX_(__NR_setsockopt, sys_setsockopt), // 294
1586 PLAXY(__NR_getsockopt, sys_getsockopt), // 295
1587 PLAX_(__NR_sendmsg, sys_sendmsg), // 296
1588 PLAXY(__NR_recvmsg, sys_recvmsg), // 297
1589 PLAX_(__NR_semop, sys_semop), // 298
1590 PLAX_(__NR_semget, sys_semget), // 299
1591 PLAXY(__NR_semctl, sys_semctl), // 300
1592 PLAX_(__NR_msgget, sys_msgget),
1593 PLAX_(__NR_msgsnd, sys_msgsnd),
1594 PLAXY(__NR_msgrcv, sys_msgrcv),
1595 PLAXY(__NR_msgctl, sys_msgctl), // 304
1596 PLAX_(__NR_semtimedop, sys_semtimedop), // 312
1598 LINX_(__NR_add_key, sys_add_key), // 286
1599 LINX_(__NR_request_key, sys_request_key), // 287
1600 LINXY(__NR_keyctl, sys_keyctl), // not 288...
1601 // LINX_(__NR_ioprio_set, sys_ioprio_set), // 289
1603 // LINX_(__NR_ioprio_get, sys_ioprio_get), // 290
1604 LINX_(__NR_inotify_init, sys_inotify_init), // 291
1605 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1606 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293
1607 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 294
1609 LINXY(__NR_openat, sys_openat), // 295
1610 LINX_(__NR_mkdirat, sys_mkdirat), // 296
1611 LINX_(__NR_mknodat, sys_mknodat), // 297
1612 LINX_(__NR_fchownat, sys_fchownat), // 298
1613 LINX_(__NR_futimesat, sys_futimesat), // 326 on arm
1615 PLAXY(__NR_fstatat64, sys_fstatat64), // 300
1616 LINX_(__NR_unlinkat, sys_unlinkat), // 301
1617 LINX_(__NR_renameat, sys_renameat), // 302
1618 LINX_(__NR_linkat, sys_linkat), // 303
1619 LINX_(__NR_symlinkat, sys_symlinkat), // 304
1621 LINX_(__NR_readlinkat, sys_readlinkat), //
1622 LINX_(__NR_fchmodat, sys_fchmodat), //
1623 LINX_(__NR_faccessat, sys_faccessat), //
1624 PLAXY(__NR_shmat, wrap_sys_shmat), //305
1625 PLAXY(__NR_shmdt, sys_shmdt), //306
1626 PLAX_(__NR_shmget, sys_shmget), //307
1627 PLAXY(__NR_shmctl, sys_shmctl), // 308
1628 // LINX_(__NR_pselect6, sys_pselect6), //
1629 // LINXY(__NR_ppoll, sys_ppoll), // 309
1631 // LINX_(__NR_unshare, sys_unshare), // 310
1632 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311
1633 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312
1634 // LINX_(__NR_splice, sys_ni_syscall), // 313
1635 // LINX_(__NR_sync_file_range, sys_sync_file_range), // 314
1637 // LINX_(__NR_tee, sys_ni_syscall), // 315
1638 // LINX_(__NR_vmsplice, sys_ni_syscall), // 316
1639 // LINX_(__NR_move_pages, sys_ni_syscall), // 317
1640 // LINX_(__NR_getcpu, sys_ni_syscall), // 318
1641 // LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 319
1643 LINX_(__NR_utimensat, sys_utimensat), // 320
1644 LINXY(__NR_signalfd, sys_signalfd), // 321
1645 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322
1646 LINX_(__NR_eventfd, sys_eventfd), // 323
1647 // LINX_(__NR_fallocate, sys_ni_syscall), // 324
1648 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325
1649 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326
1653 // JRS 2010-Jan-03: I believe that all the numbers listed
1654 // in comments in the table prior to this point (eg "// 326",
1655 // etc) are bogus since it looks to me like they are copied
1656 // verbatim from syswrap-x86-linux.c and they certainly do not
1657 // correspond to what's in include/vki/vki-scnums-arm-linux.h.
1658 // From here onwards, please ensure the numbers are correct.
1660 LINXY(__NR_signalfd4, sys_signalfd4), // 355
1661 LINX_(__NR_eventfd2, sys_eventfd2), // 356
1663 LINXY(__NR_pipe2, sys_pipe2) // 359
1667 /* These are not in the main table because there indexes are not small
1668 integers, but rather values close to one million. So their
1669 inclusion would force the main table to be huge (about 8 MB). */
1671 static SyscallTableEntry ste___ARM_set_tls
1672 = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
1674 static SyscallTableEntry ste___ARM_cacheflush
1675 = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
1677 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1679 const UInt syscall_main_table_size
1680 = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
1682 /* Is it in the contiguous initial section of the table? */
1683 if (sysno < syscall_main_table_size) {
1684 SyscallTableEntry* sys = &syscall_main_table[sysno];
1685 if (sys->before == NULL)
1686 return NULL; /* no entry */
1691 /* Check if it's one of the out-of-line entries. */
1693 case __NR_ARM_set_tls: return &ste___ARM_set_tls;
1694 case __NR_ARM_cacheflush: return &ste___ARM_cacheflush;
1698 /* Can't find a wrapper */
1702 #endif // defined(VGP_arm_linux)
1704 /*--------------------------------------------------------------------*/
1705 /*--- end syswrap-arm-linux.c ---*/
1706 /*--------------------------------------------------------------------*/