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-2013 Nicholas Nethercote
11 njn@valgrind.org
12 Copyright (C) 2008-2013 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_transtab.h" // VG_(discard_translations)
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))
69 void 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
77 asm(
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
105 extern
106 ULong 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 );
113 asm(
114 ".text\n"
115 ".globl do_syscall_clone_arm_linux\n"
116 "do_syscall_clone_arm_linux:\n"
117
118 /*Setup child stack */
119 " str r0, [r1, #-4]!\n"
120 " str r3, [r1, #-4]!\n"
121 " push {r4,r7}\n"
122 " mov r0, r2\n" /* arg1: flags */
123 /* r1 (arg2) is already our child's stack */
124 " ldr r2, [sp, #12]\n" // parent tid
125 " ldr r3, [sp, #16]\n" // tls
126 " ldr r4, [sp, #8]\n" // Child tid
127 " mov r7, #"__NR_CLONE"\n"
128 " svc 0x00000000\n"
129 " cmp r0, #0\n"
130 " beq 1f\n"
131
132 /* Parent */
133 " pop {r4,r7}\n"
134 " bx lr\n"
135
136 "1:\n" /*child*/
137 " mov lr, pc\n"
138 " pop {r0,pc}\n"
139 /* Retval from child is already in r0 */
140 " mov r7, #"__NR_EXIT"\n"
141 " svc 0x00000000\n"
142 /* Urh.. why did exit return? */
143 " .long 0\n"
144 " .previous\n"
145 );
146
147 #undef __NR_CLONE
148 #undef __NR_EXIT
149
150 // forward declarations
151 static void setup_child ( ThreadArchState*, ThreadArchState* );
152 static void assign_guest_tls(ThreadId ctid, Addr tlsptr);
153 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
154
155 /*
156 When a client clones, we need to keep track of the new thread. This means:
157 1. allocate a ThreadId+ThreadState+stack for the the thread
158
159 2. initialize the thread's new VCPU state
160
161 3. create the thread using the same args as the client requested,
162 but using the scheduler entrypoint for IP, and a separate stack
163 for SP.
164 */
do_clone(ThreadId ptid,UInt flags,Addr sp,Int * parent_tidptr,Int * child_tidptr,Addr child_tls)165 static SysRes do_clone ( ThreadId ptid,
166 UInt flags, Addr sp,
167 Int *parent_tidptr,
168 Int *child_tidptr,
169 Addr child_tls)
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 SysRes res;
177 vki_sigset_t blockall, savedmask;
178
179 VG_(sigfillset)(&blockall);
180
181 vg_assert(VG_(is_running_thread)(ptid));
182 vg_assert(VG_(is_valid_tid)(ctid));
183
184 stack = (UWord*)ML_(allocstack)(ctid);
185
186 if(stack == NULL) {
187 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
188 goto out;
189 }
190
191 setup_child( &ctst->arch, &ptst->arch );
192
193 ctst->arch.vex.guest_R0 = 0;
194 if(sp != 0)
195 ctst->arch.vex.guest_R13 = sp;
196
197 ctst->os_state.parent = ptid;
198
199 ctst->sig_mask = ptst->sig_mask;
200 ctst->tmp_sig_mask = ptst->sig_mask;
201
202 /* Start the child with its threadgroup being the same as the
203 parent's. This is so that any exit_group calls that happen
204 after the child is created but before it sets its
205 os_state.threadgroup field for real (in thread_wrapper in
206 syswrap-linux.c), really kill the new thread. a.k.a this avoids
207 a race condition in which the thread is unkillable (via
208 exit_group) because its threadgroup is not set. The race window
209 is probably only a few hundred or a few thousand cycles long.
210 See #226116. */
211 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
212
213 ML_(guess_and_register_stack) (sp, ctst);
214
215 vg_assert(VG_(owns_BigLock_LL)(ptid));
216 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
217
218 if (flags & VKI_CLONE_SETTLS) {
219 /* Just assign the tls pointer in the guest TPIDRURO. */
220 assign_guest_tls(ctid, child_tls);
221 }
222
223 flags &= ~VKI_CLONE_SETTLS;
224
225 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
226
227 r0 = do_syscall_clone_arm_linux(
228 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
229 child_tidptr, parent_tidptr, NULL
230 );
231 //VG_(printf)("AFTER SYSCALL, %x and %x CHILD: %d PARENT: %d\n",child_tidptr, parent_tidptr,*child_tidptr,*parent_tidptr);
232
233 res = VG_(mk_SysRes_arm_linux)( r0 );
234
235 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
236
237 out:
238 if (sr_isError(res)) {
239 VG_(cleanup_thread)(&ctst->arch);
240 ctst->status = VgTs_Empty;
241 VG_TRACK( pre_thread_ll_exit, ctid );
242 }
243
244 return res;
245 }
246
247
248
249 /* ---------------------------------------------------------------------
250 More thread stuff
251 ------------------------------------------------------------------ */
252
253 // ARM doesn't have any architecture specific thread stuff that
254 // needs to be cleaned up
VG_(cleanup_thread)255 void VG_(cleanup_thread) ( ThreadArchState* arch )
256 {
257 }
258
setup_child(ThreadArchState * child,ThreadArchState * parent)259 void setup_child ( /*OUT*/ ThreadArchState *child,
260 /*IN*/ ThreadArchState *parent )
261 {
262 child->vex = parent->vex;
263 child->vex_shadow1 = parent->vex_shadow1;
264 child->vex_shadow2 = parent->vex_shadow2;
265 }
266
assign_guest_tls(ThreadId tid,Addr tlsptr)267 static void assign_guest_tls(ThreadId tid, Addr tlsptr)
268 {
269 VG_(threads)[tid].arch.vex.guest_TPIDRURO = tlsptr;
270 }
271
272 /* Assigns tlsptr to the guest TPIDRURO.
273 If needed for the specific hardware, really executes
274 the set_tls syscall.
275 */
sys_set_tls(ThreadId tid,Addr tlsptr)276 static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
277 {
278 assign_guest_tls(tid, tlsptr);
279
280 if (KernelVariantiS(KernelVariant_android_no_hw_tls,
281 VG_(clo_kernel_variant))) {
282 /* Android emulator does not provide an hw tls register.
283 So, the tls register is emulated by the kernel.
284 This emulated value is set by the __NR_ARM_set_tls syscall.
285 The emulated value must be read by the kernel helper function
286 located at 0xffff0fe0.
287
288 The emulated tlsptr is located at 0xffff0ff0
289 (so slightly after the kernel helper function).
290 Note that applications are not supposed to read this directly.
291
292 For compatibility : if there is a hw tls register, the kernel
293 will put at 0xffff0fe0 the instructions to read it, so
294 as to have old applications calling the kernel helper
295 working properly.
296
297 For having emulated guest TLS working correctly with
298 Valgrind, it is needed to execute the syscall to set
299 the emulated TLS value in addition to the assignment
300 of TPIDRURO.
301
302 Note: the below means that if we need thread local storage
303 for Valgrind host, then there will be a conflict between
304 the need of the guest tls and of the host tls.
305 If all the guest code would cleanly call 0xffff0fe0,
306 then we might maybe intercept this. However, at least
307 __libc_preinit reads directly 0xffff0ff0.
308 */
309 /* ??? might call the below if auxv->u.a_val & VKI_HWCAP_TLS ???
310 Unclear if real hardware having tls hw register sets
311 VKI_HWCAP_TLS. */
312 return VG_(do_syscall1) (__NR_ARM_set_tls, tlsptr);
313 } else {
314 return VG_(mk_SysRes_Success)( 0 );
315 }
316 }
317
318 /* ---------------------------------------------------------------------
319 PRE/POST wrappers for arm/Linux-specific syscalls
320 ------------------------------------------------------------------ */
321
322 #define PRE(name) DEFN_PRE_TEMPLATE(arm_linux, name)
323 #define POST(name) DEFN_POST_TEMPLATE(arm_linux, name)
324
325 /* Add prototypes for the wrappers declared here, so that gcc doesn't
326 harass us for not having prototypes. Really this is a kludge --
327 the right thing to do is to make these wrappers 'static' since they
328 aren't visible outside this file, but that requires even more macro
329 magic. */
330
331 DECL_TEMPLATE(arm_linux, sys_mmap2);
332 DECL_TEMPLATE(arm_linux, sys_stat64);
333 DECL_TEMPLATE(arm_linux, sys_lstat64);
334 DECL_TEMPLATE(arm_linux, sys_fstatat64);
335 DECL_TEMPLATE(arm_linux, sys_fstat64);
336 DECL_TEMPLATE(arm_linux, sys_clone);
337 DECL_TEMPLATE(arm_linux, sys_sigreturn);
338 DECL_TEMPLATE(arm_linux, sys_rt_sigreturn);
339 DECL_TEMPLATE(arm_linux, sys_sigsuspend);
340 DECL_TEMPLATE(arm_linux, sys_set_tls);
341 DECL_TEMPLATE(arm_linux, sys_cacheflush);
342 DECL_TEMPLATE(arm_linux, sys_ptrace);
343
PRE(sys_mmap2)344 PRE(sys_mmap2)
345 {
346 SysRes r;
347
348 // Exactly like old_mmap() except:
349 // - all 6 args are passed in regs, rather than in a memory-block.
350 // - the file offset is specified in pagesize units rather than bytes,
351 // so that it can be used for files bigger than 2^32 bytes.
352 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is
353 // 4K-sized. Assert that the page size is 4K here for safety.
354 vg_assert(VKI_PAGE_SIZE == 4096);
355 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
356 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
357 PRE_REG_READ6(long, "mmap2",
358 unsigned long, start, unsigned long, length,
359 unsigned long, prot, unsigned long, flags,
360 unsigned long, fd, unsigned long, offset);
361
362 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
363 4096 * (Off64T)ARG6 );
364 SET_STATUS_from_SysRes(r);
365 }
366
367 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
368 // applicable to every architecture -- I think only to 32-bit archs.
369 // We're going to need something like linux/core_os32.h for such
370 // things, eventually, I think. --njn
PRE(sys_lstat64)371 PRE(sys_lstat64)
372 {
373 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
374 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
375 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
376 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
377 }
378
POST(sys_lstat64)379 POST(sys_lstat64)
380 {
381 vg_assert(SUCCESS);
382 if (RES == 0) {
383 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
384 }
385 }
386
PRE(sys_stat64)387 PRE(sys_stat64)
388 {
389 PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
390 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
391 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
392 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
393 }
394
POST(sys_stat64)395 POST(sys_stat64)
396 {
397 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
398 }
399
PRE(sys_fstatat64)400 PRE(sys_fstatat64)
401 {
402 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
403 PRE_REG_READ3(long, "fstatat64",
404 int, dfd, char *, file_name, struct stat64 *, buf);
405 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
406 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
407 }
408
POST(sys_fstatat64)409 POST(sys_fstatat64)
410 {
411 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
412 }
413
PRE(sys_fstat64)414 PRE(sys_fstat64)
415 {
416 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
417 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
418 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
419 }
420
POST(sys_fstat64)421 POST(sys_fstat64)
422 {
423 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
424 }
425
PRE(sys_clone)426 PRE(sys_clone)
427 {
428 UInt cloneflags;
429
430 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
431 PRE_REG_READ5(int, "clone",
432 unsigned long, flags,
433 void *, child_stack,
434 int *, parent_tidptr,
435 void *, child_tls,
436 int *, child_tidptr);
437
438 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
439 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
440 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
441 VKI_PROT_WRITE)) {
442 SET_STATUS_Failure( VKI_EFAULT );
443 return;
444 }
445 }
446 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
447 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
448 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
449 VKI_PROT_WRITE)) {
450 SET_STATUS_Failure( VKI_EFAULT );
451 return;
452 }
453 }
454 if (ARG1 & VKI_CLONE_SETTLS) {
455 PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
456 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
457 VKI_PROT_READ)) {
458 SET_STATUS_Failure( VKI_EFAULT );
459 return;
460 }
461 }
462
463 cloneflags = ARG1;
464
465 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
466 SET_STATUS_Failure( VKI_EINVAL );
467 return;
468 }
469
470 /* Only look at the flags we really care about */
471 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
472 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
473 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
474 /* thread creation */
475 SET_STATUS_from_SysRes(
476 do_clone(tid,
477 ARG1, /* flags */
478 (Addr)ARG2, /* child ESP */
479 (Int *)ARG3, /* parent_tidptr */
480 (Int *)ARG5, /* child_tidptr */
481 (Addr)ARG4)); /* set_tls */
482 break;
483
484 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
485 /* FALLTHROUGH - assume vfork == fork */
486 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
487
488 case 0: /* plain fork */
489 SET_STATUS_from_SysRes(
490 ML_(do_fork_clone)(tid,
491 cloneflags, /* flags */
492 (Int *)ARG3, /* parent_tidptr */
493 (Int *)ARG5)); /* child_tidptr */
494 break;
495
496 default:
497 /* should we just ENOSYS? */
498 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
499 VG_(message)(Vg_UserMsg, "\n");
500 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
501 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
502 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
503 VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver\n");
504 VG_(unimplemented)
505 ("Valgrind does not support general clone().");
506 }
507
508 if (SUCCESS) {
509 if (ARG1 & VKI_CLONE_PARENT_SETTID)
510 POST_MEM_WRITE(ARG3, sizeof(Int));
511 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
512 POST_MEM_WRITE(ARG5, sizeof(Int));
513
514 /* Thread creation was successful; let the child have the chance
515 to run */
516 *flags |= SfYieldAfter;
517 }
518 }
519
PRE(sys_sigreturn)520 PRE(sys_sigreturn)
521 {
522 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
523 an explanation of what follows. */
524
525 PRINT("sys_sigreturn ( )");
526
527 vg_assert(VG_(is_valid_tid)(tid));
528 vg_assert(tid >= 1 && tid < VG_N_THREADS);
529 vg_assert(VG_(is_running_thread)(tid));
530
531 /* Restore register state from frame and remove it */
532 VG_(sigframe_destroy)(tid, False);
533
534 /* Tell the driver not to update the guest state with the "result",
535 and set a bogus result to keep it happy. */
536 *flags |= SfNoWriteResult;
537 SET_STATUS_Success(0);
538
539 /* Check to see if any signals arose as a result of this. */
540 *flags |= SfPollAfter;
541 }
542
PRE(sys_rt_sigreturn)543 PRE(sys_rt_sigreturn)
544 {
545 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
546 an explanation of what follows. */
547
548 PRINT("rt_sigreturn ( )");
549
550 vg_assert(VG_(is_valid_tid)(tid));
551 vg_assert(tid >= 1 && tid < VG_N_THREADS);
552 vg_assert(VG_(is_running_thread)(tid));
553
554 /* Restore register state from frame and remove it */
555 VG_(sigframe_destroy)(tid, True);
556
557 /* Tell the driver not to update the guest state with the "result",
558 and set a bogus result to keep it happy. */
559 *flags |= SfNoWriteResult;
560 SET_STATUS_Success(0);
561
562 /* Check to see if any signals arose as a result of this. */
563 *flags |= SfPollAfter;
564 }
565
566 /* NB: clone of x86-linux version, and ppc32-linux has an almost
567 identical one. */
PRE(sys_sigsuspend)568 PRE(sys_sigsuspend)
569 {
570 /* The C library interface to sigsuspend just takes a pointer to
571 a signal mask but this system call has three arguments - the first
572 two don't appear to be used by the kernel and are always passed as
573 zero by glibc and the third is the first word of the signal mask
574 so only 32 signals are supported.
575
576 In fact glibc normally uses rt_sigsuspend if it is available as
577 that takes a pointer to the signal mask so supports more signals.
578 */
579 *flags |= SfMayBlock;
580 PRINT("sys_sigsuspend ( %ld, %ld, %ld )", ARG1,ARG2,ARG3 );
581 PRE_REG_READ3(int, "sigsuspend",
582 int, history0, int, history1,
583 vki_old_sigset_t, mask);
584 }
585
586 /* Very much ARM specific */
587
PRE(sys_set_tls)588 PRE(sys_set_tls)
589 {
590 PRINT("set_tls (%lx)",ARG1);
591 PRE_REG_READ1(long, "set_tls", unsigned long, addr);
592
593 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
594 }
595
PRE(sys_cacheflush)596 PRE(sys_cacheflush)
597 {
598 PRINT("cacheflush (%lx, %#lx, %#lx)",ARG1,ARG2,ARG3);
599 PRE_REG_READ3(long, "cacheflush", void*, addrlow,void*, addrhigh,int, flags);
600 VG_(discard_translations)( (Addr)ARG1,
601 ((ULong)ARG2) - ((ULong)ARG1) + 1ULL/*paranoia*/,
602 "PRE(sys_cacheflush)" );
603 SET_STATUS_Success(0);
604 }
605
606 // ARG3 is only used for pointers into the traced process's address
607 // space and for offsets into the traced process's struct
608 // user_regs_struct. It is never a pointer into this process's memory
609 // space, and we should therefore not check anything it points to.
PRE(sys_ptrace)610 PRE(sys_ptrace)
611 {
612 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
613 PRE_REG_READ4(int, "ptrace",
614 long, request, long, pid, long, addr, long, data);
615 switch (ARG1) {
616 case VKI_PTRACE_PEEKTEXT:
617 case VKI_PTRACE_PEEKDATA:
618 case VKI_PTRACE_PEEKUSR:
619 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
620 sizeof (long));
621 break;
622 case VKI_PTRACE_GETREGS:
623 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
624 sizeof (struct vki_user_regs_struct));
625 break;
626 case VKI_PTRACE_GETFPREGS:
627 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
628 sizeof (struct vki_user_fp));
629 break;
630 case VKI_PTRACE_GETWMMXREGS:
631 PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4,
632 VKI_IWMMXT_SIZE);
633 break;
634 case VKI_PTRACE_GETCRUNCHREGS:
635 PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4,
636 VKI_CRUNCH_SIZE);
637 break;
638 case VKI_PTRACE_GETVFPREGS:
639 PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4,
640 sizeof (struct vki_user_vfp) );
641 break;
642 case VKI_PTRACE_GETHBPREGS:
643 PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4,
644 sizeof (unsigned long) );
645 break;
646 case VKI_PTRACE_SETREGS:
647 PRE_MEM_READ( "ptrace(setregs)", ARG4,
648 sizeof (struct vki_user_regs_struct));
649 break;
650 case VKI_PTRACE_SETFPREGS:
651 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
652 sizeof (struct vki_user_fp));
653 break;
654 case VKI_PTRACE_SETWMMXREGS:
655 PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4,
656 VKI_IWMMXT_SIZE);
657 break;
658 case VKI_PTRACE_SETCRUNCHREGS:
659 PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4,
660 VKI_CRUNCH_SIZE);
661 break;
662 case VKI_PTRACE_SETVFPREGS:
663 PRE_MEM_READ( "ptrace(setvfpregs)", ARG4,
664 sizeof (struct vki_user_vfp));
665 break;
666 case VKI_PTRACE_SETHBPREGS:
667 PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long));
668 break;
669 case VKI_PTRACE_GET_THREAD_AREA:
670 PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long));
671 break;
672 case VKI_PTRACE_GETEVENTMSG:
673 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
674 break;
675 case VKI_PTRACE_GETSIGINFO:
676 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
677 break;
678 case VKI_PTRACE_SETSIGINFO:
679 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
680 break;
681 case VKI_PTRACE_GETREGSET:
682 ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
683 break;
684 case VKI_PTRACE_SETREGSET:
685 ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
686 break;
687 default:
688 break;
689 }
690 }
691
POST(sys_ptrace)692 POST(sys_ptrace)
693 {
694 switch (ARG1) {
695 case VKI_PTRACE_PEEKTEXT:
696 case VKI_PTRACE_PEEKDATA:
697 case VKI_PTRACE_PEEKUSR:
698 POST_MEM_WRITE( ARG4, sizeof (long));
699 break;
700 case VKI_PTRACE_GETREGS:
701 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
702 break;
703 case VKI_PTRACE_GETFPREGS:
704 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp));
705 break;
706 case VKI_PTRACE_GETWMMXREGS:
707 POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE);
708 break;
709 case VKI_PTRACE_GETCRUNCHREGS:
710 POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE);
711 break;
712 case VKI_PTRACE_GETVFPREGS:
713 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp));
714 break;
715 case VKI_PTRACE_GET_THREAD_AREA:
716 case VKI_PTRACE_GETHBPREGS:
717 case VKI_PTRACE_GETEVENTMSG:
718 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
719 break;
720 case VKI_PTRACE_GETSIGINFO:
721 /* XXX: This is a simplification. Different parts of the
722 * siginfo_t are valid depending on the type of signal.
723 */
724 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
725 break;
726 case VKI_PTRACE_GETREGSET:
727 ML_(linux_POST_getregset)(tid, ARG3, ARG4);
728 break;
729 default:
730 break;
731 }
732 }
733
734 #undef PRE
735 #undef POST
736
737 /* ---------------------------------------------------------------------
738 The arm/Linux syscall table
739 ------------------------------------------------------------------ */
740
741 #if 0
742 #define __NR_OABI_SYSCALL_BASE 0x900000
743 #else
744 #define __NR_OABI_SYSCALL_BASE 0x0
745 #endif
746
747 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(arm_linux, sysno, name)
748 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(arm_linux, sysno, name)
749
750 // This table maps from __NR_xxx syscall numbers (from
751 // linux/include/asm-arm/unistd.h) to the appropriate PRE/POST sys_foo()
752 // wrappers on arm (as per sys_call_table in linux/arch/arm/kernel/entry.S).
753 //
754 // For those syscalls not handled by Valgrind, the annotation indicate its
755 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
756 // (unknown).
757
758 static SyscallTableEntry syscall_main_table[] = {
759 //zz // (restart_syscall) // 0
760 GENX_(__NR_exit, sys_exit), // 1
761 GENX_(__NR_fork, sys_fork), // 2
762 GENXY(__NR_read, sys_read), // 3
763 GENX_(__NR_write, sys_write), // 4
764
765 GENXY(__NR_open, sys_open), // 5
766 GENXY(__NR_close, sys_close), // 6
767 // GENXY(__NR_waitpid, sys_waitpid), // 7
768 GENXY(__NR_creat, sys_creat), // 8
769 GENX_(__NR_link, sys_link), // 9
770
771 GENX_(__NR_unlink, sys_unlink), // 10
772 GENX_(__NR_execve, sys_execve), // 11
773 GENX_(__NR_chdir, sys_chdir), // 12
774 GENXY(__NR_time, sys_time), // 13
775 GENX_(__NR_mknod, sys_mknod), // 14
776
777 GENX_(__NR_chmod, sys_chmod), // 15
778 //zz LINX_(__NR_lchown, sys_lchown16), // 16
779 // GENX_(__NR_break, sys_ni_syscall), // 17
780 //zz // (__NR_oldstat, sys_stat), // 18 (obsolete)
781 LINX_(__NR_lseek, sys_lseek), // 19
782
783 GENX_(__NR_getpid, sys_getpid), // 20
784 LINX_(__NR_mount, sys_mount), // 21
785 LINX_(__NR_umount, sys_oldumount), // 22
786 LINX_(__NR_setuid, sys_setuid16), // 23 ## P
787 LINX_(__NR_getuid, sys_getuid16), // 24 ## P
788 //zz
789 //zz // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
790 PLAXY(__NR_ptrace, sys_ptrace), // 26
791 GENX_(__NR_alarm, sys_alarm), // 27
792 //zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
793 GENX_(__NR_pause, sys_pause), // 29
794
795 LINX_(__NR_utime, sys_utime), // 30
796 // GENX_(__NR_stty, sys_ni_syscall), // 31
797 // GENX_(__NR_gtty, sys_ni_syscall), // 32
798 GENX_(__NR_access, sys_access), // 33
799 GENX_(__NR_nice, sys_nice), // 34
800
801 // GENX_(__NR_ftime, sys_ni_syscall), // 35
802 GENX_(__NR_sync, sys_sync), // 36
803 GENX_(__NR_kill, sys_kill), // 37
804 GENX_(__NR_rename, sys_rename), // 38
805 GENX_(__NR_mkdir, sys_mkdir), // 39
806
807 GENX_(__NR_rmdir, sys_rmdir), // 40
808 GENXY(__NR_dup, sys_dup), // 41
809 LINXY(__NR_pipe, sys_pipe), // 42
810 GENXY(__NR_times, sys_times), // 43
811 // GENX_(__NR_prof, sys_ni_syscall), // 44
812 //zz
813 GENX_(__NR_brk, sys_brk), // 45
814 LINX_(__NR_setgid, sys_setgid16), // 46
815 LINX_(__NR_getgid, sys_getgid16), // 47
816 //zz // (__NR_signal, sys_signal), // 48 */* (ANSI C)
817 LINX_(__NR_geteuid, sys_geteuid16), // 49
818
819 LINX_(__NR_getegid, sys_getegid16), // 50
820 GENX_(__NR_acct, sys_acct), // 51
821 LINX_(__NR_umount2, sys_umount), // 52
822 // GENX_(__NR_lock, sys_ni_syscall), // 53
823 LINXY(__NR_ioctl, sys_ioctl), // 54
824
825 LINXY(__NR_fcntl, sys_fcntl), // 55
826 // GENX_(__NR_mpx, sys_ni_syscall), // 56
827 GENX_(__NR_setpgid, sys_setpgid), // 57
828 // GENX_(__NR_ulimit, sys_ni_syscall), // 58
829 //zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
830 //zz
831 GENX_(__NR_umask, sys_umask), // 60
832 GENX_(__NR_chroot, sys_chroot), // 61
833 //zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
834 GENXY(__NR_dup2, sys_dup2), // 63
835 GENX_(__NR_getppid, sys_getppid), // 64
836
837 GENX_(__NR_getpgrp, sys_getpgrp), // 65
838 GENX_(__NR_setsid, sys_setsid), // 66
839 LINXY(__NR_sigaction, sys_sigaction), // 67
840 //zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
841 //zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
842 //zz
843 LINX_(__NR_setreuid, sys_setreuid16), // 70
844 LINX_(__NR_setregid, sys_setregid16), // 71
845 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72
846 LINXY(__NR_sigpending, sys_sigpending), // 73
847 //zz // (__NR_sethostname, sys_sethostname), // 74 */*
848 //zz
849 GENX_(__NR_setrlimit, sys_setrlimit), // 75
850 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
851 GENXY(__NR_getrusage, sys_getrusage), // 77
852 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
853 GENX_(__NR_settimeofday, sys_settimeofday), // 79
854
855 LINXY(__NR_getgroups, sys_getgroups16), // 80
856 LINX_(__NR_setgroups, sys_setgroups16), // 81
857 // PLAX_(__NR_select, old_select), // 82
858 GENX_(__NR_symlink, sys_symlink), // 83
859 //zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
860 //zz
861 GENX_(__NR_readlink, sys_readlink), // 85
862 //zz // (__NR_uselib, sys_uselib), // 86 */Linux
863 //zz // (__NR_swapon, sys_swapon), // 87 */Linux
864 //zz // (__NR_reboot, sys_reboot), // 88 */Linux
865 //zz // (__NR_readdir, old_readdir), // 89 -- superseded
866 //zz
867 // _____(__NR_mmap, old_mmap), // 90
868 GENXY(__NR_munmap, sys_munmap), // 91
869 GENX_(__NR_truncate, sys_truncate), // 92
870 GENX_(__NR_ftruncate, sys_ftruncate), // 93
871 GENX_(__NR_fchmod, sys_fchmod), // 94
872
873 LINX_(__NR_fchown, sys_fchown16), // 95
874 GENX_(__NR_getpriority, sys_getpriority), // 96
875 GENX_(__NR_setpriority, sys_setpriority), // 97
876 // GENX_(__NR_profil, sys_ni_syscall), // 98
877 GENXY(__NR_statfs, sys_statfs), // 99
878
879 GENXY(__NR_fstatfs, sys_fstatfs), // 100
880 // LINX_(__NR_ioperm, sys_ioperm), // 101
881 LINXY(__NR_socketcall, sys_socketcall), // 102
882 LINXY(__NR_syslog, sys_syslog), // 103
883 GENXY(__NR_setitimer, sys_setitimer), // 104
884
885 GENXY(__NR_getitimer, sys_getitimer), // 105
886 GENXY(__NR_stat, sys_newstat), // 106
887 GENXY(__NR_lstat, sys_newlstat), // 107
888 GENXY(__NR_fstat, sys_newfstat), // 108
889 //zz // (__NR_olduname, sys_uname), // 109 -- obsolete
890 //zz
891 // GENX_(__NR_iopl, sys_iopl), // 110
892 LINX_(__NR_vhangup, sys_vhangup), // 111
893 // GENX_(__NR_idle, sys_ni_syscall), // 112
894 // PLAXY(__NR_vm86old, sys_vm86old), // 113 __NR_syscall... weird
895 GENXY(__NR_wait4, sys_wait4), // 114
896 //zz
897 //zz // (__NR_swapoff, sys_swapoff), // 115 */Linux
898 LINXY(__NR_sysinfo, sys_sysinfo), // 116
899 // _____(__NR_ipc, sys_ipc), // 117
900 GENX_(__NR_fsync, sys_fsync), // 118
901 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
902
903 PLAX_(__NR_clone, sys_clone), // 120
904 //zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
905 GENXY(__NR_uname, sys_newuname), // 122
906 // PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
907 //zz LINXY(__NR_adjtimex, sys_adjtimex), // 124
908 //zz
909 GENXY(__NR_mprotect, sys_mprotect), // 125
910 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
911 //zz // Nb: create_module() was removed 2.4-->2.6
912 // GENX_(__NR_create_module, sys_ni_syscall), // 127
913 LINX_(__NR_init_module, sys_init_module), // 128
914 LINX_(__NR_delete_module, sys_delete_module), // 129
915 //zz
916 //zz // Nb: get_kernel_syms() was removed 2.4-->2.6
917 // GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
918 LINX_(__NR_quotactl, sys_quotactl), // 131
919 GENX_(__NR_getpgid, sys_getpgid), // 132
920 GENX_(__NR_fchdir, sys_fchdir), // 133
921 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux
922 //zz
923 //zz // (__NR_sysfs, sys_sysfs), // 135 SVr4
924 LINX_(__NR_personality, sys_personality), // 136
925 // GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
926 LINX_(__NR_setfsuid, sys_setfsuid16), // 138
927 LINX_(__NR_setfsgid, sys_setfsgid16), // 139
928
929 LINXY(__NR__llseek, sys_llseek), // 140
930 GENXY(__NR_getdents, sys_getdents), // 141
931 GENX_(__NR__newselect, sys_select), // 142
932 GENX_(__NR_flock, sys_flock), // 143
933 GENX_(__NR_msync, sys_msync), // 144
934
935 GENXY(__NR_readv, sys_readv), // 145
936 GENX_(__NR_writev, sys_writev), // 146
937 GENX_(__NR_getsid, sys_getsid), // 147
938 GENX_(__NR_fdatasync, sys_fdatasync), // 148
939 LINXY(__NR__sysctl, sys_sysctl), // 149
940
941 GENX_(__NR_mlock, sys_mlock), // 150
942 GENX_(__NR_munlock, sys_munlock), // 151
943 GENX_(__NR_mlockall, sys_mlockall), // 152
944 LINX_(__NR_munlockall, sys_munlockall), // 153
945 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
946
947 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
948 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
949 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
950 LINX_(__NR_sched_yield, sys_sched_yield), // 158
951 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
952
953 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
954 //zz //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161 */*
955 GENXY(__NR_nanosleep, sys_nanosleep), // 162
956 GENX_(__NR_mremap, sys_mremap), // 163
957 LINX_(__NR_setresuid, sys_setresuid16), // 164
958
959 LINXY(__NR_getresuid, sys_getresuid16), // 165
960 // PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only
961 // GENX_(__NR_query_module, sys_ni_syscall), // 167
962 GENXY(__NR_poll, sys_poll), // 168
963 //zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
964 //zz
965 LINX_(__NR_setresgid, sys_setresgid16), // 170
966 LINXY(__NR_getresgid, sys_getresgid16), // 171
967 LINXY(__NR_prctl, sys_prctl), // 172
968 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173
969 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
970
971 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
972 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
973 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177
974 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
975 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
976
977 GENXY(__NR_pread64, sys_pread64), // 180
978 GENX_(__NR_pwrite64, sys_pwrite64), // 181
979 LINX_(__NR_chown, sys_chown16), // 182
980 GENXY(__NR_getcwd, sys_getcwd), // 183
981 LINXY(__NR_capget, sys_capget), // 184
982
983 LINX_(__NR_capset, sys_capset), // 185
984 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
985 LINXY(__NR_sendfile, sys_sendfile), // 187
986 // GENXY(__NR_getpmsg, sys_getpmsg), // 188
987 // GENX_(__NR_putpmsg, sys_putpmsg), // 189
988
989 // Nb: we treat vfork as fork
990 GENX_(__NR_vfork, sys_fork), // 190
991 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
992 PLAX_(__NR_mmap2, sys_mmap2), // 192
993 GENX_(__NR_truncate64, sys_truncate64), // 193
994 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
995
996 PLAXY(__NR_stat64, sys_stat64), // 195
997 PLAXY(__NR_lstat64, sys_lstat64), // 196
998 PLAXY(__NR_fstat64, sys_fstat64), // 197
999 GENX_(__NR_lchown32, sys_lchown), // 198
1000 GENX_(__NR_getuid32, sys_getuid), // 199
1001
1002 GENX_(__NR_getgid32, sys_getgid), // 200
1003 GENX_(__NR_geteuid32, sys_geteuid), // 201
1004 GENX_(__NR_getegid32, sys_getegid), // 202
1005 GENX_(__NR_setreuid32, sys_setreuid), // 203
1006 GENX_(__NR_setregid32, sys_setregid), // 204
1007
1008 GENXY(__NR_getgroups32, sys_getgroups), // 205
1009 GENX_(__NR_setgroups32, sys_setgroups), // 206
1010 GENX_(__NR_fchown32, sys_fchown), // 207
1011 LINX_(__NR_setresuid32, sys_setresuid), // 208
1012 LINXY(__NR_getresuid32, sys_getresuid), // 209
1013
1014 LINX_(__NR_setresgid32, sys_setresgid), // 210
1015 LINXY(__NR_getresgid32, sys_getresgid), // 211
1016 GENX_(__NR_chown32, sys_chown), // 212
1017 GENX_(__NR_setuid32, sys_setuid), // 213
1018 GENX_(__NR_setgid32, sys_setgid), // 214
1019
1020 LINX_(__NR_setfsuid32, sys_setfsuid), // 215
1021 LINX_(__NR_setfsgid32, sys_setfsgid), // 216
1022 LINX_(__NR_pivot_root, sys_pivot_root), // 217
1023 GENXY(__NR_mincore, sys_mincore), // 218
1024 GENX_(__NR_madvise, sys_madvise), // 219
1025
1026 GENXY(__NR_getdents64, sys_getdents64), // 220
1027 LINXY(__NR_fcntl64, sys_fcntl64), // 221
1028 // GENX_(222, sys_ni_syscall), // 222
1029 // PLAXY(223, sys_syscall223), // 223 // sys_bproc?
1030 LINX_(__NR_gettid, sys_gettid), // 224
1031
1032 LINX_(__NR_readahead, sys_readahead), // 225 */Linux
1033 LINX_(__NR_setxattr, sys_setxattr), // 226
1034 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227
1035 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228
1036 LINXY(__NR_getxattr, sys_getxattr), // 229
1037
1038 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230
1039 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231
1040 LINXY(__NR_listxattr, sys_listxattr), // 232
1041 LINXY(__NR_llistxattr, sys_llistxattr), // 233
1042 LINXY(__NR_flistxattr, sys_flistxattr), // 234
1043
1044 LINX_(__NR_removexattr, sys_removexattr), // 235
1045 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236
1046 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237
1047 LINXY(__NR_tkill, sys_tkill), // 238 */Linux
1048 LINXY(__NR_sendfile64, sys_sendfile64), // 239
1049
1050 LINXY(__NR_futex, sys_futex), // 240
1051 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1052 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1053 // PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
1054 // PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
1055
1056 LINXY(__NR_io_setup, sys_io_setup), // 245
1057 LINX_(__NR_io_destroy, sys_io_destroy), // 246
1058 LINXY(__NR_io_getevents, sys_io_getevents), // 247
1059 LINX_(__NR_io_submit, sys_io_submit), // 248
1060 LINXY(__NR_io_cancel, sys_io_cancel), // 249
1061
1062 // LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
1063 GENX_(251, sys_ni_syscall), // 251
1064 LINX_(__NR_exit_group, sys_exit_group), // 252
1065 // GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
1066 LINXY(__NR_epoll_create, sys_epoll_create), // 254
1067
1068 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
1069 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
1070 //zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
1071 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258
1072 LINXY(__NR_timer_create, sys_timer_create), // 259
1073
1074 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
1075 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
1076 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
1077 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
1078 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
1079
1080 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6)
1081 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
1082 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
1083 GENXY(__NR_statfs64, sys_statfs64), // 268
1084 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
1085
1086 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
1087 GENX_(__NR_utimes, sys_utimes), // 271
1088 GENX_(__NR_vserver, sys_ni_syscall), // 273
1089 LINX_(__NR_mbind, sys_mbind), // 274 ?/?
1090
1091 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
1092 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
1093 LINXY(__NR_mq_open, sys_mq_open), // 277
1094 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
1095 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
1096
1097 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
1098 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
1099 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
1100 LINXY(__NR_waitid, sys_waitid), // 280
1101
1102 LINXY(__NR_socket, sys_socket), // 281
1103 LINX_(__NR_bind, sys_bind), // 282
1104 LINX_(__NR_connect, sys_connect), // 283
1105 LINX_(__NR_listen, sys_listen), // 284
1106 LINXY(__NR_accept, sys_accept), // 285
1107 LINXY(__NR_getsockname, sys_getsockname), // 286
1108 LINXY(__NR_getpeername, sys_getpeername), // 287
1109 LINXY(__NR_socketpair, sys_socketpair), // 288
1110 LINX_(__NR_send, sys_send),
1111 LINX_(__NR_sendto, sys_sendto), // 290
1112 LINXY(__NR_recv, sys_recv),
1113 LINXY(__NR_recvfrom, sys_recvfrom), // 292
1114 LINX_(__NR_shutdown, sys_shutdown), // 293
1115 LINX_(__NR_setsockopt, sys_setsockopt), // 294
1116 LINXY(__NR_getsockopt, sys_getsockopt), // 295
1117 LINX_(__NR_sendmsg, sys_sendmsg), // 296
1118 LINXY(__NR_recvmsg, sys_recvmsg), // 297
1119 LINX_(__NR_semop, sys_semop), // 298
1120 LINX_(__NR_semget, sys_semget), // 299
1121 LINXY(__NR_semctl, sys_semctl), // 300
1122 LINX_(__NR_msgget, sys_msgget),
1123 LINX_(__NR_msgsnd, sys_msgsnd),
1124 LINXY(__NR_msgrcv, sys_msgrcv),
1125 LINXY(__NR_msgctl, sys_msgctl), // 304
1126 LINX_(__NR_semtimedop, sys_semtimedop), // 312
1127
1128 LINX_(__NR_add_key, sys_add_key), // 286
1129 LINX_(__NR_request_key, sys_request_key), // 287
1130 LINXY(__NR_keyctl, sys_keyctl), // not 288...
1131 // LINX_(__NR_ioprio_set, sys_ioprio_set), // 289
1132
1133 // LINX_(__NR_ioprio_get, sys_ioprio_get), // 290
1134 LINX_(__NR_inotify_init, sys_inotify_init), // 291
1135 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1136 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293
1137 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 294
1138
1139 LINXY(__NR_openat, sys_openat), // 295
1140 LINX_(__NR_mkdirat, sys_mkdirat), // 296
1141 LINX_(__NR_mknodat, sys_mknodat), // 297
1142 LINX_(__NR_fchownat, sys_fchownat), // 298
1143 LINX_(__NR_futimesat, sys_futimesat), // 326 on arm
1144
1145 PLAXY(__NR_fstatat64, sys_fstatat64), // 300
1146 LINX_(__NR_unlinkat, sys_unlinkat), // 301
1147 LINX_(__NR_renameat, sys_renameat), // 302
1148 LINX_(__NR_linkat, sys_linkat), // 303
1149 LINX_(__NR_symlinkat, sys_symlinkat), // 304
1150
1151 LINX_(__NR_readlinkat, sys_readlinkat), //
1152 LINX_(__NR_fchmodat, sys_fchmodat), //
1153 LINX_(__NR_faccessat, sys_faccessat), //
1154 LINXY(__NR_shmat, wrap_sys_shmat), //305
1155 LINXY(__NR_shmdt, sys_shmdt), //306
1156 LINX_(__NR_shmget, sys_shmget), //307
1157 LINXY(__NR_shmctl, sys_shmctl), // 308
1158 // LINX_(__NR_pselect6, sys_pselect6), //
1159
1160 LINX_(__NR_unshare, sys_unshare), // 310
1161 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311
1162 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312
1163 // LINX_(__NR_splice, sys_ni_syscall), // 313
1164 // LINX_(__NR_sync_file_range, sys_sync_file_range), // 314
1165
1166 // LINX_(__NR_tee, sys_ni_syscall), // 315
1167 // LINX_(__NR_vmsplice, sys_ni_syscall), // 316
1168 LINXY(__NR_move_pages, sys_move_pages), // 317
1169 // LINX_(__NR_getcpu, sys_ni_syscall), // 318
1170
1171 LINX_(__NR_utimensat, sys_utimensat), // 320
1172 LINXY(__NR_signalfd, sys_signalfd), // 321
1173 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322
1174 LINXY(__NR_eventfd, sys_eventfd), // 323
1175
1176 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325
1177 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326
1178
1179 ///////////////
1180
1181 // JRS 2010-Jan-03: I believe that all the numbers listed
1182 // in comments in the table prior to this point (eg "// 326",
1183 // etc) are bogus since it looks to me like they are copied
1184 // verbatim from syswrap-x86-linux.c and they certainly do not
1185 // correspond to what's in include/vki/vki-scnums-arm-linux.h.
1186 // From here onwards, please ensure the numbers are correct.
1187
1188 LINX_(__NR_arm_fadvise64_64, sys_fadvise64_64), // 270 */(Linux?)
1189
1190 LINX_(__NR_pselect6, sys_pselect6), // 335
1191 LINXY(__NR_ppoll, sys_ppoll), // 336
1192
1193 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 346
1194
1195 LINX_(__NR_fallocate, sys_fallocate), // 352
1196
1197 LINXY(__NR_signalfd4, sys_signalfd4), // 355
1198 LINXY(__NR_eventfd2, sys_eventfd2), // 356
1199 LINXY(__NR_epoll_create1, sys_epoll_create1), // 357
1200 LINXY(__NR_dup3, sys_dup3), // 358
1201 LINXY(__NR_pipe2, sys_pipe2), // 359
1202 LINXY(__NR_inotify_init1, sys_inotify_init1), // 360
1203 LINXY(__NR_preadv, sys_preadv), // 361
1204 LINX_(__NR_pwritev, sys_pwritev), // 362
1205 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 363
1206 LINXY(__NR_perf_event_open, sys_perf_event_open), // 364
1207 LINXY(__NR_recvmmsg, sys_recvmmsg), // 365
1208 LINXY(__NR_accept4, sys_accept4), // 366
1209 LINXY(__NR_fanotify_init, sys_fanotify_init), // 367
1210 LINX_(__NR_fanotify_mark, sys_fanotify_mark), // 368
1211 LINXY(__NR_prlimit64, sys_prlimit64), // 369
1212 LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 370
1213 LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 371
1214 LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 372
1215 LINX_(__NR_syncfs, sys_syncfs), // 373
1216 LINXY(__NR_sendmmsg, sys_sendmmsg), // 374
1217 LINXY(__NR_getrandom, sys_getrandom), // 384
1218 LINXY(__NR_memfd_create, sys_memfd_create) // 385
1219 };
1220
1221
1222 /* These are not in the main table because there indexes are not small
1223 integers, but rather values close to one million. So their
1224 inclusion would force the main table to be huge (about 8 MB). */
1225
1226 static SyscallTableEntry ste___ARM_set_tls
1227 = { WRAPPER_PRE_NAME(arm_linux,sys_set_tls), NULL };
1228
1229 static SyscallTableEntry ste___ARM_cacheflush
1230 = { WRAPPER_PRE_NAME(arm_linux,sys_cacheflush), NULL };
1231
ML_(get_linux_syscall_entry)1232 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1233 {
1234 const UInt syscall_main_table_size
1235 = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
1236
1237 /* Is it in the contiguous initial section of the table? */
1238 if (sysno < syscall_main_table_size) {
1239 SyscallTableEntry* sys = &syscall_main_table[sysno];
1240 if (sys->before == NULL)
1241 return NULL; /* no entry */
1242 else
1243 return sys;
1244 }
1245
1246 /* Check if it's one of the out-of-line entries. */
1247 switch (sysno) {
1248 case __NR_ARM_set_tls: return &ste___ARM_set_tls;
1249 case __NR_ARM_cacheflush: return &ste___ARM_cacheflush;
1250 default: break;
1251 }
1252
1253 /* Can't find a wrapper */
1254 return NULL;
1255 }
1256
1257 #endif // defined(VGP_arm_linux)
1258
1259 /*--------------------------------------------------------------------*/
1260 /*--- end syswrap-arm-linux.c ---*/
1261 /*--------------------------------------------------------------------*/
1262