8bbdf3dfe1870af3aeaf650f8a6d390684d18ae2
[sdk/tools/upstream/valgrind.git] / coregrind / m_syswrap / syswrap-s390x-linux.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff.      syswrap-s390x-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright IBM Corp. 2010-2013
11
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.
16
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.
21
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
25    02111-1307, USA.
26
27    The GNU General Public License is contained in the file COPYING.
28 */
29
30 /* Contributed by Christian Borntraeger */
31
32 #if defined(VGP_s390x_linux)
33
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)
55
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"
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    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,
77                                   Addr retaddr,
78                                   void (*f)(Word),
79                                   Word arg1 );
80 /* Upon entering this function we have the following setup:
81      r2 = stack
82      r3 = retaddr
83      r4 = f_desc
84      r5 = arg1
85 */
86 asm(
87     ".text\n"
88     ".align 4\n"
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
96     "   lghi  %r0,0\n"
97     "   lghi  %r1,0\n"
98     // r2 holds the argument for the callee
99     "   lghi  %r3,0\n"
100     // r4 holds the callee address
101     "   lghi  %r5,0\n"
102     "   lghi  %r6,0\n"
103     "   lghi  %r7,0\n"
104     "   lghi  %r8,0\n"
105     "   lghi  %r9,0\n"
106     "   lghi  %r10,0\n"
107     "   lghi  %r11,0\n"
108     "   lghi  %r12,0\n"
109     "   lghi  %r13,0\n"
110     // r14 holds the return address for the callee
111     // r15 is the stack pointer
112     "   br  %r4\n"          // jump to f
113     ".previous\n"
114     );
115
116 /*
117         Perform a clone system call.  clone is strange because it has
118         fork()-like return-twice semantics, so it needs special
119         handling here.
120
121         Upon entry, we have:
122             void*  child_stack   in r2
123             long   flags         in r3
124             int*   parent_tid    in r4
125             int*   child_tid     in r5
126             int*   tls address   in r6
127             Word   (*fn)(void *) 160(r15)
128             void   *arg          168(r15)
129
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)
136
137         Returns a ULong encoded as: top half is %cr following syscall,
138         low half is syscall return value (r3).
139  */
140 #define __NR_CLONE        VG_STRINGIFY(__NR_clone)
141 #define __NR_EXIT         VG_STRINGIFY(__NR_exit)
142
143 extern
144 ULong do_syscall_clone_s390x_linux ( void  *stack,
145                                      ULong flags,
146                                      Int   *parent_tid,
147                                      Int   *child_tid,
148                                      Addr  tlsaddr,
149                                      Word (*fn)(void *),
150                                      void  *arg);
151 asm(
152    "   .text\n"
153    "   .align  4\n"
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
162    "   jne   1f\n"
163
164    // CHILD - call thread function
165    "   lgr   %r2, %r0\n"            // get arg from r0
166    "   basr  %r14,%r1\n"            // call fn
167
168    // exit. The result is already in r2
169    "   svc " __NR_EXIT"\n"
170
171    // Exit returned?!
172    "   j +2\n"
173
174    "1:\n"  // PARENT or ERROR
175    "   br %r14\n"
176    ".previous\n"
177 );
178
179 #undef __NR_CLONE
180 #undef __NR_EXIT
181
182 void VG_(cleanup_thread) ( ThreadArchState* arch )
183 {
184   /* only used on x86 for descriptor tables */
185 }
186
187 static void setup_child ( /*OUT*/ ThreadArchState *child,
188                    /*IN*/  ThreadArchState *parent )
189 {
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;
194 }
195
196
197 /*
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
200
201    2. initialize the thread's new VCPU state
202
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
205    for SP.
206  */
207 static SysRes do_clone ( ThreadId ptid,
208                          Addr sp, ULong flags,
209                          Int *parent_tidptr,
210                          Int *child_tidptr,
211                          Addr tlsaddr)
212 {
213    static const Bool debug = False;
214
215    ThreadId     ctid = VG_(alloc_ThreadState)();
216    ThreadState* ptst = VG_(get_ThreadState)(ptid);
217    ThreadState* ctst = VG_(get_ThreadState)(ctid);
218    UWord*       stack;
219    NSegment const* seg;
220    SysRes       res;
221    ULong        r2;
222    vki_sigset_t blockall, savedmask;
223
224    VG_(sigfillset)(&blockall);
225
226    vg_assert(VG_(is_running_thread)(ptid));
227    vg_assert(VG_(is_valid_tid)(ctid));
228
229    stack = (UWord*)ML_(allocstack)(ctid);
230    if (stack == NULL) {
231       res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
232       goto out;
233    }
234
235    /* Copy register state
236
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.
240
241       The parent gets the child's new tid returned from clone, but the
242       child gets 0.
243
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.
246    */
247    setup_child( &ctst->arch, &ptst->arch );
248
249    /* Make sys_clone appear to have returned Success(0) in the
250       child. */
251    ctst->arch.vex.guest_r2 = 0;
252
253    if (sp != 0)
254       ctst->arch.vex.guest_r15 = sp;
255
256    ctst->os_state.parent = ptid;
257
258    /* inherit signal mask */
259    ctst->sig_mask = ptst->sig_mask;
260    ctst->tmp_sig_mask = ptst->sig_mask;
261
262    /* have the parents thread group */
263    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
264
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;
274
275       VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
276
277       if (debug)
278          VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
279                      ctid, seg->start, VG_PGROUNDUP(sp));
280    } else {
281       VG_(message)(Vg_UserMsg,
282                    "!? New thread %d starts with SP(%#lx) unmapped\n",
283                    ctid, sp);
284       ctst->client_stack_szB  = 0;
285    }
286
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 );
293
294    if (flags & VKI_CLONE_SETTLS) {
295       if (debug)
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;
299    }
300    flags &= ~VKI_CLONE_SETTLS;
301
302    /* start the thread with everything blocked */
303    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
304
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]);
309
310    res = VG_(mk_SysRes_s390x_linux)( r2 );
311
312    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
313
314   out:
315    if (sr_isError(res)) {
316       /* clone failed */
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 );
320    }
321
322    return res;
323
324 }
325
326
327
328 /* ---------------------------------------------------------------------
329    PRE/POST wrappers for s390x/Linux-specific syscalls
330    ------------------------------------------------------------------ */
331
332 #define PRE(name)       DEFN_PRE_TEMPLATE(s390x_linux, name)
333 #define POST(name)      DEFN_POST_TEMPLATE(s390x_linux, name)
334
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
339    magic. */
340
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);
347
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
351    instead of ARG4.
352    GETREGSET and SETREGSET use a struct iovec (pointed to by ARG4) for
353    the address and size of the user buffer. */
354
355 PRE(sys_ptrace)
356 {
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);
360    switch (ARG1) {
361    case VKI_PTRACE_PEEKTEXT:
362    case VKI_PTRACE_PEEKDATA:
363    case VKI_PTRACE_PEEKUSR:
364       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
365                      sizeof (long));
366       break;
367    case VKI_PTRACE_GETEVENTMSG:
368       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
369       break;
370    case VKI_PTRACE_GETSIGINFO:
371       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
372       break;
373    case VKI_PTRACE_SETSIGINFO:
374       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
375       break;
376    case VKI_PTRACE_PEEKUSR_AREA:
377       {
378          vki_ptrace_area *pa;
379
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);
390          break;
391       }
392    case VKI_PTRACE_POKEUSR_AREA:
393       {
394          vki_ptrace_area *pa;
395
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);
408          break;
409       }
410    case VKI_PTRACE_GETREGSET:
411       ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
412       break;
413    case VKI_PTRACE_SETREGSET:
414       ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
415       break;
416    default:
417       break;
418    }
419 }
420
421 POST(sys_ptrace)
422 {
423    switch (ARG1) {
424    case VKI_PTRACE_PEEKTEXT:
425    case VKI_PTRACE_PEEKDATA:
426    case VKI_PTRACE_PEEKUSR:
427       POST_MEM_WRITE( ARG4, sizeof (long));
428       break;
429    case VKI_PTRACE_GETEVENTMSG:
430       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
431       break;
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.
435        */
436       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
437       break;
438    case VKI_PTRACE_PEEKUSR_AREA:
439       {
440          vki_ptrace_area *pa;
441
442          pa = (vki_ptrace_area *) ARG3;
443          POST_MEM_WRITE(pa->vki_process_addr, pa->vki_len);
444          break;
445       }
446    case VKI_PTRACE_GETREGSET:
447       ML_(linux_POST_getregset)(tid, ARG3, ARG4);
448       break;
449    default:
450       break;
451    }
452 }
453
454 PRE(sys_mmap)
455 {
456    UWord a0, a1, a2, a3, a4, a5;
457    SysRes r;
458
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) );
462
463    a0 = args[0];
464    a1 = args[1];
465    a2 = args[2];
466    a3 = args[3];
467    a4 = args[4];
468    a5 = args[5];
469
470    PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
471          a0, (ULong)a1, a2, a3, a4, a5 );
472
473    r = ML_(generic_PRE_sys_mmap)( tid, a0, a1, a2, a3, a4, (Off64T)a5 );
474    SET_STATUS_from_SysRes(r);
475 }
476
477 PRE(sys_clone)
478 {
479    UInt cloneflags;
480
481    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4, ARG5);
482    PRE_REG_READ2(int, "clone",
483                  void *,        child_stack,
484                  unsigned long, flags);
485
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),
491                                              VKI_PROT_WRITE)) {
492          SET_STATUS_Failure( VKI_EFAULT );
493          return;
494       }
495    }
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),
501                                              VKI_PROT_WRITE)) {
502          SET_STATUS_Failure( VKI_EFAULT );
503          return;
504       }
505    }
506
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);
511       }
512    }
513
514    cloneflags = ARG2;
515
516    if (!ML_(client_signal_OK)(ARG2 & VKI_CSIGNAL)) {
517       SET_STATUS_Failure( VKI_EINVAL );
518       return;
519    }
520
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(
527          do_clone(tid,
528                   (Addr)ARG1,   /* child SP */
529                   ARG2,         /* flags */
530                   (Int *)ARG3,  /* parent_tidptr */
531                   (Int *)ARG4, /* child_tidptr */
532                   (Addr)ARG5)); /*  tlsaddr */
533       break;
534
535    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
536       /* FALLTHROUGH - assume vfork == fork */
537       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
538
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 */
545       break;
546
547    default:
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");
554       VG_(unimplemented)
555          ("Valgrind does not support general clone().");
556    }
557
558    if (SUCCESS) {
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));
563
564       /* Thread creation was successful; let the child have the chance
565          to run */
566       *flags |= SfYieldAfter;
567    }
568 }
569
570 PRE(sys_sigreturn)
571 {
572    ThreadState* tst;
573    PRINT("sys_sigreturn ( )");
574
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));
578
579    tst = VG_(get_ThreadState)(tid);
580
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);
584
585    /* Restore register state from frame and remove it */
586    VG_(sigframe_destroy)(tid, False);
587
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);
592
593    /* Check to see if any signals arose as a result of this. */
594    *flags |= SfPollAfter;
595 }
596
597
598 PRE(sys_rt_sigreturn)
599 {
600    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
601       an explanation of what follows. */
602
603    ThreadState* tst;
604    PRINT("sys_rt_sigreturn ( )");
605
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));
609
610    tst = VG_(get_ThreadState)(tid);
611
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);
615
616    /* Restore register state from frame and remove it */
617    VG_(sigframe_destroy)(tid, True);
618
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);
623
624    /* Check to see if any signals arose as a result of this. */
625    *flags |= SfPollAfter;
626 }
627
628 /* we cant use the LINX_ version for 64 bit */
629 PRE(sys_fadvise64)
630 {
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);
634 }
635
636 #undef PRE
637 #undef POST
638
639 /* ---------------------------------------------------------------------
640    The s390x/Linux syscall table
641    ------------------------------------------------------------------ */
642
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)
646
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), ?/?
653 // (unknown).
654
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
661
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
667
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
673
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
679
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
685
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
691
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
697
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
703
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
709
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
715
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
721
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
727
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
733
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
739
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
745
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
751
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
757
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
763
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
769
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
775
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
781
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
787
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
793
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
799
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
805
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
811
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
817
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
823
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
829
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
835
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
841
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
847
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
853
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
859
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
865
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
871
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
877
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
883
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
889
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
895
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
901
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
907
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
913
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
919
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
925
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
931
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
937
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
943
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
949
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
955
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
961
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
967
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
973
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
979
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
985
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
991
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
997
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
1003
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
1009
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
1015
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
1021
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, ),
1027
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
1033
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
1039
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
1045
1046    LINXY(__NR_pipe2,  sys_pipe2),                                     // 325
1047    // (__NR_dup3,  ),
1048    LINXY(__NR_epoll_create1,  sys_epoll_create1),                     // 327
1049    LINXY(__NR_preadv, sys_preadv),                                    // 328
1050    LINX_(__NR_pwritev, sys_pwritev),                                  // 329
1051
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
1064 };
1065
1066 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1067 {
1068    const UInt syscall_table_size
1069       = sizeof(syscall_table) / sizeof(syscall_table[0]);
1070
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 */
1076       else
1077          return sys;
1078    }
1079
1080    /* Can't find a wrapper */
1081    return NULL;
1082 }
1083
1084 #endif
1085
1086 /*--------------------------------------------------------------------*/
1087 /*--- end                                                          ---*/
1088 /*--------------------------------------------------------------------*/