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