blob: 664c6ffa2493ef3cc3f287827edb31beb9816524 [file] [log] [blame]
sewardjb5b87402011-03-07 16:05:35 +00001
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
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright IBM Corp. 2010-2013
sewardjb5b87402011-03-07 16:05:35 +000011
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"
sewardj6c591e12011-04-11 16:17:51 +000037#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
sewardjb5b87402011-03-07 16:05:35 +000038#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))
76void 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*/
86asm(
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
cborntra441570b2012-10-08 20:26:48 +0000126 int* tls address in r6
sewardjb5b87402011-03-07 16:05:35 +0000127 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
143extern
144ULong do_syscall_clone_s390x_linux ( void *stack,
145 ULong flags,
sewardjb5b87402011-03-07 16:05:35 +0000146 Int *parent_tid,
cborntra441570b2012-10-08 20:26:48 +0000147 Int *child_tid,
sewardjb5b87402011-03-07 16:05:35 +0000148 Addr tlsaddr,
149 Word (*fn)(void *),
150 void *arg);
151asm(
152 " .text\n"
153 " .align 4\n"
philippe9fdca562012-04-16 22:06:47 +0000154 ".globl do_syscall_clone_s390x_linux\n"
sewardjb5b87402011-03-07 16:05:35 +0000155 "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
182void VG_(cleanup_thread) ( ThreadArchState* arch )
183{
184 /* only used on x86 for descriptor tables */
185}
186
187static 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 */
207static 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. */
bart9a2b80d2012-03-25 17:51:59 +0000291 vg_assert(VG_(owns_BigLock_LL)(ptid));
sewardjb5b87402011-03-07 16:05:35 +0000292 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(
cborntra441570b2012-10-08 20:26:48 +0000307 stack, flags, parent_tidptr, child_tidptr, tlsaddr,
sewardjb5b87402011-03-07 16:05:35 +0000308 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
341DECL_TEMPLATE(s390x_linux, sys_ptrace);
sewardjb5b87402011-03-07 16:05:35 +0000342DECL_TEMPLATE(s390x_linux, sys_mmap);
sewardjb5b87402011-03-07 16:05:35 +0000343DECL_TEMPLATE(s390x_linux, sys_clone);
344DECL_TEMPLATE(s390x_linux, sys_sigreturn);
345DECL_TEMPLATE(s390x_linux, sys_rt_sigreturn);
346DECL_TEMPLATE(s390x_linux, sys_fadvise64);
347
cborntrae48a4442012-11-08 20:10:10 +0000348/* 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
sewardjb5b87402011-03-07 16:05:35 +0000355PRE(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 }
cborntrae48a4442012-11-08 20:10:10 +0000410 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;
sewardjb5b87402011-03-07 16:05:35 +0000416 default:
417 break;
418 }
419}
420
421POST(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);
cborntrae48a4442012-11-08 20:10:10 +0000444 break;
sewardjb5b87402011-03-07 16:05:35 +0000445 }
cborntrae48a4442012-11-08 20:10:10 +0000446 case VKI_PTRACE_GETREGSET:
447 ML_(linux_POST_getregset)(tid, ARG3, ARG4);
448 break;
sewardjb5b87402011-03-07 16:05:35 +0000449 default:
450 break;
451 }
452}
453
sewardjb5b87402011-03-07 16:05:35 +0000454PRE(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
sewardjb5b87402011-03-07 16:05:35 +0000477PRE(sys_clone)
478{
479 UInt cloneflags;
480
481 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4, ARG5);
florian44bf0662011-09-13 14:57:35 +0000482 PRE_REG_READ2(int, "clone",
sewardjb5b87402011-03-07 16:05:35 +0000483 void *, child_stack,
florian44bf0662011-09-13 14:57:35 +0000484 unsigned long, flags);
sewardjb5b87402011-03-07 16:05:35 +0000485
486 if (ARG2 & VKI_CLONE_PARENT_SETTID) {
florian44bf0662011-09-13 14:57:35 +0000487 if (VG_(tdict).track_pre_reg_read)
488 PRA3("clone(parent_tidptr)", int *, parent_tidptr);
sewardjb5b87402011-03-07 16:05:35 +0000489 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)) {
florian44bf0662011-09-13 14:57:35 +0000497 if (VG_(tdict).track_pre_reg_read)
498 PRA4("clone(child_tidptr)", int *, child_tidptr);
sewardjb5b87402011-03-07 16:05:35 +0000499 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
cborntraf9a16d42012-05-28 11:51:50 +0000507 /* 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
sewardjb5b87402011-03-07 16:05:35 +0000514 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
570PRE(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
598PRE(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 */
629PRE(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
655static 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
philippef2a7bbe2012-11-04 20:40:33 +0000778 LINXY(__NR_socketcall, sys_socketcall), // 102
sewardjb5b87402011-03-07 16:05:35 +0000779 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
philippe4eefc8c2012-10-21 20:21:17 +0000796 LINXY(__NR_ipc, sys_ipc), // 117
sewardjb5b87402011-03-07 16:05:35 +0000797 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
cborntrac2212182014-02-27 13:46:02 +0000849 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 162
sewardjb5b87402011-03-07 16:05:35 +0000850 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, ),
tom5ba95302011-08-10 09:57:27 +0000917 GENXY(__NR_mincore, sys_mincore), // 218
sewardjb5b87402011-03-07 16:05:35 +0000918 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
cborntrac2212182014-02-27 13:46:02 +00001023 LINX_(__NR_splice, sys_splice), // 306
sewardjb5b87402011-03-07 16:05:35 +00001024 LINX_(__NR_sync_file_range, sys_sync_file_range), // 307
cborntrac2212182014-02-27 13:46:02 +00001025 LINX_(__NR_tee, sys_tee), // 308
1026 LINXY(__NR_vmsplice, sys_vmsplice), // 309
sewardjb5b87402011-03-07 16:05:35 +00001027
1028 GENX_(310, sys_ni_syscall), /* unimplemented (by the kernel) */ // 310
cborntrac2212182014-02-27 13:46:02 +00001029 LINXY(__NR_getcpu, sys_getcpu), // 311
sewardjb5b87402011-03-07 16:05:35 +00001030 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
tom4f5be8c2014-01-30 21:47:30 +00001037 LINXY(__NR_eventfd, sys_eventfd), // 318
sewardjb5b87402011-03-07 16:05:35 +00001038 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
tom4f5be8c2014-01-30 21:47:30 +00001043 LINXY(__NR_eventfd2, sys_eventfd2), // 323
sewardjb5b87402011-03-07 16:05:35 +00001044 LINXY(__NR_inotify_init1, sys_inotify_init1), // 324
1045
1046 LINXY(__NR_pipe2, sys_pipe2), // 325
mjw417e1032014-02-20 15:43:07 +00001047 LINXY(__NR_dup3, sys_dup3), // 326
sewardjb5b87402011-03-07 16:05:35 +00001048 LINXY(__NR_epoll_create1, sys_epoll_create1), // 327
1049 LINXY(__NR_preadv, sys_preadv), // 328
1050 LINX_(__NR_pwritev, sys_pwritev), // 329
1051
cborntrac2212182014-02-27 13:46:02 +00001052 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo), // 330
tom50bd6bf2011-06-08 20:55:29 +00001053 LINXY(__NR_perf_event_open, sys_perf_event_open), // 331
cborntrac2212182014-02-27 13:46:02 +00001054 LINXY(__NR_fanotify_init, sys_fanotify_init), // 332
1055 LINX_(__NR_fanotify_mark, sys_fanotify_mark), // 333
florianb46d7ad2012-02-15 03:32:50 +00001056 LINXY(__NR_prlimit64, sys_prlimit64), // 334
cborntrac2212182014-02-27 13:46:02 +00001057
1058 LINXY(__NR_name_to_handle_at, sys_name_to_handle_at), // 335
1059 LINXY(__NR_open_by_handle_at, sys_open_by_handle_at), // 336
tomddc4a182014-01-30 22:33:02 +00001060 LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 337
florianb46d7ad2012-02-15 03:32:50 +00001061// ?????(__NR_syncfs, ), // 338
1062// ?????(__NR_setns, ), // 339
cborntrac2212182014-02-27 13:46:02 +00001063
florianb46d7ad2012-02-15 03:32:50 +00001064 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 340
1065 LINX_(__NR_process_vm_writev, sys_process_vm_writev), // 341
sewardjb5b87402011-03-07 16:05:35 +00001066};
1067
1068SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1069{
1070 const UInt syscall_table_size
1071 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1072
1073 /* Is it in the contiguous initial section of the table? */
1074 if (sysno < syscall_table_size) {
1075 SyscallTableEntry* sys = &syscall_table[sysno];
1076 if (sys->before == NULL)
1077 return NULL; /* no entry */
1078 else
1079 return sys;
1080 }
1081
1082 /* Can't find a wrapper */
1083 return NULL;
1084}
1085
1086#endif
1087
1088/*--------------------------------------------------------------------*/
1089/*--- end ---*/
1090/*--------------------------------------------------------------------*/