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