2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-s390x-linux.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright IBM Corp. 2010-2013
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 The GNU General Public License is contained in the file COPYING.
30 /* Contributed by Christian Borntraeger */
32 #if defined(VGP_s390x_linux)
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_vkiscnums.h"
37 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
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_mallocfree.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)
56 #include "priv_types_n_macros.h"
57 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
58 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
59 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
60 #include "priv_syswrap-main.h"
63 /* ---------------------------------------------------------------------
65 ------------------------------------------------------------------ */
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 Thought: Why are we clearing the GPRs ? The callee pointed to by f
71 is a regular C function which will play by the ABI rules. So there is
72 no need to zero out the GPRs. If we assumed that f accesses registers at
73 will, then it would make sense to create a defined register state.
74 But then, why only for the GPRs and not the FPRs ? */
75 __attribute__((noreturn))
76 void ML_(call_on_new_stack_0_1) ( Addr stack,
80 /* Upon entering this function we have the following setup:
89 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
90 ".type vgModuleLocal_call_on_new_stack_0_1, @function\n"
91 "vgModuleLocal_call_on_new_stack_0_1:\n"
92 " lgr %r15,%r2\n" // stack to r15
93 " lgr %r14,%r3\n" // retaddr to r14
94 " lgr %r2,%r5\n" // arg1 to r2
95 // zero all gprs to get a defined state
98 // r2 holds the argument for the callee
100 // r4 holds the callee address
110 // r14 holds the return address for the callee
111 // r15 is the stack pointer
112 " br %r4\n" // jump to f
117 Perform a clone system call. clone is strange because it has
118 fork()-like return-twice semantics, so it needs special
122 void* child_stack in r2
124 int* parent_tid in r4
126 int* tls address in r6
127 Word (*fn)(void *) 160(r15)
130 System call requires:
131 void* child_stack in r2 (sc arg1)
132 long flags in r3 (sc arg2)
133 int* parent_tid in r4 (sc arg3)
134 int* child_tid in r5 (sc arg4)
135 void* tlsaddr in r6 (sc arg5)
137 Returns a ULong encoded as: top half is %cr following syscall,
138 low half is syscall return value (r3).
140 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
141 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
144 ULong do_syscall_clone_s390x_linux ( void *stack,
154 ".globl do_syscall_clone_s390x_linux\n"
155 "do_syscall_clone_s390x_linux:\n"
156 " lg %r1, 160(%r15)\n" // save fn from parent stack into r1
157 " lg %r0, 168(%r15)\n" // save arg from parent stack into r0
158 " aghi %r2, -160\n" // create stack frame for child
159 // all syscall parameters are already in place (r2-r6)
160 " svc " __NR_CLONE"\n" // clone()
161 " ltgr %r2,%r2\n" // child if retval == 0
164 // CHILD - call thread function
165 " lgr %r2, %r0\n" // get arg from r0
166 " basr %r14,%r1\n" // call fn
168 // exit. The result is already in r2
169 " svc " __NR_EXIT"\n"
174 "1:\n" // PARENT or ERROR
182 void VG_(cleanup_thread) ( ThreadArchState* arch )
184 /* only used on x86 for descriptor tables */
187 static void setup_child ( /*OUT*/ ThreadArchState *child,
188 /*IN*/ ThreadArchState *parent )
190 /* We inherit our parent's guest state. */
191 child->vex = parent->vex;
192 child->vex_shadow1 = parent->vex_shadow1;
193 child->vex_shadow2 = parent->vex_shadow2;
198 When a client clones, we need to keep track of the new thread. This means:
199 1. allocate a ThreadId+ThreadState+stack for the the thread
201 2. initialize the thread's new VCPU state
203 3. create the thread using the same args as the client requested,
204 but using the scheduler entrypoint for IP, and a separate stack
207 static SysRes do_clone ( ThreadId ptid,
208 Addr sp, ULong flags,
213 static const Bool debug = False;
215 ThreadId ctid = VG_(alloc_ThreadState)();
216 ThreadState* ptst = VG_(get_ThreadState)(ptid);
217 ThreadState* ctst = VG_(get_ThreadState)(ctid);
222 vki_sigset_t blockall, savedmask;
224 VG_(sigfillset)(&blockall);
226 vg_assert(VG_(is_running_thread)(ptid));
227 vg_assert(VG_(is_valid_tid)(ctid));
229 stack = (UWord*)ML_(allocstack)(ctid);
231 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
235 /* Copy register state
237 Both parent and child return to the same place, and the code
238 following the clone syscall works out which is which, so we
239 don't need to worry about it.
241 The parent gets the child's new tid returned from clone, but the
244 If the clone call specifies a NULL sp for the new thread, then
245 it actually gets a copy of the parent's sp.
247 setup_child( &ctst->arch, &ptst->arch );
249 /* Make sys_clone appear to have returned Success(0) in the
251 ctst->arch.vex.guest_r2 = 0;
254 ctst->arch.vex.guest_r15 = sp;
256 ctst->os_state.parent = ptid;
258 /* inherit signal mask */
259 ctst->sig_mask = ptst->sig_mask;
260 ctst->tmp_sig_mask = ptst->sig_mask;
262 /* have the parents thread group */
263 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
265 /* We don't really know where the client stack is, because its
266 allocated by the client. The best we can do is look at the
267 memory mappings and try to derive some useful information. We
268 assume that esp starts near its highest possible value, and can
269 only go down to the start of the mmaped segment. */
270 seg = VG_(am_find_nsegment)((Addr)sp);
271 if (seg && seg->kind != SkResvn) {
272 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
273 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
275 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
278 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
279 ctid, seg->start, VG_PGROUNDUP(sp));
281 VG_(message)(Vg_UserMsg,
282 "!? New thread %d starts with SP(%#lx) unmapped\n",
284 ctst->client_stack_szB = 0;
287 /* Assume the clone will succeed, and tell any tool that wants to
288 know that this thread has come into existence. If the clone
289 fails, we'll send out a ll_exit notification for it at the out:
290 label below, to clean up. */
291 vg_assert(VG_(owns_BigLock_LL)(ptid));
292 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
294 if (flags & VKI_CLONE_SETTLS) {
296 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
297 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
298 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
300 flags &= ~VKI_CLONE_SETTLS;
302 /* start the thread with everything blocked */
303 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
305 /* Create the new thread */
306 r2 = do_syscall_clone_s390x_linux(
307 stack, flags, parent_tidptr, child_tidptr, tlsaddr,
308 ML_(start_thread_NORETURN), &VG_(threads)[ctid]);
310 res = VG_(mk_SysRes_s390x_linux)( r2 );
312 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
315 if (sr_isError(res)) {
317 ctst->status = VgTs_Empty;
318 /* oops. Better tell the tool the thread exited in a hurry :-) */
319 VG_TRACK( pre_thread_ll_exit, ctid );
328 /* ---------------------------------------------------------------------
329 PRE/POST wrappers for s390x/Linux-specific syscalls
330 ------------------------------------------------------------------ */
332 #define PRE(name) DEFN_PRE_TEMPLATE(s390x_linux, name)
333 #define POST(name) DEFN_POST_TEMPLATE(s390x_linux, name)
335 /* Add prototypes for the wrappers declared here, so that gcc doesn't
336 harass us for not having prototypes. Really this is a kludge --
337 the right thing to do is to make these wrappers 'static' since they
338 aren't visible outside this file, but that requires even more macro
341 DECL_TEMPLATE(s390x_linux, sys_ptrace);
342 DECL_TEMPLATE(s390x_linux, sys_mmap);
343 DECL_TEMPLATE(s390x_linux, sys_clone);
344 DECL_TEMPLATE(s390x_linux, sys_sigreturn);
345 DECL_TEMPLATE(s390x_linux, sys_rt_sigreturn);
346 DECL_TEMPLATE(s390x_linux, sys_fadvise64);
348 /* PEEK TEXT,DATA and USER are common to all architectures.
349 PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
350 containing the real addr, data, and len field pointed to by ARG3
352 GETREGSET and SETREGSET use a struct iovec (pointed to by ARG4) for
353 the address and size of the user buffer. */
357 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
358 PRE_REG_READ4(int, "ptrace",
359 long, request, long, pid, long, addr, long, data);
361 case VKI_PTRACE_PEEKTEXT:
362 case VKI_PTRACE_PEEKDATA:
363 case VKI_PTRACE_PEEKUSR:
364 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
367 case VKI_PTRACE_GETEVENTMSG:
368 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
370 case VKI_PTRACE_GETSIGINFO:
371 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
373 case VKI_PTRACE_SETSIGINFO:
374 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
376 case VKI_PTRACE_PEEKUSR_AREA:
380 /* Reads a part of the user area into memory at pa->process_addr */
381 pa = (vki_ptrace_area *) ARG3;
382 PRE_MEM_READ("ptrace(peekusrarea ptrace_area->len)",
383 (unsigned long) &pa->vki_len, sizeof(pa->vki_len));
384 PRE_MEM_READ("ptrace(peekusrarea ptrace_area->kernel_addr)",
385 (unsigned long) &pa->vki_kernel_addr, sizeof(pa->vki_kernel_addr));
386 PRE_MEM_READ("ptrace(peekusrarea ptrace_area->process_addr)",
387 (unsigned long) &pa->vki_process_addr, sizeof(pa->vki_process_addr));
388 PRE_MEM_WRITE("ptrace(peekusrarea *(ptrace_area->process_addr))",
389 pa->vki_process_addr, pa->vki_len);
392 case VKI_PTRACE_POKEUSR_AREA:
396 /* Updates a part of the user area from memory at pa->process_addr */
397 pa = (vki_ptrace_area *) ARG3;
398 PRE_MEM_READ("ptrace(pokeusrarea ptrace_area->len)",
399 (unsigned long) &pa->vki_len, sizeof(pa->vki_len));
400 PRE_MEM_READ("ptrace(pokeusrarea ptrace_area->kernel_addr)",
401 (unsigned long) &pa->vki_kernel_addr,
402 sizeof(pa->vki_kernel_addr));
403 PRE_MEM_READ("ptrace(pokeusrarea ptrace_area->process_addr)",
404 (unsigned long) &pa->vki_process_addr,
405 sizeof(pa->vki_process_addr));
406 PRE_MEM_READ("ptrace(pokeusrarea *(ptrace_area->process_addr))",
407 pa->vki_process_addr, pa->vki_len);
410 case VKI_PTRACE_GETREGSET:
411 ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
413 case VKI_PTRACE_SETREGSET:
414 ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
424 case VKI_PTRACE_PEEKTEXT:
425 case VKI_PTRACE_PEEKDATA:
426 case VKI_PTRACE_PEEKUSR:
427 POST_MEM_WRITE( ARG4, sizeof (long));
429 case VKI_PTRACE_GETEVENTMSG:
430 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
432 case VKI_PTRACE_GETSIGINFO:
433 /* XXX: This is a simplification. Different parts of the
434 * siginfo_t are valid depending on the type of signal.
436 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
438 case VKI_PTRACE_PEEKUSR_AREA:
442 pa = (vki_ptrace_area *) ARG3;
443 POST_MEM_WRITE(pa->vki_process_addr, pa->vki_len);
446 case VKI_PTRACE_GETREGSET:
447 ML_(linux_POST_getregset)(tid, ARG3, ARG4);
456 UWord a0, a1, a2, a3, a4, a5;
459 UWord* args = (UWord*)ARG1;
460 PRE_REG_READ1(long, "sys_mmap", struct mmap_arg_struct *, args);
461 PRE_MEM_READ( "sys_mmap(args)", (Addr) args, 6*sizeof(UWord) );
470 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
471 a0, (ULong)a1, a2, a3, a4, a5 );
473 r = ML_(generic_PRE_sys_mmap)( tid, a0, a1, a2, a3, a4, (Off64T)a5 );
474 SET_STATUS_from_SysRes(r);
481 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4, ARG5);
482 PRE_REG_READ2(int, "clone",
484 unsigned long, flags);
486 if (ARG2 & VKI_CLONE_PARENT_SETTID) {
487 if (VG_(tdict).track_pre_reg_read)
488 PRA3("clone(parent_tidptr)", int *, parent_tidptr);
489 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
490 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
492 SET_STATUS_Failure( VKI_EFAULT );
496 if (ARG2 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
497 if (VG_(tdict).track_pre_reg_read)
498 PRA4("clone(child_tidptr)", int *, child_tidptr);
499 PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
500 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int),
502 SET_STATUS_Failure( VKI_EFAULT );
507 /* The kernel simply copies reg6 (ARG5) into AR0 and AR1, no checks */
508 if (ARG2 & VKI_CLONE_SETTLS) {
509 if (VG_(tdict).track_pre_reg_read) {
510 PRA5("clone", Addr, tlsinfo);
516 if (!ML_(client_signal_OK)(ARG2 & VKI_CSIGNAL)) {
517 SET_STATUS_Failure( VKI_EINVAL );
521 /* Only look at the flags we really care about */
522 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
523 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
524 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
525 /* thread creation */
526 SET_STATUS_from_SysRes(
528 (Addr)ARG1, /* child SP */
530 (Int *)ARG3, /* parent_tidptr */
531 (Int *)ARG4, /* child_tidptr */
532 (Addr)ARG5)); /* tlsaddr */
535 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
536 /* FALLTHROUGH - assume vfork == fork */
537 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
539 case 0: /* plain fork */
540 SET_STATUS_from_SysRes(
541 ML_(do_fork_clone)(tid,
542 cloneflags, /* flags */
543 (Int *)ARG3, /* parent_tidptr */
544 (Int *)ARG4)); /* child_tidptr */
548 /* should we just ENOSYS? */
549 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG2);
550 VG_(message)(Vg_UserMsg, "");
551 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
552 VG_(message)(Vg_UserMsg, " - via a threads library (NPTL)");
553 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
555 ("Valgrind does not support general clone().");
559 if (ARG2 & VKI_CLONE_PARENT_SETTID)
560 POST_MEM_WRITE(ARG3, sizeof(Int));
561 if (ARG2 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
562 POST_MEM_WRITE(ARG4, sizeof(Int));
564 /* Thread creation was successful; let the child have the chance
566 *flags |= SfYieldAfter;
573 PRINT("sys_sigreturn ( )");
575 vg_assert(VG_(is_valid_tid)(tid));
576 vg_assert(tid >= 1 && tid < VG_N_THREADS);
577 vg_assert(VG_(is_running_thread)(tid));
579 tst = VG_(get_ThreadState)(tid);
581 /* This is only so that the IA is (might be) useful to report if
582 something goes wrong in the sigreturn */
583 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
585 /* Restore register state from frame and remove it */
586 VG_(sigframe_destroy)(tid, False);
588 /* Tell the driver not to update the guest state with the "result",
589 and set a bogus result to keep it happy. */
590 *flags |= SfNoWriteResult;
591 SET_STATUS_Success(0);
593 /* Check to see if any signals arose as a result of this. */
594 *flags |= SfPollAfter;
598 PRE(sys_rt_sigreturn)
600 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
601 an explanation of what follows. */
604 PRINT("sys_rt_sigreturn ( )");
606 vg_assert(VG_(is_valid_tid)(tid));
607 vg_assert(tid >= 1 && tid < VG_N_THREADS);
608 vg_assert(VG_(is_running_thread)(tid));
610 tst = VG_(get_ThreadState)(tid);
612 /* This is only so that the IA is (might be) useful to report if
613 something goes wrong in the sigreturn */
614 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
616 /* Restore register state from frame and remove it */
617 VG_(sigframe_destroy)(tid, True);
619 /* Tell the driver not to update the guest state with the "result",
620 and set a bogus result to keep it happy. */
621 *flags |= SfNoWriteResult;
622 SET_STATUS_Success(0);
624 /* Check to see if any signals arose as a result of this. */
625 *flags |= SfPollAfter;
628 /* we cant use the LINX_ version for 64 bit */
631 PRINT("sys_fadvise64 ( %ld, %ld, %ld, %ld )", ARG1,ARG2,ARG3,ARG4);
632 PRE_REG_READ4(long, "fadvise64",
633 int, fd, vki_loff_t, offset, vki_loff_t, len, int, advice);
639 /* ---------------------------------------------------------------------
640 The s390x/Linux syscall table
641 ------------------------------------------------------------------ */
643 /* Add an s390x-linux specific wrapper to a syscall table. */
644 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(s390x_linux, sysno, name)
645 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(s390x_linux, sysno, name)
647 // This table maps from __NR_xxx syscall numbers from
648 // linux/arch/s390/kernel/syscalls.S to the appropriate PRE/POST sys_foo()
649 // wrappers on s390x. There are several unused numbers, which are only
650 // defined on s390 (31bit mode) but no longer available on s390x (64 bit).
651 // For those syscalls not handled by Valgrind, the annotation indicate its
652 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
655 static SyscallTableEntry syscall_table[] = {
656 GENX_(0, sys_ni_syscall), /* unimplemented (by the kernel) */ // 0
657 GENX_(__NR_exit, sys_exit), // 1
658 GENX_(__NR_fork, sys_fork), // 2
659 GENXY(__NR_read, sys_read), // 3
660 GENX_(__NR_write, sys_write), // 4
662 GENXY(__NR_open, sys_open), // 5
663 GENXY(__NR_close, sys_close), // 6
664 // ?????(__NR_restart_syscall, ), // 7
665 GENXY(__NR_creat, sys_creat), // 8
666 GENX_(__NR_link, sys_link), // 9
668 GENX_(__NR_unlink, sys_unlink), // 10
669 GENX_(__NR_execve, sys_execve), // 11
670 GENX_(__NR_chdir, sys_chdir), // 12
671 GENX_(13, sys_ni_syscall), /* unimplemented (by the kernel) */ // 13
672 GENX_(__NR_mknod, sys_mknod), // 14
674 GENX_(__NR_chmod, sys_chmod), // 15
675 GENX_(16, sys_ni_syscall), /* unimplemented (by the kernel) */ // 16
676 GENX_(17, sys_ni_syscall), /* unimplemented (by the kernel) */ // 17
677 GENX_(18, sys_ni_syscall), /* unimplemented (by the kernel) */ // 18
678 LINX_(__NR_lseek, sys_lseek), // 19
680 GENX_(__NR_getpid, sys_getpid), // 20
681 LINX_(__NR_mount, sys_mount), // 21
682 LINX_(__NR_umount, sys_oldumount), // 22
683 GENX_(23, sys_ni_syscall), /* unimplemented (by the kernel) */ // 23
684 GENX_(24, sys_ni_syscall), /* unimplemented (by the kernel) */ // 24
686 GENX_(25, sys_ni_syscall), /* unimplemented (by the kernel) */ // 25
687 PLAXY(__NR_ptrace, sys_ptrace), // 26
688 GENX_(__NR_alarm, sys_alarm), // 27
689 GENX_(28, sys_ni_syscall), /* unimplemented (by the kernel) */ // 28
690 GENX_(__NR_pause, sys_pause), // 29
692 LINX_(__NR_utime, sys_utime), // 30
693 GENX_(31, sys_ni_syscall), /* unimplemented (by the kernel) */ // 31
694 GENX_(32, sys_ni_syscall), /* unimplemented (by the kernel) */ // 32
695 GENX_(__NR_access, sys_access), // 33
696 GENX_(__NR_nice, sys_nice), // 34
698 GENX_(35, sys_ni_syscall), /* unimplemented (by the kernel) */ // 35
699 GENX_(__NR_sync, sys_sync), // 36
700 GENX_(__NR_kill, sys_kill), // 37
701 GENX_(__NR_rename, sys_rename), // 38
702 GENX_(__NR_mkdir, sys_mkdir), // 39
704 GENX_(__NR_rmdir, sys_rmdir), // 40
705 GENXY(__NR_dup, sys_dup), // 41
706 LINXY(__NR_pipe, sys_pipe), // 42
707 GENXY(__NR_times, sys_times), // 43
708 GENX_(44, sys_ni_syscall), /* unimplemented (by the kernel) */ // 44
710 GENX_(__NR_brk, sys_brk), // 45
711 GENX_(46, sys_ni_syscall), /* unimplemented (by the kernel) */ // 46
712 GENX_(47, sys_ni_syscall), /* unimplemented (by the kernel) */ // 47
713 // ?????(__NR_signal, ), // 48
714 GENX_(49, sys_ni_syscall), /* unimplemented (by the kernel) */ // 49
716 GENX_(50, sys_ni_syscall), /* unimplemented (by the kernel) */ // 50
717 GENX_(__NR_acct, sys_acct), // 51
718 LINX_(__NR_umount2, sys_umount), // 52
719 GENX_(53, sys_ni_syscall), /* unimplemented (by the kernel) */ // 53
720 LINXY(__NR_ioctl, sys_ioctl), // 54
722 LINXY(__NR_fcntl, sys_fcntl), // 55
723 GENX_(56, sys_ni_syscall), /* unimplemented (by the kernel) */ // 56
724 GENX_(__NR_setpgid, sys_setpgid), // 57
725 GENX_(58, sys_ni_syscall), /* unimplemented (by the kernel) */ // 58
726 GENX_(59, sys_ni_syscall), /* unimplemented (by the kernel) */ // 59
728 GENX_(__NR_umask, sys_umask), // 60
729 GENX_(__NR_chroot, sys_chroot), // 61
730 // ?????(__NR_ustat, sys_ustat), /* deprecated in favor of statfs */ // 62
731 GENXY(__NR_dup2, sys_dup2), // 63
732 GENX_(__NR_getppid, sys_getppid), // 64
734 GENX_(__NR_getpgrp, sys_getpgrp), // 65
735 GENX_(__NR_setsid, sys_setsid), // 66
736 // ?????(__NR_sigaction, ), /* userspace uses rt_sigaction */ // 67
737 GENX_(68, sys_ni_syscall), /* unimplemented (by the kernel) */ // 68
738 GENX_(69, sys_ni_syscall), /* unimplemented (by the kernel) */ // 69
740 GENX_(70, sys_ni_syscall), /* unimplemented (by the kernel) */ // 70
741 GENX_(71, sys_ni_syscall), /* unimplemented (by the kernel) */ // 71
742 // ?????(__NR_sigsuspend, ), // 72
743 // ?????(__NR_sigpending, ), // 73
744 // ?????(__NR_sethostname, ), // 74
746 GENX_(__NR_setrlimit, sys_setrlimit), // 75
747 GENXY(76, sys_getrlimit), /* see also 191 */ // 76
748 GENXY(__NR_getrusage, sys_getrusage), // 77
749 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
750 GENX_(__NR_settimeofday, sys_settimeofday), // 79
752 GENX_(80, sys_ni_syscall), /* unimplemented (by the kernel) */ // 80
753 GENX_(81, sys_ni_syscall), /* unimplemented (by the kernel) */ // 81
754 GENX_(82, sys_ni_syscall), /* unimplemented (by the kernel) */ // 82
755 GENX_(__NR_symlink, sys_symlink), // 83
756 GENX_(84, sys_ni_syscall), /* unimplemented (by the kernel) */ // 84
758 GENX_(__NR_readlink, sys_readlink), // 85
759 // ?????(__NR_uselib, ), // 86
760 // ?????(__NR_swapon, ), // 87
761 // ?????(__NR_reboot, ), // 88
762 GENX_(89, sys_ni_syscall), /* unimplemented (by the kernel) */ // 89
764 PLAX_(__NR_mmap, sys_mmap ), // 90
765 GENXY(__NR_munmap, sys_munmap), // 91
766 GENX_(__NR_truncate, sys_truncate), // 92
767 GENX_(__NR_ftruncate, sys_ftruncate), // 93
768 GENX_(__NR_fchmod, sys_fchmod), // 94
770 GENX_(95, sys_ni_syscall), /* unimplemented (by the kernel) */ // 95
771 GENX_(__NR_getpriority, sys_getpriority), // 96
772 GENX_(__NR_setpriority, sys_setpriority), // 97
773 GENX_(98, sys_ni_syscall), /* unimplemented (by the kernel) */ // 98
774 GENXY(__NR_statfs, sys_statfs), // 99
776 GENXY(__NR_fstatfs, sys_fstatfs), // 100
777 GENX_(101, sys_ni_syscall), /* unimplemented (by the kernel) */ // 101
778 LINXY(__NR_socketcall, sys_socketcall), // 102
779 LINXY(__NR_syslog, sys_syslog), // 103
780 GENXY(__NR_setitimer, sys_setitimer), // 104
782 GENXY(__NR_getitimer, sys_getitimer), // 105
783 GENXY(__NR_stat, sys_newstat), // 106
784 GENXY(__NR_lstat, sys_newlstat), // 107
785 GENXY(__NR_fstat, sys_newfstat), // 108
786 GENX_(109, sys_ni_syscall), /* unimplemented (by the kernel) */ // 109
788 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 110
789 LINX_(__NR_vhangup, sys_vhangup), // 111
790 GENX_(112, sys_ni_syscall), /* unimplemented (by the kernel) */ // 112
791 GENX_(113, sys_ni_syscall), /* unimplemented (by the kernel) */ // 113
792 GENXY(__NR_wait4, sys_wait4), // 114
794 // ?????(__NR_swapoff, ), // 115
795 LINXY(__NR_sysinfo, sys_sysinfo), // 116
796 LINXY(__NR_ipc, sys_ipc), // 117
797 GENX_(__NR_fsync, sys_fsync), // 118
798 PLAX_(__NR_sigreturn, sys_sigreturn), // 119
800 PLAX_(__NR_clone, sys_clone), // 120
801 // ?????(__NR_setdomainname, ), // 121
802 GENXY(__NR_uname, sys_newuname), // 122
803 GENX_(123, sys_ni_syscall), /* unimplemented (by the kernel) */ // 123
804 // ?????(__NR_adjtimex, ), // 124
806 GENXY(__NR_mprotect, sys_mprotect), // 125
807 // LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
808 GENX_(127, sys_ni_syscall), /* unimplemented (by the kernel) */ // 127
809 LINX_(__NR_init_module, sys_init_module), // 128
810 LINX_(__NR_delete_module, sys_delete_module), // 129
812 GENX_(130, sys_ni_syscall), /* unimplemented (by the kernel) */ // 130
813 LINX_(__NR_quotactl, sys_quotactl), // 131
814 GENX_(__NR_getpgid, sys_getpgid), // 132
815 GENX_(__NR_fchdir, sys_fchdir), // 133
816 // ?????(__NR_bdflush, ), // 134
818 // ?????(__NR_sysfs, ), // 135
819 LINX_(__NR_personality, sys_personality), // 136
820 GENX_(137, sys_ni_syscall), /* unimplemented (by the kernel) */ // 137
821 GENX_(138, sys_ni_syscall), /* unimplemented (by the kernel) */ // 138
822 GENX_(139, sys_ni_syscall), /* unimplemented (by the kernel) */ // 139
824 // LINXY(__NR__llseek, sys_llseek), /* 64 bit --> lseek */ // 140
825 GENXY(__NR_getdents, sys_getdents), // 141
826 GENX_(__NR_select, sys_select), // 142
827 GENX_(__NR_flock, sys_flock), // 143
828 GENX_(__NR_msync, sys_msync), // 144
830 GENXY(__NR_readv, sys_readv), // 145
831 GENX_(__NR_writev, sys_writev), // 146
832 GENX_(__NR_getsid, sys_getsid), // 147
833 GENX_(__NR_fdatasync, sys_fdatasync), // 148
834 LINXY(__NR__sysctl, sys_sysctl), // 149
836 GENX_(__NR_mlock, sys_mlock), // 150
837 GENX_(__NR_munlock, sys_munlock), // 151
838 GENX_(__NR_mlockall, sys_mlockall), // 152
839 LINX_(__NR_munlockall, sys_munlockall), // 153
840 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
842 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
843 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
844 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
845 LINX_(__NR_sched_yield, sys_sched_yield), // 158
846 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 159
848 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 160
849 // ?????(__NR_sched_rr_get_interval, ), // 161
850 GENXY(__NR_nanosleep, sys_nanosleep), // 162
851 GENX_(__NR_mremap, sys_mremap), // 163
852 GENX_(164, sys_ni_syscall), /* unimplemented (by the kernel) */ // 164
854 GENX_(165, sys_ni_syscall), /* unimplemented (by the kernel) */ // 165
855 GENX_(166, sys_ni_syscall), /* unimplemented (by the kernel) */ // 166
856 GENX_(167, sys_ni_syscall), /* unimplemented (by the kernel) */ // 167
857 GENXY(__NR_poll, sys_poll), // 168
858 // ?????(__NR_nfsservctl, ), // 169
860 GENX_(170, sys_ni_syscall), /* unimplemented (by the kernel) */ // 170
861 GENX_(171, sys_ni_syscall), /* unimplemented (by the kernel) */ // 171
862 LINXY(__NR_prctl, sys_prctl), // 172
863 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173
864 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
866 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
867 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
868 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 177
869 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 178
870 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
872 GENXY(__NR_pread64, sys_pread64), // 180
873 GENX_(__NR_pwrite64, sys_pwrite64), // 181
874 GENX_(182, sys_ni_syscall), /* unimplemented (by the kernel) */ // 182
875 GENXY(__NR_getcwd, sys_getcwd), // 183
876 LINXY(__NR_capget, sys_capget), // 184
878 LINX_(__NR_capset, sys_capset), // 185
879 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
880 LINXY(__NR_sendfile, sys_sendfile), // 187
881 GENX_(188, sys_ni_syscall), /* unimplemented (by the kernel) */ // 188
882 GENX_(189, sys_ni_syscall), /* unimplemented (by the kernel) */ // 189
884 GENX_(__NR_vfork, sys_fork), // 190
885 GENXY(__NR_getrlimit, sys_getrlimit), // 191
886 GENX_(192, sys_ni_syscall), /* not exported on 64bit*/ // 192
887 GENX_(193, sys_ni_syscall), /* unimplemented (by the kernel) */ // 193
888 GENX_(194, sys_ni_syscall), /* unimplemented (by the kernel) */ // 194
890 GENX_(195, sys_ni_syscall), /* unimplemented (by the kernel) */ // 195
891 GENX_(196, sys_ni_syscall), /* unimplemented (by the kernel) */ // 196
892 GENX_(197, sys_ni_syscall), /* unimplemented (by the kernel) */ // 197
893 GENX_(__NR_lchown, sys_lchown), // 198
894 GENX_(__NR_getuid, sys_getuid), // 199
896 GENX_(__NR_getgid, sys_getgid), // 200
897 GENX_(__NR_geteuid, sys_geteuid), // 201
898 GENX_(__NR_getegid, sys_getegid), // 202
899 GENX_(__NR_setreuid, sys_setreuid), // 203
900 GENX_(__NR_setregid, sys_setregid), // 204
902 GENXY(__NR_getgroups, sys_getgroups), // 205
903 GENX_(__NR_setgroups, sys_setgroups), // 206
904 GENX_(__NR_fchown, sys_fchown), // 207
905 LINX_(__NR_setresuid, sys_setresuid), // 208
906 LINXY(__NR_getresuid, sys_getresuid), // 209
908 LINX_(__NR_setresgid, sys_setresgid), // 210
909 LINXY(__NR_getresgid, sys_getresgid), // 211
910 GENX_(__NR_chown, sys_chown), // 212
911 GENX_(__NR_setuid, sys_setuid), // 213
912 GENX_(__NR_setgid, sys_setgid), // 214
914 LINX_(__NR_setfsuid, sys_setfsuid), // 215
915 LINX_(__NR_setfsgid, sys_setfsgid), // 216
916 // ?????(__NR_pivot_root, ),
917 GENXY(__NR_mincore, sys_mincore), // 218
918 GENX_(__NR_madvise, sys_madvise), // 219
920 GENXY(__NR_getdents64, sys_getdents64), // 220
921 GENX_(221, sys_ni_syscall), /* unimplemented (by the kernel) */ // 221
922 LINX_(__NR_readahead, sys_readahead), // 222
923 GENX_(223, sys_ni_syscall), /* unimplemented (by the kernel) */ // 223
924 LINX_(__NR_setxattr, sys_setxattr), // 224
926 LINX_(__NR_lsetxattr, sys_lsetxattr), // 225
927 LINX_(__NR_fsetxattr, sys_fsetxattr), // 226
928 LINXY(__NR_getxattr, sys_getxattr), // 227
929 LINXY(__NR_lgetxattr, sys_lgetxattr), // 228
930 LINXY(__NR_fgetxattr, sys_fgetxattr), // 229
932 LINXY(__NR_listxattr, sys_listxattr), // 230
933 LINXY(__NR_llistxattr, sys_llistxattr), // 231
934 LINXY(__NR_flistxattr, sys_flistxattr), // 232
935 LINX_(__NR_removexattr, sys_removexattr), // 233
936 LINX_(__NR_lremovexattr, sys_lremovexattr), // 234
938 LINX_(__NR_fremovexattr, sys_fremovexattr), // 235
939 LINX_(__NR_gettid, sys_gettid), // 236
940 LINXY(__NR_tkill, sys_tkill), // 237
941 LINXY(__NR_futex, sys_futex), // 238
942 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 239
944 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 240
945 LINXY(__NR_tgkill, sys_tgkill), // 241
946 GENX_(242, sys_ni_syscall), /* unimplemented (by the kernel) */ // 242
947 LINXY(__NR_io_setup, sys_io_setup), // 243
948 LINX_(__NR_io_destroy, sys_io_destroy), // 244
950 LINXY(__NR_io_getevents, sys_io_getevents), // 245
951 LINX_(__NR_io_submit, sys_io_submit), // 246
952 LINXY(__NR_io_cancel, sys_io_cancel), // 247
953 LINX_(__NR_exit_group, sys_exit_group), // 248
954 LINXY(__NR_epoll_create, sys_epoll_create), // 249
956 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 250
957 LINXY(__NR_epoll_wait, sys_epoll_wait), // 251
958 LINX_(__NR_set_tid_address, sys_set_tid_address), // 252
959 PLAX_(__NR_fadvise64, sys_fadvise64), // 253
960 LINXY(__NR_timer_create, sys_timer_create), // 254
962 LINXY(__NR_timer_settime, sys_timer_settime), // 255
963 LINXY(__NR_timer_gettime, sys_timer_gettime), // 256
964 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 257
965 LINX_(__NR_timer_delete, sys_timer_delete), // 258
966 LINX_(__NR_clock_settime, sys_clock_settime), // 259
968 LINXY(__NR_clock_gettime, sys_clock_gettime), // 260
969 LINXY(__NR_clock_getres, sys_clock_getres), // 261
970 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 262
971 GENX_(263, sys_ni_syscall), /* unimplemented (by the kernel) */ // 263
972 GENX_(264, sys_ni_syscall), /* unimplemented (by the kernel) */ // 264
974 GENXY(__NR_statfs64, sys_statfs64), // 265
975 GENXY(__NR_fstatfs64, sys_fstatfs64), // 266
976 // ?????(__NR_remap_file_pages, ),
977 GENX_(268, sys_ni_syscall), /* unimplemented (by the kernel) */ // 268
978 GENX_(269, sys_ni_syscall), /* unimplemented (by the kernel) */ // 269
980 GENX_(270, sys_ni_syscall), /* unimplemented (by the kernel) */ // 270
981 LINXY(__NR_mq_open, sys_mq_open), // 271
982 LINX_(__NR_mq_unlink, sys_mq_unlink), // 272
983 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 273
984 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 274
986 LINX_(__NR_mq_notify, sys_mq_notify), // 275
987 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 276
988 // ?????(__NR_kexec_load, ),
989 LINX_(__NR_add_key, sys_add_key), // 278
990 LINX_(__NR_request_key, sys_request_key), // 279
992 LINXY(__NR_keyctl, sys_keyctl), // 280
993 LINXY(__NR_waitid, sys_waitid), // 281
994 LINX_(__NR_ioprio_set, sys_ioprio_set), // 282
995 LINX_(__NR_ioprio_get, sys_ioprio_get), // 283
996 LINX_(__NR_inotify_init, sys_inotify_init), // 284
998 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 285
999 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 286
1000 GENX_(287, sys_ni_syscall), /* unimplemented (by the kernel) */ // 287
1001 LINXY(__NR_openat, sys_openat), // 288
1002 LINX_(__NR_mkdirat, sys_mkdirat), // 289
1004 LINX_(__NR_mknodat, sys_mknodat), // 290
1005 LINX_(__NR_fchownat, sys_fchownat), // 291
1006 LINX_(__NR_futimesat, sys_futimesat), // 292
1007 LINXY(__NR_newfstatat, sys_newfstatat), // 293
1008 LINX_(__NR_unlinkat, sys_unlinkat), // 294
1010 LINX_(__NR_renameat, sys_renameat), // 295
1011 LINX_(__NR_linkat, sys_linkat), // 296
1012 LINX_(__NR_symlinkat, sys_symlinkat), // 297
1013 LINX_(__NR_readlinkat, sys_readlinkat), // 298
1014 LINX_(__NR_fchmodat, sys_fchmodat), // 299
1016 LINX_(__NR_faccessat, sys_faccessat), // 300
1017 LINX_(__NR_pselect6, sys_pselect6), // 301
1018 LINXY(__NR_ppoll, sys_ppoll), // 302
1019 // ?????(__NR_unshare, ),
1020 LINX_(__NR_set_robust_list, sys_set_robust_list), // 304
1022 LINXY(__NR_get_robust_list, sys_get_robust_list), // 305
1023 // ?????(__NR_splice, ),
1024 LINX_(__NR_sync_file_range, sys_sync_file_range), // 307
1025 // ?????(__NR_tee, ),
1026 // ?????(__NR_vmsplice, ),
1028 GENX_(310, sys_ni_syscall), /* unimplemented (by the kernel) */ // 310
1029 // ?????(__NR_getcpu, ),
1030 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 312
1031 GENX_(__NR_utimes, sys_utimes), // 313
1032 LINX_(__NR_fallocate, sys_fallocate), // 314
1034 LINX_(__NR_utimensat, sys_utimensat), // 315
1035 LINXY(__NR_signalfd, sys_signalfd), // 316
1036 GENX_(317, sys_ni_syscall), /* unimplemented (by the kernel) */ // 317
1037 LINX_(__NR_eventfd, sys_eventfd), // 318
1038 LINXY(__NR_timerfd_create, sys_timerfd_create), // 319
1040 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 320
1041 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 321
1042 LINXY(__NR_signalfd4, sys_signalfd4), // 322
1043 LINX_(__NR_eventfd2, sys_eventfd2), // 323
1044 LINXY(__NR_inotify_init1, sys_inotify_init1), // 324
1046 LINXY(__NR_pipe2, sys_pipe2), // 325
1048 LINXY(__NR_epoll_create1, sys_epoll_create1), // 327
1049 LINXY(__NR_preadv, sys_preadv), // 328
1050 LINX_(__NR_pwritev, sys_pwritev), // 329
1052 // ?????(__NR_rt_tgsigqueueinfo, ),
1053 LINXY(__NR_perf_event_open, sys_perf_event_open), // 331
1054 // ?????(__NR_fanotify_init, ), // 332
1055 // ?????(__NR_fanotify_mark, ), // 333
1056 LINXY(__NR_prlimit64, sys_prlimit64), // 334
1057 // ?????(__NR_name_to_handle_at, ), // 335
1058 // ?????(__NR_open_by_handle_at, ), // 336
1059 // ?????(__NR_clock_adjtime, ), // 337
1060 // ?????(__NR_syncfs, ), // 338
1061 // ?????(__NR_setns, ), // 339
1062 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 340
1063 LINX_(__NR_process_vm_writev, sys_process_vm_writev), // 341
1066 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1068 const UInt syscall_table_size
1069 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1071 /* Is it in the contiguous initial section of the table? */
1072 if (sysno < syscall_table_size) {
1073 SyscallTableEntry* sys = &syscall_table[sysno];
1074 if (sys->before == NULL)
1075 return NULL; /* no entry */
1080 /* Can't find a wrapper */
1086 /*--------------------------------------------------------------------*/
1088 /*--------------------------------------------------------------------*/