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