]> git.proxmox.com Git - mirror_qemu.git/blame - linux-user/syscall.c
linux-user: Use "!= 0" when checking if MAP_FIXED_NOREPLACE is non-zero
[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>
8853f86e 54#include <netinet/ip.h>
7854b056 55#include <netinet/tcp.h>
86fcd946 56#include <linux/wireless.h>
920394db 57#include <linux/icmp.h>
ee1ac3a1
HD
58#include <linux/icmpv6.h>
59#include <linux/errqueue.h>
d6d6d6fe 60#include <linux/random.h>
d80a1905
RV
61#ifdef CONFIG_TIMERFD
62#include <sys/timerfd.h>
63#endif
c2882b96
RV
64#ifdef CONFIG_EVENTFD
65#include <sys/eventfd.h>
66#endif
3b6edd16
PM
67#ifdef CONFIG_EPOLL
68#include <sys/epoll.h>
69#endif
a790ae38 70#ifdef CONFIG_ATTR
1de7afc9 71#include "qemu/xattr.h"
a790ae38 72#endif
a8fd1aba
PM
73#ifdef CONFIG_SENDFILE
74#include <sys/sendfile.h>
75#endif
bd27e675
AM
76#ifdef CONFIG_KCOV
77#include <sys/kcov.h>
78#endif
31e31b8a
FB
79
80#define termios host_termios
81#define winsize host_winsize
82#define termio host_termio
04369ff2
FB
83#define sgttyb host_sgttyb /* same as target */
84#define tchars host_tchars /* same as target */
85#define ltchars host_ltchars /* same as target */
31e31b8a
FB
86
87#include <linux/termios.h>
88#include <linux/unistd.h>
31e31b8a
FB
89#include <linux/cdrom.h>
90#include <linux/hdreg.h>
91#include <linux/soundcard.h>
19b84f3c 92#include <linux/kd.h>
8fbd6b52 93#include <linux/mtio.h>
350d1779 94#include <linux/fs.h>
ab22b4dd 95#include <linux/fd.h>
dace20dc 96#if defined(CONFIG_FIEMAP)
285da2b9 97#include <linux/fiemap.h>
dace20dc 98#endif
f7680a55 99#include <linux/fb.h>
6c753a63
CT
100#if defined(CONFIG_USBFS)
101#include <linux/usbdevice_fs.h>
a133367e 102#include <linux/usb/ch9.h>
6c753a63 103#endif
f7680a55 104#include <linux/vt.h>
56e904ec 105#include <linux/dm-ioctl.h>
c07ecc68 106#include <linux/reboot.h>
7ff7b666 107#include <linux/route.h>
f57d4192 108#include <linux/filter.h>
fff8c539 109#include <linux/blkpg.h>
a82ea939 110#include <netpacket/packet.h>
6c5b5645 111#include <linux/netlink.h>
f31dddd2 112#include <linux/if_alg.h>
68365f96 113#include <linux/rtc.h>
1c4c6fcd 114#include <sound/asound.h>
d6092e08
FB
115#ifdef CONFIG_BTRFS
116#include <linux/btrfs.h>
117#endif
e865b97f
CG
118#ifdef HAVE_DRM_H
119#include <libdrm/drm.h>
913b03c2 120#include <libdrm/i915_drm.h>
e865b97f 121#endif
d7e4036e 122#include "linux_loop.h"
18cb0088 123#include "uname.h"
31e31b8a 124
3ef693a0 125#include "qemu.h"
5ebdd774 126#include "qemu/guest-random.h"
01ef6b9e 127#include "qemu/selfmap.h"
c36f7a64 128#include "user/syscall-trace.h"
51977e25 129#include "qapi/error.h"
f7e6a401 130#include "fd-trans.h"
dcb32f1d 131#include "tcg/tcg.h"
31e31b8a 132
5ea2fc84
PM
133#ifndef CLONE_IO
134#define CLONE_IO 0x80000000 /* Clone io context */
135#endif
136
137/* We can't directly call the host clone syscall, because this will
138 * badly confuse libc (breaking mutexes, for example). So we must
139 * divide clone flags into:
140 * * flag combinations that look like pthread_create()
141 * * flag combinations that look like fork()
142 * * flags we can implement within QEMU itself
143 * * flags we can't support and will return an error for
144 */
145/* For thread creation, all these flags must be present; for
146 * fork, none must be present.
147 */
148#define CLONE_THREAD_FLAGS \
149 (CLONE_VM | CLONE_FS | CLONE_FILES | \
150 CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
151
152/* These flags are ignored:
153 * CLONE_DETACHED is now ignored by the kernel;
154 * CLONE_IO is just an optimisation hint to the I/O scheduler
155 */
156#define CLONE_IGNORED_FLAGS \
157 (CLONE_DETACHED | CLONE_IO)
158
159/* Flags for fork which we can implement within QEMU itself */
160#define CLONE_OPTIONAL_FORK_FLAGS \
161 (CLONE_SETTLS | CLONE_PARENT_SETTID | \
162 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
163
164/* Flags for thread creation which we can implement within QEMU itself */
165#define CLONE_OPTIONAL_THREAD_FLAGS \
166 (CLONE_SETTLS | CLONE_PARENT_SETTID | \
167 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
168
169#define CLONE_INVALID_FORK_FLAGS \
170 (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
171
172#define CLONE_INVALID_THREAD_FLAGS \
173 (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS | \
174 CLONE_IGNORED_FLAGS))
175
176/* CLONE_VFORK is special cased early in do_fork(). The other flag bits
177 * have almost all been allocated. We cannot support any of
178 * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
179 * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
180 * The checks against the invalid thread masks above will catch these.
181 * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
182 */
30813cea 183
71a8f7fe
TB
184/* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
185 * once. This exercises the codepaths for restart.
186 */
187//#define DEBUG_ERESTARTSYS
31e31b8a 188
1a9353d2 189//#include <linux/msdos_fs.h>
6556a833
AJ
190#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
191#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
1a9353d2 192
70a194b9
FB
193#undef _syscall0
194#undef _syscall1
195#undef _syscall2
196#undef _syscall3
197#undef _syscall4
198#undef _syscall5
83fcb515 199#undef _syscall6
70a194b9 200
83fcb515 201#define _syscall0(type,name) \
8fcd3692 202static type name (void) \
83fcb515
FB
203{ \
204 return syscall(__NR_##name); \
205}
70a194b9 206
83fcb515 207#define _syscall1(type,name,type1,arg1) \
8fcd3692 208static type name (type1 arg1) \
83fcb515
FB
209{ \
210 return syscall(__NR_##name, arg1); \
70a194b9
FB
211}
212
83fcb515 213#define _syscall2(type,name,type1,arg1,type2,arg2) \
8fcd3692 214static type name (type1 arg1,type2 arg2) \
83fcb515
FB
215{ \
216 return syscall(__NR_##name, arg1, arg2); \
70a194b9
FB
217}
218
83fcb515 219#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
8fcd3692 220static type name (type1 arg1,type2 arg2,type3 arg3) \
83fcb515
FB
221{ \
222 return syscall(__NR_##name, arg1, arg2, arg3); \
70a194b9
FB
223}
224
83fcb515 225#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
8fcd3692 226static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
83fcb515
FB
227{ \
228 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
70a194b9
FB
229}
230
83fcb515
FB
231#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
232 type5,arg5) \
8fcd3692 233static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
83fcb515
FB
234{ \
235 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
70a194b9
FB
236}
237
83fcb515
FB
238
239#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
240 type5,arg5,type6,arg6) \
8fcd3692
BS
241static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
242 type6 arg6) \
83fcb515
FB
243{ \
244 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
70a194b9 245}
83fcb515 246
70a194b9 247
31e31b8a 248#define __NR_sys_uname __NR_uname
72f03900 249#define __NR_sys_getcwd1 __NR_getcwd
72f03900 250#define __NR_sys_getdents __NR_getdents
dab2ed99 251#define __NR_sys_getdents64 __NR_getdents64
c6cda17a 252#define __NR_sys_getpriority __NR_getpriority
66fb9763 253#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
cf8b8bfc 254#define __NR_sys_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
7494b0f9 255#define __NR_sys_syslog __NR_syslog
14690296
AF
256#if defined(__NR_futex)
257# define __NR_sys_futex __NR_futex
258#endif
259#if defined(__NR_futex_time64)
260# define __NR_sys_futex_time64 __NR_futex_time64
261#endif
39b59763
AJ
262#define __NR_sys_inotify_init __NR_inotify_init
263#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
264#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
efa92184 265#define __NR_sys_statx __NR_statx
31e31b8a 266
b1cef6d0 267#if defined(__alpha__) || defined(__x86_64__) || defined(__s390x__)
9af9eaaa
FB
268#define __NR__llseek __NR_lseek
269#endif
270
a29e5ba2
JH
271/* Newer kernel ports have llseek() instead of _llseek() */
272#if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
273#define TARGET_NR__llseek TARGET_NR_llseek
274#endif
275
71ba74f6
DB
276#define __NR_sys_gettid __NR_gettid
277_syscall0(int, sys_gettid)
2b3f64cb
PM
278
279/* For the 64-bit guest on 32-bit host case we must emulate
280 * getdents using getdents64, because otherwise the host
281 * might hand us back more dirent records than we can fit
282 * into the guest buffer after structure format conversion.
283 * Otherwise we emulate getdents with getdents if the host has it.
284 */
285#if defined(__NR_getdents) && HOST_LONG_BITS >= TARGET_ABI_BITS
286#define EMULATE_GETDENTS_WITH_GETDENTS
287#endif
288
289#if defined(TARGET_NR_getdents) && defined(EMULATE_GETDENTS_WITH_GETDENTS)
3b3f24ad 290_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
3307e236 291#endif
2b3f64cb
PM
292#if (defined(TARGET_NR_getdents) && \
293 !defined(EMULATE_GETDENTS_WITH_GETDENTS)) || \
3307e236 294 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
3b3f24ad
AJ
295_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
296#endif
d35b261c 297#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
3b3f24ad
AJ
298_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
299 loff_t *, res, uint, wh);
300#endif
c1a402a7 301_syscall3(int, sys_rt_sigqueueinfo, pid_t, pid, int, sig, siginfo_t *, uinfo)
cf8b8bfc
MS
302_syscall4(int, sys_rt_tgsigqueueinfo, pid_t, pid, pid_t, tid, int, sig,
303 siginfo_t *, uinfo)
3b3f24ad 304_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
3b3f24ad
AJ
305#ifdef __NR_exit_group
306_syscall1(int,exit_group,int,error_code)
307#endif
308#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
309_syscall1(int,set_tid_address,int *,tidptr)
310#endif
14690296 311#if defined(__NR_futex)
3b3f24ad
AJ
312_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
313 const struct timespec *,timeout,int *,uaddr2,int,val3)
314#endif
14690296
AF
315#if defined(__NR_futex_time64)
316_syscall6(int,sys_futex_time64,int *,uaddr,int,op,int,val,
317 const struct timespec *,timeout,int *,uaddr2,int,val3)
318#endif
737de1d1
MF
319#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
320_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
321 unsigned long *, user_mask_ptr);
322#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
323_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
324 unsigned long *, user_mask_ptr);
b827c3ed
ST
325#define __NR_sys_getcpu __NR_getcpu
326_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
0f6b4d21
AG
327_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
328 void *, arg);
e0eb210e
PM
329_syscall2(int, capget, struct __user_cap_header_struct *, header,
330 struct __user_cap_data_struct *, data);
331_syscall2(int, capset, struct __user_cap_header_struct *, header,
332 struct __user_cap_data_struct *, data);
ab31cda3
PB
333#if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
334_syscall2(int, ioprio_get, int, which, int, who)
335#endif
336#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
337_syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
338#endif
f894efd1
LV
339#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
340_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
341#endif
3b3f24ad 342
2f14788c
LV
343#if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
344_syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
345 unsigned long, idx1, unsigned long, idx2)
346#endif
347
efa92184
AR
348/*
349 * It is assumed that struct statx is architecture independent.
350 */
351#if defined(TARGET_NR_statx) && defined(__NR_statx)
352_syscall5(int, sys_statx, int, dirfd, const char *, pathname, int, flags,
353 unsigned int, mask, struct target_statx *, statxbuf)
354#endif
8500476f
AS
355#if defined(TARGET_NR_membarrier) && defined(__NR_membarrier)
356_syscall2(int, membarrier, int, cmd, int, flags)
357#endif
efa92184 358
3b3f24ad
AJ
359static bitmask_transtbl fcntl_flags_tbl[] = {
360 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
361 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
362 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
363 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
364 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
365 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
366 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
367 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
afc8763f 368 { TARGET_O_SYNC, TARGET_O_DSYNC, O_SYNC, O_DSYNC, },
3b3f24ad
AJ
369 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
370 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
371 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
372 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
3b3f24ad
AJ
373#if defined(O_DIRECT)
374 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
afc8763f
RH
375#endif
376#if defined(O_NOATIME)
377 { TARGET_O_NOATIME, TARGET_O_NOATIME, O_NOATIME, O_NOATIME },
378#endif
379#if defined(O_CLOEXEC)
380 { TARGET_O_CLOEXEC, TARGET_O_CLOEXEC, O_CLOEXEC, O_CLOEXEC },
381#endif
382#if defined(O_PATH)
383 { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
5f9cee46
RV
384#endif
385#if defined(O_TMPFILE)
386 { TARGET_O_TMPFILE, TARGET_O_TMPFILE, O_TMPFILE, O_TMPFILE },
afc8763f
RH
387#endif
388 /* Don't terminate the list prematurely on 64-bit host+guest. */
389#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
390 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
3b3f24ad
AJ
391#endif
392 { 0, 0, 0, 0 }
393};
394
0f6bb195 395_syscall2(int, sys_getcwd1, char *, buf, size_t, size)
3b3f24ad 396
cac46eb0 397#if defined(TARGET_NR_utimensat) || defined(TARGET_NR_utimensat_time64)
700fa58e 398#if defined(__NR_utimensat)
1acae9f2 399#define __NR_sys_utimensat __NR_utimensat
9007f0ef
TS
400_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
401 const struct timespec *,tsp,int,flags)
1acae9f2
PM
402#else
403static int sys_utimensat(int dirfd, const char *pathname,
404 const struct timespec times[2], int flags)
405{
406 errno = ENOSYS;
407 return -1;
408}
9007f0ef 409#endif
1acae9f2 410#endif /* TARGET_NR_utimensat */
3b3f24ad 411
95d0307c
AS
412#ifdef TARGET_NR_renameat2
413#if defined(__NR_renameat2)
414#define __NR_sys_renameat2 __NR_renameat2
415_syscall5(int, sys_renameat2, int, oldfd, const char *, old, int, newfd,
416 const char *, new, unsigned int, flags)
417#else
418static int sys_renameat2(int oldfd, const char *old,
419 int newfd, const char *new, int flags)
420{
421 if (flags == 0) {
422 return renameat(oldfd, old, newfd, new);
423 }
424 errno = ENOSYS;
425 return -1;
426}
427#endif
428#endif /* TARGET_NR_renameat2 */
429
3b3f24ad 430#ifdef CONFIG_INOTIFY
8690e420 431#include <sys/inotify.h>
3b3f24ad 432
39b59763 433#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
3b3f24ad
AJ
434static int sys_inotify_init(void)
435{
436 return (inotify_init());
437}
39b59763
AJ
438#endif
439#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
3b3f24ad
AJ
440static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
441{
442 return (inotify_add_watch(fd, pathname, mask));
443}
39b59763
AJ
444#endif
445#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
3b3f24ad
AJ
446static int sys_inotify_rm_watch(int fd, int32_t wd)
447{
8690e420 448 return (inotify_rm_watch(fd, wd));
3b3f24ad 449}
bd0c5661 450#endif
c05c7a73
RV
451#ifdef CONFIG_INOTIFY1
452#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
453static int sys_inotify_init1(int flags)
454{
455 return (inotify_init1(flags));
456}
457#endif
458#endif
3b3f24ad
AJ
459#else
460/* Userspace can usually survive runtime without inotify */
461#undef TARGET_NR_inotify_init
c05c7a73 462#undef TARGET_NR_inotify_init1
3b3f24ad
AJ
463#undef TARGET_NR_inotify_add_watch
464#undef TARGET_NR_inotify_rm_watch
465#endif /* CONFIG_INOTIFY */
466
163a05a8
PM
467#if defined(TARGET_NR_prlimit64)
468#ifndef __NR_prlimit64
469# define __NR_prlimit64 -1
470#endif
471#define __NR_sys_prlimit64 __NR_prlimit64
472/* The glibc rlimit structure may not be that used by the underlying syscall */
473struct host_rlimit64 {
474 uint64_t rlim_cur;
475 uint64_t rlim_max;
476};
477_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
478 const struct host_rlimit64 *, new_limit,
479 struct host_rlimit64 *, old_limit)
480#endif
481
f4f1e10a
ECL
482
483#if defined(TARGET_NR_timer_create)
6f9ff551 484/* Maximum of 32 active POSIX timers allowed at any one time. */
f4f1e10a
ECL
485static timer_t g_posix_timers[32] = { 0, } ;
486
487static inline int next_free_host_timer(void)
488{
489 int k ;
490 /* FIXME: Does finding the next free slot require a lock? */
491 for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
492 if (g_posix_timers[k] == 0) {
493 g_posix_timers[k] = (timer_t) 1;
494 return k;
495 }
496 }
497 return -1;
498}
499#endif
500
b92c47c1
TS
501#define ERRNO_TABLE_SIZE 1200
502
503/* target_to_host_errno_table[] is initialized from
504 * host_to_target_errno_table[] in syscall_init(). */
505static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
506};
507
637947f1 508/*
fe8f096b 509 * This list is the union of errno values overridden in asm-<arch>/errno.h
637947f1
TS
510 * minus the errnos that are not actually generic to all archs.
511 */
b92c47c1 512static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
08703b9f 513 [EAGAIN] = TARGET_EAGAIN,
637947f1
TS
514 [EIDRM] = TARGET_EIDRM,
515 [ECHRNG] = TARGET_ECHRNG,
516 [EL2NSYNC] = TARGET_EL2NSYNC,
517 [EL3HLT] = TARGET_EL3HLT,
518 [EL3RST] = TARGET_EL3RST,
519 [ELNRNG] = TARGET_ELNRNG,
520 [EUNATCH] = TARGET_EUNATCH,
521 [ENOCSI] = TARGET_ENOCSI,
522 [EL2HLT] = TARGET_EL2HLT,
523 [EDEADLK] = TARGET_EDEADLK,
524 [ENOLCK] = TARGET_ENOLCK,
525 [EBADE] = TARGET_EBADE,
526 [EBADR] = TARGET_EBADR,
527 [EXFULL] = TARGET_EXFULL,
528 [ENOANO] = TARGET_ENOANO,
529 [EBADRQC] = TARGET_EBADRQC,
530 [EBADSLT] = TARGET_EBADSLT,
531 [EBFONT] = TARGET_EBFONT,
532 [ENOSTR] = TARGET_ENOSTR,
533 [ENODATA] = TARGET_ENODATA,
534 [ETIME] = TARGET_ETIME,
535 [ENOSR] = TARGET_ENOSR,
536 [ENONET] = TARGET_ENONET,
537 [ENOPKG] = TARGET_ENOPKG,
538 [EREMOTE] = TARGET_EREMOTE,
539 [ENOLINK] = TARGET_ENOLINK,
540 [EADV] = TARGET_EADV,
541 [ESRMNT] = TARGET_ESRMNT,
542 [ECOMM] = TARGET_ECOMM,
543 [EPROTO] = TARGET_EPROTO,
544 [EDOTDOT] = TARGET_EDOTDOT,
545 [EMULTIHOP] = TARGET_EMULTIHOP,
546 [EBADMSG] = TARGET_EBADMSG,
547 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
548 [EOVERFLOW] = TARGET_EOVERFLOW,
549 [ENOTUNIQ] = TARGET_ENOTUNIQ,
550 [EBADFD] = TARGET_EBADFD,
551 [EREMCHG] = TARGET_EREMCHG,
552 [ELIBACC] = TARGET_ELIBACC,
553 [ELIBBAD] = TARGET_ELIBBAD,
554 [ELIBSCN] = TARGET_ELIBSCN,
555 [ELIBMAX] = TARGET_ELIBMAX,
556 [ELIBEXEC] = TARGET_ELIBEXEC,
557 [EILSEQ] = TARGET_EILSEQ,
558 [ENOSYS] = TARGET_ENOSYS,
559 [ELOOP] = TARGET_ELOOP,
560 [ERESTART] = TARGET_ERESTART,
561 [ESTRPIPE] = TARGET_ESTRPIPE,
562 [ENOTEMPTY] = TARGET_ENOTEMPTY,
563 [EUSERS] = TARGET_EUSERS,
564 [ENOTSOCK] = TARGET_ENOTSOCK,
565 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
566 [EMSGSIZE] = TARGET_EMSGSIZE,
567 [EPROTOTYPE] = TARGET_EPROTOTYPE,
568 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
569 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
570 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
571 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
572 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
573 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
574 [EADDRINUSE] = TARGET_EADDRINUSE,
575 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
576 [ENETDOWN] = TARGET_ENETDOWN,
577 [ENETUNREACH] = TARGET_ENETUNREACH,
578 [ENETRESET] = TARGET_ENETRESET,
579 [ECONNABORTED] = TARGET_ECONNABORTED,
580 [ECONNRESET] = TARGET_ECONNRESET,
581 [ENOBUFS] = TARGET_ENOBUFS,
582 [EISCONN] = TARGET_EISCONN,
583 [ENOTCONN] = TARGET_ENOTCONN,
584 [EUCLEAN] = TARGET_EUCLEAN,
585 [ENOTNAM] = TARGET_ENOTNAM,
586 [ENAVAIL] = TARGET_ENAVAIL,
587 [EISNAM] = TARGET_EISNAM,
588 [EREMOTEIO] = TARGET_EREMOTEIO,
0444a3b7 589 [EDQUOT] = TARGET_EDQUOT,
637947f1
TS
590 [ESHUTDOWN] = TARGET_ESHUTDOWN,
591 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
592 [ETIMEDOUT] = TARGET_ETIMEDOUT,
593 [ECONNREFUSED] = TARGET_ECONNREFUSED,
594 [EHOSTDOWN] = TARGET_EHOSTDOWN,
595 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
596 [EALREADY] = TARGET_EALREADY,
597 [EINPROGRESS] = TARGET_EINPROGRESS,
598 [ESTALE] = TARGET_ESTALE,
599 [ECANCELED] = TARGET_ECANCELED,
600 [ENOMEDIUM] = TARGET_ENOMEDIUM,
601 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
b7fe5db7 602#ifdef ENOKEY
637947f1 603 [ENOKEY] = TARGET_ENOKEY,
b7fe5db7
TS
604#endif
605#ifdef EKEYEXPIRED
637947f1 606 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
b7fe5db7
TS
607#endif
608#ifdef EKEYREVOKED
637947f1 609 [EKEYREVOKED] = TARGET_EKEYREVOKED,
b7fe5db7
TS
610#endif
611#ifdef EKEYREJECTED
637947f1 612 [EKEYREJECTED] = TARGET_EKEYREJECTED,
b7fe5db7
TS
613#endif
614#ifdef EOWNERDEAD
637947f1 615 [EOWNERDEAD] = TARGET_EOWNERDEAD,
b7fe5db7
TS
616#endif
617#ifdef ENOTRECOVERABLE
637947f1 618 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
b7fe5db7 619#endif
da39db63
AM
620#ifdef ENOMSG
621 [ENOMSG] = TARGET_ENOMSG,
622#endif
fe8ed7d5
RH
623#ifdef ERKFILL
624 [ERFKILL] = TARGET_ERFKILL,
625#endif
626#ifdef EHWPOISON
627 [EHWPOISON] = TARGET_EHWPOISON,
628#endif
b92c47c1 629};
637947f1
TS
630
631static inline int host_to_target_errno(int err)
632{
2466119c
TB
633 if (err >= 0 && err < ERRNO_TABLE_SIZE &&
634 host_to_target_errno_table[err]) {
637947f1 635 return host_to_target_errno_table[err];
2466119c 636 }
637947f1
TS
637 return err;
638}
639
b92c47c1
TS
640static inline int target_to_host_errno(int err)
641{
2466119c
TB
642 if (err >= 0 && err < ERRNO_TABLE_SIZE &&
643 target_to_host_errno_table[err]) {
b92c47c1 644 return target_to_host_errno_table[err];
2466119c 645 }
b92c47c1
TS
646 return err;
647}
648
992f48a0 649static inline abi_long get_errno(abi_long ret)
31e31b8a
FB
650{
651 if (ret == -1)
637947f1 652 return -host_to_target_errno(errno);
31e31b8a
FB
653 else
654 return ret;
655}
656
7dcdaeaf 657const char *target_strerror(int err)
b92c47c1 658{
da2a34f7
PM
659 if (err == TARGET_ERESTARTSYS) {
660 return "To be restarted";
661 }
662 if (err == TARGET_QEMU_ESIGRETURN) {
663 return "Successful exit from sigreturn";
664 }
665
962b289e
AG
666 if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
667 return NULL;
668 }
b92c47c1
TS
669 return strerror(target_to_host_errno(err));
670}
671
4d330cee
TB
672#define safe_syscall0(type, name) \
673static type safe_##name(void) \
674{ \
675 return safe_syscall(__NR_##name); \
676}
677
678#define safe_syscall1(type, name, type1, arg1) \
679static type safe_##name(type1 arg1) \
680{ \
681 return safe_syscall(__NR_##name, arg1); \
682}
683
684#define safe_syscall2(type, name, type1, arg1, type2, arg2) \
685static type safe_##name(type1 arg1, type2 arg2) \
686{ \
687 return safe_syscall(__NR_##name, arg1, arg2); \
688}
689
690#define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
691static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
692{ \
693 return safe_syscall(__NR_##name, arg1, arg2, arg3); \
694}
695
696#define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
697 type4, arg4) \
698static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
699{ \
700 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
701}
702
703#define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
704 type4, arg4, type5, arg5) \
705static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
706 type5 arg5) \
707{ \
708 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
709}
710
711#define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
712 type4, arg4, type5, arg5, type6, arg6) \
713static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
714 type5 arg5, type6 arg6) \
715{ \
716 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
717}
718
50afd02b
TB
719safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
720safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
c10a0738
TB
721safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
722 int, flags, mode_t, mode)
859e8a89 723#if defined(TARGET_NR_wait4) || defined(TARGET_NR_waitpid)
4af80a37
TB
724safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
725 struct rusage *, rusage)
859e8a89 726#endif
4af80a37
TB
727safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
728 int, options, struct rusage *, rusage)
ffdcbe22 729safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
859e8a89 730#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
e5ce9688 731 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
6df9d38d
PM
732safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
733 fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
859e8a89 734#endif
e5ce9688 735#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_ppoll_time64)
a6130237
PM
736safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
737 struct timespec *, tsp, const sigset_t *, sigmask,
738 size_t, sigsetsize)
859e8a89 739#endif
227f0214
PM
740safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
741 int, maxevents, int, timeout, const sigset_t *, sigmask,
742 size_t, sigsetsize)
14690296 743#if defined(__NR_futex)
d509eeb1
PM
744safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
745 const struct timespec *,timeout,int *,uaddr2,int,val3)
859e8a89 746#endif
14690296
AF
747#if defined(__NR_futex_time64)
748safe_syscall6(int,futex_time64,int *,uaddr,int,op,int,val, \
749 const struct timespec *,timeout,int *,uaddr2,int,val3)
750#endif
2fe4fba1 751safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
bef653d9
PM
752safe_syscall2(int, kill, pid_t, pid, int, sig)
753safe_syscall2(int, tkill, int, tid, int, sig)
754safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
918c03ed
PM
755safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
756safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
0f26386c
DJ
757safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt,
758 unsigned long, pos_l, unsigned long, pos_h)
f8d00fba
DJ
759safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt,
760 unsigned long, pos_l, unsigned long, pos_h)
2a3c7619
PM
761safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
762 socklen_t, addrlen)
66687530
PM
763safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
764 int, flags, const struct sockaddr *, addr, socklen_t, addrlen)
765safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, size_t, len,
766 int, flags, struct sockaddr *, addr, socklen_t *, addrlen)
767safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, flags)
768safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
2a845989 769safe_syscall2(int, flock, int, fd, int, operation)
ddcbde15 770#if defined(TARGET_NR_rt_sigtimedwait) || defined(TARGET_NR_rt_sigtimedwait_time64)
b3f82330
PM
771safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, uinfo,
772 const struct timespec *, uts, size_t, sigsetsize)
859e8a89 773#endif
ff6dc130
PM
774safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len,
775 int, flags)
859e8a89 776#if defined(TARGET_NR_nanosleep)
9e518226
PM
777safe_syscall2(int, nanosleep, const struct timespec *, req,
778 struct timespec *, rem)
859e8a89 779#endif
6ac03b2c
FB
780#if defined(TARGET_NR_clock_nanosleep) || \
781 defined(TARGET_NR_clock_nanosleep_time64)
9e518226
PM
782safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
783 const struct timespec *, req, struct timespec *, rem)
784#endif
524fa340 785#ifdef __NR_ipc
d8c08b1e
MK
786#ifdef __s390x__
787safe_syscall5(int, ipc, int, call, long, first, long, second, long, third,
788 void *, ptr)
789#else
89f9fe44
PM
790safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
791 void *, ptr, long, fifth)
86e63695 792#endif
d8c08b1e 793#endif
86e63695
LV
794#ifdef __NR_msgsnd
795safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
796 int, flags)
86e63695
LV
797#endif
798#ifdef __NR_msgrcv
799safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
800 long, msgtype, int, flags)
86e63695
LV
801#endif
802#ifdef __NR_semtimedop
803safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
804 unsigned, nsops, const struct timespec *, timeout)
89f9fe44 805#endif
d107e375
FB
806#if defined(TARGET_NR_mq_timedsend) || \
807 defined(TARGET_NR_mq_timedsend_time64)
d40ecd66
PM
808safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
809 size_t, len, unsigned, prio, const struct timespec *, timeout)
859e8a89 810#endif
d107e375
FB
811#if defined(TARGET_NR_mq_timedreceive) || \
812 defined(TARGET_NR_mq_timedreceive_time64)
d40ecd66
PM
813safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
814 size_t, len, unsigned *, prio, const struct timespec *, timeout)
815#endif
49ca6f3e
PM
816/* We do ioctl like this rather than via safe_syscall3 to preserve the
817 * "third argument might be integer or pointer or not present" behaviour of
818 * the libc function.
819 */
820#define safe_ioctl(...) safe_syscall(__NR_ioctl, __VA_ARGS__)
435da5e7
PM
821/* Similarly for fcntl. Note that callers must always:
822 * pass the F_GETLK64 etc constants rather than the unsuffixed F_GETLK
823 * use the flock64 struct rather than unsuffixed flock
824 * This will then work and use a 64-bit offset for both 32-bit and 64-bit hosts.
825 */
826#ifdef __NR_fcntl64
827#define safe_fcntl(...) safe_syscall(__NR_fcntl64, __VA_ARGS__)
828#else
829#define safe_fcntl(...) safe_syscall(__NR_fcntl, __VA_ARGS__)
830#endif
50afd02b 831
8289d112
PB
832static inline int host_to_target_sock_type(int host_type)
833{
834 int target_type;
835
836 switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
837 case SOCK_DGRAM:
838 target_type = TARGET_SOCK_DGRAM;
839 break;
840 case SOCK_STREAM:
841 target_type = TARGET_SOCK_STREAM;
842 break;
843 default:
844 target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
845 break;
846 }
847
848#if defined(SOCK_CLOEXEC)
849 if (host_type & SOCK_CLOEXEC) {
850 target_type |= TARGET_SOCK_CLOEXEC;
851 }
852#endif
853
854#if defined(SOCK_NONBLOCK)
855 if (host_type & SOCK_NONBLOCK) {
856 target_type |= TARGET_SOCK_NONBLOCK;
857 }
858#endif
859
860 return target_type;
861}
862
992f48a0
BS
863static abi_ulong target_brk;
864static abi_ulong target_original_brk;
4d1de87c 865static abi_ulong brk_page;
31e31b8a 866
992f48a0 867void target_set_brk(abi_ulong new_brk)
31e31b8a 868{
4c1de73d 869 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
4d1de87c 870 brk_page = HOST_PAGE_ALIGN(target_brk);
31e31b8a
FB
871}
872
4d1de87c
CV
873//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
874#define DEBUGF_BRK(message, args...)
875
0da46a6e 876/* do_brk() must return target values and target errnos. */
992f48a0 877abi_long do_brk(abi_ulong new_brk)
31e31b8a 878{
992f48a0 879 abi_long mapped_addr;
ef4330c2 880 abi_ulong new_alloc_size;
31e31b8a 881
3a0c6c4a 882 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
4d1de87c
CV
883
884 if (!new_brk) {
3a0c6c4a 885 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
53a5960a 886 return target_brk;
4d1de87c
CV
887 }
888 if (new_brk < target_original_brk) {
3a0c6c4a
PB
889 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
890 target_brk);
7ab240ad 891 return target_brk;
4d1de87c 892 }
3b46e624 893
4d1de87c
CV
894 /* If the new brk is less than the highest page reserved to the
895 * target heap allocation, set it and we're almost done... */
896 if (new_brk <= brk_page) {
897 /* Heap contents are initialized to zero, as for anonymous
898 * mapped pages. */
899 if (new_brk > target_brk) {
900 memset(g2h(target_brk), 0, new_brk - target_brk);
901 }
31e31b8a 902 target_brk = new_brk;
3a0c6c4a 903 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
72e21db7 904 return target_brk;
31e31b8a
FB
905 }
906
00faf08c
PM
907 /* We need to allocate more memory after the brk... Note that
908 * we don't use MAP_FIXED because that will map over the top of
909 * any existing mapping (like the one with the host libc or qemu
910 * itself); instead we treat "mapped but at wrong address" as
911 * a failure and unmap again.
912 */
4d1de87c 913 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
5fafdf24 914 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
54936004 915 PROT_READ|PROT_WRITE,
00faf08c
PM
916 MAP_ANON|MAP_PRIVATE, 0, 0));
917
918 if (mapped_addr == brk_page) {
70afc343
CV
919 /* Heap contents are initialized to zero, as for anonymous
920 * mapped pages. Technically the new pages are already
921 * initialized to zero since they *are* anonymous mapped
922 * pages, however we have to take care with the contents that
923 * come from the remaining part of the previous page: it may
924 * contains garbage data due to a previous heap usage (grown
925 * then shrunken). */
926 memset(g2h(target_brk), 0, brk_page - target_brk);
927
00faf08c 928 target_brk = new_brk;
4d1de87c 929 brk_page = HOST_PAGE_ALIGN(target_brk);
3a0c6c4a
PB
930 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
931 target_brk);
00faf08c
PM
932 return target_brk;
933 } else if (mapped_addr != -1) {
934 /* Mapped but at wrong address, meaning there wasn't actually
935 * enough space for this brk.
936 */
937 target_munmap(mapped_addr, new_alloc_size);
938 mapped_addr = -1;
3a0c6c4a 939 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
4d1de87c
CV
940 }
941 else {
3a0c6c4a 942 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
00faf08c 943 }
7ab240ad 944
7dd46c02
RH
945#if defined(TARGET_ALPHA)
946 /* We (partially) emulate OSF/1 on Alpha, which requires we
947 return a proper errno, not an unchanged brk value. */
00faf08c 948 return -TARGET_ENOMEM;
7dd46c02 949#endif
00faf08c 950 /* For everything else, return the previous break. */
7ab240ad 951 return target_brk;
31e31b8a
FB
952}
953
859e8a89 954#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
e5ce9688 955 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
26edcf41
TS
956static inline abi_long copy_from_user_fdset(fd_set *fds,
957 abi_ulong target_fds_addr,
958 int n)
31e31b8a 959{
26edcf41
TS
960 int i, nw, j, k;
961 abi_ulong b, *target_fds;
962
b1b2db29 963 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
26edcf41
TS
964 if (!(target_fds = lock_user(VERIFY_READ,
965 target_fds_addr,
966 sizeof(abi_ulong) * nw,
967 1)))
968 return -TARGET_EFAULT;
969
970 FD_ZERO(fds);
971 k = 0;
972 for (i = 0; i < nw; i++) {
973 /* grab the abi_ulong */
974 __get_user(b, &target_fds[i]);
975 for (j = 0; j < TARGET_ABI_BITS; j++) {
976 /* check the bit inside the abi_ulong */
977 if ((b >> j) & 1)
978 FD_SET(k, fds);
979 k++;
31e31b8a 980 }
31e31b8a 981 }
26edcf41
TS
982
983 unlock_user(target_fds, target_fds_addr, 0);
984
985 return 0;
31e31b8a
FB
986}
987
055e0906
MF
988static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
989 abi_ulong target_fds_addr,
990 int n)
991{
992 if (target_fds_addr) {
993 if (copy_from_user_fdset(fds, target_fds_addr, n))
994 return -TARGET_EFAULT;
995 *fds_ptr = fds;
996 } else {
997 *fds_ptr = NULL;
998 }
999 return 0;
1000}
1001
26edcf41
TS
1002static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
1003 const fd_set *fds,
1004 int n)
31e31b8a 1005{
31e31b8a 1006 int i, nw, j, k;
992f48a0 1007 abi_long v;
26edcf41 1008 abi_ulong *target_fds;
31e31b8a 1009
b1b2db29 1010 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
26edcf41
TS
1011 if (!(target_fds = lock_user(VERIFY_WRITE,
1012 target_fds_addr,
1013 sizeof(abi_ulong) * nw,
1014 0)))
1015 return -TARGET_EFAULT;
1016
1017 k = 0;
1018 for (i = 0; i < nw; i++) {
1019 v = 0;
1020 for (j = 0; j < TARGET_ABI_BITS; j++) {
9ab709be 1021 v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
26edcf41 1022 k++;
31e31b8a 1023 }
26edcf41 1024 __put_user(v, &target_fds[i]);
31e31b8a 1025 }
26edcf41
TS
1026
1027 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
1028
1029 return 0;
31e31b8a 1030}
859e8a89 1031#endif
31e31b8a 1032
c596ed17
FB
1033#if defined(__alpha__)
1034#define HOST_HZ 1024
1035#else
1036#define HOST_HZ 100
1037#endif
1038
992f48a0 1039static inline abi_long host_to_target_clock_t(long ticks)
c596ed17
FB
1040{
1041#if HOST_HZ == TARGET_HZ
1042 return ticks;
1043#else
1044 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
1045#endif
1046}
1047
579a97f7
FB
1048static inline abi_long host_to_target_rusage(abi_ulong target_addr,
1049 const struct rusage *rusage)
b409186b 1050{
53a5960a
PB
1051 struct target_rusage *target_rusage;
1052
579a97f7
FB
1053 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
1054 return -TARGET_EFAULT;
cbb21eed
MB
1055 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
1056 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
1057 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
1058 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
1059 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
1060 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
1061 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
1062 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
1063 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
1064 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
1065 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
1066 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
1067 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
1068 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
1069 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
1070 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
1071 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
1072 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
53a5960a 1073 unlock_user_struct(target_rusage, target_addr, 1);
579a97f7
FB
1074
1075 return 0;
b409186b
FB
1076}
1077
859e8a89 1078#ifdef TARGET_NR_setrlimit
cbb21eed 1079static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
81bbe906 1080{
cbb21eed 1081 abi_ulong target_rlim_swap;
95b33b2f
WT
1082 rlim_t result;
1083
cbb21eed
MB
1084 target_rlim_swap = tswapal(target_rlim);
1085 if (target_rlim_swap == TARGET_RLIM_INFINITY)
1086 return RLIM_INFINITY;
1087
1088 result = target_rlim_swap;
1089 if (target_rlim_swap != (rlim_t)result)
1090 return RLIM_INFINITY;
95b33b2f
WT
1091
1092 return result;
81bbe906 1093}
859e8a89 1094#endif
81bbe906 1095
859e8a89 1096#if defined(TARGET_NR_getrlimit) || defined(TARGET_NR_ugetrlimit)
cbb21eed 1097static inline abi_ulong host_to_target_rlim(rlim_t rlim)
81bbe906 1098{
cbb21eed
MB
1099 abi_ulong target_rlim_swap;
1100 abi_ulong result;
95b33b2f 1101
cbb21eed 1102 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
95b33b2f 1103 target_rlim_swap = TARGET_RLIM_INFINITY;
81bbe906 1104 else
95b33b2f 1105 target_rlim_swap = rlim;
cbb21eed 1106 result = tswapal(target_rlim_swap);
95b33b2f
WT
1107
1108 return result;
81bbe906 1109}
859e8a89 1110#endif
81bbe906 1111
e22b7015
WT
1112static inline int target_to_host_resource(int code)
1113{
1114 switch (code) {
1115 case TARGET_RLIMIT_AS:
1116 return RLIMIT_AS;
1117 case TARGET_RLIMIT_CORE:
1118 return RLIMIT_CORE;
1119 case TARGET_RLIMIT_CPU:
1120 return RLIMIT_CPU;
1121 case TARGET_RLIMIT_DATA:
1122 return RLIMIT_DATA;
1123 case TARGET_RLIMIT_FSIZE:
1124 return RLIMIT_FSIZE;
1125 case TARGET_RLIMIT_LOCKS:
1126 return RLIMIT_LOCKS;
1127 case TARGET_RLIMIT_MEMLOCK:
1128 return RLIMIT_MEMLOCK;
1129 case TARGET_RLIMIT_MSGQUEUE:
1130 return RLIMIT_MSGQUEUE;
1131 case TARGET_RLIMIT_NICE:
1132 return RLIMIT_NICE;
1133 case TARGET_RLIMIT_NOFILE:
1134 return RLIMIT_NOFILE;
1135 case TARGET_RLIMIT_NPROC:
1136 return RLIMIT_NPROC;
1137 case TARGET_RLIMIT_RSS:
1138 return RLIMIT_RSS;
1139 case TARGET_RLIMIT_RTPRIO:
1140 return RLIMIT_RTPRIO;
1141 case TARGET_RLIMIT_SIGPENDING:
1142 return RLIMIT_SIGPENDING;
1143 case TARGET_RLIMIT_STACK:
1144 return RLIMIT_STACK;
1145 default:
1146 return code;
1147 }
1148}
1149
788f5ec4
TS
1150static inline abi_long copy_from_user_timeval(struct timeval *tv,
1151 abi_ulong target_tv_addr)
31e31b8a 1152{
53a5960a
PB
1153 struct target_timeval *target_tv;
1154
6d5d5dde 1155 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
579a97f7 1156 return -TARGET_EFAULT;
6d5d5dde 1157 }
788f5ec4
TS
1158
1159 __get_user(tv->tv_sec, &target_tv->tv_sec);
1160 __get_user(tv->tv_usec, &target_tv->tv_usec);
1161
1162 unlock_user_struct(target_tv, target_tv_addr, 0);
579a97f7
FB
1163
1164 return 0;
31e31b8a
FB
1165}
1166
788f5ec4
TS
1167static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1168 const struct timeval *tv)
31e31b8a 1169{
53a5960a
PB
1170 struct target_timeval *target_tv;
1171
6d5d5dde
DB
1172 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
1173 return -TARGET_EFAULT;
1174 }
1175
1176 __put_user(tv->tv_sec, &target_tv->tv_sec);
1177 __put_user(tv->tv_usec, &target_tv->tv_usec);
1178
1179 unlock_user_struct(target_tv, target_tv_addr, 1);
1180
1181 return 0;
1182}
1183
6ac03b2c
FB
1184#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
1185static inline abi_long copy_from_user_timeval64(struct timeval *tv,
1186 abi_ulong target_tv_addr)
1187{
1188 struct target__kernel_sock_timeval *target_tv;
1189
1190 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
1191 return -TARGET_EFAULT;
1192 }
1193
1194 __get_user(tv->tv_sec, &target_tv->tv_sec);
1195 __get_user(tv->tv_usec, &target_tv->tv_usec);
1196
1197 unlock_user_struct(target_tv, target_tv_addr, 0);
1198
1199 return 0;
1200}
1201#endif
1202
6d5d5dde 1203static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr,
6ac03b2c 1204 const struct timeval *tv)
6d5d5dde
DB
1205{
1206 struct target__kernel_sock_timeval *target_tv;
1207
1208 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
579a97f7 1209 return -TARGET_EFAULT;
6d5d5dde 1210 }
788f5ec4
TS
1211
1212 __put_user(tv->tv_sec, &target_tv->tv_sec);
1213 __put_user(tv->tv_usec, &target_tv->tv_usec);
1214
1215 unlock_user_struct(target_tv, target_tv_addr, 1);
579a97f7
FB
1216
1217 return 0;
31e31b8a
FB
1218}
1219
859e8a89
AF
1220#if defined(TARGET_NR_futex) || \
1221 defined(TARGET_NR_rt_sigtimedwait) || \
1222 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6) || \
1223 defined(TARGET_NR_nanosleep) || defined(TARGET_NR_clock_settime) || \
1224 defined(TARGET_NR_utimensat) || defined(TARGET_NR_mq_timedsend) || \
d8c08b1e 1225 defined(TARGET_NR_mq_timedreceive) || defined(TARGET_NR_ipc) || \
2c86c90f
FB
1226 defined(TARGET_NR_semop) || defined(TARGET_NR_semtimedop) || \
1227 defined(TARGET_NR_timer_settime) || \
1228 (defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD))
6d5d5dde
DB
1229static inline abi_long target_to_host_timespec(struct timespec *host_ts,
1230 abi_ulong target_addr)
1231{
1232 struct target_timespec *target_ts;
1233
1234 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
1235 return -TARGET_EFAULT;
1236 }
1237 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
1238 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1239 unlock_user_struct(target_ts, target_addr, 0);
1240 return 0;
1241}
859e8a89 1242#endif
6d5d5dde 1243
828cb3a1
FB
1244#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64) || \
1245 defined(TARGET_NR_timer_settime64) || \
d107e375
FB
1246 defined(TARGET_NR_mq_timedsend_time64) || \
1247 defined(TARGET_NR_mq_timedreceive_time64) || \
6ac03b2c 1248 (defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD)) || \
ddcbde15 1249 defined(TARGET_NR_clock_nanosleep_time64) || \
cac46eb0
FB
1250 defined(TARGET_NR_rt_sigtimedwait_time64) || \
1251 defined(TARGET_NR_utimensat) || \
1252 defined(TARGET_NR_utimensat_time64) || \
e5ce9688
FB
1253 defined(TARGET_NR_semtimedop_time64) || \
1254 defined(TARGET_NR_pselect6_time64) || defined(TARGET_NR_ppoll_time64)
c6c8d102
AF
1255static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
1256 abi_ulong target_addr)
1257{
1258 struct target__kernel_timespec *target_ts;
1259
1260 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
1261 return -TARGET_EFAULT;
1262 }
1263 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
1264 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
00576757
LV
1265 /* in 32bit mode, this drops the padding */
1266 host_ts->tv_nsec = (long)(abi_long)host_ts->tv_nsec;
c6c8d102
AF
1267 unlock_user_struct(target_ts, target_addr, 0);
1268 return 0;
1269}
1270#endif
1271
6d5d5dde
DB
1272static inline abi_long host_to_target_timespec(abi_ulong target_addr,
1273 struct timespec *host_ts)
1274{
1275 struct target_timespec *target_ts;
1276
1277 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) {
1278 return -TARGET_EFAULT;
1279 }
1280 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
1281 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1282 unlock_user_struct(target_ts, target_addr, 1);
1283 return 0;
1284}
1285
1286static inline abi_long host_to_target_timespec64(abi_ulong target_addr,
1287 struct timespec *host_ts)
1288{
1289 struct target__kernel_timespec *target_ts;
1290
1291 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) {
1292 return -TARGET_EFAULT;
1293 }
1294 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
1295 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1296 unlock_user_struct(target_ts, target_addr, 1);
1297 return 0;
1298}
1299
a52f5f87
RH
1300#if defined(TARGET_NR_gettimeofday)
1301static inline abi_long copy_to_user_timezone(abi_ulong target_tz_addr,
1302 struct timezone *tz)
1303{
1304 struct target_timezone *target_tz;
1305
1306 if (!lock_user_struct(VERIFY_WRITE, target_tz, target_tz_addr, 1)) {
1307 return -TARGET_EFAULT;
1308 }
1309
1310 __put_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1311 __put_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1312
1313 unlock_user_struct(target_tz, target_tz_addr, 1);
1314
1315 return 0;
1316}
1317#endif
1318
859e8a89 1319#if defined(TARGET_NR_settimeofday)
ef4467e9
PB
1320static inline abi_long copy_from_user_timezone(struct timezone *tz,
1321 abi_ulong target_tz_addr)
1322{
1323 struct target_timezone *target_tz;
1324
1325 if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
1326 return -TARGET_EFAULT;
1327 }
1328
1329 __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1330 __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1331
1332 unlock_user_struct(target_tz, target_tz_addr, 0);
1333
1334 return 0;
1335}
859e8a89 1336#endif
ef4467e9 1337
8ec9cf89
NF
1338#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1339#include <mqueue.h>
1340
24e1003a
AJ
1341static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1342 abi_ulong target_mq_attr_addr)
1343{
1344 struct target_mq_attr *target_mq_attr;
1345
1346 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1347 target_mq_attr_addr, 1))
1348 return -TARGET_EFAULT;
1349
1350 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1351 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1352 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1353 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1354
1355 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1356
1357 return 0;
1358}
1359
1360static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1361 const struct mq_attr *attr)
1362{
1363 struct target_mq_attr *target_mq_attr;
1364
1365 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1366 target_mq_attr_addr, 0))
1367 return -TARGET_EFAULT;
1368
1369 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1370 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1371 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1372 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1373
1374 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1375
1376 return 0;
1377}
8ec9cf89 1378#endif
31e31b8a 1379
055e0906 1380#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
0da46a6e 1381/* do_select() must return target values and target errnos. */
992f48a0 1382static abi_long do_select(int n,
26edcf41
TS
1383 abi_ulong rfd_addr, abi_ulong wfd_addr,
1384 abi_ulong efd_addr, abi_ulong target_tv_addr)
31e31b8a
FB
1385{
1386 fd_set rfds, wfds, efds;
1387 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6df9d38d
PM
1388 struct timeval tv;
1389 struct timespec ts, *ts_ptr;
992f48a0 1390 abi_long ret;
31e31b8a 1391
055e0906
MF
1392 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1393 if (ret) {
1394 return ret;
53a5960a 1395 }
055e0906
MF
1396 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1397 if (ret) {
1398 return ret;
53a5960a 1399 }
055e0906
MF
1400 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1401 if (ret) {
1402 return ret;
53a5960a 1403 }
3b46e624 1404
26edcf41 1405 if (target_tv_addr) {
788f5ec4
TS
1406 if (copy_from_user_timeval(&tv, target_tv_addr))
1407 return -TARGET_EFAULT;
6df9d38d
PM
1408 ts.tv_sec = tv.tv_sec;
1409 ts.tv_nsec = tv.tv_usec * 1000;
1410 ts_ptr = &ts;
31e31b8a 1411 } else {
6df9d38d 1412 ts_ptr = NULL;
31e31b8a 1413 }
26edcf41 1414
6df9d38d
PM
1415 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
1416 ts_ptr, NULL));
53a5960a 1417
26edcf41
TS
1418 if (!is_error(ret)) {
1419 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1420 return -TARGET_EFAULT;
1421 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1422 return -TARGET_EFAULT;
1423 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1424 return -TARGET_EFAULT;
31e31b8a 1425
6df9d38d
PM
1426 if (target_tv_addr) {
1427 tv.tv_sec = ts.tv_sec;
1428 tv.tv_usec = ts.tv_nsec / 1000;
1429 if (copy_to_user_timeval(target_tv_addr, &tv)) {
1430 return -TARGET_EFAULT;
1431 }
1432 }
31e31b8a 1433 }
579a97f7 1434
31e31b8a
FB
1435 return ret;
1436}
5457dc9e
LV
1437
1438#if defined(TARGET_WANT_OLD_SYS_SELECT)
1439static abi_long do_old_select(abi_ulong arg1)
1440{
1441 struct target_sel_arg_struct *sel;
1442 abi_ulong inp, outp, exp, tvp;
1443 long nsel;
1444
1445 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) {
1446 return -TARGET_EFAULT;
1447 }
1448
1449 nsel = tswapal(sel->n);
1450 inp = tswapal(sel->inp);
1451 outp = tswapal(sel->outp);
1452 exp = tswapal(sel->exp);
1453 tvp = tswapal(sel->tvp);
1454
1455 unlock_user_struct(sel, arg1, 0);
1456
1457 return do_select(nsel, inp, outp, exp, tvp);
1458}
1459#endif
055e0906 1460#endif
31e31b8a 1461
e5ce9688
FB
1462#if defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6_time64)
1463static abi_long do_pselect6(abi_long arg1, abi_long arg2, abi_long arg3,
1464 abi_long arg4, abi_long arg5, abi_long arg6,
1465 bool time64)
1466{
1467 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
1468 fd_set rfds, wfds, efds;
1469 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1470 struct timespec ts, *ts_ptr;
1471 abi_long ret;
1472
1473 /*
1474 * The 6th arg is actually two args smashed together,
1475 * so we cannot use the C library.
1476 */
1477 sigset_t set;
1478 struct {
1479 sigset_t *set;
1480 size_t size;
1481 } sig, *sig_ptr;
1482
1483 abi_ulong arg_sigset, arg_sigsize, *arg7;
1484 target_sigset_t *target_sigset;
1485
1486 n = arg1;
1487 rfd_addr = arg2;
1488 wfd_addr = arg3;
1489 efd_addr = arg4;
1490 ts_addr = arg5;
1491
1492 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1493 if (ret) {
1494 return ret;
1495 }
1496 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1497 if (ret) {
1498 return ret;
1499 }
1500 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1501 if (ret) {
1502 return ret;
1503 }
1504
1505 /*
1506 * This takes a timespec, and not a timeval, so we cannot
1507 * use the do_select() helper ...
1508 */
1509 if (ts_addr) {
1510 if (time64) {
1511 if (target_to_host_timespec64(&ts, ts_addr)) {
1512 return -TARGET_EFAULT;
1513 }
1514 } else {
1515 if (target_to_host_timespec(&ts, ts_addr)) {
1516 return -TARGET_EFAULT;
1517 }
1518 }
1519 ts_ptr = &ts;
1520 } else {
1521 ts_ptr = NULL;
1522 }
1523
1524 /* Extract the two packed args for the sigset */
1525 if (arg6) {
1526 sig_ptr = &sig;
1527 sig.size = SIGSET_T_SIZE;
1528
1529 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
1530 if (!arg7) {
1531 return -TARGET_EFAULT;
1532 }
1533 arg_sigset = tswapal(arg7[0]);
1534 arg_sigsize = tswapal(arg7[1]);
1535 unlock_user(arg7, arg6, 0);
1536
1537 if (arg_sigset) {
1538 sig.set = &set;
1539 if (arg_sigsize != sizeof(*target_sigset)) {
1540 /* Like the kernel, we enforce correct size sigsets */
1541 return -TARGET_EINVAL;
1542 }
1543 target_sigset = lock_user(VERIFY_READ, arg_sigset,
1544 sizeof(*target_sigset), 1);
1545 if (!target_sigset) {
1546 return -TARGET_EFAULT;
1547 }
1548 target_to_host_sigset(&set, target_sigset);
1549 unlock_user(target_sigset, arg_sigset, 0);
1550 } else {
1551 sig.set = NULL;
1552 }
1553 } else {
1554 sig_ptr = NULL;
1555 }
1556
1557 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
1558 ts_ptr, sig_ptr));
1559
1560 if (!is_error(ret)) {
1561 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) {
1562 return -TARGET_EFAULT;
1563 }
1564 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) {
1565 return -TARGET_EFAULT;
1566 }
1567 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) {
1568 return -TARGET_EFAULT;
1569 }
1570 if (time64) {
1571 if (ts_addr && host_to_target_timespec64(ts_addr, &ts)) {
1572 return -TARGET_EFAULT;
1573 }
1574 } else {
1575 if (ts_addr && host_to_target_timespec(ts_addr, &ts)) {
1576 return -TARGET_EFAULT;
1577 }
1578 }
1579 }
1580 return ret;
1581}
1582#endif
1583
1584#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll) || \
1585 defined(TARGET_NR_ppoll_time64)
1586static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3,
1587 abi_long arg4, abi_long arg5, bool ppoll, bool time64)
1588{
1589 struct target_pollfd *target_pfd;
1590 unsigned int nfds = arg2;
1591 struct pollfd *pfd;
1592 unsigned int i;
1593 abi_long ret;
1594
1595 pfd = NULL;
1596 target_pfd = NULL;
1597 if (nfds) {
1598 if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
1599 return -TARGET_EINVAL;
1600 }
1601 target_pfd = lock_user(VERIFY_WRITE, arg1,
1602 sizeof(struct target_pollfd) * nfds, 1);
1603 if (!target_pfd) {
1604 return -TARGET_EFAULT;
1605 }
1606
1607 pfd = alloca(sizeof(struct pollfd) * nfds);
1608 for (i = 0; i < nfds; i++) {
1609 pfd[i].fd = tswap32(target_pfd[i].fd);
1610 pfd[i].events = tswap16(target_pfd[i].events);
1611 }
1612 }
1613 if (ppoll) {
1614 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
1615 target_sigset_t *target_set;
1616 sigset_t _set, *set = &_set;
1617
1618 if (arg3) {
1619 if (time64) {
1620 if (target_to_host_timespec64(timeout_ts, arg3)) {
1621 unlock_user(target_pfd, arg1, 0);
1622 return -TARGET_EFAULT;
1623 }
1624 } else {
1625 if (target_to_host_timespec(timeout_ts, arg3)) {
1626 unlock_user(target_pfd, arg1, 0);
1627 return -TARGET_EFAULT;
1628 }
1629 }
1630 } else {
1631 timeout_ts = NULL;
1632 }
1633
1634 if (arg4) {
1635 if (arg5 != sizeof(target_sigset_t)) {
1636 unlock_user(target_pfd, arg1, 0);
1637 return -TARGET_EINVAL;
1638 }
1639
1640 target_set = lock_user(VERIFY_READ, arg4,
1641 sizeof(target_sigset_t), 1);
1642 if (!target_set) {
1643 unlock_user(target_pfd, arg1, 0);
1644 return -TARGET_EFAULT;
1645 }
1646 target_to_host_sigset(set, target_set);
1647 } else {
1648 set = NULL;
1649 }
1650
1651 ret = get_errno(safe_ppoll(pfd, nfds, timeout_ts,
1652 set, SIGSET_T_SIZE));
1653
1654 if (!is_error(ret) && arg3) {
1655 if (time64) {
1656 if (host_to_target_timespec64(arg3, timeout_ts)) {
1657 return -TARGET_EFAULT;
1658 }
1659 } else {
1660 if (host_to_target_timespec(arg3, timeout_ts)) {
1661 return -TARGET_EFAULT;
1662 }
1663 }
1664 }
1665 if (arg4) {
1666 unlock_user(target_set, arg4, 0);
1667 }
1668 } else {
1669 struct timespec ts, *pts;
1670
1671 if (arg3 >= 0) {
1672 /* Convert ms to secs, ns */
1673 ts.tv_sec = arg3 / 1000;
1674 ts.tv_nsec = (arg3 % 1000) * 1000000LL;
1675 pts = &ts;
1676 } else {
1677 /* -ve poll() timeout means "infinite" */
1678 pts = NULL;
1679 }
1680 ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
1681 }
1682
1683 if (!is_error(ret)) {
1684 for (i = 0; i < nfds; i++) {
1685 target_pfd[i].revents = tswap16(pfd[i].revents);
1686 }
1687 }
1688 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
1689 return ret;
1690}
1691#endif
1692
099d6b0f
RV
1693static abi_long do_pipe2(int host_pipe[], int flags)
1694{
1695#ifdef CONFIG_PIPE2
1696 return pipe2(host_pipe, flags);
1697#else
1698 return -ENOSYS;
1699#endif
1700}
1701
fb41a66e
RH
1702static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1703 int flags, int is_pipe2)
099d6b0f
RV
1704{
1705 int host_pipe[2];
1706 abi_long ret;
1707 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1708
1709 if (is_error(ret))
1710 return get_errno(ret);
fb41a66e
RH
1711
1712 /* Several targets have special calling conventions for the original
1713 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1714 if (!is_pipe2) {
1715#if defined(TARGET_ALPHA)
1716 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1717 return host_pipe[0];
1718#elif defined(TARGET_MIPS)
1719 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1720 return host_pipe[0];
1721#elif defined(TARGET_SH4)
597c0212 1722 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
fb41a66e 1723 return host_pipe[0];
82f05b69
PM
1724#elif defined(TARGET_SPARC)
1725 ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1726 return host_pipe[0];
597c0212 1727#endif
fb41a66e
RH
1728 }
1729
099d6b0f
RV
1730 if (put_user_s32(host_pipe[0], pipedes)
1731 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1732 return -TARGET_EFAULT;
099d6b0f
RV
1733 return get_errno(ret);
1734}
1735
b975b83b
LL
1736static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1737 abi_ulong target_addr,
1738 socklen_t len)
1739{
1740 struct target_ip_mreqn *target_smreqn;
1741
1742 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1743 if (!target_smreqn)
1744 return -TARGET_EFAULT;
1745 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1746 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1747 if (len == sizeof(struct target_ip_mreqn))
cbb21eed 1748 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
b975b83b
LL
1749 unlock_user(target_smreqn, target_addr, 0);
1750
1751 return 0;
1752}
1753
7b36f782 1754static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
579a97f7
FB
1755 abi_ulong target_addr,
1756 socklen_t len)
7854b056 1757{
607175e0
AJ
1758 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1759 sa_family_t sa_family;
53a5960a
PB
1760 struct target_sockaddr *target_saddr;
1761
7b36f782
LV
1762 if (fd_trans_target_to_host_addr(fd)) {
1763 return fd_trans_target_to_host_addr(fd)(addr, target_addr, len);
1764 }
1765
579a97f7
FB
1766 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1767 if (!target_saddr)
1768 return -TARGET_EFAULT;
607175e0
AJ
1769
1770 sa_family = tswap16(target_saddr->sa_family);
1771
1772 /* Oops. The caller might send a incomplete sun_path; sun_path
1773 * must be terminated by \0 (see the manual page), but
1774 * unfortunately it is quite common to specify sockaddr_un
1775 * length as "strlen(x->sun_path)" while it should be
1776 * "strlen(...) + 1". We'll fix that here if needed.
1777 * Linux kernel has a similar feature.
1778 */
1779
1780 if (sa_family == AF_UNIX) {
1781 if (len < unix_maxlen && len > 0) {
1782 char *cp = (char*)target_saddr;
1783
1784 if ( cp[len-1] && !cp[len] )
1785 len++;
1786 }
1787 if (len > unix_maxlen)
1788 len = unix_maxlen;
1789 }
1790
53a5960a 1791 memcpy(addr, target_saddr, len);
607175e0 1792 addr->sa_family = sa_family;
6c5b5645
LV
1793 if (sa_family == AF_NETLINK) {
1794 struct sockaddr_nl *nladdr;
1795
1796 nladdr = (struct sockaddr_nl *)addr;
1797 nladdr->nl_pid = tswap32(nladdr->nl_pid);
1798 nladdr->nl_groups = tswap32(nladdr->nl_groups);
1799 } else if (sa_family == AF_PACKET) {
33a29b51
JT
1800 struct target_sockaddr_ll *lladdr;
1801
1802 lladdr = (struct target_sockaddr_ll *)addr;
1803 lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
1804 lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
1805 }
53a5960a 1806 unlock_user(target_saddr, target_addr, 0);
579a97f7
FB
1807
1808 return 0;
7854b056
FB
1809}
1810
579a97f7
FB
1811static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1812 struct sockaddr *addr,
1813 socklen_t len)
7854b056 1814{
53a5960a
PB
1815 struct target_sockaddr *target_saddr;
1816
a1e22192
PM
1817 if (len == 0) {
1818 return 0;
1819 }
6860710c 1820 assert(addr);
a1e22192 1821
579a97f7
FB
1822 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1823 if (!target_saddr)
1824 return -TARGET_EFAULT;
53a5960a 1825 memcpy(target_saddr, addr, len);
a1e22192
PM
1826 if (len >= offsetof(struct target_sockaddr, sa_family) +
1827 sizeof(target_saddr->sa_family)) {
1828 target_saddr->sa_family = tswap16(addr->sa_family);
1829 }
a47401bc
PMD
1830 if (addr->sa_family == AF_NETLINK &&
1831 len >= sizeof(struct target_sockaddr_nl)) {
1832 struct target_sockaddr_nl *target_nl =
1833 (struct target_sockaddr_nl *)target_saddr;
6c5b5645
LV
1834 target_nl->nl_pid = tswap32(target_nl->nl_pid);
1835 target_nl->nl_groups = tswap32(target_nl->nl_groups);
a82ea939
LV
1836 } else if (addr->sa_family == AF_PACKET) {
1837 struct sockaddr_ll *target_ll = (struct sockaddr_ll *)target_saddr;
1838 target_ll->sll_ifindex = tswap32(target_ll->sll_ifindex);
1839 target_ll->sll_hatype = tswap16(target_ll->sll_hatype);
ee1ac3a1
HD
1840 } else if (addr->sa_family == AF_INET6 &&
1841 len >= sizeof(struct target_sockaddr_in6)) {
1842 struct target_sockaddr_in6 *target_in6 =
1843 (struct target_sockaddr_in6 *)target_saddr;
1844 target_in6->sin6_scope_id = tswap16(target_in6->sin6_scope_id);
6c5b5645 1845 }
53a5960a 1846 unlock_user(target_saddr, target_addr, len);
579a97f7
FB
1847
1848 return 0;
7854b056
FB
1849}
1850
5a4a898d
FB
1851static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1852 struct target_msghdr *target_msgh)
7854b056
FB
1853{
1854 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
5a4a898d
FB
1855 abi_long msg_controllen;
1856 abi_ulong target_cmsg_addr;
ee104587 1857 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
7854b056 1858 socklen_t space = 0;
5a4a898d 1859
cbb21eed 1860 msg_controllen = tswapal(target_msgh->msg_controllen);
5a4a898d
FB
1861 if (msg_controllen < sizeof (struct target_cmsghdr))
1862 goto the_end;
cbb21eed 1863 target_cmsg_addr = tswapal(target_msgh->msg_control);
5a4a898d 1864 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
ee104587 1865 target_cmsg_start = target_cmsg;
5a4a898d
FB
1866 if (!target_cmsg)
1867 return -TARGET_EFAULT;
7854b056
FB
1868
1869 while (cmsg && target_cmsg) {
1870 void *data = CMSG_DATA(cmsg);
1871 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1872
cbb21eed 1873 int len = tswapal(target_cmsg->cmsg_len)
ad762b99 1874 - sizeof(struct target_cmsghdr);
7854b056
FB
1875
1876 space += CMSG_SPACE(len);
1877 if (space > msgh->msg_controllen) {
1878 space -= CMSG_SPACE(len);
c2aeb258
PM
1879 /* This is a QEMU bug, since we allocated the payload
1880 * area ourselves (unlike overflow in host-to-target
1881 * conversion, which is just the guest giving us a buffer
1882 * that's too small). It can't happen for the payload types
1883 * we currently support; if it becomes an issue in future
1884 * we would need to improve our allocation strategy to
1885 * something more intelligent than "twice the size of the
1886 * target buffer we're reading from".
1887 */
39be5350
JK
1888 qemu_log_mask(LOG_UNIMP,
1889 ("Unsupported ancillary data %d/%d: "
1890 "unhandled msg size\n"),
1891 tswap32(target_cmsg->cmsg_level),
1892 tswap32(target_cmsg->cmsg_type));
7854b056
FB
1893 break;
1894 }
1895
dbf4f796
PJ
1896 if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1897 cmsg->cmsg_level = SOL_SOCKET;
1898 } else {
1899 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1900 }
7854b056
FB
1901 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1902 cmsg->cmsg_len = CMSG_LEN(len);
1903
30b8b68e 1904 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
7854b056
FB
1905 int *fd = (int *)data;
1906 int *target_fd = (int *)target_data;
1907 int i, numfds = len / sizeof(int);
1908
876e23cb
PM
1909 for (i = 0; i < numfds; i++) {
1910 __get_user(fd[i], target_fd + i);
1911 }
30b8b68e
AS
1912 } else if (cmsg->cmsg_level == SOL_SOCKET
1913 && cmsg->cmsg_type == SCM_CREDENTIALS) {
1914 struct ucred *cred = (struct ucred *)data;
1915 struct target_ucred *target_cred =
1916 (struct target_ucred *)target_data;
1917
876e23cb
PM
1918 __get_user(cred->pid, &target_cred->pid);
1919 __get_user(cred->uid, &target_cred->uid);
1920 __get_user(cred->gid, &target_cred->gid);
30b8b68e 1921 } else {
39be5350
JK
1922 qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
1923 cmsg->cmsg_level, cmsg->cmsg_type);
30b8b68e 1924 memcpy(data, target_data, len);
7854b056
FB
1925 }
1926
1927 cmsg = CMSG_NXTHDR(msgh, cmsg);
ee104587
JN
1928 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1929 target_cmsg_start);
7854b056 1930 }
5a4a898d
FB
1931 unlock_user(target_cmsg, target_cmsg_addr, 0);
1932 the_end:
7854b056 1933 msgh->msg_controllen = space;
5a4a898d 1934 return 0;
7854b056
FB
1935}
1936
5a4a898d
FB
1937static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1938 struct msghdr *msgh)
7854b056
FB
1939{
1940 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
5a4a898d
FB
1941 abi_long msg_controllen;
1942 abi_ulong target_cmsg_addr;
ee104587 1943 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
7854b056
FB
1944 socklen_t space = 0;
1945
cbb21eed 1946 msg_controllen = tswapal(target_msgh->msg_controllen);
5a4a898d
FB
1947 if (msg_controllen < sizeof (struct target_cmsghdr))
1948 goto the_end;
cbb21eed 1949 target_cmsg_addr = tswapal(target_msgh->msg_control);
5a4a898d 1950 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
ee104587 1951 target_cmsg_start = target_cmsg;
5a4a898d
FB
1952 if (!target_cmsg)
1953 return -TARGET_EFAULT;
1954
7854b056
FB
1955 while (cmsg && target_cmsg) {
1956 void *data = CMSG_DATA(cmsg);
1957 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1958
ad762b99 1959 int len = cmsg->cmsg_len - sizeof(struct cmsghdr);
c2aeb258 1960 int tgt_len, tgt_space;
7854b056 1961
c2aeb258
PM
1962 /* We never copy a half-header but may copy half-data;
1963 * this is Linux's behaviour in put_cmsg(). Note that
1964 * truncation here is a guest problem (which we report
1965 * to the guest via the CTRUNC bit), unlike truncation
1966 * in target_to_host_cmsg, which is a QEMU bug.
1967 */
7174970a 1968 if (msg_controllen < sizeof(struct target_cmsghdr)) {
c2aeb258 1969 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
7854b056
FB
1970 break;
1971 }
1972
dbf4f796
PJ
1973 if (cmsg->cmsg_level == SOL_SOCKET) {
1974 target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1975 } else {
1976 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1977 }
7854b056 1978 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
7854b056 1979
c2aeb258
PM
1980 /* Payload types which need a different size of payload on
1981 * the target must adjust tgt_len here.
1982 */
309786cf 1983 tgt_len = len;
c2aeb258
PM
1984 switch (cmsg->cmsg_level) {
1985 case SOL_SOCKET:
1986 switch (cmsg->cmsg_type) {
1987 case SO_TIMESTAMP:
1988 tgt_len = sizeof(struct target_timeval);
1989 break;
1990 default:
1991 break;
1992 }
309786cf 1993 break;
c2aeb258
PM
1994 default:
1995 break;
1996 }
1997
7174970a 1998 if (msg_controllen < TARGET_CMSG_LEN(tgt_len)) {
c2aeb258 1999 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
7174970a 2000 tgt_len = msg_controllen - sizeof(struct target_cmsghdr);
c2aeb258
PM
2001 }
2002
2003 /* We must now copy-and-convert len bytes of payload
2004 * into tgt_len bytes of destination space. Bear in mind
2005 * that in both source and destination we may be dealing
2006 * with a truncated value!
2007 */
52b65494
HD
2008 switch (cmsg->cmsg_level) {
2009 case SOL_SOCKET:
2010 switch (cmsg->cmsg_type) {
2011 case SCM_RIGHTS:
2012 {
2013 int *fd = (int *)data;
2014 int *target_fd = (int *)target_data;
c2aeb258 2015 int i, numfds = tgt_len / sizeof(int);
52b65494 2016
876e23cb
PM
2017 for (i = 0; i < numfds; i++) {
2018 __put_user(fd[i], target_fd + i);
2019 }
52b65494
HD
2020 break;
2021 }
2022 case SO_TIMESTAMP:
2023 {
2024 struct timeval *tv = (struct timeval *)data;
2025 struct target_timeval *target_tv =
2026 (struct target_timeval *)target_data;
2027
c2aeb258
PM
2028 if (len != sizeof(struct timeval) ||
2029 tgt_len != sizeof(struct target_timeval)) {
52b65494 2030 goto unimplemented;
c2aeb258 2031 }
52b65494
HD
2032
2033 /* copy struct timeval to target */
876e23cb
PM
2034 __put_user(tv->tv_sec, &target_tv->tv_sec);
2035 __put_user(tv->tv_usec, &target_tv->tv_usec);
52b65494
HD
2036 break;
2037 }
4bc29756
HD
2038 case SCM_CREDENTIALS:
2039 {
2040 struct ucred *cred = (struct ucred *)data;
2041 struct target_ucred *target_cred =
2042 (struct target_ucred *)target_data;
2043
2044 __put_user(cred->pid, &target_cred->pid);
2045 __put_user(cred->uid, &target_cred->uid);
2046 __put_user(cred->gid, &target_cred->gid);
2047 break;
2048 }
52b65494
HD
2049 default:
2050 goto unimplemented;
2051 }
2052 break;
7854b056 2053
ee1ac3a1
HD
2054 case SOL_IP:
2055 switch (cmsg->cmsg_type) {
2056 case IP_TTL:
2057 {
2058 uint32_t *v = (uint32_t *)data;
2059 uint32_t *t_int = (uint32_t *)target_data;
2060
7174970a
PM
2061 if (len != sizeof(uint32_t) ||
2062 tgt_len != sizeof(uint32_t)) {
2063 goto unimplemented;
2064 }
ee1ac3a1
HD
2065 __put_user(*v, t_int);
2066 break;
2067 }
2068 case IP_RECVERR:
2069 {
2070 struct errhdr_t {
2071 struct sock_extended_err ee;
2072 struct sockaddr_in offender;
2073 };
2074 struct errhdr_t *errh = (struct errhdr_t *)data;
2075 struct errhdr_t *target_errh =
2076 (struct errhdr_t *)target_data;
2077
7174970a
PM
2078 if (len != sizeof(struct errhdr_t) ||
2079 tgt_len != sizeof(struct errhdr_t)) {
2080 goto unimplemented;
2081 }
ee1ac3a1
HD
2082 __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
2083 __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
2084 __put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
2085 __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
2086 __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);
2087 __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);
2088 __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);
2089 host_to_target_sockaddr((unsigned long) &target_errh->offender,
2090 (void *) &errh->offender, sizeof(errh->offender));
2091 break;
2092 }
2093 default:
2094 goto unimplemented;
2095 }
2096 break;
2097
2098 case SOL_IPV6:
2099 switch (cmsg->cmsg_type) {
2100 case IPV6_HOPLIMIT:
2101 {
2102 uint32_t *v = (uint32_t *)data;
2103 uint32_t *t_int = (uint32_t *)target_data;
2104
7174970a
PM
2105 if (len != sizeof(uint32_t) ||
2106 tgt_len != sizeof(uint32_t)) {
2107 goto unimplemented;
2108 }
ee1ac3a1
HD
2109 __put_user(*v, t_int);
2110 break;
2111 }
2112 case IPV6_RECVERR:
2113 {
2114 struct errhdr6_t {
2115 struct sock_extended_err ee;
2116 struct sockaddr_in6 offender;
2117 };
2118 struct errhdr6_t *errh = (struct errhdr6_t *)data;
2119 struct errhdr6_t *target_errh =
2120 (struct errhdr6_t *)target_data;
2121
7174970a
PM
2122 if (len != sizeof(struct errhdr6_t) ||
2123 tgt_len != sizeof(struct errhdr6_t)) {
2124 goto unimplemented;
2125 }
ee1ac3a1
HD
2126 __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
2127 __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
2128 __put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
2129 __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
2130 __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);
2131 __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);
2132 __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);
2133 host_to_target_sockaddr((unsigned long) &target_errh->offender,
2134 (void *) &errh->offender, sizeof(errh->offender));
2135 break;
2136 }
2137 default:
2138 goto unimplemented;
2139 }
2140 break;
2141
52b65494
HD
2142 default:
2143 unimplemented:
39be5350
JK
2144 qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
2145 cmsg->cmsg_level, cmsg->cmsg_type);
c2aeb258
PM
2146 memcpy(target_data, data, MIN(len, tgt_len));
2147 if (tgt_len > len) {
2148 memset(target_data + len, 0, tgt_len - len);
2149 }
7854b056
FB
2150 }
2151
7174970a
PM
2152 target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(tgt_len));
2153 tgt_space = TARGET_CMSG_SPACE(tgt_len);
c2aeb258
PM
2154 if (msg_controllen < tgt_space) {
2155 tgt_space = msg_controllen;
2156 }
2157 msg_controllen -= tgt_space;
2158 space += tgt_space;
7854b056 2159 cmsg = CMSG_NXTHDR(msgh, cmsg);
ee104587
JN
2160 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
2161 target_cmsg_start);
7854b056 2162 }
5a4a898d
FB
2163 unlock_user(target_cmsg, target_cmsg_addr, space);
2164 the_end:
cbb21eed 2165 target_msgh->msg_controllen = tswapal(space);
5a4a898d 2166 return 0;
7854b056
FB
2167}
2168
0da46a6e 2169/* do_setsockopt() Must return target values and target errnos. */
992f48a0 2170static abi_long do_setsockopt(int sockfd, int level, int optname,
2f619698 2171 abi_ulong optval_addr, socklen_t optlen)
7854b056 2172{
992f48a0 2173 abi_long ret;
32407103 2174 int val;
b975b83b 2175 struct ip_mreqn *ip_mreq;
6e3cb58f 2176 struct ip_mreq_source *ip_mreq_source;
3b46e624 2177
8853f86e
FB
2178 switch(level) {
2179 case SOL_TCP:
7854b056 2180 /* TCP options all take an 'int' value. */
7854b056 2181 if (optlen < sizeof(uint32_t))
0da46a6e 2182 return -TARGET_EINVAL;
3b46e624 2183
2f619698
FB
2184 if (get_user_u32(val, optval_addr))
2185 return -TARGET_EFAULT;
8853f86e
FB
2186 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
2187 break;
2188 case SOL_IP:
2189 switch(optname) {
2efbe911
FB
2190 case IP_TOS:
2191 case IP_TTL:
8853f86e 2192 case IP_HDRINCL:
2efbe911
FB
2193 case IP_ROUTER_ALERT:
2194 case IP_RECVOPTS:
2195 case IP_RETOPTS:
2196 case IP_PKTINFO:
2197 case IP_MTU_DISCOVER:
2198 case IP_RECVERR:
ee1ac3a1 2199 case IP_RECVTTL:
2efbe911
FB
2200 case IP_RECVTOS:
2201#ifdef IP_FREEBIND
2202 case IP_FREEBIND:
2203#endif
2204 case IP_MULTICAST_TTL:
2205 case IP_MULTICAST_LOOP:
8853f86e
FB
2206 val = 0;
2207 if (optlen >= sizeof(uint32_t)) {
2f619698
FB
2208 if (get_user_u32(val, optval_addr))
2209 return -TARGET_EFAULT;
8853f86e 2210 } else if (optlen >= 1) {
2f619698
FB
2211 if (get_user_u8(val, optval_addr))
2212 return -TARGET_EFAULT;
8853f86e
FB
2213 }
2214 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
2215 break;
b975b83b
LL
2216 case IP_ADD_MEMBERSHIP:
2217 case IP_DROP_MEMBERSHIP:
2218 if (optlen < sizeof (struct target_ip_mreq) ||
2219 optlen > sizeof (struct target_ip_mreqn))
2220 return -TARGET_EINVAL;
2221
2222 ip_mreq = (struct ip_mreqn *) alloca(optlen);
2223 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
2224 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
2225 break;
2226
6e3cb58f
LL
2227 case IP_BLOCK_SOURCE:
2228 case IP_UNBLOCK_SOURCE:
2229 case IP_ADD_SOURCE_MEMBERSHIP:
2230 case IP_DROP_SOURCE_MEMBERSHIP:
2231 if (optlen != sizeof (struct target_ip_mreq_source))
2232 return -TARGET_EINVAL;
2233
2234 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2235 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
2236 unlock_user (ip_mreq_source, optval_addr, 0);
2237 break;
2238
920394db
JH
2239 default:
2240 goto unimplemented;
2241 }
2242 break;
0d78b3b5
LV
2243 case SOL_IPV6:
2244 switch (optname) {
2245 case IPV6_MTU_DISCOVER:
2246 case IPV6_MTU:
2247 case IPV6_V6ONLY:
2248 case IPV6_RECVPKTINFO:
ee1ac3a1 2249 case IPV6_UNICAST_HOPS:
21749c4c
LV
2250 case IPV6_MULTICAST_HOPS:
2251 case IPV6_MULTICAST_LOOP:
ee1ac3a1
HD
2252 case IPV6_RECVERR:
2253 case IPV6_RECVHOPLIMIT:
2254 case IPV6_2292HOPLIMIT:
2255 case IPV6_CHECKSUM:
b9cce6d7
HD
2256 case IPV6_ADDRFORM:
2257 case IPV6_2292PKTINFO:
2258 case IPV6_RECVTCLASS:
2259 case IPV6_RECVRTHDR:
2260 case IPV6_2292RTHDR:
2261 case IPV6_RECVHOPOPTS:
2262 case IPV6_2292HOPOPTS:
2263 case IPV6_RECVDSTOPTS:
2264 case IPV6_2292DSTOPTS:
2265 case IPV6_TCLASS:
2266#ifdef IPV6_RECVPATHMTU
2267 case IPV6_RECVPATHMTU:
2268#endif
2269#ifdef IPV6_TRANSPARENT
2270 case IPV6_TRANSPARENT:
2271#endif
2272#ifdef IPV6_FREEBIND
2273 case IPV6_FREEBIND:
2274#endif
2275#ifdef IPV6_RECVORIGDSTADDR
2276 case IPV6_RECVORIGDSTADDR:
2277#endif
0d78b3b5
LV
2278 val = 0;
2279 if (optlen < sizeof(uint32_t)) {
2280 return -TARGET_EINVAL;
2281 }
2282 if (get_user_u32(val, optval_addr)) {
2283 return -TARGET_EFAULT;
2284 }
2285 ret = get_errno(setsockopt(sockfd, level, optname,
2286 &val, sizeof(val)));
2287 break;
ee1ac3a1
HD
2288 case IPV6_PKTINFO:
2289 {
2290 struct in6_pktinfo pki;
2291
2292 if (optlen < sizeof(pki)) {
2293 return -TARGET_EINVAL;
2294 }
2295
2296 if (copy_from_user(&pki, optval_addr, sizeof(pki))) {
2297 return -TARGET_EFAULT;
2298 }
2299
2300 pki.ipi6_ifindex = tswap32(pki.ipi6_ifindex);
2301
2302 ret = get_errno(setsockopt(sockfd, level, optname,
2303 &pki, sizeof(pki)));
2304 break;
2305 }
22bf4ee9
NC
2306 case IPV6_ADD_MEMBERSHIP:
2307 case IPV6_DROP_MEMBERSHIP:
2308 {
2309 struct ipv6_mreq ipv6mreq;
2310
2311 if (optlen < sizeof(ipv6mreq)) {
2312 return -TARGET_EINVAL;
2313 }
2314
2315 if (copy_from_user(&ipv6mreq, optval_addr, sizeof(ipv6mreq))) {
2316 return -TARGET_EFAULT;
2317 }
2318
2319 ipv6mreq.ipv6mr_interface = tswap32(ipv6mreq.ipv6mr_interface);
2320
2321 ret = get_errno(setsockopt(sockfd, level, optname,
2322 &ipv6mreq, sizeof(ipv6mreq)));
2323 break;
2324 }
ee1ac3a1
HD
2325 default:
2326 goto unimplemented;
2327 }
2328 break;
2329 case SOL_ICMPV6:
2330 switch (optname) {
2331 case ICMPV6_FILTER:
2332 {
2333 struct icmp6_filter icmp6f;
2334
2335 if (optlen > sizeof(icmp6f)) {
2336 optlen = sizeof(icmp6f);
2337 }
2338
2339 if (copy_from_user(&icmp6f, optval_addr, optlen)) {
2340 return -TARGET_EFAULT;
2341 }
2342
2343 for (val = 0; val < 8; val++) {
2344 icmp6f.data[val] = tswap32(icmp6f.data[val]);
2345 }
2346
2347 ret = get_errno(setsockopt(sockfd, level, optname,
2348 &icmp6f, optlen));
2349 break;
2350 }
0d78b3b5
LV
2351 default:
2352 goto unimplemented;
2353 }
2354 break;
920394db
JH
2355 case SOL_RAW:
2356 switch (optname) {
2357 case ICMP_FILTER:
ee1ac3a1
HD
2358 case IPV6_CHECKSUM:
2359 /* those take an u32 value */
920394db
JH
2360 if (optlen < sizeof(uint32_t)) {
2361 return -TARGET_EINVAL;
2362 }
2363
2364 if (get_user_u32(val, optval_addr)) {
2365 return -TARGET_EFAULT;
2366 }
2367 ret = get_errno(setsockopt(sockfd, level, optname,
2368 &val, sizeof(val)));
2369 break;
2370
8853f86e
FB
2371 default:
2372 goto unimplemented;
2373 }
2374 break;
f31dddd2
YS
2375#if defined(SOL_ALG) && defined(ALG_SET_KEY) && defined(ALG_SET_AEAD_AUTHSIZE)
2376 case SOL_ALG:
2377 switch (optname) {
2378 case ALG_SET_KEY:
2379 {
2380 char *alg_key = g_malloc(optlen);
2381
2382 if (!alg_key) {
2383 return -TARGET_ENOMEM;
2384 }
2385 if (copy_from_user(alg_key, optval_addr, optlen)) {
2386 g_free(alg_key);
2387 return -TARGET_EFAULT;
2388 }
2389 ret = get_errno(setsockopt(sockfd, level, optname,
2390 alg_key, optlen));
2391 g_free(alg_key);
2392 break;
2393 }
2394 case ALG_SET_AEAD_AUTHSIZE:
2395 {
2396 ret = get_errno(setsockopt(sockfd, level, optname,
2397 NULL, optlen));
2398 break;
2399 }
2400 default:
2401 goto unimplemented;
2402 }
2403 break;
2404#endif
3532fa74 2405 case TARGET_SOL_SOCKET:
8853f86e 2406 switch (optname) {
1b09aeb9
LV
2407 case TARGET_SO_RCVTIMEO:
2408 {
2409 struct timeval tv;
2410
2411 optname = SO_RCVTIMEO;
2412
2413set_timeout:
2414 if (optlen != sizeof(struct target_timeval)) {
2415 return -TARGET_EINVAL;
2416 }
2417
2418 if (copy_from_user_timeval(&tv, optval_addr)) {
2419 return -TARGET_EFAULT;
2420 }
2421
2422 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2423 &tv, sizeof(tv)));
2424 return ret;
2425 }
2426 case TARGET_SO_SNDTIMEO:
2427 optname = SO_SNDTIMEO;
2428 goto set_timeout;
f57d4192
LV
2429 case TARGET_SO_ATTACH_FILTER:
2430 {
2431 struct target_sock_fprog *tfprog;
2432 struct target_sock_filter *tfilter;
2433 struct sock_fprog fprog;
2434 struct sock_filter *filter;
2435 int i;
2436
2437 if (optlen != sizeof(*tfprog)) {
2438 return -TARGET_EINVAL;
2439 }
2440 if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
2441 return -TARGET_EFAULT;
2442 }
2443 if (!lock_user_struct(VERIFY_READ, tfilter,
2444 tswapal(tfprog->filter), 0)) {
2445 unlock_user_struct(tfprog, optval_addr, 1);
2446 return -TARGET_EFAULT;
2447 }
2448
2449 fprog.len = tswap16(tfprog->len);
0e173b24 2450 filter = g_try_new(struct sock_filter, fprog.len);
f57d4192
LV
2451 if (filter == NULL) {
2452 unlock_user_struct(tfilter, tfprog->filter, 1);
2453 unlock_user_struct(tfprog, optval_addr, 1);
2454 return -TARGET_ENOMEM;
2455 }
2456 for (i = 0; i < fprog.len; i++) {
2457 filter[i].code = tswap16(tfilter[i].code);
2458 filter[i].jt = tfilter[i].jt;
2459 filter[i].jf = tfilter[i].jf;
2460 filter[i].k = tswap32(tfilter[i].k);
2461 }
2462 fprog.filter = filter;
2463
2464 ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
2465 SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
0e173b24 2466 g_free(filter);
f57d4192
LV
2467
2468 unlock_user_struct(tfilter, tfprog->filter, 1);
2469 unlock_user_struct(tfprog, optval_addr, 1);
2470 return ret;
2471 }
451aaf68
JT
2472 case TARGET_SO_BINDTODEVICE:
2473 {
2474 char *dev_ifname, *addr_ifname;
2475
2476 if (optlen > IFNAMSIZ - 1) {
2477 optlen = IFNAMSIZ - 1;
2478 }
2479 dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2480 if (!dev_ifname) {
2481 return -TARGET_EFAULT;
2482 }
2483 optname = SO_BINDTODEVICE;
2484 addr_ifname = alloca(IFNAMSIZ);
2485 memcpy(addr_ifname, dev_ifname, optlen);
2486 addr_ifname[optlen] = 0;
fad6c58a
CG
2487 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2488 addr_ifname, optlen));
451aaf68
JT
2489 unlock_user (dev_ifname, optval_addr, 0);
2490 return ret;
2491 }
83eb6e50
CMAB
2492 case TARGET_SO_LINGER:
2493 {
2494 struct linger lg;
2495 struct target_linger *tlg;
2496
2497 if (optlen != sizeof(struct target_linger)) {
2498 return -TARGET_EINVAL;
2499 }
2500 if (!lock_user_struct(VERIFY_READ, tlg, optval_addr, 1)) {
2501 return -TARGET_EFAULT;
2502 }
2503 __get_user(lg.l_onoff, &tlg->l_onoff);
2504 __get_user(lg.l_linger, &tlg->l_linger);
2505 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, SO_LINGER,
2506 &lg, sizeof(lg)));
2507 unlock_user_struct(tlg, optval_addr, 0);
2508 return ret;
2509 }
8853f86e 2510 /* Options with 'int' argument. */
3532fa74
FB
2511 case TARGET_SO_DEBUG:
2512 optname = SO_DEBUG;
2513 break;
2514 case TARGET_SO_REUSEADDR:
2515 optname = SO_REUSEADDR;
2516 break;
113a9dd7
YS
2517#ifdef SO_REUSEPORT
2518 case TARGET_SO_REUSEPORT:
2519 optname = SO_REUSEPORT;
2520 break;
2521#endif
3532fa74
FB
2522 case TARGET_SO_TYPE:
2523 optname = SO_TYPE;
2524 break;
2525 case TARGET_SO_ERROR:
2526 optname = SO_ERROR;
2527 break;
2528 case TARGET_SO_DONTROUTE:
2529 optname = SO_DONTROUTE;
2530 break;
2531 case TARGET_SO_BROADCAST:
2532 optname = SO_BROADCAST;
2533 break;
2534 case TARGET_SO_SNDBUF:
2535 optname = SO_SNDBUF;
2536 break;
d79b6cc4
PB
2537 case TARGET_SO_SNDBUFFORCE:
2538 optname = SO_SNDBUFFORCE;
2539 break;
3532fa74
FB
2540 case TARGET_SO_RCVBUF:
2541 optname = SO_RCVBUF;
2542 break;
d79b6cc4
PB
2543 case TARGET_SO_RCVBUFFORCE:
2544 optname = SO_RCVBUFFORCE;
2545 break;
3532fa74
FB
2546 case TARGET_SO_KEEPALIVE:
2547 optname = SO_KEEPALIVE;
2548 break;
2549 case TARGET_SO_OOBINLINE:
2550 optname = SO_OOBINLINE;
2551 break;
2552 case TARGET_SO_NO_CHECK:
2553 optname = SO_NO_CHECK;
2554 break;
2555 case TARGET_SO_PRIORITY:
2556 optname = SO_PRIORITY;
2557 break;
5e83e8e3 2558#ifdef SO_BSDCOMPAT
3532fa74
FB
2559 case TARGET_SO_BSDCOMPAT:
2560 optname = SO_BSDCOMPAT;
2561 break;
5e83e8e3 2562#endif
3532fa74
FB
2563 case TARGET_SO_PASSCRED:
2564 optname = SO_PASSCRED;
2565 break;
82d0fe6b
PB
2566 case TARGET_SO_PASSSEC:
2567 optname = SO_PASSSEC;
2568 break;
3532fa74
FB
2569 case TARGET_SO_TIMESTAMP:
2570 optname = SO_TIMESTAMP;
2571 break;
2572 case TARGET_SO_RCVLOWAT:
2573 optname = SO_RCVLOWAT;
2574 break;
8853f86e
FB
2575 default:
2576 goto unimplemented;
2577 }
3532fa74 2578 if (optlen < sizeof(uint32_t))
2f619698 2579 return -TARGET_EINVAL;
3532fa74 2580
2f619698
FB
2581 if (get_user_u32(val, optval_addr))
2582 return -TARGET_EFAULT;
3532fa74 2583 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
8853f86e 2584 break;
a2d86682
JK
2585#ifdef SOL_NETLINK
2586 case SOL_NETLINK:
2587 switch (optname) {
2588 case NETLINK_PKTINFO:
2589 case NETLINK_ADD_MEMBERSHIP:
2590 case NETLINK_DROP_MEMBERSHIP:
2591 case NETLINK_BROADCAST_ERROR:
2592 case NETLINK_NO_ENOBUFS:
2593#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2594 case NETLINK_LISTEN_ALL_NSID:
2595 case NETLINK_CAP_ACK:
2596#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2597#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2598 case NETLINK_EXT_ACK:
2599#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2600#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
2601 case NETLINK_GET_STRICT_CHK:
2602#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2603 break;
2604 default:
2605 goto unimplemented;
2606 }
2607 val = 0;
2608 if (optlen < sizeof(uint32_t)) {
2609 return -TARGET_EINVAL;
2610 }
2611 if (get_user_u32(val, optval_addr)) {
2612 return -TARGET_EFAULT;
2613 }
2614 ret = get_errno(setsockopt(sockfd, SOL_NETLINK, optname, &val,
2615 sizeof(val)));
2616 break;
2617#endif /* SOL_NETLINK */
7854b056 2618 default:
8853f86e 2619 unimplemented:
39be5350
JK
2620 qemu_log_mask(LOG_UNIMP, "Unsupported setsockopt level=%d optname=%d\n",
2621 level, optname);
6fa13c17 2622 ret = -TARGET_ENOPROTOOPT;
7854b056 2623 }
8853f86e 2624 return ret;
7854b056
FB
2625}
2626
0da46a6e 2627/* do_getsockopt() Must return target values and target errnos. */
992f48a0 2628static abi_long do_getsockopt(int sockfd, int level, int optname,
2f619698 2629 abi_ulong optval_addr, abi_ulong optlen)
7854b056 2630{
992f48a0 2631 abi_long ret;
b55266b5
BS
2632 int len, val;
2633 socklen_t lv;
8853f86e
FB
2634
2635 switch(level) {
3532fa74 2636 case TARGET_SOL_SOCKET:
f3b974cd
JL
2637 level = SOL_SOCKET;
2638 switch (optname) {
2639 /* These don't just return a single integer */
f3b974cd
JL
2640 case TARGET_SO_PEERNAME:
2641 goto unimplemented;
405dc4cf
AS
2642 case TARGET_SO_RCVTIMEO: {
2643 struct timeval tv;
2644 socklen_t tvlen;
2645
2646 optname = SO_RCVTIMEO;
2647
2648get_timeout:
2649 if (get_user_u32(len, optlen)) {
2650 return -TARGET_EFAULT;
2651 }
2652 if (len < 0) {
2653 return -TARGET_EINVAL;
2654 }
2655
2656 tvlen = sizeof(tv);
2657 ret = get_errno(getsockopt(sockfd, level, optname,
2658 &tv, &tvlen));
2659 if (ret < 0) {
2660 return ret;
2661 }
2662 if (len > sizeof(struct target_timeval)) {
2663 len = sizeof(struct target_timeval);
2664 }
2665 if (copy_to_user_timeval(optval_addr, &tv)) {
2666 return -TARGET_EFAULT;
2667 }
2668 if (put_user_u32(len, optlen)) {
2669 return -TARGET_EFAULT;
2670 }
2671 break;
2672 }
2673 case TARGET_SO_SNDTIMEO:
2674 optname = SO_SNDTIMEO;
2675 goto get_timeout;
583359a6
AP
2676 case TARGET_SO_PEERCRED: {
2677 struct ucred cr;
2678 socklen_t crlen;
2679 struct target_ucred *tcr;
2680
2681 if (get_user_u32(len, optlen)) {
2682 return -TARGET_EFAULT;
2683 }
2684 if (len < 0) {
2685 return -TARGET_EINVAL;
2686 }
2687
2688 crlen = sizeof(cr);
2689 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
2690 &cr, &crlen));
2691 if (ret < 0) {
2692 return ret;
2693 }
2694 if (len > crlen) {
2695 len = crlen;
2696 }
2697 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
2698 return -TARGET_EFAULT;
2699 }
2700 __put_user(cr.pid, &tcr->pid);
2701 __put_user(cr.uid, &tcr->uid);
2702 __put_user(cr.gid, &tcr->gid);
2703 unlock_user_struct(tcr, optval_addr, 1);
2704 if (put_user_u32(len, optlen)) {
83eb6e50
CMAB
2705 return -TARGET_EFAULT;
2706 }
2707 break;
2708 }
6d485a55
LV
2709 case TARGET_SO_PEERSEC: {
2710 char *name;
2711
2712 if (get_user_u32(len, optlen)) {
2713 return -TARGET_EFAULT;
2714 }
2715 if (len < 0) {
2716 return -TARGET_EINVAL;
2717 }
2718 name = lock_user(VERIFY_WRITE, optval_addr, len, 0);
2719 if (!name) {
2720 return -TARGET_EFAULT;
2721 }
2722 lv = len;
2723 ret = get_errno(getsockopt(sockfd, level, SO_PEERSEC,
2724 name, &lv));
2725 if (put_user_u32(lv, optlen)) {
2726 ret = -TARGET_EFAULT;
2727 }
2728 unlock_user(name, optval_addr, lv);
2729 break;
2730 }
83eb6e50
CMAB
2731 case TARGET_SO_LINGER:
2732 {
2733 struct linger lg;
2734 socklen_t lglen;
2735 struct target_linger *tlg;
2736
2737 if (get_user_u32(len, optlen)) {
2738 return -TARGET_EFAULT;
2739 }
2740 if (len < 0) {
2741 return -TARGET_EINVAL;
2742 }
2743
2744 lglen = sizeof(lg);
2745 ret = get_errno(getsockopt(sockfd, level, SO_LINGER,
2746 &lg, &lglen));
2747 if (ret < 0) {
2748 return ret;
2749 }
2750 if (len > lglen) {
2751 len = lglen;
2752 }
2753 if (!lock_user_struct(VERIFY_WRITE, tlg, optval_addr, 0)) {
2754 return -TARGET_EFAULT;
2755 }
2756 __put_user(lg.l_onoff, &tlg->l_onoff);
2757 __put_user(lg.l_linger, &tlg->l_linger);
2758 unlock_user_struct(tlg, optval_addr, 1);
2759 if (put_user_u32(len, optlen)) {
583359a6
AP
2760 return -TARGET_EFAULT;
2761 }
2762 break;
2763 }
f3b974cd
JL
2764 /* Options with 'int' argument. */
2765 case TARGET_SO_DEBUG:
2766 optname = SO_DEBUG;
2767 goto int_case;
2768 case TARGET_SO_REUSEADDR:
2769 optname = SO_REUSEADDR;
2770 goto int_case;
113a9dd7
YS
2771#ifdef SO_REUSEPORT
2772 case TARGET_SO_REUSEPORT:
2773 optname = SO_REUSEPORT;
2774 goto int_case;
2775#endif
f3b974cd
JL
2776 case TARGET_SO_TYPE:
2777 optname = SO_TYPE;
2778 goto int_case;
2779 case TARGET_SO_ERROR:
2780 optname = SO_ERROR;
2781 goto int_case;
2782 case TARGET_SO_DONTROUTE:
2783 optname = SO_DONTROUTE;
2784 goto int_case;
2785 case TARGET_SO_BROADCAST:
2786 optname = SO_BROADCAST;
2787 goto int_case;
2788 case TARGET_SO_SNDBUF:
2789 optname = SO_SNDBUF;
2790 goto int_case;
2791 case TARGET_SO_RCVBUF:
2792 optname = SO_RCVBUF;
2793 goto int_case;
2794 case TARGET_SO_KEEPALIVE:
2795 optname = SO_KEEPALIVE;
2796 goto int_case;
2797 case TARGET_SO_OOBINLINE:
2798 optname = SO_OOBINLINE;
2799 goto int_case;
2800 case TARGET_SO_NO_CHECK:
2801 optname = SO_NO_CHECK;
2802 goto int_case;
2803 case TARGET_SO_PRIORITY:
2804 optname = SO_PRIORITY;
2805 goto int_case;
2806#ifdef SO_BSDCOMPAT
2807 case TARGET_SO_BSDCOMPAT:
2808 optname = SO_BSDCOMPAT;
2809 goto int_case;
2810#endif
2811 case TARGET_SO_PASSCRED:
2812 optname = SO_PASSCRED;
2813 goto int_case;
2814 case TARGET_SO_TIMESTAMP:
2815 optname = SO_TIMESTAMP;
2816 goto int_case;
2817 case TARGET_SO_RCVLOWAT:
2818 optname = SO_RCVLOWAT;
2819 goto int_case;
aec1ca41
PB
2820 case TARGET_SO_ACCEPTCONN:
2821 optname = SO_ACCEPTCONN;
2822 goto int_case;
8853f86e 2823 default:
2efbe911
FB
2824 goto int_case;
2825 }
2826 break;
2827 case SOL_TCP:
2828 /* TCP options all take an 'int' value. */
2829 int_case:
2f619698
FB
2830 if (get_user_u32(len, optlen))
2831 return -TARGET_EFAULT;
2efbe911 2832 if (len < 0)
0da46a6e 2833 return -TARGET_EINVAL;
73160d95 2834 lv = sizeof(lv);
2efbe911
FB
2835 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2836 if (ret < 0)
2837 return ret;
8289d112
PB
2838 if (optname == SO_TYPE) {
2839 val = host_to_target_sock_type(val);
2840 }
2efbe911
FB
2841 if (len > lv)
2842 len = lv;
2f619698
FB
2843 if (len == 4) {
2844 if (put_user_u32(val, optval_addr))
2845 return -TARGET_EFAULT;
2846 } else {
2847 if (put_user_u8(val, optval_addr))
2848 return -TARGET_EFAULT;
f3b974cd 2849 }
2f619698
FB
2850 if (put_user_u32(len, optlen))
2851 return -TARGET_EFAULT;
2efbe911
FB
2852 break;
2853 case SOL_IP:
2854 switch(optname) {
2855 case IP_TOS:
2856 case IP_TTL:
2857 case IP_HDRINCL:
2858 case IP_ROUTER_ALERT:
2859 case IP_RECVOPTS:
2860 case IP_RETOPTS:
2861 case IP_PKTINFO:
2862 case IP_MTU_DISCOVER:
2863 case IP_RECVERR:
2864 case IP_RECVTOS:
2865#ifdef IP_FREEBIND
2866 case IP_FREEBIND:
2867#endif
2868 case IP_MULTICAST_TTL:
2869 case IP_MULTICAST_LOOP:
2f619698
FB
2870 if (get_user_u32(len, optlen))
2871 return -TARGET_EFAULT;
8853f86e 2872 if (len < 0)
0da46a6e 2873 return -TARGET_EINVAL;
73160d95 2874 lv = sizeof(lv);
8853f86e
FB
2875 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2876 if (ret < 0)
2877 return ret;
2efbe911 2878 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2efbe911 2879 len = 1;
2f619698
FB
2880 if (put_user_u32(len, optlen)
2881 || put_user_u8(val, optval_addr))
2882 return -TARGET_EFAULT;
2efbe911 2883 } else {
2efbe911
FB
2884 if (len > sizeof(int))
2885 len = sizeof(int);
2f619698
FB
2886 if (put_user_u32(len, optlen)
2887 || put_user_u32(val, optval_addr))
2888 return -TARGET_EFAULT;
2efbe911 2889 }
8853f86e 2890 break;
2efbe911 2891 default:
c02f499e
TS
2892 ret = -TARGET_ENOPROTOOPT;
2893 break;
8853f86e
FB
2894 }
2895 break;
bd8ed485
TD
2896 case SOL_IPV6:
2897 switch (optname) {
2898 case IPV6_MTU_DISCOVER:
2899 case IPV6_MTU:
2900 case IPV6_V6ONLY:
2901 case IPV6_RECVPKTINFO:
2902 case IPV6_UNICAST_HOPS:
2903 case IPV6_MULTICAST_HOPS:
2904 case IPV6_MULTICAST_LOOP:
2905 case IPV6_RECVERR:
2906 case IPV6_RECVHOPLIMIT:
2907 case IPV6_2292HOPLIMIT:
2908 case IPV6_CHECKSUM:
b9cce6d7
HD
2909 case IPV6_ADDRFORM:
2910 case IPV6_2292PKTINFO:
2911 case IPV6_RECVTCLASS:
2912 case IPV6_RECVRTHDR:
2913 case IPV6_2292RTHDR:
2914 case IPV6_RECVHOPOPTS:
2915 case IPV6_2292HOPOPTS:
2916 case IPV6_RECVDSTOPTS:
2917 case IPV6_2292DSTOPTS:
2918 case IPV6_TCLASS:
2919#ifdef IPV6_RECVPATHMTU
2920 case IPV6_RECVPATHMTU:
2921#endif
2922#ifdef IPV6_TRANSPARENT
2923 case IPV6_TRANSPARENT:
2924#endif
2925#ifdef IPV6_FREEBIND
2926 case IPV6_FREEBIND:
2927#endif
2928#ifdef IPV6_RECVORIGDSTADDR
2929 case IPV6_RECVORIGDSTADDR:
2930#endif
bd8ed485
TD
2931 if (get_user_u32(len, optlen))
2932 return -TARGET_EFAULT;
2933 if (len < 0)
2934 return -TARGET_EINVAL;
2935 lv = sizeof(lv);
2936 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2937 if (ret < 0)
2938 return ret;
2939 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2940 len = 1;
2941 if (put_user_u32(len, optlen)
2942 || put_user_u8(val, optval_addr))
2943 return -TARGET_EFAULT;
2944 } else {
2945 if (len > sizeof(int))
2946 len = sizeof(int);
2947 if (put_user_u32(len, optlen)
2948 || put_user_u32(val, optval_addr))
2949 return -TARGET_EFAULT;
2950 }
2951 break;
2952 default:
2953 ret = -TARGET_ENOPROTOOPT;
2954 break;
2955 }
2956 break;
a2d86682
JK
2957#ifdef SOL_NETLINK
2958 case SOL_NETLINK:
2959 switch (optname) {
2960 case NETLINK_PKTINFO:
2961 case NETLINK_BROADCAST_ERROR:
2962 case NETLINK_NO_ENOBUFS:
2963#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2964 case NETLINK_LISTEN_ALL_NSID:
2965 case NETLINK_CAP_ACK:
2966#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2967#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2968 case NETLINK_EXT_ACK:
2969#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2970#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
2971 case NETLINK_GET_STRICT_CHK:
2972#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2973 if (get_user_u32(len, optlen)) {
2974 return -TARGET_EFAULT;
2975 }
2976 if (len != sizeof(val)) {
2977 return -TARGET_EINVAL;
2978 }
2979 lv = len;
2980 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2981 if (ret < 0) {
2982 return ret;
2983 }
2984 if (put_user_u32(lv, optlen)
2985 || put_user_u32(val, optval_addr)) {
2986 return -TARGET_EFAULT;
2987 }
2988 break;
2989#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2990 case NETLINK_LIST_MEMBERSHIPS:
2991 {
2992 uint32_t *results;
2993 int i;
2994 if (get_user_u32(len, optlen)) {
2995 return -TARGET_EFAULT;
2996 }
2997 if (len < 0) {
2998 return -TARGET_EINVAL;
2999 }
3000 results = lock_user(VERIFY_WRITE, optval_addr, len, 1);
3001 if (!results) {
3002 return -TARGET_EFAULT;
3003 }
3004 lv = len;
3005 ret = get_errno(getsockopt(sockfd, level, optname, results, &lv));
3006 if (ret < 0) {
3007 unlock_user(results, optval_addr, 0);
3008 return ret;
3009 }
3010 /* swap host endianess to target endianess. */
3011 for (i = 0; i < (len / sizeof(uint32_t)); i++) {
3012 results[i] = tswap32(results[i]);
3013 }
3014 if (put_user_u32(lv, optlen)) {
3015 return -TARGET_EFAULT;
3016 }
3017 unlock_user(results, optval_addr, 0);
3018 break;
3019 }
3020#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
3021 default:
3022 goto unimplemented;
3023 }
c0cb8801 3024 break;
a2d86682 3025#endif /* SOL_NETLINK */
8853f86e
FB
3026 default:
3027 unimplemented:
39be5350
JK
3028 qemu_log_mask(LOG_UNIMP,
3029 "getsockopt level=%d optname=%d not yet supported\n",
3030 level, optname);
c02f499e 3031 ret = -TARGET_EOPNOTSUPP;
8853f86e
FB
3032 break;
3033 }
3034 return ret;
7854b056
FB
3035}
3036
9ac22517
MF
3037/* Convert target low/high pair representing file offset into the host
3038 * low/high pair. This function doesn't handle offsets bigger than 64 bits
3039 * as the kernel doesn't handle them either.
3040 */
3041static void target_to_host_low_high(abi_ulong tlow,
3042 abi_ulong thigh,
3043 unsigned long *hlow,
3044 unsigned long *hhigh)
3045{
3046 uint64_t off = tlow |
3047 ((unsigned long long)thigh << TARGET_LONG_BITS / 2) <<
3048 TARGET_LONG_BITS / 2;
3049
3050 *hlow = off;
3051 *hhigh = (off >> HOST_LONG_BITS / 2) >> HOST_LONG_BITS / 2;
3052}
3053
f287b2c2 3054static struct iovec *lock_iovec(int type, abi_ulong target_addr,
dab32b32 3055 abi_ulong count, int copy)
53a5960a
PB
3056{
3057 struct target_iovec *target_vec;
f287b2c2
RH
3058 struct iovec *vec;
3059 abi_ulong total_len, max_len;
d732dcb4 3060 int i;
501bb4b0 3061 int err = 0;
29560a6c 3062 bool bad_address = false;
53a5960a 3063
f287b2c2
RH
3064 if (count == 0) {
3065 errno = 0;
3066 return NULL;
3067 }
dab32b32 3068 if (count > IOV_MAX) {
f287b2c2
RH
3069 errno = EINVAL;
3070 return NULL;
3071 }
3072
0e173b24 3073 vec = g_try_new0(struct iovec, count);
f287b2c2
RH
3074 if (vec == NULL) {
3075 errno = ENOMEM;
3076 return NULL;
3077 }
3078
3079 target_vec = lock_user(VERIFY_READ, target_addr,
3080 count * sizeof(struct target_iovec), 1);
3081 if (target_vec == NULL) {
501bb4b0 3082 err = EFAULT;
f287b2c2
RH
3083 goto fail2;
3084 }
3085
3086 /* ??? If host page size > target page size, this will result in a
3087 value larger than what we can actually support. */
3088 max_len = 0x7fffffff & TARGET_PAGE_MASK;
3089 total_len = 0;
3090
3091 for (i = 0; i < count; i++) {
3092 abi_ulong base = tswapal(target_vec[i].iov_base);
3093 abi_long len = tswapal(target_vec[i].iov_len);
3094
3095 if (len < 0) {
501bb4b0 3096 err = EINVAL;
f287b2c2
RH
3097 goto fail;
3098 } else if (len == 0) {
3099 /* Zero length pointer is ignored. */
3100 vec[i].iov_base = 0;
41df8411 3101 } else {
f287b2c2 3102 vec[i].iov_base = lock_user(type, base, len, copy);
29560a6c
TM
3103 /* If the first buffer pointer is bad, this is a fault. But
3104 * subsequent bad buffers will result in a partial write; this
3105 * is realized by filling the vector with null pointers and
3106 * zero lengths. */
f287b2c2 3107 if (!vec[i].iov_base) {
29560a6c
TM
3108 if (i == 0) {
3109 err = EFAULT;
3110 goto fail;
3111 } else {
3112 bad_address = true;
3113 }
3114 }
3115 if (bad_address) {
3116 len = 0;
f287b2c2
RH
3117 }
3118 if (len > max_len - total_len) {
3119 len = max_len - total_len;
3120 }
41df8411 3121 }
f287b2c2
RH
3122 vec[i].iov_len = len;
3123 total_len += len;
579a97f7 3124 }
f287b2c2
RH
3125
3126 unlock_user(target_vec, target_addr, 0);
3127 return vec;
3128
3129 fail:
7eff518b
CG
3130 while (--i >= 0) {
3131 if (tswapal(target_vec[i].iov_len) > 0) {
3132 unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
3133 }
3134 }
f287b2c2 3135 unlock_user(target_vec, target_addr, 0);
501bb4b0 3136 fail2:
0e173b24 3137 g_free(vec);
501bb4b0 3138 errno = err;
f287b2c2 3139 return NULL;
53a5960a
PB
3140}
3141
f287b2c2 3142static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
dab32b32 3143 abi_ulong count, int copy)
53a5960a
PB
3144{
3145 struct target_iovec *target_vec;
53a5960a
PB
3146 int i;
3147
f287b2c2
RH
3148 target_vec = lock_user(VERIFY_READ, target_addr,
3149 count * sizeof(struct target_iovec), 1);
3150 if (target_vec) {
3151 for (i = 0; i < count; i++) {
3152 abi_ulong base = tswapal(target_vec[i].iov_base);
71ec7cef 3153 abi_long len = tswapal(target_vec[i].iov_len);
f287b2c2
RH
3154 if (len < 0) {
3155 break;
3156 }
d732dcb4
AZ
3157 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
3158 }
f287b2c2 3159 unlock_user(target_vec, target_addr, 0);
53a5960a 3160 }
579a97f7 3161
0e173b24 3162 g_free(vec);
53a5960a
PB
3163}
3164
53d09b76 3165static inline int target_to_host_sock_type(int *type)
3532fa74 3166{
f651e6ae
PJ
3167 int host_type = 0;
3168 int target_type = *type;
3169
3170 switch (target_type & TARGET_SOCK_TYPE_MASK) {
3532fa74 3171 case TARGET_SOCK_DGRAM:
f651e6ae 3172 host_type = SOCK_DGRAM;
3532fa74
FB
3173 break;
3174 case TARGET_SOCK_STREAM:
f651e6ae 3175 host_type = SOCK_STREAM;
3532fa74 3176 break;
f651e6ae
PJ
3177 default:
3178 host_type = target_type & TARGET_SOCK_TYPE_MASK;
3532fa74
FB
3179 break;
3180 }
f651e6ae 3181 if (target_type & TARGET_SOCK_CLOEXEC) {
53d09b76 3182#if defined(SOCK_CLOEXEC)
f651e6ae 3183 host_type |= SOCK_CLOEXEC;
53d09b76
EI
3184#else
3185 return -TARGET_EINVAL;
3186#endif
f651e6ae
PJ
3187 }
3188 if (target_type & TARGET_SOCK_NONBLOCK) {
53d09b76 3189#if defined(SOCK_NONBLOCK)
f651e6ae 3190 host_type |= SOCK_NONBLOCK;
53d09b76
EI
3191#elif !defined(O_NONBLOCK)
3192 return -TARGET_EINVAL;
3193#endif
f651e6ae
PJ
3194 }
3195 *type = host_type;
53d09b76
EI
3196 return 0;
3197}
3198
3199/* Try to emulate socket type flags after socket creation. */
3200static int sock_flags_fixup(int fd, int target_type)
3201{
3202#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
3203 if (target_type & TARGET_SOCK_NONBLOCK) {
3204 int flags = fcntl(fd, F_GETFL);
3205 if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
3206 close(fd);
3207 return -TARGET_EINVAL;
3208 }
3209 }
3210#endif
3211 return fd;
f651e6ae
PJ
3212}
3213
3214/* do_socket() Must return target values and target errnos. */
3215static abi_long do_socket(int domain, int type, int protocol)
3216{
53d09b76
EI
3217 int target_type = type;
3218 int ret;
3219
3220 ret = target_to_host_sock_type(&type);
3221 if (ret) {
3222 return ret;
3223 }
f651e6ae 3224
575b22b1
LV
3225 if (domain == PF_NETLINK && !(
3226#ifdef CONFIG_RTNETLINK
3227 protocol == NETLINK_ROUTE ||
3228#endif
3229 protocol == NETLINK_KOBJECT_UEVENT ||
3230 protocol == NETLINK_AUDIT)) {
71e2443e 3231 return -TARGET_EPROTONOSUPPORT;
6c5b5645 3232 }
ff626f2d
LV
3233
3234 if (domain == AF_PACKET ||
3235 (domain == AF_INET && type == SOCK_PACKET)) {
3236 protocol = tswap16(protocol);
3237 }
3238
53d09b76
EI
3239 ret = get_errno(socket(domain, type, protocol));
3240 if (ret >= 0) {
3241 ret = sock_flags_fixup(ret, target_type);
0cf22722
LV
3242 if (type == SOCK_PACKET) {
3243 /* Manage an obsolete case :
3244 * if socket type is SOCK_PACKET, bind by name
3245 */
3246 fd_trans_register(ret, &target_packet_trans);
6c5b5645
LV
3247 } else if (domain == PF_NETLINK) {
3248 switch (protocol) {
575b22b1 3249#ifdef CONFIG_RTNETLINK
6c5b5645
LV
3250 case NETLINK_ROUTE:
3251 fd_trans_register(ret, &target_netlink_route_trans);
3252 break;
575b22b1 3253#endif
b265620b
LV
3254 case NETLINK_KOBJECT_UEVENT:
3255 /* nothing to do: messages are strings */
3256 break;
5ce9bb59
LV
3257 case NETLINK_AUDIT:
3258 fd_trans_register(ret, &target_netlink_audit_trans);
3259 break;
6c5b5645
LV
3260 default:
3261 g_assert_not_reached();
3262 }
0cf22722 3263 }
53d09b76
EI
3264 }
3265 return ret;
3532fa74
FB
3266}
3267
0da46a6e 3268/* do_bind() Must return target values and target errnos. */
992f48a0
BS
3269static abi_long do_bind(int sockfd, abi_ulong target_addr,
3270 socklen_t addrlen)
3532fa74 3271{
8f7aeaf6 3272 void *addr;
917507b0 3273 abi_long ret;
8f7aeaf6 3274
38724253 3275 if ((int)addrlen < 0) {
8f7aeaf6 3276 return -TARGET_EINVAL;
38724253 3277 }
8f7aeaf6 3278
607175e0 3279 addr = alloca(addrlen+1);
3b46e624 3280
7b36f782 3281 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
917507b0
AP
3282 if (ret)
3283 return ret;
3284
3532fa74
FB
3285 return get_errno(bind(sockfd, addr, addrlen));
3286}
3287
0da46a6e 3288/* do_connect() Must return target values and target errnos. */
992f48a0
BS
3289static abi_long do_connect(int sockfd, abi_ulong target_addr,
3290 socklen_t addrlen)
3532fa74 3291{
8f7aeaf6 3292 void *addr;
917507b0 3293 abi_long ret;
8f7aeaf6 3294
38724253 3295 if ((int)addrlen < 0) {
8f7aeaf6 3296 return -TARGET_EINVAL;
38724253 3297 }
8f7aeaf6 3298
2dd08dfd 3299 addr = alloca(addrlen+1);
3b46e624 3300
7b36f782 3301 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
917507b0
AP
3302 if (ret)
3303 return ret;
3304
2a3c7619 3305 return get_errno(safe_connect(sockfd, addr, addrlen));
3532fa74
FB
3306}
3307
f19e00d7
AG
3308/* do_sendrecvmsg_locked() Must return target values and target errnos. */
3309static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
3310 int flags, int send)
3532fa74 3311{
6de645c7 3312 abi_long ret, len;
3532fa74 3313 struct msghdr msg;
dab32b32 3314 abi_ulong count;
3532fa74 3315 struct iovec *vec;
992f48a0 3316 abi_ulong target_vec;
3532fa74 3317
3532fa74
FB
3318 if (msgp->msg_name) {
3319 msg.msg_namelen = tswap32(msgp->msg_namelen);
2dd08dfd 3320 msg.msg_name = alloca(msg.msg_namelen+1);
7b36f782
LV
3321 ret = target_to_host_sockaddr(fd, msg.msg_name,
3322 tswapal(msgp->msg_name),
3323 msg.msg_namelen);
26a6fc96
PM
3324 if (ret == -TARGET_EFAULT) {
3325 /* For connected sockets msg_name and msg_namelen must
3326 * be ignored, so returning EFAULT immediately is wrong.
3327 * Instead, pass a bad msg_name to the host kernel, and
3328 * let it decide whether to return EFAULT or not.
3329 */
3330 msg.msg_name = (void *)-1;
3331 } else if (ret) {
f287b2c2 3332 goto out2;
917507b0 3333 }
3532fa74
FB
3334 } else {
3335 msg.msg_name = NULL;
3336 msg.msg_namelen = 0;
3337 }
cbb21eed 3338 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
3532fa74 3339 msg.msg_control = alloca(msg.msg_controllen);
1d3d1b23
JS
3340 memset(msg.msg_control, 0, msg.msg_controllen);
3341
3532fa74 3342 msg.msg_flags = tswap32(msgp->msg_flags);
3b46e624 3343
cbb21eed 3344 count = tswapal(msgp->msg_iovlen);
cbb21eed 3345 target_vec = tswapal(msgp->msg_iov);
97b07970
PM
3346
3347 if (count > IOV_MAX) {
3348 /* sendrcvmsg returns a different errno for this condition than
3349 * readv/writev, so we must catch it here before lock_iovec() does.
3350 */
3351 ret = -TARGET_EMSGSIZE;
3352 goto out2;
3353 }
3354
f287b2c2
RH
3355 vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
3356 target_vec, count, send);
3357 if (vec == NULL) {
3358 ret = -host_to_target_errno(errno);
3359 goto out2;
3360 }
3532fa74
FB
3361 msg.msg_iovlen = count;
3362 msg.msg_iov = vec;
3b46e624 3363
3532fa74 3364 if (send) {
6c5b5645 3365 if (fd_trans_target_to_host_data(fd)) {
7d61d892
LV
3366 void *host_msg;
3367
3368 host_msg = g_malloc(msg.msg_iov->iov_len);
3369 memcpy(host_msg, msg.msg_iov->iov_base, msg.msg_iov->iov_len);
3370 ret = fd_trans_target_to_host_data(fd)(host_msg,
6c5b5645 3371 msg.msg_iov->iov_len);
7d61d892
LV
3372 if (ret >= 0) {
3373 msg.msg_iov->iov_base = host_msg;
3374 ret = get_errno(safe_sendmsg(fd, &msg, flags));
3375 }
3376 g_free(host_msg);
6c5b5645
LV
3377 } else {
3378 ret = target_to_host_cmsg(&msg, msgp);
7d61d892
LV
3379 if (ret == 0) {
3380 ret = get_errno(safe_sendmsg(fd, &msg, flags));
3381 }
6c5b5645 3382 }
3532fa74 3383 } else {
66687530 3384 ret = get_errno(safe_recvmsg(fd, &msg, flags));
6de645c7
AZ
3385 if (!is_error(ret)) {
3386 len = ret;
6c5b5645
LV
3387 if (fd_trans_host_to_target_data(fd)) {
3388 ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
2a03d3e6 3389 MIN(msg.msg_iov->iov_len, len));
6c5b5645
LV
3390 } else {
3391 ret = host_to_target_cmsg(msgp, &msg);
3392 }
ca619067
JH
3393 if (!is_error(ret)) {
3394 msgp->msg_namelen = tswap32(msg.msg_namelen);
24894f39 3395 msgp->msg_flags = tswap32(msg.msg_flags);
26a6fc96 3396 if (msg.msg_name != NULL && msg.msg_name != (void *)-1) {
ca619067
JH
3397 ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
3398 msg.msg_name, msg.msg_namelen);
3399 if (ret) {
3400 goto out;
3401 }
3402 }
3403
6de645c7 3404 ret = len;
ca619067 3405 }
6de645c7 3406 }
3532fa74 3407 }
ca619067
JH
3408
3409out:
3532fa74 3410 unlock_iovec(vec, target_vec, count, !send);
f287b2c2 3411out2:
f19e00d7
AG
3412 return ret;
3413}
3414
3415static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
3416 int flags, int send)
3417{
3418 abi_long ret;
3419 struct target_msghdr *msgp;
3420
3421 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
3422 msgp,
3423 target_msg,
3424 send ? 1 : 0)) {
3425 return -TARGET_EFAULT;
3426 }
3427 ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
579a97f7 3428 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
3532fa74
FB
3429 return ret;
3430}
3431
f19e00d7
AG
3432/* We don't rely on the C library to have sendmmsg/recvmmsg support,
3433 * so it might not have this *mmsg-specific flag either.
3434 */
3435#ifndef MSG_WAITFORONE
3436#define MSG_WAITFORONE 0x10000
3437#endif
3438
3439static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
3440 unsigned int vlen, unsigned int flags,
3441 int send)
3442{
3443 struct target_mmsghdr *mmsgp;
3444 abi_long ret = 0;
3445 int i;
3446
3447 if (vlen > UIO_MAXIOV) {
3448 vlen = UIO_MAXIOV;
3449 }
3450
3451 mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
3452 if (!mmsgp) {
3453 return -TARGET_EFAULT;
3454 }
3455
3456 for (i = 0; i < vlen; i++) {
3457 ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
3458 if (is_error(ret)) {
3459 break;
3460 }
3461 mmsgp[i].msg_len = tswap32(ret);
3462 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
3463 if (flags & MSG_WAITFORONE) {
3464 flags |= MSG_DONTWAIT;
3465 }
3466 }
3467
3468 unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
3469
3470 /* Return number of datagrams sent if we sent any at all;
3471 * otherwise return the error.
3472 */
3473 if (i) {
3474 return i;
3475 }
3476 return ret;
3477}
f19e00d7 3478
a94b4987
PM
3479/* do_accept4() Must return target values and target errnos. */
3480static abi_long do_accept4(int fd, abi_ulong target_addr,
3481 abi_ulong target_addrlen_addr, int flags)
1be9e1dc 3482{
cd813367 3483 socklen_t addrlen, ret_addrlen;
2f619698 3484 void *addr;
992f48a0 3485 abi_long ret;
d25295d4
PJ
3486 int host_flags;
3487
3488 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
1be9e1dc 3489
a94b4987 3490 if (target_addr == 0) {
ff6dc130 3491 return get_errno(safe_accept4(fd, NULL, NULL, host_flags));
a94b4987 3492 }
917507b0 3493
e554eb4b 3494 /* linux returns EFAULT if addrlen pointer is invalid */
2f619698 3495 if (get_user_u32(addrlen, target_addrlen_addr))
e554eb4b 3496 return -TARGET_EFAULT;
2f619698 3497
38724253 3498 if ((int)addrlen < 0) {
8f7aeaf6 3499 return -TARGET_EINVAL;
38724253 3500 }
8f7aeaf6 3501
917507b0 3502 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
e554eb4b 3503 return -TARGET_EFAULT;
917507b0 3504
2f619698
FB
3505 addr = alloca(addrlen);
3506
cd813367
AS
3507 ret_addrlen = addrlen;
3508 ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags));
1be9e1dc 3509 if (!is_error(ret)) {
cd813367
AS
3510 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3511 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3512 ret = -TARGET_EFAULT;
cd813367 3513 }
1be9e1dc
PB
3514 }
3515 return ret;
3516}
3517
0da46a6e 3518/* do_getpeername() Must return target values and target errnos. */
992f48a0 3519static abi_long do_getpeername(int fd, abi_ulong target_addr,
2f619698 3520 abi_ulong target_addrlen_addr)
1be9e1dc 3521{
cd813367 3522 socklen_t addrlen, ret_addrlen;
2f619698 3523 void *addr;
992f48a0 3524 abi_long ret;
1be9e1dc 3525
2f619698
FB
3526 if (get_user_u32(addrlen, target_addrlen_addr))
3527 return -TARGET_EFAULT;
3528
38724253 3529 if ((int)addrlen < 0) {
8f7aeaf6 3530 return -TARGET_EINVAL;
38724253 3531 }
8f7aeaf6 3532
917507b0
AP
3533 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3534 return -TARGET_EFAULT;
3535
2f619698
FB
3536 addr = alloca(addrlen);
3537
cd813367
AS
3538 ret_addrlen = addrlen;
3539 ret = get_errno(getpeername(fd, addr, &ret_addrlen));
1be9e1dc 3540 if (!is_error(ret)) {
cd813367
AS
3541 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3542 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3543 ret = -TARGET_EFAULT;
cd813367 3544 }
1be9e1dc
PB
3545 }
3546 return ret;
3547}
3548
0da46a6e 3549/* do_getsockname() Must return target values and target errnos. */
992f48a0 3550static abi_long do_getsockname(int fd, abi_ulong target_addr,
2f619698 3551 abi_ulong target_addrlen_addr)
1be9e1dc 3552{
cd813367 3553 socklen_t addrlen, ret_addrlen;
2f619698 3554 void *addr;
992f48a0 3555 abi_long ret;
1be9e1dc 3556
2f619698
FB
3557 if (get_user_u32(addrlen, target_addrlen_addr))
3558 return -TARGET_EFAULT;
3559
38724253 3560 if ((int)addrlen < 0) {
8f7aeaf6 3561 return -TARGET_EINVAL;
38724253 3562 }
8f7aeaf6 3563
917507b0
AP
3564 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3565 return -TARGET_EFAULT;
3566
2f619698
FB
3567 addr = alloca(addrlen);
3568
cd813367
AS
3569 ret_addrlen = addrlen;
3570 ret = get_errno(getsockname(fd, addr, &ret_addrlen));
1be9e1dc 3571 if (!is_error(ret)) {
cd813367
AS
3572 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3573 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3574 ret = -TARGET_EFAULT;
cd813367 3575 }
1be9e1dc
PB
3576 }
3577 return ret;
3578}
3579
0da46a6e 3580/* do_socketpair() Must return target values and target errnos. */
992f48a0 3581static abi_long do_socketpair(int domain, int type, int protocol,
2f619698 3582 abi_ulong target_tab_addr)
1be9e1dc
PB
3583{
3584 int tab[2];
992f48a0 3585 abi_long ret;
1be9e1dc 3586
f651e6ae
PJ
3587 target_to_host_sock_type(&type);
3588
1be9e1dc
PB
3589 ret = get_errno(socketpair(domain, type, protocol, tab));
3590 if (!is_error(ret)) {
2f619698
FB
3591 if (put_user_s32(tab[0], target_tab_addr)
3592 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
3593 ret = -TARGET_EFAULT;
1be9e1dc
PB
3594 }
3595 return ret;
3596}
3597
0da46a6e 3598/* do_sendto() Must return target values and target errnos. */
992f48a0
BS
3599static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
3600 abi_ulong target_addr, socklen_t addrlen)
1be9e1dc
PB
3601{
3602 void *addr;
3603 void *host_msg;
7d61d892 3604 void *copy_msg = NULL;
992f48a0 3605 abi_long ret;
1be9e1dc 3606
38724253 3607 if ((int)addrlen < 0) {
8f7aeaf6 3608 return -TARGET_EINVAL;
38724253 3609 }
8f7aeaf6 3610
579a97f7
FB
3611 host_msg = lock_user(VERIFY_READ, msg, len, 1);
3612 if (!host_msg)
3613 return -TARGET_EFAULT;
6c5b5645 3614 if (fd_trans_target_to_host_data(fd)) {
7d61d892
LV
3615 copy_msg = host_msg;
3616 host_msg = g_malloc(len);
3617 memcpy(host_msg, copy_msg, len);
6c5b5645
LV
3618 ret = fd_trans_target_to_host_data(fd)(host_msg, len);
3619 if (ret < 0) {
7d61d892 3620 goto fail;
6c5b5645
LV
3621 }
3622 }
1be9e1dc 3623 if (target_addr) {
2dd08dfd 3624 addr = alloca(addrlen+1);
7b36f782 3625 ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
917507b0 3626 if (ret) {
7d61d892 3627 goto fail;
917507b0 3628 }
66687530 3629 ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
1be9e1dc 3630 } else {
66687530 3631 ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
1be9e1dc 3632 }
7d61d892
LV
3633fail:
3634 if (copy_msg) {
3635 g_free(host_msg);
3636 host_msg = copy_msg;
3637 }
1be9e1dc
PB
3638 unlock_user(host_msg, msg, 0);
3639 return ret;
3640}
3641
0da46a6e 3642/* do_recvfrom() Must return target values and target errnos. */
992f48a0
BS
3643static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
3644 abi_ulong target_addr,
3645 abi_ulong target_addrlen)
1be9e1dc 3646{
cd813367 3647 socklen_t addrlen, ret_addrlen;
1be9e1dc
PB
3648 void *addr;
3649 void *host_msg;
992f48a0 3650 abi_long ret;
1be9e1dc 3651
579a97f7
FB
3652 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
3653 if (!host_msg)
3654 return -TARGET_EFAULT;
1be9e1dc 3655 if (target_addr) {
2f619698
FB
3656 if (get_user_u32(addrlen, target_addrlen)) {
3657 ret = -TARGET_EFAULT;
3658 goto fail;
3659 }
38724253 3660 if ((int)addrlen < 0) {
8f7aeaf6
AJ
3661 ret = -TARGET_EINVAL;
3662 goto fail;
3663 }
1be9e1dc 3664 addr = alloca(addrlen);
cd813367 3665 ret_addrlen = addrlen;
66687530 3666 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags,
cd813367 3667 addr, &ret_addrlen));
1be9e1dc
PB
3668 } else {
3669 addr = NULL; /* To keep compiler quiet. */
cd813367 3670 addrlen = 0; /* To keep compiler quiet. */
66687530 3671 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
1be9e1dc
PB
3672 }
3673 if (!is_error(ret)) {
c35e1f9c 3674 if (fd_trans_host_to_target_data(fd)) {
2a03d3e6
LV
3675 abi_long trans;
3676 trans = fd_trans_host_to_target_data(fd)(host_msg, MIN(ret, len));
3677 if (is_error(trans)) {
3678 ret = trans;
3679 goto fail;
3680 }
c35e1f9c 3681 }
1be9e1dc 3682 if (target_addr) {
cd813367
AS
3683 host_to_target_sockaddr(target_addr, addr,
3684 MIN(addrlen, ret_addrlen));
3685 if (put_user_u32(ret_addrlen, target_addrlen)) {
2f619698
FB
3686 ret = -TARGET_EFAULT;
3687 goto fail;
3688 }
1be9e1dc
PB
3689 }
3690 unlock_user(host_msg, msg, len);
3691 } else {
2f619698 3692fail:
1be9e1dc
PB
3693 unlock_user(host_msg, msg, 0);
3694 }
3695 return ret;
3696}
3697
32407103 3698#ifdef TARGET_NR_socketcall
ff71a454 3699/* do_socketcall() must return target values and target errnos. */
992f48a0 3700static abi_long do_socketcall(int num, abi_ulong vptr)
31e31b8a 3701{
ff71a454
AM
3702 static const unsigned nargs[] = { /* number of arguments per operation */
3703 [TARGET_SYS_SOCKET] = 3, /* domain, type, protocol */
3704 [TARGET_SYS_BIND] = 3, /* fd, addr, addrlen */
3705 [TARGET_SYS_CONNECT] = 3, /* fd, addr, addrlen */
3706 [TARGET_SYS_LISTEN] = 2, /* fd, backlog */
3707 [TARGET_SYS_ACCEPT] = 3, /* fd, addr, addrlen */
3708 [TARGET_SYS_GETSOCKNAME] = 3, /* fd, addr, addrlen */
3709 [TARGET_SYS_GETPEERNAME] = 3, /* fd, addr, addrlen */
3710 [TARGET_SYS_SOCKETPAIR] = 4, /* domain, type, protocol, tab */
3711 [TARGET_SYS_SEND] = 4, /* fd, msg, len, flags */
3712 [TARGET_SYS_RECV] = 4, /* fd, msg, len, flags */
3713 [TARGET_SYS_SENDTO] = 6, /* fd, msg, len, flags, addr, addrlen */
3714 [TARGET_SYS_RECVFROM] = 6, /* fd, msg, len, flags, addr, addrlen */
3715 [TARGET_SYS_SHUTDOWN] = 2, /* fd, how */
3716 [TARGET_SYS_SETSOCKOPT] = 5, /* fd, level, optname, optval, optlen */
3717 [TARGET_SYS_GETSOCKOPT] = 5, /* fd, level, optname, optval, optlen */
3718 [TARGET_SYS_SENDMSG] = 3, /* fd, msg, flags */
3719 [TARGET_SYS_RECVMSG] = 3, /* fd, msg, flags */
3720 [TARGET_SYS_ACCEPT4] = 4, /* fd, addr, addrlen, flags */
3721 [TARGET_SYS_RECVMMSG] = 4, /* fd, msgvec, vlen, flags */
3722 [TARGET_SYS_SENDMMSG] = 4, /* fd, msgvec, vlen, flags */
62dc90c6
MT
3723 };
3724 abi_long a[6]; /* max 6 args */
ff71a454 3725 unsigned i;
62dc90c6 3726
ff71a454
AM
3727 /* check the range of the first argument num */
3728 /* (TARGET_SYS_SENDMMSG is the highest among TARGET_SYS_xxx) */
3729 if (num < 1 || num > TARGET_SYS_SENDMMSG) {
3730 return -TARGET_EINVAL;
3731 }
3732 /* ensure we have space for args */
3733 if (nargs[num] > ARRAY_SIZE(a)) {
3734 return -TARGET_EINVAL;
3735 }
3736 /* collect the arguments in a[] according to nargs[] */
3737 for (i = 0; i < nargs[num]; ++i) {
3738 if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
3739 return -TARGET_EFAULT;
31e31b8a 3740 }
62dc90c6 3741 }
ff71a454 3742 /* now when we have the args, invoke the appropriate underlying function */
62dc90c6 3743 switch (num) {
ff71a454 3744 case TARGET_SYS_SOCKET: /* domain, type, protocol */
62dc90c6 3745 return do_socket(a[0], a[1], a[2]);
ff71a454 3746 case TARGET_SYS_BIND: /* sockfd, addr, addrlen */
62dc90c6 3747 return do_bind(a[0], a[1], a[2]);
ff71a454 3748 case TARGET_SYS_CONNECT: /* sockfd, addr, addrlen */
62dc90c6 3749 return do_connect(a[0], a[1], a[2]);
ff71a454 3750 case TARGET_SYS_LISTEN: /* sockfd, backlog */
62dc90c6 3751 return get_errno(listen(a[0], a[1]));
ff71a454 3752 case TARGET_SYS_ACCEPT: /* sockfd, addr, addrlen */
62dc90c6 3753 return do_accept4(a[0], a[1], a[2], 0);
ff71a454 3754 case TARGET_SYS_GETSOCKNAME: /* sockfd, addr, addrlen */
62dc90c6 3755 return do_getsockname(a[0], a[1], a[2]);
ff71a454 3756 case TARGET_SYS_GETPEERNAME: /* sockfd, addr, addrlen */
62dc90c6 3757 return do_getpeername(a[0], a[1], a[2]);
ff71a454 3758 case TARGET_SYS_SOCKETPAIR: /* domain, type, protocol, tab */
62dc90c6 3759 return do_socketpair(a[0], a[1], a[2], a[3]);
ff71a454 3760 case TARGET_SYS_SEND: /* sockfd, msg, len, flags */
62dc90c6 3761 return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
ff71a454 3762 case TARGET_SYS_RECV: /* sockfd, msg, len, flags */
62dc90c6 3763 return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
ff71a454 3764 case TARGET_SYS_SENDTO: /* sockfd, msg, len, flags, addr, addrlen */
62dc90c6 3765 return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
ff71a454 3766 case TARGET_SYS_RECVFROM: /* sockfd, msg, len, flags, addr, addrlen */
62dc90c6 3767 return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
ff71a454 3768 case TARGET_SYS_SHUTDOWN: /* sockfd, how */
62dc90c6 3769 return get_errno(shutdown(a[0], a[1]));
ff71a454
AM
3770 case TARGET_SYS_SETSOCKOPT: /* sockfd, level, optname, optval, optlen */
3771 return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
3772 case TARGET_SYS_GETSOCKOPT: /* sockfd, level, optname, optval, optlen */
3773 return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
3774 case TARGET_SYS_SENDMSG: /* sockfd, msg, flags */
62dc90c6 3775 return do_sendrecvmsg(a[0], a[1], a[2], 1);
ff71a454 3776 case TARGET_SYS_RECVMSG: /* sockfd, msg, flags */
62dc90c6 3777 return do_sendrecvmsg(a[0], a[1], a[2], 0);
ff71a454
AM
3778 case TARGET_SYS_ACCEPT4: /* sockfd, addr, addrlen, flags */
3779 return do_accept4(a[0], a[1], a[2], a[3]);
3780 case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, flags */
5a53dc50 3781 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
ff71a454
AM
3782 case TARGET_SYS_SENDMMSG: /* sockfd, msgvec, vlen, flags */
3783 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
31e31b8a 3784 default:
39be5350 3785 qemu_log_mask(LOG_UNIMP, "Unsupported socketcall: %d\n", num);
ff71a454 3786 return -TARGET_EINVAL;
31e31b8a 3787 }
31e31b8a 3788}
32407103 3789#endif
31e31b8a 3790
8853f86e
FB
3791#define N_SHM_REGIONS 32
3792
3793static struct shm_region {
b6e17875
PM
3794 abi_ulong start;
3795 abi_ulong size;
3796 bool in_use;
8853f86e
FB
3797} shm_regions[N_SHM_REGIONS];
3798
005eb2ae
PM
3799#ifndef TARGET_SEMID64_DS
3800/* asm-generic version of this struct */
3801struct target_semid64_ds
3eb6b044
TS
3802{
3803 struct target_ipc_perm sem_perm;
992f48a0 3804 abi_ulong sem_otime;
005eb2ae 3805#if TARGET_ABI_BITS == 32
992f48a0 3806 abi_ulong __unused1;
03527344 3807#endif
992f48a0 3808 abi_ulong sem_ctime;
005eb2ae 3809#if TARGET_ABI_BITS == 32
992f48a0 3810 abi_ulong __unused2;
03527344 3811#endif
992f48a0
BS
3812 abi_ulong sem_nsems;
3813 abi_ulong __unused3;
3814 abi_ulong __unused4;
3eb6b044 3815};
005eb2ae 3816#endif
3eb6b044 3817
579a97f7
FB
3818static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
3819 abi_ulong target_addr)
3eb6b044
TS
3820{
3821 struct target_ipc_perm *target_ip;
005eb2ae 3822 struct target_semid64_ds *target_sd;
3eb6b044 3823
579a97f7
FB
3824 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3825 return -TARGET_EFAULT;
e8bbe36c 3826 target_ip = &(target_sd->sem_perm);
55a2b163
PJ
3827 host_ip->__key = tswap32(target_ip->__key);
3828 host_ip->uid = tswap32(target_ip->uid);
3829 host_ip->gid = tswap32(target_ip->gid);
3830 host_ip->cuid = tswap32(target_ip->cuid);
3831 host_ip->cgid = tswap32(target_ip->cgid);
3832#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3833 host_ip->mode = tswap32(target_ip->mode);
3834#else
cbb21eed 3835 host_ip->mode = tswap16(target_ip->mode);
55a2b163
PJ
3836#endif
3837#if defined(TARGET_PPC)
3838 host_ip->__seq = tswap32(target_ip->__seq);
3839#else
3840 host_ip->__seq = tswap16(target_ip->__seq);
3841#endif
3eb6b044 3842 unlock_user_struct(target_sd, target_addr, 0);
579a97f7 3843 return 0;
3eb6b044
TS
3844}
3845
579a97f7
FB
3846static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
3847 struct ipc_perm *host_ip)
3eb6b044
TS
3848{
3849 struct target_ipc_perm *target_ip;
005eb2ae 3850 struct target_semid64_ds *target_sd;
3eb6b044 3851
579a97f7
FB
3852 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3853 return -TARGET_EFAULT;
3eb6b044 3854 target_ip = &(target_sd->sem_perm);
55a2b163
PJ
3855 target_ip->__key = tswap32(host_ip->__key);
3856 target_ip->uid = tswap32(host_ip->uid);
3857 target_ip->gid = tswap32(host_ip->gid);
3858 target_ip->cuid = tswap32(host_ip->cuid);
3859 target_ip->cgid = tswap32(host_ip->cgid);
3860#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3861 target_ip->mode = tswap32(host_ip->mode);
3862#else
cbb21eed 3863 target_ip->mode = tswap16(host_ip->mode);
55a2b163
PJ
3864#endif
3865#if defined(TARGET_PPC)
3866 target_ip->__seq = tswap32(host_ip->__seq);
3867#else
3868 target_ip->__seq = tswap16(host_ip->__seq);
3869#endif
3eb6b044 3870 unlock_user_struct(target_sd, target_addr, 1);
579a97f7 3871 return 0;
3eb6b044
TS
3872}
3873
579a97f7
FB
3874static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
3875 abi_ulong target_addr)
3eb6b044 3876{
005eb2ae 3877 struct target_semid64_ds *target_sd;
3eb6b044 3878
579a97f7
FB
3879 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3880 return -TARGET_EFAULT;
e5289087
AJ
3881 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
3882 return -TARGET_EFAULT;
cbb21eed
MB
3883 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
3884 host_sd->sem_otime = tswapal(target_sd->sem_otime);
3885 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
3eb6b044 3886 unlock_user_struct(target_sd, target_addr, 0);
579a97f7 3887 return 0;
3eb6b044
TS
3888}
3889
579a97f7
FB
3890static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
3891 struct semid_ds *host_sd)
3eb6b044 3892{
005eb2ae 3893 struct target_semid64_ds *target_sd;
3eb6b044 3894
579a97f7
FB
3895 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3896 return -TARGET_EFAULT;
e5289087 3897 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
3a93113a 3898 return -TARGET_EFAULT;
cbb21eed
MB
3899 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
3900 target_sd->sem_otime = tswapal(host_sd->sem_otime);
3901 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
3eb6b044 3902 unlock_user_struct(target_sd, target_addr, 1);
579a97f7 3903 return 0;
3eb6b044
TS
3904}
3905
e5289087
AJ
3906struct target_seminfo {
3907 int semmap;
3908 int semmni;
3909 int semmns;
3910 int semmnu;
3911 int semmsl;
3912 int semopm;
3913 int semume;
3914 int semusz;
3915 int semvmx;
3916 int semaem;
3917};
3918
3919static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
3920 struct seminfo *host_seminfo)
3921{
3922 struct target_seminfo *target_seminfo;
3923 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
3924 return -TARGET_EFAULT;
3925 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
3926 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
3927 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
3928 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
3929 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
3930 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
3931 __put_user(host_seminfo->semume, &target_seminfo->semume);
3932 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
3933 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
3934 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
3935 unlock_user_struct(target_seminfo, target_addr, 1);
3936 return 0;
3937}
3938
fa294816
TS
3939union semun {
3940 int val;
3eb6b044 3941 struct semid_ds *buf;
fa294816 3942 unsigned short *array;
e5289087 3943 struct seminfo *__buf;
fa294816
TS
3944};
3945
3eb6b044
TS
3946union target_semun {
3947 int val;
e5289087
AJ
3948 abi_ulong buf;
3949 abi_ulong array;
3950 abi_ulong __buf;
3eb6b044
TS
3951};
3952
e5289087
AJ
3953static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
3954 abi_ulong target_addr)
3eb6b044 3955{
e5289087
AJ
3956 int nsems;
3957 unsigned short *array;
3958 union semun semun;
3959 struct semid_ds semid_ds;
3960 int i, ret;
3eb6b044 3961
e5289087
AJ
3962 semun.buf = &semid_ds;
3963
3964 ret = semctl(semid, 0, IPC_STAT, semun);
3965 if (ret == -1)
3966 return get_errno(ret);
3967
3968 nsems = semid_ds.sem_nsems;
3969
0e173b24 3970 *host_array = g_try_new(unsigned short, nsems);
69d4c703
PM
3971 if (!*host_array) {
3972 return -TARGET_ENOMEM;
3973 }
e5289087
AJ
3974 array = lock_user(VERIFY_READ, target_addr,
3975 nsems*sizeof(unsigned short), 1);
69d4c703 3976 if (!array) {
0e173b24 3977 g_free(*host_array);
e5289087 3978 return -TARGET_EFAULT;
69d4c703 3979 }
e5289087
AJ
3980
3981 for(i=0; i<nsems; i++) {
3982 __get_user((*host_array)[i], &array[i]);
3eb6b044 3983 }
e5289087
AJ
3984 unlock_user(array, target_addr, 0);
3985
579a97f7 3986 return 0;
3eb6b044
TS
3987}
3988
e5289087
AJ
3989static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
3990 unsigned short **host_array)
3eb6b044 3991{
e5289087
AJ
3992 int nsems;
3993 unsigned short *array;
3994 union semun semun;
3995 struct semid_ds semid_ds;
3996 int i, ret;
3eb6b044 3997
e5289087
AJ
3998 semun.buf = &semid_ds;
3999
4000 ret = semctl(semid, 0, IPC_STAT, semun);
4001 if (ret == -1)
4002 return get_errno(ret);
4003
4004 nsems = semid_ds.sem_nsems;
4005
4006 array = lock_user(VERIFY_WRITE, target_addr,
4007 nsems*sizeof(unsigned short), 0);
4008 if (!array)
4009 return -TARGET_EFAULT;
4010
4011 for(i=0; i<nsems; i++) {
4012 __put_user((*host_array)[i], &array[i]);
3eb6b044 4013 }
0e173b24 4014 g_free(*host_array);
e5289087
AJ
4015 unlock_user(array, target_addr, 1);
4016
579a97f7 4017 return 0;
3eb6b044
TS
4018}
4019
e5289087 4020static inline abi_long do_semctl(int semid, int semnum, int cmd,
d1c002b6 4021 abi_ulong target_arg)
3eb6b044 4022{
d1c002b6 4023 union target_semun target_su = { .buf = target_arg };
3eb6b044
TS
4024 union semun arg;
4025 struct semid_ds dsarg;
7b8118e8 4026 unsigned short *array = NULL;
e5289087
AJ
4027 struct seminfo seminfo;
4028 abi_long ret = -TARGET_EINVAL;
4029 abi_long err;
4030 cmd &= 0xff;
3eb6b044
TS
4031
4032 switch( cmd ) {
4033 case GETVAL:
3eb6b044 4034 case SETVAL:
5464baec
TM
4035 /* In 64 bit cross-endian situations, we will erroneously pick up
4036 * the wrong half of the union for the "val" element. To rectify
4037 * this, the entire 8-byte structure is byteswapped, followed by
4038 * a swap of the 4 byte val field. In other cases, the data is
4039 * already in proper host byte order. */
4040 if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
4041 target_su.buf = tswapal(target_su.buf);
4042 arg.val = tswap32(target_su.val);
4043 } else {
4044 arg.val = target_su.val;
4045 }
e5289087 4046 ret = get_errno(semctl(semid, semnum, cmd, arg));
3eb6b044
TS
4047 break;
4048 case GETALL:
3eb6b044 4049 case SETALL:
e5289087
AJ
4050 err = target_to_host_semarray(semid, &array, target_su.array);
4051 if (err)
4052 return err;
4053 arg.array = array;
4054 ret = get_errno(semctl(semid, semnum, cmd, arg));
4055 err = host_to_target_semarray(semid, target_su.array, &array);
4056 if (err)
4057 return err;
3eb6b044
TS
4058 break;
4059 case IPC_STAT:
3eb6b044 4060 case IPC_SET:
e5289087
AJ
4061 case SEM_STAT:
4062 err = target_to_host_semid_ds(&dsarg, target_su.buf);
4063 if (err)
4064 return err;
4065 arg.buf = &dsarg;
4066 ret = get_errno(semctl(semid, semnum, cmd, arg));
4067 err = host_to_target_semid_ds(target_su.buf, &dsarg);
4068 if (err)
4069 return err;
4070 break;
4071 case IPC_INFO:
4072 case SEM_INFO:
4073 arg.__buf = &seminfo;
4074 ret = get_errno(semctl(semid, semnum, cmd, arg));
4075 err = host_to_target_seminfo(target_su.__buf, &seminfo);
4076 if (err)
4077 return err;
4078 break;
4079 case IPC_RMID:
4080 case GETPID:
4081 case GETNCNT:
4082 case GETZCNT:
4083 ret = get_errno(semctl(semid, semnum, cmd, NULL));
3eb6b044 4084 break;
3eb6b044
TS
4085 }
4086
4087 return ret;
4088}
4089
e5289087
AJ
4090struct target_sembuf {
4091 unsigned short sem_num;
4092 short sem_op;
4093 short sem_flg;
4094};
4095
4096static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
4097 abi_ulong target_addr,
4098 unsigned nsops)
4099{
4100 struct target_sembuf *target_sembuf;
4101 int i;
4102
4103 target_sembuf = lock_user(VERIFY_READ, target_addr,
4104 nsops*sizeof(struct target_sembuf), 1);
4105 if (!target_sembuf)
4106 return -TARGET_EFAULT;
4107
4108 for(i=0; i<nsops; i++) {
4109 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
4110 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
4111 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
4112 }
4113
4114 unlock_user(target_sembuf, target_addr, 0);
4115
4116 return 0;
4117}
4118
d8c08b1e 4119#if defined(TARGET_NR_ipc) || defined(TARGET_NR_semop) || \
cac46eb0 4120 defined(TARGET_NR_semtimedop) || defined(TARGET_NR_semtimedop_time64)
d8c08b1e
MK
4121
4122/*
4123 * This macro is required to handle the s390 variants, which passes the
4124 * arguments in a different order than default.
4125 */
4126#ifdef __s390x__
4127#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
4128 (__nsops), (__timeout), (__sops)
4129#else
4130#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
4131 (__nsops), 0, (__sops), (__timeout)
4132#endif
4133
4134static inline abi_long do_semtimedop(int semid,
4135 abi_long ptr,
4136 unsigned nsops,
cac46eb0 4137 abi_long timeout, bool time64)
e5289087 4138{
0a7ec849 4139 struct sembuf *sops;
d8c08b1e 4140 struct timespec ts, *pts = NULL;
524fa340 4141 abi_long ret;
e5289087 4142
d8c08b1e
MK
4143 if (timeout) {
4144 pts = &ts;
cac46eb0
FB
4145 if (time64) {
4146 if (target_to_host_timespec64(pts, timeout)) {
4147 return -TARGET_EFAULT;
4148 }
4149 } else {
4150 if (target_to_host_timespec(pts, timeout)) {
4151 return -TARGET_EFAULT;
4152 }
d8c08b1e
MK
4153 }
4154 }
4155
0a7ec849
FB
4156 if (nsops > TARGET_SEMOPM) {
4157 return -TARGET_E2BIG;
4158 }
4159
4160 sops = g_new(struct sembuf, nsops);
4161
4162 if (target_to_host_sembuf(sops, ptr, nsops)) {
4163 g_free(sops);
e5289087 4164 return -TARGET_EFAULT;
0a7ec849 4165 }
e5289087 4166
524fa340
LV
4167 ret = -TARGET_ENOSYS;
4168#ifdef __NR_semtimedop
d8c08b1e 4169 ret = get_errno(safe_semtimedop(semid, sops, nsops, pts));
524fa340
LV
4170#endif
4171#ifdef __NR_ipc
4172 if (ret == -TARGET_ENOSYS) {
d8c08b1e
MK
4173 ret = get_errno(safe_ipc(IPCOP_semtimedop, semid,
4174 SEMTIMEDOP_IPC_ARGS(nsops, sops, (long)pts)));
524fa340
LV
4175 }
4176#endif
0a7ec849 4177 g_free(sops);
524fa340 4178 return ret;
e5289087 4179}
d8c08b1e 4180#endif
e5289087 4181
1bc012f6
TS
4182struct target_msqid_ds
4183{
1c54ff97
AJ
4184 struct target_ipc_perm msg_perm;
4185 abi_ulong msg_stime;
4186#if TARGET_ABI_BITS == 32
4187 abi_ulong __unused1;
4188#endif
4189 abi_ulong msg_rtime;
4190#if TARGET_ABI_BITS == 32
4191 abi_ulong __unused2;
4192#endif
4193 abi_ulong msg_ctime;
4194#if TARGET_ABI_BITS == 32
4195 abi_ulong __unused3;
4196#endif
4197 abi_ulong __msg_cbytes;
4198 abi_ulong msg_qnum;
4199 abi_ulong msg_qbytes;
4200 abi_ulong msg_lspid;
4201 abi_ulong msg_lrpid;
4202 abi_ulong __unused4;
4203 abi_ulong __unused5;
1bc012f6
TS
4204};
4205
579a97f7
FB
4206static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
4207 abi_ulong target_addr)
1bc012f6
TS
4208{
4209 struct target_msqid_ds *target_md;
4210
579a97f7
FB
4211 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
4212 return -TARGET_EFAULT;
1c54ff97
AJ
4213 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
4214 return -TARGET_EFAULT;
cbb21eed
MB
4215 host_md->msg_stime = tswapal(target_md->msg_stime);
4216 host_md->msg_rtime = tswapal(target_md->msg_rtime);
4217 host_md->msg_ctime = tswapal(target_md->msg_ctime);
4218 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
4219 host_md->msg_qnum = tswapal(target_md->msg_qnum);
4220 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
4221 host_md->msg_lspid = tswapal(target_md->msg_lspid);
4222 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
1bc012f6 4223 unlock_user_struct(target_md, target_addr, 0);
579a97f7 4224 return 0;
1bc012f6
TS
4225}
4226
579a97f7
FB
4227static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
4228 struct msqid_ds *host_md)
1bc012f6
TS
4229{
4230 struct target_msqid_ds *target_md;
4231
579a97f7
FB
4232 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
4233 return -TARGET_EFAULT;
1c54ff97
AJ
4234 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
4235 return -TARGET_EFAULT;
cbb21eed
MB
4236 target_md->msg_stime = tswapal(host_md->msg_stime);
4237 target_md->msg_rtime = tswapal(host_md->msg_rtime);
4238 target_md->msg_ctime = tswapal(host_md->msg_ctime);
4239 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
4240 target_md->msg_qnum = tswapal(host_md->msg_qnum);
4241 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
4242 target_md->msg_lspid = tswapal(host_md->msg_lspid);
4243 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
1bc012f6 4244 unlock_user_struct(target_md, target_addr, 1);
579a97f7 4245 return 0;
1bc012f6
TS
4246}
4247
1c54ff97
AJ
4248struct target_msginfo {
4249 int msgpool;
4250 int msgmap;
4251 int msgmax;
4252 int msgmnb;
4253 int msgmni;
4254 int msgssz;
4255 int msgtql;
4256 unsigned short int msgseg;
4257};
4258
4259static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
4260 struct msginfo *host_msginfo)
4261{
4262 struct target_msginfo *target_msginfo;
4263 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
4264 return -TARGET_EFAULT;
4265 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
4266 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
4267 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
4268 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
4269 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
4270 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
4271 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
4272 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
4273 unlock_user_struct(target_msginfo, target_addr, 1);
00b229ac 4274 return 0;
1c54ff97
AJ
4275}
4276
4277static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1bc012f6
TS
4278{
4279 struct msqid_ds dsarg;
1c54ff97
AJ
4280 struct msginfo msginfo;
4281 abi_long ret = -TARGET_EINVAL;
4282
4283 cmd &= 0xff;
4284
4285 switch (cmd) {
1bc012f6
TS
4286 case IPC_STAT:
4287 case IPC_SET:
1c54ff97
AJ
4288 case MSG_STAT:
4289 if (target_to_host_msqid_ds(&dsarg,ptr))
4290 return -TARGET_EFAULT;
4291 ret = get_errno(msgctl(msgid, cmd, &dsarg));
4292 if (host_to_target_msqid_ds(ptr,&dsarg))
4293 return -TARGET_EFAULT;
4294 break;
4295 case IPC_RMID:
4296 ret = get_errno(msgctl(msgid, cmd, NULL));
4297 break;
4298 case IPC_INFO:
4299 case MSG_INFO:
4300 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
4301 if (host_to_target_msginfo(ptr, &msginfo))
4302 return -TARGET_EFAULT;
4303 break;
1bc012f6 4304 }
1c54ff97 4305
1bc012f6
TS
4306 return ret;
4307}
4308
4309struct target_msgbuf {
1c54ff97
AJ
4310 abi_long mtype;
4311 char mtext[1];
1bc012f6
TS
4312};
4313
992f48a0 4314static inline abi_long do_msgsnd(int msqid, abi_long msgp,
edcc5f9d 4315 ssize_t msgsz, int msgflg)
1bc012f6
TS
4316{
4317 struct target_msgbuf *target_mb;
4318 struct msgbuf *host_mb;
992f48a0 4319 abi_long ret = 0;
1bc012f6 4320
edcc5f9d
TM
4321 if (msgsz < 0) {
4322 return -TARGET_EINVAL;
4323 }
4324
579a97f7
FB
4325 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
4326 return -TARGET_EFAULT;
0e173b24 4327 host_mb = g_try_malloc(msgsz + sizeof(long));
29e03fcb
HZ
4328 if (!host_mb) {
4329 unlock_user_struct(target_mb, msgp, 0);
4330 return -TARGET_ENOMEM;
4331 }
cbb21eed 4332 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
1c54ff97 4333 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
524fa340
LV
4334 ret = -TARGET_ENOSYS;
4335#ifdef __NR_msgsnd
89f9fe44 4336 ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
524fa340
LV
4337#endif
4338#ifdef __NR_ipc
4339 if (ret == -TARGET_ENOSYS) {
d8c08b1e
MK
4340#ifdef __s390x__
4341 ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
4342 host_mb));
4343#else
524fa340
LV
4344 ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
4345 host_mb, 0));
d8c08b1e 4346#endif
524fa340
LV
4347 }
4348#endif
0e173b24 4349 g_free(host_mb);
1bc012f6
TS
4350 unlock_user_struct(target_mb, msgp, 0);
4351
4352 return ret;
4353}
4354
d8c08b1e
MK
4355#ifdef __NR_ipc
4356#if defined(__sparc__)
4357/* SPARC for msgrcv it does not use the kludge on final 2 arguments. */
4358#define MSGRCV_ARGS(__msgp, __msgtyp) __msgp, __msgtyp
4359#elif defined(__s390x__)
4360/* The s390 sys_ipc variant has only five parameters. */
4361#define MSGRCV_ARGS(__msgp, __msgtyp) \
4362 ((long int[]){(long int)__msgp, __msgtyp})
4363#else
4364#define MSGRCV_ARGS(__msgp, __msgtyp) \
4365 ((long int[]){(long int)__msgp, __msgtyp}), 0
4366#endif
4367#endif
4368
992f48a0 4369static inline abi_long do_msgrcv(int msqid, abi_long msgp,
99874f65 4370 ssize_t msgsz, abi_long msgtyp,
992f48a0 4371 int msgflg)
1bc012f6
TS
4372{
4373 struct target_msgbuf *target_mb;
579a97f7 4374 char *target_mtext;
1bc012f6 4375 struct msgbuf *host_mb;
992f48a0 4376 abi_long ret = 0;
1bc012f6 4377
99874f65
PM
4378 if (msgsz < 0) {
4379 return -TARGET_EINVAL;
4380 }
4381
579a97f7
FB
4382 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
4383 return -TARGET_EFAULT;
1c54ff97 4384
415d8471
PM
4385 host_mb = g_try_malloc(msgsz + sizeof(long));
4386 if (!host_mb) {
4387 ret = -TARGET_ENOMEM;
4388 goto end;
4389 }
524fa340
LV
4390 ret = -TARGET_ENOSYS;
4391#ifdef __NR_msgrcv
89f9fe44 4392 ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
524fa340
LV
4393#endif
4394#ifdef __NR_ipc
4395 if (ret == -TARGET_ENOSYS) {
4396 ret = get_errno(safe_ipc(IPCOP_CALL(1, IPCOP_msgrcv), msqid, msgsz,
d8c08b1e 4397 msgflg, MSGRCV_ARGS(host_mb, msgtyp)));
524fa340
LV
4398 }
4399#endif
1c54ff97 4400
579a97f7
FB
4401 if (ret > 0) {
4402 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
4403 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
4404 if (!target_mtext) {
4405 ret = -TARGET_EFAULT;
4406 goto end;
4407 }
1c54ff97 4408 memcpy(target_mb->mtext, host_mb->mtext, ret);
579a97f7
FB
4409 unlock_user(target_mtext, target_mtext_addr, ret);
4410 }
1c54ff97 4411
cbb21eed 4412 target_mb->mtype = tswapal(host_mb->mtype);
1bc012f6 4413
579a97f7
FB
4414end:
4415 if (target_mb)
4416 unlock_user_struct(target_mb, msgp, 1);
0d07fe47 4417 g_free(host_mb);
1bc012f6
TS
4418 return ret;
4419}
4420
88a8c984
RV
4421static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
4422 abi_ulong target_addr)
4423{
4424 struct target_shmid_ds *target_sd;
4425
4426 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
4427 return -TARGET_EFAULT;
4428 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
4429 return -TARGET_EFAULT;
4430 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
4431 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
4432 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
4433 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
4434 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
4435 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
4436 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
4437 unlock_user_struct(target_sd, target_addr, 0);
4438 return 0;
4439}
4440
4441static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
4442 struct shmid_ds *host_sd)
4443{
4444 struct target_shmid_ds *target_sd;
4445
4446 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
4447 return -TARGET_EFAULT;
4448 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
4449 return -TARGET_EFAULT;
4450 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
4451 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
4452 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
4453 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
4454 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
4455 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
4456 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
4457 unlock_user_struct(target_sd, target_addr, 1);
4458 return 0;
4459}
4460
4461struct target_shminfo {
4462 abi_ulong shmmax;
4463 abi_ulong shmmin;
4464 abi_ulong shmmni;
4465 abi_ulong shmseg;
4466 abi_ulong shmall;
4467};
4468
4469static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
4470 struct shminfo *host_shminfo)
4471{
4472 struct target_shminfo *target_shminfo;
4473 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
4474 return -TARGET_EFAULT;
4475 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
4476 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
4477 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
4478 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
4479 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
4480 unlock_user_struct(target_shminfo, target_addr, 1);
4481 return 0;
4482}
4483
4484struct target_shm_info {
4485 int used_ids;
4486 abi_ulong shm_tot;
4487 abi_ulong shm_rss;
4488 abi_ulong shm_swp;
4489 abi_ulong swap_attempts;
4490 abi_ulong swap_successes;
4491};
4492
4493static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
4494 struct shm_info *host_shm_info)
4495{
4496 struct target_shm_info *target_shm_info;
4497 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
4498 return -TARGET_EFAULT;
4499 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
4500 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
4501 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
4502 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
4503 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
4504 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
4505 unlock_user_struct(target_shm_info, target_addr, 1);
4506 return 0;
4507}
4508
4509static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
4510{
4511 struct shmid_ds dsarg;
4512 struct shminfo shminfo;
4513 struct shm_info shm_info;
4514 abi_long ret = -TARGET_EINVAL;
4515
4516 cmd &= 0xff;
4517
4518 switch(cmd) {
4519 case IPC_STAT:
4520 case IPC_SET:
4521 case SHM_STAT:
4522 if (target_to_host_shmid_ds(&dsarg, buf))
4523 return -TARGET_EFAULT;
4524 ret = get_errno(shmctl(shmid, cmd, &dsarg));
4525 if (host_to_target_shmid_ds(buf, &dsarg))
4526 return -TARGET_EFAULT;
4527 break;
4528 case IPC_INFO:
4529 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
4530 if (host_to_target_shminfo(buf, &shminfo))
4531 return -TARGET_EFAULT;
4532 break;
4533 case SHM_INFO:
4534 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
4535 if (host_to_target_shm_info(buf, &shm_info))
4536 return -TARGET_EFAULT;
4537 break;
4538 case IPC_RMID:
4539 case SHM_LOCK:
4540 case SHM_UNLOCK:
4541 ret = get_errno(shmctl(shmid, cmd, NULL));
4542 break;
4543 }
4544
4545 return ret;
4546}
4547
ee8e7614
PM
4548#ifndef TARGET_FORCE_SHMLBA
4549/* For most architectures, SHMLBA is the same as the page size;
4550 * some architectures have larger values, in which case they should
4551 * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
4552 * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
4553 * and defining its own value for SHMLBA.
4554 *
4555 * The kernel also permits SHMLBA to be set by the architecture to a
4556 * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
4557 * this means that addresses are rounded to the large size if
4558 * SHM_RND is set but addresses not aligned to that size are not rejected
4559 * as long as they are at least page-aligned. Since the only architecture
4560 * which uses this is ia64 this code doesn't provide for that oddity.
4561 */
4562static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
4563{
4564 return TARGET_PAGE_SIZE;
4565}
4566#endif
4567
4568static inline abi_ulong do_shmat(CPUArchState *cpu_env,
4569 int shmid, abi_ulong shmaddr, int shmflg)
88a8c984
RV
4570{
4571 abi_long raddr;
4572 void *host_raddr;
4573 struct shmid_ds shm_info;
4574 int i,ret;
ee8e7614 4575 abi_ulong shmlba;
88a8c984
RV
4576
4577 /* find out the length of the shared memory segment */
4578 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
4579 if (is_error(ret)) {
4580 /* can't get length, bail out */
4581 return ret;
4582 }
4583
ee8e7614
PM
4584 shmlba = target_shmlba(cpu_env);
4585
4586 if (shmaddr & (shmlba - 1)) {
4587 if (shmflg & SHM_RND) {
4588 shmaddr &= ~(shmlba - 1);
4589 } else {
4590 return -TARGET_EINVAL;
4591 }
4592 }
ebf9a363
MF
4593 if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) {
4594 return -TARGET_EINVAL;
4595 }
ee8e7614 4596
88a8c984
RV
4597 mmap_lock();
4598
4599 if (shmaddr)
4600 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
4601 else {
4602 abi_ulong mmap_start;
4603
30ab9ef2
RH
4604 /* In order to use the host shmat, we need to honor host SHMLBA. */
4605 mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
88a8c984
RV
4606
4607 if (mmap_start == -1) {
4608 errno = ENOMEM;
4609 host_raddr = (void *)-1;
4610 } else
4611 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
4612 }
4613
4614 if (host_raddr == (void *)-1) {
4615 mmap_unlock();
4616 return get_errno((long)host_raddr);
4617 }
4618 raddr=h2g((unsigned long)host_raddr);
4619
4620 page_set_flags(raddr, raddr + shm_info.shm_segsz,
4621 PAGE_VALID | PAGE_READ |
4622 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
4623
4624 for (i = 0; i < N_SHM_REGIONS; i++) {
b6e17875
PM
4625 if (!shm_regions[i].in_use) {
4626 shm_regions[i].in_use = true;
88a8c984
RV
4627 shm_regions[i].start = raddr;
4628 shm_regions[i].size = shm_info.shm_segsz;
4629 break;
4630 }
4631 }
4632
4633 mmap_unlock();
4634 return raddr;
4635
4636}
4637
4638static inline abi_long do_shmdt(abi_ulong shmaddr)
4639{
4640 int i;
3c5f6a5f
MF
4641 abi_long rv;
4642
4643 mmap_lock();
88a8c984
RV
4644
4645 for (i = 0; i < N_SHM_REGIONS; ++i) {
b6e17875
PM
4646 if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
4647 shm_regions[i].in_use = false;
e00ac249 4648 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
88a8c984
RV
4649 break;
4650 }
4651 }
3c5f6a5f 4652 rv = get_errno(shmdt(g2h(shmaddr)));
88a8c984 4653
3c5f6a5f 4654 mmap_unlock();
88a8c984 4655
3c5f6a5f 4656 return rv;
88a8c984
RV
4657}
4658
1c54ff97 4659#ifdef TARGET_NR_ipc
53a5960a 4660/* ??? This only works with linear mappings. */
0da46a6e 4661/* do_ipc() must return target values and target errnos. */
ee8e7614
PM
4662static abi_long do_ipc(CPUArchState *cpu_env,
4663 unsigned int call, abi_long first,
37ed0956 4664 abi_long second, abi_long third,
992f48a0 4665 abi_long ptr, abi_long fifth)
8853f86e
FB
4666{
4667 int version;
992f48a0 4668 abi_long ret = 0;
8853f86e
FB
4669
4670 version = call >> 16;
4671 call &= 0xffff;
4672
4673 switch (call) {
fa294816 4674 case IPCOP_semop:
cac46eb0 4675 ret = do_semtimedop(first, ptr, second, 0, false);
d8c08b1e
MK
4676 break;
4677 case IPCOP_semtimedop:
4678 /*
4679 * The s390 sys_ipc variant has only five parameters instead of six
4680 * (as for default variant) and the only difference is the handling of
4681 * SEMTIMEDOP where on s390 the third parameter is used as a pointer
4682 * to a struct timespec where the generic variant uses fifth parameter.
4683 */
4684#if defined(TARGET_S390X)
cac46eb0 4685 ret = do_semtimedop(first, ptr, second, third, TARGET_ABI_BITS == 64);
d8c08b1e 4686#else
cac46eb0 4687 ret = do_semtimedop(first, ptr, second, fifth, TARGET_ABI_BITS == 64);
d8c08b1e 4688#endif
fa294816
TS
4689 break;
4690
4691 case IPCOP_semget:
4692 ret = get_errno(semget(first, second, third));
4693 break;
4694
5d2fa8eb
TM
4695 case IPCOP_semctl: {
4696 /* The semun argument to semctl is passed by value, so dereference the
4697 * ptr argument. */
4698 abi_ulong atptr;
37ed0956 4699 get_user_ual(atptr, ptr);
d1c002b6 4700 ret = do_semctl(first, second, third, atptr);
fa294816 4701 break;
5d2fa8eb 4702 }
d96372ef 4703
1c54ff97
AJ
4704 case IPCOP_msgget:
4705 ret = get_errno(msgget(first, second));
4706 break;
d96372ef 4707
1c54ff97
AJ
4708 case IPCOP_msgsnd:
4709 ret = do_msgsnd(first, ptr, second, third);
4710 break;
d96372ef 4711
1c54ff97
AJ
4712 case IPCOP_msgctl:
4713 ret = do_msgctl(first, second, ptr);
4714 break;
d96372ef 4715
1c54ff97
AJ
4716 case IPCOP_msgrcv:
4717 switch (version) {
4718 case 0:
4719 {
4720 struct target_ipc_kludge {
4721 abi_long msgp;
4722 abi_long msgtyp;
4723 } *tmp;
4724
4725 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
4726 ret = -TARGET_EFAULT;
4727 break;
4728 }
d96372ef 4729
79dd77de 4730 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
d96372ef 4731
1c54ff97
AJ
4732 unlock_user_struct(tmp, ptr, 0);
4733 break;
4734 }
4735 default:
4736 ret = do_msgrcv(first, ptr, second, fifth, third);
4737 }
4738 break;
d96372ef 4739
8853f86e 4740 case IPCOP_shmat:
88a8c984
RV
4741 switch (version) {
4742 default:
5a4a898d
FB
4743 {
4744 abi_ulong raddr;
ee8e7614 4745 raddr = do_shmat(cpu_env, first, ptr, second);
88a8c984
RV
4746 if (is_error(raddr))
4747 return get_errno(raddr);
2f619698 4748 if (put_user_ual(raddr, third))
5a4a898d 4749 return -TARGET_EFAULT;
88a8c984
RV
4750 break;
4751 }
4752 case 1:
4753 ret = -TARGET_EINVAL;
4754 break;
5a4a898d 4755 }
8853f86e
FB
4756 break;
4757 case IPCOP_shmdt:
88a8c984 4758 ret = do_shmdt(ptr);
8853f86e
FB
4759 break;
4760
4761 case IPCOP_shmget:
4762 /* IPC_* flag values are the same on all linux platforms */
4763 ret = get_errno(shmget(first, second, third));
4764 break;
4765
4766 /* IPC_* and SHM_* command values are the same on all linux platforms */
4767 case IPCOP_shmctl:
a2926784 4768 ret = do_shmctl(first, second, ptr);
8853f86e
FB
4769 break;
4770 default:
39be5350
JK
4771 qemu_log_mask(LOG_UNIMP, "Unsupported ipc call: %d (version %d)\n",
4772 call, version);
0da46a6e 4773 ret = -TARGET_ENOSYS;
8853f86e
FB
4774 break;
4775 }
4776 return ret;
4777}
32407103 4778#endif
8853f86e 4779
31e31b8a 4780/* kernel structure types definitions */
31e31b8a 4781
001faf32 4782#define STRUCT(name, ...) STRUCT_ ## name,
31e31b8a
FB
4783#define STRUCT_SPECIAL(name) STRUCT_ ## name,
4784enum {
4785#include "syscall_types.h"
8be656b8 4786STRUCT_MAX
31e31b8a
FB
4787};
4788#undef STRUCT
4789#undef STRUCT_SPECIAL
4790
001faf32 4791#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
31e31b8a
FB
4792#define STRUCT_SPECIAL(name)
4793#include "syscall_types.h"
4794#undef STRUCT
4795#undef STRUCT_SPECIAL
4796
31e31b8a
FB
4797#define MAX_STRUCT_SIZE 4096
4798
dace20dc 4799#ifdef CONFIG_FIEMAP
285da2b9
PM
4800/* So fiemap access checks don't overflow on 32 bit systems.
4801 * This is very slightly smaller than the limit imposed by
4802 * the underlying kernel.
4803 */
4804#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
4805 / sizeof(struct fiemap_extent))
4806
4807static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 4808 int fd, int cmd, abi_long arg)
285da2b9
PM
4809{
4810 /* The parameter for this ioctl is a struct fiemap followed
4811 * by an array of struct fiemap_extent whose size is set
4812 * in fiemap->fm_extent_count. The array is filled in by the
4813 * ioctl.
4814 */
4815 int target_size_in, target_size_out;
4816 struct fiemap *fm;
4817 const argtype *arg_type = ie->arg_type;
4818 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
4819 void *argptr, *p;
4820 abi_long ret;
4821 int i, extent_size = thunk_type_size(extent_arg_type, 0);
4822 uint32_t outbufsz;
4823 int free_fm = 0;
4824
4825 assert(arg_type[0] == TYPE_PTR);
4826 assert(ie->access == IOC_RW);
4827 arg_type++;
4828 target_size_in = thunk_type_size(arg_type, 0);
4829 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
4830 if (!argptr) {
4831 return -TARGET_EFAULT;
4832 }
4833 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4834 unlock_user(argptr, arg, 0);
4835 fm = (struct fiemap *)buf_temp;
4836 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
4837 return -TARGET_EINVAL;
4838 }
4839
4840 outbufsz = sizeof (*fm) +
4841 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
4842
4843 if (outbufsz > MAX_STRUCT_SIZE) {
4844 /* We can't fit all the extents into the fixed size buffer.
4845 * Allocate one that is large enough and use it instead.
4846 */
0e173b24 4847 fm = g_try_malloc(outbufsz);
285da2b9
PM
4848 if (!fm) {
4849 return -TARGET_ENOMEM;
4850 }
4851 memcpy(fm, buf_temp, sizeof(struct fiemap));
4852 free_fm = 1;
4853 }
49ca6f3e 4854 ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm));
285da2b9
PM
4855 if (!is_error(ret)) {
4856 target_size_out = target_size_in;
4857 /* An extent_count of 0 means we were only counting the extents
4858 * so there are no structs to copy
4859 */
4860 if (fm->fm_extent_count != 0) {
4861 target_size_out += fm->fm_mapped_extents * extent_size;
4862 }
4863 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
4864 if (!argptr) {
4865 ret = -TARGET_EFAULT;
4866 } else {
4867 /* Convert the struct fiemap */
4868 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
4869 if (fm->fm_extent_count != 0) {
4870 p = argptr + target_size_in;
4871 /* ...and then all the struct fiemap_extents */
4872 for (i = 0; i < fm->fm_mapped_extents; i++) {
4873 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
4874 THUNK_TARGET);
4875 p += extent_size;
4876 }
4877 }
4878 unlock_user(argptr, arg, target_size_out);
4879 }
4880 }
4881 if (free_fm) {
0e173b24 4882 g_free(fm);
285da2b9
PM
4883 }
4884 return ret;
4885}
dace20dc 4886#endif
285da2b9 4887
059c2f2c 4888static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 4889 int fd, int cmd, abi_long arg)
059c2f2c
LV
4890{
4891 const argtype *arg_type = ie->arg_type;
4892 int target_size;
4893 void *argptr;
4894 int ret;
4895 struct ifconf *host_ifconf;
4896 uint32_t outbufsz;
4897 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
4898 int target_ifreq_size;
4899 int nb_ifreq;
4900 int free_buf = 0;
4901 int i;
4902 int target_ifc_len;
4903 abi_long target_ifc_buf;
4904 int host_ifc_len;
4905 char *host_ifc_buf;
4906
4907 assert(arg_type[0] == TYPE_PTR);
4908 assert(ie->access == IOC_RW);
4909
4910 arg_type++;
4911 target_size = thunk_type_size(arg_type, 0);
4912
4913 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4914 if (!argptr)
4915 return -TARGET_EFAULT;
4916 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4917 unlock_user(argptr, arg, 0);
4918
4919 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
059c2f2c 4920 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
059c2f2c 4921 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
059c2f2c 4922
22e4a267
KL
4923 if (target_ifc_buf != 0) {
4924 target_ifc_len = host_ifconf->ifc_len;
4925 nb_ifreq = target_ifc_len / target_ifreq_size;
4926 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
4927
4928 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
4929 if (outbufsz > MAX_STRUCT_SIZE) {
4930 /*
4931 * We can't fit all the extents into the fixed size buffer.
4932 * Allocate one that is large enough and use it instead.
4933 */
4934 host_ifconf = malloc(outbufsz);
4935 if (!host_ifconf) {
4936 return -TARGET_ENOMEM;
4937 }
4938 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
4939 free_buf = 1;
059c2f2c 4940 }
22e4a267 4941 host_ifc_buf = (char *)host_ifconf + sizeof(*host_ifconf);
059c2f2c 4942
22e4a267
KL
4943 host_ifconf->ifc_len = host_ifc_len;
4944 } else {
4945 host_ifc_buf = NULL;
4946 }
059c2f2c
LV
4947 host_ifconf->ifc_buf = host_ifc_buf;
4948
49ca6f3e 4949 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
059c2f2c
LV
4950 if (!is_error(ret)) {
4951 /* convert host ifc_len to target ifc_len */
4952
4953 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
4954 target_ifc_len = nb_ifreq * target_ifreq_size;
4955 host_ifconf->ifc_len = target_ifc_len;
4956
4957 /* restore target ifc_buf */
4958
4959 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
4960
4961 /* copy struct ifconf to target user */
4962
4963 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4964 if (!argptr)
4965 return -TARGET_EFAULT;
4966 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
4967 unlock_user(argptr, arg, target_size);
4968
22e4a267
KL
4969 if (target_ifc_buf != 0) {
4970 /* copy ifreq[] to target user */
4971 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
4972 for (i = 0; i < nb_ifreq ; i++) {
4973 thunk_convert(argptr + i * target_ifreq_size,
4974 host_ifc_buf + i * sizeof(struct ifreq),
4975 ifreq_arg_type, THUNK_TARGET);
4976 }
4977 unlock_user(argptr, target_ifc_buf, target_ifc_len);
059c2f2c 4978 }
059c2f2c
LV
4979 }
4980
4981 if (free_buf) {
4982 free(host_ifconf);
4983 }
4984
4985 return ret;
4986}
4987
a133367e
CT
4988#if defined(CONFIG_USBFS)
4989#if HOST_LONG_BITS > 64
4990#error USBDEVFS thunks do not support >64 bit hosts yet.
4991#endif
4992struct live_urb {
4993 uint64_t target_urb_adr;
4994 uint64_t target_buf_adr;
4995 char *target_buf_ptr;
4996 struct usbdevfs_urb host_urb;
4997};
4998
4999static GHashTable *usbdevfs_urb_hashtable(void)
5000{
5001 static GHashTable *urb_hashtable;
5002
5003 if (!urb_hashtable) {
5004 urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal);
5005 }
5006 return urb_hashtable;
5007}
5008
5009static void urb_hashtable_insert(struct live_urb *urb)
5010{
5011 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
5012 g_hash_table_insert(urb_hashtable, urb, urb);
5013}
5014
5015static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr)
5016{
5017 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
5018 return g_hash_table_lookup(urb_hashtable, &target_urb_adr);
5019}
5020
5021static void urb_hashtable_remove(struct live_urb *urb)
5022{
5023 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
5024 g_hash_table_remove(urb_hashtable, urb);
5025}
5026
5027static abi_long
5028do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp,
5029 int fd, int cmd, abi_long arg)
5030{
5031 const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) };
5032 const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 };
5033 struct live_urb *lurb;
5034 void *argptr;
5035 uint64_t hurb;
5036 int target_size;
5037 uintptr_t target_urb_adr;
5038 abi_long ret;
5039
5040 target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET);
5041
5042 memset(buf_temp, 0, sizeof(uint64_t));
5043 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
5044 if (is_error(ret)) {
5045 return ret;
5046 }
5047
5048 memcpy(&hurb, buf_temp, sizeof(uint64_t));
5049 lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb));
5050 if (!lurb->target_urb_adr) {
5051 return -TARGET_EFAULT;
5052 }
5053 urb_hashtable_remove(lurb);
5054 unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr,
5055 lurb->host_urb.buffer_length);
5056 lurb->target_buf_ptr = NULL;
5057
5058 /* restore the guest buffer pointer */
5059 lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr;
5060
5061 /* update the guest urb struct */
5062 argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0);
5063 if (!argptr) {
5064 g_free(lurb);
5065 return -TARGET_EFAULT;
5066 }
5067 thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET);
5068 unlock_user(argptr, lurb->target_urb_adr, target_size);
5069
5070 target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET);
5071 /* write back the urb handle */
5072 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5073 if (!argptr) {
5074 g_free(lurb);
5075 return -TARGET_EFAULT;
5076 }
5077
5078 /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */
5079 target_urb_adr = lurb->target_urb_adr;
5080 thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET);
5081 unlock_user(argptr, arg, target_size);
5082
5083 g_free(lurb);
5084 return ret;
5085}
5086
5087static abi_long
5088do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie,
5089 uint8_t *buf_temp __attribute__((unused)),
5090 int fd, int cmd, abi_long arg)
5091{
5092 struct live_urb *lurb;
5093
5094 /* map target address back to host URB with metadata. */
5095 lurb = urb_hashtable_lookup(arg);
5096 if (!lurb) {
5097 return -TARGET_EFAULT;
5098 }
5099 return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
5100}
5101
5102static abi_long
5103do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp,
5104 int fd, int cmd, abi_long arg)
5105{
5106 const argtype *arg_type = ie->arg_type;
5107 int target_size;
5108 abi_long ret;
5109 void *argptr;
5110 int rw_dir;
5111 struct live_urb *lurb;
5112
5113 /*
5114 * each submitted URB needs to map to a unique ID for the
5115 * kernel, and that unique ID needs to be a pointer to
5116 * host memory. hence, we need to malloc for each URB.
5117 * isochronous transfers have a variable length struct.
5118 */
5119 arg_type++;
5120 target_size = thunk_type_size(arg_type, THUNK_TARGET);
5121
5122 /* construct host copy of urb and metadata */
5123 lurb = g_try_malloc0(sizeof(struct live_urb));
5124 if (!lurb) {
5125 return -TARGET_ENOMEM;
5126 }
5127
5128 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5129 if (!argptr) {
5130 g_free(lurb);
5131 return -TARGET_EFAULT;
5132 }
5133 thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST);
5134 unlock_user(argptr, arg, 0);
5135
5136 lurb->target_urb_adr = arg;
5137 lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer;
5138
5139 /* buffer space used depends on endpoint type so lock the entire buffer */
5140 /* control type urbs should check the buffer contents for true direction */
5141 rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ;
5142 lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr,
5143 lurb->host_urb.buffer_length, 1);
5144 if (lurb->target_buf_ptr == NULL) {
5145 g_free(lurb);
5146 return -TARGET_EFAULT;
5147 }
5148
5149 /* update buffer pointer in host copy */
5150 lurb->host_urb.buffer = lurb->target_buf_ptr;
5151
5152 ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
5153 if (is_error(ret)) {
5154 unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0);
5155 g_free(lurb);
5156 } else {
5157 urb_hashtable_insert(lurb);
5158 }
5159
5160 return ret;
5161}
5162#endif /* CONFIG_USBFS */
5163
56e904ec 5164static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
45c874eb 5165 int cmd, abi_long arg)
56e904ec
AG
5166{
5167 void *argptr;
5168 struct dm_ioctl *host_dm;
5169 abi_long guest_data;
5170 uint32_t guest_data_size;
5171 int target_size;
5172 const argtype *arg_type = ie->arg_type;
5173 abi_long ret;
5174 void *big_buf = NULL;
5175 char *host_data;
5176
5177 arg_type++;
5178 target_size = thunk_type_size(arg_type, 0);
5179 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5180 if (!argptr) {
5181 ret = -TARGET_EFAULT;
5182 goto out;
5183 }
5184 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5185 unlock_user(argptr, arg, 0);
5186
5187 /* buf_temp is too small, so fetch things into a bigger buffer */
5188 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
5189 memcpy(big_buf, buf_temp, target_size);
5190 buf_temp = big_buf;
5191 host_dm = big_buf;
5192
5193 guest_data = arg + host_dm->data_start;
5194 if ((guest_data - arg) < 0) {
f9757b1d 5195 ret = -TARGET_EINVAL;
56e904ec
AG
5196 goto out;
5197 }
5198 guest_data_size = host_dm->data_size - host_dm->data_start;
5199 host_data = (char*)host_dm + host_dm->data_start;
5200
5201 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3211215e
PM
5202 if (!argptr) {
5203 ret = -TARGET_EFAULT;
5204 goto out;
5205 }
5206
56e904ec
AG
5207 switch (ie->host_cmd) {
5208 case DM_REMOVE_ALL:
5209 case DM_LIST_DEVICES:
5210 case DM_DEV_CREATE:
5211 case DM_DEV_REMOVE:
5212 case DM_DEV_SUSPEND:
5213 case DM_DEV_STATUS:
5214 case DM_DEV_WAIT:
5215 case DM_TABLE_STATUS:
5216 case DM_TABLE_CLEAR:
5217 case DM_TABLE_DEPS:
5218 case DM_LIST_VERSIONS:
5219 /* no input data */
5220 break;
5221 case DM_DEV_RENAME:
5222 case DM_DEV_SET_GEOMETRY:
5223 /* data contains only strings */
5224 memcpy(host_data, argptr, guest_data_size);
5225 break;
5226 case DM_TARGET_MSG:
5227 memcpy(host_data, argptr, guest_data_size);
5228 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
5229 break;
5230 case DM_TABLE_LOAD:
5231 {
5232 void *gspec = argptr;
5233 void *cur_data = host_data;
5234 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
5235 int spec_size = thunk_type_size(arg_type, 0);
5236 int i;
5237
5238 for (i = 0; i < host_dm->target_count; i++) {
5239 struct dm_target_spec *spec = cur_data;
5240 uint32_t next;
5241 int slen;
5242
5243 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
5244 slen = strlen((char*)gspec + spec_size) + 1;
5245 next = spec->next;
5246 spec->next = sizeof(*spec) + slen;
5247 strcpy((char*)&spec[1], gspec + spec_size);
5248 gspec += next;
5249 cur_data += spec->next;
5250 }
5251 break;
5252 }
5253 default:
5254 ret = -TARGET_EINVAL;
dec0473d 5255 unlock_user(argptr, guest_data, 0);
56e904ec
AG
5256 goto out;
5257 }
5258 unlock_user(argptr, guest_data, 0);
5259
49ca6f3e 5260 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
56e904ec
AG
5261 if (!is_error(ret)) {
5262 guest_data = arg + host_dm->data_start;
5263 guest_data_size = host_dm->data_size - host_dm->data_start;
5264 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
5265 switch (ie->host_cmd) {
5266 case DM_REMOVE_ALL:
5267 case DM_DEV_CREATE:
5268 case DM_DEV_REMOVE:
5269 case DM_DEV_RENAME:
5270 case DM_DEV_SUSPEND:
5271 case DM_DEV_STATUS:
5272 case DM_TABLE_LOAD:
5273 case DM_TABLE_CLEAR:
5274 case DM_TARGET_MSG:
5275 case DM_DEV_SET_GEOMETRY:
5276 /* no return data */
5277 break;
5278 case DM_LIST_DEVICES:
5279 {
5280 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
5281 uint32_t remaining_data = guest_data_size;
5282 void *cur_data = argptr;
5283 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
5284 int nl_size = 12; /* can't use thunk_size due to alignment */
5285
5286 while (1) {
5287 uint32_t next = nl->next;
5288 if (next) {
5289 nl->next = nl_size + (strlen(nl->name) + 1);
5290 }
5291 if (remaining_data < nl->next) {
5292 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5293 break;
5294 }
5295 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
5296 strcpy(cur_data + nl_size, nl->name);
5297 cur_data += nl->next;
5298 remaining_data -= nl->next;
5299 if (!next) {
5300 break;
5301 }
5302 nl = (void*)nl + next;
5303 }
5304 break;
5305 }
5306 case DM_DEV_WAIT:
5307 case DM_TABLE_STATUS:
5308 {
5309 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
5310 void *cur_data = argptr;
5311 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
5312 int spec_size = thunk_type_size(arg_type, 0);
5313 int i;
5314
5315 for (i = 0; i < host_dm->target_count; i++) {
5316 uint32_t next = spec->next;
5317 int slen = strlen((char*)&spec[1]) + 1;
5318 spec->next = (cur_data - argptr) + spec_size + slen;
5319 if (guest_data_size < spec->next) {
5320 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5321 break;
5322 }
5323 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
5324 strcpy(cur_data + spec_size, (char*)&spec[1]);
5325 cur_data = argptr + spec->next;
5326 spec = (void*)host_dm + host_dm->data_start + next;
5327 }
5328 break;
5329 }
5330 case DM_TABLE_DEPS:
5331 {
5332 void *hdata = (void*)host_dm + host_dm->data_start;
5333 int count = *(uint32_t*)hdata;
5334 uint64_t *hdev = hdata + 8;
5335 uint64_t *gdev = argptr + 8;
5336 int i;
5337
5338 *(uint32_t*)argptr = tswap32(count);
5339 for (i = 0; i < count; i++) {
5340 *gdev = tswap64(*hdev);
5341 gdev++;
5342 hdev++;
5343 }
5344 break;
5345 }
5346 case DM_LIST_VERSIONS:
5347 {
5348 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
5349 uint32_t remaining_data = guest_data_size;
5350 void *cur_data = argptr;
5351 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
5352 int vers_size = thunk_type_size(arg_type, 0);
5353
5354 while (1) {
5355 uint32_t next = vers->next;
5356 if (next) {
5357 vers->next = vers_size + (strlen(vers->name) + 1);
5358 }
5359 if (remaining_data < vers->next) {
5360 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5361 break;
5362 }
5363 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
5364 strcpy(cur_data + vers_size, vers->name);
5365 cur_data += vers->next;
5366 remaining_data -= vers->next;
5367 if (!next) {
5368 break;
5369 }
5370 vers = (void*)vers + next;
5371 }
5372 break;
5373 }
5374 default:
dec0473d 5375 unlock_user(argptr, guest_data, 0);
56e904ec
AG
5376 ret = -TARGET_EINVAL;
5377 goto out;
5378 }
5379 unlock_user(argptr, guest_data, guest_data_size);
5380
5381 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5382 if (!argptr) {
5383 ret = -TARGET_EFAULT;
5384 goto out;
5385 }
5386 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5387 unlock_user(argptr, arg, target_size);
5388 }
5389out:
ad11ad77 5390 g_free(big_buf);
56e904ec
AG
5391 return ret;
5392}
5393
a59b5e35 5394static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
45c874eb 5395 int cmd, abi_long arg)
a59b5e35
AG
5396{
5397 void *argptr;
5398 int target_size;
5399 const argtype *arg_type = ie->arg_type;
5400 const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
5401 abi_long ret;
5402
5403 struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
5404 struct blkpg_partition host_part;
5405
5406 /* Read and convert blkpg */
5407 arg_type++;
5408 target_size = thunk_type_size(arg_type, 0);
5409 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5410 if (!argptr) {
5411 ret = -TARGET_EFAULT;
5412 goto out;
5413 }
5414 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5415 unlock_user(argptr, arg, 0);
5416
5417 switch (host_blkpg->op) {
5418 case BLKPG_ADD_PARTITION:
5419 case BLKPG_DEL_PARTITION:
5420 /* payload is struct blkpg_partition */
5421 break;
5422 default:
5423 /* Unknown opcode */
5424 ret = -TARGET_EINVAL;
5425 goto out;
5426 }
5427
5428 /* Read and convert blkpg->data */
5429 arg = (abi_long)(uintptr_t)host_blkpg->data;
5430 target_size = thunk_type_size(part_arg_type, 0);
5431 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5432 if (!argptr) {
5433 ret = -TARGET_EFAULT;
5434 goto out;
5435 }
5436 thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
5437 unlock_user(argptr, arg, 0);
5438
5439 /* Swizzle the data pointer to our local copy and call! */
5440 host_blkpg->data = &host_part;
49ca6f3e 5441 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg));
a59b5e35
AG
5442
5443out:
5444 return ret;
5445}
5446
7ff7b666 5447static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 5448 int fd, int cmd, abi_long arg)
7ff7b666
LV
5449{
5450 const argtype *arg_type = ie->arg_type;
5451 const StructEntry *se;
5452 const argtype *field_types;
5453 const int *dst_offsets, *src_offsets;
5454 int target_size;
5455 void *argptr;
b78c522a
MAL
5456 abi_ulong *target_rt_dev_ptr = NULL;
5457 unsigned long *host_rt_dev_ptr = NULL;
7ff7b666
LV
5458 abi_long ret;
5459 int i;
5460
5461 assert(ie->access == IOC_W);
5462 assert(*arg_type == TYPE_PTR);
5463 arg_type++;
5464 assert(*arg_type == TYPE_STRUCT);
5465 target_size = thunk_type_size(arg_type, 0);
5466 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5467 if (!argptr) {
5468 return -TARGET_EFAULT;
5469 }
5470 arg_type++;
5471 assert(*arg_type == (int)STRUCT_rtentry);
5472 se = struct_entries + *arg_type++;
5473 assert(se->convert[0] == NULL);
5474 /* convert struct here to be able to catch rt_dev string */
5475 field_types = se->field_types;
5476 dst_offsets = se->field_offsets[THUNK_HOST];
5477 src_offsets = se->field_offsets[THUNK_TARGET];
5478 for (i = 0; i < se->nb_fields; i++) {
5479 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
5480 assert(*field_types == TYPE_PTRVOID);
5481 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
5482 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
5483 if (*target_rt_dev_ptr != 0) {
5484 *host_rt_dev_ptr = (unsigned long)lock_user_string(
5485 tswapal(*target_rt_dev_ptr));
5486 if (!*host_rt_dev_ptr) {
5487 unlock_user(argptr, arg, 0);
5488 return -TARGET_EFAULT;
5489 }
5490 } else {
5491 *host_rt_dev_ptr = 0;
5492 }
5493 field_types++;
5494 continue;
5495 }
5496 field_types = thunk_convert(buf_temp + dst_offsets[i],
5497 argptr + src_offsets[i],
5498 field_types, THUNK_HOST);
5499 }
5500 unlock_user(argptr, arg, 0);
5501
49ca6f3e 5502 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
b78c522a
MAL
5503
5504 assert(host_rt_dev_ptr != NULL);
5505 assert(target_rt_dev_ptr != NULL);
7ff7b666
LV
5506 if (*host_rt_dev_ptr != 0) {
5507 unlock_user((void *)*host_rt_dev_ptr,
5508 *target_rt_dev_ptr, 0);
5509 }
5510 return ret;
5511}
5512
ca56f5b5 5513static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 5514 int fd, int cmd, abi_long arg)
ca56f5b5
PB
5515{
5516 int sig = target_to_host_signal(arg);
49ca6f3e 5517 return get_errno(safe_ioctl(fd, ie->host_cmd, sig));
ca56f5b5
PB
5518}
5519
6d5d5dde
DB
5520static abi_long do_ioctl_SIOCGSTAMP(const IOCTLEntry *ie, uint8_t *buf_temp,
5521 int fd, int cmd, abi_long arg)
5522{
5523 struct timeval tv;
5524 abi_long ret;
5525
5526 ret = get_errno(safe_ioctl(fd, SIOCGSTAMP, &tv));
5527 if (is_error(ret)) {
5528 return ret;
5529 }
5530
5531 if (cmd == (int)TARGET_SIOCGSTAMP_OLD) {
5532 if (copy_to_user_timeval(arg, &tv)) {
5533 return -TARGET_EFAULT;
5534 }
5535 } else {
5536 if (copy_to_user_timeval64(arg, &tv)) {
5537 return -TARGET_EFAULT;
5538 }
5539 }
5540
5541 return ret;
5542}
5543
5544static abi_long do_ioctl_SIOCGSTAMPNS(const IOCTLEntry *ie, uint8_t *buf_temp,
5545 int fd, int cmd, abi_long arg)
5546{
5547 struct timespec ts;
5548 abi_long ret;
5549
5550 ret = get_errno(safe_ioctl(fd, SIOCGSTAMPNS, &ts));
5551 if (is_error(ret)) {
5552 return ret;
5553 }
5554
5555 if (cmd == (int)TARGET_SIOCGSTAMPNS_OLD) {
5556 if (host_to_target_timespec(arg, &ts)) {
5557 return -TARGET_EFAULT;
5558 }
5559 } else{
5560 if (host_to_target_timespec64(arg, &ts)) {
5561 return -TARGET_EFAULT;
5562 }
5563 }
5564
5565 return ret;
5566}
5567
2b74f621
AS
5568#ifdef TIOCGPTPEER
5569static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp,
5570 int fd, int cmd, abi_long arg)
5571{
5572 int flags = target_to_host_bitmask(arg, fcntl_flags_tbl);
5573 return get_errno(safe_ioctl(fd, ie->host_cmd, flags));
5574}
5575#endif
5576
e865b97f
CG
5577#ifdef HAVE_DRM_H
5578
5579static void unlock_drm_version(struct drm_version *host_ver,
5580 struct target_drm_version *target_ver,
5581 bool copy)
5582{
5583 unlock_user(host_ver->name, target_ver->name,
5584 copy ? host_ver->name_len : 0);
5585 unlock_user(host_ver->date, target_ver->date,
5586 copy ? host_ver->date_len : 0);
5587 unlock_user(host_ver->desc, target_ver->desc,
5588 copy ? host_ver->desc_len : 0);
5589}
5590
5591static inline abi_long target_to_host_drmversion(struct drm_version *host_ver,
5592 struct target_drm_version *target_ver)
5593{
5594 memset(host_ver, 0, sizeof(*host_ver));
5595
5596 __get_user(host_ver->name_len, &target_ver->name_len);
5597 if (host_ver->name_len) {
5598 host_ver->name = lock_user(VERIFY_WRITE, target_ver->name,
5599 target_ver->name_len, 0);
5600 if (!host_ver->name) {
5601 return -EFAULT;
5602 }
5603 }
5604
5605 __get_user(host_ver->date_len, &target_ver->date_len);
5606 if (host_ver->date_len) {
5607 host_ver->date = lock_user(VERIFY_WRITE, target_ver->date,
5608 target_ver->date_len, 0);
5609 if (!host_ver->date) {
5610 goto err;
5611 }
5612 }
5613
5614 __get_user(host_ver->desc_len, &target_ver->desc_len);
5615 if (host_ver->desc_len) {
5616 host_ver->desc = lock_user(VERIFY_WRITE, target_ver->desc,
5617 target_ver->desc_len, 0);
5618 if (!host_ver->desc) {
5619 goto err;
5620 }
5621 }
5622
5623 return 0;
5624err:
5625 unlock_drm_version(host_ver, target_ver, false);
5626 return -EFAULT;
5627}
5628
5629static inline void host_to_target_drmversion(
5630 struct target_drm_version *target_ver,
5631 struct drm_version *host_ver)
5632{
5633 __put_user(host_ver->version_major, &target_ver->version_major);
5634 __put_user(host_ver->version_minor, &target_ver->version_minor);
5635 __put_user(host_ver->version_patchlevel, &target_ver->version_patchlevel);
5636 __put_user(host_ver->name_len, &target_ver->name_len);
5637 __put_user(host_ver->date_len, &target_ver->date_len);
5638 __put_user(host_ver->desc_len, &target_ver->desc_len);
5639 unlock_drm_version(host_ver, target_ver, true);
5640}
5641
5642static abi_long do_ioctl_drm(const IOCTLEntry *ie, uint8_t *buf_temp,
5643 int fd, int cmd, abi_long arg)
5644{
5645 struct drm_version *ver;
5646 struct target_drm_version *target_ver;
5647 abi_long ret;
5648
5649 switch (ie->host_cmd) {
5650 case DRM_IOCTL_VERSION:
5651 if (!lock_user_struct(VERIFY_WRITE, target_ver, arg, 0)) {
5652 return -TARGET_EFAULT;
5653 }
5654 ver = (struct drm_version *)buf_temp;
5655 ret = target_to_host_drmversion(ver, target_ver);
5656 if (!is_error(ret)) {
5657 ret = get_errno(safe_ioctl(fd, ie->host_cmd, ver));
5658 if (is_error(ret)) {
5659 unlock_drm_version(ver, target_ver, false);
5660 } else {
5661 host_to_target_drmversion(target_ver, ver);
5662 }
5663 }
5664 unlock_user_struct(target_ver, arg, 0);
5665 return ret;
5666 }
5667 return -TARGET_ENOSYS;
5668}
5669
913b03c2
CG
5670static abi_long do_ioctl_drm_i915_getparam(const IOCTLEntry *ie,
5671 struct drm_i915_getparam *gparam,
5672 int fd, abi_long arg)
5673{
5674 abi_long ret;
5675 int value;
5676 struct target_drm_i915_getparam *target_gparam;
5677
5678 if (!lock_user_struct(VERIFY_READ, target_gparam, arg, 0)) {
5679 return -TARGET_EFAULT;
5680 }
5681
5682 __get_user(gparam->param, &target_gparam->param);
5683 gparam->value = &value;
5684 ret = get_errno(safe_ioctl(fd, ie->host_cmd, gparam));
5685 put_user_s32(value, target_gparam->value);
5686
5687 unlock_user_struct(target_gparam, arg, 0);
5688 return ret;
5689}
5690
5691static abi_long do_ioctl_drm_i915(const IOCTLEntry *ie, uint8_t *buf_temp,
5692 int fd, int cmd, abi_long arg)
5693{
5694 switch (ie->host_cmd) {
5695 case DRM_IOCTL_I915_GETPARAM:
5696 return do_ioctl_drm_i915_getparam(ie,
5697 (struct drm_i915_getparam *)buf_temp,
5698 fd, arg);
5699 default:
5700 return -TARGET_ENOSYS;
5701 }
5702}
5703
e865b97f
CG
5704#endif
5705
79482e59 5706IOCTLEntry ioctl_entries[] = {
001faf32 5707#define IOCTL(cmd, access, ...) \
d2ef05bb
PM
5708 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
5709#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
5710 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
8cb762fe
HD
5711#define IOCTL_IGNORE(cmd) \
5712 { TARGET_ ## cmd, 0, #cmd },
31e31b8a
FB
5713#include "ioctls.h"
5714 { 0, 0, },
5715};
5716
53a5960a 5717/* ??? Implement proper locking for ioctls. */
0da46a6e 5718/* do_ioctl() Must return target values and target errnos. */
45c874eb 5719static abi_long do_ioctl(int fd, int cmd, abi_long arg)
31e31b8a
FB
5720{
5721 const IOCTLEntry *ie;
5722 const argtype *arg_type;
992f48a0 5723 abi_long ret;
31e31b8a 5724 uint8_t buf_temp[MAX_STRUCT_SIZE];
53a5960a
PB
5725 int target_size;
5726 void *argptr;
31e31b8a
FB
5727
5728 ie = ioctl_entries;
5729 for(;;) {
5730 if (ie->target_cmd == 0) {
39be5350
JK
5731 qemu_log_mask(
5732 LOG_UNIMP, "Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
0da46a6e 5733 return -TARGET_ENOSYS;
31e31b8a
FB
5734 }
5735 if (ie->target_cmd == cmd)
5736 break;
5737 ie++;
5738 }
5739 arg_type = ie->arg_type;
d2ef05bb
PM
5740 if (ie->do_ioctl) {
5741 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
8cb762fe
HD
5742 } else if (!ie->host_cmd) {
5743 /* Some architectures define BSD ioctls in their headers
5744 that are not implemented in Linux. */
5745 return -TARGET_ENOSYS;
d2ef05bb
PM
5746 }
5747
31e31b8a
FB
5748 switch(arg_type[0]) {
5749 case TYPE_NULL:
5750 /* no argument */
49ca6f3e 5751 ret = get_errno(safe_ioctl(fd, ie->host_cmd));
31e31b8a
FB
5752 break;
5753 case TYPE_PTRVOID:
5754 case TYPE_INT:
c858e537
FB
5755 case TYPE_LONG:
5756 case TYPE_ULONG:
49ca6f3e 5757 ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
31e31b8a
FB
5758 break;
5759 case TYPE_PTR:
5760 arg_type++;
53a5960a 5761 target_size = thunk_type_size(arg_type, 0);
31e31b8a
FB
5762 switch(ie->access) {
5763 case IOC_R:
49ca6f3e 5764 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a 5765 if (!is_error(ret)) {
579a97f7
FB
5766 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5767 if (!argptr)
5768 return -TARGET_EFAULT;
53a5960a
PB
5769 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5770 unlock_user(argptr, arg, target_size);
31e31b8a
FB
5771 }
5772 break;
5773 case IOC_W:
579a97f7
FB
5774 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5775 if (!argptr)
5776 return -TARGET_EFAULT;
53a5960a
PB
5777 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5778 unlock_user(argptr, arg, 0);
49ca6f3e 5779 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a
FB
5780 break;
5781 default:
5782 case IOC_RW:
579a97f7
FB
5783 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5784 if (!argptr)
5785 return -TARGET_EFAULT;
53a5960a
PB
5786 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5787 unlock_user(argptr, arg, 0);
49ca6f3e 5788 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a 5789 if (!is_error(ret)) {
579a97f7
FB
5790 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5791 if (!argptr)
5792 return -TARGET_EFAULT;
53a5960a
PB
5793 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5794 unlock_user(argptr, arg, target_size);
31e31b8a
FB
5795 }
5796 break;
5797 }
5798 break;
5799 default:
39be5350
JK
5800 qemu_log_mask(LOG_UNIMP,
5801 "Unsupported ioctl type: cmd=0x%04lx type=%d\n",
5802 (long)cmd, arg_type[0]);
0da46a6e 5803 ret = -TARGET_ENOSYS;
31e31b8a
FB
5804 break;
5805 }
5806 return ret;
5807}
5808
b39bc503 5809static const bitmask_transtbl iflag_tbl[] = {
31e31b8a
FB
5810 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
5811 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
5812 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
5813 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
5814 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
5815 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
5816 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
5817 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
5818 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
5819 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
5820 { TARGET_IXON, TARGET_IXON, IXON, IXON },
5821 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
5822 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
5823 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
c218b4ed 5824 { TARGET_IUTF8, TARGET_IUTF8, IUTF8, IUTF8},
31e31b8a
FB
5825 { 0, 0, 0, 0 }
5826};
5827
b39bc503 5828static const bitmask_transtbl oflag_tbl[] = {
31e31b8a
FB
5829 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
5830 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
5831 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
5832 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
5833 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
5834 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
5835 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
5836 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
5837 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
5838 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
5839 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
5840 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
5841 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
5842 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
5843 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
5844 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
5845 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
5846 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
5847 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
5848 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
5849 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
5850 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
5851 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
5852 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
5853 { 0, 0, 0, 0 }
5854};
5855
b39bc503 5856static const bitmask_transtbl cflag_tbl[] = {
31e31b8a
FB
5857 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
5858 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
5859 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
5860 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
5861 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
5862 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
5863 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
5864 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
5865 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
5866 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
5867 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
5868 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
5869 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
5870 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
5871 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
5872 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
5873 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
5874 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
5875 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
5876 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
5877 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
5878 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
5879 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
5880 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
5881 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
5882 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
5883 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
5884 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
5885 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
5886 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
5887 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
5888 { 0, 0, 0, 0 }
5889};
5890
b39bc503 5891static const bitmask_transtbl lflag_tbl[] = {
c218b4ed
FB
5892 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
5893 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
5894 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
5895 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
5896 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
5897 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
5898 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
5899 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
5900 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
5901 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
5902 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
5903 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
5904 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
5905 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
5906 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
5907 { TARGET_EXTPROC, TARGET_EXTPROC, EXTPROC, EXTPROC},
5908 { 0, 0, 0, 0 }
31e31b8a
FB
5909};
5910
5911static void target_to_host_termios (void *dst, const void *src)
5912{
5913 struct host_termios *host = dst;
5914 const struct target_termios *target = src;
3b46e624 5915
5fafdf24 5916 host->c_iflag =
31e31b8a 5917 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
5fafdf24 5918 host->c_oflag =
31e31b8a 5919 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
5fafdf24 5920 host->c_cflag =
31e31b8a 5921 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
5fafdf24 5922 host->c_lflag =
31e31b8a
FB
5923 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
5924 host->c_line = target->c_line;
3b46e624 5925
44607123 5926 memset(host->c_cc, 0, sizeof(host->c_cc));
5fafdf24
TS
5927 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
5928 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3b46e624 5929 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
5fafdf24 5930 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3b46e624 5931 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
5fafdf24 5932 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3b46e624 5933 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
5fafdf24 5934 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3b46e624 5935 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
5fafdf24
TS
5936 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
5937 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3b46e624
TS
5938 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
5939 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
5940 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
5941 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
5942 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
5fafdf24 5943 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
31e31b8a 5944}
3b46e624 5945
31e31b8a
FB
5946static void host_to_target_termios (void *dst, const void *src)
5947{
5948 struct target_termios *target = dst;
5949 const struct host_termios *host = src;
5950
5fafdf24 5951 target->c_iflag =
31e31b8a 5952 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
5fafdf24 5953 target->c_oflag =
31e31b8a 5954 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
5fafdf24 5955 target->c_cflag =
31e31b8a 5956 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
5fafdf24 5957 target->c_lflag =
31e31b8a
FB
5958 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
5959 target->c_line = host->c_line;
3b46e624 5960
44607123 5961 memset(target->c_cc, 0, sizeof(target->c_cc));
31e31b8a
FB
5962 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
5963 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
5964 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
5965 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
5966 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
5967 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
5968 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
5969 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
5970 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
5971 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
5972 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
5973 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
5974 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
5975 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
5976 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
5977 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
5978 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
5979}
5980
8e853dc7 5981static const StructEntry struct_termios_def = {
31e31b8a
FB
5982 .convert = { host_to_target_termios, target_to_host_termios },
5983 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
5984 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
888468db 5985 .print = print_termios,
31e31b8a
FB
5986};
5987
5286db75 5988static bitmask_transtbl mmap_flags_tbl[] = {
541e1690
HD
5989 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
5990 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
5991 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
5992 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS,
5993 MAP_ANONYMOUS, MAP_ANONYMOUS },
5994 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN,
5995 MAP_GROWSDOWN, MAP_GROWSDOWN },
5996 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE,
5997 MAP_DENYWRITE, MAP_DENYWRITE },
5998 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE,
5999 MAP_EXECUTABLE, MAP_EXECUTABLE },
6000 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
6001 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE,
6002 MAP_NORESERVE, MAP_NORESERVE },
6003 { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },
6004 /* MAP_STACK had been ignored by the kernel for quite some time.
6005 Recognize it for the target insofar as we do not want to pass
6006 it through to the host. */
6007 { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 },
6008 { 0, 0, 0, 0 }
5286db75
FB
6009};
6010
9d12f79d
LV
6011/*
6012 * NOTE: TARGET_ABI32 is defined for TARGET_I386 (but not for TARGET_X86_64)
6013 * TARGET_I386 is defined if TARGET_X86_64 is defined
6014 */
2ab83ea7 6015#if defined(TARGET_I386)
6dbad63e
FB
6016
6017/* NOTE: there is really one LDT for all the threads */
b1d8e52e 6018static uint8_t *ldt_table;
6dbad63e 6019
03acab66 6020static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
6dbad63e
FB
6021{
6022 int size;
53a5960a 6023 void *p;
6dbad63e
FB
6024
6025 if (!ldt_table)
6026 return 0;
6027 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
6028 if (size > bytecount)
6029 size = bytecount;
579a97f7
FB
6030 p = lock_user(VERIFY_WRITE, ptr, size, 0);
6031 if (!p)
03acab66 6032 return -TARGET_EFAULT;
579a97f7 6033 /* ??? Should this by byteswapped? */
53a5960a
PB
6034 memcpy(p, ldt_table, size);
6035 unlock_user(p, ptr, size);
6dbad63e
FB
6036 return size;
6037}
6038
6039/* XXX: add locking support */
03acab66
FB
6040static abi_long write_ldt(CPUX86State *env,
6041 abi_ulong ptr, unsigned long bytecount, int oldmode)
6dbad63e
FB
6042{
6043 struct target_modify_ldt_ldt_s ldt_info;
53a5960a 6044 struct target_modify_ldt_ldt_s *target_ldt_info;
6dbad63e 6045 int seg_32bit, contents, read_exec_only, limit_in_pages;
8d18e893 6046 int seg_not_present, useable, lm;
6dbad63e
FB
6047 uint32_t *lp, entry_1, entry_2;
6048
6049 if (bytecount != sizeof(ldt_info))
03acab66 6050 return -TARGET_EINVAL;
579a97f7 6051 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
03acab66 6052 return -TARGET_EFAULT;
53a5960a 6053 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
cbb21eed 6054 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
53a5960a
PB
6055 ldt_info.limit = tswap32(target_ldt_info->limit);
6056 ldt_info.flags = tswap32(target_ldt_info->flags);
6057 unlock_user_struct(target_ldt_info, ptr, 0);
3b46e624 6058
6dbad63e 6059 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
03acab66 6060 return -TARGET_EINVAL;
6dbad63e
FB
6061 seg_32bit = ldt_info.flags & 1;
6062 contents = (ldt_info.flags >> 1) & 3;
6063 read_exec_only = (ldt_info.flags >> 3) & 1;
6064 limit_in_pages = (ldt_info.flags >> 4) & 1;
6065 seg_not_present = (ldt_info.flags >> 5) & 1;
6066 useable = (ldt_info.flags >> 6) & 1;
8d18e893
FB
6067#ifdef TARGET_ABI32
6068 lm = 0;
6069#else
6070 lm = (ldt_info.flags >> 7) & 1;
6071#endif
6dbad63e
FB
6072 if (contents == 3) {
6073 if (oldmode)
03acab66 6074 return -TARGET_EINVAL;
6dbad63e 6075 if (seg_not_present == 0)
03acab66 6076 return -TARGET_EINVAL;
6dbad63e
FB
6077 }
6078 /* allocate the LDT */
6079 if (!ldt_table) {
e441570f
AZ
6080 env->ldt.base = target_mmap(0,
6081 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
6082 PROT_READ|PROT_WRITE,
6083 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
6084 if (env->ldt.base == -1)
03acab66 6085 return -TARGET_ENOMEM;
e441570f
AZ
6086 memset(g2h(env->ldt.base), 0,
6087 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
6dbad63e 6088 env->ldt.limit = 0xffff;
e441570f 6089 ldt_table = g2h(env->ldt.base);
6dbad63e
FB
6090 }
6091
6092 /* NOTE: same code as Linux kernel */
6093 /* Allow LDTs to be cleared by the user. */
6094 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
6095 if (oldmode ||
6096 (contents == 0 &&
6097 read_exec_only == 1 &&
6098 seg_32bit == 0 &&
6099 limit_in_pages == 0 &&
6100 seg_not_present == 1 &&
6101 useable == 0 )) {
6102 entry_1 = 0;
6103 entry_2 = 0;
6104 goto install;
6105 }
6106 }
3b46e624 6107
6dbad63e
FB
6108 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
6109 (ldt_info.limit & 0x0ffff);
6110 entry_2 = (ldt_info.base_addr & 0xff000000) |
6111 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
6112 (ldt_info.limit & 0xf0000) |
6113 ((read_exec_only ^ 1) << 9) |
6114 (contents << 10) |
6115 ((seg_not_present ^ 1) << 15) |
6116 (seg_32bit << 22) |
6117 (limit_in_pages << 23) |
8d18e893 6118 (lm << 21) |
6dbad63e
FB
6119 0x7000;
6120 if (!oldmode)
6121 entry_2 |= (useable << 20);
14ae3ba7 6122
6dbad63e
FB
6123 /* Install the new entry ... */
6124install:
6125 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
6126 lp[0] = tswap32(entry_1);
6127 lp[1] = tswap32(entry_2);
6128 return 0;
6129}
6130
6131/* specific and weird i386 syscalls */
8fcd3692
BS
6132static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
6133 unsigned long bytecount)
6dbad63e 6134{
03acab66 6135 abi_long ret;
3b46e624 6136
6dbad63e
FB
6137 switch (func) {
6138 case 0:
6139 ret = read_ldt(ptr, bytecount);
6140 break;
6141 case 1:
6142 ret = write_ldt(env, ptr, bytecount, 1);
6143 break;
6144 case 0x11:
6145 ret = write_ldt(env, ptr, bytecount, 0);
6146 break;
03acab66
FB
6147 default:
6148 ret = -TARGET_ENOSYS;
6149 break;
6dbad63e
FB
6150 }
6151 return ret;
6152}
1b6b029e 6153
9d12f79d 6154#if defined(TARGET_ABI32)
bc22eb44 6155abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
8d18e893
FB
6156{
6157 uint64_t *gdt_table = g2h(env->gdt.base);
6158 struct target_modify_ldt_ldt_s ldt_info;
6159 struct target_modify_ldt_ldt_s *target_ldt_info;
6160 int seg_32bit, contents, read_exec_only, limit_in_pages;
6161 int seg_not_present, useable, lm;
6162 uint32_t *lp, entry_1, entry_2;
6163 int i;
6164
6165 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
6166 if (!target_ldt_info)
6167 return -TARGET_EFAULT;
6168 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
cbb21eed 6169 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
8d18e893
FB
6170 ldt_info.limit = tswap32(target_ldt_info->limit);
6171 ldt_info.flags = tswap32(target_ldt_info->flags);
6172 if (ldt_info.entry_number == -1) {
6173 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
6174 if (gdt_table[i] == 0) {
6175 ldt_info.entry_number = i;
6176 target_ldt_info->entry_number = tswap32(i);
6177 break;
6178 }
6179 }
6180 }
6181 unlock_user_struct(target_ldt_info, ptr, 1);
6182
6183 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
6184 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
6185 return -TARGET_EINVAL;
6186 seg_32bit = ldt_info.flags & 1;
6187 contents = (ldt_info.flags >> 1) & 3;
6188 read_exec_only = (ldt_info.flags >> 3) & 1;
6189 limit_in_pages = (ldt_info.flags >> 4) & 1;
6190 seg_not_present = (ldt_info.flags >> 5) & 1;
6191 useable = (ldt_info.flags >> 6) & 1;
6192#ifdef TARGET_ABI32
6193 lm = 0;
6194#else
6195 lm = (ldt_info.flags >> 7) & 1;
6196#endif
6197
6198 if (contents == 3) {
6199 if (seg_not_present == 0)
6200 return -TARGET_EINVAL;
6201 }
6202
6203 /* NOTE: same code as Linux kernel */
6204 /* Allow LDTs to be cleared by the user. */
6205 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
6206 if ((contents == 0 &&
6207 read_exec_only == 1 &&
6208 seg_32bit == 0 &&
6209 limit_in_pages == 0 &&
6210 seg_not_present == 1 &&
6211 useable == 0 )) {
6212 entry_1 = 0;
6213 entry_2 = 0;
6214 goto install;
6215 }
6216 }
6217
6218 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
6219 (ldt_info.limit & 0x0ffff);
6220 entry_2 = (ldt_info.base_addr & 0xff000000) |
6221 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
6222 (ldt_info.limit & 0xf0000) |
6223 ((read_exec_only ^ 1) << 9) |
6224 (contents << 10) |
6225 ((seg_not_present ^ 1) << 15) |
6226 (seg_32bit << 22) |
6227 (limit_in_pages << 23) |
6228 (useable << 20) |
6229 (lm << 21) |
6230 0x7000;
6231
6232 /* Install the new entry ... */
6233install:
6234 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
6235 lp[0] = tswap32(entry_1);
6236 lp[1] = tswap32(entry_2);
6237 return 0;
6238}
6239
8fcd3692 6240static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
8d18e893
FB
6241{
6242 struct target_modify_ldt_ldt_s *target_ldt_info;
6243 uint64_t *gdt_table = g2h(env->gdt.base);
6244 uint32_t base_addr, limit, flags;
6245 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
6246 int seg_not_present, useable, lm;
6247 uint32_t *lp, entry_1, entry_2;
6248
6249 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
6250 if (!target_ldt_info)
6251 return -TARGET_EFAULT;
6252 idx = tswap32(target_ldt_info->entry_number);
6253 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
6254 idx > TARGET_GDT_ENTRY_TLS_MAX) {
6255 unlock_user_struct(target_ldt_info, ptr, 1);
6256 return -TARGET_EINVAL;
6257 }
6258 lp = (uint32_t *)(gdt_table + idx);
6259 entry_1 = tswap32(lp[0]);
6260 entry_2 = tswap32(lp[1]);
6261
6262 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
6263 contents = (entry_2 >> 10) & 3;
6264 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
6265 seg_32bit = (entry_2 >> 22) & 1;
6266 limit_in_pages = (entry_2 >> 23) & 1;
6267 useable = (entry_2 >> 20) & 1;
6268#ifdef TARGET_ABI32
6269 lm = 0;
6270#else
6271 lm = (entry_2 >> 21) & 1;
6272#endif
6273 flags = (seg_32bit << 0) | (contents << 1) |
6274 (read_exec_only << 3) | (limit_in_pages << 4) |
6275 (seg_not_present << 5) | (useable << 6) | (lm << 7);
6276 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
6277 base_addr = (entry_1 >> 16) |
6278 (entry_2 & 0xff000000) |
6279 ((entry_2 & 0xff) << 16);
cbb21eed 6280 target_ldt_info->base_addr = tswapal(base_addr);
8d18e893
FB
6281 target_ldt_info->limit = tswap32(limit);
6282 target_ldt_info->flags = tswap32(flags);
6283 unlock_user_struct(target_ldt_info, ptr, 1);
6284 return 0;
6285}
6286
9d12f79d
LV
6287abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
6288{
538fabcb 6289 return -TARGET_ENOSYS;
9d12f79d
LV
6290}
6291#else
2667e71c 6292abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
d2fd1af7 6293{
1add8698 6294 abi_long ret = 0;
d2fd1af7
FB
6295 abi_ulong val;
6296 int idx;
1add8698 6297
d2fd1af7
FB
6298 switch(code) {
6299 case TARGET_ARCH_SET_GS:
6300 case TARGET_ARCH_SET_FS:
6301 if (code == TARGET_ARCH_SET_GS)
6302 idx = R_GS;
6303 else
6304 idx = R_FS;
6305 cpu_x86_load_seg(env, idx, 0);
6306 env->segs[idx].base = addr;
6307 break;
6308 case TARGET_ARCH_GET_GS:
6309 case TARGET_ARCH_GET_FS:
6310 if (code == TARGET_ARCH_GET_GS)
6311 idx = R_GS;
6312 else
6313 idx = R_FS;
6314 val = env->segs[idx].base;
6315 if (put_user(val, addr, abi_ulong))
1add8698 6316 ret = -TARGET_EFAULT;
d2fd1af7
FB
6317 break;
6318 default:
6319 ret = -TARGET_EINVAL;
6320 break;
6321 }
1add8698 6322 return ret;
d2fd1af7 6323}
9d12f79d 6324#endif /* defined(TARGET_ABI32 */
d2fd1af7 6325
2ab83ea7
FB
6326#endif /* defined(TARGET_I386) */
6327
05098a93 6328#define NEW_STACK_SIZE 0x40000
d865bab5 6329
d865bab5
PB
6330
6331static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
6332typedef struct {
9349b4f9 6333 CPUArchState *env;
d865bab5
PB
6334 pthread_mutex_t mutex;
6335 pthread_cond_t cond;
6336 pthread_t thread;
6337 uint32_t tid;
6338 abi_ulong child_tidptr;
6339 abi_ulong parent_tidptr;
6340 sigset_t sigmask;
6341} new_thread_info;
6342
6343static void *clone_func(void *arg)
6344{
6345 new_thread_info *info = arg;
9349b4f9 6346 CPUArchState *env;
0d34282f 6347 CPUState *cpu;
edf8e2af 6348 TaskState *ts;
d865bab5 6349
70903763 6350 rcu_register_thread();
3468b59e 6351 tcg_register_thread();
d865bab5 6352 env = info->env;
29a0af61 6353 cpu = env_cpu(env);
a2247f8e 6354 thread_cpu = cpu;
0429a971 6355 ts = (TaskState *)cpu->opaque;
71ba74f6 6356 info->tid = sys_gettid();
edf8e2af 6357 task_settid(ts);
d865bab5
PB
6358 if (info->child_tidptr)
6359 put_user_u32(info->tid, info->child_tidptr);
6360 if (info->parent_tidptr)
6361 put_user_u32(info->tid, info->parent_tidptr);
5ebdd774 6362 qemu_guest_random_seed_thread_part2(cpu->random_seed);
d865bab5
PB
6363 /* Enable signals. */
6364 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
6365 /* Signal to the parent that we're ready. */
6366 pthread_mutex_lock(&info->mutex);
6367 pthread_cond_broadcast(&info->cond);
6368 pthread_mutex_unlock(&info->mutex);
a4dd3d51 6369 /* Wait until the parent has finished initializing the tls state. */
d865bab5
PB
6370 pthread_mutex_lock(&clone_lock);
6371 pthread_mutex_unlock(&clone_lock);
6372 cpu_loop(env);
6373 /* never exits */
6374 return NULL;
6375}
1b6b029e 6376
0da46a6e
TS
6377/* do_fork() Must return host values and target errnos (unlike most
6378 do_*() functions). */
9349b4f9 6379static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
d865bab5
PB
6380 abi_ulong parent_tidptr, target_ulong newtls,
6381 abi_ulong child_tidptr)
1b6b029e 6382{
29a0af61 6383 CPUState *cpu = env_cpu(env);
1b6b029e 6384 int ret;
5cd4393b 6385 TaskState *ts;
0429a971 6386 CPUState *new_cpu;
9349b4f9 6387 CPUArchState *new_env;
d865bab5 6388 sigset_t sigmask;
3b46e624 6389
5ea2fc84
PM
6390 flags &= ~CLONE_IGNORED_FLAGS;
6391
436d124b
AZ
6392 /* Emulate vfork() with fork() */
6393 if (flags & CLONE_VFORK)
6394 flags &= ~(CLONE_VFORK | CLONE_VM);
6395
1b6b029e 6396 if (flags & CLONE_VM) {
0429a971 6397 TaskState *parent_ts = (TaskState *)cpu->opaque;
d865bab5
PB
6398 new_thread_info info;
6399 pthread_attr_t attr;
24cb36a6 6400
5ea2fc84
PM
6401 if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
6402 (flags & CLONE_INVALID_THREAD_FLAGS)) {
6403 return -TARGET_EINVAL;
6404 }
6405
c78d65e8 6406 ts = g_new0(TaskState, 1);
624f7979 6407 init_task_state(ts);
73a988d9
MF
6408
6409 /* Grab a mutex so that thread setup appears atomic. */
6410 pthread_mutex_lock(&clone_lock);
6411
1b6b029e 6412 /* we create a new CPU instance. */
c5be9f08 6413 new_env = cpu_copy(env);
6e68e076 6414 /* Init regs that differ from the parent. */
608999d1 6415 cpu_clone_regs_child(new_env, newsp, flags);
07a6ecf4 6416 cpu_clone_regs_parent(env, flags);
29a0af61 6417 new_cpu = env_cpu(new_env);
0429a971 6418 new_cpu->opaque = ts;
edf8e2af
MW
6419 ts->bprm = parent_ts->bprm;
6420 ts->info = parent_ts->info;
3d3efba0 6421 ts->signal_mask = parent_ts->signal_mask;
d865bab5 6422
7cfbd386 6423 if (flags & CLONE_CHILD_CLEARTID) {
c2764719
PB
6424 ts->child_tidptr = child_tidptr;
6425 }
6426
7cfbd386 6427 if (flags & CLONE_SETTLS) {
d865bab5 6428 cpu_set_tls (new_env, newtls);
7cfbd386 6429 }
d865bab5 6430
d865bab5
PB
6431 memset(&info, 0, sizeof(info));
6432 pthread_mutex_init(&info.mutex, NULL);
6433 pthread_mutex_lock(&info.mutex);
6434 pthread_cond_init(&info.cond, NULL);
6435 info.env = new_env;
7cfbd386 6436 if (flags & CLONE_CHILD_SETTID) {
d865bab5 6437 info.child_tidptr = child_tidptr;
7cfbd386
PM
6438 }
6439 if (flags & CLONE_PARENT_SETTID) {
d865bab5 6440 info.parent_tidptr = parent_tidptr;
7cfbd386 6441 }
d865bab5
PB
6442
6443 ret = pthread_attr_init(&attr);
48e15fc2
NF
6444 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
6445 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
d865bab5
PB
6446 /* It is not safe to deliver signals until the child has finished
6447 initializing, so temporarily block all signals. */
6448 sigfillset(&sigmask);
6449 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
5ebdd774 6450 cpu->random_seed = qemu_guest_random_seed_thread_part1();
d865bab5 6451
b67cb68b
AB
6452 /* If this is our first additional thread, we need to ensure we
6453 * generate code for parallel execution and flush old translations.
6454 */
6455 if (!parallel_cpus) {
6456 parallel_cpus = true;
6457 tb_flush(cpu);
6458 }
6459
d865bab5 6460 ret = pthread_create(&info.thread, &attr, clone_func, &info);
c2764719 6461 /* TODO: Free new CPU state if thread creation failed. */
d865bab5
PB
6462
6463 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
6464 pthread_attr_destroy(&attr);
6465 if (ret == 0) {
6466 /* Wait for the child to initialize. */
6467 pthread_cond_wait(&info.cond, &info.mutex);
6468 ret = info.tid;
d865bab5
PB
6469 } else {
6470 ret = -1;
6471 }
6472 pthread_mutex_unlock(&info.mutex);
6473 pthread_cond_destroy(&info.cond);
6474 pthread_mutex_destroy(&info.mutex);
6475 pthread_mutex_unlock(&clone_lock);
1b6b029e
FB
6476 } else {
6477 /* if no CLONE_VM, we consider it is a fork */
5ea2fc84
PM
6478 if (flags & CLONE_INVALID_FORK_FLAGS) {
6479 return -TARGET_EINVAL;
6480 }
6481
6482 /* We can't support custom termination signals */
6483 if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
93b4eff8
TB
6484 return -TARGET_EINVAL;
6485 }
7d92d34e
TB
6486
6487 if (block_signals()) {
6488 return -TARGET_ERESTARTSYS;
6489 }
6490
d865bab5 6491 fork_start();
1b6b029e 6492 ret = fork();
d865bab5 6493 if (ret == 0) {
2b1319c8 6494 /* Child Process. */
608999d1 6495 cpu_clone_regs_child(env, newsp, flags);
d865bab5 6496 fork_end(1);
2b1319c8
AJ
6497 /* There is a race condition here. The parent process could
6498 theoretically read the TID in the child process before the child
6499 tid is set. This would require using either ptrace
6500 (not implemented) or having *_tidptr to point at a shared memory
6501 mapping. We can't repeat the spinlock hack used above because
6502 the child process gets its own copy of the lock. */
d865bab5 6503 if (flags & CLONE_CHILD_SETTID)
71ba74f6 6504 put_user_u32(sys_gettid(), child_tidptr);
d865bab5 6505 if (flags & CLONE_PARENT_SETTID)
71ba74f6 6506 put_user_u32(sys_gettid(), parent_tidptr);
0429a971 6507 ts = (TaskState *)cpu->opaque;
d865bab5
PB
6508 if (flags & CLONE_SETTLS)
6509 cpu_set_tls (env, newtls);
c2764719
PB
6510 if (flags & CLONE_CHILD_CLEARTID)
6511 ts->child_tidptr = child_tidptr;
d865bab5 6512 } else {
07a6ecf4 6513 cpu_clone_regs_parent(env, flags);
d865bab5
PB
6514 fork_end(0);
6515 }
1b6b029e
FB
6516 }
6517 return ret;
6518}
6519
5f106811
APR
6520/* warning : doesn't handle linux specific flags... */
6521static int target_to_host_fcntl_cmd(int cmd)
6522{
4a545761
SB
6523 int ret;
6524
5f106811 6525 switch(cmd) {
4a545761
SB
6526 case TARGET_F_DUPFD:
6527 case TARGET_F_GETFD:
6528 case TARGET_F_SETFD:
6529 case TARGET_F_GETFL:
6530 case TARGET_F_SETFL:
2d92c682
AS
6531 case TARGET_F_OFD_GETLK:
6532 case TARGET_F_OFD_SETLK:
6533 case TARGET_F_OFD_SETLKW:
4a545761
SB
6534 ret = cmd;
6535 break;
6536 case TARGET_F_GETLK:
6537 ret = F_GETLK64;
6538 break;
6539 case TARGET_F_SETLK:
6540 ret = F_SETLK64;
6541 break;
6542 case TARGET_F_SETLKW:
6543 ret = F_SETLKW64;
6544 break;
6545 case TARGET_F_GETOWN:
6546 ret = F_GETOWN;
6547 break;
6548 case TARGET_F_SETOWN:
6549 ret = F_SETOWN;
6550 break;
6551 case TARGET_F_GETSIG:
6552 ret = F_GETSIG;
6553 break;
6554 case TARGET_F_SETSIG:
6555 ret = F_SETSIG;
6556 break;
5f106811 6557#if TARGET_ABI_BITS == 32
4a545761
SB
6558 case TARGET_F_GETLK64:
6559 ret = F_GETLK64;
6560 break;
6561 case TARGET_F_SETLK64:
6562 ret = F_SETLK64;
6563 break;
6564 case TARGET_F_SETLKW64:
6565 ret = F_SETLKW64;
6566 break;
5f106811 6567#endif
4a545761
SB
6568 case TARGET_F_SETLEASE:
6569 ret = F_SETLEASE;
6570 break;
6571 case TARGET_F_GETLEASE:
6572 ret = F_GETLEASE;
6573 break;
fbd5de9b 6574#ifdef F_DUPFD_CLOEXEC
4a545761
SB
6575 case TARGET_F_DUPFD_CLOEXEC:
6576 ret = F_DUPFD_CLOEXEC;
6577 break;
fbd5de9b 6578#endif
4a545761
SB
6579 case TARGET_F_NOTIFY:
6580 ret = F_NOTIFY;
6581 break;
8d5d3004 6582#ifdef F_GETOWN_EX
4a545761
SB
6583 case TARGET_F_GETOWN_EX:
6584 ret = F_GETOWN_EX;
6585 break;
8d5d3004
AS
6586#endif
6587#ifdef F_SETOWN_EX
4a545761
SB
6588 case TARGET_F_SETOWN_EX:
6589 ret = F_SETOWN_EX;
6590 break;
8d5d3004 6591#endif
ddf31aa8 6592#ifdef F_SETPIPE_SZ
4a545761
SB
6593 case TARGET_F_SETPIPE_SZ:
6594 ret = F_SETPIPE_SZ;
6595 break;
6596 case TARGET_F_GETPIPE_SZ:
6597 ret = F_GETPIPE_SZ;
6598 break;
ddf31aa8 6599#endif
4a545761
SB
6600 default:
6601 ret = -TARGET_EINVAL;
6602 break;
6603 }
6604
6605#if defined(__powerpc64__)
6606 /* On PPC64, glibc headers has the F_*LK* defined to 12, 13 and 14 and
6607 * is not supported by kernel. The glibc fcntl call actually adjusts
6608 * them to 5, 6 and 7 before making the syscall(). Since we make the
6609 * syscall directly, adjust to what is supported by the kernel.
6610 */
6611 if (ret >= F_GETLK64 && ret <= F_SETLKW64) {
6612 ret -= F_GETLK64 - 5;
5f106811 6613 }
4a545761
SB
6614#endif
6615
6616 return ret;
5f106811
APR
6617}
6618
ae68ad9f
LV
6619#define FLOCK_TRANSTBL \
6620 switch (type) { \
6621 TRANSTBL_CONVERT(F_RDLCK); \
6622 TRANSTBL_CONVERT(F_WRLCK); \
6623 TRANSTBL_CONVERT(F_UNLCK); \
6624 TRANSTBL_CONVERT(F_EXLCK); \
6625 TRANSTBL_CONVERT(F_SHLCK); \
6626 }
6627
6628static int target_to_host_flock(int type)
6629{
6630#define TRANSTBL_CONVERT(a) case TARGET_##a: return a
6631 FLOCK_TRANSTBL
6632#undef TRANSTBL_CONVERT
6633 return -TARGET_EINVAL;
6634}
6635
6636static int host_to_target_flock(int type)
6637{
6638#define TRANSTBL_CONVERT(a) case a: return TARGET_##a
6639 FLOCK_TRANSTBL
6640#undef TRANSTBL_CONVERT
6641 /* if we don't know how to convert the value coming
6642 * from the host we copy to the target field as-is
6643 */
6644 return type;
6645}
2ba7f730 6646
213d3e9e
PM
6647static inline abi_long copy_from_user_flock(struct flock64 *fl,
6648 abi_ulong target_flock_addr)
7775e9ec 6649{
53a5960a 6650 struct target_flock *target_fl;
ae68ad9f 6651 int l_type;
213d3e9e
PM
6652
6653 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6654 return -TARGET_EFAULT;
6655 }
6656
6657 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6658 l_type = target_to_host_flock(l_type);
6659 if (l_type < 0) {
6660 return l_type;
6661 }
6662 fl->l_type = l_type;
213d3e9e
PM
6663 __get_user(fl->l_whence, &target_fl->l_whence);
6664 __get_user(fl->l_start, &target_fl->l_start);
6665 __get_user(fl->l_len, &target_fl->l_len);
6666 __get_user(fl->l_pid, &target_fl->l_pid);
6667 unlock_user_struct(target_fl, target_flock_addr, 0);
6668 return 0;
6669}
6670
6671static inline abi_long copy_to_user_flock(abi_ulong target_flock_addr,
6672 const struct flock64 *fl)
6673{
6674 struct target_flock *target_fl;
6675 short l_type;
6676
6677 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6678 return -TARGET_EFAULT;
6679 }
6680
ae68ad9f 6681 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6682 __put_user(l_type, &target_fl->l_type);
6683 __put_user(fl->l_whence, &target_fl->l_whence);
6684 __put_user(fl->l_start, &target_fl->l_start);
6685 __put_user(fl->l_len, &target_fl->l_len);
6686 __put_user(fl->l_pid, &target_fl->l_pid);
6687 unlock_user_struct(target_fl, target_flock_addr, 1);
6688 return 0;
6689}
6690
6691typedef abi_long from_flock64_fn(struct flock64 *fl, abi_ulong target_addr);
6692typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
6693
6694#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
7f254c5c 6695static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
213d3e9e
PM
6696 abi_ulong target_flock_addr)
6697{
7f254c5c 6698 struct target_oabi_flock64 *target_fl;
ae68ad9f 6699 int l_type;
213d3e9e
PM
6700
6701 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6702 return -TARGET_EFAULT;
6703 }
6704
6705 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6706 l_type = target_to_host_flock(l_type);
6707 if (l_type < 0) {
6708 return l_type;
6709 }
6710 fl->l_type = l_type;
213d3e9e
PM
6711 __get_user(fl->l_whence, &target_fl->l_whence);
6712 __get_user(fl->l_start, &target_fl->l_start);
6713 __get_user(fl->l_len, &target_fl->l_len);
6714 __get_user(fl->l_pid, &target_fl->l_pid);
6715 unlock_user_struct(target_fl, target_flock_addr, 0);
6716 return 0;
6717}
6718
7f254c5c 6719static inline abi_long copy_to_user_oabi_flock64(abi_ulong target_flock_addr,
213d3e9e
PM
6720 const struct flock64 *fl)
6721{
7f254c5c 6722 struct target_oabi_flock64 *target_fl;
213d3e9e
PM
6723 short l_type;
6724
6725 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6726 return -TARGET_EFAULT;
6727 }
6728
ae68ad9f 6729 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6730 __put_user(l_type, &target_fl->l_type);
6731 __put_user(fl->l_whence, &target_fl->l_whence);
6732 __put_user(fl->l_start, &target_fl->l_start);
6733 __put_user(fl->l_len, &target_fl->l_len);
6734 __put_user(fl->l_pid, &target_fl->l_pid);
6735 unlock_user_struct(target_fl, target_flock_addr, 1);
6736 return 0;
6737}
6738#endif
6739
6740static inline abi_long copy_from_user_flock64(struct flock64 *fl,
6741 abi_ulong target_flock_addr)
6742{
6743 struct target_flock64 *target_fl;
ae68ad9f 6744 int l_type;
213d3e9e
PM
6745
6746 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6747 return -TARGET_EFAULT;
6748 }
6749
6750 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6751 l_type = target_to_host_flock(l_type);
6752 if (l_type < 0) {
6753 return l_type;
6754 }
6755 fl->l_type = l_type;
213d3e9e
PM
6756 __get_user(fl->l_whence, &target_fl->l_whence);
6757 __get_user(fl->l_start, &target_fl->l_start);
6758 __get_user(fl->l_len, &target_fl->l_len);
6759 __get_user(fl->l_pid, &target_fl->l_pid);
6760 unlock_user_struct(target_fl, target_flock_addr, 0);
6761 return 0;
6762}
6763
6764static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr,
6765 const struct flock64 *fl)
6766{
6767 struct target_flock64 *target_fl;
6768 short l_type;
6769
6770 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6771 return -TARGET_EFAULT;
6772 }
6773
ae68ad9f 6774 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6775 __put_user(l_type, &target_fl->l_type);
6776 __put_user(fl->l_whence, &target_fl->l_whence);
6777 __put_user(fl->l_start, &target_fl->l_start);
6778 __put_user(fl->l_len, &target_fl->l_len);
6779 __put_user(fl->l_pid, &target_fl->l_pid);
6780 unlock_user_struct(target_fl, target_flock_addr, 1);
6781 return 0;
6782}
6783
6784static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
6785{
43f238d7 6786 struct flock64 fl64;
8d5d3004
AS
6787#ifdef F_GETOWN_EX
6788 struct f_owner_ex fox;
6789 struct target_f_owner_ex *target_fox;
6790#endif
992f48a0 6791 abi_long ret;
5f106811
APR
6792 int host_cmd = target_to_host_fcntl_cmd(cmd);
6793
6794 if (host_cmd == -TARGET_EINVAL)
6795 return host_cmd;
53a5960a 6796
7775e9ec
FB
6797 switch(cmd) {
6798 case TARGET_F_GETLK:
213d3e9e
PM
6799 ret = copy_from_user_flock(&fl64, arg);
6800 if (ret) {
6801 return ret;
6802 }
435da5e7 6803 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec 6804 if (ret == 0) {
213d3e9e 6805 ret = copy_to_user_flock(arg, &fl64);
7775e9ec
FB
6806 }
6807 break;
3b46e624 6808
7775e9ec
FB
6809 case TARGET_F_SETLK:
6810 case TARGET_F_SETLKW:
213d3e9e
PM
6811 ret = copy_from_user_flock(&fl64, arg);
6812 if (ret) {
6813 return ret;
6814 }
435da5e7 6815 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec 6816 break;
3b46e624 6817
7775e9ec 6818 case TARGET_F_GETLK64:
2d92c682 6819 case TARGET_F_OFD_GETLK:
213d3e9e
PM
6820 ret = copy_from_user_flock64(&fl64, arg);
6821 if (ret) {
6822 return ret;
6823 }
435da5e7 6824 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
43f238d7 6825 if (ret == 0) {
213d3e9e 6826 ret = copy_to_user_flock64(arg, &fl64);
43f238d7 6827 }
9ee1fa2c 6828 break;
7775e9ec
FB
6829 case TARGET_F_SETLK64:
6830 case TARGET_F_SETLKW64:
2d92c682
AS
6831 case TARGET_F_OFD_SETLK:
6832 case TARGET_F_OFD_SETLKW:
213d3e9e
PM
6833 ret = copy_from_user_flock64(&fl64, arg);
6834 if (ret) {
6835 return ret;
6836 }
435da5e7 6837 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec
FB
6838 break;
6839
5f106811 6840 case TARGET_F_GETFL:
435da5e7 6841 ret = get_errno(safe_fcntl(fd, host_cmd, arg));
9ee1fa2c
FB
6842 if (ret >= 0) {
6843 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
6844 }
ffa65c3b
FB
6845 break;
6846
5f106811 6847 case TARGET_F_SETFL:
435da5e7
PM
6848 ret = get_errno(safe_fcntl(fd, host_cmd,
6849 target_to_host_bitmask(arg,
6850 fcntl_flags_tbl)));
5f106811
APR
6851 break;
6852
8d5d3004
AS
6853#ifdef F_GETOWN_EX
6854 case TARGET_F_GETOWN_EX:
435da5e7 6855 ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
8d5d3004
AS
6856 if (ret >= 0) {
6857 if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
6858 return -TARGET_EFAULT;
6859 target_fox->type = tswap32(fox.type);
6860 target_fox->pid = tswap32(fox.pid);
6861 unlock_user_struct(target_fox, arg, 1);
6862 }
6863 break;
6864#endif
6865
6866#ifdef F_SETOWN_EX
6867 case TARGET_F_SETOWN_EX:
6868 if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1))
6869 return -TARGET_EFAULT;
6870 fox.type = tswap32(target_fox->type);
6871 fox.pid = tswap32(target_fox->pid);
6872 unlock_user_struct(target_fox, arg, 0);
435da5e7 6873 ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
8d5d3004
AS
6874 break;
6875#endif
6876
5f106811 6877 case TARGET_F_SETSIG:
a7b4c9b1
TB
6878 ret = get_errno(safe_fcntl(fd, host_cmd, target_to_host_signal(arg)));
6879 break;
6880
5f106811 6881 case TARGET_F_GETSIG:
a7b4c9b1
TB
6882 ret = host_to_target_signal(get_errno(safe_fcntl(fd, host_cmd, arg)));
6883 break;
6884
6885 case TARGET_F_SETOWN:
6886 case TARGET_F_GETOWN:
7e22e546
UH
6887 case TARGET_F_SETLEASE:
6888 case TARGET_F_GETLEASE:
7e3b92ec
PM
6889 case TARGET_F_SETPIPE_SZ:
6890 case TARGET_F_GETPIPE_SZ:
435da5e7 6891 ret = get_errno(safe_fcntl(fd, host_cmd, arg));
ffa65c3b
FB
6892 break;
6893
7775e9ec 6894 default:
435da5e7 6895 ret = get_errno(safe_fcntl(fd, cmd, arg));
7775e9ec
FB
6896 break;
6897 }
6898 return ret;
6899}
6900
67867308 6901#ifdef USE_UID16
7775e9ec 6902
67867308
FB
6903static inline int high2lowuid(int uid)
6904{
6905 if (uid > 65535)
6906 return 65534;
6907 else
6908 return uid;
6909}
6910
6911static inline int high2lowgid(int gid)
6912{
6913 if (gid > 65535)
6914 return 65534;
6915 else
6916 return gid;
6917}
6918
6919static inline int low2highuid(int uid)
6920{
6921 if ((int16_t)uid == -1)
6922 return -1;
6923 else
6924 return uid;
6925}
6926
6927static inline int low2highgid(int gid)
6928{
6929 if ((int16_t)gid == -1)
6930 return -1;
6931 else
6932 return gid;
6933}
0c866a7e
RV
6934static inline int tswapid(int id)
6935{
6936 return tswap16(id);
6937}
76ca310a
PM
6938
6939#define put_user_id(x, gaddr) put_user_u16(x, gaddr)
6940
0c866a7e
RV
6941#else /* !USE_UID16 */
6942static inline int high2lowuid(int uid)
6943{
6944 return uid;
6945}
6946static inline int high2lowgid(int gid)
6947{
6948 return gid;
6949}
6950static inline int low2highuid(int uid)
6951{
6952 return uid;
6953}
6954static inline int low2highgid(int gid)
6955{
6956 return gid;
6957}
6958static inline int tswapid(int id)
6959{
6960 return tswap32(id);
6961}
76ca310a
PM
6962
6963#define put_user_id(x, gaddr) put_user_u32(x, gaddr)
6964
67867308 6965#endif /* USE_UID16 */
1b6b029e 6966
fd6f7798
PM
6967/* We must do direct syscalls for setting UID/GID, because we want to
6968 * implement the Linux system call semantics of "change only for this thread",
6969 * not the libc/POSIX semantics of "change for all threads in process".
6970 * (See http://ewontfix.com/17/ for more details.)
6971 * We use the 32-bit version of the syscalls if present; if it is not
6972 * then either the host architecture supports 32-bit UIDs natively with
6973 * the standard syscall, or the 16-bit UID is the best we can do.
6974 */
6975#ifdef __NR_setuid32
6976#define __NR_sys_setuid __NR_setuid32
6977#else
6978#define __NR_sys_setuid __NR_setuid
6979#endif
6980#ifdef __NR_setgid32
6981#define __NR_sys_setgid __NR_setgid32
6982#else
6983#define __NR_sys_setgid __NR_setgid
6984#endif
6985#ifdef __NR_setresuid32
6986#define __NR_sys_setresuid __NR_setresuid32
6987#else
6988#define __NR_sys_setresuid __NR_setresuid
6989#endif
6990#ifdef __NR_setresgid32
6991#define __NR_sys_setresgid __NR_setresgid32
6992#else
6993#define __NR_sys_setresgid __NR_setresgid
6994#endif
6995
6996_syscall1(int, sys_setuid, uid_t, uid)
6997_syscall1(int, sys_setgid, gid_t, gid)
6998_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
6999_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
7000
31e31b8a
FB
7001void syscall_init(void)
7002{
2ab83ea7
FB
7003 IOCTLEntry *ie;
7004 const argtype *arg_type;
7005 int size;
b92c47c1 7006 int i;
2ab83ea7 7007
8be656b8
AG
7008 thunk_init(STRUCT_MAX);
7009
001faf32 7010#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
5fafdf24 7011#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
31e31b8a
FB
7012#include "syscall_types.h"
7013#undef STRUCT
7014#undef STRUCT_SPECIAL
2ab83ea7 7015
dd6e957a
PM
7016 /* Build target_to_host_errno_table[] table from
7017 * host_to_target_errno_table[]. */
7018 for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
7019 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
7020 }
7021
2ab83ea7
FB
7022 /* we patch the ioctl size if necessary. We rely on the fact that
7023 no ioctl has all the bits at '1' in the size field */
7024 ie = ioctl_entries;
7025 while (ie->target_cmd != 0) {
7026 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
7027 TARGET_IOC_SIZEMASK) {
7028 arg_type = ie->arg_type;
7029 if (arg_type[0] != TYPE_PTR) {
5fafdf24 7030 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
2ab83ea7
FB
7031 ie->target_cmd);
7032 exit(1);
7033 }
7034 arg_type++;
7035 size = thunk_type_size(arg_type, 0);
5fafdf24 7036 ie->target_cmd = (ie->target_cmd &
2ab83ea7
FB
7037 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
7038 (size << TARGET_IOC_SIZESHIFT);
7039 }
b92c47c1 7040
2ab83ea7 7041 /* automatic consistency check if same arch */
872ea0c0
AZ
7042#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
7043 (defined(__x86_64__) && defined(TARGET_X86_64))
7044 if (unlikely(ie->target_cmd != ie->host_cmd)) {
7045 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
7046 ie->name, ie->target_cmd, ie->host_cmd);
2ab83ea7
FB
7047 }
7048#endif
7049 ie++;
7050 }
31e31b8a 7051}
c573ff67 7052
ce4defa0 7053#ifdef TARGET_NR_truncate64
992f48a0
BS
7054static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
7055 abi_long arg2,
7056 abi_long arg3,
7057 abi_long arg4)
ce4defa0 7058{
8bf8e9df 7059 if (regpairs_aligned(cpu_env, TARGET_NR_truncate64)) {
ce4defa0
PB
7060 arg2 = arg3;
7061 arg3 = arg4;
48e515d4 7062 }
ce4defa0
PB
7063 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
7064}
7065#endif
7066
7067#ifdef TARGET_NR_ftruncate64
992f48a0
BS
7068static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
7069 abi_long arg2,
7070 abi_long arg3,
7071 abi_long arg4)
ce4defa0 7072{
8bf8e9df 7073 if (regpairs_aligned(cpu_env, TARGET_NR_ftruncate64)) {
ce4defa0
PB
7074 arg2 = arg3;
7075 arg3 = arg4;
48e515d4 7076 }
ce4defa0
PB
7077 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
7078}
7079#endif
7080
859e8a89
AF
7081#if defined(TARGET_NR_timer_settime) || \
7082 (defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD))
2c86c90f 7083static inline abi_long target_to_host_itimerspec(struct itimerspec *host_its,
f4f1e10a
ECL
7084 abi_ulong target_addr)
7085{
2c86c90f
FB
7086 if (target_to_host_timespec(&host_its->it_interval, target_addr +
7087 offsetof(struct target_itimerspec,
7088 it_interval)) ||
7089 target_to_host_timespec(&host_its->it_value, target_addr +
7090 offsetof(struct target_itimerspec,
7091 it_value))) {
f4f1e10a
ECL
7092 return -TARGET_EFAULT;
7093 }
7094
f4f1e10a
ECL
7095 return 0;
7096}
859e8a89 7097#endif
f4f1e10a 7098
828cb3a1
FB
7099#if defined(TARGET_NR_timer_settime64) || \
7100 (defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD))
7101static inline abi_long target_to_host_itimerspec64(struct itimerspec *host_its,
7102 abi_ulong target_addr)
7103{
7104 if (target_to_host_timespec64(&host_its->it_interval, target_addr +
7105 offsetof(struct target__kernel_itimerspec,
7106 it_interval)) ||
7107 target_to_host_timespec64(&host_its->it_value, target_addr +
7108 offsetof(struct target__kernel_itimerspec,
7109 it_value))) {
7110 return -TARGET_EFAULT;
7111 }
7112
7113 return 0;
7114}
7115#endif
7116
859e8a89
AF
7117#if ((defined(TARGET_NR_timerfd_gettime) || \
7118 defined(TARGET_NR_timerfd_settime)) && defined(CONFIG_TIMERFD)) || \
2c86c90f 7119 defined(TARGET_NR_timer_gettime) || defined(TARGET_NR_timer_settime)
f4f1e10a 7120static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
2c86c90f
FB
7121 struct itimerspec *host_its)
7122{
7123 if (host_to_target_timespec(target_addr + offsetof(struct target_itimerspec,
7124 it_interval),
7125 &host_its->it_interval) ||
7126 host_to_target_timespec(target_addr + offsetof(struct target_itimerspec,
7127 it_value),
7128 &host_its->it_value)) {
f4f1e10a
ECL
7129 return -TARGET_EFAULT;
7130 }
f4f1e10a
ECL
7131 return 0;
7132}
859e8a89 7133#endif
f4f1e10a 7134
828cb3a1
FB
7135#if ((defined(TARGET_NR_timerfd_gettime64) || \
7136 defined(TARGET_NR_timerfd_settime64)) && defined(CONFIG_TIMERFD)) || \
7137 defined(TARGET_NR_timer_gettime64) || defined(TARGET_NR_timer_settime64)
7138static inline abi_long host_to_target_itimerspec64(abi_ulong target_addr,
7139 struct itimerspec *host_its)
7140{
7141 if (host_to_target_timespec64(target_addr +
7142 offsetof(struct target__kernel_itimerspec,
7143 it_interval),
7144 &host_its->it_interval) ||
7145 host_to_target_timespec64(target_addr +
7146 offsetof(struct target__kernel_itimerspec,
7147 it_value),
7148 &host_its->it_value)) {
7149 return -TARGET_EFAULT;
7150 }
7151 return 0;
7152}
7153#endif
7154
859e8a89
AF
7155#if defined(TARGET_NR_adjtimex) || \
7156 (defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME))
19f59bce
AM
7157static inline abi_long target_to_host_timex(struct timex *host_tx,
7158 abi_long target_addr)
7159{
7160 struct target_timex *target_tx;
7161
7162 if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
7163 return -TARGET_EFAULT;
7164 }
7165
7166 __get_user(host_tx->modes, &target_tx->modes);
7167 __get_user(host_tx->offset, &target_tx->offset);
7168 __get_user(host_tx->freq, &target_tx->freq);
7169 __get_user(host_tx->maxerror, &target_tx->maxerror);
7170 __get_user(host_tx->esterror, &target_tx->esterror);
7171 __get_user(host_tx->status, &target_tx->status);
7172 __get_user(host_tx->constant, &target_tx->constant);
7173 __get_user(host_tx->precision, &target_tx->precision);
7174 __get_user(host_tx->tolerance, &target_tx->tolerance);
7175 __get_user(host_tx->time.tv_sec, &target_tx->time.tv_sec);
7176 __get_user(host_tx->time.tv_usec, &target_tx->time.tv_usec);
7177 __get_user(host_tx->tick, &target_tx->tick);
7178 __get_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7179 __get_user(host_tx->jitter, &target_tx->jitter);
7180 __get_user(host_tx->shift, &target_tx->shift);
7181 __get_user(host_tx->stabil, &target_tx->stabil);
7182 __get_user(host_tx->jitcnt, &target_tx->jitcnt);
7183 __get_user(host_tx->calcnt, &target_tx->calcnt);
7184 __get_user(host_tx->errcnt, &target_tx->errcnt);
7185 __get_user(host_tx->stbcnt, &target_tx->stbcnt);
7186 __get_user(host_tx->tai, &target_tx->tai);
7187
7188 unlock_user_struct(target_tx, target_addr, 0);
7189 return 0;
7190}
7191
7192static inline abi_long host_to_target_timex(abi_long target_addr,
7193 struct timex *host_tx)
7194{
7195 struct target_timex *target_tx;
7196
7197 if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) {
7198 return -TARGET_EFAULT;
7199 }
7200
7201 __put_user(host_tx->modes, &target_tx->modes);
7202 __put_user(host_tx->offset, &target_tx->offset);
7203 __put_user(host_tx->freq, &target_tx->freq);
7204 __put_user(host_tx->maxerror, &target_tx->maxerror);
7205 __put_user(host_tx->esterror, &target_tx->esterror);
7206 __put_user(host_tx->status, &target_tx->status);
7207 __put_user(host_tx->constant, &target_tx->constant);
7208 __put_user(host_tx->precision, &target_tx->precision);
7209 __put_user(host_tx->tolerance, &target_tx->tolerance);
7210 __put_user(host_tx->time.tv_sec, &target_tx->time.tv_sec);
7211 __put_user(host_tx->time.tv_usec, &target_tx->time.tv_usec);
7212 __put_user(host_tx->tick, &target_tx->tick);
7213 __put_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7214 __put_user(host_tx->jitter, &target_tx->jitter);
7215 __put_user(host_tx->shift, &target_tx->shift);
7216 __put_user(host_tx->stabil, &target_tx->stabil);
7217 __put_user(host_tx->jitcnt, &target_tx->jitcnt);
7218 __put_user(host_tx->calcnt, &target_tx->calcnt);
7219 __put_user(host_tx->errcnt, &target_tx->errcnt);
7220 __put_user(host_tx->stbcnt, &target_tx->stbcnt);
7221 __put_user(host_tx->tai, &target_tx->tai);
7222
7223 unlock_user_struct(target_tx, target_addr, 1);
7224 return 0;
7225}
859e8a89 7226#endif
19f59bce 7227
6ac03b2c
FB
7228
7229#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
7230static inline abi_long target_to_host_timex64(struct timex *host_tx,
7231 abi_long target_addr)
7232{
7233 struct target__kernel_timex *target_tx;
7234
7235 if (copy_from_user_timeval64(&host_tx->time, target_addr +
7236 offsetof(struct target__kernel_timex,
7237 time))) {
7238 return -TARGET_EFAULT;
7239 }
7240
7241 if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
7242 return -TARGET_EFAULT;
7243 }
7244
7245 __get_user(host_tx->modes, &target_tx->modes);
7246 __get_user(host_tx->offset, &target_tx->offset);
7247 __get_user(host_tx->freq, &target_tx->freq);
7248 __get_user(host_tx->maxerror, &target_tx->maxerror);
7249 __get_user(host_tx->esterror, &target_tx->esterror);
7250 __get_user(host_tx->status, &target_tx->status);
7251 __get_user(host_tx->constant, &target_tx->constant);
7252 __get_user(host_tx->precision, &target_tx->precision);
7253 __get_user(host_tx->tolerance, &target_tx->tolerance);
7254 __get_user(host_tx->tick, &target_tx->tick);
7255 __get_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7256 __get_user(host_tx->jitter, &target_tx->jitter);
7257 __get_user(host_tx->shift, &target_tx->shift);
7258 __get_user(host_tx->stabil, &target_tx->stabil);
7259 __get_user(host_tx->jitcnt, &target_tx->jitcnt);
7260 __get_user(host_tx->calcnt, &target_tx->calcnt);
7261 __get_user(host_tx->errcnt, &target_tx->errcnt);
7262 __get_user(host_tx->stbcnt, &target_tx->stbcnt);
7263 __get_user(host_tx->tai, &target_tx->tai);
7264
7265 unlock_user_struct(target_tx, target_addr, 0);
7266 return 0;
7267}
7268
7269static inline abi_long host_to_target_timex64(abi_long target_addr,
7270 struct timex *host_tx)
7271{
7272 struct target__kernel_timex *target_tx;
7273
7274 if (copy_to_user_timeval64(target_addr +
7275 offsetof(struct target__kernel_timex, time),
7276 &host_tx->time)) {
7277 return -TARGET_EFAULT;
7278 }
7279
7280 if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) {
7281 return -TARGET_EFAULT;
7282 }
7283
7284 __put_user(host_tx->modes, &target_tx->modes);
7285 __put_user(host_tx->offset, &target_tx->offset);
7286 __put_user(host_tx->freq, &target_tx->freq);
7287 __put_user(host_tx->maxerror, &target_tx->maxerror);
7288 __put_user(host_tx->esterror, &target_tx->esterror);
7289 __put_user(host_tx->status, &target_tx->status);
7290 __put_user(host_tx->constant, &target_tx->constant);
7291 __put_user(host_tx->precision, &target_tx->precision);
7292 __put_user(host_tx->tolerance, &target_tx->tolerance);
7293 __put_user(host_tx->tick, &target_tx->tick);
7294 __put_user(host_tx->ppsfreq, &target_tx->ppsfreq);
7295 __put_user(host_tx->jitter, &target_tx->jitter);
7296 __put_user(host_tx->shift, &target_tx->shift);
7297 __put_user(host_tx->stabil, &target_tx->stabil);
7298 __put_user(host_tx->jitcnt, &target_tx->jitcnt);
7299 __put_user(host_tx->calcnt, &target_tx->calcnt);
7300 __put_user(host_tx->errcnt, &target_tx->errcnt);
7301 __put_user(host_tx->stbcnt, &target_tx->stbcnt);
7302 __put_user(host_tx->tai, &target_tx->tai);
7303
7304 unlock_user_struct(target_tx, target_addr, 1);
7305 return 0;
7306}
7307#endif
7308
c065976f
PM
7309static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
7310 abi_ulong target_addr)
7311{
7312 struct target_sigevent *target_sevp;
7313
7314 if (!lock_user_struct(VERIFY_READ, target_sevp, target_addr, 1)) {
7315 return -TARGET_EFAULT;
7316 }
7317
7318 /* This union is awkward on 64 bit systems because it has a 32 bit
7319 * integer and a pointer in it; we follow the conversion approach
7320 * used for handling sigval types in signal.c so the guest should get
7321 * the correct value back even if we did a 64 bit byteswap and it's
7322 * using the 32 bit integer.
7323 */
7324 host_sevp->sigev_value.sival_ptr =
7325 (void *)(uintptr_t)tswapal(target_sevp->sigev_value.sival_ptr);
7326 host_sevp->sigev_signo =
7327 target_to_host_signal(tswap32(target_sevp->sigev_signo));
7328 host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
7329 host_sevp->_sigev_un._tid = tswap32(target_sevp->_sigev_un._tid);
7330
7331 unlock_user_struct(target_sevp, target_addr, 1);
7332 return 0;
7333}
7334
6f6a4032
TM
7335#if defined(TARGET_NR_mlockall)
7336static inline int target_to_host_mlockall_arg(int arg)
7337{
7338 int result = 0;
7339
02e5d7d7 7340 if (arg & TARGET_MCL_CURRENT) {
6f6a4032
TM
7341 result |= MCL_CURRENT;
7342 }
02e5d7d7 7343 if (arg & TARGET_MCL_FUTURE) {
6f6a4032
TM
7344 result |= MCL_FUTURE;
7345 }
02e5d7d7
FB
7346#ifdef MCL_ONFAULT
7347 if (arg & TARGET_MCL_ONFAULT) {
7348 result |= MCL_ONFAULT;
7349 }
7350#endif
7351
6f6a4032
TM
7352 return result;
7353}
7354#endif
7355
4f7f8924
AR
7356#if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) || \
7357 defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) || \
7358 defined(TARGET_NR_newfstatat))
6a24a778
AZ
7359static inline abi_long host_to_target_stat64(void *cpu_env,
7360 abi_ulong target_addr,
7361 struct stat *host_st)
7362{
09701199 7363#if defined(TARGET_ARM) && defined(TARGET_ABI32)
6a24a778
AZ
7364 if (((CPUARMState *)cpu_env)->eabi) {
7365 struct target_eabi_stat64 *target_st;
7366
7367 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
7368 return -TARGET_EFAULT;
7369 memset(target_st, 0, sizeof(struct target_eabi_stat64));
7370 __put_user(host_st->st_dev, &target_st->st_dev);
7371 __put_user(host_st->st_ino, &target_st->st_ino);
7372#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
7373 __put_user(host_st->st_ino, &target_st->__st_ino);
7374#endif
7375 __put_user(host_st->st_mode, &target_st->st_mode);
7376 __put_user(host_st->st_nlink, &target_st->st_nlink);
7377 __put_user(host_st->st_uid, &target_st->st_uid);
7378 __put_user(host_st->st_gid, &target_st->st_gid);
7379 __put_user(host_st->st_rdev, &target_st->st_rdev);
7380 __put_user(host_st->st_size, &target_st->st_size);
7381 __put_user(host_st->st_blksize, &target_st->st_blksize);
7382 __put_user(host_st->st_blocks, &target_st->st_blocks);
7383 __put_user(host_st->st_atime, &target_st->target_st_atime);
7384 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
7385 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5f992db6
CYT
7386#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
7387 __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
7388 __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
7389 __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
7390#endif
6a24a778
AZ
7391 unlock_user_struct(target_st, target_addr, 1);
7392 } else
7393#endif
7394 {
20d155bc 7395#if defined(TARGET_HAS_STRUCT_STAT64)
6a24a778 7396 struct target_stat64 *target_st;
20d155bc
SW
7397#else
7398 struct target_stat *target_st;
9d33b76b 7399#endif
6a24a778
AZ
7400
7401 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
7402 return -TARGET_EFAULT;
9d33b76b 7403 memset(target_st, 0, sizeof(*target_st));
6a24a778
AZ
7404 __put_user(host_st->st_dev, &target_st->st_dev);
7405 __put_user(host_st->st_ino, &target_st->st_ino);
7406#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
7407 __put_user(host_st->st_ino, &target_st->__st_ino);
7408#endif
7409 __put_user(host_st->st_mode, &target_st->st_mode);
7410 __put_user(host_st->st_nlink, &target_st->st_nlink);
7411 __put_user(host_st->st_uid, &target_st->st_uid);
7412 __put_user(host_st->st_gid, &target_st->st_gid);
7413 __put_user(host_st->st_rdev, &target_st->st_rdev);
7414 /* XXX: better use of kernel struct */
7415 __put_user(host_st->st_size, &target_st->st_size);
7416 __put_user(host_st->st_blksize, &target_st->st_blksize);
7417 __put_user(host_st->st_blocks, &target_st->st_blocks);
7418 __put_user(host_st->st_atime, &target_st->target_st_atime);
7419 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
7420 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5f992db6
CYT
7421#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
7422 __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
7423 __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
7424 __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
7425#endif
6a24a778
AZ
7426 unlock_user_struct(target_st, target_addr, 1);
7427 }
7428
7429 return 0;
7430}
4f7f8924 7431#endif
6a24a778 7432
efa92184
AR
7433#if defined(TARGET_NR_statx) && defined(__NR_statx)
7434static inline abi_long host_to_target_statx(struct target_statx *host_stx,
7435 abi_ulong target_addr)
7436{
7437 struct target_statx *target_stx;
7438
7439 if (!lock_user_struct(VERIFY_WRITE, target_stx, target_addr, 0)) {
7440 return -TARGET_EFAULT;
7441 }
7442 memset(target_stx, 0, sizeof(*target_stx));
7443
7444 __put_user(host_stx->stx_mask, &target_stx->stx_mask);
7445 __put_user(host_stx->stx_blksize, &target_stx->stx_blksize);
7446 __put_user(host_stx->stx_attributes, &target_stx->stx_attributes);
7447 __put_user(host_stx->stx_nlink, &target_stx->stx_nlink);
7448 __put_user(host_stx->stx_uid, &target_stx->stx_uid);
7449 __put_user(host_stx->stx_gid, &target_stx->stx_gid);
7450 __put_user(host_stx->stx_mode, &target_stx->stx_mode);
7451 __put_user(host_stx->stx_ino, &target_stx->stx_ino);
7452 __put_user(host_stx->stx_size, &target_stx->stx_size);
7453 __put_user(host_stx->stx_blocks, &target_stx->stx_blocks);
7454 __put_user(host_stx->stx_attributes_mask, &target_stx->stx_attributes_mask);
7455 __put_user(host_stx->stx_atime.tv_sec, &target_stx->stx_atime.tv_sec);
7456 __put_user(host_stx->stx_atime.tv_nsec, &target_stx->stx_atime.tv_nsec);
d1e26707
AC
7457 __put_user(host_stx->stx_btime.tv_sec, &target_stx->stx_btime.tv_sec);
7458 __put_user(host_stx->stx_btime.tv_nsec, &target_stx->stx_btime.tv_nsec);
7459 __put_user(host_stx->stx_ctime.tv_sec, &target_stx->stx_ctime.tv_sec);
7460 __put_user(host_stx->stx_ctime.tv_nsec, &target_stx->stx_ctime.tv_nsec);
7461 __put_user(host_stx->stx_mtime.tv_sec, &target_stx->stx_mtime.tv_sec);
7462 __put_user(host_stx->stx_mtime.tv_nsec, &target_stx->stx_mtime.tv_nsec);
efa92184
AR
7463 __put_user(host_stx->stx_rdev_major, &target_stx->stx_rdev_major);
7464 __put_user(host_stx->stx_rdev_minor, &target_stx->stx_rdev_minor);
7465 __put_user(host_stx->stx_dev_major, &target_stx->stx_dev_major);
7466 __put_user(host_stx->stx_dev_minor, &target_stx->stx_dev_minor);
7467
7468 unlock_user_struct(target_stx, target_addr, 1);
7469
7470 return 0;
7471}
7472#endif
7473
14690296
AF
7474static int do_sys_futex(int *uaddr, int op, int val,
7475 const struct timespec *timeout, int *uaddr2,
7476 int val3)
7477{
7478#if HOST_LONG_BITS == 64
7479#if defined(__NR_futex)
7480 /* always a 64-bit time_t, it doesn't define _time64 version */
7481 return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
7482
7483#endif
7484#else /* HOST_LONG_BITS == 64 */
7485#if defined(__NR_futex_time64)
7486 if (sizeof(timeout->tv_sec) == 8) {
7487 /* _time64 function on 32bit arch */
7488 return sys_futex_time64(uaddr, op, val, timeout, uaddr2, val3);
7489 }
7490#endif
7491#if defined(__NR_futex)
7492 /* old function on 32bit arch */
7493 return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
7494#endif
7495#endif /* HOST_LONG_BITS == 64 */
7496 g_assert_not_reached();
7497}
7498
7499static int do_safe_futex(int *uaddr, int op, int val,
7500 const struct timespec *timeout, int *uaddr2,
7501 int val3)
7502{
7503#if HOST_LONG_BITS == 64
7504#if defined(__NR_futex)
7505 /* always a 64-bit time_t, it doesn't define _time64 version */
7506 return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
7507#endif
7508#else /* HOST_LONG_BITS == 64 */
7509#if defined(__NR_futex_time64)
7510 if (sizeof(timeout->tv_sec) == 8) {
7511 /* _time64 function on 32bit arch */
7512 return get_errno(safe_futex_time64(uaddr, op, val, timeout, uaddr2,
7513 val3));
7514 }
7515#endif
7516#if defined(__NR_futex)
7517 /* old function on 32bit arch */
7518 return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
7519#endif
7520#endif /* HOST_LONG_BITS == 64 */
7521 return -TARGET_ENOSYS;
7522}
efa92184 7523
bd0c5661
PB
7524/* ??? Using host futex calls even when target atomic operations
7525 are not really atomic probably breaks things. However implementing
7526 futexes locally would make futexes shared between multiple processes
7527 tricky. However they're probably useless because guest atomic
7528 operations won't work either. */
859e8a89 7529#if defined(TARGET_NR_futex)
8fcd3692
BS
7530static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
7531 target_ulong uaddr2, int val3)
bd0c5661
PB
7532{
7533 struct timespec ts, *pts;
a16aae0c 7534 int base_op;
bd0c5661
PB
7535
7536 /* ??? We assume FUTEX_* constants are the same on both host
7537 and target. */
a29ccd63 7538#ifdef FUTEX_CMD_MASK
a16aae0c 7539 base_op = op & FUTEX_CMD_MASK;
a29ccd63 7540#else
a16aae0c 7541 base_op = op;
a29ccd63 7542#endif
a16aae0c 7543 switch (base_op) {
bd0c5661 7544 case FUTEX_WAIT:
cce246e0 7545 case FUTEX_WAIT_BITSET:
bd0c5661
PB
7546 if (timeout) {
7547 pts = &ts;
7548 target_to_host_timespec(pts, timeout);
7549 } else {
7550 pts = NULL;
7551 }
14690296 7552 return do_safe_futex(g2h(uaddr), op, tswap32(val), pts, NULL, val3);
bd0c5661 7553 case FUTEX_WAKE:
14690296 7554 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
bd0c5661 7555 case FUTEX_FD:
14690296 7556 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
bd0c5661 7557 case FUTEX_REQUEUE:
bd0c5661 7558 case FUTEX_CMP_REQUEUE:
a16aae0c
NF
7559 case FUTEX_WAKE_OP:
7560 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
7561 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
7562 But the prototype takes a `struct timespec *'; insert casts
7563 to satisfy the compiler. We do not need to tswap TIMEOUT
7564 since it's not compared to guest memory. */
7565 pts = (struct timespec *)(uintptr_t) timeout;
14690296
AF
7566 return do_safe_futex(g2h(uaddr), op, val, pts, g2h(uaddr2),
7567 (base_op == FUTEX_CMP_REQUEUE
7568 ? tswap32(val3)
7569 : val3));
bd0c5661
PB
7570 default:
7571 return -TARGET_ENOSYS;
7572 }
7573}
859e8a89 7574#endif
14690296
AF
7575
7576#if defined(TARGET_NR_futex_time64)
7577static int do_futex_time64(target_ulong uaddr, int op, int val, target_ulong timeout,
7578 target_ulong uaddr2, int val3)
7579{
7580 struct timespec ts, *pts;
7581 int base_op;
7582
7583 /* ??? We assume FUTEX_* constants are the same on both host
7584 and target. */
7585#ifdef FUTEX_CMD_MASK
7586 base_op = op & FUTEX_CMD_MASK;
7587#else
7588 base_op = op;
7589#endif
7590 switch (base_op) {
7591 case FUTEX_WAIT:
7592 case FUTEX_WAIT_BITSET:
7593 if (timeout) {
7594 pts = &ts;
7595 target_to_host_timespec64(pts, timeout);
7596 } else {
7597 pts = NULL;
7598 }
7599 return do_safe_futex(g2h(uaddr), op, tswap32(val), pts, NULL, val3);
7600 case FUTEX_WAKE:
7601 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
7602 case FUTEX_FD:
7603 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
7604 case FUTEX_REQUEUE:
7605 case FUTEX_CMP_REQUEUE:
7606 case FUTEX_WAKE_OP:
7607 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
7608 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
7609 But the prototype takes a `struct timespec *'; insert casts
7610 to satisfy the compiler. We do not need to tswap TIMEOUT
7611 since it's not compared to guest memory. */
7612 pts = (struct timespec *)(uintptr_t) timeout;
7613 return do_safe_futex(g2h(uaddr), op, val, pts, g2h(uaddr2),
7614 (base_op == FUTEX_CMP_REQUEUE
7615 ? tswap32(val3)
7616 : val3));
7617 default:
7618 return -TARGET_ENOSYS;
7619 }
7620}
7621#endif
7622
0f0426f3
LV
7623#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7624static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
7625 abi_long handle, abi_long mount_id,
7626 abi_long flags)
7627{
7628 struct file_handle *target_fh;
7629 struct file_handle *fh;
7630 int mid = 0;
7631 abi_long ret;
7632 char *name;
7633 unsigned int size, total_size;
7634
7635 if (get_user_s32(size, handle)) {
7636 return -TARGET_EFAULT;
7637 }
7638
7639 name = lock_user_string(pathname);
7640 if (!name) {
7641 return -TARGET_EFAULT;
7642 }
7643
7644 total_size = sizeof(struct file_handle) + size;
7645 target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
7646 if (!target_fh) {
7647 unlock_user(name, pathname, 0);
7648 return -TARGET_EFAULT;
7649 }
7650
7651 fh = g_malloc0(total_size);
7652 fh->handle_bytes = size;
7653
7654 ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
7655 unlock_user(name, pathname, 0);
7656
7657 /* man name_to_handle_at(2):
7658 * Other than the use of the handle_bytes field, the caller should treat
7659 * the file_handle structure as an opaque data type
7660 */
7661
7662 memcpy(target_fh, fh, total_size);
7663 target_fh->handle_bytes = tswap32(fh->handle_bytes);
7664 target_fh->handle_type = tswap32(fh->handle_type);
7665 g_free(fh);
7666 unlock_user(target_fh, handle, total_size);
7667
7668 if (put_user_s32(mid, mount_id)) {
7669 return -TARGET_EFAULT;
7670 }
7671
7672 return ret;
7673
7674}
7675#endif
7676
7677#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7678static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
7679 abi_long flags)
7680{
7681 struct file_handle *target_fh;
7682 struct file_handle *fh;
7683 unsigned int size, total_size;
7684 abi_long ret;
7685
7686 if (get_user_s32(size, handle)) {
7687 return -TARGET_EFAULT;
7688 }
7689
7690 total_size = sizeof(struct file_handle) + size;
7691 target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
7692 if (!target_fh) {
7693 return -TARGET_EFAULT;
7694 }
7695
e9d49d51 7696 fh = g_memdup(target_fh, total_size);
0f0426f3
LV
7697 fh->handle_bytes = size;
7698 fh->handle_type = tswap32(target_fh->handle_type);
7699
7700 ret = get_errno(open_by_handle_at(mount_fd, fh,
7701 target_to_host_bitmask(flags, fcntl_flags_tbl)));
7702
7703 g_free(fh);
7704
7705 unlock_user(target_fh, handle, total_size);
7706
7707 return ret;
7708}
7709#endif
bd0c5661 7710
e36800c9
LV
7711#if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
7712
e36800c9
LV
7713static abi_long do_signalfd4(int fd, abi_long mask, int flags)
7714{
7715 int host_flags;
7716 target_sigset_t *target_mask;
7717 sigset_t host_mask;
7718 abi_long ret;
7719
7720 if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
7721 return -TARGET_EINVAL;
7722 }
7723 if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
7724 return -TARGET_EFAULT;
7725 }
7726
7727 target_to_host_sigset(&host_mask, target_mask);
7728
7729 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
7730
7731 ret = get_errno(signalfd(fd, &host_mask, host_flags));
7732 if (ret >= 0) {
7733 fd_trans_register(ret, &target_signalfd_trans);
7734 }
7735
7736 unlock_user_struct(target_mask, mask, 0);
7737
7738 return ret;
7739}
7740#endif
7741
1d9d8b55
PB
7742/* Map host to target signal numbers for the wait family of syscalls.
7743 Assume all other status bits are the same. */
a05c6409 7744int host_to_target_waitstatus(int status)
1d9d8b55
PB
7745{
7746 if (WIFSIGNALED(status)) {
7747 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
7748 }
7749 if (WIFSTOPPED(status)) {
7750 return (host_to_target_signal(WSTOPSIG(status)) << 8)
7751 | (status & 0xff);
7752 }
7753 return status;
7754}
7755
76b94245
WVS
7756static int open_self_cmdline(void *cpu_env, int fd)
7757{
29a0af61 7758 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
58de8b96
AS
7759 struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
7760 int i;
76b94245 7761
58de8b96
AS
7762 for (i = 0; i < bprm->argc; i++) {
7763 size_t len = strlen(bprm->argv[i]) + 1;
76b94245 7764
58de8b96 7765 if (write(fd, bprm->argv[i], len) != len) {
76b94245 7766 return -1;
76b94245
WVS
7767 }
7768 }
7769
58de8b96 7770 return 0;
76b94245
WVS
7771}
7772
36c08d49
AG
7773static int open_self_maps(void *cpu_env, int fd)
7774{
29a0af61 7775 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7776 TaskState *ts = cpu->opaque;
01ef6b9e
AB
7777 GSList *map_info = read_self_maps();
7778 GSList *s;
bb55173c 7779 int count;
1a49ef2a 7780
01ef6b9e
AB
7781 for (s = map_info; s; s = g_slist_next(s)) {
7782 MapInfo *e = (MapInfo *) s->data;
1a49ef2a 7783
01ef6b9e
AB
7784 if (h2g_valid(e->start)) {
7785 unsigned long min = e->start;
7786 unsigned long max = e->end;
d67f4aaa 7787 int flags = page_get_flags(h2g(min));
01ef6b9e
AB
7788 const char *path;
7789
7790 max = h2g_valid(max - 1) ?
7791 max : (uintptr_t) g2h(GUEST_ADDR_MAX) + 1;
7792
d67f4aaa
MI
7793 if (page_check_range(h2g(min), max - min, flags) == -1) {
7794 continue;
7795 }
01ef6b9e 7796
d67f4aaa 7797 if (h2g(min) == ts->info->stack_limit) {
bb55173c 7798 path = "[stack]";
01ef6b9e
AB
7799 } else {
7800 path = e->path;
d67f4aaa 7801 }
01ef6b9e 7802
bb55173c
AB
7803 count = dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr
7804 " %c%c%c%c %08" PRIx64 " %s %"PRId64,
7805 h2g(min), h2g(max - 1) + 1,
7806 e->is_read ? 'r' : '-',
7807 e->is_write ? 'w' : '-',
7808 e->is_exec ? 'x' : '-',
7809 e->is_priv ? 'p' : '-',
7810 (uint64_t) e->offset, e->dev, e->inode);
7811 if (path) {
7812 dprintf(fd, "%*s%s\n", 73 - count, "", path);
7813 } else {
7814 dprintf(fd, "\n");
7815 }
1a49ef2a
AG
7816 }
7817 }
7818
01ef6b9e
AB
7819 free_self_maps(map_info);
7820
bf02adcd
RH
7821#ifdef TARGET_VSYSCALL_PAGE
7822 /*
7823 * We only support execution from the vsyscall page.
7824 * This is as if CONFIG_LEGACY_VSYSCALL_XONLY=y from v5.3.
7825 */
bb55173c
AB
7826 count = dprintf(fd, TARGET_FMT_lx "-" TARGET_FMT_lx
7827 " --xp 00000000 00:00 0",
7828 TARGET_VSYSCALL_PAGE, TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE);
7829 dprintf(fd, "%*s%s\n", 73 - count, "", "[vsyscall]");
bf02adcd
RH
7830#endif
7831
36c08d49
AG
7832 return 0;
7833}
7834
480b8e7d
AG
7835static int open_self_stat(void *cpu_env, int fd)
7836{
29a0af61 7837 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7838 TaskState *ts = cpu->opaque;
7ad4d5a4 7839 g_autoptr(GString) buf = g_string_new(NULL);
480b8e7d
AG
7840 int i;
7841
7842 for (i = 0; i < 44; i++) {
7ad4d5a4
AB
7843 if (i == 0) {
7844 /* pid */
7845 g_string_printf(buf, FMT_pid " ", getpid());
7846 } else if (i == 1) {
7847 /* app name */
7848 gchar *bin = g_strrstr(ts->bprm->argv[0], "/");
7849 bin = bin ? bin + 1 : ts->bprm->argv[0];
7850 g_string_printf(buf, "(%.15s) ", bin);
7851 } else if (i == 27) {
7852 /* stack bottom */
7853 g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
7854 } else {
7855 /* for the rest, there is MasterCard */
7856 g_string_printf(buf, "0%c", i == 43 ? '\n' : ' ');
7857 }
7858
7859 if (write(fd, buf->str, buf->len) != buf->len) {
7860 return -1;
7861 }
480b8e7d
AG
7862 }
7863
7864 return 0;
7865}
7866
257450ee
AG
7867static int open_self_auxv(void *cpu_env, int fd)
7868{
29a0af61 7869 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7870 TaskState *ts = cpu->opaque;
257450ee
AG
7871 abi_ulong auxv = ts->info->saved_auxv;
7872 abi_ulong len = ts->info->auxv_len;
7873 char *ptr;
7874
7875 /*
7876 * Auxiliary vector is stored in target process stack.
7877 * read in whole auxv vector and copy it to file
7878 */
7879 ptr = lock_user(VERIFY_READ, auxv, len, 0);
7880 if (ptr != NULL) {
7881 while (len > 0) {
7882 ssize_t r;
7883 r = write(fd, ptr, len);
7884 if (r <= 0) {
7885 break;
7886 }
7887 len -= r;
7888 ptr += r;
7889 }
7890 lseek(fd, 0, SEEK_SET);
7891 unlock_user(ptr, auxv, len);
7892 }
7893
7894 return 0;
7895}
7896
463d8e73
AS
7897static int is_proc_myself(const char *filename, const char *entry)
7898{
7899 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
7900 filename += strlen("/proc/");
7901 if (!strncmp(filename, "self/", strlen("self/"))) {
7902 filename += strlen("self/");
7903 } else if (*filename >= '1' && *filename <= '9') {
7904 char myself[80];
7905 snprintf(myself, sizeof(myself), "%d/", getpid());
7906 if (!strncmp(filename, myself, strlen(myself))) {
7907 filename += strlen(myself);
7908 } else {
7909 return 0;
7910 }
7911 } else {
7912 return 0;
7913 }
7914 if (!strcmp(filename, entry)) {
7915 return 1;
7916 }
7917 }
7918 return 0;
7919}
7920
fff69382 7921#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \
93a5661d 7922 defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
de6b9933
LV
7923static int is_proc(const char *filename, const char *entry)
7924{
7925 return strcmp(filename, entry) == 0;
7926}
fff69382 7927#endif
de6b9933 7928
fff69382 7929#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
de6b9933
LV
7930static int open_net_route(void *cpu_env, int fd)
7931{
7932 FILE *fp;
7933 char *line = NULL;
7934 size_t len = 0;
7935 ssize_t read;
7936
7937 fp = fopen("/proc/net/route", "r");
7938 if (fp == NULL) {
a3ca7bb2 7939 return -1;
de6b9933
LV
7940 }
7941
7942 /* read header */
7943
7944 read = getline(&line, &len, fp);
7945 dprintf(fd, "%s", line);
7946
7947 /* read routes */
7948
7949 while ((read = getline(&line, &len, fp)) != -1) {
7950 char iface[16];
7951 uint32_t dest, gw, mask;
7952 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
9d0bd0cd
PM
7953 int fields;
7954
7955 fields = sscanf(line,
7956 "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
7957 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
7958 &mask, &mtu, &window, &irtt);
7959 if (fields != 11) {
7960 continue;
7961 }
de6b9933
LV
7962 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
7963 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
7964 metric, tswap32(mask), mtu, window, irtt);
7965 }
7966
7967 free(line);
7968 fclose(fp);
7969
7970 return 0;
7971}
7972#endif
7973
fff69382
LV
7974#if defined(TARGET_SPARC)
7975static int open_cpuinfo(void *cpu_env, int fd)
7976{
7977 dprintf(fd, "type\t\t: sun4u\n");
7978 return 0;
7979}
7980#endif
7981
93a5661d
HD
7982#if defined(TARGET_HPPA)
7983static int open_cpuinfo(void *cpu_env, int fd)
7984{
7985 dprintf(fd, "cpu family\t: PA-RISC 1.1e\n");
7986 dprintf(fd, "cpu\t\t: PA7300LC (PCX-L2)\n");
7987 dprintf(fd, "capabilities\t: os32\n");
7988 dprintf(fd, "model\t\t: 9000/778/B160L\n");
7989 dprintf(fd, "model name\t: Merlin L2 160 QEMU (9000/778/B160L)\n");
7990 return 0;
7991}
7992#endif
7993
4ab6713e
LV
7994#if defined(TARGET_M68K)
7995static int open_hardware(void *cpu_env, int fd)
7996{
7997 dprintf(fd, "Model:\t\tqemu-m68k\n");
7998 return 0;
7999}
8000#endif
8001
0b2effd7 8002static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
3be14d05
AG
8003{
8004 struct fake_open {
8005 const char *filename;
8006 int (*fill)(void *cpu_env, int fd);
de6b9933 8007 int (*cmp)(const char *s1, const char *s2);
3be14d05
AG
8008 };
8009 const struct fake_open *fake_open;
8010 static const struct fake_open fakes[] = {
de6b9933
LV
8011 { "maps", open_self_maps, is_proc_myself },
8012 { "stat", open_self_stat, is_proc_myself },
8013 { "auxv", open_self_auxv, is_proc_myself },
76b94245 8014 { "cmdline", open_self_cmdline, is_proc_myself },
de6b9933
LV
8015#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
8016 { "/proc/net/route", open_net_route, is_proc },
fff69382 8017#endif
93a5661d 8018#if defined(TARGET_SPARC) || defined(TARGET_HPPA)
fff69382 8019 { "/proc/cpuinfo", open_cpuinfo, is_proc },
4ab6713e
LV
8020#endif
8021#if defined(TARGET_M68K)
8022 { "/proc/hardware", open_hardware, is_proc },
de6b9933
LV
8023#endif
8024 { NULL, NULL, NULL }
3be14d05
AG
8025 };
8026
aa07f5ec
MO
8027 if (is_proc_myself(pathname, "exe")) {
8028 int execfd = qemu_getauxval(AT_EXECFD);
c10a0738 8029 return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
aa07f5ec
MO
8030 }
8031
3be14d05 8032 for (fake_open = fakes; fake_open->filename; fake_open++) {
de6b9933 8033 if (fake_open->cmp(pathname, fake_open->filename)) {
3be14d05
AG
8034 break;
8035 }
8036 }
8037
8038 if (fake_open->filename) {
8039 const char *tmpdir;
8040 char filename[PATH_MAX];
8041 int fd, r;
8042
8043 /* create temporary file to map stat to */
8044 tmpdir = getenv("TMPDIR");
8045 if (!tmpdir)
8046 tmpdir = "/tmp";
8047 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
8048 fd = mkstemp(filename);
8049 if (fd < 0) {
8050 return fd;
8051 }
8052 unlink(filename);
8053
8054 if ((r = fake_open->fill(cpu_env, fd))) {
a3ca7bb2 8055 int e = errno;
3be14d05 8056 close(fd);
a3ca7bb2 8057 errno = e;
3be14d05
AG
8058 return r;
8059 }
8060 lseek(fd, 0, SEEK_SET);
8061
8062 return fd;
8063 }
8064
c10a0738 8065 return safe_openat(dirfd, path(pathname), flags, mode);
3be14d05
AG
8066}
8067
aecc8861
AG
8068#define TIMER_MAGIC 0x0caf0000
8069#define TIMER_MAGIC_MASK 0xffff0000
8070
8071/* Convert QEMU provided timer ID back to internal 16bit index format */
8072static target_timer_t get_timer_id(abi_long arg)
8073{
8074 target_timer_t timerid = arg;
8075
8076 if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
8077 return -TARGET_EINVAL;
8078 }
8079
8080 timerid &= 0xffff;
8081
8082 if (timerid >= ARRAY_SIZE(g_posix_timers)) {
8083 return -TARGET_EINVAL;
8084 }
8085
8086 return timerid;
8087}
8088
2e0a8713
ST
8089static int target_to_host_cpu_mask(unsigned long *host_mask,
8090 size_t host_size,
8091 abi_ulong target_addr,
8092 size_t target_size)
8093{
8094 unsigned target_bits = sizeof(abi_ulong) * 8;
8095 unsigned host_bits = sizeof(*host_mask) * 8;
8096 abi_ulong *target_mask;
8097 unsigned i, j;
8098
8099 assert(host_size >= target_size);
8100
8101 target_mask = lock_user(VERIFY_READ, target_addr, target_size, 1);
8102 if (!target_mask) {
8103 return -TARGET_EFAULT;
8104 }
8105 memset(host_mask, 0, host_size);
8106
8107 for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
8108 unsigned bit = i * target_bits;
8109 abi_ulong val;
8110
8111 __get_user(val, &target_mask[i]);
8112 for (j = 0; j < target_bits; j++, bit++) {
8113 if (val & (1UL << j)) {
8114 host_mask[bit / host_bits] |= 1UL << (bit % host_bits);
8115 }
8116 }
8117 }
8118
8119 unlock_user(target_mask, target_addr, 0);
8120 return 0;
8121}
8122
8123static int host_to_target_cpu_mask(const unsigned long *host_mask,
8124 size_t host_size,
8125 abi_ulong target_addr,
8126 size_t target_size)
8127{
8128 unsigned target_bits = sizeof(abi_ulong) * 8;
8129 unsigned host_bits = sizeof(*host_mask) * 8;
8130 abi_ulong *target_mask;
8131 unsigned i, j;
8132
8133 assert(host_size >= target_size);
8134
8135 target_mask = lock_user(VERIFY_WRITE, target_addr, target_size, 0);
8136 if (!target_mask) {
8137 return -TARGET_EFAULT;
8138 }
8139
8140 for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
8141 unsigned bit = i * target_bits;
8142 abi_ulong val = 0;
8143
8144 for (j = 0; j < target_bits; j++, bit++) {
8145 if (host_mask[bit / host_bits] & (1UL << (bit % host_bits))) {
8146 val |= 1UL << j;
8147 }
8148 }
8149 __put_user(val, &target_mask[i]);
8150 }
8151
8152 unlock_user(target_mask, target_addr, target_size);
8153 return 0;
8154}
8155
dc1ce18b
RH
8156/* This is an internal helper for do_syscall so that it is easier
8157 * to have a single return point, so that actions, such as logging
8158 * of syscall results, can be performed.
8159 * All errnos that do_syscall() returns must be -TARGET_<errcode>.
8160 */
8161static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
8162 abi_long arg2, abi_long arg3, abi_long arg4,
8163 abi_long arg5, abi_long arg6, abi_long arg7,
8164 abi_long arg8)
31e31b8a 8165{
29a0af61 8166 CPUState *cpu = env_cpu(cpu_env);
992f48a0 8167 abi_long ret;
4f7f8924
AR
8168#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
8169 || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
efa92184
AR
8170 || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \
8171 || defined(TARGET_NR_statx)
31e31b8a 8172 struct stat st;
4f7f8924
AR
8173#endif
8174#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
8175 || defined(TARGET_NR_fstatfs)
56c8f68f 8176 struct statfs stfs;
4f7f8924 8177#endif
53a5960a 8178 void *p;
3b46e624 8179
31e31b8a
FB
8180 switch(num) {
8181 case TARGET_NR_exit:
9b056fcc 8182 /* In old applications this may be used to implement _exit(2).
6f9ff551 8183 However in threaded applications it is used for thread termination,
9b056fcc
AF
8184 and _exit_group is used for application termination.
8185 Do thread termination if we have more then one thread. */
a0995886
TB
8186
8187 if (block_signals()) {
72eb7ea8 8188 return -TARGET_ERESTARTSYS;
a0995886
TB
8189 }
8190
1f81ce90 8191 pthread_mutex_lock(&clone_lock);
dd1f6349 8192
bdc44640 8193 if (CPU_NEXT(first_cpu)) {
1f81ce90 8194 TaskState *ts = cpu->opaque;
9b056fcc 8195
5325cc34 8196 object_property_set_bool(OBJECT(cpu), "realized", false, NULL);
1f81ce90
AB
8197 object_unref(OBJECT(cpu));
8198 /*
8199 * At this point the CPU should be unrealized and removed
8200 * from cpu lists. We can clean-up the rest of the thread
8201 * data without the lock held.
8202 */
dd1f6349 8203
1f81ce90 8204 pthread_mutex_unlock(&clone_lock);
dd1f6349 8205
9b056fcc
AF
8206 if (ts->child_tidptr) {
8207 put_user_u32(0, ts->child_tidptr);
14690296 8208 do_sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
9b056fcc
AF
8209 NULL, NULL, 0);
8210 }
a2247f8e 8211 thread_cpu = NULL;
9b056fcc 8212 g_free(ts);
70903763 8213 rcu_unregister_thread();
9b056fcc
AF
8214 pthread_exit(NULL);
8215 }
dd1f6349 8216
1f81ce90 8217 pthread_mutex_unlock(&clone_lock);
708b6a64 8218 preexit_cleanup(cpu_env, arg1);
c2764719 8219 _exit(arg1);
72eb7ea8 8220 return 0; /* avoid warning */
31e31b8a 8221 case TARGET_NR_read:
ba584f1d
AS
8222 if (arg2 == 0 && arg3 == 0) {
8223 return get_errno(safe_read(arg1, 0, 0));
72eb7ea8 8224 } else {
38d840e6 8225 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
2852aafd 8226 return -TARGET_EFAULT;
50afd02b 8227 ret = get_errno(safe_read(arg1, p, arg3));
e36800c9 8228 if (ret >= 0 &&
5d4d3665
LV
8229 fd_trans_host_to_target_data(arg1)) {
8230 ret = fd_trans_host_to_target_data(arg1)(p, ret);
e36800c9 8231 }
38d840e6
AJ
8232 unlock_user(p, arg2, ret);
8233 }
72eb7ea8 8234 return ret;
31e31b8a 8235 case TARGET_NR_write:
58cfa6c2
TGJ
8236 if (arg2 == 0 && arg3 == 0) {
8237 return get_errno(safe_write(arg1, 0, 0));
8238 }
579a97f7 8239 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
2852aafd 8240 return -TARGET_EFAULT;
04b9bcf9
LV
8241 if (fd_trans_target_to_host_data(arg1)) {
8242 void *copy = g_malloc(arg3);
8243 memcpy(copy, p, arg3);
8244 ret = fd_trans_target_to_host_data(arg1)(copy, arg3);
8245 if (ret >= 0) {
8246 ret = get_errno(safe_write(arg1, copy, ret));
8247 }
8248 g_free(copy);
8249 } else {
8250 ret = get_errno(safe_write(arg1, p, arg3));
8251 }
53a5960a 8252 unlock_user(p, arg2, 0);
72eb7ea8
RH
8253 return ret;
8254
704eff6c 8255#ifdef TARGET_NR_open
31e31b8a 8256 case TARGET_NR_open:
2f619698 8257 if (!(p = lock_user_string(arg1)))
2852aafd 8258 return -TARGET_EFAULT;
0b2effd7
RV
8259 ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
8260 target_to_host_bitmask(arg2, fcntl_flags_tbl),
8261 arg3));
e36800c9 8262 fd_trans_unregister(ret);
53a5960a 8263 unlock_user(p, arg1, 0);
72eb7ea8 8264 return ret;
704eff6c 8265#endif
82424832 8266 case TARGET_NR_openat:
579a97f7 8267 if (!(p = lock_user_string(arg2)))
2852aafd 8268 return -TARGET_EFAULT;
0b2effd7
RV
8269 ret = get_errno(do_openat(cpu_env, arg1, p,
8270 target_to_host_bitmask(arg3, fcntl_flags_tbl),
8271 arg4));
e36800c9 8272 fd_trans_unregister(ret);
579a97f7 8273 unlock_user(p, arg2, 0);
72eb7ea8 8274 return ret;
0f0426f3
LV
8275#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
8276 case TARGET_NR_name_to_handle_at:
8277 ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
72eb7ea8 8278 return ret;
0f0426f3
LV
8279#endif
8280#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
8281 case TARGET_NR_open_by_handle_at:
8282 ret = do_open_by_handle_at(arg1, arg2, arg3);
e36800c9 8283 fd_trans_unregister(ret);
72eb7ea8 8284 return ret;
0f0426f3 8285#endif
31e31b8a 8286 case TARGET_NR_close:
e36800c9 8287 fd_trans_unregister(arg1);
72eb7ea8
RH
8288 return get_errno(close(arg1));
8289
31e31b8a 8290 case TARGET_NR_brk:
72eb7ea8 8291 return do_brk(arg1);
704eff6c 8292#ifdef TARGET_NR_fork
31e31b8a 8293 case TARGET_NR_fork:
72eb7ea8 8294 return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
704eff6c 8295#endif
e5febef5 8296#ifdef TARGET_NR_waitpid
31e31b8a
FB
8297 case TARGET_NR_waitpid:
8298 {
53a5960a 8299 int status;
4af80a37 8300 ret = get_errno(safe_wait4(arg1, &status, arg3, 0));
5379557b 8301 if (!is_error(ret) && arg2 && ret
1d9d8b55 8302 && put_user_s32(host_to_target_waitstatus(status), arg2))
2852aafd 8303 return -TARGET_EFAULT;
31e31b8a 8304 }
72eb7ea8 8305 return ret;
e5febef5 8306#endif
f0cbb613
PB
8307#ifdef TARGET_NR_waitid
8308 case TARGET_NR_waitid:
8309 {
8310 siginfo_t info;
8311 info.si_pid = 0;
4af80a37 8312 ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
f0cbb613 8313 if (!is_error(ret) && arg3 && info.si_pid != 0) {
c227f099 8314 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
2852aafd 8315 return -TARGET_EFAULT;
f0cbb613 8316 host_to_target_siginfo(p, &info);
c227f099 8317 unlock_user(p, arg3, sizeof(target_siginfo_t));
f0cbb613
PB
8318 }
8319 }
72eb7ea8 8320 return ret;
f0cbb613 8321#endif
7a3148a9 8322#ifdef TARGET_NR_creat /* not on alpha */
31e31b8a 8323 case TARGET_NR_creat:
579a97f7 8324 if (!(p = lock_user_string(arg1)))
2852aafd 8325 return -TARGET_EFAULT;
53a5960a 8326 ret = get_errno(creat(p, arg2));
e36800c9 8327 fd_trans_unregister(ret);
53a5960a 8328 unlock_user(p, arg1, 0);
72eb7ea8 8329 return ret;
7a3148a9 8330#endif
704eff6c 8331#ifdef TARGET_NR_link
31e31b8a 8332 case TARGET_NR_link:
53a5960a
PB
8333 {
8334 void * p2;
8335 p = lock_user_string(arg1);
8336 p2 = lock_user_string(arg2);
579a97f7
FB
8337 if (!p || !p2)
8338 ret = -TARGET_EFAULT;
8339 else
8340 ret = get_errno(link(p, p2));
53a5960a
PB
8341 unlock_user(p2, arg2, 0);
8342 unlock_user(p, arg1, 0);
8343 }
72eb7ea8 8344 return ret;
704eff6c 8345#endif
c0d472b1 8346#if defined(TARGET_NR_linkat)
64f0ce4c 8347 case TARGET_NR_linkat:
64f0ce4c
TS
8348 {
8349 void * p2 = NULL;
579a97f7 8350 if (!arg2 || !arg4)
2852aafd 8351 return -TARGET_EFAULT;
64f0ce4c
TS
8352 p = lock_user_string(arg2);
8353 p2 = lock_user_string(arg4);
579a97f7 8354 if (!p || !p2)
0da46a6e 8355 ret = -TARGET_EFAULT;
64f0ce4c 8356 else
c0d472b1 8357 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
579a97f7
FB
8358 unlock_user(p, arg2, 0);
8359 unlock_user(p2, arg4, 0);
64f0ce4c 8360 }
72eb7ea8 8361 return ret;
64f0ce4c 8362#endif
704eff6c 8363#ifdef TARGET_NR_unlink
31e31b8a 8364 case TARGET_NR_unlink:
579a97f7 8365 if (!(p = lock_user_string(arg1)))
2852aafd 8366 return -TARGET_EFAULT;
53a5960a
PB
8367 ret = get_errno(unlink(p));
8368 unlock_user(p, arg1, 0);
72eb7ea8 8369 return ret;
704eff6c 8370#endif
c0d472b1 8371#if defined(TARGET_NR_unlinkat)
8170f56b 8372 case TARGET_NR_unlinkat:
579a97f7 8373 if (!(p = lock_user_string(arg2)))
2852aafd 8374 return -TARGET_EFAULT;
c0d472b1 8375 ret = get_errno(unlinkat(arg1, p, arg3));
579a97f7 8376 unlock_user(p, arg2, 0);
72eb7ea8 8377 return ret;
b7d35e65 8378#endif
31e31b8a 8379 case TARGET_NR_execve:
7854b056
FB
8380 {
8381 char **argp, **envp;
f7341ff4 8382 int argc, envc;
992f48a0
BS
8383 abi_ulong gp;
8384 abi_ulong guest_argp;
8385 abi_ulong guest_envp;
8386 abi_ulong addr;
7854b056 8387 char **q;
a6f79cc9 8388 int total_size = 0;
7854b056 8389
f7341ff4 8390 argc = 0;
53a5960a 8391 guest_argp = arg2;
da94d263 8392 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
03aa1976 8393 if (get_user_ual(addr, gp))
2852aafd 8394 return -TARGET_EFAULT;
03aa1976 8395 if (!addr)
2f619698 8396 break;
7854b056 8397 argc++;
2f619698 8398 }
f7341ff4 8399 envc = 0;
53a5960a 8400 guest_envp = arg3;
da94d263 8401 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
03aa1976 8402 if (get_user_ual(addr, gp))
2852aafd 8403 return -TARGET_EFAULT;
03aa1976 8404 if (!addr)
2f619698 8405 break;
7854b056 8406 envc++;
2f619698 8407 }
7854b056 8408
b936cb50
PP
8409 argp = g_new0(char *, argc + 1);
8410 envp = g_new0(char *, envc + 1);
7854b056 8411
da94d263 8412 for (gp = guest_argp, q = argp; gp;
992f48a0 8413 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8414 if (get_user_ual(addr, gp))
8415 goto execve_efault;
53a5960a
PB
8416 if (!addr)
8417 break;
2f619698
FB
8418 if (!(*q = lock_user_string(addr)))
8419 goto execve_efault;
a6f79cc9 8420 total_size += strlen(*q) + 1;
53a5960a 8421 }
f7341ff4
FB
8422 *q = NULL;
8423
da94d263 8424 for (gp = guest_envp, q = envp; gp;
992f48a0 8425 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8426 if (get_user_ual(addr, gp))
8427 goto execve_efault;
53a5960a
PB
8428 if (!addr)
8429 break;
2f619698
FB
8430 if (!(*q = lock_user_string(addr)))
8431 goto execve_efault;
a6f79cc9 8432 total_size += strlen(*q) + 1;
53a5960a 8433 }
f7341ff4 8434 *q = NULL;
7854b056 8435
2f619698
FB
8436 if (!(p = lock_user_string(arg1)))
8437 goto execve_efault;
ffdcbe22
TB
8438 /* Although execve() is not an interruptible syscall it is
8439 * a special case where we must use the safe_syscall wrapper:
8440 * if we allow a signal to happen before we make the host
8441 * syscall then we will 'lose' it, because at the point of
8442 * execve the process leaves QEMU's control. So we use the
8443 * safe syscall wrapper to ensure that we either take the
8444 * signal as a guest signal, or else it does not happen
8445 * before the execve completes and makes it the other
8446 * program's problem.
8447 */
8448 ret = get_errno(safe_execve(p, argp, envp));
53a5960a
PB
8449 unlock_user(p, arg1, 0);
8450
2f619698
FB
8451 goto execve_end;
8452
8453 execve_efault:
8454 ret = -TARGET_EFAULT;
8455
8456 execve_end:
53a5960a 8457 for (gp = guest_argp, q = argp; *q;
992f48a0 8458 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8459 if (get_user_ual(addr, gp)
8460 || !addr)
8461 break;
53a5960a
PB
8462 unlock_user(*q, addr, 0);
8463 }
8464 for (gp = guest_envp, q = envp; *q;
992f48a0 8465 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8466 if (get_user_ual(addr, gp)
8467 || !addr)
8468 break;
53a5960a
PB
8469 unlock_user(*q, addr, 0);
8470 }
b936cb50
PP
8471
8472 g_free(argp);
8473 g_free(envp);
7854b056 8474 }
72eb7ea8 8475 return ret;
31e31b8a 8476 case TARGET_NR_chdir:
579a97f7 8477 if (!(p = lock_user_string(arg1)))
2852aafd 8478 return -TARGET_EFAULT;
53a5960a
PB
8479 ret = get_errno(chdir(p));
8480 unlock_user(p, arg1, 0);
72eb7ea8 8481 return ret;
a315a145 8482#ifdef TARGET_NR_time
31e31b8a
FB
8483 case TARGET_NR_time:
8484 {
53a5960a
PB
8485 time_t host_time;
8486 ret = get_errno(time(&host_time));
2f619698
FB
8487 if (!is_error(ret)
8488 && arg1
8489 && put_user_sal(host_time, arg1))
2852aafd 8490 return -TARGET_EFAULT;
31e31b8a 8491 }
72eb7ea8 8492 return ret;
a315a145 8493#endif
704eff6c 8494#ifdef TARGET_NR_mknod
31e31b8a 8495 case TARGET_NR_mknod:
579a97f7 8496 if (!(p = lock_user_string(arg1)))
2852aafd 8497 return -TARGET_EFAULT;
53a5960a
PB
8498 ret = get_errno(mknod(p, arg2, arg3));
8499 unlock_user(p, arg1, 0);
72eb7ea8 8500 return ret;
704eff6c 8501#endif
c0d472b1 8502#if defined(TARGET_NR_mknodat)
75ac37a0 8503 case TARGET_NR_mknodat:
579a97f7 8504 if (!(p = lock_user_string(arg2)))
2852aafd 8505 return -TARGET_EFAULT;
c0d472b1 8506 ret = get_errno(mknodat(arg1, p, arg3, arg4));
579a97f7 8507 unlock_user(p, arg2, 0);
72eb7ea8 8508 return ret;
75ac37a0 8509#endif
704eff6c 8510#ifdef TARGET_NR_chmod
31e31b8a 8511 case TARGET_NR_chmod:
579a97f7 8512 if (!(p = lock_user_string(arg1)))
2852aafd 8513 return -TARGET_EFAULT;
53a5960a
PB
8514 ret = get_errno(chmod(p, arg2));
8515 unlock_user(p, arg1, 0);
72eb7ea8 8516 return ret;
704eff6c 8517#endif
4f7f8924 8518#ifdef TARGET_NR_lseek
31e31b8a 8519 case TARGET_NR_lseek:
72eb7ea8 8520 return get_errno(lseek(arg1, arg2, arg3));
4f7f8924 8521#endif
9231733a
RH
8522#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
8523 /* Alpha specific */
7a3148a9 8524 case TARGET_NR_getxpid:
9231733a 8525 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
72eb7ea8 8526 return get_errno(getpid());
7a3148a9 8527#endif
9231733a
RH
8528#ifdef TARGET_NR_getpid
8529 case TARGET_NR_getpid:
72eb7ea8 8530 return get_errno(getpid());
9231733a 8531#endif
31e31b8a 8532 case TARGET_NR_mount:
356d771b
PB
8533 {
8534 /* need to look at the data field */
8535 void *p2, *p3;
8536
8537 if (arg1) {
8538 p = lock_user_string(arg1);
8539 if (!p) {
2852aafd 8540 return -TARGET_EFAULT;
356d771b
PB
8541 }
8542 } else {
8543 p = NULL;
8544 }
8545
8546 p2 = lock_user_string(arg2);
8547 if (!p2) {
8548 if (arg1) {
8549 unlock_user(p, arg1, 0);
8550 }
2852aafd 8551 return -TARGET_EFAULT;
356d771b
PB
8552 }
8553
8554 if (arg3) {
8555 p3 = lock_user_string(arg3);
8556 if (!p3) {
8557 if (arg1) {
579a97f7 8558 unlock_user(p, arg1, 0);
356d771b
PB
8559 }
8560 unlock_user(p2, arg2, 0);
2852aafd 8561 return -TARGET_EFAULT;
356d771b
PB
8562 }
8563 } else {
8564 p3 = NULL;
8565 }
8566
8567 /* FIXME - arg5 should be locked, but it isn't clear how to
8568 * do that since it's not guaranteed to be a NULL-terminated
8569 * string.
8570 */
8571 if (!arg5) {
8572 ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
8573 } else {
8574 ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
8575 }
8576 ret = get_errno(ret);
8577
8578 if (arg1) {
8579 unlock_user(p, arg1, 0);
8580 }
8581 unlock_user(p2, arg2, 0);
8582 if (arg3) {
8583 unlock_user(p3, arg3, 0);
8584 }
8585 }
72eb7ea8 8586 return ret;
6eb9dbf6
LV
8587#if defined(TARGET_NR_umount) || defined(TARGET_NR_oldumount)
8588#if defined(TARGET_NR_umount)
31e31b8a 8589 case TARGET_NR_umount:
6eb9dbf6
LV
8590#endif
8591#if defined(TARGET_NR_oldumount)
8592 case TARGET_NR_oldumount:
8593#endif
579a97f7 8594 if (!(p = lock_user_string(arg1)))
2852aafd 8595 return -TARGET_EFAULT;
53a5960a
PB
8596 ret = get_errno(umount(p));
8597 unlock_user(p, arg1, 0);
72eb7ea8 8598 return ret;
e5febef5 8599#endif
7a3148a9 8600#ifdef TARGET_NR_stime /* not on alpha */
31e31b8a
FB
8601 case TARGET_NR_stime:
8602 {
0f1f2d45
LV
8603 struct timespec ts;
8604 ts.tv_nsec = 0;
8605 if (get_user_sal(ts.tv_sec, arg1)) {
2852aafd 8606 return -TARGET_EFAULT;
0f1f2d45
LV
8607 }
8608 return get_errno(clock_settime(CLOCK_REALTIME, &ts));
31e31b8a 8609 }
7a3148a9 8610#endif
7a3148a9 8611#ifdef TARGET_NR_alarm /* not on alpha */
31e31b8a 8612 case TARGET_NR_alarm:
72eb7ea8 8613 return alarm(arg1);
7a3148a9 8614#endif
7a3148a9 8615#ifdef TARGET_NR_pause /* not on alpha */
31e31b8a 8616 case TARGET_NR_pause:
f59ec606
TB
8617 if (!block_signals()) {
8618 sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
8619 }
72eb7ea8 8620 return -TARGET_EINTR;
7a3148a9 8621#endif
e5febef5 8622#ifdef TARGET_NR_utime
31e31b8a 8623 case TARGET_NR_utime:
ebc05488 8624 {
53a5960a
PB
8625 struct utimbuf tbuf, *host_tbuf;
8626 struct target_utimbuf *target_tbuf;
8627 if (arg2) {
579a97f7 8628 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
2852aafd 8629 return -TARGET_EFAULT;
cbb21eed
MB
8630 tbuf.actime = tswapal(target_tbuf->actime);
8631 tbuf.modtime = tswapal(target_tbuf->modtime);
53a5960a
PB
8632 unlock_user_struct(target_tbuf, arg2, 0);
8633 host_tbuf = &tbuf;
f72e8ff4 8634 } else {
53a5960a 8635 host_tbuf = NULL;
f72e8ff4 8636 }
579a97f7 8637 if (!(p = lock_user_string(arg1)))
2852aafd 8638 return -TARGET_EFAULT;
53a5960a
PB
8639 ret = get_errno(utime(p, host_tbuf));
8640 unlock_user(p, arg1, 0);
ebc05488 8641 }
72eb7ea8 8642 return ret;
e5febef5 8643#endif
704eff6c 8644#ifdef TARGET_NR_utimes
978a66ff
FB
8645 case TARGET_NR_utimes:
8646 {
978a66ff 8647 struct timeval *tvp, tv[2];
53a5960a 8648 if (arg2) {
788f5ec4
TS
8649 if (copy_from_user_timeval(&tv[0], arg2)
8650 || copy_from_user_timeval(&tv[1],
8651 arg2 + sizeof(struct target_timeval)))
2852aafd 8652 return -TARGET_EFAULT;
978a66ff
FB
8653 tvp = tv;
8654 } else {
8655 tvp = NULL;
8656 }
579a97f7 8657 if (!(p = lock_user_string(arg1)))
2852aafd 8658 return -TARGET_EFAULT;
53a5960a
PB
8659 ret = get_errno(utimes(p, tvp));
8660 unlock_user(p, arg1, 0);
978a66ff 8661 }
72eb7ea8 8662 return ret;
704eff6c 8663#endif
c0d472b1 8664#if defined(TARGET_NR_futimesat)
ac8a6556
AZ
8665 case TARGET_NR_futimesat:
8666 {
8667 struct timeval *tvp, tv[2];
8668 if (arg3) {
8669 if (copy_from_user_timeval(&tv[0], arg3)
8670 || copy_from_user_timeval(&tv[1],
8671 arg3 + sizeof(struct target_timeval)))
2852aafd 8672 return -TARGET_EFAULT;
ac8a6556
AZ
8673 tvp = tv;
8674 } else {
8675 tvp = NULL;
8676 }
2852aafd
RH
8677 if (!(p = lock_user_string(arg2))) {
8678 return -TARGET_EFAULT;
8679 }
c0d472b1 8680 ret = get_errno(futimesat(arg1, path(p), tvp));
ac8a6556
AZ
8681 unlock_user(p, arg2, 0);
8682 }
72eb7ea8 8683 return ret;
ac8a6556 8684#endif
704eff6c 8685#ifdef TARGET_NR_access
31e31b8a 8686 case TARGET_NR_access:
2852aafd
RH
8687 if (!(p = lock_user_string(arg1))) {
8688 return -TARGET_EFAULT;
8689 }
719f908e 8690 ret = get_errno(access(path(p), arg2));
53a5960a 8691 unlock_user(p, arg1, 0);
72eb7ea8 8692 return ret;
704eff6c 8693#endif
92a34c10
TS
8694#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
8695 case TARGET_NR_faccessat:
2852aafd
RH
8696 if (!(p = lock_user_string(arg2))) {
8697 return -TARGET_EFAULT;
8698 }
c0d472b1 8699 ret = get_errno(faccessat(arg1, p, arg3, 0));
579a97f7 8700 unlock_user(p, arg2, 0);
72eb7ea8 8701 return ret;
92a34c10 8702#endif
7a3148a9 8703#ifdef TARGET_NR_nice /* not on alpha */
31e31b8a 8704 case TARGET_NR_nice:
72eb7ea8 8705 return get_errno(nice(arg1));
ebc05488 8706#endif
31e31b8a 8707 case TARGET_NR_sync:
04369ff2 8708 sync();
72eb7ea8 8709 return 0;
5a03cd00
AM
8710#if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS)
8711 case TARGET_NR_syncfs:
72eb7ea8 8712 return get_errno(syncfs(arg1));
5a03cd00 8713#endif
31e31b8a 8714 case TARGET_NR_kill:
72eb7ea8 8715 return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
704eff6c 8716#ifdef TARGET_NR_rename
31e31b8a 8717 case TARGET_NR_rename:
53a5960a
PB
8718 {
8719 void *p2;
8720 p = lock_user_string(arg1);
8721 p2 = lock_user_string(arg2);
579a97f7
FB
8722 if (!p || !p2)
8723 ret = -TARGET_EFAULT;
8724 else
8725 ret = get_errno(rename(p, p2));
53a5960a
PB
8726 unlock_user(p2, arg2, 0);
8727 unlock_user(p, arg1, 0);
8728 }
72eb7ea8 8729 return ret;
704eff6c 8730#endif
c0d472b1 8731#if defined(TARGET_NR_renameat)
722183f6 8732 case TARGET_NR_renameat:
722183f6 8733 {
579a97f7 8734 void *p2;
722183f6
TS
8735 p = lock_user_string(arg2);
8736 p2 = lock_user_string(arg4);
579a97f7 8737 if (!p || !p2)
0da46a6e 8738 ret = -TARGET_EFAULT;
722183f6 8739 else
c0d472b1 8740 ret = get_errno(renameat(arg1, p, arg3, p2));
579a97f7
FB
8741 unlock_user(p2, arg4, 0);
8742 unlock_user(p, arg2, 0);
722183f6 8743 }
72eb7ea8 8744 return ret;
95d0307c
AS
8745#endif
8746#if defined(TARGET_NR_renameat2)
8747 case TARGET_NR_renameat2:
8748 {
8749 void *p2;
8750 p = lock_user_string(arg2);
8751 p2 = lock_user_string(arg4);
8752 if (!p || !p2) {
8753 ret = -TARGET_EFAULT;
8754 } else {
8755 ret = get_errno(sys_renameat2(arg1, p, arg3, p2, arg5));
8756 }
8757 unlock_user(p2, arg4, 0);
8758 unlock_user(p, arg2, 0);
8759 }
72eb7ea8 8760 return ret;
722183f6 8761#endif
704eff6c 8762#ifdef TARGET_NR_mkdir
31e31b8a 8763 case TARGET_NR_mkdir:
579a97f7 8764 if (!(p = lock_user_string(arg1)))
2852aafd 8765 return -TARGET_EFAULT;
53a5960a
PB
8766 ret = get_errno(mkdir(p, arg2));
8767 unlock_user(p, arg1, 0);
72eb7ea8 8768 return ret;
704eff6c 8769#endif
c0d472b1 8770#if defined(TARGET_NR_mkdirat)
4472ad0d 8771 case TARGET_NR_mkdirat:
579a97f7 8772 if (!(p = lock_user_string(arg2)))
2852aafd 8773 return -TARGET_EFAULT;
c0d472b1 8774 ret = get_errno(mkdirat(arg1, p, arg3));
579a97f7 8775 unlock_user(p, arg2, 0);
72eb7ea8 8776 return ret;
4472ad0d 8777#endif
704eff6c 8778#ifdef TARGET_NR_rmdir
31e31b8a 8779 case TARGET_NR_rmdir:
579a97f7 8780 if (!(p = lock_user_string(arg1)))
2852aafd 8781 return -TARGET_EFAULT;
53a5960a
PB
8782 ret = get_errno(rmdir(p));
8783 unlock_user(p, arg1, 0);
72eb7ea8 8784 return ret;
704eff6c 8785#endif
31e31b8a
FB
8786 case TARGET_NR_dup:
8787 ret = get_errno(dup(arg1));
e36800c9
LV
8788 if (ret >= 0) {
8789 fd_trans_dup(arg1, ret);
8790 }
72eb7ea8 8791 return ret;
704eff6c 8792#ifdef TARGET_NR_pipe
31e31b8a 8793 case TARGET_NR_pipe:
72eb7ea8 8794 return do_pipe(cpu_env, arg1, 0, 0);
704eff6c 8795#endif
099d6b0f
RV
8796#ifdef TARGET_NR_pipe2
8797 case TARGET_NR_pipe2:
72eb7ea8
RH
8798 return do_pipe(cpu_env, arg1,
8799 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
099d6b0f 8800#endif
31e31b8a 8801 case TARGET_NR_times:
32f36bce 8802 {
53a5960a 8803 struct target_tms *tmsp;
32f36bce
FB
8804 struct tms tms;
8805 ret = get_errno(times(&tms));
53a5960a 8806 if (arg1) {
579a97f7
FB
8807 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
8808 if (!tmsp)
2852aafd 8809 return -TARGET_EFAULT;
cbb21eed
MB
8810 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
8811 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
8812 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
8813 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
32f36bce 8814 }
c596ed17
FB
8815 if (!is_error(ret))
8816 ret = host_to_target_clock_t(ret);
32f36bce 8817 }
72eb7ea8 8818 return ret;
31e31b8a 8819 case TARGET_NR_acct:
38d840e6
AJ
8820 if (arg1 == 0) {
8821 ret = get_errno(acct(NULL));
8822 } else {
2852aafd
RH
8823 if (!(p = lock_user_string(arg1))) {
8824 return -TARGET_EFAULT;
8825 }
38d840e6
AJ
8826 ret = get_errno(acct(path(p)));
8827 unlock_user(p, arg1, 0);
8828 }
72eb7ea8 8829 return ret;
8070e7be 8830#ifdef TARGET_NR_umount2
31e31b8a 8831 case TARGET_NR_umount2:
579a97f7 8832 if (!(p = lock_user_string(arg1)))
2852aafd 8833 return -TARGET_EFAULT;
53a5960a
PB
8834 ret = get_errno(umount2(p, arg2));
8835 unlock_user(p, arg1, 0);
72eb7ea8 8836 return ret;
ebc05488 8837#endif
31e31b8a 8838 case TARGET_NR_ioctl:
72eb7ea8 8839 return do_ioctl(arg1, arg2, arg3);
47ae93cd 8840#ifdef TARGET_NR_fcntl
31e31b8a 8841 case TARGET_NR_fcntl:
72eb7ea8 8842 return do_fcntl(arg1, arg2, arg3);
ebc05488 8843#endif
31e31b8a 8844 case TARGET_NR_setpgid:
72eb7ea8 8845 return get_errno(setpgid(arg1, arg2));
31e31b8a 8846 case TARGET_NR_umask:
72eb7ea8 8847 return get_errno(umask(arg1));
31e31b8a 8848 case TARGET_NR_chroot:
579a97f7 8849 if (!(p = lock_user_string(arg1)))
2852aafd 8850 return -TARGET_EFAULT;
53a5960a
PB
8851 ret = get_errno(chroot(p));
8852 unlock_user(p, arg1, 0);
72eb7ea8 8853 return ret;
704eff6c 8854#ifdef TARGET_NR_dup2
31e31b8a
FB
8855 case TARGET_NR_dup2:
8856 ret = get_errno(dup2(arg1, arg2));
e36800c9
LV
8857 if (ret >= 0) {
8858 fd_trans_dup(arg1, arg2);
8859 }
72eb7ea8 8860 return ret;
704eff6c 8861#endif
d0927938
UH
8862#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
8863 case TARGET_NR_dup3:
10fa993a
PM
8864 {
8865 int host_flags;
8866
8867 if ((arg3 & ~TARGET_O_CLOEXEC) != 0) {
8868 return -EINVAL;
8869 }
8870 host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl);
8871 ret = get_errno(dup3(arg1, arg2, host_flags));
e36800c9
LV
8872 if (ret >= 0) {
8873 fd_trans_dup(arg1, arg2);
8874 }
72eb7ea8 8875 return ret;
10fa993a 8876 }
d0927938 8877#endif
7a3148a9 8878#ifdef TARGET_NR_getppid /* not on alpha */
31e31b8a 8879 case TARGET_NR_getppid:
72eb7ea8 8880 return get_errno(getppid());
7a3148a9 8881#endif
704eff6c 8882#ifdef TARGET_NR_getpgrp
31e31b8a 8883 case TARGET_NR_getpgrp:
72eb7ea8 8884 return get_errno(getpgrp());
704eff6c 8885#endif
31e31b8a 8886 case TARGET_NR_setsid:
72eb7ea8 8887 return get_errno(setsid());
e5febef5 8888#ifdef TARGET_NR_sigaction
31e31b8a 8889 case TARGET_NR_sigaction:
31e31b8a 8890 {
6049f4f8
RH
8891#if defined(TARGET_ALPHA)
8892 struct target_sigaction act, oact, *pact = 0;
53a5960a 8893 struct target_old_sigaction *old_act;
53a5960a 8894 if (arg2) {
579a97f7 8895 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 8896 return -TARGET_EFAULT;
66fb9763
FB
8897 act._sa_handler = old_act->_sa_handler;
8898 target_siginitset(&act.sa_mask, old_act->sa_mask);
8899 act.sa_flags = old_act->sa_flags;
6049f4f8 8900 act.sa_restorer = 0;
53a5960a 8901 unlock_user_struct(old_act, arg2, 0);
66fb9763 8902 pact = &act;
66fb9763
FB
8903 }
8904 ret = get_errno(do_sigaction(arg1, pact, &oact));
53a5960a 8905 if (!is_error(ret) && arg3) {
579a97f7 8906 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 8907 return -TARGET_EFAULT;
53a5960a
PB
8908 old_act->_sa_handler = oact._sa_handler;
8909 old_act->sa_mask = oact.sa_mask.sig[0];
8910 old_act->sa_flags = oact.sa_flags;
53a5960a 8911 unlock_user_struct(old_act, arg3, 1);
66fb9763 8912 }
6049f4f8 8913#elif defined(TARGET_MIPS)
106ec879
FB
8914 struct target_sigaction act, oact, *pact, *old_act;
8915
8916 if (arg2) {
579a97f7 8917 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 8918 return -TARGET_EFAULT;
106ec879
FB
8919 act._sa_handler = old_act->_sa_handler;
8920 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
8921 act.sa_flags = old_act->sa_flags;
8922 unlock_user_struct(old_act, arg2, 0);
8923 pact = &act;
8924 } else {
8925 pact = NULL;
8926 }
8927
8928 ret = get_errno(do_sigaction(arg1, pact, &oact));
8929
8930 if (!is_error(ret) && arg3) {
579a97f7 8931 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 8932 return -TARGET_EFAULT;
106ec879
FB
8933 old_act->_sa_handler = oact._sa_handler;
8934 old_act->sa_flags = oact.sa_flags;
8935 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
8936 old_act->sa_mask.sig[1] = 0;
8937 old_act->sa_mask.sig[2] = 0;
8938 old_act->sa_mask.sig[3] = 0;
8939 unlock_user_struct(old_act, arg3, 1);
8940 }
6049f4f8
RH
8941#else
8942 struct target_old_sigaction *old_act;
8943 struct target_sigaction act, oact, *pact;
8944 if (arg2) {
8945 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 8946 return -TARGET_EFAULT;
6049f4f8
RH
8947 act._sa_handler = old_act->_sa_handler;
8948 target_siginitset(&act.sa_mask, old_act->sa_mask);
8949 act.sa_flags = old_act->sa_flags;
8950 act.sa_restorer = old_act->sa_restorer;
5de154e8
LV
8951#ifdef TARGET_ARCH_HAS_KA_RESTORER
8952 act.ka_restorer = 0;
8953#endif
6049f4f8
RH
8954 unlock_user_struct(old_act, arg2, 0);
8955 pact = &act;
8956 } else {
8957 pact = NULL;
8958 }
8959 ret = get_errno(do_sigaction(arg1, pact, &oact));
8960 if (!is_error(ret) && arg3) {
8961 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 8962 return -TARGET_EFAULT;
6049f4f8
RH
8963 old_act->_sa_handler = oact._sa_handler;
8964 old_act->sa_mask = oact.sa_mask.sig[0];
8965 old_act->sa_flags = oact.sa_flags;
8966 old_act->sa_restorer = oact.sa_restorer;
8967 unlock_user_struct(old_act, arg3, 1);
8968 }
388bb21a 8969#endif
31e31b8a 8970 }
72eb7ea8 8971 return ret;
e5febef5 8972#endif
66fb9763 8973 case TARGET_NR_rt_sigaction:
53a5960a 8974 {
6049f4f8 8975#if defined(TARGET_ALPHA)
78bfef72
PM
8976 /* For Alpha and SPARC this is a 5 argument syscall, with
8977 * a 'restorer' parameter which must be copied into the
8978 * sa_restorer field of the sigaction struct.
8979 * For Alpha that 'restorer' is arg5; for SPARC it is arg4,
8980 * and arg5 is the sigsetsize.
8981 * Alpha also has a separate rt_sigaction struct that it uses
8982 * here; SPARC uses the usual sigaction struct.
8983 */
6049f4f8 8984 struct target_rt_sigaction *rt_act;
78bfef72 8985 struct target_sigaction act, oact, *pact = 0;
c815701e
PM
8986
8987 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 8988 return -TARGET_EINVAL;
c815701e 8989 }
6049f4f8
RH
8990 if (arg2) {
8991 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
2852aafd 8992 return -TARGET_EFAULT;
6049f4f8
RH
8993 act._sa_handler = rt_act->_sa_handler;
8994 act.sa_mask = rt_act->sa_mask;
8995 act.sa_flags = rt_act->sa_flags;
8996 act.sa_restorer = arg5;
8997 unlock_user_struct(rt_act, arg2, 0);
8998 pact = &act;
8999 }
9000 ret = get_errno(do_sigaction(arg1, pact, &oact));
9001 if (!is_error(ret) && arg3) {
9002 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
2852aafd 9003 return -TARGET_EFAULT;
6049f4f8
RH
9004 rt_act->_sa_handler = oact._sa_handler;
9005 rt_act->sa_mask = oact.sa_mask;
9006 rt_act->sa_flags = oact.sa_flags;
9007 unlock_user_struct(rt_act, arg3, 1);
9008 }
9009#else
78bfef72
PM
9010#ifdef TARGET_SPARC
9011 target_ulong restorer = arg4;
9012 target_ulong sigsetsize = arg5;
9013#else
9014 target_ulong sigsetsize = arg4;
9015#endif
53a5960a
PB
9016 struct target_sigaction *act;
9017 struct target_sigaction *oact;
9018
78bfef72 9019 if (sigsetsize != sizeof(target_sigset_t)) {
72eb7ea8 9020 return -TARGET_EINVAL;
c815701e 9021 }
579a97f7 9022 if (arg2) {
78bfef72 9023 if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
2852aafd 9024 return -TARGET_EFAULT;
78bfef72 9025 }
5de154e8
LV
9026#ifdef TARGET_ARCH_HAS_KA_RESTORER
9027 act->ka_restorer = restorer;
78bfef72
PM
9028#endif
9029 } else {
53a5960a 9030 act = NULL;
78bfef72 9031 }
579a97f7
FB
9032 if (arg3) {
9033 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
9034 ret = -TARGET_EFAULT;
9035 goto rt_sigaction_fail;
9036 }
9037 } else
53a5960a
PB
9038 oact = NULL;
9039 ret = get_errno(do_sigaction(arg1, act, oact));
579a97f7
FB
9040 rt_sigaction_fail:
9041 if (act)
53a5960a 9042 unlock_user_struct(act, arg2, 0);
579a97f7 9043 if (oact)
53a5960a 9044 unlock_user_struct(oact, arg3, 1);
6049f4f8 9045#endif
53a5960a 9046 }
72eb7ea8 9047 return ret;
7a3148a9 9048#ifdef TARGET_NR_sgetmask /* not on alpha */
31e31b8a 9049 case TARGET_NR_sgetmask:
66fb9763
FB
9050 {
9051 sigset_t cur_set;
992f48a0 9052 abi_ulong target_set;
3d3efba0
PM
9053 ret = do_sigprocmask(0, NULL, &cur_set);
9054 if (!ret) {
9055 host_to_target_old_sigset(&target_set, &cur_set);
9056 ret = target_set;
9057 }
66fb9763 9058 }
72eb7ea8 9059 return ret;
7a3148a9
JM
9060#endif
9061#ifdef TARGET_NR_ssetmask /* not on alpha */
31e31b8a 9062 case TARGET_NR_ssetmask:
66fb9763 9063 {
a8617d8c 9064 sigset_t set, oset;
992f48a0 9065 abi_ulong target_set = arg1;
66fb9763 9066 target_to_host_old_sigset(&set, &target_set);
3d3efba0
PM
9067 ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
9068 if (!ret) {
9069 host_to_target_old_sigset(&target_set, &oset);
9070 ret = target_set;
9071 }
66fb9763 9072 }
72eb7ea8 9073 return ret;
7a3148a9 9074#endif
e5febef5 9075#ifdef TARGET_NR_sigprocmask
66fb9763
FB
9076 case TARGET_NR_sigprocmask:
9077 {
a5b3b13b
RH
9078#if defined(TARGET_ALPHA)
9079 sigset_t set, oldset;
9080 abi_ulong mask;
9081 int how;
9082
9083 switch (arg1) {
9084 case TARGET_SIG_BLOCK:
9085 how = SIG_BLOCK;
9086 break;
9087 case TARGET_SIG_UNBLOCK:
9088 how = SIG_UNBLOCK;
9089 break;
9090 case TARGET_SIG_SETMASK:
9091 how = SIG_SETMASK;
9092 break;
9093 default:
259841c1 9094 return -TARGET_EINVAL;
a5b3b13b
RH
9095 }
9096 mask = arg2;
9097 target_to_host_old_sigset(&set, &mask);
9098
3d3efba0 9099 ret = do_sigprocmask(how, &set, &oldset);
a5b3b13b
RH
9100 if (!is_error(ret)) {
9101 host_to_target_old_sigset(&mask, &oldset);
9102 ret = mask;
0229f5a3 9103 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
a5b3b13b
RH
9104 }
9105#else
66fb9763 9106 sigset_t set, oldset, *set_ptr;
a5b3b13b 9107 int how;
3b46e624 9108
53a5960a 9109 if (arg2) {
a5b3b13b 9110 switch (arg1) {
66fb9763
FB
9111 case TARGET_SIG_BLOCK:
9112 how = SIG_BLOCK;
9113 break;
9114 case TARGET_SIG_UNBLOCK:
9115 how = SIG_UNBLOCK;
9116 break;
9117 case TARGET_SIG_SETMASK:
9118 how = SIG_SETMASK;
9119 break;
9120 default:
259841c1 9121 return -TARGET_EINVAL;
66fb9763 9122 }
c227f099 9123 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
2852aafd 9124 return -TARGET_EFAULT;
53a5960a
PB
9125 target_to_host_old_sigset(&set, p);
9126 unlock_user(p, arg2, 0);
66fb9763
FB
9127 set_ptr = &set;
9128 } else {
9129 how = 0;
9130 set_ptr = NULL;
9131 }
3d3efba0 9132 ret = do_sigprocmask(how, set_ptr, &oldset);
53a5960a 9133 if (!is_error(ret) && arg3) {
c227f099 9134 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
2852aafd 9135 return -TARGET_EFAULT;
53a5960a 9136 host_to_target_old_sigset(p, &oldset);
c227f099 9137 unlock_user(p, arg3, sizeof(target_sigset_t));
66fb9763 9138 }
a5b3b13b 9139#endif
66fb9763 9140 }
72eb7ea8 9141 return ret;
e5febef5 9142#endif
66fb9763
FB
9143 case TARGET_NR_rt_sigprocmask:
9144 {
9145 int how = arg1;
9146 sigset_t set, oldset, *set_ptr;
3b46e624 9147
c815701e 9148 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 9149 return -TARGET_EINVAL;
c815701e
PM
9150 }
9151
53a5960a 9152 if (arg2) {
66fb9763
FB
9153 switch(how) {
9154 case TARGET_SIG_BLOCK:
9155 how = SIG_BLOCK;
9156 break;
9157 case TARGET_SIG_UNBLOCK:
9158 how = SIG_UNBLOCK;
9159 break;
9160 case TARGET_SIG_SETMASK:
9161 how = SIG_SETMASK;
9162 break;
9163 default:
259841c1 9164 return -TARGET_EINVAL;
66fb9763 9165 }
c227f099 9166 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
2852aafd 9167 return -TARGET_EFAULT;
53a5960a
PB
9168 target_to_host_sigset(&set, p);
9169 unlock_user(p, arg2, 0);
66fb9763
FB
9170 set_ptr = &set;
9171 } else {
9172 how = 0;
9173 set_ptr = NULL;
9174 }
3d3efba0 9175 ret = do_sigprocmask(how, set_ptr, &oldset);
53a5960a 9176 if (!is_error(ret) && arg3) {
c227f099 9177 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
2852aafd 9178 return -TARGET_EFAULT;
53a5960a 9179 host_to_target_sigset(p, &oldset);
c227f099 9180 unlock_user(p, arg3, sizeof(target_sigset_t));
66fb9763
FB
9181 }
9182 }
72eb7ea8 9183 return ret;
e5febef5 9184#ifdef TARGET_NR_sigpending
66fb9763
FB
9185 case TARGET_NR_sigpending:
9186 {
9187 sigset_t set;
9188 ret = get_errno(sigpending(&set));
9189 if (!is_error(ret)) {
c227f099 9190 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
2852aafd 9191 return -TARGET_EFAULT;
53a5960a 9192 host_to_target_old_sigset(p, &set);
c227f099 9193 unlock_user(p, arg1, sizeof(target_sigset_t));
66fb9763
FB
9194 }
9195 }
72eb7ea8 9196 return ret;
e5febef5 9197#endif
66fb9763
FB
9198 case TARGET_NR_rt_sigpending:
9199 {
9200 sigset_t set;
c815701e
PM
9201
9202 /* Yes, this check is >, not != like most. We follow the kernel's
9203 * logic and it does it like this because it implements
9204 * NR_sigpending through the same code path, and in that case
9205 * the old_sigset_t is smaller in size.
9206 */
9207 if (arg2 > sizeof(target_sigset_t)) {
72eb7ea8 9208 return -TARGET_EINVAL;
c815701e
PM
9209 }
9210
66fb9763
FB
9211 ret = get_errno(sigpending(&set));
9212 if (!is_error(ret)) {
c227f099 9213 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
2852aafd 9214 return -TARGET_EFAULT;
53a5960a 9215 host_to_target_sigset(p, &set);
c227f099 9216 unlock_user(p, arg1, sizeof(target_sigset_t));
66fb9763
FB
9217 }
9218 }
72eb7ea8 9219 return ret;
e5febef5 9220#ifdef TARGET_NR_sigsuspend
66fb9763
FB
9221 case TARGET_NR_sigsuspend:
9222 {
3d3efba0 9223 TaskState *ts = cpu->opaque;
f43ce12b
RH
9224#if defined(TARGET_ALPHA)
9225 abi_ulong mask = arg1;
3d3efba0 9226 target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
f43ce12b 9227#else
c227f099 9228 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 9229 return -TARGET_EFAULT;
3d3efba0 9230 target_to_host_old_sigset(&ts->sigsuspend_mask, p);
53a5960a 9231 unlock_user(p, arg1, 0);
f43ce12b 9232#endif
3d3efba0
PM
9233 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
9234 SIGSET_T_SIZE));
9235 if (ret != -TARGET_ERESTARTSYS) {
9236 ts->in_sigsuspend = 1;
9237 }
66fb9763 9238 }
72eb7ea8 9239 return ret;
e5febef5 9240#endif
66fb9763
FB
9241 case TARGET_NR_rt_sigsuspend:
9242 {
3d3efba0 9243 TaskState *ts = cpu->opaque;
c815701e
PM
9244
9245 if (arg2 != sizeof(target_sigset_t)) {
72eb7ea8 9246 return -TARGET_EINVAL;
c815701e 9247 }
c227f099 9248 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 9249 return -TARGET_EFAULT;
3d3efba0 9250 target_to_host_sigset(&ts->sigsuspend_mask, p);
53a5960a 9251 unlock_user(p, arg1, 0);
3d3efba0
PM
9252 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
9253 SIGSET_T_SIZE));
9254 if (ret != -TARGET_ERESTARTSYS) {
9255 ts->in_sigsuspend = 1;
9256 }
66fb9763 9257 }
72eb7ea8 9258 return ret;
859e8a89 9259#ifdef TARGET_NR_rt_sigtimedwait
66fb9763
FB
9260 case TARGET_NR_rt_sigtimedwait:
9261 {
66fb9763
FB
9262 sigset_t set;
9263 struct timespec uts, *puts;
9264 siginfo_t uinfo;
3b46e624 9265
c815701e 9266 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 9267 return -TARGET_EINVAL;
c815701e
PM
9268 }
9269
c227f099 9270 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 9271 return -TARGET_EFAULT;
53a5960a
PB
9272 target_to_host_sigset(&set, p);
9273 unlock_user(p, arg1, 0);
9274 if (arg3) {
66fb9763 9275 puts = &uts;
4d213001
FB
9276 if (target_to_host_timespec(puts, arg3)) {
9277 return -TARGET_EFAULT;
9278 }
66fb9763
FB
9279 } else {
9280 puts = NULL;
9281 }
b3f82330
PM
9282 ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
9283 SIGSET_T_SIZE));
974a196d
PJ
9284 if (!is_error(ret)) {
9285 if (arg2) {
9286 p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
9287 0);
9288 if (!p) {
2852aafd 9289 return -TARGET_EFAULT;
974a196d
PJ
9290 }
9291 host_to_target_siginfo(p, &uinfo);
9292 unlock_user(p, arg2, sizeof(target_siginfo_t));
9293 }
9294 ret = host_to_target_signal(ret);
66fb9763
FB
9295 }
9296 }
72eb7ea8 9297 return ret;
ddcbde15
FB
9298#endif
9299#ifdef TARGET_NR_rt_sigtimedwait_time64
9300 case TARGET_NR_rt_sigtimedwait_time64:
9301 {
9302 sigset_t set;
9303 struct timespec uts, *puts;
9304 siginfo_t uinfo;
9305
9306 if (arg4 != sizeof(target_sigset_t)) {
9307 return -TARGET_EINVAL;
9308 }
9309
9310 p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
9311 if (!p) {
9312 return -TARGET_EFAULT;
9313 }
9314 target_to_host_sigset(&set, p);
9315 unlock_user(p, arg1, 0);
9316 if (arg3) {
9317 puts = &uts;
9318 if (target_to_host_timespec64(puts, arg3)) {
9319 return -TARGET_EFAULT;
9320 }
9321 } else {
9322 puts = NULL;
9323 }
9324 ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
9325 SIGSET_T_SIZE));
9326 if (!is_error(ret)) {
9327 if (arg2) {
9328 p = lock_user(VERIFY_WRITE, arg2,
9329 sizeof(target_siginfo_t), 0);
9330 if (!p) {
9331 return -TARGET_EFAULT;
9332 }
9333 host_to_target_siginfo(p, &uinfo);
9334 unlock_user(p, arg2, sizeof(target_siginfo_t));
9335 }
9336 ret = host_to_target_signal(ret);
9337 }
9338 }
9339 return ret;
859e8a89 9340#endif
66fb9763
FB
9341 case TARGET_NR_rt_sigqueueinfo:
9342 {
9343 siginfo_t uinfo;
4debae6f
PM
9344
9345 p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
9346 if (!p) {
2852aafd 9347 return -TARGET_EFAULT;
4debae6f 9348 }
53a5960a 9349 target_to_host_siginfo(&uinfo, p);
d8b6d892 9350 unlock_user(p, arg3, 0);
66fb9763
FB
9351 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
9352 }
72eb7ea8 9353 return ret;
cf8b8bfc
MS
9354 case TARGET_NR_rt_tgsigqueueinfo:
9355 {
9356 siginfo_t uinfo;
9357
9358 p = lock_user(VERIFY_READ, arg4, sizeof(target_siginfo_t), 1);
9359 if (!p) {
2852aafd 9360 return -TARGET_EFAULT;
cf8b8bfc
MS
9361 }
9362 target_to_host_siginfo(&uinfo, p);
9363 unlock_user(p, arg4, 0);
9364 ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, &uinfo));
9365 }
72eb7ea8 9366 return ret;
e5febef5 9367#ifdef TARGET_NR_sigreturn
66fb9763 9368 case TARGET_NR_sigreturn:
3d3efba0 9369 if (block_signals()) {
72eb7ea8 9370 return -TARGET_ERESTARTSYS;
3d3efba0 9371 }
72eb7ea8 9372 return do_sigreturn(cpu_env);
e5febef5 9373#endif
66fb9763 9374 case TARGET_NR_rt_sigreturn:
3d3efba0 9375 if (block_signals()) {
72eb7ea8 9376 return -TARGET_ERESTARTSYS;
3d3efba0 9377 }
72eb7ea8 9378 return do_rt_sigreturn(cpu_env);
31e31b8a 9379 case TARGET_NR_sethostname:
579a97f7 9380 if (!(p = lock_user_string(arg1)))
2852aafd 9381 return -TARGET_EFAULT;
53a5960a
PB
9382 ret = get_errno(sethostname(p, arg2));
9383 unlock_user(p, arg1, 0);
72eb7ea8 9384 return ret;
4f7f8924 9385#ifdef TARGET_NR_setrlimit
31e31b8a 9386 case TARGET_NR_setrlimit:
9de5e440 9387 {
e22b7015 9388 int resource = target_to_host_resource(arg1);
53a5960a 9389 struct target_rlimit *target_rlim;
9de5e440 9390 struct rlimit rlim;
579a97f7 9391 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
2852aafd 9392 return -TARGET_EFAULT;
81bbe906
TY
9393 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
9394 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
53a5960a 9395 unlock_user_struct(target_rlim, arg2, 0);
5dfa88f7
MF
9396 /*
9397 * If we just passed through resource limit settings for memory then
9398 * they would also apply to QEMU's own allocations, and QEMU will
9399 * crash or hang or die if its allocations fail. Ideally we would
9400 * track the guest allocations in QEMU and apply the limits ourselves.
9401 * For now, just tell the guest the call succeeded but don't actually
9402 * limit anything.
9403 */
9404 if (resource != RLIMIT_AS &&
9405 resource != RLIMIT_DATA &&
9406 resource != RLIMIT_STACK) {
9407 return get_errno(setrlimit(resource, &rlim));
9408 } else {
9409 return 0;
9410 }
9de5e440 9411 }
4f7f8924
AR
9412#endif
9413#ifdef TARGET_NR_getrlimit
31e31b8a 9414 case TARGET_NR_getrlimit:
9de5e440 9415 {
e22b7015 9416 int resource = target_to_host_resource(arg1);
53a5960a 9417 struct target_rlimit *target_rlim;
9de5e440 9418 struct rlimit rlim;
3b46e624 9419
9de5e440
FB
9420 ret = get_errno(getrlimit(resource, &rlim));
9421 if (!is_error(ret)) {
579a97f7 9422 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
2852aafd 9423 return -TARGET_EFAULT;
81bbe906
TY
9424 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
9425 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
53a5960a 9426 unlock_user_struct(target_rlim, arg2, 1);
9de5e440
FB
9427 }
9428 }
72eb7ea8 9429 return ret;
4f7f8924 9430#endif
31e31b8a 9431 case TARGET_NR_getrusage:
b409186b
FB
9432 {
9433 struct rusage rusage;
b409186b
FB
9434 ret = get_errno(getrusage(arg1, &rusage));
9435 if (!is_error(ret)) {
a39fb273 9436 ret = host_to_target_rusage(arg2, &rusage);
b409186b
FB
9437 }
9438 }
72eb7ea8 9439 return ret;
859e8a89 9440#if defined(TARGET_NR_gettimeofday)
31e31b8a
FB
9441 case TARGET_NR_gettimeofday:
9442 {
31e31b8a 9443 struct timeval tv;
a52f5f87
RH
9444 struct timezone tz;
9445
9446 ret = get_errno(gettimeofday(&tv, &tz));
31e31b8a 9447 if (!is_error(ret)) {
a52f5f87
RH
9448 if (arg1 && copy_to_user_timeval(arg1, &tv)) {
9449 return -TARGET_EFAULT;
9450 }
9451 if (arg2 && copy_to_user_timezone(arg2, &tz)) {
2852aafd 9452 return -TARGET_EFAULT;
a52f5f87 9453 }
31e31b8a
FB
9454 }
9455 }
72eb7ea8 9456 return ret;
859e8a89
AF
9457#endif
9458#if defined(TARGET_NR_settimeofday)
31e31b8a
FB
9459 case TARGET_NR_settimeofday:
9460 {
b67d8031 9461 struct timeval tv, *ptv = NULL;
ef4467e9
PB
9462 struct timezone tz, *ptz = NULL;
9463
b67d8031
PB
9464 if (arg1) {
9465 if (copy_from_user_timeval(&tv, arg1)) {
2852aafd 9466 return -TARGET_EFAULT;
b67d8031
PB
9467 }
9468 ptv = &tv;
9469 }
ef4467e9
PB
9470
9471 if (arg2) {
9472 if (copy_from_user_timezone(&tz, arg2)) {
2852aafd 9473 return -TARGET_EFAULT;
ef4467e9
PB
9474 }
9475 ptz = &tz;
9476 }
9477
72eb7ea8 9478 return get_errno(settimeofday(ptv, ptz));
31e31b8a 9479 }
859e8a89 9480#endif
9468a5d4 9481#if defined(TARGET_NR_select)
31e31b8a 9482 case TARGET_NR_select:
5457dc9e
LV
9483#if defined(TARGET_WANT_NI_OLD_SELECT)
9484 /* some architectures used to have old_select here
9485 * but now ENOSYS it.
9486 */
9487 ret = -TARGET_ENOSYS;
9488#elif defined(TARGET_WANT_OLD_SYS_SELECT)
9489 ret = do_old_select(arg1);
9468a5d4 9490#else
5457dc9e 9491 ret = do_select(arg1, arg2, arg3, arg4, arg5);
9468a5d4 9492#endif
72eb7ea8 9493 return ret;
9e42382f
RV
9494#endif
9495#ifdef TARGET_NR_pselect6
9496 case TARGET_NR_pselect6:
e5ce9688
FB
9497 return do_pselect6(arg1, arg2, arg3, arg4, arg5, arg6, false);
9498#endif
9499#ifdef TARGET_NR_pselect6_time64
9500 case TARGET_NR_pselect6_time64:
9501 return do_pselect6(arg1, arg2, arg3, arg4, arg5, arg6, true);
048f6b4d 9502#endif
704eff6c 9503#ifdef TARGET_NR_symlink
31e31b8a 9504 case TARGET_NR_symlink:
53a5960a
PB
9505 {
9506 void *p2;
9507 p = lock_user_string(arg1);
9508 p2 = lock_user_string(arg2);
579a97f7
FB
9509 if (!p || !p2)
9510 ret = -TARGET_EFAULT;
9511 else
9512 ret = get_errno(symlink(p, p2));
53a5960a
PB
9513 unlock_user(p2, arg2, 0);
9514 unlock_user(p, arg1, 0);
9515 }
72eb7ea8 9516 return ret;
704eff6c 9517#endif
c0d472b1 9518#if defined(TARGET_NR_symlinkat)
f0b6243d 9519 case TARGET_NR_symlinkat:
f0b6243d 9520 {
579a97f7 9521 void *p2;
f0b6243d
TS
9522 p = lock_user_string(arg1);
9523 p2 = lock_user_string(arg3);
579a97f7 9524 if (!p || !p2)
0da46a6e 9525 ret = -TARGET_EFAULT;
f0b6243d 9526 else
c0d472b1 9527 ret = get_errno(symlinkat(p, arg2, p2));
579a97f7
FB
9528 unlock_user(p2, arg3, 0);
9529 unlock_user(p, arg1, 0);
f0b6243d 9530 }
72eb7ea8 9531 return ret;
f0b6243d 9532#endif
704eff6c 9533#ifdef TARGET_NR_readlink
31e31b8a 9534 case TARGET_NR_readlink:
53a5960a 9535 {
463d8e73 9536 void *p2;
53a5960a 9537 p = lock_user_string(arg1);
579a97f7 9538 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
463d8e73 9539 if (!p || !p2) {
579a97f7 9540 ret = -TARGET_EFAULT;
f17f4989
MF
9541 } else if (!arg3) {
9542 /* Short circuit this for the magic exe check. */
9543 ret = -TARGET_EINVAL;
463d8e73
AS
9544 } else if (is_proc_myself((const char *)p, "exe")) {
9545 char real[PATH_MAX], *temp;
9546 temp = realpath(exec_path, real);
f17f4989
MF
9547 /* Return value is # of bytes that we wrote to the buffer. */
9548 if (temp == NULL) {
9549 ret = get_errno(-1);
9550 } else {
9551 /* Don't worry about sign mismatch as earlier mapping
9552 * logic would have thrown a bad address error. */
9553 ret = MIN(strlen(real), arg3);
9554 /* We cannot NUL terminate the string. */
9555 memcpy(p2, real, ret);
9556 }
463d8e73
AS
9557 } else {
9558 ret = get_errno(readlink(path(p), p2, arg3));
d088d664 9559 }
53a5960a
PB
9560 unlock_user(p2, arg2, ret);
9561 unlock_user(p, arg1, 0);
9562 }
72eb7ea8 9563 return ret;
704eff6c 9564#endif
c0d472b1 9565#if defined(TARGET_NR_readlinkat)
5e0ccb18 9566 case TARGET_NR_readlinkat:
5e0ccb18 9567 {
579a97f7 9568 void *p2;
5e0ccb18 9569 p = lock_user_string(arg2);
579a97f7 9570 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
463d8e73
AS
9571 if (!p || !p2) {
9572 ret = -TARGET_EFAULT;
9573 } else if (is_proc_myself((const char *)p, "exe")) {
9574 char real[PATH_MAX], *temp;
9575 temp = realpath(exec_path, real);
9576 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
9577 snprintf((char *)p2, arg4, "%s", real);
9578 } else {
c0d472b1 9579 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
463d8e73 9580 }
579a97f7
FB
9581 unlock_user(p2, arg3, ret);
9582 unlock_user(p, arg2, 0);
5e0ccb18 9583 }
72eb7ea8 9584 return ret;
5e0ccb18 9585#endif
e5febef5 9586#ifdef TARGET_NR_swapon
31e31b8a 9587 case TARGET_NR_swapon:
579a97f7 9588 if (!(p = lock_user_string(arg1)))
2852aafd 9589 return -TARGET_EFAULT;
53a5960a
PB
9590 ret = get_errno(swapon(p, arg2));
9591 unlock_user(p, arg1, 0);
72eb7ea8 9592 return ret;
e5febef5 9593#endif
31e31b8a 9594 case TARGET_NR_reboot:
c07ecc68
LV
9595 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
9596 /* arg4 must be ignored in all other cases */
9597 p = lock_user_string(arg4);
9598 if (!p) {
2852aafd 9599 return -TARGET_EFAULT;
c07ecc68
LV
9600 }
9601 ret = get_errno(reboot(arg1, arg2, arg3, p));
9602 unlock_user(p, arg4, 0);
9603 } else {
9604 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
9605 }
72eb7ea8 9606 return ret;
e5febef5 9607#ifdef TARGET_NR_mmap
31e31b8a 9608 case TARGET_NR_mmap:
09701199
AG
9609#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
9610 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
a4c075f1
UH
9611 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
9612 || defined(TARGET_S390X)
31e31b8a 9613 {
992f48a0
BS
9614 abi_ulong *v;
9615 abi_ulong v1, v2, v3, v4, v5, v6;
579a97f7 9616 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
2852aafd 9617 return -TARGET_EFAULT;
cbb21eed
MB
9618 v1 = tswapal(v[0]);
9619 v2 = tswapal(v[1]);
9620 v3 = tswapal(v[2]);
9621 v4 = tswapal(v[3]);
9622 v5 = tswapal(v[4]);
9623 v6 = tswapal(v[5]);
53a5960a 9624 unlock_user(v, arg1, 0);
5fafdf24 9625 ret = get_errno(target_mmap(v1, v2, v3,
5286db75
FB
9626 target_to_host_bitmask(v4, mmap_flags_tbl),
9627 v5, v6));
31e31b8a 9628 }
31e31b8a 9629#else
5fafdf24
TS
9630 ret = get_errno(target_mmap(arg1, arg2, arg3,
9631 target_to_host_bitmask(arg4, mmap_flags_tbl),
6fb883e8
FB
9632 arg5,
9633 arg6));
31e31b8a 9634#endif
72eb7ea8 9635 return ret;
e5febef5 9636#endif
a315a145 9637#ifdef TARGET_NR_mmap2
6fb883e8 9638 case TARGET_NR_mmap2:
bb7ec043 9639#ifndef MMAP_SHIFT
c573ff67 9640#define MMAP_SHIFT 12
c573ff67 9641#endif
72eb7ea8
RH
9642 ret = target_mmap(arg1, arg2, arg3,
9643 target_to_host_bitmask(arg4, mmap_flags_tbl),
9644 arg5, arg6 << MMAP_SHIFT);
9645 return get_errno(ret);
a315a145 9646#endif
31e31b8a 9647 case TARGET_NR_munmap:
72eb7ea8 9648 return get_errno(target_munmap(arg1, arg2));
9de5e440 9649 case TARGET_NR_mprotect:
97374d38 9650 {
0429a971 9651 TaskState *ts = cpu->opaque;
97374d38
PB
9652 /* Special hack to detect libc making the stack executable. */
9653 if ((arg3 & PROT_GROWSDOWN)
9654 && arg1 >= ts->info->stack_limit
9655 && arg1 <= ts->info->start_stack) {
9656 arg3 &= ~PROT_GROWSDOWN;
9657 arg2 = arg2 + arg1 - ts->info->stack_limit;
9658 arg1 = ts->info->stack_limit;
9659 }
9660 }
72eb7ea8 9661 return get_errno(target_mprotect(arg1, arg2, arg3));
e5febef5 9662#ifdef TARGET_NR_mremap
9de5e440 9663 case TARGET_NR_mremap:
72eb7ea8 9664 return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
e5febef5 9665#endif
53a5960a 9666 /* ??? msync/mlock/munlock are broken for softmmu. */
e5febef5 9667#ifdef TARGET_NR_msync
9de5e440 9668 case TARGET_NR_msync:
72eb7ea8 9669 return get_errno(msync(g2h(arg1), arg2, arg3));
e5febef5
TS
9670#endif
9671#ifdef TARGET_NR_mlock
9de5e440 9672 case TARGET_NR_mlock:
72eb7ea8 9673 return get_errno(mlock(g2h(arg1), arg2));
e5febef5
TS
9674#endif
9675#ifdef TARGET_NR_munlock
9de5e440 9676 case TARGET_NR_munlock:
72eb7ea8 9677 return get_errno(munlock(g2h(arg1), arg2));
e5febef5
TS
9678#endif
9679#ifdef TARGET_NR_mlockall
9de5e440 9680 case TARGET_NR_mlockall:
72eb7ea8 9681 return get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
e5febef5
TS
9682#endif
9683#ifdef TARGET_NR_munlockall
9de5e440 9684 case TARGET_NR_munlockall:
72eb7ea8 9685 return get_errno(munlockall());
e5febef5 9686#endif
4f7f8924 9687#ifdef TARGET_NR_truncate
31e31b8a 9688 case TARGET_NR_truncate:
579a97f7 9689 if (!(p = lock_user_string(arg1)))
2852aafd 9690 return -TARGET_EFAULT;
53a5960a
PB
9691 ret = get_errno(truncate(p, arg2));
9692 unlock_user(p, arg1, 0);
72eb7ea8 9693 return ret;
4f7f8924
AR
9694#endif
9695#ifdef TARGET_NR_ftruncate
31e31b8a 9696 case TARGET_NR_ftruncate:
72eb7ea8 9697 return get_errno(ftruncate(arg1, arg2));
4f7f8924 9698#endif
31e31b8a 9699 case TARGET_NR_fchmod:
72eb7ea8 9700 return get_errno(fchmod(arg1, arg2));
c0d472b1 9701#if defined(TARGET_NR_fchmodat)
814d7977 9702 case TARGET_NR_fchmodat:
579a97f7 9703 if (!(p = lock_user_string(arg2)))
2852aafd 9704 return -TARGET_EFAULT;
c0d472b1 9705 ret = get_errno(fchmodat(arg1, p, arg3, 0));
579a97f7 9706 unlock_user(p, arg2, 0);
72eb7ea8 9707 return ret;
814d7977 9708#endif
31e31b8a 9709 case TARGET_NR_getpriority:
95c09828
RH
9710 /* Note that negative values are valid for getpriority, so we must
9711 differentiate based on errno settings. */
9712 errno = 0;
9713 ret = getpriority(arg1, arg2);
9714 if (ret == -1 && errno != 0) {
72eb7ea8 9715 return -host_to_target_errno(errno);
95c09828
RH
9716 }
9717#ifdef TARGET_ALPHA
9718 /* Return value is the unbiased priority. Signal no error. */
9719 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
9720#else
9721 /* Return value is a biased priority to avoid negative numbers. */
9722 ret = 20 - ret;
9723#endif
72eb7ea8 9724 return ret;
31e31b8a 9725 case TARGET_NR_setpriority:
72eb7ea8 9726 return get_errno(setpriority(arg1, arg2, arg3));
4f7f8924 9727#ifdef TARGET_NR_statfs
31e31b8a 9728 case TARGET_NR_statfs:
2852aafd
RH
9729 if (!(p = lock_user_string(arg1))) {
9730 return -TARGET_EFAULT;
9731 }
53a5960a
PB
9732 ret = get_errno(statfs(path(p), &stfs));
9733 unlock_user(p, arg1, 0);
31e31b8a
FB
9734 convert_statfs:
9735 if (!is_error(ret)) {
53a5960a 9736 struct target_statfs *target_stfs;
3b46e624 9737
579a97f7 9738 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
2852aafd 9739 return -TARGET_EFAULT;
579a97f7
FB
9740 __put_user(stfs.f_type, &target_stfs->f_type);
9741 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
9742 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
9743 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
9744 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
9745 __put_user(stfs.f_files, &target_stfs->f_files);
9746 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
9747 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
9748 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
9749 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
229d3376 9750 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
d4247ec2
SL
9751#ifdef _STATFS_F_FLAGS
9752 __put_user(stfs.f_flags, &target_stfs->f_flags);
9753#else
9754 __put_user(0, &target_stfs->f_flags);
9755#endif
229d3376 9756 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
53a5960a 9757 unlock_user_struct(target_stfs, arg2, 1);
31e31b8a 9758 }
72eb7ea8 9759 return ret;
4f7f8924
AR
9760#endif
9761#ifdef TARGET_NR_fstatfs
31e31b8a 9762 case TARGET_NR_fstatfs:
56c8f68f 9763 ret = get_errno(fstatfs(arg1, &stfs));
31e31b8a 9764 goto convert_statfs;
4f7f8924 9765#endif
56c8f68f
FB
9766#ifdef TARGET_NR_statfs64
9767 case TARGET_NR_statfs64:
2852aafd
RH
9768 if (!(p = lock_user_string(arg1))) {
9769 return -TARGET_EFAULT;
9770 }
53a5960a
PB
9771 ret = get_errno(statfs(path(p), &stfs));
9772 unlock_user(p, arg1, 0);
56c8f68f
FB
9773 convert_statfs64:
9774 if (!is_error(ret)) {
53a5960a 9775 struct target_statfs64 *target_stfs;
3b46e624 9776
579a97f7 9777 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
2852aafd 9778 return -TARGET_EFAULT;
579a97f7
FB
9779 __put_user(stfs.f_type, &target_stfs->f_type);
9780 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
9781 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
9782 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
9783 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
9784 __put_user(stfs.f_files, &target_stfs->f_files);
9785 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
9786 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
9787 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
9788 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
229d3376 9789 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
b94e2b4e
F
9790#ifdef _STATFS_F_FLAGS
9791 __put_user(stfs.f_flags, &target_stfs->f_flags);
9792#else
9793 __put_user(0, &target_stfs->f_flags);
9794#endif
229d3376 9795 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
579a97f7 9796 unlock_user_struct(target_stfs, arg3, 1);
56c8f68f 9797 }
72eb7ea8 9798 return ret;
56c8f68f
FB
9799 case TARGET_NR_fstatfs64:
9800 ret = get_errno(fstatfs(arg1, &stfs));
9801 goto convert_statfs64;
9802#endif
e5febef5 9803#ifdef TARGET_NR_socketcall
31e31b8a 9804 case TARGET_NR_socketcall:
72eb7ea8 9805 return do_socketcall(arg1, arg2);
e5febef5 9806#endif
3532fa74
FB
9807#ifdef TARGET_NR_accept
9808 case TARGET_NR_accept:
72eb7ea8 9809 return do_accept4(arg1, arg2, arg3, 0);
a94b4987
PM
9810#endif
9811#ifdef TARGET_NR_accept4
9812 case TARGET_NR_accept4:
72eb7ea8 9813 return do_accept4(arg1, arg2, arg3, arg4);
3532fa74
FB
9814#endif
9815#ifdef TARGET_NR_bind
9816 case TARGET_NR_bind:
72eb7ea8 9817 return do_bind(arg1, arg2, arg3);
3532fa74
FB
9818#endif
9819#ifdef TARGET_NR_connect
9820 case TARGET_NR_connect:
72eb7ea8 9821 return do_connect(arg1, arg2, arg3);
3532fa74
FB
9822#endif
9823#ifdef TARGET_NR_getpeername
9824 case TARGET_NR_getpeername:
72eb7ea8 9825 return do_getpeername(arg1, arg2, arg3);
3532fa74
FB
9826#endif
9827#ifdef TARGET_NR_getsockname
9828 case TARGET_NR_getsockname:
72eb7ea8 9829 return do_getsockname(arg1, arg2, arg3);
3532fa74
FB
9830#endif
9831#ifdef TARGET_NR_getsockopt
9832 case TARGET_NR_getsockopt:
72eb7ea8 9833 return do_getsockopt(arg1, arg2, arg3, arg4, arg5);
3532fa74
FB
9834#endif
9835#ifdef TARGET_NR_listen
9836 case TARGET_NR_listen:
72eb7ea8 9837 return get_errno(listen(arg1, arg2));
3532fa74
FB
9838#endif
9839#ifdef TARGET_NR_recv
9840 case TARGET_NR_recv:
72eb7ea8 9841 return do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
3532fa74
FB
9842#endif
9843#ifdef TARGET_NR_recvfrom
9844 case TARGET_NR_recvfrom:
72eb7ea8 9845 return do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
3532fa74
FB
9846#endif
9847#ifdef TARGET_NR_recvmsg
9848 case TARGET_NR_recvmsg:
72eb7ea8 9849 return do_sendrecvmsg(arg1, arg2, arg3, 0);
3532fa74
FB
9850#endif
9851#ifdef TARGET_NR_send
9852 case TARGET_NR_send:
72eb7ea8 9853 return do_sendto(arg1, arg2, arg3, arg4, 0, 0);
3532fa74
FB
9854#endif
9855#ifdef TARGET_NR_sendmsg
9856 case TARGET_NR_sendmsg:
72eb7ea8 9857 return do_sendrecvmsg(arg1, arg2, arg3, 1);
3532fa74 9858#endif
f19e00d7
AG
9859#ifdef TARGET_NR_sendmmsg
9860 case TARGET_NR_sendmmsg:
72eb7ea8 9861 return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
859e8a89
AF
9862#endif
9863#ifdef TARGET_NR_recvmmsg
f19e00d7 9864 case TARGET_NR_recvmmsg:
72eb7ea8 9865 return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
f19e00d7 9866#endif
3532fa74
FB
9867#ifdef TARGET_NR_sendto
9868 case TARGET_NR_sendto:
72eb7ea8 9869 return do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
3532fa74
FB
9870#endif
9871#ifdef TARGET_NR_shutdown
9872 case TARGET_NR_shutdown:
72eb7ea8 9873 return get_errno(shutdown(arg1, arg2));
3532fa74 9874#endif
f894efd1
LV
9875#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
9876 case TARGET_NR_getrandom:
9877 p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9878 if (!p) {
2852aafd 9879 return -TARGET_EFAULT;
f894efd1
LV
9880 }
9881 ret = get_errno(getrandom(p, arg2, arg3));
9882 unlock_user(p, arg1, ret);
72eb7ea8 9883 return ret;
f894efd1 9884#endif
3532fa74
FB
9885#ifdef TARGET_NR_socket
9886 case TARGET_NR_socket:
72eb7ea8 9887 return do_socket(arg1, arg2, arg3);
3532fa74
FB
9888#endif
9889#ifdef TARGET_NR_socketpair
9890 case TARGET_NR_socketpair:
72eb7ea8 9891 return do_socketpair(arg1, arg2, arg3, arg4);
3532fa74
FB
9892#endif
9893#ifdef TARGET_NR_setsockopt
9894 case TARGET_NR_setsockopt:
72eb7ea8 9895 return do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
3532fa74 9896#endif
da2c8ad7 9897#if defined(TARGET_NR_syslog)
31e31b8a 9898 case TARGET_NR_syslog:
da2c8ad7
AM
9899 {
9900 int len = arg2;
7494b0f9 9901
da2c8ad7
AM
9902 switch (arg1) {
9903 case TARGET_SYSLOG_ACTION_CLOSE: /* Close log */
9904 case TARGET_SYSLOG_ACTION_OPEN: /* Open log */
9905 case TARGET_SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
9906 case TARGET_SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging */
9907 case TARGET_SYSLOG_ACTION_CONSOLE_ON: /* Enable logging */
9908 case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: /* Set messages level */
9909 case TARGET_SYSLOG_ACTION_SIZE_UNREAD: /* Number of chars */
9910 case TARGET_SYSLOG_ACTION_SIZE_BUFFER: /* Size of the buffer */
72eb7ea8 9911 return get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
da2c8ad7
AM
9912 case TARGET_SYSLOG_ACTION_READ: /* Read from log */
9913 case TARGET_SYSLOG_ACTION_READ_CLEAR: /* Read/clear msgs */
9914 case TARGET_SYSLOG_ACTION_READ_ALL: /* Read last messages */
9915 {
da2c8ad7 9916 if (len < 0) {
259841c1 9917 return -TARGET_EINVAL;
da2c8ad7 9918 }
da2c8ad7 9919 if (len == 0) {
72eb7ea8 9920 return 0;
da2c8ad7
AM
9921 }
9922 p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
9923 if (!p) {
259841c1 9924 return -TARGET_EFAULT;
da2c8ad7
AM
9925 }
9926 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
9927 unlock_user(p, arg2, arg3);
9928 }
72eb7ea8 9929 return ret;
da2c8ad7 9930 default:
72eb7ea8 9931 return -TARGET_EINVAL;
da2c8ad7
AM
9932 }
9933 }
9934 break;
9935#endif
31e31b8a 9936 case TARGET_NR_setitimer:
66fb9763 9937 {
66fb9763
FB
9938 struct itimerval value, ovalue, *pvalue;
9939
53a5960a 9940 if (arg2) {
66fb9763 9941 pvalue = &value;
788f5ec4
TS
9942 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
9943 || copy_from_user_timeval(&pvalue->it_value,
9944 arg2 + sizeof(struct target_timeval)))
2852aafd 9945 return -TARGET_EFAULT;
66fb9763
FB
9946 } else {
9947 pvalue = NULL;
9948 }
9949 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
53a5960a 9950 if (!is_error(ret) && arg3) {
788f5ec4
TS
9951 if (copy_to_user_timeval(arg3,
9952 &ovalue.it_interval)
9953 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
9954 &ovalue.it_value))
2852aafd 9955 return -TARGET_EFAULT;
66fb9763
FB
9956 }
9957 }
72eb7ea8 9958 return ret;
31e31b8a 9959 case TARGET_NR_getitimer:
66fb9763 9960 {
66fb9763 9961 struct itimerval value;
3b46e624 9962
66fb9763 9963 ret = get_errno(getitimer(arg1, &value));
53a5960a 9964 if (!is_error(ret) && arg2) {
788f5ec4
TS
9965 if (copy_to_user_timeval(arg2,
9966 &value.it_interval)
9967 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
9968 &value.it_value))
2852aafd 9969 return -TARGET_EFAULT;
66fb9763
FB
9970 }
9971 }
72eb7ea8 9972 return ret;
704eff6c 9973#ifdef TARGET_NR_stat
31e31b8a 9974 case TARGET_NR_stat:
2852aafd
RH
9975 if (!(p = lock_user_string(arg1))) {
9976 return -TARGET_EFAULT;
9977 }
53a5960a
PB
9978 ret = get_errno(stat(path(p), &st));
9979 unlock_user(p, arg1, 0);
31e31b8a 9980 goto do_stat;
704eff6c
CG
9981#endif
9982#ifdef TARGET_NR_lstat
31e31b8a 9983 case TARGET_NR_lstat:
2852aafd
RH
9984 if (!(p = lock_user_string(arg1))) {
9985 return -TARGET_EFAULT;
9986 }
53a5960a
PB
9987 ret = get_errno(lstat(path(p), &st));
9988 unlock_user(p, arg1, 0);
31e31b8a 9989 goto do_stat;
704eff6c 9990#endif
4f7f8924 9991#ifdef TARGET_NR_fstat
31e31b8a
FB
9992 case TARGET_NR_fstat:
9993 {
9994 ret = get_errno(fstat(arg1, &st));
704eff6c 9995#if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat)
31e31b8a 9996 do_stat:
704eff6c 9997#endif
31e31b8a 9998 if (!is_error(ret)) {
53a5960a 9999 struct target_stat *target_st;
e3584658 10000
579a97f7 10001 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
2852aafd 10002 return -TARGET_EFAULT;
12727917 10003 memset(target_st, 0, sizeof(*target_st));
d2fd1af7
FB
10004 __put_user(st.st_dev, &target_st->st_dev);
10005 __put_user(st.st_ino, &target_st->st_ino);
10006 __put_user(st.st_mode, &target_st->st_mode);
10007 __put_user(st.st_uid, &target_st->st_uid);
10008 __put_user(st.st_gid, &target_st->st_gid);
10009 __put_user(st.st_nlink, &target_st->st_nlink);
10010 __put_user(st.st_rdev, &target_st->st_rdev);
10011 __put_user(st.st_size, &target_st->st_size);
10012 __put_user(st.st_blksize, &target_st->st_blksize);
10013 __put_user(st.st_blocks, &target_st->st_blocks);
10014 __put_user(st.st_atime, &target_st->target_st_atime);
10015 __put_user(st.st_mtime, &target_st->target_st_mtime);
10016 __put_user(st.st_ctime, &target_st->target_st_ctime);
5f992db6
CYT
10017#if (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) && \
10018 defined(TARGET_STAT_HAVE_NSEC)
10019 __put_user(st.st_atim.tv_nsec,
10020 &target_st->target_st_atime_nsec);
10021 __put_user(st.st_mtim.tv_nsec,
10022 &target_st->target_st_mtime_nsec);
10023 __put_user(st.st_ctim.tv_nsec,
10024 &target_st->target_st_ctime_nsec);
10025#endif
53a5960a 10026 unlock_user_struct(target_st, arg2, 1);
31e31b8a
FB
10027 }
10028 }
72eb7ea8 10029 return ret;
ebc05488 10030#endif
31e31b8a 10031 case TARGET_NR_vhangup:
72eb7ea8 10032 return get_errno(vhangup());
42ad6ae9
FB
10033#ifdef TARGET_NR_syscall
10034 case TARGET_NR_syscall:
72eb7ea8
RH
10035 return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
10036 arg6, arg7, arg8, 0);
ebc05488 10037#endif
859e8a89 10038#if defined(TARGET_NR_wait4)
31e31b8a
FB
10039 case TARGET_NR_wait4:
10040 {
10041 int status;
992f48a0 10042 abi_long status_ptr = arg2;
31e31b8a 10043 struct rusage rusage, *rusage_ptr;
992f48a0 10044 abi_ulong target_rusage = arg4;
a39fb273 10045 abi_long rusage_err;
31e31b8a
FB
10046 if (target_rusage)
10047 rusage_ptr = &rusage;
10048 else
10049 rusage_ptr = NULL;
4af80a37 10050 ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr));
31e31b8a 10051 if (!is_error(ret)) {
5379557b 10052 if (status_ptr && ret) {
1d9d8b55 10053 status = host_to_target_waitstatus(status);
2f619698 10054 if (put_user_s32(status, status_ptr))
2852aafd 10055 return -TARGET_EFAULT;
31e31b8a 10056 }
a39fb273
PJ
10057 if (target_rusage) {
10058 rusage_err = host_to_target_rusage(target_rusage, &rusage);
10059 if (rusage_err) {
10060 ret = rusage_err;
10061 }
10062 }
31e31b8a
FB
10063 }
10064 }
72eb7ea8 10065 return ret;
859e8a89 10066#endif
e5febef5 10067#ifdef TARGET_NR_swapoff
31e31b8a 10068 case TARGET_NR_swapoff:
579a97f7 10069 if (!(p = lock_user_string(arg1)))
2852aafd 10070 return -TARGET_EFAULT;
53a5960a
PB
10071 ret = get_errno(swapoff(p));
10072 unlock_user(p, arg1, 0);
72eb7ea8 10073 return ret;
e5febef5 10074#endif
31e31b8a 10075 case TARGET_NR_sysinfo:
a5448a7d 10076 {
53a5960a 10077 struct target_sysinfo *target_value;
a5448a7d
FB
10078 struct sysinfo value;
10079 ret = get_errno(sysinfo(&value));
53a5960a 10080 if (!is_error(ret) && arg1)
a5448a7d 10081 {
579a97f7 10082 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
2852aafd 10083 return -TARGET_EFAULT;
a5448a7d
FB
10084 __put_user(value.uptime, &target_value->uptime);
10085 __put_user(value.loads[0], &target_value->loads[0]);
10086 __put_user(value.loads[1], &target_value->loads[1]);
10087 __put_user(value.loads[2], &target_value->loads[2]);
10088 __put_user(value.totalram, &target_value->totalram);
10089 __put_user(value.freeram, &target_value->freeram);
10090 __put_user(value.sharedram, &target_value->sharedram);
10091 __put_user(value.bufferram, &target_value->bufferram);
10092 __put_user(value.totalswap, &target_value->totalswap);
10093 __put_user(value.freeswap, &target_value->freeswap);
10094 __put_user(value.procs, &target_value->procs);
10095 __put_user(value.totalhigh, &target_value->totalhigh);
10096 __put_user(value.freehigh, &target_value->freehigh);
10097 __put_user(value.mem_unit, &target_value->mem_unit);
53a5960a 10098 unlock_user_struct(target_value, arg1, 1);
a5448a7d
FB
10099 }
10100 }
72eb7ea8 10101 return ret;
e5febef5 10102#ifdef TARGET_NR_ipc
31e31b8a 10103 case TARGET_NR_ipc:
72eb7ea8 10104 return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
e5febef5 10105#endif
e5289087
AJ
10106#ifdef TARGET_NR_semget
10107 case TARGET_NR_semget:
72eb7ea8 10108 return get_errno(semget(arg1, arg2, arg3));
e5289087
AJ
10109#endif
10110#ifdef TARGET_NR_semop
10111 case TARGET_NR_semop:
cac46eb0 10112 return do_semtimedop(arg1, arg2, arg3, 0, false);
d8c08b1e
MK
10113#endif
10114#ifdef TARGET_NR_semtimedop
10115 case TARGET_NR_semtimedop:
cac46eb0
FB
10116 return do_semtimedop(arg1, arg2, arg3, arg4, false);
10117#endif
10118#ifdef TARGET_NR_semtimedop_time64
10119 case TARGET_NR_semtimedop_time64:
10120 return do_semtimedop(arg1, arg2, arg3, arg4, true);
e5289087
AJ
10121#endif
10122#ifdef TARGET_NR_semctl
10123 case TARGET_NR_semctl:
72eb7ea8 10124 return do_semctl(arg1, arg2, arg3, arg4);
e5289087 10125#endif
eeb438c1
AJ
10126#ifdef TARGET_NR_msgctl
10127 case TARGET_NR_msgctl:
72eb7ea8 10128 return do_msgctl(arg1, arg2, arg3);
eeb438c1
AJ
10129#endif
10130#ifdef TARGET_NR_msgget
10131 case TARGET_NR_msgget:
72eb7ea8 10132 return get_errno(msgget(arg1, arg2));
eeb438c1
AJ
10133#endif
10134#ifdef TARGET_NR_msgrcv
10135 case TARGET_NR_msgrcv:
72eb7ea8 10136 return do_msgrcv(arg1, arg2, arg3, arg4, arg5);
eeb438c1
AJ
10137#endif
10138#ifdef TARGET_NR_msgsnd
10139 case TARGET_NR_msgsnd:
72eb7ea8 10140 return do_msgsnd(arg1, arg2, arg3, arg4);
88a8c984
RV
10141#endif
10142#ifdef TARGET_NR_shmget
10143 case TARGET_NR_shmget:
72eb7ea8 10144 return get_errno(shmget(arg1, arg2, arg3));
88a8c984
RV
10145#endif
10146#ifdef TARGET_NR_shmctl
10147 case TARGET_NR_shmctl:
72eb7ea8 10148 return do_shmctl(arg1, arg2, arg3);
88a8c984
RV
10149#endif
10150#ifdef TARGET_NR_shmat
10151 case TARGET_NR_shmat:
72eb7ea8 10152 return do_shmat(cpu_env, arg1, arg2, arg3);
88a8c984
RV
10153#endif
10154#ifdef TARGET_NR_shmdt
10155 case TARGET_NR_shmdt:
72eb7ea8 10156 return do_shmdt(arg1);
eeb438c1 10157#endif
31e31b8a 10158 case TARGET_NR_fsync:
72eb7ea8 10159 return get_errno(fsync(arg1));
31e31b8a 10160 case TARGET_NR_clone:
4ce6243d
PM
10161 /* Linux manages to have three different orderings for its
10162 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
10163 * match the kernel's CONFIG_CLONE_* settings.
10164 * Microblaze is further special in that it uses a sixth
10165 * implicit argument to clone for the TLS pointer.
10166 */
10167#if defined(TARGET_MICROBLAZE)
a5b3bdcb 10168 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
4ce6243d
PM
10169#elif defined(TARGET_CLONE_BACKWARDS)
10170 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
10171#elif defined(TARGET_CLONE_BACKWARDS2)
a4c075f1 10172 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
0b6d3ae0 10173#else
4ce6243d 10174 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
0b6d3ae0 10175#endif
72eb7ea8 10176 return ret;
ec86b0fb
FB
10177#ifdef __NR_exit_group
10178 /* new thread calls */
10179 case TARGET_NR_exit_group:
708b6a64 10180 preexit_cleanup(cpu_env, arg1);
72eb7ea8 10181 return get_errno(exit_group(arg1));
ec86b0fb 10182#endif
31e31b8a 10183 case TARGET_NR_setdomainname:
579a97f7 10184 if (!(p = lock_user_string(arg1)))
2852aafd 10185 return -TARGET_EFAULT;
53a5960a
PB
10186 ret = get_errno(setdomainname(p, arg2));
10187 unlock_user(p, arg1, 0);
72eb7ea8 10188 return ret;
31e31b8a
FB
10189 case TARGET_NR_uname:
10190 /* no need to transcode because we use the linux syscall */
29e619b1
FB
10191 {
10192 struct new_utsname * buf;
3b46e624 10193
579a97f7 10194 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
2852aafd 10195 return -TARGET_EFAULT;
29e619b1
FB
10196 ret = get_errno(sys_uname(buf));
10197 if (!is_error(ret)) {
332c9781 10198 /* Overwrite the native machine name with whatever is being
29e619b1 10199 emulated. */
871f95c6
PMD
10200 g_strlcpy(buf->machine, cpu_to_uname_machine(cpu_env),
10201 sizeof(buf->machine));
c5937220 10202 /* Allow the user to override the reported release. */
332c9781
PM
10203 if (qemu_uname_release && *qemu_uname_release) {
10204 g_strlcpy(buf->release, qemu_uname_release,
10205 sizeof(buf->release));
10206 }
29e619b1 10207 }
53a5960a 10208 unlock_user_struct(buf, arg1, 1);
29e619b1 10209 }
72eb7ea8 10210 return ret;
6dbad63e 10211#ifdef TARGET_I386
31e31b8a 10212 case TARGET_NR_modify_ldt:
72eb7ea8 10213 return do_modify_ldt(cpu_env, arg1, arg2, arg3);
84409ddb 10214#if !defined(TARGET_X86_64)
5cd4393b 10215 case TARGET_NR_vm86:
72eb7ea8 10216 return do_vm86(cpu_env, arg1, arg2);
84409ddb 10217#endif
6dbad63e 10218#endif
859e8a89 10219#if defined(TARGET_NR_adjtimex)
31e31b8a 10220 case TARGET_NR_adjtimex:
19f59bce
AM
10221 {
10222 struct timex host_buf;
10223
10224 if (target_to_host_timex(&host_buf, arg1) != 0) {
2852aafd 10225 return -TARGET_EFAULT;
19f59bce
AM
10226 }
10227 ret = get_errno(adjtimex(&host_buf));
10228 if (!is_error(ret)) {
10229 if (host_to_target_timex(arg1, &host_buf) != 0) {
2852aafd 10230 return -TARGET_EFAULT;
19f59bce
AM
10231 }
10232 }
10233 }
72eb7ea8 10234 return ret;
859e8a89 10235#endif
38860a03
AM
10236#if defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME)
10237 case TARGET_NR_clock_adjtime:
10238 {
10239 struct timex htx, *phtx = &htx;
10240
10241 if (target_to_host_timex(phtx, arg2) != 0) {
2852aafd 10242 return -TARGET_EFAULT;
38860a03
AM
10243 }
10244 ret = get_errno(clock_adjtime(arg1, phtx));
10245 if (!is_error(ret) && phtx) {
10246 if (host_to_target_timex(arg2, phtx) != 0) {
2852aafd 10247 return -TARGET_EFAULT;
38860a03
AM
10248 }
10249 }
10250 }
72eb7ea8 10251 return ret;
6ac03b2c
FB
10252#endif
10253#if defined(TARGET_NR_clock_adjtime64) && defined(CONFIG_CLOCK_ADJTIME)
10254 case TARGET_NR_clock_adjtime64:
10255 {
10256 struct timex htx;
10257
10258 if (target_to_host_timex64(&htx, arg2) != 0) {
10259 return -TARGET_EFAULT;
10260 }
10261 ret = get_errno(clock_adjtime(arg1, &htx));
10262 if (!is_error(ret) && host_to_target_timex64(arg2, &htx)) {
10263 return -TARGET_EFAULT;
10264 }
10265 }
10266 return ret;
38860a03 10267#endif
31e31b8a 10268 case TARGET_NR_getpgid:
72eb7ea8 10269 return get_errno(getpgid(arg1));
31e31b8a 10270 case TARGET_NR_fchdir:
72eb7ea8 10271 return get_errno(fchdir(arg1));
31e31b8a 10272 case TARGET_NR_personality:
72eb7ea8 10273 return get_errno(personality(arg1));
7a3148a9 10274#ifdef TARGET_NR__llseek /* Not on alpha */
31e31b8a
FB
10275 case TARGET_NR__llseek:
10276 {
0c1592d9 10277 int64_t res;
d35b261c 10278#if !defined(__NR_llseek)
9fea273c 10279 res = lseek(arg1, ((uint64_t)arg2 << 32) | (abi_ulong)arg3, arg5);
0c1592d9
PM
10280 if (res == -1) {
10281 ret = get_errno(res);
10282 } else {
10283 ret = 0;
10284 }
4f2ac237 10285#else
31e31b8a 10286 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4f2ac237 10287#endif
0c1592d9 10288 if ((ret == 0) && put_user_s64(res, arg4)) {
2852aafd 10289 return -TARGET_EFAULT;
0c1592d9 10290 }
31e31b8a 10291 }
72eb7ea8 10292 return ret;
7a3148a9 10293#endif
704eff6c 10294#ifdef TARGET_NR_getdents
31e31b8a 10295 case TARGET_NR_getdents:
2b3f64cb 10296#ifdef EMULATE_GETDENTS_WITH_GETDENTS
d83c8733 10297#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4add45b4 10298 {
53a5960a 10299 struct target_dirent *target_dirp;
6556a833 10300 struct linux_dirent *dirp;
992f48a0 10301 abi_long count = arg3;
4add45b4 10302
0e173b24
HK
10303 dirp = g_try_malloc(count);
10304 if (!dirp) {
259841c1 10305 return -TARGET_ENOMEM;
0da46a6e 10306 }
3b46e624 10307
4add45b4
FB
10308 ret = get_errno(sys_getdents(arg1, dirp, count));
10309 if (!is_error(ret)) {
6556a833 10310 struct linux_dirent *de;
4add45b4
FB
10311 struct target_dirent *tde;
10312 int len = ret;
10313 int reclen, treclen;
10314 int count1, tnamelen;
10315
10316 count1 = 0;
10317 de = dirp;
579a97f7 10318 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
2852aafd 10319 return -TARGET_EFAULT;
4add45b4
FB
10320 tde = target_dirp;
10321 while (len > 0) {
10322 reclen = de->d_reclen;
333858b7
DL
10323 tnamelen = reclen - offsetof(struct linux_dirent, d_name);
10324 assert(tnamelen >= 0);
10325 treclen = tnamelen + offsetof(struct target_dirent, d_name);
10326 assert(count1 + treclen <= count);
4add45b4 10327 tde->d_reclen = tswap16(treclen);
cbb21eed
MB
10328 tde->d_ino = tswapal(de->d_ino);
10329 tde->d_off = tswapal(de->d_off);
333858b7 10330 memcpy(tde->d_name, de->d_name, tnamelen);
6556a833 10331 de = (struct linux_dirent *)((char *)de + reclen);
4add45b4 10332 len -= reclen;
1c5bf3bf 10333 tde = (struct target_dirent *)((char *)tde + treclen);
4add45b4
FB
10334 count1 += treclen;
10335 }
10336 ret = count1;
579a97f7 10337 unlock_user(target_dirp, arg2, ret);
4add45b4 10338 }
0e173b24 10339 g_free(dirp);
4add45b4
FB
10340 }
10341#else
31e31b8a 10342 {
6556a833 10343 struct linux_dirent *dirp;
992f48a0 10344 abi_long count = arg3;
dab2ed99 10345
579a97f7 10346 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
2852aafd 10347 return -TARGET_EFAULT;
72f03900 10348 ret = get_errno(sys_getdents(arg1, dirp, count));
31e31b8a 10349 if (!is_error(ret)) {
6556a833 10350 struct linux_dirent *de;
31e31b8a
FB
10351 int len = ret;
10352 int reclen;
10353 de = dirp;
10354 while (len > 0) {
8083a3e5 10355 reclen = de->d_reclen;
31e31b8a
FB
10356 if (reclen > len)
10357 break;
8083a3e5 10358 de->d_reclen = tswap16(reclen);
31e31b8a
FB
10359 tswapls(&de->d_ino);
10360 tswapls(&de->d_off);
6556a833 10361 de = (struct linux_dirent *)((char *)de + reclen);
31e31b8a
FB
10362 len -= reclen;
10363 }
10364 }
53a5960a 10365 unlock_user(dirp, arg2, ret);
3307e236
PM
10366 }
10367#endif
10368#else
10369 /* Implement getdents in terms of getdents64 */
10370 {
10371 struct linux_dirent64 *dirp;
10372 abi_long count = arg3;
10373
10374 dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
10375 if (!dirp) {
2852aafd 10376 return -TARGET_EFAULT;
3307e236
PM
10377 }
10378 ret = get_errno(sys_getdents64(arg1, dirp, count));
10379 if (!is_error(ret)) {
10380 /* Convert the dirent64 structs to target dirent. We do this
10381 * in-place, since we can guarantee that a target_dirent is no
10382 * larger than a dirent64; however this means we have to be
10383 * careful to read everything before writing in the new format.
10384 */
10385 struct linux_dirent64 *de;
10386 struct target_dirent *tde;
10387 int len = ret;
10388 int tlen = 0;
10389
10390 de = dirp;
10391 tde = (struct target_dirent *)dirp;
10392 while (len > 0) {
10393 int namelen, treclen;
10394 int reclen = de->d_reclen;
10395 uint64_t ino = de->d_ino;
10396 int64_t off = de->d_off;
10397 uint8_t type = de->d_type;
10398
10399 namelen = strlen(de->d_name);
10400 treclen = offsetof(struct target_dirent, d_name)
10401 + namelen + 2;
10402 treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
10403
10404 memmove(tde->d_name, de->d_name, namelen + 1);
10405 tde->d_ino = tswapal(ino);
10406 tde->d_off = tswapal(off);
10407 tde->d_reclen = tswap16(treclen);
10408 /* The target_dirent type is in what was formerly a padding
10409 * byte at the end of the structure:
10410 */
10411 *(((char *)tde) + treclen - 1) = type;
10412
10413 de = (struct linux_dirent64 *)((char *)de + reclen);
10414 tde = (struct target_dirent *)((char *)tde + treclen);
10415 len -= reclen;
10416 tlen += treclen;
10417 }
10418 ret = tlen;
10419 }
10420 unlock_user(dirp, arg2, ret);
31e31b8a 10421 }
4add45b4 10422#endif
72eb7ea8 10423 return ret;
704eff6c 10424#endif /* TARGET_NR_getdents */
3ae43202 10425#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
dab2ed99
FB
10426 case TARGET_NR_getdents64:
10427 {
6556a833 10428 struct linux_dirent64 *dirp;
992f48a0 10429 abi_long count = arg3;
579a97f7 10430 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
2852aafd 10431 return -TARGET_EFAULT;
dab2ed99
FB
10432 ret = get_errno(sys_getdents64(arg1, dirp, count));
10433 if (!is_error(ret)) {
6556a833 10434 struct linux_dirent64 *de;
dab2ed99
FB
10435 int len = ret;
10436 int reclen;
10437 de = dirp;
10438 while (len > 0) {
8083a3e5 10439 reclen = de->d_reclen;
dab2ed99
FB
10440 if (reclen > len)
10441 break;
8083a3e5 10442 de->d_reclen = tswap16(reclen);
8582a53a
FB
10443 tswap64s((uint64_t *)&de->d_ino);
10444 tswap64s((uint64_t *)&de->d_off);
6556a833 10445 de = (struct linux_dirent64 *)((char *)de + reclen);
dab2ed99
FB
10446 len -= reclen;
10447 }
10448 }
53a5960a 10449 unlock_user(dirp, arg2, ret);
dab2ed99 10450 }
72eb7ea8 10451 return ret;
a541f297 10452#endif /* TARGET_NR_getdents64 */
9468a5d4 10453#if defined(TARGET_NR__newselect)
31e31b8a 10454 case TARGET_NR__newselect:
72eb7ea8 10455 return do_select(arg1, arg2, arg3, arg4, arg5);
e5febef5 10456#endif
e5ce9688 10457#ifdef TARGET_NR_poll
9de5e440 10458 case TARGET_NR_poll:
e5ce9688
FB
10459 return do_ppoll(arg1, arg2, arg3, arg4, arg5, false, false);
10460#endif
10461#ifdef TARGET_NR_ppoll
d8035d4c 10462 case TARGET_NR_ppoll:
e5ce9688
FB
10463 return do_ppoll(arg1, arg2, arg3, arg4, arg5, true, false);
10464#endif
10465#ifdef TARGET_NR_ppoll_time64
10466 case TARGET_NR_ppoll_time64:
10467 return do_ppoll(arg1, arg2, arg3, arg4, arg5, true, true);
e5febef5 10468#endif
31e31b8a 10469 case TARGET_NR_flock:
9de5e440
FB
10470 /* NOTE: the flock constant seems to be the same for every
10471 Linux platform */
72eb7ea8 10472 return get_errno(safe_flock(arg1, arg2));
31e31b8a
FB
10473 case TARGET_NR_readv:
10474 {
f287b2c2
RH
10475 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
10476 if (vec != NULL) {
918c03ed 10477 ret = get_errno(safe_readv(arg1, vec, arg3));
f287b2c2
RH
10478 unlock_iovec(vec, arg2, arg3, 1);
10479 } else {
10480 ret = -host_to_target_errno(errno);
10481 }
31e31b8a 10482 }
72eb7ea8 10483 return ret;
31e31b8a
FB
10484 case TARGET_NR_writev:
10485 {
f287b2c2
RH
10486 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10487 if (vec != NULL) {
918c03ed 10488 ret = get_errno(safe_writev(arg1, vec, arg3));
f287b2c2
RH
10489 unlock_iovec(vec, arg2, arg3, 0);
10490 } else {
10491 ret = -host_to_target_errno(errno);
10492 }
31e31b8a 10493 }
72eb7ea8 10494 return ret;
0f26386c
DJ
10495#if defined(TARGET_NR_preadv)
10496 case TARGET_NR_preadv:
10497 {
10498 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
10499 if (vec != NULL) {
9ac22517
MF
10500 unsigned long low, high;
10501
10502 target_to_host_low_high(arg4, arg5, &low, &high);
10503 ret = get_errno(safe_preadv(arg1, vec, arg3, low, high));
0f26386c
DJ
10504 unlock_iovec(vec, arg2, arg3, 1);
10505 } else {
10506 ret = -host_to_target_errno(errno);
f8d00fba
DJ
10507 }
10508 }
72eb7ea8 10509 return ret;
f8d00fba
DJ
10510#endif
10511#if defined(TARGET_NR_pwritev)
10512 case TARGET_NR_pwritev:
10513 {
10514 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10515 if (vec != NULL) {
9ac22517
MF
10516 unsigned long low, high;
10517
10518 target_to_host_low_high(arg4, arg5, &low, &high);
10519 ret = get_errno(safe_pwritev(arg1, vec, arg3, low, high));
f8d00fba
DJ
10520 unlock_iovec(vec, arg2, arg3, 0);
10521 } else {
10522 ret = -host_to_target_errno(errno);
0f26386c
DJ
10523 }
10524 }
72eb7ea8 10525 return ret;
0f26386c 10526#endif
31e31b8a 10527 case TARGET_NR_getsid:
72eb7ea8 10528 return get_errno(getsid(arg1));
7a3148a9 10529#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
31e31b8a 10530 case TARGET_NR_fdatasync:
72eb7ea8 10531 return get_errno(fdatasync(arg1));
704eff6c 10532#endif
737de1d1
MF
10533 case TARGET_NR_sched_getaffinity:
10534 {
10535 unsigned int mask_size;
10536 unsigned long *mask;
10537
10538 /*
10539 * sched_getaffinity needs multiples of ulong, so need to take
10540 * care of mismatches between target ulong and host ulong sizes.
10541 */
10542 if (arg2 & (sizeof(abi_ulong) - 1)) {
72eb7ea8 10543 return -TARGET_EINVAL;
737de1d1
MF
10544 }
10545 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
10546
10547 mask = alloca(mask_size);
2e0a8713 10548 memset(mask, 0, mask_size);
737de1d1
MF
10549 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
10550
10551 if (!is_error(ret)) {
be3bd286
PM
10552 if (ret > arg2) {
10553 /* More data returned than the caller's buffer will fit.
10554 * This only happens if sizeof(abi_long) < sizeof(long)
10555 * and the caller passed us a buffer holding an odd number
10556 * of abi_longs. If the host kernel is actually using the
10557 * extra 4 bytes then fail EINVAL; otherwise we can just
10558 * ignore them and only copy the interesting part.
10559 */
10560 int numcpus = sysconf(_SC_NPROCESSORS_CONF);
10561 if (numcpus > arg2 * 8) {
72eb7ea8 10562 return -TARGET_EINVAL;
be3bd286
PM
10563 }
10564 ret = arg2;
10565 }
10566
5fdefcf8 10567 if (host_to_target_cpu_mask(mask, mask_size, arg3, ret)) {
2852aafd 10568 return -TARGET_EFAULT;
5fdefcf8 10569 }
737de1d1
MF
10570 }
10571 }
72eb7ea8 10572 return ret;
737de1d1
MF
10573 case TARGET_NR_sched_setaffinity:
10574 {
10575 unsigned int mask_size;
10576 unsigned long *mask;
10577
10578 /*
10579 * sched_setaffinity needs multiples of ulong, so need to take
10580 * care of mismatches between target ulong and host ulong sizes.
10581 */
10582 if (arg2 & (sizeof(abi_ulong) - 1)) {
72eb7ea8 10583 return -TARGET_EINVAL;
737de1d1
MF
10584 }
10585 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
737de1d1 10586 mask = alloca(mask_size);
2e0a8713
ST
10587
10588 ret = target_to_host_cpu_mask(mask, mask_size, arg3, arg2);
10589 if (ret) {
72eb7ea8 10590 return ret;
737de1d1 10591 }
737de1d1 10592
72eb7ea8 10593 return get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
737de1d1 10594 }
b827c3ed
ST
10595 case TARGET_NR_getcpu:
10596 {
10597 unsigned cpu, node;
10598 ret = get_errno(sys_getcpu(arg1 ? &cpu : NULL,
10599 arg2 ? &node : NULL,
10600 NULL));
10601 if (is_error(ret)) {
259841c1 10602 return ret;
b827c3ed
ST
10603 }
10604 if (arg1 && put_user_u32(cpu, arg1)) {
2852aafd 10605 return -TARGET_EFAULT;
b827c3ed
ST
10606 }
10607 if (arg2 && put_user_u32(node, arg2)) {
2852aafd 10608 return -TARGET_EFAULT;
b827c3ed
ST
10609 }
10610 }
72eb7ea8 10611 return ret;
31e31b8a 10612 case TARGET_NR_sched_setparam:
5cd4393b 10613 {
53a5960a 10614 struct sched_param *target_schp;
5cd4393b 10615 struct sched_param schp;
53a5960a 10616
a1d5c5b2
TM
10617 if (arg2 == 0) {
10618 return -TARGET_EINVAL;
10619 }
579a97f7 10620 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
2852aafd 10621 return -TARGET_EFAULT;
5cd4393b 10622 schp.sched_priority = tswap32(target_schp->sched_priority);
53a5960a 10623 unlock_user_struct(target_schp, arg2, 0);
72eb7ea8 10624 return get_errno(sched_setparam(arg1, &schp));
5cd4393b 10625 }
31e31b8a 10626 case TARGET_NR_sched_getparam:
5cd4393b 10627 {
53a5960a 10628 struct sched_param *target_schp;
5cd4393b 10629 struct sched_param schp;
a1d5c5b2
TM
10630
10631 if (arg2 == 0) {
10632 return -TARGET_EINVAL;
10633 }
5cd4393b
FB
10634 ret = get_errno(sched_getparam(arg1, &schp));
10635 if (!is_error(ret)) {
579a97f7 10636 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
2852aafd 10637 return -TARGET_EFAULT;
5cd4393b 10638 target_schp->sched_priority = tswap32(schp.sched_priority);
53a5960a 10639 unlock_user_struct(target_schp, arg2, 1);
5cd4393b
FB
10640 }
10641 }
72eb7ea8 10642 return ret;
31e31b8a 10643 case TARGET_NR_sched_setscheduler:
5cd4393b 10644 {
53a5960a 10645 struct sched_param *target_schp;
5cd4393b 10646 struct sched_param schp;
a1d5c5b2
TM
10647 if (arg3 == 0) {
10648 return -TARGET_EINVAL;
10649 }
579a97f7 10650 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
2852aafd 10651 return -TARGET_EFAULT;
5cd4393b 10652 schp.sched_priority = tswap32(target_schp->sched_priority);
53a5960a 10653 unlock_user_struct(target_schp, arg3, 0);
72eb7ea8 10654 return get_errno(sched_setscheduler(arg1, arg2, &schp));
5cd4393b 10655 }
31e31b8a 10656 case TARGET_NR_sched_getscheduler:
72eb7ea8 10657 return get_errno(sched_getscheduler(arg1));
31e31b8a 10658 case TARGET_NR_sched_yield:
72eb7ea8 10659 return get_errno(sched_yield());
31e31b8a 10660 case TARGET_NR_sched_get_priority_max:
72eb7ea8 10661 return get_errno(sched_get_priority_max(arg1));
31e31b8a 10662 case TARGET_NR_sched_get_priority_min:
72eb7ea8 10663 return get_errno(sched_get_priority_min(arg1));
859e8a89 10664#ifdef TARGET_NR_sched_rr_get_interval
31e31b8a 10665 case TARGET_NR_sched_rr_get_interval:
5cd4393b 10666 {
5cd4393b
FB
10667 struct timespec ts;
10668 ret = get_errno(sched_rr_get_interval(arg1, &ts));
10669 if (!is_error(ret)) {
d4290c40 10670 ret = host_to_target_timespec(arg2, &ts);
5cd4393b
FB
10671 }
10672 }
72eb7ea8 10673 return ret;
859e8a89 10674#endif
ddcbde15
FB
10675#ifdef TARGET_NR_sched_rr_get_interval_time64
10676 case TARGET_NR_sched_rr_get_interval_time64:
10677 {
10678 struct timespec ts;
10679 ret = get_errno(sched_rr_get_interval(arg1, &ts));
10680 if (!is_error(ret)) {
10681 ret = host_to_target_timespec64(arg2, &ts);
10682 }
10683 }
10684 return ret;
10685#endif
859e8a89 10686#if defined(TARGET_NR_nanosleep)
31e31b8a 10687 case TARGET_NR_nanosleep:
1b6b029e 10688 {
1b6b029e 10689 struct timespec req, rem;
53a5960a 10690 target_to_host_timespec(&req, arg1);
9e518226 10691 ret = get_errno(safe_nanosleep(&req, &rem));
53a5960a
PB
10692 if (is_error(ret) && arg2) {
10693 host_to_target_timespec(arg2, &rem);
1b6b029e
FB
10694 }
10695 }
72eb7ea8 10696 return ret;
859e8a89 10697#endif
31e31b8a 10698 case TARGET_NR_prctl:
1e6722f8
PM
10699 switch (arg1) {
10700 case PR_GET_PDEATHSIG:
10701 {
10702 int deathsig;
10703 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
10704 if (!is_error(ret) && arg2
d9a5eba4 10705 && put_user_s32(deathsig, arg2)) {
2852aafd 10706 return -TARGET_EFAULT;
e5574487 10707 }
72eb7ea8 10708 return ret;
1e6722f8 10709 }
db9526b1
PM
10710#ifdef PR_GET_NAME
10711 case PR_GET_NAME:
10712 {
10713 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
10714 if (!name) {
2852aafd 10715 return -TARGET_EFAULT;
db9526b1
PM
10716 }
10717 ret = get_errno(prctl(arg1, (unsigned long)name,
10718 arg3, arg4, arg5));
10719 unlock_user(name, arg2, 16);
72eb7ea8 10720 return ret;
db9526b1
PM
10721 }
10722 case PR_SET_NAME:
10723 {
10724 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
10725 if (!name) {
2852aafd 10726 return -TARGET_EFAULT;
db9526b1
PM
10727 }
10728 ret = get_errno(prctl(arg1, (unsigned long)name,
10729 arg3, arg4, arg5));
10730 unlock_user(name, arg2, 0);
72eb7ea8 10731 return ret;
db9526b1
PM
10732 }
10733#endif
5b702ffd
SM
10734#ifdef TARGET_MIPS
10735 case TARGET_PR_GET_FP_MODE:
64ea3d67
SM
10736 {
10737 CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
10738 ret = 0;
10739 if (env->CP0_Status & (1 << CP0St_FR)) {
10740 ret |= TARGET_PR_FP_MODE_FR;
10741 }
10742 if (env->CP0_Config5 & (1 << CP0C5_FRE)) {
10743 ret |= TARGET_PR_FP_MODE_FRE;
10744 }
10745 return ret;
10746 }
5b702ffd 10747 case TARGET_PR_SET_FP_MODE:
64ea3d67
SM
10748 {
10749 CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
10750 bool old_fr = env->CP0_Status & (1 << CP0St_FR);
6456c510 10751 bool old_fre = env->CP0_Config5 & (1 << CP0C5_FRE);
64ea3d67
SM
10752 bool new_fr = arg2 & TARGET_PR_FP_MODE_FR;
10753 bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE;
10754
6456c510
SM
10755 const unsigned int known_bits = TARGET_PR_FP_MODE_FR |
10756 TARGET_PR_FP_MODE_FRE;
10757
10758 /* If nothing to change, return right away, successfully. */
10759 if (old_fr == new_fr && old_fre == new_fre) {
10760 return 0;
10761 }
10762 /* Check the value is valid */
10763 if (arg2 & ~known_bits) {
10764 return -TARGET_EOPNOTSUPP;
10765 }
10766 /* Setting FRE without FR is not supported. */
10767 if (new_fre && !new_fr) {
10768 return -TARGET_EOPNOTSUPP;
10769 }
64ea3d67
SM
10770 if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) {
10771 /* FR1 is not supported */
10772 return -TARGET_EOPNOTSUPP;
10773 }
10774 if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64))
10775 && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
10776 /* cannot set FR=0 */
10777 return -TARGET_EOPNOTSUPP;
10778 }
10779 if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) {
10780 /* Cannot set FRE=1 */
10781 return -TARGET_EOPNOTSUPP;
10782 }
10783
10784 int i;
10785 fpr_t *fpr = env->active_fpu.fpr;
10786 for (i = 0; i < 32 ; i += 2) {
10787 if (!old_fr && new_fr) {
10788 fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX];
10789 } else if (old_fr && !new_fr) {
10790 fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX];
10791 }
10792 }
10793
10794 if (new_fr) {
10795 env->CP0_Status |= (1 << CP0St_FR);
10796 env->hflags |= MIPS_HFLAG_F64;
10797 } else {
10798 env->CP0_Status &= ~(1 << CP0St_FR);
6456c510 10799 env->hflags &= ~MIPS_HFLAG_F64;
64ea3d67
SM
10800 }
10801 if (new_fre) {
10802 env->CP0_Config5 |= (1 << CP0C5_FRE);
10803 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
10804 env->hflags |= MIPS_HFLAG_FRE;
10805 }
10806 } else {
10807 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
6456c510 10808 env->hflags &= ~MIPS_HFLAG_FRE;
64ea3d67
SM
10809 }
10810
10811 return 0;
10812 }
5b702ffd 10813#endif /* MIPS */
85fc7167
RH
10814#ifdef TARGET_AARCH64
10815 case TARGET_PR_SVE_SET_VL:
adf92eab
RH
10816 /*
10817 * We cannot support either PR_SVE_SET_VL_ONEXEC or
10818 * PR_SVE_VL_INHERIT. Note the kernel definition
10819 * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
10820 * even though the current architectural maximum is VQ=16.
10821 */
85fc7167 10822 ret = -TARGET_EINVAL;
2fc0cc0e 10823 if (cpu_isar_feature(aa64_sve, env_archcpu(cpu_env))
adf92eab 10824 && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
85fc7167 10825 CPUARMState *env = cpu_env;
2fc0cc0e 10826 ARMCPU *cpu = env_archcpu(env);
adf92eab
RH
10827 uint32_t vq, old_vq;
10828
10829 old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
10830 vq = MAX(arg2 / 16, 1);
10831 vq = MIN(vq, cpu->sve_max_vq);
85fc7167
RH
10832
10833 if (vq < old_vq) {
10834 aarch64_sve_narrow_vq(env, vq);
10835 }
10836 env->vfp.zcr_el[1] = vq - 1;
a8a79c7a 10837 arm_rebuild_hflags(env);
85fc7167
RH
10838 ret = vq * 16;
10839 }
72eb7ea8 10840 return ret;
85fc7167
RH
10841 case TARGET_PR_SVE_GET_VL:
10842 ret = -TARGET_EINVAL;
cd208a1c 10843 {
2fc0cc0e 10844 ARMCPU *cpu = env_archcpu(cpu_env);
cd208a1c
RH
10845 if (cpu_isar_feature(aa64_sve, cpu)) {
10846 ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
10847 }
85fc7167 10848 }
72eb7ea8 10849 return ret;
bff63fbf
RH
10850 case TARGET_PR_PAC_RESET_KEYS:
10851 {
10852 CPUARMState *env = cpu_env;
2fc0cc0e 10853 ARMCPU *cpu = env_archcpu(env);
bff63fbf
RH
10854
10855 if (arg3 || arg4 || arg5) {
10856 return -TARGET_EINVAL;
10857 }
10858 if (cpu_isar_feature(aa64_pauth, cpu)) {
10859 int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
10860 TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
10861 TARGET_PR_PAC_APGAKEY);
51977e25
RH
10862 int ret = 0;
10863 Error *err = NULL;
10864
bff63fbf
RH
10865 if (arg2 == 0) {
10866 arg2 = all;
10867 } else if (arg2 & ~all) {
10868 return -TARGET_EINVAL;
10869 }
10870 if (arg2 & TARGET_PR_PAC_APIAKEY) {
108b3ba8 10871 ret |= qemu_guest_getrandom(&env->keys.apia,
51977e25 10872 sizeof(ARMPACKey), &err);
bff63fbf
RH
10873 }
10874 if (arg2 & TARGET_PR_PAC_APIBKEY) {
108b3ba8 10875 ret |= qemu_guest_getrandom(&env->keys.apib,
51977e25 10876 sizeof(ARMPACKey), &err);
bff63fbf
RH
10877 }
10878 if (arg2 & TARGET_PR_PAC_APDAKEY) {
108b3ba8 10879 ret |= qemu_guest_getrandom(&env->keys.apda,
51977e25 10880 sizeof(ARMPACKey), &err);
bff63fbf
RH
10881 }
10882 if (arg2 & TARGET_PR_PAC_APDBKEY) {
108b3ba8 10883 ret |= qemu_guest_getrandom(&env->keys.apdb,
51977e25 10884 sizeof(ARMPACKey), &err);
bff63fbf
RH
10885 }
10886 if (arg2 & TARGET_PR_PAC_APGAKEY) {
108b3ba8 10887 ret |= qemu_guest_getrandom(&env->keys.apga,
51977e25
RH
10888 sizeof(ARMPACKey), &err);
10889 }
10890 if (ret != 0) {
10891 /*
10892 * Some unknown failure in the crypto. The best
10893 * we can do is log it and fail the syscall.
10894 * The real syscall cannot fail this way.
10895 */
10896 qemu_log_mask(LOG_UNIMP,
10897 "PR_PAC_RESET_KEYS: Crypto failure: %s",
10898 error_get_pretty(err));
10899 error_free(err);
10900 return -TARGET_EIO;
bff63fbf
RH
10901 }
10902 return 0;
10903 }
10904 }
10905 return -TARGET_EINVAL;
85fc7167 10906#endif /* AARCH64 */
a8b154a6
JC
10907 case PR_GET_SECCOMP:
10908 case PR_SET_SECCOMP:
10909 /* Disable seccomp to prevent the target disabling syscalls we
10910 * need. */
72eb7ea8 10911 return -TARGET_EINVAL;
1e6722f8
PM
10912 default:
10913 /* Most prctl options have no pointer arguments */
72eb7ea8 10914 return get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
1e6722f8 10915 }
39b9aae1 10916 break;
d2fd1af7
FB
10917#ifdef TARGET_NR_arch_prctl
10918 case TARGET_NR_arch_prctl:
72eb7ea8 10919 return do_arch_prctl(cpu_env, arg1, arg2);
d2fd1af7 10920#endif
f2c7ba15
AJ
10921#ifdef TARGET_NR_pread64
10922 case TARGET_NR_pread64:
8bf8e9df 10923 if (regpairs_aligned(cpu_env, num)) {
ae017a5b
AG
10924 arg4 = arg5;
10925 arg5 = arg6;
10926 }
2bd3f899
PM
10927 if (arg2 == 0 && arg3 == 0) {
10928 /* Special-case NULL buffer and zero length, which should succeed */
10929 p = 0;
10930 } else {
10931 p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
10932 if (!p) {
10933 return -TARGET_EFAULT;
10934 }
10935 }
f2c7ba15
AJ
10936 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
10937 unlock_user(p, arg2, ret);
72eb7ea8 10938 return ret;
f2c7ba15 10939 case TARGET_NR_pwrite64:
8bf8e9df 10940 if (regpairs_aligned(cpu_env, num)) {
ae017a5b
AG
10941 arg4 = arg5;
10942 arg5 = arg6;
10943 }
2bd3f899
PM
10944 if (arg2 == 0 && arg3 == 0) {
10945 /* Special-case NULL buffer and zero length, which should succeed */
10946 p = 0;
10947 } else {
10948 p = lock_user(VERIFY_READ, arg2, arg3, 1);
10949 if (!p) {
10950 return -TARGET_EFAULT;
10951 }
10952 }
f2c7ba15
AJ
10953 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
10954 unlock_user(p, arg2, 0);
72eb7ea8 10955 return ret;
67867308 10956#endif
31e31b8a 10957 case TARGET_NR_getcwd:
579a97f7 10958 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
2852aafd 10959 return -TARGET_EFAULT;
53a5960a
PB
10960 ret = get_errno(sys_getcwd1(p, arg2));
10961 unlock_user(p, arg1, ret);
72eb7ea8 10962 return ret;
31e31b8a
FB
10963 case TARGET_NR_capget:
10964 case TARGET_NR_capset:
e0eb210e
PM
10965 {
10966 struct target_user_cap_header *target_header;
10967 struct target_user_cap_data *target_data = NULL;
10968 struct __user_cap_header_struct header;
10969 struct __user_cap_data_struct data[2];
10970 struct __user_cap_data_struct *dataptr = NULL;
10971 int i, target_datalen;
10972 int data_items = 1;
10973
10974 if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
2852aafd 10975 return -TARGET_EFAULT;
e0eb210e
PM
10976 }
10977 header.version = tswap32(target_header->version);
10978 header.pid = tswap32(target_header->pid);
10979
ec864874 10980 if (header.version != _LINUX_CAPABILITY_VERSION) {
e0eb210e
PM
10981 /* Version 2 and up takes pointer to two user_data structs */
10982 data_items = 2;
10983 }
10984
10985 target_datalen = sizeof(*target_data) * data_items;
10986
10987 if (arg2) {
10988 if (num == TARGET_NR_capget) {
10989 target_data = lock_user(VERIFY_WRITE, arg2, target_datalen, 0);
10990 } else {
10991 target_data = lock_user(VERIFY_READ, arg2, target_datalen, 1);
10992 }
10993 if (!target_data) {
10994 unlock_user_struct(target_header, arg1, 0);
2852aafd 10995 return -TARGET_EFAULT;
e0eb210e
PM
10996 }
10997
10998 if (num == TARGET_NR_capset) {
10999 for (i = 0; i < data_items; i++) {
11000 data[i].effective = tswap32(target_data[i].effective);
11001 data[i].permitted = tswap32(target_data[i].permitted);
11002 data[i].inheritable = tswap32(target_data[i].inheritable);
11003 }
11004 }
11005
11006 dataptr = data;
11007 }
11008
11009 if (num == TARGET_NR_capget) {
11010 ret = get_errno(capget(&header, dataptr));
11011 } else {
11012 ret = get_errno(capset(&header, dataptr));
11013 }
11014
11015 /* The kernel always updates version for both capget and capset */
11016 target_header->version = tswap32(header.version);
11017 unlock_user_struct(target_header, arg1, 1);
11018
11019 if (arg2) {
11020 if (num == TARGET_NR_capget) {
11021 for (i = 0; i < data_items; i++) {
11022 target_data[i].effective = tswap32(data[i].effective);
11023 target_data[i].permitted = tswap32(data[i].permitted);
11024 target_data[i].inheritable = tswap32(data[i].inheritable);
11025 }
11026 unlock_user(target_data, arg2, target_datalen);
11027 } else {
11028 unlock_user(target_data, arg2, 0);
11029 }
11030 }
72eb7ea8 11031 return ret;
e0eb210e 11032 }
31e31b8a 11033 case TARGET_NR_sigaltstack:
72eb7ea8
RH
11034 return do_sigaltstack(arg1, arg2,
11035 get_sp_from_cpustate((CPUArchState *)cpu_env));
a8fd1aba
PM
11036
11037#ifdef CONFIG_SENDFILE
4f7f8924 11038#ifdef TARGET_NR_sendfile
a8fd1aba
PM
11039 case TARGET_NR_sendfile:
11040 {
11041 off_t *offp = NULL;
11042 off_t off;
11043 if (arg3) {
11044 ret = get_user_sal(off, arg3);
11045 if (is_error(ret)) {
72eb7ea8 11046 return ret;
a8fd1aba
PM
11047 }
11048 offp = &off;
11049 }
11050 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
11051 if (!is_error(ret) && arg3) {
11052 abi_long ret2 = put_user_sal(off, arg3);
11053 if (is_error(ret2)) {
11054 ret = ret2;
11055 }
11056 }
72eb7ea8 11057 return ret;
a8fd1aba 11058 }
4f7f8924 11059#endif
a8fd1aba
PM
11060#ifdef TARGET_NR_sendfile64
11061 case TARGET_NR_sendfile64:
11062 {
11063 off_t *offp = NULL;
11064 off_t off;
11065 if (arg3) {
11066 ret = get_user_s64(off, arg3);
11067 if (is_error(ret)) {
72eb7ea8 11068 return ret;
a8fd1aba
PM
11069 }
11070 offp = &off;
11071 }
11072 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
11073 if (!is_error(ret) && arg3) {
11074 abi_long ret2 = put_user_s64(off, arg3);
11075 if (is_error(ret2)) {
11076 ret = ret2;
11077 }
11078 }
72eb7ea8 11079 return ret;
a8fd1aba
PM
11080 }
11081#endif
ebc05488 11082#endif
048f6b4d 11083#ifdef TARGET_NR_vfork
31e31b8a 11084 case TARGET_NR_vfork:
72eb7ea8
RH
11085 return get_errno(do_fork(cpu_env,
11086 CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
11087 0, 0, 0, 0));
048f6b4d 11088#endif
ebc05488 11089#ifdef TARGET_NR_ugetrlimit
31e31b8a 11090 case TARGET_NR_ugetrlimit:
728584be
FB
11091 {
11092 struct rlimit rlim;
e22b7015
WT
11093 int resource = target_to_host_resource(arg1);
11094 ret = get_errno(getrlimit(resource, &rlim));
728584be 11095 if (!is_error(ret)) {
53a5960a 11096 struct target_rlimit *target_rlim;
579a97f7 11097 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
2852aafd 11098 return -TARGET_EFAULT;
81bbe906
TY
11099 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
11100 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
53a5960a 11101 unlock_user_struct(target_rlim, arg2, 1);
728584be 11102 }
72eb7ea8 11103 return ret;
728584be 11104 }
ebc05488 11105#endif
a315a145 11106#ifdef TARGET_NR_truncate64
31e31b8a 11107 case TARGET_NR_truncate64:
579a97f7 11108 if (!(p = lock_user_string(arg1)))
2852aafd 11109 return -TARGET_EFAULT;
53a5960a
PB
11110 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
11111 unlock_user(p, arg1, 0);
72eb7ea8 11112 return ret;
a315a145
FB
11113#endif
11114#ifdef TARGET_NR_ftruncate64
31e31b8a 11115 case TARGET_NR_ftruncate64:
72eb7ea8 11116 return target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
a315a145
FB
11117#endif
11118#ifdef TARGET_NR_stat64
31e31b8a 11119 case TARGET_NR_stat64:
2852aafd
RH
11120 if (!(p = lock_user_string(arg1))) {
11121 return -TARGET_EFAULT;
11122 }
53a5960a
PB
11123 ret = get_errno(stat(path(p), &st));
11124 unlock_user(p, arg1, 0);
6a24a778
AZ
11125 if (!is_error(ret))
11126 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 11127 return ret;
a315a145
FB
11128#endif
11129#ifdef TARGET_NR_lstat64
31e31b8a 11130 case TARGET_NR_lstat64:
2852aafd
RH
11131 if (!(p = lock_user_string(arg1))) {
11132 return -TARGET_EFAULT;
11133 }
53a5960a
PB
11134 ret = get_errno(lstat(path(p), &st));
11135 unlock_user(p, arg1, 0);
6a24a778
AZ
11136 if (!is_error(ret))
11137 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 11138 return ret;
a315a145
FB
11139#endif
11140#ifdef TARGET_NR_fstat64
31e31b8a 11141 case TARGET_NR_fstat64:
6a24a778
AZ
11142 ret = get_errno(fstat(arg1, &st));
11143 if (!is_error(ret))
11144 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 11145 return ret;
ce4defa0 11146#endif
c0d472b1 11147#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
9d33b76b 11148#ifdef TARGET_NR_fstatat64
6a24a778 11149 case TARGET_NR_fstatat64:
9d33b76b
AJ
11150#endif
11151#ifdef TARGET_NR_newfstatat
11152 case TARGET_NR_newfstatat:
11153#endif
2852aafd
RH
11154 if (!(p = lock_user_string(arg2))) {
11155 return -TARGET_EFAULT;
11156 }
c0d472b1 11157 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
2852aafd 11158 unlock_user(p, arg2, 0);
6a24a778
AZ
11159 if (!is_error(ret))
11160 ret = host_to_target_stat64(cpu_env, arg3, &st);
72eb7ea8 11161 return ret;
a315a145 11162#endif
efa92184
AR
11163#if defined(TARGET_NR_statx)
11164 case TARGET_NR_statx:
11165 {
11166 struct target_statx *target_stx;
11167 int dirfd = arg1;
11168 int flags = arg3;
11169
11170 p = lock_user_string(arg2);
11171 if (p == NULL) {
11172 return -TARGET_EFAULT;
11173 }
11174#if defined(__NR_statx)
11175 {
11176 /*
11177 * It is assumed that struct statx is architecture independent.
11178 */
11179 struct target_statx host_stx;
11180 int mask = arg4;
11181
11182 ret = get_errno(sys_statx(dirfd, p, flags, mask, &host_stx));
11183 if (!is_error(ret)) {
11184 if (host_to_target_statx(&host_stx, arg5) != 0) {
11185 unlock_user(p, arg2, 0);
11186 return -TARGET_EFAULT;
11187 }
11188 }
11189
11190 if (ret != -TARGET_ENOSYS) {
11191 unlock_user(p, arg2, 0);
11192 return ret;
11193 }
11194 }
11195#endif
11196 ret = get_errno(fstatat(dirfd, path(p), &st, flags));
11197 unlock_user(p, arg2, 0);
11198
11199 if (!is_error(ret)) {
11200 if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
11201 return -TARGET_EFAULT;
11202 }
11203 memset(target_stx, 0, sizeof(*target_stx));
11204 __put_user(major(st.st_dev), &target_stx->stx_dev_major);
11205 __put_user(minor(st.st_dev), &target_stx->stx_dev_minor);
11206 __put_user(st.st_ino, &target_stx->stx_ino);
11207 __put_user(st.st_mode, &target_stx->stx_mode);
11208 __put_user(st.st_uid, &target_stx->stx_uid);
11209 __put_user(st.st_gid, &target_stx->stx_gid);
11210 __put_user(st.st_nlink, &target_stx->stx_nlink);
11211 __put_user(major(st.st_rdev), &target_stx->stx_rdev_major);
11212 __put_user(minor(st.st_rdev), &target_stx->stx_rdev_minor);
11213 __put_user(st.st_size, &target_stx->stx_size);
11214 __put_user(st.st_blksize, &target_stx->stx_blksize);
11215 __put_user(st.st_blocks, &target_stx->stx_blocks);
11216 __put_user(st.st_atime, &target_stx->stx_atime.tv_sec);
11217 __put_user(st.st_mtime, &target_stx->stx_mtime.tv_sec);
11218 __put_user(st.st_ctime, &target_stx->stx_ctime.tv_sec);
11219 unlock_user_struct(target_stx, arg5, 1);
11220 }
11221 }
11222 return ret;
11223#endif
704eff6c 11224#ifdef TARGET_NR_lchown
67867308 11225 case TARGET_NR_lchown:
579a97f7 11226 if (!(p = lock_user_string(arg1)))
2852aafd 11227 return -TARGET_EFAULT;
53a5960a
PB
11228 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
11229 unlock_user(p, arg1, 0);
72eb7ea8 11230 return ret;
704eff6c 11231#endif
0c866a7e 11232#ifdef TARGET_NR_getuid
67867308 11233 case TARGET_NR_getuid:
72eb7ea8 11234 return get_errno(high2lowuid(getuid()));
0c866a7e
RV
11235#endif
11236#ifdef TARGET_NR_getgid
67867308 11237 case TARGET_NR_getgid:
72eb7ea8 11238 return get_errno(high2lowgid(getgid()));
0c866a7e
RV
11239#endif
11240#ifdef TARGET_NR_geteuid
67867308 11241 case TARGET_NR_geteuid:
72eb7ea8 11242 return get_errno(high2lowuid(geteuid()));
0c866a7e
RV
11243#endif
11244#ifdef TARGET_NR_getegid
67867308 11245 case TARGET_NR_getegid:
72eb7ea8 11246 return get_errno(high2lowgid(getegid()));
0c866a7e 11247#endif
67867308 11248 case TARGET_NR_setreuid:
72eb7ea8 11249 return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
67867308 11250 case TARGET_NR_setregid:
72eb7ea8 11251 return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
67867308
FB
11252 case TARGET_NR_getgroups:
11253 {
11254 int gidsetsize = arg1;
0c866a7e 11255 target_id *target_grouplist;
67867308
FB
11256 gid_t *grouplist;
11257 int i;
11258
11259 grouplist = alloca(gidsetsize * sizeof(gid_t));
11260 ret = get_errno(getgroups(gidsetsize, grouplist));
cb3bc233 11261 if (gidsetsize == 0)
72eb7ea8 11262 return ret;
67867308 11263 if (!is_error(ret)) {
03903ffc 11264 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
579a97f7 11265 if (!target_grouplist)
2852aafd 11266 return -TARGET_EFAULT;
a2155fcc 11267 for(i = 0;i < ret; i++)
0c866a7e 11268 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
03903ffc 11269 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
67867308
FB
11270 }
11271 }
72eb7ea8 11272 return ret;
67867308
FB
11273 case TARGET_NR_setgroups:
11274 {
11275 int gidsetsize = arg1;
0c866a7e 11276 target_id *target_grouplist;
f2b79ce9 11277 gid_t *grouplist = NULL;
67867308 11278 int i;
f2b79ce9
DA
11279 if (gidsetsize) {
11280 grouplist = alloca(gidsetsize * sizeof(gid_t));
03903ffc 11281 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
f2b79ce9 11282 if (!target_grouplist) {
259841c1 11283 return -TARGET_EFAULT;
f2b79ce9
DA
11284 }
11285 for (i = 0; i < gidsetsize; i++) {
11286 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
11287 }
11288 unlock_user(target_grouplist, arg2, 0);
579a97f7 11289 }
72eb7ea8 11290 return get_errno(setgroups(gidsetsize, grouplist));
67867308 11291 }
67867308 11292 case TARGET_NR_fchown:
72eb7ea8 11293 return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
c0d472b1 11294#if defined(TARGET_NR_fchownat)
ccfa72b7 11295 case TARGET_NR_fchownat:
579a97f7 11296 if (!(p = lock_user_string(arg2)))
2852aafd 11297 return -TARGET_EFAULT;
c0d472b1
PM
11298 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
11299 low2highgid(arg4), arg5));
579a97f7 11300 unlock_user(p, arg2, 0);
72eb7ea8 11301 return ret;
ccfa72b7 11302#endif
67867308
FB
11303#ifdef TARGET_NR_setresuid
11304 case TARGET_NR_setresuid:
72eb7ea8
RH
11305 return get_errno(sys_setresuid(low2highuid(arg1),
11306 low2highuid(arg2),
11307 low2highuid(arg3)));
67867308
FB
11308#endif
11309#ifdef TARGET_NR_getresuid
11310 case TARGET_NR_getresuid:
11311 {
53a5960a 11312 uid_t ruid, euid, suid;
67867308
FB
11313 ret = get_errno(getresuid(&ruid, &euid, &suid));
11314 if (!is_error(ret)) {
76ca310a
PM
11315 if (put_user_id(high2lowuid(ruid), arg1)
11316 || put_user_id(high2lowuid(euid), arg2)
11317 || put_user_id(high2lowuid(suid), arg3))
2852aafd 11318 return -TARGET_EFAULT;
67867308
FB
11319 }
11320 }
72eb7ea8 11321 return ret;
67867308
FB
11322#endif
11323#ifdef TARGET_NR_getresgid
11324 case TARGET_NR_setresgid:
72eb7ea8
RH
11325 return get_errno(sys_setresgid(low2highgid(arg1),
11326 low2highgid(arg2),
11327 low2highgid(arg3)));
67867308
FB
11328#endif
11329#ifdef TARGET_NR_getresgid
11330 case TARGET_NR_getresgid:
11331 {
53a5960a 11332 gid_t rgid, egid, sgid;
67867308
FB
11333 ret = get_errno(getresgid(&rgid, &egid, &sgid));
11334 if (!is_error(ret)) {
76ca310a
PM
11335 if (put_user_id(high2lowgid(rgid), arg1)
11336 || put_user_id(high2lowgid(egid), arg2)
11337 || put_user_id(high2lowgid(sgid), arg3))
2852aafd 11338 return -TARGET_EFAULT;
67867308
FB
11339 }
11340 }
72eb7ea8 11341 return ret;
67867308 11342#endif
704eff6c 11343#ifdef TARGET_NR_chown
67867308 11344 case TARGET_NR_chown:
579a97f7 11345 if (!(p = lock_user_string(arg1)))
2852aafd 11346 return -TARGET_EFAULT;
53a5960a
PB
11347 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
11348 unlock_user(p, arg1, 0);
72eb7ea8 11349 return ret;
704eff6c 11350#endif
67867308 11351 case TARGET_NR_setuid:
72eb7ea8 11352 return get_errno(sys_setuid(low2highuid(arg1)));
67867308 11353 case TARGET_NR_setgid:
72eb7ea8 11354 return get_errno(sys_setgid(low2highgid(arg1)));
67867308 11355 case TARGET_NR_setfsuid:
72eb7ea8 11356 return get_errno(setfsuid(arg1));
67867308 11357 case TARGET_NR_setfsgid:
72eb7ea8 11358 return get_errno(setfsgid(arg1));
67867308 11359
a315a145 11360#ifdef TARGET_NR_lchown32
31e31b8a 11361 case TARGET_NR_lchown32:
579a97f7 11362 if (!(p = lock_user_string(arg1)))
2852aafd 11363 return -TARGET_EFAULT;
53a5960a
PB
11364 ret = get_errno(lchown(p, arg2, arg3));
11365 unlock_user(p, arg1, 0);
72eb7ea8 11366 return ret;
a315a145
FB
11367#endif
11368#ifdef TARGET_NR_getuid32
31e31b8a 11369 case TARGET_NR_getuid32:
72eb7ea8 11370 return get_errno(getuid());
a315a145 11371#endif
64b4d28c
AJ
11372
11373#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
11374 /* Alpha specific */
11375 case TARGET_NR_getxuid:
ba0e276d
RH
11376 {
11377 uid_t euid;
11378 euid=geteuid();
11379 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
11380 }
72eb7ea8 11381 return get_errno(getuid());
64b4d28c
AJ
11382#endif
11383#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
11384 /* Alpha specific */
11385 case TARGET_NR_getxgid:
ba0e276d
RH
11386 {
11387 uid_t egid;
11388 egid=getegid();
11389 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
11390 }
72eb7ea8 11391 return get_errno(getgid());
64b4d28c 11392#endif
ba0e276d
RH
11393#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
11394 /* Alpha specific */
11395 case TARGET_NR_osf_getsysinfo:
11396 ret = -TARGET_EOPNOTSUPP;
11397 switch (arg1) {
11398 case TARGET_GSI_IEEE_FP_CONTROL:
11399 {
21ba8564
RH
11400 uint64_t fpcr = cpu_alpha_load_fpcr(cpu_env);
11401 uint64_t swcr = ((CPUAlphaState *)cpu_env)->swcr;
11402
11403 swcr &= ~SWCR_STATUS_MASK;
11404 swcr |= (fpcr >> 35) & SWCR_STATUS_MASK;
ba0e276d
RH
11405
11406 if (put_user_u64 (swcr, arg2))
2852aafd 11407 return -TARGET_EFAULT;
ba0e276d
RH
11408 ret = 0;
11409 }
11410 break;
11411
11412 /* case GSI_IEEE_STATE_AT_SIGNAL:
11413 -- Not implemented in linux kernel.
11414 case GSI_UACPROC:
11415 -- Retrieves current unaligned access state; not much used.
11416 case GSI_PROC_TYPE:
11417 -- Retrieves implver information; surely not used.
11418 case GSI_GET_HWRPB:
11419 -- Grabs a copy of the HWRPB; surely not used.
11420 */
11421 }
72eb7ea8 11422 return ret;
ba0e276d
RH
11423#endif
11424#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
11425 /* Alpha specific */
11426 case TARGET_NR_osf_setsysinfo:
11427 ret = -TARGET_EOPNOTSUPP;
11428 switch (arg1) {
11429 case TARGET_SSI_IEEE_FP_CONTROL:
ba0e276d 11430 {
21ba8564 11431 uint64_t swcr, fpcr;
ba0e276d 11432
6e06d515 11433 if (get_user_u64 (swcr, arg2)) {
2852aafd 11434 return -TARGET_EFAULT;
6e06d515 11435 }
ba0e276d 11436
21ba8564
RH
11437 /*
11438 * The kernel calls swcr_update_status to update the
11439 * status bits from the fpcr at every point that it
11440 * could be queried. Therefore, we store the status
11441 * bits only in FPCR.
11442 */
11443 ((CPUAlphaState *)cpu_env)->swcr
11444 = swcr & (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK);
11445
11446 fpcr = cpu_alpha_load_fpcr(cpu_env);
11447 fpcr &= ((uint64_t)FPCR_DYN_MASK << 32);
11448 fpcr |= alpha_ieee_swcr_to_fpcr(swcr);
6e06d515 11449 cpu_alpha_store_fpcr(cpu_env, fpcr);
ba0e276d 11450 ret = 0;
6e06d515
RH
11451 }
11452 break;
11453
11454 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
11455 {
21ba8564 11456 uint64_t exc, fpcr, fex;
6e06d515
RH
11457
11458 if (get_user_u64(exc, arg2)) {
2852aafd 11459 return -TARGET_EFAULT;
6e06d515 11460 }
21ba8564
RH
11461 exc &= SWCR_STATUS_MASK;
11462 fpcr = cpu_alpha_load_fpcr(cpu_env);
ba0e276d 11463
21ba8564
RH
11464 /* Old exceptions are not signaled. */
11465 fex = alpha_ieee_fpcr_to_swcr(fpcr);
11466 fex = exc & ~fex;
11467 fex >>= SWCR_STATUS_TO_EXCSUM_SHIFT;
11468 fex &= ((CPUArchState *)cpu_env)->swcr;
6e06d515 11469
21ba8564
RH
11470 /* Update the hardware fpcr. */
11471 fpcr |= alpha_ieee_swcr_to_fpcr(exc);
6e06d515 11472 cpu_alpha_store_fpcr(cpu_env, fpcr);
6e06d515 11473
21ba8564
RH
11474 if (fex) {
11475 int si_code = TARGET_FPE_FLTUNK;
6e06d515 11476 target_siginfo_t info;
21ba8564
RH
11477
11478 if (fex & SWCR_TRAP_ENABLE_DNO) {
11479 si_code = TARGET_FPE_FLTUND;
11480 }
11481 if (fex & SWCR_TRAP_ENABLE_INE) {
11482 si_code = TARGET_FPE_FLTRES;
11483 }
11484 if (fex & SWCR_TRAP_ENABLE_UNF) {
11485 si_code = TARGET_FPE_FLTUND;
11486 }
11487 if (fex & SWCR_TRAP_ENABLE_OVF) {
11488 si_code = TARGET_FPE_FLTOVF;
11489 }
11490 if (fex & SWCR_TRAP_ENABLE_DZE) {
11491 si_code = TARGET_FPE_FLTDIV;
11492 }
11493 if (fex & SWCR_TRAP_ENABLE_INV) {
11494 si_code = TARGET_FPE_FLTINV;
11495 }
11496
6e06d515
RH
11497 info.si_signo = SIGFPE;
11498 info.si_errno = 0;
11499 info.si_code = si_code;
11500 info._sifields._sigfault._addr
11501 = ((CPUArchState *)cpu_env)->pc;
9d2803f7
PM
11502 queue_signal((CPUArchState *)cpu_env, info.si_signo,
11503 QEMU_SI_FAULT, &info);
ba0e276d 11504 }
21ba8564 11505 ret = 0;
ba0e276d
RH
11506 }
11507 break;
11508
11509 /* case SSI_NVPAIRS:
11510 -- Used with SSIN_UACPROC to enable unaligned accesses.
11511 case SSI_IEEE_STATE_AT_SIGNAL:
11512 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
11513 -- Not implemented in linux kernel
11514 */
11515 }
72eb7ea8 11516 return ret;
ba0e276d
RH
11517#endif
11518#ifdef TARGET_NR_osf_sigprocmask
11519 /* Alpha specific. */
11520 case TARGET_NR_osf_sigprocmask:
11521 {
11522 abi_ulong mask;
bc088ba1 11523 int how;
ba0e276d
RH
11524 sigset_t set, oldset;
11525
11526 switch(arg1) {
11527 case TARGET_SIG_BLOCK:
11528 how = SIG_BLOCK;
11529 break;
11530 case TARGET_SIG_UNBLOCK:
11531 how = SIG_UNBLOCK;
11532 break;
11533 case TARGET_SIG_SETMASK:
11534 how = SIG_SETMASK;
11535 break;
11536 default:
259841c1 11537 return -TARGET_EINVAL;
ba0e276d
RH
11538 }
11539 mask = arg2;
11540 target_to_host_old_sigset(&set, &mask);
3d3efba0
PM
11541 ret = do_sigprocmask(how, &set, &oldset);
11542 if (!ret) {
11543 host_to_target_old_sigset(&mask, &oldset);
11544 ret = mask;
11545 }
ba0e276d 11546 }
72eb7ea8 11547 return ret;
ba0e276d 11548#endif
64b4d28c 11549
a315a145 11550#ifdef TARGET_NR_getgid32
31e31b8a 11551 case TARGET_NR_getgid32:
72eb7ea8 11552 return get_errno(getgid());
a315a145
FB
11553#endif
11554#ifdef TARGET_NR_geteuid32
31e31b8a 11555 case TARGET_NR_geteuid32:
72eb7ea8 11556 return get_errno(geteuid());
a315a145
FB
11557#endif
11558#ifdef TARGET_NR_getegid32
31e31b8a 11559 case TARGET_NR_getegid32:
72eb7ea8 11560 return get_errno(getegid());
a315a145
FB
11561#endif
11562#ifdef TARGET_NR_setreuid32
31e31b8a 11563 case TARGET_NR_setreuid32:
72eb7ea8 11564 return get_errno(setreuid(arg1, arg2));
a315a145
FB
11565#endif
11566#ifdef TARGET_NR_setregid32
31e31b8a 11567 case TARGET_NR_setregid32:
72eb7ea8 11568 return get_errno(setregid(arg1, arg2));
a315a145
FB
11569#endif
11570#ifdef TARGET_NR_getgroups32
31e31b8a 11571 case TARGET_NR_getgroups32:
99c475ab
FB
11572 {
11573 int gidsetsize = arg1;
53a5960a 11574 uint32_t *target_grouplist;
99c475ab
FB
11575 gid_t *grouplist;
11576 int i;
11577
11578 grouplist = alloca(gidsetsize * sizeof(gid_t));
11579 ret = get_errno(getgroups(gidsetsize, grouplist));
cb3bc233 11580 if (gidsetsize == 0)
72eb7ea8 11581 return ret;
99c475ab 11582 if (!is_error(ret)) {
579a97f7
FB
11583 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
11584 if (!target_grouplist) {
259841c1 11585 return -TARGET_EFAULT;
579a97f7 11586 }
a2155fcc 11587 for(i = 0;i < ret; i++)
53a5960a
PB
11588 target_grouplist[i] = tswap32(grouplist[i]);
11589 unlock_user(target_grouplist, arg2, gidsetsize * 4);
99c475ab
FB
11590 }
11591 }
72eb7ea8 11592 return ret;
a315a145
FB
11593#endif
11594#ifdef TARGET_NR_setgroups32
31e31b8a 11595 case TARGET_NR_setgroups32:
99c475ab
FB
11596 {
11597 int gidsetsize = arg1;
53a5960a 11598 uint32_t *target_grouplist;
99c475ab
FB
11599 gid_t *grouplist;
11600 int i;
3b46e624 11601
99c475ab 11602 grouplist = alloca(gidsetsize * sizeof(gid_t));
579a97f7
FB
11603 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
11604 if (!target_grouplist) {
259841c1 11605 return -TARGET_EFAULT;
579a97f7 11606 }
99c475ab 11607 for(i = 0;i < gidsetsize; i++)
53a5960a
PB
11608 grouplist[i] = tswap32(target_grouplist[i]);
11609 unlock_user(target_grouplist, arg2, 0);
72eb7ea8 11610 return get_errno(setgroups(gidsetsize, grouplist));
99c475ab 11611 }
a315a145
FB
11612#endif
11613#ifdef TARGET_NR_fchown32
31e31b8a 11614 case TARGET_NR_fchown32:
72eb7ea8 11615 return get_errno(fchown(arg1, arg2, arg3));
a315a145
FB
11616#endif
11617#ifdef TARGET_NR_setresuid32
31e31b8a 11618 case TARGET_NR_setresuid32:
72eb7ea8 11619 return get_errno(sys_setresuid(arg1, arg2, arg3));
a315a145
FB
11620#endif
11621#ifdef TARGET_NR_getresuid32
31e31b8a 11622 case TARGET_NR_getresuid32:
b03c60f3 11623 {
53a5960a 11624 uid_t ruid, euid, suid;
b03c60f3
FB
11625 ret = get_errno(getresuid(&ruid, &euid, &suid));
11626 if (!is_error(ret)) {
2f619698
FB
11627 if (put_user_u32(ruid, arg1)
11628 || put_user_u32(euid, arg2)
11629 || put_user_u32(suid, arg3))
2852aafd 11630 return -TARGET_EFAULT;
b03c60f3
FB
11631 }
11632 }
72eb7ea8 11633 return ret;
a315a145
FB
11634#endif
11635#ifdef TARGET_NR_setresgid32
31e31b8a 11636 case TARGET_NR_setresgid32:
72eb7ea8 11637 return get_errno(sys_setresgid(arg1, arg2, arg3));
a315a145
FB
11638#endif
11639#ifdef TARGET_NR_getresgid32
31e31b8a 11640 case TARGET_NR_getresgid32:
b03c60f3 11641 {
53a5960a 11642 gid_t rgid, egid, sgid;
b03c60f3
FB
11643 ret = get_errno(getresgid(&rgid, &egid, &sgid));
11644 if (!is_error(ret)) {
2f619698
FB
11645 if (put_user_u32(rgid, arg1)
11646 || put_user_u32(egid, arg2)
11647 || put_user_u32(sgid, arg3))
2852aafd 11648 return -TARGET_EFAULT;
b03c60f3
FB
11649 }
11650 }
72eb7ea8 11651 return ret;
a315a145
FB
11652#endif
11653#ifdef TARGET_NR_chown32
31e31b8a 11654 case TARGET_NR_chown32:
579a97f7 11655 if (!(p = lock_user_string(arg1)))
2852aafd 11656 return -TARGET_EFAULT;
53a5960a
PB
11657 ret = get_errno(chown(p, arg2, arg3));
11658 unlock_user(p, arg1, 0);
72eb7ea8 11659 return ret;
a315a145
FB
11660#endif
11661#ifdef TARGET_NR_setuid32
31e31b8a 11662 case TARGET_NR_setuid32:
72eb7ea8 11663 return get_errno(sys_setuid(arg1));
a315a145
FB
11664#endif
11665#ifdef TARGET_NR_setgid32
31e31b8a 11666 case TARGET_NR_setgid32:
72eb7ea8 11667 return get_errno(sys_setgid(arg1));
a315a145
FB
11668#endif
11669#ifdef TARGET_NR_setfsuid32
31e31b8a 11670 case TARGET_NR_setfsuid32:
72eb7ea8 11671 return get_errno(setfsuid(arg1));
a315a145
FB
11672#endif
11673#ifdef TARGET_NR_setfsgid32
31e31b8a 11674 case TARGET_NR_setfsgid32:
72eb7ea8 11675 return get_errno(setfsgid(arg1));
a315a145 11676#endif
ffa65c3b 11677#ifdef TARGET_NR_mincore
31e31b8a 11678 case TARGET_NR_mincore:
04bb9ace 11679 {
259841c1 11680 void *a = lock_user(VERIFY_READ, arg1, arg2, 0);
98a3331a 11681 if (!a) {
259841c1 11682 return -TARGET_ENOMEM;
98a3331a 11683 }
98a3331a
FSM
11684 p = lock_user_string(arg3);
11685 if (!p) {
259841c1
RH
11686 ret = -TARGET_EFAULT;
11687 } else {
11688 ret = get_errno(mincore(a, arg2, p));
11689 unlock_user(p, arg3, ret);
98a3331a 11690 }
04bb9ace
AJ
11691 unlock_user(a, arg1, 0);
11692 }
72eb7ea8 11693 return ret;
ffa65c3b 11694#endif
408321b6
AJ
11695#ifdef TARGET_NR_arm_fadvise64_64
11696 case TARGET_NR_arm_fadvise64_64:
e0156a9d
PM
11697 /* arm_fadvise64_64 looks like fadvise64_64 but
11698 * with different argument order: fd, advice, offset, len
11699 * rather than the usual fd, offset, len, advice.
11700 * Note that offset and len are both 64-bit so appear as
11701 * pairs of 32-bit registers.
11702 */
11703 ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
11704 target_offset64(arg5, arg6), arg2);
72eb7ea8 11705 return -host_to_target_errno(ret);
408321b6 11706#endif
badd3cd8
PM
11707
11708#if TARGET_ABI_BITS == 32
11709
11710#ifdef TARGET_NR_fadvise64_64
11711 case TARGET_NR_fadvise64_64:
64a563dd 11712#if defined(TARGET_PPC) || defined(TARGET_XTENSA)
43046b5a
LV
11713 /* 6 args: fd, advice, offset (high, low), len (high, low) */
11714 ret = arg2;
11715 arg2 = arg3;
11716 arg3 = arg4;
11717 arg4 = arg5;
11718 arg5 = arg6;
11719 arg6 = ret;
11720#else
badd3cd8 11721 /* 6 args: fd, offset (high, low), len (high, low), advice */
8bf8e9df 11722 if (regpairs_aligned(cpu_env, num)) {
badd3cd8
PM
11723 /* offset is in (3,4), len in (5,6) and advice in 7 */
11724 arg2 = arg3;
11725 arg3 = arg4;
11726 arg4 = arg5;
11727 arg5 = arg6;
11728 arg6 = arg7;
11729 }
43046b5a 11730#endif
72eb7ea8
RH
11731 ret = posix_fadvise(arg1, target_offset64(arg2, arg3),
11732 target_offset64(arg4, arg5), arg6);
11733 return -host_to_target_errno(ret);
badd3cd8
PM
11734#endif
11735
11736#ifdef TARGET_NR_fadvise64
11737 case TARGET_NR_fadvise64:
11738 /* 5 args: fd, offset (high, low), len, advice */
8bf8e9df 11739 if (regpairs_aligned(cpu_env, num)) {
badd3cd8
PM
11740 /* offset is in (3,4), len in 5 and advice in 6 */
11741 arg2 = arg3;
11742 arg3 = arg4;
11743 arg4 = arg5;
11744 arg5 = arg6;
11745 }
72eb7ea8
RH
11746 ret = posix_fadvise(arg1, target_offset64(arg2, arg3), arg4, arg5);
11747 return -host_to_target_errno(ret);
408321b6 11748#endif
badd3cd8
PM
11749
11750#else /* not a 32-bit ABI */
e0156a9d 11751#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64)
408321b6
AJ
11752#ifdef TARGET_NR_fadvise64_64
11753 case TARGET_NR_fadvise64_64:
11754#endif
e72d2cc7
UH
11755#ifdef TARGET_NR_fadvise64
11756 case TARGET_NR_fadvise64:
11757#endif
11758#ifdef TARGET_S390X
11759 switch (arg4) {
11760 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
11761 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
11762 case 6: arg4 = POSIX_FADV_DONTNEED; break;
11763 case 7: arg4 = POSIX_FADV_NOREUSE; break;
11764 default: break;
11765 }
11766#endif
72eb7ea8 11767 return -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
408321b6 11768#endif
badd3cd8
PM
11769#endif /* end of 64-bit ABI fadvise handling */
11770
ffa65c3b 11771#ifdef TARGET_NR_madvise
31e31b8a 11772 case TARGET_NR_madvise:
24836689 11773 /* A straight passthrough may not be safe because qemu sometimes
d2d6b857 11774 turns private file-backed mappings into anonymous mappings.
24836689
PB
11775 This will break MADV_DONTNEED.
11776 This is a hint, so ignoring and returning success is ok. */
72eb7ea8 11777 return 0;
ffa65c3b 11778#endif
bbf5f2a1 11779#ifdef TARGET_NR_fcntl64
31e31b8a 11780 case TARGET_NR_fcntl64:
77e4672d 11781 {
bbf5f2a1
AB
11782 int cmd;
11783 struct flock64 fl;
213d3e9e
PM
11784 from_flock64_fn *copyfrom = copy_from_user_flock64;
11785 to_flock64_fn *copyto = copy_to_user_flock64;
11786
ce4defa0 11787#ifdef TARGET_ARM
7f254c5c
LV
11788 if (!((CPUARMState *)cpu_env)->eabi) {
11789 copyfrom = copy_from_user_oabi_flock64;
11790 copyto = copy_to_user_oabi_flock64;
213d3e9e 11791 }
ce4defa0 11792#endif
77e4672d 11793
bbf5f2a1 11794 cmd = target_to_host_fcntl_cmd(arg2);
31b63193 11795 if (cmd == -TARGET_EINVAL) {
72eb7ea8 11796 return cmd;
31b63193 11797 }
b1e341eb 11798
60cd49d5 11799 switch(arg2) {
b1e341eb 11800 case TARGET_F_GETLK64:
213d3e9e
PM
11801 ret = copyfrom(&fl, arg3);
11802 if (ret) {
11803 break;
5813427b 11804 }
af8ab2bf 11805 ret = get_errno(safe_fcntl(arg1, cmd, &fl));
213d3e9e
PM
11806 if (ret == 0) {
11807 ret = copyto(arg3, &fl);
11808 }
77e4672d
FB
11809 break;
11810
b1e341eb
TS
11811 case TARGET_F_SETLK64:
11812 case TARGET_F_SETLKW64:
213d3e9e
PM
11813 ret = copyfrom(&fl, arg3);
11814 if (ret) {
11815 break;
ce4defa0 11816 }
435da5e7 11817 ret = get_errno(safe_fcntl(arg1, cmd, &fl));
77e4672d 11818 break;
60cd49d5 11819 default:
5f106811 11820 ret = do_fcntl(arg1, arg2, arg3);
60cd49d5
FB
11821 break;
11822 }
72eb7ea8 11823 return ret;
77e4672d 11824 }
60cd49d5 11825#endif
7d600c80
TS
11826#ifdef TARGET_NR_cacheflush
11827 case TARGET_NR_cacheflush:
11828 /* self-modifying code is handled automatically, so nothing needed */
72eb7ea8 11829 return 0;
7d600c80 11830#endif
c573ff67
FB
11831#ifdef TARGET_NR_getpagesize
11832 case TARGET_NR_getpagesize:
72eb7ea8 11833 return TARGET_PAGE_SIZE;
ebc05488 11834#endif
31e31b8a 11835 case TARGET_NR_gettid:
71ba74f6 11836 return get_errno(sys_gettid());
e5febef5 11837#ifdef TARGET_NR_readahead
31e31b8a 11838 case TARGET_NR_readahead:
2054ac9b 11839#if TARGET_ABI_BITS == 32
8bf8e9df 11840 if (regpairs_aligned(cpu_env, num)) {
2054ac9b
AJ
11841 arg2 = arg3;
11842 arg3 = arg4;
11843 arg4 = arg5;
11844 }
77c6850f 11845 ret = get_errno(readahead(arg1, target_offset64(arg2, arg3) , arg4));
2054ac9b
AJ
11846#else
11847 ret = get_errno(readahead(arg1, arg2, arg3));
11848#endif
72eb7ea8 11849 return ret;
e5febef5 11850#endif
a790ae38 11851#ifdef CONFIG_ATTR
ebc05488 11852#ifdef TARGET_NR_setxattr
31e31b8a
FB
11853 case TARGET_NR_listxattr:
11854 case TARGET_NR_llistxattr:
fb5590f7
PM
11855 {
11856 void *p, *b = 0;
11857 if (arg2) {
11858 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
11859 if (!b) {
72eb7ea8 11860 return -TARGET_EFAULT;
fb5590f7
PM
11861 }
11862 }
11863 p = lock_user_string(arg1);
11864 if (p) {
11865 if (num == TARGET_NR_listxattr) {
11866 ret = get_errno(listxattr(p, b, arg3));
11867 } else {
11868 ret = get_errno(llistxattr(p, b, arg3));
11869 }
11870 } else {
11871 ret = -TARGET_EFAULT;
11872 }
11873 unlock_user(p, arg1, 0);
11874 unlock_user(b, arg2, arg3);
72eb7ea8 11875 return ret;
fb5590f7 11876 }
31e31b8a 11877 case TARGET_NR_flistxattr:
fb5590f7
PM
11878 {
11879 void *b = 0;
11880 if (arg2) {
11881 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
11882 if (!b) {
72eb7ea8 11883 return -TARGET_EFAULT;
fb5590f7
PM
11884 }
11885 }
11886 ret = get_errno(flistxattr(arg1, b, arg3));
11887 unlock_user(b, arg2, arg3);
72eb7ea8 11888 return ret;
fb5590f7 11889 }
a790ae38 11890 case TARGET_NR_setxattr:
30297b55 11891 case TARGET_NR_lsetxattr:
a790ae38 11892 {
e3c33ec6
PM
11893 void *p, *n, *v = 0;
11894 if (arg3) {
11895 v = lock_user(VERIFY_READ, arg3, arg4, 1);
11896 if (!v) {
72eb7ea8 11897 return -TARGET_EFAULT;
e3c33ec6
PM
11898 }
11899 }
a790ae38
ACH
11900 p = lock_user_string(arg1);
11901 n = lock_user_string(arg2);
e3c33ec6 11902 if (p && n) {
30297b55
PM
11903 if (num == TARGET_NR_setxattr) {
11904 ret = get_errno(setxattr(p, n, v, arg4, arg5));
11905 } else {
11906 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
11907 }
a790ae38
ACH
11908 } else {
11909 ret = -TARGET_EFAULT;
11910 }
11911 unlock_user(p, arg1, 0);
11912 unlock_user(n, arg2, 0);
11913 unlock_user(v, arg3, 0);
11914 }
72eb7ea8 11915 return ret;
30297b55
PM
11916 case TARGET_NR_fsetxattr:
11917 {
11918 void *n, *v = 0;
11919 if (arg3) {
11920 v = lock_user(VERIFY_READ, arg3, arg4, 1);
11921 if (!v) {
72eb7ea8 11922 return -TARGET_EFAULT;
30297b55
PM
11923 }
11924 }
11925 n = lock_user_string(arg2);
11926 if (n) {
11927 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
11928 } else {
11929 ret = -TARGET_EFAULT;
11930 }
11931 unlock_user(n, arg2, 0);
11932 unlock_user(v, arg3, 0);
11933 }
72eb7ea8 11934 return ret;
a790ae38 11935 case TARGET_NR_getxattr:
30297b55 11936 case TARGET_NR_lgetxattr:
a790ae38 11937 {
e3c33ec6
PM
11938 void *p, *n, *v = 0;
11939 if (arg3) {
11940 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
11941 if (!v) {
72eb7ea8 11942 return -TARGET_EFAULT;
e3c33ec6
PM
11943 }
11944 }
a790ae38
ACH
11945 p = lock_user_string(arg1);
11946 n = lock_user_string(arg2);
e3c33ec6 11947 if (p && n) {
30297b55
PM
11948 if (num == TARGET_NR_getxattr) {
11949 ret = get_errno(getxattr(p, n, v, arg4));
11950 } else {
11951 ret = get_errno(lgetxattr(p, n, v, arg4));
11952 }
a790ae38
ACH
11953 } else {
11954 ret = -TARGET_EFAULT;
11955 }
11956 unlock_user(p, arg1, 0);
11957 unlock_user(n, arg2, 0);
11958 unlock_user(v, arg3, arg4);
11959 }
72eb7ea8 11960 return ret;
30297b55
PM
11961 case TARGET_NR_fgetxattr:
11962 {
11963 void *n, *v = 0;
11964 if (arg3) {
11965 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
11966 if (!v) {
72eb7ea8 11967 return -TARGET_EFAULT;
30297b55
PM
11968 }
11969 }
11970 n = lock_user_string(arg2);
11971 if (n) {
11972 ret = get_errno(fgetxattr(arg1, n, v, arg4));
11973 } else {
11974 ret = -TARGET_EFAULT;
11975 }
11976 unlock_user(n, arg2, 0);
11977 unlock_user(v, arg3, arg4);
11978 }
72eb7ea8 11979 return ret;
a790ae38 11980 case TARGET_NR_removexattr:
30297b55 11981 case TARGET_NR_lremovexattr:
a790ae38
ACH
11982 {
11983 void *p, *n;
11984 p = lock_user_string(arg1);
11985 n = lock_user_string(arg2);
11986 if (p && n) {
30297b55
PM
11987 if (num == TARGET_NR_removexattr) {
11988 ret = get_errno(removexattr(p, n));
11989 } else {
11990 ret = get_errno(lremovexattr(p, n));
11991 }
a790ae38
ACH
11992 } else {
11993 ret = -TARGET_EFAULT;
11994 }
11995 unlock_user(p, arg1, 0);
11996 unlock_user(n, arg2, 0);
11997 }
72eb7ea8 11998 return ret;
30297b55
PM
11999 case TARGET_NR_fremovexattr:
12000 {
12001 void *n;
12002 n = lock_user_string(arg2);
12003 if (n) {
12004 ret = get_errno(fremovexattr(arg1, n));
12005 } else {
12006 ret = -TARGET_EFAULT;
12007 }
12008 unlock_user(n, arg2, 0);
12009 }
72eb7ea8 12010 return ret;
ebc05488 12011#endif
a790ae38 12012#endif /* CONFIG_ATTR */
ebc05488 12013#ifdef TARGET_NR_set_thread_area
5cd4393b 12014 case TARGET_NR_set_thread_area:
8d18e893 12015#if defined(TARGET_MIPS)
d279279e 12016 ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
72eb7ea8 12017 return 0;
ef96779b
EI
12018#elif defined(TARGET_CRIS)
12019 if (arg1 & 0xff)
12020 ret = -TARGET_EINVAL;
12021 else {
12022 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
12023 ret = 0;
12024 }
72eb7ea8 12025 return ret;
8d18e893 12026#elif defined(TARGET_I386) && defined(TARGET_ABI32)
72eb7ea8 12027 return do_set_thread_area(cpu_env, arg1);
1ccd9374
PM
12028#elif defined(TARGET_M68K)
12029 {
0429a971 12030 TaskState *ts = cpu->opaque;
1ccd9374 12031 ts->tp_value = arg1;
72eb7ea8 12032 return 0;
1ccd9374 12033 }
6f5b89a0 12034#else
10f45d98 12035 return -TARGET_ENOSYS;
6f5b89a0
TS
12036#endif
12037#endif
12038#ifdef TARGET_NR_get_thread_area
5cd4393b 12039 case TARGET_NR_get_thread_area:
8d18e893 12040#if defined(TARGET_I386) && defined(TARGET_ABI32)
72eb7ea8 12041 return do_get_thread_area(cpu_env, arg1);
1ccd9374
PM
12042#elif defined(TARGET_M68K)
12043 {
0429a971 12044 TaskState *ts = cpu->opaque;
72eb7ea8 12045 return ts->tp_value;
1ccd9374 12046 }
8d18e893 12047#else
10f45d98 12048 return -TARGET_ENOSYS;
48dc41eb 12049#endif
8d18e893 12050#endif
48dc41eb
FB
12051#ifdef TARGET_NR_getdomainname
12052 case TARGET_NR_getdomainname:
10f45d98 12053 return -TARGET_ENOSYS;
ebc05488 12054#endif
6f5b89a0 12055
12e3340c
MF
12056#ifdef TARGET_NR_clock_settime
12057 case TARGET_NR_clock_settime:
12058 {
12059 struct timespec ts;
12060
12061 ret = target_to_host_timespec(&ts, arg2);
12062 if (!is_error(ret)) {
12063 ret = get_errno(clock_settime(arg1, &ts));
12064 }
72eb7ea8 12065 return ret;
12e3340c
MF
12066 }
12067#endif
c6c8d102
AF
12068#ifdef TARGET_NR_clock_settime64
12069 case TARGET_NR_clock_settime64:
12070 {
12071 struct timespec ts;
12072
12073 ret = target_to_host_timespec64(&ts, arg2);
12074 if (!is_error(ret)) {
12075 ret = get_errno(clock_settime(arg1, &ts));
12076 }
12077 return ret;
12078 }
12079#endif
b5906f95
TS
12080#ifdef TARGET_NR_clock_gettime
12081 case TARGET_NR_clock_gettime:
12082 {
12083 struct timespec ts;
12084 ret = get_errno(clock_gettime(arg1, &ts));
12085 if (!is_error(ret)) {
b9f9908e 12086 ret = host_to_target_timespec(arg2, &ts);
b5906f95 12087 }
72eb7ea8 12088 return ret;
b5906f95
TS
12089 }
12090#endif
c6c8d102
AF
12091#ifdef TARGET_NR_clock_gettime64
12092 case TARGET_NR_clock_gettime64:
12093 {
12094 struct timespec ts;
12095 ret = get_errno(clock_gettime(arg1, &ts));
12096 if (!is_error(ret)) {
12097 ret = host_to_target_timespec64(arg2, &ts);
12098 }
12099 return ret;
12100 }
12101#endif
b5906f95
TS
12102#ifdef TARGET_NR_clock_getres
12103 case TARGET_NR_clock_getres:
12104 {
12105 struct timespec ts;
12106 ret = get_errno(clock_getres(arg1, &ts));
12107 if (!is_error(ret)) {
12108 host_to_target_timespec(arg2, &ts);
12109 }
72eb7ea8 12110 return ret;
b5906f95
TS
12111 }
12112#endif
828cb3a1
FB
12113#ifdef TARGET_NR_clock_getres_time64
12114 case TARGET_NR_clock_getres_time64:
12115 {
12116 struct timespec ts;
12117 ret = get_errno(clock_getres(arg1, &ts));
12118 if (!is_error(ret)) {
12119 host_to_target_timespec64(arg2, &ts);
12120 }
12121 return ret;
12122 }
12123#endif
63d7651b
PB
12124#ifdef TARGET_NR_clock_nanosleep
12125 case TARGET_NR_clock_nanosleep:
12126 {
12127 struct timespec ts;
b09d6406
FB
12128 if (target_to_host_timespec(&ts, arg3)) {
12129 return -TARGET_EFAULT;
12130 }
9e518226
PM
12131 ret = get_errno(safe_clock_nanosleep(arg1, arg2,
12132 &ts, arg4 ? &ts : NULL));
8ec68a0a
LV
12133 /*
12134 * if the call is interrupted by a signal handler, it fails
12135 * with error -TARGET_EINTR and if arg4 is not NULL and arg2 is not
12136 * TIMER_ABSTIME, it returns the remaining unslept time in arg4.
12137 */
b09d6406
FB
12138 if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME &&
12139 host_to_target_timespec(arg4, &ts)) {
12140 return -TARGET_EFAULT;
8ec68a0a 12141 }
8fbe8fdf 12142
72eb7ea8 12143 return ret;
63d7651b
PB
12144 }
12145#endif
6ac03b2c
FB
12146#ifdef TARGET_NR_clock_nanosleep_time64
12147 case TARGET_NR_clock_nanosleep_time64:
12148 {
12149 struct timespec ts;
12150
12151 if (target_to_host_timespec64(&ts, arg3)) {
12152 return -TARGET_EFAULT;
12153 }
12154
12155 ret = get_errno(safe_clock_nanosleep(arg1, arg2,
12156 &ts, arg4 ? &ts : NULL));
12157
12158 if (ret == -TARGET_EINTR && arg4 && arg2 != TIMER_ABSTIME &&
12159 host_to_target_timespec64(arg4, &ts)) {
12160 return -TARGET_EFAULT;
12161 }
12162 return ret;
12163 }
12164#endif
b5906f95 12165
6f5b89a0
TS
12166#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
12167 case TARGET_NR_set_tid_address:
72eb7ea8 12168 return get_errno(set_tid_address((int *)g2h(arg1)));
6f5b89a0
TS
12169#endif
12170
4cae1d16 12171 case TARGET_NR_tkill:
72eb7ea8 12172 return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
4cae1d16 12173
71455574 12174 case TARGET_NR_tgkill:
72eb7ea8
RH
12175 return get_errno(safe_tgkill((int)arg1, (int)arg2,
12176 target_to_host_signal(arg3)));
71455574 12177
4f2b1fe8
TS
12178#ifdef TARGET_NR_set_robust_list
12179 case TARGET_NR_set_robust_list:
e9a970a8
PM
12180 case TARGET_NR_get_robust_list:
12181 /* The ABI for supporting robust futexes has userspace pass
12182 * the kernel a pointer to a linked list which is updated by
12183 * userspace after the syscall; the list is walked by the kernel
12184 * when the thread exits. Since the linked list in QEMU guest
12185 * memory isn't a valid linked list for the host and we have
12186 * no way to reliably intercept the thread-death event, we can't
12187 * support these. Silently return ENOSYS so that guest userspace
12188 * falls back to a non-robust futex implementation (which should
12189 * be OK except in the corner case of the guest crashing while
12190 * holding a mutex that is shared with another process via
12191 * shared memory).
12192 */
10f45d98 12193 return -TARGET_ENOSYS;
4f2b1fe8
TS
12194#endif
12195
1acae9f2 12196#if defined(TARGET_NR_utimensat)
9007f0ef
TS
12197 case TARGET_NR_utimensat:
12198 {
ebc996f3
RV
12199 struct timespec *tsp, ts[2];
12200 if (!arg3) {
12201 tsp = NULL;
12202 } else {
b3a3af70
FB
12203 if (target_to_host_timespec(ts, arg3)) {
12204 return -TARGET_EFAULT;
12205 }
12206 if (target_to_host_timespec(ts + 1, arg3 +
12207 sizeof(struct target_timespec))) {
12208 return -TARGET_EFAULT;
12209 }
ebc996f3
RV
12210 tsp = ts;
12211 }
9007f0ef 12212 if (!arg2)
ebc996f3 12213 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
9007f0ef 12214 else {
579a97f7 12215 if (!(p = lock_user_string(arg2))) {
259841c1 12216 return -TARGET_EFAULT;
579a97f7 12217 }
ebc996f3 12218 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
579a97f7 12219 unlock_user(p, arg2, 0);
cac46eb0
FB
12220 }
12221 }
12222 return ret;
12223#endif
12224#ifdef TARGET_NR_utimensat_time64
12225 case TARGET_NR_utimensat_time64:
12226 {
12227 struct timespec *tsp, ts[2];
12228 if (!arg3) {
12229 tsp = NULL;
12230 } else {
12231 if (target_to_host_timespec64(ts, arg3)) {
12232 return -TARGET_EFAULT;
12233 }
12234 if (target_to_host_timespec64(ts + 1, arg3 +
12235 sizeof(struct target__kernel_timespec))) {
12236 return -TARGET_EFAULT;
12237 }
12238 tsp = ts;
12239 }
12240 if (!arg2)
12241 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
12242 else {
12243 p = lock_user_string(arg2);
12244 if (!p) {
12245 return -TARGET_EFAULT;
12246 }
12247 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
12248 unlock_user(p, arg2, 0);
9007f0ef
TS
12249 }
12250 }
72eb7ea8 12251 return ret;
9007f0ef 12252#endif
859e8a89 12253#ifdef TARGET_NR_futex
bd0c5661 12254 case TARGET_NR_futex:
72eb7ea8 12255 return do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
859e8a89 12256#endif
14690296
AF
12257#ifdef TARGET_NR_futex_time64
12258 case TARGET_NR_futex_time64:
12259 return do_futex_time64(arg1, arg2, arg3, arg4, arg5, arg6);
12260#endif
dbfe4c36 12261#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
39b59763
AJ
12262 case TARGET_NR_inotify_init:
12263 ret = get_errno(sys_inotify_init());
b929f7e5
PMD
12264 if (ret >= 0) {
12265 fd_trans_register(ret, &target_inotify_trans);
12266 }
72eb7ea8 12267 return ret;
39b59763 12268#endif
a1606b0b 12269#ifdef CONFIG_INOTIFY1
c05c7a73
RV
12270#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
12271 case TARGET_NR_inotify_init1:
fea243e9
LD
12272 ret = get_errno(sys_inotify_init1(target_to_host_bitmask(arg1,
12273 fcntl_flags_tbl)));
b929f7e5
PMD
12274 if (ret >= 0) {
12275 fd_trans_register(ret, &target_inotify_trans);
12276 }
72eb7ea8 12277 return ret;
c05c7a73 12278#endif
a1606b0b 12279#endif
dbfe4c36 12280#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
39b59763
AJ
12281 case TARGET_NR_inotify_add_watch:
12282 p = lock_user_string(arg2);
12283 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
12284 unlock_user(p, arg2, 0);
72eb7ea8 12285 return ret;
39b59763 12286#endif
dbfe4c36 12287#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
39b59763 12288 case TARGET_NR_inotify_rm_watch:
72eb7ea8 12289 return get_errno(sys_inotify_rm_watch(arg1, arg2));
39b59763 12290#endif
9007f0ef 12291
8ec9cf89 12292#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
24e1003a
AJ
12293 case TARGET_NR_mq_open:
12294 {
c7536ab6 12295 struct mq_attr posix_mq_attr;
26400775 12296 struct mq_attr *pposix_mq_attr;
c7536ab6 12297 int host_flags;
24e1003a 12298
c7536ab6 12299 host_flags = target_to_host_bitmask(arg2, fcntl_flags_tbl);
26400775
LD
12300 pposix_mq_attr = NULL;
12301 if (arg4) {
12302 if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) {
2852aafd 12303 return -TARGET_EFAULT;
26400775
LD
12304 }
12305 pposix_mq_attr = &posix_mq_attr;
c7536ab6 12306 }
24e1003a 12307 p = lock_user_string(arg1 - 1);
c7536ab6 12308 if (!p) {
2852aafd 12309 return -TARGET_EFAULT;
b6ce1f6b 12310 }
26400775 12311 ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr));
24e1003a
AJ
12312 unlock_user (p, arg1, 0);
12313 }
72eb7ea8 12314 return ret;
24e1003a
AJ
12315
12316 case TARGET_NR_mq_unlink:
12317 p = lock_user_string(arg1 - 1);
3211215e 12318 if (!p) {
72eb7ea8 12319 return -TARGET_EFAULT;
3211215e 12320 }
24e1003a
AJ
12321 ret = get_errno(mq_unlink(p));
12322 unlock_user (p, arg1, 0);
72eb7ea8 12323 return ret;
24e1003a 12324
859e8a89 12325#ifdef TARGET_NR_mq_timedsend
24e1003a
AJ
12326 case TARGET_NR_mq_timedsend:
12327 {
12328 struct timespec ts;
12329
12330 p = lock_user (VERIFY_READ, arg2, arg3, 1);
12331 if (arg5 != 0) {
dcbcf5cf
FB
12332 if (target_to_host_timespec(&ts, arg5)) {
12333 return -TARGET_EFAULT;
12334 }
d40ecd66 12335 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
dcbcf5cf
FB
12336 if (!is_error(ret) && host_to_target_timespec(arg5, &ts)) {
12337 return -TARGET_EFAULT;
12338 }
d40ecd66
PM
12339 } else {
12340 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
24e1003a 12341 }
24e1003a
AJ
12342 unlock_user (p, arg2, arg3);
12343 }
72eb7ea8 12344 return ret;
859e8a89 12345#endif
d107e375
FB
12346#ifdef TARGET_NR_mq_timedsend_time64
12347 case TARGET_NR_mq_timedsend_time64:
12348 {
12349 struct timespec ts;
12350
12351 p = lock_user(VERIFY_READ, arg2, arg3, 1);
12352 if (arg5 != 0) {
12353 if (target_to_host_timespec64(&ts, arg5)) {
12354 return -TARGET_EFAULT;
12355 }
12356 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
12357 if (!is_error(ret) && host_to_target_timespec64(arg5, &ts)) {
12358 return -TARGET_EFAULT;
12359 }
12360 } else {
12361 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
12362 }
12363 unlock_user(p, arg2, arg3);
12364 }
12365 return ret;
12366#endif
24e1003a 12367
859e8a89 12368#ifdef TARGET_NR_mq_timedreceive
24e1003a
AJ
12369 case TARGET_NR_mq_timedreceive:
12370 {
12371 struct timespec ts;
12372 unsigned int prio;
12373
12374 p = lock_user (VERIFY_READ, arg2, arg3, 1);
12375 if (arg5 != 0) {
dcbcf5cf
FB
12376 if (target_to_host_timespec(&ts, arg5)) {
12377 return -TARGET_EFAULT;
12378 }
d40ecd66
PM
12379 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12380 &prio, &ts));
dcbcf5cf
FB
12381 if (!is_error(ret) && host_to_target_timespec(arg5, &ts)) {
12382 return -TARGET_EFAULT;
12383 }
d40ecd66
PM
12384 } else {
12385 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12386 &prio, NULL));
24e1003a 12387 }
24e1003a
AJ
12388 unlock_user (p, arg2, arg3);
12389 if (arg4 != 0)
12390 put_user_u32(prio, arg4);
12391 }
72eb7ea8 12392 return ret;
859e8a89 12393#endif
d107e375
FB
12394#ifdef TARGET_NR_mq_timedreceive_time64
12395 case TARGET_NR_mq_timedreceive_time64:
12396 {
12397 struct timespec ts;
12398 unsigned int prio;
12399
12400 p = lock_user(VERIFY_READ, arg2, arg3, 1);
12401 if (arg5 != 0) {
12402 if (target_to_host_timespec64(&ts, arg5)) {
12403 return -TARGET_EFAULT;
12404 }
12405 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12406 &prio, &ts));
12407 if (!is_error(ret) && host_to_target_timespec64(arg5, &ts)) {
12408 return -TARGET_EFAULT;
12409 }
12410 } else {
12411 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12412 &prio, NULL));
12413 }
12414 unlock_user(p, arg2, arg3);
12415 if (arg4 != 0) {
12416 put_user_u32(prio, arg4);
12417 }
12418 }
12419 return ret;
12420#endif
24e1003a
AJ
12421
12422 /* Not implemented for now... */
12423/* case TARGET_NR_mq_notify: */
12424/* break; */
12425
12426 case TARGET_NR_mq_getsetattr:
12427 {
12428 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
12429 ret = 0;
24e1003a
AJ
12430 if (arg2 != 0) {
12431 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
a23ea409
MF
12432 ret = get_errno(mq_setattr(arg1, &posix_mq_attr_in,
12433 &posix_mq_attr_out));
12434 } else if (arg3 != 0) {
12435 ret = get_errno(mq_getattr(arg1, &posix_mq_attr_out));
12436 }
12437 if (ret == 0 && arg3 != 0) {
12438 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
24e1003a 12439 }
24e1003a 12440 }
72eb7ea8 12441 return ret;
24e1003a
AJ
12442#endif
12443
3ce34dfb
VS
12444#ifdef CONFIG_SPLICE
12445#ifdef TARGET_NR_tee
12446 case TARGET_NR_tee:
12447 {
12448 ret = get_errno(tee(arg1,arg2,arg3,arg4));
12449 }
72eb7ea8 12450 return ret;
3ce34dfb
VS
12451#endif
12452#ifdef TARGET_NR_splice
12453 case TARGET_NR_splice:
12454 {
12455 loff_t loff_in, loff_out;
12456 loff_t *ploff_in = NULL, *ploff_out = NULL;
17644b36
AS
12457 if (arg2) {
12458 if (get_user_u64(loff_in, arg2)) {
2852aafd 12459 return -TARGET_EFAULT;
17644b36 12460 }
3ce34dfb
VS
12461 ploff_in = &loff_in;
12462 }
17644b36
AS
12463 if (arg4) {
12464 if (get_user_u64(loff_out, arg4)) {
2852aafd 12465 return -TARGET_EFAULT;
17644b36 12466 }
3ce34dfb
VS
12467 ploff_out = &loff_out;
12468 }
12469 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
17644b36
AS
12470 if (arg2) {
12471 if (put_user_u64(loff_in, arg2)) {
2852aafd 12472 return -TARGET_EFAULT;
17644b36
AS
12473 }
12474 }
12475 if (arg4) {
12476 if (put_user_u64(loff_out, arg4)) {
2852aafd 12477 return -TARGET_EFAULT;
17644b36
AS
12478 }
12479 }
3ce34dfb 12480 }
72eb7ea8 12481 return ret;
3ce34dfb
VS
12482#endif
12483#ifdef TARGET_NR_vmsplice
12484 case TARGET_NR_vmsplice:
12485 {
f287b2c2
RH
12486 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
12487 if (vec != NULL) {
12488 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
12489 unlock_iovec(vec, arg2, arg3, 0);
12490 } else {
12491 ret = -host_to_target_errno(errno);
12492 }
3ce34dfb 12493 }
72eb7ea8 12494 return ret;
3ce34dfb
VS
12495#endif
12496#endif /* CONFIG_SPLICE */
c2882b96
RV
12497#ifdef CONFIG_EVENTFD
12498#if defined(TARGET_NR_eventfd)
12499 case TARGET_NR_eventfd:
12500 ret = get_errno(eventfd(arg1, 0));
b929f7e5
PMD
12501 if (ret >= 0) {
12502 fd_trans_register(ret, &target_eventfd_trans);
12503 }
72eb7ea8 12504 return ret;
c2882b96
RV
12505#endif
12506#if defined(TARGET_NR_eventfd2)
12507 case TARGET_NR_eventfd2:
5947c697
PJ
12508 {
12509 int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
12510 if (arg2 & TARGET_O_NONBLOCK) {
12511 host_flags |= O_NONBLOCK;
12512 }
12513 if (arg2 & TARGET_O_CLOEXEC) {
12514 host_flags |= O_CLOEXEC;
12515 }
12516 ret = get_errno(eventfd(arg1, host_flags));
b929f7e5
PMD
12517 if (ret >= 0) {
12518 fd_trans_register(ret, &target_eventfd_trans);
12519 }
72eb7ea8 12520 return ret;
5947c697 12521 }
c2882b96
RV
12522#endif
12523#endif /* CONFIG_EVENTFD */
d0927938
UH
12524#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
12525 case TARGET_NR_fallocate:
20249ae1
AG
12526#if TARGET_ABI_BITS == 32
12527 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
12528 target_offset64(arg5, arg6)));
12529#else
d0927938 12530 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
20249ae1 12531#endif
72eb7ea8 12532 return ret;
c727f47d
PM
12533#endif
12534#if defined(CONFIG_SYNC_FILE_RANGE)
12535#if defined(TARGET_NR_sync_file_range)
12536 case TARGET_NR_sync_file_range:
12537#if TARGET_ABI_BITS == 32
bfcedc57
RV
12538#if defined(TARGET_MIPS)
12539 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
12540 target_offset64(arg5, arg6), arg7));
12541#else
c727f47d
PM
12542 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
12543 target_offset64(arg4, arg5), arg6));
bfcedc57 12544#endif /* !TARGET_MIPS */
c727f47d
PM
12545#else
12546 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
12547#endif
72eb7ea8 12548 return ret;
c727f47d 12549#endif
5bcb4986
LV
12550#if defined(TARGET_NR_sync_file_range2) || \
12551 defined(TARGET_NR_arm_sync_file_range)
c727f47d
PM
12552#if defined(TARGET_NR_sync_file_range2)
12553 case TARGET_NR_sync_file_range2:
5bcb4986
LV
12554#endif
12555#if defined(TARGET_NR_arm_sync_file_range)
12556 case TARGET_NR_arm_sync_file_range:
12557#endif
c727f47d
PM
12558 /* This is like sync_file_range but the arguments are reordered */
12559#if TARGET_ABI_BITS == 32
12560 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
12561 target_offset64(arg5, arg6), arg2));
12562#else
12563 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
12564#endif
72eb7ea8 12565 return ret;
c727f47d 12566#endif
3b6edd16 12567#endif
e36800c9
LV
12568#if defined(TARGET_NR_signalfd4)
12569 case TARGET_NR_signalfd4:
72eb7ea8 12570 return do_signalfd4(arg1, arg2, arg4);
e36800c9
LV
12571#endif
12572#if defined(TARGET_NR_signalfd)
12573 case TARGET_NR_signalfd:
72eb7ea8 12574 return do_signalfd4(arg1, arg2, 0);
e36800c9 12575#endif
3b6edd16
PM
12576#if defined(CONFIG_EPOLL)
12577#if defined(TARGET_NR_epoll_create)
12578 case TARGET_NR_epoll_create:
72eb7ea8 12579 return get_errno(epoll_create(arg1));
3b6edd16
PM
12580#endif
12581#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
12582 case TARGET_NR_epoll_create1:
386d3865 12583 return get_errno(epoll_create1(target_to_host_bitmask(arg1, fcntl_flags_tbl)));
3b6edd16
PM
12584#endif
12585#if defined(TARGET_NR_epoll_ctl)
12586 case TARGET_NR_epoll_ctl:
12587 {
12588 struct epoll_event ep;
12589 struct epoll_event *epp = 0;
12590 if (arg4) {
12591 struct target_epoll_event *target_ep;
12592 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
2852aafd 12593 return -TARGET_EFAULT;
3b6edd16
PM
12594 }
12595 ep.events = tswap32(target_ep->events);
12596 /* The epoll_data_t union is just opaque data to the kernel,
12597 * so we transfer all 64 bits across and need not worry what
12598 * actual data type it is.
12599 */
12600 ep.data.u64 = tswap64(target_ep->data.u64);
12601 unlock_user_struct(target_ep, arg4, 0);
12602 epp = &ep;
12603 }
72eb7ea8 12604 return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
3b6edd16
PM
12605 }
12606#endif
12607
227f0214 12608#if defined(TARGET_NR_epoll_wait) || defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12609#if defined(TARGET_NR_epoll_wait)
12610 case TARGET_NR_epoll_wait:
12611#endif
227f0214 12612#if defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12613 case TARGET_NR_epoll_pwait:
12614#endif
12615 {
12616 struct target_epoll_event *target_ep;
12617 struct epoll_event *ep;
12618 int epfd = arg1;
12619 int maxevents = arg3;
12620 int timeout = arg4;
12621
2ba7fae3 12622 if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
72eb7ea8 12623 return -TARGET_EINVAL;
2ba7fae3
PM
12624 }
12625
3b6edd16
PM
12626 target_ep = lock_user(VERIFY_WRITE, arg2,
12627 maxevents * sizeof(struct target_epoll_event), 1);
12628 if (!target_ep) {
2852aafd 12629 return -TARGET_EFAULT;
3b6edd16
PM
12630 }
12631
04c95f4d
PM
12632 ep = g_try_new(struct epoll_event, maxevents);
12633 if (!ep) {
12634 unlock_user(target_ep, arg2, 0);
72eb7ea8 12635 return -TARGET_ENOMEM;
04c95f4d 12636 }
3b6edd16
PM
12637
12638 switch (num) {
227f0214 12639#if defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12640 case TARGET_NR_epoll_pwait:
12641 {
12642 target_sigset_t *target_set;
12643 sigset_t _set, *set = &_set;
12644
12645 if (arg5) {
c815701e
PM
12646 if (arg6 != sizeof(target_sigset_t)) {
12647 ret = -TARGET_EINVAL;
12648 break;
12649 }
12650
3b6edd16
PM
12651 target_set = lock_user(VERIFY_READ, arg5,
12652 sizeof(target_sigset_t), 1);
12653 if (!target_set) {
04c95f4d
PM
12654 ret = -TARGET_EFAULT;
12655 break;
3b6edd16
PM
12656 }
12657 target_to_host_sigset(set, target_set);
12658 unlock_user(target_set, arg5, 0);
12659 } else {
12660 set = NULL;
12661 }
12662
227f0214
PM
12663 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
12664 set, SIGSET_T_SIZE));
3b6edd16
PM
12665 break;
12666 }
12667#endif
12668#if defined(TARGET_NR_epoll_wait)
12669 case TARGET_NR_epoll_wait:
227f0214
PM
12670 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
12671 NULL, 0));
3b6edd16
PM
12672 break;
12673#endif
12674 default:
12675 ret = -TARGET_ENOSYS;
12676 }
12677 if (!is_error(ret)) {
12678 int i;
12679 for (i = 0; i < ret; i++) {
12680 target_ep[i].events = tswap32(ep[i].events);
12681 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
12682 }
04c95f4d
PM
12683 unlock_user(target_ep, arg2,
12684 ret * sizeof(struct target_epoll_event));
12685 } else {
12686 unlock_user(target_ep, arg2, 0);
3b6edd16 12687 }
04c95f4d 12688 g_free(ep);
72eb7ea8 12689 return ret;
3b6edd16
PM
12690 }
12691#endif
163a05a8
PM
12692#endif
12693#ifdef TARGET_NR_prlimit64
12694 case TARGET_NR_prlimit64:
12695 {
12696 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
12697 struct target_rlimit64 *target_rnew, *target_rold;
12698 struct host_rlimit64 rnew, rold, *rnewp = 0;
95018018 12699 int resource = target_to_host_resource(arg2);
055d92f8
TK
12700
12701 if (arg3 && (resource != RLIMIT_AS &&
12702 resource != RLIMIT_DATA &&
12703 resource != RLIMIT_STACK)) {
163a05a8 12704 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
2852aafd 12705 return -TARGET_EFAULT;
163a05a8
PM
12706 }
12707 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
12708 rnew.rlim_max = tswap64(target_rnew->rlim_max);
12709 unlock_user_struct(target_rnew, arg3, 0);
12710 rnewp = &rnew;
12711 }
12712
95018018 12713 ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
163a05a8
PM
12714 if (!is_error(ret) && arg4) {
12715 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
2852aafd 12716 return -TARGET_EFAULT;
163a05a8
PM
12717 }
12718 target_rold->rlim_cur = tswap64(rold.rlim_cur);
12719 target_rold->rlim_max = tswap64(rold.rlim_max);
12720 unlock_user_struct(target_rold, arg4, 1);
12721 }
72eb7ea8 12722 return ret;
163a05a8 12723 }
3d21d29c
RH
12724#endif
12725#ifdef TARGET_NR_gethostname
12726 case TARGET_NR_gethostname:
12727 {
12728 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
12729 if (name) {
12730 ret = get_errno(gethostname(name, arg2));
12731 unlock_user(name, arg1, arg2);
12732 } else {
12733 ret = -TARGET_EFAULT;
12734 }
72eb7ea8 12735 return ret;
3d21d29c 12736 }
89aaf1a6
RV
12737#endif
12738#ifdef TARGET_NR_atomic_cmpxchg_32
12739 case TARGET_NR_atomic_cmpxchg_32:
12740 {
12741 /* should use start_exclusive from main.c */
12742 abi_ulong mem_value;
12743 if (get_user_u32(mem_value, arg6)) {
12744 target_siginfo_t info;
12745 info.si_signo = SIGSEGV;
12746 info.si_errno = 0;
12747 info.si_code = TARGET_SEGV_MAPERR;
12748 info._sifields._sigfault._addr = arg6;
9d2803f7
PM
12749 queue_signal((CPUArchState *)cpu_env, info.si_signo,
12750 QEMU_SI_FAULT, &info);
89aaf1a6
RV
12751 ret = 0xdeadbeef;
12752
12753 }
12754 if (mem_value == arg2)
12755 put_user_u32(arg1, arg6);
72eb7ea8 12756 return mem_value;
89aaf1a6
RV
12757 }
12758#endif
12759#ifdef TARGET_NR_atomic_barrier
12760 case TARGET_NR_atomic_barrier:
72eb7ea8
RH
12761 /* Like the kernel implementation and the
12762 qemu arm barrier, no-op this? */
12763 return 0;
d0927938 12764#endif
f4f1e10a
ECL
12765
12766#ifdef TARGET_NR_timer_create
12767 case TARGET_NR_timer_create:
12768 {
12769 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
12770
12771 struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
f4f1e10a
ECL
12772
12773 int clkid = arg1;
12774 int timer_index = next_free_host_timer();
12775
12776 if (timer_index < 0) {
12777 ret = -TARGET_EAGAIN;
12778 } else {
12779 timer_t *phtimer = g_posix_timers + timer_index;
12780
12781 if (arg2) {
f4f1e10a 12782 phost_sevp = &host_sevp;
c065976f
PM
12783 ret = target_to_host_sigevent(phost_sevp, arg2);
12784 if (ret != 0) {
72eb7ea8 12785 return ret;
c065976f 12786 }
f4f1e10a
ECL
12787 }
12788
12789 ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
12790 if (ret) {
12791 phtimer = NULL;
12792 } else {
aecc8861 12793 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
2852aafd 12794 return -TARGET_EFAULT;
f4f1e10a 12795 }
f4f1e10a
ECL
12796 }
12797 }
72eb7ea8 12798 return ret;
f4f1e10a
ECL
12799 }
12800#endif
12801
12802#ifdef TARGET_NR_timer_settime
12803 case TARGET_NR_timer_settime:
12804 {
12805 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
12806 * struct itimerspec * old_value */
aecc8861 12807 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12808
aecc8861
AG
12809 if (timerid < 0) {
12810 ret = timerid;
12811 } else if (arg3 == 0) {
f4f1e10a
ECL
12812 ret = -TARGET_EINVAL;
12813 } else {
e52a99f7 12814 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12815 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
12816
40c80b5e 12817 if (target_to_host_itimerspec(&hspec_new, arg3)) {
2852aafd 12818 return -TARGET_EFAULT;
40c80b5e 12819 }
f4f1e10a
ECL
12820 ret = get_errno(
12821 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
40c80b5e 12822 if (arg4 && host_to_target_itimerspec(arg4, &hspec_old)) {
2852aafd 12823 return -TARGET_EFAULT;
40c80b5e 12824 }
f4f1e10a 12825 }
72eb7ea8 12826 return ret;
f4f1e10a
ECL
12827 }
12828#endif
12829
828cb3a1
FB
12830#ifdef TARGET_NR_timer_settime64
12831 case TARGET_NR_timer_settime64:
12832 {
12833 target_timer_t timerid = get_timer_id(arg1);
12834
12835 if (timerid < 0) {
12836 ret = timerid;
12837 } else if (arg3 == 0) {
12838 ret = -TARGET_EINVAL;
12839 } else {
12840 timer_t htimer = g_posix_timers[timerid];
12841 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
12842
12843 if (target_to_host_itimerspec64(&hspec_new, arg3)) {
12844 return -TARGET_EFAULT;
12845 }
12846 ret = get_errno(
12847 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
12848 if (arg4 && host_to_target_itimerspec64(arg4, &hspec_old)) {
12849 return -TARGET_EFAULT;
12850 }
12851 }
12852 return ret;
12853 }
12854#endif
12855
f4f1e10a
ECL
12856#ifdef TARGET_NR_timer_gettime
12857 case TARGET_NR_timer_gettime:
12858 {
12859 /* args: timer_t timerid, struct itimerspec *curr_value */
aecc8861 12860 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12861
aecc8861
AG
12862 if (timerid < 0) {
12863 ret = timerid;
12864 } else if (!arg2) {
12865 ret = -TARGET_EFAULT;
f4f1e10a 12866 } else {
e52a99f7 12867 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12868 struct itimerspec hspec;
12869 ret = get_errno(timer_gettime(htimer, &hspec));
12870
12871 if (host_to_target_itimerspec(arg2, &hspec)) {
12872 ret = -TARGET_EFAULT;
12873 }
12874 }
72eb7ea8 12875 return ret;
f4f1e10a
ECL
12876 }
12877#endif
12878
828cb3a1
FB
12879#ifdef TARGET_NR_timer_gettime64
12880 case TARGET_NR_timer_gettime64:
12881 {
12882 /* args: timer_t timerid, struct itimerspec64 *curr_value */
12883 target_timer_t timerid = get_timer_id(arg1);
12884
12885 if (timerid < 0) {
12886 ret = timerid;
12887 } else if (!arg2) {
12888 ret = -TARGET_EFAULT;
12889 } else {
12890 timer_t htimer = g_posix_timers[timerid];
12891 struct itimerspec hspec;
12892 ret = get_errno(timer_gettime(htimer, &hspec));
12893
12894 if (host_to_target_itimerspec64(arg2, &hspec)) {
12895 ret = -TARGET_EFAULT;
12896 }
12897 }
12898 return ret;
12899 }
12900#endif
12901
f4f1e10a
ECL
12902#ifdef TARGET_NR_timer_getoverrun
12903 case TARGET_NR_timer_getoverrun:
12904 {
12905 /* args: timer_t timerid */
aecc8861 12906 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12907
aecc8861
AG
12908 if (timerid < 0) {
12909 ret = timerid;
f4f1e10a 12910 } else {
e52a99f7 12911 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12912 ret = get_errno(timer_getoverrun(htimer));
12913 }
72eb7ea8 12914 return ret;
f4f1e10a
ECL
12915 }
12916#endif
12917
12918#ifdef TARGET_NR_timer_delete
12919 case TARGET_NR_timer_delete:
12920 {
12921 /* args: timer_t timerid */
aecc8861 12922 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12923
aecc8861
AG
12924 if (timerid < 0) {
12925 ret = timerid;
f4f1e10a 12926 } else {
e52a99f7 12927 timer_t htimer = g_posix_timers[timerid];
f4f1e10a 12928 ret = get_errno(timer_delete(htimer));
e52a99f7 12929 g_posix_timers[timerid] = 0;
f4f1e10a 12930 }
72eb7ea8 12931 return ret;
f4f1e10a
ECL
12932 }
12933#endif
12934
51834341
RV
12935#if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
12936 case TARGET_NR_timerfd_create:
72eb7ea8
RH
12937 return get_errno(timerfd_create(arg1,
12938 target_to_host_bitmask(arg2, fcntl_flags_tbl)));
51834341
RV
12939#endif
12940
12941#if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
12942 case TARGET_NR_timerfd_gettime:
12943 {
12944 struct itimerspec its_curr;
12945
12946 ret = get_errno(timerfd_gettime(arg1, &its_curr));
12947
12948 if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
2852aafd 12949 return -TARGET_EFAULT;
51834341
RV
12950 }
12951 }
72eb7ea8 12952 return ret;
51834341
RV
12953#endif
12954
828cb3a1
FB
12955#if defined(TARGET_NR_timerfd_gettime64) && defined(CONFIG_TIMERFD)
12956 case TARGET_NR_timerfd_gettime64:
12957 {
12958 struct itimerspec its_curr;
12959
12960 ret = get_errno(timerfd_gettime(arg1, &its_curr));
12961
12962 if (arg2 && host_to_target_itimerspec64(arg2, &its_curr)) {
12963 return -TARGET_EFAULT;
12964 }
12965 }
12966 return ret;
12967#endif
12968
51834341
RV
12969#if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
12970 case TARGET_NR_timerfd_settime:
12971 {
12972 struct itimerspec its_new, its_old, *p_new;
12973
12974 if (arg3) {
12975 if (target_to_host_itimerspec(&its_new, arg3)) {
2852aafd 12976 return -TARGET_EFAULT;
51834341
RV
12977 }
12978 p_new = &its_new;
12979 } else {
12980 p_new = NULL;
12981 }
12982
12983 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
12984
12985 if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
2852aafd 12986 return -TARGET_EFAULT;
51834341
RV
12987 }
12988 }
72eb7ea8 12989 return ret;
51834341
RV
12990#endif
12991
828cb3a1
FB
12992#if defined(TARGET_NR_timerfd_settime64) && defined(CONFIG_TIMERFD)
12993 case TARGET_NR_timerfd_settime64:
12994 {
12995 struct itimerspec its_new, its_old, *p_new;
12996
12997 if (arg3) {
12998 if (target_to_host_itimerspec64(&its_new, arg3)) {
12999 return -TARGET_EFAULT;
13000 }
13001 p_new = &its_new;
13002 } else {
13003 p_new = NULL;
13004 }
13005
13006 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
13007
13008 if (arg4 && host_to_target_itimerspec64(arg4, &its_old)) {
13009 return -TARGET_EFAULT;
13010 }
13011 }
13012 return ret;
13013#endif
13014
ab31cda3
PB
13015#if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
13016 case TARGET_NR_ioprio_get:
72eb7ea8 13017 return get_errno(ioprio_get(arg1, arg2));
ab31cda3
PB
13018#endif
13019
13020#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
13021 case TARGET_NR_ioprio_set:
72eb7ea8 13022 return get_errno(ioprio_set(arg1, arg2, arg3));
ab31cda3
PB
13023#endif
13024
9af5c906
RV
13025#if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
13026 case TARGET_NR_setns:
72eb7ea8 13027 return get_errno(setns(arg1, arg2));
9af5c906
RV
13028#endif
13029#if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
13030 case TARGET_NR_unshare:
72eb7ea8 13031 return get_errno(unshare(arg1));
9af5c906 13032#endif
2f14788c
LV
13033#if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
13034 case TARGET_NR_kcmp:
72eb7ea8 13035 return get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
2f14788c 13036#endif
fa97e38e
RH
13037#ifdef TARGET_NR_swapcontext
13038 case TARGET_NR_swapcontext:
13039 /* PowerPC specific. */
72eb7ea8 13040 return do_swapcontext(cpu_env, arg1, arg2, arg3);
fa97e38e 13041#endif
9bdfa4d2
SCW
13042#ifdef TARGET_NR_memfd_create
13043 case TARGET_NR_memfd_create:
13044 p = lock_user_string(arg1);
13045 if (!p) {
13046 return -TARGET_EFAULT;
13047 }
13048 ret = get_errno(memfd_create(p, arg2));
13049 fd_trans_unregister(ret);
13050 unlock_user(p, arg1, 0);
13051 return ret;
13052#endif
8500476f
AS
13053#if defined TARGET_NR_membarrier && defined __NR_membarrier
13054 case TARGET_NR_membarrier:
13055 return get_errno(membarrier(arg1, arg2));
13056#endif
9af5c906 13057
31e31b8a 13058 default:
122f9c83 13059 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
72eb7ea8 13060 return -TARGET_ENOSYS;
31e31b8a 13061 }
31e31b8a
FB
13062 return ret;
13063}
dc1ce18b
RH
13064
13065abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
13066 abi_long arg2, abi_long arg3, abi_long arg4,
13067 abi_long arg5, abi_long arg6, abi_long arg7,
13068 abi_long arg8)
13069{
29a0af61 13070 CPUState *cpu = env_cpu(cpu_env);
dc1ce18b
RH
13071 abi_long ret;
13072
13073#ifdef DEBUG_ERESTARTSYS
13074 /* Debug-only code for exercising the syscall-restart code paths
13075 * in the per-architecture cpu main loops: restart every syscall
13076 * the guest makes once before letting it through.
13077 */
13078 {
13079 static bool flag;
13080 flag = !flag;
13081 if (flag) {
13082 return -TARGET_ERESTARTSYS;
13083 }
13084 }
13085#endif
13086
c36f7a64
EC
13087 record_syscall_start(cpu, num, arg1,
13088 arg2, arg3, arg4, arg5, arg6, arg7, arg8);
dc1ce18b 13089
4b25a506 13090 if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
e400e119 13091 print_syscall(cpu_env, num, arg1, arg2, arg3, arg4, arg5, arg6);
4b25a506
JK
13092 }
13093
13094 ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
13095 arg5, arg6, arg7, arg8);
13096
13097 if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
e400e119
FB
13098 print_syscall_ret(cpu_env, num, ret, arg1, arg2,
13099 arg3, arg4, arg5, arg6);
dc1ce18b
RH
13100 }
13101
c36f7a64 13102 record_syscall_return(cpu, num, ret);
dc1ce18b
RH
13103 return ret;
13104}