]>
git.proxmox.com Git - mirror_qemu.git/blob - bsd-user/freebsd/os-syscall.c
67851937a8fa0e735af03e88fe887dafffd84c2f
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/>.
22 * We need the FreeBSD "legacy" definitions. Rust needs the FreeBSD 11 system
23 * calls since it doesn't use libc at all, so we have to emulate that despite
24 * FreeBSD 11 being EOL'd.
26 #define _WANT_FREEBSD11_STAT
27 #define _WANT_FREEBSD11_STATFS
28 #define _WANT_FREEBSD11_DIRENT
29 #define _WANT_KERNEL_ERRNO
31 #include "qemu/osdep.h"
32 #include "qemu/cutils.h"
33 #include "qemu/path.h"
34 #include <sys/syscall.h>
35 #include <sys/param.h>
36 #include <sys/sysctl.h>
40 #include "signal-common.h"
41 #include "user/syscall-trace.h"
45 void target_set_brk(abi_ulong new_brk
)
52 abi_long
get_errno(abi_long ret
)
55 return -host_to_target_errno(errno
);
61 int host_to_target_errno(int err
)
64 * All the BSDs have the property that the error numbers are uniform across
65 * all architectures for a given BSD, though they may vary between different
71 bool is_error(abi_long ret
)
73 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
77 * Unlocks a iovec. Unlike unlock_iovec, it assumes the tvec array itself is
78 * already locked from target_addr. It will be unlocked as well as all the iovec
81 static void helper_unlock_iovec(struct target_iovec
*target_vec
,
82 abi_ulong target_addr
, struct iovec
*vec
,
85 for (int i
= 0; i
< count
; i
++) {
86 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
88 if (vec
[i
].iov_base
) {
89 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
92 unlock_user(target_vec
, target_addr
, 0);
95 struct iovec
*lock_iovec(int type
, abi_ulong target_addr
,
98 struct target_iovec
*target_vec
;
100 abi_ulong total_len
, max_len
;
108 if (count
< 0 || count
> IOV_MAX
) {
113 vec
= g_try_new0(struct iovec
, count
);
119 target_vec
= lock_user(VERIFY_READ
, target_addr
,
120 count
* sizeof(struct target_iovec
), 1);
121 if (target_vec
== NULL
) {
126 max_len
= 0x7fffffff & MIN(TARGET_PAGE_MASK
, PAGE_MASK
);
129 for (i
= 0; i
< count
; i
++) {
130 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
131 abi_long len
= tswapal(target_vec
[i
].iov_len
);
136 } else if (len
== 0) {
137 /* Zero length pointer is ignored. */
140 vec
[i
].iov_base
= lock_user(type
, base
, len
, copy
);
142 * If the first buffer pointer is bad, this is a fault. But
143 * subsequent bad buffers will result in a partial write; this is
144 * realized by filling the vector with null pointers and zero
147 if (!vec
[i
].iov_base
) {
153 * Fail all the subsequent addresses, they are already
159 if (len
> max_len
- total_len
) {
160 len
= max_len
- total_len
;
163 vec
[i
].iov_len
= len
;
167 unlock_user(target_vec
, target_addr
, 0);
171 helper_unlock_iovec(target_vec
, target_addr
, vec
, i
, copy
);
179 * do_syscall() should always have a single exit point at the end so that
180 * actions, such as logging of syscall results, can be performed. All errnos
181 * that do_syscall() returns must be -TARGET_<errcode>.
183 abi_long
do_freebsd_syscall(void *cpu_env
, int num
, abi_long arg1
,
184 abi_long arg2
, abi_long arg3
, abi_long arg4
,
185 abi_long arg5
, abi_long arg6
, abi_long arg7
,
191 void syscall_init(void)