4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) 2013-2014 Stacey D. Son
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "qemu/cutils.h"
22 #include "qemu/path.h"
23 #include <sys/syscall.h>
24 #include <sys/cdefs.h>
25 #include <sys/param.h>
26 #include <sys/mount.h>
27 #include <sys/sysctl.h>
30 #include "include/gdbstub/syscalls.h"
33 #include "signal-common.h"
34 #include "user/syscall-trace.h"
36 /* BSD independent syscall shims */
40 /* BSD dependent syscall shims */
46 safe_syscall3(int, open
, const char *, path
, int, flags
, mode_t
, mode
);
47 safe_syscall4(int, openat
, int, fd
, const char *, path
, int, flags
, mode_t
,
50 safe_syscall3(ssize_t
, read
, int, fd
, void *, buf
, size_t, nbytes
);
51 safe_syscall4(ssize_t
, pread
, int, fd
, void *, buf
, size_t, nbytes
, off_t
,
53 safe_syscall3(ssize_t
, readv
, int, fd
, const struct iovec
*, iov
, int, iovcnt
);
54 safe_syscall4(ssize_t
, preadv
, int, fd
, const struct iovec
*, iov
, int, iovcnt
,
57 safe_syscall3(ssize_t
, write
, int, fd
, void *, buf
, size_t, nbytes
);
58 safe_syscall4(ssize_t
, pwrite
, int, fd
, void *, buf
, size_t, nbytes
, off_t
,
60 safe_syscall3(ssize_t
, writev
, int, fd
, const struct iovec
*, iov
, int, iovcnt
);
61 safe_syscall4(ssize_t
, pwritev
, int, fd
, const struct iovec
*, iov
, int, iovcnt
,
65 safe_syscall4(pid_t
, wait4
, pid_t
, wpid
, int *, status
, int, options
,
66 struct rusage
*, rusage
);
67 safe_syscall6(pid_t
, wait6
, idtype_t
, idtype
, id_t
, id
, int *, status
, int,
68 options
, struct __wrusage
*, wrusage
, siginfo_t
*, infop
);
73 abi_long
get_errno(abi_long ret
)
76 return -host_to_target_errno(errno
);
82 int host_to_target_errno(int err
)
85 * All the BSDs have the property that the error numbers are uniform across
86 * all architectures for a given BSD, though they may vary between different
92 bool is_error(abi_long ret
)
94 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
98 * Unlocks a iovec. Unlike unlock_iovec, it assumes the tvec array itself is
99 * already locked from target_addr. It will be unlocked as well as all the iovec
102 static void helper_unlock_iovec(struct target_iovec
*target_vec
,
103 abi_ulong target_addr
, struct iovec
*vec
,
106 for (int i
= 0; i
< count
; i
++) {
107 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
109 if (vec
[i
].iov_base
) {
110 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
113 unlock_user(target_vec
, target_addr
, 0);
116 struct iovec
*lock_iovec(int type
, abi_ulong target_addr
,
119 struct target_iovec
*target_vec
;
121 abi_ulong total_len
, max_len
;
129 if (count
< 0 || count
> IOV_MAX
) {
134 vec
= g_try_new0(struct iovec
, count
);
140 target_vec
= lock_user(VERIFY_READ
, target_addr
,
141 count
* sizeof(struct target_iovec
), 1);
142 if (target_vec
== NULL
) {
147 max_len
= 0x7fffffff & MIN(TARGET_PAGE_MASK
, PAGE_MASK
);
150 for (i
= 0; i
< count
; i
++) {
151 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
152 abi_long len
= tswapal(target_vec
[i
].iov_len
);
157 } else if (len
== 0) {
158 /* Zero length pointer is ignored. */
161 vec
[i
].iov_base
= lock_user(type
, base
, len
, copy
);
163 * If the first buffer pointer is bad, this is a fault. But
164 * subsequent bad buffers will result in a partial write; this is
165 * realized by filling the vector with null pointers and zero
168 if (!vec
[i
].iov_base
) {
174 * Fail all the subsequent addresses, they are already
180 if (len
> max_len
- total_len
) {
181 len
= max_len
- total_len
;
184 vec
[i
].iov_len
= len
;
188 unlock_user(target_vec
, target_addr
, 0);
192 helper_unlock_iovec(target_vec
, target_addr
, vec
, i
, copy
);
199 void unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
202 struct target_iovec
*target_vec
;
204 target_vec
= lock_user(VERIFY_READ
, target_addr
,
205 count
* sizeof(struct target_iovec
), 1);
207 helper_unlock_iovec(target_vec
, target_addr
, vec
, count
, copy
);
214 * All errnos that freebsd_syscall() returns must be -TARGET_<errcode>.
216 static abi_long
freebsd_syscall(void *cpu_env
, int num
, abi_long arg1
,
217 abi_long arg2
, abi_long arg3
, abi_long arg4
,
218 abi_long arg5
, abi_long arg6
, abi_long arg7
,
225 * process system calls
227 case TARGET_FREEBSD_NR_fork
: /* fork(2) */
228 ret
= do_freebsd_fork(cpu_env
);
231 case TARGET_FREEBSD_NR_vfork
: /* vfork(2) */
232 ret
= do_freebsd_vfork(cpu_env
);
235 case TARGET_FREEBSD_NR_rfork
: /* rfork(2) */
236 ret
= do_freebsd_rfork(cpu_env
, arg1
);
239 case TARGET_FREEBSD_NR_pdfork
: /* pdfork(2) */
240 ret
= do_freebsd_pdfork(cpu_env
, arg1
, arg2
);
243 case TARGET_FREEBSD_NR_execve
: /* execve(2) */
244 ret
= do_freebsd_execve(arg1
, arg2
, arg3
);
247 case TARGET_FREEBSD_NR_fexecve
: /* fexecve(2) */
248 ret
= do_freebsd_fexecve(arg1
, arg2
, arg3
);
251 case TARGET_FREEBSD_NR_wait4
: /* wait4(2) */
252 ret
= do_freebsd_wait4(arg1
, arg2
, arg3
, arg4
);
255 case TARGET_FREEBSD_NR_wait6
: /* wait6(2) */
256 ret
= do_freebsd_wait6(cpu_env
, arg1
, arg2
, arg3
,
257 arg4
, arg5
, arg6
, arg7
, arg8
);
260 case TARGET_FREEBSD_NR_exit
: /* exit(2) */
261 ret
= do_bsd_exit(cpu_env
, arg1
);
264 case TARGET_FREEBSD_NR_getgroups
: /* getgroups(2) */
265 ret
= do_bsd_getgroups(arg1
, arg2
);
268 case TARGET_FREEBSD_NR_setgroups
: /* setgroups(2) */
269 ret
= do_bsd_setgroups(arg1
, arg2
);
272 case TARGET_FREEBSD_NR_umask
: /* umask(2) */
273 ret
= do_bsd_umask(arg1
);
276 case TARGET_FREEBSD_NR_setlogin
: /* setlogin(2) */
277 ret
= do_bsd_setlogin(arg1
);
280 case TARGET_FREEBSD_NR_getlogin
: /* getlogin(2) */
281 ret
= do_bsd_getlogin(arg1
, arg2
);
284 case TARGET_FREEBSD_NR_getrusage
: /* getrusage(2) */
285 ret
= do_bsd_getrusage(arg1
, arg2
);
288 case TARGET_FREEBSD_NR_getrlimit
: /* getrlimit(2) */
289 ret
= do_bsd_getrlimit(arg1
, arg2
);
292 case TARGET_FREEBSD_NR_setrlimit
: /* setrlimit(2) */
293 ret
= do_bsd_setrlimit(arg1
, arg2
);
296 case TARGET_FREEBSD_NR_getpid
: /* getpid(2) */
297 ret
= do_bsd_getpid();
300 case TARGET_FREEBSD_NR_getppid
: /* getppid(2) */
301 ret
= do_bsd_getppid();
304 case TARGET_FREEBSD_NR_getuid
: /* getuid(2) */
305 ret
= do_bsd_getuid();
308 case TARGET_FREEBSD_NR_geteuid
: /* geteuid(2) */
309 ret
= do_bsd_geteuid();
312 case TARGET_FREEBSD_NR_getgid
: /* getgid(2) */
313 ret
= do_bsd_getgid();
316 case TARGET_FREEBSD_NR_getegid
: /* getegid(2) */
317 ret
= do_bsd_getegid();
320 case TARGET_FREEBSD_NR_setuid
: /* setuid(2) */
321 ret
= do_bsd_setuid(arg1
);
324 case TARGET_FREEBSD_NR_seteuid
: /* seteuid(2) */
325 ret
= do_bsd_seteuid(arg1
);
328 case TARGET_FREEBSD_NR_setgid
: /* setgid(2) */
329 ret
= do_bsd_setgid(arg1
);
332 case TARGET_FREEBSD_NR_setegid
: /* setegid(2) */
333 ret
= do_bsd_setegid(arg1
);
336 case TARGET_FREEBSD_NR_getpgrp
: /* getpgrp(2) */
337 ret
= do_bsd_getpgrp();
340 case TARGET_FREEBSD_NR_getpgid
: /* getpgid(2) */
341 ret
= do_bsd_getpgid(arg1
);
344 case TARGET_FREEBSD_NR_setpgid
: /* setpgid(2) */
345 ret
= do_bsd_setpgid(arg1
, arg2
);
348 case TARGET_FREEBSD_NR_setreuid
: /* setreuid(2) */
349 ret
= do_bsd_setreuid(arg1
, arg2
);
352 case TARGET_FREEBSD_NR_setregid
: /* setregid(2) */
353 ret
= do_bsd_setregid(arg1
, arg2
);
356 case TARGET_FREEBSD_NR_getresuid
: /* getresuid(2) */
357 ret
= do_bsd_getresuid(arg1
, arg2
, arg3
);
360 case TARGET_FREEBSD_NR_getresgid
: /* getresgid(2) */
361 ret
= do_bsd_getresgid(arg1
, arg2
, arg3
);
364 case TARGET_FREEBSD_NR_setresuid
: /* setresuid(2) */
365 ret
= do_bsd_setresuid(arg1
, arg2
, arg3
);
368 case TARGET_FREEBSD_NR_setresgid
: /* setresgid(2) */
369 ret
= do_bsd_setresgid(arg1
, arg2
, arg3
);
372 case TARGET_FREEBSD_NR_getsid
: /* getsid(2) */
373 ret
= do_bsd_getsid(arg1
);
376 case TARGET_FREEBSD_NR_setsid
: /* setsid(2) */
377 ret
= do_bsd_setsid();
380 case TARGET_FREEBSD_NR_issetugid
: /* issetugid(2) */
381 ret
= do_bsd_issetugid();
384 case TARGET_FREEBSD_NR_profil
: /* profil(2) */
385 ret
= do_bsd_profil(arg1
, arg2
, arg3
, arg4
);
388 case TARGET_FREEBSD_NR_ktrace
: /* ktrace(2) */
389 ret
= do_bsd_ktrace(arg1
, arg2
, arg3
, arg4
);
392 case TARGET_FREEBSD_NR_setloginclass
: /* setloginclass(2) */
393 ret
= do_freebsd_setloginclass(arg1
);
396 case TARGET_FREEBSD_NR_getloginclass
: /* getloginclass(2) */
397 ret
= do_freebsd_getloginclass(arg1
, arg2
);
400 case TARGET_FREEBSD_NR_pdgetpid
: /* pdgetpid(2) */
401 ret
= do_freebsd_pdgetpid(arg1
, arg2
);
404 case TARGET_FREEBSD_NR___setugid
: /* undocumented */
405 ret
= do_freebsd___setugid(arg1
);
408 case TARGET_FREEBSD_NR_utrace
: /* utrace(2) */
409 ret
= do_bsd_utrace(arg1
, arg2
);
412 case TARGET_FREEBSD_NR_ptrace
: /* ptrace(2) */
413 ret
= do_bsd_ptrace(arg1
, arg2
, arg3
, arg4
);
416 case TARGET_FREEBSD_NR_getpriority
: /* getpriority(2) */
417 ret
= do_bsd_getpriority(arg1
, arg2
);
420 case TARGET_FREEBSD_NR_setpriority
: /* setpriority(2) */
421 ret
= do_bsd_setpriority(arg1
, arg2
, arg3
);
424 case TARGET_FREEBSD_NR_procctl
: /* procctl(2) */
425 ret
= do_freebsd_procctl(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
431 case TARGET_FREEBSD_NR_read
: /* read(2) */
432 ret
= do_bsd_read(arg1
, arg2
, arg3
);
435 case TARGET_FREEBSD_NR_pread
: /* pread(2) */
436 ret
= do_bsd_pread(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
439 case TARGET_FREEBSD_NR_readv
: /* readv(2) */
440 ret
= do_bsd_readv(arg1
, arg2
, arg3
);
443 case TARGET_FREEBSD_NR_preadv
: /* preadv(2) */
444 ret
= do_bsd_preadv(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
447 case TARGET_FREEBSD_NR_write
: /* write(2) */
448 ret
= do_bsd_write(arg1
, arg2
, arg3
);
451 case TARGET_FREEBSD_NR_pwrite
: /* pwrite(2) */
452 ret
= do_bsd_pwrite(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
455 case TARGET_FREEBSD_NR_writev
: /* writev(2) */
456 ret
= do_bsd_writev(arg1
, arg2
, arg3
);
459 case TARGET_FREEBSD_NR_pwritev
: /* pwritev(2) */
460 ret
= do_bsd_pwritev(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
463 case TARGET_FREEBSD_NR_open
: /* open(2) */
464 ret
= do_bsd_open(arg1
, arg2
, arg3
);
467 case TARGET_FREEBSD_NR_openat
: /* openat(2) */
468 ret
= do_bsd_openat(arg1
, arg2
, arg3
, arg4
);
471 case TARGET_FREEBSD_NR_close
: /* close(2) */
472 ret
= do_bsd_close(arg1
);
475 case TARGET_FREEBSD_NR_fdatasync
: /* fdatasync(2) */
476 ret
= do_bsd_fdatasync(arg1
);
479 case TARGET_FREEBSD_NR_fsync
: /* fsync(2) */
480 ret
= do_bsd_fsync(arg1
);
483 case TARGET_FREEBSD_NR_freebsd12_closefrom
: /* closefrom(2) */
484 ret
= do_bsd_closefrom(arg1
);
487 case TARGET_FREEBSD_NR_revoke
: /* revoke(2) */
488 ret
= do_bsd_revoke(arg1
);
491 case TARGET_FREEBSD_NR_access
: /* access(2) */
492 ret
= do_bsd_access(arg1
, arg2
);
495 case TARGET_FREEBSD_NR_eaccess
: /* eaccess(2) */
496 ret
= do_bsd_eaccess(arg1
, arg2
);
499 case TARGET_FREEBSD_NR_faccessat
: /* faccessat(2) */
500 ret
= do_bsd_faccessat(arg1
, arg2
, arg3
, arg4
);
503 case TARGET_FREEBSD_NR_chdir
: /* chdir(2) */
504 ret
= do_bsd_chdir(arg1
);
507 case TARGET_FREEBSD_NR_fchdir
: /* fchdir(2) */
508 ret
= do_bsd_fchdir(arg1
);
511 case TARGET_FREEBSD_NR_rename
: /* rename(2) */
512 ret
= do_bsd_rename(arg1
, arg2
);
515 case TARGET_FREEBSD_NR_renameat
: /* renameat(2) */
516 ret
= do_bsd_renameat(arg1
, arg2
, arg3
, arg4
);
519 case TARGET_FREEBSD_NR_link
: /* link(2) */
520 ret
= do_bsd_link(arg1
, arg2
);
523 case TARGET_FREEBSD_NR_linkat
: /* linkat(2) */
524 ret
= do_bsd_linkat(arg1
, arg2
, arg3
, arg4
, arg5
);
527 case TARGET_FREEBSD_NR_unlink
: /* unlink(2) */
528 ret
= do_bsd_unlink(arg1
);
531 case TARGET_FREEBSD_NR_unlinkat
: /* unlinkat(2) */
532 ret
= do_bsd_unlinkat(arg1
, arg2
, arg3
);
535 case TARGET_FREEBSD_NR_mkdir
: /* mkdir(2) */
536 ret
= do_bsd_mkdir(arg1
, arg2
);
539 case TARGET_FREEBSD_NR_mkdirat
: /* mkdirat(2) */
540 ret
= do_bsd_mkdirat(arg1
, arg2
, arg3
);
543 case TARGET_FREEBSD_NR_rmdir
: /* rmdir(2) (XXX no rmdirat()?) */
544 ret
= do_bsd_rmdir(arg1
);
547 case TARGET_FREEBSD_NR___getcwd
: /* undocumented __getcwd() */
548 ret
= do_bsd___getcwd(arg1
, arg2
);
551 case TARGET_FREEBSD_NR_dup
: /* dup(2) */
552 ret
= do_bsd_dup(arg1
);
555 case TARGET_FREEBSD_NR_dup2
: /* dup2(2) */
556 ret
= do_bsd_dup2(arg1
, arg2
);
559 case TARGET_FREEBSD_NR_truncate
: /* truncate(2) */
560 ret
= do_bsd_truncate(cpu_env
, arg1
, arg2
, arg3
, arg4
);
563 case TARGET_FREEBSD_NR_ftruncate
: /* ftruncate(2) */
564 ret
= do_bsd_ftruncate(cpu_env
, arg1
, arg2
, arg3
, arg4
);
567 case TARGET_FREEBSD_NR_acct
: /* acct(2) */
568 ret
= do_bsd_acct(arg1
);
571 case TARGET_FREEBSD_NR_sync
: /* sync(2) */
575 case TARGET_FREEBSD_NR_mount
: /* mount(2) */
576 ret
= do_bsd_mount(arg1
, arg2
, arg3
, arg4
);
579 case TARGET_FREEBSD_NR_unmount
: /* unmount(2) */
580 ret
= do_bsd_unmount(arg1
, arg2
);
583 case TARGET_FREEBSD_NR_nmount
: /* nmount(2) */
584 ret
= do_bsd_nmount(arg1
, arg2
, arg3
);
587 case TARGET_FREEBSD_NR_symlink
: /* symlink(2) */
588 ret
= do_bsd_symlink(arg1
, arg2
);
591 case TARGET_FREEBSD_NR_symlinkat
: /* symlinkat(2) */
592 ret
= do_bsd_symlinkat(arg1
, arg2
, arg3
);
595 case TARGET_FREEBSD_NR_readlink
: /* readlink(2) */
596 ret
= do_bsd_readlink(cpu_env
, arg1
, arg2
, arg3
);
599 case TARGET_FREEBSD_NR_readlinkat
: /* readlinkat(2) */
600 ret
= do_bsd_readlinkat(arg1
, arg2
, arg3
, arg4
);
603 case TARGET_FREEBSD_NR_chmod
: /* chmod(2) */
604 ret
= do_bsd_chmod(arg1
, arg2
);
607 case TARGET_FREEBSD_NR_fchmod
: /* fchmod(2) */
608 ret
= do_bsd_fchmod(arg1
, arg2
);
611 case TARGET_FREEBSD_NR_lchmod
: /* lchmod(2) */
612 ret
= do_bsd_lchmod(arg1
, arg2
);
615 case TARGET_FREEBSD_NR_fchmodat
: /* fchmodat(2) */
616 ret
= do_bsd_fchmodat(arg1
, arg2
, arg3
, arg4
);
619 case TARGET_FREEBSD_NR_freebsd11_mknod
: /* mknod(2) */
620 ret
= do_bsd_freebsd11_mknod(arg1
, arg2
, arg3
);
623 case TARGET_FREEBSD_NR_freebsd11_mknodat
: /* mknodat(2) */
624 ret
= do_bsd_freebsd11_mknodat(arg1
, arg2
, arg3
, arg4
);
627 case TARGET_FREEBSD_NR_mknodat
: /* mknodat(2) */
628 ret
= do_bsd_mknodat(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
631 case TARGET_FREEBSD_NR_chown
: /* chown(2) */
632 ret
= do_bsd_chown(arg1
, arg2
, arg3
);
635 case TARGET_FREEBSD_NR_fchown
: /* fchown(2) */
636 ret
= do_bsd_fchown(arg1
, arg2
, arg3
);
639 case TARGET_FREEBSD_NR_lchown
: /* lchown(2) */
640 ret
= do_bsd_lchown(arg1
, arg2
, arg3
);
643 case TARGET_FREEBSD_NR_fchownat
: /* fchownat(2) */
644 ret
= do_bsd_fchownat(arg1
, arg2
, arg3
, arg4
, arg5
);
647 case TARGET_FREEBSD_NR_chflags
: /* chflags(2) */
648 ret
= do_bsd_chflags(arg1
, arg2
);
651 case TARGET_FREEBSD_NR_lchflags
: /* lchflags(2) */
652 ret
= do_bsd_lchflags(arg1
, arg2
);
655 case TARGET_FREEBSD_NR_fchflags
: /* fchflags(2) */
656 ret
= do_bsd_fchflags(arg1
, arg2
);
659 case TARGET_FREEBSD_NR_chroot
: /* chroot(2) */
660 ret
= do_bsd_chroot(arg1
);
663 case TARGET_FREEBSD_NR_flock
: /* flock(2) */
664 ret
= do_bsd_flock(arg1
, arg2
);
667 case TARGET_FREEBSD_NR_mkfifo
: /* mkfifo(2) */
668 ret
= do_bsd_mkfifo(arg1
, arg2
);
671 case TARGET_FREEBSD_NR_mkfifoat
: /* mkfifoat(2) */
672 ret
= do_bsd_mkfifoat(arg1
, arg2
, arg3
);
675 case TARGET_FREEBSD_NR_pathconf
: /* pathconf(2) */
676 ret
= do_bsd_pathconf(arg1
, arg2
);
679 case TARGET_FREEBSD_NR_lpathconf
: /* lpathconf(2) */
680 ret
= do_bsd_lpathconf(arg1
, arg2
);
683 case TARGET_FREEBSD_NR_fpathconf
: /* fpathconf(2) */
684 ret
= do_bsd_fpathconf(arg1
, arg2
);
687 case TARGET_FREEBSD_NR_undelete
: /* undelete(2) */
688 ret
= do_bsd_undelete(arg1
);
694 case TARGET_FREEBSD_NR_freebsd11_stat
: /* stat(2) */
695 ret
= do_freebsd11_stat(arg1
, arg2
);
698 case TARGET_FREEBSD_NR_freebsd11_lstat
: /* lstat(2) */
699 ret
= do_freebsd11_lstat(arg1
, arg2
);
702 case TARGET_FREEBSD_NR_freebsd11_fstat
: /* fstat(2) */
703 ret
= do_freebsd11_fstat(arg1
, arg2
);
706 case TARGET_FREEBSD_NR_fstat
: /* fstat(2) */
707 ret
= do_freebsd_fstat(arg1
, arg2
);
710 case TARGET_FREEBSD_NR_freebsd11_fstatat
: /* fstatat(2) */
711 ret
= do_freebsd11_fstatat(arg1
, arg2
, arg3
, arg4
);
714 case TARGET_FREEBSD_NR_fstatat
: /* fstatat(2) */
715 ret
= do_freebsd_fstatat(arg1
, arg2
, arg3
, arg4
);
718 case TARGET_FREEBSD_NR_freebsd11_nstat
: /* undocumented */
719 ret
= do_freebsd11_nstat(arg1
, arg2
);
722 case TARGET_FREEBSD_NR_freebsd11_nfstat
: /* undocumented */
723 ret
= do_freebsd11_nfstat(arg1
, arg2
);
726 case TARGET_FREEBSD_NR_freebsd11_nlstat
: /* undocumented */
727 ret
= do_freebsd11_nlstat(arg1
, arg2
);
730 case TARGET_FREEBSD_NR_getfh
: /* getfh(2) */
731 ret
= do_freebsd_getfh(arg1
, arg2
);
734 case TARGET_FREEBSD_NR_lgetfh
: /* lgetfh(2) */
735 ret
= do_freebsd_lgetfh(arg1
, arg2
);
738 case TARGET_FREEBSD_NR_fhopen
: /* fhopen(2) */
739 ret
= do_freebsd_fhopen(arg1
, arg2
);
742 case TARGET_FREEBSD_NR_freebsd11_fhstat
: /* fhstat(2) */
743 ret
= do_freebsd11_fhstat(arg1
, arg2
);
746 case TARGET_FREEBSD_NR_fhstat
: /* fhstat(2) */
747 ret
= do_freebsd_fhstat(arg1
, arg2
);
750 case TARGET_FREEBSD_NR_freebsd11_fhstatfs
: /* fhstatfs(2) */
751 ret
= do_freebsd11_fhstatfs(arg1
, arg2
);
754 case TARGET_FREEBSD_NR_fhstatfs
: /* fhstatfs(2) */
755 ret
= do_freebsd_fhstatfs(arg1
, arg2
);
758 case TARGET_FREEBSD_NR_freebsd11_statfs
: /* statfs(2) */
759 ret
= do_freebsd11_statfs(arg1
, arg2
);
762 case TARGET_FREEBSD_NR_statfs
: /* statfs(2) */
763 ret
= do_freebsd_statfs(arg1
, arg2
);
766 case TARGET_FREEBSD_NR_freebsd11_fstatfs
: /* fstatfs(2) */
767 ret
= do_freebsd11_fstatfs(arg1
, arg2
);
770 case TARGET_FREEBSD_NR_fstatfs
: /* fstatfs(2) */
771 ret
= do_freebsd_fstatfs(arg1
, arg2
);
774 case TARGET_FREEBSD_NR_freebsd11_getfsstat
: /* getfsstat(2) */
775 ret
= do_freebsd11_getfsstat(arg1
, arg2
, arg3
);
778 case TARGET_FREEBSD_NR_getfsstat
: /* getfsstat(2) */
779 ret
= do_freebsd_getfsstat(arg1
, arg2
, arg3
);
782 case TARGET_FREEBSD_NR_freebsd11_getdents
: /* getdents(2) */
783 ret
= do_freebsd11_getdents(arg1
, arg2
, arg3
);
786 case TARGET_FREEBSD_NR_getdirentries
: /* getdirentries(2) */
787 ret
= do_freebsd_getdirentries(arg1
, arg2
, arg3
, arg4
);
790 case TARGET_FREEBSD_NR_freebsd11_getdirentries
: /* getdirentries(2) */
791 ret
= do_freebsd11_getdirentries(arg1
, arg2
, arg3
, arg4
);
793 case TARGET_FREEBSD_NR_fcntl
: /* fcntl(2) */
794 ret
= do_freebsd_fcntl(arg1
, arg2
, arg3
);
798 * Memory management system calls.
800 #if defined(__FreeBSD_version) && __FreeBSD_version >= 1300048
801 case TARGET_FREEBSD_NR_shm_open2
: /* shm_open2(2) */
802 ret
= do_freebsd_shm_open2(arg1
, arg2
, arg3
, arg4
, arg5
);
806 #if defined(__FreeBSD_version) && __FreeBSD_version >= 1300049
807 case TARGET_FREEBSD_NR_shm_rename
: /* shm_rename(2) */
808 ret
= do_freebsd_shm_rename(arg1
, arg2
, arg3
);
813 * sys{ctl, arch, call}
815 case TARGET_FREEBSD_NR___sysctl
: /* sysctl(3) */
816 ret
= do_freebsd_sysctl(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
819 case TARGET_FREEBSD_NR___sysctlbyname
: /* sysctlbyname(2) */
820 ret
= do_freebsd_sysctlbyname(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
823 case TARGET_FREEBSD_NR_sysarch
: /* sysarch(2) */
824 ret
= do_freebsd_sysarch(cpu_env
, arg1
, arg2
);
828 qemu_log_mask(LOG_UNIMP
, "Unsupported syscall: %d\n", num
);
829 ret
= -TARGET_ENOSYS
;
837 * do_freebsd_syscall() should always have a single exit point at the end so
838 * that actions, such as logging of syscall results, can be performed. This
839 * as a wrapper around freebsd_syscall() so that actually happens. Since
840 * that is a singleton, modern compilers will inline it anyway...
842 abi_long
do_freebsd_syscall(void *cpu_env
, int num
, abi_long arg1
,
843 abi_long arg2
, abi_long arg3
, abi_long arg4
,
844 abi_long arg5
, abi_long arg6
, abi_long arg7
,
850 print_freebsd_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
853 ret
= freebsd_syscall(cpu_env
, num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
,
856 print_freebsd_syscall_ret(num
, ret
);
862 void syscall_init(void)