]> git.proxmox.com Git - mirror_qemu.git/blame - linux-user/syscall.c
linux-user: Rename TARGET_QEMU_ESIGRETURN to QEMU_ESIGRETURN
[mirror_qemu.git] / linux-user / syscall.c
CommitLineData
31e31b8a
FB
1/*
2 * Linux syscalls
5fafdf24 3 *
31e31b8a
FB
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
8167ee88 17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
31e31b8a 18 */
d5b3a9b6 19#define _ATFILE_SOURCE
d39594e9 20#include "qemu/osdep.h"
f348b6d1
VB
21#include "qemu/cutils.h"
22#include "qemu/path.h"
9bdfa4d2 23#include "qemu/memfd.h"
dc5e9ac7 24#include "qemu/queue.h"
31e31b8a
FB
25#include <elf.h>
26#include <endian.h>
c56dc774 27#include <grp.h>
d08d3bb8
TS
28#include <sys/ipc.h>
29#include <sys/msg.h>
31e31b8a 30#include <sys/wait.h>
31e31b8a 31#include <sys/mount.h>
586b0bef
JS
32#include <sys/file.h>
33#include <sys/fsuid.h>
34#include <sys/personality.h>
39b9aae1 35#include <sys/prctl.h>
31e31b8a 36#include <sys/resource.h>
31e31b8a 37#include <sys/swap.h>
e0eb210e 38#include <linux/capability.h>
31e31b8a 39#include <sched.h>
19f59bce 40#include <sys/timex.h>
31e31b8a 41#include <sys/socket.h>
6d5d5dde 42#include <linux/sockios.h>
607175e0 43#include <sys/un.h>
31e31b8a 44#include <sys/uio.h>
0839f11c 45#include <poll.h>
32f36bce 46#include <sys/times.h>
8853f86e 47#include <sys/shm.h>
fa294816 48#include <sys/sem.h>
56c8f68f 49#include <sys/statfs.h>
ebc05488 50#include <utime.h>
a5448a7d 51#include <sys/sysinfo.h>
e36800c9 52#include <sys/signalfd.h>
72f03900 53//#include <sys/user.h>
22db1213 54#include <netinet/in.h>
8853f86e 55#include <netinet/ip.h>
7854b056 56#include <netinet/tcp.h>
fe51b0a5 57#include <netinet/udp.h>
86fcd946 58#include <linux/wireless.h>
920394db 59#include <linux/icmp.h>
ee1ac3a1 60#include <linux/icmpv6.h>
6addf06a 61#include <linux/if_tun.h>
22db1213 62#include <linux/in6.h>
ee1ac3a1 63#include <linux/errqueue.h>
d6d6d6fe 64#include <linux/random.h>
d80a1905
RV
65#ifdef CONFIG_TIMERFD
66#include <sys/timerfd.h>
67#endif
c2882b96
RV
68#ifdef CONFIG_EVENTFD
69#include <sys/eventfd.h>
70#endif
3b6edd16
PM
71#ifdef CONFIG_EPOLL
72#include <sys/epoll.h>
73#endif
a790ae38 74#ifdef CONFIG_ATTR
1de7afc9 75#include "qemu/xattr.h"
a790ae38 76#endif
a8fd1aba
PM
77#ifdef CONFIG_SENDFILE
78#include <sys/sendfile.h>
79#endif
4a9d5f89 80#ifdef HAVE_SYS_KCOV_H
bd27e675
AM
81#include <sys/kcov.h>
82#endif
31e31b8a
FB
83
84#define termios host_termios
85#define winsize host_winsize
86#define termio host_termio
04369ff2
FB
87#define sgttyb host_sgttyb /* same as target */
88#define tchars host_tchars /* same as target */
89#define ltchars host_ltchars /* same as target */
31e31b8a
FB
90
91#include <linux/termios.h>
92#include <linux/unistd.h>
31e31b8a
FB
93#include <linux/cdrom.h>
94#include <linux/hdreg.h>
95#include <linux/soundcard.h>
19b84f3c 96#include <linux/kd.h>
8fbd6b52 97#include <linux/mtio.h>
350d1779 98#include <linux/fs.h>
ab22b4dd 99#include <linux/fd.h>
dace20dc 100#if defined(CONFIG_FIEMAP)
285da2b9 101#include <linux/fiemap.h>
dace20dc 102#endif
f7680a55 103#include <linux/fb.h>
6c753a63
CT
104#if defined(CONFIG_USBFS)
105#include <linux/usbdevice_fs.h>
a133367e 106#include <linux/usb/ch9.h>
6c753a63 107#endif
f7680a55 108#include <linux/vt.h>
56e904ec 109#include <linux/dm-ioctl.h>
c07ecc68 110#include <linux/reboot.h>
7ff7b666 111#include <linux/route.h>
f57d4192 112#include <linux/filter.h>
fff8c539 113#include <linux/blkpg.h>
a82ea939 114#include <netpacket/packet.h>
6c5b5645 115#include <linux/netlink.h>
f31dddd2 116#include <linux/if_alg.h>
68365f96 117#include <linux/rtc.h>
1c4c6fcd 118#include <sound/asound.h>
48f670ec 119#ifdef HAVE_BTRFS_H
d6092e08
FB
120#include <linux/btrfs.h>
121#endif
e865b97f
CG
122#ifdef HAVE_DRM_H
123#include <libdrm/drm.h>
913b03c2 124#include <libdrm/i915_drm.h>
e865b97f 125#endif
d7e4036e 126#include "linux_loop.h"
18cb0088 127#include "uname.h"
31e31b8a 128
3ef693a0 129#include "qemu.h"
3b249d26 130#include "user-internals.h"
a44d57a3 131#include "strace.h"
2113aed6 132#include "signal-common.h"
3ad0a769 133#include "loader.h"
5423e6d3 134#include "user-mmap.h"
a57e0c36 135#include "safe-syscall.h"
5ebdd774 136#include "qemu/guest-random.h"
01ef6b9e 137#include "qemu/selfmap.h"
c36f7a64 138#include "user/syscall-trace.h"
51977e25 139#include "qapi/error.h"
f7e6a401 140#include "fd-trans.h"
dcb32f1d 141#include "tcg/tcg.h"
31e31b8a 142
5ea2fc84
PM
143#ifndef CLONE_IO
144#define CLONE_IO 0x80000000 /* Clone io context */
145#endif
146
147/* We can't directly call the host clone syscall, because this will
148 * badly confuse libc (breaking mutexes, for example). So we must
149 * divide clone flags into:
150 * * flag combinations that look like pthread_create()
151 * * flag combinations that look like fork()
152 * * flags we can implement within QEMU itself
153 * * flags we can't support and will return an error for
154 */
155/* For thread creation, all these flags must be present; for
156 * fork, none must be present.
157 */
158#define CLONE_THREAD_FLAGS \
159 (CLONE_VM | CLONE_FS | CLONE_FILES | \
160 CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
161
162/* These flags are ignored:
163 * CLONE_DETACHED is now ignored by the kernel;
164 * CLONE_IO is just an optimisation hint to the I/O scheduler
165 */
166#define CLONE_IGNORED_FLAGS \
167 (CLONE_DETACHED | CLONE_IO)
168
169/* Flags for fork which we can implement within QEMU itself */
170#define CLONE_OPTIONAL_FORK_FLAGS \
171 (CLONE_SETTLS | CLONE_PARENT_SETTID | \
172 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
173
174/* Flags for thread creation which we can implement within QEMU itself */
175#define CLONE_OPTIONAL_THREAD_FLAGS \
176 (CLONE_SETTLS | CLONE_PARENT_SETTID | \
177 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
178
179#define CLONE_INVALID_FORK_FLAGS \
180 (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
181
182#define CLONE_INVALID_THREAD_FLAGS \
183 (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS | \
184 CLONE_IGNORED_FLAGS))
185
186/* CLONE_VFORK is special cased early in do_fork(). The other flag bits
187 * have almost all been allocated. We cannot support any of
188 * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
189 * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
190 * The checks against the invalid thread masks above will catch these.
191 * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
192 */
30813cea 193
71a8f7fe
TB
194/* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
195 * once. This exercises the codepaths for restart.
196 */
197//#define DEBUG_ERESTARTSYS
31e31b8a 198
1a9353d2 199//#include <linux/msdos_fs.h>
540a736f
RH
200#define VFAT_IOCTL_READDIR_BOTH \
201 _IOC(_IOC_READ, 'r', 1, (sizeof(struct linux_dirent) + 256) * 2)
202#define VFAT_IOCTL_READDIR_SHORT \
203 _IOC(_IOC_READ, 'r', 2, (sizeof(struct linux_dirent) + 256) * 2)
1a9353d2 204
70a194b9
FB
205#undef _syscall0
206#undef _syscall1
207#undef _syscall2
208#undef _syscall3
209#undef _syscall4
210#undef _syscall5
83fcb515 211#undef _syscall6
70a194b9 212
83fcb515 213#define _syscall0(type,name) \
8fcd3692 214static type name (void) \
83fcb515
FB
215{ \
216 return syscall(__NR_##name); \
217}
70a194b9 218
83fcb515 219#define _syscall1(type,name,type1,arg1) \
8fcd3692 220static type name (type1 arg1) \
83fcb515
FB
221{ \
222 return syscall(__NR_##name, arg1); \
70a194b9
FB
223}
224
83fcb515 225#define _syscall2(type,name,type1,arg1,type2,arg2) \
8fcd3692 226static type name (type1 arg1,type2 arg2) \
83fcb515
FB
227{ \
228 return syscall(__NR_##name, arg1, arg2); \
70a194b9
FB
229}
230
83fcb515 231#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
8fcd3692 232static type name (type1 arg1,type2 arg2,type3 arg3) \
83fcb515
FB
233{ \
234 return syscall(__NR_##name, arg1, arg2, arg3); \
70a194b9
FB
235}
236
83fcb515 237#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
8fcd3692 238static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
83fcb515
FB
239{ \
240 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
70a194b9
FB
241}
242
83fcb515
FB
243#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
244 type5,arg5) \
8fcd3692 245static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
83fcb515
FB
246{ \
247 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
70a194b9
FB
248}
249
83fcb515
FB
250
251#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
252 type5,arg5,type6,arg6) \
8fcd3692
BS
253static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
254 type6 arg6) \
83fcb515
FB
255{ \
256 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
70a194b9 257}
83fcb515 258
70a194b9 259
31e31b8a 260#define __NR_sys_uname __NR_uname
72f03900 261#define __NR_sys_getcwd1 __NR_getcwd
72f03900 262#define __NR_sys_getdents __NR_getdents
dab2ed99 263#define __NR_sys_getdents64 __NR_getdents64
c6cda17a 264#define __NR_sys_getpriority __NR_getpriority
66fb9763 265#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
cf8b8bfc 266#define __NR_sys_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
7494b0f9 267#define __NR_sys_syslog __NR_syslog
14690296
AF
268#if defined(__NR_futex)
269# define __NR_sys_futex __NR_futex
270#endif
271#if defined(__NR_futex_time64)
272# define __NR_sys_futex_time64 __NR_futex_time64
273#endif
39b59763
AJ
274#define __NR_sys_inotify_init __NR_inotify_init
275#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
276#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
efa92184 277#define __NR_sys_statx __NR_statx
31e31b8a 278
b1cef6d0 279#if defined(__alpha__) || defined(__x86_64__) || defined(__s390x__)
9af9eaaa
FB
280#define __NR__llseek __NR_lseek
281#endif
282
a29e5ba2
JH
283/* Newer kernel ports have llseek() instead of _llseek() */
284#if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
285#define TARGET_NR__llseek TARGET_NR_llseek
286#endif
287
78721301
HD
288/* some platforms need to mask more bits than just TARGET_O_NONBLOCK */
289#ifndef TARGET_O_NONBLOCK_MASK
290#define TARGET_O_NONBLOCK_MASK TARGET_O_NONBLOCK
291#endif
292
71ba74f6
DB
293#define __NR_sys_gettid __NR_gettid
294_syscall0(int, sys_gettid)
2b3f64cb
PM
295
296/* For the 64-bit guest on 32-bit host case we must emulate
297 * getdents using getdents64, because otherwise the host
298 * might hand us back more dirent records than we can fit
299 * into the guest buffer after structure format conversion.
300 * Otherwise we emulate getdents with getdents if the host has it.
301 */
302#if defined(__NR_getdents) && HOST_LONG_BITS >= TARGET_ABI_BITS
303#define EMULATE_GETDENTS_WITH_GETDENTS
304#endif
305
306#if defined(TARGET_NR_getdents) && defined(EMULATE_GETDENTS_WITH_GETDENTS)
3b3f24ad 307_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
3307e236 308#endif
2b3f64cb
PM
309#if (defined(TARGET_NR_getdents) && \
310 !defined(EMULATE_GETDENTS_WITH_GETDENTS)) || \
3307e236 311 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
3b3f24ad
AJ
312_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
313#endif
d35b261c 314#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
3b3f24ad
AJ
315_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
316 loff_t *, res, uint, wh);
317#endif
c1a402a7 318_syscall3(int, sys_rt_sigqueueinfo, pid_t, pid, int, sig, siginfo_t *, uinfo)
cf8b8bfc
MS
319_syscall4(int, sys_rt_tgsigqueueinfo, pid_t, pid, pid_t, tid, int, sig,
320 siginfo_t *, uinfo)
3b3f24ad 321_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
3b3f24ad
AJ
322#ifdef __NR_exit_group
323_syscall1(int,exit_group,int,error_code)
324#endif
325#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
326_syscall1(int,set_tid_address,int *,tidptr)
327#endif
14690296 328#if defined(__NR_futex)
3b3f24ad
AJ
329_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
330 const struct timespec *,timeout,int *,uaddr2,int,val3)
331#endif
14690296
AF
332#if defined(__NR_futex_time64)
333_syscall6(int,sys_futex_time64,int *,uaddr,int,op,int,val,
334 const struct timespec *,timeout,int *,uaddr2,int,val3)
335#endif
737de1d1
MF
336#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
337_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
338 unsigned long *, user_mask_ptr);
339#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
340_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
341 unsigned long *, user_mask_ptr);
b827c3ed
ST
342#define __NR_sys_getcpu __NR_getcpu
343_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
0f6b4d21
AG
344_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
345 void *, arg);
e0eb210e
PM
346_syscall2(int, capget, struct __user_cap_header_struct *, header,
347 struct __user_cap_data_struct *, data);
348_syscall2(int, capset, struct __user_cap_header_struct *, header,
349 struct __user_cap_data_struct *, data);
ab31cda3
PB
350#if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
351_syscall2(int, ioprio_get, int, which, int, who)
352#endif
353#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
354_syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
355#endif
f894efd1
LV
356#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
357_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
358#endif
3b3f24ad 359
2f14788c
LV
360#if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
361_syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
362 unsigned long, idx1, unsigned long, idx2)
363#endif
364
efa92184
AR
365/*
366 * It is assumed that struct statx is architecture independent.
367 */
368#if defined(TARGET_NR_statx) && defined(__NR_statx)
369_syscall5(int, sys_statx, int, dirfd, const char *, pathname, int, flags,
370 unsigned int, mask, struct target_statx *, statxbuf)
371#endif
8500476f
AS
372#if defined(TARGET_NR_membarrier) && defined(__NR_membarrier)
373_syscall2(int, membarrier, int, cmd, int, flags)
374#endif
efa92184 375
180d4ef3 376static const bitmask_transtbl fcntl_flags_tbl[] = {
3b3f24ad
AJ
377 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
378 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
379 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
380 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
381 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
382 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
383 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
384 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
afc8763f 385 { TARGET_O_SYNC, TARGET_O_DSYNC, O_SYNC, O_DSYNC, },
3b3f24ad
AJ
386 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
387 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
388 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
389 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
3b3f24ad
AJ
390#if defined(O_DIRECT)
391 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
afc8763f
RH
392#endif
393#if defined(O_NOATIME)
394 { TARGET_O_NOATIME, TARGET_O_NOATIME, O_NOATIME, O_NOATIME },
395#endif
396#if defined(O_CLOEXEC)
397 { TARGET_O_CLOEXEC, TARGET_O_CLOEXEC, O_CLOEXEC, O_CLOEXEC },
398#endif
399#if defined(O_PATH)
400 { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
5f9cee46
RV
401#endif
402#if defined(O_TMPFILE)
403 { TARGET_O_TMPFILE, TARGET_O_TMPFILE, O_TMPFILE, O_TMPFILE },
afc8763f
RH
404#endif
405 /* Don't terminate the list prematurely on 64-bit host+guest. */
406#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
407 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
3b3f24ad
AJ
408#endif
409 { 0, 0, 0, 0 }
410};
411
0f6bb195 412_syscall2(int, sys_getcwd1, char *, buf, size_t, size)
3b3f24ad 413
cac46eb0 414#if defined(TARGET_NR_utimensat) || defined(TARGET_NR_utimensat_time64)
700fa58e 415#if defined(__NR_utimensat)
1acae9f2 416#define __NR_sys_utimensat __NR_utimensat
9007f0ef
TS
417_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
418 const struct timespec *,tsp,int,flags)
1acae9f2
PM
419#else
420static int sys_utimensat(int dirfd, const char *pathname,
421 const struct timespec times[2], int flags)
422{
423 errno = ENOSYS;
424 return -1;
425}
9007f0ef 426#endif
1acae9f2 427#endif /* TARGET_NR_utimensat */
3b3f24ad 428
95d0307c
AS
429#ifdef TARGET_NR_renameat2
430#if defined(__NR_renameat2)
431#define __NR_sys_renameat2 __NR_renameat2
432_syscall5(int, sys_renameat2, int, oldfd, const char *, old, int, newfd,
433 const char *, new, unsigned int, flags)
434#else
435static int sys_renameat2(int oldfd, const char *old,
436 int newfd, const char *new, int flags)
437{
438 if (flags == 0) {
439 return renameat(oldfd, old, newfd, new);
440 }
441 errno = ENOSYS;
442 return -1;
443}
444#endif
445#endif /* TARGET_NR_renameat2 */
446
3b3f24ad 447#ifdef CONFIG_INOTIFY
8690e420 448#include <sys/inotify.h>
3b3f24ad 449
39b59763 450#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
3b3f24ad
AJ
451static int sys_inotify_init(void)
452{
453 return (inotify_init());
454}
39b59763
AJ
455#endif
456#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
3b3f24ad
AJ
457static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
458{
459 return (inotify_add_watch(fd, pathname, mask));
460}
39b59763
AJ
461#endif
462#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
3b3f24ad
AJ
463static int sys_inotify_rm_watch(int fd, int32_t wd)
464{
8690e420 465 return (inotify_rm_watch(fd, wd));
3b3f24ad 466}
bd0c5661 467#endif
c05c7a73
RV
468#ifdef CONFIG_INOTIFY1
469#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
470static int sys_inotify_init1(int flags)
471{
472 return (inotify_init1(flags));
473}
474#endif
475#endif
3b3f24ad
AJ
476#else
477/* Userspace can usually survive runtime without inotify */
478#undef TARGET_NR_inotify_init
c05c7a73 479#undef TARGET_NR_inotify_init1
3b3f24ad
AJ
480#undef TARGET_NR_inotify_add_watch
481#undef TARGET_NR_inotify_rm_watch
482#endif /* CONFIG_INOTIFY */
483
163a05a8
PM
484#if defined(TARGET_NR_prlimit64)
485#ifndef __NR_prlimit64
486# define __NR_prlimit64 -1
487#endif
488#define __NR_sys_prlimit64 __NR_prlimit64
489/* The glibc rlimit structure may not be that used by the underlying syscall */
490struct host_rlimit64 {
491 uint64_t rlim_cur;
492 uint64_t rlim_max;
493};
494_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
495 const struct host_rlimit64 *, new_limit,
496 struct host_rlimit64 *, old_limit)
497#endif
498
f4f1e10a
ECL
499
500#if defined(TARGET_NR_timer_create)
6f9ff551 501/* Maximum of 32 active POSIX timers allowed at any one time. */
f4f1e10a
ECL
502static timer_t g_posix_timers[32] = { 0, } ;
503
504static inline int next_free_host_timer(void)
505{
506 int k ;
507 /* FIXME: Does finding the next free slot require a lock? */
508 for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
509 if (g_posix_timers[k] == 0) {
510 g_posix_timers[k] = (timer_t) 1;
511 return k;
512 }
513 }
514 return -1;
515}
516#endif
517
3ffe3268 518static inline int host_to_target_errno(int host_errno)
637947f1 519{
3ffe3268
PMD
520 switch (host_errno) {
521#define E(X) case X: return TARGET_##X;
522#include "errnos.c.inc"
523#undef E
524 default:
525 return host_errno;
2466119c 526 }
637947f1
TS
527}
528
3ffe3268 529static inline int target_to_host_errno(int target_errno)
b92c47c1 530{
3ffe3268
PMD
531 switch (target_errno) {
532#define E(X) case TARGET_##X: return X;
533#include "errnos.c.inc"
534#undef E
535 default:
536 return target_errno;
2466119c 537 }
b92c47c1
TS
538}
539
992f48a0 540static inline abi_long get_errno(abi_long ret)
31e31b8a
FB
541{
542 if (ret == -1)
637947f1 543 return -host_to_target_errno(errno);
31e31b8a
FB
544 else
545 return ret;
546}
547
7dcdaeaf 548const char *target_strerror(int err)
b92c47c1 549{
af254a27 550 if (err == QEMU_ERESTARTSYS) {
da2a34f7
PM
551 return "To be restarted";
552 }
57a0c938 553 if (err == QEMU_ESIGRETURN) {
da2a34f7
PM
554 return "Successful exit from sigreturn";
555 }
556
b92c47c1
TS
557 return strerror(target_to_host_errno(err));
558}
559
4d330cee
TB
560#define safe_syscall0(type, name) \
561static type safe_##name(void) \
562{ \
563 return safe_syscall(__NR_##name); \
564}
565
566#define safe_syscall1(type, name, type1, arg1) \
567static type safe_##name(type1 arg1) \
568{ \
569 return safe_syscall(__NR_##name, arg1); \
570}
571
572#define safe_syscall2(type, name, type1, arg1, type2, arg2) \
573static type safe_##name(type1 arg1, type2 arg2) \
574{ \
575 return safe_syscall(__NR_##name, arg1, arg2); \
576}
577
578#define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
579static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
580{ \
581 return safe_syscall(__NR_##name, arg1, arg2, arg3); \
582}
583
584#define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
585 type4, arg4) \
586static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
587{ \
588 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
589}
590
591#define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
592 type4, arg4, type5, arg5) \
593static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
594 type5 arg5) \
595{ \
596 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
597}
598
599#define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
600 type4, arg4, type5, arg5, type6, arg6) \
601static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
602 type5 arg5, type6 arg6) \
603{ \
604 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
605}
606
50afd02b
TB
607safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
608safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
c10a0738
TB
609safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
610 int, flags, mode_t, mode)
859e8a89 611#if defined(TARGET_NR_wait4) || defined(TARGET_NR_waitpid)
4af80a37
TB
612safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
613 struct rusage *, rusage)
859e8a89 614#endif
4af80a37
TB
615safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
616 int, options, struct rusage *, rusage)
ffdcbe22 617safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
859e8a89 618#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
e5ce9688 619 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
6df9d38d
PM
620safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
621 fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
859e8a89 622#endif
e5ce9688 623#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_ppoll_time64)
a6130237
PM
624safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
625 struct timespec *, tsp, const sigset_t *, sigmask,
626 size_t, sigsetsize)
859e8a89 627#endif
227f0214
PM
628safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
629 int, maxevents, int, timeout, const sigset_t *, sigmask,
630 size_t, sigsetsize)
14690296 631#if defined(__NR_futex)
d509eeb1
PM
632safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
633 const struct timespec *,timeout,int *,uaddr2,int,val3)
859e8a89 634#endif
14690296
AF
635#if defined(__NR_futex_time64)
636safe_syscall6(int,futex_time64,int *,uaddr,int,op,int,val, \
637 const struct timespec *,timeout,int *,uaddr2,int,val3)
638#endif
2fe4fba1 639safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
bef653d9
PM
640safe_syscall2(int, kill, pid_t, pid, int, sig)
641safe_syscall2(int, tkill, int, tid, int, sig)
642safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
918c03ed
PM
643safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
644safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
0f26386c
DJ
645safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt,
646 unsigned long, pos_l, unsigned long, pos_h)
f8d00fba
DJ
647safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt,
648 unsigned long, pos_l, unsigned long, pos_h)
2a3c7619
PM
649safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
650 socklen_t, addrlen)
66687530
PM
651safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
652 int, flags, const struct sockaddr *, addr, socklen_t, addrlen)
653safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, size_t, len,
654 int, flags, struct sockaddr *, addr, socklen_t *, addrlen)
655safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, flags)
656safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
2a845989 657safe_syscall2(int, flock, int, fd, int, operation)
ddcbde15 658#if defined(TARGET_NR_rt_sigtimedwait) || defined(TARGET_NR_rt_sigtimedwait_time64)
b3f82330
PM
659safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, uinfo,
660 const struct timespec *, uts, size_t, sigsetsize)
859e8a89 661#endif
ff6dc130
PM
662safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len,
663 int, flags)
859e8a89 664#if defined(TARGET_NR_nanosleep)
9e518226
PM
665safe_syscall2(int, nanosleep, const struct timespec *, req,
666 struct timespec *, rem)
859e8a89 667#endif
6ac03b2c
FB
668#if defined(TARGET_NR_clock_nanosleep) || \
669 defined(TARGET_NR_clock_nanosleep_time64)
9e518226
PM
670safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
671 const struct timespec *, req, struct timespec *, rem)
672#endif
524fa340 673#ifdef __NR_ipc
d8c08b1e
MK
674#ifdef __s390x__
675safe_syscall5(int, ipc, int, call, long, first, long, second, long, third,
676 void *, ptr)
677#else
89f9fe44
PM
678safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
679 void *, ptr, long, fifth)
86e63695 680#endif
d8c08b1e 681#endif
86e63695
LV
682#ifdef __NR_msgsnd
683safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
684 int, flags)
86e63695
LV
685#endif
686#ifdef __NR_msgrcv
687safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
688 long, msgtype, int, flags)
86e63695
LV
689#endif
690#ifdef __NR_semtimedop
691safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
692 unsigned, nsops, const struct timespec *, timeout)
89f9fe44 693#endif
d107e375
FB
694#if defined(TARGET_NR_mq_timedsend) || \
695 defined(TARGET_NR_mq_timedsend_time64)
d40ecd66
PM
696safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
697 size_t, len, unsigned, prio, const struct timespec *, timeout)
859e8a89 698#endif
d107e375
FB
699#if defined(TARGET_NR_mq_timedreceive) || \
700 defined(TARGET_NR_mq_timedreceive_time64)
d40ecd66
PM
701safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
702 size_t, len, unsigned *, prio, const struct timespec *, timeout)
703#endif
84946457
AS
704#if defined(TARGET_NR_copy_file_range) && defined(__NR_copy_file_range)
705safe_syscall6(ssize_t, copy_file_range, int, infd, loff_t *, pinoff,
706 int, outfd, loff_t *, poutoff, size_t, length,
707 unsigned int, flags)
708#endif
709
49ca6f3e
PM
710/* We do ioctl like this rather than via safe_syscall3 to preserve the
711 * "third argument might be integer or pointer or not present" behaviour of
712 * the libc function.
713 */
714#define safe_ioctl(...) safe_syscall(__NR_ioctl, __VA_ARGS__)
435da5e7
PM
715/* Similarly for fcntl. Note that callers must always:
716 * pass the F_GETLK64 etc constants rather than the unsuffixed F_GETLK
717 * use the flock64 struct rather than unsuffixed flock
718 * This will then work and use a 64-bit offset for both 32-bit and 64-bit hosts.
719 */
720#ifdef __NR_fcntl64
721#define safe_fcntl(...) safe_syscall(__NR_fcntl64, __VA_ARGS__)
722#else
723#define safe_fcntl(...) safe_syscall(__NR_fcntl, __VA_ARGS__)
724#endif
50afd02b 725
8289d112
PB
726static inline int host_to_target_sock_type(int host_type)
727{
728 int target_type;
729
730 switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
731 case SOCK_DGRAM:
732 target_type = TARGET_SOCK_DGRAM;
733 break;
734 case SOCK_STREAM:
735 target_type = TARGET_SOCK_STREAM;
736 break;
737 default:
738 target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
739 break;
740 }
741
742#if defined(SOCK_CLOEXEC)
743 if (host_type & SOCK_CLOEXEC) {
744 target_type |= TARGET_SOCK_CLOEXEC;
745 }
746#endif
747
748#if defined(SOCK_NONBLOCK)
749 if (host_type & SOCK_NONBLOCK) {
750 target_type |= TARGET_SOCK_NONBLOCK;
751 }
752#endif
753
754 return target_type;
755}
756
992f48a0
BS
757static abi_ulong target_brk;
758static abi_ulong target_original_brk;
4d1de87c 759static abi_ulong brk_page;
31e31b8a 760
992f48a0 761void target_set_brk(abi_ulong new_brk)
31e31b8a 762{
4c1de73d 763 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
4d1de87c 764 brk_page = HOST_PAGE_ALIGN(target_brk);
31e31b8a
FB
765}
766
4d1de87c
CV
767//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
768#define DEBUGF_BRK(message, args...)
769
0da46a6e 770/* do_brk() must return target values and target errnos. */
992f48a0 771abi_long do_brk(abi_ulong new_brk)
31e31b8a 772{
992f48a0 773 abi_long mapped_addr;
ef4330c2 774 abi_ulong new_alloc_size;
31e31b8a 775
ee1bf83d
RH
776 /* brk pointers are always untagged */
777
3a0c6c4a 778 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
4d1de87c
CV
779
780 if (!new_brk) {
3a0c6c4a 781 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
53a5960a 782 return target_brk;
4d1de87c
CV
783 }
784 if (new_brk < target_original_brk) {
3a0c6c4a
PB
785 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
786 target_brk);
7ab240ad 787 return target_brk;
4d1de87c 788 }
3b46e624 789
4d1de87c
CV
790 /* If the new brk is less than the highest page reserved to the
791 * target heap allocation, set it and we're almost done... */
792 if (new_brk <= brk_page) {
793 /* Heap contents are initialized to zero, as for anonymous
794 * mapped pages. */
795 if (new_brk > target_brk) {
3e8f1628 796 memset(g2h_untagged(target_brk), 0, new_brk - target_brk);
4d1de87c 797 }
31e31b8a 798 target_brk = new_brk;
3a0c6c4a 799 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
72e21db7 800 return target_brk;
31e31b8a
FB
801 }
802
00faf08c
PM
803 /* We need to allocate more memory after the brk... Note that
804 * we don't use MAP_FIXED because that will map over the top of
805 * any existing mapping (like the one with the host libc or qemu
806 * itself); instead we treat "mapped but at wrong address" as
807 * a failure and unmap again.
808 */
4d1de87c 809 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
5fafdf24 810 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
54936004 811 PROT_READ|PROT_WRITE,
00faf08c
PM
812 MAP_ANON|MAP_PRIVATE, 0, 0));
813
814 if (mapped_addr == brk_page) {
70afc343
CV
815 /* Heap contents are initialized to zero, as for anonymous
816 * mapped pages. Technically the new pages are already
817 * initialized to zero since they *are* anonymous mapped
818 * pages, however we have to take care with the contents that
819 * come from the remaining part of the previous page: it may
820 * contains garbage data due to a previous heap usage (grown
821 * then shrunken). */
3e8f1628 822 memset(g2h_untagged(target_brk), 0, brk_page - target_brk);
70afc343 823
00faf08c 824 target_brk = new_brk;
4d1de87c 825 brk_page = HOST_PAGE_ALIGN(target_brk);
3a0c6c4a
PB
826 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
827 target_brk);
00faf08c
PM
828 return target_brk;
829 } else if (mapped_addr != -1) {
830 /* Mapped but at wrong address, meaning there wasn't actually
831 * enough space for this brk.
832 */
833 target_munmap(mapped_addr, new_alloc_size);
834 mapped_addr = -1;
3a0c6c4a 835 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
4d1de87c
CV
836 }
837 else {
3a0c6c4a 838 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
00faf08c 839 }
7ab240ad 840
7dd46c02
RH
841#if defined(TARGET_ALPHA)
842 /* We (partially) emulate OSF/1 on Alpha, which requires we
843 return a proper errno, not an unchanged brk value. */
00faf08c 844 return -TARGET_ENOMEM;
7dd46c02 845#endif
00faf08c 846 /* For everything else, return the previous break. */
7ab240ad 847 return target_brk;
31e31b8a
FB
848}
849
859e8a89 850#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
e5ce9688 851 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
26edcf41
TS
852static inline abi_long copy_from_user_fdset(fd_set *fds,
853 abi_ulong target_fds_addr,
854 int n)
31e31b8a 855{
26edcf41
TS
856 int i, nw, j, k;
857 abi_ulong b, *target_fds;
858
b1b2db29 859 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
26edcf41
TS
860 if (!(target_fds = lock_user(VERIFY_READ,
861 target_fds_addr,
862 sizeof(abi_ulong) * nw,
863 1)))
864 return -TARGET_EFAULT;
865
866 FD_ZERO(fds);
867 k = 0;
868 for (i = 0; i < nw; i++) {
869 /* grab the abi_ulong */
870 __get_user(b, &target_fds[i]);
871 for (j = 0; j < TARGET_ABI_BITS; j++) {
872 /* check the bit inside the abi_ulong */
873 if ((b >> j) & 1)
874 FD_SET(k, fds);
875 k++;
31e31b8a 876 }
31e31b8a 877 }
26edcf41
TS
878
879 unlock_user(target_fds, target_fds_addr, 0);
880
881 return 0;
31e31b8a
FB
882}
883
055e0906
MF
884static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
885 abi_ulong target_fds_addr,
886 int n)
887{
888 if (target_fds_addr) {
889 if (copy_from_user_fdset(fds, target_fds_addr, n))
890 return -TARGET_EFAULT;
891 *fds_ptr = fds;
892 } else {
893 *fds_ptr = NULL;
894 }
895 return 0;
896}
897
26edcf41
TS
898static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
899 const fd_set *fds,
900 int n)
31e31b8a 901{
31e31b8a 902 int i, nw, j, k;
992f48a0 903 abi_long v;
26edcf41 904 abi_ulong *target_fds;
31e31b8a 905
b1b2db29 906 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
26edcf41
TS
907 if (!(target_fds = lock_user(VERIFY_WRITE,
908 target_fds_addr,
909 sizeof(abi_ulong) * nw,
910 0)))
911 return -TARGET_EFAULT;
912
913 k = 0;
914 for (i = 0; i < nw; i++) {
915 v = 0;
916 for (j = 0; j < TARGET_ABI_BITS; j++) {
9ab709be 917 v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
26edcf41 918 k++;
31e31b8a 919 }
26edcf41 920 __put_user(v, &target_fds[i]);
31e31b8a 921 }
26edcf41
TS
922
923 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
924
925 return 0;
31e31b8a 926}
859e8a89 927#endif
31e31b8a 928
c596ed17
FB
929#if defined(__alpha__)
930#define HOST_HZ 1024
931#else
932#define HOST_HZ 100
933#endif
934
992f48a0 935static inline abi_long host_to_target_clock_t(long ticks)
c596ed17
FB
936{
937#if HOST_HZ == TARGET_HZ
938 return ticks;
939#else
940 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
941#endif
942}
943
579a97f7
FB
944static inline abi_long host_to_target_rusage(abi_ulong target_addr,
945 const struct rusage *rusage)
b409186b 946{
53a5960a
PB
947 struct target_rusage *target_rusage;
948
579a97f7
FB
949 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
950 return -TARGET_EFAULT;
cbb21eed
MB
951 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
952 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
953 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
954 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
955 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
956 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
957 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
958 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
959 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
960 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
961 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
962 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
963 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
964 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
965 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
966 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
967 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
968 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
53a5960a 969 unlock_user_struct(target_rusage, target_addr, 1);
579a97f7
FB
970
971 return 0;
b409186b
FB
972}
973
859e8a89 974#ifdef TARGET_NR_setrlimit
cbb21eed 975static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
81bbe906 976{
cbb21eed 977 abi_ulong target_rlim_swap;
95b33b2f
WT
978 rlim_t result;
979
cbb21eed
MB
980 target_rlim_swap = tswapal(target_rlim);
981 if (target_rlim_swap == TARGET_RLIM_INFINITY)
982 return RLIM_INFINITY;
983
984 result = target_rlim_swap;
985 if (target_rlim_swap != (rlim_t)result)
986 return RLIM_INFINITY;
95b33b2f
WT
987
988 return result;
81bbe906 989}
859e8a89 990#endif
81bbe906 991
859e8a89 992#if defined(TARGET_NR_getrlimit) || defined(TARGET_NR_ugetrlimit)
cbb21eed 993static inline abi_ulong host_to_target_rlim(rlim_t rlim)
81bbe906 994{
cbb21eed
MB
995 abi_ulong target_rlim_swap;
996 abi_ulong result;
95b33b2f 997
cbb21eed 998 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
95b33b2f 999 target_rlim_swap = TARGET_RLIM_INFINITY;
81bbe906 1000 else
95b33b2f 1001 target_rlim_swap = rlim;
cbb21eed 1002 result = tswapal(target_rlim_swap);
95b33b2f
WT
1003
1004 return result;
81bbe906 1005}
859e8a89 1006#endif
81bbe906 1007
e22b7015
WT
1008static inline int target_to_host_resource(int code)
1009{
1010 switch (code) {
1011 case TARGET_RLIMIT_AS:
1012 return RLIMIT_AS;
1013 case TARGET_RLIMIT_CORE:
1014 return RLIMIT_CORE;
1015 case TARGET_RLIMIT_CPU:
1016 return RLIMIT_CPU;
1017 case TARGET_RLIMIT_DATA:
1018 return RLIMIT_DATA;
1019 case TARGET_RLIMIT_FSIZE:
1020 return RLIMIT_FSIZE;
1021 case TARGET_RLIMIT_LOCKS:
1022 return RLIMIT_LOCKS;
1023 case TARGET_RLIMIT_MEMLOCK:
1024 return RLIMIT_MEMLOCK;
1025 case TARGET_RLIMIT_MSGQUEUE:
1026 return RLIMIT_MSGQUEUE;
1027 case TARGET_RLIMIT_NICE:
1028 return RLIMIT_NICE;
1029 case TARGET_RLIMIT_NOFILE:
1030 return RLIMIT_NOFILE;
1031 case TARGET_RLIMIT_NPROC:
1032 return RLIMIT_NPROC;
1033 case TARGET_RLIMIT_RSS:
1034 return RLIMIT_RSS;
1035 case TARGET_RLIMIT_RTPRIO:
1036 return RLIMIT_RTPRIO;
1037 case TARGET_RLIMIT_SIGPENDING:
1038 return RLIMIT_SIGPENDING;
1039 case TARGET_RLIMIT_STACK:
1040 return RLIMIT_STACK;
1041 default:
1042 return code;
1043 }
1044}
1045
788f5ec4
TS
1046static inline abi_long copy_from_user_timeval(struct timeval *tv,
1047 abi_ulong target_tv_addr)
31e31b8a 1048{
53a5960a
PB
1049 struct target_timeval *target_tv;
1050
6d5d5dde 1051 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
579a97f7 1052 return -TARGET_EFAULT;
6d5d5dde 1053 }
788f5ec4
TS
1054
1055 __get_user(tv->tv_sec, &target_tv->tv_sec);
1056 __get_user(tv->tv_usec, &target_tv->tv_usec);
1057
1058 unlock_user_struct(target_tv, target_tv_addr, 0);
579a97f7
FB
1059
1060 return 0;
31e31b8a
FB
1061}
1062
788f5ec4
TS
1063static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1064 const struct timeval *tv)
31e31b8a 1065{
53a5960a
PB
1066 struct target_timeval *target_tv;
1067
6d5d5dde
DB
1068 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
1069 return -TARGET_EFAULT;
1070 }
1071
1072 __put_user(tv->tv_sec, &target_tv->tv_sec);
1073 __put_user(tv->tv_usec, &target_tv->tv_usec);
1074
1075 unlock_user_struct(target_tv, target_tv_addr, 1);
1076
1077 return 0;
1078}
1079
6ac03b2c
FB
1080#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
1081static inline abi_long copy_from_user_timeval64(struct timeval *tv,
1082 abi_ulong target_tv_addr)
1083{
1084 struct target__kernel_sock_timeval *target_tv;
1085
1086 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
1087 return -TARGET_EFAULT;
1088 }
1089
1090 __get_user(tv->tv_sec, &target_tv->tv_sec);
1091 __get_user(tv->tv_usec, &target_tv->tv_usec);
1092
1093 unlock_user_struct(target_tv, target_tv_addr, 0);
1094
1095 return 0;
1096}
1097#endif
1098
6d5d5dde 1099static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr,
6ac03b2c 1100 const struct timeval *tv)
6d5d5dde
DB
1101{
1102 struct target__kernel_sock_timeval *target_tv;
1103
1104 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
579a97f7 1105 return -TARGET_EFAULT;
6d5d5dde 1106 }
788f5ec4
TS
1107
1108 __put_user(tv->tv_sec, &target_tv->tv_sec);
1109 __put_user(tv->tv_usec, &target_tv->tv_usec);
1110
1111 unlock_user_struct(target_tv, target_tv_addr, 1);
579a97f7
FB
1112
1113 return 0;
31e31b8a
FB
1114}
1115
859e8a89
AF
1116#if defined(TARGET_NR_futex) || \
1117 defined(TARGET_NR_rt_sigtimedwait) || \
1118 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6) || \
1119 defined(TARGET_NR_nanosleep) || defined(TARGET_NR_clock_settime) || \
1120 defined(TARGET_NR_utimensat) || defined(TARGET_NR_mq_timedsend) || \
d8c08b1e 1121 defined(TARGET_NR_mq_timedreceive) || defined(TARGET_NR_ipc) || \
2c86c90f
FB
1122 defined(TARGET_NR_semop) || defined(TARGET_NR_semtimedop) || \
1123 defined(TARGET_NR_timer_settime) || \
1124 (defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD))
6d5d5dde
DB
1125static inline abi_long target_to_host_timespec(struct timespec *host_ts,
1126 abi_ulong target_addr)
1127{
1128 struct target_timespec *target_ts;
1129
1130 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
1131 return -TARGET_EFAULT;
1132 }
1133 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
1134 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1135 unlock_user_struct(target_ts, target_addr, 0);
1136 return 0;
1137}
859e8a89 1138#endif
6d5d5dde 1139
828cb3a1
FB
1140#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || \
1141 defined(TARGET_NR_timer_settime64) || \
d107e375
FB
1142 defined(TARGET_NR_mq_timedsend_time64) || \
1143 defined(TARGET_NR_mq_timedreceive_time64) || \
6ac03b2c 1144 (defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD)) || \
ddcbde15 1145 defined(TARGET_NR_clock_nanosleep_time64) || \
cac46eb0
FB
1146 defined(TARGET_NR_rt_sigtimedwait_time64) || \
1147 defined(TARGET_NR_utimensat) || \
1148 defined(TARGET_NR_utimensat_time64) || \
e5ce9688
FB
1149 defined(TARGET_NR_semtimedop_time64) || \
1150 defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64)
c6c8d102
AF
1151static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
1152 abi_ulong target_addr)
1153{
1154 struct target__kernel_timespec *target_ts;
1155
1156 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
1157 return -TARGET_EFAULT;
1158 }
1159 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
1160 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
00576757
LV
1161 /* in 32bit mode, this drops the padding */
1162 host_ts->tv_nsec = (long)(abi_long)host_ts->tv_nsec;
c6c8d102
AF
1163 unlock_user_struct(target_ts, target_addr, 0);
1164 return 0;
1165}
1166#endif
1167
6d5d5dde
DB
1168static inline abi_long host_to_target_timespec(abi_ulong target_addr,
1169 struct timespec *host_ts)
1170{
1171 struct target_timespec *target_ts;
1172
1173 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) {
1174 return -TARGET_EFAULT;
1175 }
1176 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
1177 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1178 unlock_user_struct(target_ts, target_addr, 1);
1179 return 0;
1180}
1181
1182static inline abi_long host_to_target_timespec64(abi_ulong target_addr,
1183 struct timespec *host_ts)
1184{
1185 struct target__kernel_timespec *target_ts;
1186
1187 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) {
1188 return -TARGET_EFAULT;
1189 }
1190 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
1191 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1192 unlock_user_struct(target_ts, target_addr, 1);
1193 return 0;
1194}
1195
a52f5f87
RH
1196#if defined(TARGET_NR_gettimeofday)
1197static inline abi_long copy_to_user_timezone(abi_ulong target_tz_addr,
1198 struct timezone *tz)
1199{
1200 struct target_timezone *target_tz;
1201
1202 if (!lock_user_struct(VERIFY_WRITE, target_tz, target_tz_addr, 1)) {
1203 return -TARGET_EFAULT;
1204 }
1205
1206 __put_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1207 __put_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1208
1209 unlock_user_struct(target_tz, target_tz_addr, 1);
1210
1211 return 0;
1212}
1213#endif
1214
859e8a89 1215#if defined(TARGET_NR_settimeofday)
ef4467e9
PB
1216static inline abi_long copy_from_user_timezone(struct timezone *tz,
1217 abi_ulong target_tz_addr)
1218{
1219 struct target_timezone *target_tz;
1220
1221 if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
1222 return -TARGET_EFAULT;
1223 }
1224
1225 __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1226 __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1227
1228 unlock_user_struct(target_tz, target_tz_addr, 0);
1229
1230 return 0;
1231}
859e8a89 1232#endif
ef4467e9 1233
8ec9cf89
NF
1234#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1235#include <mqueue.h>
1236
24e1003a
AJ
1237static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1238 abi_ulong target_mq_attr_addr)
1239{
1240 struct target_mq_attr *target_mq_attr;
1241
1242 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1243 target_mq_attr_addr, 1))
1244 return -TARGET_EFAULT;
1245
1246 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1247 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1248 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1249 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1250
1251 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1252
1253 return 0;
1254}
1255
1256static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1257 const struct mq_attr *attr)
1258{
1259 struct target_mq_attr *target_mq_attr;
1260
1261 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1262 target_mq_attr_addr, 0))
1263 return -TARGET_EFAULT;
1264
1265 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1266 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1267 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1268 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1269
1270 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1271
1272 return 0;
1273}
8ec9cf89 1274#endif
31e31b8a 1275
055e0906 1276#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
0da46a6e 1277/* do_select() must return target values and target errnos. */
992f48a0 1278static abi_long do_select(int n,
26edcf41
TS
1279 abi_ulong rfd_addr, abi_ulong wfd_addr,
1280 abi_ulong efd_addr, abi_ulong target_tv_addr)
31e31b8a
FB
1281{
1282 fd_set rfds, wfds, efds;
1283 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6df9d38d
PM
1284 struct timeval tv;
1285 struct timespec ts, *ts_ptr;
992f48a0 1286 abi_long ret;
31e31b8a 1287
055e0906
MF
1288 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1289 if (ret) {
1290 return ret;
53a5960a 1291 }
055e0906
MF
1292 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1293 if (ret) {
1294 return ret;
53a5960a 1295 }
055e0906
MF
1296 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1297 if (ret) {
1298 return ret;
53a5960a 1299 }
3b46e624 1300
26edcf41 1301 if (target_tv_addr) {
788f5ec4
TS
1302 if (copy_from_user_timeval(&tv, target_tv_addr))
1303 return -TARGET_EFAULT;
6df9d38d
PM
1304 ts.tv_sec = tv.tv_sec;
1305 ts.tv_nsec = tv.tv_usec * 1000;
1306 ts_ptr = &ts;
31e31b8a 1307 } else {
6df9d38d 1308 ts_ptr = NULL;
31e31b8a 1309 }
26edcf41 1310
6df9d38d
PM
1311 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
1312 ts_ptr, NULL));
53a5960a 1313
26edcf41
TS
1314 if (!is_error(ret)) {
1315 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1316 return -TARGET_EFAULT;
1317 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1318 return -TARGET_EFAULT;
1319 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1320 return -TARGET_EFAULT;
31e31b8a 1321
6df9d38d
PM
1322 if (target_tv_addr) {
1323 tv.tv_sec = ts.tv_sec;
1324 tv.tv_usec = ts.tv_nsec / 1000;
1325 if (copy_to_user_timeval(target_tv_addr, &tv)) {
1326 return -TARGET_EFAULT;
1327 }
1328 }
31e31b8a 1329 }
579a97f7 1330
31e31b8a
FB
1331 return ret;
1332}
5457dc9e
LV
1333
1334#if defined(TARGET_WANT_OLD_SYS_SELECT)
1335static abi_long do_old_select(abi_ulong arg1)
1336{
1337 struct target_sel_arg_struct *sel;
1338 abi_ulong inp, outp, exp, tvp;
1339 long nsel;
1340
1341 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) {
1342 return -TARGET_EFAULT;
1343 }
1344
1345 nsel = tswapal(sel->n);
1346 inp = tswapal(sel->inp);
1347 outp = tswapal(sel->outp);
1348 exp = tswapal(sel->exp);
1349 tvp = tswapal(sel->tvp);
1350
1351 unlock_user_struct(sel, arg1, 0);
1352
1353 return do_select(nsel, inp, outp, exp, tvp);
1354}
1355#endif
055e0906 1356#endif
31e31b8a 1357
e5ce9688
FB
1358#if defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
1359static abi_long do_pselect6(abi_long arg1, abi_long arg2, abi_long arg3,
1360 abi_long arg4, abi_long arg5, abi_long arg6,
1361 bool time64)
1362{
1363 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
1364 fd_set rfds, wfds, efds;
1365 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1366 struct timespec ts, *ts_ptr;
1367 abi_long ret;
1368
1369 /*
1370 * The 6th arg is actually two args smashed together,
1371 * so we cannot use the C library.
1372 */
1373 sigset_t set;
1374 struct {
1375 sigset_t *set;
1376 size_t size;
1377 } sig, *sig_ptr;
1378
1379 abi_ulong arg_sigset, arg_sigsize, *arg7;
1380 target_sigset_t *target_sigset;
1381
1382 n = arg1;
1383 rfd_addr = arg2;
1384 wfd_addr = arg3;
1385 efd_addr = arg4;
1386 ts_addr = arg5;
1387
1388 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1389 if (ret) {
1390 return ret;
1391 }
1392 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1393 if (ret) {
1394 return ret;
1395 }
1396 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1397 if (ret) {
1398 return ret;
1399 }
1400
1401 /*
1402 * This takes a timespec, and not a timeval, so we cannot
1403 * use the do_select() helper ...
1404 */
1405 if (ts_addr) {
1406 if (time64) {
1407 if (target_to_host_timespec64(&ts, ts_addr)) {
1408 return -TARGET_EFAULT;
1409 }
1410 } else {
1411 if (target_to_host_timespec(&ts, ts_addr)) {
1412 return -TARGET_EFAULT;
1413 }
1414 }
1415 ts_ptr = &ts;
1416 } else {
1417 ts_ptr = NULL;
1418 }
1419
1420 /* Extract the two packed args for the sigset */
1421 if (arg6) {
1422 sig_ptr = &sig;
1423 sig.size = SIGSET_T_SIZE;
1424
1425 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
1426 if (!arg7) {
1427 return -TARGET_EFAULT;
1428 }
1429 arg_sigset = tswapal(arg7[0]);
1430 arg_sigsize = tswapal(arg7[1]);
1431 unlock_user(arg7, arg6, 0);
1432
1433 if (arg_sigset) {
1434 sig.set = &set;
1435 if (arg_sigsize != sizeof(*target_sigset)) {
1436 /* Like the kernel, we enforce correct size sigsets */
1437 return -TARGET_EINVAL;
1438 }
1439 target_sigset = lock_user(VERIFY_READ, arg_sigset,
1440 sizeof(*target_sigset), 1);
1441 if (!target_sigset) {
1442 return -TARGET_EFAULT;
1443 }
1444 target_to_host_sigset(&set, target_sigset);
1445 unlock_user(target_sigset, arg_sigset, 0);
1446 } else {
1447 sig.set = NULL;
1448 }
1449 } else {
1450 sig_ptr = NULL;
1451 }
1452
1453 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
1454 ts_ptr, sig_ptr));
1455
1456 if (!is_error(ret)) {
1457 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) {
1458 return -TARGET_EFAULT;
1459 }
1460 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) {
1461 return -TARGET_EFAULT;
1462 }
1463 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) {
1464 return -TARGET_EFAULT;
1465 }
1466 if (time64) {
1467 if (ts_addr && host_to_target_timespec64(ts_addr, &ts)) {
1468 return -TARGET_EFAULT;
1469 }
1470 } else {
1471 if (ts_addr && host_to_target_timespec(ts_addr, &ts)) {
1472 return -TARGET_EFAULT;
1473 }
1474 }
1475 }
1476 return ret;
1477}
1478#endif
1479
1480#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll) || \
1481 defined(TARGET_NR_ppoll_time64)
1482static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3,
1483 abi_long arg4, abi_long arg5, bool ppoll, bool time64)
1484{
1485 struct target_pollfd *target_pfd;
1486 unsigned int nfds = arg2;
1487 struct pollfd *pfd;
1488 unsigned int i;
1489 abi_long ret;
1490
1491 pfd = NULL;
1492 target_pfd = NULL;
1493 if (nfds) {
1494 if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
1495 return -TARGET_EINVAL;
1496 }
1497 target_pfd = lock_user(VERIFY_WRITE, arg1,
1498 sizeof(struct target_pollfd) * nfds, 1);
1499 if (!target_pfd) {
1500 return -TARGET_EFAULT;
1501 }
1502
1503 pfd = alloca(sizeof(struct pollfd) * nfds);
1504 for (i = 0; i < nfds; i++) {
1505 pfd[i].fd = tswap32(target_pfd[i].fd);
1506 pfd[i].events = tswap16(target_pfd[i].events);
1507 }
1508 }
1509 if (ppoll) {
1510 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
1511 target_sigset_t *target_set;
1512 sigset_t _set, *set = &_set;
1513
1514 if (arg3) {
1515 if (time64) {
1516 if (target_to_host_timespec64(timeout_ts, arg3)) {
1517 unlock_user(target_pfd, arg1, 0);
1518 return -TARGET_EFAULT;
1519 }
1520 } else {
1521 if (target_to_host_timespec(timeout_ts, arg3)) {
1522 unlock_user(target_pfd, arg1, 0);
1523 return -TARGET_EFAULT;
1524 }
1525 }
1526 } else {
1527 timeout_ts = NULL;
1528 }
1529
1530 if (arg4) {
1531 if (arg5 != sizeof(target_sigset_t)) {
1532 unlock_user(target_pfd, arg1, 0);
1533 return -TARGET_EINVAL;
1534 }
1535
1536 target_set = lock_user(VERIFY_READ, arg4,
1537 sizeof(target_sigset_t), 1);
1538 if (!target_set) {
1539 unlock_user(target_pfd, arg1, 0);
1540 return -TARGET_EFAULT;
1541 }
1542 target_to_host_sigset(set, target_set);
1543 } else {
1544 set = NULL;
1545 }
1546
1547 ret = get_errno(safe_ppoll(pfd, nfds, timeout_ts,
1548 set, SIGSET_T_SIZE));
1549
1550 if (!is_error(ret) && arg3) {
1551 if (time64) {
1552 if (host_to_target_timespec64(arg3, timeout_ts)) {
1553 return -TARGET_EFAULT;
1554 }
1555 } else {
1556 if (host_to_target_timespec(arg3, timeout_ts)) {
1557 return -TARGET_EFAULT;
1558 }
1559 }
1560 }
1561 if (arg4) {
1562 unlock_user(target_set, arg4, 0);
1563 }
1564 } else {
1565 struct timespec ts, *pts;
1566
1567 if (arg3 >= 0) {
1568 /* Convert ms to secs, ns */
1569 ts.tv_sec = arg3 / 1000;
1570 ts.tv_nsec = (arg3 % 1000) * 1000000LL;
1571 pts = &ts;
1572 } else {
1573 /* -ve poll() timeout means "infinite" */
1574 pts = NULL;
1575 }
1576 ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
1577 }
1578
1579 if (!is_error(ret)) {
1580 for (i = 0; i < nfds; i++) {
1581 target_pfd[i].revents = tswap16(pfd[i].revents);
1582 }
1583 }
1584 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
1585 return ret;
1586}
1587#endif
1588
099d6b0f
RV
1589static abi_long do_pipe2(int host_pipe[], int flags)
1590{
1591#ifdef CONFIG_PIPE2
1592 return pipe2(host_pipe, flags);
1593#else
1594 return -ENOSYS;
1595#endif
1596}
1597
fb41a66e
RH
1598static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1599 int flags, int is_pipe2)
099d6b0f
RV
1600{
1601 int host_pipe[2];
1602 abi_long ret;
1603 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1604
1605 if (is_error(ret))
1606 return get_errno(ret);
fb41a66e
RH
1607
1608 /* Several targets have special calling conventions for the original
1609 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1610 if (!is_pipe2) {
1611#if defined(TARGET_ALPHA)
1612 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1613 return host_pipe[0];
1614#elif defined(TARGET_MIPS)
1615 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1616 return host_pipe[0];
1617#elif defined(TARGET_SH4)
597c0212 1618 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
fb41a66e 1619 return host_pipe[0];
82f05b69
PM
1620#elif defined(TARGET_SPARC)
1621 ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1622 return host_pipe[0];
597c0212 1623#endif
fb41a66e
RH
1624 }
1625
099d6b0f
RV
1626 if (put_user_s32(host_pipe[0], pipedes)
1627 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1628 return -TARGET_EFAULT;
099d6b0f
RV
1629 return get_errno(ret);
1630}
1631
b975b83b
LL
1632static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1633 abi_ulong target_addr,
1634 socklen_t len)
1635{
1636 struct target_ip_mreqn *target_smreqn;
1637
1638 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1639 if (!target_smreqn)
1640 return -TARGET_EFAULT;
1641 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1642 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1643 if (len == sizeof(struct target_ip_mreqn))
cbb21eed 1644 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
b975b83b
LL
1645 unlock_user(target_smreqn, target_addr, 0);
1646
1647 return 0;
1648}
1649
7b36f782 1650static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
579a97f7
FB
1651 abi_ulong target_addr,
1652 socklen_t len)
7854b056 1653{
607175e0
AJ
1654 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1655 sa_family_t sa_family;
53a5960a
PB
1656 struct target_sockaddr *target_saddr;
1657
7b36f782
LV
1658 if (fd_trans_target_to_host_addr(fd)) {
1659 return fd_trans_target_to_host_addr(fd)(addr, target_addr, len);
1660 }
1661
579a97f7
FB
1662 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1663 if (!target_saddr)
1664 return -TARGET_EFAULT;
607175e0
AJ
1665
1666 sa_family = tswap16(target_saddr->sa_family);
1667
1668 /* Oops. The caller might send a incomplete sun_path; sun_path
1669 * must be terminated by \0 (see the manual page), but
1670 * unfortunately it is quite common to specify sockaddr_un
1671 * length as "strlen(x->sun_path)" while it should be
1672 * "strlen(...) + 1". We'll fix that here if needed.
1673 * Linux kernel has a similar feature.
1674 */
1675
1676 if (sa_family == AF_UNIX) {
1677 if (len < unix_maxlen && len > 0) {
1678 char *cp = (char*)target_saddr;
1679
1680 if ( cp[len-1] && !cp[len] )
1681 len++;
1682 }
1683 if (len > unix_maxlen)
1684 len = unix_maxlen;
1685 }
1686
53a5960a 1687 memcpy(addr, target_saddr, len);
607175e0 1688 addr->sa_family = sa_family;
6c5b5645
LV
1689 if (sa_family == AF_NETLINK) {
1690 struct sockaddr_nl *nladdr;
1691
1692 nladdr = (struct sockaddr_nl *)addr;
1693 nladdr->nl_pid = tswap32(nladdr->nl_pid);
1694 nladdr->nl_groups = tswap32(nladdr->nl_groups);
1695 } else if (sa_family == AF_PACKET) {
33a29b51
JT
1696 struct target_sockaddr_ll *lladdr;
1697
1698 lladdr = (struct target_sockaddr_ll *)addr;
1699 lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
1700 lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
1701 }
53a5960a 1702 unlock_user(target_saddr, target_addr, 0);
579a97f7
FB
1703
1704 return 0;
7854b056
FB
1705}
1706
579a97f7
FB
1707static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1708 struct sockaddr *addr,
1709 socklen_t len)
7854b056 1710{
53a5960a
PB
1711 struct target_sockaddr *target_saddr;
1712
a1e22192
PM
1713 if (len == 0) {
1714 return 0;
1715 }
6860710c 1716 assert(addr);
a1e22192 1717
579a97f7
FB
1718 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1719 if (!target_saddr)
1720 return -TARGET_EFAULT;
53a5960a 1721 memcpy(target_saddr, addr, len);
a1e22192
PM
1722 if (len >= offsetof(struct target_sockaddr, sa_family) +
1723 sizeof(target_saddr->sa_family)) {
1724 target_saddr->sa_family = tswap16(addr->sa_family);
1725 }
a47401bc
PMD
1726 if (addr->sa_family == AF_NETLINK &&
1727 len >= sizeof(struct target_sockaddr_nl)) {
1728 struct target_sockaddr_nl *target_nl =
1729 (struct target_sockaddr_nl *)target_saddr;
6c5b5645
LV
1730 target_nl->nl_pid = tswap32(target_nl->nl_pid);
1731 target_nl->nl_groups = tswap32(target_nl->nl_groups);
a82ea939
LV
1732 } else if (addr->sa_family == AF_PACKET) {
1733 struct sockaddr_ll *target_ll = (struct sockaddr_ll *)target_saddr;
1734 target_ll->sll_ifindex = tswap32(target_ll->sll_ifindex);
1735 target_ll->sll_hatype = tswap16(target_ll->sll_hatype);
ee1ac3a1
HD
1736 } else if (addr->sa_family == AF_INET6 &&
1737 len >= sizeof(struct target_sockaddr_in6)) {
1738 struct target_sockaddr_in6 *target_in6 =
1739 (struct target_sockaddr_in6 *)target_saddr;
1740 target_in6->sin6_scope_id = tswap16(target_in6->sin6_scope_id);
6c5b5645 1741 }
53a5960a 1742 unlock_user(target_saddr, target_addr, len);
579a97f7
FB
1743
1744 return 0;
7854b056
FB
1745}
1746
5a4a898d
FB
1747static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1748 struct target_msghdr *target_msgh)
7854b056
FB
1749{
1750 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
5a4a898d
FB
1751 abi_long msg_controllen;
1752 abi_ulong target_cmsg_addr;
ee104587 1753 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
7854b056 1754 socklen_t space = 0;
5a4a898d 1755
cbb21eed 1756 msg_controllen = tswapal(target_msgh->msg_controllen);
5a4a898d
FB
1757 if (msg_controllen < sizeof (struct target_cmsghdr))
1758 goto the_end;
cbb21eed 1759 target_cmsg_addr = tswapal(target_msgh->msg_control);
5a4a898d 1760 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
ee104587 1761 target_cmsg_start = target_cmsg;
5a4a898d
FB
1762 if (!target_cmsg)
1763 return -TARGET_EFAULT;
7854b056
FB
1764
1765 while (cmsg && target_cmsg) {
1766 void *data = CMSG_DATA(cmsg);
1767 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1768
cbb21eed 1769 int len = tswapal(target_cmsg->cmsg_len)
ad762b99 1770 - sizeof(struct target_cmsghdr);
7854b056
FB
1771
1772 space += CMSG_SPACE(len);
1773 if (space > msgh->msg_controllen) {
1774 space -= CMSG_SPACE(len);
c2aeb258
PM
1775 /* This is a QEMU bug, since we allocated the payload
1776 * area ourselves (unlike overflow in host-to-target
1777 * conversion, which is just the guest giving us a buffer
1778 * that's too small). It can't happen for the payload types
1779 * we currently support; if it becomes an issue in future
1780 * we would need to improve our allocation strategy to
1781 * something more intelligent than "twice the size of the
1782 * target buffer we're reading from".
1783 */
39be5350
JK
1784 qemu_log_mask(LOG_UNIMP,
1785 ("Unsupported ancillary data %d/%d: "
1786 "unhandled msg size\n"),
1787 tswap32(target_cmsg->cmsg_level),
1788 tswap32(target_cmsg->cmsg_type));
7854b056
FB
1789 break;
1790 }
1791
dbf4f796
PJ
1792 if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1793 cmsg->cmsg_level = SOL_SOCKET;
1794 } else {
1795 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1796 }
7854b056
FB
1797 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1798 cmsg->cmsg_len = CMSG_LEN(len);
1799
30b8b68e 1800 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
7854b056
FB
1801 int *fd = (int *)data;
1802 int *target_fd = (int *)target_data;
1803 int i, numfds = len / sizeof(int);
1804
876e23cb
PM
1805 for (i = 0; i < numfds; i++) {
1806 __get_user(fd[i], target_fd + i);
1807 }
30b8b68e
AS
1808 } else if (cmsg->cmsg_level == SOL_SOCKET
1809 && cmsg->cmsg_type == SCM_CREDENTIALS) {
1810 struct ucred *cred = (struct ucred *)data;
1811 struct target_ucred *target_cred =
1812 (struct target_ucred *)target_data;
1813
876e23cb
PM
1814 __get_user(cred->pid, &target_cred->pid);
1815 __get_user(cred->uid, &target_cred->uid);
1816 __get_user(cred->gid, &target_cred->gid);
30b8b68e 1817 } else {
39be5350
JK
1818 qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
1819 cmsg->cmsg_level, cmsg->cmsg_type);
30b8b68e 1820 memcpy(data, target_data, len);
7854b056
FB
1821 }
1822
1823 cmsg = CMSG_NXTHDR(msgh, cmsg);
ee104587
JN
1824 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1825 target_cmsg_start);
7854b056 1826 }
5a4a898d
FB
1827 unlock_user(target_cmsg, target_cmsg_addr, 0);
1828 the_end:
7854b056 1829 msgh->msg_controllen = space;
5a4a898d 1830 return 0;
7854b056
FB
1831}
1832
5a4a898d
FB
1833static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1834 struct msghdr *msgh)
7854b056
FB
1835{
1836 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
5a4a898d
FB
1837 abi_long msg_controllen;
1838 abi_ulong target_cmsg_addr;
ee104587 1839 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
7854b056
FB
1840 socklen_t space = 0;
1841
cbb21eed 1842 msg_controllen = tswapal(target_msgh->msg_controllen);
5a4a898d
FB
1843 if (msg_controllen < sizeof (struct target_cmsghdr))
1844 goto the_end;
cbb21eed 1845 target_cmsg_addr = tswapal(target_msgh->msg_control);
5a4a898d 1846 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
ee104587 1847 target_cmsg_start = target_cmsg;
5a4a898d
FB
1848 if (!target_cmsg)
1849 return -TARGET_EFAULT;
1850
7854b056
FB
1851 while (cmsg && target_cmsg) {
1852 void *data = CMSG_DATA(cmsg);
1853 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1854
ad762b99 1855 int len = cmsg->cmsg_len - sizeof(struct cmsghdr);
c2aeb258 1856 int tgt_len, tgt_space;
7854b056 1857
c2aeb258
PM
1858 /* We never copy a half-header but may copy half-data;
1859 * this is Linux's behaviour in put_cmsg(). Note that
1860 * truncation here is a guest problem (which we report
1861 * to the guest via the CTRUNC bit), unlike truncation
1862 * in target_to_host_cmsg, which is a QEMU bug.
1863 */
7174970a 1864 if (msg_controllen < sizeof(struct target_cmsghdr)) {
c2aeb258 1865 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
7854b056
FB
1866 break;
1867 }
1868
dbf4f796
PJ
1869 if (cmsg->cmsg_level == SOL_SOCKET) {
1870 target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1871 } else {
1872 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1873 }
7854b056 1874 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
7854b056 1875
c2aeb258
PM
1876 /* Payload types which need a different size of payload on
1877 * the target must adjust tgt_len here.
1878 */
309786cf 1879 tgt_len = len;
c2aeb258
PM
1880 switch (cmsg->cmsg_level) {
1881 case SOL_SOCKET:
1882 switch (cmsg->cmsg_type) {
1883 case SO_TIMESTAMP:
1884 tgt_len = sizeof(struct target_timeval);
1885 break;
1886 default:
1887 break;
1888 }
309786cf 1889 break;
c2aeb258
PM
1890 default:
1891 break;
1892 }
1893
7174970a 1894 if (msg_controllen < TARGET_CMSG_LEN(tgt_len)) {
c2aeb258 1895 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
7174970a 1896 tgt_len = msg_controllen - sizeof(struct target_cmsghdr);
c2aeb258
PM
1897 }
1898
1899 /* We must now copy-and-convert len bytes of payload
1900 * into tgt_len bytes of destination space. Bear in mind
1901 * that in both source and destination we may be dealing
1902 * with a truncated value!
1903 */
52b65494
HD
1904 switch (cmsg->cmsg_level) {
1905 case SOL_SOCKET:
1906 switch (cmsg->cmsg_type) {
1907 case SCM_RIGHTS:
1908 {
1909 int *fd = (int *)data;
1910 int *target_fd = (int *)target_data;
c2aeb258 1911 int i, numfds = tgt_len / sizeof(int);
52b65494 1912
876e23cb
PM
1913 for (i = 0; i < numfds; i++) {
1914 __put_user(fd[i], target_fd + i);
1915 }
52b65494
HD
1916 break;
1917 }
1918 case SO_TIMESTAMP:
1919 {
1920 struct timeval *tv = (struct timeval *)data;
1921 struct target_timeval *target_tv =
1922 (struct target_timeval *)target_data;
1923
c2aeb258
PM
1924 if (len != sizeof(struct timeval) ||
1925 tgt_len != sizeof(struct target_timeval)) {
52b65494 1926 goto unimplemented;
c2aeb258 1927 }
52b65494
HD
1928
1929 /* copy struct timeval to target */
876e23cb
PM
1930 __put_user(tv->tv_sec, &target_tv->tv_sec);
1931 __put_user(tv->tv_usec, &target_tv->tv_usec);
52b65494
HD
1932 break;
1933 }
4bc29756
HD
1934 case SCM_CREDENTIALS:
1935 {
1936 struct ucred *cred = (struct ucred *)data;
1937 struct target_ucred *target_cred =
1938 (struct target_ucred *)target_data;
1939
1940 __put_user(cred->pid, &target_cred->pid);
1941 __put_user(cred->uid, &target_cred->uid);
1942 __put_user(cred->gid, &target_cred->gid);
1943 break;
1944 }
52b65494
HD
1945 default:
1946 goto unimplemented;
1947 }
1948 break;
7854b056 1949
ee1ac3a1
HD
1950 case SOL_IP:
1951 switch (cmsg->cmsg_type) {
1952 case IP_TTL:
1953 {
1954 uint32_t *v = (uint32_t *)data;
1955 uint32_t *t_int = (uint32_t *)target_data;
1956
7174970a
PM
1957 if (len != sizeof(uint32_t) ||
1958 tgt_len != sizeof(uint32_t)) {
1959 goto unimplemented;
1960 }
ee1ac3a1
HD
1961 __put_user(*v, t_int);
1962 break;
1963 }
1964 case IP_RECVERR:
1965 {
1966 struct errhdr_t {
1967 struct sock_extended_err ee;
1968 struct sockaddr_in offender;
1969 };
1970 struct errhdr_t *errh = (struct errhdr_t *)data;
1971 struct errhdr_t *target_errh =
1972 (struct errhdr_t *)target_data;
1973
7174970a
PM
1974 if (len != sizeof(struct errhdr_t) ||
1975 tgt_len != sizeof(struct errhdr_t)) {
1976 goto unimplemented;
1977 }
ee1ac3a1
HD
1978 __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
1979 __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
1980 __put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
1981 __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
1982 __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);
1983 __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);
1984 __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);
1985 host_to_target_sockaddr((unsigned long) &target_errh->offender,
1986 (void *) &errh->offender, sizeof(errh->offender));
1987 break;
1988 }
1989 default:
1990 goto unimplemented;
1991 }
1992 break;
1993
1994 case SOL_IPV6:
1995 switch (cmsg->cmsg_type) {
1996 case IPV6_HOPLIMIT:
1997 {
1998 uint32_t *v = (uint32_t *)data;
1999 uint32_t *t_int = (uint32_t *)target_data;
2000
7174970a
PM
2001 if (len != sizeof(uint32_t) ||
2002 tgt_len != sizeof(uint32_t)) {
2003 goto unimplemented;
2004 }
ee1ac3a1
HD
2005 __put_user(*v, t_int);
2006 break;
2007 }
2008 case IPV6_RECVERR:
2009 {
2010 struct errhdr6_t {
2011 struct sock_extended_err ee;
2012 struct sockaddr_in6 offender;
2013 };
2014 struct errhdr6_t *errh = (struct errhdr6_t *)data;
2015 struct errhdr6_t *target_errh =
2016 (struct errhdr6_t *)target_data;
2017
7174970a
PM
2018 if (len != sizeof(struct errhdr6_t) ||
2019 tgt_len != sizeof(struct errhdr6_t)) {
2020 goto unimplemented;
2021 }
ee1ac3a1
HD
2022 __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
2023 __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
2024 __put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
2025 __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
2026 __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);
2027 __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);
2028 __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);
2029 host_to_target_sockaddr((unsigned long) &target_errh->offender,
2030 (void *) &errh->offender, sizeof(errh->offender));
2031 break;
2032 }
2033 default:
2034 goto unimplemented;
2035 }
2036 break;
2037
52b65494
HD
2038 default:
2039 unimplemented:
39be5350
JK
2040 qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
2041 cmsg->cmsg_level, cmsg->cmsg_type);
c2aeb258
PM
2042 memcpy(target_data, data, MIN(len, tgt_len));
2043 if (tgt_len > len) {
2044 memset(target_data + len, 0, tgt_len - len);
2045 }
7854b056
FB
2046 }
2047
7174970a
PM
2048 target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(tgt_len));
2049 tgt_space = TARGET_CMSG_SPACE(tgt_len);
c2aeb258
PM
2050 if (msg_controllen < tgt_space) {
2051 tgt_space = msg_controllen;
2052 }
2053 msg_controllen -= tgt_space;
2054 space += tgt_space;
7854b056 2055 cmsg = CMSG_NXTHDR(msgh, cmsg);
ee104587
JN
2056 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
2057 target_cmsg_start);
7854b056 2058 }
5a4a898d
FB
2059 unlock_user(target_cmsg, target_cmsg_addr, space);
2060 the_end:
cbb21eed 2061 target_msgh->msg_controllen = tswapal(space);
5a4a898d 2062 return 0;
7854b056
FB
2063}
2064
0da46a6e 2065/* do_setsockopt() Must return target values and target errnos. */
992f48a0 2066static abi_long do_setsockopt(int sockfd, int level, int optname,
2f619698 2067 abi_ulong optval_addr, socklen_t optlen)
7854b056 2068{
992f48a0 2069 abi_long ret;
32407103 2070 int val;
b975b83b 2071 struct ip_mreqn *ip_mreq;
6e3cb58f 2072 struct ip_mreq_source *ip_mreq_source;
3b46e624 2073
8853f86e
FB
2074 switch(level) {
2075 case SOL_TCP:
fe51b0a5
SCW
2076 case SOL_UDP:
2077 /* TCP and UDP options all take an 'int' value. */
7854b056 2078 if (optlen < sizeof(uint32_t))
0da46a6e 2079 return -TARGET_EINVAL;
3b46e624 2080
2f619698
FB
2081 if (get_user_u32(val, optval_addr))
2082 return -TARGET_EFAULT;
8853f86e
FB
2083 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
2084 break;
2085 case SOL_IP:
2086 switch(optname) {
2efbe911
FB
2087 case IP_TOS:
2088 case IP_TTL:
8853f86e 2089 case IP_HDRINCL:
2efbe911
FB
2090 case IP_ROUTER_ALERT:
2091 case IP_RECVOPTS:
2092 case IP_RETOPTS:
2093 case IP_PKTINFO:
2094 case IP_MTU_DISCOVER:
2095 case IP_RECVERR:
ee1ac3a1 2096 case IP_RECVTTL:
2efbe911
FB
2097 case IP_RECVTOS:
2098#ifdef IP_FREEBIND
2099 case IP_FREEBIND:
2100#endif
2101 case IP_MULTICAST_TTL:
2102 case IP_MULTICAST_LOOP:
8853f86e
FB
2103 val = 0;
2104 if (optlen >= sizeof(uint32_t)) {
2f619698
FB
2105 if (get_user_u32(val, optval_addr))
2106 return -TARGET_EFAULT;
8853f86e 2107 } else if (optlen >= 1) {
2f619698
FB
2108 if (get_user_u8(val, optval_addr))
2109 return -TARGET_EFAULT;
8853f86e
FB
2110 }
2111 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
2112 break;
b975b83b
LL
2113 case IP_ADD_MEMBERSHIP:
2114 case IP_DROP_MEMBERSHIP:
2115 if (optlen < sizeof (struct target_ip_mreq) ||
2116 optlen > sizeof (struct target_ip_mreqn))
2117 return -TARGET_EINVAL;
2118
2119 ip_mreq = (struct ip_mreqn *) alloca(optlen);
2120 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
2121 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
2122 break;
2123
6e3cb58f
LL
2124 case IP_BLOCK_SOURCE:
2125 case IP_UNBLOCK_SOURCE:
2126 case IP_ADD_SOURCE_MEMBERSHIP:
2127 case IP_DROP_SOURCE_MEMBERSHIP:
2128 if (optlen != sizeof (struct target_ip_mreq_source))
2129 return -TARGET_EINVAL;
2130
2131 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
74e43b04
PM
2132 if (!ip_mreq_source) {
2133 return -TARGET_EFAULT;
2134 }
6e3cb58f
LL
2135 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
2136 unlock_user (ip_mreq_source, optval_addr, 0);
2137 break;
2138
920394db
JH
2139 default:
2140 goto unimplemented;
2141 }
2142 break;
0d78b3b5
LV
2143 case SOL_IPV6:
2144 switch (optname) {
2145 case IPV6_MTU_DISCOVER:
2146 case IPV6_MTU:
2147 case IPV6_V6ONLY:
2148 case IPV6_RECVPKTINFO:
ee1ac3a1 2149 case IPV6_UNICAST_HOPS:
21749c4c
LV
2150 case IPV6_MULTICAST_HOPS:
2151 case IPV6_MULTICAST_LOOP:
ee1ac3a1
HD
2152 case IPV6_RECVERR:
2153 case IPV6_RECVHOPLIMIT:
2154 case IPV6_2292HOPLIMIT:
2155 case IPV6_CHECKSUM:
b9cce6d7
HD
2156 case IPV6_ADDRFORM:
2157 case IPV6_2292PKTINFO:
2158 case IPV6_RECVTCLASS:
2159 case IPV6_RECVRTHDR:
2160 case IPV6_2292RTHDR:
2161 case IPV6_RECVHOPOPTS:
2162 case IPV6_2292HOPOPTS:
2163 case IPV6_RECVDSTOPTS:
2164 case IPV6_2292DSTOPTS:
2165 case IPV6_TCLASS:
22db1213 2166 case IPV6_ADDR_PREFERENCES:
b9cce6d7
HD
2167#ifdef IPV6_RECVPATHMTU
2168 case IPV6_RECVPATHMTU:
2169#endif
2170#ifdef IPV6_TRANSPARENT
2171 case IPV6_TRANSPARENT:
2172#endif
2173#ifdef IPV6_FREEBIND
2174 case IPV6_FREEBIND:
2175#endif
2176#ifdef IPV6_RECVORIGDSTADDR
2177 case IPV6_RECVORIGDSTADDR:
2178#endif
0d78b3b5
LV
2179 val = 0;
2180 if (optlen < sizeof(uint32_t)) {
2181 return -TARGET_EINVAL;
2182 }
2183 if (get_user_u32(val, optval_addr)) {
2184 return -TARGET_EFAULT;
2185 }
2186 ret = get_errno(setsockopt(sockfd, level, optname,
2187 &val, sizeof(val)));
2188 break;
ee1ac3a1
HD
2189 case IPV6_PKTINFO:
2190 {
2191 struct in6_pktinfo pki;
2192
2193 if (optlen < sizeof(pki)) {
2194 return -TARGET_EINVAL;
2195 }
2196
2197 if (copy_from_user(&pki, optval_addr, sizeof(pki))) {
2198 return -TARGET_EFAULT;
2199 }
2200
2201 pki.ipi6_ifindex = tswap32(pki.ipi6_ifindex);
2202
2203 ret = get_errno(setsockopt(sockfd, level, optname,
2204 &pki, sizeof(pki)));
2205 break;
2206 }
22bf4ee9
NC
2207 case IPV6_ADD_MEMBERSHIP:
2208 case IPV6_DROP_MEMBERSHIP:
2209 {
2210 struct ipv6_mreq ipv6mreq;
2211
2212 if (optlen < sizeof(ipv6mreq)) {
2213 return -TARGET_EINVAL;
2214 }
2215
2216 if (copy_from_user(&ipv6mreq, optval_addr, sizeof(ipv6mreq))) {
2217 return -TARGET_EFAULT;
2218 }
2219
2220 ipv6mreq.ipv6mr_interface = tswap32(ipv6mreq.ipv6mr_interface);
2221
2222 ret = get_errno(setsockopt(sockfd, level, optname,
2223 &ipv6mreq, sizeof(ipv6mreq)));
2224 break;
2225 }
ee1ac3a1
HD
2226 default:
2227 goto unimplemented;
2228 }
2229 break;
2230 case SOL_ICMPV6:
2231 switch (optname) {
2232 case ICMPV6_FILTER:
2233 {
2234 struct icmp6_filter icmp6f;
2235
2236 if (optlen > sizeof(icmp6f)) {
2237 optlen = sizeof(icmp6f);
2238 }
2239
2240 if (copy_from_user(&icmp6f, optval_addr, optlen)) {
2241 return -TARGET_EFAULT;
2242 }
2243
2244 for (val = 0; val < 8; val++) {
2245 icmp6f.data[val] = tswap32(icmp6f.data[val]);
2246 }
2247
2248 ret = get_errno(setsockopt(sockfd, level, optname,
2249 &icmp6f, optlen));
2250 break;
2251 }
0d78b3b5
LV
2252 default:
2253 goto unimplemented;
2254 }
2255 break;
920394db
JH
2256 case SOL_RAW:
2257 switch (optname) {
2258 case ICMP_FILTER:
ee1ac3a1
HD
2259 case IPV6_CHECKSUM:
2260 /* those take an u32 value */
920394db
JH
2261 if (optlen < sizeof(uint32_t)) {
2262 return -TARGET_EINVAL;
2263 }
2264
2265 if (get_user_u32(val, optval_addr)) {
2266 return -TARGET_EFAULT;
2267 }
2268 ret = get_errno(setsockopt(sockfd, level, optname,
2269 &val, sizeof(val)));
2270 break;
2271
8853f86e
FB
2272 default:
2273 goto unimplemented;
2274 }
2275 break;
f31dddd2
YS
2276#if defined(SOL_ALG) && defined(ALG_SET_KEY) && defined(ALG_SET_AEAD_AUTHSIZE)
2277 case SOL_ALG:
2278 switch (optname) {
2279 case ALG_SET_KEY:
2280 {
2281 char *alg_key = g_malloc(optlen);
2282
2283 if (!alg_key) {
2284 return -TARGET_ENOMEM;
2285 }
2286 if (copy_from_user(alg_key, optval_addr, optlen)) {
2287 g_free(alg_key);
2288 return -TARGET_EFAULT;
2289 }
2290 ret = get_errno(setsockopt(sockfd, level, optname,
2291 alg_key, optlen));
2292 g_free(alg_key);
2293 break;
2294 }
2295 case ALG_SET_AEAD_AUTHSIZE:
2296 {
2297 ret = get_errno(setsockopt(sockfd, level, optname,
2298 NULL, optlen));
2299 break;
2300 }
2301 default:
2302 goto unimplemented;
2303 }
2304 break;
2305#endif
3532fa74 2306 case TARGET_SOL_SOCKET:
8853f86e 2307 switch (optname) {
1b09aeb9
LV
2308 case TARGET_SO_RCVTIMEO:
2309 {
2310 struct timeval tv;
2311
2312 optname = SO_RCVTIMEO;
2313
2314set_timeout:
2315 if (optlen != sizeof(struct target_timeval)) {
2316 return -TARGET_EINVAL;
2317 }
2318
2319 if (copy_from_user_timeval(&tv, optval_addr)) {
2320 return -TARGET_EFAULT;
2321 }
2322
2323 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2324 &tv, sizeof(tv)));
2325 return ret;
2326 }
2327 case TARGET_SO_SNDTIMEO:
2328 optname = SO_SNDTIMEO;
2329 goto set_timeout;
f57d4192
LV
2330 case TARGET_SO_ATTACH_FILTER:
2331 {
2332 struct target_sock_fprog *tfprog;
2333 struct target_sock_filter *tfilter;
2334 struct sock_fprog fprog;
2335 struct sock_filter *filter;
2336 int i;
2337
2338 if (optlen != sizeof(*tfprog)) {
2339 return -TARGET_EINVAL;
2340 }
2341 if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
2342 return -TARGET_EFAULT;
2343 }
2344 if (!lock_user_struct(VERIFY_READ, tfilter,
2345 tswapal(tfprog->filter), 0)) {
2346 unlock_user_struct(tfprog, optval_addr, 1);
2347 return -TARGET_EFAULT;
2348 }
2349
2350 fprog.len = tswap16(tfprog->len);
0e173b24 2351 filter = g_try_new(struct sock_filter, fprog.len);
f57d4192
LV
2352 if (filter == NULL) {
2353 unlock_user_struct(tfilter, tfprog->filter, 1);
2354 unlock_user_struct(tfprog, optval_addr, 1);
2355 return -TARGET_ENOMEM;
2356 }
2357 for (i = 0; i < fprog.len; i++) {
2358 filter[i].code = tswap16(tfilter[i].code);
2359 filter[i].jt = tfilter[i].jt;
2360 filter[i].jf = tfilter[i].jf;
2361 filter[i].k = tswap32(tfilter[i].k);
2362 }
2363 fprog.filter = filter;
2364
2365 ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
2366 SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
0e173b24 2367 g_free(filter);
f57d4192
LV
2368
2369 unlock_user_struct(tfilter, tfprog->filter, 1);
2370 unlock_user_struct(tfprog, optval_addr, 1);
2371 return ret;
2372 }
451aaf68
JT
2373 case TARGET_SO_BINDTODEVICE:
2374 {
2375 char *dev_ifname, *addr_ifname;
2376
2377 if (optlen > IFNAMSIZ - 1) {
2378 optlen = IFNAMSIZ - 1;
2379 }
2380 dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2381 if (!dev_ifname) {
2382 return -TARGET_EFAULT;
2383 }
2384 optname = SO_BINDTODEVICE;
2385 addr_ifname = alloca(IFNAMSIZ);
2386 memcpy(addr_ifname, dev_ifname, optlen);
2387 addr_ifname[optlen] = 0;
fad6c58a
CG
2388 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2389 addr_ifname, optlen));
451aaf68
JT
2390 unlock_user (dev_ifname, optval_addr, 0);
2391 return ret;
2392 }
83eb6e50
CMAB
2393 case TARGET_SO_LINGER:
2394 {
2395 struct linger lg;
2396 struct target_linger *tlg;
2397
2398 if (optlen != sizeof(struct target_linger)) {
2399 return -TARGET_EINVAL;
2400 }
2401 if (!lock_user_struct(VERIFY_READ, tlg, optval_addr, 1)) {
2402 return -TARGET_EFAULT;
2403 }
2404 __get_user(lg.l_onoff, &tlg->l_onoff);
2405 __get_user(lg.l_linger, &tlg->l_linger);
2406 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, SO_LINGER,
2407 &lg, sizeof(lg)));
2408 unlock_user_struct(tlg, optval_addr, 0);
2409 return ret;
2410 }
8853f86e 2411 /* Options with 'int' argument. */
3532fa74
FB
2412 case TARGET_SO_DEBUG:
2413 optname = SO_DEBUG;
2414 break;
2415 case TARGET_SO_REUSEADDR:
2416 optname = SO_REUSEADDR;
2417 break;
113a9dd7
YS
2418#ifdef SO_REUSEPORT
2419 case TARGET_SO_REUSEPORT:
2420 optname = SO_REUSEPORT;
2421 break;
2422#endif
3532fa74
FB
2423 case TARGET_SO_TYPE:
2424 optname = SO_TYPE;
2425 break;
2426 case TARGET_SO_ERROR:
2427 optname = SO_ERROR;
2428 break;
2429 case TARGET_SO_DONTROUTE:
2430 optname = SO_DONTROUTE;
2431 break;
2432 case TARGET_SO_BROADCAST:
2433 optname = SO_BROADCAST;
2434 break;
2435 case TARGET_SO_SNDBUF:
2436 optname = SO_SNDBUF;
2437 break;
d79b6cc4
PB
2438 case TARGET_SO_SNDBUFFORCE:
2439 optname = SO_SNDBUFFORCE;
2440 break;
3532fa74
FB
2441 case TARGET_SO_RCVBUF:
2442 optname = SO_RCVBUF;
2443 break;
d79b6cc4
PB
2444 case TARGET_SO_RCVBUFFORCE:
2445 optname = SO_RCVBUFFORCE;
2446 break;
3532fa74
FB
2447 case TARGET_SO_KEEPALIVE:
2448 optname = SO_KEEPALIVE;
2449 break;
2450 case TARGET_SO_OOBINLINE:
2451 optname = SO_OOBINLINE;
2452 break;
2453 case TARGET_SO_NO_CHECK:
2454 optname = SO_NO_CHECK;
2455 break;
2456 case TARGET_SO_PRIORITY:
2457 optname = SO_PRIORITY;
2458 break;
5e83e8e3 2459#ifdef SO_BSDCOMPAT
3532fa74
FB
2460 case TARGET_SO_BSDCOMPAT:
2461 optname = SO_BSDCOMPAT;
2462 break;
5e83e8e3 2463#endif
3532fa74
FB
2464 case TARGET_SO_PASSCRED:
2465 optname = SO_PASSCRED;
2466 break;
82d0fe6b
PB
2467 case TARGET_SO_PASSSEC:
2468 optname = SO_PASSSEC;
2469 break;
3532fa74
FB
2470 case TARGET_SO_TIMESTAMP:
2471 optname = SO_TIMESTAMP;
2472 break;
2473 case TARGET_SO_RCVLOWAT:
2474 optname = SO_RCVLOWAT;
2475 break;
8853f86e
FB
2476 default:
2477 goto unimplemented;
2478 }
3532fa74 2479 if (optlen < sizeof(uint32_t))
2f619698 2480 return -TARGET_EINVAL;
3532fa74 2481
2f619698
FB
2482 if (get_user_u32(val, optval_addr))
2483 return -TARGET_EFAULT;
3532fa74 2484 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
8853f86e 2485 break;
a2d86682
JK
2486#ifdef SOL_NETLINK
2487 case SOL_NETLINK:
2488 switch (optname) {
2489 case NETLINK_PKTINFO:
2490 case NETLINK_ADD_MEMBERSHIP:
2491 case NETLINK_DROP_MEMBERSHIP:
2492 case NETLINK_BROADCAST_ERROR:
2493 case NETLINK_NO_ENOBUFS:
2494#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2495 case NETLINK_LISTEN_ALL_NSID:
2496 case NETLINK_CAP_ACK:
2497#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2498#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2499 case NETLINK_EXT_ACK:
2500#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2501#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
2502 case NETLINK_GET_STRICT_CHK:
2503#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2504 break;
2505 default:
2506 goto unimplemented;
2507 }
2508 val = 0;
2509 if (optlen < sizeof(uint32_t)) {
2510 return -TARGET_EINVAL;
2511 }
2512 if (get_user_u32(val, optval_addr)) {
2513 return -TARGET_EFAULT;
2514 }
2515 ret = get_errno(setsockopt(sockfd, SOL_NETLINK, optname, &val,
2516 sizeof(val)));
2517 break;
2518#endif /* SOL_NETLINK */
7854b056 2519 default:
8853f86e 2520 unimplemented:
39be5350
JK
2521 qemu_log_mask(LOG_UNIMP, "Unsupported setsockopt level=%d optname=%d\n",
2522 level, optname);
6fa13c17 2523 ret = -TARGET_ENOPROTOOPT;
7854b056 2524 }
8853f86e 2525 return ret;
7854b056
FB
2526}
2527
0da46a6e 2528/* do_getsockopt() Must return target values and target errnos. */
992f48a0 2529static abi_long do_getsockopt(int sockfd, int level, int optname,
2f619698 2530 abi_ulong optval_addr, abi_ulong optlen)
7854b056 2531{
992f48a0 2532 abi_long ret;
b55266b5
BS
2533 int len, val;
2534 socklen_t lv;
8853f86e
FB
2535
2536 switch(level) {
3532fa74 2537 case TARGET_SOL_SOCKET:
f3b974cd
JL
2538 level = SOL_SOCKET;
2539 switch (optname) {
2540 /* These don't just return a single integer */
f3b974cd
JL
2541 case TARGET_SO_PEERNAME:
2542 goto unimplemented;
405dc4cf
AS
2543 case TARGET_SO_RCVTIMEO: {
2544 struct timeval tv;
2545 socklen_t tvlen;
2546
2547 optname = SO_RCVTIMEO;
2548
2549get_timeout:
2550 if (get_user_u32(len, optlen)) {
2551 return -TARGET_EFAULT;
2552 }
2553 if (len < 0) {
2554 return -TARGET_EINVAL;
2555 }
2556
2557 tvlen = sizeof(tv);
2558 ret = get_errno(getsockopt(sockfd, level, optname,
2559 &tv, &tvlen));
2560 if (ret < 0) {
2561 return ret;
2562 }
2563 if (len > sizeof(struct target_timeval)) {
2564 len = sizeof(struct target_timeval);
2565 }
2566 if (copy_to_user_timeval(optval_addr, &tv)) {
2567 return -TARGET_EFAULT;
2568 }
2569 if (put_user_u32(len, optlen)) {
2570 return -TARGET_EFAULT;
2571 }
2572 break;
2573 }
2574 case TARGET_SO_SNDTIMEO:
2575 optname = SO_SNDTIMEO;
2576 goto get_timeout;
583359a6
AP
2577 case TARGET_SO_PEERCRED: {
2578 struct ucred cr;
2579 socklen_t crlen;
2580 struct target_ucred *tcr;
2581
2582 if (get_user_u32(len, optlen)) {
2583 return -TARGET_EFAULT;
2584 }
2585 if (len < 0) {
2586 return -TARGET_EINVAL;
2587 }
2588
2589 crlen = sizeof(cr);
2590 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
2591 &cr, &crlen));
2592 if (ret < 0) {
2593 return ret;
2594 }
2595 if (len > crlen) {
2596 len = crlen;
2597 }
2598 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
2599 return -TARGET_EFAULT;
2600 }
2601 __put_user(cr.pid, &tcr->pid);
2602 __put_user(cr.uid, &tcr->uid);
2603 __put_user(cr.gid, &tcr->gid);
2604 unlock_user_struct(tcr, optval_addr, 1);
2605 if (put_user_u32(len, optlen)) {
83eb6e50
CMAB
2606 return -TARGET_EFAULT;
2607 }
2608 break;
2609 }
6d485a55
LV
2610 case TARGET_SO_PEERSEC: {
2611 char *name;
2612
2613 if (get_user_u32(len, optlen)) {
2614 return -TARGET_EFAULT;
2615 }
2616 if (len < 0) {
2617 return -TARGET_EINVAL;
2618 }
2619 name = lock_user(VERIFY_WRITE, optval_addr, len, 0);
2620 if (!name) {
2621 return -TARGET_EFAULT;
2622 }
2623 lv = len;
2624 ret = get_errno(getsockopt(sockfd, level, SO_PEERSEC,
2625 name, &lv));
2626 if (put_user_u32(lv, optlen)) {
2627 ret = -TARGET_EFAULT;
2628 }
2629 unlock_user(name, optval_addr, lv);
2630 break;
2631 }
83eb6e50
CMAB
2632 case TARGET_SO_LINGER:
2633 {
2634 struct linger lg;
2635 socklen_t lglen;
2636 struct target_linger *tlg;
2637
2638 if (get_user_u32(len, optlen)) {
2639 return -TARGET_EFAULT;
2640 }
2641 if (len < 0) {
2642 return -TARGET_EINVAL;
2643 }
2644
2645 lglen = sizeof(lg);
2646 ret = get_errno(getsockopt(sockfd, level, SO_LINGER,
2647 &lg, &lglen));
2648 if (ret < 0) {
2649 return ret;
2650 }
2651 if (len > lglen) {
2652 len = lglen;
2653 }
2654 if (!lock_user_struct(VERIFY_WRITE, tlg, optval_addr, 0)) {
2655 return -TARGET_EFAULT;
2656 }
2657 __put_user(lg.l_onoff, &tlg->l_onoff);
2658 __put_user(lg.l_linger, &tlg->l_linger);
2659 unlock_user_struct(tlg, optval_addr, 1);
2660 if (put_user_u32(len, optlen)) {
583359a6
AP
2661 return -TARGET_EFAULT;
2662 }
2663 break;
2664 }
f3b974cd
JL
2665 /* Options with 'int' argument. */
2666 case TARGET_SO_DEBUG:
2667 optname = SO_DEBUG;
2668 goto int_case;
2669 case TARGET_SO_REUSEADDR:
2670 optname = SO_REUSEADDR;
2671 goto int_case;
113a9dd7
YS
2672#ifdef SO_REUSEPORT
2673 case TARGET_SO_REUSEPORT:
2674 optname = SO_REUSEPORT;
2675 goto int_case;
2676#endif
f3b974cd
JL
2677 case TARGET_SO_TYPE:
2678 optname = SO_TYPE;
2679 goto int_case;
2680 case TARGET_SO_ERROR:
2681 optname = SO_ERROR;
2682 goto int_case;
2683 case TARGET_SO_DONTROUTE:
2684 optname = SO_DONTROUTE;
2685 goto int_case;
2686 case TARGET_SO_BROADCAST:
2687 optname = SO_BROADCAST;
2688 goto int_case;
2689 case TARGET_SO_SNDBUF:
2690 optname = SO_SNDBUF;
2691 goto int_case;
2692 case TARGET_SO_RCVBUF:
2693 optname = SO_RCVBUF;
2694 goto int_case;
2695 case TARGET_SO_KEEPALIVE:
2696 optname = SO_KEEPALIVE;
2697 goto int_case;
2698 case TARGET_SO_OOBINLINE:
2699 optname = SO_OOBINLINE;
2700 goto int_case;
2701 case TARGET_SO_NO_CHECK:
2702 optname = SO_NO_CHECK;
2703 goto int_case;
2704 case TARGET_SO_PRIORITY:
2705 optname = SO_PRIORITY;
2706 goto int_case;
2707#ifdef SO_BSDCOMPAT
2708 case TARGET_SO_BSDCOMPAT:
2709 optname = SO_BSDCOMPAT;
2710 goto int_case;
2711#endif
2712 case TARGET_SO_PASSCRED:
2713 optname = SO_PASSCRED;
2714 goto int_case;
2715 case TARGET_SO_TIMESTAMP:
2716 optname = SO_TIMESTAMP;
2717 goto int_case;
2718 case TARGET_SO_RCVLOWAT:
2719 optname = SO_RCVLOWAT;
2720 goto int_case;
aec1ca41
PB
2721 case TARGET_SO_ACCEPTCONN:
2722 optname = SO_ACCEPTCONN;
2723 goto int_case;
ec63e06e
JD
2724 case TARGET_SO_PROTOCOL:
2725 optname = SO_PROTOCOL;
2726 goto int_case;
2727 case TARGET_SO_DOMAIN:
2728 optname = SO_DOMAIN;
2729 goto int_case;
8853f86e 2730 default:
2efbe911
FB
2731 goto int_case;
2732 }
2733 break;
2734 case SOL_TCP:
fe51b0a5
SCW
2735 case SOL_UDP:
2736 /* TCP and UDP options all take an 'int' value. */
2efbe911 2737 int_case:
2f619698
FB
2738 if (get_user_u32(len, optlen))
2739 return -TARGET_EFAULT;
2efbe911 2740 if (len < 0)
0da46a6e 2741 return -TARGET_EINVAL;
73160d95 2742 lv = sizeof(lv);
2efbe911
FB
2743 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2744 if (ret < 0)
2745 return ret;
8289d112
PB
2746 if (optname == SO_TYPE) {
2747 val = host_to_target_sock_type(val);
2748 }
2efbe911
FB
2749 if (len > lv)
2750 len = lv;
2f619698
FB
2751 if (len == 4) {
2752 if (put_user_u32(val, optval_addr))
2753 return -TARGET_EFAULT;
2754 } else {
2755 if (put_user_u8(val, optval_addr))
2756 return -TARGET_EFAULT;
f3b974cd 2757 }
2f619698
FB
2758 if (put_user_u32(len, optlen))
2759 return -TARGET_EFAULT;
2efbe911
FB
2760 break;
2761 case SOL_IP:
2762 switch(optname) {
2763 case IP_TOS:
2764 case IP_TTL:
2765 case IP_HDRINCL:
2766 case IP_ROUTER_ALERT:
2767 case IP_RECVOPTS:
2768 case IP_RETOPTS:
2769 case IP_PKTINFO:
2770 case IP_MTU_DISCOVER:
2771 case IP_RECVERR:
2772 case IP_RECVTOS:
2773#ifdef IP_FREEBIND
2774 case IP_FREEBIND:
2775#endif
2776 case IP_MULTICAST_TTL:
2777 case IP_MULTICAST_LOOP:
2f619698
FB
2778 if (get_user_u32(len, optlen))
2779 return -TARGET_EFAULT;
8853f86e 2780 if (len < 0)
0da46a6e 2781 return -TARGET_EINVAL;
73160d95 2782 lv = sizeof(lv);
8853f86e
FB
2783 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2784 if (ret < 0)
2785 return ret;
2efbe911 2786 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2efbe911 2787 len = 1;
2f619698
FB
2788 if (put_user_u32(len, optlen)
2789 || put_user_u8(val, optval_addr))
2790 return -TARGET_EFAULT;
2efbe911 2791 } else {
2efbe911
FB
2792 if (len > sizeof(int))
2793 len = sizeof(int);
2f619698
FB
2794 if (put_user_u32(len, optlen)
2795 || put_user_u32(val, optval_addr))
2796 return -TARGET_EFAULT;
2efbe911 2797 }
8853f86e 2798 break;
2efbe911 2799 default:
c02f499e
TS
2800 ret = -TARGET_ENOPROTOOPT;
2801 break;
8853f86e
FB
2802 }
2803 break;
bd8ed485
TD
2804 case SOL_IPV6:
2805 switch (optname) {
2806 case IPV6_MTU_DISCOVER:
2807 case IPV6_MTU:
2808 case IPV6_V6ONLY:
2809 case IPV6_RECVPKTINFO:
2810 case IPV6_UNICAST_HOPS:
2811 case IPV6_MULTICAST_HOPS:
2812 case IPV6_MULTICAST_LOOP:
2813 case IPV6_RECVERR:
2814 case IPV6_RECVHOPLIMIT:
2815 case IPV6_2292HOPLIMIT:
2816 case IPV6_CHECKSUM:
b9cce6d7
HD
2817 case IPV6_ADDRFORM:
2818 case IPV6_2292PKTINFO:
2819 case IPV6_RECVTCLASS:
2820 case IPV6_RECVRTHDR:
2821 case IPV6_2292RTHDR:
2822 case IPV6_RECVHOPOPTS:
2823 case IPV6_2292HOPOPTS:
2824 case IPV6_RECVDSTOPTS:
2825 case IPV6_2292DSTOPTS:
2826 case IPV6_TCLASS:
22db1213 2827 case IPV6_ADDR_PREFERENCES:
b9cce6d7
HD
2828#ifdef IPV6_RECVPATHMTU
2829 case IPV6_RECVPATHMTU:
2830#endif
2831#ifdef IPV6_TRANSPARENT
2832 case IPV6_TRANSPARENT:
2833#endif
2834#ifdef IPV6_FREEBIND
2835 case IPV6_FREEBIND:
2836#endif
2837#ifdef IPV6_RECVORIGDSTADDR
2838 case IPV6_RECVORIGDSTADDR:
2839#endif
bd8ed485
TD
2840 if (get_user_u32(len, optlen))
2841 return -TARGET_EFAULT;
2842 if (len < 0)
2843 return -TARGET_EINVAL;
2844 lv = sizeof(lv);
2845 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2846 if (ret < 0)
2847 return ret;
2848 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2849 len = 1;
2850 if (put_user_u32(len, optlen)
2851 || put_user_u8(val, optval_addr))
2852 return -TARGET_EFAULT;
2853 } else {
2854 if (len > sizeof(int))
2855 len = sizeof(int);
2856 if (put_user_u32(len, optlen)
2857 || put_user_u32(val, optval_addr))
2858 return -TARGET_EFAULT;
2859 }
2860 break;
2861 default:
2862 ret = -TARGET_ENOPROTOOPT;
2863 break;
2864 }
2865 break;
a2d86682
JK
2866#ifdef SOL_NETLINK
2867 case SOL_NETLINK:
2868 switch (optname) {
2869 case NETLINK_PKTINFO:
2870 case NETLINK_BROADCAST_ERROR:
2871 case NETLINK_NO_ENOBUFS:
2872#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2873 case NETLINK_LISTEN_ALL_NSID:
2874 case NETLINK_CAP_ACK:
2875#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2876#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2877 case NETLINK_EXT_ACK:
2878#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2879#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
2880 case NETLINK_GET_STRICT_CHK:
2881#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2882 if (get_user_u32(len, optlen)) {
2883 return -TARGET_EFAULT;
2884 }
2885 if (len != sizeof(val)) {
2886 return -TARGET_EINVAL;
2887 }
2888 lv = len;
2889 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2890 if (ret < 0) {
2891 return ret;
2892 }
2893 if (put_user_u32(lv, optlen)
2894 || put_user_u32(val, optval_addr)) {
2895 return -TARGET_EFAULT;
2896 }
2897 break;
2898#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2899 case NETLINK_LIST_MEMBERSHIPS:
2900 {
2901 uint32_t *results;
2902 int i;
2903 if (get_user_u32(len, optlen)) {
2904 return -TARGET_EFAULT;
2905 }
2906 if (len < 0) {
2907 return -TARGET_EINVAL;
2908 }
2909 results = lock_user(VERIFY_WRITE, optval_addr, len, 1);
13e340c8 2910 if (!results && len > 0) {
a2d86682
JK
2911 return -TARGET_EFAULT;
2912 }
2913 lv = len;
2914 ret = get_errno(getsockopt(sockfd, level, optname, results, &lv));
2915 if (ret < 0) {
2916 unlock_user(results, optval_addr, 0);
2917 return ret;
2918 }
2919 /* swap host endianess to target endianess. */
2920 for (i = 0; i < (len / sizeof(uint32_t)); i++) {
2921 results[i] = tswap32(results[i]);
2922 }
2923 if (put_user_u32(lv, optlen)) {
2924 return -TARGET_EFAULT;
2925 }
2926 unlock_user(results, optval_addr, 0);
2927 break;
2928 }
2929#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2930 default:
2931 goto unimplemented;
2932 }
c0cb8801 2933 break;
a2d86682 2934#endif /* SOL_NETLINK */
8853f86e
FB
2935 default:
2936 unimplemented:
39be5350
JK
2937 qemu_log_mask(LOG_UNIMP,
2938 "getsockopt level=%d optname=%d not yet supported\n",
2939 level, optname);
c02f499e 2940 ret = -TARGET_EOPNOTSUPP;
8853f86e
FB
2941 break;
2942 }
2943 return ret;
7854b056
FB
2944}
2945
9ac22517
MF
2946/* Convert target low/high pair representing file offset into the host
2947 * low/high pair. This function doesn't handle offsets bigger than 64 bits
2948 * as the kernel doesn't handle them either.
2949 */
2950static void target_to_host_low_high(abi_ulong tlow,
2951 abi_ulong thigh,
2952 unsigned long *hlow,
2953 unsigned long *hhigh)
2954{
2955 uint64_t off = tlow |
2956 ((unsigned long long)thigh << TARGET_LONG_BITS / 2) <<
2957 TARGET_LONG_BITS / 2;
2958
2959 *hlow = off;
2960 *hhigh = (off >> HOST_LONG_BITS / 2) >> HOST_LONG_BITS / 2;
2961}
2962
f287b2c2 2963static struct iovec *lock_iovec(int type, abi_ulong target_addr,
dab32b32 2964 abi_ulong count, int copy)
53a5960a
PB
2965{
2966 struct target_iovec *target_vec;
f287b2c2
RH
2967 struct iovec *vec;
2968 abi_ulong total_len, max_len;
d732dcb4 2969 int i;
501bb4b0 2970 int err = 0;
29560a6c 2971 bool bad_address = false;
53a5960a 2972
f287b2c2
RH
2973 if (count == 0) {
2974 errno = 0;
2975 return NULL;
2976 }
dab32b32 2977 if (count > IOV_MAX) {
f287b2c2
RH
2978 errno = EINVAL;
2979 return NULL;
2980 }
2981
0e173b24 2982 vec = g_try_new0(struct iovec, count);
f287b2c2
RH
2983 if (vec == NULL) {
2984 errno = ENOMEM;
2985 return NULL;
2986 }
2987
2988 target_vec = lock_user(VERIFY_READ, target_addr,
2989 count * sizeof(struct target_iovec), 1);
2990 if (target_vec == NULL) {
501bb4b0 2991 err = EFAULT;
f287b2c2
RH
2992 goto fail2;
2993 }
2994
2995 /* ??? If host page size > target page size, this will result in a
2996 value larger than what we can actually support. */
2997 max_len = 0x7fffffff & TARGET_PAGE_MASK;
2998 total_len = 0;
2999
3000 for (i = 0; i < count; i++) {
3001 abi_ulong base = tswapal(target_vec[i].iov_base);
3002 abi_long len = tswapal(target_vec[i].iov_len);
3003
3004 if (len < 0) {
501bb4b0 3005 err = EINVAL;
f287b2c2
RH
3006 goto fail;
3007 } else if (len == 0) {
3008 /* Zero length pointer is ignored. */
3009 vec[i].iov_base = 0;
41df8411 3010 } else {
f287b2c2 3011 vec[i].iov_base = lock_user(type, base, len, copy);
29560a6c
TM
3012 /* If the first buffer pointer is bad, this is a fault. But
3013 * subsequent bad buffers will result in a partial write; this
3014 * is realized by filling the vector with null pointers and
3015 * zero lengths. */
f287b2c2 3016 if (!vec[i].iov_base) {
29560a6c
TM
3017 if (i == 0) {
3018 err = EFAULT;
3019 goto fail;
3020 } else {
3021 bad_address = true;
3022 }
3023 }
3024 if (bad_address) {
3025 len = 0;
f287b2c2
RH
3026 }
3027 if (len > max_len - total_len) {
3028 len = max_len - total_len;
3029 }
41df8411 3030 }
f287b2c2
RH
3031 vec[i].iov_len = len;
3032 total_len += len;
579a97f7 3033 }
f287b2c2
RH
3034
3035 unlock_user(target_vec, target_addr, 0);
3036 return vec;
3037
3038 fail:
7eff518b
CG
3039 while (--i >= 0) {
3040 if (tswapal(target_vec[i].iov_len) > 0) {
3041 unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
3042 }
3043 }
f287b2c2 3044 unlock_user(target_vec, target_addr, 0);
501bb4b0 3045 fail2:
0e173b24 3046 g_free(vec);
501bb4b0 3047 errno = err;
f287b2c2 3048 return NULL;
53a5960a
PB
3049}
3050
f287b2c2 3051static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
dab32b32 3052 abi_ulong count, int copy)
53a5960a
PB
3053{
3054 struct target_iovec *target_vec;
53a5960a
PB
3055 int i;
3056
f287b2c2
RH
3057 target_vec = lock_user(VERIFY_READ, target_addr,
3058 count * sizeof(struct target_iovec), 1);
3059 if (target_vec) {
3060 for (i = 0; i < count; i++) {
3061 abi_ulong base = tswapal(target_vec[i].iov_base);
71ec7cef 3062 abi_long len = tswapal(target_vec[i].iov_len);
f287b2c2
RH
3063 if (len < 0) {
3064 break;
3065 }
d732dcb4
AZ
3066 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
3067 }
f287b2c2 3068 unlock_user(target_vec, target_addr, 0);
53a5960a 3069 }
579a97f7 3070
0e173b24 3071 g_free(vec);
53a5960a
PB
3072}
3073
53d09b76 3074static inline int target_to_host_sock_type(int *type)
3532fa74 3075{
f651e6ae
PJ
3076 int host_type = 0;
3077 int target_type = *type;
3078
3079 switch (target_type & TARGET_SOCK_TYPE_MASK) {
3532fa74 3080 case TARGET_SOCK_DGRAM:
f651e6ae 3081 host_type = SOCK_DGRAM;
3532fa74
FB
3082 break;
3083 case TARGET_SOCK_STREAM:
f651e6ae 3084 host_type = SOCK_STREAM;
3532fa74 3085 break;
f651e6ae
PJ
3086 default:
3087 host_type = target_type & TARGET_SOCK_TYPE_MASK;
3532fa74
FB
3088 break;
3089 }
f651e6ae 3090 if (target_type & TARGET_SOCK_CLOEXEC) {
53d09b76 3091#if defined(SOCK_CLOEXEC)
f651e6ae 3092 host_type |= SOCK_CLOEXEC;
53d09b76
EI
3093#else
3094 return -TARGET_EINVAL;
3095#endif
f651e6ae
PJ
3096 }
3097 if (target_type & TARGET_SOCK_NONBLOCK) {
53d09b76 3098#if defined(SOCK_NONBLOCK)
f651e6ae 3099 host_type |= SOCK_NONBLOCK;
53d09b76
EI
3100#elif !defined(O_NONBLOCK)
3101 return -TARGET_EINVAL;
3102#endif
f651e6ae
PJ
3103 }
3104 *type = host_type;
53d09b76
EI
3105 return 0;
3106}
3107
3108/* Try to emulate socket type flags after socket creation. */
3109static int sock_flags_fixup(int fd, int target_type)
3110{
3111#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
3112 if (target_type & TARGET_SOCK_NONBLOCK) {
3113 int flags = fcntl(fd, F_GETFL);
3114 if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
3115 close(fd);
3116 return -TARGET_EINVAL;
3117 }
3118 }
3119#endif
3120 return fd;
f651e6ae
PJ
3121}
3122
3123/* do_socket() Must return target values and target errnos. */
3124static abi_long do_socket(int domain, int type, int protocol)
3125{
53d09b76
EI
3126 int target_type = type;
3127 int ret;
3128
3129 ret = target_to_host_sock_type(&type);
3130 if (ret) {
3131 return ret;
3132 }
f651e6ae 3133
575b22b1
LV
3134 if (domain == PF_NETLINK && !(
3135#ifdef CONFIG_RTNETLINK
3136 protocol == NETLINK_ROUTE ||
3137#endif
3138 protocol == NETLINK_KOBJECT_UEVENT ||
3139 protocol == NETLINK_AUDIT)) {
71e2443e 3140 return -TARGET_EPROTONOSUPPORT;
6c5b5645 3141 }
ff626f2d
LV
3142
3143 if (domain == AF_PACKET ||
3144 (domain == AF_INET && type == SOCK_PACKET)) {
3145 protocol = tswap16(protocol);
3146 }
3147
53d09b76
EI
3148 ret = get_errno(socket(domain, type, protocol));
3149 if (ret >= 0) {
3150 ret = sock_flags_fixup(ret, target_type);
0cf22722
LV
3151 if (type == SOCK_PACKET) {
3152 /* Manage an obsolete case :
3153 * if socket type is SOCK_PACKET, bind by name
3154 */
3155 fd_trans_register(ret, &target_packet_trans);
6c5b5645
LV
3156 } else if (domain == PF_NETLINK) {
3157 switch (protocol) {
575b22b1 3158#ifdef CONFIG_RTNETLINK
6c5b5645
LV
3159 case NETLINK_ROUTE:
3160 fd_trans_register(ret, &target_netlink_route_trans);
3161 break;
575b22b1 3162#endif
b265620b
LV
3163 case NETLINK_KOBJECT_UEVENT:
3164 /* nothing to do: messages are strings */
3165 break;
5ce9bb59
LV
3166 case NETLINK_AUDIT:
3167 fd_trans_register(ret, &target_netlink_audit_trans);
3168 break;
6c5b5645
LV
3169 default:
3170 g_assert_not_reached();
3171 }
0cf22722 3172 }
53d09b76
EI
3173 }
3174 return ret;
3532fa74
FB
3175}
3176
0da46a6e 3177/* do_bind() Must return target values and target errnos. */
992f48a0
BS
3178static abi_long do_bind(int sockfd, abi_ulong target_addr,
3179 socklen_t addrlen)
3532fa74 3180{
8f7aeaf6 3181 void *addr;
917507b0 3182 abi_long ret;
8f7aeaf6 3183
38724253 3184 if ((int)addrlen < 0) {
8f7aeaf6 3185 return -TARGET_EINVAL;
38724253 3186 }
8f7aeaf6 3187
607175e0 3188 addr = alloca(addrlen+1);
3b46e624 3189
7b36f782 3190 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
917507b0
AP
3191 if (ret)
3192 return ret;
3193
3532fa74
FB
3194 return get_errno(bind(sockfd, addr, addrlen));
3195}
3196
0da46a6e 3197/* do_connect() Must return target values and target errnos. */
992f48a0
BS
3198static abi_long do_connect(int sockfd, abi_ulong target_addr,
3199 socklen_t addrlen)
3532fa74 3200{
8f7aeaf6 3201 void *addr;
917507b0 3202 abi_long ret;
8f7aeaf6 3203
38724253 3204 if ((int)addrlen < 0) {
8f7aeaf6 3205 return -TARGET_EINVAL;
38724253 3206 }
8f7aeaf6 3207
2dd08dfd 3208 addr = alloca(addrlen+1);
3b46e624 3209
7b36f782 3210 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
917507b0
AP
3211 if (ret)
3212 return ret;
3213
2a3c7619 3214 return get_errno(safe_connect(sockfd, addr, addrlen));
3532fa74
FB
3215}
3216
f19e00d7
AG
3217/* do_sendrecvmsg_locked() Must return target values and target errnos. */
3218static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
3219 int flags, int send)
3532fa74 3220{
6de645c7 3221 abi_long ret, len;
3532fa74 3222 struct msghdr msg;
dab32b32 3223 abi_ulong count;
3532fa74 3224 struct iovec *vec;
992f48a0 3225 abi_ulong target_vec;
3532fa74 3226
3532fa74
FB
3227 if (msgp->msg_name) {
3228 msg.msg_namelen = tswap32(msgp->msg_namelen);
2dd08dfd 3229 msg.msg_name = alloca(msg.msg_namelen+1);
7b36f782
LV
3230 ret = target_to_host_sockaddr(fd, msg.msg_name,
3231 tswapal(msgp->msg_name),
3232 msg.msg_namelen);
26a6fc96
PM
3233 if (ret == -TARGET_EFAULT) {
3234 /* For connected sockets msg_name and msg_namelen must
3235 * be ignored, so returning EFAULT immediately is wrong.
3236 * Instead, pass a bad msg_name to the host kernel, and
3237 * let it decide whether to return EFAULT or not.
3238 */
3239 msg.msg_name = (void *)-1;
3240 } else if (ret) {
f287b2c2 3241 goto out2;
917507b0 3242 }
3532fa74
FB
3243 } else {
3244 msg.msg_name = NULL;
3245 msg.msg_namelen = 0;
3246 }
cbb21eed 3247 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
3532fa74 3248 msg.msg_control = alloca(msg.msg_controllen);
1d3d1b23
JS
3249 memset(msg.msg_control, 0, msg.msg_controllen);
3250
3532fa74 3251 msg.msg_flags = tswap32(msgp->msg_flags);
3b46e624 3252
cbb21eed 3253 count = tswapal(msgp->msg_iovlen);
cbb21eed 3254 target_vec = tswapal(msgp->msg_iov);
97b07970
PM
3255
3256 if (count > IOV_MAX) {
3257 /* sendrcvmsg returns a different errno for this condition than
3258 * readv/writev, so we must catch it here before lock_iovec() does.
3259 */
3260 ret = -TARGET_EMSGSIZE;
3261 goto out2;
3262 }
3263
f287b2c2
RH
3264 vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
3265 target_vec, count, send);
3266 if (vec == NULL) {
3267 ret = -host_to_target_errno(errno);
3268 goto out2;
3269 }
3532fa74
FB
3270 msg.msg_iovlen = count;
3271 msg.msg_iov = vec;
3b46e624 3272
3532fa74 3273 if (send) {
6c5b5645 3274 if (fd_trans_target_to_host_data(fd)) {
7d61d892
LV
3275 void *host_msg;
3276
3277 host_msg = g_malloc(msg.msg_iov->iov_len);
3278 memcpy(host_msg, msg.msg_iov->iov_base, msg.msg_iov->iov_len);
3279 ret = fd_trans_target_to_host_data(fd)(host_msg,
6c5b5645 3280 msg.msg_iov->iov_len);
7d61d892
LV
3281 if (ret >= 0) {
3282 msg.msg_iov->iov_base = host_msg;
3283 ret = get_errno(safe_sendmsg(fd, &msg, flags));
3284 }
3285 g_free(host_msg);
6c5b5645
LV
3286 } else {
3287 ret = target_to_host_cmsg(&msg, msgp);
7d61d892
LV
3288 if (ret == 0) {
3289 ret = get_errno(safe_sendmsg(fd, &msg, flags));
3290 }
6c5b5645 3291 }
3532fa74 3292 } else {
66687530 3293 ret = get_errno(safe_recvmsg(fd, &msg, flags));
6de645c7
AZ
3294 if (!is_error(ret)) {
3295 len = ret;
6c5b5645
LV
3296 if (fd_trans_host_to_target_data(fd)) {
3297 ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
2a03d3e6 3298 MIN(msg.msg_iov->iov_len, len));
6c5b5645
LV
3299 } else {
3300 ret = host_to_target_cmsg(msgp, &msg);
3301 }
ca619067
JH
3302 if (!is_error(ret)) {
3303 msgp->msg_namelen = tswap32(msg.msg_namelen);
24894f39 3304 msgp->msg_flags = tswap32(msg.msg_flags);
26a6fc96 3305 if (msg.msg_name != NULL && msg.msg_name != (void *)-1) {
ca619067
JH
3306 ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
3307 msg.msg_name, msg.msg_namelen);
3308 if (ret) {
3309 goto out;
3310 }
3311 }
3312
6de645c7 3313 ret = len;
ca619067 3314 }
6de645c7 3315 }
3532fa74 3316 }
ca619067
JH
3317
3318out:
3532fa74 3319 unlock_iovec(vec, target_vec, count, !send);
f287b2c2 3320out2:
f19e00d7
AG
3321 return ret;
3322}
3323
3324static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
3325 int flags, int send)
3326{
3327 abi_long ret;
3328 struct target_msghdr *msgp;
3329
3330 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
3331 msgp,
3332 target_msg,
3333 send ? 1 : 0)) {
3334 return -TARGET_EFAULT;
3335 }
3336 ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
579a97f7 3337 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
3532fa74
FB
3338 return ret;
3339}
3340
f19e00d7
AG
3341/* We don't rely on the C library to have sendmmsg/recvmmsg support,
3342 * so it might not have this *mmsg-specific flag either.
3343 */
3344#ifndef MSG_WAITFORONE
3345#define MSG_WAITFORONE 0x10000
3346#endif
3347
3348static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
3349 unsigned int vlen, unsigned int flags,
3350 int send)
3351{
3352 struct target_mmsghdr *mmsgp;
3353 abi_long ret = 0;
3354 int i;
3355
3356 if (vlen > UIO_MAXIOV) {
3357 vlen = UIO_MAXIOV;
3358 }
3359
3360 mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
3361 if (!mmsgp) {
3362 return -TARGET_EFAULT;
3363 }
3364
3365 for (i = 0; i < vlen; i++) {
3366 ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
3367 if (is_error(ret)) {
3368 break;
3369 }
3370 mmsgp[i].msg_len = tswap32(ret);
3371 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
3372 if (flags & MSG_WAITFORONE) {
3373 flags |= MSG_DONTWAIT;
3374 }
3375 }
3376
3377 unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
3378
3379 /* Return number of datagrams sent if we sent any at all;
3380 * otherwise return the error.
3381 */
3382 if (i) {
3383 return i;
3384 }
3385 return ret;
3386}
f19e00d7 3387
a94b4987
PM
3388/* do_accept4() Must return target values and target errnos. */
3389static abi_long do_accept4(int fd, abi_ulong target_addr,
3390 abi_ulong target_addrlen_addr, int flags)
1be9e1dc 3391{
cd813367 3392 socklen_t addrlen, ret_addrlen;
2f619698 3393 void *addr;
992f48a0 3394 abi_long ret;
d25295d4
PJ
3395 int host_flags;
3396
3397 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
1be9e1dc 3398
a94b4987 3399 if (target_addr == 0) {
ff6dc130 3400 return get_errno(safe_accept4(fd, NULL, NULL, host_flags));
a94b4987 3401 }
917507b0 3402
e554eb4b 3403 /* linux returns EFAULT if addrlen pointer is invalid */
2f619698 3404 if (get_user_u32(addrlen, target_addrlen_addr))
e554eb4b 3405 return -TARGET_EFAULT;
2f619698 3406
38724253 3407 if ((int)addrlen < 0) {
8f7aeaf6 3408 return -TARGET_EINVAL;
38724253 3409 }
8f7aeaf6 3410
c7169b02 3411 if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
e554eb4b 3412 return -TARGET_EFAULT;
c7169b02 3413 }
917507b0 3414
2f619698
FB
3415 addr = alloca(addrlen);
3416
cd813367
AS
3417 ret_addrlen = addrlen;
3418 ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags));
1be9e1dc 3419 if (!is_error(ret)) {
cd813367
AS
3420 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3421 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3422 ret = -TARGET_EFAULT;
cd813367 3423 }
1be9e1dc
PB
3424 }
3425 return ret;
3426}
3427
0da46a6e 3428/* do_getpeername() Must return target values and target errnos. */
992f48a0 3429static abi_long do_getpeername(int fd, abi_ulong target_addr,
2f619698 3430 abi_ulong target_addrlen_addr)
1be9e1dc 3431{
cd813367 3432 socklen_t addrlen, ret_addrlen;
2f619698 3433 void *addr;
992f48a0 3434 abi_long ret;
1be9e1dc 3435
2f619698
FB
3436 if (get_user_u32(addrlen, target_addrlen_addr))
3437 return -TARGET_EFAULT;
3438
38724253 3439 if ((int)addrlen < 0) {
8f7aeaf6 3440 return -TARGET_EINVAL;
38724253 3441 }
8f7aeaf6 3442
c7169b02 3443 if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
917507b0 3444 return -TARGET_EFAULT;
c7169b02 3445 }
917507b0 3446
2f619698
FB
3447 addr = alloca(addrlen);
3448
cd813367
AS
3449 ret_addrlen = addrlen;
3450 ret = get_errno(getpeername(fd, addr, &ret_addrlen));
1be9e1dc 3451 if (!is_error(ret)) {
cd813367
AS
3452 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3453 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3454 ret = -TARGET_EFAULT;
cd813367 3455 }
1be9e1dc
PB
3456 }
3457 return ret;
3458}
3459
0da46a6e 3460/* do_getsockname() Must return target values and target errnos. */
992f48a0 3461static abi_long do_getsockname(int fd, abi_ulong target_addr,
2f619698 3462 abi_ulong target_addrlen_addr)
1be9e1dc 3463{
cd813367 3464 socklen_t addrlen, ret_addrlen;
2f619698 3465 void *addr;
992f48a0 3466 abi_long ret;
1be9e1dc 3467
2f619698
FB
3468 if (get_user_u32(addrlen, target_addrlen_addr))
3469 return -TARGET_EFAULT;
3470
38724253 3471 if ((int)addrlen < 0) {
8f7aeaf6 3472 return -TARGET_EINVAL;
38724253 3473 }
8f7aeaf6 3474
c7169b02 3475 if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
917507b0 3476 return -TARGET_EFAULT;
c7169b02 3477 }
917507b0 3478
2f619698
FB
3479 addr = alloca(addrlen);
3480
cd813367
AS
3481 ret_addrlen = addrlen;
3482 ret = get_errno(getsockname(fd, addr, &ret_addrlen));
1be9e1dc 3483 if (!is_error(ret)) {
cd813367
AS
3484 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3485 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3486 ret = -TARGET_EFAULT;
cd813367 3487 }
1be9e1dc
PB
3488 }
3489 return ret;
3490}
3491
0da46a6e 3492/* do_socketpair() Must return target values and target errnos. */
992f48a0 3493static abi_long do_socketpair(int domain, int type, int protocol,
2f619698 3494 abi_ulong target_tab_addr)
1be9e1dc
PB
3495{
3496 int tab[2];
992f48a0 3497 abi_long ret;
1be9e1dc 3498
f651e6ae
PJ
3499 target_to_host_sock_type(&type);
3500
1be9e1dc
PB
3501 ret = get_errno(socketpair(domain, type, protocol, tab));
3502 if (!is_error(ret)) {
2f619698
FB
3503 if (put_user_s32(tab[0], target_tab_addr)
3504 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
3505 ret = -TARGET_EFAULT;
1be9e1dc
PB
3506 }
3507 return ret;
3508}
3509
0da46a6e 3510/* do_sendto() Must return target values and target errnos. */
992f48a0
BS
3511static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
3512 abi_ulong target_addr, socklen_t addrlen)
1be9e1dc
PB
3513{
3514 void *addr;
3515 void *host_msg;
7d61d892 3516 void *copy_msg = NULL;
992f48a0 3517 abi_long ret;
1be9e1dc 3518
38724253 3519 if ((int)addrlen < 0) {
8f7aeaf6 3520 return -TARGET_EINVAL;
38724253 3521 }
8f7aeaf6 3522
579a97f7
FB
3523 host_msg = lock_user(VERIFY_READ, msg, len, 1);
3524 if (!host_msg)
3525 return -TARGET_EFAULT;
6c5b5645 3526 if (fd_trans_target_to_host_data(fd)) {
7d61d892
LV
3527 copy_msg = host_msg;
3528 host_msg = g_malloc(len);
3529 memcpy(host_msg, copy_msg, len);
6c5b5645
LV
3530 ret = fd_trans_target_to_host_data(fd)(host_msg, len);
3531 if (ret < 0) {
7d61d892 3532 goto fail;
6c5b5645
LV
3533 }
3534 }
1be9e1dc 3535 if (target_addr) {
2dd08dfd 3536 addr = alloca(addrlen+1);
7b36f782 3537 ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
917507b0 3538 if (ret) {
7d61d892 3539 goto fail;
917507b0 3540 }
66687530 3541 ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
1be9e1dc 3542 } else {
66687530 3543 ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
1be9e1dc 3544 }
7d61d892
LV
3545fail:
3546 if (copy_msg) {
3547 g_free(host_msg);
3548 host_msg = copy_msg;
3549 }
1be9e1dc
PB
3550 unlock_user(host_msg, msg, 0);
3551 return ret;
3552}
3553
0da46a6e 3554/* do_recvfrom() Must return target values and target errnos. */
992f48a0
BS
3555static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
3556 abi_ulong target_addr,
3557 abi_ulong target_addrlen)
1be9e1dc 3558{
cd813367 3559 socklen_t addrlen, ret_addrlen;
1be9e1dc
PB
3560 void *addr;
3561 void *host_msg;
992f48a0 3562 abi_long ret;
1be9e1dc 3563
4a1e6bce
ZR
3564 if (!msg) {
3565 host_msg = NULL;
3566 } else {
3567 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
3568 if (!host_msg) {
3569 return -TARGET_EFAULT;
3570 }
3571 }
1be9e1dc 3572 if (target_addr) {
2f619698
FB
3573 if (get_user_u32(addrlen, target_addrlen)) {
3574 ret = -TARGET_EFAULT;
3575 goto fail;
3576 }
38724253 3577 if ((int)addrlen < 0) {
8f7aeaf6
AJ
3578 ret = -TARGET_EINVAL;
3579 goto fail;
3580 }
1be9e1dc 3581 addr = alloca(addrlen);
cd813367 3582 ret_addrlen = addrlen;
66687530 3583 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags,
cd813367 3584 addr, &ret_addrlen));
1be9e1dc
PB
3585 } else {
3586 addr = NULL; /* To keep compiler quiet. */
cd813367 3587 addrlen = 0; /* To keep compiler quiet. */
66687530 3588 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
1be9e1dc
PB
3589 }
3590 if (!is_error(ret)) {
c35e1f9c 3591 if (fd_trans_host_to_target_data(fd)) {
2a03d3e6
LV
3592 abi_long trans;
3593 trans = fd_trans_host_to_target_data(fd)(host_msg, MIN(ret, len));
3594 if (is_error(trans)) {
3595 ret = trans;
3596 goto fail;
3597 }
c35e1f9c 3598 }
1be9e1dc 3599 if (target_addr) {
cd813367
AS
3600 host_to_target_sockaddr(target_addr, addr,
3601 MIN(addrlen, ret_addrlen));
3602 if (put_user_u32(ret_addrlen, target_addrlen)) {
2f619698
FB
3603 ret = -TARGET_EFAULT;
3604 goto fail;
3605 }
1be9e1dc
PB
3606 }
3607 unlock_user(host_msg, msg, len);
3608 } else {
2f619698 3609fail:
1be9e1dc
PB
3610 unlock_user(host_msg, msg, 0);
3611 }
3612 return ret;
3613}
3614
32407103 3615#ifdef TARGET_NR_socketcall
ff71a454 3616/* do_socketcall() must return target values and target errnos. */
992f48a0 3617static abi_long do_socketcall(int num, abi_ulong vptr)
31e31b8a 3618{
ff71a454
AM
3619 static const unsigned nargs[] = { /* number of arguments per operation */
3620 [TARGET_SYS_SOCKET] = 3, /* domain, type, protocol */
3621 [TARGET_SYS_BIND] = 3, /* fd, addr, addrlen */
3622 [TARGET_SYS_CONNECT] = 3, /* fd, addr, addrlen */
3623 [TARGET_SYS_LISTEN] = 2, /* fd, backlog */
3624 [TARGET_SYS_ACCEPT] = 3, /* fd, addr, addrlen */
3625 [TARGET_SYS_GETSOCKNAME] = 3, /* fd, addr, addrlen */
3626 [TARGET_SYS_GETPEERNAME] = 3, /* fd, addr, addrlen */
3627 [TARGET_SYS_SOCKETPAIR] = 4, /* domain, type, protocol, tab */
3628 [TARGET_SYS_SEND] = 4, /* fd, msg, len, flags */
3629 [TARGET_SYS_RECV] = 4, /* fd, msg, len, flags */
3630 [TARGET_SYS_SENDTO] = 6, /* fd, msg, len, flags, addr, addrlen */
3631 [TARGET_SYS_RECVFROM] = 6, /* fd, msg, len, flags, addr, addrlen */
3632 [TARGET_SYS_SHUTDOWN] = 2, /* fd, how */
3633 [TARGET_SYS_SETSOCKOPT] = 5, /* fd, level, optname, optval, optlen */
3634 [TARGET_SYS_GETSOCKOPT] = 5, /* fd, level, optname, optval, optlen */
3635 [TARGET_SYS_SENDMSG] = 3, /* fd, msg, flags */
3636 [TARGET_SYS_RECVMSG] = 3, /* fd, msg, flags */
3637 [TARGET_SYS_ACCEPT4] = 4, /* fd, addr, addrlen, flags */
3638 [TARGET_SYS_RECVMMSG] = 4, /* fd, msgvec, vlen, flags */
3639 [TARGET_SYS_SENDMMSG] = 4, /* fd, msgvec, vlen, flags */
62dc90c6
MT
3640 };
3641 abi_long a[6]; /* max 6 args */
ff71a454 3642 unsigned i;
62dc90c6 3643
ff71a454
AM
3644 /* check the range of the first argument num */
3645 /* (TARGET_SYS_SENDMMSG is the highest among TARGET_SYS_xxx) */
3646 if (num < 1 || num > TARGET_SYS_SENDMMSG) {
3647 return -TARGET_EINVAL;
3648 }
3649 /* ensure we have space for args */
3650 if (nargs[num] > ARRAY_SIZE(a)) {
3651 return -TARGET_EINVAL;
3652 }
3653 /* collect the arguments in a[] according to nargs[] */
3654 for (i = 0; i < nargs[num]; ++i) {
3655 if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
3656 return -TARGET_EFAULT;
31e31b8a 3657 }
62dc90c6 3658 }
ff71a454 3659 /* now when we have the args, invoke the appropriate underlying function */
62dc90c6 3660 switch (num) {
ff71a454 3661 case TARGET_SYS_SOCKET: /* domain, type, protocol */
62dc90c6 3662 return do_socket(a[0], a[1], a[2]);
ff71a454 3663 case TARGET_SYS_BIND: /* sockfd, addr, addrlen */
62dc90c6 3664 return do_bind(a[0], a[1], a[2]);
ff71a454 3665 case TARGET_SYS_CONNECT: /* sockfd, addr, addrlen */
62dc90c6 3666 return do_connect(a[0], a[1], a[2]);
ff71a454 3667 case TARGET_SYS_LISTEN: /* sockfd, backlog */
62dc90c6 3668 return get_errno(listen(a[0], a[1]));
ff71a454 3669 case TARGET_SYS_ACCEPT: /* sockfd, addr, addrlen */
62dc90c6 3670 return do_accept4(a[0], a[1], a[2], 0);
ff71a454 3671 case TARGET_SYS_GETSOCKNAME: /* sockfd, addr, addrlen */
62dc90c6 3672 return do_getsockname(a[0], a[1], a[2]);
ff71a454 3673 case TARGET_SYS_GETPEERNAME: /* sockfd, addr, addrlen */
62dc90c6 3674 return do_getpeername(a[0], a[1], a[2]);
ff71a454 3675 case TARGET_SYS_SOCKETPAIR: /* domain, type, protocol, tab */
62dc90c6 3676 return do_socketpair(a[0], a[1], a[2], a[3]);
ff71a454 3677 case TARGET_SYS_SEND: /* sockfd, msg, len, flags */
62dc90c6 3678 return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
ff71a454 3679 case TARGET_SYS_RECV: /* sockfd, msg, len, flags */
62dc90c6 3680 return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
ff71a454 3681 case TARGET_SYS_SENDTO: /* sockfd, msg, len, flags, addr, addrlen */
62dc90c6 3682 return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
ff71a454 3683 case TARGET_SYS_RECVFROM: /* sockfd, msg, len, flags, addr, addrlen */
62dc90c6 3684 return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
ff71a454 3685 case TARGET_SYS_SHUTDOWN: /* sockfd, how */
62dc90c6 3686 return get_errno(shutdown(a[0], a[1]));
ff71a454
AM
3687 case TARGET_SYS_SETSOCKOPT: /* sockfd, level, optname, optval, optlen */
3688 return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
3689 case TARGET_SYS_GETSOCKOPT: /* sockfd, level, optname, optval, optlen */
3690 return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
3691 case TARGET_SYS_SENDMSG: /* sockfd, msg, flags */
62dc90c6 3692 return do_sendrecvmsg(a[0], a[1], a[2], 1);
ff71a454 3693 case TARGET_SYS_RECVMSG: /* sockfd, msg, flags */
62dc90c6 3694 return do_sendrecvmsg(a[0], a[1], a[2], 0);
ff71a454
AM
3695 case TARGET_SYS_ACCEPT4: /* sockfd, addr, addrlen, flags */
3696 return do_accept4(a[0], a[1], a[2], a[3]);
3697 case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, flags */
5a53dc50 3698 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
ff71a454
AM
3699 case TARGET_SYS_SENDMMSG: /* sockfd, msgvec, vlen, flags */
3700 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
31e31b8a 3701 default:
39be5350 3702 qemu_log_mask(LOG_UNIMP, "Unsupported socketcall: %d\n", num);
ff71a454 3703 return -TARGET_EINVAL;
31e31b8a 3704 }
31e31b8a 3705}
32407103 3706#endif
31e31b8a 3707
8853f86e
FB
3708#define N_SHM_REGIONS 32
3709
3710static struct shm_region {
b6e17875
PM
3711 abi_ulong start;
3712 abi_ulong size;
3713 bool in_use;
8853f86e
FB
3714} shm_regions[N_SHM_REGIONS];
3715
005eb2ae
PM
3716#ifndef TARGET_SEMID64_DS
3717/* asm-generic version of this struct */
3718struct target_semid64_ds
3eb6b044
TS
3719{
3720 struct target_ipc_perm sem_perm;
992f48a0 3721 abi_ulong sem_otime;
005eb2ae 3722#if TARGET_ABI_BITS == 32
992f48a0 3723 abi_ulong __unused1;
03527344 3724#endif
992f48a0 3725 abi_ulong sem_ctime;
005eb2ae 3726#if TARGET_ABI_BITS == 32
992f48a0 3727 abi_ulong __unused2;
03527344 3728#endif
992f48a0
BS
3729 abi_ulong sem_nsems;
3730 abi_ulong __unused3;
3731 abi_ulong __unused4;
3eb6b044 3732};
005eb2ae 3733#endif
3eb6b044 3734
579a97f7
FB
3735static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
3736 abi_ulong target_addr)
3eb6b044
TS
3737{
3738 struct target_ipc_perm *target_ip;
005eb2ae 3739 struct target_semid64_ds *target_sd;
3eb6b044 3740
579a97f7
FB
3741 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3742 return -TARGET_EFAULT;
e8bbe36c 3743 target_ip = &(target_sd->sem_perm);
55a2b163
PJ
3744 host_ip->__key = tswap32(target_ip->__key);
3745 host_ip->uid = tswap32(target_ip->uid);
3746 host_ip->gid = tswap32(target_ip->gid);
3747 host_ip->cuid = tswap32(target_ip->cuid);
3748 host_ip->cgid = tswap32(target_ip->cgid);
3749#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3750 host_ip->mode = tswap32(target_ip->mode);
3751#else
cbb21eed 3752 host_ip->mode = tswap16(target_ip->mode);
55a2b163
PJ
3753#endif
3754#if defined(TARGET_PPC)
3755 host_ip->__seq = tswap32(target_ip->__seq);
3756#else
3757 host_ip->__seq = tswap16(target_ip->__seq);
3758#endif
3eb6b044 3759 unlock_user_struct(target_sd, target_addr, 0);
579a97f7 3760 return 0;
3eb6b044
TS
3761}
3762
579a97f7
FB
3763static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
3764 struct ipc_perm *host_ip)
3eb6b044
TS
3765{
3766 struct target_ipc_perm *target_ip;
005eb2ae 3767 struct target_semid64_ds *target_sd;
3eb6b044 3768
579a97f7
FB
3769 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3770 return -TARGET_EFAULT;
3eb6b044 3771 target_ip = &(target_sd->sem_perm);
55a2b163
PJ
3772 target_ip->__key = tswap32(host_ip->__key);
3773 target_ip->uid = tswap32(host_ip->uid);
3774 target_ip->gid = tswap32(host_ip->gid);
3775 target_ip->cuid = tswap32(host_ip->cuid);
3776 target_ip->cgid = tswap32(host_ip->cgid);
3777#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3778 target_ip->mode = tswap32(host_ip->mode);
3779#else
cbb21eed 3780 target_ip->mode = tswap16(host_ip->mode);
55a2b163
PJ
3781#endif
3782#if defined(TARGET_PPC)
3783 target_ip->__seq = tswap32(host_ip->__seq);
3784#else
3785 target_ip->__seq = tswap16(host_ip->__seq);
3786#endif
3eb6b044 3787 unlock_user_struct(target_sd, target_addr, 1);
579a97f7 3788 return 0;
3eb6b044
TS
3789}
3790
579a97f7
FB
3791static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
3792 abi_ulong target_addr)
3eb6b044 3793{
005eb2ae 3794 struct target_semid64_ds *target_sd;
3eb6b044 3795
579a97f7
FB
3796 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3797 return -TARGET_EFAULT;
e5289087
AJ
3798 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
3799 return -TARGET_EFAULT;
cbb21eed
MB
3800 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
3801 host_sd->sem_otime = tswapal(target_sd->sem_otime);
3802 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
3eb6b044 3803 unlock_user_struct(target_sd, target_addr, 0);
579a97f7 3804 return 0;
3eb6b044
TS
3805}
3806
579a97f7
FB
3807static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
3808 struct semid_ds *host_sd)
3eb6b044 3809{
005eb2ae 3810 struct target_semid64_ds *target_sd;
3eb6b044 3811
579a97f7
FB
3812 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3813 return -TARGET_EFAULT;
e5289087 3814 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
3a93113a 3815 return -TARGET_EFAULT;
cbb21eed
MB
3816 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
3817 target_sd->sem_otime = tswapal(host_sd->sem_otime);
3818 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
3eb6b044 3819 unlock_user_struct(target_sd, target_addr, 1);
579a97f7 3820 return 0;
3eb6b044
TS
3821}
3822
e5289087
AJ
3823struct target_seminfo {
3824 int semmap;
3825 int semmni;
3826 int semmns;
3827 int semmnu;
3828 int semmsl;
3829 int semopm;
3830 int semume;
3831 int semusz;
3832 int semvmx;
3833 int semaem;
3834};
3835
3836static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
3837 struct seminfo *host_seminfo)
3838{
3839 struct target_seminfo *target_seminfo;
3840 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
3841 return -TARGET_EFAULT;
3842 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
3843 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
3844 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
3845 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
3846 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
3847 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
3848 __put_user(host_seminfo->semume, &target_seminfo->semume);
3849 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
3850 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
3851 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
3852 unlock_user_struct(target_seminfo, target_addr, 1);
3853 return 0;
3854}
3855
fa294816
TS
3856union semun {
3857 int val;
3eb6b044 3858 struct semid_ds *buf;
fa294816 3859 unsigned short *array;
e5289087 3860 struct seminfo *__buf;
fa294816
TS
3861};
3862
3eb6b044
TS
3863union target_semun {
3864 int val;
e5289087
AJ
3865 abi_ulong buf;
3866 abi_ulong array;
3867 abi_ulong __buf;
3eb6b044
TS
3868};
3869
e5289087
AJ
3870static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
3871 abi_ulong target_addr)
3eb6b044 3872{
e5289087
AJ
3873 int nsems;
3874 unsigned short *array;
3875 union semun semun;
3876 struct semid_ds semid_ds;
3877 int i, ret;
3eb6b044 3878
e5289087
AJ
3879 semun.buf = &semid_ds;
3880
3881 ret = semctl(semid, 0, IPC_STAT, semun);
3882 if (ret == -1)
3883 return get_errno(ret);
3884
3885 nsems = semid_ds.sem_nsems;
3886
0e173b24 3887 *host_array = g_try_new(unsigned short, nsems);
69d4c703
PM
3888 if (!*host_array) {
3889 return -TARGET_ENOMEM;
3890 }
e5289087
AJ
3891 array = lock_user(VERIFY_READ, target_addr,
3892 nsems*sizeof(unsigned short), 1);
69d4c703 3893 if (!array) {
0e173b24 3894 g_free(*host_array);
e5289087 3895 return -TARGET_EFAULT;
69d4c703 3896 }
e5289087
AJ
3897
3898 for(i=0; i<nsems; i++) {
3899 __get_user((*host_array)[i], &array[i]);
3eb6b044 3900 }
e5289087
AJ
3901 unlock_user(array, target_addr, 0);
3902
579a97f7 3903 return 0;
3eb6b044
TS
3904}
3905
e5289087
AJ
3906static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
3907 unsigned short **host_array)
3eb6b044 3908{
e5289087
AJ
3909 int nsems;
3910 unsigned short *array;
3911 union semun semun;
3912 struct semid_ds semid_ds;
3913 int i, ret;
3eb6b044 3914
e5289087
AJ
3915 semun.buf = &semid_ds;
3916
3917 ret = semctl(semid, 0, IPC_STAT, semun);
3918 if (ret == -1)
3919 return get_errno(ret);
3920
3921 nsems = semid_ds.sem_nsems;
3922
3923 array = lock_user(VERIFY_WRITE, target_addr,
3924 nsems*sizeof(unsigned short), 0);
3925 if (!array)
3926 return -TARGET_EFAULT;
3927
3928 for(i=0; i<nsems; i++) {
3929 __put_user((*host_array)[i], &array[i]);
3eb6b044 3930 }
0e173b24 3931 g_free(*host_array);
e5289087
AJ
3932 unlock_user(array, target_addr, 1);
3933
579a97f7 3934 return 0;
3eb6b044
TS
3935}
3936
e5289087 3937static inline abi_long do_semctl(int semid, int semnum, int cmd,
d1c002b6 3938 abi_ulong target_arg)
3eb6b044 3939{
d1c002b6 3940 union target_semun target_su = { .buf = target_arg };
3eb6b044
TS
3941 union semun arg;
3942 struct semid_ds dsarg;
7b8118e8 3943 unsigned short *array = NULL;
e5289087
AJ
3944 struct seminfo seminfo;
3945 abi_long ret = -TARGET_EINVAL;
3946 abi_long err;
3947 cmd &= 0xff;
3eb6b044
TS
3948
3949 switch( cmd ) {
3950 case GETVAL:
3eb6b044 3951 case SETVAL:
5464baec
TM
3952 /* In 64 bit cross-endian situations, we will erroneously pick up
3953 * the wrong half of the union for the "val" element. To rectify
3954 * this, the entire 8-byte structure is byteswapped, followed by
3955 * a swap of the 4 byte val field. In other cases, the data is
3956 * already in proper host byte order. */
3957 if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
3958 target_su.buf = tswapal(target_su.buf);
3959 arg.val = tswap32(target_su.val);
3960 } else {
3961 arg.val = target_su.val;
3962 }
e5289087 3963 ret = get_errno(semctl(semid, semnum, cmd, arg));
3eb6b044
TS
3964 break;
3965 case GETALL:
3eb6b044 3966 case SETALL:
e5289087
AJ
3967 err = target_to_host_semarray(semid, &array, target_su.array);
3968 if (err)
3969 return err;
3970 arg.array = array;
3971 ret = get_errno(semctl(semid, semnum, cmd, arg));
3972 err = host_to_target_semarray(semid, target_su.array, &array);
3973 if (err)
3974 return err;
3eb6b044
TS
3975 break;
3976 case IPC_STAT:
3eb6b044 3977 case IPC_SET:
e5289087
AJ
3978 case SEM_STAT:
3979 err = target_to_host_semid_ds(&dsarg, target_su.buf);
3980 if (err)
3981 return err;
3982 arg.buf = &dsarg;
3983 ret = get_errno(semctl(semid, semnum, cmd, arg));
3984 err = host_to_target_semid_ds(target_su.buf, &dsarg);
3985 if (err)
3986 return err;
3987 break;
3988 case IPC_INFO:
3989 case SEM_INFO:
3990 arg.__buf = &seminfo;
3991 ret = get_errno(semctl(semid, semnum, cmd, arg));
3992 err = host_to_target_seminfo(target_su.__buf, &seminfo);
3993 if (err)
3994 return err;
3995 break;
3996 case IPC_RMID:
3997 case GETPID:
3998 case GETNCNT:
3999 case GETZCNT:
4000 ret = get_errno(semctl(semid, semnum, cmd, NULL));
3eb6b044 4001 break;
3eb6b044
TS
4002 }
4003
4004 return ret;
4005}
4006
e5289087
AJ
4007struct target_sembuf {
4008 unsigned short sem_num;
4009 short sem_op;
4010 short sem_flg;
4011};
4012
4013static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
4014 abi_ulong target_addr,
4015 unsigned nsops)
4016{
4017 struct target_sembuf *target_sembuf;
4018 int i;
4019
4020 target_sembuf = lock_user(VERIFY_READ, target_addr,
4021 nsops*sizeof(struct target_sembuf), 1);
4022 if (!target_sembuf)
4023 return -TARGET_EFAULT;
4024
4025 for(i=0; i<nsops; i++) {
4026 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
4027 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
4028 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
4029 }
4030
4031 unlock_user(target_sembuf, target_addr, 0);
4032
4033 return 0;
4034}
4035
d8c08b1e 4036#if defined(TARGET_NR_ipc) || defined(TARGET_NR_semop) || \
cac46eb0 4037 defined(TARGET_NR_semtimedop) || defined(TARGET_NR_semtimedop_time64)
d8c08b1e
MK
4038
4039/*
4040 * This macro is required to handle the s390 variants, which passes the
4041 * arguments in a different order than default.
4042 */
4043#ifdef __s390x__
4044#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
4045 (__nsops), (__timeout), (__sops)
4046#else
4047#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
4048 (__nsops), 0, (__sops), (__timeout)
4049#endif
4050
4051static inline abi_long do_semtimedop(int semid,
4052 abi_long ptr,
4053 unsigned nsops,
cac46eb0 4054 abi_long timeout, bool time64)
e5289087 4055{
0a7ec849 4056 struct sembuf *sops;
d8c08b1e 4057 struct timespec ts, *pts = NULL;
524fa340 4058 abi_long ret;
e5289087 4059
d8c08b1e
MK
4060 if (timeout) {
4061 pts = &ts;
cac46eb0
FB
4062 if (time64) {
4063 if (target_to_host_timespec64(pts, timeout)) {
4064 return -TARGET_EFAULT;
4065 }
4066 } else {
4067 if (target_to_host_timespec(pts, timeout)) {
4068 return -TARGET_EFAULT;
4069 }
d8c08b1e
MK
4070 }
4071 }
4072
0a7ec849
FB
4073 if (nsops > TARGET_SEMOPM) {
4074 return -TARGET_E2BIG;
4075 }
4076
4077 sops = g_new(struct sembuf, nsops);
4078
4079 if (target_to_host_sembuf(sops, ptr, nsops)) {
4080 g_free(sops);
e5289087 4081 return -TARGET_EFAULT;
0a7ec849 4082 }
e5289087 4083
524fa340
LV
4084 ret = -TARGET_ENOSYS;
4085#ifdef __NR_semtimedop
d8c08b1e 4086 ret = get_errno(safe_semtimedop(semid, sops, nsops, pts));
524fa340
LV
4087#endif
4088#ifdef __NR_ipc
4089 if (ret == -TARGET_ENOSYS) {
d8c08b1e
MK
4090 ret = get_errno(safe_ipc(IPCOP_semtimedop, semid,
4091 SEMTIMEDOP_IPC_ARGS(nsops, sops, (long)pts)));
524fa340
LV
4092 }
4093#endif
0a7ec849 4094 g_free(sops);
524fa340 4095 return ret;
e5289087 4096}
d8c08b1e 4097#endif
e5289087 4098
1bc012f6
TS
4099struct target_msqid_ds
4100{
1c54ff97
AJ
4101 struct target_ipc_perm msg_perm;
4102 abi_ulong msg_stime;
4103#if TARGET_ABI_BITS == 32
4104 abi_ulong __unused1;
4105#endif
4106 abi_ulong msg_rtime;
4107#if TARGET_ABI_BITS == 32
4108 abi_ulong __unused2;
4109#endif
4110 abi_ulong msg_ctime;
4111#if TARGET_ABI_BITS == 32
4112 abi_ulong __unused3;
4113#endif
4114 abi_ulong __msg_cbytes;
4115 abi_ulong msg_qnum;
4116 abi_ulong msg_qbytes;
4117 abi_ulong msg_lspid;
4118 abi_ulong msg_lrpid;
4119 abi_ulong __unused4;
4120 abi_ulong __unused5;
1bc012f6
TS
4121};
4122
579a97f7
FB
4123static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
4124 abi_ulong target_addr)
1bc012f6
TS
4125{
4126 struct target_msqid_ds *target_md;
4127
579a97f7
FB
4128 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
4129 return -TARGET_EFAULT;
1c54ff97
AJ
4130 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
4131 return -TARGET_EFAULT;
cbb21eed
MB
4132 host_md->msg_stime = tswapal(target_md->msg_stime);
4133 host_md->msg_rtime = tswapal(target_md->msg_rtime);
4134 host_md->msg_ctime = tswapal(target_md->msg_ctime);
4135 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
4136 host_md->msg_qnum = tswapal(target_md->msg_qnum);
4137 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
4138 host_md->msg_lspid = tswapal(target_md->msg_lspid);
4139 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
1bc012f6 4140 unlock_user_struct(target_md, target_addr, 0);
579a97f7 4141 return 0;
1bc012f6
TS
4142}
4143
579a97f7
FB
4144static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
4145 struct msqid_ds *host_md)
1bc012f6
TS
4146{
4147 struct target_msqid_ds *target_md;
4148
579a97f7
FB
4149 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
4150 return -TARGET_EFAULT;
1c54ff97
AJ
4151 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
4152 return -TARGET_EFAULT;
cbb21eed
MB
4153 target_md->msg_stime = tswapal(host_md->msg_stime);
4154 target_md->msg_rtime = tswapal(host_md->msg_rtime);
4155 target_md->msg_ctime = tswapal(host_md->msg_ctime);
4156 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
4157 target_md->msg_qnum = tswapal(host_md->msg_qnum);
4158 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
4159 target_md->msg_lspid = tswapal(host_md->msg_lspid);
4160 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
1bc012f6 4161 unlock_user_struct(target_md, target_addr, 1);
579a97f7 4162 return 0;
1bc012f6
TS
4163}
4164
1c54ff97
AJ
4165struct target_msginfo {
4166 int msgpool;
4167 int msgmap;
4168 int msgmax;
4169 int msgmnb;
4170 int msgmni;
4171 int msgssz;
4172 int msgtql;
4173 unsigned short int msgseg;
4174};
4175
4176static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
4177 struct msginfo *host_msginfo)
4178{
4179 struct target_msginfo *target_msginfo;
4180 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
4181 return -TARGET_EFAULT;
4182 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
4183 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
4184 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
4185 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
4186 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
4187 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
4188 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
4189 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
4190 unlock_user_struct(target_msginfo, target_addr, 1);
00b229ac 4191 return 0;
1c54ff97
AJ
4192}
4193
4194static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1bc012f6
TS
4195{
4196 struct msqid_ds dsarg;
1c54ff97
AJ
4197 struct msginfo msginfo;
4198 abi_long ret = -TARGET_EINVAL;
4199
4200 cmd &= 0xff;
4201
4202 switch (cmd) {
1bc012f6
TS
4203 case IPC_STAT:
4204 case IPC_SET:
1c54ff97
AJ
4205 case MSG_STAT:
4206 if (target_to_host_msqid_ds(&dsarg,ptr))
4207 return -TARGET_EFAULT;
4208 ret = get_errno(msgctl(msgid, cmd, &dsarg));
4209 if (host_to_target_msqid_ds(ptr,&dsarg))
4210 return -TARGET_EFAULT;
4211 break;
4212 case IPC_RMID:
4213 ret = get_errno(msgctl(msgid, cmd, NULL));
4214 break;
4215 case IPC_INFO:
4216 case MSG_INFO:
4217 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
4218 if (host_to_target_msginfo(ptr, &msginfo))
4219 return -TARGET_EFAULT;
4220 break;
1bc012f6 4221 }
1c54ff97 4222
1bc012f6
TS
4223 return ret;
4224}
4225
4226struct target_msgbuf {
1c54ff97
AJ
4227 abi_long mtype;
4228 char mtext[1];
1bc012f6
TS
4229};
4230
992f48a0 4231static inline abi_long do_msgsnd(int msqid, abi_long msgp,
edcc5f9d 4232 ssize_t msgsz, int msgflg)
1bc012f6
TS
4233{
4234 struct target_msgbuf *target_mb;
4235 struct msgbuf *host_mb;
992f48a0 4236 abi_long ret = 0;
1bc012f6 4237
edcc5f9d
TM
4238 if (msgsz < 0) {
4239 return -TARGET_EINVAL;
4240 }
4241
579a97f7
FB
4242 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
4243 return -TARGET_EFAULT;
0e173b24 4244 host_mb = g_try_malloc(msgsz + sizeof(long));
29e03fcb
HZ
4245 if (!host_mb) {
4246 unlock_user_struct(target_mb, msgp, 0);
4247 return -TARGET_ENOMEM;
4248 }
cbb21eed 4249 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
1c54ff97 4250 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
524fa340
LV
4251 ret = -TARGET_ENOSYS;
4252#ifdef __NR_msgsnd
89f9fe44 4253 ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
524fa340
LV
4254#endif
4255#ifdef __NR_ipc
4256 if (ret == -TARGET_ENOSYS) {
d8c08b1e
MK
4257#ifdef __s390x__
4258 ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
4259 host_mb));
4260#else
524fa340
LV
4261 ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
4262 host_mb, 0));
d8c08b1e 4263#endif
524fa340
LV
4264 }
4265#endif
0e173b24 4266 g_free(host_mb);
1bc012f6
TS
4267 unlock_user_struct(target_mb, msgp, 0);
4268
4269 return ret;
4270}
4271
d8c08b1e
MK
4272#ifdef __NR_ipc
4273#if defined(__sparc__)
4274/* SPARC for msgrcv it does not use the kludge on final 2 arguments. */
4275#define MSGRCV_ARGS(__msgp, __msgtyp) __msgp, __msgtyp
4276#elif defined(__s390x__)
4277/* The s390 sys_ipc variant has only five parameters. */
4278#define MSGRCV_ARGS(__msgp, __msgtyp) \
4279 ((long int[]){(long int)__msgp, __msgtyp})
4280#else
4281#define MSGRCV_ARGS(__msgp, __msgtyp) \
4282 ((long int[]){(long int)__msgp, __msgtyp}), 0
4283#endif
4284#endif
4285
992f48a0 4286static inline abi_long do_msgrcv(int msqid, abi_long msgp,
99874f65 4287 ssize_t msgsz, abi_long msgtyp,
992f48a0 4288 int msgflg)
1bc012f6
TS
4289{
4290 struct target_msgbuf *target_mb;
579a97f7 4291 char *target_mtext;
1bc012f6 4292 struct msgbuf *host_mb;
992f48a0 4293 abi_long ret = 0;
1bc012f6 4294
99874f65
PM
4295 if (msgsz < 0) {
4296 return -TARGET_EINVAL;
4297 }
4298
579a97f7
FB
4299 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
4300 return -TARGET_EFAULT;
1c54ff97 4301
415d8471
PM
4302 host_mb = g_try_malloc(msgsz + sizeof(long));
4303 if (!host_mb) {
4304 ret = -TARGET_ENOMEM;
4305 goto end;
4306 }
524fa340
LV
4307 ret = -TARGET_ENOSYS;
4308#ifdef __NR_msgrcv
89f9fe44 4309 ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
524fa340
LV
4310#endif
4311#ifdef __NR_ipc
4312 if (ret == -TARGET_ENOSYS) {
4313 ret = get_errno(safe_ipc(IPCOP_CALL(1, IPCOP_msgrcv), msqid, msgsz,
d8c08b1e 4314 msgflg, MSGRCV_ARGS(host_mb, msgtyp)));
524fa340
LV
4315 }
4316#endif
1c54ff97 4317
579a97f7
FB
4318 if (ret > 0) {
4319 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
4320 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
4321 if (!target_mtext) {
4322 ret = -TARGET_EFAULT;
4323 goto end;
4324 }
1c54ff97 4325 memcpy(target_mb->mtext, host_mb->mtext, ret);
579a97f7
FB
4326 unlock_user(target_mtext, target_mtext_addr, ret);
4327 }
1c54ff97 4328
cbb21eed 4329 target_mb->mtype = tswapal(host_mb->mtype);
1bc012f6 4330
579a97f7
FB
4331end:
4332 if (target_mb)
4333 unlock_user_struct(target_mb, msgp, 1);
0d07fe47 4334 g_free(host_mb);
1bc012f6
TS
4335 return ret;
4336}
4337
88a8c984
RV
4338static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
4339 abi_ulong target_addr)
4340{
4341 struct target_shmid_ds *target_sd;
4342
4343 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
4344 return -TARGET_EFAULT;
4345 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
4346 return -TARGET_EFAULT;
4347 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
4348 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
4349 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
4350 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
4351 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
4352 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
4353 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
4354 unlock_user_struct(target_sd, target_addr, 0);
4355 return 0;
4356}
4357
4358static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
4359 struct shmid_ds *host_sd)
4360{
4361 struct target_shmid_ds *target_sd;
4362
4363 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
4364 return -TARGET_EFAULT;
4365 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
4366 return -TARGET_EFAULT;
4367 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
4368 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
4369 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
4370 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
4371 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
4372 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
4373 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
4374 unlock_user_struct(target_sd, target_addr, 1);
4375 return 0;
4376}
4377
4378struct target_shminfo {
4379 abi_ulong shmmax;
4380 abi_ulong shmmin;
4381 abi_ulong shmmni;
4382 abi_ulong shmseg;
4383 abi_ulong shmall;
4384};
4385
4386static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
4387 struct shminfo *host_shminfo)
4388{
4389 struct target_shminfo *target_shminfo;
4390 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
4391 return -TARGET_EFAULT;
4392 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
4393 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
4394 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
4395 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
4396 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
4397 unlock_user_struct(target_shminfo, target_addr, 1);
4398 return 0;
4399}
4400
4401struct target_shm_info {
4402 int used_ids;
4403 abi_ulong shm_tot;
4404 abi_ulong shm_rss;
4405 abi_ulong shm_swp;
4406 abi_ulong swap_attempts;
4407 abi_ulong swap_successes;
4408};
4409
4410static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
4411 struct shm_info *host_shm_info)
4412{
4413 struct target_shm_info *target_shm_info;
4414 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
4415 return -TARGET_EFAULT;
4416 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
4417 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
4418 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
4419 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
4420 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
4421 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
4422 unlock_user_struct(target_shm_info, target_addr, 1);
4423 return 0;
4424}
4425
4426static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
4427{
4428 struct shmid_ds dsarg;
4429 struct shminfo shminfo;
4430 struct shm_info shm_info;
4431 abi_long ret = -TARGET_EINVAL;
4432
4433 cmd &= 0xff;
4434
4435 switch(cmd) {
4436 case IPC_STAT:
4437 case IPC_SET:
4438 case SHM_STAT:
4439 if (target_to_host_shmid_ds(&dsarg, buf))
4440 return -TARGET_EFAULT;
4441 ret = get_errno(shmctl(shmid, cmd, &dsarg));
4442 if (host_to_target_shmid_ds(buf, &dsarg))
4443 return -TARGET_EFAULT;
4444 break;
4445 case IPC_INFO:
4446 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
4447 if (host_to_target_shminfo(buf, &shminfo))
4448 return -TARGET_EFAULT;
4449 break;
4450 case SHM_INFO:
4451 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
4452 if (host_to_target_shm_info(buf, &shm_info))
4453 return -TARGET_EFAULT;
4454 break;
4455 case IPC_RMID:
4456 case SHM_LOCK:
4457 case SHM_UNLOCK:
4458 ret = get_errno(shmctl(shmid, cmd, NULL));
4459 break;
4460 }
4461
4462 return ret;
4463}
4464
ee8e7614
PM
4465#ifndef TARGET_FORCE_SHMLBA
4466/* For most architectures, SHMLBA is the same as the page size;
4467 * some architectures have larger values, in which case they should
4468 * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
4469 * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
4470 * and defining its own value for SHMLBA.
4471 *
4472 * The kernel also permits SHMLBA to be set by the architecture to a
4473 * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
4474 * this means that addresses are rounded to the large size if
4475 * SHM_RND is set but addresses not aligned to that size are not rejected
4476 * as long as they are at least page-aligned. Since the only architecture
4477 * which uses this is ia64 this code doesn't provide for that oddity.
4478 */
4479static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
4480{
4481 return TARGET_PAGE_SIZE;
4482}
4483#endif
4484
4485static inline abi_ulong do_shmat(CPUArchState *cpu_env,
4486 int shmid, abi_ulong shmaddr, int shmflg)
88a8c984 4487{
228168cb 4488 CPUState *cpu = env_cpu(cpu_env);
88a8c984
RV
4489 abi_long raddr;
4490 void *host_raddr;
4491 struct shmid_ds shm_info;
4492 int i,ret;
ee8e7614 4493 abi_ulong shmlba;
88a8c984 4494
ee1bf83d
RH
4495 /* shmat pointers are always untagged */
4496
88a8c984
RV
4497 /* find out the length of the shared memory segment */
4498 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
4499 if (is_error(ret)) {
4500 /* can't get length, bail out */
4501 return ret;
4502 }
4503
ee8e7614
PM
4504 shmlba = target_shmlba(cpu_env);
4505
4506 if (shmaddr & (shmlba - 1)) {
4507 if (shmflg & SHM_RND) {
4508 shmaddr &= ~(shmlba - 1);
4509 } else {
4510 return -TARGET_EINVAL;
4511 }
4512 }
46b12f46 4513 if (!guest_range_valid_untagged(shmaddr, shm_info.shm_segsz)) {
ebf9a363
MF
4514 return -TARGET_EINVAL;
4515 }
ee8e7614 4516
88a8c984
RV
4517 mmap_lock();
4518
228168cb
RH
4519 /*
4520 * We're mapping shared memory, so ensure we generate code for parallel
4521 * execution and flush old translations. This will work up to the level
4522 * supported by the host -- anything that requires EXCP_ATOMIC will not
4523 * be atomic with respect to an external process.
4524 */
4525 if (!(cpu->tcg_cflags & CF_PARALLEL)) {
4526 cpu->tcg_cflags |= CF_PARALLEL;
4527 tb_flush(cpu);
4528 }
4529
88a8c984 4530 if (shmaddr)
3e8f1628 4531 host_raddr = shmat(shmid, (void *)g2h_untagged(shmaddr), shmflg);
88a8c984
RV
4532 else {
4533 abi_ulong mmap_start;
4534
30ab9ef2
RH
4535 /* In order to use the host shmat, we need to honor host SHMLBA. */
4536 mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
88a8c984
RV
4537
4538 if (mmap_start == -1) {
4539 errno = ENOMEM;
4540 host_raddr = (void *)-1;
4541 } else
3e8f1628
RH
4542 host_raddr = shmat(shmid, g2h_untagged(mmap_start),
4543 shmflg | SHM_REMAP);
88a8c984
RV
4544 }
4545
4546 if (host_raddr == (void *)-1) {
4547 mmap_unlock();
4548 return get_errno((long)host_raddr);
4549 }
4550 raddr=h2g((unsigned long)host_raddr);
4551
4552 page_set_flags(raddr, raddr + shm_info.shm_segsz,
d9c58585
RH
4553 PAGE_VALID | PAGE_RESET | PAGE_READ |
4554 (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE));
88a8c984
RV
4555
4556 for (i = 0; i < N_SHM_REGIONS; i++) {
b6e17875
PM
4557 if (!shm_regions[i].in_use) {
4558 shm_regions[i].in_use = true;
88a8c984
RV
4559 shm_regions[i].start = raddr;
4560 shm_regions[i].size = shm_info.shm_segsz;
4561 break;
4562 }
4563 }
4564
4565 mmap_unlock();
4566 return raddr;
4567
4568}
4569
4570static inline abi_long do_shmdt(abi_ulong shmaddr)
4571{
4572 int i;
3c5f6a5f
MF
4573 abi_long rv;
4574
ee1bf83d
RH
4575 /* shmdt pointers are always untagged */
4576
3c5f6a5f 4577 mmap_lock();
88a8c984
RV
4578
4579 for (i = 0; i < N_SHM_REGIONS; ++i) {
b6e17875
PM
4580 if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
4581 shm_regions[i].in_use = false;
e00ac249 4582 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
88a8c984
RV
4583 break;
4584 }
4585 }
3e8f1628 4586 rv = get_errno(shmdt(g2h_untagged(shmaddr)));
88a8c984 4587
3c5f6a5f 4588 mmap_unlock();
88a8c984 4589
3c5f6a5f 4590 return rv;
88a8c984
RV
4591}
4592
1c54ff97 4593#ifdef TARGET_NR_ipc
53a5960a 4594/* ??? This only works with linear mappings. */
0da46a6e 4595/* do_ipc() must return target values and target errnos. */
ee8e7614
PM
4596static abi_long do_ipc(CPUArchState *cpu_env,
4597 unsigned int call, abi_long first,
37ed0956 4598 abi_long second, abi_long third,
992f48a0 4599 abi_long ptr, abi_long fifth)
8853f86e
FB
4600{
4601 int version;
992f48a0 4602 abi_long ret = 0;
8853f86e
FB
4603
4604 version = call >> 16;
4605 call &= 0xffff;
4606
4607 switch (call) {
fa294816 4608 case IPCOP_semop:
cac46eb0 4609 ret = do_semtimedop(first, ptr, second, 0, false);
d8c08b1e
MK
4610 break;
4611 case IPCOP_semtimedop:
4612 /*
4613 * The s390 sys_ipc variant has only five parameters instead of six
4614 * (as for default variant) and the only difference is the handling of
4615 * SEMTIMEDOP where on s390 the third parameter is used as a pointer
4616 * to a struct timespec where the generic variant uses fifth parameter.
4617 */
4618#if defined(TARGET_S390X)
cac46eb0 4619 ret = do_semtimedop(first, ptr, second, third, TARGET_ABI_BITS == 64);
d8c08b1e 4620#else
cac46eb0 4621 ret = do_semtimedop(first, ptr, second, fifth, TARGET_ABI_BITS == 64);
d8c08b1e 4622#endif
fa294816
TS
4623 break;
4624
4625 case IPCOP_semget:
4626 ret = get_errno(semget(first, second, third));
4627 break;
4628
5d2fa8eb
TM
4629 case IPCOP_semctl: {
4630 /* The semun argument to semctl is passed by value, so dereference the
4631 * ptr argument. */
4632 abi_ulong atptr;
37ed0956 4633 get_user_ual(atptr, ptr);
d1c002b6 4634 ret = do_semctl(first, second, third, atptr);
fa294816 4635 break;
5d2fa8eb 4636 }
d96372ef 4637
1c54ff97
AJ
4638 case IPCOP_msgget:
4639 ret = get_errno(msgget(first, second));
4640 break;
d96372ef 4641
1c54ff97
AJ
4642 case IPCOP_msgsnd:
4643 ret = do_msgsnd(first, ptr, second, third);
4644 break;
d96372ef 4645
1c54ff97
AJ
4646 case IPCOP_msgctl:
4647 ret = do_msgctl(first, second, ptr);
4648 break;
d96372ef 4649
1c54ff97
AJ
4650 case IPCOP_msgrcv:
4651 switch (version) {
4652 case 0:
4653 {
4654 struct target_ipc_kludge {
4655 abi_long msgp;
4656 abi_long msgtyp;
4657 } *tmp;
4658
4659 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
4660 ret = -TARGET_EFAULT;
4661 break;
4662 }
d96372ef 4663
79dd77de 4664 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
d96372ef 4665
1c54ff97
AJ
4666 unlock_user_struct(tmp, ptr, 0);
4667 break;
4668 }
4669 default:
4670 ret = do_msgrcv(first, ptr, second, fifth, third);
4671 }
4672 break;
d96372ef 4673
8853f86e 4674 case IPCOP_shmat:
88a8c984
RV
4675 switch (version) {
4676 default:
5a4a898d
FB
4677 {
4678 abi_ulong raddr;
ee8e7614 4679 raddr = do_shmat(cpu_env, first, ptr, second);
88a8c984
RV
4680 if (is_error(raddr))
4681 return get_errno(raddr);
2f619698 4682 if (put_user_ual(raddr, third))
5a4a898d 4683 return -TARGET_EFAULT;
88a8c984
RV
4684 break;
4685 }
4686 case 1:
4687 ret = -TARGET_EINVAL;
4688 break;
5a4a898d 4689 }
8853f86e
FB
4690 break;
4691 case IPCOP_shmdt:
88a8c984 4692 ret = do_shmdt(ptr);
8853f86e
FB
4693 break;
4694
4695 case IPCOP_shmget:
4696 /* IPC_* flag values are the same on all linux platforms */
4697 ret = get_errno(shmget(first, second, third));
4698 break;
4699
4700 /* IPC_* and SHM_* command values are the same on all linux platforms */
4701 case IPCOP_shmctl:
a2926784 4702 ret = do_shmctl(first, second, ptr);
8853f86e
FB
4703 break;
4704 default:
39be5350
JK
4705 qemu_log_mask(LOG_UNIMP, "Unsupported ipc call: %d (version %d)\n",
4706 call, version);
0da46a6e 4707 ret = -TARGET_ENOSYS;
8853f86e
FB
4708 break;
4709 }
4710 return ret;
4711}
32407103 4712#endif
8853f86e 4713
31e31b8a 4714/* kernel structure types definitions */
31e31b8a 4715
001faf32 4716#define STRUCT(name, ...) STRUCT_ ## name,
31e31b8a
FB
4717#define STRUCT_SPECIAL(name) STRUCT_ ## name,
4718enum {
4719#include "syscall_types.h"
8be656b8 4720STRUCT_MAX
31e31b8a
FB
4721};
4722#undef STRUCT
4723#undef STRUCT_SPECIAL
4724
001faf32 4725#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
31e31b8a
FB
4726#define STRUCT_SPECIAL(name)
4727#include "syscall_types.h"
4728#undef STRUCT
4729#undef STRUCT_SPECIAL
4730
31e31b8a
FB
4731#define MAX_STRUCT_SIZE 4096
4732
dace20dc 4733#ifdef CONFIG_FIEMAP
285da2b9
PM
4734/* So fiemap access checks don't overflow on 32 bit systems.
4735 * This is very slightly smaller than the limit imposed by
4736 * the underlying kernel.
4737 */
4738#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
4739 / sizeof(struct fiemap_extent))
4740
4741static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 4742 int fd, int cmd, abi_long arg)
285da2b9
PM
4743{
4744 /* The parameter for this ioctl is a struct fiemap followed
4745 * by an array of struct fiemap_extent whose size is set
4746 * in fiemap->fm_extent_count. The array is filled in by the
4747 * ioctl.
4748 */
4749 int target_size_in, target_size_out;
4750 struct fiemap *fm;
4751 const argtype *arg_type = ie->arg_type;
4752 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
4753 void *argptr, *p;
4754 abi_long ret;
4755 int i, extent_size = thunk_type_size(extent_arg_type, 0);
4756 uint32_t outbufsz;
4757 int free_fm = 0;
4758
4759 assert(arg_type[0] == TYPE_PTR);
4760 assert(ie->access == IOC_RW);
4761 arg_type++;
4762 target_size_in = thunk_type_size(arg_type, 0);
4763 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
4764 if (!argptr) {
4765 return -TARGET_EFAULT;
4766 }
4767 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4768 unlock_user(argptr, arg, 0);
4769 fm = (struct fiemap *)buf_temp;
4770 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
4771 return -TARGET_EINVAL;
4772 }
4773
4774 outbufsz = sizeof (*fm) +
4775 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
4776
4777 if (outbufsz > MAX_STRUCT_SIZE) {
4778 /* We can't fit all the extents into the fixed size buffer.
4779 * Allocate one that is large enough and use it instead.
4780 */
0e173b24 4781 fm = g_try_malloc(outbufsz);
285da2b9
PM
4782 if (!fm) {
4783 return -TARGET_ENOMEM;
4784 }
4785 memcpy(fm, buf_temp, sizeof(struct fiemap));
4786 free_fm = 1;
4787 }
49ca6f3e 4788 ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm));
285da2b9
PM
4789 if (!is_error(ret)) {
4790 target_size_out = target_size_in;
4791 /* An extent_count of 0 means we were only counting the extents
4792 * so there are no structs to copy
4793 */
4794 if (fm->fm_extent_count != 0) {
4795 target_size_out += fm->fm_mapped_extents * extent_size;
4796 }
4797 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
4798 if (!argptr) {
4799 ret = -TARGET_EFAULT;
4800 } else {
4801 /* Convert the struct fiemap */
4802 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
4803 if (fm->fm_extent_count != 0) {
4804 p = argptr + target_size_in;
4805 /* ...and then all the struct fiemap_extents */
4806 for (i = 0; i < fm->fm_mapped_extents; i++) {
4807 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
4808 THUNK_TARGET);
4809 p += extent_size;
4810 }
4811 }
4812 unlock_user(argptr, arg, target_size_out);
4813 }
4814 }
4815 if (free_fm) {
0e173b24 4816 g_free(fm);
285da2b9
PM
4817 }
4818 return ret;
4819}
dace20dc 4820#endif
285da2b9 4821
059c2f2c 4822static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 4823 int fd, int cmd, abi_long arg)
059c2f2c
LV
4824{
4825 const argtype *arg_type = ie->arg_type;
4826 int target_size;
4827 void *argptr;
4828 int ret;
4829 struct ifconf *host_ifconf;
4830 uint32_t outbufsz;
4831 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
4df7b7fa 4832 const argtype ifreq_max_type[] = { MK_STRUCT(STRUCT_ifmap_ifreq) };
059c2f2c
LV
4833 int target_ifreq_size;
4834 int nb_ifreq;
4835 int free_buf = 0;
4836 int i;
4837 int target_ifc_len;
4838 abi_long target_ifc_buf;
4839 int host_ifc_len;
4840 char *host_ifc_buf;
4841
4842 assert(arg_type[0] == TYPE_PTR);
4843 assert(ie->access == IOC_RW);
4844
4845 arg_type++;
4846 target_size = thunk_type_size(arg_type, 0);
4847
4848 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4849 if (!argptr)
4850 return -TARGET_EFAULT;
4851 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4852 unlock_user(argptr, arg, 0);
4853
4854 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
059c2f2c 4855 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
4df7b7fa 4856 target_ifreq_size = thunk_type_size(ifreq_max_type, 0);
059c2f2c 4857
22e4a267
KL
4858 if (target_ifc_buf != 0) {
4859 target_ifc_len = host_ifconf->ifc_len;
4860 nb_ifreq = target_ifc_len / target_ifreq_size;
4861 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
4862
4863 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
4864 if (outbufsz > MAX_STRUCT_SIZE) {
4865 /*
4866 * We can't fit all the extents into the fixed size buffer.
4867 * Allocate one that is large enough and use it instead.
4868 */
4869 host_ifconf = malloc(outbufsz);
4870 if (!host_ifconf) {
4871 return -TARGET_ENOMEM;
4872 }
4873 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
4874 free_buf = 1;
059c2f2c 4875 }
22e4a267 4876 host_ifc_buf = (char *)host_ifconf + sizeof(*host_ifconf);
059c2f2c 4877
22e4a267
KL
4878 host_ifconf->ifc_len = host_ifc_len;
4879 } else {
4880 host_ifc_buf = NULL;
4881 }
059c2f2c
LV
4882 host_ifconf->ifc_buf = host_ifc_buf;
4883
49ca6f3e 4884 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
059c2f2c
LV
4885 if (!is_error(ret)) {
4886 /* convert host ifc_len to target ifc_len */
4887
4888 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
4889 target_ifc_len = nb_ifreq * target_ifreq_size;
4890 host_ifconf->ifc_len = target_ifc_len;
4891
4892 /* restore target ifc_buf */
4893
4894 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
4895
4896 /* copy struct ifconf to target user */
4897
4898 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4899 if (!argptr)
4900 return -TARGET_EFAULT;
4901 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
4902 unlock_user(argptr, arg, target_size);
4903
22e4a267
KL
4904 if (target_ifc_buf != 0) {
4905 /* copy ifreq[] to target user */
4906 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
4907 for (i = 0; i < nb_ifreq ; i++) {
4908 thunk_convert(argptr + i * target_ifreq_size,
4909 host_ifc_buf + i * sizeof(struct ifreq),
4910 ifreq_arg_type, THUNK_TARGET);
4911 }
4912 unlock_user(argptr, target_ifc_buf, target_ifc_len);
059c2f2c 4913 }
059c2f2c
LV
4914 }
4915
4916 if (free_buf) {
4917 free(host_ifconf);
4918 }
4919
4920 return ret;
4921}
4922
a133367e
CT
4923#if defined(CONFIG_USBFS)
4924#if HOST_LONG_BITS > 64
4925#error USBDEVFS thunks do not support >64 bit hosts yet.
4926#endif
4927struct live_urb {
4928 uint64_t target_urb_adr;
4929 uint64_t target_buf_adr;
4930 char *target_buf_ptr;
4931 struct usbdevfs_urb host_urb;
4932};
4933
4934static GHashTable *usbdevfs_urb_hashtable(void)
4935{
4936 static GHashTable *urb_hashtable;
4937
4938 if (!urb_hashtable) {
4939 urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal);
4940 }
4941 return urb_hashtable;
4942}
4943
4944static void urb_hashtable_insert(struct live_urb *urb)
4945{
4946 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
4947 g_hash_table_insert(urb_hashtable, urb, urb);
4948}
4949
4950static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr)
4951{
4952 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
4953 return g_hash_table_lookup(urb_hashtable, &target_urb_adr);
4954}
4955
4956static void urb_hashtable_remove(struct live_urb *urb)
4957{
4958 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
4959 g_hash_table_remove(urb_hashtable, urb);
4960}
4961
4962static abi_long
4963do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp,
4964 int fd, int cmd, abi_long arg)
4965{
4966 const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) };
4967 const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 };
4968 struct live_urb *lurb;
4969 void *argptr;
4970 uint64_t hurb;
4971 int target_size;
4972 uintptr_t target_urb_adr;
4973 abi_long ret;
4974
4975 target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET);
4976
4977 memset(buf_temp, 0, sizeof(uint64_t));
4978 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4979 if (is_error(ret)) {
4980 return ret;
4981 }
4982
4983 memcpy(&hurb, buf_temp, sizeof(uint64_t));
4984 lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb));
4985 if (!lurb->target_urb_adr) {
4986 return -TARGET_EFAULT;
4987 }
4988 urb_hashtable_remove(lurb);
4989 unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr,
4990 lurb->host_urb.buffer_length);
4991 lurb->target_buf_ptr = NULL;
4992
4993 /* restore the guest buffer pointer */
4994 lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr;
4995
4996 /* update the guest urb struct */
4997 argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0);
4998 if (!argptr) {
4999 g_free(lurb);
5000 return -TARGET_EFAULT;
5001 }
5002 thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET);
5003 unlock_user(argptr, lurb->target_urb_adr, target_size);
5004
5005 target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET);
5006 /* write back the urb handle */
5007 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5008 if (!argptr) {
5009 g_free(lurb);
5010 return -TARGET_EFAULT;
5011 }
5012
5013 /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */
5014 target_urb_adr = lurb->target_urb_adr;
5015 thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET);
5016 unlock_user(argptr, arg, target_size);
5017
5018 g_free(lurb);
5019 return ret;
5020}
5021
5022static abi_long
5023do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie,
5024 uint8_t *buf_temp __attribute__((unused)),
5025 int fd, int cmd, abi_long arg)
5026{
5027 struct live_urb *lurb;
5028
5029 /* map target address back to host URB with metadata. */
5030 lurb = urb_hashtable_lookup(arg);
5031 if (!lurb) {
5032 return -TARGET_EFAULT;
5033 }
5034 return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
5035}
5036
5037static abi_long
5038do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp,
5039 int fd, int cmd, abi_long arg)
5040{
5041 const argtype *arg_type = ie->arg_type;
5042 int target_size;
5043 abi_long ret;
5044 void *argptr;
5045 int rw_dir;
5046 struct live_urb *lurb;
5047
5048 /*
5049 * each submitted URB needs to map to a unique ID for the
5050 * kernel, and that unique ID needs to be a pointer to
5051 * host memory. hence, we need to malloc for each URB.
5052 * isochronous transfers have a variable length struct.
5053 */
5054 arg_type++;
5055 target_size = thunk_type_size(arg_type, THUNK_TARGET);
5056
5057 /* construct host copy of urb and metadata */
5058 lurb = g_try_malloc0(sizeof(struct live_urb));
5059 if (!lurb) {
5060 return -TARGET_ENOMEM;
5061 }
5062
5063 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5064 if (!argptr) {
5065 g_free(lurb);
5066 return -TARGET_EFAULT;
5067 }
5068 thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST);
5069 unlock_user(argptr, arg, 0);
5070
5071 lurb->target_urb_adr = arg;
5072 lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer;
5073
5074 /* buffer space used depends on endpoint type so lock the entire buffer */
5075 /* control type urbs should check the buffer contents for true direction */
5076 rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ;
5077 lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr,
5078 lurb->host_urb.buffer_length, 1);
5079 if (lurb->target_buf_ptr == NULL) {
5080 g_free(lurb);
5081 return -TARGET_EFAULT;
5082 }
5083
5084 /* update buffer pointer in host copy */
5085 lurb->host_urb.buffer = lurb->target_buf_ptr;
5086
5087 ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
5088 if (is_error(ret)) {
5089 unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0);
5090 g_free(lurb);
5091 } else {
5092 urb_hashtable_insert(lurb);
5093 }
5094
5095 return ret;
5096}
5097#endif /* CONFIG_USBFS */
5098
56e904ec 5099static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
45c874eb 5100 int cmd, abi_long arg)
56e904ec
AG
5101{
5102 void *argptr;
5103 struct dm_ioctl *host_dm;
5104 abi_long guest_data;
5105 uint32_t guest_data_size;
5106 int target_size;
5107 const argtype *arg_type = ie->arg_type;
5108 abi_long ret;
5109 void *big_buf = NULL;
5110 char *host_data;
5111
5112 arg_type++;
5113 target_size = thunk_type_size(arg_type, 0);
5114 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5115 if (!argptr) {
5116 ret = -TARGET_EFAULT;
5117 goto out;
5118 }
5119 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5120 unlock_user(argptr, arg, 0);
5121
5122 /* buf_temp is too small, so fetch things into a bigger buffer */
5123 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
5124 memcpy(big_buf, buf_temp, target_size);
5125 buf_temp = big_buf;
5126 host_dm = big_buf;
5127
5128 guest_data = arg + host_dm->data_start;
5129 if ((guest_data - arg) < 0) {
f9757b1d 5130 ret = -TARGET_EINVAL;
56e904ec
AG
5131 goto out;
5132 }
5133 guest_data_size = host_dm->data_size - host_dm->data_start;
5134 host_data = (char*)host_dm + host_dm->data_start;
5135
5136 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3211215e
PM
5137 if (!argptr) {
5138 ret = -TARGET_EFAULT;
5139 goto out;
5140 }
5141
56e904ec
AG
5142 switch (ie->host_cmd) {
5143 case DM_REMOVE_ALL:
5144 case DM_LIST_DEVICES:
5145 case DM_DEV_CREATE:
5146 case DM_DEV_REMOVE:
5147 case DM_DEV_SUSPEND:
5148 case DM_DEV_STATUS:
5149 case DM_DEV_WAIT:
5150 case DM_TABLE_STATUS:
5151 case DM_TABLE_CLEAR:
5152 case DM_TABLE_DEPS:
5153 case DM_LIST_VERSIONS:
5154 /* no input data */
5155 break;
5156 case DM_DEV_RENAME:
5157 case DM_DEV_SET_GEOMETRY:
5158 /* data contains only strings */
5159 memcpy(host_data, argptr, guest_data_size);
5160 break;
5161 case DM_TARGET_MSG:
5162 memcpy(host_data, argptr, guest_data_size);
5163 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
5164 break;
5165 case DM_TABLE_LOAD:
5166 {
5167 void *gspec = argptr;
5168 void *cur_data = host_data;
5169 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
5170 int spec_size = thunk_type_size(arg_type, 0);
5171 int i;
5172
5173 for (i = 0; i < host_dm->target_count; i++) {
5174 struct dm_target_spec *spec = cur_data;
5175 uint32_t next;
5176 int slen;
5177
5178 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
5179 slen = strlen((char*)gspec + spec_size) + 1;
5180 next = spec->next;
5181 spec->next = sizeof(*spec) + slen;
5182 strcpy((char*)&spec[1], gspec + spec_size);
5183 gspec += next;
5184 cur_data += spec->next;
5185 }
5186 break;
5187 }
5188 default:
5189 ret = -TARGET_EINVAL;
dec0473d 5190 unlock_user(argptr, guest_data, 0);
56e904ec
AG
5191 goto out;
5192 }
5193 unlock_user(argptr, guest_data, 0);
5194
49ca6f3e 5195 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
56e904ec
AG
5196 if (!is_error(ret)) {
5197 guest_data = arg + host_dm->data_start;
5198 guest_data_size = host_dm->data_size - host_dm->data_start;
5199 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
5200 switch (ie->host_cmd) {
5201 case DM_REMOVE_ALL:
5202 case DM_DEV_CREATE:
5203 case DM_DEV_REMOVE:
5204 case DM_DEV_RENAME:
5205 case DM_DEV_SUSPEND:
5206 case DM_DEV_STATUS:
5207 case DM_TABLE_LOAD:
5208 case DM_TABLE_CLEAR:
5209 case DM_TARGET_MSG:
5210 case DM_DEV_SET_GEOMETRY:
5211 /* no return data */
5212 break;
5213 case DM_LIST_DEVICES:
5214 {
5215 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
5216 uint32_t remaining_data = guest_data_size;
5217 void *cur_data = argptr;
5218 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
5219 int nl_size = 12; /* can't use thunk_size due to alignment */
5220
5221 while (1) {
5222 uint32_t next = nl->next;
5223 if (next) {
5224 nl->next = nl_size + (strlen(nl->name) + 1);
5225 }
5226 if (remaining_data < nl->next) {
5227 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5228 break;
5229 }
5230 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
5231 strcpy(cur_data + nl_size, nl->name);
5232 cur_data += nl->next;
5233 remaining_data -= nl->next;
5234 if (!next) {
5235 break;
5236 }
5237 nl = (void*)nl + next;
5238 }
5239 break;
5240 }
5241 case DM_DEV_WAIT:
5242 case DM_TABLE_STATUS:
5243 {
5244 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
5245 void *cur_data = argptr;
5246 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
5247 int spec_size = thunk_type_size(arg_type, 0);
5248 int i;
5249
5250 for (i = 0; i < host_dm->target_count; i++) {
5251 uint32_t next = spec->next;
5252 int slen = strlen((char*)&spec[1]) + 1;
5253 spec->next = (cur_data - argptr) + spec_size + slen;
5254 if (guest_data_size < spec->next) {
5255 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5256 break;
5257 }
5258 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
5259 strcpy(cur_data + spec_size, (char*)&spec[1]);
5260 cur_data = argptr + spec->next;
5261 spec = (void*)host_dm + host_dm->data_start + next;
5262 }
5263 break;
5264 }
5265 case DM_TABLE_DEPS:
5266 {
5267 void *hdata = (void*)host_dm + host_dm->data_start;
5268 int count = *(uint32_t*)hdata;
5269 uint64_t *hdev = hdata + 8;
5270 uint64_t *gdev = argptr + 8;
5271 int i;
5272
5273 *(uint32_t*)argptr = tswap32(count);
5274 for (i = 0; i < count; i++) {
5275 *gdev = tswap64(*hdev);
5276 gdev++;
5277 hdev++;
5278 }
5279 break;
5280 }
5281 case DM_LIST_VERSIONS:
5282 {
5283 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
5284 uint32_t remaining_data = guest_data_size;
5285 void *cur_data = argptr;
5286 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
5287 int vers_size = thunk_type_size(arg_type, 0);
5288
5289 while (1) {
5290 uint32_t next = vers->next;
5291 if (next) {
5292 vers->next = vers_size + (strlen(vers->name) + 1);
5293 }
5294 if (remaining_data < vers->next) {
5295 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5296 break;
5297 }
5298 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
5299 strcpy(cur_data + vers_size, vers->name);
5300 cur_data += vers->next;
5301 remaining_data -= vers->next;
5302 if (!next) {
5303 break;
5304 }
5305 vers = (void*)vers + next;
5306 }
5307 break;
5308 }
5309 default:
dec0473d 5310 unlock_user(argptr, guest_data, 0);
56e904ec
AG
5311 ret = -TARGET_EINVAL;
5312 goto out;
5313 }
5314 unlock_user(argptr, guest_data, guest_data_size);
5315
5316 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5317 if (!argptr) {
5318 ret = -TARGET_EFAULT;
5319 goto out;
5320 }
5321 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5322 unlock_user(argptr, arg, target_size);
5323 }
5324out:
ad11ad77 5325 g_free(big_buf);
56e904ec
AG
5326 return ret;
5327}
5328
a59b5e35 5329static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
45c874eb 5330 int cmd, abi_long arg)
a59b5e35
AG
5331{
5332 void *argptr;
5333 int target_size;
5334 const argtype *arg_type = ie->arg_type;
5335 const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
5336 abi_long ret;
5337
5338 struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
5339 struct blkpg_partition host_part;
5340
5341 /* Read and convert blkpg */
5342 arg_type++;
5343 target_size = thunk_type_size(arg_type, 0);
5344 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5345 if (!argptr) {
5346 ret = -TARGET_EFAULT;
5347 goto out;
5348 }
5349 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5350 unlock_user(argptr, arg, 0);
5351
5352 switch (host_blkpg->op) {
5353 case BLKPG_ADD_PARTITION:
5354 case BLKPG_DEL_PARTITION:
5355 /* payload is struct blkpg_partition */
5356 break;
5357 default:
5358 /* Unknown opcode */
5359 ret = -TARGET_EINVAL;
5360 goto out;
5361 }
5362
5363 /* Read and convert blkpg->data */
5364 arg = (abi_long)(uintptr_t)host_blkpg->data;
5365 target_size = thunk_type_size(part_arg_type, 0);
5366 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5367 if (!argptr) {
5368 ret = -TARGET_EFAULT;
5369 goto out;
5370 }
5371 thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
5372 unlock_user(argptr, arg, 0);
5373
5374 /* Swizzle the data pointer to our local copy and call! */
5375 host_blkpg->data = &host_part;
49ca6f3e 5376 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg));
a59b5e35
AG
5377
5378out:
5379 return ret;
5380}
5381
7ff7b666 5382static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 5383 int fd, int cmd, abi_long arg)
7ff7b666
LV
5384{
5385 const argtype *arg_type = ie->arg_type;
5386 const StructEntry *se;
5387 const argtype *field_types;
5388 const int *dst_offsets, *src_offsets;
5389 int target_size;
5390 void *argptr;
b78c522a
MAL
5391 abi_ulong *target_rt_dev_ptr = NULL;
5392 unsigned long *host_rt_dev_ptr = NULL;
7ff7b666
LV
5393 abi_long ret;
5394 int i;
5395
5396 assert(ie->access == IOC_W);
5397 assert(*arg_type == TYPE_PTR);
5398 arg_type++;
5399 assert(*arg_type == TYPE_STRUCT);
5400 target_size = thunk_type_size(arg_type, 0);
5401 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5402 if (!argptr) {
5403 return -TARGET_EFAULT;
5404 }
5405 arg_type++;
5406 assert(*arg_type == (int)STRUCT_rtentry);
5407 se = struct_entries + *arg_type++;
5408 assert(se->convert[0] == NULL);
5409 /* convert struct here to be able to catch rt_dev string */
5410 field_types = se->field_types;
5411 dst_offsets = se->field_offsets[THUNK_HOST];
5412 src_offsets = se->field_offsets[THUNK_TARGET];
5413 for (i = 0; i < se->nb_fields; i++) {
5414 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
5415 assert(*field_types == TYPE_PTRVOID);
5416 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
5417 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
5418 if (*target_rt_dev_ptr != 0) {
5419 *host_rt_dev_ptr = (unsigned long)lock_user_string(
5420 tswapal(*target_rt_dev_ptr));
5421 if (!*host_rt_dev_ptr) {
5422 unlock_user(argptr, arg, 0);
5423 return -TARGET_EFAULT;
5424 }
5425 } else {
5426 *host_rt_dev_ptr = 0;
5427 }
5428 field_types++;
5429 continue;
5430 }
5431 field_types = thunk_convert(buf_temp + dst_offsets[i],
5432 argptr + src_offsets[i],
5433 field_types, THUNK_HOST);
5434 }
5435 unlock_user(argptr, arg, 0);
5436
49ca6f3e 5437 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
b78c522a
MAL
5438
5439 assert(host_rt_dev_ptr != NULL);
5440 assert(target_rt_dev_ptr != NULL);
7ff7b666
LV
5441 if (*host_rt_dev_ptr != 0) {
5442 unlock_user((void *)*host_rt_dev_ptr,
5443 *target_rt_dev_ptr, 0);
5444 }
5445 return ret;
5446}
5447
ca56f5b5 5448static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 5449 int fd, int cmd, abi_long arg)
ca56f5b5
PB
5450{
5451 int sig = target_to_host_signal(arg);
49ca6f3e 5452 return get_errno(safe_ioctl(fd, ie->host_cmd, sig));
ca56f5b5
PB
5453}
5454
6d5d5dde
DB
5455static abi_long do_ioctl_SIOCGSTAMP(const IOCTLEntry *ie, uint8_t *buf_temp,
5456 int fd, int cmd, abi_long arg)
5457{
5458 struct timeval tv;
5459 abi_long ret;
5460
5461 ret = get_errno(safe_ioctl(fd, SIOCGSTAMP, &tv));
5462 if (is_error(ret)) {
5463 return ret;
5464 }
5465
5466 if (cmd == (int)TARGET_SIOCGSTAMP_OLD) {
5467 if (copy_to_user_timeval(arg, &tv)) {
5468 return -TARGET_EFAULT;
5469 }
5470 } else {
5471 if (copy_to_user_timeval64(arg, &tv)) {
5472 return -TARGET_EFAULT;
5473 }
5474 }
5475
5476 return ret;
5477}
5478
5479static abi_long do_ioctl_SIOCGSTAMPNS(const IOCTLEntry *ie, uint8_t *buf_temp,
5480 int fd, int cmd, abi_long arg)
5481{
5482 struct timespec ts;
5483 abi_long ret;
5484
5485 ret = get_errno(safe_ioctl(fd, SIOCGSTAMPNS, &ts));
5486 if (is_error(ret)) {
5487 return ret;
5488 }
5489
5490 if (cmd == (int)TARGET_SIOCGSTAMPNS_OLD) {
5491 if (host_to_target_timespec(arg, &ts)) {
5492 return -TARGET_EFAULT;
5493 }
5494 } else{
5495 if (host_to_target_timespec64(arg, &ts)) {
5496 return -TARGET_EFAULT;
5497 }
5498 }
5499
5500 return ret;
5501}
5502
2b74f621
AS
5503#ifdef TIOCGPTPEER
5504static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp,
5505 int fd, int cmd, abi_long arg)
5506{
5507 int flags = target_to_host_bitmask(arg, fcntl_flags_tbl);
5508 return get_errno(safe_ioctl(fd, ie->host_cmd, flags));
5509}
5510#endif
5511
e865b97f
CG
5512#ifdef HAVE_DRM_H
5513
5514static void unlock_drm_version(struct drm_version *host_ver,
5515 struct target_drm_version *target_ver,
5516 bool copy)
5517{
5518 unlock_user(host_ver->name, target_ver->name,
5519 copy ? host_ver->name_len : 0);
5520 unlock_user(host_ver->date, target_ver->date,
5521 copy ? host_ver->date_len : 0);
5522 unlock_user(host_ver->desc, target_ver->desc,
5523 copy ? host_ver->desc_len : 0);
5524}
5525
5526static inline abi_long target_to_host_drmversion(struct drm_version *host_ver,
5527 struct target_drm_version *target_ver)
5528{
5529 memset(host_ver, 0, sizeof(*host_ver));
5530
5531 __get_user(host_ver->name_len, &target_ver->name_len);
5532 if (host_ver->name_len) {
5533 host_ver->name = lock_user(VERIFY_WRITE, target_ver->name,
5534 target_ver->name_len, 0);
5535 if (!host_ver->name) {
5536 return -EFAULT;
5537 }
5538 }
5539
5540 __get_user(host_ver->date_len, &target_ver->date_len);
5541 if (host_ver->date_len) {
5542 host_ver->date = lock_user(VERIFY_WRITE, target_ver->date,
5543 target_ver->date_len, 0);
5544 if (!host_ver->date) {
5545 goto err;
5546 }
5547 }
5548
5549 __get_user(host_ver->desc_len, &target_ver->desc_len);
5550 if (host_ver->desc_len) {
5551 host_ver->desc = lock_user(VERIFY_WRITE, target_ver->desc,
5552 target_ver->desc_len, 0);
5553 if (!host_ver->desc) {
5554 goto err;
5555 }
5556 }
5557
5558 return 0;
5559err:
5560 unlock_drm_version(host_ver, target_ver, false);
5561 return -EFAULT;
5562}
5563
5564static inline void host_to_target_drmversion(
5565 struct target_drm_version *target_ver,
5566 struct drm_version *host_ver)
5567{
5568 __put_user(host_ver->version_major, &target_ver->version_major);
5569 __put_user(host_ver->version_minor, &target_ver->version_minor);
5570 __put_user(host_ver->version_patchlevel, &target_ver->version_patchlevel);
5571 __put_user(host_ver->name_len, &target_ver->name_len);
5572 __put_user(host_ver->date_len, &target_ver->date_len);
5573 __put_user(host_ver->desc_len, &target_ver->desc_len);
5574 unlock_drm_version(host_ver, target_ver, true);
5575}
5576
5577static abi_long do_ioctl_drm(const IOCTLEntry *ie, uint8_t *buf_temp,
5578 int fd, int cmd, abi_long arg)
5579{
5580 struct drm_version *ver;
5581 struct target_drm_version *target_ver;
5582 abi_long ret;
5583
5584 switch (ie->host_cmd) {
5585 case DRM_IOCTL_VERSION:
5586 if (!lock_user_struct(VERIFY_WRITE, target_ver, arg, 0)) {
5587 return -TARGET_EFAULT;
5588 }
5589 ver = (struct drm_version *)buf_temp;
5590 ret = target_to_host_drmversion(ver, target_ver);
5591 if (!is_error(ret)) {
5592 ret = get_errno(safe_ioctl(fd, ie->host_cmd, ver));
5593 if (is_error(ret)) {
5594 unlock_drm_version(ver, target_ver, false);
5595 } else {
5596 host_to_target_drmversion(target_ver, ver);
5597 }
5598 }
5599 unlock_user_struct(target_ver, arg, 0);
5600 return ret;
5601 }
5602 return -TARGET_ENOSYS;
5603}
5604
913b03c2
CG
5605static abi_long do_ioctl_drm_i915_getparam(const IOCTLEntry *ie,
5606 struct drm_i915_getparam *gparam,
5607 int fd, abi_long arg)
5608{
5609 abi_long ret;
5610 int value;
5611 struct target_drm_i915_getparam *target_gparam;
5612
5613 if (!lock_user_struct(VERIFY_READ, target_gparam, arg, 0)) {
5614 return -TARGET_EFAULT;
5615 }
5616
5617 __get_user(gparam->param, &target_gparam->param);
5618 gparam->value = &value;
5619 ret = get_errno(safe_ioctl(fd, ie->host_cmd, gparam));
5620 put_user_s32(value, target_gparam->value);
5621
5622 unlock_user_struct(target_gparam, arg, 0);
5623 return ret;
5624}
5625
5626static abi_long do_ioctl_drm_i915(const IOCTLEntry *ie, uint8_t *buf_temp,
5627 int fd, int cmd, abi_long arg)
5628{
5629 switch (ie->host_cmd) {
5630 case DRM_IOCTL_I915_GETPARAM:
5631 return do_ioctl_drm_i915_getparam(ie,
5632 (struct drm_i915_getparam *)buf_temp,
5633 fd, arg);
5634 default:
5635 return -TARGET_ENOSYS;
5636 }
5637}
5638
e865b97f
CG
5639#endif
5640
6addf06a
SCW
5641static abi_long do_ioctl_TUNSETTXFILTER(const IOCTLEntry *ie, uint8_t *buf_temp,
5642 int fd, int cmd, abi_long arg)
5643{
5644 struct tun_filter *filter = (struct tun_filter *)buf_temp;
5645 struct tun_filter *target_filter;
5646 char *target_addr;
5647
5648 assert(ie->access == IOC_W);
5649
5650 target_filter = lock_user(VERIFY_READ, arg, sizeof(*target_filter), 1);
5651 if (!target_filter) {
5652 return -TARGET_EFAULT;
5653 }
5654 filter->flags = tswap16(target_filter->flags);
5655 filter->count = tswap16(target_filter->count);
5656 unlock_user(target_filter, arg, 0);
5657
5658 if (filter->count) {
5659 if (offsetof(struct tun_filter, addr) + filter->count * ETH_ALEN >
5660 MAX_STRUCT_SIZE) {
5661 return -TARGET_EFAULT;
5662 }
5663
5664 target_addr = lock_user(VERIFY_READ,
5665 arg + offsetof(struct tun_filter, addr),
5666 filter->count * ETH_ALEN, 1);
5667 if (!target_addr) {
5668 return -TARGET_EFAULT;
5669 }
5670 memcpy(filter->addr, target_addr, filter->count * ETH_ALEN);
5671 unlock_user(target_addr, arg + offsetof(struct tun_filter, addr), 0);
5672 }
5673
5674 return get_errno(safe_ioctl(fd, ie->host_cmd, filter));
5675}
5676
79482e59 5677IOCTLEntry ioctl_entries[] = {
001faf32 5678#define IOCTL(cmd, access, ...) \
d2ef05bb
PM
5679 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
5680#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
5681 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
8cb762fe
HD
5682#define IOCTL_IGNORE(cmd) \
5683 { TARGET_ ## cmd, 0, #cmd },
31e31b8a
FB
5684#include "ioctls.h"
5685 { 0, 0, },
5686};
5687
53a5960a 5688/* ??? Implement proper locking for ioctls. */
0da46a6e 5689/* do_ioctl() Must return target values and target errnos. */
45c874eb 5690static abi_long do_ioctl(int fd, int cmd, abi_long arg)
31e31b8a
FB
5691{
5692 const IOCTLEntry *ie;
5693 const argtype *arg_type;
992f48a0 5694 abi_long ret;
31e31b8a 5695 uint8_t buf_temp[MAX_STRUCT_SIZE];
53a5960a
PB
5696 int target_size;
5697 void *argptr;
31e31b8a
FB
5698
5699 ie = ioctl_entries;
5700 for(;;) {
5701 if (ie->target_cmd == 0) {
39be5350
JK
5702 qemu_log_mask(
5703 LOG_UNIMP, "Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
0da46a6e 5704 return -TARGET_ENOSYS;
31e31b8a
FB
5705 }
5706 if (ie->target_cmd == cmd)
5707 break;
5708 ie++;
5709 }
5710 arg_type = ie->arg_type;
d2ef05bb
PM
5711 if (ie->do_ioctl) {
5712 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
8cb762fe
HD
5713 } else if (!ie->host_cmd) {
5714 /* Some architectures define BSD ioctls in their headers
5715 that are not implemented in Linux. */
5716 return -TARGET_ENOSYS;
d2ef05bb
PM
5717 }
5718
31e31b8a
FB
5719 switch(arg_type[0]) {
5720 case TYPE_NULL:
5721 /* no argument */
49ca6f3e 5722 ret = get_errno(safe_ioctl(fd, ie->host_cmd));
31e31b8a
FB
5723 break;
5724 case TYPE_PTRVOID:
5725 case TYPE_INT:
c858e537
FB
5726 case TYPE_LONG:
5727 case TYPE_ULONG:
49ca6f3e 5728 ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
31e31b8a
FB
5729 break;
5730 case TYPE_PTR:
5731 arg_type++;
53a5960a 5732 target_size = thunk_type_size(arg_type, 0);
31e31b8a
FB
5733 switch(ie->access) {
5734 case IOC_R:
49ca6f3e 5735 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a 5736 if (!is_error(ret)) {
579a97f7
FB
5737 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5738 if (!argptr)
5739 return -TARGET_EFAULT;
53a5960a
PB
5740 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5741 unlock_user(argptr, arg, target_size);
31e31b8a
FB
5742 }
5743 break;
5744 case IOC_W:
579a97f7
FB
5745 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5746 if (!argptr)
5747 return -TARGET_EFAULT;
53a5960a
PB
5748 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5749 unlock_user(argptr, arg, 0);
49ca6f3e 5750 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a
FB
5751 break;
5752 default:
5753 case IOC_RW:
579a97f7
FB
5754 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5755 if (!argptr)
5756 return -TARGET_EFAULT;
53a5960a
PB
5757 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5758 unlock_user(argptr, arg, 0);
49ca6f3e 5759 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a 5760 if (!is_error(ret)) {
579a97f7
FB
5761 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5762 if (!argptr)
5763 return -TARGET_EFAULT;
53a5960a
PB
5764 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5765 unlock_user(argptr, arg, target_size);
31e31b8a
FB
5766 }
5767 break;
5768 }
5769 break;
5770 default:
39be5350
JK
5771 qemu_log_mask(LOG_UNIMP,
5772 "Unsupported ioctl type: cmd=0x%04lx type=%d\n",
5773 (long)cmd, arg_type[0]);
0da46a6e 5774 ret = -TARGET_ENOSYS;
31e31b8a
FB
5775 break;
5776 }
5777 return ret;
5778}
5779
b39bc503 5780static const bitmask_transtbl iflag_tbl[] = {
31e31b8a
FB
5781 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
5782 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
5783 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
5784 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
5785 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
5786 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
5787 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
5788 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
5789 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
5790 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
5791 { TARGET_IXON, TARGET_IXON, IXON, IXON },
5792 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
5793 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
5794 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
c218b4ed 5795 { TARGET_IUTF8, TARGET_IUTF8, IUTF8, IUTF8},
31e31b8a
FB
5796 { 0, 0, 0, 0 }
5797};
5798
b39bc503 5799static const bitmask_transtbl oflag_tbl[] = {
31e31b8a
FB
5800 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
5801 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
5802 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
5803 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
5804 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
5805 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
5806 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
5807 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
5808 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
5809 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
5810 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
5811 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
5812 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
5813 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
5814 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
5815 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
5816 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
5817 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
5818 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
5819 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
5820 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
5821 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
5822 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
5823 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
5824 { 0, 0, 0, 0 }
5825};
5826
b39bc503 5827static const bitmask_transtbl cflag_tbl[] = {
31e31b8a
FB
5828 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
5829 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
5830 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
5831 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
5832 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
5833 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
5834 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
5835 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
5836 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
5837 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
5838 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
5839 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
5840 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
5841 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
5842 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
5843 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
5844 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
5845 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
5846 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
5847 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
5848 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
5849 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
5850 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
5851 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
5852 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
5853 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
5854 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
5855 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
5856 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
5857 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
5858 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
5859 { 0, 0, 0, 0 }
5860};
5861
b39bc503 5862static const bitmask_transtbl lflag_tbl[] = {
c218b4ed
FB
5863 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
5864 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
5865 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
5866 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
5867 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
5868 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
5869 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
5870 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
5871 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
5872 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
5873 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
5874 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
5875 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
5876 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
5877 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
5878 { TARGET_EXTPROC, TARGET_EXTPROC, EXTPROC, EXTPROC},
5879 { 0, 0, 0, 0 }
31e31b8a
FB
5880};
5881
5882static void target_to_host_termios (void *dst, const void *src)
5883{
5884 struct host_termios *host = dst;
5885 const struct target_termios *target = src;
3b46e624 5886
5fafdf24 5887 host->c_iflag =
31e31b8a 5888 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
5fafdf24 5889 host->c_oflag =
31e31b8a 5890 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
5fafdf24 5891 host->c_cflag =
31e31b8a 5892 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
5fafdf24 5893 host->c_lflag =
31e31b8a
FB
5894 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
5895 host->c_line = target->c_line;
3b46e624 5896
44607123 5897 memset(host->c_cc, 0, sizeof(host->c_cc));
5fafdf24
TS
5898 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
5899 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3b46e624 5900 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
5fafdf24 5901 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3b46e624 5902 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
5fafdf24 5903 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3b46e624 5904 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
5fafdf24 5905 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3b46e624 5906 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
5fafdf24
TS
5907 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
5908 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3b46e624
TS
5909 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
5910 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
5911 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
5912 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
5913 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
5fafdf24 5914 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
31e31b8a 5915}
3b46e624 5916
31e31b8a
FB
5917static void host_to_target_termios (void *dst, const void *src)
5918{
5919 struct target_termios *target = dst;
5920 const struct host_termios *host = src;
5921
5fafdf24 5922 target->c_iflag =
31e31b8a 5923 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
5fafdf24 5924 target->c_oflag =
31e31b8a 5925 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
5fafdf24 5926 target->c_cflag =
31e31b8a 5927 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
5fafdf24 5928 target->c_lflag =
31e31b8a
FB
5929 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
5930 target->c_line = host->c_line;
3b46e624 5931
44607123 5932 memset(target->c_cc, 0, sizeof(target->c_cc));
31e31b8a
FB
5933 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
5934 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
5935 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
5936 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
5937 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
5938 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
5939 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
5940 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
5941 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
5942 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
5943 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
5944 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
5945 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
5946 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
5947 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
5948 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
5949 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
5950}
5951
8e853dc7 5952static const StructEntry struct_termios_def = {
31e31b8a
FB
5953 .convert = { host_to_target_termios, target_to_host_termios },
5954 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
5955 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
888468db 5956 .print = print_termios,
31e31b8a
FB
5957};
5958
180d4ef3 5959static const bitmask_transtbl mmap_flags_tbl[] = {
541e1690
HD
5960 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
5961 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
5962 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
5963 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS,
5964 MAP_ANONYMOUS, MAP_ANONYMOUS },
5965 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN,
5966 MAP_GROWSDOWN, MAP_GROWSDOWN },
5967 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE,
5968 MAP_DENYWRITE, MAP_DENYWRITE },
5969 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE,
5970 MAP_EXECUTABLE, MAP_EXECUTABLE },
5971 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
5972 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE,
5973 MAP_NORESERVE, MAP_NORESERVE },
5974 { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },
5975 /* MAP_STACK had been ignored by the kernel for quite some time.
5976 Recognize it for the target insofar as we do not want to pass
5977 it through to the host. */
5978 { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 },
5979 { 0, 0, 0, 0 }
5286db75
FB
5980};
5981
9d12f79d
LV
5982/*
5983 * NOTE: TARGET_ABI32 is defined for TARGET_I386 (but not for TARGET_X86_64)
5984 * TARGET_I386 is defined if TARGET_X86_64 is defined
5985 */
2ab83ea7 5986#if defined(TARGET_I386)
6dbad63e
FB
5987
5988/* NOTE: there is really one LDT for all the threads */
b1d8e52e 5989static uint8_t *ldt_table;
6dbad63e 5990
03acab66 5991static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
6dbad63e
FB
5992{
5993 int size;
53a5960a 5994 void *p;
6dbad63e
FB
5995
5996 if (!ldt_table)
5997 return 0;
5998 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
5999 if (size > bytecount)
6000 size = bytecount;
579a97f7
FB
6001 p = lock_user(VERIFY_WRITE, ptr, size, 0);
6002 if (!p)
03acab66 6003 return -TARGET_EFAULT;
579a97f7 6004 /* ??? Should this by byteswapped? */
53a5960a
PB
6005 memcpy(p, ldt_table, size);
6006 unlock_user(p, ptr, size);
6dbad63e
FB
6007 return size;
6008}
6009
6010/* XXX: add locking support */
03acab66
FB
6011static abi_long write_ldt(CPUX86State *env,
6012 abi_ulong ptr, unsigned long bytecount, int oldmode)
6dbad63e
FB
6013{
6014 struct target_modify_ldt_ldt_s ldt_info;
53a5960a 6015 struct target_modify_ldt_ldt_s *target_ldt_info;
6dbad63e 6016 int seg_32bit, contents, read_exec_only, limit_in_pages;
8d18e893 6017 int seg_not_present, useable, lm;
6dbad63e
FB
6018 uint32_t *lp, entry_1, entry_2;
6019
6020 if (bytecount != sizeof(ldt_info))
03acab66 6021 return -TARGET_EINVAL;
579a97f7 6022 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
03acab66 6023 return -TARGET_EFAULT;
53a5960a 6024 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
cbb21eed 6025 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
53a5960a
PB
6026 ldt_info.limit = tswap32(target_ldt_info->limit);
6027 ldt_info.flags = tswap32(target_ldt_info->flags);
6028 unlock_user_struct(target_ldt_info, ptr, 0);
3b46e624 6029
6dbad63e 6030 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
03acab66 6031 return -TARGET_EINVAL;
6dbad63e
FB
6032 seg_32bit = ldt_info.flags & 1;
6033 contents = (ldt_info.flags >> 1) & 3;
6034 read_exec_only = (ldt_info.flags >> 3) & 1;
6035 limit_in_pages = (ldt_info.flags >> 4) & 1;
6036 seg_not_present = (ldt_info.flags >> 5) & 1;
6037 useable = (ldt_info.flags >> 6) & 1;
8d18e893
FB
6038#ifdef TARGET_ABI32
6039 lm = 0;
6040#else
6041 lm = (ldt_info.flags >> 7) & 1;
6042#endif
6dbad63e
FB
6043 if (contents == 3) {
6044 if (oldmode)
03acab66 6045 return -TARGET_EINVAL;
6dbad63e 6046 if (seg_not_present == 0)
03acab66 6047 return -TARGET_EINVAL;
6dbad63e
FB
6048 }
6049 /* allocate the LDT */
6050 if (!ldt_table) {
e441570f
AZ
6051 env->ldt.base = target_mmap(0,
6052 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
6053 PROT_READ|PROT_WRITE,
6054 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
6055 if (env->ldt.base == -1)
03acab66 6056 return -TARGET_ENOMEM;
3e8f1628 6057 memset(g2h_untagged(env->ldt.base), 0,
e441570f 6058 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
6dbad63e 6059 env->ldt.limit = 0xffff;
3e8f1628 6060 ldt_table = g2h_untagged(env->ldt.base);
6dbad63e
FB
6061 }
6062
6063 /* NOTE: same code as Linux kernel */
6064 /* Allow LDTs to be cleared by the user. */
6065 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
6066 if (oldmode ||
6067 (contents == 0 &&
6068 read_exec_only == 1 &&
6069 seg_32bit == 0 &&
6070 limit_in_pages == 0 &&
6071 seg_not_present == 1 &&
6072 useable == 0 )) {
6073 entry_1 = 0;
6074 entry_2 = 0;
6075 goto install;
6076 }
6077 }
3b46e624 6078
6dbad63e
FB
6079 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
6080 (ldt_info.limit & 0x0ffff);
6081 entry_2 = (ldt_info.base_addr & 0xff000000) |
6082 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
6083 (ldt_info.limit & 0xf0000) |
6084 ((read_exec_only ^ 1) << 9) |
6085 (contents << 10) |
6086 ((seg_not_present ^ 1) << 15) |
6087 (seg_32bit << 22) |
6088 (limit_in_pages << 23) |
8d18e893 6089 (lm << 21) |
6dbad63e
FB
6090 0x7000;
6091 if (!oldmode)
6092 entry_2 |= (useable << 20);
14ae3ba7 6093
6dbad63e
FB
6094 /* Install the new entry ... */
6095install:
6096 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
6097 lp[0] = tswap32(entry_1);
6098 lp[1] = tswap32(entry_2);
6099 return 0;
6100}
6101
6102/* specific and weird i386 syscalls */
8fcd3692
BS
6103static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
6104 unsigned long bytecount)
6dbad63e 6105{
03acab66 6106 abi_long ret;
3b46e624 6107
6dbad63e
FB
6108 switch (func) {
6109 case 0:
6110 ret = read_ldt(ptr, bytecount);
6111 break;
6112 case 1:
6113 ret = write_ldt(env, ptr, bytecount, 1);
6114 break;
6115 case 0x11:
6116 ret = write_ldt(env, ptr, bytecount, 0);
6117 break;
03acab66
FB
6118 default:
6119 ret = -TARGET_ENOSYS;
6120 break;
6dbad63e
FB
6121 }
6122 return ret;
6123}
1b6b029e 6124
9d12f79d 6125#if defined(TARGET_ABI32)
bc22eb44 6126abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
8d18e893 6127{
3e8f1628 6128 uint64_t *gdt_table = g2h_untagged(env->gdt.base);
8d18e893
FB
6129 struct target_modify_ldt_ldt_s ldt_info;
6130 struct target_modify_ldt_ldt_s *target_ldt_info;
6131 int seg_32bit, contents, read_exec_only, limit_in_pages;
6132 int seg_not_present, useable, lm;
6133 uint32_t *lp, entry_1, entry_2;
6134 int i;
6135
6136 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
6137 if (!target_ldt_info)
6138 return -TARGET_EFAULT;
6139 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
cbb21eed 6140 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
8d18e893
FB
6141 ldt_info.limit = tswap32(target_ldt_info->limit);
6142 ldt_info.flags = tswap32(target_ldt_info->flags);
6143 if (ldt_info.entry_number == -1) {
6144 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
6145 if (gdt_table[i] == 0) {
6146 ldt_info.entry_number = i;
6147 target_ldt_info->entry_number = tswap32(i);
6148 break;
6149 }
6150 }
6151 }
6152 unlock_user_struct(target_ldt_info, ptr, 1);
6153
6154 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
6155 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
6156 return -TARGET_EINVAL;
6157 seg_32bit = ldt_info.flags & 1;
6158 contents = (ldt_info.flags >> 1) & 3;
6159 read_exec_only = (ldt_info.flags >> 3) & 1;
6160 limit_in_pages = (ldt_info.flags >> 4) & 1;
6161 seg_not_present = (ldt_info.flags >> 5) & 1;
6162 useable = (ldt_info.flags >> 6) & 1;
6163#ifdef TARGET_ABI32
6164 lm = 0;
6165#else
6166 lm = (ldt_info.flags >> 7) & 1;
6167#endif
6168
6169 if (contents == 3) {
6170 if (seg_not_present == 0)
6171 return -TARGET_EINVAL;
6172 }
6173
6174 /* NOTE: same code as Linux kernel */
6175 /* Allow LDTs to be cleared by the user. */
6176 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
6177 if ((contents == 0 &&
6178 read_exec_only == 1 &&
6179 seg_32bit == 0 &&
6180 limit_in_pages == 0 &&
6181 seg_not_present == 1 &&
6182 useable == 0 )) {
6183 entry_1 = 0;
6184 entry_2 = 0;
6185 goto install;
6186 }
6187 }
6188
6189 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
6190 (ldt_info.limit & 0x0ffff);
6191 entry_2 = (ldt_info.base_addr & 0xff000000) |
6192 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
6193 (ldt_info.limit & 0xf0000) |
6194 ((read_exec_only ^ 1) << 9) |
6195 (contents << 10) |
6196 ((seg_not_present ^ 1) << 15) |
6197 (seg_32bit << 22) |
6198 (limit_in_pages << 23) |
6199 (useable << 20) |
6200 (lm << 21) |
6201 0x7000;
6202
6203 /* Install the new entry ... */
6204install:
6205 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
6206 lp[0] = tswap32(entry_1);
6207 lp[1] = tswap32(entry_2);
6208 return 0;
6209}
6210
8fcd3692 6211static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
8d18e893
FB
6212{
6213 struct target_modify_ldt_ldt_s *target_ldt_info;
3e8f1628 6214 uint64_t *gdt_table = g2h_untagged(env->gdt.base);
8d18e893
FB
6215 uint32_t base_addr, limit, flags;
6216 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
6217 int seg_not_present, useable, lm;
6218 uint32_t *lp, entry_1, entry_2;
6219
6220 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
6221 if (!target_ldt_info)
6222 return -TARGET_EFAULT;
6223 idx = tswap32(target_ldt_info->entry_number);
6224 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
6225 idx > TARGET_GDT_ENTRY_TLS_MAX) {
6226 unlock_user_struct(target_ldt_info, ptr, 1);
6227 return -TARGET_EINVAL;
6228 }
6229 lp = (uint32_t *)(gdt_table + idx);
6230 entry_1 = tswap32(lp[0]);
6231 entry_2 = tswap32(lp[1]);
6232
6233 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
6234 contents = (entry_2 >> 10) & 3;
6235 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
6236 seg_32bit = (entry_2 >> 22) & 1;
6237 limit_in_pages = (entry_2 >> 23) & 1;
6238 useable = (entry_2 >> 20) & 1;
6239#ifdef TARGET_ABI32
6240 lm = 0;
6241#else
6242 lm = (entry_2 >> 21) & 1;
6243#endif
6244 flags = (seg_32bit << 0) | (contents << 1) |
6245 (read_exec_only << 3) | (limit_in_pages << 4) |
6246 (seg_not_present << 5) | (useable << 6) | (lm << 7);
6247 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
6248 base_addr = (entry_1 >> 16) |
6249 (entry_2 & 0xff000000) |
6250 ((entry_2 & 0xff) << 16);
cbb21eed 6251 target_ldt_info->base_addr = tswapal(base_addr);
8d18e893
FB
6252 target_ldt_info->limit = tswap32(limit);
6253 target_ldt_info->flags = tswap32(flags);
6254 unlock_user_struct(target_ldt_info, ptr, 1);
6255 return 0;
6256}
6257
9d12f79d
LV
6258abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
6259{
538fabcb 6260 return -TARGET_ENOSYS;
9d12f79d
LV
6261}
6262#else
2667e71c 6263abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
d2fd1af7 6264{
1add8698 6265 abi_long ret = 0;
d2fd1af7
FB
6266 abi_ulong val;
6267 int idx;
1add8698 6268
d2fd1af7
FB
6269 switch(code) {
6270 case TARGET_ARCH_SET_GS:
6271 case TARGET_ARCH_SET_FS:
6272 if (code == TARGET_ARCH_SET_GS)
6273 idx = R_GS;
6274 else
6275 idx = R_FS;
6276 cpu_x86_load_seg(env, idx, 0);
6277 env->segs[idx].base = addr;
6278 break;
6279 case TARGET_ARCH_GET_GS:
6280 case TARGET_ARCH_GET_FS:
6281 if (code == TARGET_ARCH_GET_GS)
6282 idx = R_GS;
6283 else
6284 idx = R_FS;
6285 val = env->segs[idx].base;
6286 if (put_user(val, addr, abi_ulong))
1add8698 6287 ret = -TARGET_EFAULT;
d2fd1af7
FB
6288 break;
6289 default:
6290 ret = -TARGET_EINVAL;
6291 break;
6292 }
1add8698 6293 return ret;
d2fd1af7 6294}
9d12f79d 6295#endif /* defined(TARGET_ABI32 */
d2fd1af7 6296
2ab83ea7
FB
6297#endif /* defined(TARGET_I386) */
6298
05098a93 6299#define NEW_STACK_SIZE 0x40000
d865bab5 6300
d865bab5
PB
6301
6302static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
6303typedef struct {
9349b4f9 6304 CPUArchState *env;
d865bab5
PB
6305 pthread_mutex_t mutex;
6306 pthread_cond_t cond;
6307 pthread_t thread;
6308 uint32_t tid;
6309 abi_ulong child_tidptr;
6310 abi_ulong parent_tidptr;
6311 sigset_t sigmask;
6312} new_thread_info;
6313
6314static void *clone_func(void *arg)
6315{
6316 new_thread_info *info = arg;
9349b4f9 6317 CPUArchState *env;
0d34282f 6318 CPUState *cpu;
edf8e2af 6319 TaskState *ts;
d865bab5 6320
70903763 6321 rcu_register_thread();
3468b59e 6322 tcg_register_thread();
d865bab5 6323 env = info->env;
29a0af61 6324 cpu = env_cpu(env);
a2247f8e 6325 thread_cpu = cpu;
0429a971 6326 ts = (TaskState *)cpu->opaque;
71ba74f6 6327 info->tid = sys_gettid();
edf8e2af 6328 task_settid(ts);
d865bab5
PB
6329 if (info->child_tidptr)
6330 put_user_u32(info->tid, info->child_tidptr);
6331 if (info->parent_tidptr)
6332 put_user_u32(info->tid, info->parent_tidptr);
5ebdd774 6333 qemu_guest_random_seed_thread_part2(cpu->random_seed);
d865bab5
PB
6334 /* Enable signals. */
6335 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
6336 /* Signal to the parent that we're ready. */
6337 pthread_mutex_lock(&info->mutex);
6338 pthread_cond_broadcast(&info->cond);
6339 pthread_mutex_unlock(&info->mutex);
a4dd3d51 6340 /* Wait until the parent has finished initializing the tls state. */
d865bab5
PB
6341 pthread_mutex_lock(&clone_lock);
6342 pthread_mutex_unlock(&clone_lock);
6343 cpu_loop(env);
6344 /* never exits */
6345 return NULL;
6346}
1b6b029e 6347
0da46a6e
TS
6348/* do_fork() Must return host values and target errnos (unlike most
6349 do_*() functions). */
9349b4f9 6350static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
d865bab5
PB
6351 abi_ulong parent_tidptr, target_ulong newtls,
6352 abi_ulong child_tidptr)
1b6b029e 6353{
29a0af61 6354 CPUState *cpu = env_cpu(env);
1b6b029e 6355 int ret;
5cd4393b 6356 TaskState *ts;
0429a971 6357 CPUState *new_cpu;
9349b4f9 6358 CPUArchState *new_env;
d865bab5 6359 sigset_t sigmask;
3b46e624 6360
5ea2fc84
PM
6361 flags &= ~CLONE_IGNORED_FLAGS;
6362
436d124b
AZ
6363 /* Emulate vfork() with fork() */
6364 if (flags & CLONE_VFORK)
6365 flags &= ~(CLONE_VFORK | CLONE_VM);
6366
1b6b029e 6367 if (flags & CLONE_VM) {
0429a971 6368 TaskState *parent_ts = (TaskState *)cpu->opaque;
d865bab5
PB
6369 new_thread_info info;
6370 pthread_attr_t attr;
24cb36a6 6371
5ea2fc84
PM
6372 if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
6373 (flags & CLONE_INVALID_THREAD_FLAGS)) {
6374 return -TARGET_EINVAL;
6375 }
6376
c78d65e8 6377 ts = g_new0(TaskState, 1);
624f7979 6378 init_task_state(ts);
73a988d9
MF
6379
6380 /* Grab a mutex so that thread setup appears atomic. */
6381 pthread_mutex_lock(&clone_lock);
6382
6cc9d67c
RH
6383 /*
6384 * If this is our first additional thread, we need to ensure we
6385 * generate code for parallel execution and flush old translations.
6386 * Do this now so that the copy gets CF_PARALLEL too.
6387 */
6388 if (!(cpu->tcg_cflags & CF_PARALLEL)) {
6389 cpu->tcg_cflags |= CF_PARALLEL;
6390 tb_flush(cpu);
6391 }
6392
1b6b029e 6393 /* we create a new CPU instance. */
c5be9f08 6394 new_env = cpu_copy(env);
6e68e076 6395 /* Init regs that differ from the parent. */
608999d1 6396 cpu_clone_regs_child(new_env, newsp, flags);
07a6ecf4 6397 cpu_clone_regs_parent(env, flags);
29a0af61 6398 new_cpu = env_cpu(new_env);
0429a971 6399 new_cpu->opaque = ts;
edf8e2af
MW
6400 ts->bprm = parent_ts->bprm;
6401 ts->info = parent_ts->info;
3d3efba0 6402 ts->signal_mask = parent_ts->signal_mask;
d865bab5 6403
7cfbd386 6404 if (flags & CLONE_CHILD_CLEARTID) {
c2764719
PB
6405 ts->child_tidptr = child_tidptr;
6406 }
6407
7cfbd386 6408 if (flags & CLONE_SETTLS) {
d865bab5 6409 cpu_set_tls (new_env, newtls);
7cfbd386 6410 }
d865bab5 6411
d865bab5
PB
6412 memset(&info, 0, sizeof(info));
6413 pthread_mutex_init(&info.mutex, NULL);
6414 pthread_mutex_lock(&info.mutex);
6415 pthread_cond_init(&info.cond, NULL);
6416 info.env = new_env;
7cfbd386 6417 if (flags & CLONE_CHILD_SETTID) {
d865bab5 6418 info.child_tidptr = child_tidptr;
7cfbd386
PM
6419 }
6420 if (flags & CLONE_PARENT_SETTID) {
d865bab5 6421 info.parent_tidptr = parent_tidptr;
7cfbd386 6422 }
d865bab5
PB
6423
6424 ret = pthread_attr_init(&attr);
48e15fc2
NF
6425 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
6426 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
d865bab5
PB
6427 /* It is not safe to deliver signals until the child has finished
6428 initializing, so temporarily block all signals. */
6429 sigfillset(&sigmask);
6430 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
5ebdd774 6431 cpu->random_seed = qemu_guest_random_seed_thread_part1();
d865bab5
PB
6432
6433 ret = pthread_create(&info.thread, &attr, clone_func, &info);
c2764719 6434 /* TODO: Free new CPU state if thread creation failed. */
d865bab5
PB
6435
6436 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
6437 pthread_attr_destroy(&attr);
6438 if (ret == 0) {
6439 /* Wait for the child to initialize. */
6440 pthread_cond_wait(&info.cond, &info.mutex);
6441 ret = info.tid;
d865bab5
PB
6442 } else {
6443 ret = -1;
6444 }
6445 pthread_mutex_unlock(&info.mutex);
6446 pthread_cond_destroy(&info.cond);
6447 pthread_mutex_destroy(&info.mutex);
6448 pthread_mutex_unlock(&clone_lock);
1b6b029e
FB
6449 } else {
6450 /* if no CLONE_VM, we consider it is a fork */
5ea2fc84
PM
6451 if (flags & CLONE_INVALID_FORK_FLAGS) {
6452 return -TARGET_EINVAL;
6453 }
6454
6455 /* We can't support custom termination signals */
6456 if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
93b4eff8
TB
6457 return -TARGET_EINVAL;
6458 }
7d92d34e
TB
6459
6460 if (block_signals()) {
af254a27 6461 return -QEMU_ERESTARTSYS;
7d92d34e
TB
6462 }
6463
d865bab5 6464 fork_start();
1b6b029e 6465 ret = fork();
d865bab5 6466 if (ret == 0) {
2b1319c8 6467 /* Child Process. */
608999d1 6468 cpu_clone_regs_child(env, newsp, flags);
d865bab5 6469 fork_end(1);
2b1319c8
AJ
6470 /* There is a race condition here. The parent process could
6471 theoretically read the TID in the child process before the child
6472 tid is set. This would require using either ptrace
6473 (not implemented) or having *_tidptr to point at a shared memory
6474 mapping. We can't repeat the spinlock hack used above because
6475 the child process gets its own copy of the lock. */
d865bab5 6476 if (flags & CLONE_CHILD_SETTID)
71ba74f6 6477 put_user_u32(sys_gettid(), child_tidptr);
d865bab5 6478 if (flags & CLONE_PARENT_SETTID)
71ba74f6 6479 put_user_u32(sys_gettid(), parent_tidptr);
0429a971 6480 ts = (TaskState *)cpu->opaque;
d865bab5
PB
6481 if (flags & CLONE_SETTLS)
6482 cpu_set_tls (env, newtls);
c2764719
PB
6483 if (flags & CLONE_CHILD_CLEARTID)
6484 ts->child_tidptr = child_tidptr;
d865bab5 6485 } else {
07a6ecf4 6486 cpu_clone_regs_parent(env, flags);
d865bab5
PB
6487 fork_end(0);
6488 }
1b6b029e
FB
6489 }
6490 return ret;
6491}
6492
5f106811
APR
6493/* warning : doesn't handle linux specific flags... */
6494static int target_to_host_fcntl_cmd(int cmd)
6495{
4a545761
SB
6496 int ret;
6497
5f106811 6498 switch(cmd) {
4a545761
SB
6499 case TARGET_F_DUPFD:
6500 case TARGET_F_GETFD:
6501 case TARGET_F_SETFD:
6502 case TARGET_F_GETFL:
6503 case TARGET_F_SETFL:
2d92c682
AS
6504 case TARGET_F_OFD_GETLK:
6505 case TARGET_F_OFD_SETLK:
6506 case TARGET_F_OFD_SETLKW:
4a545761
SB
6507 ret = cmd;
6508 break;
6509 case TARGET_F_GETLK:
6510 ret = F_GETLK64;
6511 break;
6512 case TARGET_F_SETLK:
6513 ret = F_SETLK64;
6514 break;
6515 case TARGET_F_SETLKW:
6516 ret = F_SETLKW64;
6517 break;
6518 case TARGET_F_GETOWN:
6519 ret = F_GETOWN;
6520 break;
6521 case TARGET_F_SETOWN:
6522 ret = F_SETOWN;
6523 break;
6524 case TARGET_F_GETSIG:
6525 ret = F_GETSIG;
6526 break;
6527 case TARGET_F_SETSIG:
6528 ret = F_SETSIG;
6529 break;
5f106811 6530#if TARGET_ABI_BITS == 32
4a545761
SB
6531 case TARGET_F_GETLK64:
6532 ret = F_GETLK64;
6533 break;
6534 case TARGET_F_SETLK64:
6535 ret = F_SETLK64;
6536 break;
6537 case TARGET_F_SETLKW64:
6538 ret = F_SETLKW64;
6539 break;
5f106811 6540#endif
4a545761
SB
6541 case TARGET_F_SETLEASE:
6542 ret = F_SETLEASE;
6543 break;
6544 case TARGET_F_GETLEASE:
6545 ret = F_GETLEASE;
6546 break;
fbd5de9b 6547#ifdef F_DUPFD_CLOEXEC
4a545761
SB
6548 case TARGET_F_DUPFD_CLOEXEC:
6549 ret = F_DUPFD_CLOEXEC;
6550 break;
fbd5de9b 6551#endif
4a545761
SB
6552 case TARGET_F_NOTIFY:
6553 ret = F_NOTIFY;
6554 break;
8d5d3004 6555#ifdef F_GETOWN_EX
4a545761
SB
6556 case TARGET_F_GETOWN_EX:
6557 ret = F_GETOWN_EX;
6558 break;
8d5d3004
AS
6559#endif
6560#ifdef F_SETOWN_EX
4a545761
SB
6561 case TARGET_F_SETOWN_EX:
6562 ret = F_SETOWN_EX;
6563 break;
8d5d3004 6564#endif
ddf31aa8 6565#ifdef F_SETPIPE_SZ
4a545761
SB
6566 case TARGET_F_SETPIPE_SZ:
6567 ret = F_SETPIPE_SZ;
6568 break;
6569 case TARGET_F_GETPIPE_SZ:
6570 ret = F_GETPIPE_SZ;
6571 break;
2bb963ff
SCW
6572#endif
6573#ifdef F_ADD_SEALS
6574 case TARGET_F_ADD_SEALS:
6575 ret = F_ADD_SEALS;
6576 break;
6577 case TARGET_F_GET_SEALS:
6578 ret = F_GET_SEALS;
6579 break;
ddf31aa8 6580#endif
4a545761
SB
6581 default:
6582 ret = -TARGET_EINVAL;
6583 break;
6584 }
6585
6586#if defined(__powerpc64__)
6587 /* On PPC64, glibc headers has the F_*LK* defined to 12, 13 and 14 and
6588 * is not supported by kernel. The glibc fcntl call actually adjusts
6589 * them to 5, 6 and 7 before making the syscall(). Since we make the
6590 * syscall directly, adjust to what is supported by the kernel.
6591 */
6592 if (ret >= F_GETLK64 && ret <= F_SETLKW64) {
6593 ret -= F_GETLK64 - 5;
5f106811 6594 }
4a545761
SB
6595#endif
6596
6597 return ret;
5f106811
APR
6598}
6599
ae68ad9f
LV
6600#define FLOCK_TRANSTBL \
6601 switch (type) { \
6602 TRANSTBL_CONVERT(F_RDLCK); \
6603 TRANSTBL_CONVERT(F_WRLCK); \
6604 TRANSTBL_CONVERT(F_UNLCK); \
ae68ad9f
LV
6605 }
6606
6607static int target_to_host_flock(int type)
6608{
6609#define TRANSTBL_CONVERT(a) case TARGET_##a: return a
6610 FLOCK_TRANSTBL
6611#undef TRANSTBL_CONVERT
6612 return -TARGET_EINVAL;
6613}
6614
6615static int host_to_target_flock(int type)
6616{
6617#define TRANSTBL_CONVERT(a) case a: return TARGET_##a
6618 FLOCK_TRANSTBL
6619#undef TRANSTBL_CONVERT
6620 /* if we don't know how to convert the value coming
6621 * from the host we copy to the target field as-is
6622 */
6623 return type;
6624}
2ba7f730 6625
213d3e9e
PM
6626static inline abi_long copy_from_user_flock(struct flock64 *fl,
6627 abi_ulong target_flock_addr)
7775e9ec 6628{
53a5960a 6629 struct target_flock *target_fl;
ae68ad9f 6630 int l_type;
213d3e9e
PM
6631
6632 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6633 return -TARGET_EFAULT;
6634 }
6635
6636 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6637 l_type = target_to_host_flock(l_type);
6638 if (l_type < 0) {
6639 return l_type;
6640 }
6641 fl->l_type = l_type;
213d3e9e
PM
6642 __get_user(fl->l_whence, &target_fl->l_whence);
6643 __get_user(fl->l_start, &target_fl->l_start);
6644 __get_user(fl->l_len, &target_fl->l_len);
6645 __get_user(fl->l_pid, &target_fl->l_pid);
6646 unlock_user_struct(target_fl, target_flock_addr, 0);
6647 return 0;
6648}
6649
6650static inline abi_long copy_to_user_flock(abi_ulong target_flock_addr,
6651 const struct flock64 *fl)
6652{
6653 struct target_flock *target_fl;
6654 short l_type;
6655
6656 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6657 return -TARGET_EFAULT;
6658 }
6659
ae68ad9f 6660 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6661 __put_user(l_type, &target_fl->l_type);
6662 __put_user(fl->l_whence, &target_fl->l_whence);
6663 __put_user(fl->l_start, &target_fl->l_start);
6664 __put_user(fl->l_len, &target_fl->l_len);
6665 __put_user(fl->l_pid, &target_fl->l_pid);
6666 unlock_user_struct(target_fl, target_flock_addr, 1);
6667 return 0;
6668}
6669
6670typedef abi_long from_flock64_fn(struct flock64 *fl, abi_ulong target_addr);
6671typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
6672
6673#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
7f254c5c 6674static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
213d3e9e
PM
6675 abi_ulong target_flock_addr)
6676{
7f254c5c 6677 struct target_oabi_flock64 *target_fl;
ae68ad9f 6678 int l_type;
213d3e9e
PM
6679
6680 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6681 return -TARGET_EFAULT;
6682 }
6683
6684 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6685 l_type = target_to_host_flock(l_type);
6686 if (l_type < 0) {
6687 return l_type;
6688 }
6689 fl->l_type = l_type;
213d3e9e
PM
6690 __get_user(fl->l_whence, &target_fl->l_whence);
6691 __get_user(fl->l_start, &target_fl->l_start);
6692 __get_user(fl->l_len, &target_fl->l_len);
6693 __get_user(fl->l_pid, &target_fl->l_pid);
6694 unlock_user_struct(target_fl, target_flock_addr, 0);
6695 return 0;
6696}
6697
7f254c5c 6698static inline abi_long copy_to_user_oabi_flock64(abi_ulong target_flock_addr,
213d3e9e
PM
6699 const struct flock64 *fl)
6700{
7f254c5c 6701 struct target_oabi_flock64 *target_fl;
213d3e9e
PM
6702 short l_type;
6703
6704 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6705 return -TARGET_EFAULT;
6706 }
6707
ae68ad9f 6708 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6709 __put_user(l_type, &target_fl->l_type);
6710 __put_user(fl->l_whence, &target_fl->l_whence);
6711 __put_user(fl->l_start, &target_fl->l_start);
6712 __put_user(fl->l_len, &target_fl->l_len);
6713 __put_user(fl->l_pid, &target_fl->l_pid);
6714 unlock_user_struct(target_fl, target_flock_addr, 1);
6715 return 0;
6716}
6717#endif
6718
6719static inline abi_long copy_from_user_flock64(struct flock64 *fl,
6720 abi_ulong target_flock_addr)
6721{
6722 struct target_flock64 *target_fl;
ae68ad9f 6723 int l_type;
213d3e9e
PM
6724
6725 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6726 return -TARGET_EFAULT;
6727 }
6728
6729 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6730 l_type = target_to_host_flock(l_type);
6731 if (l_type < 0) {
6732 return l_type;
6733 }
6734 fl->l_type = l_type;
213d3e9e
PM
6735 __get_user(fl->l_whence, &target_fl->l_whence);
6736 __get_user(fl->l_start, &target_fl->l_start);
6737 __get_user(fl->l_len, &target_fl->l_len);
6738 __get_user(fl->l_pid, &target_fl->l_pid);
6739 unlock_user_struct(target_fl, target_flock_addr, 0);
6740 return 0;
6741}
6742
6743static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr,
6744 const struct flock64 *fl)
6745{
6746 struct target_flock64 *target_fl;
6747 short l_type;
6748
6749 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6750 return -TARGET_EFAULT;
6751 }
6752
ae68ad9f 6753 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6754 __put_user(l_type, &target_fl->l_type);
6755 __put_user(fl->l_whence, &target_fl->l_whence);
6756 __put_user(fl->l_start, &target_fl->l_start);
6757 __put_user(fl->l_len, &target_fl->l_len);
6758 __put_user(fl->l_pid, &target_fl->l_pid);
6759 unlock_user_struct(target_fl, target_flock_addr, 1);
6760 return 0;
6761}
6762
6763static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
6764{
43f238d7 6765 struct flock64 fl64;
8d5d3004
AS
6766#ifdef F_GETOWN_EX
6767 struct f_owner_ex fox;
6768 struct target_f_owner_ex *target_fox;
6769#endif
992f48a0 6770 abi_long ret;
5f106811
APR
6771 int host_cmd = target_to_host_fcntl_cmd(cmd);
6772
6773 if (host_cmd == -TARGET_EINVAL)
6774 return host_cmd;
53a5960a 6775
7775e9ec
FB
6776 switch(cmd) {
6777 case TARGET_F_GETLK:
213d3e9e
PM
6778 ret = copy_from_user_flock(&fl64, arg);
6779 if (ret) {
6780 return ret;
6781 }
435da5e7 6782 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec 6783 if (ret == 0) {
213d3e9e 6784 ret = copy_to_user_flock(arg, &fl64);
7775e9ec
FB
6785 }
6786 break;
3b46e624 6787
7775e9ec
FB
6788 case TARGET_F_SETLK:
6789 case TARGET_F_SETLKW:
213d3e9e
PM
6790 ret = copy_from_user_flock(&fl64, arg);
6791 if (ret) {
6792 return ret;
6793 }
435da5e7 6794 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec 6795 break;
3b46e624 6796
7775e9ec 6797 case TARGET_F_GETLK64:
2d92c682 6798 case TARGET_F_OFD_GETLK:
213d3e9e
PM
6799 ret = copy_from_user_flock64(&fl64, arg);
6800 if (ret) {
6801 return ret;
6802 }
435da5e7 6803 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
43f238d7 6804 if (ret == 0) {
213d3e9e 6805 ret = copy_to_user_flock64(arg, &fl64);
43f238d7 6806 }
9ee1fa2c 6807 break;
7775e9ec
FB
6808 case TARGET_F_SETLK64:
6809 case TARGET_F_SETLKW64:
2d92c682
AS
6810 case TARGET_F_OFD_SETLK:
6811 case TARGET_F_OFD_SETLKW:
213d3e9e
PM
6812 ret = copy_from_user_flock64(&fl64, arg);
6813 if (ret) {
6814 return ret;
6815 }
435da5e7 6816 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec
FB
6817 break;
6818
5f106811 6819 case TARGET_F_GETFL:
435da5e7 6820 ret = get_errno(safe_fcntl(fd, host_cmd, arg));
9ee1fa2c
FB
6821 if (ret >= 0) {
6822 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
6823 }
ffa65c3b
FB
6824 break;
6825
5f106811 6826 case TARGET_F_SETFL:
435da5e7
PM
6827 ret = get_errno(safe_fcntl(fd, host_cmd,
6828 target_to_host_bitmask(arg,
6829 fcntl_flags_tbl)));
5f106811
APR
6830 break;
6831
8d5d3004
AS
6832#ifdef F_GETOWN_EX
6833 case TARGET_F_GETOWN_EX:
435da5e7 6834 ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
8d5d3004
AS
6835 if (ret >= 0) {
6836 if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
6837 return -TARGET_EFAULT;
6838 target_fox->type = tswap32(fox.type);
6839 target_fox->pid = tswap32(fox.pid);
6840 unlock_user_struct(target_fox, arg, 1);
6841 }
6842 break;
6843#endif
6844
6845#ifdef F_SETOWN_EX
6846 case TARGET_F_SETOWN_EX:
6847 if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1))
6848 return -TARGET_EFAULT;
6849 fox.type = tswap32(target_fox->type);
6850 fox.pid = tswap32(target_fox->pid);
6851 unlock_user_struct(target_fox, arg, 0);
435da5e7 6852 ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
8d5d3004
AS
6853 break;
6854#endif
6855
5f106811 6856 case TARGET_F_SETSIG:
a7b4c9b1
TB
6857 ret = get_errno(safe_fcntl(fd, host_cmd, target_to_host_signal(arg)));
6858 break;
6859
5f106811 6860 case TARGET_F_GETSIG:
a7b4c9b1
TB
6861 ret = host_to_target_signal(get_errno(safe_fcntl(fd, host_cmd, arg)));
6862 break;
6863
6864 case TARGET_F_SETOWN:
6865 case TARGET_F_GETOWN:
7e22e546
UH
6866 case TARGET_F_SETLEASE:
6867 case TARGET_F_GETLEASE:
7e3b92ec
PM
6868 case TARGET_F_SETPIPE_SZ:
6869 case TARGET_F_GETPIPE_SZ:
2bb963ff
SCW
6870 case TARGET_F_ADD_SEALS:
6871 case TARGET_F_GET_SEALS:
435da5e7 6872 ret = get_errno(safe_fcntl(fd, host_cmd, arg));
ffa65c3b
FB
6873 break;
6874
7775e9ec 6875 default:
435da5e7 6876 ret = get_errno(safe_fcntl(fd, cmd, arg));
7775e9ec
FB
6877 break;
6878 }
6879 return ret;
6880}
6881
67867308 6882#ifdef USE_UID16
7775e9ec 6883
67867308
FB
6884static inline int high2lowuid(int uid)
6885{
6886 if (uid > 65535)
6887 return 65534;
6888 else
6889 return uid;
6890}
6891
6892static inline int high2lowgid(int gid)
6893{
6894 if (gid > 65535)
6895 return 65534;
6896 else
6897 return gid;
6898}
6899
6900static inline int low2highuid(int uid)
6901{
6902 if ((int16_t)uid == -1)
6903 return -1;
6904 else
6905 return uid;
6906}
6907
6908static inline int low2highgid(int gid)
6909{
6910 if ((int16_t)gid == -1)
6911 return -1;
6912 else
6913 return gid;
6914}
0c866a7e
RV
6915static inline int tswapid(int id)
6916{
6917 return tswap16(id);
6918}
76ca310a
PM
6919
6920#define put_user_id(x, gaddr) put_user_u16(x, gaddr)
6921
0c866a7e
RV
6922#else /* !USE_UID16 */
6923static inline int high2lowuid(int uid)
6924{
6925 return uid;
6926}
6927static inline int high2lowgid(int gid)
6928{
6929 return gid;
6930}
6931static inline int low2highuid(int uid)
6932{
6933 return uid;
6934}
6935static inline int low2highgid(int gid)
6936{
6937 return gid;
6938}
6939static inline int tswapid(int id)
6940{
6941 return tswap32(id);
6942}
76ca310a
PM
6943
6944#define put_user_id(x, gaddr) put_user_u32(x, gaddr)
6945
67867308 6946#endif /* USE_UID16 */
1b6b029e 6947
fd6f7798
PM
6948/* We must do direct syscalls for setting UID/GID, because we want to
6949 * implement the Linux system call semantics of "change only for this thread",
6950 * not the libc/POSIX semantics of "change for all threads in process".
6951 * (See http://ewontfix.com/17/ for more details.)
6952 * We use the 32-bit version of the syscalls if present; if it is not
6953 * then either the host architecture supports 32-bit UIDs natively with
6954 * the standard syscall, or the 16-bit UID is the best we can do.
6955 */
6956#ifdef __NR_setuid32
6957#define __NR_sys_setuid __NR_setuid32
6958#else
6959#define __NR_sys_setuid __NR_setuid
6960#endif
6961#ifdef __NR_setgid32
6962#define __NR_sys_setgid __NR_setgid32
6963#else
6964#define __NR_sys_setgid __NR_setgid
6965#endif
6966#ifdef __NR_setresuid32
6967#define __NR_sys_setresuid __NR_setresuid32
6968#else
6969#define __NR_sys_setresuid __NR_setresuid
6970#endif
6971#ifdef __NR_setresgid32
6972#define __NR_sys_setresgid __NR_setresgid32
6973#else
6974#define __NR_sys_setresgid __NR_setresgid
6975#endif
6976
6977_syscall1(int, sys_setuid, uid_t, uid)
6978_syscall1(int, sys_setgid, gid_t, gid)
6979_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
6980_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
6981
31e31b8a
FB
6982void syscall_init(void)
6983{
2ab83ea7
FB
6984 IOCTLEntry *ie;
6985 const argtype *arg_type;
6986 int size;
6987
8be656b8
AG
6988 thunk_init(STRUCT_MAX);
6989
001faf32 6990#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
5fafdf24 6991#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
31e31b8a
FB
6992#include "syscall_types.h"
6993#undef STRUCT
6994#undef STRUCT_SPECIAL
2ab83ea7
FB
6995
6996 /* we patch the ioctl size if necessary. We rely on the fact that
6997 no ioctl has all the bits at '1' in the size field */
6998 ie = ioctl_entries;
6999 while (ie->target_cmd != 0) {
7000 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
7001 TARGET_IOC_SIZEMASK) {
7002 arg_type = ie->arg_type;
7003 if (arg_type[0] != TYPE_PTR) {
5fafdf24 7004 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
2ab83ea7
FB
7005 ie->target_cmd);
7006 exit(1);
7007 }
7008 arg_type++;
7009 size = thunk_type_size(arg_type, 0);
5fafdf24 7010 ie->target_cmd = (ie->target_cmd &
2ab83ea7
FB
7011 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
7012 (size << TARGET_IOC_SIZESHIFT);
7013 }
b92c47c1 7014
2ab83ea7 7015 /* automatic consistency check if same arch */
872ea0c0
AZ
7016#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
7017 (defined(__x86_64__) && defined(TARGET_X86_64))
7018 if (unlikely(ie->target_cmd != ie->host_cmd)) {
7019 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
7020 ie->name, ie->target_cmd, ie->host_cmd);
2ab83ea7
FB
7021 }
7022#endif
7023 ie++;
7024 }
31e31b8a 7025}
c573ff67 7026
ce4defa0 7027#ifdef TARGET_NR_truncate64
992f48a0
BS
7028static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
7029 abi_long arg2,
7030 abi_long arg3,
7031 abi_long arg4)
ce4defa0 7032{
8bf8e9df 7033 if (regpairs_aligned(cpu_env, TARGET_NR_truncate64)) {
ce4defa0
PB
7034 arg2 = arg3;
7035 arg3 = arg4;
48e515d4 7036 }
ce4defa0
PB
7037 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
7038}
7039#endif
7040
7041#ifdef TARGET_NR_ftruncate64
992f48a0
BS
7042static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
7043 abi_long arg2,
7044 abi_long arg3,
7045 abi_long arg4)
ce4defa0 7046{
8bf8e9df 7047 if (regpairs_aligned(cpu_env, TARGET_NR_ftruncate64)) {
ce4defa0
PB
7048 arg2 = arg3;
7049 arg3 = arg4;
48e515d4 7050 }
ce4defa0
PB
7051 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
7052}
7053#endif
7054
859e8a89
AF
7055#if defined(TARGET_NR_timer_settime) || \
7056 (defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD))
2c86c90f 7057static inline abi_long target_to_host_itimerspec(struct itimerspec *host_its,
f4f1e10a
ECL
7058 abi_ulong target_addr)
7059{
2c86c90f
FB
7060 if (target_to_host_timespec(&host_its->it_interval, target_addr +
7061 offsetof(struct target_itimerspec,
7062 it_interval)) ||
7063 target_to_host_timespec(&host_its->it_value, target_addr +
7064 offsetof(struct target_itimerspec,
7065 it_value))) {
f4f1e10a
ECL
7066 return -TARGET_EFAULT;
7067 }
7068
f4f1e10a
ECL
7069 return 0;
7070}
859e8a89 7071#endif
f4f1e10a 7072
828cb3a1
FB
7073#if defined(TARGET_NR_timer_settime64) || \
7074 (defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD))
7075static inline abi_long target_to_host_itimerspec64(struct itimerspec *host_its,
7076 abi_ulong target_addr)
7077{
7078 if (target_to_host_timespec64(&host_its->it_interval, target_addr +
7079 offsetof(struct target__kernel_itimerspec,
7080 it_interval)) ||
7081 target_to_host_timespec64(&host_its->it_value, target_addr +
7082 offsetof(struct target__kernel_itimerspec,
7083 it_value))) {
7084 return -TARGET_EFAULT;
7085 }
7086
7087 return 0;
7088}
7089#endif
7090
859e8a89
AF
7091#if ((defined(TARGET_NR_timerfd_gettime) || \
7092 defined(TARGET_NR_timerfd_settime)) && defined(CONFIG_TIMERFD)) || \
2c86c90f 7093 defined(TARGET_NR_timer_gettime) || defined(TARGET_NR_timer_settime)
f4f1e10a 7094static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
2c86c90f
FB
7095 struct itimerspec *host_its)
7096{
7097 if (host_to_target_timespec(target_addr + offsetof(struct target_itimerspec,
7098 it_interval),
7099 &host_its->it_interval) ||
7100 host_to_target_timespec(target_addr + offsetof(struct target_itimerspec,
7101 it_value),
7102 &host_its->it_value)) {
f4f1e10a
ECL
7103 return -TARGET_EFAULT;
7104 }
f4f1e10a
ECL
7105 return 0;
7106}
859e8a89 7107#endif
f4f1e10a 7108
828cb3a1
FB
7109#if ((defined(TARGET_NR_timerfd_gettime64) || \
7110 defined(TARGET_NR_timerfd_settime64)) && defined(CONFIG_TIMERFD)) || \
7111 defined(TARGET_NR_timer_gettime64) || defined(TARGET_NR_timer_settime64)
7112static inline abi_long host_to_target_itimerspec64(abi_ulong target_addr,
7113 struct itimerspec *host_its)
7114{
7115 if (host_to_target_timespec64(target_addr +
7116 offsetof(struct target__kernel_itimerspec,
7117 it_interval),
7118 &host_its->it_interval) ||
7119 host_to_target_timespec64(target_addr +
7120 offsetof(struct target__kernel_itimerspec,
7121 it_value),
7122 &host_its->it_value)) {
7123 return -TARGET_EFAULT;
7124 }
7125 return 0;
7126}
7127#endif
7128
859e8a89
AF
7129#if defined(TARGET_NR_adjtimex) || \
7130 (defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME))
19f59bce
AM
7131static inline abi_long target_to_host_timex(struct timex *host_tx,
7132 abi_long target_addr)
7133{
7134 struct target_timex *target_tx;
7135
7136 if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
7137 return -TARGET_EFAULT;
7138 }
7139
7140 __get_user(host_tx->modes, &target_tx->modes);
7141 __get_user(host_tx->offset, &target_tx->offset);
7142 __get_user(host_tx->freq, &target_tx->freq);
7143 __get_user(host_tx->maxerror, &target_tx->maxerror);
7144 __get_user(host_tx->esterror, &target_tx->esterror);
7145 __get_user(host_tx->status, &target_tx->status);
7146 __get_user(host_tx->constant, &target_tx->constant);
7147 __get_user(host_tx->precision, &target_tx->precision);
7148 __get_user(host_tx->tolerance, &target_tx->tolerance);
7149 __get_user(host_tx->time.tv_sec, &target_tx->time.tv_sec);
7150 __get_user(host_tx->time.tv_usec, &target_tx->time.tv_usec);
7151 __get_user(host_tx->tick, &target_tx->tick);
7152 __get_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7153 __get_user(host_tx->jitter, &target_tx->jitter);
7154 __get_user(host_tx->shift, &target_tx->shift);
7155 __get_user(host_tx->stabil, &target_tx->stabil);
7156 __get_user(host_tx->jitcnt, &target_tx->jitcnt);
7157 __get_user(host_tx->calcnt, &target_tx->calcnt);
7158 __get_user(host_tx->errcnt, &target_tx->errcnt);
7159 __get_user(host_tx->stbcnt, &target_tx->stbcnt);
7160 __get_user(host_tx->tai, &target_tx->tai);
7161
7162 unlock_user_struct(target_tx, target_addr, 0);
7163 return 0;
7164}
7165
7166static inline abi_long host_to_target_timex(abi_long target_addr,
7167 struct timex *host_tx)
7168{
7169 struct target_timex *target_tx;
7170
7171 if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) {
7172 return -TARGET_EFAULT;
7173 }
7174
7175 __put_user(host_tx->modes, &target_tx->modes);
7176 __put_user(host_tx->offset, &target_tx->offset);
7177 __put_user(host_tx->freq, &target_tx->freq);
7178 __put_user(host_tx->maxerror, &target_tx->maxerror);
7179 __put_user(host_tx->esterror, &target_tx->esterror);
7180 __put_user(host_tx->status, &target_tx->status);
7181 __put_user(host_tx->constant, &target_tx->constant);
7182 __put_user(host_tx->precision, &target_tx->precision);
7183 __put_user(host_tx->tolerance, &target_tx->tolerance);
7184 __put_user(host_tx->time.tv_sec, &target_tx->time.tv_sec);
7185 __put_user(host_tx->time.tv_usec, &target_tx->time.tv_usec);
7186 __put_user(host_tx->tick, &target_tx->tick);
7187 __put_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7188 __put_user(host_tx->jitter, &target_tx->jitter);
7189 __put_user(host_tx->shift, &target_tx->shift);
7190 __put_user(host_tx->stabil, &target_tx->stabil);
7191 __put_user(host_tx->jitcnt, &target_tx->jitcnt);
7192 __put_user(host_tx->calcnt, &target_tx->calcnt);
7193 __put_user(host_tx->errcnt, &target_tx->errcnt);
7194 __put_user(host_tx->stbcnt, &target_tx->stbcnt);
7195 __put_user(host_tx->tai, &target_tx->tai);
7196
7197 unlock_user_struct(target_tx, target_addr, 1);
7198 return 0;
7199}
859e8a89 7200#endif
19f59bce 7201
6ac03b2c
FB
7202
7203#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
7204static inline abi_long target_to_host_timex64(struct timex *host_tx,
7205 abi_long target_addr)
7206{
7207 struct target__kernel_timex *target_tx;
7208
7209 if (copy_from_user_timeval64(&host_tx->time, target_addr +
7210 offsetof(struct target__kernel_timex,
7211 time))) {
7212 return -TARGET_EFAULT;
7213 }
7214
7215 if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
7216 return -TARGET_EFAULT;
7217 }
7218
7219 __get_user(host_tx->modes, &target_tx->modes);
7220 __get_user(host_tx->offset, &target_tx->offset);
7221 __get_user(host_tx->freq, &target_tx->freq);
7222 __get_user(host_tx->maxerror, &target_tx->maxerror);
7223 __get_user(host_tx->esterror, &target_tx->esterror);
7224 __get_user(host_tx->status, &target_tx->status);
7225 __get_user(host_tx->constant, &target_tx->constant);
7226 __get_user(host_tx->precision, &target_tx->precision);
7227 __get_user(host_tx->tolerance, &target_tx->tolerance);
7228 __get_user(host_tx->tick, &target_tx->tick);
7229 __get_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7230 __get_user(host_tx->jitter, &target_tx->jitter);
7231 __get_user(host_tx->shift, &target_tx->shift);
7232 __get_user(host_tx->stabil, &target_tx->stabil);
7233 __get_user(host_tx->jitcnt, &target_tx->jitcnt);
7234 __get_user(host_tx->calcnt, &target_tx->calcnt);
7235 __get_user(host_tx->errcnt, &target_tx->errcnt);
7236 __get_user(host_tx->stbcnt, &target_tx->stbcnt);
7237 __get_user(host_tx->tai, &target_tx->tai);
7238
7239 unlock_user_struct(target_tx, target_addr, 0);
7240 return 0;
7241}
7242
7243static inline abi_long host_to_target_timex64(abi_long target_addr,
7244 struct timex *host_tx)
7245{
7246 struct target__kernel_timex *target_tx;
7247
7248 if (copy_to_user_timeval64(target_addr +
7249 offsetof(struct target__kernel_timex, time),
7250 &host_tx->time)) {
7251 return -TARGET_EFAULT;
7252 }
7253
7254 if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) {
7255 return -TARGET_EFAULT;
7256 }
7257
7258 __put_user(host_tx->modes, &target_tx->modes);
7259 __put_user(host_tx->offset, &target_tx->offset);
7260 __put_user(host_tx->freq, &target_tx->freq);
7261 __put_user(host_tx->maxerror, &target_tx->maxerror);
7262 __put_user(host_tx->esterror, &target_tx->esterror);
7263 __put_user(host_tx->status, &target_tx->status);
7264 __put_user(host_tx->constant, &target_tx->constant);
7265 __put_user(host_tx->precision, &target_tx->precision);
7266 __put_user(host_tx->tolerance, &target_tx->tolerance);
7267 __put_user(host_tx->tick, &target_tx->tick);
7268 __put_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7269 __put_user(host_tx->jitter, &target_tx->jitter);
7270 __put_user(host_tx->shift, &target_tx->shift);
7271 __put_user(host_tx->stabil, &target_tx->stabil);
7272 __put_user(host_tx->jitcnt, &target_tx->jitcnt);
7273 __put_user(host_tx->calcnt, &target_tx->calcnt);
7274 __put_user(host_tx->errcnt, &target_tx->errcnt);
7275 __put_user(host_tx->stbcnt, &target_tx->stbcnt);
7276 __put_user(host_tx->tai, &target_tx->tai);
7277
7278 unlock_user_struct(target_tx, target_addr, 1);
7279 return 0;
7280}
7281#endif
7282
96ff758c
MF
7283#ifndef HAVE_SIGEV_NOTIFY_THREAD_ID
7284#define sigev_notify_thread_id _sigev_un._tid
7285#endif
7286
c065976f
PM
7287static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
7288 abi_ulong target_addr)
7289{
7290 struct target_sigevent *target_sevp;
7291
7292 if (!lock_user_struct(VERIFY_READ, target_sevp, target_addr, 1)) {
7293 return -TARGET_EFAULT;
7294 }
7295
7296 /* This union is awkward on 64 bit systems because it has a 32 bit
7297 * integer and a pointer in it; we follow the conversion approach
7298 * used for handling sigval types in signal.c so the guest should get
7299 * the correct value back even if we did a 64 bit byteswap and it's
7300 * using the 32 bit integer.
7301 */
7302 host_sevp->sigev_value.sival_ptr =
7303 (void *)(uintptr_t)tswapal(target_sevp->sigev_value.sival_ptr);
7304 host_sevp->sigev_signo =
7305 target_to_host_signal(tswap32(target_sevp->sigev_signo));
7306 host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
96ff758c 7307 host_sevp->sigev_notify_thread_id = tswap32(target_sevp->_sigev_un._tid);
c065976f
PM
7308
7309 unlock_user_struct(target_sevp, target_addr, 1);
7310 return 0;
7311}
7312
6f6a4032
TM
7313#if defined(TARGET_NR_mlockall)
7314static inline int target_to_host_mlockall_arg(int arg)
7315{
7316 int result = 0;
7317
02e5d7d7 7318 if (arg & TARGET_MCL_CURRENT) {
6f6a4032
TM
7319 result |= MCL_CURRENT;
7320 }
02e5d7d7 7321 if (arg & TARGET_MCL_FUTURE) {
6f6a4032
TM
7322 result |= MCL_FUTURE;
7323 }
02e5d7d7
FB
7324#ifdef MCL_ONFAULT
7325 if (arg & TARGET_MCL_ONFAULT) {
7326 result |= MCL_ONFAULT;
7327 }
7328#endif
7329
6f6a4032
TM
7330 return result;
7331}
7332#endif
7333
4f7f8924
AR
7334#if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) || \
7335 defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) || \
7336 defined(TARGET_NR_newfstatat))
6a24a778
AZ
7337static inline abi_long host_to_target_stat64(void *cpu_env,
7338 abi_ulong target_addr,
7339 struct stat *host_st)
7340{
09701199 7341#if defined(TARGET_ARM) && defined(TARGET_ABI32)
6a24a778
AZ
7342 if (((CPUARMState *)cpu_env)->eabi) {
7343 struct target_eabi_stat64 *target_st;
7344
7345 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
7346 return -TARGET_EFAULT;
7347 memset(target_st, 0, sizeof(struct target_eabi_stat64));
7348 __put_user(host_st->st_dev, &target_st->st_dev);
7349 __put_user(host_st->st_ino, &target_st->st_ino);
7350#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
7351 __put_user(host_st->st_ino, &target_st->__st_ino);
7352#endif
7353 __put_user(host_st->st_mode, &target_st->st_mode);
7354 __put_user(host_st->st_nlink, &target_st->st_nlink);
7355 __put_user(host_st->st_uid, &target_st->st_uid);
7356 __put_user(host_st->st_gid, &target_st->st_gid);
7357 __put_user(host_st->st_rdev, &target_st->st_rdev);
7358 __put_user(host_st->st_size, &target_st->st_size);
7359 __put_user(host_st->st_blksize, &target_st->st_blksize);
7360 __put_user(host_st->st_blocks, &target_st->st_blocks);
7361 __put_user(host_st->st_atime, &target_st->target_st_atime);
7362 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
7363 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
febf6fad 7364#ifdef HAVE_STRUCT_STAT_ST_ATIM
5f992db6
CYT
7365 __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
7366 __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
7367 __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
7368#endif
6a24a778
AZ
7369 unlock_user_struct(target_st, target_addr, 1);
7370 } else
7371#endif
7372 {
20d155bc 7373#if defined(TARGET_HAS_STRUCT_STAT64)
6a24a778 7374 struct target_stat64 *target_st;
20d155bc
SW
7375#else
7376 struct target_stat *target_st;
9d33b76b 7377#endif
6a24a778
AZ
7378
7379 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
7380 return -TARGET_EFAULT;
9d33b76b 7381 memset(target_st, 0, sizeof(*target_st));
6a24a778
AZ
7382 __put_user(host_st->st_dev, &target_st->st_dev);
7383 __put_user(host_st->st_ino, &target_st->st_ino);
7384#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
7385 __put_user(host_st->st_ino, &target_st->__st_ino);
7386#endif
7387 __put_user(host_st->st_mode, &target_st->st_mode);
7388 __put_user(host_st->st_nlink, &target_st->st_nlink);
7389 __put_user(host_st->st_uid, &target_st->st_uid);
7390 __put_user(host_st->st_gid, &target_st->st_gid);
7391 __put_user(host_st->st_rdev, &target_st->st_rdev);
7392 /* XXX: better use of kernel struct */
7393 __put_user(host_st->st_size, &target_st->st_size);
7394 __put_user(host_st->st_blksize, &target_st->st_blksize);
7395 __put_user(host_st->st_blocks, &target_st->st_blocks);
7396 __put_user(host_st->st_atime, &target_st->target_st_atime);
7397 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
7398 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
febf6fad 7399#ifdef HAVE_STRUCT_STAT_ST_ATIM
5f992db6
CYT
7400 __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
7401 __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
7402 __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
7403#endif
6a24a778
AZ
7404 unlock_user_struct(target_st, target_addr, 1);
7405 }
7406
7407 return 0;
7408}
4f7f8924 7409#endif
6a24a778 7410
efa92184
AR
7411#if defined(TARGET_NR_statx) && defined(__NR_statx)
7412static inline abi_long host_to_target_statx(struct target_statx *host_stx,
7413 abi_ulong target_addr)
7414{
7415 struct target_statx *target_stx;
7416
7417 if (!lock_user_struct(VERIFY_WRITE, target_stx, target_addr, 0)) {
7418 return -TARGET_EFAULT;
7419 }
7420 memset(target_stx, 0, sizeof(*target_stx));
7421
7422 __put_user(host_stx->stx_mask, &target_stx->stx_mask);
7423 __put_user(host_stx->stx_blksize, &target_stx->stx_blksize);
7424 __put_user(host_stx->stx_attributes, &target_stx->stx_attributes);
7425 __put_user(host_stx->stx_nlink, &target_stx->stx_nlink);
7426 __put_user(host_stx->stx_uid, &target_stx->stx_uid);
7427 __put_user(host_stx->stx_gid, &target_stx->stx_gid);
7428 __put_user(host_stx->stx_mode, &target_stx->stx_mode);
7429 __put_user(host_stx->stx_ino, &target_stx->stx_ino);
7430 __put_user(host_stx->stx_size, &target_stx->stx_size);
7431 __put_user(host_stx->stx_blocks, &target_stx->stx_blocks);
7432 __put_user(host_stx->stx_attributes_mask, &target_stx->stx_attributes_mask);
7433 __put_user(host_stx->stx_atime.tv_sec, &target_stx->stx_atime.tv_sec);
7434 __put_user(host_stx->stx_atime.tv_nsec, &target_stx->stx_atime.tv_nsec);
d1e26707
AC
7435 __put_user(host_stx->stx_btime.tv_sec, &target_stx->stx_btime.tv_sec);
7436 __put_user(host_stx->stx_btime.tv_nsec, &target_stx->stx_btime.tv_nsec);
7437 __put_user(host_stx->stx_ctime.tv_sec, &target_stx->stx_ctime.tv_sec);
7438 __put_user(host_stx->stx_ctime.tv_nsec, &target_stx->stx_ctime.tv_nsec);
7439 __put_user(host_stx->stx_mtime.tv_sec, &target_stx->stx_mtime.tv_sec);
7440 __put_user(host_stx->stx_mtime.tv_nsec, &target_stx->stx_mtime.tv_nsec);
efa92184
AR
7441 __put_user(host_stx->stx_rdev_major, &target_stx->stx_rdev_major);
7442 __put_user(host_stx->stx_rdev_minor, &target_stx->stx_rdev_minor);
7443 __put_user(host_stx->stx_dev_major, &target_stx->stx_dev_major);
7444 __put_user(host_stx->stx_dev_minor, &target_stx->stx_dev_minor);
7445
7446 unlock_user_struct(target_stx, target_addr, 1);
7447
7448 return 0;
7449}
7450#endif
7451
14690296
AF
7452static int do_sys_futex(int *uaddr, int op, int val,
7453 const struct timespec *timeout, int *uaddr2,
7454 int val3)
7455{
7456#if HOST_LONG_BITS == 64
7457#if defined(__NR_futex)
7458 /* always a 64-bit time_t, it doesn't define _time64 version */
7459 return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
7460
7461#endif
7462#else /* HOST_LONG_BITS == 64 */
7463#if defined(__NR_futex_time64)
7464 if (sizeof(timeout->tv_sec) == 8) {
7465 /* _time64 function on 32bit arch */
7466 return sys_futex_time64(uaddr, op, val, timeout, uaddr2, val3);
7467 }
7468#endif
7469#if defined(__NR_futex)
7470 /* old function on 32bit arch */
7471 return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
7472#endif
7473#endif /* HOST_LONG_BITS == 64 */
7474 g_assert_not_reached();
7475}
7476
7477static int do_safe_futex(int *uaddr, int op, int val,
7478 const struct timespec *timeout, int *uaddr2,
7479 int val3)
7480{
7481#if HOST_LONG_BITS == 64
7482#if defined(__NR_futex)
7483 /* always a 64-bit time_t, it doesn't define _time64 version */
7484 return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
7485#endif
7486#else /* HOST_LONG_BITS == 64 */
7487#if defined(__NR_futex_time64)
7488 if (sizeof(timeout->tv_sec) == 8) {
7489 /* _time64 function on 32bit arch */
7490 return get_errno(safe_futex_time64(uaddr, op, val, timeout, uaddr2,
7491 val3));
7492 }
7493#endif
7494#if defined(__NR_futex)
7495 /* old function on 32bit arch */
7496 return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
7497#endif
7498#endif /* HOST_LONG_BITS == 64 */
7499 return -TARGET_ENOSYS;
7500}
efa92184 7501
bd0c5661
PB
7502/* ??? Using host futex calls even when target atomic operations
7503 are not really atomic probably breaks things. However implementing
7504 futexes locally would make futexes shared between multiple processes
7505 tricky. However they're probably useless because guest atomic
7506 operations won't work either. */
859e8a89 7507#if defined(TARGET_NR_futex)
3e8f1628
RH
7508static int do_futex(CPUState *cpu, target_ulong uaddr, int op, int val,
7509 target_ulong timeout, target_ulong uaddr2, int val3)
bd0c5661
PB
7510{
7511 struct timespec ts, *pts;
a16aae0c 7512 int base_op;
bd0c5661
PB
7513
7514 /* ??? We assume FUTEX_* constants are the same on both host
7515 and target. */
a29ccd63 7516#ifdef FUTEX_CMD_MASK
a16aae0c 7517 base_op = op & FUTEX_CMD_MASK;
a29ccd63 7518#else
a16aae0c 7519 base_op = op;
a29ccd63 7520#endif
a16aae0c 7521 switch (base_op) {
bd0c5661 7522 case FUTEX_WAIT:
cce246e0 7523 case FUTEX_WAIT_BITSET:
bd0c5661
PB
7524 if (timeout) {
7525 pts = &ts;
7526 target_to_host_timespec(pts, timeout);
7527 } else {
7528 pts = NULL;
7529 }
3e8f1628
RH
7530 return do_safe_futex(g2h(cpu, uaddr),
7531 op, tswap32(val), pts, NULL, val3);
bd0c5661 7532 case FUTEX_WAKE:
3e8f1628
RH
7533 return do_safe_futex(g2h(cpu, uaddr),
7534 op, val, NULL, NULL, 0);
bd0c5661 7535 case FUTEX_FD:
3e8f1628
RH
7536 return do_safe_futex(g2h(cpu, uaddr),
7537 op, val, NULL, NULL, 0);
bd0c5661 7538 case FUTEX_REQUEUE:
bd0c5661 7539 case FUTEX_CMP_REQUEUE:
a16aae0c
NF
7540 case FUTEX_WAKE_OP:
7541 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
7542 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
7543 But the prototype takes a `struct timespec *'; insert casts
7544 to satisfy the compiler. We do not need to tswap TIMEOUT
7545 since it's not compared to guest memory. */
7546 pts = (struct timespec *)(uintptr_t) timeout;
3e8f1628 7547 return do_safe_futex(g2h(cpu, uaddr), op, val, pts, g2h(cpu, uaddr2),
14690296 7548 (base_op == FUTEX_CMP_REQUEUE
3e8f1628 7549 ? tswap32(val3) : val3));
bd0c5661
PB
7550 default:
7551 return -TARGET_ENOSYS;
7552 }
7553}
859e8a89 7554#endif
14690296
AF
7555
7556#if defined(TARGET_NR_futex_time64)
3e8f1628
RH
7557static int do_futex_time64(CPUState *cpu, target_ulong uaddr, int op,
7558 int val, target_ulong timeout,
14690296
AF
7559 target_ulong uaddr2, int val3)
7560{
7561 struct timespec ts, *pts;
7562 int base_op;
7563
7564 /* ??? We assume FUTEX_* constants are the same on both host
7565 and target. */
7566#ifdef FUTEX_CMD_MASK
7567 base_op = op & FUTEX_CMD_MASK;
7568#else
7569 base_op = op;
7570#endif
7571 switch (base_op) {
7572 case FUTEX_WAIT:
7573 case FUTEX_WAIT_BITSET:
7574 if (timeout) {
7575 pts = &ts;
e4ce178b
AF
7576 if (target_to_host_timespec64(pts, timeout)) {
7577 return -TARGET_EFAULT;
7578 }
14690296
AF
7579 } else {
7580 pts = NULL;
7581 }
3e8f1628
RH
7582 return do_safe_futex(g2h(cpu, uaddr), op,
7583 tswap32(val), pts, NULL, val3);
14690296 7584 case FUTEX_WAKE:
3e8f1628 7585 return do_safe_futex(g2h(cpu, uaddr), op, val, NULL, NULL, 0);
14690296 7586 case FUTEX_FD:
3e8f1628 7587 return do_safe_futex(g2h(cpu, uaddr), op, val, NULL, NULL, 0);
14690296
AF
7588 case FUTEX_REQUEUE:
7589 case FUTEX_CMP_REQUEUE:
7590 case FUTEX_WAKE_OP:
7591 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
7592 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
7593 But the prototype takes a `struct timespec *'; insert casts
7594 to satisfy the compiler. We do not need to tswap TIMEOUT
7595 since it's not compared to guest memory. */
7596 pts = (struct timespec *)(uintptr_t) timeout;
3e8f1628 7597 return do_safe_futex(g2h(cpu, uaddr), op, val, pts, g2h(cpu, uaddr2),
14690296 7598 (base_op == FUTEX_CMP_REQUEUE
3e8f1628 7599 ? tswap32(val3) : val3));
14690296
AF
7600 default:
7601 return -TARGET_ENOSYS;
7602 }
7603}
7604#endif
7605
0f0426f3
LV
7606#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7607static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
7608 abi_long handle, abi_long mount_id,
7609 abi_long flags)
7610{
7611 struct file_handle *target_fh;
7612 struct file_handle *fh;
7613 int mid = 0;
7614 abi_long ret;
7615 char *name;
7616 unsigned int size, total_size;
7617
7618 if (get_user_s32(size, handle)) {
7619 return -TARGET_EFAULT;
7620 }
7621
7622 name = lock_user_string(pathname);
7623 if (!name) {
7624 return -TARGET_EFAULT;
7625 }
7626
7627 total_size = sizeof(struct file_handle) + size;
7628 target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
7629 if (!target_fh) {
7630 unlock_user(name, pathname, 0);
7631 return -TARGET_EFAULT;
7632 }
7633
7634 fh = g_malloc0(total_size);
7635 fh->handle_bytes = size;
7636
7637 ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
7638 unlock_user(name, pathname, 0);
7639
7640 /* man name_to_handle_at(2):
7641 * Other than the use of the handle_bytes field, the caller should treat
7642 * the file_handle structure as an opaque data type
7643 */
7644
7645 memcpy(target_fh, fh, total_size);
7646 target_fh->handle_bytes = tswap32(fh->handle_bytes);
7647 target_fh->handle_type = tswap32(fh->handle_type);
7648 g_free(fh);
7649 unlock_user(target_fh, handle, total_size);
7650
7651 if (put_user_s32(mid, mount_id)) {
7652 return -TARGET_EFAULT;
7653 }
7654
7655 return ret;
7656
7657}
7658#endif
7659
7660#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7661static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
7662 abi_long flags)
7663{
7664 struct file_handle *target_fh;
7665 struct file_handle *fh;
7666 unsigned int size, total_size;
7667 abi_long ret;
7668
7669 if (get_user_s32(size, handle)) {
7670 return -TARGET_EFAULT;
7671 }
7672
7673 total_size = sizeof(struct file_handle) + size;
7674 target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
7675 if (!target_fh) {
7676 return -TARGET_EFAULT;
7677 }
7678
e9d49d51 7679 fh = g_memdup(target_fh, total_size);
0f0426f3
LV
7680 fh->handle_bytes = size;
7681 fh->handle_type = tswap32(target_fh->handle_type);
7682
7683 ret = get_errno(open_by_handle_at(mount_fd, fh,
7684 target_to_host_bitmask(flags, fcntl_flags_tbl)));
7685
7686 g_free(fh);
7687
7688 unlock_user(target_fh, handle, total_size);
7689
7690 return ret;
7691}
7692#endif
bd0c5661 7693
e36800c9
LV
7694#if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
7695
e36800c9
LV
7696static abi_long do_signalfd4(int fd, abi_long mask, int flags)
7697{
7698 int host_flags;
7699 target_sigset_t *target_mask;
7700 sigset_t host_mask;
7701 abi_long ret;
7702
78721301 7703 if (flags & ~(TARGET_O_NONBLOCK_MASK | TARGET_O_CLOEXEC)) {
e36800c9
LV
7704 return -TARGET_EINVAL;
7705 }
7706 if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
7707 return -TARGET_EFAULT;
7708 }
7709
7710 target_to_host_sigset(&host_mask, target_mask);
7711
7712 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
7713
7714 ret = get_errno(signalfd(fd, &host_mask, host_flags));
7715 if (ret >= 0) {
7716 fd_trans_register(ret, &target_signalfd_trans);
7717 }
7718
7719 unlock_user_struct(target_mask, mask, 0);
7720
7721 return ret;
7722}
7723#endif
7724
1d9d8b55
PB
7725/* Map host to target signal numbers for the wait family of syscalls.
7726 Assume all other status bits are the same. */
a05c6409 7727int host_to_target_waitstatus(int status)
1d9d8b55
PB
7728{
7729 if (WIFSIGNALED(status)) {
7730 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
7731 }
7732 if (WIFSTOPPED(status)) {
7733 return (host_to_target_signal(WSTOPSIG(status)) << 8)
7734 | (status & 0xff);
7735 }
7736 return status;
7737}
7738
76b94245
WVS
7739static int open_self_cmdline(void *cpu_env, int fd)
7740{
29a0af61 7741 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
58de8b96
AS
7742 struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
7743 int i;
76b94245 7744
58de8b96
AS
7745 for (i = 0; i < bprm->argc; i++) {
7746 size_t len = strlen(bprm->argv[i]) + 1;
76b94245 7747
58de8b96 7748 if (write(fd, bprm->argv[i], len) != len) {
76b94245 7749 return -1;
76b94245
WVS
7750 }
7751 }
7752
58de8b96 7753 return 0;
76b94245
WVS
7754}
7755
36c08d49
AG
7756static int open_self_maps(void *cpu_env, int fd)
7757{
29a0af61 7758 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7759 TaskState *ts = cpu->opaque;
01ef6b9e
AB
7760 GSList *map_info = read_self_maps();
7761 GSList *s;
bb55173c 7762 int count;
1a49ef2a 7763
01ef6b9e
AB
7764 for (s = map_info; s; s = g_slist_next(s)) {
7765 MapInfo *e = (MapInfo *) s->data;
1a49ef2a 7766
01ef6b9e
AB
7767 if (h2g_valid(e->start)) {
7768 unsigned long min = e->start;
7769 unsigned long max = e->end;
d67f4aaa 7770 int flags = page_get_flags(h2g(min));
01ef6b9e
AB
7771 const char *path;
7772
7773 max = h2g_valid(max - 1) ?
3e8f1628 7774 max : (uintptr_t) g2h_untagged(GUEST_ADDR_MAX) + 1;
01ef6b9e 7775
d67f4aaa
MI
7776 if (page_check_range(h2g(min), max - min, flags) == -1) {
7777 continue;
7778 }
01ef6b9e 7779
d67f4aaa 7780 if (h2g(min) == ts->info->stack_limit) {
bb55173c 7781 path = "[stack]";
01ef6b9e
AB
7782 } else {
7783 path = e->path;
d67f4aaa 7784 }
01ef6b9e 7785
bb55173c
AB
7786 count = dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr
7787 " %c%c%c%c %08" PRIx64 " %s %"PRId64,
7788 h2g(min), h2g(max - 1) + 1,
08f3a96b
NS
7789 (flags & PAGE_READ) ? 'r' : '-',
7790 (flags & PAGE_WRITE_ORG) ? 'w' : '-',
7791 (flags & PAGE_EXEC) ? 'x' : '-',
bb55173c
AB
7792 e->is_priv ? 'p' : '-',
7793 (uint64_t) e->offset, e->dev, e->inode);
7794 if (path) {
7795 dprintf(fd, "%*s%s\n", 73 - count, "", path);
7796 } else {
7797 dprintf(fd, "\n");
7798 }
1a49ef2a
AG
7799 }
7800 }
7801
01ef6b9e
AB
7802 free_self_maps(map_info);
7803
bf02adcd
RH
7804#ifdef TARGET_VSYSCALL_PAGE
7805 /*
7806 * We only support execution from the vsyscall page.
7807 * This is as if CONFIG_LEGACY_VSYSCALL_XONLY=y from v5.3.
7808 */
bb55173c
AB
7809 count = dprintf(fd, TARGET_FMT_lx "-" TARGET_FMT_lx
7810 " --xp 00000000 00:00 0",
7811 TARGET_VSYSCALL_PAGE, TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE);
7812 dprintf(fd, "%*s%s\n", 73 - count, "", "[vsyscall]");
bf02adcd
RH
7813#endif
7814
36c08d49
AG
7815 return 0;
7816}
7817
480b8e7d
AG
7818static int open_self_stat(void *cpu_env, int fd)
7819{
29a0af61 7820 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7821 TaskState *ts = cpu->opaque;
7ad4d5a4 7822 g_autoptr(GString) buf = g_string_new(NULL);
480b8e7d
AG
7823 int i;
7824
7825 for (i = 0; i < 44; i++) {
7ad4d5a4
AB
7826 if (i == 0) {
7827 /* pid */
7828 g_string_printf(buf, FMT_pid " ", getpid());
7829 } else if (i == 1) {
7830 /* app name */
7831 gchar *bin = g_strrstr(ts->bprm->argv[0], "/");
7832 bin = bin ? bin + 1 : ts->bprm->argv[0];
7833 g_string_printf(buf, "(%.15s) ", bin);
7aa9fe3a
AS
7834 } else if (i == 3) {
7835 /* ppid */
7836 g_string_printf(buf, FMT_pid " ", getppid());
7ad4d5a4
AB
7837 } else if (i == 27) {
7838 /* stack bottom */
7839 g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
7840 } else {
7841 /* for the rest, there is MasterCard */
7842 g_string_printf(buf, "0%c", i == 43 ? '\n' : ' ');
7843 }
7844
7845 if (write(fd, buf->str, buf->len) != buf->len) {
7846 return -1;
7847 }
480b8e7d
AG
7848 }
7849
7850 return 0;
7851}
7852
257450ee
AG
7853static int open_self_auxv(void *cpu_env, int fd)
7854{
29a0af61 7855 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7856 TaskState *ts = cpu->opaque;
257450ee
AG
7857 abi_ulong auxv = ts->info->saved_auxv;
7858 abi_ulong len = ts->info->auxv_len;
7859 char *ptr;
7860
7861 /*
7862 * Auxiliary vector is stored in target process stack.
7863 * read in whole auxv vector and copy it to file
7864 */
7865 ptr = lock_user(VERIFY_READ, auxv, len, 0);
7866 if (ptr != NULL) {
7867 while (len > 0) {
7868 ssize_t r;
7869 r = write(fd, ptr, len);
7870 if (r <= 0) {
7871 break;
7872 }
7873 len -= r;
7874 ptr += r;
7875 }
7876 lseek(fd, 0, SEEK_SET);
7877 unlock_user(ptr, auxv, len);
7878 }
7879
7880 return 0;
7881}
7882
463d8e73
AS
7883static int is_proc_myself(const char *filename, const char *entry)
7884{
7885 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
7886 filename += strlen("/proc/");
7887 if (!strncmp(filename, "self/", strlen("self/"))) {
7888 filename += strlen("self/");
7889 } else if (*filename >= '1' && *filename <= '9') {
7890 char myself[80];
7891 snprintf(myself, sizeof(myself), "%d/", getpid());
7892 if (!strncmp(filename, myself, strlen(myself))) {
7893 filename += strlen(myself);
7894 } else {
7895 return 0;
7896 }
7897 } else {
7898 return 0;
7899 }
7900 if (!strcmp(filename, entry)) {
7901 return 1;
7902 }
7903 }
7904 return 0;
7905}
7906
fff69382 7907#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \
93a5661d 7908 defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
de6b9933
LV
7909static int is_proc(const char *filename, const char *entry)
7910{
7911 return strcmp(filename, entry) == 0;
7912}
fff69382 7913#endif
de6b9933 7914
fff69382 7915#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
de6b9933
LV
7916static int open_net_route(void *cpu_env, int fd)
7917{
7918 FILE *fp;
7919 char *line = NULL;
7920 size_t len = 0;
7921 ssize_t read;
7922
7923 fp = fopen("/proc/net/route", "r");
7924 if (fp == NULL) {
a3ca7bb2 7925 return -1;
de6b9933
LV
7926 }
7927
7928 /* read header */
7929
7930 read = getline(&line, &len, fp);
7931 dprintf(fd, "%s", line);
7932
7933 /* read routes */
7934
7935 while ((read = getline(&line, &len, fp)) != -1) {
7936 char iface[16];
7937 uint32_t dest, gw, mask;
7938 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
9d0bd0cd
PM
7939 int fields;
7940
7941 fields = sscanf(line,
7942 "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
7943 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
7944 &mask, &mtu, &window, &irtt);
7945 if (fields != 11) {
7946 continue;
7947 }
de6b9933
LV
7948 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
7949 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
7950 metric, tswap32(mask), mtu, window, irtt);
7951 }
7952
7953 free(line);
7954 fclose(fp);
7955
7956 return 0;
7957}
7958#endif
7959
fff69382
LV
7960#if defined(TARGET_SPARC)
7961static int open_cpuinfo(void *cpu_env, int fd)
7962{
7963 dprintf(fd, "type\t\t: sun4u\n");
7964 return 0;
7965}
7966#endif
7967
93a5661d
HD
7968#if defined(TARGET_HPPA)
7969static int open_cpuinfo(void *cpu_env, int fd)
7970{
7971 dprintf(fd, "cpu family\t: PA-RISC 1.1e\n");
7972 dprintf(fd, "cpu\t\t: PA7300LC (PCX-L2)\n");
7973 dprintf(fd, "capabilities\t: os32\n");
7974 dprintf(fd, "model\t\t: 9000/778/B160L\n");
7975 dprintf(fd, "model name\t: Merlin L2 160 QEMU (9000/778/B160L)\n");
7976 return 0;
7977}
7978#endif
7979
4ab6713e
LV
7980#if defined(TARGET_M68K)
7981static int open_hardware(void *cpu_env, int fd)
7982{
7983 dprintf(fd, "Model:\t\tqemu-m68k\n");
7984 return 0;
7985}
7986#endif
7987
0b2effd7 7988static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
3be14d05
AG
7989{
7990 struct fake_open {
7991 const char *filename;
7992 int (*fill)(void *cpu_env, int fd);
de6b9933 7993 int (*cmp)(const char *s1, const char *s2);
3be14d05
AG
7994 };
7995 const struct fake_open *fake_open;
7996 static const struct fake_open fakes[] = {
de6b9933
LV
7997 { "maps", open_self_maps, is_proc_myself },
7998 { "stat", open_self_stat, is_proc_myself },
7999 { "auxv", open_self_auxv, is_proc_myself },
76b94245 8000 { "cmdline", open_self_cmdline, is_proc_myself },
de6b9933
LV
8001#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
8002 { "/proc/net/route", open_net_route, is_proc },
fff69382 8003#endif
93a5661d 8004#if defined(TARGET_SPARC) || defined(TARGET_HPPA)
fff69382 8005 { "/proc/cpuinfo", open_cpuinfo, is_proc },
4ab6713e
LV
8006#endif
8007#if defined(TARGET_M68K)
8008 { "/proc/hardware", open_hardware, is_proc },
de6b9933
LV
8009#endif
8010 { NULL, NULL, NULL }
3be14d05
AG
8011 };
8012
aa07f5ec
MO
8013 if (is_proc_myself(pathname, "exe")) {
8014 int execfd = qemu_getauxval(AT_EXECFD);
c10a0738 8015 return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
aa07f5ec
MO
8016 }
8017
3be14d05 8018 for (fake_open = fakes; fake_open->filename; fake_open++) {
de6b9933 8019 if (fake_open->cmp(pathname, fake_open->filename)) {
3be14d05
AG
8020 break;
8021 }
8022 }
8023
8024 if (fake_open->filename) {
8025 const char *tmpdir;
8026 char filename[PATH_MAX];
8027 int fd, r;
8028
8029 /* create temporary file to map stat to */
8030 tmpdir = getenv("TMPDIR");
8031 if (!tmpdir)
8032 tmpdir = "/tmp";
8033 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
8034 fd = mkstemp(filename);
8035 if (fd < 0) {
8036 return fd;
8037 }
8038 unlink(filename);
8039
8040 if ((r = fake_open->fill(cpu_env, fd))) {
a3ca7bb2 8041 int e = errno;
3be14d05 8042 close(fd);
a3ca7bb2 8043 errno = e;
3be14d05
AG
8044 return r;
8045 }
8046 lseek(fd, 0, SEEK_SET);
8047
8048 return fd;
8049 }
8050
c10a0738 8051 return safe_openat(dirfd, path(pathname), flags, mode);
3be14d05
AG
8052}
8053
aecc8861
AG
8054#define TIMER_MAGIC 0x0caf0000
8055#define TIMER_MAGIC_MASK 0xffff0000
8056
8057/* Convert QEMU provided timer ID back to internal 16bit index format */
8058static target_timer_t get_timer_id(abi_long arg)
8059{
8060 target_timer_t timerid = arg;
8061
8062 if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
8063 return -TARGET_EINVAL;
8064 }
8065
8066 timerid &= 0xffff;
8067
8068 if (timerid >= ARRAY_SIZE(g_posix_timers)) {
8069 return -TARGET_EINVAL;
8070 }
8071
8072 return timerid;
8073}
8074
2e0a8713
ST
8075static int target_to_host_cpu_mask(unsigned long *host_mask,
8076 size_t host_size,
8077 abi_ulong target_addr,
8078 size_t target_size)
8079{
8080 unsigned target_bits = sizeof(abi_ulong) * 8;
8081 unsigned host_bits = sizeof(*host_mask) * 8;
8082 abi_ulong *target_mask;
8083 unsigned i, j;
8084
8085 assert(host_size >= target_size);
8086
8087 target_mask = lock_user(VERIFY_READ, target_addr, target_size, 1);
8088 if (!target_mask) {
8089 return -TARGET_EFAULT;
8090 }
8091 memset(host_mask, 0, host_size);
8092
8093 for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
8094 unsigned bit = i * target_bits;
8095 abi_ulong val;
8096
8097 __get_user(val, &target_mask[i]);
8098 for (j = 0; j < target_bits; j++, bit++) {
8099 if (val & (1UL << j)) {
8100 host_mask[bit / host_bits] |= 1UL << (bit % host_bits);
8101 }
8102 }
8103 }
8104
8105 unlock_user(target_mask, target_addr, 0);
8106 return 0;
8107}
8108
8109static int host_to_target_cpu_mask(const unsigned long *host_mask,
8110 size_t host_size,
8111 abi_ulong target_addr,
8112 size_t target_size)
8113{
8114 unsigned target_bits = sizeof(abi_ulong) * 8;
8115 unsigned host_bits = sizeof(*host_mask) * 8;
8116 abi_ulong *target_mask;
8117 unsigned i, j;
8118
8119 assert(host_size >= target_size);
8120
8121 target_mask = lock_user(VERIFY_WRITE, target_addr, target_size, 0);
8122 if (!target_mask) {
8123 return -TARGET_EFAULT;
8124 }
8125
8126 for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
8127 unsigned bit = i * target_bits;
8128 abi_ulong val = 0;
8129
8130 for (j = 0; j < target_bits; j++, bit++) {
8131 if (host_mask[bit / host_bits] & (1UL << (bit % host_bits))) {
8132 val |= 1UL << j;
8133 }
8134 }
8135 __put_user(val, &target_mask[i]);
8136 }
8137
8138 unlock_user(target_mask, target_addr, target_size);
8139 return 0;
8140}
8141
fd08ddb9 8142#ifdef TARGET_NR_getdents
aee14c77 8143static int do_getdents(abi_long dirfd, abi_long arg2, abi_long count)
fd08ddb9 8144{
aee14c77
RH
8145 g_autofree void *hdirp = NULL;
8146 void *tdirp;
8147 int hlen, hoff, toff;
8148 int hreclen, treclen;
8149 off64_t prev_diroff = 0;
8150
8151 hdirp = g_try_malloc(count);
8152 if (!hdirp) {
8153 return -TARGET_ENOMEM;
8154 }
fd08ddb9
RH
8155
8156#ifdef EMULATE_GETDENTS_WITH_GETDENTS
aee14c77
RH
8157 hlen = sys_getdents(dirfd, hdirp, count);
8158#else
8159 hlen = sys_getdents64(dirfd, hdirp, count);
8160#endif
fd08ddb9 8161
aee14c77
RH
8162 hlen = get_errno(hlen);
8163 if (is_error(hlen)) {
8164 return hlen;
fd08ddb9
RH
8165 }
8166
aee14c77
RH
8167 tdirp = lock_user(VERIFY_WRITE, arg2, count, 0);
8168 if (!tdirp) {
fd08ddb9
RH
8169 return -TARGET_EFAULT;
8170 }
aee14c77
RH
8171
8172 for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) {
8173#ifdef EMULATE_GETDENTS_WITH_GETDENTS
8174 struct linux_dirent *hde = hdirp + hoff;
fd08ddb9 8175#else
aee14c77
RH
8176 struct linux_dirent64 *hde = hdirp + hoff;
8177#endif
8178 struct target_dirent *tde = tdirp + toff;
8179 int namelen;
8180 uint8_t type;
fd08ddb9 8181
aee14c77
RH
8182 namelen = strlen(hde->d_name);
8183 hreclen = hde->d_reclen;
8184 treclen = offsetof(struct target_dirent, d_name) + namelen + 2;
8185 treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent));
fd08ddb9 8186
aee14c77 8187 if (toff + treclen > count) {
fd08ddb9 8188 /*
aee14c77
RH
8189 * If the host struct is smaller than the target struct, or
8190 * requires less alignment and thus packs into less space,
8191 * then the host can return more entries than we can pass
8192 * on to the guest.
fd08ddb9 8193 */
aee14c77
RH
8194 if (toff == 0) {
8195 toff = -TARGET_EINVAL; /* result buffer is too small */
8196 break;
8197 }
8198 /*
8199 * Return what we have, resetting the file pointer to the
8200 * location of the first record not returned.
8201 */
8202 lseek64(dirfd, prev_diroff, SEEK_SET);
8203 break;
fd08ddb9 8204 }
aee14c77
RH
8205
8206 prev_diroff = hde->d_off;
8207 tde->d_ino = tswapal(hde->d_ino);
8208 tde->d_off = tswapal(hde->d_off);
8209 tde->d_reclen = tswap16(treclen);
8210 memcpy(tde->d_name, hde->d_name, namelen + 1);
8211
8212 /*
8213 * The getdents type is in what was formerly a padding byte at the
8214 * end of the structure.
8215 */
8216#ifdef EMULATE_GETDENTS_WITH_GETDENTS
8217 type = *((uint8_t *)hde + hreclen - 1);
8218#else
8219 type = hde->d_type;
fd08ddb9 8220#endif
aee14c77
RH
8221 *((uint8_t *)tde + treclen - 1) = type;
8222 }
8223
8224 unlock_user(tdirp, arg2, toff);
8225 return toff;
fd08ddb9
RH
8226}
8227#endif /* TARGET_NR_getdents */
8228
8229#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
aee14c77 8230static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
fd08ddb9 8231{
aee14c77
RH
8232 g_autofree void *hdirp = NULL;
8233 void *tdirp;
8234 int hlen, hoff, toff;
8235 int hreclen, treclen;
8236 off64_t prev_diroff = 0;
8237
8238 hdirp = g_try_malloc(count);
8239 if (!hdirp) {
8240 return -TARGET_ENOMEM;
8241 }
fd08ddb9 8242
aee14c77
RH
8243 hlen = get_errno(sys_getdents64(dirfd, hdirp, count));
8244 if (is_error(hlen)) {
8245 return hlen;
8246 }
8247
8248 tdirp = lock_user(VERIFY_WRITE, arg2, count, 0);
8249 if (!tdirp) {
fd08ddb9
RH
8250 return -TARGET_EFAULT;
8251 }
aee14c77
RH
8252
8253 for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) {
8254 struct linux_dirent64 *hde = hdirp + hoff;
8255 struct target_dirent64 *tde = tdirp + toff;
8256 int namelen;
8257
8258 namelen = strlen(hde->d_name) + 1;
8259 hreclen = hde->d_reclen;
8260 treclen = offsetof(struct target_dirent64, d_name) + namelen;
8261 treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent64));
8262
8263 if (toff + treclen > count) {
8264 /*
8265 * If the host struct is smaller than the target struct, or
8266 * requires less alignment and thus packs into less space,
8267 * then the host can return more entries than we can pass
8268 * on to the guest.
8269 */
8270 if (toff == 0) {
8271 toff = -TARGET_EINVAL; /* result buffer is too small */
fd08ddb9
RH
8272 break;
8273 }
aee14c77
RH
8274 /*
8275 * Return what we have, resetting the file pointer to the
8276 * location of the first record not returned.
8277 */
8278 lseek64(dirfd, prev_diroff, SEEK_SET);
8279 break;
fd08ddb9 8280 }
aee14c77
RH
8281
8282 prev_diroff = hde->d_off;
8283 tde->d_ino = tswap64(hde->d_ino);
8284 tde->d_off = tswap64(hde->d_off);
8285 tde->d_reclen = tswap16(treclen);
8286 tde->d_type = hde->d_type;
8287 memcpy(tde->d_name, hde->d_name, namelen);
fd08ddb9 8288 }
aee14c77
RH
8289
8290 unlock_user(tdirp, arg2, toff);
8291 return toff;
fd08ddb9
RH
8292}
8293#endif /* TARGET_NR_getdents64 */
8294
e10fbe8f
YT
8295#if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root)
8296_syscall2(int, pivot_root, const char *, new_root, const char *, put_old)
8297#endif
8298
dc1ce18b
RH
8299/* This is an internal helper for do_syscall so that it is easier
8300 * to have a single return point, so that actions, such as logging
8301 * of syscall results, can be performed.
8302 * All errnos that do_syscall() returns must be -TARGET_<errcode>.
8303 */
8304static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
8305 abi_long arg2, abi_long arg3, abi_long arg4,
8306 abi_long arg5, abi_long arg6, abi_long arg7,
8307 abi_long arg8)
31e31b8a 8308{
29a0af61 8309 CPUState *cpu = env_cpu(cpu_env);
992f48a0 8310 abi_long ret;
4f7f8924
AR
8311#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
8312 || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
efa92184
AR
8313 || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \
8314 || defined(TARGET_NR_statx)
31e31b8a 8315 struct stat st;
4f7f8924
AR
8316#endif
8317#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
8318 || defined(TARGET_NR_fstatfs)
56c8f68f 8319 struct statfs stfs;
4f7f8924 8320#endif
53a5960a 8321 void *p;
3b46e624 8322
31e31b8a
FB
8323 switch(num) {
8324 case TARGET_NR_exit:
9b056fcc 8325 /* In old applications this may be used to implement _exit(2).
6f9ff551 8326 However in threaded applications it is used for thread termination,
9b056fcc
AF
8327 and _exit_group is used for application termination.
8328 Do thread termination if we have more then one thread. */
a0995886
TB
8329
8330 if (block_signals()) {
af254a27 8331 return -QEMU_ERESTARTSYS;
a0995886
TB
8332 }
8333
1f81ce90 8334 pthread_mutex_lock(&clone_lock);
dd1f6349 8335
bdc44640 8336 if (CPU_NEXT(first_cpu)) {
1f81ce90 8337 TaskState *ts = cpu->opaque;
9b056fcc 8338
5325cc34 8339 object_property_set_bool(OBJECT(cpu), "realized", false, NULL);
1f81ce90
AB
8340 object_unref(OBJECT(cpu));
8341 /*
8342 * At this point the CPU should be unrealized and removed
8343 * from cpu lists. We can clean-up the rest of the thread
8344 * data without the lock held.
8345 */
dd1f6349 8346
1f81ce90 8347 pthread_mutex_unlock(&clone_lock);
dd1f6349 8348
9b056fcc
AF
8349 if (ts->child_tidptr) {
8350 put_user_u32(0, ts->child_tidptr);
3e8f1628
RH
8351 do_sys_futex(g2h(cpu, ts->child_tidptr),
8352 FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
9b056fcc 8353 }
a2247f8e 8354 thread_cpu = NULL;
9b056fcc 8355 g_free(ts);
70903763 8356 rcu_unregister_thread();
9b056fcc
AF
8357 pthread_exit(NULL);
8358 }
dd1f6349 8359
1f81ce90 8360 pthread_mutex_unlock(&clone_lock);
708b6a64 8361 preexit_cleanup(cpu_env, arg1);
c2764719 8362 _exit(arg1);
72eb7ea8 8363 return 0; /* avoid warning */
31e31b8a 8364 case TARGET_NR_read:
ba584f1d
AS
8365 if (arg2 == 0 && arg3 == 0) {
8366 return get_errno(safe_read(arg1, 0, 0));
72eb7ea8 8367 } else {
38d840e6 8368 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
2852aafd 8369 return -TARGET_EFAULT;
50afd02b 8370 ret = get_errno(safe_read(arg1, p, arg3));
e36800c9 8371 if (ret >= 0 &&
5d4d3665
LV
8372 fd_trans_host_to_target_data(arg1)) {
8373 ret = fd_trans_host_to_target_data(arg1)(p, ret);
e36800c9 8374 }
38d840e6
AJ
8375 unlock_user(p, arg2, ret);
8376 }
72eb7ea8 8377 return ret;
31e31b8a 8378 case TARGET_NR_write:
58cfa6c2
TGJ
8379 if (arg2 == 0 && arg3 == 0) {
8380 return get_errno(safe_write(arg1, 0, 0));
8381 }
579a97f7 8382 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
2852aafd 8383 return -TARGET_EFAULT;
04b9bcf9
LV
8384 if (fd_trans_target_to_host_data(arg1)) {
8385 void *copy = g_malloc(arg3);
8386 memcpy(copy, p, arg3);
8387 ret = fd_trans_target_to_host_data(arg1)(copy, arg3);
8388 if (ret >= 0) {
8389 ret = get_errno(safe_write(arg1, copy, ret));
8390 }
8391 g_free(copy);
8392 } else {
8393 ret = get_errno(safe_write(arg1, p, arg3));
8394 }
53a5960a 8395 unlock_user(p, arg2, 0);
72eb7ea8
RH
8396 return ret;
8397
704eff6c 8398#ifdef TARGET_NR_open
31e31b8a 8399 case TARGET_NR_open:
2f619698 8400 if (!(p = lock_user_string(arg1)))
2852aafd 8401 return -TARGET_EFAULT;
0b2effd7
RV
8402 ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
8403 target_to_host_bitmask(arg2, fcntl_flags_tbl),
8404 arg3));
e36800c9 8405 fd_trans_unregister(ret);
53a5960a 8406 unlock_user(p, arg1, 0);
72eb7ea8 8407 return ret;
704eff6c 8408#endif
82424832 8409 case TARGET_NR_openat:
579a97f7 8410 if (!(p = lock_user_string(arg2)))
2852aafd 8411 return -TARGET_EFAULT;
0b2effd7
RV
8412 ret = get_errno(do_openat(cpu_env, arg1, p,
8413 target_to_host_bitmask(arg3, fcntl_flags_tbl),
8414 arg4));
e36800c9 8415 fd_trans_unregister(ret);
579a97f7 8416 unlock_user(p, arg2, 0);
72eb7ea8 8417 return ret;
0f0426f3
LV
8418#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
8419 case TARGET_NR_name_to_handle_at:
8420 ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
72eb7ea8 8421 return ret;
0f0426f3
LV
8422#endif
8423#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
8424 case TARGET_NR_open_by_handle_at:
8425 ret = do_open_by_handle_at(arg1, arg2, arg3);
e36800c9 8426 fd_trans_unregister(ret);
72eb7ea8 8427 return ret;
0f0426f3 8428#endif
31e31b8a 8429 case TARGET_NR_close:
e36800c9 8430 fd_trans_unregister(arg1);
72eb7ea8
RH
8431 return get_errno(close(arg1));
8432
31e31b8a 8433 case TARGET_NR_brk:
72eb7ea8 8434 return do_brk(arg1);
704eff6c 8435#ifdef TARGET_NR_fork
31e31b8a 8436 case TARGET_NR_fork:
72eb7ea8 8437 return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
704eff6c 8438#endif
e5febef5 8439#ifdef TARGET_NR_waitpid
31e31b8a
FB
8440 case TARGET_NR_waitpid:
8441 {
53a5960a 8442 int status;
4af80a37 8443 ret = get_errno(safe_wait4(arg1, &status, arg3, 0));
5379557b 8444 if (!is_error(ret) && arg2 && ret
1d9d8b55 8445 && put_user_s32(host_to_target_waitstatus(status), arg2))
2852aafd 8446 return -TARGET_EFAULT;
31e31b8a 8447 }
72eb7ea8 8448 return ret;
e5febef5 8449#endif
f0cbb613
PB
8450#ifdef TARGET_NR_waitid
8451 case TARGET_NR_waitid:
8452 {
8453 siginfo_t info;
8454 info.si_pid = 0;
4af80a37 8455 ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
f0cbb613 8456 if (!is_error(ret) && arg3 && info.si_pid != 0) {
c227f099 8457 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
2852aafd 8458 return -TARGET_EFAULT;
f0cbb613 8459 host_to_target_siginfo(p, &info);
c227f099 8460 unlock_user(p, arg3, sizeof(target_siginfo_t));
f0cbb613
PB
8461 }
8462 }
72eb7ea8 8463 return ret;
f0cbb613 8464#endif
7a3148a9 8465#ifdef TARGET_NR_creat /* not on alpha */
31e31b8a 8466 case TARGET_NR_creat:
579a97f7 8467 if (!(p = lock_user_string(arg1)))
2852aafd 8468 return -TARGET_EFAULT;
53a5960a 8469 ret = get_errno(creat(p, arg2));
e36800c9 8470 fd_trans_unregister(ret);
53a5960a 8471 unlock_user(p, arg1, 0);
72eb7ea8 8472 return ret;
7a3148a9 8473#endif
704eff6c 8474#ifdef TARGET_NR_link
31e31b8a 8475 case TARGET_NR_link:
53a5960a
PB
8476 {
8477 void * p2;
8478 p = lock_user_string(arg1);
8479 p2 = lock_user_string(arg2);
579a97f7
FB
8480 if (!p || !p2)
8481 ret = -TARGET_EFAULT;
8482 else
8483 ret = get_errno(link(p, p2));
53a5960a
PB
8484 unlock_user(p2, arg2, 0);
8485 unlock_user(p, arg1, 0);
8486 }
72eb7ea8 8487 return ret;
704eff6c 8488#endif
c0d472b1 8489#if defined(TARGET_NR_linkat)
64f0ce4c 8490 case TARGET_NR_linkat:
64f0ce4c
TS
8491 {
8492 void * p2 = NULL;
579a97f7 8493 if (!arg2 || !arg4)
2852aafd 8494 return -TARGET_EFAULT;
64f0ce4c
TS
8495 p = lock_user_string(arg2);
8496 p2 = lock_user_string(arg4);
579a97f7 8497 if (!p || !p2)
0da46a6e 8498 ret = -TARGET_EFAULT;
64f0ce4c 8499 else
c0d472b1 8500 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
579a97f7
FB
8501 unlock_user(p, arg2, 0);
8502 unlock_user(p2, arg4, 0);
64f0ce4c 8503 }
72eb7ea8 8504 return ret;
64f0ce4c 8505#endif
704eff6c 8506#ifdef TARGET_NR_unlink
31e31b8a 8507 case TARGET_NR_unlink:
579a97f7 8508 if (!(p = lock_user_string(arg1)))
2852aafd 8509 return -TARGET_EFAULT;
53a5960a
PB
8510 ret = get_errno(unlink(p));
8511 unlock_user(p, arg1, 0);
72eb7ea8 8512 return ret;
704eff6c 8513#endif
c0d472b1 8514#if defined(TARGET_NR_unlinkat)
8170f56b 8515 case TARGET_NR_unlinkat:
579a97f7 8516 if (!(p = lock_user_string(arg2)))
2852aafd 8517 return -TARGET_EFAULT;
c0d472b1 8518 ret = get_errno(unlinkat(arg1, p, arg3));
579a97f7 8519 unlock_user(p, arg2, 0);
72eb7ea8 8520 return ret;
b7d35e65 8521#endif
31e31b8a 8522 case TARGET_NR_execve:
7854b056
FB
8523 {
8524 char **argp, **envp;
f7341ff4 8525 int argc, envc;
992f48a0
BS
8526 abi_ulong gp;
8527 abi_ulong guest_argp;
8528 abi_ulong guest_envp;
8529 abi_ulong addr;
7854b056
FB
8530 char **q;
8531
f7341ff4 8532 argc = 0;
53a5960a 8533 guest_argp = arg2;
da94d263 8534 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
03aa1976 8535 if (get_user_ual(addr, gp))
2852aafd 8536 return -TARGET_EFAULT;
03aa1976 8537 if (!addr)
2f619698 8538 break;
7854b056 8539 argc++;
2f619698 8540 }
f7341ff4 8541 envc = 0;
53a5960a 8542 guest_envp = arg3;
da94d263 8543 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
03aa1976 8544 if (get_user_ual(addr, gp))
2852aafd 8545 return -TARGET_EFAULT;
03aa1976 8546 if (!addr)
2f619698 8547 break;
7854b056 8548 envc++;
2f619698 8549 }
7854b056 8550
b936cb50
PP
8551 argp = g_new0(char *, argc + 1);
8552 envp = g_new0(char *, envc + 1);
7854b056 8553
da94d263 8554 for (gp = guest_argp, q = argp; gp;
992f48a0 8555 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8556 if (get_user_ual(addr, gp))
8557 goto execve_efault;
53a5960a
PB
8558 if (!addr)
8559 break;
2f619698
FB
8560 if (!(*q = lock_user_string(addr)))
8561 goto execve_efault;
53a5960a 8562 }
f7341ff4
FB
8563 *q = NULL;
8564
da94d263 8565 for (gp = guest_envp, q = envp; gp;
992f48a0 8566 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8567 if (get_user_ual(addr, gp))
8568 goto execve_efault;
53a5960a
PB
8569 if (!addr)
8570 break;
2f619698
FB
8571 if (!(*q = lock_user_string(addr)))
8572 goto execve_efault;
53a5960a 8573 }
f7341ff4 8574 *q = NULL;
7854b056 8575
2f619698
FB
8576 if (!(p = lock_user_string(arg1)))
8577 goto execve_efault;
ffdcbe22
TB
8578 /* Although execve() is not an interruptible syscall it is
8579 * a special case where we must use the safe_syscall wrapper:
8580 * if we allow a signal to happen before we make the host
8581 * syscall then we will 'lose' it, because at the point of
8582 * execve the process leaves QEMU's control. So we use the
8583 * safe syscall wrapper to ensure that we either take the
8584 * signal as a guest signal, or else it does not happen
8585 * before the execve completes and makes it the other
8586 * program's problem.
8587 */
8588 ret = get_errno(safe_execve(p, argp, envp));
53a5960a
PB
8589 unlock_user(p, arg1, 0);
8590
2f619698
FB
8591 goto execve_end;
8592
8593 execve_efault:
8594 ret = -TARGET_EFAULT;
8595
8596 execve_end:
53a5960a 8597 for (gp = guest_argp, q = argp; *q;
992f48a0 8598 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8599 if (get_user_ual(addr, gp)
8600 || !addr)
8601 break;
53a5960a
PB
8602 unlock_user(*q, addr, 0);
8603 }
8604 for (gp = guest_envp, q = envp; *q;
992f48a0 8605 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8606 if (get_user_ual(addr, gp)
8607 || !addr)
8608 break;
53a5960a
PB
8609 unlock_user(*q, addr, 0);
8610 }
b936cb50
PP
8611
8612 g_free(argp);
8613 g_free(envp);
7854b056 8614 }
72eb7ea8 8615 return ret;
31e31b8a 8616 case TARGET_NR_chdir:
579a97f7 8617 if (!(p = lock_user_string(arg1)))
2852aafd 8618 return -TARGET_EFAULT;
53a5960a
PB
8619 ret = get_errno(chdir(p));
8620 unlock_user(p, arg1, 0);
72eb7ea8 8621 return ret;
a315a145 8622#ifdef TARGET_NR_time
31e31b8a
FB
8623 case TARGET_NR_time:
8624 {
53a5960a
PB
8625 time_t host_time;
8626 ret = get_errno(time(&host_time));
2f619698
FB
8627 if (!is_error(ret)
8628 && arg1
8629 && put_user_sal(host_time, arg1))
2852aafd 8630 return -TARGET_EFAULT;
31e31b8a 8631 }
72eb7ea8 8632 return ret;
a315a145 8633#endif
704eff6c 8634#ifdef TARGET_NR_mknod
31e31b8a 8635 case TARGET_NR_mknod:
579a97f7 8636 if (!(p = lock_user_string(arg1)))
2852aafd 8637 return -TARGET_EFAULT;
53a5960a
PB
8638 ret = get_errno(mknod(p, arg2, arg3));
8639 unlock_user(p, arg1, 0);
72eb7ea8 8640 return ret;
704eff6c 8641#endif
c0d472b1 8642#if defined(TARGET_NR_mknodat)
75ac37a0 8643 case TARGET_NR_mknodat:
579a97f7 8644 if (!(p = lock_user_string(arg2)))
2852aafd 8645 return -TARGET_EFAULT;
c0d472b1 8646 ret = get_errno(mknodat(arg1, p, arg3, arg4));
579a97f7 8647 unlock_user(p, arg2, 0);
72eb7ea8 8648 return ret;
75ac37a0 8649#endif
704eff6c 8650#ifdef TARGET_NR_chmod
31e31b8a 8651 case TARGET_NR_chmod:
579a97f7 8652 if (!(p = lock_user_string(arg1)))
2852aafd 8653 return -TARGET_EFAULT;
53a5960a
PB
8654 ret = get_errno(chmod(p, arg2));
8655 unlock_user(p, arg1, 0);
72eb7ea8 8656 return ret;
704eff6c 8657#endif
4f7f8924 8658#ifdef TARGET_NR_lseek
31e31b8a 8659 case TARGET_NR_lseek:
72eb7ea8 8660 return get_errno(lseek(arg1, arg2, arg3));
4f7f8924 8661#endif
9231733a
RH
8662#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
8663 /* Alpha specific */
7a3148a9 8664 case TARGET_NR_getxpid:
9231733a 8665 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
72eb7ea8 8666 return get_errno(getpid());
7a3148a9 8667#endif
9231733a
RH
8668#ifdef TARGET_NR_getpid
8669 case TARGET_NR_getpid:
72eb7ea8 8670 return get_errno(getpid());
9231733a 8671#endif
31e31b8a 8672 case TARGET_NR_mount:
356d771b
PB
8673 {
8674 /* need to look at the data field */
8675 void *p2, *p3;
8676
8677 if (arg1) {
8678 p = lock_user_string(arg1);
8679 if (!p) {
2852aafd 8680 return -TARGET_EFAULT;
356d771b
PB
8681 }
8682 } else {
8683 p = NULL;
8684 }
8685
8686 p2 = lock_user_string(arg2);
8687 if (!p2) {
8688 if (arg1) {
8689 unlock_user(p, arg1, 0);
8690 }
2852aafd 8691 return -TARGET_EFAULT;
356d771b
PB
8692 }
8693
8694 if (arg3) {
8695 p3 = lock_user_string(arg3);
8696 if (!p3) {
8697 if (arg1) {
579a97f7 8698 unlock_user(p, arg1, 0);
356d771b
PB
8699 }
8700 unlock_user(p2, arg2, 0);
2852aafd 8701 return -TARGET_EFAULT;
356d771b
PB
8702 }
8703 } else {
8704 p3 = NULL;
8705 }
8706
8707 /* FIXME - arg5 should be locked, but it isn't clear how to
8708 * do that since it's not guaranteed to be a NULL-terminated
8709 * string.
8710 */
8711 if (!arg5) {
8712 ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
8713 } else {
3e8f1628 8714 ret = mount(p, p2, p3, (unsigned long)arg4, g2h(cpu, arg5));
356d771b
PB
8715 }
8716 ret = get_errno(ret);
8717
8718 if (arg1) {
8719 unlock_user(p, arg1, 0);
8720 }
8721 unlock_user(p2, arg2, 0);
8722 if (arg3) {
8723 unlock_user(p3, arg3, 0);
8724 }
8725 }
72eb7ea8 8726 return ret;
6eb9dbf6
LV
8727#if defined(TARGET_NR_umount) || defined(TARGET_NR_oldumount)
8728#if defined(TARGET_NR_umount)
31e31b8a 8729 case TARGET_NR_umount:
6eb9dbf6
LV
8730#endif
8731#if defined(TARGET_NR_oldumount)
8732 case TARGET_NR_oldumount:
8733#endif
579a97f7 8734 if (!(p = lock_user_string(arg1)))
2852aafd 8735 return -TARGET_EFAULT;
53a5960a
PB
8736 ret = get_errno(umount(p));
8737 unlock_user(p, arg1, 0);
72eb7ea8 8738 return ret;
e5febef5 8739#endif
7a3148a9 8740#ifdef TARGET_NR_stime /* not on alpha */
31e31b8a
FB
8741 case TARGET_NR_stime:
8742 {
0f1f2d45
LV
8743 struct timespec ts;
8744 ts.tv_nsec = 0;
8745 if (get_user_sal(ts.tv_sec, arg1)) {
2852aafd 8746 return -TARGET_EFAULT;
0f1f2d45
LV
8747 }
8748 return get_errno(clock_settime(CLOCK_REALTIME, &ts));
31e31b8a 8749 }
7a3148a9 8750#endif
7a3148a9 8751#ifdef TARGET_NR_alarm /* not on alpha */
31e31b8a 8752 case TARGET_NR_alarm:
72eb7ea8 8753 return alarm(arg1);
7a3148a9 8754#endif
7a3148a9 8755#ifdef TARGET_NR_pause /* not on alpha */
31e31b8a 8756 case TARGET_NR_pause:
f59ec606
TB
8757 if (!block_signals()) {
8758 sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
8759 }
72eb7ea8 8760 return -TARGET_EINTR;
7a3148a9 8761#endif
e5febef5 8762#ifdef TARGET_NR_utime
31e31b8a 8763 case TARGET_NR_utime:
ebc05488 8764 {
53a5960a
PB
8765 struct utimbuf tbuf, *host_tbuf;
8766 struct target_utimbuf *target_tbuf;
8767 if (arg2) {
579a97f7 8768 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
2852aafd 8769 return -TARGET_EFAULT;
cbb21eed
MB
8770 tbuf.actime = tswapal(target_tbuf->actime);
8771 tbuf.modtime = tswapal(target_tbuf->modtime);
53a5960a
PB
8772 unlock_user_struct(target_tbuf, arg2, 0);
8773 host_tbuf = &tbuf;
f72e8ff4 8774 } else {
53a5960a 8775 host_tbuf = NULL;
f72e8ff4 8776 }
579a97f7 8777 if (!(p = lock_user_string(arg1)))
2852aafd 8778 return -TARGET_EFAULT;
53a5960a
PB
8779 ret = get_errno(utime(p, host_tbuf));
8780 unlock_user(p, arg1, 0);
ebc05488 8781 }
72eb7ea8 8782 return ret;
e5febef5 8783#endif
704eff6c 8784#ifdef TARGET_NR_utimes
978a66ff
FB
8785 case TARGET_NR_utimes:
8786 {
978a66ff 8787 struct timeval *tvp, tv[2];
53a5960a 8788 if (arg2) {
788f5ec4
TS
8789 if (copy_from_user_timeval(&tv[0], arg2)
8790 || copy_from_user_timeval(&tv[1],
8791 arg2 + sizeof(struct target_timeval)))
2852aafd 8792 return -TARGET_EFAULT;
978a66ff
FB
8793 tvp = tv;
8794 } else {
8795 tvp = NULL;
8796 }
579a97f7 8797 if (!(p = lock_user_string(arg1)))
2852aafd 8798 return -TARGET_EFAULT;
53a5960a
PB
8799 ret = get_errno(utimes(p, tvp));
8800 unlock_user(p, arg1, 0);
978a66ff 8801 }
72eb7ea8 8802 return ret;
704eff6c 8803#endif
c0d472b1 8804#if defined(TARGET_NR_futimesat)
ac8a6556
AZ
8805 case TARGET_NR_futimesat:
8806 {
8807 struct timeval *tvp, tv[2];
8808 if (arg3) {
8809 if (copy_from_user_timeval(&tv[0], arg3)
8810 || copy_from_user_timeval(&tv[1],
8811 arg3 + sizeof(struct target_timeval)))
2852aafd 8812 return -TARGET_EFAULT;
ac8a6556
AZ
8813 tvp = tv;
8814 } else {
8815 tvp = NULL;
8816 }
2852aafd
RH
8817 if (!(p = lock_user_string(arg2))) {
8818 return -TARGET_EFAULT;
8819 }
c0d472b1 8820 ret = get_errno(futimesat(arg1, path(p), tvp));
ac8a6556
AZ
8821 unlock_user(p, arg2, 0);
8822 }
72eb7ea8 8823 return ret;
ac8a6556 8824#endif
704eff6c 8825#ifdef TARGET_NR_access
31e31b8a 8826 case TARGET_NR_access:
2852aafd
RH
8827 if (!(p = lock_user_string(arg1))) {
8828 return -TARGET_EFAULT;
8829 }
719f908e 8830 ret = get_errno(access(path(p), arg2));
53a5960a 8831 unlock_user(p, arg1, 0);
72eb7ea8 8832 return ret;
704eff6c 8833#endif
92a34c10
TS
8834#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
8835 case TARGET_NR_faccessat:
2852aafd
RH
8836 if (!(p = lock_user_string(arg2))) {
8837 return -TARGET_EFAULT;
8838 }
c0d472b1 8839 ret = get_errno(faccessat(arg1, p, arg3, 0));
579a97f7 8840 unlock_user(p, arg2, 0);
72eb7ea8 8841 return ret;
92a34c10 8842#endif
7a3148a9 8843#ifdef TARGET_NR_nice /* not on alpha */
31e31b8a 8844 case TARGET_NR_nice:
72eb7ea8 8845 return get_errno(nice(arg1));
ebc05488 8846#endif
31e31b8a 8847 case TARGET_NR_sync:
04369ff2 8848 sync();
72eb7ea8 8849 return 0;
5a03cd00
AM
8850#if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS)
8851 case TARGET_NR_syncfs:
72eb7ea8 8852 return get_errno(syncfs(arg1));
5a03cd00 8853#endif
31e31b8a 8854 case TARGET_NR_kill:
72eb7ea8 8855 return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
704eff6c 8856#ifdef TARGET_NR_rename
31e31b8a 8857 case TARGET_NR_rename:
53a5960a
PB
8858 {
8859 void *p2;
8860 p = lock_user_string(arg1);
8861 p2 = lock_user_string(arg2);
579a97f7
FB
8862 if (!p || !p2)
8863 ret = -TARGET_EFAULT;
8864 else
8865 ret = get_errno(rename(p, p2));
53a5960a
PB
8866 unlock_user(p2, arg2, 0);
8867 unlock_user(p, arg1, 0);
8868 }
72eb7ea8 8869 return ret;
704eff6c 8870#endif
c0d472b1 8871#if defined(TARGET_NR_renameat)
722183f6 8872 case TARGET_NR_renameat:
722183f6 8873 {
579a97f7 8874 void *p2;
722183f6
TS
8875 p = lock_user_string(arg2);
8876 p2 = lock_user_string(arg4);
579a97f7 8877 if (!p || !p2)
0da46a6e 8878 ret = -TARGET_EFAULT;
722183f6 8879 else
c0d472b1 8880 ret = get_errno(renameat(arg1, p, arg3, p2));
579a97f7
FB
8881 unlock_user(p2, arg4, 0);
8882 unlock_user(p, arg2, 0);
722183f6 8883 }
72eb7ea8 8884 return ret;
95d0307c
AS
8885#endif
8886#if defined(TARGET_NR_renameat2)
8887 case TARGET_NR_renameat2:
8888 {
8889 void *p2;
8890 p = lock_user_string(arg2);
8891 p2 = lock_user_string(arg4);
8892 if (!p || !p2) {
8893 ret = -TARGET_EFAULT;
8894 } else {
8895 ret = get_errno(sys_renameat2(arg1, p, arg3, p2, arg5));
8896 }
8897 unlock_user(p2, arg4, 0);
8898 unlock_user(p, arg2, 0);
8899 }
72eb7ea8 8900 return ret;
722183f6 8901#endif
704eff6c 8902#ifdef TARGET_NR_mkdir
31e31b8a 8903 case TARGET_NR_mkdir:
579a97f7 8904 if (!(p = lock_user_string(arg1)))
2852aafd 8905 return -TARGET_EFAULT;
53a5960a
PB
8906 ret = get_errno(mkdir(p, arg2));
8907 unlock_user(p, arg1, 0);
72eb7ea8 8908 return ret;
704eff6c 8909#endif
c0d472b1 8910#if defined(TARGET_NR_mkdirat)
4472ad0d 8911 case TARGET_NR_mkdirat:
579a97f7 8912 if (!(p = lock_user_string(arg2)))
2852aafd 8913 return -TARGET_EFAULT;
c0d472b1 8914 ret = get_errno(mkdirat(arg1, p, arg3));
579a97f7 8915 unlock_user(p, arg2, 0);
72eb7ea8 8916 return ret;
4472ad0d 8917#endif
704eff6c 8918#ifdef TARGET_NR_rmdir
31e31b8a 8919 case TARGET_NR_rmdir:
579a97f7 8920 if (!(p = lock_user_string(arg1)))
2852aafd 8921 return -TARGET_EFAULT;
53a5960a
PB
8922 ret = get_errno(rmdir(p));
8923 unlock_user(p, arg1, 0);
72eb7ea8 8924 return ret;
704eff6c 8925#endif
31e31b8a
FB
8926 case TARGET_NR_dup:
8927 ret = get_errno(dup(arg1));
e36800c9
LV
8928 if (ret >= 0) {
8929 fd_trans_dup(arg1, ret);
8930 }
72eb7ea8 8931 return ret;
704eff6c 8932#ifdef TARGET_NR_pipe
31e31b8a 8933 case TARGET_NR_pipe:
72eb7ea8 8934 return do_pipe(cpu_env, arg1, 0, 0);
704eff6c 8935#endif
099d6b0f
RV
8936#ifdef TARGET_NR_pipe2
8937 case TARGET_NR_pipe2:
72eb7ea8
RH
8938 return do_pipe(cpu_env, arg1,
8939 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
099d6b0f 8940#endif
31e31b8a 8941 case TARGET_NR_times:
32f36bce 8942 {
53a5960a 8943 struct target_tms *tmsp;
32f36bce
FB
8944 struct tms tms;
8945 ret = get_errno(times(&tms));
53a5960a 8946 if (arg1) {
579a97f7
FB
8947 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
8948 if (!tmsp)
2852aafd 8949 return -TARGET_EFAULT;
cbb21eed
MB
8950 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
8951 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
8952 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
8953 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
32f36bce 8954 }
c596ed17
FB
8955 if (!is_error(ret))
8956 ret = host_to_target_clock_t(ret);
32f36bce 8957 }
72eb7ea8 8958 return ret;
31e31b8a 8959 case TARGET_NR_acct:
38d840e6
AJ
8960 if (arg1 == 0) {
8961 ret = get_errno(acct(NULL));
8962 } else {
2852aafd
RH
8963 if (!(p = lock_user_string(arg1))) {
8964 return -TARGET_EFAULT;
8965 }
38d840e6
AJ
8966 ret = get_errno(acct(path(p)));
8967 unlock_user(p, arg1, 0);
8968 }
72eb7ea8 8969 return ret;
8070e7be 8970#ifdef TARGET_NR_umount2
31e31b8a 8971 case TARGET_NR_umount2:
579a97f7 8972 if (!(p = lock_user_string(arg1)))
2852aafd 8973 return -TARGET_EFAULT;
53a5960a
PB
8974 ret = get_errno(umount2(p, arg2));
8975 unlock_user(p, arg1, 0);
72eb7ea8 8976 return ret;
ebc05488 8977#endif
31e31b8a 8978 case TARGET_NR_ioctl:
72eb7ea8 8979 return do_ioctl(arg1, arg2, arg3);
47ae93cd 8980#ifdef TARGET_NR_fcntl
31e31b8a 8981 case TARGET_NR_fcntl:
72eb7ea8 8982 return do_fcntl(arg1, arg2, arg3);
ebc05488 8983#endif
31e31b8a 8984 case TARGET_NR_setpgid:
72eb7ea8 8985 return get_errno(setpgid(arg1, arg2));
31e31b8a 8986 case TARGET_NR_umask:
72eb7ea8 8987 return get_errno(umask(arg1));
31e31b8a 8988 case TARGET_NR_chroot:
579a97f7 8989 if (!(p = lock_user_string(arg1)))
2852aafd 8990 return -TARGET_EFAULT;
53a5960a
PB
8991 ret = get_errno(chroot(p));
8992 unlock_user(p, arg1, 0);
72eb7ea8 8993 return ret;
704eff6c 8994#ifdef TARGET_NR_dup2
31e31b8a
FB
8995 case TARGET_NR_dup2:
8996 ret = get_errno(dup2(arg1, arg2));
e36800c9
LV
8997 if (ret >= 0) {
8998 fd_trans_dup(arg1, arg2);
8999 }
72eb7ea8 9000 return ret;
704eff6c 9001#endif
d0927938
UH
9002#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
9003 case TARGET_NR_dup3:
10fa993a
PM
9004 {
9005 int host_flags;
9006
9007 if ((arg3 & ~TARGET_O_CLOEXEC) != 0) {
9008 return -EINVAL;
9009 }
9010 host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl);
9011 ret = get_errno(dup3(arg1, arg2, host_flags));
e36800c9
LV
9012 if (ret >= 0) {
9013 fd_trans_dup(arg1, arg2);
9014 }
72eb7ea8 9015 return ret;
10fa993a 9016 }
d0927938 9017#endif
7a3148a9 9018#ifdef TARGET_NR_getppid /* not on alpha */
31e31b8a 9019 case TARGET_NR_getppid:
72eb7ea8 9020 return get_errno(getppid());
7a3148a9 9021#endif
704eff6c 9022#ifdef TARGET_NR_getpgrp
31e31b8a 9023 case TARGET_NR_getpgrp:
72eb7ea8 9024 return get_errno(getpgrp());
704eff6c 9025#endif
31e31b8a 9026 case TARGET_NR_setsid:
72eb7ea8 9027 return get_errno(setsid());
e5febef5 9028#ifdef TARGET_NR_sigaction
31e31b8a 9029 case TARGET_NR_sigaction:
31e31b8a 9030 {
02d0de10 9031#if defined(TARGET_MIPS)
106ec879
FB
9032 struct target_sigaction act, oact, *pact, *old_act;
9033
9034 if (arg2) {
579a97f7 9035 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 9036 return -TARGET_EFAULT;
106ec879
FB
9037 act._sa_handler = old_act->_sa_handler;
9038 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
9039 act.sa_flags = old_act->sa_flags;
9040 unlock_user_struct(old_act, arg2, 0);
9041 pact = &act;
9042 } else {
9043 pact = NULL;
9044 }
9045
02fb28e8 9046 ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
106ec879
FB
9047
9048 if (!is_error(ret) && arg3) {
579a97f7 9049 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 9050 return -TARGET_EFAULT;
106ec879
FB
9051 old_act->_sa_handler = oact._sa_handler;
9052 old_act->sa_flags = oact.sa_flags;
9053 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
9054 old_act->sa_mask.sig[1] = 0;
9055 old_act->sa_mask.sig[2] = 0;
9056 old_act->sa_mask.sig[3] = 0;
9057 unlock_user_struct(old_act, arg3, 1);
9058 }
6049f4f8
RH
9059#else
9060 struct target_old_sigaction *old_act;
9061 struct target_sigaction act, oact, *pact;
9062 if (arg2) {
9063 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 9064 return -TARGET_EFAULT;
6049f4f8
RH
9065 act._sa_handler = old_act->_sa_handler;
9066 target_siginitset(&act.sa_mask, old_act->sa_mask);
9067 act.sa_flags = old_act->sa_flags;
ca192277 9068#ifdef TARGET_ARCH_HAS_SA_RESTORER
6049f4f8 9069 act.sa_restorer = old_act->sa_restorer;
ca192277 9070#endif
6049f4f8
RH
9071 unlock_user_struct(old_act, arg2, 0);
9072 pact = &act;
9073 } else {
9074 pact = NULL;
9075 }
02fb28e8 9076 ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
6049f4f8
RH
9077 if (!is_error(ret) && arg3) {
9078 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 9079 return -TARGET_EFAULT;
6049f4f8
RH
9080 old_act->_sa_handler = oact._sa_handler;
9081 old_act->sa_mask = oact.sa_mask.sig[0];
9082 old_act->sa_flags = oact.sa_flags;
ca192277 9083#ifdef TARGET_ARCH_HAS_SA_RESTORER
6049f4f8 9084 old_act->sa_restorer = oact.sa_restorer;
ca192277 9085#endif
6049f4f8
RH
9086 unlock_user_struct(old_act, arg3, 1);
9087 }
388bb21a 9088#endif
31e31b8a 9089 }
72eb7ea8 9090 return ret;
e5febef5 9091#endif
66fb9763 9092 case TARGET_NR_rt_sigaction:
53a5960a 9093 {
0f6f9903
RH
9094 /*
9095 * For Alpha and SPARC this is a 5 argument syscall, with
78bfef72
PM
9096 * a 'restorer' parameter which must be copied into the
9097 * sa_restorer field of the sigaction struct.
9098 * For Alpha that 'restorer' is arg5; for SPARC it is arg4,
9099 * and arg5 is the sigsetsize.
78bfef72 9100 */
0f6f9903
RH
9101#if defined(TARGET_ALPHA)
9102 target_ulong sigsetsize = arg4;
9103 target_ulong restorer = arg5;
9104#elif defined(TARGET_SPARC)
78bfef72
PM
9105 target_ulong restorer = arg4;
9106 target_ulong sigsetsize = arg5;
9107#else
9108 target_ulong sigsetsize = arg4;
02fb28e8 9109 target_ulong restorer = 0;
78bfef72 9110#endif
fb80439b
RH
9111 struct target_sigaction *act = NULL;
9112 struct target_sigaction *oact = NULL;
53a5960a 9113
78bfef72 9114 if (sigsetsize != sizeof(target_sigset_t)) {
72eb7ea8 9115 return -TARGET_EINVAL;
c815701e 9116 }
fb80439b
RH
9117 if (arg2 && !lock_user_struct(VERIFY_READ, act, arg2, 1)) {
9118 return -TARGET_EFAULT;
78bfef72 9119 }
fb80439b
RH
9120 if (arg3 && !lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
9121 ret = -TARGET_EFAULT;
9122 } else {
9123 ret = get_errno(do_sigaction(arg1, act, oact, restorer));
9124 if (oact) {
9125 unlock_user_struct(oact, arg3, 1);
579a97f7 9126 }
fb80439b
RH
9127 }
9128 if (act) {
53a5960a 9129 unlock_user_struct(act, arg2, 0);
fb80439b 9130 }
53a5960a 9131 }
72eb7ea8 9132 return ret;
7a3148a9 9133#ifdef TARGET_NR_sgetmask /* not on alpha */
31e31b8a 9134 case TARGET_NR_sgetmask:
66fb9763
FB
9135 {
9136 sigset_t cur_set;
992f48a0 9137 abi_ulong target_set;
3d3efba0
PM
9138 ret = do_sigprocmask(0, NULL, &cur_set);
9139 if (!ret) {
9140 host_to_target_old_sigset(&target_set, &cur_set);
9141 ret = target_set;
9142 }
66fb9763 9143 }
72eb7ea8 9144 return ret;
7a3148a9
JM
9145#endif
9146#ifdef TARGET_NR_ssetmask /* not on alpha */
31e31b8a 9147 case TARGET_NR_ssetmask:
66fb9763 9148 {
a8617d8c 9149 sigset_t set, oset;
992f48a0 9150 abi_ulong target_set = arg1;
66fb9763 9151 target_to_host_old_sigset(&set, &target_set);
3d3efba0
PM
9152 ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
9153 if (!ret) {
9154 host_to_target_old_sigset(&target_set, &oset);
9155 ret = target_set;
9156 }
66fb9763 9157 }
72eb7ea8 9158 return ret;
7a3148a9 9159#endif
e5febef5 9160#ifdef TARGET_NR_sigprocmask
66fb9763
FB
9161 case TARGET_NR_sigprocmask:
9162 {
a5b3b13b
RH
9163#if defined(TARGET_ALPHA)
9164 sigset_t set, oldset;
9165 abi_ulong mask;
9166 int how;
9167
9168 switch (arg1) {
9169 case TARGET_SIG_BLOCK:
9170 how = SIG_BLOCK;
9171 break;
9172 case TARGET_SIG_UNBLOCK:
9173 how = SIG_UNBLOCK;
9174 break;
9175 case TARGET_SIG_SETMASK:
9176 how = SIG_SETMASK;
9177 break;
9178 default:
259841c1 9179 return -TARGET_EINVAL;
a5b3b13b
RH
9180 }
9181 mask = arg2;
9182 target_to_host_old_sigset(&set, &mask);
9183
3d3efba0 9184 ret = do_sigprocmask(how, &set, &oldset);
a5b3b13b
RH
9185 if (!is_error(ret)) {
9186 host_to_target_old_sigset(&mask, &oldset);
9187 ret = mask;
0229f5a3 9188 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
a5b3b13b
RH
9189 }
9190#else
66fb9763 9191 sigset_t set, oldset, *set_ptr;
a5b3b13b 9192 int how;
3b46e624 9193
53a5960a 9194 if (arg2) {
a5b3b13b 9195 switch (arg1) {
66fb9763
FB
9196 case TARGET_SIG_BLOCK:
9197 how = SIG_BLOCK;
9198 break;
9199 case TARGET_SIG_UNBLOCK:
9200 how = SIG_UNBLOCK;
9201 break;
9202 case TARGET_SIG_SETMASK:
9203 how = SIG_SETMASK;
9204 break;
9205 default:
259841c1 9206 return -TARGET_EINVAL;
66fb9763 9207 }
c227f099 9208 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
2852aafd 9209 return -TARGET_EFAULT;
53a5960a
PB
9210 target_to_host_old_sigset(&set, p);
9211 unlock_user(p, arg2, 0);
66fb9763
FB
9212 set_ptr = &set;
9213 } else {
9214 how = 0;
9215 set_ptr = NULL;
9216 }
3d3efba0 9217 ret = do_sigprocmask(how, set_ptr, &oldset);
53a5960a 9218 if (!is_error(ret) && arg3) {
c227f099 9219 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
2852aafd 9220 return -TARGET_EFAULT;
53a5960a 9221 host_to_target_old_sigset(p, &oldset);
c227f099 9222 unlock_user(p, arg3, sizeof(target_sigset_t));
66fb9763 9223 }
a5b3b13b 9224#endif
66fb9763 9225 }
72eb7ea8 9226 return ret;
e5febef5 9227#endif
66fb9763
FB
9228 case TARGET_NR_rt_sigprocmask:
9229 {
9230 int how = arg1;
9231 sigset_t set, oldset, *set_ptr;
3b46e624 9232
c815701e 9233 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 9234 return -TARGET_EINVAL;
c815701e
PM
9235 }
9236
53a5960a 9237 if (arg2) {
66fb9763
FB
9238 switch(how) {
9239 case TARGET_SIG_BLOCK:
9240 how = SIG_BLOCK;
9241 break;
9242 case TARGET_SIG_UNBLOCK:
9243 how = SIG_UNBLOCK;
9244 break;
9245 case TARGET_SIG_SETMASK:
9246 how = SIG_SETMASK;
9247 break;
9248 default:
259841c1 9249 return -TARGET_EINVAL;
66fb9763 9250 }
c227f099 9251 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
2852aafd 9252 return -TARGET_EFAULT;
53a5960a
PB
9253 target_to_host_sigset(&set, p);
9254 unlock_user(p, arg2, 0);
66fb9763
FB
9255 set_ptr = &set;
9256 } else {
9257 how = 0;
9258 set_ptr = NULL;
9259 }
3d3efba0 9260 ret = do_sigprocmask(how, set_ptr, &oldset);
53a5960a 9261 if (!is_error(ret) && arg3) {
c227f099 9262 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
2852aafd 9263 return -TARGET_EFAULT;
53a5960a 9264 host_to_target_sigset(p, &oldset);
c227f099 9265 unlock_user(p, arg3, sizeof(target_sigset_t));
66fb9763
FB
9266 }
9267 }
72eb7ea8 9268 return ret;
e5febef5 9269#ifdef TARGET_NR_sigpending
66fb9763
FB
9270 case TARGET_NR_sigpending:
9271 {
9272 sigset_t set;
9273 ret = get_errno(sigpending(&set));
9274 if (!is_error(ret)) {
c227f099 9275 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
2852aafd 9276 return -TARGET_EFAULT;
53a5960a 9277 host_to_target_old_sigset(p, &set);
c227f099 9278 unlock_user(p, arg1, sizeof(target_sigset_t));
66fb9763
FB
9279 }
9280 }
72eb7ea8 9281 return ret;
e5febef5 9282#endif
66fb9763
FB
9283 case TARGET_NR_rt_sigpending:
9284 {
9285 sigset_t set;
c815701e
PM
9286
9287 /* Yes, this check is >, not != like most. We follow the kernel's
9288 * logic and it does it like this because it implements
9289 * NR_sigpending through the same code path, and in that case
9290 * the old_sigset_t is smaller in size.
9291 */
9292 if (arg2 > sizeof(target_sigset_t)) {
72eb7ea8 9293 return -TARGET_EINVAL;
c815701e
PM
9294 }
9295
66fb9763
FB
9296 ret = get_errno(sigpending(&set));
9297 if (!is_error(ret)) {
c227f099 9298 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
2852aafd 9299 return -TARGET_EFAULT;
53a5960a 9300 host_to_target_sigset(p, &set);
c227f099 9301 unlock_user(p, arg1, sizeof(target_sigset_t));
66fb9763
FB
9302 }
9303 }
72eb7ea8 9304 return ret;
e5febef5 9305#ifdef TARGET_NR_sigsuspend
66fb9763
FB
9306 case TARGET_NR_sigsuspend:
9307 {
3d3efba0 9308 TaskState *ts = cpu->opaque;
f43ce12b
RH
9309#if defined(TARGET_ALPHA)
9310 abi_ulong mask = arg1;
3d3efba0 9311 target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
f43ce12b 9312#else
c227f099 9313 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 9314 return -TARGET_EFAULT;
3d3efba0 9315 target_to_host_old_sigset(&ts->sigsuspend_mask, p);
53a5960a 9316 unlock_user(p, arg1, 0);
f43ce12b 9317#endif
3d3efba0
PM
9318 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
9319 SIGSET_T_SIZE));
af254a27 9320 if (ret != -QEMU_ERESTARTSYS) {
3d3efba0
PM
9321 ts->in_sigsuspend = 1;
9322 }
66fb9763 9323 }
72eb7ea8 9324 return ret;
e5febef5 9325#endif
66fb9763
FB
9326 case TARGET_NR_rt_sigsuspend:
9327 {
3d3efba0 9328 TaskState *ts = cpu->opaque;
c815701e
PM
9329
9330 if (arg2 != sizeof(target_sigset_t)) {
72eb7ea8 9331 return -TARGET_EINVAL;
c815701e 9332 }
c227f099 9333 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 9334 return -TARGET_EFAULT;
3d3efba0 9335 target_to_host_sigset(&ts->sigsuspend_mask, p);
53a5960a 9336 unlock_user(p, arg1, 0);
3d3efba0
PM
9337 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
9338 SIGSET_T_SIZE));
af254a27 9339 if (ret != -QEMU_ERESTARTSYS) {
3d3efba0
PM
9340 ts->in_sigsuspend = 1;
9341 }
66fb9763 9342 }
72eb7ea8 9343 return ret;
859e8a89 9344#ifdef TARGET_NR_rt_sigtimedwait
66fb9763
FB
9345 case TARGET_NR_rt_sigtimedwait:
9346 {
66fb9763
FB
9347 sigset_t set;
9348 struct timespec uts, *puts;
9349 siginfo_t uinfo;
3b46e624 9350
c815701e 9351 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 9352 return -TARGET_EINVAL;
c815701e
PM
9353 }
9354
c227f099 9355 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 9356 return -TARGET_EFAULT;
53a5960a
PB
9357 target_to_host_sigset(&set, p);
9358 unlock_user(p, arg1, 0);
9359 if (arg3) {
66fb9763 9360 puts = &uts;
4d213001
FB
9361 if (target_to_host_timespec(puts, arg3)) {
9362 return -TARGET_EFAULT;
9363 }
66fb9763
FB
9364 } else {
9365 puts = NULL;
9366 }
b3f82330
PM
9367 ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
9368 SIGSET_T_SIZE));
974a196d
PJ
9369 if (!is_error(ret)) {
9370 if (arg2) {
9371 p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
9372 0);
9373 if (!p) {
2852aafd 9374 return -TARGET_EFAULT;
974a196d
PJ
9375 }
9376 host_to_target_siginfo(p, &uinfo);
9377 unlock_user(p, arg2, sizeof(target_siginfo_t));
9378 }
9379 ret = host_to_target_signal(ret);
66fb9763
FB
9380 }
9381 }
72eb7ea8 9382 return ret;
ddcbde15
FB
9383#endif
9384#ifdef TARGET_NR_rt_sigtimedwait_time64
9385 case TARGET_NR_rt_sigtimedwait_time64:
9386 {
9387 sigset_t set;
9388 struct timespec uts, *puts;
9389 siginfo_t uinfo;
9390
9391 if (arg4 != sizeof(target_sigset_t)) {
9392 return -TARGET_EINVAL;
9393 }
9394
9395 p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
9396 if (!p) {
9397 return -TARGET_EFAULT;
9398 }
9399 target_to_host_sigset(&set, p);
9400 unlock_user(p, arg1, 0);
9401 if (arg3) {
9402 puts = &uts;
9403 if (target_to_host_timespec64(puts, arg3)) {
9404 return -TARGET_EFAULT;
9405 }
9406 } else {
9407 puts = NULL;
9408 }
9409 ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
9410 SIGSET_T_SIZE));
9411 if (!is_error(ret)) {
9412 if (arg2) {
9413 p = lock_user(VERIFY_WRITE, arg2,
9414 sizeof(target_siginfo_t), 0);
9415 if (!p) {
9416 return -TARGET_EFAULT;
9417 }
9418 host_to_target_siginfo(p, &uinfo);
9419 unlock_user(p, arg2, sizeof(target_siginfo_t));
9420 }
9421 ret = host_to_target_signal(ret);
9422 }
9423 }
9424 return ret;
859e8a89 9425#endif
66fb9763
FB
9426 case TARGET_NR_rt_sigqueueinfo:
9427 {
9428 siginfo_t uinfo;
4debae6f
PM
9429
9430 p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
9431 if (!p) {
2852aafd 9432 return -TARGET_EFAULT;
4debae6f 9433 }
53a5960a 9434 target_to_host_siginfo(&uinfo, p);
d8b6d892 9435 unlock_user(p, arg3, 0);
66fb9763
FB
9436 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
9437 }
72eb7ea8 9438 return ret;
cf8b8bfc
MS
9439 case TARGET_NR_rt_tgsigqueueinfo:
9440 {
9441 siginfo_t uinfo;
9442
9443 p = lock_user(VERIFY_READ, arg4, sizeof(target_siginfo_t), 1);
9444 if (!p) {
2852aafd 9445 return -TARGET_EFAULT;
cf8b8bfc
MS
9446 }
9447 target_to_host_siginfo(&uinfo, p);
9448 unlock_user(p, arg4, 0);
9449 ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, &uinfo));
9450 }
72eb7ea8 9451 return ret;
e5febef5 9452#ifdef TARGET_NR_sigreturn
66fb9763 9453 case TARGET_NR_sigreturn:
3d3efba0 9454 if (block_signals()) {
af254a27 9455 return -QEMU_ERESTARTSYS;
3d3efba0 9456 }
72eb7ea8 9457 return do_sigreturn(cpu_env);
e5febef5 9458#endif
66fb9763 9459 case TARGET_NR_rt_sigreturn:
3d3efba0 9460 if (block_signals()) {
af254a27 9461 return -QEMU_ERESTARTSYS;
3d3efba0 9462 }
72eb7ea8 9463 return do_rt_sigreturn(cpu_env);
31e31b8a 9464 case TARGET_NR_sethostname:
579a97f7 9465 if (!(p = lock_user_string(arg1)))
2852aafd 9466 return -TARGET_EFAULT;
53a5960a
PB
9467 ret = get_errno(sethostname(p, arg2));
9468 unlock_user(p, arg1, 0);
72eb7ea8 9469 return ret;
4f7f8924 9470#ifdef TARGET_NR_setrlimit
31e31b8a 9471 case TARGET_NR_setrlimit:
9de5e440 9472 {
e22b7015 9473 int resource = target_to_host_resource(arg1);
53a5960a 9474 struct target_rlimit *target_rlim;
9de5e440 9475 struct rlimit rlim;
579a97f7 9476 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
2852aafd 9477 return -TARGET_EFAULT;
81bbe906
TY
9478 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
9479 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
53a5960a 9480 unlock_user_struct(target_rlim, arg2, 0);
5dfa88f7
MF
9481 /*
9482 * If we just passed through resource limit settings for memory then
9483 * they would also apply to QEMU's own allocations, and QEMU will
9484 * crash or hang or die if its allocations fail. Ideally we would
9485 * track the guest allocations in QEMU and apply the limits ourselves.
9486 * For now, just tell the guest the call succeeded but don't actually
9487 * limit anything.
9488 */
9489 if (resource != RLIMIT_AS &&
9490 resource != RLIMIT_DATA &&
9491 resource != RLIMIT_STACK) {
9492 return get_errno(setrlimit(resource, &rlim));
9493 } else {
9494 return 0;
9495 }
9de5e440 9496 }
4f7f8924
AR
9497#endif
9498#ifdef TARGET_NR_getrlimit
31e31b8a 9499 case TARGET_NR_getrlimit:
9de5e440 9500 {
e22b7015 9501 int resource = target_to_host_resource(arg1);
53a5960a 9502 struct target_rlimit *target_rlim;
9de5e440 9503 struct rlimit rlim;
3b46e624 9504
9de5e440
FB
9505 ret = get_errno(getrlimit(resource, &rlim));
9506 if (!is_error(ret)) {
579a97f7 9507 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
2852aafd 9508 return -TARGET_EFAULT;
81bbe906
TY
9509 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
9510 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
53a5960a 9511 unlock_user_struct(target_rlim, arg2, 1);
9de5e440
FB
9512 }
9513 }
72eb7ea8 9514 return ret;
4f7f8924 9515#endif
31e31b8a 9516 case TARGET_NR_getrusage:
b409186b
FB
9517 {
9518 struct rusage rusage;
b409186b
FB
9519 ret = get_errno(getrusage(arg1, &rusage));
9520 if (!is_error(ret)) {
a39fb273 9521 ret = host_to_target_rusage(arg2, &rusage);
b409186b
FB
9522 }
9523 }
72eb7ea8 9524 return ret;
859e8a89 9525#if defined(TARGET_NR_gettimeofday)
31e31b8a
FB
9526 case TARGET_NR_gettimeofday:
9527 {
31e31b8a 9528 struct timeval tv;
a52f5f87
RH
9529 struct timezone tz;
9530
9531 ret = get_errno(gettimeofday(&tv, &tz));
31e31b8a 9532 if (!is_error(ret)) {
a52f5f87
RH
9533 if (arg1 && copy_to_user_timeval(arg1, &tv)) {
9534 return -TARGET_EFAULT;
9535 }
9536 if (arg2 && copy_to_user_timezone(arg2, &tz)) {
2852aafd 9537 return -TARGET_EFAULT;
a52f5f87 9538 }
31e31b8a
FB
9539 }
9540 }
72eb7ea8 9541 return ret;
859e8a89
AF
9542#endif
9543#if defined(TARGET_NR_settimeofday)
31e31b8a
FB
9544 case TARGET_NR_settimeofday:
9545 {
b67d8031 9546 struct timeval tv, *ptv = NULL;
ef4467e9
PB
9547 struct timezone tz, *ptz = NULL;
9548
b67d8031
PB
9549 if (arg1) {
9550 if (copy_from_user_timeval(&tv, arg1)) {
2852aafd 9551 return -TARGET_EFAULT;
b67d8031
PB
9552 }
9553 ptv = &tv;
9554 }
ef4467e9
PB
9555
9556 if (arg2) {
9557 if (copy_from_user_timezone(&tz, arg2)) {
2852aafd 9558 return -TARGET_EFAULT;
ef4467e9
PB
9559 }
9560 ptz = &tz;
9561 }
9562
72eb7ea8 9563 return get_errno(settimeofday(ptv, ptz));
31e31b8a 9564 }
859e8a89 9565#endif
9468a5d4 9566#if defined(TARGET_NR_select)
31e31b8a 9567 case TARGET_NR_select:
5457dc9e
LV
9568#if defined(TARGET_WANT_NI_OLD_SELECT)
9569 /* some architectures used to have old_select here
9570 * but now ENOSYS it.
9571 */
9572 ret = -TARGET_ENOSYS;
9573#elif defined(TARGET_WANT_OLD_SYS_SELECT)
9574 ret = do_old_select(arg1);
9468a5d4 9575#else
5457dc9e 9576 ret = do_select(arg1, arg2, arg3, arg4, arg5);
9468a5d4 9577#endif
72eb7ea8 9578 return ret;
9e42382f
RV
9579#endif
9580#ifdef TARGET_NR_pselect6
9581 case TARGET_NR_pselect6:
e5ce9688
FB
9582 return do_pselect6(arg1, arg2, arg3, arg4, arg5, arg6, false);
9583#endif
9584#ifdef TARGET_NR_pselect6_time64
9585 case TARGET_NR_pselect6_time64:
9586 return do_pselect6(arg1, arg2, arg3, arg4, arg5, arg6, true);
048f6b4d 9587#endif
704eff6c 9588#ifdef TARGET_NR_symlink
31e31b8a 9589 case TARGET_NR_symlink:
53a5960a
PB
9590 {
9591 void *p2;
9592 p = lock_user_string(arg1);
9593 p2 = lock_user_string(arg2);
579a97f7
FB
9594 if (!p || !p2)
9595 ret = -TARGET_EFAULT;
9596 else
9597 ret = get_errno(symlink(p, p2));
53a5960a
PB
9598 unlock_user(p2, arg2, 0);
9599 unlock_user(p, arg1, 0);
9600 }
72eb7ea8 9601 return ret;
704eff6c 9602#endif
c0d472b1 9603#if defined(TARGET_NR_symlinkat)
f0b6243d 9604 case TARGET_NR_symlinkat:
f0b6243d 9605 {
579a97f7 9606 void *p2;
f0b6243d
TS
9607 p = lock_user_string(arg1);
9608 p2 = lock_user_string(arg3);
579a97f7 9609 if (!p || !p2)
0da46a6e 9610 ret = -TARGET_EFAULT;
f0b6243d 9611 else
c0d472b1 9612 ret = get_errno(symlinkat(p, arg2, p2));
579a97f7
FB
9613 unlock_user(p2, arg3, 0);
9614 unlock_user(p, arg1, 0);
f0b6243d 9615 }
72eb7ea8 9616 return ret;
f0b6243d 9617#endif
704eff6c 9618#ifdef TARGET_NR_readlink
31e31b8a 9619 case TARGET_NR_readlink:
53a5960a 9620 {
463d8e73 9621 void *p2;
53a5960a 9622 p = lock_user_string(arg1);
579a97f7 9623 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
463d8e73 9624 if (!p || !p2) {
579a97f7 9625 ret = -TARGET_EFAULT;
f17f4989
MF
9626 } else if (!arg3) {
9627 /* Short circuit this for the magic exe check. */
9628 ret = -TARGET_EINVAL;
463d8e73
AS
9629 } else if (is_proc_myself((const char *)p, "exe")) {
9630 char real[PATH_MAX], *temp;
9631 temp = realpath(exec_path, real);
f17f4989
MF
9632 /* Return value is # of bytes that we wrote to the buffer. */
9633 if (temp == NULL) {
9634 ret = get_errno(-1);
9635 } else {
9636 /* Don't worry about sign mismatch as earlier mapping
9637 * logic would have thrown a bad address error. */
9638 ret = MIN(strlen(real), arg3);
9639 /* We cannot NUL terminate the string. */
9640 memcpy(p2, real, ret);
9641 }
463d8e73
AS
9642 } else {
9643 ret = get_errno(readlink(path(p), p2, arg3));
d088d664 9644 }
53a5960a
PB
9645 unlock_user(p2, arg2, ret);
9646 unlock_user(p, arg1, 0);
9647 }
72eb7ea8 9648 return ret;
704eff6c 9649#endif
c0d472b1 9650#if defined(TARGET_NR_readlinkat)
5e0ccb18 9651 case TARGET_NR_readlinkat:
5e0ccb18 9652 {
579a97f7 9653 void *p2;
5e0ccb18 9654 p = lock_user_string(arg2);
579a97f7 9655 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
463d8e73
AS
9656 if (!p || !p2) {
9657 ret = -TARGET_EFAULT;
9658 } else if (is_proc_myself((const char *)p, "exe")) {
9659 char real[PATH_MAX], *temp;
9660 temp = realpath(exec_path, real);
9661 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
9662 snprintf((char *)p2, arg4, "%s", real);
9663 } else {
c0d472b1 9664 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
463d8e73 9665 }
579a97f7
FB
9666 unlock_user(p2, arg3, ret);
9667 unlock_user(p, arg2, 0);
5e0ccb18 9668 }
72eb7ea8 9669 return ret;
5e0ccb18 9670#endif
e5febef5 9671#ifdef TARGET_NR_swapon
31e31b8a 9672 case TARGET_NR_swapon:
579a97f7 9673 if (!(p = lock_user_string(arg1)))
2852aafd 9674 return -TARGET_EFAULT;
53a5960a
PB
9675 ret = get_errno(swapon(p, arg2));
9676 unlock_user(p, arg1, 0);
72eb7ea8 9677 return ret;
e5febef5 9678#endif
31e31b8a 9679 case TARGET_NR_reboot:
c07ecc68
LV
9680 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
9681 /* arg4 must be ignored in all other cases */
9682 p = lock_user_string(arg4);
9683 if (!p) {
2852aafd 9684 return -TARGET_EFAULT;
c07ecc68
LV
9685 }
9686 ret = get_errno(reboot(arg1, arg2, arg3, p));
9687 unlock_user(p, arg4, 0);
9688 } else {
9689 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
9690 }
72eb7ea8 9691 return ret;
e5febef5 9692#ifdef TARGET_NR_mmap
31e31b8a 9693 case TARGET_NR_mmap:
09701199
AG
9694#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
9695 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
a4c075f1
UH
9696 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
9697 || defined(TARGET_S390X)
31e31b8a 9698 {
992f48a0
BS
9699 abi_ulong *v;
9700 abi_ulong v1, v2, v3, v4, v5, v6;
579a97f7 9701 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
2852aafd 9702 return -TARGET_EFAULT;
cbb21eed
MB
9703 v1 = tswapal(v[0]);
9704 v2 = tswapal(v[1]);
9705 v3 = tswapal(v[2]);
9706 v4 = tswapal(v[3]);
9707 v5 = tswapal(v[4]);
9708 v6 = tswapal(v[5]);
53a5960a 9709 unlock_user(v, arg1, 0);
5fafdf24 9710 ret = get_errno(target_mmap(v1, v2, v3,
5286db75
FB
9711 target_to_host_bitmask(v4, mmap_flags_tbl),
9712 v5, v6));
31e31b8a 9713 }
31e31b8a 9714#else
ee1bf83d 9715 /* mmap pointers are always untagged */
5fafdf24
TS
9716 ret = get_errno(target_mmap(arg1, arg2, arg3,
9717 target_to_host_bitmask(arg4, mmap_flags_tbl),
6fb883e8
FB
9718 arg5,
9719 arg6));
31e31b8a 9720#endif
72eb7ea8 9721 return ret;
e5febef5 9722#endif
a315a145 9723#ifdef TARGET_NR_mmap2
6fb883e8 9724 case TARGET_NR_mmap2:
bb7ec043 9725#ifndef MMAP_SHIFT
c573ff67 9726#define MMAP_SHIFT 12
c573ff67 9727#endif
72eb7ea8
RH
9728 ret = target_mmap(arg1, arg2, arg3,
9729 target_to_host_bitmask(arg4, mmap_flags_tbl),
9730 arg5, arg6 << MMAP_SHIFT);
9731 return get_errno(ret);
a315a145 9732#endif
31e31b8a 9733 case TARGET_NR_munmap:
ee1bf83d 9734 arg1 = cpu_untagged_addr(cpu, arg1);
72eb7ea8 9735 return get_errno(target_munmap(arg1, arg2));
9de5e440 9736 case TARGET_NR_mprotect:
ee1bf83d 9737 arg1 = cpu_untagged_addr(cpu, arg1);
97374d38 9738 {
0429a971 9739 TaskState *ts = cpu->opaque;
97374d38
PB
9740 /* Special hack to detect libc making the stack executable. */
9741 if ((arg3 & PROT_GROWSDOWN)
9742 && arg1 >= ts->info->stack_limit
9743 && arg1 <= ts->info->start_stack) {
9744 arg3 &= ~PROT_GROWSDOWN;
9745 arg2 = arg2 + arg1 - ts->info->stack_limit;
9746 arg1 = ts->info->stack_limit;
9747 }
9748 }
72eb7ea8 9749 return get_errno(target_mprotect(arg1, arg2, arg3));
e5febef5 9750#ifdef TARGET_NR_mremap
9de5e440 9751 case TARGET_NR_mremap:
ee1bf83d
RH
9752 arg1 = cpu_untagged_addr(cpu, arg1);
9753 /* mremap new_addr (arg5) is always untagged */
72eb7ea8 9754 return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
e5febef5 9755#endif
53a5960a 9756 /* ??? msync/mlock/munlock are broken for softmmu. */
e5febef5 9757#ifdef TARGET_NR_msync
9de5e440 9758 case TARGET_NR_msync:
3e8f1628 9759 return get_errno(msync(g2h(cpu, arg1), arg2, arg3));
e5febef5
TS
9760#endif
9761#ifdef TARGET_NR_mlock
9de5e440 9762 case TARGET_NR_mlock:
3e8f1628 9763 return get_errno(mlock(g2h(cpu, arg1), arg2));
e5febef5
TS
9764#endif
9765#ifdef TARGET_NR_munlock
9de5e440 9766 case TARGET_NR_munlock:
3e8f1628 9767 return get_errno(munlock(g2h(cpu, arg1), arg2));
e5febef5
TS
9768#endif
9769#ifdef TARGET_NR_mlockall
9de5e440 9770 case TARGET_NR_mlockall:
72eb7ea8 9771 return get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
e5febef5
TS
9772#endif
9773#ifdef TARGET_NR_munlockall
9de5e440 9774 case TARGET_NR_munlockall:
72eb7ea8 9775 return get_errno(munlockall());
e5febef5 9776#endif
4f7f8924 9777#ifdef TARGET_NR_truncate
31e31b8a 9778 case TARGET_NR_truncate:
579a97f7 9779 if (!(p = lock_user_string(arg1)))
2852aafd 9780 return -TARGET_EFAULT;
53a5960a
PB
9781 ret = get_errno(truncate(p, arg2));
9782 unlock_user(p, arg1, 0);
72eb7ea8 9783 return ret;
4f7f8924
AR
9784#endif
9785#ifdef TARGET_NR_ftruncate
31e31b8a 9786 case TARGET_NR_ftruncate:
72eb7ea8 9787 return get_errno(ftruncate(arg1, arg2));
4f7f8924 9788#endif
31e31b8a 9789 case TARGET_NR_fchmod:
72eb7ea8 9790 return get_errno(fchmod(arg1, arg2));
c0d472b1 9791#if defined(TARGET_NR_fchmodat)
814d7977 9792 case TARGET_NR_fchmodat:
579a97f7 9793 if (!(p = lock_user_string(arg2)))
2852aafd 9794 return -TARGET_EFAULT;
c0d472b1 9795 ret = get_errno(fchmodat(arg1, p, arg3, 0));
579a97f7 9796 unlock_user(p, arg2, 0);
72eb7ea8 9797 return ret;
814d7977 9798#endif
31e31b8a 9799 case TARGET_NR_getpriority:
95c09828
RH
9800 /* Note that negative values are valid for getpriority, so we must
9801 differentiate based on errno settings. */
9802 errno = 0;
9803 ret = getpriority(arg1, arg2);
9804 if (ret == -1 && errno != 0) {
72eb7ea8 9805 return -host_to_target_errno(errno);
95c09828
RH
9806 }
9807#ifdef TARGET_ALPHA
9808 /* Return value is the unbiased priority. Signal no error. */
9809 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
9810#else
9811 /* Return value is a biased priority to avoid negative numbers. */
9812 ret = 20 - ret;
9813#endif
72eb7ea8 9814 return ret;
31e31b8a 9815 case TARGET_NR_setpriority:
72eb7ea8 9816 return get_errno(setpriority(arg1, arg2, arg3));
4f7f8924 9817#ifdef TARGET_NR_statfs
31e31b8a 9818 case TARGET_NR_statfs:
2852aafd
RH
9819 if (!(p = lock_user_string(arg1))) {
9820 return -TARGET_EFAULT;
9821 }
53a5960a
PB
9822 ret = get_errno(statfs(path(p), &stfs));
9823 unlock_user(p, arg1, 0);
31e31b8a
FB
9824 convert_statfs:
9825 if (!is_error(ret)) {
53a5960a 9826 struct target_statfs *target_stfs;
3b46e624 9827
579a97f7 9828 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
2852aafd 9829 return -TARGET_EFAULT;
579a97f7
FB
9830 __put_user(stfs.f_type, &target_stfs->f_type);
9831 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
9832 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
9833 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
9834 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
9835 __put_user(stfs.f_files, &target_stfs->f_files);
9836 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
9837 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
9838 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
9839 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
229d3376 9840 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
d4247ec2
SL
9841#ifdef _STATFS_F_FLAGS
9842 __put_user(stfs.f_flags, &target_stfs->f_flags);
9843#else
9844 __put_user(0, &target_stfs->f_flags);
9845#endif
229d3376 9846 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
53a5960a 9847 unlock_user_struct(target_stfs, arg2, 1);
31e31b8a 9848 }
72eb7ea8 9849 return ret;
4f7f8924
AR
9850#endif
9851#ifdef TARGET_NR_fstatfs
31e31b8a 9852 case TARGET_NR_fstatfs:
56c8f68f 9853 ret = get_errno(fstatfs(arg1, &stfs));
31e31b8a 9854 goto convert_statfs;
4f7f8924 9855#endif
56c8f68f
FB
9856#ifdef TARGET_NR_statfs64
9857 case TARGET_NR_statfs64:
2852aafd
RH
9858 if (!(p = lock_user_string(arg1))) {
9859 return -TARGET_EFAULT;
9860 }
53a5960a
PB
9861 ret = get_errno(statfs(path(p), &stfs));
9862 unlock_user(p, arg1, 0);
56c8f68f
FB
9863 convert_statfs64:
9864 if (!is_error(ret)) {
53a5960a 9865 struct target_statfs64 *target_stfs;
3b46e624 9866
579a97f7 9867 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
2852aafd 9868 return -TARGET_EFAULT;
579a97f7
FB
9869 __put_user(stfs.f_type, &target_stfs->f_type);
9870 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
9871 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
9872 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
9873 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
9874 __put_user(stfs.f_files, &target_stfs->f_files);
9875 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
9876 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
9877 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
9878 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
229d3376 9879 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
b94e2b4e
F
9880#ifdef _STATFS_F_FLAGS
9881 __put_user(stfs.f_flags, &target_stfs->f_flags);
9882#else
9883 __put_user(0, &target_stfs->f_flags);
9884#endif
229d3376 9885 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
579a97f7 9886 unlock_user_struct(target_stfs, arg3, 1);
56c8f68f 9887 }
72eb7ea8 9888 return ret;
56c8f68f
FB
9889 case TARGET_NR_fstatfs64:
9890 ret = get_errno(fstatfs(arg1, &stfs));
9891 goto convert_statfs64;
9892#endif
e5febef5 9893#ifdef TARGET_NR_socketcall
31e31b8a 9894 case TARGET_NR_socketcall:
72eb7ea8 9895 return do_socketcall(arg1, arg2);
e5febef5 9896#endif
3532fa74
FB
9897#ifdef TARGET_NR_accept
9898 case TARGET_NR_accept:
72eb7ea8 9899 return do_accept4(arg1, arg2, arg3, 0);
a94b4987
PM
9900#endif
9901#ifdef TARGET_NR_accept4
9902 case TARGET_NR_accept4:
72eb7ea8 9903 return do_accept4(arg1, arg2, arg3, arg4);
3532fa74
FB
9904#endif
9905#ifdef TARGET_NR_bind
9906 case TARGET_NR_bind:
72eb7ea8 9907 return do_bind(arg1, arg2, arg3);
3532fa74
FB
9908#endif
9909#ifdef TARGET_NR_connect
9910 case TARGET_NR_connect:
72eb7ea8 9911 return do_connect(arg1, arg2, arg3);
3532fa74
FB
9912#endif
9913#ifdef TARGET_NR_getpeername
9914 case TARGET_NR_getpeername:
72eb7ea8 9915 return do_getpeername(arg1, arg2, arg3);
3532fa74
FB
9916#endif
9917#ifdef TARGET_NR_getsockname
9918 case TARGET_NR_getsockname:
72eb7ea8 9919 return do_getsockname(arg1, arg2, arg3);
3532fa74
FB
9920#endif
9921#ifdef TARGET_NR_getsockopt
9922 case TARGET_NR_getsockopt:
72eb7ea8 9923 return do_getsockopt(arg1, arg2, arg3, arg4, arg5);
3532fa74
FB
9924#endif
9925#ifdef TARGET_NR_listen
9926 case TARGET_NR_listen:
72eb7ea8 9927 return get_errno(listen(arg1, arg2));
3532fa74
FB
9928#endif
9929#ifdef TARGET_NR_recv
9930 case TARGET_NR_recv:
72eb7ea8 9931 return do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
3532fa74
FB
9932#endif
9933#ifdef TARGET_NR_recvfrom
9934 case TARGET_NR_recvfrom:
72eb7ea8 9935 return do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
3532fa74
FB
9936#endif
9937#ifdef TARGET_NR_recvmsg
9938 case TARGET_NR_recvmsg:
72eb7ea8 9939 return do_sendrecvmsg(arg1, arg2, arg3, 0);
3532fa74
FB
9940#endif
9941#ifdef TARGET_NR_send
9942 case TARGET_NR_send:
72eb7ea8 9943 return do_sendto(arg1, arg2, arg3, arg4, 0, 0);
3532fa74
FB
9944#endif
9945#ifdef TARGET_NR_sendmsg
9946 case TARGET_NR_sendmsg:
72eb7ea8 9947 return do_sendrecvmsg(arg1, arg2, arg3, 1);
3532fa74 9948#endif
f19e00d7
AG
9949#ifdef TARGET_NR_sendmmsg
9950 case TARGET_NR_sendmmsg:
72eb7ea8 9951 return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
859e8a89
AF
9952#endif
9953#ifdef TARGET_NR_recvmmsg
f19e00d7 9954 case TARGET_NR_recvmmsg:
72eb7ea8 9955 return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
f19e00d7 9956#endif
3532fa74
FB
9957#ifdef TARGET_NR_sendto
9958 case TARGET_NR_sendto:
72eb7ea8 9959 return do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
3532fa74
FB
9960#endif
9961#ifdef TARGET_NR_shutdown
9962 case TARGET_NR_shutdown:
72eb7ea8 9963 return get_errno(shutdown(arg1, arg2));
3532fa74 9964#endif
f894efd1
LV
9965#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
9966 case TARGET_NR_getrandom:
9967 p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9968 if (!p) {
2852aafd 9969 return -TARGET_EFAULT;
f894efd1
LV
9970 }
9971 ret = get_errno(getrandom(p, arg2, arg3));
9972 unlock_user(p, arg1, ret);
72eb7ea8 9973 return ret;
f894efd1 9974#endif
3532fa74
FB
9975#ifdef TARGET_NR_socket
9976 case TARGET_NR_socket:
72eb7ea8 9977 return do_socket(arg1, arg2, arg3);
3532fa74
FB
9978#endif
9979#ifdef TARGET_NR_socketpair
9980 case TARGET_NR_socketpair:
72eb7ea8 9981 return do_socketpair(arg1, arg2, arg3, arg4);
3532fa74
FB
9982#endif
9983#ifdef TARGET_NR_setsockopt
9984 case TARGET_NR_setsockopt:
72eb7ea8 9985 return do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
3532fa74 9986#endif
da2c8ad7 9987#if defined(TARGET_NR_syslog)
31e31b8a 9988 case TARGET_NR_syslog:
da2c8ad7
AM
9989 {
9990 int len = arg2;
7494b0f9 9991
da2c8ad7
AM
9992 switch (arg1) {
9993 case TARGET_SYSLOG_ACTION_CLOSE: /* Close log */
9994 case TARGET_SYSLOG_ACTION_OPEN: /* Open log */
9995 case TARGET_SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
9996 case TARGET_SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging */
9997 case TARGET_SYSLOG_ACTION_CONSOLE_ON: /* Enable logging */
9998 case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: /* Set messages level */
9999 case TARGET_SYSLOG_ACTION_SIZE_UNREAD: /* Number of chars */
10000 case TARGET_SYSLOG_ACTION_SIZE_BUFFER: /* Size of the buffer */
72eb7ea8 10001 return get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
da2c8ad7
AM
10002 case TARGET_SYSLOG_ACTION_READ: /* Read from log */
10003 case TARGET_SYSLOG_ACTION_READ_CLEAR: /* Read/clear msgs */
10004 case TARGET_SYSLOG_ACTION_READ_ALL: /* Read last messages */
10005 {
da2c8ad7 10006 if (len < 0) {
259841c1 10007 return -TARGET_EINVAL;
da2c8ad7 10008 }
da2c8ad7 10009 if (len == 0) {
72eb7ea8 10010 return 0;
da2c8ad7
AM
10011 }
10012 p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
10013 if (!p) {
259841c1 10014 return -TARGET_EFAULT;
da2c8ad7
AM
10015 }
10016 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
10017 unlock_user(p, arg2, arg3);
10018 }
72eb7ea8 10019 return ret;
da2c8ad7 10020 default:
72eb7ea8 10021 return -TARGET_EINVAL;
da2c8ad7
AM
10022 }
10023 }
10024 break;
10025#endif
31e31b8a 10026 case TARGET_NR_setitimer:
66fb9763 10027 {
66fb9763
FB
10028 struct itimerval value, ovalue, *pvalue;
10029
53a5960a 10030 if (arg2) {
66fb9763 10031 pvalue = &value;
788f5ec4
TS
10032 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
10033 || copy_from_user_timeval(&pvalue->it_value,
10034 arg2 + sizeof(struct target_timeval)))
2852aafd 10035 return -TARGET_EFAULT;
66fb9763
FB
10036 } else {
10037 pvalue = NULL;
10038 }
10039 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
53a5960a 10040 if (!is_error(ret) && arg3) {
788f5ec4
TS
10041 if (copy_to_user_timeval(arg3,
10042 &ovalue.it_interval)
10043 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
10044 &ovalue.it_value))
2852aafd 10045 return -TARGET_EFAULT;
66fb9763
FB
10046 }
10047 }
72eb7ea8 10048 return ret;
31e31b8a 10049 case TARGET_NR_getitimer:
66fb9763 10050 {
66fb9763 10051 struct itimerval value;
3b46e624 10052
66fb9763 10053 ret = get_errno(getitimer(arg1, &value));
53a5960a 10054 if (!is_error(ret) && arg2) {
788f5ec4
TS
10055 if (copy_to_user_timeval(arg2,
10056 &value.it_interval)
10057 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
10058 &value.it_value))
2852aafd 10059 return -TARGET_EFAULT;
66fb9763
FB
10060 }
10061 }
72eb7ea8 10062 return ret;
704eff6c 10063#ifdef TARGET_NR_stat
31e31b8a 10064 case TARGET_NR_stat:
2852aafd
RH
10065 if (!(p = lock_user_string(arg1))) {
10066 return -TARGET_EFAULT;
10067 }
53a5960a
PB
10068 ret = get_errno(stat(path(p), &st));
10069 unlock_user(p, arg1, 0);
31e31b8a 10070 goto do_stat;
704eff6c
CG
10071#endif
10072#ifdef TARGET_NR_lstat
31e31b8a 10073 case TARGET_NR_lstat:
2852aafd
RH
10074 if (!(p = lock_user_string(arg1))) {
10075 return -TARGET_EFAULT;
10076 }
53a5960a
PB
10077 ret = get_errno(lstat(path(p), &st));
10078 unlock_user(p, arg1, 0);
31e31b8a 10079 goto do_stat;
704eff6c 10080#endif
4f7f8924 10081#ifdef TARGET_NR_fstat
31e31b8a
FB
10082 case TARGET_NR_fstat:
10083 {
10084 ret = get_errno(fstat(arg1, &st));
704eff6c 10085#if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat)
31e31b8a 10086 do_stat:
704eff6c 10087#endif
31e31b8a 10088 if (!is_error(ret)) {
53a5960a 10089 struct target_stat *target_st;
e3584658 10090
579a97f7 10091 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
2852aafd 10092 return -TARGET_EFAULT;
12727917 10093 memset(target_st, 0, sizeof(*target_st));
d2fd1af7
FB
10094 __put_user(st.st_dev, &target_st->st_dev);
10095 __put_user(st.st_ino, &target_st->st_ino);
10096 __put_user(st.st_mode, &target_st->st_mode);
10097 __put_user(st.st_uid, &target_st->st_uid);
10098 __put_user(st.st_gid, &target_st->st_gid);
10099 __put_user(st.st_nlink, &target_st->st_nlink);
10100 __put_user(st.st_rdev, &target_st->st_rdev);
10101 __put_user(st.st_size, &target_st->st_size);
10102 __put_user(st.st_blksize, &target_st->st_blksize);
10103 __put_user(st.st_blocks, &target_st->st_blocks);
10104 __put_user(st.st_atime, &target_st->target_st_atime);
10105 __put_user(st.st_mtime, &target_st->target_st_mtime);
10106 __put_user(st.st_ctime, &target_st->target_st_ctime);
febf6fad 10107#if defined(HAVE_STRUCT_STAT_ST_ATIM) && defined(TARGET_STAT_HAVE_NSEC)
5f992db6
CYT
10108 __put_user(st.st_atim.tv_nsec,
10109 &target_st->target_st_atime_nsec);
10110 __put_user(st.st_mtim.tv_nsec,
10111 &target_st->target_st_mtime_nsec);
10112 __put_user(st.st_ctim.tv_nsec,
10113 &target_st->target_st_ctime_nsec);
10114#endif
53a5960a 10115 unlock_user_struct(target_st, arg2, 1);
31e31b8a
FB
10116 }
10117 }
72eb7ea8 10118 return ret;
ebc05488 10119#endif
31e31b8a 10120 case TARGET_NR_vhangup:
72eb7ea8 10121 return get_errno(vhangup());
42ad6ae9
FB
10122#ifdef TARGET_NR_syscall
10123 case TARGET_NR_syscall:
72eb7ea8
RH
10124 return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
10125 arg6, arg7, arg8, 0);
ebc05488 10126#endif
859e8a89 10127#if defined(TARGET_NR_wait4)
31e31b8a
FB
10128 case TARGET_NR_wait4:
10129 {
10130 int status;
992f48a0 10131 abi_long status_ptr = arg2;
31e31b8a 10132 struct rusage rusage, *rusage_ptr;
992f48a0 10133 abi_ulong target_rusage = arg4;
a39fb273 10134 abi_long rusage_err;
31e31b8a
FB
10135 if (target_rusage)
10136 rusage_ptr = &rusage;
10137 else
10138 rusage_ptr = NULL;
4af80a37 10139 ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr));
31e31b8a 10140 if (!is_error(ret)) {
5379557b 10141 if (status_ptr && ret) {
1d9d8b55 10142 status = host_to_target_waitstatus(status);
2f619698 10143 if (put_user_s32(status, status_ptr))
2852aafd 10144 return -TARGET_EFAULT;
31e31b8a 10145 }
a39fb273
PJ
10146 if (target_rusage) {
10147 rusage_err = host_to_target_rusage(target_rusage, &rusage);
10148 if (rusage_err) {
10149 ret = rusage_err;
10150 }
10151 }
31e31b8a
FB
10152 }
10153 }
72eb7ea8 10154 return ret;
859e8a89 10155#endif
e5febef5 10156#ifdef TARGET_NR_swapoff
31e31b8a 10157 case TARGET_NR_swapoff:
579a97f7 10158 if (!(p = lock_user_string(arg1)))
2852aafd 10159 return -TARGET_EFAULT;
53a5960a
PB
10160 ret = get_errno(swapoff(p));
10161 unlock_user(p, arg1, 0);
72eb7ea8 10162 return ret;
e5febef5 10163#endif
31e31b8a 10164 case TARGET_NR_sysinfo:
a5448a7d 10165 {
53a5960a 10166 struct target_sysinfo *target_value;
a5448a7d
FB
10167 struct sysinfo value;
10168 ret = get_errno(sysinfo(&value));
53a5960a 10169 if (!is_error(ret) && arg1)
a5448a7d 10170 {
579a97f7 10171 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
2852aafd 10172 return -TARGET_EFAULT;
a5448a7d
FB
10173 __put_user(value.uptime, &target_value->uptime);
10174 __put_user(value.loads[0], &target_value->loads[0]);
10175 __put_user(value.loads[1], &target_value->loads[1]);
10176 __put_user(value.loads[2], &target_value->loads[2]);
10177 __put_user(value.totalram, &target_value->totalram);
10178 __put_user(value.freeram, &target_value->freeram);
10179 __put_user(value.sharedram, &target_value->sharedram);
10180 __put_user(value.bufferram, &target_value->bufferram);
10181 __put_user(value.totalswap, &target_value->totalswap);
10182 __put_user(value.freeswap, &target_value->freeswap);
10183 __put_user(value.procs, &target_value->procs);
10184 __put_user(value.totalhigh, &target_value->totalhigh);
10185 __put_user(value.freehigh, &target_value->freehigh);
10186 __put_user(value.mem_unit, &target_value->mem_unit);
53a5960a 10187 unlock_user_struct(target_value, arg1, 1);
a5448a7d
FB
10188 }
10189 }
72eb7ea8 10190 return ret;
e5febef5 10191#ifdef TARGET_NR_ipc
31e31b8a 10192 case TARGET_NR_ipc:
72eb7ea8 10193 return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
e5febef5 10194#endif
e5289087
AJ
10195#ifdef TARGET_NR_semget
10196 case TARGET_NR_semget:
72eb7ea8 10197 return get_errno(semget(arg1, arg2, arg3));
e5289087
AJ
10198#endif
10199#ifdef TARGET_NR_semop
10200 case TARGET_NR_semop:
cac46eb0 10201 return do_semtimedop(arg1, arg2, arg3, 0, false);
d8c08b1e
MK
10202#endif
10203#ifdef TARGET_NR_semtimedop
10204 case TARGET_NR_semtimedop:
cac46eb0
FB
10205 return do_semtimedop(arg1, arg2, arg3, arg4, false);
10206#endif
10207#ifdef TARGET_NR_semtimedop_time64
10208 case TARGET_NR_semtimedop_time64:
10209 return do_semtimedop(arg1, arg2, arg3, arg4, true);
e5289087
AJ
10210#endif
10211#ifdef TARGET_NR_semctl
10212 case TARGET_NR_semctl:
72eb7ea8 10213 return do_semctl(arg1, arg2, arg3, arg4);
e5289087 10214#endif
eeb438c1
AJ
10215#ifdef TARGET_NR_msgctl
10216 case TARGET_NR_msgctl:
72eb7ea8 10217 return do_msgctl(arg1, arg2, arg3);
eeb438c1
AJ
10218#endif
10219#ifdef TARGET_NR_msgget
10220 case TARGET_NR_msgget:
72eb7ea8 10221 return get_errno(msgget(arg1, arg2));
eeb438c1
AJ
10222#endif
10223#ifdef TARGET_NR_msgrcv
10224 case TARGET_NR_msgrcv:
72eb7ea8 10225 return do_msgrcv(arg1, arg2, arg3, arg4, arg5);
eeb438c1
AJ
10226#endif
10227#ifdef TARGET_NR_msgsnd
10228 case TARGET_NR_msgsnd:
72eb7ea8 10229 return do_msgsnd(arg1, arg2, arg3, arg4);
88a8c984
RV
10230#endif
10231#ifdef TARGET_NR_shmget
10232 case TARGET_NR_shmget:
72eb7ea8 10233 return get_errno(shmget(arg1, arg2, arg3));
88a8c984
RV
10234#endif
10235#ifdef TARGET_NR_shmctl
10236 case TARGET_NR_shmctl:
72eb7ea8 10237 return do_shmctl(arg1, arg2, arg3);
88a8c984
RV
10238#endif
10239#ifdef TARGET_NR_shmat
10240 case TARGET_NR_shmat:
72eb7ea8 10241 return do_shmat(cpu_env, arg1, arg2, arg3);
88a8c984
RV
10242#endif
10243#ifdef TARGET_NR_shmdt
10244 case TARGET_NR_shmdt:
72eb7ea8 10245 return do_shmdt(arg1);
eeb438c1 10246#endif
31e31b8a 10247 case TARGET_NR_fsync:
72eb7ea8 10248 return get_errno(fsync(arg1));
31e31b8a 10249 case TARGET_NR_clone:
4ce6243d
PM
10250 /* Linux manages to have three different orderings for its
10251 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
10252 * match the kernel's CONFIG_CLONE_* settings.
10253 * Microblaze is further special in that it uses a sixth
10254 * implicit argument to clone for the TLS pointer.
10255 */
10256#if defined(TARGET_MICROBLAZE)
a5b3bdcb 10257 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
4ce6243d
PM
10258#elif defined(TARGET_CLONE_BACKWARDS)
10259 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
10260#elif defined(TARGET_CLONE_BACKWARDS2)
a4c075f1 10261 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
0b6d3ae0 10262#else
4ce6243d 10263 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
0b6d3ae0 10264#endif
72eb7ea8 10265 return ret;
ec86b0fb
FB
10266#ifdef __NR_exit_group
10267 /* new thread calls */
10268 case TARGET_NR_exit_group:
708b6a64 10269 preexit_cleanup(cpu_env, arg1);
72eb7ea8 10270 return get_errno(exit_group(arg1));
ec86b0fb 10271#endif
31e31b8a 10272 case TARGET_NR_setdomainname:
579a97f7 10273 if (!(p = lock_user_string(arg1)))
2852aafd 10274 return -TARGET_EFAULT;
53a5960a
PB
10275 ret = get_errno(setdomainname(p, arg2));
10276 unlock_user(p, arg1, 0);
72eb7ea8 10277 return ret;
31e31b8a
FB
10278 case TARGET_NR_uname:
10279 /* no need to transcode because we use the linux syscall */
29e619b1
FB
10280 {
10281 struct new_utsname * buf;
3b46e624 10282
579a97f7 10283 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
2852aafd 10284 return -TARGET_EFAULT;
29e619b1
FB
10285 ret = get_errno(sys_uname(buf));
10286 if (!is_error(ret)) {
332c9781 10287 /* Overwrite the native machine name with whatever is being
29e619b1 10288 emulated. */
871f95c6
PMD
10289 g_strlcpy(buf->machine, cpu_to_uname_machine(cpu_env),
10290 sizeof(buf->machine));
c5937220 10291 /* Allow the user to override the reported release. */
332c9781
PM
10292 if (qemu_uname_release && *qemu_uname_release) {
10293 g_strlcpy(buf->release, qemu_uname_release,
10294 sizeof(buf->release));
10295 }
29e619b1 10296 }
53a5960a 10297 unlock_user_struct(buf, arg1, 1);
29e619b1 10298 }
72eb7ea8 10299 return ret;
6dbad63e 10300#ifdef TARGET_I386
31e31b8a 10301 case TARGET_NR_modify_ldt:
72eb7ea8 10302 return do_modify_ldt(cpu_env, arg1, arg2, arg3);
84409ddb 10303#if !defined(TARGET_X86_64)
5cd4393b 10304 case TARGET_NR_vm86:
72eb7ea8 10305 return do_vm86(cpu_env, arg1, arg2);
84409ddb 10306#endif
6dbad63e 10307#endif
859e8a89 10308#if defined(TARGET_NR_adjtimex)
31e31b8a 10309 case TARGET_NR_adjtimex:
19f59bce
AM
10310 {
10311 struct timex host_buf;
10312
10313 if (target_to_host_timex(&host_buf, arg1) != 0) {
2852aafd 10314 return -TARGET_EFAULT;
19f59bce
AM
10315 }
10316 ret = get_errno(adjtimex(&host_buf));
10317 if (!is_error(ret)) {
10318 if (host_to_target_timex(arg1, &host_buf) != 0) {
2852aafd 10319 return -TARGET_EFAULT;
19f59bce
AM
10320 }
10321 }
10322 }
72eb7ea8 10323 return ret;
859e8a89 10324#endif
38860a03
AM
10325#if defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME)
10326 case TARGET_NR_clock_adjtime:
10327 {
10328 struct timex htx, *phtx = &htx;
10329
10330 if (target_to_host_timex(phtx, arg2) != 0) {
2852aafd 10331 return -TARGET_EFAULT;
38860a03
AM
10332 }
10333 ret = get_errno(clock_adjtime(arg1, phtx));
10334 if (!is_error(ret) && phtx) {
10335 if (host_to_target_timex(arg2, phtx) != 0) {
2852aafd 10336 return -TARGET_EFAULT;
38860a03
AM
10337 }
10338 }
10339 }
72eb7ea8 10340 return ret;
6ac03b2c
FB
10341#endif
10342#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
10343 case TARGET_NR_clock_adjtime64:
10344 {
10345 struct timex htx;
10346
10347 if (target_to_host_timex64(&htx, arg2) != 0) {
10348 return -TARGET_EFAULT;
10349 }
10350 ret = get_errno(clock_adjtime(arg1, &htx));
10351 if (!is_error(ret) && host_to_target_timex64(arg2, &htx)) {
10352 return -TARGET_EFAULT;
10353 }
10354 }
10355 return ret;
38860a03 10356#endif
31e31b8a 10357 case TARGET_NR_getpgid:
72eb7ea8 10358 return get_errno(getpgid(arg1));
31e31b8a 10359 case TARGET_NR_fchdir:
72eb7ea8 10360 return get_errno(fchdir(arg1));
31e31b8a 10361 case TARGET_NR_personality:
72eb7ea8 10362 return get_errno(personality(arg1));
7a3148a9 10363#ifdef TARGET_NR__llseek /* Not on alpha */
31e31b8a
FB
10364 case TARGET_NR__llseek:
10365 {
0c1592d9 10366 int64_t res;
d35b261c 10367#if !defined(__NR_llseek)
9fea273c 10368 res = lseek(arg1, ((uint64_t)arg2 << 32) | (abi_ulong)arg3, arg5);
0c1592d9
PM
10369 if (res == -1) {
10370 ret = get_errno(res);
10371 } else {
10372 ret = 0;
10373 }
4f2ac237 10374#else
31e31b8a 10375 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4f2ac237 10376#endif
0c1592d9 10377 if ((ret == 0) && put_user_s64(res, arg4)) {
2852aafd 10378 return -TARGET_EFAULT;
0c1592d9 10379 }
31e31b8a 10380 }
72eb7ea8 10381 return ret;
7a3148a9 10382#endif
704eff6c 10383#ifdef TARGET_NR_getdents
31e31b8a 10384 case TARGET_NR_getdents:
fd08ddb9 10385 return do_getdents(arg1, arg2, arg3);
704eff6c 10386#endif /* TARGET_NR_getdents */
3ae43202 10387#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
dab2ed99 10388 case TARGET_NR_getdents64:
fd08ddb9 10389 return do_getdents64(arg1, arg2, arg3);
a541f297 10390#endif /* TARGET_NR_getdents64 */
9468a5d4 10391#if defined(TARGET_NR__newselect)
31e31b8a 10392 case TARGET_NR__newselect:
72eb7ea8 10393 return do_select(arg1, arg2, arg3, arg4, arg5);
e5febef5 10394#endif
e5ce9688 10395#ifdef TARGET_NR_poll
9de5e440 10396 case TARGET_NR_poll:
e5ce9688
FB
10397 return do_ppoll(arg1, arg2, arg3, arg4, arg5, false, false);
10398#endif
10399#ifdef TARGET_NR_ppoll
d8035d4c 10400 case TARGET_NR_ppoll:
e5ce9688
FB
10401 return do_ppoll(arg1, arg2, arg3, arg4, arg5, true, false);
10402#endif
10403#ifdef TARGET_NR_ppoll_time64
10404 case TARGET_NR_ppoll_time64:
10405 return do_ppoll(arg1, arg2, arg3, arg4, arg5, true, true);
e5febef5 10406#endif
31e31b8a 10407 case TARGET_NR_flock:
9de5e440
FB
10408 /* NOTE: the flock constant seems to be the same for every
10409 Linux platform */
72eb7ea8 10410 return get_errno(safe_flock(arg1, arg2));
31e31b8a
FB
10411 case TARGET_NR_readv:
10412 {
f287b2c2
RH
10413 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
10414 if (vec != NULL) {
918c03ed 10415 ret = get_errno(safe_readv(arg1, vec, arg3));
f287b2c2
RH
10416 unlock_iovec(vec, arg2, arg3, 1);
10417 } else {
10418 ret = -host_to_target_errno(errno);
10419 }
31e31b8a 10420 }
72eb7ea8 10421 return ret;
31e31b8a
FB
10422 case TARGET_NR_writev:
10423 {
f287b2c2
RH
10424 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10425 if (vec != NULL) {
918c03ed 10426 ret = get_errno(safe_writev(arg1, vec, arg3));
f287b2c2
RH
10427 unlock_iovec(vec, arg2, arg3, 0);
10428 } else {
10429 ret = -host_to_target_errno(errno);
10430 }
31e31b8a 10431 }
72eb7ea8 10432 return ret;
0f26386c
DJ
10433#if defined(TARGET_NR_preadv)
10434 case TARGET_NR_preadv:
10435 {
10436 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
10437 if (vec != NULL) {
9ac22517
MF
10438 unsigned long low, high;
10439
10440 target_to_host_low_high(arg4, arg5, &low, &high);
10441 ret = get_errno(safe_preadv(arg1, vec, arg3, low, high));
0f26386c
DJ
10442 unlock_iovec(vec, arg2, arg3, 1);
10443 } else {
10444 ret = -host_to_target_errno(errno);
f8d00fba
DJ
10445 }
10446 }
72eb7ea8 10447 return ret;
f8d00fba
DJ
10448#endif
10449#if defined(TARGET_NR_pwritev)
10450 case TARGET_NR_pwritev:
10451 {
10452 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10453 if (vec != NULL) {
9ac22517
MF
10454 unsigned long low, high;
10455
10456 target_to_host_low_high(arg4, arg5, &low, &high);
10457 ret = get_errno(safe_pwritev(arg1, vec, arg3, low, high));
f8d00fba
DJ
10458 unlock_iovec(vec, arg2, arg3, 0);
10459 } else {
10460 ret = -host_to_target_errno(errno);
0f26386c
DJ
10461 }
10462 }
72eb7ea8 10463 return ret;
0f26386c 10464#endif
31e31b8a 10465 case TARGET_NR_getsid:
72eb7ea8 10466 return get_errno(getsid(arg1));
7a3148a9 10467#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
31e31b8a 10468 case TARGET_NR_fdatasync:
72eb7ea8 10469 return get_errno(fdatasync(arg1));
704eff6c 10470#endif
737de1d1
MF
10471 case TARGET_NR_sched_getaffinity:
10472 {
10473 unsigned int mask_size;
10474 unsigned long *mask;
10475
10476 /*
10477 * sched_getaffinity needs multiples of ulong, so need to take
10478 * care of mismatches between target ulong and host ulong sizes.
10479 */
10480 if (arg2 & (sizeof(abi_ulong) - 1)) {
72eb7ea8 10481 return -TARGET_EINVAL;
737de1d1
MF
10482 }
10483 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
10484
10485 mask = alloca(mask_size);
2e0a8713 10486 memset(mask, 0, mask_size);
737de1d1
MF
10487 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
10488
10489 if (!is_error(ret)) {
be3bd286
PM
10490 if (ret > arg2) {
10491 /* More data returned than the caller's buffer will fit.
10492 * This only happens if sizeof(abi_long) < sizeof(long)
10493 * and the caller passed us a buffer holding an odd number
10494 * of abi_longs. If the host kernel is actually using the
10495 * extra 4 bytes then fail EINVAL; otherwise we can just
10496 * ignore them and only copy the interesting part.
10497 */
10498 int numcpus = sysconf(_SC_NPROCESSORS_CONF);
10499 if (numcpus > arg2 * 8) {
72eb7ea8 10500 return -TARGET_EINVAL;
be3bd286
PM
10501 }
10502 ret = arg2;
10503 }
10504
5fdefcf8 10505 if (host_to_target_cpu_mask(mask, mask_size, arg3, ret)) {
2852aafd 10506 return -TARGET_EFAULT;
5fdefcf8 10507 }
737de1d1
MF
10508 }
10509 }
72eb7ea8 10510 return ret;
737de1d1
MF
10511 case TARGET_NR_sched_setaffinity:
10512 {
10513 unsigned int mask_size;
10514 unsigned long *mask;
10515
10516 /*
10517 * sched_setaffinity needs multiples of ulong, so need to take
10518 * care of mismatches between target ulong and host ulong sizes.
10519 */
10520 if (arg2 & (sizeof(abi_ulong) - 1)) {
72eb7ea8 10521 return -TARGET_EINVAL;
737de1d1
MF
10522 }
10523 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
737de1d1 10524 mask = alloca(mask_size);
2e0a8713
ST
10525
10526 ret = target_to_host_cpu_mask(mask, mask_size, arg3, arg2);
10527 if (ret) {
72eb7ea8 10528 return ret;
737de1d1 10529 }
737de1d1 10530
72eb7ea8 10531 return get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
737de1d1 10532 }
b827c3ed
ST
10533 case TARGET_NR_getcpu:
10534 {
10535 unsigned cpu, node;
10536 ret = get_errno(sys_getcpu(arg1 ? &cpu : NULL,
10537 arg2 ? &node : NULL,
10538 NULL));
10539 if (is_error(ret)) {
259841c1 10540 return ret;
b827c3ed
ST
10541 }
10542 if (arg1 && put_user_u32(cpu, arg1)) {
2852aafd 10543 return -TARGET_EFAULT;
b827c3ed
ST
10544 }
10545 if (arg2 && put_user_u32(node, arg2)) {
2852aafd 10546 return -TARGET_EFAULT;
b827c3ed
ST
10547 }
10548 }
72eb7ea8 10549 return ret;
31e31b8a 10550 case TARGET_NR_sched_setparam:
5cd4393b 10551 {
53a5960a 10552 struct sched_param *target_schp;
5cd4393b 10553 struct sched_param schp;
53a5960a 10554
a1d5c5b2
TM
10555 if (arg2 == 0) {
10556 return -TARGET_EINVAL;
10557 }
579a97f7 10558 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
2852aafd 10559 return -TARGET_EFAULT;
5cd4393b 10560 schp.sched_priority = tswap32(target_schp->sched_priority);
53a5960a 10561 unlock_user_struct(target_schp, arg2, 0);
72eb7ea8 10562 return get_errno(sched_setparam(arg1, &schp));
5cd4393b 10563 }
31e31b8a 10564 case TARGET_NR_sched_getparam:
5cd4393b 10565 {
53a5960a 10566 struct sched_param *target_schp;
5cd4393b 10567 struct sched_param schp;
a1d5c5b2
TM
10568
10569 if (arg2 == 0) {
10570 return -TARGET_EINVAL;
10571 }
5cd4393b
FB
10572 ret = get_errno(sched_getparam(arg1, &schp));
10573 if (!is_error(ret)) {
579a97f7 10574 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
2852aafd 10575 return -TARGET_EFAULT;
5cd4393b 10576 target_schp->sched_priority = tswap32(schp.sched_priority);
53a5960a 10577 unlock_user_struct(target_schp, arg2, 1);
5cd4393b
FB
10578 }
10579 }
72eb7ea8 10580 return ret;
31e31b8a 10581 case TARGET_NR_sched_setscheduler:
5cd4393b 10582 {
53a5960a 10583 struct sched_param *target_schp;
5cd4393b 10584 struct sched_param schp;
a1d5c5b2
TM
10585 if (arg3 == 0) {
10586 return -TARGET_EINVAL;
10587 }
579a97f7 10588 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
2852aafd 10589 return -TARGET_EFAULT;
5cd4393b 10590 schp.sched_priority = tswap32(target_schp->sched_priority);
53a5960a 10591 unlock_user_struct(target_schp, arg3, 0);
72eb7ea8 10592 return get_errno(sched_setscheduler(arg1, arg2, &schp));
5cd4393b 10593 }
31e31b8a 10594 case TARGET_NR_sched_getscheduler:
72eb7ea8 10595 return get_errno(sched_getscheduler(arg1));
31e31b8a 10596 case TARGET_NR_sched_yield:
72eb7ea8 10597 return get_errno(sched_yield());
31e31b8a 10598 case TARGET_NR_sched_get_priority_max:
72eb7ea8 10599 return get_errno(sched_get_priority_max(arg1));
31e31b8a 10600 case TARGET_NR_sched_get_priority_min:
72eb7ea8 10601 return get_errno(sched_get_priority_min(arg1));
859e8a89 10602#ifdef TARGET_NR_sched_rr_get_interval
31e31b8a 10603 case TARGET_NR_sched_rr_get_interval:
5cd4393b 10604 {
5cd4393b
FB
10605 struct timespec ts;
10606 ret = get_errno(sched_rr_get_interval(arg1, &ts));
10607 if (!is_error(ret)) {
d4290c40 10608 ret = host_to_target_timespec(arg2, &ts);
5cd4393b
FB
10609 }
10610 }
72eb7ea8 10611 return ret;
859e8a89 10612#endif
ddcbde15
FB
10613#ifdef TARGET_NR_sched_rr_get_interval_time64
10614 case TARGET_NR_sched_rr_get_interval_time64:
10615 {
10616 struct timespec ts;
10617 ret = get_errno(sched_rr_get_interval(arg1, &ts));
10618 if (!is_error(ret)) {
10619 ret = host_to_target_timespec64(arg2, &ts);
10620 }
10621 }
10622 return ret;
10623#endif
859e8a89 10624#if defined(TARGET_NR_nanosleep)
31e31b8a 10625 case TARGET_NR_nanosleep:
1b6b029e 10626 {
1b6b029e 10627 struct timespec req, rem;
53a5960a 10628 target_to_host_timespec(&req, arg1);
9e518226 10629 ret = get_errno(safe_nanosleep(&req, &rem));
53a5960a
PB
10630 if (is_error(ret) && arg2) {
10631 host_to_target_timespec(arg2, &rem);
1b6b029e
FB
10632 }
10633 }
72eb7ea8 10634 return ret;
859e8a89 10635#endif
31e31b8a 10636 case TARGET_NR_prctl:
1e6722f8
PM
10637 switch (arg1) {
10638 case PR_GET_PDEATHSIG:
10639 {
10640 int deathsig;
10641 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
10642 if (!is_error(ret) && arg2
d9a5eba4 10643 && put_user_s32(deathsig, arg2)) {
2852aafd 10644 return -TARGET_EFAULT;
e5574487 10645 }
72eb7ea8 10646 return ret;
1e6722f8 10647 }
db9526b1
PM
10648#ifdef PR_GET_NAME
10649 case PR_GET_NAME:
10650 {
10651 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
10652 if (!name) {
2852aafd 10653 return -TARGET_EFAULT;
db9526b1
PM
10654 }
10655 ret = get_errno(prctl(arg1, (unsigned long)name,
10656 arg3, arg4, arg5));
10657 unlock_user(name, arg2, 16);
72eb7ea8 10658 return ret;
db9526b1
PM
10659 }
10660 case PR_SET_NAME:
10661 {
10662 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
10663 if (!name) {
2852aafd 10664 return -TARGET_EFAULT;
db9526b1
PM
10665 }
10666 ret = get_errno(prctl(arg1, (unsigned long)name,
10667 arg3, arg4, arg5));
10668 unlock_user(name, arg2, 0);
72eb7ea8 10669 return ret;
db9526b1
PM
10670 }
10671#endif
5b702ffd
SM
10672#ifdef TARGET_MIPS
10673 case TARGET_PR_GET_FP_MODE:
64ea3d67
SM
10674 {
10675 CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
10676 ret = 0;
10677 if (env->CP0_Status & (1 << CP0St_FR)) {
10678 ret |= TARGET_PR_FP_MODE_FR;
10679 }
10680 if (env->CP0_Config5 & (1 << CP0C5_FRE)) {
10681 ret |= TARGET_PR_FP_MODE_FRE;
10682 }
10683 return ret;
10684 }
5b702ffd 10685 case TARGET_PR_SET_FP_MODE:
64ea3d67
SM
10686 {
10687 CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
10688 bool old_fr = env->CP0_Status & (1 << CP0St_FR);
6456c510 10689 bool old_fre = env->CP0_Config5 & (1 << CP0C5_FRE);
64ea3d67
SM
10690 bool new_fr = arg2 & TARGET_PR_FP_MODE_FR;
10691 bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE;
10692
6456c510
SM
10693 const unsigned int known_bits = TARGET_PR_FP_MODE_FR |
10694 TARGET_PR_FP_MODE_FRE;
10695
10696 /* If nothing to change, return right away, successfully. */
10697 if (old_fr == new_fr && old_fre == new_fre) {
10698 return 0;
10699 }
10700 /* Check the value is valid */
10701 if (arg2 & ~known_bits) {
10702 return -TARGET_EOPNOTSUPP;
10703 }
10704 /* Setting FRE without FR is not supported. */
10705 if (new_fre && !new_fr) {
10706 return -TARGET_EOPNOTSUPP;
10707 }
64ea3d67
SM
10708 if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) {
10709 /* FR1 is not supported */
10710 return -TARGET_EOPNOTSUPP;
10711 }
10712 if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64))
10713 && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
10714 /* cannot set FR=0 */
10715 return -TARGET_EOPNOTSUPP;
10716 }
10717 if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) {
10718 /* Cannot set FRE=1 */
10719 return -TARGET_EOPNOTSUPP;
10720 }
10721
10722 int i;
10723 fpr_t *fpr = env->active_fpu.fpr;
10724 for (i = 0; i < 32 ; i += 2) {
10725 if (!old_fr && new_fr) {
10726 fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX];
10727 } else if (old_fr && !new_fr) {
10728 fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX];
10729 }
10730 }
10731
10732 if (new_fr) {
10733 env->CP0_Status |= (1 << CP0St_FR);
10734 env->hflags |= MIPS_HFLAG_F64;
10735 } else {
10736 env->CP0_Status &= ~(1 << CP0St_FR);
6456c510 10737 env->hflags &= ~MIPS_HFLAG_F64;
64ea3d67
SM
10738 }
10739 if (new_fre) {
10740 env->CP0_Config5 |= (1 << CP0C5_FRE);
10741 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
10742 env->hflags |= MIPS_HFLAG_FRE;
10743 }
10744 } else {
10745 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
6456c510 10746 env->hflags &= ~MIPS_HFLAG_FRE;
64ea3d67
SM
10747 }
10748
10749 return 0;
10750 }
5b702ffd 10751#endif /* MIPS */
85fc7167
RH
10752#ifdef TARGET_AARCH64
10753 case TARGET_PR_SVE_SET_VL:
adf92eab
RH
10754 /*
10755 * We cannot support either PR_SVE_SET_VL_ONEXEC or
10756 * PR_SVE_VL_INHERIT. Note the kernel definition
10757 * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
10758 * even though the current architectural maximum is VQ=16.
10759 */
85fc7167 10760 ret = -TARGET_EINVAL;
2fc0cc0e 10761 if (cpu_isar_feature(aa64_sve, env_archcpu(cpu_env))
adf92eab 10762 && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
85fc7167 10763 CPUARMState *env = cpu_env;
2fc0cc0e 10764 ARMCPU *cpu = env_archcpu(env);
adf92eab
RH
10765 uint32_t vq, old_vq;
10766
10767 old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
10768 vq = MAX(arg2 / 16, 1);
10769 vq = MIN(vq, cpu->sve_max_vq);
85fc7167
RH
10770
10771 if (vq < old_vq) {
10772 aarch64_sve_narrow_vq(env, vq);
10773 }
10774 env->vfp.zcr_el[1] = vq - 1;
a8a79c7a 10775 arm_rebuild_hflags(env);
85fc7167
RH
10776 ret = vq * 16;
10777 }
72eb7ea8 10778 return ret;
85fc7167
RH
10779 case TARGET_PR_SVE_GET_VL:
10780 ret = -TARGET_EINVAL;
cd208a1c 10781 {
2fc0cc0e 10782 ARMCPU *cpu = env_archcpu(cpu_env);
cd208a1c
RH
10783 if (cpu_isar_feature(aa64_sve, cpu)) {
10784 ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
10785 }
85fc7167 10786 }
72eb7ea8 10787 return ret;
bff63fbf
RH
10788 case TARGET_PR_PAC_RESET_KEYS:
10789 {
10790 CPUARMState *env = cpu_env;
2fc0cc0e 10791 ARMCPU *cpu = env_archcpu(env);
bff63fbf
RH
10792
10793 if (arg3 || arg4 || arg5) {
10794 return -TARGET_EINVAL;
10795 }
10796 if (cpu_isar_feature(aa64_pauth, cpu)) {
10797 int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
10798 TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
10799 TARGET_PR_PAC_APGAKEY);
51977e25
RH
10800 int ret = 0;
10801 Error *err = NULL;
10802
bff63fbf
RH
10803 if (arg2 == 0) {
10804 arg2 = all;
10805 } else if (arg2 & ~all) {
10806 return -TARGET_EINVAL;
10807 }
10808 if (arg2 & TARGET_PR_PAC_APIAKEY) {
108b3ba8 10809 ret |= qemu_guest_getrandom(&env->keys.apia,
51977e25 10810 sizeof(ARMPACKey), &err);
bff63fbf
RH
10811 }
10812 if (arg2 & TARGET_PR_PAC_APIBKEY) {
108b3ba8 10813 ret |= qemu_guest_getrandom(&env->keys.apib,
51977e25 10814 sizeof(ARMPACKey), &err);
bff63fbf
RH
10815 }
10816 if (arg2 & TARGET_PR_PAC_APDAKEY) {
108b3ba8 10817 ret |= qemu_guest_getrandom(&env->keys.apda,
51977e25 10818 sizeof(ARMPACKey), &err);
bff63fbf
RH
10819 }
10820 if (arg2 & TARGET_PR_PAC_APDBKEY) {
108b3ba8 10821 ret |= qemu_guest_getrandom(&env->keys.apdb,
51977e25 10822 sizeof(ARMPACKey), &err);
bff63fbf
RH
10823 }
10824 if (arg2 & TARGET_PR_PAC_APGAKEY) {
108b3ba8 10825 ret |= qemu_guest_getrandom(&env->keys.apga,
51977e25
RH
10826 sizeof(ARMPACKey), &err);
10827 }
10828 if (ret != 0) {
10829 /*
10830 * Some unknown failure in the crypto. The best
10831 * we can do is log it and fail the syscall.
10832 * The real syscall cannot fail this way.
10833 */
10834 qemu_log_mask(LOG_UNIMP,
10835 "PR_PAC_RESET_KEYS: Crypto failure: %s",
10836 error_get_pretty(err));
10837 error_free(err);
10838 return -TARGET_EIO;
bff63fbf
RH
10839 }
10840 return 0;
10841 }
10842 }
10843 return -TARGET_EINVAL;
0e0c030c
RH
10844 case TARGET_PR_SET_TAGGED_ADDR_CTRL:
10845 {
10846 abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
10847 CPUARMState *env = cpu_env;
bfd0572f
RH
10848 ARMCPU *cpu = env_archcpu(env);
10849
10850 if (cpu_isar_feature(aa64_mte, cpu)) {
10851 valid_mask |= TARGET_PR_MTE_TCF_MASK;
10852 valid_mask |= TARGET_PR_MTE_TAG_MASK;
10853 }
0e0c030c
RH
10854
10855 if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
10856 return -TARGET_EINVAL;
10857 }
10858 env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
bfd0572f
RH
10859
10860 if (cpu_isar_feature(aa64_mte, cpu)) {
10861 switch (arg2 & TARGET_PR_MTE_TCF_MASK) {
10862 case TARGET_PR_MTE_TCF_NONE:
10863 case TARGET_PR_MTE_TCF_SYNC:
10864 case TARGET_PR_MTE_TCF_ASYNC:
10865 break;
10866 default:
10867 return -EINVAL;
10868 }
10869
10870 /*
10871 * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
10872 * Note that the syscall values are consistent with hw.
10873 */
10874 env->cp15.sctlr_el[1] =
10875 deposit64(env->cp15.sctlr_el[1], 38, 2,
10876 arg2 >> TARGET_PR_MTE_TCF_SHIFT);
10877
10878 /*
10879 * Write PR_MTE_TAG to GCR_EL1[Exclude].
10880 * Note that the syscall uses an include mask,
10881 * and hardware uses an exclude mask -- invert.
10882 */
10883 env->cp15.gcr_el1 =
10884 deposit64(env->cp15.gcr_el1, 0, 16,
10885 ~arg2 >> TARGET_PR_MTE_TAG_SHIFT);
10886 arm_rebuild_hflags(env);
10887 }
0e0c030c
RH
10888 return 0;
10889 }
10890 case TARGET_PR_GET_TAGGED_ADDR_CTRL:
10891 {
10892 abi_long ret = 0;
10893 CPUARMState *env = cpu_env;
bfd0572f 10894 ARMCPU *cpu = env_archcpu(env);
0e0c030c
RH
10895
10896 if (arg2 || arg3 || arg4 || arg5) {
10897 return -TARGET_EINVAL;
10898 }
10899 if (env->tagged_addr_enable) {
10900 ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
10901 }
bfd0572f
RH
10902 if (cpu_isar_feature(aa64_mte, cpu)) {
10903 /* See above. */
10904 ret |= (extract64(env->cp15.sctlr_el[1], 38, 2)
10905 << TARGET_PR_MTE_TCF_SHIFT);
10906 ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16,
10907 ~env->cp15.gcr_el1);
10908 }
0e0c030c
RH
10909 return ret;
10910 }
85fc7167 10911#endif /* AARCH64 */
a8b154a6
JC
10912 case PR_GET_SECCOMP:
10913 case PR_SET_SECCOMP:
10914 /* Disable seccomp to prevent the target disabling syscalls we
10915 * need. */
72eb7ea8 10916 return -TARGET_EINVAL;
1e6722f8
PM
10917 default:
10918 /* Most prctl options have no pointer arguments */
72eb7ea8 10919 return get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
1e6722f8 10920 }
39b9aae1 10921 break;
d2fd1af7
FB
10922#ifdef TARGET_NR_arch_prctl
10923 case TARGET_NR_arch_prctl:
72eb7ea8 10924 return do_arch_prctl(cpu_env, arg1, arg2);
d2fd1af7 10925#endif
f2c7ba15
AJ
10926#ifdef TARGET_NR_pread64
10927 case TARGET_NR_pread64:
8bf8e9df 10928 if (regpairs_aligned(cpu_env, num)) {
ae017a5b
AG
10929 arg4 = arg5;
10930 arg5 = arg6;
10931 }
2bd3f899
PM
10932 if (arg2 == 0 && arg3 == 0) {
10933 /* Special-case NULL buffer and zero length, which should succeed */
10934 p = 0;
10935 } else {
10936 p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
10937 if (!p) {
10938 return -TARGET_EFAULT;
10939 }
10940 }
f2c7ba15
AJ
10941 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
10942 unlock_user(p, arg2, ret);
72eb7ea8 10943 return ret;
f2c7ba15 10944 case TARGET_NR_pwrite64:
8bf8e9df 10945 if (regpairs_aligned(cpu_env, num)) {
ae017a5b
AG
10946 arg4 = arg5;
10947 arg5 = arg6;
10948 }
2bd3f899
PM
10949 if (arg2 == 0 && arg3 == 0) {
10950 /* Special-case NULL buffer and zero length, which should succeed */
10951 p = 0;
10952 } else {
10953 p = lock_user(VERIFY_READ, arg2, arg3, 1);
10954 if (!p) {
10955 return -TARGET_EFAULT;
10956 }
10957 }
f2c7ba15
AJ
10958 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
10959 unlock_user(p, arg2, 0);
72eb7ea8 10960 return ret;
67867308 10961#endif
31e31b8a 10962 case TARGET_NR_getcwd:
579a97f7 10963 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
2852aafd 10964 return -TARGET_EFAULT;
53a5960a
PB
10965 ret = get_errno(sys_getcwd1(p, arg2));
10966 unlock_user(p, arg1, ret);
72eb7ea8 10967 return ret;
31e31b8a
FB
10968 case TARGET_NR_capget:
10969 case TARGET_NR_capset:
e0eb210e
PM
10970 {
10971 struct target_user_cap_header *target_header;
10972 struct target_user_cap_data *target_data = NULL;
10973 struct __user_cap_header_struct header;
10974 struct __user_cap_data_struct data[2];
10975 struct __user_cap_data_struct *dataptr = NULL;
10976 int i, target_datalen;
10977 int data_items = 1;
10978
10979 if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
2852aafd 10980 return -TARGET_EFAULT;
e0eb210e
PM
10981 }
10982 header.version = tswap32(target_header->version);
10983 header.pid = tswap32(target_header->pid);
10984
ec864874 10985 if (header.version != _LINUX_CAPABILITY_VERSION) {
e0eb210e
PM
10986 /* Version 2 and up takes pointer to two user_data structs */
10987 data_items = 2;
10988 }
10989
10990 target_datalen = sizeof(*target_data) * data_items;
10991
10992 if (arg2) {
10993 if (num == TARGET_NR_capget) {
10994 target_data = lock_user(VERIFY_WRITE, arg2, target_datalen, 0);
10995 } else {
10996 target_data = lock_user(VERIFY_READ, arg2, target_datalen, 1);
10997 }
10998 if (!target_data) {
10999 unlock_user_struct(target_header, arg1, 0);
2852aafd 11000 return -TARGET_EFAULT;
e0eb210e
PM
11001 }
11002
11003 if (num == TARGET_NR_capset) {
11004 for (i = 0; i < data_items; i++) {
11005 data[i].effective = tswap32(target_data[i].effective);
11006 data[i].permitted = tswap32(target_data[i].permitted);
11007 data[i].inheritable = tswap32(target_data[i].inheritable);
11008 }
11009 }
11010
11011 dataptr = data;
11012 }
11013
11014 if (num == TARGET_NR_capget) {
11015 ret = get_errno(capget(&header, dataptr));
11016 } else {
11017 ret = get_errno(capset(&header, dataptr));
11018 }
11019
11020 /* The kernel always updates version for both capget and capset */
11021 target_header->version = tswap32(header.version);
11022 unlock_user_struct(target_header, arg1, 1);
11023
11024 if (arg2) {
11025 if (num == TARGET_NR_capget) {
11026 for (i = 0; i < data_items; i++) {
11027 target_data[i].effective = tswap32(data[i].effective);
11028 target_data[i].permitted = tswap32(data[i].permitted);
11029 target_data[i].inheritable = tswap32(data[i].inheritable);
11030 }
11031 unlock_user(target_data, arg2, target_datalen);
11032 } else {
11033 unlock_user(target_data, arg2, 0);
11034 }
11035 }
72eb7ea8 11036 return ret;
e0eb210e 11037 }
31e31b8a 11038 case TARGET_NR_sigaltstack:
6b208755 11039 return do_sigaltstack(arg1, arg2, cpu_env);
a8fd1aba
PM
11040
11041#ifdef CONFIG_SENDFILE
4f7f8924 11042#ifdef TARGET_NR_sendfile
a8fd1aba
PM
11043 case TARGET_NR_sendfile:
11044 {
11045 off_t *offp = NULL;
11046 off_t off;
11047 if (arg3) {
11048 ret = get_user_sal(off, arg3);
11049 if (is_error(ret)) {
72eb7ea8 11050 return ret;
a8fd1aba
PM
11051 }
11052 offp = &off;
11053 }
11054 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
11055 if (!is_error(ret) && arg3) {
11056 abi_long ret2 = put_user_sal(off, arg3);
11057 if (is_error(ret2)) {
11058 ret = ret2;
11059 }
11060 }
72eb7ea8 11061 return ret;
a8fd1aba 11062 }
4f7f8924 11063#endif
a8fd1aba
PM
11064#ifdef TARGET_NR_sendfile64
11065 case TARGET_NR_sendfile64:
11066 {
11067 off_t *offp = NULL;
11068 off_t off;
11069 if (arg3) {
11070 ret = get_user_s64(off, arg3);
11071 if (is_error(ret)) {
72eb7ea8 11072 return ret;
a8fd1aba
PM
11073 }
11074 offp = &off;
11075 }
11076 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
11077 if (!is_error(ret) && arg3) {
11078 abi_long ret2 = put_user_s64(off, arg3);
11079 if (is_error(ret2)) {
11080 ret = ret2;
11081 }
11082 }
72eb7ea8 11083 return ret;
a8fd1aba
PM
11084 }
11085#endif
ebc05488 11086#endif
048f6b4d 11087#ifdef TARGET_NR_vfork
31e31b8a 11088 case TARGET_NR_vfork:
72eb7ea8
RH
11089 return get_errno(do_fork(cpu_env,
11090 CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
11091 0, 0, 0, 0));
048f6b4d 11092#endif
ebc05488 11093#ifdef TARGET_NR_ugetrlimit
31e31b8a 11094 case TARGET_NR_ugetrlimit:
728584be
FB
11095 {
11096 struct rlimit rlim;
e22b7015
WT
11097 int resource = target_to_host_resource(arg1);
11098 ret = get_errno(getrlimit(resource, &rlim));
728584be 11099 if (!is_error(ret)) {
53a5960a 11100 struct target_rlimit *target_rlim;
579a97f7 11101 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
2852aafd 11102 return -TARGET_EFAULT;
81bbe906
TY
11103 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
11104 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
53a5960a 11105 unlock_user_struct(target_rlim, arg2, 1);
728584be 11106 }
72eb7ea8 11107 return ret;
728584be 11108 }
ebc05488 11109#endif
a315a145 11110#ifdef TARGET_NR_truncate64
31e31b8a 11111 case TARGET_NR_truncate64:
579a97f7 11112 if (!(p = lock_user_string(arg1)))
2852aafd 11113 return -TARGET_EFAULT;
53a5960a
PB
11114 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
11115 unlock_user(p, arg1, 0);
72eb7ea8 11116 return ret;
a315a145
FB
11117#endif
11118#ifdef TARGET_NR_ftruncate64
31e31b8a 11119 case TARGET_NR_ftruncate64:
72eb7ea8 11120 return target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
a315a145
FB
11121#endif
11122#ifdef TARGET_NR_stat64
31e31b8a 11123 case TARGET_NR_stat64:
2852aafd
RH
11124 if (!(p = lock_user_string(arg1))) {
11125 return -TARGET_EFAULT;
11126 }
53a5960a
PB
11127 ret = get_errno(stat(path(p), &st));
11128 unlock_user(p, arg1, 0);
6a24a778
AZ
11129 if (!is_error(ret))
11130 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 11131 return ret;
a315a145
FB
11132#endif
11133#ifdef TARGET_NR_lstat64
31e31b8a 11134 case TARGET_NR_lstat64:
2852aafd
RH
11135 if (!(p = lock_user_string(arg1))) {
11136 return -TARGET_EFAULT;
11137 }
53a5960a
PB
11138 ret = get_errno(lstat(path(p), &st));
11139 unlock_user(p, arg1, 0);
6a24a778
AZ
11140 if (!is_error(ret))
11141 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 11142 return ret;
a315a145
FB
11143#endif
11144#ifdef TARGET_NR_fstat64
31e31b8a 11145 case TARGET_NR_fstat64:
6a24a778
AZ
11146 ret = get_errno(fstat(arg1, &st));
11147 if (!is_error(ret))
11148 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 11149 return ret;
ce4defa0 11150#endif
c0d472b1 11151#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
9d33b76b 11152#ifdef TARGET_NR_fstatat64
6a24a778 11153 case TARGET_NR_fstatat64:
9d33b76b
AJ
11154#endif
11155#ifdef TARGET_NR_newfstatat
11156 case TARGET_NR_newfstatat:
11157#endif
2852aafd
RH
11158 if (!(p = lock_user_string(arg2))) {
11159 return -TARGET_EFAULT;
11160 }
c0d472b1 11161 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
2852aafd 11162 unlock_user(p, arg2, 0);
6a24a778
AZ
11163 if (!is_error(ret))
11164 ret = host_to_target_stat64(cpu_env, arg3, &st);
72eb7ea8 11165 return ret;
a315a145 11166#endif
efa92184
AR
11167#if defined(TARGET_NR_statx)
11168 case TARGET_NR_statx:
11169 {
11170 struct target_statx *target_stx;
11171 int dirfd = arg1;
11172 int flags = arg3;
11173
11174 p = lock_user_string(arg2);
11175 if (p == NULL) {
11176 return -TARGET_EFAULT;
11177 }
11178#if defined(__NR_statx)
11179 {
11180 /*
11181 * It is assumed that struct statx is architecture independent.
11182 */
11183 struct target_statx host_stx;
11184 int mask = arg4;
11185
11186 ret = get_errno(sys_statx(dirfd, p, flags, mask, &host_stx));
11187 if (!is_error(ret)) {
11188 if (host_to_target_statx(&host_stx, arg5) != 0) {
11189 unlock_user(p, arg2, 0);
11190 return -TARGET_EFAULT;
11191 }
11192 }
11193
11194 if (ret != -TARGET_ENOSYS) {
11195 unlock_user(p, arg2, 0);
11196 return ret;
11197 }
11198 }
11199#endif
11200 ret = get_errno(fstatat(dirfd, path(p), &st, flags));
11201 unlock_user(p, arg2, 0);
11202
11203 if (!is_error(ret)) {
11204 if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
11205 return -TARGET_EFAULT;
11206 }
11207 memset(target_stx, 0, sizeof(*target_stx));
11208 __put_user(major(st.st_dev), &target_stx->stx_dev_major);
11209 __put_user(minor(st.st_dev), &target_stx->stx_dev_minor);
11210 __put_user(st.st_ino, &target_stx->stx_ino);
11211 __put_user(st.st_mode, &target_stx->stx_mode);
11212 __put_user(st.st_uid, &target_stx->stx_uid);
11213 __put_user(st.st_gid, &target_stx->stx_gid);
11214 __put_user(st.st_nlink, &target_stx->stx_nlink);
11215 __put_user(major(st.st_rdev), &target_stx->stx_rdev_major);
11216 __put_user(minor(st.st_rdev), &target_stx->stx_rdev_minor);
11217 __put_user(st.st_size, &target_stx->stx_size);
11218 __put_user(st.st_blksize, &target_stx->stx_blksize);
11219 __put_user(st.st_blocks, &target_stx->stx_blocks);
11220 __put_user(st.st_atime, &target_stx->stx_atime.tv_sec);
11221 __put_user(st.st_mtime, &target_stx->stx_mtime.tv_sec);
11222 __put_user(st.st_ctime, &target_stx->stx_ctime.tv_sec);
11223 unlock_user_struct(target_stx, arg5, 1);
11224 }
11225 }
11226 return ret;
11227#endif
704eff6c 11228#ifdef TARGET_NR_lchown
67867308 11229 case TARGET_NR_lchown:
579a97f7 11230 if (!(p = lock_user_string(arg1)))
2852aafd 11231 return -TARGET_EFAULT;
53a5960a
PB
11232 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
11233 unlock_user(p, arg1, 0);
72eb7ea8 11234 return ret;
704eff6c 11235#endif
0c866a7e 11236#ifdef TARGET_NR_getuid
67867308 11237 case TARGET_NR_getuid:
72eb7ea8 11238 return get_errno(high2lowuid(getuid()));
0c866a7e
RV
11239#endif
11240#ifdef TARGET_NR_getgid
67867308 11241 case TARGET_NR_getgid:
72eb7ea8 11242 return get_errno(high2lowgid(getgid()));
0c866a7e
RV
11243#endif
11244#ifdef TARGET_NR_geteuid
67867308 11245 case TARGET_NR_geteuid:
72eb7ea8 11246 return get_errno(high2lowuid(geteuid()));
0c866a7e
RV
11247#endif
11248#ifdef TARGET_NR_getegid
67867308 11249 case TARGET_NR_getegid:
72eb7ea8 11250 return get_errno(high2lowgid(getegid()));
0c866a7e 11251#endif
67867308 11252 case TARGET_NR_setreuid:
72eb7ea8 11253 return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
67867308 11254 case TARGET_NR_setregid:
72eb7ea8 11255 return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
67867308
FB
11256 case TARGET_NR_getgroups:
11257 {
11258 int gidsetsize = arg1;
0c866a7e 11259 target_id *target_grouplist;
67867308
FB
11260 gid_t *grouplist;
11261 int i;
11262
11263 grouplist = alloca(gidsetsize * sizeof(gid_t));
11264 ret = get_errno(getgroups(gidsetsize, grouplist));
cb3bc233 11265 if (gidsetsize == 0)
72eb7ea8 11266 return ret;
67867308 11267 if (!is_error(ret)) {
03903ffc 11268 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
579a97f7 11269 if (!target_grouplist)
2852aafd 11270 return -TARGET_EFAULT;
a2155fcc 11271 for(i = 0;i < ret; i++)
0c866a7e 11272 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
03903ffc 11273 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
67867308
FB
11274 }
11275 }
72eb7ea8 11276 return ret;
67867308
FB
11277 case TARGET_NR_setgroups:
11278 {
11279 int gidsetsize = arg1;
0c866a7e 11280 target_id *target_grouplist;
f2b79ce9 11281 gid_t *grouplist = NULL;
67867308 11282 int i;
f2b79ce9
DA
11283 if (gidsetsize) {
11284 grouplist = alloca(gidsetsize * sizeof(gid_t));
03903ffc 11285 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
f2b79ce9 11286 if (!target_grouplist) {
259841c1 11287 return -TARGET_EFAULT;
f2b79ce9
DA
11288 }
11289 for (i = 0; i < gidsetsize; i++) {
11290 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
11291 }
11292 unlock_user(target_grouplist, arg2, 0);
579a97f7 11293 }
72eb7ea8 11294 return get_errno(setgroups(gidsetsize, grouplist));
67867308 11295 }
67867308 11296 case TARGET_NR_fchown:
72eb7ea8 11297 return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
c0d472b1 11298#if defined(TARGET_NR_fchownat)
ccfa72b7 11299 case TARGET_NR_fchownat:
579a97f7 11300 if (!(p = lock_user_string(arg2)))
2852aafd 11301 return -TARGET_EFAULT;
c0d472b1
PM
11302 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
11303 low2highgid(arg4), arg5));
579a97f7 11304 unlock_user(p, arg2, 0);
72eb7ea8 11305 return ret;
ccfa72b7 11306#endif
67867308
FB
11307#ifdef TARGET_NR_setresuid
11308 case TARGET_NR_setresuid:
72eb7ea8
RH
11309 return get_errno(sys_setresuid(low2highuid(arg1),
11310 low2highuid(arg2),
11311 low2highuid(arg3)));
67867308
FB
11312#endif
11313#ifdef TARGET_NR_getresuid
11314 case TARGET_NR_getresuid:
11315 {
53a5960a 11316 uid_t ruid, euid, suid;
67867308
FB
11317 ret = get_errno(getresuid(&ruid, &euid, &suid));
11318 if (!is_error(ret)) {
76ca310a
PM
11319 if (put_user_id(high2lowuid(ruid), arg1)
11320 || put_user_id(high2lowuid(euid), arg2)
11321 || put_user_id(high2lowuid(suid), arg3))
2852aafd 11322 return -TARGET_EFAULT;
67867308
FB
11323 }
11324 }
72eb7ea8 11325 return ret;
67867308
FB
11326#endif
11327#ifdef TARGET_NR_getresgid
11328 case TARGET_NR_setresgid:
72eb7ea8
RH
11329 return get_errno(sys_setresgid(low2highgid(arg1),
11330 low2highgid(arg2),
11331 low2highgid(arg3)));
67867308
FB
11332#endif
11333#ifdef TARGET_NR_getresgid
11334 case TARGET_NR_getresgid:
11335 {
53a5960a 11336 gid_t rgid, egid, sgid;
67867308
FB
11337 ret = get_errno(getresgid(&rgid, &egid, &sgid));
11338 if (!is_error(ret)) {
76ca310a
PM
11339 if (put_user_id(high2lowgid(rgid), arg1)
11340 || put_user_id(high2lowgid(egid), arg2)
11341 || put_user_id(high2lowgid(sgid), arg3))
2852aafd 11342 return -TARGET_EFAULT;
67867308
FB
11343 }
11344 }
72eb7ea8 11345 return ret;
67867308 11346#endif
704eff6c 11347#ifdef TARGET_NR_chown
67867308 11348 case TARGET_NR_chown:
579a97f7 11349 if (!(p = lock_user_string(arg1)))
2852aafd 11350 return -TARGET_EFAULT;
53a5960a
PB
11351 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
11352 unlock_user(p, arg1, 0);
72eb7ea8 11353 return ret;
704eff6c 11354#endif
67867308 11355 case TARGET_NR_setuid:
72eb7ea8 11356 return get_errno(sys_setuid(low2highuid(arg1)));
67867308 11357 case TARGET_NR_setgid:
72eb7ea8 11358 return get_errno(sys_setgid(low2highgid(arg1)));
67867308 11359 case TARGET_NR_setfsuid:
72eb7ea8 11360 return get_errno(setfsuid(arg1));
67867308 11361 case TARGET_NR_setfsgid:
72eb7ea8 11362 return get_errno(setfsgid(arg1));
67867308 11363
a315a145 11364#ifdef TARGET_NR_lchown32
31e31b8a 11365 case TARGET_NR_lchown32:
579a97f7 11366 if (!(p = lock_user_string(arg1)))
2852aafd 11367 return -TARGET_EFAULT;
53a5960a
PB
11368 ret = get_errno(lchown(p, arg2, arg3));
11369 unlock_user(p, arg1, 0);
72eb7ea8 11370 return ret;
a315a145
FB
11371#endif
11372#ifdef TARGET_NR_getuid32
31e31b8a 11373 case TARGET_NR_getuid32:
72eb7ea8 11374 return get_errno(getuid());
a315a145 11375#endif
64b4d28c
AJ
11376
11377#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
11378 /* Alpha specific */
11379 case TARGET_NR_getxuid:
ba0e276d
RH
11380 {
11381 uid_t euid;
11382 euid=geteuid();
11383 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
11384 }
72eb7ea8 11385 return get_errno(getuid());
64b4d28c
AJ
11386#endif
11387#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
11388 /* Alpha specific */
11389 case TARGET_NR_getxgid:
ba0e276d
RH
11390 {
11391 uid_t egid;
11392 egid=getegid();
11393 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
11394 }
72eb7ea8 11395 return get_errno(getgid());
64b4d28c 11396#endif
ba0e276d
RH
11397#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
11398 /* Alpha specific */
11399 case TARGET_NR_osf_getsysinfo:
11400 ret = -TARGET_EOPNOTSUPP;
11401 switch (arg1) {
11402 case TARGET_GSI_IEEE_FP_CONTROL:
11403 {
21ba8564
RH
11404 uint64_t fpcr = cpu_alpha_load_fpcr(cpu_env);
11405 uint64_t swcr = ((CPUAlphaState *)cpu_env)->swcr;
11406
11407 swcr &= ~SWCR_STATUS_MASK;
11408 swcr |= (fpcr >> 35) & SWCR_STATUS_MASK;
ba0e276d
RH
11409
11410 if (put_user_u64 (swcr, arg2))
2852aafd 11411 return -TARGET_EFAULT;
ba0e276d
RH
11412 ret = 0;
11413 }
11414 break;
11415
11416 /* case GSI_IEEE_STATE_AT_SIGNAL:
11417 -- Not implemented in linux kernel.
11418 case GSI_UACPROC:
11419 -- Retrieves current unaligned access state; not much used.
11420 case GSI_PROC_TYPE:
11421 -- Retrieves implver information; surely not used.
11422 case GSI_GET_HWRPB:
11423 -- Grabs a copy of the HWRPB; surely not used.
11424 */
11425 }
72eb7ea8 11426 return ret;
ba0e276d
RH
11427#endif
11428#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
11429 /* Alpha specific */
11430 case TARGET_NR_osf_setsysinfo:
11431 ret = -TARGET_EOPNOTSUPP;
11432 switch (arg1) {
11433 case TARGET_SSI_IEEE_FP_CONTROL:
ba0e276d 11434 {
21ba8564 11435 uint64_t swcr, fpcr;
ba0e276d 11436
6e06d515 11437 if (get_user_u64 (swcr, arg2)) {
2852aafd 11438 return -TARGET_EFAULT;
6e06d515 11439 }
ba0e276d 11440
21ba8564
RH
11441 /*
11442 * The kernel calls swcr_update_status to update the
11443 * status bits from the fpcr at every point that it
11444 * could be queried. Therefore, we store the status
11445 * bits only in FPCR.
11446 */
11447 ((CPUAlphaState *)cpu_env)->swcr
11448 = swcr & (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK);
11449
11450 fpcr = cpu_alpha_load_fpcr(cpu_env);
11451 fpcr &= ((uint64_t)FPCR_DYN_MASK << 32);
11452 fpcr |= alpha_ieee_swcr_to_fpcr(swcr);
6e06d515 11453 cpu_alpha_store_fpcr(cpu_env, fpcr);
ba0e276d 11454 ret = 0;
6e06d515
RH
11455 }
11456 break;
11457
11458 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
11459 {
21ba8564 11460 uint64_t exc, fpcr, fex;
6e06d515
RH
11461
11462 if (get_user_u64(exc, arg2)) {
2852aafd 11463 return -TARGET_EFAULT;
6e06d515 11464 }
21ba8564
RH
11465 exc &= SWCR_STATUS_MASK;
11466 fpcr = cpu_alpha_load_fpcr(cpu_env);
ba0e276d 11467
21ba8564
RH
11468 /* Old exceptions are not signaled. */
11469 fex = alpha_ieee_fpcr_to_swcr(fpcr);
11470 fex = exc & ~fex;
11471 fex >>= SWCR_STATUS_TO_EXCSUM_SHIFT;
11472 fex &= ((CPUArchState *)cpu_env)->swcr;
6e06d515 11473
21ba8564
RH
11474 /* Update the hardware fpcr. */
11475 fpcr |= alpha_ieee_swcr_to_fpcr(exc);
6e06d515 11476 cpu_alpha_store_fpcr(cpu_env, fpcr);
6e06d515 11477
21ba8564
RH
11478 if (fex) {
11479 int si_code = TARGET_FPE_FLTUNK;
6e06d515 11480 target_siginfo_t info;
21ba8564
RH
11481
11482 if (fex & SWCR_TRAP_ENABLE_DNO) {
11483 si_code = TARGET_FPE_FLTUND;
11484 }
11485 if (fex & SWCR_TRAP_ENABLE_INE) {
11486 si_code = TARGET_FPE_FLTRES;
11487 }
11488 if (fex & SWCR_TRAP_ENABLE_UNF) {
11489 si_code = TARGET_FPE_FLTUND;
11490 }
11491 if (fex & SWCR_TRAP_ENABLE_OVF) {
11492 si_code = TARGET_FPE_FLTOVF;
11493 }
11494 if (fex & SWCR_TRAP_ENABLE_DZE) {
11495 si_code = TARGET_FPE_FLTDIV;
11496 }
11497 if (fex & SWCR_TRAP_ENABLE_INV) {
11498 si_code = TARGET_FPE_FLTINV;
11499 }
11500
6e06d515
RH
11501 info.si_signo = SIGFPE;
11502 info.si_errno = 0;
11503 info.si_code = si_code;
11504 info._sifields._sigfault._addr
11505 = ((CPUArchState *)cpu_env)->pc;
9d2803f7
PM
11506 queue_signal((CPUArchState *)cpu_env, info.si_signo,
11507 QEMU_SI_FAULT, &info);
ba0e276d 11508 }
21ba8564 11509 ret = 0;
ba0e276d
RH
11510 }
11511 break;
11512
11513 /* case SSI_NVPAIRS:
11514 -- Used with SSIN_UACPROC to enable unaligned accesses.
11515 case SSI_IEEE_STATE_AT_SIGNAL:
11516 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
11517 -- Not implemented in linux kernel
11518 */
11519 }
72eb7ea8 11520 return ret;
ba0e276d
RH
11521#endif
11522#ifdef TARGET_NR_osf_sigprocmask
11523 /* Alpha specific. */
11524 case TARGET_NR_osf_sigprocmask:
11525 {
11526 abi_ulong mask;
bc088ba1 11527 int how;
ba0e276d
RH
11528 sigset_t set, oldset;
11529
11530 switch(arg1) {
11531 case TARGET_SIG_BLOCK:
11532 how = SIG_BLOCK;
11533 break;
11534 case TARGET_SIG_UNBLOCK:
11535 how = SIG_UNBLOCK;
11536 break;
11537 case TARGET_SIG_SETMASK:
11538 how = SIG_SETMASK;
11539 break;
11540 default:
259841c1 11541 return -TARGET_EINVAL;
ba0e276d
RH
11542 }
11543 mask = arg2;
11544 target_to_host_old_sigset(&set, &mask);
3d3efba0
PM
11545 ret = do_sigprocmask(how, &set, &oldset);
11546 if (!ret) {
11547 host_to_target_old_sigset(&mask, &oldset);
11548 ret = mask;
11549 }
ba0e276d 11550 }
72eb7ea8 11551 return ret;
ba0e276d 11552#endif
64b4d28c 11553
a315a145 11554#ifdef TARGET_NR_getgid32
31e31b8a 11555 case TARGET_NR_getgid32:
72eb7ea8 11556 return get_errno(getgid());
a315a145
FB
11557#endif
11558#ifdef TARGET_NR_geteuid32
31e31b8a 11559 case TARGET_NR_geteuid32:
72eb7ea8 11560 return get_errno(geteuid());
a315a145
FB
11561#endif
11562#ifdef TARGET_NR_getegid32
31e31b8a 11563 case TARGET_NR_getegid32:
72eb7ea8 11564 return get_errno(getegid());
a315a145
FB
11565#endif
11566#ifdef TARGET_NR_setreuid32
31e31b8a 11567 case TARGET_NR_setreuid32:
72eb7ea8 11568 return get_errno(setreuid(arg1, arg2));
a315a145
FB
11569#endif
11570#ifdef TARGET_NR_setregid32
31e31b8a 11571 case TARGET_NR_setregid32:
72eb7ea8 11572 return get_errno(setregid(arg1, arg2));
a315a145
FB
11573#endif
11574#ifdef TARGET_NR_getgroups32
31e31b8a 11575 case TARGET_NR_getgroups32:
99c475ab
FB
11576 {
11577 int gidsetsize = arg1;
53a5960a 11578 uint32_t *target_grouplist;
99c475ab
FB
11579 gid_t *grouplist;
11580 int i;
11581
11582 grouplist = alloca(gidsetsize * sizeof(gid_t));
11583 ret = get_errno(getgroups(gidsetsize, grouplist));
cb3bc233 11584 if (gidsetsize == 0)
72eb7ea8 11585 return ret;
99c475ab 11586 if (!is_error(ret)) {
579a97f7
FB
11587 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
11588 if (!target_grouplist) {
259841c1 11589 return -TARGET_EFAULT;
579a97f7 11590 }
a2155fcc 11591 for(i = 0;i < ret; i++)
53a5960a
PB
11592 target_grouplist[i] = tswap32(grouplist[i]);
11593 unlock_user(target_grouplist, arg2, gidsetsize * 4);
99c475ab
FB
11594 }
11595 }
72eb7ea8 11596 return ret;
a315a145
FB
11597#endif
11598#ifdef TARGET_NR_setgroups32
31e31b8a 11599 case TARGET_NR_setgroups32:
99c475ab
FB
11600 {
11601 int gidsetsize = arg1;
53a5960a 11602 uint32_t *target_grouplist;
99c475ab
FB
11603 gid_t *grouplist;
11604 int i;
3b46e624 11605
99c475ab 11606 grouplist = alloca(gidsetsize * sizeof(gid_t));
579a97f7
FB
11607 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
11608 if (!target_grouplist) {
259841c1 11609 return -TARGET_EFAULT;
579a97f7 11610 }
99c475ab 11611 for(i = 0;i < gidsetsize; i++)
53a5960a
PB
11612 grouplist[i] = tswap32(target_grouplist[i]);
11613 unlock_user(target_grouplist, arg2, 0);
72eb7ea8 11614 return get_errno(setgroups(gidsetsize, grouplist));
99c475ab 11615 }
a315a145
FB
11616#endif
11617#ifdef TARGET_NR_fchown32
31e31b8a 11618 case TARGET_NR_fchown32:
72eb7ea8 11619 return get_errno(fchown(arg1, arg2, arg3));
a315a145
FB
11620#endif
11621#ifdef TARGET_NR_setresuid32
31e31b8a 11622 case TARGET_NR_setresuid32:
72eb7ea8 11623 return get_errno(sys_setresuid(arg1, arg2, arg3));
a315a145
FB
11624#endif
11625#ifdef TARGET_NR_getresuid32
31e31b8a 11626 case TARGET_NR_getresuid32:
b03c60f3 11627 {
53a5960a 11628 uid_t ruid, euid, suid;
b03c60f3
FB
11629 ret = get_errno(getresuid(&ruid, &euid, &suid));
11630 if (!is_error(ret)) {
2f619698
FB
11631 if (put_user_u32(ruid, arg1)
11632 || put_user_u32(euid, arg2)
11633 || put_user_u32(suid, arg3))
2852aafd 11634 return -TARGET_EFAULT;
b03c60f3
FB
11635 }
11636 }
72eb7ea8 11637 return ret;
a315a145
FB
11638#endif
11639#ifdef TARGET_NR_setresgid32
31e31b8a 11640 case TARGET_NR_setresgid32:
72eb7ea8 11641 return get_errno(sys_setresgid(arg1, arg2, arg3));
a315a145
FB
11642#endif
11643#ifdef TARGET_NR_getresgid32
31e31b8a 11644 case TARGET_NR_getresgid32:
b03c60f3 11645 {
53a5960a 11646 gid_t rgid, egid, sgid;
b03c60f3
FB
11647 ret = get_errno(getresgid(&rgid, &egid, &sgid));
11648 if (!is_error(ret)) {
2f619698
FB
11649 if (put_user_u32(rgid, arg1)
11650 || put_user_u32(egid, arg2)
11651 || put_user_u32(sgid, arg3))
2852aafd 11652 return -TARGET_EFAULT;
b03c60f3
FB
11653 }
11654 }
72eb7ea8 11655 return ret;
a315a145
FB
11656#endif
11657#ifdef TARGET_NR_chown32
31e31b8a 11658 case TARGET_NR_chown32:
579a97f7 11659 if (!(p = lock_user_string(arg1)))
2852aafd 11660 return -TARGET_EFAULT;
53a5960a
PB
11661 ret = get_errno(chown(p, arg2, arg3));
11662 unlock_user(p, arg1, 0);
72eb7ea8 11663 return ret;
a315a145
FB
11664#endif
11665#ifdef TARGET_NR_setuid32
31e31b8a 11666 case TARGET_NR_setuid32:
72eb7ea8 11667 return get_errno(sys_setuid(arg1));
a315a145
FB
11668#endif
11669#ifdef TARGET_NR_setgid32
31e31b8a 11670 case TARGET_NR_setgid32:
72eb7ea8 11671 return get_errno(sys_setgid(arg1));
a315a145
FB
11672#endif
11673#ifdef TARGET_NR_setfsuid32
31e31b8a 11674 case TARGET_NR_setfsuid32:
72eb7ea8 11675 return get_errno(setfsuid(arg1));
a315a145
FB
11676#endif
11677#ifdef TARGET_NR_setfsgid32
31e31b8a 11678 case TARGET_NR_setfsgid32:
72eb7ea8 11679 return get_errno(setfsgid(arg1));
a315a145 11680#endif
ffa65c3b 11681#ifdef TARGET_NR_mincore
31e31b8a 11682 case TARGET_NR_mincore:
04bb9ace 11683 {
259841c1 11684 void *a = lock_user(VERIFY_READ, arg1, arg2, 0);
98a3331a 11685 if (!a) {
259841c1 11686 return -TARGET_ENOMEM;
98a3331a 11687 }
98a3331a
FSM
11688 p = lock_user_string(arg3);
11689 if (!p) {
259841c1
RH
11690 ret = -TARGET_EFAULT;
11691 } else {
11692 ret = get_errno(mincore(a, arg2, p));
11693 unlock_user(p, arg3, ret);
98a3331a 11694 }
04bb9ace
AJ
11695 unlock_user(a, arg1, 0);
11696 }
72eb7ea8 11697 return ret;
ffa65c3b 11698#endif
408321b6
AJ
11699#ifdef TARGET_NR_arm_fadvise64_64
11700 case TARGET_NR_arm_fadvise64_64:
e0156a9d
PM
11701 /* arm_fadvise64_64 looks like fadvise64_64 but
11702 * with different argument order: fd, advice, offset, len
11703 * rather than the usual fd, offset, len, advice.
11704 * Note that offset and len are both 64-bit so appear as
11705 * pairs of 32-bit registers.
11706 */
11707 ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
11708 target_offset64(arg5, arg6), arg2);
72eb7ea8 11709 return -host_to_target_errno(ret);
408321b6 11710#endif
badd3cd8
PM
11711
11712#if TARGET_ABI_BITS == 32
11713
11714#ifdef TARGET_NR_fadvise64_64
11715 case TARGET_NR_fadvise64_64:
64a563dd 11716#if defined(TARGET_PPC) || defined(TARGET_XTENSA)
43046b5a
LV
11717 /* 6 args: fd, advice, offset (high, low), len (high, low) */
11718 ret = arg2;
11719 arg2 = arg3;
11720 arg3 = arg4;
11721 arg4 = arg5;
11722 arg5 = arg6;
11723 arg6 = ret;
11724#else
badd3cd8 11725 /* 6 args: fd, offset (high, low), len (high, low), advice */
8bf8e9df 11726 if (regpairs_aligned(cpu_env, num)) {
badd3cd8
PM
11727 /* offset is in (3,4), len in (5,6) and advice in 7 */
11728 arg2 = arg3;
11729 arg3 = arg4;
11730 arg4 = arg5;
11731 arg5 = arg6;
11732 arg6 = arg7;
11733 }
43046b5a 11734#endif
72eb7ea8
RH
11735 ret = posix_fadvise(arg1, target_offset64(arg2, arg3),
11736 target_offset64(arg4, arg5), arg6);
11737 return -host_to_target_errno(ret);
badd3cd8
PM
11738#endif
11739
11740#ifdef TARGET_NR_fadvise64
11741 case TARGET_NR_fadvise64:
11742 /* 5 args: fd, offset (high, low), len, advice */
8bf8e9df 11743 if (regpairs_aligned(cpu_env, num)) {
badd3cd8
PM
11744 /* offset is in (3,4), len in 5 and advice in 6 */
11745 arg2 = arg3;
11746 arg3 = arg4;
11747 arg4 = arg5;
11748 arg5 = arg6;
11749 }
72eb7ea8
RH
11750 ret = posix_fadvise(arg1, target_offset64(arg2, arg3), arg4, arg5);
11751 return -host_to_target_errno(ret);
408321b6 11752#endif
badd3cd8
PM
11753
11754#else /* not a 32-bit ABI */
e0156a9d 11755#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64)
408321b6
AJ
11756#ifdef TARGET_NR_fadvise64_64
11757 case TARGET_NR_fadvise64_64:
11758#endif
e72d2cc7
UH
11759#ifdef TARGET_NR_fadvise64
11760 case TARGET_NR_fadvise64:
11761#endif
11762#ifdef TARGET_S390X
11763 switch (arg4) {
11764 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
11765 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
11766 case 6: arg4 = POSIX_FADV_DONTNEED; break;
11767 case 7: arg4 = POSIX_FADV_NOREUSE; break;
11768 default: break;
11769 }
11770#endif
72eb7ea8 11771 return -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
408321b6 11772#endif
badd3cd8
PM
11773#endif /* end of 64-bit ABI fadvise handling */
11774
ffa65c3b 11775#ifdef TARGET_NR_madvise
31e31b8a 11776 case TARGET_NR_madvise:
24836689 11777 /* A straight passthrough may not be safe because qemu sometimes
d2d6b857 11778 turns private file-backed mappings into anonymous mappings.
24836689
PB
11779 This will break MADV_DONTNEED.
11780 This is a hint, so ignoring and returning success is ok. */
72eb7ea8 11781 return 0;
ffa65c3b 11782#endif
bbf5f2a1 11783#ifdef TARGET_NR_fcntl64
31e31b8a 11784 case TARGET_NR_fcntl64:
77e4672d 11785 {
bbf5f2a1
AB
11786 int cmd;
11787 struct flock64 fl;
213d3e9e
PM
11788 from_flock64_fn *copyfrom = copy_from_user_flock64;
11789 to_flock64_fn *copyto = copy_to_user_flock64;
11790
ce4defa0 11791#ifdef TARGET_ARM
7f254c5c
LV
11792 if (!((CPUARMState *)cpu_env)->eabi) {
11793 copyfrom = copy_from_user_oabi_flock64;
11794 copyto = copy_to_user_oabi_flock64;
213d3e9e 11795 }
ce4defa0 11796#endif
77e4672d 11797
bbf5f2a1 11798 cmd = target_to_host_fcntl_cmd(arg2);
31b63193 11799 if (cmd == -TARGET_EINVAL) {
72eb7ea8 11800 return cmd;
31b63193 11801 }
b1e341eb 11802
60cd49d5 11803 switch(arg2) {
b1e341eb 11804 case TARGET_F_GETLK64:
213d3e9e
PM
11805 ret = copyfrom(&fl, arg3);
11806 if (ret) {
11807 break;
5813427b 11808 }
af8ab2bf 11809 ret = get_errno(safe_fcntl(arg1, cmd, &fl));
213d3e9e
PM
11810 if (ret == 0) {
11811 ret = copyto(arg3, &fl);
11812 }
77e4672d
FB
11813 break;
11814
b1e341eb
TS
11815 case TARGET_F_SETLK64:
11816 case TARGET_F_SETLKW64:
213d3e9e
PM
11817 ret = copyfrom(&fl, arg3);
11818 if (ret) {
11819 break;
ce4defa0 11820 }
435da5e7 11821 ret = get_errno(safe_fcntl(arg1, cmd, &fl));
77e4672d 11822 break;
60cd49d5 11823 default:
5f106811 11824 ret = do_fcntl(arg1, arg2, arg3);
60cd49d5
FB
11825 break;
11826 }
72eb7ea8 11827 return ret;
77e4672d 11828 }
60cd49d5 11829#endif
7d600c80
TS
11830#ifdef TARGET_NR_cacheflush
11831 case TARGET_NR_cacheflush:
11832 /* self-modifying code is handled automatically, so nothing needed */
72eb7ea8 11833 return 0;
7d600c80 11834#endif
c573ff67
FB
11835#ifdef TARGET_NR_getpagesize
11836 case TARGET_NR_getpagesize:
72eb7ea8 11837 return TARGET_PAGE_SIZE;
ebc05488 11838#endif
31e31b8a 11839 case TARGET_NR_gettid:
71ba74f6 11840 return get_errno(sys_gettid());
e5febef5 11841#ifdef TARGET_NR_readahead
31e31b8a 11842 case TARGET_NR_readahead:
2054ac9b 11843#if TARGET_ABI_BITS == 32
8bf8e9df 11844 if (regpairs_aligned(cpu_env, num)) {
2054ac9b
AJ
11845 arg2 = arg3;
11846 arg3 = arg4;
11847 arg4 = arg5;
11848 }
77c6850f 11849 ret = get_errno(readahead(arg1, target_offset64(arg2, arg3) , arg4));
2054ac9b
AJ
11850#else
11851 ret = get_errno(readahead(arg1, arg2, arg3));
11852#endif
72eb7ea8 11853 return ret;
e5febef5 11854#endif
a790ae38 11855#ifdef CONFIG_ATTR
ebc05488 11856#ifdef TARGET_NR_setxattr
31e31b8a
FB
11857 case TARGET_NR_listxattr:
11858 case TARGET_NR_llistxattr:
fb5590f7
PM
11859 {
11860 void *p, *b = 0;
11861 if (arg2) {
11862 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
11863 if (!b) {
72eb7ea8 11864 return -TARGET_EFAULT;
fb5590f7
PM
11865 }
11866 }
11867 p = lock_user_string(arg1);
11868 if (p) {
11869 if (num == TARGET_NR_listxattr) {
11870 ret = get_errno(listxattr(p, b, arg3));
11871 } else {
11872 ret = get_errno(llistxattr(p, b, arg3));
11873 }
11874 } else {
11875 ret = -TARGET_EFAULT;
11876 }
11877 unlock_user(p, arg1, 0);
11878 unlock_user(b, arg2, arg3);
72eb7ea8 11879 return ret;
fb5590f7 11880 }
31e31b8a 11881 case TARGET_NR_flistxattr:
fb5590f7
PM
11882 {
11883 void *b = 0;
11884 if (arg2) {
11885 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
11886 if (!b) {
72eb7ea8 11887 return -TARGET_EFAULT;
fb5590f7
PM
11888 }
11889 }
11890 ret = get_errno(flistxattr(arg1, b, arg3));
11891 unlock_user(b, arg2, arg3);
72eb7ea8 11892 return ret;
fb5590f7 11893 }
a790ae38 11894 case TARGET_NR_setxattr:
30297b55 11895 case TARGET_NR_lsetxattr:
a790ae38 11896 {
e3c33ec6
PM
11897 void *p, *n, *v = 0;
11898 if (arg3) {
11899 v = lock_user(VERIFY_READ, arg3, arg4, 1);
11900 if (!v) {
72eb7ea8 11901 return -TARGET_EFAULT;
e3c33ec6
PM
11902 }
11903 }
a790ae38
ACH
11904 p = lock_user_string(arg1);
11905 n = lock_user_string(arg2);
e3c33ec6 11906 if (p && n) {
30297b55
PM
11907 if (num == TARGET_NR_setxattr) {
11908 ret = get_errno(setxattr(p, n, v, arg4, arg5));
11909 } else {
11910 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
11911 }
a790ae38
ACH
11912 } else {
11913 ret = -TARGET_EFAULT;
11914 }
11915 unlock_user(p, arg1, 0);
11916 unlock_user(n, arg2, 0);
11917 unlock_user(v, arg3, 0);
11918 }
72eb7ea8 11919 return ret;
30297b55
PM
11920 case TARGET_NR_fsetxattr:
11921 {
11922 void *n, *v = 0;
11923 if (arg3) {
11924 v = lock_user(VERIFY_READ, arg3, arg4, 1);
11925 if (!v) {
72eb7ea8 11926 return -TARGET_EFAULT;
30297b55
PM
11927 }
11928 }
11929 n = lock_user_string(arg2);
11930 if (n) {
11931 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
11932 } else {
11933 ret = -TARGET_EFAULT;
11934 }
11935 unlock_user(n, arg2, 0);
11936 unlock_user(v, arg3, 0);
11937 }
72eb7ea8 11938 return ret;
a790ae38 11939 case TARGET_NR_getxattr:
30297b55 11940 case TARGET_NR_lgetxattr:
a790ae38 11941 {
e3c33ec6
PM
11942 void *p, *n, *v = 0;
11943 if (arg3) {
11944 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
11945 if (!v) {
72eb7ea8 11946 return -TARGET_EFAULT;
e3c33ec6
PM
11947 }
11948 }
a790ae38
ACH
11949 p = lock_user_string(arg1);
11950 n = lock_user_string(arg2);
e3c33ec6 11951 if (p && n) {
30297b55
PM
11952 if (num == TARGET_NR_getxattr) {
11953 ret = get_errno(getxattr(p, n, v, arg4));
11954 } else {
11955 ret = get_errno(lgetxattr(p, n, v, arg4));
11956 }
a790ae38
ACH
11957 } else {
11958 ret = -TARGET_EFAULT;
11959 }
11960 unlock_user(p, arg1, 0);
11961 unlock_user(n, arg2, 0);
11962 unlock_user(v, arg3, arg4);
11963 }
72eb7ea8 11964 return ret;
30297b55
PM
11965 case TARGET_NR_fgetxattr:
11966 {
11967 void *n, *v = 0;
11968 if (arg3) {
11969 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
11970 if (!v) {
72eb7ea8 11971 return -TARGET_EFAULT;
30297b55
PM
11972 }
11973 }
11974 n = lock_user_string(arg2);
11975 if (n) {
11976 ret = get_errno(fgetxattr(arg1, n, v, arg4));
11977 } else {
11978 ret = -TARGET_EFAULT;
11979 }
11980 unlock_user(n, arg2, 0);
11981 unlock_user(v, arg3, arg4);
11982 }
72eb7ea8 11983 return ret;
a790ae38 11984 case TARGET_NR_removexattr:
30297b55 11985 case TARGET_NR_lremovexattr:
a790ae38
ACH
11986 {
11987 void *p, *n;
11988 p = lock_user_string(arg1);
11989 n = lock_user_string(arg2);
11990 if (p && n) {
30297b55
PM
11991 if (num == TARGET_NR_removexattr) {
11992 ret = get_errno(removexattr(p, n));
11993 } else {
11994 ret = get_errno(lremovexattr(p, n));
11995 }
a790ae38
ACH
11996 } else {
11997 ret = -TARGET_EFAULT;
11998 }
11999 unlock_user(p, arg1, 0);
12000 unlock_user(n, arg2, 0);
12001 }
72eb7ea8 12002 return ret;
30297b55
PM
12003 case TARGET_NR_fremovexattr:
12004 {
12005 void *n;
12006 n = lock_user_string(arg2);
12007 if (n) {
12008 ret = get_errno(fremovexattr(arg1, n));
12009 } else {
12010 ret = -TARGET_EFAULT;
12011 }
12012 unlock_user(n, arg2, 0);
12013 }
72eb7ea8 12014 return ret;
ebc05488 12015#endif
a790ae38 12016#endif /* CONFIG_ATTR */
ebc05488 12017#ifdef TARGET_NR_set_thread_area
5cd4393b 12018 case TARGET_NR_set_thread_area:
8d18e893 12019#if defined(TARGET_MIPS)
d279279e 12020 ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
72eb7ea8 12021 return 0;
ef96779b
EI
12022#elif defined(TARGET_CRIS)
12023 if (arg1 & 0xff)
12024 ret = -TARGET_EINVAL;
12025 else {
12026 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
12027 ret = 0;
12028 }
72eb7ea8 12029 return ret;
8d18e893 12030#elif defined(TARGET_I386) && defined(TARGET_ABI32)
72eb7ea8 12031 return do_set_thread_area(cpu_env, arg1);
1ccd9374
PM
12032#elif defined(TARGET_M68K)
12033 {
0429a971 12034 TaskState *ts = cpu->opaque;
1ccd9374 12035 ts->tp_value = arg1;
72eb7ea8 12036 return 0;
1ccd9374 12037 }
6f5b89a0 12038#else
10f45d98 12039 return -TARGET_ENOSYS;
6f5b89a0
TS
12040#endif
12041#endif
12042#ifdef TARGET_NR_get_thread_area
5cd4393b 12043 case TARGET_NR_get_thread_area:
8d18e893 12044#if defined(TARGET_I386) && defined(TARGET_ABI32)
72eb7ea8 12045 return do_get_thread_area(cpu_env, arg1);
1ccd9374
PM
12046#elif defined(TARGET_M68K)
12047 {
0429a971 12048 TaskState *ts = cpu->opaque;
72eb7ea8 12049 return ts->tp_value;
1ccd9374 12050 }
8d18e893 12051#else
10f45d98 12052 return -TARGET_ENOSYS;
48dc41eb 12053#endif
8d18e893 12054#endif
48dc41eb
FB
12055#ifdef TARGET_NR_getdomainname
12056 case TARGET_NR_getdomainname:
10f45d98 12057 return -TARGET_ENOSYS;
ebc05488 12058#endif
6f5b89a0 12059
12e3340c
MF
12060#ifdef TARGET_NR_clock_settime
12061 case TARGET_NR_clock_settime:
12062 {
12063 struct timespec ts;
12064
12065 ret = target_to_host_timespec(&ts, arg2);
12066 if (!is_error(ret)) {
12067 ret = get_errno(clock_settime(arg1, &ts));
12068 }
72eb7ea8 12069 return ret;
12e3340c
MF
12070 }
12071#endif
c6c8d102
AF
12072#ifdef TARGET_NR_clock_settime64
12073 case TARGET_NR_clock_settime64:
12074 {
12075 struct timespec ts;
12076
12077 ret = target_to_host_timespec64(&ts, arg2);
12078 if (!is_error(ret)) {
12079 ret = get_errno(clock_settime(arg1, &ts));
12080 }
12081 return ret;
12082 }
12083#endif
b5906f95
TS
12084#ifdef TARGET_NR_clock_gettime
12085 case TARGET_NR_clock_gettime:
12086 {
12087 struct timespec ts;
12088 ret = get_errno(clock_gettime(arg1, &ts));
12089 if (!is_error(ret)) {
b9f9908e 12090 ret = host_to_target_timespec(arg2, &ts);
b5906f95 12091 }
72eb7ea8 12092 return ret;
b5906f95
TS
12093 }
12094#endif
c6c8d102
AF
12095#ifdef TARGET_NR_clock_gettime64
12096 case TARGET_NR_clock_gettime64:
12097 {
12098 struct timespec ts;
12099 ret = get_errno(clock_gettime(arg1, &ts));
12100 if (!is_error(ret)) {
12101 ret = host_to_target_timespec64(arg2, &ts);
12102 }
12103 return ret;
12104 }
12105#endif
b5906f95
TS
12106#ifdef TARGET_NR_clock_getres
12107 case TARGET_NR_clock_getres:
12108 {
12109 struct timespec ts;
12110 ret = get_errno(clock_getres(arg1, &ts));
12111 if (!is_error(ret)) {
12112 host_to_target_timespec(arg2, &ts);
12113 }
72eb7ea8 12114 return ret;
b5906f95
TS
12115 }
12116#endif
828cb3a1
FB
12117#ifdef TARGET_NR_clock_getres_time64
12118 case TARGET_NR_clock_getres_time64:
12119 {
12120 struct timespec ts;
12121 ret = get_errno(clock_getres(arg1, &ts));
12122 if (!is_error(ret)) {
12123 host_to_target_timespec64(arg2, &ts);
12124 }
12125 return ret;
12126 }
12127#endif
63d7651b
PB
12128#ifdef TARGET_NR_clock_nanosleep
12129 case TARGET_NR_clock_nanosleep:
12130 {
12131 struct timespec ts;
b09d6406
FB
12132 if (target_to_host_timespec(&ts, arg3)) {
12133 return -TARGET_EFAULT;
12134 }
9e518226
PM
12135 ret = get_errno(safe_clock_nanosleep(arg1, arg2,
12136 &ts, arg4 ? &ts : NULL));
8ec68a0a
LV
12137 /*
12138 * if the call is interrupted by a signal handler, it fails
12139 * with error -TARGET_EINTR and if arg4 is not NULL and arg2 is not
12140 * TIMER_ABSTIME, it returns the remaining unslept time in arg4.
12141 */
b09d6406
FB
12142 if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME &&
12143 host_to_target_timespec(arg4, &ts)) {
12144 return -TARGET_EFAULT;
8ec68a0a 12145 }
8fbe8fdf 12146
72eb7ea8 12147 return ret;
63d7651b
PB
12148 }
12149#endif
6ac03b2c
FB
12150#ifdef TARGET_NR_clock_nanosleep_time64
12151 case TARGET_NR_clock_nanosleep_time64:
12152 {
12153 struct timespec ts;
12154
12155 if (target_to_host_timespec64(&ts, arg3)) {
12156 return -TARGET_EFAULT;
12157 }
12158
12159 ret = get_errno(safe_clock_nanosleep(arg1, arg2,
12160 &ts, arg4 ? &ts : NULL));
12161
12162 if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME &&
12163 host_to_target_timespec64(arg4, &ts)) {
12164 return -TARGET_EFAULT;
12165 }
12166 return ret;
12167 }
12168#endif
b5906f95 12169
6f5b89a0
TS
12170#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
12171 case TARGET_NR_set_tid_address:
3e8f1628 12172 return get_errno(set_tid_address((int *)g2h(cpu, arg1)));
6f5b89a0
TS
12173#endif
12174
4cae1d16 12175 case TARGET_NR_tkill:
72eb7ea8 12176 return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
4cae1d16 12177
71455574 12178 case TARGET_NR_tgkill:
72eb7ea8
RH
12179 return get_errno(safe_tgkill((int)arg1, (int)arg2,
12180 target_to_host_signal(arg3)));
71455574 12181
4f2b1fe8
TS
12182#ifdef TARGET_NR_set_robust_list
12183 case TARGET_NR_set_robust_list:
e9a970a8
PM
12184 case TARGET_NR_get_robust_list:
12185 /* The ABI for supporting robust futexes has userspace pass
12186 * the kernel a pointer to a linked list which is updated by
12187 * userspace after the syscall; the list is walked by the kernel
12188 * when the thread exits. Since the linked list in QEMU guest
12189 * memory isn't a valid linked list for the host and we have
12190 * no way to reliably intercept the thread-death event, we can't
12191 * support these. Silently return ENOSYS so that guest userspace
12192 * falls back to a non-robust futex implementation (which should
12193 * be OK except in the corner case of the guest crashing while
12194 * holding a mutex that is shared with another process via
12195 * shared memory).
12196 */
10f45d98 12197 return -TARGET_ENOSYS;
4f2b1fe8
TS
12198#endif
12199
1acae9f2 12200#if defined(TARGET_NR_utimensat)
9007f0ef
TS
12201 case TARGET_NR_utimensat:
12202 {
ebc996f3
RV
12203 struct timespec *tsp, ts[2];
12204 if (!arg3) {
12205 tsp = NULL;
12206 } else {
b3a3af70
FB
12207 if (target_to_host_timespec(ts, arg3)) {
12208 return -TARGET_EFAULT;
12209 }
12210 if (target_to_host_timespec(ts + 1, arg3 +
12211 sizeof(struct target_timespec))) {
12212 return -TARGET_EFAULT;
12213 }
ebc996f3
RV
12214 tsp = ts;
12215 }
9007f0ef 12216 if (!arg2)
ebc996f3 12217 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
9007f0ef 12218 else {
579a97f7 12219 if (!(p = lock_user_string(arg2))) {
259841c1 12220 return -TARGET_EFAULT;
579a97f7 12221 }
ebc996f3 12222 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
579a97f7 12223 unlock_user(p, arg2, 0);
cac46eb0
FB
12224 }
12225 }
12226 return ret;
12227#endif
12228#ifdef TARGET_NR_utimensat_time64
12229 case TARGET_NR_utimensat_time64:
12230 {
12231 struct timespec *tsp, ts[2];
12232 if (!arg3) {
12233 tsp = NULL;
12234 } else {
12235 if (target_to_host_timespec64(ts, arg3)) {
12236 return -TARGET_EFAULT;
12237 }
12238 if (target_to_host_timespec64(ts + 1, arg3 +
12239 sizeof(struct target__kernel_timespec))) {
12240 return -TARGET_EFAULT;
12241 }
12242 tsp = ts;
12243 }
12244 if (!arg2)
12245 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
12246 else {
12247 p = lock_user_string(arg2);
12248 if (!p) {
12249 return -TARGET_EFAULT;
12250 }
12251 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
12252 unlock_user(p, arg2, 0);
9007f0ef
TS
12253 }
12254 }
72eb7ea8 12255 return ret;
9007f0ef 12256#endif
859e8a89 12257#ifdef TARGET_NR_futex
bd0c5661 12258 case TARGET_NR_futex:
3e8f1628 12259 return do_futex(cpu, arg1, arg2, arg3, arg4, arg5, arg6);
859e8a89 12260#endif
14690296
AF
12261#ifdef TARGET_NR_futex_time64
12262 case TARGET_NR_futex_time64:
3e8f1628 12263 return do_futex_time64(cpu, arg1, arg2, arg3, arg4, arg5, arg6);
14690296 12264#endif
dbfe4c36 12265#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
39b59763
AJ
12266 case TARGET_NR_inotify_init:
12267 ret = get_errno(sys_inotify_init());
b929f7e5
PMD
12268 if (ret >= 0) {
12269 fd_trans_register(ret, &target_inotify_trans);
12270 }
72eb7ea8 12271 return ret;
39b59763 12272#endif
a1606b0b 12273#ifdef CONFIG_INOTIFY1
c05c7a73
RV
12274#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
12275 case TARGET_NR_inotify_init1:
fea243e9
LD
12276 ret = get_errno(sys_inotify_init1(target_to_host_bitmask(arg1,
12277 fcntl_flags_tbl)));
b929f7e5
PMD
12278 if (ret >= 0) {
12279 fd_trans_register(ret, &target_inotify_trans);
12280 }
72eb7ea8 12281 return ret;
c05c7a73 12282#endif
a1606b0b 12283#endif
dbfe4c36 12284#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
39b59763
AJ
12285 case TARGET_NR_inotify_add_watch:
12286 p = lock_user_string(arg2);
12287 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
12288 unlock_user(p, arg2, 0);
72eb7ea8 12289 return ret;
39b59763 12290#endif
dbfe4c36 12291#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
39b59763 12292 case TARGET_NR_inotify_rm_watch:
72eb7ea8 12293 return get_errno(sys_inotify_rm_watch(arg1, arg2));
39b59763 12294#endif
9007f0ef 12295
8ec9cf89 12296#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
24e1003a
AJ
12297 case TARGET_NR_mq_open:
12298 {
c7536ab6 12299 struct mq_attr posix_mq_attr;
26400775 12300 struct mq_attr *pposix_mq_attr;
c7536ab6 12301 int host_flags;
24e1003a 12302
c7536ab6 12303 host_flags = target_to_host_bitmask(arg2, fcntl_flags_tbl);
26400775
LD
12304 pposix_mq_attr = NULL;
12305 if (arg4) {
12306 if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) {
2852aafd 12307 return -TARGET_EFAULT;
26400775
LD
12308 }
12309 pposix_mq_attr = &posix_mq_attr;
c7536ab6 12310 }
24e1003a 12311 p = lock_user_string(arg1 - 1);
c7536ab6 12312 if (!p) {
2852aafd 12313 return -TARGET_EFAULT;
b6ce1f6b 12314 }
26400775 12315 ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr));
24e1003a
AJ
12316 unlock_user (p, arg1, 0);
12317 }
72eb7ea8 12318 return ret;
24e1003a
AJ
12319
12320 case TARGET_NR_mq_unlink:
12321 p = lock_user_string(arg1 - 1);
3211215e 12322 if (!p) {
72eb7ea8 12323 return -TARGET_EFAULT;
3211215e 12324 }
24e1003a
AJ
12325 ret = get_errno(mq_unlink(p));
12326 unlock_user (p, arg1, 0);
72eb7ea8 12327 return ret;
24e1003a 12328
859e8a89 12329#ifdef TARGET_NR_mq_timedsend
24e1003a
AJ
12330 case TARGET_NR_mq_timedsend:
12331 {
12332 struct timespec ts;
12333
12334 p = lock_user (VERIFY_READ, arg2, arg3, 1);
12335 if (arg5 != 0) {
dcbcf5cf
FB
12336 if (target_to_host_timespec(&ts, arg5)) {
12337 return -TARGET_EFAULT;
12338 }
d40ecd66 12339 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
dcbcf5cf
FB
12340 if (!is_error(ret) && host_to_target_timespec(arg5, &ts)) {
12341 return -TARGET_EFAULT;
12342 }
d40ecd66
PM
12343 } else {
12344 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
24e1003a 12345 }
24e1003a
AJ
12346 unlock_user (p, arg2, arg3);
12347 }
72eb7ea8 12348 return ret;
859e8a89 12349#endif
d107e375
FB
12350#ifdef TARGET_NR_mq_timedsend_time64
12351 case TARGET_NR_mq_timedsend_time64:
12352 {
12353 struct timespec ts;
12354
12355 p = lock_user(VERIFY_READ, arg2, arg3, 1);
12356 if (arg5 != 0) {
12357 if (target_to_host_timespec64(&ts, arg5)) {
12358 return -TARGET_EFAULT;
12359 }
12360 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
12361 if (!is_error(ret) && host_to_target_timespec64(arg5, &ts)) {
12362 return -TARGET_EFAULT;
12363 }
12364 } else {
12365 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
12366 }
12367 unlock_user(p, arg2, arg3);
12368 }
12369 return ret;
12370#endif
24e1003a 12371
859e8a89 12372#ifdef TARGET_NR_mq_timedreceive
24e1003a
AJ
12373 case TARGET_NR_mq_timedreceive:
12374 {
12375 struct timespec ts;
12376 unsigned int prio;
12377
12378 p = lock_user (VERIFY_READ, arg2, arg3, 1);
12379 if (arg5 != 0) {
dcbcf5cf
FB
12380 if (target_to_host_timespec(&ts, arg5)) {
12381 return -TARGET_EFAULT;
12382 }
d40ecd66
PM
12383 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12384 &prio, &ts));
dcbcf5cf
FB
12385 if (!is_error(ret) && host_to_target_timespec(arg5, &ts)) {
12386 return -TARGET_EFAULT;
12387 }
d40ecd66
PM
12388 } else {
12389 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12390 &prio, NULL));
24e1003a 12391 }
24e1003a
AJ
12392 unlock_user (p, arg2, arg3);
12393 if (arg4 != 0)
12394 put_user_u32(prio, arg4);
12395 }
72eb7ea8 12396 return ret;
859e8a89 12397#endif
d107e375
FB
12398#ifdef TARGET_NR_mq_timedreceive_time64
12399 case TARGET_NR_mq_timedreceive_time64:
12400 {
12401 struct timespec ts;
12402 unsigned int prio;
12403
12404 p = lock_user(VERIFY_READ, arg2, arg3, 1);
12405 if (arg5 != 0) {
12406 if (target_to_host_timespec64(&ts, arg5)) {
12407 return -TARGET_EFAULT;
12408 }
12409 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12410 &prio, &ts));
12411 if (!is_error(ret) && host_to_target_timespec64(arg5, &ts)) {
12412 return -TARGET_EFAULT;
12413 }
12414 } else {
12415 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12416 &prio, NULL));
12417 }
12418 unlock_user(p, arg2, arg3);
12419 if (arg4 != 0) {
12420 put_user_u32(prio, arg4);
12421 }
12422 }
12423 return ret;
12424#endif
24e1003a
AJ
12425
12426 /* Not implemented for now... */
12427/* case TARGET_NR_mq_notify: */
12428/* break; */
12429
12430 case TARGET_NR_mq_getsetattr:
12431 {
12432 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
12433 ret = 0;
24e1003a
AJ
12434 if (arg2 != 0) {
12435 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
a23ea409
MF
12436 ret = get_errno(mq_setattr(arg1, &posix_mq_attr_in,
12437 &posix_mq_attr_out));
12438 } else if (arg3 != 0) {
12439 ret = get_errno(mq_getattr(arg1, &posix_mq_attr_out));
12440 }
12441 if (ret == 0 && arg3 != 0) {
12442 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
24e1003a 12443 }
24e1003a 12444 }
72eb7ea8 12445 return ret;
24e1003a
AJ
12446#endif
12447
3ce34dfb
VS
12448#ifdef CONFIG_SPLICE
12449#ifdef TARGET_NR_tee
12450 case TARGET_NR_tee:
12451 {
12452 ret = get_errno(tee(arg1,arg2,arg3,arg4));
12453 }
72eb7ea8 12454 return ret;
3ce34dfb
VS
12455#endif
12456#ifdef TARGET_NR_splice
12457 case TARGET_NR_splice:
12458 {
12459 loff_t loff_in, loff_out;
12460 loff_t *ploff_in = NULL, *ploff_out = NULL;
17644b36
AS
12461 if (arg2) {
12462 if (get_user_u64(loff_in, arg2)) {
2852aafd 12463 return -TARGET_EFAULT;
17644b36 12464 }
3ce34dfb
VS
12465 ploff_in = &loff_in;
12466 }
17644b36
AS
12467 if (arg4) {
12468 if (get_user_u64(loff_out, arg4)) {
2852aafd 12469 return -TARGET_EFAULT;
17644b36 12470 }
3ce34dfb
VS
12471 ploff_out = &loff_out;
12472 }
12473 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
17644b36
AS
12474 if (arg2) {
12475 if (put_user_u64(loff_in, arg2)) {
2852aafd 12476 return -TARGET_EFAULT;
17644b36
AS
12477 }
12478 }
12479 if (arg4) {
12480 if (put_user_u64(loff_out, arg4)) {
2852aafd 12481 return -TARGET_EFAULT;
17644b36
AS
12482 }
12483 }
3ce34dfb 12484 }
72eb7ea8 12485 return ret;
3ce34dfb
VS
12486#endif
12487#ifdef TARGET_NR_vmsplice
12488 case TARGET_NR_vmsplice:
12489 {
f287b2c2
RH
12490 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
12491 if (vec != NULL) {
12492 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
12493 unlock_iovec(vec, arg2, arg3, 0);
12494 } else {
12495 ret = -host_to_target_errno(errno);
12496 }
3ce34dfb 12497 }
72eb7ea8 12498 return ret;
3ce34dfb
VS
12499#endif
12500#endif /* CONFIG_SPLICE */
c2882b96
RV
12501#ifdef CONFIG_EVENTFD
12502#if defined(TARGET_NR_eventfd)
12503 case TARGET_NR_eventfd:
12504 ret = get_errno(eventfd(arg1, 0));
b929f7e5
PMD
12505 if (ret >= 0) {
12506 fd_trans_register(ret, &target_eventfd_trans);
12507 }
72eb7ea8 12508 return ret;
c2882b96
RV
12509#endif
12510#if defined(TARGET_NR_eventfd2)
12511 case TARGET_NR_eventfd2:
5947c697 12512 {
78721301 12513 int host_flags = arg2 & (~(TARGET_O_NONBLOCK_MASK | TARGET_O_CLOEXEC));
5947c697
PJ
12514 if (arg2 & TARGET_O_NONBLOCK) {
12515 host_flags |= O_NONBLOCK;
12516 }
12517 if (arg2 & TARGET_O_CLOEXEC) {
12518 host_flags |= O_CLOEXEC;
12519 }
12520 ret = get_errno(eventfd(arg1, host_flags));
b929f7e5
PMD
12521 if (ret >= 0) {
12522 fd_trans_register(ret, &target_eventfd_trans);
12523 }
72eb7ea8 12524 return ret;
5947c697 12525 }
c2882b96
RV
12526#endif
12527#endif /* CONFIG_EVENTFD */
d0927938
UH
12528#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
12529 case TARGET_NR_fallocate:
20249ae1
AG
12530#if TARGET_ABI_BITS == 32
12531 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
12532 target_offset64(arg5, arg6)));
12533#else
d0927938 12534 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
20249ae1 12535#endif
72eb7ea8 12536 return ret;
c727f47d
PM
12537#endif
12538#if defined(CONFIG_SYNC_FILE_RANGE)
12539#if defined(TARGET_NR_sync_file_range)
12540 case TARGET_NR_sync_file_range:
12541#if TARGET_ABI_BITS == 32
bfcedc57
RV
12542#if defined(TARGET_MIPS)
12543 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
12544 target_offset64(arg5, arg6), arg7));
12545#else
c727f47d
PM
12546 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
12547 target_offset64(arg4, arg5), arg6));
bfcedc57 12548#endif /* !TARGET_MIPS */
c727f47d
PM
12549#else
12550 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
12551#endif
72eb7ea8 12552 return ret;
c727f47d 12553#endif
5bcb4986
LV
12554#if defined(TARGET_NR_sync_file_range2) || \
12555 defined(TARGET_NR_arm_sync_file_range)
c727f47d
PM
12556#if defined(TARGET_NR_sync_file_range2)
12557 case TARGET_NR_sync_file_range2:
5bcb4986
LV
12558#endif
12559#if defined(TARGET_NR_arm_sync_file_range)
12560 case TARGET_NR_arm_sync_file_range:
12561#endif
c727f47d
PM
12562 /* This is like sync_file_range but the arguments are reordered */
12563#if TARGET_ABI_BITS == 32
12564 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
12565 target_offset64(arg5, arg6), arg2));
12566#else
12567 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
12568#endif
72eb7ea8 12569 return ret;
c727f47d 12570#endif
3b6edd16 12571#endif
e36800c9
LV
12572#if defined(TARGET_NR_signalfd4)
12573 case TARGET_NR_signalfd4:
72eb7ea8 12574 return do_signalfd4(arg1, arg2, arg4);
e36800c9
LV
12575#endif
12576#if defined(TARGET_NR_signalfd)
12577 case TARGET_NR_signalfd:
72eb7ea8 12578 return do_signalfd4(arg1, arg2, 0);
e36800c9 12579#endif
3b6edd16
PM
12580#if defined(CONFIG_EPOLL)
12581#if defined(TARGET_NR_epoll_create)
12582 case TARGET_NR_epoll_create:
72eb7ea8 12583 return get_errno(epoll_create(arg1));
3b6edd16
PM
12584#endif
12585#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
12586 case TARGET_NR_epoll_create1:
386d3865 12587 return get_errno(epoll_create1(target_to_host_bitmask(arg1, fcntl_flags_tbl)));
3b6edd16
PM
12588#endif
12589#if defined(TARGET_NR_epoll_ctl)
12590 case TARGET_NR_epoll_ctl:
12591 {
12592 struct epoll_event ep;
12593 struct epoll_event *epp = 0;
12594 if (arg4) {
c7811022
L
12595 if (arg2 != EPOLL_CTL_DEL) {
12596 struct target_epoll_event *target_ep;
12597 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
12598 return -TARGET_EFAULT;
12599 }
12600 ep.events = tswap32(target_ep->events);
12601 /*
12602 * The epoll_data_t union is just opaque data to the kernel,
12603 * so we transfer all 64 bits across and need not worry what
12604 * actual data type it is.
12605 */
12606 ep.data.u64 = tswap64(target_ep->data.u64);
12607 unlock_user_struct(target_ep, arg4, 0);
3b6edd16 12608 }
c7811022
L
12609 /*
12610 * before kernel 2.6.9, EPOLL_CTL_DEL operation required a
12611 * non-null pointer, even though this argument is ignored.
12612 *
3b6edd16 12613 */
3b6edd16
PM
12614 epp = &ep;
12615 }
72eb7ea8 12616 return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
3b6edd16
PM
12617 }
12618#endif
12619
227f0214 12620#if defined(TARGET_NR_epoll_wait) || defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12621#if defined(TARGET_NR_epoll_wait)
12622 case TARGET_NR_epoll_wait:
12623#endif
227f0214 12624#if defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12625 case TARGET_NR_epoll_pwait:
12626#endif
12627 {
12628 struct target_epoll_event *target_ep;
12629 struct epoll_event *ep;
12630 int epfd = arg1;
12631 int maxevents = arg3;
12632 int timeout = arg4;
12633
2ba7fae3 12634 if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
72eb7ea8 12635 return -TARGET_EINVAL;
2ba7fae3
PM
12636 }
12637
3b6edd16
PM
12638 target_ep = lock_user(VERIFY_WRITE, arg2,
12639 maxevents * sizeof(struct target_epoll_event), 1);
12640 if (!target_ep) {
2852aafd 12641 return -TARGET_EFAULT;
3b6edd16
PM
12642 }
12643
04c95f4d
PM
12644 ep = g_try_new(struct epoll_event, maxevents);
12645 if (!ep) {
12646 unlock_user(target_ep, arg2, 0);
72eb7ea8 12647 return -TARGET_ENOMEM;
04c95f4d 12648 }
3b6edd16
PM
12649
12650 switch (num) {
227f0214 12651#if defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12652 case TARGET_NR_epoll_pwait:
12653 {
12654 target_sigset_t *target_set;
12655 sigset_t _set, *set = &_set;
12656
12657 if (arg5) {
c815701e
PM
12658 if (arg6 != sizeof(target_sigset_t)) {
12659 ret = -TARGET_EINVAL;
12660 break;
12661 }
12662
3b6edd16
PM
12663 target_set = lock_user(VERIFY_READ, arg5,
12664 sizeof(target_sigset_t), 1);
12665 if (!target_set) {
04c95f4d
PM
12666 ret = -TARGET_EFAULT;
12667 break;
3b6edd16
PM
12668 }
12669 target_to_host_sigset(set, target_set);
12670 unlock_user(target_set, arg5, 0);
12671 } else {
12672 set = NULL;
12673 }
12674
227f0214
PM
12675 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
12676 set, SIGSET_T_SIZE));
3b6edd16
PM
12677 break;
12678 }
12679#endif
12680#if defined(TARGET_NR_epoll_wait)
12681 case TARGET_NR_epoll_wait:
227f0214
PM
12682 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
12683 NULL, 0));
3b6edd16
PM
12684 break;
12685#endif
12686 default:
12687 ret = -TARGET_ENOSYS;
12688 }
12689 if (!is_error(ret)) {
12690 int i;
12691 for (i = 0; i < ret; i++) {
12692 target_ep[i].events = tswap32(ep[i].events);
12693 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
12694 }
04c95f4d
PM
12695 unlock_user(target_ep, arg2,
12696 ret * sizeof(struct target_epoll_event));
12697 } else {
12698 unlock_user(target_ep, arg2, 0);
3b6edd16 12699 }
04c95f4d 12700 g_free(ep);
72eb7ea8 12701 return ret;
3b6edd16
PM
12702 }
12703#endif
163a05a8
PM
12704#endif
12705#ifdef TARGET_NR_prlimit64
12706 case TARGET_NR_prlimit64:
12707 {
12708 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
12709 struct target_rlimit64 *target_rnew, *target_rold;
12710 struct host_rlimit64 rnew, rold, *rnewp = 0;
95018018 12711 int resource = target_to_host_resource(arg2);
055d92f8
TK
12712
12713 if (arg3 && (resource != RLIMIT_AS &&
12714 resource != RLIMIT_DATA &&
12715 resource != RLIMIT_STACK)) {
163a05a8 12716 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
2852aafd 12717 return -TARGET_EFAULT;
163a05a8
PM
12718 }
12719 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
12720 rnew.rlim_max = tswap64(target_rnew->rlim_max);
12721 unlock_user_struct(target_rnew, arg3, 0);
12722 rnewp = &rnew;
12723 }
12724
95018018 12725 ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
163a05a8
PM
12726 if (!is_error(ret) && arg4) {
12727 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
2852aafd 12728 return -TARGET_EFAULT;
163a05a8
PM
12729 }
12730 target_rold->rlim_cur = tswap64(rold.rlim_cur);
12731 target_rold->rlim_max = tswap64(rold.rlim_max);
12732 unlock_user_struct(target_rold, arg4, 1);
12733 }
72eb7ea8 12734 return ret;
163a05a8 12735 }
3d21d29c
RH
12736#endif
12737#ifdef TARGET_NR_gethostname
12738 case TARGET_NR_gethostname:
12739 {
12740 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
12741 if (name) {
12742 ret = get_errno(gethostname(name, arg2));
12743 unlock_user(name, arg1, arg2);
12744 } else {
12745 ret = -TARGET_EFAULT;
12746 }
72eb7ea8 12747 return ret;
3d21d29c 12748 }
89aaf1a6
RV
12749#endif
12750#ifdef TARGET_NR_atomic_cmpxchg_32
12751 case TARGET_NR_atomic_cmpxchg_32:
12752 {
12753 /* should use start_exclusive from main.c */
12754 abi_ulong mem_value;
12755 if (get_user_u32(mem_value, arg6)) {
12756 target_siginfo_t info;
12757 info.si_signo = SIGSEGV;
12758 info.si_errno = 0;
12759 info.si_code = TARGET_SEGV_MAPERR;
12760 info._sifields._sigfault._addr = arg6;
9d2803f7
PM
12761 queue_signal((CPUArchState *)cpu_env, info.si_signo,
12762 QEMU_SI_FAULT, &info);
89aaf1a6
RV
12763 ret = 0xdeadbeef;
12764
12765 }
12766 if (mem_value == arg2)
12767 put_user_u32(arg1, arg6);
72eb7ea8 12768 return mem_value;
89aaf1a6
RV
12769 }
12770#endif
12771#ifdef TARGET_NR_atomic_barrier
12772 case TARGET_NR_atomic_barrier:
72eb7ea8
RH
12773 /* Like the kernel implementation and the
12774 qemu arm barrier, no-op this? */
12775 return 0;
d0927938 12776#endif
f4f1e10a
ECL
12777
12778#ifdef TARGET_NR_timer_create
12779 case TARGET_NR_timer_create:
12780 {
12781 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
12782
12783 struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
f4f1e10a
ECL
12784
12785 int clkid = arg1;
12786 int timer_index = next_free_host_timer();
12787
12788 if (timer_index < 0) {
12789 ret = -TARGET_EAGAIN;
12790 } else {
12791 timer_t *phtimer = g_posix_timers + timer_index;
12792
12793 if (arg2) {
f4f1e10a 12794 phost_sevp = &host_sevp;
c065976f
PM
12795 ret = target_to_host_sigevent(phost_sevp, arg2);
12796 if (ret != 0) {
72eb7ea8 12797 return ret;
c065976f 12798 }
f4f1e10a
ECL
12799 }
12800
12801 ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
12802 if (ret) {
12803 phtimer = NULL;
12804 } else {
aecc8861 12805 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
2852aafd 12806 return -TARGET_EFAULT;
f4f1e10a 12807 }
f4f1e10a
ECL
12808 }
12809 }
72eb7ea8 12810 return ret;
f4f1e10a
ECL
12811 }
12812#endif
12813
12814#ifdef TARGET_NR_timer_settime
12815 case TARGET_NR_timer_settime:
12816 {
12817 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
12818 * struct itimerspec * old_value */
aecc8861 12819 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12820
aecc8861
AG
12821 if (timerid < 0) {
12822 ret = timerid;
12823 } else if (arg3 == 0) {
f4f1e10a
ECL
12824 ret = -TARGET_EINVAL;
12825 } else {
e52a99f7 12826 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12827 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
12828
40c80b5e 12829 if (target_to_host_itimerspec(&hspec_new, arg3)) {
2852aafd 12830 return -TARGET_EFAULT;
40c80b5e 12831 }
f4f1e10a
ECL
12832 ret = get_errno(
12833 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
40c80b5e 12834 if (arg4 && host_to_target_itimerspec(arg4, &hspec_old)) {
2852aafd 12835 return -TARGET_EFAULT;
40c80b5e 12836 }
f4f1e10a 12837 }
72eb7ea8 12838 return ret;
f4f1e10a
ECL
12839 }
12840#endif
12841
828cb3a1
FB
12842#ifdef TARGET_NR_timer_settime64
12843 case TARGET_NR_timer_settime64:
12844 {
12845 target_timer_t timerid = get_timer_id(arg1);
12846
12847 if (timerid < 0) {
12848 ret = timerid;
12849 } else if (arg3 == 0) {
12850 ret = -TARGET_EINVAL;
12851 } else {
12852 timer_t htimer = g_posix_timers[timerid];
12853 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
12854
12855 if (target_to_host_itimerspec64(&hspec_new, arg3)) {
12856 return -TARGET_EFAULT;
12857 }
12858 ret = get_errno(
12859 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
12860 if (arg4 && host_to_target_itimerspec64(arg4, &hspec_old)) {
12861 return -TARGET_EFAULT;
12862 }
12863 }
12864 return ret;
12865 }
12866#endif
12867
f4f1e10a
ECL
12868#ifdef TARGET_NR_timer_gettime
12869 case TARGET_NR_timer_gettime:
12870 {
12871 /* args: timer_t timerid, struct itimerspec *curr_value */
aecc8861 12872 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12873
aecc8861
AG
12874 if (timerid < 0) {
12875 ret = timerid;
12876 } else if (!arg2) {
12877 ret = -TARGET_EFAULT;
f4f1e10a 12878 } else {
e52a99f7 12879 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12880 struct itimerspec hspec;
12881 ret = get_errno(timer_gettime(htimer, &hspec));
12882
12883 if (host_to_target_itimerspec(arg2, &hspec)) {
12884 ret = -TARGET_EFAULT;
12885 }
12886 }
72eb7ea8 12887 return ret;
f4f1e10a
ECL
12888 }
12889#endif
12890
828cb3a1
FB
12891#ifdef TARGET_NR_timer_gettime64
12892 case TARGET_NR_timer_gettime64:
12893 {
12894 /* args: timer_t timerid, struct itimerspec64 *curr_value */
12895 target_timer_t timerid = get_timer_id(arg1);
12896
12897 if (timerid < 0) {
12898 ret = timerid;
12899 } else if (!arg2) {
12900 ret = -TARGET_EFAULT;
12901 } else {
12902 timer_t htimer = g_posix_timers[timerid];
12903 struct itimerspec hspec;
12904 ret = get_errno(timer_gettime(htimer, &hspec));
12905
12906 if (host_to_target_itimerspec64(arg2, &hspec)) {
12907 ret = -TARGET_EFAULT;
12908 }
12909 }
12910 return ret;
12911 }
12912#endif
12913
f4f1e10a
ECL
12914#ifdef TARGET_NR_timer_getoverrun
12915 case TARGET_NR_timer_getoverrun:
12916 {
12917 /* args: timer_t timerid */
aecc8861 12918 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12919
aecc8861
AG
12920 if (timerid < 0) {
12921 ret = timerid;
f4f1e10a 12922 } else {
e52a99f7 12923 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12924 ret = get_errno(timer_getoverrun(htimer));
12925 }
72eb7ea8 12926 return ret;
f4f1e10a
ECL
12927 }
12928#endif
12929
12930#ifdef TARGET_NR_timer_delete
12931 case TARGET_NR_timer_delete:
12932 {
12933 /* args: timer_t timerid */
aecc8861 12934 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12935
aecc8861
AG
12936 if (timerid < 0) {
12937 ret = timerid;
f4f1e10a 12938 } else {
e52a99f7 12939 timer_t htimer = g_posix_timers[timerid];
f4f1e10a 12940 ret = get_errno(timer_delete(htimer));
e52a99f7 12941 g_posix_timers[timerid] = 0;
f4f1e10a 12942 }
72eb7ea8 12943 return ret;
f4f1e10a
ECL
12944 }
12945#endif
12946
51834341
RV
12947#if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
12948 case TARGET_NR_timerfd_create:
72eb7ea8
RH
12949 return get_errno(timerfd_create(arg1,
12950 target_to_host_bitmask(arg2, fcntl_flags_tbl)));
51834341
RV
12951#endif
12952
12953#if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
12954 case TARGET_NR_timerfd_gettime:
12955 {
12956 struct itimerspec its_curr;
12957
12958 ret = get_errno(timerfd_gettime(arg1, &its_curr));
12959
12960 if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
2852aafd 12961 return -TARGET_EFAULT;
51834341
RV
12962 }
12963 }
72eb7ea8 12964 return ret;
51834341
RV
12965#endif
12966
828cb3a1
FB
12967#if defined(TARGET_NR_timerfd_gettime64) && defined(CONFIG_TIMERFD)
12968 case TARGET_NR_timerfd_gettime64:
12969 {
12970 struct itimerspec its_curr;
12971
12972 ret = get_errno(timerfd_gettime(arg1, &its_curr));
12973
12974 if (arg2 && host_to_target_itimerspec64(arg2, &its_curr)) {
12975 return -TARGET_EFAULT;
12976 }
12977 }
12978 return ret;
12979#endif
12980
51834341
RV
12981#if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
12982 case TARGET_NR_timerfd_settime:
12983 {
12984 struct itimerspec its_new, its_old, *p_new;
12985
12986 if (arg3) {
12987 if (target_to_host_itimerspec(&its_new, arg3)) {
2852aafd 12988 return -TARGET_EFAULT;
51834341
RV
12989 }
12990 p_new = &its_new;
12991 } else {
12992 p_new = NULL;
12993 }
12994
12995 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
12996
12997 if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
2852aafd 12998 return -TARGET_EFAULT;
51834341
RV
12999 }
13000 }
72eb7ea8 13001 return ret;
51834341
RV
13002#endif
13003
828cb3a1
FB
13004#if defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD)
13005 case TARGET_NR_timerfd_settime64:
13006 {
13007 struct itimerspec its_new, its_old, *p_new;
13008
13009 if (arg3) {
13010 if (target_to_host_itimerspec64(&its_new, arg3)) {
13011 return -TARGET_EFAULT;
13012 }
13013 p_new = &its_new;
13014 } else {
13015 p_new = NULL;
13016 }
13017
13018 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
13019
13020 if (arg4 && host_to_target_itimerspec64(arg4, &its_old)) {
13021 return -TARGET_EFAULT;
13022 }
13023 }
13024 return ret;
13025#endif
13026
ab31cda3
PB
13027#if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
13028 case TARGET_NR_ioprio_get:
72eb7ea8 13029 return get_errno(ioprio_get(arg1, arg2));
ab31cda3
PB
13030#endif
13031
13032#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
13033 case TARGET_NR_ioprio_set:
72eb7ea8 13034 return get_errno(ioprio_set(arg1, arg2, arg3));
ab31cda3
PB
13035#endif
13036
9af5c906
RV
13037#if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
13038 case TARGET_NR_setns:
72eb7ea8 13039 return get_errno(setns(arg1, arg2));
9af5c906
RV
13040#endif
13041#if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
13042 case TARGET_NR_unshare:
72eb7ea8 13043 return get_errno(unshare(arg1));
9af5c906 13044#endif
2f14788c
LV
13045#if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
13046 case TARGET_NR_kcmp:
72eb7ea8 13047 return get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
2f14788c 13048#endif
fa97e38e
RH
13049#ifdef TARGET_NR_swapcontext
13050 case TARGET_NR_swapcontext:
13051 /* PowerPC specific. */
72eb7ea8 13052 return do_swapcontext(cpu_env, arg1, arg2, arg3);
fa97e38e 13053#endif
9bdfa4d2
SCW
13054#ifdef TARGET_NR_memfd_create
13055 case TARGET_NR_memfd_create:
13056 p = lock_user_string(arg1);
13057 if (!p) {
13058 return -TARGET_EFAULT;
13059 }
13060 ret = get_errno(memfd_create(p, arg2));
13061 fd_trans_unregister(ret);
13062 unlock_user(p, arg1, 0);
13063 return ret;
13064#endif
8500476f
AS
13065#if defined TARGET_NR_membarrier && defined __NR_membarrier
13066 case TARGET_NR_membarrier:
13067 return get_errno(membarrier(arg1, arg2));
13068#endif
9af5c906 13069
84946457
AS
13070#if defined(TARGET_NR_copy_file_range) && defined(__NR_copy_file_range)
13071 case TARGET_NR_copy_file_range:
13072 {
13073 loff_t inoff, outoff;
13074 loff_t *pinoff = NULL, *poutoff = NULL;
13075
13076 if (arg2) {
13077 if (get_user_u64(inoff, arg2)) {
13078 return -TARGET_EFAULT;
13079 }
13080 pinoff = &inoff;
13081 }
13082 if (arg4) {
13083 if (get_user_u64(outoff, arg4)) {
13084 return -TARGET_EFAULT;
13085 }
13086 poutoff = &outoff;
13087 }
0fa259dd 13088 /* Do not sign-extend the count parameter. */
84946457 13089 ret = get_errno(safe_copy_file_range(arg1, pinoff, arg3, poutoff,
0fa259dd 13090 (abi_ulong)arg5, arg6));
84946457
AS
13091 if (!is_error(ret) && ret > 0) {
13092 if (arg2) {
13093 if (put_user_u64(inoff, arg2)) {
13094 return -TARGET_EFAULT;
13095 }
13096 }
13097 if (arg4) {
13098 if (put_user_u64(outoff, arg4)) {
13099 return -TARGET_EFAULT;
13100 }
13101 }
13102 }
13103 }
13104 return ret;
13105#endif
13106
e10fbe8f
YT
13107#if defined(TARGET_NR_pivot_root)
13108 case TARGET_NR_pivot_root:
13109 {
13110 void *p2;
13111 p = lock_user_string(arg1); /* new_root */
13112 p2 = lock_user_string(arg2); /* put_old */
13113 if (!p || !p2) {
13114 ret = -TARGET_EFAULT;
13115 } else {
13116 ret = get_errno(pivot_root(p, p2));
13117 }
13118 unlock_user(p2, arg2, 0);
13119 unlock_user(p, arg1, 0);
13120 }
13121 return ret;
13122#endif
13123
31e31b8a 13124 default:
122f9c83 13125 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
72eb7ea8 13126 return -TARGET_ENOSYS;
31e31b8a 13127 }
31e31b8a
FB
13128 return ret;
13129}
dc1ce18b
RH
13130
13131abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
13132 abi_long arg2, abi_long arg3, abi_long arg4,
13133 abi_long arg5, abi_long arg6, abi_long arg7,
13134 abi_long arg8)
13135{
29a0af61 13136 CPUState *cpu = env_cpu(cpu_env);
dc1ce18b
RH
13137 abi_long ret;
13138
13139#ifdef DEBUG_ERESTARTSYS
13140 /* Debug-only code for exercising the syscall-restart code paths
13141 * in the per-architecture cpu main loops: restart every syscall
13142 * the guest makes once before letting it through.
13143 */
13144 {
13145 static bool flag;
13146 flag = !flag;
13147 if (flag) {
af254a27 13148 return -QEMU_ERESTARTSYS;
dc1ce18b
RH
13149 }
13150 }
13151#endif
13152
c36f7a64
EC
13153 record_syscall_start(cpu, num, arg1,
13154 arg2, arg3, arg4, arg5, arg6, arg7, arg8);
dc1ce18b 13155
4b25a506 13156 if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
e400e119 13157 print_syscall(cpu_env, num, arg1, arg2, arg3, arg4, arg5, arg6);
4b25a506
JK
13158 }
13159
13160 ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
13161 arg5, arg6, arg7, arg8);
13162
13163 if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
e400e119
FB
13164 print_syscall_ret(cpu_env, num, ret, arg1, arg2,
13165 arg3, arg4, arg5, arg6);
dc1ce18b
RH
13166 }
13167
c36f7a64 13168 record_syscall_return(cpu, num, ret);
dc1ce18b
RH
13169 return ret;
13170}