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