2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-nanomips-linux.c ----*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2017-2018 RT-RK
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, see <http://www.gnu.org/licenses/>.
25 The GNU General Public License is contained in the file COPYING.
28 #if defined(VGP_nanomips_linux)
29 #include "pub_core_basics.h"
30 #include "pub_core_vki.h"
31 #include "pub_core_vkiscnums.h"
32 #include "pub_core_threadstate.h"
33 #include "pub_core_aspacemgr.h"
34 #include "pub_core_debuglog.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_libcassert.h"
37 #include "pub_core_libcprint.h"
38 #include "pub_core_libcproc.h"
39 #include "pub_core_libcsignal.h"
40 #include "pub_core_options.h"
41 #include "pub_core_scheduler.h"
42 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
43 #include "pub_core_signals.h"
44 #include "pub_core_syscall.h"
45 #include "pub_core_syswrap.h"
46 #include "pub_core_tooliface.h"
47 #include "pub_core_transtab.h" // VG_(discard_translations)
48 #include "priv_types_n_macros.h"
49 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
50 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
51 #include "priv_syswrap-main.h"
53 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
54 #include "pub_core_xarray.h"
55 #include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit)
56 #include "pub_core_errormgr.h"
57 #include "pub_core_gdbserver.h" // VG_(gdbserver)
58 #include "pub_core_libcfile.h"
59 #include "pub_core_machine.h" // VG_(get_SP)
60 #include "pub_core_mallocfree.h"
61 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
62 #include "pub_core_ume.h"
63 #include "priv_syswrap-generic.h"
68 /* ---------------------------------------------------------------------
70 ------------------------------------------------------------------ */
71 /* Call f(arg1), but first switch stacks, using 'stack' as the new
72 stack, and use 'retaddr' as f's return-to address. Also, clear all
73 the integer registers before entering f.*/
75 __attribute__ ((noreturn
))
76 void ML_ (call_on_new_stack_0_1
) (Addr stack
, Addr retaddr
,
77 void (*f
) (Word
), Word arg1
);
84 ".globl vgModuleLocal_call_on_new_stack_0_1 \n"
85 "vgModuleLocal_call_on_new_stack_0_1: \n"
86 " move $sp, $a0 \n\t" // stack to $sp
87 " move $ra, $a1 \n\t" // retaddr to $ra
88 " move $t9, $a2 \n\t" // f to t9
89 " move $a0, $a3 \n\t" // arg1 to $a0
90 " li $t4, 0 \n\t" // zero all GP regs
108 " jrc $t9 \n\t" // jump to dst
109 " break 0x7 \n" // should never get here
114 Perform a clone system call. clone is strange because it has
115 fork()-like return-twice semantics, so it needs special
118 int (fn)(void*) in $a0 0
119 void* child_stack in $a1 4
122 pid_t* child_tid in $a4 16
123 pid_t* parent_tid in $a5 20
124 void* tls_ptr in $a6 24
126 System call requires:
127 int $__NR_clone in $t4
129 void* child_stack in $a1 4
130 pid_t* parent_tid in $a2 8
131 void* tls_ptr in $a3 12
132 pid_t* child_tid in $a4 16
134 int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
135 void *parent_tidptr, void *tls, void *child_tidptr)
137 Returns an Int encoded in the linux-mips way, not a SysRes.
139 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
140 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
142 // See priv_syswrap-linux.h for arg profile.
147 " .globl do_syscall_clone_nanomips_linux \n"
148 " do_syscall_clone_nanomips_linux: \n\t"
149 " addiu $sp, $sp, -16 \n\t"
150 " sw $ra, 0($sp) \n\t"
151 " sw $fp, 4($sp) \n\t"
152 " sw $gp, 8($sp) \n\t"
154 " addiu $a1, $a1, -16 \n\t"
155 " sw $a0, 0($a1) \n\t" /* fn */
156 " sw $a3, 4($a1) \n\t" /* arg */
158 /* 1. arg for syscalls */
159 " move $a0, $a2 \n\t" /* flags */
160 " move $a2, $a5 \n\t" /* parent */
161 " move $a3, $a6 \n\t" /* tls */
163 /* 2. do a syscall to clone */
164 " li $t4, " __NR_CLONE
"\n\t" /* __NR_clone */
167 /* 3. See if we are a child, call fn and after that exit */
168 " bnezc $a0, p_or_error \n\t"
170 " lw $t9, 0($sp) \n\t"
171 " lw $a0, 4($sp) \n\t"
174 " li $t4, " __NR_EXIT
"\n\t" /* NR_exit */
177 /* 4. If we are parent or error, just return to caller */
179 " lw $ra, 0($sp) \n\t"
180 " lw $fp, 4($sp) \n\t"
181 " lw $gp, 8($sp) \n\t"
182 " addiu $sp, $sp, 16 \n\t"
191 // forward declarations
192 static SysRes
sys_set_tls (ThreadId tid
, Addr tlsptr
);
193 static SysRes
nanomips_PRE_sys_mmap (ThreadId tid
,
194 UWord arg1
, UWord arg2
, UWord arg3
,
195 UWord arg4
, UWord arg5
, Off64T arg6
);
196 /* ---------------------------------------------------------------------
198 ------------------------------------------------------------------ */
200 // MIPS doesn't have any architecture specific thread stuff that
201 // needs to be cleaned up
203 VG_ (cleanup_thread
) (ThreadArchState
* arch
) { }
205 SysRes
sys_set_tls ( ThreadId tid
, Addr tlsptr
)
207 VG_(threads
)[tid
].arch
.vex
.guest_ULR
= tlsptr
;
208 return VG_(mk_SysRes_Success
)( 0 );
211 /* ---------------------------------------------------------------------
212 mips handler for mmap and mmap2
213 ------------------------------------------------------------------ */
214 static void notify_core_of_mmap(Addr a
, SizeT len
, UInt prot
,
215 UInt flags
, Int fd
, Off64T offset
)
219 /* 'a' is the return value from a real kernel mmap, hence: */
220 vg_assert(VG_IS_PAGE_ALIGNED(a
));
221 /* whereas len is whatever the syscall supplied. So: */
222 len
= VG_PGROUNDUP(len
);
224 d
= VG_(am_notify_client_mmap
)( a
, len
, prot
, flags
, fd
, offset
);
227 VG_(discard_translations
)( a
, (ULong
)len
,
228 "notify_core_of_mmap" );
231 static void notify_tool_of_mmap(Addr a
, SizeT len
, UInt prot
, ULong di_handle
)
235 /* 'a' is the return value from a real kernel mmap, hence: */
236 vg_assert(VG_IS_PAGE_ALIGNED(a
));
237 /* whereas len is whatever the syscall supplied. So: */
238 len
= VG_PGROUNDUP(len
);
240 rr
= toBool(prot
& VKI_PROT_READ
);
241 ww
= toBool(prot
& VKI_PROT_WRITE
);
242 xx
= toBool(prot
& VKI_PROT_EXEC
);
244 VG_TRACK( new_mem_mmap
, a
, len
, rr
, ww
, xx
, di_handle
);
247 /* Based on ML_(generic_PRE_sys_mmap) from syswrap-generic.c.
248 If we are trying to do mmap with VKI_MAP_SHARED flag we need to align the
249 start address on VKI_SHMLBA like we did in
250 VG_(am_mmap_file_float_valgrind_flags)
252 static SysRes
nanomips_PRE_sys_mmap(ThreadId tid
,
253 UWord arg1
, UWord arg2
, UWord arg3
,
254 UWord arg4
, UWord arg5
, Off64T arg6
)
262 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
263 shall be established. */
264 return VG_(mk_SysRes_Error
)( VKI_EINVAL
);
267 if (!VG_IS_PAGE_ALIGNED(arg1
)) {
268 /* zap any misaligned addresses. */
269 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
270 to fail. Here, we catch them all. */
271 return VG_(mk_SysRes_Error
)( VKI_EINVAL
);
274 if (!VG_IS_PAGE_ALIGNED(arg6
)) {
275 /* zap any misaligned offsets. */
276 /* SuSV3 says: The off argument is constrained to be aligned and
277 sized according to the value returned by sysconf() when
278 passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
279 return VG_(mk_SysRes_Error
)( VKI_EINVAL
);
282 /* Figure out what kind of allocation constraints there are
283 (fixed/hint/any), and ask aspacem what we should do. */
287 if (arg4
& VKI_MAP_FIXED
) {
289 } else if (arg1
!= 0) {
295 if ((VKI_SHMLBA
> VKI_PAGE_SIZE
) && (VKI_MAP_SHARED
& arg4
)
296 && !(VKI_MAP_FIXED
& arg4
))
297 mreq
.len
= arg2
+ VKI_SHMLBA
- VKI_PAGE_SIZE
;
300 advised
= VG_(am_get_advisory
)( &mreq
, True
/*client*/, &mreq_ok
);
302 if ((VKI_SHMLBA
> VKI_PAGE_SIZE
) && (VKI_MAP_SHARED
& arg4
)
303 && !(VKI_MAP_FIXED
& arg4
))
304 advised
= VG_ROUNDUP(advised
, VKI_SHMLBA
);
307 /* Our request was bounced, so we'd better fail. */
308 return VG_(mk_SysRes_Error
)( VKI_EINVAL
);
311 /* Otherwise we're OK (so far). Install aspacem's choice of
312 address, and let the mmap go through. */
313 sres
= VG_(am_do_mmap_NO_NOTIFY
)(advised
, arg2
, arg3
,
314 arg4
| VKI_MAP_FIXED
,
317 /* A refinement: it may be that the kernel refused aspacem's choice
318 of address. If we were originally asked for a hinted mapping,
319 there is still a last chance: try again at any address.
321 if (mreq
.rkind
== MHint
&& sr_isError(sres
)) {
325 advised
= VG_(am_get_advisory
)( &mreq
, True
/*client*/, &mreq_ok
);
328 /* Our request was bounced, so we'd better fail. */
329 return VG_(mk_SysRes_Error
)( VKI_EINVAL
);
332 /* and try again with the kernel */
333 sres
= VG_(am_do_mmap_NO_NOTIFY
)(advised
, arg2
, arg3
,
334 arg4
| VKI_MAP_FIXED
,
338 if (!sr_isError(sres
)) {
340 /* Notify aspacem. */
342 (Addr
)sr_Res(sres
), /* addr kernel actually assigned */
345 arg4
, /* the original flags value */
350 di_handle
= VG_(di_notify_mmap
)( (Addr
)sr_Res(sres
),
351 False
/*allow_SkFileV*/, (Int
)arg5
);
352 /* Notify the tool. */
354 (Addr
)sr_Res(sres
), /* addr kernel actually assigned */
357 di_handle
/* so the tool can refer to the read debuginfo later,
363 if (!sr_isError(sres
) && (arg4
& VKI_MAP_FIXED
))
364 vg_assert(sr_Res(sres
) == arg1
);
368 /* ---------------------------------------------------------------------
369 PRE/POST wrappers for mips/Linux-specific syscalls
370 ------------------------------------------------------------------ */
371 #define PRE(name) DEFN_PRE_TEMPLATE(mips_linux, name)
372 #define POST(name) DEFN_POST_TEMPLATE(mips_linux, name)
374 /* Add prototypes for the wrappers declared here, so that gcc doesn't
375 harass us for not having prototypes. Really this is a kludge --
376 the right thing to do is to make these wrappers 'static' since they
377 aren't visible outside this file, but that requires even more macro
379 DECL_TEMPLATE (mips_linux
, sys_mmap2
);
380 DECL_TEMPLATE (mips_linux
, sys_rt_sigreturn
);
381 DECL_TEMPLATE (mips_linux
, sys_set_thread_area
);
382 DECL_TEMPLATE (mips_linux
, sys_ptrace
);
383 DECL_TEMPLATE (mips_linux
, sys_unshare
);
384 DECL_TEMPLATE (mips_linux
, sys_reboot
);
385 DECL_TEMPLATE (mips_linux
, sys_setdomainname
);
386 DECL_TEMPLATE (mips_linux
, sys_sethostname
);
387 DECL_TEMPLATE (mips_linux
, sys_swapon
);
388 DECL_TEMPLATE (mips_linux
, sys_swapoff
);
392 /* Exactly like sys_mmap() except the file offset is specified in 4096 byte
393 units rather than bytes, so that it can be used for files bigger than
396 PRINT("sys_mmap2 ( %#lx, %lu, %ld, %ld, %ld, %ld )",
397 ARG1
, ARG2
, SARG3
, SARG4
, SARG5
, SARG6
);
398 PRE_REG_READ6(long, "mmap2", unsigned long, start
, unsigned long, length
,
399 unsigned long, prot
, unsigned long, flags
,
400 unsigned long, fd
, unsigned long, offset
);
401 r
= nanomips_PRE_sys_mmap(tid
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
,
402 4096 * (Off64T
) ARG6
);
403 SET_STATUS_from_SysRes(r
);
408 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1
, SARG2
, ARG3
, ARG4
);
409 PRE_REG_READ4(int, "ptrace",
410 long, request
, long, pid
, unsigned long, addr
,
411 unsigned long, data
);
414 case VKI_PTRACE_PEEKTEXT
:
415 case VKI_PTRACE_PEEKDATA
:
416 case VKI_PTRACE_PEEKUSR
:
417 PRE_MEM_WRITE("ptrace(peek)", ARG4
, sizeof(long));
420 case VKI_PTRACE_GETEVENTMSG
:
421 PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4
, sizeof(unsigned long));
424 case VKI_PTRACE_GETSIGINFO
:
425 PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4
, sizeof(vki_siginfo_t
));
428 case VKI_PTRACE_SETSIGINFO
:
429 PRE_MEM_READ("ptrace(setsiginfo)", ARG4
, sizeof(vki_siginfo_t
));
432 case VKI_PTRACE_GETREGSET
:
433 ML_(linux_PRE_getregset
)(tid
, ARG3
, ARG4
);
444 case VKI_PTRACE_TRACEME
:
445 ML_(linux_POST_traceme
)(tid
);
448 case VKI_PTRACE_PEEKTEXT
:
449 case VKI_PTRACE_PEEKDATA
:
450 case VKI_PTRACE_PEEKUSR
:
451 POST_MEM_WRITE (ARG4
, sizeof(long));
454 case VKI_PTRACE_GETEVENTMSG
:
455 POST_MEM_WRITE (ARG4
, sizeof(unsigned long));
458 case VKI_PTRACE_GETSIGINFO
:
459 POST_MEM_WRITE (ARG4
, sizeof(vki_siginfo_t
));
462 case VKI_PTRACE_GETREGSET
:
463 ML_(linux_POST_getregset
)(tid
, ARG3
, ARG4
);
471 PRE(sys_rt_sigreturn
)
474 PRINT ("rt_sigreturn ( )");
475 vg_assert (VG_ (is_valid_tid
) (tid
));
476 vg_assert (tid
>= 1 && tid
< VG_N_THREADS
);
477 vg_assert (VG_ (is_running_thread
) (tid
));
479 tst
= VG_(get_ThreadState
)(tid
);
481 ML_(fixup_guest_state_to_restart_syscall
)(&tst
->arch
);
483 /* Restore register state from frame and remove it */
484 VG_ (sigframe_destroy
) (tid
, True
);
485 /* Tell the driver not to update the guest state with the "result",
486 and set a bogus result to keep it happy. */
487 *flags
|= SfNoWriteResult
;
488 SET_STATUS_Success (0);
489 /* Check to see if any signals arose as a result of this. */
490 *flags
|= SfPollAfter
;
493 PRE(sys_set_thread_area
)
495 PRINT ("set_thread_area (%lx)", ARG1
);
496 PRE_REG_READ1(long, "set_thread_area", unsigned long, addr
);
497 SET_STATUS_from_SysRes( sys_set_tls( tid
, ARG1
) );
502 PRINT("sys_unshare ( %lu )", ARG1
);
503 PRE_REG_READ1(long, "sys_unshare", unsigned long, flags
);
508 PRINT("sys_reboot ( %ld, %lu, %lu, %#lx )", SARG1
, ARG2
, ARG3
, ARG4
);
509 // An approximation. ARG4 is only read conditionally by the kernel
510 PRE_REG_READ4(int, "reboot",
511 int, magic1
, int, magic2
, unsigned int, cmd
,
514 *flags
|= SfMayBlock
;
517 PRE(sys_setdomainname
)
519 PRINT ("sys_setdomainname ( %#lx, %ld )", ARG1
, SARG2
);
520 PRE_REG_READ2 (long, "setdomainname", const void *, name
, int, len
);
525 PRINT ("sys_sethostname ( %#lx, %ld )", ARG1
, SARG2
);
526 PRE_REG_READ2 (long, "sethostname", const void *, name
, int, len
);
531 PRINT("sys_swapon ( %#lx, %#lx )", ARG1
, ARG2
);
532 PRE_REG_READ2(long, "swapon", const void *, path
, int, flags
);
537 PRINT("sys_swapoff ( %#lx )", ARG1
);
538 PRE_REG_READ1(long, "swapoff", const void *, path
);
544 /* ---------------------------------------------------------------------
545 The mips/Linux syscall table
546 ------------------------------------------------------------------ */
547 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(mips_linux, sysno, name)
548 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(mips_linux, sysno, name)
550 // This table maps from __NR_xxx syscall numbers (from
551 // linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo()
552 // wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S).
555 // For those syscalls not handled by Valgrind, the annotation indicate its
556 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
559 static SyscallTableEntry syscall_main_table
[] = {
560 LINXY (__NR_io_setup
, sys_io_setup
),
561 LINX_ (__NR_io_destroy
, sys_io_destroy
),
562 LINX_ (__NR_io_submit
, sys_io_submit
),
563 LINXY (__NR_io_cancel
, sys_io_cancel
),
564 LINXY (__NR_io_getevents
, sys_io_getevents
),
565 LINX_ (__NR_setxattr
, sys_setxattr
),
566 LINX_ (__NR_lsetxattr
, sys_lsetxattr
),
567 LINX_ (__NR_fsetxattr
, sys_fsetxattr
),
568 LINXY (__NR_getxattr
, sys_getxattr
),
569 LINXY (__NR_lgetxattr
, sys_lgetxattr
),
570 LINXY (__NR_fgetxattr
, sys_fgetxattr
),
571 LINXY (__NR_listxattr
, sys_listxattr
),
572 LINXY (__NR_llistxattr
, sys_llistxattr
),
573 LINXY (__NR_flistxattr
, sys_flistxattr
),
574 LINX_ (__NR_removexattr
, sys_removexattr
),
575 LINX_ (__NR_lremovexattr
, sys_lremovexattr
),
576 LINX_ (__NR_fremovexattr
, sys_fremovexattr
),
577 GENXY (__NR_getcwd
, sys_getcwd
),
578 LINXY (__NR_lookup_dcookie
, sys_lookup_dcookie
),
579 LINXY (__NR_eventfd2
, sys_eventfd2
),
580 LINXY (__NR_epoll_create1
, sys_epoll_create1
),
581 LINX_ (__NR_epoll_ctl
, sys_epoll_ctl
),
582 LINXY (__NR_epoll_pwait
, sys_epoll_pwait
),
583 GENXY (__NR_dup
, sys_dup
),
584 LINXY (__NR_dup3
, sys_dup3
),
585 LINXY (__NR_fcntl64
, sys_fcntl64
),
586 LINXY (__NR_inotify_init1
, sys_inotify_init1
),
587 LINX_ (__NR_inotify_add_watch
, sys_inotify_add_watch
),
588 LINX_ (__NR_inotify_rm_watch
, sys_inotify_rm_watch
),
589 LINXY (__NR_ioctl
, sys_ioctl
),
590 LINX_ (__NR_ioprio_set
, sys_ioprio_set
),
591 LINX_ (__NR_ioprio_get
, sys_ioprio_get
),
592 GENX_ (__NR_flock
, sys_flock
),
593 LINX_ (__NR_mknodat
, sys_mknodat
),
594 LINX_ (__NR_mkdirat
, sys_mkdirat
),
595 LINX_ (__NR_unlinkat
, sys_unlinkat
),
596 LINX_ (__NR_symlinkat
, sys_symlinkat
),
597 LINX_ (__NR_linkat
, sys_linkat
),
598 LINX_ (__NR_umount2
, sys_umount
),
599 LINX_ (__NR_mount
, sys_mount
),
600 LINX_ (__NR_pivot_root
, sys_pivot_root
),
601 GENX_ (__NR_truncate64
, sys_truncate64
),
602 GENX_ (__NR_ftruncate64
, sys_ftruncate64
),
603 LINX_ (__NR_fallocate
, sys_fallocate
),
604 LINX_ (__NR_faccessat
, sys_faccessat
),
605 GENX_ (__NR_chdir
, sys_chdir
),
606 GENX_ (__NR_fchdir
, sys_fchdir
),
607 GENX_ (__NR_chroot
, sys_chroot
),
608 GENX_ (__NR_fchmod
, sys_fchmod
),
609 LINX_ (__NR_fchmodat
, sys_fchmodat
),
610 LINX_ (__NR_fchownat
, sys_fchownat
),
611 GENX_ (__NR_fchown
, sys_fchown
),
612 LINXY (__NR_openat
, sys_openat
),
613 GENXY (__NR_close
, sys_close
),
614 LINX_ (__NR_vhangup
, sys_vhangup
),
615 LINXY (__NR_pipe2
, sys_pipe2
),
616 LINX_ (__NR_quotactl
, sys_quotactl
),
617 GENXY (__NR_getdents64
, sys_getdents64
),
618 LINXY (__NR__llseek
, sys_llseek
),
619 GENXY (__NR_read
, sys_read
),
620 GENX_ (__NR_write
, sys_write
),
621 GENXY (__NR_readv
, sys_readv
),
622 GENX_ (__NR_writev
, sys_writev
),
623 GENXY (__NR_pread64
, sys_pread64
),
624 GENX_ (__NR_pwrite64
, sys_pwrite64
),
625 LINXY (__NR_preadv
, sys_preadv
),
626 LINX_ (__NR_pwritev
, sys_pwritev
),
627 LINXY (__NR_sendfile64
, sys_sendfile64
),
628 LINXY (__NR_pselect6
, sys_pselect6
),
629 LINXY (__NR_ppoll
, sys_ppoll
),
630 LINXY (__NR_signalfd4
, sys_signalfd4
),
631 LINX_ (__NR_vmsplice
, sys_vmsplice
),
632 LINX_ (__NR_splice
, sys_splice
),
633 LINX_ (__NR_tee
, sys_tee
),
634 LINX_ (__NR_readlinkat
, sys_readlinkat
),
635 GENX_ (__NR_sync
, sys_sync
),
636 GENX_ (__NR_fsync
, sys_fsync
),
637 GENX_ (__NR_fdatasync
, sys_fdatasync
),
638 LINX_ (__NR_sync_file_range2
, sys_sync_file_range2
),
639 LINXY (__NR_timerfd_create
, sys_timerfd_create
),
640 LINXY (__NR_timerfd_settime
, sys_timerfd_settime
),
641 LINXY (__NR_timerfd_gettime
, sys_timerfd_gettime
),
642 LINX_ (__NR_utimensat
, sys_utimensat
),
643 GENX_ (__NR_acct
, sys_acct
),
644 LINXY (__NR_capget
, sys_capget
),
645 LINX_ (__NR_capset
, sys_capset
),
646 LINX_ (__NR_personality
, sys_personality
),
647 GENX_ (__NR_exit
, sys_exit
),
648 LINX_ (__NR_exit_group
, sys_exit_group
),
649 LINXY (__NR_waitid
, sys_waitid
),
650 LINX_ (__NR_set_tid_address
, sys_set_tid_address
),
651 PLAX_ (__NR_unshare
, sys_unshare
),
652 LINXY (__NR_futex
, sys_futex
),
653 LINX_ (__NR_set_robust_list
, sys_set_robust_list
),
654 LINXY (__NR_get_robust_list
, sys_get_robust_list
),
655 GENXY (__NR_nanosleep
, sys_nanosleep
),
656 GENXY (__NR_getitimer
, sys_getitimer
),
657 GENXY (__NR_setitimer
, sys_setitimer
),
658 GENX_ (__NR_kexec_load
, sys_ni_syscall
),
659 LINX_ (__NR_init_module
, sys_init_module
),
660 LINX_ (__NR_delete_module
, sys_delete_module
),
661 LINXY (__NR_timer_create
, sys_timer_create
),
662 LINXY (__NR_timer_gettime
, sys_timer_gettime
),
663 LINX_ (__NR_timer_getoverrun
, sys_timer_getoverrun
),
664 LINXY (__NR_timer_settime
, sys_timer_settime
),
665 LINX_ (__NR_timer_delete
, sys_timer_delete
),
666 LINX_ (__NR_clock_settime
, sys_clock_settime
),
667 LINXY (__NR_clock_gettime
, sys_clock_gettime
),
668 LINXY (__NR_clock_getres
, sys_clock_getres
),
669 LINXY (__NR_clock_nanosleep
, sys_clock_nanosleep
),
670 LINXY (__NR_syslog
, sys_syslog
),
671 PLAXY (__NR_ptrace
, sys_ptrace
),
672 LINXY (__NR_sched_setparam
, sys_sched_setparam
),
673 LINX_ (__NR_sched_setscheduler
, sys_sched_setscheduler
),
674 LINX_ (__NR_sched_getscheduler
, sys_sched_getscheduler
),
675 LINXY (__NR_sched_getparam
, sys_sched_getparam
),
676 LINX_ (__NR_sched_setaffinity
, sys_sched_setaffinity
),
677 LINXY (__NR_sched_getaffinity
, sys_sched_getaffinity
),
678 LINX_ (__NR_sched_yield
, sys_sched_yield
),
679 LINX_ (__NR_sched_get_priority_max
, sys_sched_get_priority_max
),
680 LINX_ (__NR_sched_get_priority_min
, sys_sched_get_priority_min
),
681 LINX_ (__NR_sched_rr_get_interval
, sys_sched_rr_get_interval
),
682 GENX_ (__NR_kill
, sys_kill
),
683 LINXY (__NR_tkill
, sys_tkill
),
684 LINXY (__NR_tgkill
, sys_tgkill
),
685 GENXY (__NR_sigaltstack
, sys_sigaltstack
),
686 LINX_ (__NR_rt_sigsuspend
, sys_rt_sigsuspend
),
687 LINXY (__NR_rt_sigaction
, sys_rt_sigaction
),
688 LINXY (__NR_rt_sigprocmask
, sys_rt_sigprocmask
),
689 LINXY (__NR_rt_sigpending
, sys_rt_sigpending
),
690 LINXY (__NR_rt_sigtimedwait
, sys_rt_sigtimedwait
),
691 LINXY (__NR_rt_sigqueueinfo
, sys_rt_sigqueueinfo
),
692 PLAX_ (__NR_rt_sigreturn
, sys_rt_sigreturn
),
693 GENX_ (__NR_setpriority
, sys_setpriority
),
694 GENX_ (__NR_getpriority
, sys_getpriority
),
695 PLAX_ (__NR_reboot
, sys_reboot
),
696 GENX_ (__NR_setregid
, sys_setregid
),
697 GENX_ (__NR_setgid
, sys_setgid
),
698 GENX_ (__NR_setreuid
, sys_setreuid
),
699 GENX_ (__NR_setuid
, sys_setuid
),
700 LINX_ (__NR_setresuid
, sys_setresuid
),
701 LINXY (__NR_getresuid
, sys_getresuid
),
702 LINX_ (__NR_setresgid
, sys_setresgid
),
703 LINXY (__NR_getresgid
, sys_getresgid
),
704 LINX_ (__NR_setfsuid
, sys_setfsuid
),
705 LINX_ (__NR_setfsgid
, sys_setfsgid
),
706 GENXY (__NR_times
, sys_times
),
707 GENX_ (__NR_setpgid
, sys_setpgid
),
708 GENX_ (__NR_getpgid
, sys_getpgid
),
709 GENX_ (__NR_getsid
, sys_getsid
),
710 GENX_ (__NR_setsid
, sys_setsid
),
711 GENXY (__NR_getgroups
, sys_getgroups
),
712 GENX_ (__NR_setgroups
, sys_setgroups
),
713 GENXY (__NR_uname
, sys_newuname
),
714 PLAX_ (__NR_sethostname
, sys_sethostname
),
715 PLAX_ (__NR_setdomainname
, sys_setdomainname
),
716 GENXY (__NR_getrusage
, sys_getrusage
),
717 GENX_ (__NR_umask
, sys_umask
),
718 LINXY (__NR_prctl
, sys_prctl
),
719 LINXY (__NR_getcpu
, sys_getcpu
),
720 GENXY (__NR_gettimeofday
, sys_gettimeofday
),
721 GENX_ (__NR_settimeofday
, sys_settimeofday
),
722 LINXY (__NR_adjtimex
, sys_adjtimex
),
723 GENX_ (__NR_getpid
, sys_getpid
),
724 GENX_ (__NR_getppid
, sys_getppid
),
725 GENX_ (__NR_getuid
, sys_getuid
),
726 GENX_ (__NR_geteuid
, sys_geteuid
),
727 GENX_ (__NR_getgid
, sys_getgid
),
728 GENX_ (__NR_getegid
, sys_getegid
),
729 LINX_ (__NR_gettid
, sys_gettid
),
730 LINXY (__NR_sysinfo
, sys_sysinfo
),
731 LINXY (__NR_mq_open
, sys_mq_open
),
732 LINX_ (__NR_mq_unlink
, sys_mq_unlink
),
733 LINX_ (__NR_mq_timedsend
, sys_mq_timedsend
),
734 LINXY (__NR_mq_timedreceive
, sys_mq_timedreceive
),
735 LINX_ (__NR_mq_notify
, sys_mq_notify
),
736 LINXY (__NR_mq_getsetattr
, sys_mq_getsetattr
),
737 LINX_ (__NR_msgget
, sys_msgget
),
738 LINXY (__NR_msgctl
, sys_msgctl
),
739 LINXY (__NR_msgrcv
, sys_msgrcv
),
740 LINX_ (__NR_msgsnd
, sys_msgsnd
),
741 LINX_ (__NR_semget
, sys_semget
),
742 LINXY (__NR_semctl
, sys_semctl
),
743 LINX_ (__NR_semtimedop
, sys_semtimedop
),
744 LINX_ (__NR_semop
, sys_semop
),
745 LINX_ (__NR_shmget
, sys_shmget
),
746 LINXY (__NR_shmctl
, sys_shmctl
),
747 LINXY (__NR_shmat
, sys_shmat
),
748 LINXY (__NR_shmdt
, sys_shmdt
),
749 LINXY (__NR_socket
, sys_socket
),
750 LINXY (__NR_socketpair
, sys_socketpair
),
751 LINX_ (__NR_bind
, sys_bind
),
752 LINX_ (__NR_listen
, sys_listen
),
753 LINXY (__NR_accept
, sys_accept
),
754 LINX_ (__NR_connect
, sys_connect
),
755 LINXY (__NR_getsockname
, sys_getsockname
),
756 LINXY (__NR_getpeername
, sys_getpeername
),
757 LINX_ (__NR_sendto
, sys_sendto
),
758 LINXY (__NR_recvfrom
, sys_recvfrom
),
759 LINX_ (__NR_setsockopt
, sys_setsockopt
),
760 LINXY (__NR_getsockopt
, sys_getsockopt
),
761 LINX_ (__NR_shutdown
, sys_shutdown
),
762 LINX_ (__NR_sendmsg
, sys_sendmsg
),
763 LINXY (__NR_recvmsg
, sys_recvmsg
),
764 LINX_ (__NR_readahead
, sys_readahead
),
765 GENX_ (__NR_brk
, sys_brk
),
766 GENXY (__NR_munmap
, sys_munmap
),
767 GENX_ (__NR_mremap
, sys_mremap
),
768 LINX_ (__NR_add_key
, sys_add_key
),
769 LINX_ (__NR_request_key
, sys_request_key
),
770 LINXY (__NR_keyctl
, sys_keyctl
),
771 LINX_ (__NR_clone
, sys_clone
),
772 GENX_ (__NR_execve
, sys_execve
),
773 PLAX_ (__NR_mmap2
, sys_mmap2
),
774 LINX_ (__NR_fadvise64_64
, sys_fadvise64_64
),
775 PLAX_ (__NR_swapon
, sys_swapon
),
776 PLAX_ (__NR_swapoff
, sys_swapoff
),
777 GENXY (__NR_mprotect
, sys_mprotect
),
778 GENX_ (__NR_msync
, sys_msync
),
779 GENX_ (__NR_mlock
, sys_mlock
),
780 GENX_ (__NR_munlock
, sys_munlock
),
781 GENX_ (__NR_mlockall
, sys_mlockall
),
782 LINX_ (__NR_munlockall
, sys_munlockall
),
783 GENXY (__NR_mincore
, sys_mincore
),
784 GENX_ (__NR_madvise
, sys_madvise
),
785 LINX_ (__NR_mbind
, sys_mbind
),
786 LINXY (__NR_get_mempolicy
, sys_get_mempolicy
),
787 LINX_ (__NR_set_mempolicy
, sys_set_mempolicy
),
788 LINXY (__NR_move_pages
, sys_move_pages
),
789 LINXY (__NR_rt_tgsigqueueinfo
, sys_rt_tgsigqueueinfo
),
790 LINXY (__NR_perf_event_open
, sys_perf_event_open
),
791 LINXY (__NR_accept4
, sys_accept4
),
792 LINXY (__NR_recvmmsg
, sys_recvmmsg
),
793 PLAX_ (__NR_set_thread_area
, sys_set_thread_area
),
794 GENXY (__NR_wait4
, sys_wait4
),
795 LINXY (__NR_prlimit64
, sys_prlimit64
),
796 LINXY (__NR_fanotify_init
, sys_fanotify_init
),
797 LINX_ (__NR_fanotify_mark
, sys_fanotify_mark
),
798 LINXY (__NR_name_to_handle_at
, sys_name_to_handle_at
),
799 LINXY (__NR_open_by_handle_at
, sys_open_by_handle_at
),
800 LINXY (__NR_clock_adjtime
, sys_clock_adjtime
),
801 LINX_ (__NR_syncfs
, sys_syncfs
),
802 LINXY (__NR_sendmmsg
, sys_sendmmsg
),
803 LINXY (__NR_process_vm_readv
, sys_process_vm_readv
),
804 LINX_ (__NR_process_vm_writev
, sys_process_vm_writev
),
805 LINX_ (__NR_kcmp
, sys_kcmp
),
806 LINX_ (__NR_renameat2
, sys_renameat2
),
807 LINX_ (__NR_sched_setattr
, sys_sched_setattr
),
808 LINXY (__NR_sched_getattr
, sys_sched_getattr
),
809 LINXY (__NR_getrandom
, sys_getrandom
),
810 LINXY (__NR_memfd_create
, sys_memfd_create
),
811 LINXY (__NR_statx
, sys_statx
),
812 LINX_ (__NR_setns
, sys_setns
),
813 // (__NR_bpf, sys_ni_syscall),
814 LINX_ (__NR_execveat
, sys_execveat
),
815 // (__NR_userfaultfd, sys_ni_syscall),
816 LINX_ (__NR_membarrier
, sys_membarrier
),
817 // (__NR_mlock2, sys_ni_syscall),
818 // (__NR_copy_file_range, sys_ni_syscall),
819 // (__NR_preadv2, sys_ni_syscall),
820 // (__NR_pwritev2, sys_ni_syscall),
821 // (__NR_pkey_mprotect, sys_ni_syscall),
822 // (__NR_pkey_alloc, sys_ni_syscall),
823 // (__NR_pkey_free, sys_ni_syscall),
824 LINXY (__NR_io_uring_setup
, sys_io_uring_setup
),
825 LINXY (__NR_io_uring_enter
, sys_io_uring_enter
),
826 LINXY (__NR_io_uring_register
, sys_io_uring_register
),
827 GENX_ (__NR_clone3
, sys_ni_syscall
),
828 LINX_ (__NR_faccessat2
, sys_faccessat2
),
831 SyscallTableEntry
* ML_(get_linux_syscall_entry
) (UInt sysno
)
833 const UInt syscall_main_table_size
834 = sizeof (syscall_main_table
) / sizeof (syscall_main_table
[0]);
836 /* Is it in the contiguous initial section of the table? */
837 if (sysno
< syscall_main_table_size
) {
838 SyscallTableEntry
* sys
= &syscall_main_table
[sysno
];
840 if (sys
->before
== NULL
)
841 return NULL
; /* No entry. */
846 /* Can't find a wrapper. */
850 #endif // defined(VGP_nanomips_linux)
852 /*--------------------------------------------------------------------*/
853 /*--- end syswrap-nanomips-linux.c ---*/
854 /*--------------------------------------------------------------------*/