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