1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-amd64-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2015 Nicholas Nethercote
11 njn@valgrind.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #if defined(VGP_amd64_linux)
32
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_threadstate.h"
37 #include "pub_core_aspacemgr.h"
38 #include "pub_core_debuglog.h"
39 #include "pub_core_options.h"
40 #include "pub_core_libcbase.h"
41 #include "pub_core_libcassert.h"
42 #include "pub_core_libcprint.h"
43 #include "pub_core_libcproc.h"
44 #include "pub_core_libcsignal.h"
45 #include "pub_core_scheduler.h"
46 #include "pub_core_sigframe.h"
47 #include "pub_core_signals.h"
48 #include "pub_core_syscall.h"
49 #include "pub_core_syswrap.h"
50 #include "pub_core_tooliface.h"
51
52 #include "priv_types_n_macros.h"
53 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
54 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
55 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
56 #include "priv_syswrap-main.h"
57
58
59 /* ---------------------------------------------------------------------
60 clone() handling
61 ------------------------------------------------------------------ */
62
63 /* Call f(arg1), but first switch stacks, using 'stack' as the new
64 stack, and use 'retaddr' as f's return-to address. Also, clear all
65 the integer registers before entering f. */
66 __attribute__((noreturn))
67 void ML_(call_on_new_stack_0_1) ( Addr stack,
68 Addr retaddr,
69 void (*f)(Word),
70 Word arg1 );
71 // %rdi == stack
72 // %rsi == retaddr
73 // %rdx == f
74 // %rcx == arg1
75 asm(
76 ".text\n"
77 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
78 "vgModuleLocal_call_on_new_stack_0_1:\n"
79 " movq %rdi, %rsp\n" // set stack
80 " pushq %rsi\n" // retaddr to stack
81 " pushq %rdx\n" // f to stack
82 " pushq %rcx\n" // arg1 to stack
83 " movq $0, %rax\n" // zero all GP regs
84 " movq $0, %rbx\n"
85 " movq $0, %rcx\n"
86 " movq $0, %rdx\n"
87 " movq $0, %rsi\n"
88 " movq $0, %rdi\n"
89 " movq $0, %rbp\n"
90 " movq $0, %r8\n"
91 " movq $0, %r9\n"
92 " movq $0, %r10\n"
93 " movq $0, %r11\n"
94 " movq $0, %r12\n"
95 " movq $0, %r13\n"
96 " movq $0, %r14\n"
97 " movq $0, %r15\n"
98 " popq %rdi\n" // arg1 to correct arg reg
99 " ret\n" // jump to f
100 " ud2\n" // should never get here
101 ".previous\n"
102 );
103
104 /*
105 Perform a clone system call. clone is strange because it has
106 fork()-like return-twice semantics, so it needs special
107 handling here.
108
109 Upon entry, we have:
110
111 int (*fn)(void*) in %rdi
112 void* child_stack in %rsi
113 int flags in %rdx
114 void* arg in %rcx
115 pid_t* child_tid in %r8
116 pid_t* parent_tid in %r9
117 void* tls_ptr at 8(%rsp)
118
119 System call requires:
120
121 int $__NR_clone in %rax
122 int flags in %rdi
123 void* child_stack in %rsi
124 pid_t* parent_tid in %rdx
125 pid_t* child_tid in %r10
126 void* tls_ptr in %r8
127
128 Returns a Long encoded in the linux-amd64 way, not a SysRes.
129 */
130 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
131 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
132
133 extern
134 Long do_syscall_clone_amd64_linux ( Word (*fn)(void *),
135 void* stack,
136 Long flags,
137 void* arg,
138 Long* child_tid,
139 Long* parent_tid,
140 vki_modify_ldt_t * );
141 asm(
142 ".text\n"
143 ".globl do_syscall_clone_amd64_linux\n"
144 "do_syscall_clone_amd64_linux:\n"
145 // set up child stack, temporarily preserving fn and arg
146 " subq $16, %rsi\n" // make space on stack
147 " movq %rcx, 8(%rsi)\n" // save arg
148 " movq %rdi, 0(%rsi)\n" // save fn
149
150 // setup syscall
151 " movq $"__NR_CLONE", %rax\n" // syscall number
152 " movq %rdx, %rdi\n" // syscall arg1: flags
153 // %rsi already setup // syscall arg2: child_stack
154 " movq %r9, %rdx\n" // syscall arg3: parent_tid
155 " movq %r8, %r10\n" // syscall arg4: child_tid
156 " movq 8(%rsp), %r8\n" // syscall arg5: tls_ptr
157
158 " syscall\n" // clone()
159
160 " testq %rax, %rax\n" // child if retval == 0
161 " jnz 1f\n"
162
163 // CHILD - call thread function
164 " pop %rax\n" // pop fn
165 " pop %rdi\n" // pop fn arg1: arg
166 " call *%rax\n" // call fn
167
168 // exit with result
169 " movq %rax, %rdi\n" // arg1: return value from fn
170 " movq $"__NR_EXIT", %rax\n"
171
172 " syscall\n"
173
174 // Exit returned?!
175 " ud2\n"
176
177 "1:\n" // PARENT or ERROR
178 " ret\n"
179 ".previous\n"
180 );
181
182 #undef __NR_CLONE
183 #undef __NR_EXIT
184
185
186 // forward declaration
187 static void setup_child ( ThreadArchState*, ThreadArchState* );
188
189 /*
190 When a client clones, we need to keep track of the new thread. This means:
191 1. allocate a ThreadId+ThreadState+stack for the thread
192
193 2. initialize the thread's new VCPU state
194
195 3. create the thread using the same args as the client requested,
196 but using the scheduler entrypoint for EIP, and a separate stack
197 for ESP.
198 */
do_clone(ThreadId ptid,ULong flags,Addr rsp,Long * parent_tidptr,Long * child_tidptr,Addr tlsaddr)199 static SysRes do_clone ( ThreadId ptid,
200 ULong flags, Addr rsp,
201 Long* parent_tidptr,
202 Long* child_tidptr,
203 Addr tlsaddr )
204 {
205 static const Bool debug = False;
206
207 ThreadId ctid = VG_(alloc_ThreadState)();
208 ThreadState* ptst = VG_(get_ThreadState)(ptid);
209 ThreadState* ctst = VG_(get_ThreadState)(ctid);
210 UWord* stack;
211 SysRes res;
212 Long rax;
213 vki_sigset_t blockall, savedmask;
214
215 VG_(sigfillset)(&blockall);
216
217 vg_assert(VG_(is_running_thread)(ptid));
218 vg_assert(VG_(is_valid_tid)(ctid));
219
220 stack = (UWord*)ML_(allocstack)(ctid);
221 if (stack == NULL) {
222 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
223 goto out;
224 }
225
226 /* Copy register state
227
228 Both parent and child return to the same place, and the code
229 following the clone syscall works out which is which, so we
230 don't need to worry about it.
231
232 The parent gets the child's new tid returned from clone, but the
233 child gets 0.
234
235 If the clone call specifies a NULL rsp for the new thread, then
236 it actually gets a copy of the parent's rsp.
237 */
238 setup_child( &ctst->arch, &ptst->arch );
239
240 /* Make sys_clone appear to have returned Success(0) in the
241 child. */
242 ctst->arch.vex.guest_RAX = 0;
243
244 if (rsp != 0)
245 ctst->arch.vex.guest_RSP = rsp;
246
247 ctst->os_state.parent = ptid;
248
249 /* inherit signal mask */
250 ctst->sig_mask = ptst->sig_mask;
251 ctst->tmp_sig_mask = ptst->sig_mask;
252
253 /* Start the child with its threadgroup being the same as the
254 parent's. This is so that any exit_group calls that happen
255 after the child is created but before it sets its
256 os_state.threadgroup field for real (in thread_wrapper in
257 syswrap-linux.c), really kill the new thread. a.k.a this avoids
258 a race condition in which the thread is unkillable (via
259 exit_group) because its threadgroup is not set. The race window
260 is probably only a few hundred or a few thousand cycles long.
261 See #226116. */
262 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
263
264 ML_(guess_and_register_stack) (rsp, ctst);
265
266 /* Assume the clone will succeed, and tell any tool that wants to
267 know that this thread has come into existence. If the clone
268 fails, we'll send out a ll_exit notification for it at the out:
269 label below, to clean up. */
270 vg_assert(VG_(owns_BigLock_LL)(ptid));
271 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
272
273 if (flags & VKI_CLONE_SETTLS) {
274 if (debug)
275 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
276 ctst->arch.vex.guest_FS_CONST = tlsaddr;
277 }
278
279 flags &= ~VKI_CLONE_SETTLS;
280
281 /* start the thread with everything blocked */
282 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
283
284 /* Create the new thread */
285 rax = do_syscall_clone_amd64_linux(
286 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
287 child_tidptr, parent_tidptr, NULL
288 );
289 res = VG_(mk_SysRes_amd64_linux)( rax );
290
291 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
292
293 out:
294 if (sr_isError(res)) {
295 /* clone failed */
296 VG_(cleanup_thread)(&ctst->arch);
297 ctst->status = VgTs_Empty;
298 /* oops. Better tell the tool the thread exited in a hurry :-) */
299 VG_TRACK( pre_thread_ll_exit, ctid );
300 }
301
302 return res;
303 }
304
305
306 /* ---------------------------------------------------------------------
307 More thread stuff
308 ------------------------------------------------------------------ */
309
VG_(cleanup_thread)310 void VG_(cleanup_thread) ( ThreadArchState *arch )
311 {
312 }
313
setup_child(ThreadArchState * child,ThreadArchState * parent)314 void setup_child ( /*OUT*/ ThreadArchState *child,
315 /*IN*/ ThreadArchState *parent )
316 {
317 /* We inherit our parent's guest state. */
318 child->vex = parent->vex;
319 child->vex_shadow1 = parent->vex_shadow1;
320 child->vex_shadow2 = parent->vex_shadow2;
321 }
322
323
324 /* ---------------------------------------------------------------------
325 PRE/POST wrappers for AMD64/Linux-specific syscalls
326 ------------------------------------------------------------------ */
327
328 #define PRE(name) DEFN_PRE_TEMPLATE(amd64_linux, name)
329 #define POST(name) DEFN_POST_TEMPLATE(amd64_linux, name)
330
331 /* Add prototypes for the wrappers declared here, so that gcc doesn't
332 harass us for not having prototypes. Really this is a kludge --
333 the right thing to do is to make these wrappers 'static' since they
334 aren't visible outside this file, but that requires even more macro
335 magic. */
336 DECL_TEMPLATE(amd64_linux, sys_clone);
337 DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
338 DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
339 DECL_TEMPLATE(amd64_linux, sys_ptrace);
340 DECL_TEMPLATE(amd64_linux, sys_fadvise64);
341 DECL_TEMPLATE(amd64_linux, sys_mmap);
342 DECL_TEMPLATE(amd64_linux, sys_syscall184);
343
344
PRE(sys_clone)345 PRE(sys_clone)
346 {
347 ULong cloneflags;
348
349 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
350 PRE_REG_READ2(int, "clone",
351 unsigned long, flags,
352 void *, child_stack);
353
354 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
355 if (VG_(tdict).track_pre_reg_read) {
356 PRA3("clone", int *, parent_tidptr);
357 }
358 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
359 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
360 SET_STATUS_Failure( VKI_EFAULT );
361 return;
362 }
363 }
364 if (ARG1 & VKI_CLONE_SETTLS) {
365 if (VG_(tdict).track_pre_reg_read) {
366 PRA4("clone", vki_modify_ldt_t *, tlsinfo);
367 }
368 PRE_MEM_READ("clone(tlsinfo)", ARG4, sizeof(vki_modify_ldt_t));
369 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
370 VKI_PROT_READ)) {
371 SET_STATUS_Failure( VKI_EFAULT );
372 return;
373 }
374 }
375 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
376 if (VG_(tdict).track_pre_reg_read) {
377 PRA5("clone", int *, child_tidptr);
378 }
379 PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
380 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
381 SET_STATUS_Failure( VKI_EFAULT );
382 return;
383 }
384 }
385
386 cloneflags = ARG1;
387
388 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
389 SET_STATUS_Failure( VKI_EINVAL );
390 return;
391 }
392
393 /* Only look at the flags we really care about */
394 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
395 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
396 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
397 /* thread creation */
398 SET_STATUS_from_SysRes(
399 do_clone(tid,
400 ARG1, /* flags */
401 (Addr)ARG2, /* child ESP */
402 (Long *)ARG3, /* parent_tidptr */
403 (Long *)ARG4, /* child_tidptr */
404 (Addr)ARG5)); /* set_tls */
405 break;
406
407 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
408 /* FALLTHROUGH - assume vfork == fork */
409 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
410
411 case 0: /* plain fork */
412 SET_STATUS_from_SysRes(
413 ML_(do_fork_clone)(tid,
414 cloneflags, /* flags */
415 (Int *)ARG3, /* parent_tidptr */
416 (Int *)ARG4)); /* child_tidptr */
417 break;
418
419 default:
420 /* should we just ENOSYS? */
421 VG_(message)(Vg_UserMsg,
422 "Unsupported clone() flags: 0x%lx\n", ARG1);
423 VG_(message)(Vg_UserMsg,
424 "\n");
425 VG_(message)(Vg_UserMsg,
426 "The only supported clone() uses are:\n");
427 VG_(message)(Vg_UserMsg,
428 " - via a threads library (LinuxThreads or NPTL)\n");
429 VG_(message)(Vg_UserMsg,
430 " - via the implementation of fork or vfork\n");
431 VG_(unimplemented)
432 ("Valgrind does not support general clone().");
433 }
434
435 if (SUCCESS) {
436 if (ARG1 & VKI_CLONE_PARENT_SETTID)
437 POST_MEM_WRITE(ARG3, sizeof(Int));
438 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
439 POST_MEM_WRITE(ARG4, sizeof(Int));
440
441 /* Thread creation was successful; let the child have the chance
442 to run */
443 *flags |= SfYieldAfter;
444 }
445 }
446
PRE(sys_rt_sigreturn)447 PRE(sys_rt_sigreturn)
448 {
449 /* This isn't really a syscall at all - it's a misuse of the
450 syscall mechanism by m_sigframe. VG_(sigframe_create) sets the
451 return address of the signal frames it creates to be a short
452 piece of code which does this "syscall". The only purpose of
453 the syscall is to call VG_(sigframe_destroy), which restores the
454 thread's registers from the frame and then removes it.
455 Consequently we must ask the syswrap driver logic not to write
456 back the syscall "result" as that would overwrite the
457 just-restored register state. */
458
459 ThreadState* tst;
460 PRINT("sys_rt_sigreturn ( )");
461
462 vg_assert(VG_(is_valid_tid)(tid));
463 vg_assert(tid >= 1 && tid < VG_N_THREADS);
464 vg_assert(VG_(is_running_thread)(tid));
465
466 /* Adjust RSP to point to start of frame; skip back up over handler
467 ret addr */
468 tst = VG_(get_ThreadState)(tid);
469 tst->arch.vex.guest_RSP -= sizeof(Addr);
470
471 /* This is only so that the RIP is (might be) useful to report if
472 something goes wrong in the sigreturn. JRS 20070318: no idea
473 what this is for */
474 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
475
476 /* Restore register state from frame and remove it, as
477 described above */
478 VG_(sigframe_destroy)(tid, True);
479
480 /* Tell the driver not to update the guest state with the "result",
481 and set a bogus result to keep it happy. */
482 *flags |= SfNoWriteResult;
483 SET_STATUS_Success(0);
484
485 /* Check to see if any signals arose as a result of this. */
486 *flags |= SfPollAfter;
487 }
488
PRE(sys_arch_prctl)489 PRE(sys_arch_prctl)
490 {
491 ThreadState* tst;
492 PRINT( "arch_prctl ( %ld, %lx )", SARG1, ARG2 );
493
494 vg_assert(VG_(is_valid_tid)(tid));
495 vg_assert(tid >= 1 && tid < VG_N_THREADS);
496 vg_assert(VG_(is_running_thread)(tid));
497
498 // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
499 PRE_REG_READ2(long, "arch_prctl",
500 int, option, unsigned long, arg2);
501 // XXX: totally wrong... we need to look at the 'option' arg, and do
502 // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
503
504 /* "do" the syscall ourselves; the kernel never sees it */
505 if (ARG1 == VKI_ARCH_SET_FS) {
506 tst = VG_(get_ThreadState)(tid);
507 tst->arch.vex.guest_FS_CONST = ARG2;
508 }
509 else if (ARG1 == VKI_ARCH_GET_FS) {
510 PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
511 tst = VG_(get_ThreadState)(tid);
512 *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_CONST;
513 POST_MEM_WRITE(ARG2, sizeof(unsigned long));
514 }
515 else if (ARG1 == VKI_ARCH_SET_GS) {
516 tst = VG_(get_ThreadState)(tid);
517 tst->arch.vex.guest_GS_CONST = ARG2;
518 }
519 else if (ARG1 == VKI_ARCH_GET_GS) {
520 PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
521 tst = VG_(get_ThreadState)(tid);
522 *(unsigned long *)ARG2 = tst->arch.vex.guest_GS_CONST;
523 POST_MEM_WRITE(ARG2, sizeof(unsigned long));
524 }
525 else {
526 VG_(core_panic)("Unsupported arch_prctl option");
527 }
528
529 /* Note; the Status writeback to guest state that happens after
530 this wrapper returns does not change guest_FS_CONST or guest_GS_CONST;
531 hence that direct assignment to the guest state is safe here. */
532 SET_STATUS_Success( 0 );
533 }
534
535 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
536 //
537 // ARG3 is only used for pointers into the traced process's address
538 // space and for offsets into the traced process's struct
539 // user_regs_struct. It is never a pointer into this process's memory
540 // space, and we should therefore not check anything it points to.
PRE(sys_ptrace)541 PRE(sys_ptrace)
542 {
543 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
544 PRE_REG_READ4(int, "ptrace",
545 long, request, long, pid, long, addr, long, data);
546 switch (ARG1) {
547 case VKI_PTRACE_PEEKTEXT:
548 case VKI_PTRACE_PEEKDATA:
549 case VKI_PTRACE_PEEKUSR:
550 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
551 sizeof (long));
552 break;
553 case VKI_PTRACE_GETREGS:
554 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
555 sizeof (struct vki_user_regs_struct));
556 break;
557 case VKI_PTRACE_GETFPREGS:
558 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
559 sizeof (struct vki_user_i387_struct));
560 break;
561 case VKI_PTRACE_SETREGS:
562 PRE_MEM_READ( "ptrace(setregs)", ARG4,
563 sizeof (struct vki_user_regs_struct));
564 break;
565 case VKI_PTRACE_SETFPREGS:
566 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
567 sizeof (struct vki_user_i387_struct));
568 break;
569 case VKI_PTRACE_GETEVENTMSG:
570 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
571 break;
572 case VKI_PTRACE_GETSIGINFO:
573 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
574 break;
575 case VKI_PTRACE_SETSIGINFO:
576 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
577 break;
578 case VKI_PTRACE_GETREGSET:
579 ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
580 break;
581 case VKI_PTRACE_SETREGSET:
582 ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
583 break;
584 default:
585 break;
586 }
587 }
588
POST(sys_ptrace)589 POST(sys_ptrace)
590 {
591 switch (ARG1) {
592 case VKI_PTRACE_PEEKTEXT:
593 case VKI_PTRACE_PEEKDATA:
594 case VKI_PTRACE_PEEKUSR:
595 POST_MEM_WRITE( ARG4, sizeof (long));
596 break;
597 case VKI_PTRACE_GETREGS:
598 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
599 break;
600 case VKI_PTRACE_GETFPREGS:
601 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
602 break;
603 case VKI_PTRACE_GETEVENTMSG:
604 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
605 break;
606 case VKI_PTRACE_GETSIGINFO:
607 /* XXX: This is a simplification. Different parts of the
608 * siginfo_t are valid depending on the type of signal.
609 */
610 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
611 break;
612 case VKI_PTRACE_GETREGSET:
613 ML_(linux_POST_getregset)(tid, ARG3, ARG4);
614 break;
615 default:
616 break;
617 }
618 }
619
PRE(sys_fadvise64)620 PRE(sys_fadvise64)
621 {
622 PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", SARG1, SARG2, ARG3, SARG4);
623 PRE_REG_READ4(long, "fadvise64",
624 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
625 }
626
PRE(sys_mmap)627 PRE(sys_mmap)
628 {
629 SysRes r;
630
631 PRINT("sys_mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )",
632 ARG1, ARG2, SARG3, SARG4, SARG5, SARG6 );
633 PRE_REG_READ6(long, "mmap",
634 unsigned long, start, unsigned long, length,
635 int, prot, int, flags, int, fd, vki_off_t, offset);
636
637 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
638 SET_STATUS_from_SysRes(r);
639 }
640
641
642 /* ---------------------------------------------------------------
643 PRE/POST wrappers for AMD64/Linux-variant specific syscalls
644 ------------------------------------------------------------ */
645
PRE(sys_syscall184)646 PRE(sys_syscall184)
647 {
648 Int err;
649
650 /* 184 is used by sys_bproc. If we're not on a declared bproc
651 variant, fail in the usual way, since it is otherwise unused. */
652
653 if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
654 PRINT("non-existent syscall! (syscall 184)");
655 PRE_REG_READ0(long, "ni_syscall(184)");
656 SET_STATUS_Failure( VKI_ENOSYS );
657 return;
658 }
659
660 err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
661 ARG4, ARG5, ARG6 );
662 if (err) {
663 SET_STATUS_Failure( err );
664 return;
665 }
666 /* Let it go through. */
667 *flags |= SfMayBlock; /* who knows? play safe. */
668 }
669
POST(sys_syscall184)670 POST(sys_syscall184)
671 {
672 ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
673 ARG4, ARG5, ARG6 );
674 }
675
676 #undef PRE
677 #undef POST
678
679
680 /* ---------------------------------------------------------------------
681 The AMD64/Linux syscall table
682 ------------------------------------------------------------------ */
683
684 /* Add an amd64-linux specific wrapper to a syscall table. */
685 #define PLAX_(const, name) WRAPPER_ENTRY_X_(amd64_linux, const, name)
686 #define PLAXY(const, name) WRAPPER_ENTRY_XY(amd64_linux, const, name)
687
688 // This table maps from __NR_xxx syscall numbers (from
689 // linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
690 // wrappers on AMD64 (as per sys_call_table in
691 // linux/arch/x86_64/kernel/entry.S).
692 //
693 // When implementing these wrappers, you need to work out if the wrapper is
694 // generic, Linux-only (but arch-independent), or AMD64/Linux only.
695
696 static SyscallTableEntry syscall_table[] = {
697 GENXY(__NR_read, sys_read), // 0
698 GENX_(__NR_write, sys_write), // 1
699 GENXY(__NR_open, sys_open), // 2
700 GENXY(__NR_close, sys_close), // 3
701 GENXY(__NR_stat, sys_newstat), // 4
702
703 GENXY(__NR_fstat, sys_newfstat), // 5
704 GENXY(__NR_lstat, sys_newlstat), // 6
705 GENXY(__NR_poll, sys_poll), // 7
706 LINX_(__NR_lseek, sys_lseek), // 8
707 PLAX_(__NR_mmap, sys_mmap), // 9
708
709 GENXY(__NR_mprotect, sys_mprotect), // 10
710 GENXY(__NR_munmap, sys_munmap), // 11
711 GENX_(__NR_brk, sys_brk), // 12
712 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 13
713 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 14
714
715 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 15
716 LINXY(__NR_ioctl, sys_ioctl), // 16
717 GENXY(__NR_pread64, sys_pread64), // 17
718 GENX_(__NR_pwrite64, sys_pwrite64), // 18
719 GENXY(__NR_readv, sys_readv), // 19
720
721 GENX_(__NR_writev, sys_writev), // 20
722 GENX_(__NR_access, sys_access), // 21
723 LINXY(__NR_pipe, sys_pipe), // 22
724 GENX_(__NR_select, sys_select), // 23
725 LINX_(__NR_sched_yield, sys_sched_yield), // 24
726
727 GENX_(__NR_mremap, sys_mremap), // 25
728 GENX_(__NR_msync, sys_msync), // 26
729 GENXY(__NR_mincore, sys_mincore), // 27
730 GENX_(__NR_madvise, sys_madvise), // 28
731 LINX_(__NR_shmget, sys_shmget), // 29
732
733 LINXY(__NR_shmat, wrap_sys_shmat), // 30
734 LINXY(__NR_shmctl, sys_shmctl), // 31
735 GENXY(__NR_dup, sys_dup), // 32
736 GENXY(__NR_dup2, sys_dup2), // 33
737 GENX_(__NR_pause, sys_pause), // 34
738
739 GENXY(__NR_nanosleep, sys_nanosleep), // 35
740 GENXY(__NR_getitimer, sys_getitimer), // 36
741 GENX_(__NR_alarm, sys_alarm), // 37
742 GENXY(__NR_setitimer, sys_setitimer), // 38
743 GENX_(__NR_getpid, sys_getpid), // 39
744
745 LINXY(__NR_sendfile, sys_sendfile), // 40
746 LINXY(__NR_socket, sys_socket), // 41
747 LINX_(__NR_connect, sys_connect), // 42
748 LINXY(__NR_accept, sys_accept), // 43
749 LINX_(__NR_sendto, sys_sendto), // 44
750
751 LINXY(__NR_recvfrom, sys_recvfrom), // 45
752 LINX_(__NR_sendmsg, sys_sendmsg), // 46
753 LINXY(__NR_recvmsg, sys_recvmsg), // 47
754 LINX_(__NR_shutdown, sys_shutdown), // 48
755 LINX_(__NR_bind, sys_bind), // 49
756
757 LINX_(__NR_listen, sys_listen), // 50
758 LINXY(__NR_getsockname, sys_getsockname), // 51
759 LINXY(__NR_getpeername, sys_getpeername), // 52
760 LINXY(__NR_socketpair, sys_socketpair), // 53
761 LINX_(__NR_setsockopt, sys_setsockopt), // 54
762
763 LINXY(__NR_getsockopt, sys_getsockopt), // 55
764 PLAX_(__NR_clone, sys_clone), // 56
765 GENX_(__NR_fork, sys_fork), // 57
766 GENX_(__NR_vfork, sys_fork), // 58 treat as fork
767 GENX_(__NR_execve, sys_execve), // 59
768
769 GENX_(__NR_exit, sys_exit), // 60
770 GENXY(__NR_wait4, sys_wait4), // 61
771 GENX_(__NR_kill, sys_kill), // 62
772 GENXY(__NR_uname, sys_newuname), // 63
773 LINX_(__NR_semget, sys_semget), // 64
774
775 LINX_(__NR_semop, sys_semop), // 65
776 LINXY(__NR_semctl, sys_semctl), // 66
777 LINXY(__NR_shmdt, sys_shmdt), // 67
778 LINX_(__NR_msgget, sys_msgget), // 68
779 LINX_(__NR_msgsnd, sys_msgsnd), // 69
780
781 LINXY(__NR_msgrcv, sys_msgrcv), // 70
782 LINXY(__NR_msgctl, sys_msgctl), // 71
783 LINXY(__NR_fcntl, sys_fcntl), // 72
784 GENX_(__NR_flock, sys_flock), // 73
785 GENX_(__NR_fsync, sys_fsync), // 74
786
787 GENX_(__NR_fdatasync, sys_fdatasync), // 75
788 GENX_(__NR_truncate, sys_truncate), // 76
789 GENX_(__NR_ftruncate, sys_ftruncate), // 77
790 GENXY(__NR_getdents, sys_getdents), // 78
791 GENXY(__NR_getcwd, sys_getcwd), // 79
792
793 GENX_(__NR_chdir, sys_chdir), // 80
794 GENX_(__NR_fchdir, sys_fchdir), // 81
795 GENX_(__NR_rename, sys_rename), // 82
796 GENX_(__NR_mkdir, sys_mkdir), // 83
797 GENX_(__NR_rmdir, sys_rmdir), // 84
798
799 GENXY(__NR_creat, sys_creat), // 85
800 GENX_(__NR_link, sys_link), // 86
801 GENX_(__NR_unlink, sys_unlink), // 87
802 GENX_(__NR_symlink, sys_symlink), // 88
803 GENX_(__NR_readlink, sys_readlink), // 89
804
805 GENX_(__NR_chmod, sys_chmod), // 90
806 GENX_(__NR_fchmod, sys_fchmod), // 91
807 GENX_(__NR_chown, sys_chown), // 92
808 GENX_(__NR_fchown, sys_fchown), // 93
809 GENX_(__NR_lchown, sys_lchown), // 94
810
811 GENX_(__NR_umask, sys_umask), // 95
812 GENXY(__NR_gettimeofday, sys_gettimeofday), // 96
813 GENXY(__NR_getrlimit, sys_getrlimit), // 97
814 GENXY(__NR_getrusage, sys_getrusage), // 98
815 LINXY(__NR_sysinfo, sys_sysinfo), // 99
816
817 GENXY(__NR_times, sys_times), // 100
818 PLAXY(__NR_ptrace, sys_ptrace), // 101
819 GENX_(__NR_getuid, sys_getuid), // 102
820 LINXY(__NR_syslog, sys_syslog), // 103
821 GENX_(__NR_getgid, sys_getgid), // 104
822
823 GENX_(__NR_setuid, sys_setuid), // 105
824 GENX_(__NR_setgid, sys_setgid), // 106
825 GENX_(__NR_geteuid, sys_geteuid), // 107
826 GENX_(__NR_getegid, sys_getegid), // 108
827 GENX_(__NR_setpgid, sys_setpgid), // 109
828
829 GENX_(__NR_getppid, sys_getppid), // 110
830 GENX_(__NR_getpgrp, sys_getpgrp), // 111
831 GENX_(__NR_setsid, sys_setsid), // 112
832 GENX_(__NR_setreuid, sys_setreuid), // 113
833 GENX_(__NR_setregid, sys_setregid), // 114
834
835 GENXY(__NR_getgroups, sys_getgroups), // 115
836 GENX_(__NR_setgroups, sys_setgroups), // 116
837 LINX_(__NR_setresuid, sys_setresuid), // 117
838 LINXY(__NR_getresuid, sys_getresuid), // 118
839 LINX_(__NR_setresgid, sys_setresgid), // 119
840
841 LINXY(__NR_getresgid, sys_getresgid), // 120
842 GENX_(__NR_getpgid, sys_getpgid), // 121
843 LINX_(__NR_setfsuid, sys_setfsuid), // 122
844 LINX_(__NR_setfsgid, sys_setfsgid), // 123
845 GENX_(__NR_getsid, sys_getsid), // 124
846
847 LINXY(__NR_capget, sys_capget), // 125
848 LINX_(__NR_capset, sys_capset), // 126
849 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 127
850 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 128
851 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 129
852
853 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 130
854 GENXY(__NR_sigaltstack, sys_sigaltstack), // 131
855 LINX_(__NR_utime, sys_utime), // 132
856 GENX_(__NR_mknod, sys_mknod), // 133
857 // (__NR_uselib, sys_uselib), // 134
858
859 LINX_(__NR_personality, sys_personality), // 135
860 // (__NR_ustat, sys_ustat), // 136
861 GENXY(__NR_statfs, sys_statfs), // 137
862 GENXY(__NR_fstatfs, sys_fstatfs), // 138
863 // (__NR_sysfs, sys_sysfs), // 139
864
865 GENX_(__NR_getpriority, sys_getpriority), // 140
866 GENX_(__NR_setpriority, sys_setpriority), // 141
867 LINXY(__NR_sched_setparam, sys_sched_setparam), // 142
868 LINXY(__NR_sched_getparam, sys_sched_getparam), // 143
869 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 144
870
871 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 145
872 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 146
873 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 147
874 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 148
875 GENX_(__NR_mlock, sys_mlock), // 149
876
877 GENX_(__NR_munlock, sys_munlock), // 150
878 GENX_(__NR_mlockall, sys_mlockall), // 151
879 LINX_(__NR_munlockall, sys_munlockall), // 152
880 LINX_(__NR_vhangup, sys_vhangup), // 153
881 // (__NR_modify_ldt, sys_modify_ldt), // 154
882
883 LINX_(__NR_pivot_root, sys_pivot_root), // 155
884 LINXY(__NR__sysctl, sys_sysctl), // 156
885 LINXY(__NR_prctl, sys_prctl), // 157
886 PLAX_(__NR_arch_prctl, sys_arch_prctl), // 158
887 LINXY(__NR_adjtimex, sys_adjtimex), // 159
888
889 GENX_(__NR_setrlimit, sys_setrlimit), // 160
890 GENX_(__NR_chroot, sys_chroot), // 161
891 GENX_(__NR_sync, sys_sync), // 162
892 // (__NR_acct, sys_acct), // 163
893 GENX_(__NR_settimeofday, sys_settimeofday), // 164
894
895 LINX_(__NR_mount, sys_mount), // 165
896 LINX_(__NR_umount2, sys_umount), // 166
897 // (__NR_swapon, sys_swapon), // 167
898 // (__NR_swapoff, sys_swapoff), // 168
899 // (__NR_reboot, sys_reboot), // 169
900
901 GENX_(__NR_sethostname, sys_sethostname), // 170
902 // (__NR_setdomainname, sys_setdomainname), // 171
903 GENX_(__NR_iopl, sys_iopl), // 172
904 LINX_(__NR_ioperm, sys_ioperm), // 173
905 GENX_(__NR_create_module, sys_ni_syscall), // 174
906
907 LINX_(__NR_init_module, sys_init_module), // 175
908 LINX_(__NR_delete_module, sys_delete_module), // 176
909 // (__NR_get_kernel_syms, sys_ni_syscall), // 177
910 // (__NR_query_module, sys_ni_syscall), // 178
911 LINX_(__NR_quotactl, sys_quotactl), // 179
912
913 // (__NR_nfsservctl, sys_nfsservctl), // 180
914 // (__NR_getpmsg, sys_ni_syscall), // 181
915 // (__NR_putpmsg, sys_ni_syscall), // 182
916 // (__NR_afs_syscall, sys_ni_syscall), // 183
917 PLAXY(184, sys_syscall184), // 184 // sys_bproc?
918
919 // (__NR_security, sys_ni_syscall), // 185
920 LINX_(__NR_gettid, sys_gettid), // 186
921 LINX_(__NR_readahead, sys_readahead), // 187
922 LINX_(__NR_setxattr, sys_setxattr), // 188
923 LINX_(__NR_lsetxattr, sys_lsetxattr), // 189
924
925 LINX_(__NR_fsetxattr, sys_fsetxattr), // 190
926 LINXY(__NR_getxattr, sys_getxattr), // 191
927 LINXY(__NR_lgetxattr, sys_lgetxattr), // 192
928 LINXY(__NR_fgetxattr, sys_fgetxattr), // 193
929 LINXY(__NR_listxattr, sys_listxattr), // 194
930
931 LINXY(__NR_llistxattr, sys_llistxattr), // 195
932 LINXY(__NR_flistxattr, sys_flistxattr), // 196
933 LINX_(__NR_removexattr, sys_removexattr), // 197
934 LINX_(__NR_lremovexattr, sys_lremovexattr), // 198
935 LINX_(__NR_fremovexattr, sys_fremovexattr), // 199
936
937 LINXY(__NR_tkill, sys_tkill), // 200
938 GENXY(__NR_time, sys_time), /*was sys_time64*/ // 201
939 LINXY(__NR_futex, sys_futex), // 202
940 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
941 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
942
943 // (__NR_set_thread_area, sys_ni_syscall), // 205
944 LINXY(__NR_io_setup, sys_io_setup), // 206
945 LINX_(__NR_io_destroy, sys_io_destroy), // 207
946 LINXY(__NR_io_getevents, sys_io_getevents), // 208
947 LINX_(__NR_io_submit, sys_io_submit), // 209
948
949 LINXY(__NR_io_cancel, sys_io_cancel), // 210
950 // (__NR_get_thread_area, sys_ni_syscall), // 211
951 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 212
952 LINXY(__NR_epoll_create, sys_epoll_create), // 213
953 // (__NR_epoll_ctl_old, sys_ni_syscall), // 214
954
955 // (__NR_epoll_wait_old, sys_ni_syscall), // 215
956 // (__NR_remap_file_pages, sys_remap_file_pages)// 216
957 GENXY(__NR_getdents64, sys_getdents64), // 217
958 LINX_(__NR_set_tid_address, sys_set_tid_address),// 218
959 // (__NR_restart_syscall, sys_restart_syscall),// 219
960
961 LINX_(__NR_semtimedop, sys_semtimedop), // 220
962 PLAX_(__NR_fadvise64, sys_fadvise64), // 221
963 LINXY(__NR_timer_create, sys_timer_create), // 222
964 LINXY(__NR_timer_settime, sys_timer_settime), // 223
965 LINXY(__NR_timer_gettime, sys_timer_gettime), // 224
966
967 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 225
968 LINX_(__NR_timer_delete, sys_timer_delete), // 226
969 LINX_(__NR_clock_settime, sys_clock_settime), // 227
970 LINXY(__NR_clock_gettime, sys_clock_gettime), // 228
971 LINXY(__NR_clock_getres, sys_clock_getres), // 229
972
973 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// 230
974 LINX_(__NR_exit_group, sys_exit_group), // 231
975 LINXY(__NR_epoll_wait, sys_epoll_wait), // 232
976 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 233
977 LINXY(__NR_tgkill, sys_tgkill), // 234
978
979 GENX_(__NR_utimes, sys_utimes), // 235
980 // (__NR_vserver, sys_ni_syscall), // 236
981 LINX_(__NR_mbind, sys_mbind), // 237
982 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 238
983 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 239
984
985 LINXY(__NR_mq_open, sys_mq_open), // 240
986 LINX_(__NR_mq_unlink, sys_mq_unlink), // 241
987 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 242
988 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// 243
989 LINX_(__NR_mq_notify, sys_mq_notify), // 244
990
991 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 245
992 // (__NR_kexec_load, sys_ni_syscall), // 246
993 LINXY(__NR_waitid, sys_waitid), // 247
994 LINX_(__NR_add_key, sys_add_key), // 248
995 LINX_(__NR_request_key, sys_request_key), // 249
996
997 LINXY(__NR_keyctl, sys_keyctl), // 250
998 LINX_(__NR_ioprio_set, sys_ioprio_set), // 251
999 LINX_(__NR_ioprio_get, sys_ioprio_get), // 252
1000 LINX_(__NR_inotify_init, sys_inotify_init), // 253
1001 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
1002
1003 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 255
1004 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 256
1005 LINXY(__NR_openat, sys_openat), // 257
1006 LINX_(__NR_mkdirat, sys_mkdirat), // 258
1007 LINX_(__NR_mknodat, sys_mknodat), // 259
1008
1009 LINX_(__NR_fchownat, sys_fchownat), // 260
1010 LINX_(__NR_futimesat, sys_futimesat), // 261
1011 LINXY(__NR_newfstatat, sys_newfstatat), // 262
1012 LINX_(__NR_unlinkat, sys_unlinkat), // 263
1013 LINX_(__NR_renameat, sys_renameat), // 264
1014
1015 LINX_(__NR_linkat, sys_linkat), // 265
1016 LINX_(__NR_symlinkat, sys_symlinkat), // 266
1017 LINX_(__NR_readlinkat, sys_readlinkat), // 267
1018 LINX_(__NR_fchmodat, sys_fchmodat), // 268
1019 LINX_(__NR_faccessat, sys_faccessat), // 269
1020
1021 LINX_(__NR_pselect6, sys_pselect6), // 270
1022 LINXY(__NR_ppoll, sys_ppoll), // 271
1023 LINX_(__NR_unshare, sys_unshare), // 272
1024 LINX_(__NR_set_robust_list, sys_set_robust_list), // 273
1025 LINXY(__NR_get_robust_list, sys_get_robust_list), // 274
1026
1027 LINX_(__NR_splice, sys_splice), // 275
1028 LINX_(__NR_tee, sys_tee), // 276
1029 LINX_(__NR_sync_file_range, sys_sync_file_range), // 277
1030 LINXY(__NR_vmsplice, sys_vmsplice), // 278
1031 LINXY(__NR_move_pages, sys_move_pages), // 279
1032
1033 LINX_(__NR_utimensat, sys_utimensat), // 280
1034 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 281
1035 LINXY(__NR_signalfd, sys_signalfd), // 282
1036 LINXY(__NR_timerfd_create, sys_timerfd_create), // 283
1037 LINXY(__NR_eventfd, sys_eventfd), // 284
1038
1039 LINX_(__NR_fallocate, sys_fallocate), // 285
1040 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 286
1041 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 287
1042 LINXY(__NR_accept4, sys_accept4), // 288
1043 LINXY(__NR_signalfd4, sys_signalfd4), // 289
1044
1045 LINXY(__NR_eventfd2, sys_eventfd2), // 290
1046 LINXY(__NR_epoll_create1, sys_epoll_create1), // 291
1047 LINXY(__NR_dup3, sys_dup3), // 292
1048 LINXY(__NR_pipe2, sys_pipe2), // 293
1049 LINXY(__NR_inotify_init1, sys_inotify_init1), // 294
1050
1051 LINXY(__NR_preadv, sys_preadv), // 295
1052 LINX_(__NR_pwritev, sys_pwritev), // 296
1053 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
1054 LINXY(__NR_perf_event_open, sys_perf_event_open), // 298
1055 LINXY(__NR_recvmmsg, sys_recvmmsg), // 299
1056
1057 LINXY(__NR_fanotify_init, sys_fanotify_init), // 300
1058 LINX_(__NR_fanotify_mark, sys_fanotify_mark), // 301
1059 LINXY(__NR_prlimit64, sys_prlimit64), // 302
1060 LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 303
1061 LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 304
1062
1063 LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 305
1064 LINX_(__NR_syncfs, sys_syncfs), // 306
1065 LINXY(__NR_sendmmsg, sys_sendmmsg), // 307
1066 // LINX_(__NR_setns, sys_ni_syscall), // 308
1067 LINXY(__NR_getcpu, sys_getcpu), // 309
1068
1069 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 310
1070 LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 311
1071 LINX_(__NR_kcmp, sys_kcmp), // 312
1072 // LIN__(__NR_finit_module, sys_ni_syscall), // 313
1073 // LIN__(__NR_sched_setattr, sys_ni_syscall), // 314
1074
1075 // LIN__(__NR_sched_getattr, sys_ni_syscall), // 315
1076 // LIN__(__NR_renameat2, sys_ni_syscall), // 316
1077 // LIN__(__NR_seccomp, sys_ni_syscall), // 317
1078 LINXY(__NR_getrandom, sys_getrandom), // 318
1079 LINXY(__NR_memfd_create, sys_memfd_create) // 319
1080
1081 // LIN__(__NR_kexec_file_load, sys_ni_syscall), // 320
1082 // LIN__(__NR_bpf, sys_ni_syscall) // 321
1083 };
1084
ML_(get_linux_syscall_entry)1085 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1086 {
1087 const UInt syscall_table_size
1088 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1089
1090 /* Is it in the contiguous initial section of the table? */
1091 if (sysno < syscall_table_size) {
1092 SyscallTableEntry* sys = &syscall_table[sysno];
1093 if (sys->before == NULL)
1094 return NULL; /* no entry */
1095 else
1096 return sys;
1097 }
1098
1099 /* Can't find a wrapper */
1100 return NULL;
1101 }
1102
1103 #endif // defined(VGP_amd64_linux)
1104
1105 /*--------------------------------------------------------------------*/
1106 /*--- end ---*/
1107 /*--------------------------------------------------------------------*/
1108