]> git.proxmox.com Git - mirror_qemu.git/blame - linux-user/syscall.c
Merge remote-tracking branch 'remotes/cminyard/tags/for-qemu-i2c-5' into staging
[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>
e865b97f
CG
115#ifdef HAVE_DRM_H
116#include <libdrm/drm.h>
117#endif
d7e4036e 118#include "linux_loop.h"
18cb0088 119#include "uname.h"
31e31b8a 120
3ef693a0 121#include "qemu.h"
5ebdd774 122#include "qemu/guest-random.h"
01ef6b9e 123#include "qemu/selfmap.h"
c36f7a64 124#include "user/syscall-trace.h"
51977e25 125#include "qapi/error.h"
f7e6a401 126#include "fd-trans.h"
dcb32f1d 127#include "tcg/tcg.h"
31e31b8a 128
5ea2fc84
PM
129#ifndef CLONE_IO
130#define CLONE_IO 0x80000000 /* Clone io context */
131#endif
132
133/* We can't directly call the host clone syscall, because this will
134 * badly confuse libc (breaking mutexes, for example). So we must
135 * divide clone flags into:
136 * * flag combinations that look like pthread_create()
137 * * flag combinations that look like fork()
138 * * flags we can implement within QEMU itself
139 * * flags we can't support and will return an error for
140 */
141/* For thread creation, all these flags must be present; for
142 * fork, none must be present.
143 */
144#define CLONE_THREAD_FLAGS \
145 (CLONE_VM | CLONE_FS | CLONE_FILES | \
146 CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
147
148/* These flags are ignored:
149 * CLONE_DETACHED is now ignored by the kernel;
150 * CLONE_IO is just an optimisation hint to the I/O scheduler
151 */
152#define CLONE_IGNORED_FLAGS \
153 (CLONE_DETACHED | CLONE_IO)
154
155/* Flags for fork which we can implement within QEMU itself */
156#define CLONE_OPTIONAL_FORK_FLAGS \
157 (CLONE_SETTLS | CLONE_PARENT_SETTID | \
158 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
159
160/* Flags for thread creation which we can implement within QEMU itself */
161#define CLONE_OPTIONAL_THREAD_FLAGS \
162 (CLONE_SETTLS | CLONE_PARENT_SETTID | \
163 CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
164
165#define CLONE_INVALID_FORK_FLAGS \
166 (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
167
168#define CLONE_INVALID_THREAD_FLAGS \
169 (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS | \
170 CLONE_IGNORED_FLAGS))
171
172/* CLONE_VFORK is special cased early in do_fork(). The other flag bits
173 * have almost all been allocated. We cannot support any of
174 * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
175 * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
176 * The checks against the invalid thread masks above will catch these.
177 * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
178 */
30813cea 179
71a8f7fe
TB
180/* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
181 * once. This exercises the codepaths for restart.
182 */
183//#define DEBUG_ERESTARTSYS
31e31b8a 184
1a9353d2 185//#include <linux/msdos_fs.h>
6556a833
AJ
186#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
187#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
1a9353d2 188
70a194b9
FB
189#undef _syscall0
190#undef _syscall1
191#undef _syscall2
192#undef _syscall3
193#undef _syscall4
194#undef _syscall5
83fcb515 195#undef _syscall6
70a194b9 196
83fcb515 197#define _syscall0(type,name) \
8fcd3692 198static type name (void) \
83fcb515
FB
199{ \
200 return syscall(__NR_##name); \
201}
70a194b9 202
83fcb515 203#define _syscall1(type,name,type1,arg1) \
8fcd3692 204static type name (type1 arg1) \
83fcb515
FB
205{ \
206 return syscall(__NR_##name, arg1); \
70a194b9
FB
207}
208
83fcb515 209#define _syscall2(type,name,type1,arg1,type2,arg2) \
8fcd3692 210static type name (type1 arg1,type2 arg2) \
83fcb515
FB
211{ \
212 return syscall(__NR_##name, arg1, arg2); \
70a194b9
FB
213}
214
83fcb515 215#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
8fcd3692 216static type name (type1 arg1,type2 arg2,type3 arg3) \
83fcb515
FB
217{ \
218 return syscall(__NR_##name, arg1, arg2, arg3); \
70a194b9
FB
219}
220
83fcb515 221#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
8fcd3692 222static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
83fcb515
FB
223{ \
224 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
70a194b9
FB
225}
226
83fcb515
FB
227#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
228 type5,arg5) \
8fcd3692 229static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
83fcb515
FB
230{ \
231 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
70a194b9
FB
232}
233
83fcb515
FB
234
235#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
236 type5,arg5,type6,arg6) \
8fcd3692
BS
237static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
238 type6 arg6) \
83fcb515
FB
239{ \
240 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
70a194b9 241}
83fcb515 242
70a194b9 243
31e31b8a 244#define __NR_sys_uname __NR_uname
72f03900 245#define __NR_sys_getcwd1 __NR_getcwd
72f03900 246#define __NR_sys_getdents __NR_getdents
dab2ed99 247#define __NR_sys_getdents64 __NR_getdents64
c6cda17a 248#define __NR_sys_getpriority __NR_getpriority
66fb9763 249#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
cf8b8bfc 250#define __NR_sys_rt_tgsigqueueinfo __NR_rt_tgsigqueueinfo
7494b0f9 251#define __NR_sys_syslog __NR_syslog
14690296
AF
252#if defined(__NR_futex)
253# define __NR_sys_futex __NR_futex
254#endif
255#if defined(__NR_futex_time64)
256# define __NR_sys_futex_time64 __NR_futex_time64
257#endif
39b59763
AJ
258#define __NR_sys_inotify_init __NR_inotify_init
259#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
260#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
efa92184 261#define __NR_sys_statx __NR_statx
31e31b8a 262
b1cef6d0 263#if defined(__alpha__) || defined(__x86_64__) || defined(__s390x__)
9af9eaaa
FB
264#define __NR__llseek __NR_lseek
265#endif
266
a29e5ba2
JH
267/* Newer kernel ports have llseek() instead of _llseek() */
268#if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
269#define TARGET_NR__llseek TARGET_NR_llseek
270#endif
271
71ba74f6
DB
272#define __NR_sys_gettid __NR_gettid
273_syscall0(int, sys_gettid)
2b3f64cb
PM
274
275/* For the 64-bit guest on 32-bit host case we must emulate
276 * getdents using getdents64, because otherwise the host
277 * might hand us back more dirent records than we can fit
278 * into the guest buffer after structure format conversion.
279 * Otherwise we emulate getdents with getdents if the host has it.
280 */
281#if defined(__NR_getdents) && HOST_LONG_BITS >= TARGET_ABI_BITS
282#define EMULATE_GETDENTS_WITH_GETDENTS
283#endif
284
285#if defined(TARGET_NR_getdents) && defined(EMULATE_GETDENTS_WITH_GETDENTS)
3b3f24ad 286_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
3307e236 287#endif
2b3f64cb
PM
288#if (defined(TARGET_NR_getdents) && \
289 !defined(EMULATE_GETDENTS_WITH_GETDENTS)) || \
3307e236 290 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
3b3f24ad
AJ
291_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
292#endif
d35b261c 293#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
3b3f24ad
AJ
294_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
295 loff_t *, res, uint, wh);
296#endif
c1a402a7 297_syscall3(int, sys_rt_sigqueueinfo, pid_t, pid, int, sig, siginfo_t *, uinfo)
cf8b8bfc
MS
298_syscall4(int, sys_rt_tgsigqueueinfo, pid_t, pid, pid_t, tid, int, sig,
299 siginfo_t *, uinfo)
3b3f24ad 300_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
3b3f24ad
AJ
301#ifdef __NR_exit_group
302_syscall1(int,exit_group,int,error_code)
303#endif
304#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
305_syscall1(int,set_tid_address,int *,tidptr)
306#endif
14690296 307#if defined(__NR_futex)
3b3f24ad
AJ
308_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
309 const struct timespec *,timeout,int *,uaddr2,int,val3)
310#endif
14690296
AF
311#if defined(__NR_futex_time64)
312_syscall6(int,sys_futex_time64,int *,uaddr,int,op,int,val,
313 const struct timespec *,timeout,int *,uaddr2,int,val3)
314#endif
737de1d1
MF
315#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
316_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
317 unsigned long *, user_mask_ptr);
318#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
319_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
320 unsigned long *, user_mask_ptr);
b827c3ed
ST
321#define __NR_sys_getcpu __NR_getcpu
322_syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
0f6b4d21
AG
323_syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
324 void *, arg);
e0eb210e
PM
325_syscall2(int, capget, struct __user_cap_header_struct *, header,
326 struct __user_cap_data_struct *, data);
327_syscall2(int, capset, struct __user_cap_header_struct *, header,
328 struct __user_cap_data_struct *, data);
ab31cda3
PB
329#if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
330_syscall2(int, ioprio_get, int, which, int, who)
331#endif
332#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
333_syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
334#endif
f894efd1
LV
335#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
336_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
337#endif
3b3f24ad 338
2f14788c
LV
339#if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
340_syscall5(int, kcmp, pid_t, pid1, pid_t, pid2, int, type,
341 unsigned long, idx1, unsigned long, idx2)
342#endif
343
efa92184
AR
344/*
345 * It is assumed that struct statx is architecture independent.
346 */
347#if defined(TARGET_NR_statx) && defined(__NR_statx)
348_syscall5(int, sys_statx, int, dirfd, const char *, pathname, int, flags,
349 unsigned int, mask, struct target_statx *, statxbuf)
350#endif
8500476f
AS
351#if defined(TARGET_NR_membarrier) && defined(__NR_membarrier)
352_syscall2(int, membarrier, int, cmd, int, flags)
353#endif
efa92184 354
3b3f24ad
AJ
355static bitmask_transtbl fcntl_flags_tbl[] = {
356 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
357 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
358 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
359 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
360 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
361 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
362 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
363 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
afc8763f 364 { TARGET_O_SYNC, TARGET_O_DSYNC, O_SYNC, O_DSYNC, },
3b3f24ad
AJ
365 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
366 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
367 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
368 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
3b3f24ad
AJ
369#if defined(O_DIRECT)
370 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
afc8763f
RH
371#endif
372#if defined(O_NOATIME)
373 { TARGET_O_NOATIME, TARGET_O_NOATIME, O_NOATIME, O_NOATIME },
374#endif
375#if defined(O_CLOEXEC)
376 { TARGET_O_CLOEXEC, TARGET_O_CLOEXEC, O_CLOEXEC, O_CLOEXEC },
377#endif
378#if defined(O_PATH)
379 { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
5f9cee46
RV
380#endif
381#if defined(O_TMPFILE)
382 { TARGET_O_TMPFILE, TARGET_O_TMPFILE, O_TMPFILE, O_TMPFILE },
afc8763f
RH
383#endif
384 /* Don't terminate the list prematurely on 64-bit host+guest. */
385#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
386 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
3b3f24ad
AJ
387#endif
388 { 0, 0, 0, 0 }
389};
390
3b3f24ad
AJ
391static int sys_getcwd1(char *buf, size_t size)
392{
393 if (getcwd(buf, size) == NULL) {
394 /* getcwd() sets errno */
395 return (-1);
396 }
aaf4ad39 397 return strlen(buf)+1;
3b3f24ad
AJ
398}
399
1acae9f2 400#ifdef TARGET_NR_utimensat
700fa58e 401#if defined(__NR_utimensat)
1acae9f2 402#define __NR_sys_utimensat __NR_utimensat
9007f0ef
TS
403_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
404 const struct timespec *,tsp,int,flags)
1acae9f2
PM
405#else
406static int sys_utimensat(int dirfd, const char *pathname,
407 const struct timespec times[2], int flags)
408{
409 errno = ENOSYS;
410 return -1;
411}
9007f0ef 412#endif
1acae9f2 413#endif /* TARGET_NR_utimensat */
3b3f24ad 414
95d0307c
AS
415#ifdef TARGET_NR_renameat2
416#if defined(__NR_renameat2)
417#define __NR_sys_renameat2 __NR_renameat2
418_syscall5(int, sys_renameat2, int, oldfd, const char *, old, int, newfd,
419 const char *, new, unsigned int, flags)
420#else
421static int sys_renameat2(int oldfd, const char *old,
422 int newfd, const char *new, int flags)
423{
424 if (flags == 0) {
425 return renameat(oldfd, old, newfd, new);
426 }
427 errno = ENOSYS;
428 return -1;
429}
430#endif
431#endif /* TARGET_NR_renameat2 */
432
3b3f24ad 433#ifdef CONFIG_INOTIFY
8690e420 434#include <sys/inotify.h>
3b3f24ad 435
39b59763 436#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
3b3f24ad
AJ
437static int sys_inotify_init(void)
438{
439 return (inotify_init());
440}
39b59763
AJ
441#endif
442#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
3b3f24ad
AJ
443static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
444{
445 return (inotify_add_watch(fd, pathname, mask));
446}
39b59763
AJ
447#endif
448#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
3b3f24ad
AJ
449static int sys_inotify_rm_watch(int fd, int32_t wd)
450{
8690e420 451 return (inotify_rm_watch(fd, wd));
3b3f24ad 452}
bd0c5661 453#endif
c05c7a73
RV
454#ifdef CONFIG_INOTIFY1
455#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
456static int sys_inotify_init1(int flags)
457{
458 return (inotify_init1(flags));
459}
460#endif
461#endif
3b3f24ad
AJ
462#else
463/* Userspace can usually survive runtime without inotify */
464#undef TARGET_NR_inotify_init
c05c7a73 465#undef TARGET_NR_inotify_init1
3b3f24ad
AJ
466#undef TARGET_NR_inotify_add_watch
467#undef TARGET_NR_inotify_rm_watch
468#endif /* CONFIG_INOTIFY */
469
163a05a8
PM
470#if defined(TARGET_NR_prlimit64)
471#ifndef __NR_prlimit64
472# define __NR_prlimit64 -1
473#endif
474#define __NR_sys_prlimit64 __NR_prlimit64
475/* The glibc rlimit structure may not be that used by the underlying syscall */
476struct host_rlimit64 {
477 uint64_t rlim_cur;
478 uint64_t rlim_max;
479};
480_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
481 const struct host_rlimit64 *, new_limit,
482 struct host_rlimit64 *, old_limit)
483#endif
484
f4f1e10a
ECL
485
486#if defined(TARGET_NR_timer_create)
487/* Maxiumum of 32 active POSIX timers allowed at any one time. */
488static timer_t g_posix_timers[32] = { 0, } ;
489
490static inline int next_free_host_timer(void)
491{
492 int k ;
493 /* FIXME: Does finding the next free slot require a lock? */
494 for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
495 if (g_posix_timers[k] == 0) {
496 g_posix_timers[k] = (timer_t) 1;
497 return k;
498 }
499 }
500 return -1;
501}
502#endif
503
48e515d4 504/* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
4a1def4e 505#ifdef TARGET_ARM
8bf8e9df
JC
506static inline int regpairs_aligned(void *cpu_env, int num)
507{
48e515d4
RV
508 return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
509}
d7779acb 510#elif defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32)
8bf8e9df 511static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
4a1def4e
AG
512#elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
513/* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
514 * of registers which translates to the same as ARM/MIPS, because we start with
515 * r3 as arg1 */
8bf8e9df
JC
516static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
517#elif defined(TARGET_SH4)
518/* SH4 doesn't align register pairs, except for p{read,write}64 */
519static inline int regpairs_aligned(void *cpu_env, int num)
520{
521 switch (num) {
522 case TARGET_NR_pread64:
523 case TARGET_NR_pwrite64:
524 return 1;
525
526 default:
527 return 0;
528 }
529}
ba7651fb
MF
530#elif defined(TARGET_XTENSA)
531static inline int regpairs_aligned(void *cpu_env, int num) { return 1; }
48e515d4 532#else
8bf8e9df 533static inline int regpairs_aligned(void *cpu_env, int num) { return 0; }
48e515d4
RV
534#endif
535
b92c47c1
TS
536#define ERRNO_TABLE_SIZE 1200
537
538/* target_to_host_errno_table[] is initialized from
539 * host_to_target_errno_table[] in syscall_init(). */
540static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
541};
542
637947f1 543/*
fe8f096b 544 * This list is the union of errno values overridden in asm-<arch>/errno.h
637947f1
TS
545 * minus the errnos that are not actually generic to all archs.
546 */
b92c47c1 547static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
08703b9f 548 [EAGAIN] = TARGET_EAGAIN,
637947f1
TS
549 [EIDRM] = TARGET_EIDRM,
550 [ECHRNG] = TARGET_ECHRNG,
551 [EL2NSYNC] = TARGET_EL2NSYNC,
552 [EL3HLT] = TARGET_EL3HLT,
553 [EL3RST] = TARGET_EL3RST,
554 [ELNRNG] = TARGET_ELNRNG,
555 [EUNATCH] = TARGET_EUNATCH,
556 [ENOCSI] = TARGET_ENOCSI,
557 [EL2HLT] = TARGET_EL2HLT,
558 [EDEADLK] = TARGET_EDEADLK,
559 [ENOLCK] = TARGET_ENOLCK,
560 [EBADE] = TARGET_EBADE,
561 [EBADR] = TARGET_EBADR,
562 [EXFULL] = TARGET_EXFULL,
563 [ENOANO] = TARGET_ENOANO,
564 [EBADRQC] = TARGET_EBADRQC,
565 [EBADSLT] = TARGET_EBADSLT,
566 [EBFONT] = TARGET_EBFONT,
567 [ENOSTR] = TARGET_ENOSTR,
568 [ENODATA] = TARGET_ENODATA,
569 [ETIME] = TARGET_ETIME,
570 [ENOSR] = TARGET_ENOSR,
571 [ENONET] = TARGET_ENONET,
572 [ENOPKG] = TARGET_ENOPKG,
573 [EREMOTE] = TARGET_EREMOTE,
574 [ENOLINK] = TARGET_ENOLINK,
575 [EADV] = TARGET_EADV,
576 [ESRMNT] = TARGET_ESRMNT,
577 [ECOMM] = TARGET_ECOMM,
578 [EPROTO] = TARGET_EPROTO,
579 [EDOTDOT] = TARGET_EDOTDOT,
580 [EMULTIHOP] = TARGET_EMULTIHOP,
581 [EBADMSG] = TARGET_EBADMSG,
582 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
583 [EOVERFLOW] = TARGET_EOVERFLOW,
584 [ENOTUNIQ] = TARGET_ENOTUNIQ,
585 [EBADFD] = TARGET_EBADFD,
586 [EREMCHG] = TARGET_EREMCHG,
587 [ELIBACC] = TARGET_ELIBACC,
588 [ELIBBAD] = TARGET_ELIBBAD,
589 [ELIBSCN] = TARGET_ELIBSCN,
590 [ELIBMAX] = TARGET_ELIBMAX,
591 [ELIBEXEC] = TARGET_ELIBEXEC,
592 [EILSEQ] = TARGET_EILSEQ,
593 [ENOSYS] = TARGET_ENOSYS,
594 [ELOOP] = TARGET_ELOOP,
595 [ERESTART] = TARGET_ERESTART,
596 [ESTRPIPE] = TARGET_ESTRPIPE,
597 [ENOTEMPTY] = TARGET_ENOTEMPTY,
598 [EUSERS] = TARGET_EUSERS,
599 [ENOTSOCK] = TARGET_ENOTSOCK,
600 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
601 [EMSGSIZE] = TARGET_EMSGSIZE,
602 [EPROTOTYPE] = TARGET_EPROTOTYPE,
603 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
604 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
605 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
606 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
607 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
608 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
609 [EADDRINUSE] = TARGET_EADDRINUSE,
610 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
611 [ENETDOWN] = TARGET_ENETDOWN,
612 [ENETUNREACH] = TARGET_ENETUNREACH,
613 [ENETRESET] = TARGET_ENETRESET,
614 [ECONNABORTED] = TARGET_ECONNABORTED,
615 [ECONNRESET] = TARGET_ECONNRESET,
616 [ENOBUFS] = TARGET_ENOBUFS,
617 [EISCONN] = TARGET_EISCONN,
618 [ENOTCONN] = TARGET_ENOTCONN,
619 [EUCLEAN] = TARGET_EUCLEAN,
620 [ENOTNAM] = TARGET_ENOTNAM,
621 [ENAVAIL] = TARGET_ENAVAIL,
622 [EISNAM] = TARGET_EISNAM,
623 [EREMOTEIO] = TARGET_EREMOTEIO,
0444a3b7 624 [EDQUOT] = TARGET_EDQUOT,
637947f1
TS
625 [ESHUTDOWN] = TARGET_ESHUTDOWN,
626 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
627 [ETIMEDOUT] = TARGET_ETIMEDOUT,
628 [ECONNREFUSED] = TARGET_ECONNREFUSED,
629 [EHOSTDOWN] = TARGET_EHOSTDOWN,
630 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
631 [EALREADY] = TARGET_EALREADY,
632 [EINPROGRESS] = TARGET_EINPROGRESS,
633 [ESTALE] = TARGET_ESTALE,
634 [ECANCELED] = TARGET_ECANCELED,
635 [ENOMEDIUM] = TARGET_ENOMEDIUM,
636 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
b7fe5db7 637#ifdef ENOKEY
637947f1 638 [ENOKEY] = TARGET_ENOKEY,
b7fe5db7
TS
639#endif
640#ifdef EKEYEXPIRED
637947f1 641 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
b7fe5db7
TS
642#endif
643#ifdef EKEYREVOKED
637947f1 644 [EKEYREVOKED] = TARGET_EKEYREVOKED,
b7fe5db7
TS
645#endif
646#ifdef EKEYREJECTED
637947f1 647 [EKEYREJECTED] = TARGET_EKEYREJECTED,
b7fe5db7
TS
648#endif
649#ifdef EOWNERDEAD
637947f1 650 [EOWNERDEAD] = TARGET_EOWNERDEAD,
b7fe5db7
TS
651#endif
652#ifdef ENOTRECOVERABLE
637947f1 653 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
b7fe5db7 654#endif
da39db63
AM
655#ifdef ENOMSG
656 [ENOMSG] = TARGET_ENOMSG,
657#endif
fe8ed7d5
RH
658#ifdef ERKFILL
659 [ERFKILL] = TARGET_ERFKILL,
660#endif
661#ifdef EHWPOISON
662 [EHWPOISON] = TARGET_EHWPOISON,
663#endif
b92c47c1 664};
637947f1
TS
665
666static inline int host_to_target_errno(int err)
667{
2466119c
TB
668 if (err >= 0 && err < ERRNO_TABLE_SIZE &&
669 host_to_target_errno_table[err]) {
637947f1 670 return host_to_target_errno_table[err];
2466119c 671 }
637947f1
TS
672 return err;
673}
674
b92c47c1
TS
675static inline int target_to_host_errno(int err)
676{
2466119c
TB
677 if (err >= 0 && err < ERRNO_TABLE_SIZE &&
678 target_to_host_errno_table[err]) {
b92c47c1 679 return target_to_host_errno_table[err];
2466119c 680 }
b92c47c1
TS
681 return err;
682}
683
992f48a0 684static inline abi_long get_errno(abi_long ret)
31e31b8a
FB
685{
686 if (ret == -1)
637947f1 687 return -host_to_target_errno(errno);
31e31b8a
FB
688 else
689 return ret;
690}
691
7dcdaeaf 692const char *target_strerror(int err)
b92c47c1 693{
da2a34f7
PM
694 if (err == TARGET_ERESTARTSYS) {
695 return "To be restarted";
696 }
697 if (err == TARGET_QEMU_ESIGRETURN) {
698 return "Successful exit from sigreturn";
699 }
700
962b289e
AG
701 if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
702 return NULL;
703 }
b92c47c1
TS
704 return strerror(target_to_host_errno(err));
705}
706
4d330cee
TB
707#define safe_syscall0(type, name) \
708static type safe_##name(void) \
709{ \
710 return safe_syscall(__NR_##name); \
711}
712
713#define safe_syscall1(type, name, type1, arg1) \
714static type safe_##name(type1 arg1) \
715{ \
716 return safe_syscall(__NR_##name, arg1); \
717}
718
719#define safe_syscall2(type, name, type1, arg1, type2, arg2) \
720static type safe_##name(type1 arg1, type2 arg2) \
721{ \
722 return safe_syscall(__NR_##name, arg1, arg2); \
723}
724
725#define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
726static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
727{ \
728 return safe_syscall(__NR_##name, arg1, arg2, arg3); \
729}
730
731#define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
732 type4, arg4) \
733static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
734{ \
735 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
736}
737
738#define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
739 type4, arg4, type5, arg5) \
740static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
741 type5 arg5) \
742{ \
743 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
744}
745
746#define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
747 type4, arg4, type5, arg5, type6, arg6) \
748static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
749 type5 arg5, type6 arg6) \
750{ \
751 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
752}
753
50afd02b
TB
754safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
755safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
c10a0738
TB
756safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
757 int, flags, mode_t, mode)
859e8a89 758#if defined(TARGET_NR_wait4) || defined(TARGET_NR_waitpid)
4af80a37
TB
759safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
760 struct rusage *, rusage)
859e8a89 761#endif
4af80a37
TB
762safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
763 int, options, struct rusage *, rusage)
ffdcbe22 764safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
859e8a89
AF
765#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
766 defined(TARGET_NR_pselect6)
6df9d38d
PM
767safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
768 fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
859e8a89
AF
769#endif
770#if defined(TARGET_NR_ppoll) || defined(TARGET_NR_poll)
a6130237
PM
771safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
772 struct timespec *, tsp, const sigset_t *, sigmask,
773 size_t, sigsetsize)
859e8a89 774#endif
227f0214
PM
775safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
776 int, maxevents, int, timeout, const sigset_t *, sigmask,
777 size_t, sigsetsize)
14690296 778#if defined(__NR_futex)
d509eeb1
PM
779safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
780 const struct timespec *,timeout,int *,uaddr2,int,val3)
859e8a89 781#endif
14690296
AF
782#if defined(__NR_futex_time64)
783safe_syscall6(int,futex_time64,int *,uaddr,int,op,int,val, \
784 const struct timespec *,timeout,int *,uaddr2,int,val3)
785#endif
2fe4fba1 786safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
bef653d9
PM
787safe_syscall2(int, kill, pid_t, pid, int, sig)
788safe_syscall2(int, tkill, int, tid, int, sig)
789safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
918c03ed
PM
790safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
791safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
0f26386c
DJ
792safe_syscall5(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt,
793 unsigned long, pos_l, unsigned long, pos_h)
f8d00fba
DJ
794safe_syscall5(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt,
795 unsigned long, pos_l, unsigned long, pos_h)
2a3c7619
PM
796safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
797 socklen_t, addrlen)
66687530
PM
798safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
799 int, flags, const struct sockaddr *, addr, socklen_t, addrlen)
800safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, size_t, len,
801 int, flags, struct sockaddr *, addr, socklen_t *, addrlen)
802safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, flags)
803safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
2a845989 804safe_syscall2(int, flock, int, fd, int, operation)
859e8a89 805#ifdef TARGET_NR_rt_sigtimedwait
b3f82330
PM
806safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, uinfo,
807 const struct timespec *, uts, size_t, sigsetsize)
859e8a89 808#endif
ff6dc130
PM
809safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len,
810 int, flags)
859e8a89 811#if defined(TARGET_NR_nanosleep)
9e518226
PM
812safe_syscall2(int, nanosleep, const struct timespec *, req,
813 struct timespec *, rem)
859e8a89 814#endif
9e518226
PM
815#ifdef TARGET_NR_clock_nanosleep
816safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
817 const struct timespec *, req, struct timespec *, rem)
818#endif
524fa340 819#ifdef __NR_ipc
d8c08b1e
MK
820#ifdef __s390x__
821safe_syscall5(int, ipc, int, call, long, first, long, second, long, third,
822 void *, ptr)
823#else
89f9fe44
PM
824safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
825 void *, ptr, long, fifth)
86e63695 826#endif
d8c08b1e 827#endif
86e63695
LV
828#ifdef __NR_msgsnd
829safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
830 int, flags)
86e63695
LV
831#endif
832#ifdef __NR_msgrcv
833safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
834 long, msgtype, int, flags)
86e63695
LV
835#endif
836#ifdef __NR_semtimedop
837safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
838 unsigned, nsops, const struct timespec *, timeout)
89f9fe44 839#endif
859e8a89 840#ifdef TARGET_NR_mq_timedsend
d40ecd66
PM
841safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
842 size_t, len, unsigned, prio, const struct timespec *, timeout)
859e8a89
AF
843#endif
844#ifdef TARGET_NR_mq_timedreceive
d40ecd66
PM
845safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
846 size_t, len, unsigned *, prio, const struct timespec *, timeout)
847#endif
49ca6f3e
PM
848/* We do ioctl like this rather than via safe_syscall3 to preserve the
849 * "third argument might be integer or pointer or not present" behaviour of
850 * the libc function.
851 */
852#define safe_ioctl(...) safe_syscall(__NR_ioctl, __VA_ARGS__)
435da5e7
PM
853/* Similarly for fcntl. Note that callers must always:
854 * pass the F_GETLK64 etc constants rather than the unsuffixed F_GETLK
855 * use the flock64 struct rather than unsuffixed flock
856 * This will then work and use a 64-bit offset for both 32-bit and 64-bit hosts.
857 */
858#ifdef __NR_fcntl64
859#define safe_fcntl(...) safe_syscall(__NR_fcntl64, __VA_ARGS__)
860#else
861#define safe_fcntl(...) safe_syscall(__NR_fcntl, __VA_ARGS__)
862#endif
50afd02b 863
8289d112
PB
864static inline int host_to_target_sock_type(int host_type)
865{
866 int target_type;
867
868 switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
869 case SOCK_DGRAM:
870 target_type = TARGET_SOCK_DGRAM;
871 break;
872 case SOCK_STREAM:
873 target_type = TARGET_SOCK_STREAM;
874 break;
875 default:
876 target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
877 break;
878 }
879
880#if defined(SOCK_CLOEXEC)
881 if (host_type & SOCK_CLOEXEC) {
882 target_type |= TARGET_SOCK_CLOEXEC;
883 }
884#endif
885
886#if defined(SOCK_NONBLOCK)
887 if (host_type & SOCK_NONBLOCK) {
888 target_type |= TARGET_SOCK_NONBLOCK;
889 }
890#endif
891
892 return target_type;
893}
894
992f48a0
BS
895static abi_ulong target_brk;
896static abi_ulong target_original_brk;
4d1de87c 897static abi_ulong brk_page;
31e31b8a 898
992f48a0 899void target_set_brk(abi_ulong new_brk)
31e31b8a 900{
4c1de73d 901 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
4d1de87c 902 brk_page = HOST_PAGE_ALIGN(target_brk);
31e31b8a
FB
903}
904
4d1de87c
CV
905//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
906#define DEBUGF_BRK(message, args...)
907
0da46a6e 908/* do_brk() must return target values and target errnos. */
992f48a0 909abi_long do_brk(abi_ulong new_brk)
31e31b8a 910{
992f48a0 911 abi_long mapped_addr;
ef4330c2 912 abi_ulong new_alloc_size;
31e31b8a 913
3a0c6c4a 914 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
4d1de87c
CV
915
916 if (!new_brk) {
3a0c6c4a 917 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
53a5960a 918 return target_brk;
4d1de87c
CV
919 }
920 if (new_brk < target_original_brk) {
3a0c6c4a
PB
921 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
922 target_brk);
7ab240ad 923 return target_brk;
4d1de87c 924 }
3b46e624 925
4d1de87c
CV
926 /* If the new brk is less than the highest page reserved to the
927 * target heap allocation, set it and we're almost done... */
928 if (new_brk <= brk_page) {
929 /* Heap contents are initialized to zero, as for anonymous
930 * mapped pages. */
931 if (new_brk > target_brk) {
932 memset(g2h(target_brk), 0, new_brk - target_brk);
933 }
31e31b8a 934 target_brk = new_brk;
3a0c6c4a 935 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
72e21db7 936 return target_brk;
31e31b8a
FB
937 }
938
00faf08c
PM
939 /* We need to allocate more memory after the brk... Note that
940 * we don't use MAP_FIXED because that will map over the top of
941 * any existing mapping (like the one with the host libc or qemu
942 * itself); instead we treat "mapped but at wrong address" as
943 * a failure and unmap again.
944 */
4d1de87c 945 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
5fafdf24 946 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
54936004 947 PROT_READ|PROT_WRITE,
00faf08c
PM
948 MAP_ANON|MAP_PRIVATE, 0, 0));
949
950 if (mapped_addr == brk_page) {
70afc343
CV
951 /* Heap contents are initialized to zero, as for anonymous
952 * mapped pages. Technically the new pages are already
953 * initialized to zero since they *are* anonymous mapped
954 * pages, however we have to take care with the contents that
955 * come from the remaining part of the previous page: it may
956 * contains garbage data due to a previous heap usage (grown
957 * then shrunken). */
958 memset(g2h(target_brk), 0, brk_page - target_brk);
959
00faf08c 960 target_brk = new_brk;
4d1de87c 961 brk_page = HOST_PAGE_ALIGN(target_brk);
3a0c6c4a
PB
962 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
963 target_brk);
00faf08c
PM
964 return target_brk;
965 } else if (mapped_addr != -1) {
966 /* Mapped but at wrong address, meaning there wasn't actually
967 * enough space for this brk.
968 */
969 target_munmap(mapped_addr, new_alloc_size);
970 mapped_addr = -1;
3a0c6c4a 971 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
4d1de87c
CV
972 }
973 else {
3a0c6c4a 974 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
00faf08c 975 }
7ab240ad 976
7dd46c02
RH
977#if defined(TARGET_ALPHA)
978 /* We (partially) emulate OSF/1 on Alpha, which requires we
979 return a proper errno, not an unchanged brk value. */
00faf08c 980 return -TARGET_ENOMEM;
7dd46c02 981#endif
00faf08c 982 /* For everything else, return the previous break. */
7ab240ad 983 return target_brk;
31e31b8a
FB
984}
985
859e8a89
AF
986#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) || \
987 defined(TARGET_NR_pselect6)
26edcf41
TS
988static inline abi_long copy_from_user_fdset(fd_set *fds,
989 abi_ulong target_fds_addr,
990 int n)
31e31b8a 991{
26edcf41
TS
992 int i, nw, j, k;
993 abi_ulong b, *target_fds;
994
b1b2db29 995 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
26edcf41
TS
996 if (!(target_fds = lock_user(VERIFY_READ,
997 target_fds_addr,
998 sizeof(abi_ulong) * nw,
999 1)))
1000 return -TARGET_EFAULT;
1001
1002 FD_ZERO(fds);
1003 k = 0;
1004 for (i = 0; i < nw; i++) {
1005 /* grab the abi_ulong */
1006 __get_user(b, &target_fds[i]);
1007 for (j = 0; j < TARGET_ABI_BITS; j++) {
1008 /* check the bit inside the abi_ulong */
1009 if ((b >> j) & 1)
1010 FD_SET(k, fds);
1011 k++;
31e31b8a 1012 }
31e31b8a 1013 }
26edcf41
TS
1014
1015 unlock_user(target_fds, target_fds_addr, 0);
1016
1017 return 0;
31e31b8a
FB
1018}
1019
055e0906
MF
1020static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
1021 abi_ulong target_fds_addr,
1022 int n)
1023{
1024 if (target_fds_addr) {
1025 if (copy_from_user_fdset(fds, target_fds_addr, n))
1026 return -TARGET_EFAULT;
1027 *fds_ptr = fds;
1028 } else {
1029 *fds_ptr = NULL;
1030 }
1031 return 0;
1032}
1033
26edcf41
TS
1034static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
1035 const fd_set *fds,
1036 int n)
31e31b8a 1037{
31e31b8a 1038 int i, nw, j, k;
992f48a0 1039 abi_long v;
26edcf41 1040 abi_ulong *target_fds;
31e31b8a 1041
b1b2db29 1042 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
26edcf41
TS
1043 if (!(target_fds = lock_user(VERIFY_WRITE,
1044 target_fds_addr,
1045 sizeof(abi_ulong) * nw,
1046 0)))
1047 return -TARGET_EFAULT;
1048
1049 k = 0;
1050 for (i = 0; i < nw; i++) {
1051 v = 0;
1052 for (j = 0; j < TARGET_ABI_BITS; j++) {
9ab709be 1053 v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
26edcf41 1054 k++;
31e31b8a 1055 }
26edcf41 1056 __put_user(v, &target_fds[i]);
31e31b8a 1057 }
26edcf41
TS
1058
1059 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
1060
1061 return 0;
31e31b8a 1062}
859e8a89 1063#endif
31e31b8a 1064
c596ed17
FB
1065#if defined(__alpha__)
1066#define HOST_HZ 1024
1067#else
1068#define HOST_HZ 100
1069#endif
1070
992f48a0 1071static inline abi_long host_to_target_clock_t(long ticks)
c596ed17
FB
1072{
1073#if HOST_HZ == TARGET_HZ
1074 return ticks;
1075#else
1076 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
1077#endif
1078}
1079
579a97f7
FB
1080static inline abi_long host_to_target_rusage(abi_ulong target_addr,
1081 const struct rusage *rusage)
b409186b 1082{
53a5960a
PB
1083 struct target_rusage *target_rusage;
1084
579a97f7
FB
1085 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
1086 return -TARGET_EFAULT;
cbb21eed
MB
1087 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
1088 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
1089 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
1090 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
1091 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
1092 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
1093 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
1094 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
1095 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
1096 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
1097 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
1098 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
1099 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
1100 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
1101 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
1102 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
1103 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
1104 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
53a5960a 1105 unlock_user_struct(target_rusage, target_addr, 1);
579a97f7
FB
1106
1107 return 0;
b409186b
FB
1108}
1109
859e8a89 1110#ifdef TARGET_NR_setrlimit
cbb21eed 1111static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
81bbe906 1112{
cbb21eed 1113 abi_ulong target_rlim_swap;
95b33b2f
WT
1114 rlim_t result;
1115
cbb21eed
MB
1116 target_rlim_swap = tswapal(target_rlim);
1117 if (target_rlim_swap == TARGET_RLIM_INFINITY)
1118 return RLIM_INFINITY;
1119
1120 result = target_rlim_swap;
1121 if (target_rlim_swap != (rlim_t)result)
1122 return RLIM_INFINITY;
95b33b2f
WT
1123
1124 return result;
81bbe906 1125}
859e8a89 1126#endif
81bbe906 1127
859e8a89 1128#if defined(TARGET_NR_getrlimit) || defined(TARGET_NR_ugetrlimit)
cbb21eed 1129static inline abi_ulong host_to_target_rlim(rlim_t rlim)
81bbe906 1130{
cbb21eed
MB
1131 abi_ulong target_rlim_swap;
1132 abi_ulong result;
95b33b2f 1133
cbb21eed 1134 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
95b33b2f 1135 target_rlim_swap = TARGET_RLIM_INFINITY;
81bbe906 1136 else
95b33b2f 1137 target_rlim_swap = rlim;
cbb21eed 1138 result = tswapal(target_rlim_swap);
95b33b2f
WT
1139
1140 return result;
81bbe906 1141}
859e8a89 1142#endif
81bbe906 1143
e22b7015
WT
1144static inline int target_to_host_resource(int code)
1145{
1146 switch (code) {
1147 case TARGET_RLIMIT_AS:
1148 return RLIMIT_AS;
1149 case TARGET_RLIMIT_CORE:
1150 return RLIMIT_CORE;
1151 case TARGET_RLIMIT_CPU:
1152 return RLIMIT_CPU;
1153 case TARGET_RLIMIT_DATA:
1154 return RLIMIT_DATA;
1155 case TARGET_RLIMIT_FSIZE:
1156 return RLIMIT_FSIZE;
1157 case TARGET_RLIMIT_LOCKS:
1158 return RLIMIT_LOCKS;
1159 case TARGET_RLIMIT_MEMLOCK:
1160 return RLIMIT_MEMLOCK;
1161 case TARGET_RLIMIT_MSGQUEUE:
1162 return RLIMIT_MSGQUEUE;
1163 case TARGET_RLIMIT_NICE:
1164 return RLIMIT_NICE;
1165 case TARGET_RLIMIT_NOFILE:
1166 return RLIMIT_NOFILE;
1167 case TARGET_RLIMIT_NPROC:
1168 return RLIMIT_NPROC;
1169 case TARGET_RLIMIT_RSS:
1170 return RLIMIT_RSS;
1171 case TARGET_RLIMIT_RTPRIO:
1172 return RLIMIT_RTPRIO;
1173 case TARGET_RLIMIT_SIGPENDING:
1174 return RLIMIT_SIGPENDING;
1175 case TARGET_RLIMIT_STACK:
1176 return RLIMIT_STACK;
1177 default:
1178 return code;
1179 }
1180}
1181
788f5ec4
TS
1182static inline abi_long copy_from_user_timeval(struct timeval *tv,
1183 abi_ulong target_tv_addr)
31e31b8a 1184{
53a5960a
PB
1185 struct target_timeval *target_tv;
1186
6d5d5dde 1187 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1)) {
579a97f7 1188 return -TARGET_EFAULT;
6d5d5dde 1189 }
788f5ec4
TS
1190
1191 __get_user(tv->tv_sec, &target_tv->tv_sec);
1192 __get_user(tv->tv_usec, &target_tv->tv_usec);
1193
1194 unlock_user_struct(target_tv, target_tv_addr, 0);
579a97f7
FB
1195
1196 return 0;
31e31b8a
FB
1197}
1198
788f5ec4
TS
1199static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1200 const struct timeval *tv)
31e31b8a 1201{
53a5960a
PB
1202 struct target_timeval *target_tv;
1203
6d5d5dde
DB
1204 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
1205 return -TARGET_EFAULT;
1206 }
1207
1208 __put_user(tv->tv_sec, &target_tv->tv_sec);
1209 __put_user(tv->tv_usec, &target_tv->tv_usec);
1210
1211 unlock_user_struct(target_tv, target_tv_addr, 1);
1212
1213 return 0;
1214}
1215
1216static inline abi_long copy_to_user_timeval64(abi_ulong target_tv_addr,
1217 const struct timeval *tv)
1218{
1219 struct target__kernel_sock_timeval *target_tv;
1220
1221 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
579a97f7 1222 return -TARGET_EFAULT;
6d5d5dde 1223 }
788f5ec4
TS
1224
1225 __put_user(tv->tv_sec, &target_tv->tv_sec);
1226 __put_user(tv->tv_usec, &target_tv->tv_usec);
1227
1228 unlock_user_struct(target_tv, target_tv_addr, 1);
579a97f7
FB
1229
1230 return 0;
31e31b8a
FB
1231}
1232
859e8a89
AF
1233#if defined(TARGET_NR_futex) || \
1234 defined(TARGET_NR_rt_sigtimedwait) || \
1235 defined(TARGET_NR_pselect6) || defined(TARGET_NR_pselect6) || \
1236 defined(TARGET_NR_nanosleep) || defined(TARGET_NR_clock_settime) || \
1237 defined(TARGET_NR_utimensat) || defined(TARGET_NR_mq_timedsend) || \
d8c08b1e
MK
1238 defined(TARGET_NR_mq_timedreceive) || defined(TARGET_NR_ipc) || \
1239 defined(TARGET_NR_semop) || defined(TARGET_NR_semtimedop)
6d5d5dde
DB
1240static inline abi_long target_to_host_timespec(struct timespec *host_ts,
1241 abi_ulong target_addr)
1242{
1243 struct target_timespec *target_ts;
1244
1245 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
1246 return -TARGET_EFAULT;
1247 }
1248 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
1249 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1250 unlock_user_struct(target_ts, target_addr, 0);
1251 return 0;
1252}
859e8a89 1253#endif
6d5d5dde 1254
14690296 1255#if defined(TARGET_NR_clock_settime64) || defined(TARGET_NR_futex_time64)
c6c8d102
AF
1256static inline abi_long target_to_host_timespec64(struct timespec *host_ts,
1257 abi_ulong target_addr)
1258{
1259 struct target__kernel_timespec *target_ts;
1260
1261 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1)) {
1262 return -TARGET_EFAULT;
1263 }
1264 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
1265 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1266 unlock_user_struct(target_ts, target_addr, 0);
1267 return 0;
1268}
1269#endif
1270
6d5d5dde
DB
1271static inline abi_long host_to_target_timespec(abi_ulong target_addr,
1272 struct timespec *host_ts)
1273{
1274 struct target_timespec *target_ts;
1275
1276 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) {
1277 return -TARGET_EFAULT;
1278 }
1279 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
1280 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1281 unlock_user_struct(target_ts, target_addr, 1);
1282 return 0;
1283}
1284
1285static inline abi_long host_to_target_timespec64(abi_ulong target_addr,
1286 struct timespec *host_ts)
1287{
1288 struct target__kernel_timespec *target_ts;
1289
1290 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0)) {
1291 return -TARGET_EFAULT;
1292 }
1293 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
1294 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
1295 unlock_user_struct(target_ts, target_addr, 1);
1296 return 0;
1297}
1298
a52f5f87
RH
1299#if defined(TARGET_NR_gettimeofday)
1300static inline abi_long copy_to_user_timezone(abi_ulong target_tz_addr,
1301 struct timezone *tz)
1302{
1303 struct target_timezone *target_tz;
1304
1305 if (!lock_user_struct(VERIFY_WRITE, target_tz, target_tz_addr, 1)) {
1306 return -TARGET_EFAULT;
1307 }
1308
1309 __put_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1310 __put_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1311
1312 unlock_user_struct(target_tz, target_tz_addr, 1);
1313
1314 return 0;
1315}
1316#endif
1317
859e8a89 1318#if defined(TARGET_NR_settimeofday)
ef4467e9
PB
1319static inline abi_long copy_from_user_timezone(struct timezone *tz,
1320 abi_ulong target_tz_addr)
1321{
1322 struct target_timezone *target_tz;
1323
1324 if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
1325 return -TARGET_EFAULT;
1326 }
1327
1328 __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1329 __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1330
1331 unlock_user_struct(target_tz, target_tz_addr, 0);
1332
1333 return 0;
1334}
859e8a89 1335#endif
ef4467e9 1336
8ec9cf89
NF
1337#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1338#include <mqueue.h>
1339
24e1003a
AJ
1340static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1341 abi_ulong target_mq_attr_addr)
1342{
1343 struct target_mq_attr *target_mq_attr;
1344
1345 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1346 target_mq_attr_addr, 1))
1347 return -TARGET_EFAULT;
1348
1349 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1350 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1351 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1352 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1353
1354 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1355
1356 return 0;
1357}
1358
1359static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1360 const struct mq_attr *attr)
1361{
1362 struct target_mq_attr *target_mq_attr;
1363
1364 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1365 target_mq_attr_addr, 0))
1366 return -TARGET_EFAULT;
1367
1368 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1369 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1370 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1371 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1372
1373 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1374
1375 return 0;
1376}
8ec9cf89 1377#endif
31e31b8a 1378
055e0906 1379#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
0da46a6e 1380/* do_select() must return target values and target errnos. */
992f48a0 1381static abi_long do_select(int n,
26edcf41
TS
1382 abi_ulong rfd_addr, abi_ulong wfd_addr,
1383 abi_ulong efd_addr, abi_ulong target_tv_addr)
31e31b8a
FB
1384{
1385 fd_set rfds, wfds, efds;
1386 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6df9d38d
PM
1387 struct timeval tv;
1388 struct timespec ts, *ts_ptr;
992f48a0 1389 abi_long ret;
31e31b8a 1390
055e0906
MF
1391 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1392 if (ret) {
1393 return ret;
53a5960a 1394 }
055e0906
MF
1395 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1396 if (ret) {
1397 return ret;
53a5960a 1398 }
055e0906
MF
1399 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1400 if (ret) {
1401 return ret;
53a5960a 1402 }
3b46e624 1403
26edcf41 1404 if (target_tv_addr) {
788f5ec4
TS
1405 if (copy_from_user_timeval(&tv, target_tv_addr))
1406 return -TARGET_EFAULT;
6df9d38d
PM
1407 ts.tv_sec = tv.tv_sec;
1408 ts.tv_nsec = tv.tv_usec * 1000;
1409 ts_ptr = &ts;
31e31b8a 1410 } else {
6df9d38d 1411 ts_ptr = NULL;
31e31b8a 1412 }
26edcf41 1413
6df9d38d
PM
1414 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
1415 ts_ptr, NULL));
53a5960a 1416
26edcf41
TS
1417 if (!is_error(ret)) {
1418 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1419 return -TARGET_EFAULT;
1420 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1421 return -TARGET_EFAULT;
1422 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1423 return -TARGET_EFAULT;
31e31b8a 1424
6df9d38d
PM
1425 if (target_tv_addr) {
1426 tv.tv_sec = ts.tv_sec;
1427 tv.tv_usec = ts.tv_nsec / 1000;
1428 if (copy_to_user_timeval(target_tv_addr, &tv)) {
1429 return -TARGET_EFAULT;
1430 }
1431 }
31e31b8a 1432 }
579a97f7 1433
31e31b8a
FB
1434 return ret;
1435}
5457dc9e
LV
1436
1437#if defined(TARGET_WANT_OLD_SYS_SELECT)
1438static abi_long do_old_select(abi_ulong arg1)
1439{
1440 struct target_sel_arg_struct *sel;
1441 abi_ulong inp, outp, exp, tvp;
1442 long nsel;
1443
1444 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) {
1445 return -TARGET_EFAULT;
1446 }
1447
1448 nsel = tswapal(sel->n);
1449 inp = tswapal(sel->inp);
1450 outp = tswapal(sel->outp);
1451 exp = tswapal(sel->exp);
1452 tvp = tswapal(sel->tvp);
1453
1454 unlock_user_struct(sel, arg1, 0);
1455
1456 return do_select(nsel, inp, outp, exp, tvp);
1457}
1458#endif
055e0906 1459#endif
31e31b8a 1460
099d6b0f
RV
1461static abi_long do_pipe2(int host_pipe[], int flags)
1462{
1463#ifdef CONFIG_PIPE2
1464 return pipe2(host_pipe, flags);
1465#else
1466 return -ENOSYS;
1467#endif
1468}
1469
fb41a66e
RH
1470static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1471 int flags, int is_pipe2)
099d6b0f
RV
1472{
1473 int host_pipe[2];
1474 abi_long ret;
1475 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1476
1477 if (is_error(ret))
1478 return get_errno(ret);
fb41a66e
RH
1479
1480 /* Several targets have special calling conventions for the original
1481 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1482 if (!is_pipe2) {
1483#if defined(TARGET_ALPHA)
1484 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1485 return host_pipe[0];
1486#elif defined(TARGET_MIPS)
1487 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1488 return host_pipe[0];
1489#elif defined(TARGET_SH4)
597c0212 1490 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
fb41a66e 1491 return host_pipe[0];
82f05b69
PM
1492#elif defined(TARGET_SPARC)
1493 ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1494 return host_pipe[0];
597c0212 1495#endif
fb41a66e
RH
1496 }
1497
099d6b0f
RV
1498 if (put_user_s32(host_pipe[0], pipedes)
1499 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1500 return -TARGET_EFAULT;
099d6b0f
RV
1501 return get_errno(ret);
1502}
1503
b975b83b
LL
1504static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1505 abi_ulong target_addr,
1506 socklen_t len)
1507{
1508 struct target_ip_mreqn *target_smreqn;
1509
1510 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1511 if (!target_smreqn)
1512 return -TARGET_EFAULT;
1513 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1514 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1515 if (len == sizeof(struct target_ip_mreqn))
cbb21eed 1516 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
b975b83b
LL
1517 unlock_user(target_smreqn, target_addr, 0);
1518
1519 return 0;
1520}
1521
7b36f782 1522static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
579a97f7
FB
1523 abi_ulong target_addr,
1524 socklen_t len)
7854b056 1525{
607175e0
AJ
1526 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1527 sa_family_t sa_family;
53a5960a
PB
1528 struct target_sockaddr *target_saddr;
1529
7b36f782
LV
1530 if (fd_trans_target_to_host_addr(fd)) {
1531 return fd_trans_target_to_host_addr(fd)(addr, target_addr, len);
1532 }
1533
579a97f7
FB
1534 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1535 if (!target_saddr)
1536 return -TARGET_EFAULT;
607175e0
AJ
1537
1538 sa_family = tswap16(target_saddr->sa_family);
1539
1540 /* Oops. The caller might send a incomplete sun_path; sun_path
1541 * must be terminated by \0 (see the manual page), but
1542 * unfortunately it is quite common to specify sockaddr_un
1543 * length as "strlen(x->sun_path)" while it should be
1544 * "strlen(...) + 1". We'll fix that here if needed.
1545 * Linux kernel has a similar feature.
1546 */
1547
1548 if (sa_family == AF_UNIX) {
1549 if (len < unix_maxlen && len > 0) {
1550 char *cp = (char*)target_saddr;
1551
1552 if ( cp[len-1] && !cp[len] )
1553 len++;
1554 }
1555 if (len > unix_maxlen)
1556 len = unix_maxlen;
1557 }
1558
53a5960a 1559 memcpy(addr, target_saddr, len);
607175e0 1560 addr->sa_family = sa_family;
6c5b5645
LV
1561 if (sa_family == AF_NETLINK) {
1562 struct sockaddr_nl *nladdr;
1563
1564 nladdr = (struct sockaddr_nl *)addr;
1565 nladdr->nl_pid = tswap32(nladdr->nl_pid);
1566 nladdr->nl_groups = tswap32(nladdr->nl_groups);
1567 } else if (sa_family == AF_PACKET) {
33a29b51
JT
1568 struct target_sockaddr_ll *lladdr;
1569
1570 lladdr = (struct target_sockaddr_ll *)addr;
1571 lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
1572 lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
1573 }
53a5960a 1574 unlock_user(target_saddr, target_addr, 0);
579a97f7
FB
1575
1576 return 0;
7854b056
FB
1577}
1578
579a97f7
FB
1579static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1580 struct sockaddr *addr,
1581 socklen_t len)
7854b056 1582{
53a5960a
PB
1583 struct target_sockaddr *target_saddr;
1584
a1e22192
PM
1585 if (len == 0) {
1586 return 0;
1587 }
6860710c 1588 assert(addr);
a1e22192 1589
579a97f7
FB
1590 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1591 if (!target_saddr)
1592 return -TARGET_EFAULT;
53a5960a 1593 memcpy(target_saddr, addr, len);
a1e22192
PM
1594 if (len >= offsetof(struct target_sockaddr, sa_family) +
1595 sizeof(target_saddr->sa_family)) {
1596 target_saddr->sa_family = tswap16(addr->sa_family);
1597 }
a47401bc
PMD
1598 if (addr->sa_family == AF_NETLINK &&
1599 len >= sizeof(struct target_sockaddr_nl)) {
1600 struct target_sockaddr_nl *target_nl =
1601 (struct target_sockaddr_nl *)target_saddr;
6c5b5645
LV
1602 target_nl->nl_pid = tswap32(target_nl->nl_pid);
1603 target_nl->nl_groups = tswap32(target_nl->nl_groups);
a82ea939
LV
1604 } else if (addr->sa_family == AF_PACKET) {
1605 struct sockaddr_ll *target_ll = (struct sockaddr_ll *)target_saddr;
1606 target_ll->sll_ifindex = tswap32(target_ll->sll_ifindex);
1607 target_ll->sll_hatype = tswap16(target_ll->sll_hatype);
ee1ac3a1
HD
1608 } else if (addr->sa_family == AF_INET6 &&
1609 len >= sizeof(struct target_sockaddr_in6)) {
1610 struct target_sockaddr_in6 *target_in6 =
1611 (struct target_sockaddr_in6 *)target_saddr;
1612 target_in6->sin6_scope_id = tswap16(target_in6->sin6_scope_id);
6c5b5645 1613 }
53a5960a 1614 unlock_user(target_saddr, target_addr, len);
579a97f7
FB
1615
1616 return 0;
7854b056
FB
1617}
1618
5a4a898d
FB
1619static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1620 struct target_msghdr *target_msgh)
7854b056
FB
1621{
1622 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
5a4a898d
FB
1623 abi_long msg_controllen;
1624 abi_ulong target_cmsg_addr;
ee104587 1625 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
7854b056 1626 socklen_t space = 0;
5a4a898d 1627
cbb21eed 1628 msg_controllen = tswapal(target_msgh->msg_controllen);
5a4a898d
FB
1629 if (msg_controllen < sizeof (struct target_cmsghdr))
1630 goto the_end;
cbb21eed 1631 target_cmsg_addr = tswapal(target_msgh->msg_control);
5a4a898d 1632 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
ee104587 1633 target_cmsg_start = target_cmsg;
5a4a898d
FB
1634 if (!target_cmsg)
1635 return -TARGET_EFAULT;
7854b056
FB
1636
1637 while (cmsg && target_cmsg) {
1638 void *data = CMSG_DATA(cmsg);
1639 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1640
cbb21eed 1641 int len = tswapal(target_cmsg->cmsg_len)
ad762b99 1642 - sizeof(struct target_cmsghdr);
7854b056
FB
1643
1644 space += CMSG_SPACE(len);
1645 if (space > msgh->msg_controllen) {
1646 space -= CMSG_SPACE(len);
c2aeb258
PM
1647 /* This is a QEMU bug, since we allocated the payload
1648 * area ourselves (unlike overflow in host-to-target
1649 * conversion, which is just the guest giving us a buffer
1650 * that's too small). It can't happen for the payload types
1651 * we currently support; if it becomes an issue in future
1652 * we would need to improve our allocation strategy to
1653 * something more intelligent than "twice the size of the
1654 * target buffer we're reading from".
1655 */
39be5350
JK
1656 qemu_log_mask(LOG_UNIMP,
1657 ("Unsupported ancillary data %d/%d: "
1658 "unhandled msg size\n"),
1659 tswap32(target_cmsg->cmsg_level),
1660 tswap32(target_cmsg->cmsg_type));
7854b056
FB
1661 break;
1662 }
1663
dbf4f796
PJ
1664 if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1665 cmsg->cmsg_level = SOL_SOCKET;
1666 } else {
1667 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1668 }
7854b056
FB
1669 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1670 cmsg->cmsg_len = CMSG_LEN(len);
1671
30b8b68e 1672 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
7854b056
FB
1673 int *fd = (int *)data;
1674 int *target_fd = (int *)target_data;
1675 int i, numfds = len / sizeof(int);
1676
876e23cb
PM
1677 for (i = 0; i < numfds; i++) {
1678 __get_user(fd[i], target_fd + i);
1679 }
30b8b68e
AS
1680 } else if (cmsg->cmsg_level == SOL_SOCKET
1681 && cmsg->cmsg_type == SCM_CREDENTIALS) {
1682 struct ucred *cred = (struct ucred *)data;
1683 struct target_ucred *target_cred =
1684 (struct target_ucred *)target_data;
1685
876e23cb
PM
1686 __get_user(cred->pid, &target_cred->pid);
1687 __get_user(cred->uid, &target_cred->uid);
1688 __get_user(cred->gid, &target_cred->gid);
30b8b68e 1689 } else {
39be5350
JK
1690 qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
1691 cmsg->cmsg_level, cmsg->cmsg_type);
30b8b68e 1692 memcpy(data, target_data, len);
7854b056
FB
1693 }
1694
1695 cmsg = CMSG_NXTHDR(msgh, cmsg);
ee104587
JN
1696 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1697 target_cmsg_start);
7854b056 1698 }
5a4a898d
FB
1699 unlock_user(target_cmsg, target_cmsg_addr, 0);
1700 the_end:
7854b056 1701 msgh->msg_controllen = space;
5a4a898d 1702 return 0;
7854b056
FB
1703}
1704
5a4a898d
FB
1705static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1706 struct msghdr *msgh)
7854b056
FB
1707{
1708 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
5a4a898d
FB
1709 abi_long msg_controllen;
1710 abi_ulong target_cmsg_addr;
ee104587 1711 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
7854b056
FB
1712 socklen_t space = 0;
1713
cbb21eed 1714 msg_controllen = tswapal(target_msgh->msg_controllen);
5a4a898d
FB
1715 if (msg_controllen < sizeof (struct target_cmsghdr))
1716 goto the_end;
cbb21eed 1717 target_cmsg_addr = tswapal(target_msgh->msg_control);
5a4a898d 1718 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
ee104587 1719 target_cmsg_start = target_cmsg;
5a4a898d
FB
1720 if (!target_cmsg)
1721 return -TARGET_EFAULT;
1722
7854b056
FB
1723 while (cmsg && target_cmsg) {
1724 void *data = CMSG_DATA(cmsg);
1725 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1726
ad762b99 1727 int len = cmsg->cmsg_len - sizeof(struct cmsghdr);
c2aeb258 1728 int tgt_len, tgt_space;
7854b056 1729
c2aeb258
PM
1730 /* We never copy a half-header but may copy half-data;
1731 * this is Linux's behaviour in put_cmsg(). Note that
1732 * truncation here is a guest problem (which we report
1733 * to the guest via the CTRUNC bit), unlike truncation
1734 * in target_to_host_cmsg, which is a QEMU bug.
1735 */
7174970a 1736 if (msg_controllen < sizeof(struct target_cmsghdr)) {
c2aeb258 1737 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
7854b056
FB
1738 break;
1739 }
1740
dbf4f796
PJ
1741 if (cmsg->cmsg_level == SOL_SOCKET) {
1742 target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1743 } else {
1744 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1745 }
7854b056 1746 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
7854b056 1747
c2aeb258
PM
1748 /* Payload types which need a different size of payload on
1749 * the target must adjust tgt_len here.
1750 */
309786cf 1751 tgt_len = len;
c2aeb258
PM
1752 switch (cmsg->cmsg_level) {
1753 case SOL_SOCKET:
1754 switch (cmsg->cmsg_type) {
1755 case SO_TIMESTAMP:
1756 tgt_len = sizeof(struct target_timeval);
1757 break;
1758 default:
1759 break;
1760 }
309786cf 1761 break;
c2aeb258
PM
1762 default:
1763 break;
1764 }
1765
7174970a 1766 if (msg_controllen < TARGET_CMSG_LEN(tgt_len)) {
c2aeb258 1767 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
7174970a 1768 tgt_len = msg_controllen - sizeof(struct target_cmsghdr);
c2aeb258
PM
1769 }
1770
1771 /* We must now copy-and-convert len bytes of payload
1772 * into tgt_len bytes of destination space. Bear in mind
1773 * that in both source and destination we may be dealing
1774 * with a truncated value!
1775 */
52b65494
HD
1776 switch (cmsg->cmsg_level) {
1777 case SOL_SOCKET:
1778 switch (cmsg->cmsg_type) {
1779 case SCM_RIGHTS:
1780 {
1781 int *fd = (int *)data;
1782 int *target_fd = (int *)target_data;
c2aeb258 1783 int i, numfds = tgt_len / sizeof(int);
52b65494 1784
876e23cb
PM
1785 for (i = 0; i < numfds; i++) {
1786 __put_user(fd[i], target_fd + i);
1787 }
52b65494
HD
1788 break;
1789 }
1790 case SO_TIMESTAMP:
1791 {
1792 struct timeval *tv = (struct timeval *)data;
1793 struct target_timeval *target_tv =
1794 (struct target_timeval *)target_data;
1795
c2aeb258
PM
1796 if (len != sizeof(struct timeval) ||
1797 tgt_len != sizeof(struct target_timeval)) {
52b65494 1798 goto unimplemented;
c2aeb258 1799 }
52b65494
HD
1800
1801 /* copy struct timeval to target */
876e23cb
PM
1802 __put_user(tv->tv_sec, &target_tv->tv_sec);
1803 __put_user(tv->tv_usec, &target_tv->tv_usec);
52b65494
HD
1804 break;
1805 }
4bc29756
HD
1806 case SCM_CREDENTIALS:
1807 {
1808 struct ucred *cred = (struct ucred *)data;
1809 struct target_ucred *target_cred =
1810 (struct target_ucred *)target_data;
1811
1812 __put_user(cred->pid, &target_cred->pid);
1813 __put_user(cred->uid, &target_cred->uid);
1814 __put_user(cred->gid, &target_cred->gid);
1815 break;
1816 }
52b65494
HD
1817 default:
1818 goto unimplemented;
1819 }
1820 break;
7854b056 1821
ee1ac3a1
HD
1822 case SOL_IP:
1823 switch (cmsg->cmsg_type) {
1824 case IP_TTL:
1825 {
1826 uint32_t *v = (uint32_t *)data;
1827 uint32_t *t_int = (uint32_t *)target_data;
1828
7174970a
PM
1829 if (len != sizeof(uint32_t) ||
1830 tgt_len != sizeof(uint32_t)) {
1831 goto unimplemented;
1832 }
ee1ac3a1
HD
1833 __put_user(*v, t_int);
1834 break;
1835 }
1836 case IP_RECVERR:
1837 {
1838 struct errhdr_t {
1839 struct sock_extended_err ee;
1840 struct sockaddr_in offender;
1841 };
1842 struct errhdr_t *errh = (struct errhdr_t *)data;
1843 struct errhdr_t *target_errh =
1844 (struct errhdr_t *)target_data;
1845
7174970a
PM
1846 if (len != sizeof(struct errhdr_t) ||
1847 tgt_len != sizeof(struct errhdr_t)) {
1848 goto unimplemented;
1849 }
ee1ac3a1
HD
1850 __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
1851 __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
1852 __put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
1853 __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
1854 __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);
1855 __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);
1856 __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);
1857 host_to_target_sockaddr((unsigned long) &target_errh->offender,
1858 (void *) &errh->offender, sizeof(errh->offender));
1859 break;
1860 }
1861 default:
1862 goto unimplemented;
1863 }
1864 break;
1865
1866 case SOL_IPV6:
1867 switch (cmsg->cmsg_type) {
1868 case IPV6_HOPLIMIT:
1869 {
1870 uint32_t *v = (uint32_t *)data;
1871 uint32_t *t_int = (uint32_t *)target_data;
1872
7174970a
PM
1873 if (len != sizeof(uint32_t) ||
1874 tgt_len != sizeof(uint32_t)) {
1875 goto unimplemented;
1876 }
ee1ac3a1
HD
1877 __put_user(*v, t_int);
1878 break;
1879 }
1880 case IPV6_RECVERR:
1881 {
1882 struct errhdr6_t {
1883 struct sock_extended_err ee;
1884 struct sockaddr_in6 offender;
1885 };
1886 struct errhdr6_t *errh = (struct errhdr6_t *)data;
1887 struct errhdr6_t *target_errh =
1888 (struct errhdr6_t *)target_data;
1889
7174970a
PM
1890 if (len != sizeof(struct errhdr6_t) ||
1891 tgt_len != sizeof(struct errhdr6_t)) {
1892 goto unimplemented;
1893 }
ee1ac3a1
HD
1894 __put_user(errh->ee.ee_errno, &target_errh->ee.ee_errno);
1895 __put_user(errh->ee.ee_origin, &target_errh->ee.ee_origin);
1896 __put_user(errh->ee.ee_type, &target_errh->ee.ee_type);
1897 __put_user(errh->ee.ee_code, &target_errh->ee.ee_code);
1898 __put_user(errh->ee.ee_pad, &target_errh->ee.ee_pad);
1899 __put_user(errh->ee.ee_info, &target_errh->ee.ee_info);
1900 __put_user(errh->ee.ee_data, &target_errh->ee.ee_data);
1901 host_to_target_sockaddr((unsigned long) &target_errh->offender,
1902 (void *) &errh->offender, sizeof(errh->offender));
1903 break;
1904 }
1905 default:
1906 goto unimplemented;
1907 }
1908 break;
1909
52b65494
HD
1910 default:
1911 unimplemented:
39be5350
JK
1912 qemu_log_mask(LOG_UNIMP, "Unsupported ancillary data: %d/%d\n",
1913 cmsg->cmsg_level, cmsg->cmsg_type);
c2aeb258
PM
1914 memcpy(target_data, data, MIN(len, tgt_len));
1915 if (tgt_len > len) {
1916 memset(target_data + len, 0, tgt_len - len);
1917 }
7854b056
FB
1918 }
1919
7174970a
PM
1920 target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(tgt_len));
1921 tgt_space = TARGET_CMSG_SPACE(tgt_len);
c2aeb258
PM
1922 if (msg_controllen < tgt_space) {
1923 tgt_space = msg_controllen;
1924 }
1925 msg_controllen -= tgt_space;
1926 space += tgt_space;
7854b056 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, space);
1932 the_end:
cbb21eed 1933 target_msgh->msg_controllen = tswapal(space);
5a4a898d 1934 return 0;
7854b056
FB
1935}
1936
0da46a6e 1937/* do_setsockopt() Must return target values and target errnos. */
992f48a0 1938static abi_long do_setsockopt(int sockfd, int level, int optname,
2f619698 1939 abi_ulong optval_addr, socklen_t optlen)
7854b056 1940{
992f48a0 1941 abi_long ret;
32407103 1942 int val;
b975b83b 1943 struct ip_mreqn *ip_mreq;
6e3cb58f 1944 struct ip_mreq_source *ip_mreq_source;
3b46e624 1945
8853f86e
FB
1946 switch(level) {
1947 case SOL_TCP:
7854b056 1948 /* TCP options all take an 'int' value. */
7854b056 1949 if (optlen < sizeof(uint32_t))
0da46a6e 1950 return -TARGET_EINVAL;
3b46e624 1951
2f619698
FB
1952 if (get_user_u32(val, optval_addr))
1953 return -TARGET_EFAULT;
8853f86e
FB
1954 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1955 break;
1956 case SOL_IP:
1957 switch(optname) {
2efbe911
FB
1958 case IP_TOS:
1959 case IP_TTL:
8853f86e 1960 case IP_HDRINCL:
2efbe911
FB
1961 case IP_ROUTER_ALERT:
1962 case IP_RECVOPTS:
1963 case IP_RETOPTS:
1964 case IP_PKTINFO:
1965 case IP_MTU_DISCOVER:
1966 case IP_RECVERR:
ee1ac3a1 1967 case IP_RECVTTL:
2efbe911
FB
1968 case IP_RECVTOS:
1969#ifdef IP_FREEBIND
1970 case IP_FREEBIND:
1971#endif
1972 case IP_MULTICAST_TTL:
1973 case IP_MULTICAST_LOOP:
8853f86e
FB
1974 val = 0;
1975 if (optlen >= sizeof(uint32_t)) {
2f619698
FB
1976 if (get_user_u32(val, optval_addr))
1977 return -TARGET_EFAULT;
8853f86e 1978 } else if (optlen >= 1) {
2f619698
FB
1979 if (get_user_u8(val, optval_addr))
1980 return -TARGET_EFAULT;
8853f86e
FB
1981 }
1982 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1983 break;
b975b83b
LL
1984 case IP_ADD_MEMBERSHIP:
1985 case IP_DROP_MEMBERSHIP:
1986 if (optlen < sizeof (struct target_ip_mreq) ||
1987 optlen > sizeof (struct target_ip_mreqn))
1988 return -TARGET_EINVAL;
1989
1990 ip_mreq = (struct ip_mreqn *) alloca(optlen);
1991 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1992 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1993 break;
1994
6e3cb58f
LL
1995 case IP_BLOCK_SOURCE:
1996 case IP_UNBLOCK_SOURCE:
1997 case IP_ADD_SOURCE_MEMBERSHIP:
1998 case IP_DROP_SOURCE_MEMBERSHIP:
1999 if (optlen != sizeof (struct target_ip_mreq_source))
2000 return -TARGET_EINVAL;
2001
2002 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2003 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
2004 unlock_user (ip_mreq_source, optval_addr, 0);
2005 break;
2006
920394db
JH
2007 default:
2008 goto unimplemented;
2009 }
2010 break;
0d78b3b5
LV
2011 case SOL_IPV6:
2012 switch (optname) {
2013 case IPV6_MTU_DISCOVER:
2014 case IPV6_MTU:
2015 case IPV6_V6ONLY:
2016 case IPV6_RECVPKTINFO:
ee1ac3a1 2017 case IPV6_UNICAST_HOPS:
21749c4c
LV
2018 case IPV6_MULTICAST_HOPS:
2019 case IPV6_MULTICAST_LOOP:
ee1ac3a1
HD
2020 case IPV6_RECVERR:
2021 case IPV6_RECVHOPLIMIT:
2022 case IPV6_2292HOPLIMIT:
2023 case IPV6_CHECKSUM:
b9cce6d7
HD
2024 case IPV6_ADDRFORM:
2025 case IPV6_2292PKTINFO:
2026 case IPV6_RECVTCLASS:
2027 case IPV6_RECVRTHDR:
2028 case IPV6_2292RTHDR:
2029 case IPV6_RECVHOPOPTS:
2030 case IPV6_2292HOPOPTS:
2031 case IPV6_RECVDSTOPTS:
2032 case IPV6_2292DSTOPTS:
2033 case IPV6_TCLASS:
2034#ifdef IPV6_RECVPATHMTU
2035 case IPV6_RECVPATHMTU:
2036#endif
2037#ifdef IPV6_TRANSPARENT
2038 case IPV6_TRANSPARENT:
2039#endif
2040#ifdef IPV6_FREEBIND
2041 case IPV6_FREEBIND:
2042#endif
2043#ifdef IPV6_RECVORIGDSTADDR
2044 case IPV6_RECVORIGDSTADDR:
2045#endif
0d78b3b5
LV
2046 val = 0;
2047 if (optlen < sizeof(uint32_t)) {
2048 return -TARGET_EINVAL;
2049 }
2050 if (get_user_u32(val, optval_addr)) {
2051 return -TARGET_EFAULT;
2052 }
2053 ret = get_errno(setsockopt(sockfd, level, optname,
2054 &val, sizeof(val)));
2055 break;
ee1ac3a1
HD
2056 case IPV6_PKTINFO:
2057 {
2058 struct in6_pktinfo pki;
2059
2060 if (optlen < sizeof(pki)) {
2061 return -TARGET_EINVAL;
2062 }
2063
2064 if (copy_from_user(&pki, optval_addr, sizeof(pki))) {
2065 return -TARGET_EFAULT;
2066 }
2067
2068 pki.ipi6_ifindex = tswap32(pki.ipi6_ifindex);
2069
2070 ret = get_errno(setsockopt(sockfd, level, optname,
2071 &pki, sizeof(pki)));
2072 break;
2073 }
22bf4ee9
NC
2074 case IPV6_ADD_MEMBERSHIP:
2075 case IPV6_DROP_MEMBERSHIP:
2076 {
2077 struct ipv6_mreq ipv6mreq;
2078
2079 if (optlen < sizeof(ipv6mreq)) {
2080 return -TARGET_EINVAL;
2081 }
2082
2083 if (copy_from_user(&ipv6mreq, optval_addr, sizeof(ipv6mreq))) {
2084 return -TARGET_EFAULT;
2085 }
2086
2087 ipv6mreq.ipv6mr_interface = tswap32(ipv6mreq.ipv6mr_interface);
2088
2089 ret = get_errno(setsockopt(sockfd, level, optname,
2090 &ipv6mreq, sizeof(ipv6mreq)));
2091 break;
2092 }
ee1ac3a1
HD
2093 default:
2094 goto unimplemented;
2095 }
2096 break;
2097 case SOL_ICMPV6:
2098 switch (optname) {
2099 case ICMPV6_FILTER:
2100 {
2101 struct icmp6_filter icmp6f;
2102
2103 if (optlen > sizeof(icmp6f)) {
2104 optlen = sizeof(icmp6f);
2105 }
2106
2107 if (copy_from_user(&icmp6f, optval_addr, optlen)) {
2108 return -TARGET_EFAULT;
2109 }
2110
2111 for (val = 0; val < 8; val++) {
2112 icmp6f.data[val] = tswap32(icmp6f.data[val]);
2113 }
2114
2115 ret = get_errno(setsockopt(sockfd, level, optname,
2116 &icmp6f, optlen));
2117 break;
2118 }
0d78b3b5
LV
2119 default:
2120 goto unimplemented;
2121 }
2122 break;
920394db
JH
2123 case SOL_RAW:
2124 switch (optname) {
2125 case ICMP_FILTER:
ee1ac3a1
HD
2126 case IPV6_CHECKSUM:
2127 /* those take an u32 value */
920394db
JH
2128 if (optlen < sizeof(uint32_t)) {
2129 return -TARGET_EINVAL;
2130 }
2131
2132 if (get_user_u32(val, optval_addr)) {
2133 return -TARGET_EFAULT;
2134 }
2135 ret = get_errno(setsockopt(sockfd, level, optname,
2136 &val, sizeof(val)));
2137 break;
2138
8853f86e
FB
2139 default:
2140 goto unimplemented;
2141 }
2142 break;
f31dddd2
YS
2143#if defined(SOL_ALG) && defined(ALG_SET_KEY) && defined(ALG_SET_AEAD_AUTHSIZE)
2144 case SOL_ALG:
2145 switch (optname) {
2146 case ALG_SET_KEY:
2147 {
2148 char *alg_key = g_malloc(optlen);
2149
2150 if (!alg_key) {
2151 return -TARGET_ENOMEM;
2152 }
2153 if (copy_from_user(alg_key, optval_addr, optlen)) {
2154 g_free(alg_key);
2155 return -TARGET_EFAULT;
2156 }
2157 ret = get_errno(setsockopt(sockfd, level, optname,
2158 alg_key, optlen));
2159 g_free(alg_key);
2160 break;
2161 }
2162 case ALG_SET_AEAD_AUTHSIZE:
2163 {
2164 ret = get_errno(setsockopt(sockfd, level, optname,
2165 NULL, optlen));
2166 break;
2167 }
2168 default:
2169 goto unimplemented;
2170 }
2171 break;
2172#endif
3532fa74 2173 case TARGET_SOL_SOCKET:
8853f86e 2174 switch (optname) {
1b09aeb9
LV
2175 case TARGET_SO_RCVTIMEO:
2176 {
2177 struct timeval tv;
2178
2179 optname = SO_RCVTIMEO;
2180
2181set_timeout:
2182 if (optlen != sizeof(struct target_timeval)) {
2183 return -TARGET_EINVAL;
2184 }
2185
2186 if (copy_from_user_timeval(&tv, optval_addr)) {
2187 return -TARGET_EFAULT;
2188 }
2189
2190 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2191 &tv, sizeof(tv)));
2192 return ret;
2193 }
2194 case TARGET_SO_SNDTIMEO:
2195 optname = SO_SNDTIMEO;
2196 goto set_timeout;
f57d4192
LV
2197 case TARGET_SO_ATTACH_FILTER:
2198 {
2199 struct target_sock_fprog *tfprog;
2200 struct target_sock_filter *tfilter;
2201 struct sock_fprog fprog;
2202 struct sock_filter *filter;
2203 int i;
2204
2205 if (optlen != sizeof(*tfprog)) {
2206 return -TARGET_EINVAL;
2207 }
2208 if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
2209 return -TARGET_EFAULT;
2210 }
2211 if (!lock_user_struct(VERIFY_READ, tfilter,
2212 tswapal(tfprog->filter), 0)) {
2213 unlock_user_struct(tfprog, optval_addr, 1);
2214 return -TARGET_EFAULT;
2215 }
2216
2217 fprog.len = tswap16(tfprog->len);
0e173b24 2218 filter = g_try_new(struct sock_filter, fprog.len);
f57d4192
LV
2219 if (filter == NULL) {
2220 unlock_user_struct(tfilter, tfprog->filter, 1);
2221 unlock_user_struct(tfprog, optval_addr, 1);
2222 return -TARGET_ENOMEM;
2223 }
2224 for (i = 0; i < fprog.len; i++) {
2225 filter[i].code = tswap16(tfilter[i].code);
2226 filter[i].jt = tfilter[i].jt;
2227 filter[i].jf = tfilter[i].jf;
2228 filter[i].k = tswap32(tfilter[i].k);
2229 }
2230 fprog.filter = filter;
2231
2232 ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
2233 SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
0e173b24 2234 g_free(filter);
f57d4192
LV
2235
2236 unlock_user_struct(tfilter, tfprog->filter, 1);
2237 unlock_user_struct(tfprog, optval_addr, 1);
2238 return ret;
2239 }
451aaf68
JT
2240 case TARGET_SO_BINDTODEVICE:
2241 {
2242 char *dev_ifname, *addr_ifname;
2243
2244 if (optlen > IFNAMSIZ - 1) {
2245 optlen = IFNAMSIZ - 1;
2246 }
2247 dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2248 if (!dev_ifname) {
2249 return -TARGET_EFAULT;
2250 }
2251 optname = SO_BINDTODEVICE;
2252 addr_ifname = alloca(IFNAMSIZ);
2253 memcpy(addr_ifname, dev_ifname, optlen);
2254 addr_ifname[optlen] = 0;
fad6c58a
CG
2255 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2256 addr_ifname, optlen));
451aaf68
JT
2257 unlock_user (dev_ifname, optval_addr, 0);
2258 return ret;
2259 }
83eb6e50
CMAB
2260 case TARGET_SO_LINGER:
2261 {
2262 struct linger lg;
2263 struct target_linger *tlg;
2264
2265 if (optlen != sizeof(struct target_linger)) {
2266 return -TARGET_EINVAL;
2267 }
2268 if (!lock_user_struct(VERIFY_READ, tlg, optval_addr, 1)) {
2269 return -TARGET_EFAULT;
2270 }
2271 __get_user(lg.l_onoff, &tlg->l_onoff);
2272 __get_user(lg.l_linger, &tlg->l_linger);
2273 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, SO_LINGER,
2274 &lg, sizeof(lg)));
2275 unlock_user_struct(tlg, optval_addr, 0);
2276 return ret;
2277 }
8853f86e 2278 /* Options with 'int' argument. */
3532fa74
FB
2279 case TARGET_SO_DEBUG:
2280 optname = SO_DEBUG;
2281 break;
2282 case TARGET_SO_REUSEADDR:
2283 optname = SO_REUSEADDR;
2284 break;
113a9dd7
YS
2285#ifdef SO_REUSEPORT
2286 case TARGET_SO_REUSEPORT:
2287 optname = SO_REUSEPORT;
2288 break;
2289#endif
3532fa74
FB
2290 case TARGET_SO_TYPE:
2291 optname = SO_TYPE;
2292 break;
2293 case TARGET_SO_ERROR:
2294 optname = SO_ERROR;
2295 break;
2296 case TARGET_SO_DONTROUTE:
2297 optname = SO_DONTROUTE;
2298 break;
2299 case TARGET_SO_BROADCAST:
2300 optname = SO_BROADCAST;
2301 break;
2302 case TARGET_SO_SNDBUF:
2303 optname = SO_SNDBUF;
2304 break;
d79b6cc4
PB
2305 case TARGET_SO_SNDBUFFORCE:
2306 optname = SO_SNDBUFFORCE;
2307 break;
3532fa74
FB
2308 case TARGET_SO_RCVBUF:
2309 optname = SO_RCVBUF;
2310 break;
d79b6cc4
PB
2311 case TARGET_SO_RCVBUFFORCE:
2312 optname = SO_RCVBUFFORCE;
2313 break;
3532fa74
FB
2314 case TARGET_SO_KEEPALIVE:
2315 optname = SO_KEEPALIVE;
2316 break;
2317 case TARGET_SO_OOBINLINE:
2318 optname = SO_OOBINLINE;
2319 break;
2320 case TARGET_SO_NO_CHECK:
2321 optname = SO_NO_CHECK;
2322 break;
2323 case TARGET_SO_PRIORITY:
2324 optname = SO_PRIORITY;
2325 break;
5e83e8e3 2326#ifdef SO_BSDCOMPAT
3532fa74
FB
2327 case TARGET_SO_BSDCOMPAT:
2328 optname = SO_BSDCOMPAT;
2329 break;
5e83e8e3 2330#endif
3532fa74
FB
2331 case TARGET_SO_PASSCRED:
2332 optname = SO_PASSCRED;
2333 break;
82d0fe6b
PB
2334 case TARGET_SO_PASSSEC:
2335 optname = SO_PASSSEC;
2336 break;
3532fa74
FB
2337 case TARGET_SO_TIMESTAMP:
2338 optname = SO_TIMESTAMP;
2339 break;
2340 case TARGET_SO_RCVLOWAT:
2341 optname = SO_RCVLOWAT;
2342 break;
8853f86e
FB
2343 default:
2344 goto unimplemented;
2345 }
3532fa74 2346 if (optlen < sizeof(uint32_t))
2f619698 2347 return -TARGET_EINVAL;
3532fa74 2348
2f619698
FB
2349 if (get_user_u32(val, optval_addr))
2350 return -TARGET_EFAULT;
3532fa74 2351 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
8853f86e 2352 break;
a2d86682
JK
2353#ifdef SOL_NETLINK
2354 case SOL_NETLINK:
2355 switch (optname) {
2356 case NETLINK_PKTINFO:
2357 case NETLINK_ADD_MEMBERSHIP:
2358 case NETLINK_DROP_MEMBERSHIP:
2359 case NETLINK_BROADCAST_ERROR:
2360 case NETLINK_NO_ENOBUFS:
2361#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2362 case NETLINK_LISTEN_ALL_NSID:
2363 case NETLINK_CAP_ACK:
2364#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2365#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2366 case NETLINK_EXT_ACK:
2367#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2368#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
2369 case NETLINK_GET_STRICT_CHK:
2370#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2371 break;
2372 default:
2373 goto unimplemented;
2374 }
2375 val = 0;
2376 if (optlen < sizeof(uint32_t)) {
2377 return -TARGET_EINVAL;
2378 }
2379 if (get_user_u32(val, optval_addr)) {
2380 return -TARGET_EFAULT;
2381 }
2382 ret = get_errno(setsockopt(sockfd, SOL_NETLINK, optname, &val,
2383 sizeof(val)));
2384 break;
2385#endif /* SOL_NETLINK */
7854b056 2386 default:
8853f86e 2387 unimplemented:
39be5350
JK
2388 qemu_log_mask(LOG_UNIMP, "Unsupported setsockopt level=%d optname=%d\n",
2389 level, optname);
6fa13c17 2390 ret = -TARGET_ENOPROTOOPT;
7854b056 2391 }
8853f86e 2392 return ret;
7854b056
FB
2393}
2394
0da46a6e 2395/* do_getsockopt() Must return target values and target errnos. */
992f48a0 2396static abi_long do_getsockopt(int sockfd, int level, int optname,
2f619698 2397 abi_ulong optval_addr, abi_ulong optlen)
7854b056 2398{
992f48a0 2399 abi_long ret;
b55266b5
BS
2400 int len, val;
2401 socklen_t lv;
8853f86e
FB
2402
2403 switch(level) {
3532fa74 2404 case TARGET_SOL_SOCKET:
f3b974cd
JL
2405 level = SOL_SOCKET;
2406 switch (optname) {
2407 /* These don't just return a single integer */
f3b974cd
JL
2408 case TARGET_SO_PEERNAME:
2409 goto unimplemented;
405dc4cf
AS
2410 case TARGET_SO_RCVTIMEO: {
2411 struct timeval tv;
2412 socklen_t tvlen;
2413
2414 optname = SO_RCVTIMEO;
2415
2416get_timeout:
2417 if (get_user_u32(len, optlen)) {
2418 return -TARGET_EFAULT;
2419 }
2420 if (len < 0) {
2421 return -TARGET_EINVAL;
2422 }
2423
2424 tvlen = sizeof(tv);
2425 ret = get_errno(getsockopt(sockfd, level, optname,
2426 &tv, &tvlen));
2427 if (ret < 0) {
2428 return ret;
2429 }
2430 if (len > sizeof(struct target_timeval)) {
2431 len = sizeof(struct target_timeval);
2432 }
2433 if (copy_to_user_timeval(optval_addr, &tv)) {
2434 return -TARGET_EFAULT;
2435 }
2436 if (put_user_u32(len, optlen)) {
2437 return -TARGET_EFAULT;
2438 }
2439 break;
2440 }
2441 case TARGET_SO_SNDTIMEO:
2442 optname = SO_SNDTIMEO;
2443 goto get_timeout;
583359a6
AP
2444 case TARGET_SO_PEERCRED: {
2445 struct ucred cr;
2446 socklen_t crlen;
2447 struct target_ucred *tcr;
2448
2449 if (get_user_u32(len, optlen)) {
2450 return -TARGET_EFAULT;
2451 }
2452 if (len < 0) {
2453 return -TARGET_EINVAL;
2454 }
2455
2456 crlen = sizeof(cr);
2457 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
2458 &cr, &crlen));
2459 if (ret < 0) {
2460 return ret;
2461 }
2462 if (len > crlen) {
2463 len = crlen;
2464 }
2465 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
2466 return -TARGET_EFAULT;
2467 }
2468 __put_user(cr.pid, &tcr->pid);
2469 __put_user(cr.uid, &tcr->uid);
2470 __put_user(cr.gid, &tcr->gid);
2471 unlock_user_struct(tcr, optval_addr, 1);
2472 if (put_user_u32(len, optlen)) {
83eb6e50
CMAB
2473 return -TARGET_EFAULT;
2474 }
2475 break;
2476 }
6d485a55
LV
2477 case TARGET_SO_PEERSEC: {
2478 char *name;
2479
2480 if (get_user_u32(len, optlen)) {
2481 return -TARGET_EFAULT;
2482 }
2483 if (len < 0) {
2484 return -TARGET_EINVAL;
2485 }
2486 name = lock_user(VERIFY_WRITE, optval_addr, len, 0);
2487 if (!name) {
2488 return -TARGET_EFAULT;
2489 }
2490 lv = len;
2491 ret = get_errno(getsockopt(sockfd, level, SO_PEERSEC,
2492 name, &lv));
2493 if (put_user_u32(lv, optlen)) {
2494 ret = -TARGET_EFAULT;
2495 }
2496 unlock_user(name, optval_addr, lv);
2497 break;
2498 }
83eb6e50
CMAB
2499 case TARGET_SO_LINGER:
2500 {
2501 struct linger lg;
2502 socklen_t lglen;
2503 struct target_linger *tlg;
2504
2505 if (get_user_u32(len, optlen)) {
2506 return -TARGET_EFAULT;
2507 }
2508 if (len < 0) {
2509 return -TARGET_EINVAL;
2510 }
2511
2512 lglen = sizeof(lg);
2513 ret = get_errno(getsockopt(sockfd, level, SO_LINGER,
2514 &lg, &lglen));
2515 if (ret < 0) {
2516 return ret;
2517 }
2518 if (len > lglen) {
2519 len = lglen;
2520 }
2521 if (!lock_user_struct(VERIFY_WRITE, tlg, optval_addr, 0)) {
2522 return -TARGET_EFAULT;
2523 }
2524 __put_user(lg.l_onoff, &tlg->l_onoff);
2525 __put_user(lg.l_linger, &tlg->l_linger);
2526 unlock_user_struct(tlg, optval_addr, 1);
2527 if (put_user_u32(len, optlen)) {
583359a6
AP
2528 return -TARGET_EFAULT;
2529 }
2530 break;
2531 }
f3b974cd
JL
2532 /* Options with 'int' argument. */
2533 case TARGET_SO_DEBUG:
2534 optname = SO_DEBUG;
2535 goto int_case;
2536 case TARGET_SO_REUSEADDR:
2537 optname = SO_REUSEADDR;
2538 goto int_case;
113a9dd7
YS
2539#ifdef SO_REUSEPORT
2540 case TARGET_SO_REUSEPORT:
2541 optname = SO_REUSEPORT;
2542 goto int_case;
2543#endif
f3b974cd
JL
2544 case TARGET_SO_TYPE:
2545 optname = SO_TYPE;
2546 goto int_case;
2547 case TARGET_SO_ERROR:
2548 optname = SO_ERROR;
2549 goto int_case;
2550 case TARGET_SO_DONTROUTE:
2551 optname = SO_DONTROUTE;
2552 goto int_case;
2553 case TARGET_SO_BROADCAST:
2554 optname = SO_BROADCAST;
2555 goto int_case;
2556 case TARGET_SO_SNDBUF:
2557 optname = SO_SNDBUF;
2558 goto int_case;
2559 case TARGET_SO_RCVBUF:
2560 optname = SO_RCVBUF;
2561 goto int_case;
2562 case TARGET_SO_KEEPALIVE:
2563 optname = SO_KEEPALIVE;
2564 goto int_case;
2565 case TARGET_SO_OOBINLINE:
2566 optname = SO_OOBINLINE;
2567 goto int_case;
2568 case TARGET_SO_NO_CHECK:
2569 optname = SO_NO_CHECK;
2570 goto int_case;
2571 case TARGET_SO_PRIORITY:
2572 optname = SO_PRIORITY;
2573 goto int_case;
2574#ifdef SO_BSDCOMPAT
2575 case TARGET_SO_BSDCOMPAT:
2576 optname = SO_BSDCOMPAT;
2577 goto int_case;
2578#endif
2579 case TARGET_SO_PASSCRED:
2580 optname = SO_PASSCRED;
2581 goto int_case;
2582 case TARGET_SO_TIMESTAMP:
2583 optname = SO_TIMESTAMP;
2584 goto int_case;
2585 case TARGET_SO_RCVLOWAT:
2586 optname = SO_RCVLOWAT;
2587 goto int_case;
aec1ca41
PB
2588 case TARGET_SO_ACCEPTCONN:
2589 optname = SO_ACCEPTCONN;
2590 goto int_case;
8853f86e 2591 default:
2efbe911
FB
2592 goto int_case;
2593 }
2594 break;
2595 case SOL_TCP:
2596 /* TCP options all take an 'int' value. */
2597 int_case:
2f619698
FB
2598 if (get_user_u32(len, optlen))
2599 return -TARGET_EFAULT;
2efbe911 2600 if (len < 0)
0da46a6e 2601 return -TARGET_EINVAL;
73160d95 2602 lv = sizeof(lv);
2efbe911
FB
2603 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2604 if (ret < 0)
2605 return ret;
8289d112
PB
2606 if (optname == SO_TYPE) {
2607 val = host_to_target_sock_type(val);
2608 }
2efbe911
FB
2609 if (len > lv)
2610 len = lv;
2f619698
FB
2611 if (len == 4) {
2612 if (put_user_u32(val, optval_addr))
2613 return -TARGET_EFAULT;
2614 } else {
2615 if (put_user_u8(val, optval_addr))
2616 return -TARGET_EFAULT;
f3b974cd 2617 }
2f619698
FB
2618 if (put_user_u32(len, optlen))
2619 return -TARGET_EFAULT;
2efbe911
FB
2620 break;
2621 case SOL_IP:
2622 switch(optname) {
2623 case IP_TOS:
2624 case IP_TTL:
2625 case IP_HDRINCL:
2626 case IP_ROUTER_ALERT:
2627 case IP_RECVOPTS:
2628 case IP_RETOPTS:
2629 case IP_PKTINFO:
2630 case IP_MTU_DISCOVER:
2631 case IP_RECVERR:
2632 case IP_RECVTOS:
2633#ifdef IP_FREEBIND
2634 case IP_FREEBIND:
2635#endif
2636 case IP_MULTICAST_TTL:
2637 case IP_MULTICAST_LOOP:
2f619698
FB
2638 if (get_user_u32(len, optlen))
2639 return -TARGET_EFAULT;
8853f86e 2640 if (len < 0)
0da46a6e 2641 return -TARGET_EINVAL;
73160d95 2642 lv = sizeof(lv);
8853f86e
FB
2643 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2644 if (ret < 0)
2645 return ret;
2efbe911 2646 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2efbe911 2647 len = 1;
2f619698
FB
2648 if (put_user_u32(len, optlen)
2649 || put_user_u8(val, optval_addr))
2650 return -TARGET_EFAULT;
2efbe911 2651 } else {
2efbe911
FB
2652 if (len > sizeof(int))
2653 len = sizeof(int);
2f619698
FB
2654 if (put_user_u32(len, optlen)
2655 || put_user_u32(val, optval_addr))
2656 return -TARGET_EFAULT;
2efbe911 2657 }
8853f86e 2658 break;
2efbe911 2659 default:
c02f499e
TS
2660 ret = -TARGET_ENOPROTOOPT;
2661 break;
8853f86e
FB
2662 }
2663 break;
bd8ed485
TD
2664 case SOL_IPV6:
2665 switch (optname) {
2666 case IPV6_MTU_DISCOVER:
2667 case IPV6_MTU:
2668 case IPV6_V6ONLY:
2669 case IPV6_RECVPKTINFO:
2670 case IPV6_UNICAST_HOPS:
2671 case IPV6_MULTICAST_HOPS:
2672 case IPV6_MULTICAST_LOOP:
2673 case IPV6_RECVERR:
2674 case IPV6_RECVHOPLIMIT:
2675 case IPV6_2292HOPLIMIT:
2676 case IPV6_CHECKSUM:
b9cce6d7
HD
2677 case IPV6_ADDRFORM:
2678 case IPV6_2292PKTINFO:
2679 case IPV6_RECVTCLASS:
2680 case IPV6_RECVRTHDR:
2681 case IPV6_2292RTHDR:
2682 case IPV6_RECVHOPOPTS:
2683 case IPV6_2292HOPOPTS:
2684 case IPV6_RECVDSTOPTS:
2685 case IPV6_2292DSTOPTS:
2686 case IPV6_TCLASS:
2687#ifdef IPV6_RECVPATHMTU
2688 case IPV6_RECVPATHMTU:
2689#endif
2690#ifdef IPV6_TRANSPARENT
2691 case IPV6_TRANSPARENT:
2692#endif
2693#ifdef IPV6_FREEBIND
2694 case IPV6_FREEBIND:
2695#endif
2696#ifdef IPV6_RECVORIGDSTADDR
2697 case IPV6_RECVORIGDSTADDR:
2698#endif
bd8ed485
TD
2699 if (get_user_u32(len, optlen))
2700 return -TARGET_EFAULT;
2701 if (len < 0)
2702 return -TARGET_EINVAL;
2703 lv = sizeof(lv);
2704 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2705 if (ret < 0)
2706 return ret;
2707 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2708 len = 1;
2709 if (put_user_u32(len, optlen)
2710 || put_user_u8(val, optval_addr))
2711 return -TARGET_EFAULT;
2712 } else {
2713 if (len > sizeof(int))
2714 len = sizeof(int);
2715 if (put_user_u32(len, optlen)
2716 || put_user_u32(val, optval_addr))
2717 return -TARGET_EFAULT;
2718 }
2719 break;
2720 default:
2721 ret = -TARGET_ENOPROTOOPT;
2722 break;
2723 }
2724 break;
a2d86682
JK
2725#ifdef SOL_NETLINK
2726 case SOL_NETLINK:
2727 switch (optname) {
2728 case NETLINK_PKTINFO:
2729 case NETLINK_BROADCAST_ERROR:
2730 case NETLINK_NO_ENOBUFS:
2731#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2732 case NETLINK_LISTEN_ALL_NSID:
2733 case NETLINK_CAP_ACK:
2734#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2735#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
2736 case NETLINK_EXT_ACK:
2737#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2738#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
2739 case NETLINK_GET_STRICT_CHK:
2740#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) */
2741 if (get_user_u32(len, optlen)) {
2742 return -TARGET_EFAULT;
2743 }
2744 if (len != sizeof(val)) {
2745 return -TARGET_EINVAL;
2746 }
2747 lv = len;
2748 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2749 if (ret < 0) {
2750 return ret;
2751 }
2752 if (put_user_u32(lv, optlen)
2753 || put_user_u32(val, optval_addr)) {
2754 return -TARGET_EFAULT;
2755 }
2756 break;
2757#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
2758 case NETLINK_LIST_MEMBERSHIPS:
2759 {
2760 uint32_t *results;
2761 int i;
2762 if (get_user_u32(len, optlen)) {
2763 return -TARGET_EFAULT;
2764 }
2765 if (len < 0) {
2766 return -TARGET_EINVAL;
2767 }
2768 results = lock_user(VERIFY_WRITE, optval_addr, len, 1);
2769 if (!results) {
2770 return -TARGET_EFAULT;
2771 }
2772 lv = len;
2773 ret = get_errno(getsockopt(sockfd, level, optname, results, &lv));
2774 if (ret < 0) {
2775 unlock_user(results, optval_addr, 0);
2776 return ret;
2777 }
2778 /* swap host endianess to target endianess. */
2779 for (i = 0; i < (len / sizeof(uint32_t)); i++) {
2780 results[i] = tswap32(results[i]);
2781 }
2782 if (put_user_u32(lv, optlen)) {
2783 return -TARGET_EFAULT;
2784 }
2785 unlock_user(results, optval_addr, 0);
2786 break;
2787 }
2788#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) */
2789 default:
2790 goto unimplemented;
2791 }
c0cb8801 2792 break;
a2d86682 2793#endif /* SOL_NETLINK */
8853f86e
FB
2794 default:
2795 unimplemented:
39be5350
JK
2796 qemu_log_mask(LOG_UNIMP,
2797 "getsockopt level=%d optname=%d not yet supported\n",
2798 level, optname);
c02f499e 2799 ret = -TARGET_EOPNOTSUPP;
8853f86e
FB
2800 break;
2801 }
2802 return ret;
7854b056
FB
2803}
2804
9ac22517
MF
2805/* Convert target low/high pair representing file offset into the host
2806 * low/high pair. This function doesn't handle offsets bigger than 64 bits
2807 * as the kernel doesn't handle them either.
2808 */
2809static void target_to_host_low_high(abi_ulong tlow,
2810 abi_ulong thigh,
2811 unsigned long *hlow,
2812 unsigned long *hhigh)
2813{
2814 uint64_t off = tlow |
2815 ((unsigned long long)thigh << TARGET_LONG_BITS / 2) <<
2816 TARGET_LONG_BITS / 2;
2817
2818 *hlow = off;
2819 *hhigh = (off >> HOST_LONG_BITS / 2) >> HOST_LONG_BITS / 2;
2820}
2821
f287b2c2 2822static struct iovec *lock_iovec(int type, abi_ulong target_addr,
dab32b32 2823 abi_ulong count, int copy)
53a5960a
PB
2824{
2825 struct target_iovec *target_vec;
f287b2c2
RH
2826 struct iovec *vec;
2827 abi_ulong total_len, max_len;
d732dcb4 2828 int i;
501bb4b0 2829 int err = 0;
29560a6c 2830 bool bad_address = false;
53a5960a 2831
f287b2c2
RH
2832 if (count == 0) {
2833 errno = 0;
2834 return NULL;
2835 }
dab32b32 2836 if (count > IOV_MAX) {
f287b2c2
RH
2837 errno = EINVAL;
2838 return NULL;
2839 }
2840
0e173b24 2841 vec = g_try_new0(struct iovec, count);
f287b2c2
RH
2842 if (vec == NULL) {
2843 errno = ENOMEM;
2844 return NULL;
2845 }
2846
2847 target_vec = lock_user(VERIFY_READ, target_addr,
2848 count * sizeof(struct target_iovec), 1);
2849 if (target_vec == NULL) {
501bb4b0 2850 err = EFAULT;
f287b2c2
RH
2851 goto fail2;
2852 }
2853
2854 /* ??? If host page size > target page size, this will result in a
2855 value larger than what we can actually support. */
2856 max_len = 0x7fffffff & TARGET_PAGE_MASK;
2857 total_len = 0;
2858
2859 for (i = 0; i < count; i++) {
2860 abi_ulong base = tswapal(target_vec[i].iov_base);
2861 abi_long len = tswapal(target_vec[i].iov_len);
2862
2863 if (len < 0) {
501bb4b0 2864 err = EINVAL;
f287b2c2
RH
2865 goto fail;
2866 } else if (len == 0) {
2867 /* Zero length pointer is ignored. */
2868 vec[i].iov_base = 0;
41df8411 2869 } else {
f287b2c2 2870 vec[i].iov_base = lock_user(type, base, len, copy);
29560a6c
TM
2871 /* If the first buffer pointer is bad, this is a fault. But
2872 * subsequent bad buffers will result in a partial write; this
2873 * is realized by filling the vector with null pointers and
2874 * zero lengths. */
f287b2c2 2875 if (!vec[i].iov_base) {
29560a6c
TM
2876 if (i == 0) {
2877 err = EFAULT;
2878 goto fail;
2879 } else {
2880 bad_address = true;
2881 }
2882 }
2883 if (bad_address) {
2884 len = 0;
f287b2c2
RH
2885 }
2886 if (len > max_len - total_len) {
2887 len = max_len - total_len;
2888 }
41df8411 2889 }
f287b2c2
RH
2890 vec[i].iov_len = len;
2891 total_len += len;
579a97f7 2892 }
f287b2c2
RH
2893
2894 unlock_user(target_vec, target_addr, 0);
2895 return vec;
2896
2897 fail:
7eff518b
CG
2898 while (--i >= 0) {
2899 if (tswapal(target_vec[i].iov_len) > 0) {
2900 unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
2901 }
2902 }
f287b2c2 2903 unlock_user(target_vec, target_addr, 0);
501bb4b0 2904 fail2:
0e173b24 2905 g_free(vec);
501bb4b0 2906 errno = err;
f287b2c2 2907 return NULL;
53a5960a
PB
2908}
2909
f287b2c2 2910static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
dab32b32 2911 abi_ulong count, int copy)
53a5960a
PB
2912{
2913 struct target_iovec *target_vec;
53a5960a
PB
2914 int i;
2915
f287b2c2
RH
2916 target_vec = lock_user(VERIFY_READ, target_addr,
2917 count * sizeof(struct target_iovec), 1);
2918 if (target_vec) {
2919 for (i = 0; i < count; i++) {
2920 abi_ulong base = tswapal(target_vec[i].iov_base);
71ec7cef 2921 abi_long len = tswapal(target_vec[i].iov_len);
f287b2c2
RH
2922 if (len < 0) {
2923 break;
2924 }
d732dcb4
AZ
2925 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
2926 }
f287b2c2 2927 unlock_user(target_vec, target_addr, 0);
53a5960a 2928 }
579a97f7 2929
0e173b24 2930 g_free(vec);
53a5960a
PB
2931}
2932
53d09b76 2933static inline int target_to_host_sock_type(int *type)
3532fa74 2934{
f651e6ae
PJ
2935 int host_type = 0;
2936 int target_type = *type;
2937
2938 switch (target_type & TARGET_SOCK_TYPE_MASK) {
3532fa74 2939 case TARGET_SOCK_DGRAM:
f651e6ae 2940 host_type = SOCK_DGRAM;
3532fa74
FB
2941 break;
2942 case TARGET_SOCK_STREAM:
f651e6ae 2943 host_type = SOCK_STREAM;
3532fa74 2944 break;
f651e6ae
PJ
2945 default:
2946 host_type = target_type & TARGET_SOCK_TYPE_MASK;
3532fa74
FB
2947 break;
2948 }
f651e6ae 2949 if (target_type & TARGET_SOCK_CLOEXEC) {
53d09b76 2950#if defined(SOCK_CLOEXEC)
f651e6ae 2951 host_type |= SOCK_CLOEXEC;
53d09b76
EI
2952#else
2953 return -TARGET_EINVAL;
2954#endif
f651e6ae
PJ
2955 }
2956 if (target_type & TARGET_SOCK_NONBLOCK) {
53d09b76 2957#if defined(SOCK_NONBLOCK)
f651e6ae 2958 host_type |= SOCK_NONBLOCK;
53d09b76
EI
2959#elif !defined(O_NONBLOCK)
2960 return -TARGET_EINVAL;
2961#endif
f651e6ae
PJ
2962 }
2963 *type = host_type;
53d09b76
EI
2964 return 0;
2965}
2966
2967/* Try to emulate socket type flags after socket creation. */
2968static int sock_flags_fixup(int fd, int target_type)
2969{
2970#if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
2971 if (target_type & TARGET_SOCK_NONBLOCK) {
2972 int flags = fcntl(fd, F_GETFL);
2973 if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
2974 close(fd);
2975 return -TARGET_EINVAL;
2976 }
2977 }
2978#endif
2979 return fd;
f651e6ae
PJ
2980}
2981
2982/* do_socket() Must return target values and target errnos. */
2983static abi_long do_socket(int domain, int type, int protocol)
2984{
53d09b76
EI
2985 int target_type = type;
2986 int ret;
2987
2988 ret = target_to_host_sock_type(&type);
2989 if (ret) {
2990 return ret;
2991 }
f651e6ae 2992
575b22b1
LV
2993 if (domain == PF_NETLINK && !(
2994#ifdef CONFIG_RTNETLINK
2995 protocol == NETLINK_ROUTE ||
2996#endif
2997 protocol == NETLINK_KOBJECT_UEVENT ||
2998 protocol == NETLINK_AUDIT)) {
71e2443e 2999 return -TARGET_EPROTONOSUPPORT;
6c5b5645 3000 }
ff626f2d
LV
3001
3002 if (domain == AF_PACKET ||
3003 (domain == AF_INET && type == SOCK_PACKET)) {
3004 protocol = tswap16(protocol);
3005 }
3006
53d09b76
EI
3007 ret = get_errno(socket(domain, type, protocol));
3008 if (ret >= 0) {
3009 ret = sock_flags_fixup(ret, target_type);
0cf22722
LV
3010 if (type == SOCK_PACKET) {
3011 /* Manage an obsolete case :
3012 * if socket type is SOCK_PACKET, bind by name
3013 */
3014 fd_trans_register(ret, &target_packet_trans);
6c5b5645
LV
3015 } else if (domain == PF_NETLINK) {
3016 switch (protocol) {
575b22b1 3017#ifdef CONFIG_RTNETLINK
6c5b5645
LV
3018 case NETLINK_ROUTE:
3019 fd_trans_register(ret, &target_netlink_route_trans);
3020 break;
575b22b1 3021#endif
b265620b
LV
3022 case NETLINK_KOBJECT_UEVENT:
3023 /* nothing to do: messages are strings */
3024 break;
5ce9bb59
LV
3025 case NETLINK_AUDIT:
3026 fd_trans_register(ret, &target_netlink_audit_trans);
3027 break;
6c5b5645
LV
3028 default:
3029 g_assert_not_reached();
3030 }
0cf22722 3031 }
53d09b76
EI
3032 }
3033 return ret;
3532fa74
FB
3034}
3035
0da46a6e 3036/* do_bind() Must return target values and target errnos. */
992f48a0
BS
3037static abi_long do_bind(int sockfd, abi_ulong target_addr,
3038 socklen_t addrlen)
3532fa74 3039{
8f7aeaf6 3040 void *addr;
917507b0 3041 abi_long ret;
8f7aeaf6 3042
38724253 3043 if ((int)addrlen < 0) {
8f7aeaf6 3044 return -TARGET_EINVAL;
38724253 3045 }
8f7aeaf6 3046
607175e0 3047 addr = alloca(addrlen+1);
3b46e624 3048
7b36f782 3049 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
917507b0
AP
3050 if (ret)
3051 return ret;
3052
3532fa74
FB
3053 return get_errno(bind(sockfd, addr, addrlen));
3054}
3055
0da46a6e 3056/* do_connect() Must return target values and target errnos. */
992f48a0
BS
3057static abi_long do_connect(int sockfd, abi_ulong target_addr,
3058 socklen_t addrlen)
3532fa74 3059{
8f7aeaf6 3060 void *addr;
917507b0 3061 abi_long ret;
8f7aeaf6 3062
38724253 3063 if ((int)addrlen < 0) {
8f7aeaf6 3064 return -TARGET_EINVAL;
38724253 3065 }
8f7aeaf6 3066
2dd08dfd 3067 addr = alloca(addrlen+1);
3b46e624 3068
7b36f782 3069 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
917507b0
AP
3070 if (ret)
3071 return ret;
3072
2a3c7619 3073 return get_errno(safe_connect(sockfd, addr, addrlen));
3532fa74
FB
3074}
3075
f19e00d7
AG
3076/* do_sendrecvmsg_locked() Must return target values and target errnos. */
3077static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
3078 int flags, int send)
3532fa74 3079{
6de645c7 3080 abi_long ret, len;
3532fa74 3081 struct msghdr msg;
dab32b32 3082 abi_ulong count;
3532fa74 3083 struct iovec *vec;
992f48a0 3084 abi_ulong target_vec;
3532fa74 3085
3532fa74
FB
3086 if (msgp->msg_name) {
3087 msg.msg_namelen = tswap32(msgp->msg_namelen);
2dd08dfd 3088 msg.msg_name = alloca(msg.msg_namelen+1);
7b36f782
LV
3089 ret = target_to_host_sockaddr(fd, msg.msg_name,
3090 tswapal(msgp->msg_name),
3091 msg.msg_namelen);
26a6fc96
PM
3092 if (ret == -TARGET_EFAULT) {
3093 /* For connected sockets msg_name and msg_namelen must
3094 * be ignored, so returning EFAULT immediately is wrong.
3095 * Instead, pass a bad msg_name to the host kernel, and
3096 * let it decide whether to return EFAULT or not.
3097 */
3098 msg.msg_name = (void *)-1;
3099 } else if (ret) {
f287b2c2 3100 goto out2;
917507b0 3101 }
3532fa74
FB
3102 } else {
3103 msg.msg_name = NULL;
3104 msg.msg_namelen = 0;
3105 }
cbb21eed 3106 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
3532fa74 3107 msg.msg_control = alloca(msg.msg_controllen);
1d3d1b23
JS
3108 memset(msg.msg_control, 0, msg.msg_controllen);
3109
3532fa74 3110 msg.msg_flags = tswap32(msgp->msg_flags);
3b46e624 3111
cbb21eed 3112 count = tswapal(msgp->msg_iovlen);
cbb21eed 3113 target_vec = tswapal(msgp->msg_iov);
97b07970
PM
3114
3115 if (count > IOV_MAX) {
3116 /* sendrcvmsg returns a different errno for this condition than
3117 * readv/writev, so we must catch it here before lock_iovec() does.
3118 */
3119 ret = -TARGET_EMSGSIZE;
3120 goto out2;
3121 }
3122
f287b2c2
RH
3123 vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
3124 target_vec, count, send);
3125 if (vec == NULL) {
3126 ret = -host_to_target_errno(errno);
3127 goto out2;
3128 }
3532fa74
FB
3129 msg.msg_iovlen = count;
3130 msg.msg_iov = vec;
3b46e624 3131
3532fa74 3132 if (send) {
6c5b5645 3133 if (fd_trans_target_to_host_data(fd)) {
7d61d892
LV
3134 void *host_msg;
3135
3136 host_msg = g_malloc(msg.msg_iov->iov_len);
3137 memcpy(host_msg, msg.msg_iov->iov_base, msg.msg_iov->iov_len);
3138 ret = fd_trans_target_to_host_data(fd)(host_msg,
6c5b5645 3139 msg.msg_iov->iov_len);
7d61d892
LV
3140 if (ret >= 0) {
3141 msg.msg_iov->iov_base = host_msg;
3142 ret = get_errno(safe_sendmsg(fd, &msg, flags));
3143 }
3144 g_free(host_msg);
6c5b5645
LV
3145 } else {
3146 ret = target_to_host_cmsg(&msg, msgp);
7d61d892
LV
3147 if (ret == 0) {
3148 ret = get_errno(safe_sendmsg(fd, &msg, flags));
3149 }
6c5b5645 3150 }
3532fa74 3151 } else {
66687530 3152 ret = get_errno(safe_recvmsg(fd, &msg, flags));
6de645c7
AZ
3153 if (!is_error(ret)) {
3154 len = ret;
6c5b5645
LV
3155 if (fd_trans_host_to_target_data(fd)) {
3156 ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
2a03d3e6 3157 MIN(msg.msg_iov->iov_len, len));
6c5b5645
LV
3158 } else {
3159 ret = host_to_target_cmsg(msgp, &msg);
3160 }
ca619067
JH
3161 if (!is_error(ret)) {
3162 msgp->msg_namelen = tswap32(msg.msg_namelen);
24894f39 3163 msgp->msg_flags = tswap32(msg.msg_flags);
26a6fc96 3164 if (msg.msg_name != NULL && msg.msg_name != (void *)-1) {
ca619067
JH
3165 ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
3166 msg.msg_name, msg.msg_namelen);
3167 if (ret) {
3168 goto out;
3169 }
3170 }
3171
6de645c7 3172 ret = len;
ca619067 3173 }
6de645c7 3174 }
3532fa74 3175 }
ca619067
JH
3176
3177out:
3532fa74 3178 unlock_iovec(vec, target_vec, count, !send);
f287b2c2 3179out2:
f19e00d7
AG
3180 return ret;
3181}
3182
3183static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
3184 int flags, int send)
3185{
3186 abi_long ret;
3187 struct target_msghdr *msgp;
3188
3189 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
3190 msgp,
3191 target_msg,
3192 send ? 1 : 0)) {
3193 return -TARGET_EFAULT;
3194 }
3195 ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
579a97f7 3196 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
3532fa74
FB
3197 return ret;
3198}
3199
f19e00d7
AG
3200/* We don't rely on the C library to have sendmmsg/recvmmsg support,
3201 * so it might not have this *mmsg-specific flag either.
3202 */
3203#ifndef MSG_WAITFORONE
3204#define MSG_WAITFORONE 0x10000
3205#endif
3206
3207static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
3208 unsigned int vlen, unsigned int flags,
3209 int send)
3210{
3211 struct target_mmsghdr *mmsgp;
3212 abi_long ret = 0;
3213 int i;
3214
3215 if (vlen > UIO_MAXIOV) {
3216 vlen = UIO_MAXIOV;
3217 }
3218
3219 mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
3220 if (!mmsgp) {
3221 return -TARGET_EFAULT;
3222 }
3223
3224 for (i = 0; i < vlen; i++) {
3225 ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
3226 if (is_error(ret)) {
3227 break;
3228 }
3229 mmsgp[i].msg_len = tswap32(ret);
3230 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
3231 if (flags & MSG_WAITFORONE) {
3232 flags |= MSG_DONTWAIT;
3233 }
3234 }
3235
3236 unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
3237
3238 /* Return number of datagrams sent if we sent any at all;
3239 * otherwise return the error.
3240 */
3241 if (i) {
3242 return i;
3243 }
3244 return ret;
3245}
f19e00d7 3246
a94b4987
PM
3247/* do_accept4() Must return target values and target errnos. */
3248static abi_long do_accept4(int fd, abi_ulong target_addr,
3249 abi_ulong target_addrlen_addr, int flags)
1be9e1dc 3250{
cd813367 3251 socklen_t addrlen, ret_addrlen;
2f619698 3252 void *addr;
992f48a0 3253 abi_long ret;
d25295d4
PJ
3254 int host_flags;
3255
3256 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
1be9e1dc 3257
a94b4987 3258 if (target_addr == 0) {
ff6dc130 3259 return get_errno(safe_accept4(fd, NULL, NULL, host_flags));
a94b4987 3260 }
917507b0
AP
3261
3262 /* linux returns EINVAL if addrlen pointer is invalid */
2f619698 3263 if (get_user_u32(addrlen, target_addrlen_addr))
917507b0 3264 return -TARGET_EINVAL;
2f619698 3265
38724253 3266 if ((int)addrlen < 0) {
8f7aeaf6 3267 return -TARGET_EINVAL;
38724253 3268 }
8f7aeaf6 3269
917507b0
AP
3270 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3271 return -TARGET_EINVAL;
3272
2f619698
FB
3273 addr = alloca(addrlen);
3274
cd813367
AS
3275 ret_addrlen = addrlen;
3276 ret = get_errno(safe_accept4(fd, addr, &ret_addrlen, host_flags));
1be9e1dc 3277 if (!is_error(ret)) {
cd813367
AS
3278 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3279 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3280 ret = -TARGET_EFAULT;
cd813367 3281 }
1be9e1dc
PB
3282 }
3283 return ret;
3284}
3285
0da46a6e 3286/* do_getpeername() Must return target values and target errnos. */
992f48a0 3287static abi_long do_getpeername(int fd, abi_ulong target_addr,
2f619698 3288 abi_ulong target_addrlen_addr)
1be9e1dc 3289{
cd813367 3290 socklen_t addrlen, ret_addrlen;
2f619698 3291 void *addr;
992f48a0 3292 abi_long ret;
1be9e1dc 3293
2f619698
FB
3294 if (get_user_u32(addrlen, target_addrlen_addr))
3295 return -TARGET_EFAULT;
3296
38724253 3297 if ((int)addrlen < 0) {
8f7aeaf6 3298 return -TARGET_EINVAL;
38724253 3299 }
8f7aeaf6 3300
917507b0
AP
3301 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3302 return -TARGET_EFAULT;
3303
2f619698
FB
3304 addr = alloca(addrlen);
3305
cd813367
AS
3306 ret_addrlen = addrlen;
3307 ret = get_errno(getpeername(fd, addr, &ret_addrlen));
1be9e1dc 3308 if (!is_error(ret)) {
cd813367
AS
3309 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3310 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3311 ret = -TARGET_EFAULT;
cd813367 3312 }
1be9e1dc
PB
3313 }
3314 return ret;
3315}
3316
0da46a6e 3317/* do_getsockname() Must return target values and target errnos. */
992f48a0 3318static abi_long do_getsockname(int fd, abi_ulong target_addr,
2f619698 3319 abi_ulong target_addrlen_addr)
1be9e1dc 3320{
cd813367 3321 socklen_t addrlen, ret_addrlen;
2f619698 3322 void *addr;
992f48a0 3323 abi_long ret;
1be9e1dc 3324
2f619698
FB
3325 if (get_user_u32(addrlen, target_addrlen_addr))
3326 return -TARGET_EFAULT;
3327
38724253 3328 if ((int)addrlen < 0) {
8f7aeaf6 3329 return -TARGET_EINVAL;
38724253 3330 }
8f7aeaf6 3331
917507b0
AP
3332 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3333 return -TARGET_EFAULT;
3334
2f619698
FB
3335 addr = alloca(addrlen);
3336
cd813367
AS
3337 ret_addrlen = addrlen;
3338 ret = get_errno(getsockname(fd, addr, &ret_addrlen));
1be9e1dc 3339 if (!is_error(ret)) {
cd813367
AS
3340 host_to_target_sockaddr(target_addr, addr, MIN(addrlen, ret_addrlen));
3341 if (put_user_u32(ret_addrlen, target_addrlen_addr)) {
2f619698 3342 ret = -TARGET_EFAULT;
cd813367 3343 }
1be9e1dc
PB
3344 }
3345 return ret;
3346}
3347
0da46a6e 3348/* do_socketpair() Must return target values and target errnos. */
992f48a0 3349static abi_long do_socketpair(int domain, int type, int protocol,
2f619698 3350 abi_ulong target_tab_addr)
1be9e1dc
PB
3351{
3352 int tab[2];
992f48a0 3353 abi_long ret;
1be9e1dc 3354
f651e6ae
PJ
3355 target_to_host_sock_type(&type);
3356
1be9e1dc
PB
3357 ret = get_errno(socketpair(domain, type, protocol, tab));
3358 if (!is_error(ret)) {
2f619698
FB
3359 if (put_user_s32(tab[0], target_tab_addr)
3360 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
3361 ret = -TARGET_EFAULT;
1be9e1dc
PB
3362 }
3363 return ret;
3364}
3365
0da46a6e 3366/* do_sendto() Must return target values and target errnos. */
992f48a0
BS
3367static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
3368 abi_ulong target_addr, socklen_t addrlen)
1be9e1dc
PB
3369{
3370 void *addr;
3371 void *host_msg;
7d61d892 3372 void *copy_msg = NULL;
992f48a0 3373 abi_long ret;
1be9e1dc 3374
38724253 3375 if ((int)addrlen < 0) {
8f7aeaf6 3376 return -TARGET_EINVAL;
38724253 3377 }
8f7aeaf6 3378
579a97f7
FB
3379 host_msg = lock_user(VERIFY_READ, msg, len, 1);
3380 if (!host_msg)
3381 return -TARGET_EFAULT;
6c5b5645 3382 if (fd_trans_target_to_host_data(fd)) {
7d61d892
LV
3383 copy_msg = host_msg;
3384 host_msg = g_malloc(len);
3385 memcpy(host_msg, copy_msg, len);
6c5b5645
LV
3386 ret = fd_trans_target_to_host_data(fd)(host_msg, len);
3387 if (ret < 0) {
7d61d892 3388 goto fail;
6c5b5645
LV
3389 }
3390 }
1be9e1dc 3391 if (target_addr) {
2dd08dfd 3392 addr = alloca(addrlen+1);
7b36f782 3393 ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
917507b0 3394 if (ret) {
7d61d892 3395 goto fail;
917507b0 3396 }
66687530 3397 ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
1be9e1dc 3398 } else {
66687530 3399 ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
1be9e1dc 3400 }
7d61d892
LV
3401fail:
3402 if (copy_msg) {
3403 g_free(host_msg);
3404 host_msg = copy_msg;
3405 }
1be9e1dc
PB
3406 unlock_user(host_msg, msg, 0);
3407 return ret;
3408}
3409
0da46a6e 3410/* do_recvfrom() Must return target values and target errnos. */
992f48a0
BS
3411static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
3412 abi_ulong target_addr,
3413 abi_ulong target_addrlen)
1be9e1dc 3414{
cd813367 3415 socklen_t addrlen, ret_addrlen;
1be9e1dc
PB
3416 void *addr;
3417 void *host_msg;
992f48a0 3418 abi_long ret;
1be9e1dc 3419
579a97f7
FB
3420 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
3421 if (!host_msg)
3422 return -TARGET_EFAULT;
1be9e1dc 3423 if (target_addr) {
2f619698
FB
3424 if (get_user_u32(addrlen, target_addrlen)) {
3425 ret = -TARGET_EFAULT;
3426 goto fail;
3427 }
38724253 3428 if ((int)addrlen < 0) {
8f7aeaf6
AJ
3429 ret = -TARGET_EINVAL;
3430 goto fail;
3431 }
1be9e1dc 3432 addr = alloca(addrlen);
cd813367 3433 ret_addrlen = addrlen;
66687530 3434 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags,
cd813367 3435 addr, &ret_addrlen));
1be9e1dc
PB
3436 } else {
3437 addr = NULL; /* To keep compiler quiet. */
cd813367 3438 addrlen = 0; /* To keep compiler quiet. */
66687530 3439 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
1be9e1dc
PB
3440 }
3441 if (!is_error(ret)) {
c35e1f9c 3442 if (fd_trans_host_to_target_data(fd)) {
2a03d3e6
LV
3443 abi_long trans;
3444 trans = fd_trans_host_to_target_data(fd)(host_msg, MIN(ret, len));
3445 if (is_error(trans)) {
3446 ret = trans;
3447 goto fail;
3448 }
c35e1f9c 3449 }
1be9e1dc 3450 if (target_addr) {
cd813367
AS
3451 host_to_target_sockaddr(target_addr, addr,
3452 MIN(addrlen, ret_addrlen));
3453 if (put_user_u32(ret_addrlen, target_addrlen)) {
2f619698
FB
3454 ret = -TARGET_EFAULT;
3455 goto fail;
3456 }
1be9e1dc
PB
3457 }
3458 unlock_user(host_msg, msg, len);
3459 } else {
2f619698 3460fail:
1be9e1dc
PB
3461 unlock_user(host_msg, msg, 0);
3462 }
3463 return ret;
3464}
3465
32407103 3466#ifdef TARGET_NR_socketcall
ff71a454 3467/* do_socketcall() must return target values and target errnos. */
992f48a0 3468static abi_long do_socketcall(int num, abi_ulong vptr)
31e31b8a 3469{
ff71a454
AM
3470 static const unsigned nargs[] = { /* number of arguments per operation */
3471 [TARGET_SYS_SOCKET] = 3, /* domain, type, protocol */
3472 [TARGET_SYS_BIND] = 3, /* fd, addr, addrlen */
3473 [TARGET_SYS_CONNECT] = 3, /* fd, addr, addrlen */
3474 [TARGET_SYS_LISTEN] = 2, /* fd, backlog */
3475 [TARGET_SYS_ACCEPT] = 3, /* fd, addr, addrlen */
3476 [TARGET_SYS_GETSOCKNAME] = 3, /* fd, addr, addrlen */
3477 [TARGET_SYS_GETPEERNAME] = 3, /* fd, addr, addrlen */
3478 [TARGET_SYS_SOCKETPAIR] = 4, /* domain, type, protocol, tab */
3479 [TARGET_SYS_SEND] = 4, /* fd, msg, len, flags */
3480 [TARGET_SYS_RECV] = 4, /* fd, msg, len, flags */
3481 [TARGET_SYS_SENDTO] = 6, /* fd, msg, len, flags, addr, addrlen */
3482 [TARGET_SYS_RECVFROM] = 6, /* fd, msg, len, flags, addr, addrlen */
3483 [TARGET_SYS_SHUTDOWN] = 2, /* fd, how */
3484 [TARGET_SYS_SETSOCKOPT] = 5, /* fd, level, optname, optval, optlen */
3485 [TARGET_SYS_GETSOCKOPT] = 5, /* fd, level, optname, optval, optlen */
3486 [TARGET_SYS_SENDMSG] = 3, /* fd, msg, flags */
3487 [TARGET_SYS_RECVMSG] = 3, /* fd, msg, flags */
3488 [TARGET_SYS_ACCEPT4] = 4, /* fd, addr, addrlen, flags */
3489 [TARGET_SYS_RECVMMSG] = 4, /* fd, msgvec, vlen, flags */
3490 [TARGET_SYS_SENDMMSG] = 4, /* fd, msgvec, vlen, flags */
62dc90c6
MT
3491 };
3492 abi_long a[6]; /* max 6 args */
ff71a454 3493 unsigned i;
62dc90c6 3494
ff71a454
AM
3495 /* check the range of the first argument num */
3496 /* (TARGET_SYS_SENDMMSG is the highest among TARGET_SYS_xxx) */
3497 if (num < 1 || num > TARGET_SYS_SENDMMSG) {
3498 return -TARGET_EINVAL;
3499 }
3500 /* ensure we have space for args */
3501 if (nargs[num] > ARRAY_SIZE(a)) {
3502 return -TARGET_EINVAL;
3503 }
3504 /* collect the arguments in a[] according to nargs[] */
3505 for (i = 0; i < nargs[num]; ++i) {
3506 if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
3507 return -TARGET_EFAULT;
31e31b8a 3508 }
62dc90c6 3509 }
ff71a454 3510 /* now when we have the args, invoke the appropriate underlying function */
62dc90c6 3511 switch (num) {
ff71a454 3512 case TARGET_SYS_SOCKET: /* domain, type, protocol */
62dc90c6 3513 return do_socket(a[0], a[1], a[2]);
ff71a454 3514 case TARGET_SYS_BIND: /* sockfd, addr, addrlen */
62dc90c6 3515 return do_bind(a[0], a[1], a[2]);
ff71a454 3516 case TARGET_SYS_CONNECT: /* sockfd, addr, addrlen */
62dc90c6 3517 return do_connect(a[0], a[1], a[2]);
ff71a454 3518 case TARGET_SYS_LISTEN: /* sockfd, backlog */
62dc90c6 3519 return get_errno(listen(a[0], a[1]));
ff71a454 3520 case TARGET_SYS_ACCEPT: /* sockfd, addr, addrlen */
62dc90c6 3521 return do_accept4(a[0], a[1], a[2], 0);
ff71a454 3522 case TARGET_SYS_GETSOCKNAME: /* sockfd, addr, addrlen */
62dc90c6 3523 return do_getsockname(a[0], a[1], a[2]);
ff71a454 3524 case TARGET_SYS_GETPEERNAME: /* sockfd, addr, addrlen */
62dc90c6 3525 return do_getpeername(a[0], a[1], a[2]);
ff71a454 3526 case TARGET_SYS_SOCKETPAIR: /* domain, type, protocol, tab */
62dc90c6 3527 return do_socketpair(a[0], a[1], a[2], a[3]);
ff71a454 3528 case TARGET_SYS_SEND: /* sockfd, msg, len, flags */
62dc90c6 3529 return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
ff71a454 3530 case TARGET_SYS_RECV: /* sockfd, msg, len, flags */
62dc90c6 3531 return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
ff71a454 3532 case TARGET_SYS_SENDTO: /* sockfd, msg, len, flags, addr, addrlen */
62dc90c6 3533 return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
ff71a454 3534 case TARGET_SYS_RECVFROM: /* sockfd, msg, len, flags, addr, addrlen */
62dc90c6 3535 return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
ff71a454 3536 case TARGET_SYS_SHUTDOWN: /* sockfd, how */
62dc90c6 3537 return get_errno(shutdown(a[0], a[1]));
ff71a454
AM
3538 case TARGET_SYS_SETSOCKOPT: /* sockfd, level, optname, optval, optlen */
3539 return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
3540 case TARGET_SYS_GETSOCKOPT: /* sockfd, level, optname, optval, optlen */
3541 return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
3542 case TARGET_SYS_SENDMSG: /* sockfd, msg, flags */
62dc90c6 3543 return do_sendrecvmsg(a[0], a[1], a[2], 1);
ff71a454 3544 case TARGET_SYS_RECVMSG: /* sockfd, msg, flags */
62dc90c6 3545 return do_sendrecvmsg(a[0], a[1], a[2], 0);
ff71a454
AM
3546 case TARGET_SYS_ACCEPT4: /* sockfd, addr, addrlen, flags */
3547 return do_accept4(a[0], a[1], a[2], a[3]);
3548 case TARGET_SYS_RECVMMSG: /* sockfd, msgvec, vlen, flags */
5a53dc50 3549 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
ff71a454
AM
3550 case TARGET_SYS_SENDMMSG: /* sockfd, msgvec, vlen, flags */
3551 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
31e31b8a 3552 default:
39be5350 3553 qemu_log_mask(LOG_UNIMP, "Unsupported socketcall: %d\n", num);
ff71a454 3554 return -TARGET_EINVAL;
31e31b8a 3555 }
31e31b8a 3556}
32407103 3557#endif
31e31b8a 3558
8853f86e
FB
3559#define N_SHM_REGIONS 32
3560
3561static struct shm_region {
b6e17875
PM
3562 abi_ulong start;
3563 abi_ulong size;
3564 bool in_use;
8853f86e
FB
3565} shm_regions[N_SHM_REGIONS];
3566
005eb2ae
PM
3567#ifndef TARGET_SEMID64_DS
3568/* asm-generic version of this struct */
3569struct target_semid64_ds
3eb6b044
TS
3570{
3571 struct target_ipc_perm sem_perm;
992f48a0 3572 abi_ulong sem_otime;
005eb2ae 3573#if TARGET_ABI_BITS == 32
992f48a0 3574 abi_ulong __unused1;
03527344 3575#endif
992f48a0 3576 abi_ulong sem_ctime;
005eb2ae 3577#if TARGET_ABI_BITS == 32
992f48a0 3578 abi_ulong __unused2;
03527344 3579#endif
992f48a0
BS
3580 abi_ulong sem_nsems;
3581 abi_ulong __unused3;
3582 abi_ulong __unused4;
3eb6b044 3583};
005eb2ae 3584#endif
3eb6b044 3585
579a97f7
FB
3586static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
3587 abi_ulong target_addr)
3eb6b044
TS
3588{
3589 struct target_ipc_perm *target_ip;
005eb2ae 3590 struct target_semid64_ds *target_sd;
3eb6b044 3591
579a97f7
FB
3592 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3593 return -TARGET_EFAULT;
e8bbe36c 3594 target_ip = &(target_sd->sem_perm);
55a2b163
PJ
3595 host_ip->__key = tswap32(target_ip->__key);
3596 host_ip->uid = tswap32(target_ip->uid);
3597 host_ip->gid = tswap32(target_ip->gid);
3598 host_ip->cuid = tswap32(target_ip->cuid);
3599 host_ip->cgid = tswap32(target_ip->cgid);
3600#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3601 host_ip->mode = tswap32(target_ip->mode);
3602#else
cbb21eed 3603 host_ip->mode = tswap16(target_ip->mode);
55a2b163
PJ
3604#endif
3605#if defined(TARGET_PPC)
3606 host_ip->__seq = tswap32(target_ip->__seq);
3607#else
3608 host_ip->__seq = tswap16(target_ip->__seq);
3609#endif
3eb6b044 3610 unlock_user_struct(target_sd, target_addr, 0);
579a97f7 3611 return 0;
3eb6b044
TS
3612}
3613
579a97f7
FB
3614static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
3615 struct ipc_perm *host_ip)
3eb6b044
TS
3616{
3617 struct target_ipc_perm *target_ip;
005eb2ae 3618 struct target_semid64_ds *target_sd;
3eb6b044 3619
579a97f7
FB
3620 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3621 return -TARGET_EFAULT;
3eb6b044 3622 target_ip = &(target_sd->sem_perm);
55a2b163
PJ
3623 target_ip->__key = tswap32(host_ip->__key);
3624 target_ip->uid = tswap32(host_ip->uid);
3625 target_ip->gid = tswap32(host_ip->gid);
3626 target_ip->cuid = tswap32(host_ip->cuid);
3627 target_ip->cgid = tswap32(host_ip->cgid);
3628#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3629 target_ip->mode = tswap32(host_ip->mode);
3630#else
cbb21eed 3631 target_ip->mode = tswap16(host_ip->mode);
55a2b163
PJ
3632#endif
3633#if defined(TARGET_PPC)
3634 target_ip->__seq = tswap32(host_ip->__seq);
3635#else
3636 target_ip->__seq = tswap16(host_ip->__seq);
3637#endif
3eb6b044 3638 unlock_user_struct(target_sd, target_addr, 1);
579a97f7 3639 return 0;
3eb6b044
TS
3640}
3641
579a97f7
FB
3642static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
3643 abi_ulong target_addr)
3eb6b044 3644{
005eb2ae 3645 struct target_semid64_ds *target_sd;
3eb6b044 3646
579a97f7
FB
3647 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3648 return -TARGET_EFAULT;
e5289087
AJ
3649 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
3650 return -TARGET_EFAULT;
cbb21eed
MB
3651 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
3652 host_sd->sem_otime = tswapal(target_sd->sem_otime);
3653 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
3eb6b044 3654 unlock_user_struct(target_sd, target_addr, 0);
579a97f7 3655 return 0;
3eb6b044
TS
3656}
3657
579a97f7
FB
3658static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
3659 struct semid_ds *host_sd)
3eb6b044 3660{
005eb2ae 3661 struct target_semid64_ds *target_sd;
3eb6b044 3662
579a97f7
FB
3663 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3664 return -TARGET_EFAULT;
e5289087 3665 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
3a93113a 3666 return -TARGET_EFAULT;
cbb21eed
MB
3667 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
3668 target_sd->sem_otime = tswapal(host_sd->sem_otime);
3669 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
3eb6b044 3670 unlock_user_struct(target_sd, target_addr, 1);
579a97f7 3671 return 0;
3eb6b044
TS
3672}
3673
e5289087
AJ
3674struct target_seminfo {
3675 int semmap;
3676 int semmni;
3677 int semmns;
3678 int semmnu;
3679 int semmsl;
3680 int semopm;
3681 int semume;
3682 int semusz;
3683 int semvmx;
3684 int semaem;
3685};
3686
3687static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
3688 struct seminfo *host_seminfo)
3689{
3690 struct target_seminfo *target_seminfo;
3691 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
3692 return -TARGET_EFAULT;
3693 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
3694 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
3695 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
3696 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
3697 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
3698 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
3699 __put_user(host_seminfo->semume, &target_seminfo->semume);
3700 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
3701 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
3702 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
3703 unlock_user_struct(target_seminfo, target_addr, 1);
3704 return 0;
3705}
3706
fa294816
TS
3707union semun {
3708 int val;
3eb6b044 3709 struct semid_ds *buf;
fa294816 3710 unsigned short *array;
e5289087 3711 struct seminfo *__buf;
fa294816
TS
3712};
3713
3eb6b044
TS
3714union target_semun {
3715 int val;
e5289087
AJ
3716 abi_ulong buf;
3717 abi_ulong array;
3718 abi_ulong __buf;
3eb6b044
TS
3719};
3720
e5289087
AJ
3721static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
3722 abi_ulong target_addr)
3eb6b044 3723{
e5289087
AJ
3724 int nsems;
3725 unsigned short *array;
3726 union semun semun;
3727 struct semid_ds semid_ds;
3728 int i, ret;
3eb6b044 3729
e5289087
AJ
3730 semun.buf = &semid_ds;
3731
3732 ret = semctl(semid, 0, IPC_STAT, semun);
3733 if (ret == -1)
3734 return get_errno(ret);
3735
3736 nsems = semid_ds.sem_nsems;
3737
0e173b24 3738 *host_array = g_try_new(unsigned short, nsems);
69d4c703
PM
3739 if (!*host_array) {
3740 return -TARGET_ENOMEM;
3741 }
e5289087
AJ
3742 array = lock_user(VERIFY_READ, target_addr,
3743 nsems*sizeof(unsigned short), 1);
69d4c703 3744 if (!array) {
0e173b24 3745 g_free(*host_array);
e5289087 3746 return -TARGET_EFAULT;
69d4c703 3747 }
e5289087
AJ
3748
3749 for(i=0; i<nsems; i++) {
3750 __get_user((*host_array)[i], &array[i]);
3eb6b044 3751 }
e5289087
AJ
3752 unlock_user(array, target_addr, 0);
3753
579a97f7 3754 return 0;
3eb6b044
TS
3755}
3756
e5289087
AJ
3757static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
3758 unsigned short **host_array)
3eb6b044 3759{
e5289087
AJ
3760 int nsems;
3761 unsigned short *array;
3762 union semun semun;
3763 struct semid_ds semid_ds;
3764 int i, ret;
3eb6b044 3765
e5289087
AJ
3766 semun.buf = &semid_ds;
3767
3768 ret = semctl(semid, 0, IPC_STAT, semun);
3769 if (ret == -1)
3770 return get_errno(ret);
3771
3772 nsems = semid_ds.sem_nsems;
3773
3774 array = lock_user(VERIFY_WRITE, target_addr,
3775 nsems*sizeof(unsigned short), 0);
3776 if (!array)
3777 return -TARGET_EFAULT;
3778
3779 for(i=0; i<nsems; i++) {
3780 __put_user((*host_array)[i], &array[i]);
3eb6b044 3781 }
0e173b24 3782 g_free(*host_array);
e5289087
AJ
3783 unlock_user(array, target_addr, 1);
3784
579a97f7 3785 return 0;
3eb6b044
TS
3786}
3787
e5289087 3788static inline abi_long do_semctl(int semid, int semnum, int cmd,
d1c002b6 3789 abi_ulong target_arg)
3eb6b044 3790{
d1c002b6 3791 union target_semun target_su = { .buf = target_arg };
3eb6b044
TS
3792 union semun arg;
3793 struct semid_ds dsarg;
7b8118e8 3794 unsigned short *array = NULL;
e5289087
AJ
3795 struct seminfo seminfo;
3796 abi_long ret = -TARGET_EINVAL;
3797 abi_long err;
3798 cmd &= 0xff;
3eb6b044
TS
3799
3800 switch( cmd ) {
3801 case GETVAL:
3eb6b044 3802 case SETVAL:
5464baec
TM
3803 /* In 64 bit cross-endian situations, we will erroneously pick up
3804 * the wrong half of the union for the "val" element. To rectify
3805 * this, the entire 8-byte structure is byteswapped, followed by
3806 * a swap of the 4 byte val field. In other cases, the data is
3807 * already in proper host byte order. */
3808 if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
3809 target_su.buf = tswapal(target_su.buf);
3810 arg.val = tswap32(target_su.val);
3811 } else {
3812 arg.val = target_su.val;
3813 }
e5289087 3814 ret = get_errno(semctl(semid, semnum, cmd, arg));
3eb6b044
TS
3815 break;
3816 case GETALL:
3eb6b044 3817 case SETALL:
e5289087
AJ
3818 err = target_to_host_semarray(semid, &array, target_su.array);
3819 if (err)
3820 return err;
3821 arg.array = array;
3822 ret = get_errno(semctl(semid, semnum, cmd, arg));
3823 err = host_to_target_semarray(semid, target_su.array, &array);
3824 if (err)
3825 return err;
3eb6b044
TS
3826 break;
3827 case IPC_STAT:
3eb6b044 3828 case IPC_SET:
e5289087
AJ
3829 case SEM_STAT:
3830 err = target_to_host_semid_ds(&dsarg, target_su.buf);
3831 if (err)
3832 return err;
3833 arg.buf = &dsarg;
3834 ret = get_errno(semctl(semid, semnum, cmd, arg));
3835 err = host_to_target_semid_ds(target_su.buf, &dsarg);
3836 if (err)
3837 return err;
3838 break;
3839 case IPC_INFO:
3840 case SEM_INFO:
3841 arg.__buf = &seminfo;
3842 ret = get_errno(semctl(semid, semnum, cmd, arg));
3843 err = host_to_target_seminfo(target_su.__buf, &seminfo);
3844 if (err)
3845 return err;
3846 break;
3847 case IPC_RMID:
3848 case GETPID:
3849 case GETNCNT:
3850 case GETZCNT:
3851 ret = get_errno(semctl(semid, semnum, cmd, NULL));
3eb6b044 3852 break;
3eb6b044
TS
3853 }
3854
3855 return ret;
3856}
3857
e5289087
AJ
3858struct target_sembuf {
3859 unsigned short sem_num;
3860 short sem_op;
3861 short sem_flg;
3862};
3863
3864static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
3865 abi_ulong target_addr,
3866 unsigned nsops)
3867{
3868 struct target_sembuf *target_sembuf;
3869 int i;
3870
3871 target_sembuf = lock_user(VERIFY_READ, target_addr,
3872 nsops*sizeof(struct target_sembuf), 1);
3873 if (!target_sembuf)
3874 return -TARGET_EFAULT;
3875
3876 for(i=0; i<nsops; i++) {
3877 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
3878 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
3879 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
3880 }
3881
3882 unlock_user(target_sembuf, target_addr, 0);
3883
3884 return 0;
3885}
3886
d8c08b1e
MK
3887#if defined(TARGET_NR_ipc) || defined(TARGET_NR_semop) || \
3888 defined(TARGET_NR_semtimedop)
3889
3890/*
3891 * This macro is required to handle the s390 variants, which passes the
3892 * arguments in a different order than default.
3893 */
3894#ifdef __s390x__
3895#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
3896 (__nsops), (__timeout), (__sops)
3897#else
3898#define SEMTIMEDOP_IPC_ARGS(__nsops, __sops, __timeout) \
3899 (__nsops), 0, (__sops), (__timeout)
3900#endif
3901
3902static inline abi_long do_semtimedop(int semid,
3903 abi_long ptr,
3904 unsigned nsops,
3905 abi_long timeout)
e5289087
AJ
3906{
3907 struct sembuf sops[nsops];
d8c08b1e 3908 struct timespec ts, *pts = NULL;
524fa340 3909 abi_long ret;
e5289087 3910
d8c08b1e
MK
3911 if (timeout) {
3912 pts = &ts;
3913 if (target_to_host_timespec(pts, timeout)) {
3914 return -TARGET_EFAULT;
3915 }
3916 }
3917
e5289087
AJ
3918 if (target_to_host_sembuf(sops, ptr, nsops))
3919 return -TARGET_EFAULT;
3920
524fa340
LV
3921 ret = -TARGET_ENOSYS;
3922#ifdef __NR_semtimedop
d8c08b1e 3923 ret = get_errno(safe_semtimedop(semid, sops, nsops, pts));
524fa340
LV
3924#endif
3925#ifdef __NR_ipc
3926 if (ret == -TARGET_ENOSYS) {
d8c08b1e
MK
3927 ret = get_errno(safe_ipc(IPCOP_semtimedop, semid,
3928 SEMTIMEDOP_IPC_ARGS(nsops, sops, (long)pts)));
524fa340
LV
3929 }
3930#endif
3931 return ret;
e5289087 3932}
d8c08b1e 3933#endif
e5289087 3934
1bc012f6
TS
3935struct target_msqid_ds
3936{
1c54ff97
AJ
3937 struct target_ipc_perm msg_perm;
3938 abi_ulong msg_stime;
3939#if TARGET_ABI_BITS == 32
3940 abi_ulong __unused1;
3941#endif
3942 abi_ulong msg_rtime;
3943#if TARGET_ABI_BITS == 32
3944 abi_ulong __unused2;
3945#endif
3946 abi_ulong msg_ctime;
3947#if TARGET_ABI_BITS == 32
3948 abi_ulong __unused3;
3949#endif
3950 abi_ulong __msg_cbytes;
3951 abi_ulong msg_qnum;
3952 abi_ulong msg_qbytes;
3953 abi_ulong msg_lspid;
3954 abi_ulong msg_lrpid;
3955 abi_ulong __unused4;
3956 abi_ulong __unused5;
1bc012f6
TS
3957};
3958
579a97f7
FB
3959static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
3960 abi_ulong target_addr)
1bc012f6
TS
3961{
3962 struct target_msqid_ds *target_md;
3963
579a97f7
FB
3964 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
3965 return -TARGET_EFAULT;
1c54ff97
AJ
3966 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
3967 return -TARGET_EFAULT;
cbb21eed
MB
3968 host_md->msg_stime = tswapal(target_md->msg_stime);
3969 host_md->msg_rtime = tswapal(target_md->msg_rtime);
3970 host_md->msg_ctime = tswapal(target_md->msg_ctime);
3971 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
3972 host_md->msg_qnum = tswapal(target_md->msg_qnum);
3973 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
3974 host_md->msg_lspid = tswapal(target_md->msg_lspid);
3975 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
1bc012f6 3976 unlock_user_struct(target_md, target_addr, 0);
579a97f7 3977 return 0;
1bc012f6
TS
3978}
3979
579a97f7
FB
3980static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
3981 struct msqid_ds *host_md)
1bc012f6
TS
3982{
3983 struct target_msqid_ds *target_md;
3984
579a97f7
FB
3985 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
3986 return -TARGET_EFAULT;
1c54ff97
AJ
3987 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
3988 return -TARGET_EFAULT;
cbb21eed
MB
3989 target_md->msg_stime = tswapal(host_md->msg_stime);
3990 target_md->msg_rtime = tswapal(host_md->msg_rtime);
3991 target_md->msg_ctime = tswapal(host_md->msg_ctime);
3992 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
3993 target_md->msg_qnum = tswapal(host_md->msg_qnum);
3994 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
3995 target_md->msg_lspid = tswapal(host_md->msg_lspid);
3996 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
1bc012f6 3997 unlock_user_struct(target_md, target_addr, 1);
579a97f7 3998 return 0;
1bc012f6
TS
3999}
4000
1c54ff97
AJ
4001struct target_msginfo {
4002 int msgpool;
4003 int msgmap;
4004 int msgmax;
4005 int msgmnb;
4006 int msgmni;
4007 int msgssz;
4008 int msgtql;
4009 unsigned short int msgseg;
4010};
4011
4012static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
4013 struct msginfo *host_msginfo)
4014{
4015 struct target_msginfo *target_msginfo;
4016 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
4017 return -TARGET_EFAULT;
4018 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
4019 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
4020 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
4021 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
4022 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
4023 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
4024 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
4025 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
4026 unlock_user_struct(target_msginfo, target_addr, 1);
00b229ac 4027 return 0;
1c54ff97
AJ
4028}
4029
4030static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
1bc012f6
TS
4031{
4032 struct msqid_ds dsarg;
1c54ff97
AJ
4033 struct msginfo msginfo;
4034 abi_long ret = -TARGET_EINVAL;
4035
4036 cmd &= 0xff;
4037
4038 switch (cmd) {
1bc012f6
TS
4039 case IPC_STAT:
4040 case IPC_SET:
1c54ff97
AJ
4041 case MSG_STAT:
4042 if (target_to_host_msqid_ds(&dsarg,ptr))
4043 return -TARGET_EFAULT;
4044 ret = get_errno(msgctl(msgid, cmd, &dsarg));
4045 if (host_to_target_msqid_ds(ptr,&dsarg))
4046 return -TARGET_EFAULT;
4047 break;
4048 case IPC_RMID:
4049 ret = get_errno(msgctl(msgid, cmd, NULL));
4050 break;
4051 case IPC_INFO:
4052 case MSG_INFO:
4053 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
4054 if (host_to_target_msginfo(ptr, &msginfo))
4055 return -TARGET_EFAULT;
4056 break;
1bc012f6 4057 }
1c54ff97 4058
1bc012f6
TS
4059 return ret;
4060}
4061
4062struct target_msgbuf {
1c54ff97
AJ
4063 abi_long mtype;
4064 char mtext[1];
1bc012f6
TS
4065};
4066
992f48a0 4067static inline abi_long do_msgsnd(int msqid, abi_long msgp,
edcc5f9d 4068 ssize_t msgsz, int msgflg)
1bc012f6
TS
4069{
4070 struct target_msgbuf *target_mb;
4071 struct msgbuf *host_mb;
992f48a0 4072 abi_long ret = 0;
1bc012f6 4073
edcc5f9d
TM
4074 if (msgsz < 0) {
4075 return -TARGET_EINVAL;
4076 }
4077
579a97f7
FB
4078 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
4079 return -TARGET_EFAULT;
0e173b24 4080 host_mb = g_try_malloc(msgsz + sizeof(long));
29e03fcb
HZ
4081 if (!host_mb) {
4082 unlock_user_struct(target_mb, msgp, 0);
4083 return -TARGET_ENOMEM;
4084 }
cbb21eed 4085 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
1c54ff97 4086 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
524fa340
LV
4087 ret = -TARGET_ENOSYS;
4088#ifdef __NR_msgsnd
89f9fe44 4089 ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
524fa340
LV
4090#endif
4091#ifdef __NR_ipc
4092 if (ret == -TARGET_ENOSYS) {
d8c08b1e
MK
4093#ifdef __s390x__
4094 ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
4095 host_mb));
4096#else
524fa340
LV
4097 ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
4098 host_mb, 0));
d8c08b1e 4099#endif
524fa340
LV
4100 }
4101#endif
0e173b24 4102 g_free(host_mb);
1bc012f6
TS
4103 unlock_user_struct(target_mb, msgp, 0);
4104
4105 return ret;
4106}
4107
d8c08b1e
MK
4108#ifdef __NR_ipc
4109#if defined(__sparc__)
4110/* SPARC for msgrcv it does not use the kludge on final 2 arguments. */
4111#define MSGRCV_ARGS(__msgp, __msgtyp) __msgp, __msgtyp
4112#elif defined(__s390x__)
4113/* The s390 sys_ipc variant has only five parameters. */
4114#define MSGRCV_ARGS(__msgp, __msgtyp) \
4115 ((long int[]){(long int)__msgp, __msgtyp})
4116#else
4117#define MSGRCV_ARGS(__msgp, __msgtyp) \
4118 ((long int[]){(long int)__msgp, __msgtyp}), 0
4119#endif
4120#endif
4121
992f48a0 4122static inline abi_long do_msgrcv(int msqid, abi_long msgp,
99874f65 4123 ssize_t msgsz, abi_long msgtyp,
992f48a0 4124 int msgflg)
1bc012f6
TS
4125{
4126 struct target_msgbuf *target_mb;
579a97f7 4127 char *target_mtext;
1bc012f6 4128 struct msgbuf *host_mb;
992f48a0 4129 abi_long ret = 0;
1bc012f6 4130
99874f65
PM
4131 if (msgsz < 0) {
4132 return -TARGET_EINVAL;
4133 }
4134
579a97f7
FB
4135 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
4136 return -TARGET_EFAULT;
1c54ff97 4137
415d8471
PM
4138 host_mb = g_try_malloc(msgsz + sizeof(long));
4139 if (!host_mb) {
4140 ret = -TARGET_ENOMEM;
4141 goto end;
4142 }
524fa340
LV
4143 ret = -TARGET_ENOSYS;
4144#ifdef __NR_msgrcv
89f9fe44 4145 ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
524fa340
LV
4146#endif
4147#ifdef __NR_ipc
4148 if (ret == -TARGET_ENOSYS) {
4149 ret = get_errno(safe_ipc(IPCOP_CALL(1, IPCOP_msgrcv), msqid, msgsz,
d8c08b1e 4150 msgflg, MSGRCV_ARGS(host_mb, msgtyp)));
524fa340
LV
4151 }
4152#endif
1c54ff97 4153
579a97f7
FB
4154 if (ret > 0) {
4155 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
4156 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
4157 if (!target_mtext) {
4158 ret = -TARGET_EFAULT;
4159 goto end;
4160 }
1c54ff97 4161 memcpy(target_mb->mtext, host_mb->mtext, ret);
579a97f7
FB
4162 unlock_user(target_mtext, target_mtext_addr, ret);
4163 }
1c54ff97 4164
cbb21eed 4165 target_mb->mtype = tswapal(host_mb->mtype);
1bc012f6 4166
579a97f7
FB
4167end:
4168 if (target_mb)
4169 unlock_user_struct(target_mb, msgp, 1);
0d07fe47 4170 g_free(host_mb);
1bc012f6
TS
4171 return ret;
4172}
4173
88a8c984
RV
4174static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
4175 abi_ulong target_addr)
4176{
4177 struct target_shmid_ds *target_sd;
4178
4179 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
4180 return -TARGET_EFAULT;
4181 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
4182 return -TARGET_EFAULT;
4183 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
4184 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
4185 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
4186 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
4187 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
4188 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
4189 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
4190 unlock_user_struct(target_sd, target_addr, 0);
4191 return 0;
4192}
4193
4194static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
4195 struct shmid_ds *host_sd)
4196{
4197 struct target_shmid_ds *target_sd;
4198
4199 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
4200 return -TARGET_EFAULT;
4201 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
4202 return -TARGET_EFAULT;
4203 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
4204 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
4205 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
4206 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
4207 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
4208 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
4209 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
4210 unlock_user_struct(target_sd, target_addr, 1);
4211 return 0;
4212}
4213
4214struct target_shminfo {
4215 abi_ulong shmmax;
4216 abi_ulong shmmin;
4217 abi_ulong shmmni;
4218 abi_ulong shmseg;
4219 abi_ulong shmall;
4220};
4221
4222static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
4223 struct shminfo *host_shminfo)
4224{
4225 struct target_shminfo *target_shminfo;
4226 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
4227 return -TARGET_EFAULT;
4228 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
4229 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
4230 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
4231 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
4232 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
4233 unlock_user_struct(target_shminfo, target_addr, 1);
4234 return 0;
4235}
4236
4237struct target_shm_info {
4238 int used_ids;
4239 abi_ulong shm_tot;
4240 abi_ulong shm_rss;
4241 abi_ulong shm_swp;
4242 abi_ulong swap_attempts;
4243 abi_ulong swap_successes;
4244};
4245
4246static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
4247 struct shm_info *host_shm_info)
4248{
4249 struct target_shm_info *target_shm_info;
4250 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
4251 return -TARGET_EFAULT;
4252 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
4253 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
4254 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
4255 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
4256 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
4257 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
4258 unlock_user_struct(target_shm_info, target_addr, 1);
4259 return 0;
4260}
4261
4262static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
4263{
4264 struct shmid_ds dsarg;
4265 struct shminfo shminfo;
4266 struct shm_info shm_info;
4267 abi_long ret = -TARGET_EINVAL;
4268
4269 cmd &= 0xff;
4270
4271 switch(cmd) {
4272 case IPC_STAT:
4273 case IPC_SET:
4274 case SHM_STAT:
4275 if (target_to_host_shmid_ds(&dsarg, buf))
4276 return -TARGET_EFAULT;
4277 ret = get_errno(shmctl(shmid, cmd, &dsarg));
4278 if (host_to_target_shmid_ds(buf, &dsarg))
4279 return -TARGET_EFAULT;
4280 break;
4281 case IPC_INFO:
4282 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
4283 if (host_to_target_shminfo(buf, &shminfo))
4284 return -TARGET_EFAULT;
4285 break;
4286 case SHM_INFO:
4287 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
4288 if (host_to_target_shm_info(buf, &shm_info))
4289 return -TARGET_EFAULT;
4290 break;
4291 case IPC_RMID:
4292 case SHM_LOCK:
4293 case SHM_UNLOCK:
4294 ret = get_errno(shmctl(shmid, cmd, NULL));
4295 break;
4296 }
4297
4298 return ret;
4299}
4300
ee8e7614
PM
4301#ifndef TARGET_FORCE_SHMLBA
4302/* For most architectures, SHMLBA is the same as the page size;
4303 * some architectures have larger values, in which case they should
4304 * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
4305 * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
4306 * and defining its own value for SHMLBA.
4307 *
4308 * The kernel also permits SHMLBA to be set by the architecture to a
4309 * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
4310 * this means that addresses are rounded to the large size if
4311 * SHM_RND is set but addresses not aligned to that size are not rejected
4312 * as long as they are at least page-aligned. Since the only architecture
4313 * which uses this is ia64 this code doesn't provide for that oddity.
4314 */
4315static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
4316{
4317 return TARGET_PAGE_SIZE;
4318}
4319#endif
4320
4321static inline abi_ulong do_shmat(CPUArchState *cpu_env,
4322 int shmid, abi_ulong shmaddr, int shmflg)
88a8c984
RV
4323{
4324 abi_long raddr;
4325 void *host_raddr;
4326 struct shmid_ds shm_info;
4327 int i,ret;
ee8e7614 4328 abi_ulong shmlba;
88a8c984
RV
4329
4330 /* find out the length of the shared memory segment */
4331 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
4332 if (is_error(ret)) {
4333 /* can't get length, bail out */
4334 return ret;
4335 }
4336
ee8e7614
PM
4337 shmlba = target_shmlba(cpu_env);
4338
4339 if (shmaddr & (shmlba - 1)) {
4340 if (shmflg & SHM_RND) {
4341 shmaddr &= ~(shmlba - 1);
4342 } else {
4343 return -TARGET_EINVAL;
4344 }
4345 }
ebf9a363
MF
4346 if (!guest_range_valid(shmaddr, shm_info.shm_segsz)) {
4347 return -TARGET_EINVAL;
4348 }
ee8e7614 4349
88a8c984
RV
4350 mmap_lock();
4351
4352 if (shmaddr)
4353 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
4354 else {
4355 abi_ulong mmap_start;
4356
30ab9ef2
RH
4357 /* In order to use the host shmat, we need to honor host SHMLBA. */
4358 mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
88a8c984
RV
4359
4360 if (mmap_start == -1) {
4361 errno = ENOMEM;
4362 host_raddr = (void *)-1;
4363 } else
4364 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
4365 }
4366
4367 if (host_raddr == (void *)-1) {
4368 mmap_unlock();
4369 return get_errno((long)host_raddr);
4370 }
4371 raddr=h2g((unsigned long)host_raddr);
4372
4373 page_set_flags(raddr, raddr + shm_info.shm_segsz,
4374 PAGE_VALID | PAGE_READ |
4375 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
4376
4377 for (i = 0; i < N_SHM_REGIONS; i++) {
b6e17875
PM
4378 if (!shm_regions[i].in_use) {
4379 shm_regions[i].in_use = true;
88a8c984
RV
4380 shm_regions[i].start = raddr;
4381 shm_regions[i].size = shm_info.shm_segsz;
4382 break;
4383 }
4384 }
4385
4386 mmap_unlock();
4387 return raddr;
4388
4389}
4390
4391static inline abi_long do_shmdt(abi_ulong shmaddr)
4392{
4393 int i;
3c5f6a5f
MF
4394 abi_long rv;
4395
4396 mmap_lock();
88a8c984
RV
4397
4398 for (i = 0; i < N_SHM_REGIONS; ++i) {
b6e17875
PM
4399 if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
4400 shm_regions[i].in_use = false;
e00ac249 4401 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
88a8c984
RV
4402 break;
4403 }
4404 }
3c5f6a5f 4405 rv = get_errno(shmdt(g2h(shmaddr)));
88a8c984 4406
3c5f6a5f 4407 mmap_unlock();
88a8c984 4408
3c5f6a5f 4409 return rv;
88a8c984
RV
4410}
4411
1c54ff97 4412#ifdef TARGET_NR_ipc
53a5960a 4413/* ??? This only works with linear mappings. */
0da46a6e 4414/* do_ipc() must return target values and target errnos. */
ee8e7614
PM
4415static abi_long do_ipc(CPUArchState *cpu_env,
4416 unsigned int call, abi_long first,
37ed0956 4417 abi_long second, abi_long third,
992f48a0 4418 abi_long ptr, abi_long fifth)
8853f86e
FB
4419{
4420 int version;
992f48a0 4421 abi_long ret = 0;
8853f86e
FB
4422
4423 version = call >> 16;
4424 call &= 0xffff;
4425
4426 switch (call) {
fa294816 4427 case IPCOP_semop:
d8c08b1e
MK
4428 ret = do_semtimedop(first, ptr, second, 0);
4429 break;
4430 case IPCOP_semtimedop:
4431 /*
4432 * The s390 sys_ipc variant has only five parameters instead of six
4433 * (as for default variant) and the only difference is the handling of
4434 * SEMTIMEDOP where on s390 the third parameter is used as a pointer
4435 * to a struct timespec where the generic variant uses fifth parameter.
4436 */
4437#if defined(TARGET_S390X)
4438 ret = do_semtimedop(first, ptr, second, third);
4439#else
4440 ret = do_semtimedop(first, ptr, second, fifth);
4441#endif
fa294816
TS
4442 break;
4443
4444 case IPCOP_semget:
4445 ret = get_errno(semget(first, second, third));
4446 break;
4447
5d2fa8eb
TM
4448 case IPCOP_semctl: {
4449 /* The semun argument to semctl is passed by value, so dereference the
4450 * ptr argument. */
4451 abi_ulong atptr;
37ed0956 4452 get_user_ual(atptr, ptr);
d1c002b6 4453 ret = do_semctl(first, second, third, atptr);
fa294816 4454 break;
5d2fa8eb 4455 }
d96372ef 4456
1c54ff97
AJ
4457 case IPCOP_msgget:
4458 ret = get_errno(msgget(first, second));
4459 break;
d96372ef 4460
1c54ff97
AJ
4461 case IPCOP_msgsnd:
4462 ret = do_msgsnd(first, ptr, second, third);
4463 break;
d96372ef 4464
1c54ff97
AJ
4465 case IPCOP_msgctl:
4466 ret = do_msgctl(first, second, ptr);
4467 break;
d96372ef 4468
1c54ff97
AJ
4469 case IPCOP_msgrcv:
4470 switch (version) {
4471 case 0:
4472 {
4473 struct target_ipc_kludge {
4474 abi_long msgp;
4475 abi_long msgtyp;
4476 } *tmp;
4477
4478 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
4479 ret = -TARGET_EFAULT;
4480 break;
4481 }
d96372ef 4482
79dd77de 4483 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
d96372ef 4484
1c54ff97
AJ
4485 unlock_user_struct(tmp, ptr, 0);
4486 break;
4487 }
4488 default:
4489 ret = do_msgrcv(first, ptr, second, fifth, third);
4490 }
4491 break;
d96372ef 4492
8853f86e 4493 case IPCOP_shmat:
88a8c984
RV
4494 switch (version) {
4495 default:
5a4a898d
FB
4496 {
4497 abi_ulong raddr;
ee8e7614 4498 raddr = do_shmat(cpu_env, first, ptr, second);
88a8c984
RV
4499 if (is_error(raddr))
4500 return get_errno(raddr);
2f619698 4501 if (put_user_ual(raddr, third))
5a4a898d 4502 return -TARGET_EFAULT;
88a8c984
RV
4503 break;
4504 }
4505 case 1:
4506 ret = -TARGET_EINVAL;
4507 break;
5a4a898d 4508 }
8853f86e
FB
4509 break;
4510 case IPCOP_shmdt:
88a8c984 4511 ret = do_shmdt(ptr);
8853f86e
FB
4512 break;
4513
4514 case IPCOP_shmget:
4515 /* IPC_* flag values are the same on all linux platforms */
4516 ret = get_errno(shmget(first, second, third));
4517 break;
4518
4519 /* IPC_* and SHM_* command values are the same on all linux platforms */
4520 case IPCOP_shmctl:
a2926784 4521 ret = do_shmctl(first, second, ptr);
8853f86e
FB
4522 break;
4523 default:
39be5350
JK
4524 qemu_log_mask(LOG_UNIMP, "Unsupported ipc call: %d (version %d)\n",
4525 call, version);
0da46a6e 4526 ret = -TARGET_ENOSYS;
8853f86e
FB
4527 break;
4528 }
4529 return ret;
4530}
32407103 4531#endif
8853f86e 4532
31e31b8a 4533/* kernel structure types definitions */
31e31b8a 4534
001faf32 4535#define STRUCT(name, ...) STRUCT_ ## name,
31e31b8a
FB
4536#define STRUCT_SPECIAL(name) STRUCT_ ## name,
4537enum {
4538#include "syscall_types.h"
8be656b8 4539STRUCT_MAX
31e31b8a
FB
4540};
4541#undef STRUCT
4542#undef STRUCT_SPECIAL
4543
001faf32 4544#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
31e31b8a
FB
4545#define STRUCT_SPECIAL(name)
4546#include "syscall_types.h"
4547#undef STRUCT
4548#undef STRUCT_SPECIAL
4549
31e31b8a
FB
4550#define MAX_STRUCT_SIZE 4096
4551
dace20dc 4552#ifdef CONFIG_FIEMAP
285da2b9
PM
4553/* So fiemap access checks don't overflow on 32 bit systems.
4554 * This is very slightly smaller than the limit imposed by
4555 * the underlying kernel.
4556 */
4557#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
4558 / sizeof(struct fiemap_extent))
4559
4560static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 4561 int fd, int cmd, abi_long arg)
285da2b9
PM
4562{
4563 /* The parameter for this ioctl is a struct fiemap followed
4564 * by an array of struct fiemap_extent whose size is set
4565 * in fiemap->fm_extent_count. The array is filled in by the
4566 * ioctl.
4567 */
4568 int target_size_in, target_size_out;
4569 struct fiemap *fm;
4570 const argtype *arg_type = ie->arg_type;
4571 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
4572 void *argptr, *p;
4573 abi_long ret;
4574 int i, extent_size = thunk_type_size(extent_arg_type, 0);
4575 uint32_t outbufsz;
4576 int free_fm = 0;
4577
4578 assert(arg_type[0] == TYPE_PTR);
4579 assert(ie->access == IOC_RW);
4580 arg_type++;
4581 target_size_in = thunk_type_size(arg_type, 0);
4582 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
4583 if (!argptr) {
4584 return -TARGET_EFAULT;
4585 }
4586 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4587 unlock_user(argptr, arg, 0);
4588 fm = (struct fiemap *)buf_temp;
4589 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
4590 return -TARGET_EINVAL;
4591 }
4592
4593 outbufsz = sizeof (*fm) +
4594 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
4595
4596 if (outbufsz > MAX_STRUCT_SIZE) {
4597 /* We can't fit all the extents into the fixed size buffer.
4598 * Allocate one that is large enough and use it instead.
4599 */
0e173b24 4600 fm = g_try_malloc(outbufsz);
285da2b9
PM
4601 if (!fm) {
4602 return -TARGET_ENOMEM;
4603 }
4604 memcpy(fm, buf_temp, sizeof(struct fiemap));
4605 free_fm = 1;
4606 }
49ca6f3e 4607 ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm));
285da2b9
PM
4608 if (!is_error(ret)) {
4609 target_size_out = target_size_in;
4610 /* An extent_count of 0 means we were only counting the extents
4611 * so there are no structs to copy
4612 */
4613 if (fm->fm_extent_count != 0) {
4614 target_size_out += fm->fm_mapped_extents * extent_size;
4615 }
4616 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
4617 if (!argptr) {
4618 ret = -TARGET_EFAULT;
4619 } else {
4620 /* Convert the struct fiemap */
4621 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
4622 if (fm->fm_extent_count != 0) {
4623 p = argptr + target_size_in;
4624 /* ...and then all the struct fiemap_extents */
4625 for (i = 0; i < fm->fm_mapped_extents; i++) {
4626 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
4627 THUNK_TARGET);
4628 p += extent_size;
4629 }
4630 }
4631 unlock_user(argptr, arg, target_size_out);
4632 }
4633 }
4634 if (free_fm) {
0e173b24 4635 g_free(fm);
285da2b9
PM
4636 }
4637 return ret;
4638}
dace20dc 4639#endif
285da2b9 4640
059c2f2c 4641static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 4642 int fd, int cmd, abi_long arg)
059c2f2c
LV
4643{
4644 const argtype *arg_type = ie->arg_type;
4645 int target_size;
4646 void *argptr;
4647 int ret;
4648 struct ifconf *host_ifconf;
4649 uint32_t outbufsz;
4650 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
4651 int target_ifreq_size;
4652 int nb_ifreq;
4653 int free_buf = 0;
4654 int i;
4655 int target_ifc_len;
4656 abi_long target_ifc_buf;
4657 int host_ifc_len;
4658 char *host_ifc_buf;
4659
4660 assert(arg_type[0] == TYPE_PTR);
4661 assert(ie->access == IOC_RW);
4662
4663 arg_type++;
4664 target_size = thunk_type_size(arg_type, 0);
4665
4666 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4667 if (!argptr)
4668 return -TARGET_EFAULT;
4669 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4670 unlock_user(argptr, arg, 0);
4671
4672 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
059c2f2c 4673 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
059c2f2c 4674 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
059c2f2c 4675
22e4a267
KL
4676 if (target_ifc_buf != 0) {
4677 target_ifc_len = host_ifconf->ifc_len;
4678 nb_ifreq = target_ifc_len / target_ifreq_size;
4679 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
4680
4681 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
4682 if (outbufsz > MAX_STRUCT_SIZE) {
4683 /*
4684 * We can't fit all the extents into the fixed size buffer.
4685 * Allocate one that is large enough and use it instead.
4686 */
4687 host_ifconf = malloc(outbufsz);
4688 if (!host_ifconf) {
4689 return -TARGET_ENOMEM;
4690 }
4691 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
4692 free_buf = 1;
059c2f2c 4693 }
22e4a267 4694 host_ifc_buf = (char *)host_ifconf + sizeof(*host_ifconf);
059c2f2c 4695
22e4a267
KL
4696 host_ifconf->ifc_len = host_ifc_len;
4697 } else {
4698 host_ifc_buf = NULL;
4699 }
059c2f2c
LV
4700 host_ifconf->ifc_buf = host_ifc_buf;
4701
49ca6f3e 4702 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
059c2f2c
LV
4703 if (!is_error(ret)) {
4704 /* convert host ifc_len to target ifc_len */
4705
4706 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
4707 target_ifc_len = nb_ifreq * target_ifreq_size;
4708 host_ifconf->ifc_len = target_ifc_len;
4709
4710 /* restore target ifc_buf */
4711
4712 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
4713
4714 /* copy struct ifconf to target user */
4715
4716 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4717 if (!argptr)
4718 return -TARGET_EFAULT;
4719 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
4720 unlock_user(argptr, arg, target_size);
4721
22e4a267
KL
4722 if (target_ifc_buf != 0) {
4723 /* copy ifreq[] to target user */
4724 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
4725 for (i = 0; i < nb_ifreq ; i++) {
4726 thunk_convert(argptr + i * target_ifreq_size,
4727 host_ifc_buf + i * sizeof(struct ifreq),
4728 ifreq_arg_type, THUNK_TARGET);
4729 }
4730 unlock_user(argptr, target_ifc_buf, target_ifc_len);
059c2f2c 4731 }
059c2f2c
LV
4732 }
4733
4734 if (free_buf) {
4735 free(host_ifconf);
4736 }
4737
4738 return ret;
4739}
4740
a133367e
CT
4741#if defined(CONFIG_USBFS)
4742#if HOST_LONG_BITS > 64
4743#error USBDEVFS thunks do not support >64 bit hosts yet.
4744#endif
4745struct live_urb {
4746 uint64_t target_urb_adr;
4747 uint64_t target_buf_adr;
4748 char *target_buf_ptr;
4749 struct usbdevfs_urb host_urb;
4750};
4751
4752static GHashTable *usbdevfs_urb_hashtable(void)
4753{
4754 static GHashTable *urb_hashtable;
4755
4756 if (!urb_hashtable) {
4757 urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal);
4758 }
4759 return urb_hashtable;
4760}
4761
4762static void urb_hashtable_insert(struct live_urb *urb)
4763{
4764 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
4765 g_hash_table_insert(urb_hashtable, urb, urb);
4766}
4767
4768static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr)
4769{
4770 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
4771 return g_hash_table_lookup(urb_hashtable, &target_urb_adr);
4772}
4773
4774static void urb_hashtable_remove(struct live_urb *urb)
4775{
4776 GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
4777 g_hash_table_remove(urb_hashtable, urb);
4778}
4779
4780static abi_long
4781do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp,
4782 int fd, int cmd, abi_long arg)
4783{
4784 const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) };
4785 const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 };
4786 struct live_urb *lurb;
4787 void *argptr;
4788 uint64_t hurb;
4789 int target_size;
4790 uintptr_t target_urb_adr;
4791 abi_long ret;
4792
4793 target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET);
4794
4795 memset(buf_temp, 0, sizeof(uint64_t));
4796 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4797 if (is_error(ret)) {
4798 return ret;
4799 }
4800
4801 memcpy(&hurb, buf_temp, sizeof(uint64_t));
4802 lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb));
4803 if (!lurb->target_urb_adr) {
4804 return -TARGET_EFAULT;
4805 }
4806 urb_hashtable_remove(lurb);
4807 unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr,
4808 lurb->host_urb.buffer_length);
4809 lurb->target_buf_ptr = NULL;
4810
4811 /* restore the guest buffer pointer */
4812 lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr;
4813
4814 /* update the guest urb struct */
4815 argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0);
4816 if (!argptr) {
4817 g_free(lurb);
4818 return -TARGET_EFAULT;
4819 }
4820 thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET);
4821 unlock_user(argptr, lurb->target_urb_adr, target_size);
4822
4823 target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET);
4824 /* write back the urb handle */
4825 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4826 if (!argptr) {
4827 g_free(lurb);
4828 return -TARGET_EFAULT;
4829 }
4830
4831 /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */
4832 target_urb_adr = lurb->target_urb_adr;
4833 thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET);
4834 unlock_user(argptr, arg, target_size);
4835
4836 g_free(lurb);
4837 return ret;
4838}
4839
4840static abi_long
4841do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie,
4842 uint8_t *buf_temp __attribute__((unused)),
4843 int fd, int cmd, abi_long arg)
4844{
4845 struct live_urb *lurb;
4846
4847 /* map target address back to host URB with metadata. */
4848 lurb = urb_hashtable_lookup(arg);
4849 if (!lurb) {
4850 return -TARGET_EFAULT;
4851 }
4852 return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
4853}
4854
4855static abi_long
4856do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp,
4857 int fd, int cmd, abi_long arg)
4858{
4859 const argtype *arg_type = ie->arg_type;
4860 int target_size;
4861 abi_long ret;
4862 void *argptr;
4863 int rw_dir;
4864 struct live_urb *lurb;
4865
4866 /*
4867 * each submitted URB needs to map to a unique ID for the
4868 * kernel, and that unique ID needs to be a pointer to
4869 * host memory. hence, we need to malloc for each URB.
4870 * isochronous transfers have a variable length struct.
4871 */
4872 arg_type++;
4873 target_size = thunk_type_size(arg_type, THUNK_TARGET);
4874
4875 /* construct host copy of urb and metadata */
4876 lurb = g_try_malloc0(sizeof(struct live_urb));
4877 if (!lurb) {
4878 return -TARGET_ENOMEM;
4879 }
4880
4881 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4882 if (!argptr) {
4883 g_free(lurb);
4884 return -TARGET_EFAULT;
4885 }
4886 thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST);
4887 unlock_user(argptr, arg, 0);
4888
4889 lurb->target_urb_adr = arg;
4890 lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer;
4891
4892 /* buffer space used depends on endpoint type so lock the entire buffer */
4893 /* control type urbs should check the buffer contents for true direction */
4894 rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ;
4895 lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr,
4896 lurb->host_urb.buffer_length, 1);
4897 if (lurb->target_buf_ptr == NULL) {
4898 g_free(lurb);
4899 return -TARGET_EFAULT;
4900 }
4901
4902 /* update buffer pointer in host copy */
4903 lurb->host_urb.buffer = lurb->target_buf_ptr;
4904
4905 ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
4906 if (is_error(ret)) {
4907 unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0);
4908 g_free(lurb);
4909 } else {
4910 urb_hashtable_insert(lurb);
4911 }
4912
4913 return ret;
4914}
4915#endif /* CONFIG_USBFS */
4916
56e904ec 4917static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
45c874eb 4918 int cmd, abi_long arg)
56e904ec
AG
4919{
4920 void *argptr;
4921 struct dm_ioctl *host_dm;
4922 abi_long guest_data;
4923 uint32_t guest_data_size;
4924 int target_size;
4925 const argtype *arg_type = ie->arg_type;
4926 abi_long ret;
4927 void *big_buf = NULL;
4928 char *host_data;
4929
4930 arg_type++;
4931 target_size = thunk_type_size(arg_type, 0);
4932 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4933 if (!argptr) {
4934 ret = -TARGET_EFAULT;
4935 goto out;
4936 }
4937 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4938 unlock_user(argptr, arg, 0);
4939
4940 /* buf_temp is too small, so fetch things into a bigger buffer */
4941 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
4942 memcpy(big_buf, buf_temp, target_size);
4943 buf_temp = big_buf;
4944 host_dm = big_buf;
4945
4946 guest_data = arg + host_dm->data_start;
4947 if ((guest_data - arg) < 0) {
f9757b1d 4948 ret = -TARGET_EINVAL;
56e904ec
AG
4949 goto out;
4950 }
4951 guest_data_size = host_dm->data_size - host_dm->data_start;
4952 host_data = (char*)host_dm + host_dm->data_start;
4953
4954 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3211215e
PM
4955 if (!argptr) {
4956 ret = -TARGET_EFAULT;
4957 goto out;
4958 }
4959
56e904ec
AG
4960 switch (ie->host_cmd) {
4961 case DM_REMOVE_ALL:
4962 case DM_LIST_DEVICES:
4963 case DM_DEV_CREATE:
4964 case DM_DEV_REMOVE:
4965 case DM_DEV_SUSPEND:
4966 case DM_DEV_STATUS:
4967 case DM_DEV_WAIT:
4968 case DM_TABLE_STATUS:
4969 case DM_TABLE_CLEAR:
4970 case DM_TABLE_DEPS:
4971 case DM_LIST_VERSIONS:
4972 /* no input data */
4973 break;
4974 case DM_DEV_RENAME:
4975 case DM_DEV_SET_GEOMETRY:
4976 /* data contains only strings */
4977 memcpy(host_data, argptr, guest_data_size);
4978 break;
4979 case DM_TARGET_MSG:
4980 memcpy(host_data, argptr, guest_data_size);
4981 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
4982 break;
4983 case DM_TABLE_LOAD:
4984 {
4985 void *gspec = argptr;
4986 void *cur_data = host_data;
4987 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
4988 int spec_size = thunk_type_size(arg_type, 0);
4989 int i;
4990
4991 for (i = 0; i < host_dm->target_count; i++) {
4992 struct dm_target_spec *spec = cur_data;
4993 uint32_t next;
4994 int slen;
4995
4996 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
4997 slen = strlen((char*)gspec + spec_size) + 1;
4998 next = spec->next;
4999 spec->next = sizeof(*spec) + slen;
5000 strcpy((char*)&spec[1], gspec + spec_size);
5001 gspec += next;
5002 cur_data += spec->next;
5003 }
5004 break;
5005 }
5006 default:
5007 ret = -TARGET_EINVAL;
dec0473d 5008 unlock_user(argptr, guest_data, 0);
56e904ec
AG
5009 goto out;
5010 }
5011 unlock_user(argptr, guest_data, 0);
5012
49ca6f3e 5013 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
56e904ec
AG
5014 if (!is_error(ret)) {
5015 guest_data = arg + host_dm->data_start;
5016 guest_data_size = host_dm->data_size - host_dm->data_start;
5017 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
5018 switch (ie->host_cmd) {
5019 case DM_REMOVE_ALL:
5020 case DM_DEV_CREATE:
5021 case DM_DEV_REMOVE:
5022 case DM_DEV_RENAME:
5023 case DM_DEV_SUSPEND:
5024 case DM_DEV_STATUS:
5025 case DM_TABLE_LOAD:
5026 case DM_TABLE_CLEAR:
5027 case DM_TARGET_MSG:
5028 case DM_DEV_SET_GEOMETRY:
5029 /* no return data */
5030 break;
5031 case DM_LIST_DEVICES:
5032 {
5033 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
5034 uint32_t remaining_data = guest_data_size;
5035 void *cur_data = argptr;
5036 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
5037 int nl_size = 12; /* can't use thunk_size due to alignment */
5038
5039 while (1) {
5040 uint32_t next = nl->next;
5041 if (next) {
5042 nl->next = nl_size + (strlen(nl->name) + 1);
5043 }
5044 if (remaining_data < nl->next) {
5045 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5046 break;
5047 }
5048 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
5049 strcpy(cur_data + nl_size, nl->name);
5050 cur_data += nl->next;
5051 remaining_data -= nl->next;
5052 if (!next) {
5053 break;
5054 }
5055 nl = (void*)nl + next;
5056 }
5057 break;
5058 }
5059 case DM_DEV_WAIT:
5060 case DM_TABLE_STATUS:
5061 {
5062 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
5063 void *cur_data = argptr;
5064 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
5065 int spec_size = thunk_type_size(arg_type, 0);
5066 int i;
5067
5068 for (i = 0; i < host_dm->target_count; i++) {
5069 uint32_t next = spec->next;
5070 int slen = strlen((char*)&spec[1]) + 1;
5071 spec->next = (cur_data - argptr) + spec_size + slen;
5072 if (guest_data_size < spec->next) {
5073 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5074 break;
5075 }
5076 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
5077 strcpy(cur_data + spec_size, (char*)&spec[1]);
5078 cur_data = argptr + spec->next;
5079 spec = (void*)host_dm + host_dm->data_start + next;
5080 }
5081 break;
5082 }
5083 case DM_TABLE_DEPS:
5084 {
5085 void *hdata = (void*)host_dm + host_dm->data_start;
5086 int count = *(uint32_t*)hdata;
5087 uint64_t *hdev = hdata + 8;
5088 uint64_t *gdev = argptr + 8;
5089 int i;
5090
5091 *(uint32_t*)argptr = tswap32(count);
5092 for (i = 0; i < count; i++) {
5093 *gdev = tswap64(*hdev);
5094 gdev++;
5095 hdev++;
5096 }
5097 break;
5098 }
5099 case DM_LIST_VERSIONS:
5100 {
5101 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
5102 uint32_t remaining_data = guest_data_size;
5103 void *cur_data = argptr;
5104 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
5105 int vers_size = thunk_type_size(arg_type, 0);
5106
5107 while (1) {
5108 uint32_t next = vers->next;
5109 if (next) {
5110 vers->next = vers_size + (strlen(vers->name) + 1);
5111 }
5112 if (remaining_data < vers->next) {
5113 host_dm->flags |= DM_BUFFER_FULL_FLAG;
5114 break;
5115 }
5116 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
5117 strcpy(cur_data + vers_size, vers->name);
5118 cur_data += vers->next;
5119 remaining_data -= vers->next;
5120 if (!next) {
5121 break;
5122 }
5123 vers = (void*)vers + next;
5124 }
5125 break;
5126 }
5127 default:
dec0473d 5128 unlock_user(argptr, guest_data, 0);
56e904ec
AG
5129 ret = -TARGET_EINVAL;
5130 goto out;
5131 }
5132 unlock_user(argptr, guest_data, guest_data_size);
5133
5134 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5135 if (!argptr) {
5136 ret = -TARGET_EFAULT;
5137 goto out;
5138 }
5139 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5140 unlock_user(argptr, arg, target_size);
5141 }
5142out:
ad11ad77 5143 g_free(big_buf);
56e904ec
AG
5144 return ret;
5145}
5146
a59b5e35 5147static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
45c874eb 5148 int cmd, abi_long arg)
a59b5e35
AG
5149{
5150 void *argptr;
5151 int target_size;
5152 const argtype *arg_type = ie->arg_type;
5153 const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
5154 abi_long ret;
5155
5156 struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
5157 struct blkpg_partition host_part;
5158
5159 /* Read and convert blkpg */
5160 arg_type++;
5161 target_size = thunk_type_size(arg_type, 0);
5162 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5163 if (!argptr) {
5164 ret = -TARGET_EFAULT;
5165 goto out;
5166 }
5167 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5168 unlock_user(argptr, arg, 0);
5169
5170 switch (host_blkpg->op) {
5171 case BLKPG_ADD_PARTITION:
5172 case BLKPG_DEL_PARTITION:
5173 /* payload is struct blkpg_partition */
5174 break;
5175 default:
5176 /* Unknown opcode */
5177 ret = -TARGET_EINVAL;
5178 goto out;
5179 }
5180
5181 /* Read and convert blkpg->data */
5182 arg = (abi_long)(uintptr_t)host_blkpg->data;
5183 target_size = thunk_type_size(part_arg_type, 0);
5184 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5185 if (!argptr) {
5186 ret = -TARGET_EFAULT;
5187 goto out;
5188 }
5189 thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
5190 unlock_user(argptr, arg, 0);
5191
5192 /* Swizzle the data pointer to our local copy and call! */
5193 host_blkpg->data = &host_part;
49ca6f3e 5194 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg));
a59b5e35
AG
5195
5196out:
5197 return ret;
5198}
5199
7ff7b666 5200static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 5201 int fd, int cmd, abi_long arg)
7ff7b666
LV
5202{
5203 const argtype *arg_type = ie->arg_type;
5204 const StructEntry *se;
5205 const argtype *field_types;
5206 const int *dst_offsets, *src_offsets;
5207 int target_size;
5208 void *argptr;
b78c522a
MAL
5209 abi_ulong *target_rt_dev_ptr = NULL;
5210 unsigned long *host_rt_dev_ptr = NULL;
7ff7b666
LV
5211 abi_long ret;
5212 int i;
5213
5214 assert(ie->access == IOC_W);
5215 assert(*arg_type == TYPE_PTR);
5216 arg_type++;
5217 assert(*arg_type == TYPE_STRUCT);
5218 target_size = thunk_type_size(arg_type, 0);
5219 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5220 if (!argptr) {
5221 return -TARGET_EFAULT;
5222 }
5223 arg_type++;
5224 assert(*arg_type == (int)STRUCT_rtentry);
5225 se = struct_entries + *arg_type++;
5226 assert(se->convert[0] == NULL);
5227 /* convert struct here to be able to catch rt_dev string */
5228 field_types = se->field_types;
5229 dst_offsets = se->field_offsets[THUNK_HOST];
5230 src_offsets = se->field_offsets[THUNK_TARGET];
5231 for (i = 0; i < se->nb_fields; i++) {
5232 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
5233 assert(*field_types == TYPE_PTRVOID);
5234 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
5235 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
5236 if (*target_rt_dev_ptr != 0) {
5237 *host_rt_dev_ptr = (unsigned long)lock_user_string(
5238 tswapal(*target_rt_dev_ptr));
5239 if (!*host_rt_dev_ptr) {
5240 unlock_user(argptr, arg, 0);
5241 return -TARGET_EFAULT;
5242 }
5243 } else {
5244 *host_rt_dev_ptr = 0;
5245 }
5246 field_types++;
5247 continue;
5248 }
5249 field_types = thunk_convert(buf_temp + dst_offsets[i],
5250 argptr + src_offsets[i],
5251 field_types, THUNK_HOST);
5252 }
5253 unlock_user(argptr, arg, 0);
5254
49ca6f3e 5255 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
b78c522a
MAL
5256
5257 assert(host_rt_dev_ptr != NULL);
5258 assert(target_rt_dev_ptr != NULL);
7ff7b666
LV
5259 if (*host_rt_dev_ptr != 0) {
5260 unlock_user((void *)*host_rt_dev_ptr,
5261 *target_rt_dev_ptr, 0);
5262 }
5263 return ret;
5264}
5265
ca56f5b5 5266static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
45c874eb 5267 int fd, int cmd, abi_long arg)
ca56f5b5
PB
5268{
5269 int sig = target_to_host_signal(arg);
49ca6f3e 5270 return get_errno(safe_ioctl(fd, ie->host_cmd, sig));
ca56f5b5
PB
5271}
5272
6d5d5dde
DB
5273static abi_long do_ioctl_SIOCGSTAMP(const IOCTLEntry *ie, uint8_t *buf_temp,
5274 int fd, int cmd, abi_long arg)
5275{
5276 struct timeval tv;
5277 abi_long ret;
5278
5279 ret = get_errno(safe_ioctl(fd, SIOCGSTAMP, &tv));
5280 if (is_error(ret)) {
5281 return ret;
5282 }
5283
5284 if (cmd == (int)TARGET_SIOCGSTAMP_OLD) {
5285 if (copy_to_user_timeval(arg, &tv)) {
5286 return -TARGET_EFAULT;
5287 }
5288 } else {
5289 if (copy_to_user_timeval64(arg, &tv)) {
5290 return -TARGET_EFAULT;
5291 }
5292 }
5293
5294 return ret;
5295}
5296
5297static abi_long do_ioctl_SIOCGSTAMPNS(const IOCTLEntry *ie, uint8_t *buf_temp,
5298 int fd, int cmd, abi_long arg)
5299{
5300 struct timespec ts;
5301 abi_long ret;
5302
5303 ret = get_errno(safe_ioctl(fd, SIOCGSTAMPNS, &ts));
5304 if (is_error(ret)) {
5305 return ret;
5306 }
5307
5308 if (cmd == (int)TARGET_SIOCGSTAMPNS_OLD) {
5309 if (host_to_target_timespec(arg, &ts)) {
5310 return -TARGET_EFAULT;
5311 }
5312 } else{
5313 if (host_to_target_timespec64(arg, &ts)) {
5314 return -TARGET_EFAULT;
5315 }
5316 }
5317
5318 return ret;
5319}
5320
2b74f621
AS
5321#ifdef TIOCGPTPEER
5322static abi_long do_ioctl_tiocgptpeer(const IOCTLEntry *ie, uint8_t *buf_temp,
5323 int fd, int cmd, abi_long arg)
5324{
5325 int flags = target_to_host_bitmask(arg, fcntl_flags_tbl);
5326 return get_errno(safe_ioctl(fd, ie->host_cmd, flags));
5327}
5328#endif
5329
e865b97f
CG
5330#ifdef HAVE_DRM_H
5331
5332static void unlock_drm_version(struct drm_version *host_ver,
5333 struct target_drm_version *target_ver,
5334 bool copy)
5335{
5336 unlock_user(host_ver->name, target_ver->name,
5337 copy ? host_ver->name_len : 0);
5338 unlock_user(host_ver->date, target_ver->date,
5339 copy ? host_ver->date_len : 0);
5340 unlock_user(host_ver->desc, target_ver->desc,
5341 copy ? host_ver->desc_len : 0);
5342}
5343
5344static inline abi_long target_to_host_drmversion(struct drm_version *host_ver,
5345 struct target_drm_version *target_ver)
5346{
5347 memset(host_ver, 0, sizeof(*host_ver));
5348
5349 __get_user(host_ver->name_len, &target_ver->name_len);
5350 if (host_ver->name_len) {
5351 host_ver->name = lock_user(VERIFY_WRITE, target_ver->name,
5352 target_ver->name_len, 0);
5353 if (!host_ver->name) {
5354 return -EFAULT;
5355 }
5356 }
5357
5358 __get_user(host_ver->date_len, &target_ver->date_len);
5359 if (host_ver->date_len) {
5360 host_ver->date = lock_user(VERIFY_WRITE, target_ver->date,
5361 target_ver->date_len, 0);
5362 if (!host_ver->date) {
5363 goto err;
5364 }
5365 }
5366
5367 __get_user(host_ver->desc_len, &target_ver->desc_len);
5368 if (host_ver->desc_len) {
5369 host_ver->desc = lock_user(VERIFY_WRITE, target_ver->desc,
5370 target_ver->desc_len, 0);
5371 if (!host_ver->desc) {
5372 goto err;
5373 }
5374 }
5375
5376 return 0;
5377err:
5378 unlock_drm_version(host_ver, target_ver, false);
5379 return -EFAULT;
5380}
5381
5382static inline void host_to_target_drmversion(
5383 struct target_drm_version *target_ver,
5384 struct drm_version *host_ver)
5385{
5386 __put_user(host_ver->version_major, &target_ver->version_major);
5387 __put_user(host_ver->version_minor, &target_ver->version_minor);
5388 __put_user(host_ver->version_patchlevel, &target_ver->version_patchlevel);
5389 __put_user(host_ver->name_len, &target_ver->name_len);
5390 __put_user(host_ver->date_len, &target_ver->date_len);
5391 __put_user(host_ver->desc_len, &target_ver->desc_len);
5392 unlock_drm_version(host_ver, target_ver, true);
5393}
5394
5395static abi_long do_ioctl_drm(const IOCTLEntry *ie, uint8_t *buf_temp,
5396 int fd, int cmd, abi_long arg)
5397{
5398 struct drm_version *ver;
5399 struct target_drm_version *target_ver;
5400 abi_long ret;
5401
5402 switch (ie->host_cmd) {
5403 case DRM_IOCTL_VERSION:
5404 if (!lock_user_struct(VERIFY_WRITE, target_ver, arg, 0)) {
5405 return -TARGET_EFAULT;
5406 }
5407 ver = (struct drm_version *)buf_temp;
5408 ret = target_to_host_drmversion(ver, target_ver);
5409 if (!is_error(ret)) {
5410 ret = get_errno(safe_ioctl(fd, ie->host_cmd, ver));
5411 if (is_error(ret)) {
5412 unlock_drm_version(ver, target_ver, false);
5413 } else {
5414 host_to_target_drmversion(target_ver, ver);
5415 }
5416 }
5417 unlock_user_struct(target_ver, arg, 0);
5418 return ret;
5419 }
5420 return -TARGET_ENOSYS;
5421}
5422
5423#endif
5424
79482e59 5425IOCTLEntry ioctl_entries[] = {
001faf32 5426#define IOCTL(cmd, access, ...) \
d2ef05bb
PM
5427 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
5428#define IOCTL_SPECIAL(cmd, access, dofn, ...) \
5429 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
8cb762fe
HD
5430#define IOCTL_IGNORE(cmd) \
5431 { TARGET_ ## cmd, 0, #cmd },
31e31b8a
FB
5432#include "ioctls.h"
5433 { 0, 0, },
5434};
5435
53a5960a 5436/* ??? Implement proper locking for ioctls. */
0da46a6e 5437/* do_ioctl() Must return target values and target errnos. */
45c874eb 5438static abi_long do_ioctl(int fd, int cmd, abi_long arg)
31e31b8a
FB
5439{
5440 const IOCTLEntry *ie;
5441 const argtype *arg_type;
992f48a0 5442 abi_long ret;
31e31b8a 5443 uint8_t buf_temp[MAX_STRUCT_SIZE];
53a5960a
PB
5444 int target_size;
5445 void *argptr;
31e31b8a
FB
5446
5447 ie = ioctl_entries;
5448 for(;;) {
5449 if (ie->target_cmd == 0) {
39be5350
JK
5450 qemu_log_mask(
5451 LOG_UNIMP, "Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
0da46a6e 5452 return -TARGET_ENOSYS;
31e31b8a
FB
5453 }
5454 if (ie->target_cmd == cmd)
5455 break;
5456 ie++;
5457 }
5458 arg_type = ie->arg_type;
d2ef05bb
PM
5459 if (ie->do_ioctl) {
5460 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
8cb762fe
HD
5461 } else if (!ie->host_cmd) {
5462 /* Some architectures define BSD ioctls in their headers
5463 that are not implemented in Linux. */
5464 return -TARGET_ENOSYS;
d2ef05bb
PM
5465 }
5466
31e31b8a
FB
5467 switch(arg_type[0]) {
5468 case TYPE_NULL:
5469 /* no argument */
49ca6f3e 5470 ret = get_errno(safe_ioctl(fd, ie->host_cmd));
31e31b8a
FB
5471 break;
5472 case TYPE_PTRVOID:
5473 case TYPE_INT:
c858e537
FB
5474 case TYPE_LONG:
5475 case TYPE_ULONG:
49ca6f3e 5476 ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
31e31b8a
FB
5477 break;
5478 case TYPE_PTR:
5479 arg_type++;
53a5960a 5480 target_size = thunk_type_size(arg_type, 0);
31e31b8a
FB
5481 switch(ie->access) {
5482 case IOC_R:
49ca6f3e 5483 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a 5484 if (!is_error(ret)) {
579a97f7
FB
5485 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5486 if (!argptr)
5487 return -TARGET_EFAULT;
53a5960a
PB
5488 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5489 unlock_user(argptr, arg, target_size);
31e31b8a
FB
5490 }
5491 break;
5492 case IOC_W:
579a97f7
FB
5493 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5494 if (!argptr)
5495 return -TARGET_EFAULT;
53a5960a
PB
5496 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5497 unlock_user(argptr, arg, 0);
49ca6f3e 5498 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a
FB
5499 break;
5500 default:
5501 case IOC_RW:
579a97f7
FB
5502 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
5503 if (!argptr)
5504 return -TARGET_EFAULT;
53a5960a
PB
5505 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
5506 unlock_user(argptr, arg, 0);
49ca6f3e 5507 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
31e31b8a 5508 if (!is_error(ret)) {
579a97f7
FB
5509 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
5510 if (!argptr)
5511 return -TARGET_EFAULT;
53a5960a
PB
5512 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
5513 unlock_user(argptr, arg, target_size);
31e31b8a
FB
5514 }
5515 break;
5516 }
5517 break;
5518 default:
39be5350
JK
5519 qemu_log_mask(LOG_UNIMP,
5520 "Unsupported ioctl type: cmd=0x%04lx type=%d\n",
5521 (long)cmd, arg_type[0]);
0da46a6e 5522 ret = -TARGET_ENOSYS;
31e31b8a
FB
5523 break;
5524 }
5525 return ret;
5526}
5527
b39bc503 5528static const bitmask_transtbl iflag_tbl[] = {
31e31b8a
FB
5529 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
5530 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
5531 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
5532 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
5533 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
5534 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
5535 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
5536 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
5537 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
5538 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
5539 { TARGET_IXON, TARGET_IXON, IXON, IXON },
5540 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
5541 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
5542 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
5543 { 0, 0, 0, 0 }
5544};
5545
b39bc503 5546static const bitmask_transtbl oflag_tbl[] = {
31e31b8a
FB
5547 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
5548 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
5549 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
5550 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
5551 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
5552 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
5553 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
5554 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
5555 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
5556 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
5557 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
5558 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
5559 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
5560 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
5561 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
5562 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
5563 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
5564 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
5565 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
5566 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
5567 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
5568 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
5569 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
5570 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
5571 { 0, 0, 0, 0 }
5572};
5573
b39bc503 5574static const bitmask_transtbl cflag_tbl[] = {
31e31b8a
FB
5575 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
5576 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
5577 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
5578 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
5579 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
5580 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
5581 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
5582 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
5583 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
5584 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
5585 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
5586 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
5587 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
5588 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
5589 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
5590 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
5591 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
5592 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
5593 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
5594 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
5595 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
5596 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
5597 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
5598 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
5599 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
5600 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
5601 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
5602 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
5603 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
5604 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
5605 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
5606 { 0, 0, 0, 0 }
5607};
5608
b39bc503 5609static const bitmask_transtbl lflag_tbl[] = {
31e31b8a
FB
5610 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
5611 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
5612 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
5613 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
5614 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
5615 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
5616 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
5617 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
5618 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
5619 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
5620 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
5621 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
5622 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
5623 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
5624 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
5625 { 0, 0, 0, 0 }
5626};
5627
5628static void target_to_host_termios (void *dst, const void *src)
5629{
5630 struct host_termios *host = dst;
5631 const struct target_termios *target = src;
3b46e624 5632
5fafdf24 5633 host->c_iflag =
31e31b8a 5634 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
5fafdf24 5635 host->c_oflag =
31e31b8a 5636 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
5fafdf24 5637 host->c_cflag =
31e31b8a 5638 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
5fafdf24 5639 host->c_lflag =
31e31b8a
FB
5640 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
5641 host->c_line = target->c_line;
3b46e624 5642
44607123 5643 memset(host->c_cc, 0, sizeof(host->c_cc));
5fafdf24
TS
5644 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
5645 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3b46e624 5646 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
5fafdf24 5647 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3b46e624 5648 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
5fafdf24 5649 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3b46e624 5650 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
5fafdf24 5651 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3b46e624 5652 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
5fafdf24
TS
5653 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
5654 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3b46e624
TS
5655 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
5656 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
5657 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
5658 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
5659 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
5fafdf24 5660 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
31e31b8a 5661}
3b46e624 5662
31e31b8a
FB
5663static void host_to_target_termios (void *dst, const void *src)
5664{
5665 struct target_termios *target = dst;
5666 const struct host_termios *host = src;
5667
5fafdf24 5668 target->c_iflag =
31e31b8a 5669 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
5fafdf24 5670 target->c_oflag =
31e31b8a 5671 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
5fafdf24 5672 target->c_cflag =
31e31b8a 5673 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
5fafdf24 5674 target->c_lflag =
31e31b8a
FB
5675 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
5676 target->c_line = host->c_line;
3b46e624 5677
44607123 5678 memset(target->c_cc, 0, sizeof(target->c_cc));
31e31b8a
FB
5679 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
5680 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
5681 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
5682 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
5683 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
5684 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
5685 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
5686 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
5687 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
5688 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
5689 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
5690 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
5691 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
5692 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
5693 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
5694 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
5695 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
5696}
5697
8e853dc7 5698static const StructEntry struct_termios_def = {
31e31b8a
FB
5699 .convert = { host_to_target_termios, target_to_host_termios },
5700 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
5701 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
5702};
5703
5286db75 5704static bitmask_transtbl mmap_flags_tbl[] = {
541e1690
HD
5705 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
5706 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
5707 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
5708 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS,
5709 MAP_ANONYMOUS, MAP_ANONYMOUS },
5710 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN,
5711 MAP_GROWSDOWN, MAP_GROWSDOWN },
5712 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE,
5713 MAP_DENYWRITE, MAP_DENYWRITE },
5714 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE,
5715 MAP_EXECUTABLE, MAP_EXECUTABLE },
5716 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
5717 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE,
5718 MAP_NORESERVE, MAP_NORESERVE },
5719 { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },
5720 /* MAP_STACK had been ignored by the kernel for quite some time.
5721 Recognize it for the target insofar as we do not want to pass
5722 it through to the host. */
5723 { TARGET_MAP_STACK, TARGET_MAP_STACK, 0, 0 },
5724 { 0, 0, 0, 0 }
5286db75
FB
5725};
5726
9d12f79d
LV
5727/*
5728 * NOTE: TARGET_ABI32 is defined for TARGET_I386 (but not for TARGET_X86_64)
5729 * TARGET_I386 is defined if TARGET_X86_64 is defined
5730 */
2ab83ea7 5731#if defined(TARGET_I386)
6dbad63e
FB
5732
5733/* NOTE: there is really one LDT for all the threads */
b1d8e52e 5734static uint8_t *ldt_table;
6dbad63e 5735
03acab66 5736static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
6dbad63e
FB
5737{
5738 int size;
53a5960a 5739 void *p;
6dbad63e
FB
5740
5741 if (!ldt_table)
5742 return 0;
5743 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
5744 if (size > bytecount)
5745 size = bytecount;
579a97f7
FB
5746 p = lock_user(VERIFY_WRITE, ptr, size, 0);
5747 if (!p)
03acab66 5748 return -TARGET_EFAULT;
579a97f7 5749 /* ??? Should this by byteswapped? */
53a5960a
PB
5750 memcpy(p, ldt_table, size);
5751 unlock_user(p, ptr, size);
6dbad63e
FB
5752 return size;
5753}
5754
5755/* XXX: add locking support */
03acab66
FB
5756static abi_long write_ldt(CPUX86State *env,
5757 abi_ulong ptr, unsigned long bytecount, int oldmode)
6dbad63e
FB
5758{
5759 struct target_modify_ldt_ldt_s ldt_info;
53a5960a 5760 struct target_modify_ldt_ldt_s *target_ldt_info;
6dbad63e 5761 int seg_32bit, contents, read_exec_only, limit_in_pages;
8d18e893 5762 int seg_not_present, useable, lm;
6dbad63e
FB
5763 uint32_t *lp, entry_1, entry_2;
5764
5765 if (bytecount != sizeof(ldt_info))
03acab66 5766 return -TARGET_EINVAL;
579a97f7 5767 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
03acab66 5768 return -TARGET_EFAULT;
53a5960a 5769 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
cbb21eed 5770 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
53a5960a
PB
5771 ldt_info.limit = tswap32(target_ldt_info->limit);
5772 ldt_info.flags = tswap32(target_ldt_info->flags);
5773 unlock_user_struct(target_ldt_info, ptr, 0);
3b46e624 5774
6dbad63e 5775 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
03acab66 5776 return -TARGET_EINVAL;
6dbad63e
FB
5777 seg_32bit = ldt_info.flags & 1;
5778 contents = (ldt_info.flags >> 1) & 3;
5779 read_exec_only = (ldt_info.flags >> 3) & 1;
5780 limit_in_pages = (ldt_info.flags >> 4) & 1;
5781 seg_not_present = (ldt_info.flags >> 5) & 1;
5782 useable = (ldt_info.flags >> 6) & 1;
8d18e893
FB
5783#ifdef TARGET_ABI32
5784 lm = 0;
5785#else
5786 lm = (ldt_info.flags >> 7) & 1;
5787#endif
6dbad63e
FB
5788 if (contents == 3) {
5789 if (oldmode)
03acab66 5790 return -TARGET_EINVAL;
6dbad63e 5791 if (seg_not_present == 0)
03acab66 5792 return -TARGET_EINVAL;
6dbad63e
FB
5793 }
5794 /* allocate the LDT */
5795 if (!ldt_table) {
e441570f
AZ
5796 env->ldt.base = target_mmap(0,
5797 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
5798 PROT_READ|PROT_WRITE,
5799 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
5800 if (env->ldt.base == -1)
03acab66 5801 return -TARGET_ENOMEM;
e441570f
AZ
5802 memset(g2h(env->ldt.base), 0,
5803 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
6dbad63e 5804 env->ldt.limit = 0xffff;
e441570f 5805 ldt_table = g2h(env->ldt.base);
6dbad63e
FB
5806 }
5807
5808 /* NOTE: same code as Linux kernel */
5809 /* Allow LDTs to be cleared by the user. */
5810 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
5811 if (oldmode ||
5812 (contents == 0 &&
5813 read_exec_only == 1 &&
5814 seg_32bit == 0 &&
5815 limit_in_pages == 0 &&
5816 seg_not_present == 1 &&
5817 useable == 0 )) {
5818 entry_1 = 0;
5819 entry_2 = 0;
5820 goto install;
5821 }
5822 }
3b46e624 5823
6dbad63e
FB
5824 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
5825 (ldt_info.limit & 0x0ffff);
5826 entry_2 = (ldt_info.base_addr & 0xff000000) |
5827 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
5828 (ldt_info.limit & 0xf0000) |
5829 ((read_exec_only ^ 1) << 9) |
5830 (contents << 10) |
5831 ((seg_not_present ^ 1) << 15) |
5832 (seg_32bit << 22) |
5833 (limit_in_pages << 23) |
8d18e893 5834 (lm << 21) |
6dbad63e
FB
5835 0x7000;
5836 if (!oldmode)
5837 entry_2 |= (useable << 20);
14ae3ba7 5838
6dbad63e
FB
5839 /* Install the new entry ... */
5840install:
5841 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
5842 lp[0] = tswap32(entry_1);
5843 lp[1] = tswap32(entry_2);
5844 return 0;
5845}
5846
5847/* specific and weird i386 syscalls */
8fcd3692
BS
5848static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
5849 unsigned long bytecount)
6dbad63e 5850{
03acab66 5851 abi_long ret;
3b46e624 5852
6dbad63e
FB
5853 switch (func) {
5854 case 0:
5855 ret = read_ldt(ptr, bytecount);
5856 break;
5857 case 1:
5858 ret = write_ldt(env, ptr, bytecount, 1);
5859 break;
5860 case 0x11:
5861 ret = write_ldt(env, ptr, bytecount, 0);
5862 break;
03acab66
FB
5863 default:
5864 ret = -TARGET_ENOSYS;
5865 break;
6dbad63e
FB
5866 }
5867 return ret;
5868}
1b6b029e 5869
9d12f79d 5870#if defined(TARGET_ABI32)
bc22eb44 5871abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
8d18e893
FB
5872{
5873 uint64_t *gdt_table = g2h(env->gdt.base);
5874 struct target_modify_ldt_ldt_s ldt_info;
5875 struct target_modify_ldt_ldt_s *target_ldt_info;
5876 int seg_32bit, contents, read_exec_only, limit_in_pages;
5877 int seg_not_present, useable, lm;
5878 uint32_t *lp, entry_1, entry_2;
5879 int i;
5880
5881 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
5882 if (!target_ldt_info)
5883 return -TARGET_EFAULT;
5884 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
cbb21eed 5885 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
8d18e893
FB
5886 ldt_info.limit = tswap32(target_ldt_info->limit);
5887 ldt_info.flags = tswap32(target_ldt_info->flags);
5888 if (ldt_info.entry_number == -1) {
5889 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
5890 if (gdt_table[i] == 0) {
5891 ldt_info.entry_number = i;
5892 target_ldt_info->entry_number = tswap32(i);
5893 break;
5894 }
5895 }
5896 }
5897 unlock_user_struct(target_ldt_info, ptr, 1);
5898
5899 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
5900 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
5901 return -TARGET_EINVAL;
5902 seg_32bit = ldt_info.flags & 1;
5903 contents = (ldt_info.flags >> 1) & 3;
5904 read_exec_only = (ldt_info.flags >> 3) & 1;
5905 limit_in_pages = (ldt_info.flags >> 4) & 1;
5906 seg_not_present = (ldt_info.flags >> 5) & 1;
5907 useable = (ldt_info.flags >> 6) & 1;
5908#ifdef TARGET_ABI32
5909 lm = 0;
5910#else
5911 lm = (ldt_info.flags >> 7) & 1;
5912#endif
5913
5914 if (contents == 3) {
5915 if (seg_not_present == 0)
5916 return -TARGET_EINVAL;
5917 }
5918
5919 /* NOTE: same code as Linux kernel */
5920 /* Allow LDTs to be cleared by the user. */
5921 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
5922 if ((contents == 0 &&
5923 read_exec_only == 1 &&
5924 seg_32bit == 0 &&
5925 limit_in_pages == 0 &&
5926 seg_not_present == 1 &&
5927 useable == 0 )) {
5928 entry_1 = 0;
5929 entry_2 = 0;
5930 goto install;
5931 }
5932 }
5933
5934 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
5935 (ldt_info.limit & 0x0ffff);
5936 entry_2 = (ldt_info.base_addr & 0xff000000) |
5937 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
5938 (ldt_info.limit & 0xf0000) |
5939 ((read_exec_only ^ 1) << 9) |
5940 (contents << 10) |
5941 ((seg_not_present ^ 1) << 15) |
5942 (seg_32bit << 22) |
5943 (limit_in_pages << 23) |
5944 (useable << 20) |
5945 (lm << 21) |
5946 0x7000;
5947
5948 /* Install the new entry ... */
5949install:
5950 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
5951 lp[0] = tswap32(entry_1);
5952 lp[1] = tswap32(entry_2);
5953 return 0;
5954}
5955
8fcd3692 5956static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
8d18e893
FB
5957{
5958 struct target_modify_ldt_ldt_s *target_ldt_info;
5959 uint64_t *gdt_table = g2h(env->gdt.base);
5960 uint32_t base_addr, limit, flags;
5961 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
5962 int seg_not_present, useable, lm;
5963 uint32_t *lp, entry_1, entry_2;
5964
5965 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
5966 if (!target_ldt_info)
5967 return -TARGET_EFAULT;
5968 idx = tswap32(target_ldt_info->entry_number);
5969 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
5970 idx > TARGET_GDT_ENTRY_TLS_MAX) {
5971 unlock_user_struct(target_ldt_info, ptr, 1);
5972 return -TARGET_EINVAL;
5973 }
5974 lp = (uint32_t *)(gdt_table + idx);
5975 entry_1 = tswap32(lp[0]);
5976 entry_2 = tswap32(lp[1]);
5977
5978 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
5979 contents = (entry_2 >> 10) & 3;
5980 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
5981 seg_32bit = (entry_2 >> 22) & 1;
5982 limit_in_pages = (entry_2 >> 23) & 1;
5983 useable = (entry_2 >> 20) & 1;
5984#ifdef TARGET_ABI32
5985 lm = 0;
5986#else
5987 lm = (entry_2 >> 21) & 1;
5988#endif
5989 flags = (seg_32bit << 0) | (contents << 1) |
5990 (read_exec_only << 3) | (limit_in_pages << 4) |
5991 (seg_not_present << 5) | (useable << 6) | (lm << 7);
5992 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
5993 base_addr = (entry_1 >> 16) |
5994 (entry_2 & 0xff000000) |
5995 ((entry_2 & 0xff) << 16);
cbb21eed 5996 target_ldt_info->base_addr = tswapal(base_addr);
8d18e893
FB
5997 target_ldt_info->limit = tswap32(limit);
5998 target_ldt_info->flags = tswap32(flags);
5999 unlock_user_struct(target_ldt_info, ptr, 1);
6000 return 0;
6001}
6002
9d12f79d
LV
6003abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
6004{
538fabcb 6005 return -TARGET_ENOSYS;
9d12f79d
LV
6006}
6007#else
2667e71c 6008abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
d2fd1af7 6009{
1add8698 6010 abi_long ret = 0;
d2fd1af7
FB
6011 abi_ulong val;
6012 int idx;
1add8698 6013
d2fd1af7
FB
6014 switch(code) {
6015 case TARGET_ARCH_SET_GS:
6016 case TARGET_ARCH_SET_FS:
6017 if (code == TARGET_ARCH_SET_GS)
6018 idx = R_GS;
6019 else
6020 idx = R_FS;
6021 cpu_x86_load_seg(env, idx, 0);
6022 env->segs[idx].base = addr;
6023 break;
6024 case TARGET_ARCH_GET_GS:
6025 case TARGET_ARCH_GET_FS:
6026 if (code == TARGET_ARCH_GET_GS)
6027 idx = R_GS;
6028 else
6029 idx = R_FS;
6030 val = env->segs[idx].base;
6031 if (put_user(val, addr, abi_ulong))
1add8698 6032 ret = -TARGET_EFAULT;
d2fd1af7
FB
6033 break;
6034 default:
6035 ret = -TARGET_EINVAL;
6036 break;
6037 }
1add8698 6038 return ret;
d2fd1af7 6039}
9d12f79d 6040#endif /* defined(TARGET_ABI32 */
d2fd1af7 6041
2ab83ea7
FB
6042#endif /* defined(TARGET_I386) */
6043
05098a93 6044#define NEW_STACK_SIZE 0x40000
d865bab5 6045
d865bab5
PB
6046
6047static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
6048typedef struct {
9349b4f9 6049 CPUArchState *env;
d865bab5
PB
6050 pthread_mutex_t mutex;
6051 pthread_cond_t cond;
6052 pthread_t thread;
6053 uint32_t tid;
6054 abi_ulong child_tidptr;
6055 abi_ulong parent_tidptr;
6056 sigset_t sigmask;
6057} new_thread_info;
6058
6059static void *clone_func(void *arg)
6060{
6061 new_thread_info *info = arg;
9349b4f9 6062 CPUArchState *env;
0d34282f 6063 CPUState *cpu;
edf8e2af 6064 TaskState *ts;
d865bab5 6065
70903763 6066 rcu_register_thread();
3468b59e 6067 tcg_register_thread();
d865bab5 6068 env = info->env;
29a0af61 6069 cpu = env_cpu(env);
a2247f8e 6070 thread_cpu = cpu;
0429a971 6071 ts = (TaskState *)cpu->opaque;
71ba74f6 6072 info->tid = sys_gettid();
edf8e2af 6073 task_settid(ts);
d865bab5
PB
6074 if (info->child_tidptr)
6075 put_user_u32(info->tid, info->child_tidptr);
6076 if (info->parent_tidptr)
6077 put_user_u32(info->tid, info->parent_tidptr);
5ebdd774 6078 qemu_guest_random_seed_thread_part2(cpu->random_seed);
d865bab5
PB
6079 /* Enable signals. */
6080 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
6081 /* Signal to the parent that we're ready. */
6082 pthread_mutex_lock(&info->mutex);
6083 pthread_cond_broadcast(&info->cond);
6084 pthread_mutex_unlock(&info->mutex);
a4dd3d51 6085 /* Wait until the parent has finished initializing the tls state. */
d865bab5
PB
6086 pthread_mutex_lock(&clone_lock);
6087 pthread_mutex_unlock(&clone_lock);
6088 cpu_loop(env);
6089 /* never exits */
6090 return NULL;
6091}
1b6b029e 6092
0da46a6e
TS
6093/* do_fork() Must return host values and target errnos (unlike most
6094 do_*() functions). */
9349b4f9 6095static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
d865bab5
PB
6096 abi_ulong parent_tidptr, target_ulong newtls,
6097 abi_ulong child_tidptr)
1b6b029e 6098{
29a0af61 6099 CPUState *cpu = env_cpu(env);
1b6b029e 6100 int ret;
5cd4393b 6101 TaskState *ts;
0429a971 6102 CPUState *new_cpu;
9349b4f9 6103 CPUArchState *new_env;
d865bab5 6104 sigset_t sigmask;
3b46e624 6105
5ea2fc84
PM
6106 flags &= ~CLONE_IGNORED_FLAGS;
6107
436d124b
AZ
6108 /* Emulate vfork() with fork() */
6109 if (flags & CLONE_VFORK)
6110 flags &= ~(CLONE_VFORK | CLONE_VM);
6111
1b6b029e 6112 if (flags & CLONE_VM) {
0429a971 6113 TaskState *parent_ts = (TaskState *)cpu->opaque;
d865bab5
PB
6114 new_thread_info info;
6115 pthread_attr_t attr;
24cb36a6 6116
5ea2fc84
PM
6117 if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
6118 (flags & CLONE_INVALID_THREAD_FLAGS)) {
6119 return -TARGET_EINVAL;
6120 }
6121
c78d65e8 6122 ts = g_new0(TaskState, 1);
624f7979 6123 init_task_state(ts);
73a988d9
MF
6124
6125 /* Grab a mutex so that thread setup appears atomic. */
6126 pthread_mutex_lock(&clone_lock);
6127
1b6b029e 6128 /* we create a new CPU instance. */
c5be9f08 6129 new_env = cpu_copy(env);
6e68e076 6130 /* Init regs that differ from the parent. */
608999d1 6131 cpu_clone_regs_child(new_env, newsp, flags);
07a6ecf4 6132 cpu_clone_regs_parent(env, flags);
29a0af61 6133 new_cpu = env_cpu(new_env);
0429a971 6134 new_cpu->opaque = ts;
edf8e2af
MW
6135 ts->bprm = parent_ts->bprm;
6136 ts->info = parent_ts->info;
3d3efba0 6137 ts->signal_mask = parent_ts->signal_mask;
d865bab5 6138
7cfbd386 6139 if (flags & CLONE_CHILD_CLEARTID) {
c2764719
PB
6140 ts->child_tidptr = child_tidptr;
6141 }
6142
7cfbd386 6143 if (flags & CLONE_SETTLS) {
d865bab5 6144 cpu_set_tls (new_env, newtls);
7cfbd386 6145 }
d865bab5 6146
d865bab5
PB
6147 memset(&info, 0, sizeof(info));
6148 pthread_mutex_init(&info.mutex, NULL);
6149 pthread_mutex_lock(&info.mutex);
6150 pthread_cond_init(&info.cond, NULL);
6151 info.env = new_env;
7cfbd386 6152 if (flags & CLONE_CHILD_SETTID) {
d865bab5 6153 info.child_tidptr = child_tidptr;
7cfbd386
PM
6154 }
6155 if (flags & CLONE_PARENT_SETTID) {
d865bab5 6156 info.parent_tidptr = parent_tidptr;
7cfbd386 6157 }
d865bab5
PB
6158
6159 ret = pthread_attr_init(&attr);
48e15fc2
NF
6160 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
6161 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
d865bab5
PB
6162 /* It is not safe to deliver signals until the child has finished
6163 initializing, so temporarily block all signals. */
6164 sigfillset(&sigmask);
6165 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
5ebdd774 6166 cpu->random_seed = qemu_guest_random_seed_thread_part1();
d865bab5 6167
b67cb68b
AB
6168 /* If this is our first additional thread, we need to ensure we
6169 * generate code for parallel execution and flush old translations.
6170 */
6171 if (!parallel_cpus) {
6172 parallel_cpus = true;
6173 tb_flush(cpu);
6174 }
6175
d865bab5 6176 ret = pthread_create(&info.thread, &attr, clone_func, &info);
c2764719 6177 /* TODO: Free new CPU state if thread creation failed. */
d865bab5
PB
6178
6179 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
6180 pthread_attr_destroy(&attr);
6181 if (ret == 0) {
6182 /* Wait for the child to initialize. */
6183 pthread_cond_wait(&info.cond, &info.mutex);
6184 ret = info.tid;
d865bab5
PB
6185 } else {
6186 ret = -1;
6187 }
6188 pthread_mutex_unlock(&info.mutex);
6189 pthread_cond_destroy(&info.cond);
6190 pthread_mutex_destroy(&info.mutex);
6191 pthread_mutex_unlock(&clone_lock);
1b6b029e
FB
6192 } else {
6193 /* if no CLONE_VM, we consider it is a fork */
5ea2fc84
PM
6194 if (flags & CLONE_INVALID_FORK_FLAGS) {
6195 return -TARGET_EINVAL;
6196 }
6197
6198 /* We can't support custom termination signals */
6199 if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
93b4eff8
TB
6200 return -TARGET_EINVAL;
6201 }
7d92d34e
TB
6202
6203 if (block_signals()) {
6204 return -TARGET_ERESTARTSYS;
6205 }
6206
d865bab5 6207 fork_start();
1b6b029e 6208 ret = fork();
d865bab5 6209 if (ret == 0) {
2b1319c8 6210 /* Child Process. */
608999d1 6211 cpu_clone_regs_child(env, newsp, flags);
d865bab5 6212 fork_end(1);
2b1319c8
AJ
6213 /* There is a race condition here. The parent process could
6214 theoretically read the TID in the child process before the child
6215 tid is set. This would require using either ptrace
6216 (not implemented) or having *_tidptr to point at a shared memory
6217 mapping. We can't repeat the spinlock hack used above because
6218 the child process gets its own copy of the lock. */
d865bab5 6219 if (flags & CLONE_CHILD_SETTID)
71ba74f6 6220 put_user_u32(sys_gettid(), child_tidptr);
d865bab5 6221 if (flags & CLONE_PARENT_SETTID)
71ba74f6 6222 put_user_u32(sys_gettid(), parent_tidptr);
0429a971 6223 ts = (TaskState *)cpu->opaque;
d865bab5
PB
6224 if (flags & CLONE_SETTLS)
6225 cpu_set_tls (env, newtls);
c2764719
PB
6226 if (flags & CLONE_CHILD_CLEARTID)
6227 ts->child_tidptr = child_tidptr;
d865bab5 6228 } else {
07a6ecf4 6229 cpu_clone_regs_parent(env, flags);
d865bab5
PB
6230 fork_end(0);
6231 }
1b6b029e
FB
6232 }
6233 return ret;
6234}
6235
5f106811
APR
6236/* warning : doesn't handle linux specific flags... */
6237static int target_to_host_fcntl_cmd(int cmd)
6238{
4a545761
SB
6239 int ret;
6240
5f106811 6241 switch(cmd) {
4a545761
SB
6242 case TARGET_F_DUPFD:
6243 case TARGET_F_GETFD:
6244 case TARGET_F_SETFD:
6245 case TARGET_F_GETFL:
6246 case TARGET_F_SETFL:
2d92c682
AS
6247 case TARGET_F_OFD_GETLK:
6248 case TARGET_F_OFD_SETLK:
6249 case TARGET_F_OFD_SETLKW:
4a545761
SB
6250 ret = cmd;
6251 break;
6252 case TARGET_F_GETLK:
6253 ret = F_GETLK64;
6254 break;
6255 case TARGET_F_SETLK:
6256 ret = F_SETLK64;
6257 break;
6258 case TARGET_F_SETLKW:
6259 ret = F_SETLKW64;
6260 break;
6261 case TARGET_F_GETOWN:
6262 ret = F_GETOWN;
6263 break;
6264 case TARGET_F_SETOWN:
6265 ret = F_SETOWN;
6266 break;
6267 case TARGET_F_GETSIG:
6268 ret = F_GETSIG;
6269 break;
6270 case TARGET_F_SETSIG:
6271 ret = F_SETSIG;
6272 break;
5f106811 6273#if TARGET_ABI_BITS == 32
4a545761
SB
6274 case TARGET_F_GETLK64:
6275 ret = F_GETLK64;
6276 break;
6277 case TARGET_F_SETLK64:
6278 ret = F_SETLK64;
6279 break;
6280 case TARGET_F_SETLKW64:
6281 ret = F_SETLKW64;
6282 break;
5f106811 6283#endif
4a545761
SB
6284 case TARGET_F_SETLEASE:
6285 ret = F_SETLEASE;
6286 break;
6287 case TARGET_F_GETLEASE:
6288 ret = F_GETLEASE;
6289 break;
fbd5de9b 6290#ifdef F_DUPFD_CLOEXEC
4a545761
SB
6291 case TARGET_F_DUPFD_CLOEXEC:
6292 ret = F_DUPFD_CLOEXEC;
6293 break;
fbd5de9b 6294#endif
4a545761
SB
6295 case TARGET_F_NOTIFY:
6296 ret = F_NOTIFY;
6297 break;
8d5d3004 6298#ifdef F_GETOWN_EX
4a545761
SB
6299 case TARGET_F_GETOWN_EX:
6300 ret = F_GETOWN_EX;
6301 break;
8d5d3004
AS
6302#endif
6303#ifdef F_SETOWN_EX
4a545761
SB
6304 case TARGET_F_SETOWN_EX:
6305 ret = F_SETOWN_EX;
6306 break;
8d5d3004 6307#endif
ddf31aa8 6308#ifdef F_SETPIPE_SZ
4a545761
SB
6309 case TARGET_F_SETPIPE_SZ:
6310 ret = F_SETPIPE_SZ;
6311 break;
6312 case TARGET_F_GETPIPE_SZ:
6313 ret = F_GETPIPE_SZ;
6314 break;
ddf31aa8 6315#endif
4a545761
SB
6316 default:
6317 ret = -TARGET_EINVAL;
6318 break;
6319 }
6320
6321#if defined(__powerpc64__)
6322 /* On PPC64, glibc headers has the F_*LK* defined to 12, 13 and 14 and
6323 * is not supported by kernel. The glibc fcntl call actually adjusts
6324 * them to 5, 6 and 7 before making the syscall(). Since we make the
6325 * syscall directly, adjust to what is supported by the kernel.
6326 */
6327 if (ret >= F_GETLK64 && ret <= F_SETLKW64) {
6328 ret -= F_GETLK64 - 5;
5f106811 6329 }
4a545761
SB
6330#endif
6331
6332 return ret;
5f106811
APR
6333}
6334
ae68ad9f
LV
6335#define FLOCK_TRANSTBL \
6336 switch (type) { \
6337 TRANSTBL_CONVERT(F_RDLCK); \
6338 TRANSTBL_CONVERT(F_WRLCK); \
6339 TRANSTBL_CONVERT(F_UNLCK); \
6340 TRANSTBL_CONVERT(F_EXLCK); \
6341 TRANSTBL_CONVERT(F_SHLCK); \
6342 }
6343
6344static int target_to_host_flock(int type)
6345{
6346#define TRANSTBL_CONVERT(a) case TARGET_##a: return a
6347 FLOCK_TRANSTBL
6348#undef TRANSTBL_CONVERT
6349 return -TARGET_EINVAL;
6350}
6351
6352static int host_to_target_flock(int type)
6353{
6354#define TRANSTBL_CONVERT(a) case a: return TARGET_##a
6355 FLOCK_TRANSTBL
6356#undef TRANSTBL_CONVERT
6357 /* if we don't know how to convert the value coming
6358 * from the host we copy to the target field as-is
6359 */
6360 return type;
6361}
2ba7f730 6362
213d3e9e
PM
6363static inline abi_long copy_from_user_flock(struct flock64 *fl,
6364 abi_ulong target_flock_addr)
7775e9ec 6365{
53a5960a 6366 struct target_flock *target_fl;
ae68ad9f 6367 int l_type;
213d3e9e
PM
6368
6369 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6370 return -TARGET_EFAULT;
6371 }
6372
6373 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6374 l_type = target_to_host_flock(l_type);
6375 if (l_type < 0) {
6376 return l_type;
6377 }
6378 fl->l_type = l_type;
213d3e9e
PM
6379 __get_user(fl->l_whence, &target_fl->l_whence);
6380 __get_user(fl->l_start, &target_fl->l_start);
6381 __get_user(fl->l_len, &target_fl->l_len);
6382 __get_user(fl->l_pid, &target_fl->l_pid);
6383 unlock_user_struct(target_fl, target_flock_addr, 0);
6384 return 0;
6385}
6386
6387static inline abi_long copy_to_user_flock(abi_ulong target_flock_addr,
6388 const struct flock64 *fl)
6389{
6390 struct target_flock *target_fl;
6391 short l_type;
6392
6393 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6394 return -TARGET_EFAULT;
6395 }
6396
ae68ad9f 6397 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6398 __put_user(l_type, &target_fl->l_type);
6399 __put_user(fl->l_whence, &target_fl->l_whence);
6400 __put_user(fl->l_start, &target_fl->l_start);
6401 __put_user(fl->l_len, &target_fl->l_len);
6402 __put_user(fl->l_pid, &target_fl->l_pid);
6403 unlock_user_struct(target_fl, target_flock_addr, 1);
6404 return 0;
6405}
6406
6407typedef abi_long from_flock64_fn(struct flock64 *fl, abi_ulong target_addr);
6408typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
6409
6410#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
7f254c5c 6411static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
213d3e9e
PM
6412 abi_ulong target_flock_addr)
6413{
7f254c5c 6414 struct target_oabi_flock64 *target_fl;
ae68ad9f 6415 int l_type;
213d3e9e
PM
6416
6417 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6418 return -TARGET_EFAULT;
6419 }
6420
6421 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6422 l_type = target_to_host_flock(l_type);
6423 if (l_type < 0) {
6424 return l_type;
6425 }
6426 fl->l_type = l_type;
213d3e9e
PM
6427 __get_user(fl->l_whence, &target_fl->l_whence);
6428 __get_user(fl->l_start, &target_fl->l_start);
6429 __get_user(fl->l_len, &target_fl->l_len);
6430 __get_user(fl->l_pid, &target_fl->l_pid);
6431 unlock_user_struct(target_fl, target_flock_addr, 0);
6432 return 0;
6433}
6434
7f254c5c 6435static inline abi_long copy_to_user_oabi_flock64(abi_ulong target_flock_addr,
213d3e9e
PM
6436 const struct flock64 *fl)
6437{
7f254c5c 6438 struct target_oabi_flock64 *target_fl;
213d3e9e
PM
6439 short l_type;
6440
6441 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6442 return -TARGET_EFAULT;
6443 }
6444
ae68ad9f 6445 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6446 __put_user(l_type, &target_fl->l_type);
6447 __put_user(fl->l_whence, &target_fl->l_whence);
6448 __put_user(fl->l_start, &target_fl->l_start);
6449 __put_user(fl->l_len, &target_fl->l_len);
6450 __put_user(fl->l_pid, &target_fl->l_pid);
6451 unlock_user_struct(target_fl, target_flock_addr, 1);
6452 return 0;
6453}
6454#endif
6455
6456static inline abi_long copy_from_user_flock64(struct flock64 *fl,
6457 abi_ulong target_flock_addr)
6458{
6459 struct target_flock64 *target_fl;
ae68ad9f 6460 int l_type;
213d3e9e
PM
6461
6462 if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
6463 return -TARGET_EFAULT;
6464 }
6465
6466 __get_user(l_type, &target_fl->l_type);
ae68ad9f
LV
6467 l_type = target_to_host_flock(l_type);
6468 if (l_type < 0) {
6469 return l_type;
6470 }
6471 fl->l_type = l_type;
213d3e9e
PM
6472 __get_user(fl->l_whence, &target_fl->l_whence);
6473 __get_user(fl->l_start, &target_fl->l_start);
6474 __get_user(fl->l_len, &target_fl->l_len);
6475 __get_user(fl->l_pid, &target_fl->l_pid);
6476 unlock_user_struct(target_fl, target_flock_addr, 0);
6477 return 0;
6478}
6479
6480static inline abi_long copy_to_user_flock64(abi_ulong target_flock_addr,
6481 const struct flock64 *fl)
6482{
6483 struct target_flock64 *target_fl;
6484 short l_type;
6485
6486 if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
6487 return -TARGET_EFAULT;
6488 }
6489
ae68ad9f 6490 l_type = host_to_target_flock(fl->l_type);
213d3e9e
PM
6491 __put_user(l_type, &target_fl->l_type);
6492 __put_user(fl->l_whence, &target_fl->l_whence);
6493 __put_user(fl->l_start, &target_fl->l_start);
6494 __put_user(fl->l_len, &target_fl->l_len);
6495 __put_user(fl->l_pid, &target_fl->l_pid);
6496 unlock_user_struct(target_fl, target_flock_addr, 1);
6497 return 0;
6498}
6499
6500static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
6501{
43f238d7 6502 struct flock64 fl64;
8d5d3004
AS
6503#ifdef F_GETOWN_EX
6504 struct f_owner_ex fox;
6505 struct target_f_owner_ex *target_fox;
6506#endif
992f48a0 6507 abi_long ret;
5f106811
APR
6508 int host_cmd = target_to_host_fcntl_cmd(cmd);
6509
6510 if (host_cmd == -TARGET_EINVAL)
6511 return host_cmd;
53a5960a 6512
7775e9ec
FB
6513 switch(cmd) {
6514 case TARGET_F_GETLK:
213d3e9e
PM
6515 ret = copy_from_user_flock(&fl64, arg);
6516 if (ret) {
6517 return ret;
6518 }
435da5e7 6519 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec 6520 if (ret == 0) {
213d3e9e 6521 ret = copy_to_user_flock(arg, &fl64);
7775e9ec
FB
6522 }
6523 break;
3b46e624 6524
7775e9ec
FB
6525 case TARGET_F_SETLK:
6526 case TARGET_F_SETLKW:
213d3e9e
PM
6527 ret = copy_from_user_flock(&fl64, arg);
6528 if (ret) {
6529 return ret;
6530 }
435da5e7 6531 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec 6532 break;
3b46e624 6533
7775e9ec 6534 case TARGET_F_GETLK64:
2d92c682 6535 case TARGET_F_OFD_GETLK:
213d3e9e
PM
6536 ret = copy_from_user_flock64(&fl64, arg);
6537 if (ret) {
6538 return ret;
6539 }
435da5e7 6540 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
43f238d7 6541 if (ret == 0) {
213d3e9e 6542 ret = copy_to_user_flock64(arg, &fl64);
43f238d7 6543 }
9ee1fa2c 6544 break;
7775e9ec
FB
6545 case TARGET_F_SETLK64:
6546 case TARGET_F_SETLKW64:
2d92c682
AS
6547 case TARGET_F_OFD_SETLK:
6548 case TARGET_F_OFD_SETLKW:
213d3e9e
PM
6549 ret = copy_from_user_flock64(&fl64, arg);
6550 if (ret) {
6551 return ret;
6552 }
435da5e7 6553 ret = get_errno(safe_fcntl(fd, host_cmd, &fl64));
7775e9ec
FB
6554 break;
6555
5f106811 6556 case TARGET_F_GETFL:
435da5e7 6557 ret = get_errno(safe_fcntl(fd, host_cmd, arg));
9ee1fa2c
FB
6558 if (ret >= 0) {
6559 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
6560 }
ffa65c3b
FB
6561 break;
6562
5f106811 6563 case TARGET_F_SETFL:
435da5e7
PM
6564 ret = get_errno(safe_fcntl(fd, host_cmd,
6565 target_to_host_bitmask(arg,
6566 fcntl_flags_tbl)));
5f106811
APR
6567 break;
6568
8d5d3004
AS
6569#ifdef F_GETOWN_EX
6570 case TARGET_F_GETOWN_EX:
435da5e7 6571 ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
8d5d3004
AS
6572 if (ret >= 0) {
6573 if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
6574 return -TARGET_EFAULT;
6575 target_fox->type = tswap32(fox.type);
6576 target_fox->pid = tswap32(fox.pid);
6577 unlock_user_struct(target_fox, arg, 1);
6578 }
6579 break;
6580#endif
6581
6582#ifdef F_SETOWN_EX
6583 case TARGET_F_SETOWN_EX:
6584 if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1))
6585 return -TARGET_EFAULT;
6586 fox.type = tswap32(target_fox->type);
6587 fox.pid = tswap32(target_fox->pid);
6588 unlock_user_struct(target_fox, arg, 0);
435da5e7 6589 ret = get_errno(safe_fcntl(fd, host_cmd, &fox));
8d5d3004
AS
6590 break;
6591#endif
6592
5f106811
APR
6593 case TARGET_F_SETOWN:
6594 case TARGET_F_GETOWN:
6595 case TARGET_F_SETSIG:
6596 case TARGET_F_GETSIG:
7e22e546
UH
6597 case TARGET_F_SETLEASE:
6598 case TARGET_F_GETLEASE:
7e3b92ec
PM
6599 case TARGET_F_SETPIPE_SZ:
6600 case TARGET_F_GETPIPE_SZ:
435da5e7 6601 ret = get_errno(safe_fcntl(fd, host_cmd, arg));
ffa65c3b
FB
6602 break;
6603
7775e9ec 6604 default:
435da5e7 6605 ret = get_errno(safe_fcntl(fd, cmd, arg));
7775e9ec
FB
6606 break;
6607 }
6608 return ret;
6609}
6610
67867308 6611#ifdef USE_UID16
7775e9ec 6612
67867308
FB
6613static inline int high2lowuid(int uid)
6614{
6615 if (uid > 65535)
6616 return 65534;
6617 else
6618 return uid;
6619}
6620
6621static inline int high2lowgid(int gid)
6622{
6623 if (gid > 65535)
6624 return 65534;
6625 else
6626 return gid;
6627}
6628
6629static inline int low2highuid(int uid)
6630{
6631 if ((int16_t)uid == -1)
6632 return -1;
6633 else
6634 return uid;
6635}
6636
6637static inline int low2highgid(int gid)
6638{
6639 if ((int16_t)gid == -1)
6640 return -1;
6641 else
6642 return gid;
6643}
0c866a7e
RV
6644static inline int tswapid(int id)
6645{
6646 return tswap16(id);
6647}
76ca310a
PM
6648
6649#define put_user_id(x, gaddr) put_user_u16(x, gaddr)
6650
0c866a7e
RV
6651#else /* !USE_UID16 */
6652static inline int high2lowuid(int uid)
6653{
6654 return uid;
6655}
6656static inline int high2lowgid(int gid)
6657{
6658 return gid;
6659}
6660static inline int low2highuid(int uid)
6661{
6662 return uid;
6663}
6664static inline int low2highgid(int gid)
6665{
6666 return gid;
6667}
6668static inline int tswapid(int id)
6669{
6670 return tswap32(id);
6671}
76ca310a
PM
6672
6673#define put_user_id(x, gaddr) put_user_u32(x, gaddr)
6674
67867308 6675#endif /* USE_UID16 */
1b6b029e 6676
fd6f7798
PM
6677/* We must do direct syscalls for setting UID/GID, because we want to
6678 * implement the Linux system call semantics of "change only for this thread",
6679 * not the libc/POSIX semantics of "change for all threads in process".
6680 * (See http://ewontfix.com/17/ for more details.)
6681 * We use the 32-bit version of the syscalls if present; if it is not
6682 * then either the host architecture supports 32-bit UIDs natively with
6683 * the standard syscall, or the 16-bit UID is the best we can do.
6684 */
6685#ifdef __NR_setuid32
6686#define __NR_sys_setuid __NR_setuid32
6687#else
6688#define __NR_sys_setuid __NR_setuid
6689#endif
6690#ifdef __NR_setgid32
6691#define __NR_sys_setgid __NR_setgid32
6692#else
6693#define __NR_sys_setgid __NR_setgid
6694#endif
6695#ifdef __NR_setresuid32
6696#define __NR_sys_setresuid __NR_setresuid32
6697#else
6698#define __NR_sys_setresuid __NR_setresuid
6699#endif
6700#ifdef __NR_setresgid32
6701#define __NR_sys_setresgid __NR_setresgid32
6702#else
6703#define __NR_sys_setresgid __NR_setresgid
6704#endif
6705
6706_syscall1(int, sys_setuid, uid_t, uid)
6707_syscall1(int, sys_setgid, gid_t, gid)
6708_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
6709_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
6710
31e31b8a
FB
6711void syscall_init(void)
6712{
2ab83ea7
FB
6713 IOCTLEntry *ie;
6714 const argtype *arg_type;
6715 int size;
b92c47c1 6716 int i;
2ab83ea7 6717
8be656b8
AG
6718 thunk_init(STRUCT_MAX);
6719
001faf32 6720#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
5fafdf24 6721#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
31e31b8a
FB
6722#include "syscall_types.h"
6723#undef STRUCT
6724#undef STRUCT_SPECIAL
2ab83ea7 6725
dd6e957a
PM
6726 /* Build target_to_host_errno_table[] table from
6727 * host_to_target_errno_table[]. */
6728 for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
6729 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
6730 }
6731
2ab83ea7
FB
6732 /* we patch the ioctl size if necessary. We rely on the fact that
6733 no ioctl has all the bits at '1' in the size field */
6734 ie = ioctl_entries;
6735 while (ie->target_cmd != 0) {
6736 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
6737 TARGET_IOC_SIZEMASK) {
6738 arg_type = ie->arg_type;
6739 if (arg_type[0] != TYPE_PTR) {
5fafdf24 6740 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
2ab83ea7
FB
6741 ie->target_cmd);
6742 exit(1);
6743 }
6744 arg_type++;
6745 size = thunk_type_size(arg_type, 0);
5fafdf24 6746 ie->target_cmd = (ie->target_cmd &
2ab83ea7
FB
6747 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
6748 (size << TARGET_IOC_SIZESHIFT);
6749 }
b92c47c1 6750
2ab83ea7 6751 /* automatic consistency check if same arch */
872ea0c0
AZ
6752#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6753 (defined(__x86_64__) && defined(TARGET_X86_64))
6754 if (unlikely(ie->target_cmd != ie->host_cmd)) {
6755 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
6756 ie->name, ie->target_cmd, ie->host_cmd);
2ab83ea7
FB
6757 }
6758#endif
6759 ie++;
6760 }
31e31b8a 6761}
c573ff67 6762
ce4defa0 6763#ifdef TARGET_NR_truncate64
992f48a0
BS
6764static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
6765 abi_long arg2,
6766 abi_long arg3,
6767 abi_long arg4)
ce4defa0 6768{
8bf8e9df 6769 if (regpairs_aligned(cpu_env, TARGET_NR_truncate64)) {
ce4defa0
PB
6770 arg2 = arg3;
6771 arg3 = arg4;
48e515d4 6772 }
ce4defa0
PB
6773 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
6774}
6775#endif
6776
6777#ifdef TARGET_NR_ftruncate64
992f48a0
BS
6778static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
6779 abi_long arg2,
6780 abi_long arg3,
6781 abi_long arg4)
ce4defa0 6782{
8bf8e9df 6783 if (regpairs_aligned(cpu_env, TARGET_NR_ftruncate64)) {
ce4defa0
PB
6784 arg2 = arg3;
6785 arg3 = arg4;
48e515d4 6786 }
ce4defa0
PB
6787 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
6788}
6789#endif
6790
859e8a89
AF
6791#if defined(TARGET_NR_timer_settime) || \
6792 (defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD))
f4f1e10a
ECL
6793static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec,
6794 abi_ulong target_addr)
6795{
6796 struct target_itimerspec *target_itspec;
6797
6798 if (!lock_user_struct(VERIFY_READ, target_itspec, target_addr, 1)) {
6799 return -TARGET_EFAULT;
6800 }
6801
6802 host_itspec->it_interval.tv_sec =
6803 tswapal(target_itspec->it_interval.tv_sec);
6804 host_itspec->it_interval.tv_nsec =
6805 tswapal(target_itspec->it_interval.tv_nsec);
6806 host_itspec->it_value.tv_sec = tswapal(target_itspec->it_value.tv_sec);
6807 host_itspec->it_value.tv_nsec = tswapal(target_itspec->it_value.tv_nsec);
6808
6809 unlock_user_struct(target_itspec, target_addr, 1);
6810 return 0;
6811}
859e8a89 6812#endif
f4f1e10a 6813
859e8a89
AF
6814#if ((defined(TARGET_NR_timerfd_gettime) || \
6815 defined(TARGET_NR_timerfd_settime)) && defined(CONFIG_TIMERFD)) || \
6816 defined(TARGET_NR_timer_gettime) || defined(TARGET_NR_timer_settime)
f4f1e10a
ECL
6817static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
6818 struct itimerspec *host_its)
6819{
6820 struct target_itimerspec *target_itspec;
6821
6822 if (!lock_user_struct(VERIFY_WRITE, target_itspec, target_addr, 0)) {
6823 return -TARGET_EFAULT;
6824 }
6825
6826 target_itspec->it_interval.tv_sec = tswapal(host_its->it_interval.tv_sec);
6827 target_itspec->it_interval.tv_nsec = tswapal(host_its->it_interval.tv_nsec);
6828
6829 target_itspec->it_value.tv_sec = tswapal(host_its->it_value.tv_sec);
6830 target_itspec->it_value.tv_nsec = tswapal(host_its->it_value.tv_nsec);
6831
6832 unlock_user_struct(target_itspec, target_addr, 0);
6833 return 0;
6834}
859e8a89 6835#endif
f4f1e10a 6836
859e8a89
AF
6837#if defined(TARGET_NR_adjtimex) || \
6838 (defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME))
19f59bce
AM
6839static inline abi_long target_to_host_timex(struct timex *host_tx,
6840 abi_long target_addr)
6841{
6842 struct target_timex *target_tx;
6843
6844 if (!lock_user_struct(VERIFY_READ, target_tx, target_addr, 1)) {
6845 return -TARGET_EFAULT;
6846 }
6847
6848 __get_user(host_tx->modes, &target_tx->modes);
6849 __get_user(host_tx->offset, &target_tx->offset);
6850 __get_user(host_tx->freq, &target_tx->freq);
6851 __get_user(host_tx->maxerror, &target_tx->maxerror);
6852 __get_user(host_tx->esterror, &target_tx->esterror);
6853 __get_user(host_tx->status, &target_tx->status);
6854 __get_user(host_tx->constant, &target_tx->constant);
6855 __get_user(host_tx->precision, &target_tx->precision);
6856 __get_user(host_tx->tolerance, &target_tx->tolerance);
6857 __get_user(host_tx->time.tv_sec, &target_tx->time.tv_sec);
6858 __get_user(host_tx->time.tv_usec, &target_tx->time.tv_usec);
6859 __get_user(host_tx->tick, &target_tx->tick);
6860 __get_user(host_tx->ppsfreq, &target_tx->ppsfreq);
6861 __get_user(host_tx->jitter, &target_tx->jitter);
6862 __get_user(host_tx->shift, &target_tx->shift);
6863 __get_user(host_tx->stabil, &target_tx->stabil);
6864 __get_user(host_tx->jitcnt, &target_tx->jitcnt);
6865 __get_user(host_tx->calcnt, &target_tx->calcnt);
6866 __get_user(host_tx->errcnt, &target_tx->errcnt);
6867 __get_user(host_tx->stbcnt, &target_tx->stbcnt);
6868 __get_user(host_tx->tai, &target_tx->tai);
6869
6870 unlock_user_struct(target_tx, target_addr, 0);
6871 return 0;
6872}
6873
6874static inline abi_long host_to_target_timex(abi_long target_addr,
6875 struct timex *host_tx)
6876{
6877 struct target_timex *target_tx;
6878
6879 if (!lock_user_struct(VERIFY_WRITE, target_tx, target_addr, 0)) {
6880 return -TARGET_EFAULT;
6881 }
6882
6883 __put_user(host_tx->modes, &target_tx->modes);
6884 __put_user(host_tx->offset, &target_tx->offset);
6885 __put_user(host_tx->freq, &target_tx->freq);
6886 __put_user(host_tx->maxerror, &target_tx->maxerror);
6887 __put_user(host_tx->esterror, &target_tx->esterror);
6888 __put_user(host_tx->status, &target_tx->status);
6889 __put_user(host_tx->constant, &target_tx->constant);
6890 __put_user(host_tx->precision, &target_tx->precision);
6891 __put_user(host_tx->tolerance, &target_tx->tolerance);
6892 __put_user(host_tx->time.tv_sec, &target_tx->time.tv_sec);
6893 __put_user(host_tx->time.tv_usec, &target_tx->time.tv_usec);
6894 __put_user(host_tx->tick, &target_tx->tick);
6895 __put_user(host_tx->ppsfreq, &target_tx->ppsfreq);
6896 __put_user(host_tx->jitter, &target_tx->jitter);
6897 __put_user(host_tx->shift, &target_tx->shift);
6898 __put_user(host_tx->stabil, &target_tx->stabil);
6899 __put_user(host_tx->jitcnt, &target_tx->jitcnt);
6900 __put_user(host_tx->calcnt, &target_tx->calcnt);
6901 __put_user(host_tx->errcnt, &target_tx->errcnt);
6902 __put_user(host_tx->stbcnt, &target_tx->stbcnt);
6903 __put_user(host_tx->tai, &target_tx->tai);
6904
6905 unlock_user_struct(target_tx, target_addr, 1);
6906 return 0;
6907}
859e8a89 6908#endif
19f59bce 6909
c065976f
PM
6910static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
6911 abi_ulong target_addr)
6912{
6913 struct target_sigevent *target_sevp;
6914
6915 if (!lock_user_struct(VERIFY_READ, target_sevp, target_addr, 1)) {
6916 return -TARGET_EFAULT;
6917 }
6918
6919 /* This union is awkward on 64 bit systems because it has a 32 bit
6920 * integer and a pointer in it; we follow the conversion approach
6921 * used for handling sigval types in signal.c so the guest should get
6922 * the correct value back even if we did a 64 bit byteswap and it's
6923 * using the 32 bit integer.
6924 */
6925 host_sevp->sigev_value.sival_ptr =
6926 (void *)(uintptr_t)tswapal(target_sevp->sigev_value.sival_ptr);
6927 host_sevp->sigev_signo =
6928 target_to_host_signal(tswap32(target_sevp->sigev_signo));
6929 host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
6930 host_sevp->_sigev_un._tid = tswap32(target_sevp->_sigev_un._tid);
6931
6932 unlock_user_struct(target_sevp, target_addr, 1);
6933 return 0;
6934}
6935
6f6a4032
TM
6936#if defined(TARGET_NR_mlockall)
6937static inline int target_to_host_mlockall_arg(int arg)
6938{
6939 int result = 0;
6940
6941 if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
6942 result |= MCL_CURRENT;
6943 }
6944 if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
6945 result |= MCL_FUTURE;
6946 }
6947 return result;
6948}
6949#endif
6950
4f7f8924
AR
6951#if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) || \
6952 defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) || \
6953 defined(TARGET_NR_newfstatat))
6a24a778
AZ
6954static inline abi_long host_to_target_stat64(void *cpu_env,
6955 abi_ulong target_addr,
6956 struct stat *host_st)
6957{
09701199 6958#if defined(TARGET_ARM) && defined(TARGET_ABI32)
6a24a778
AZ
6959 if (((CPUARMState *)cpu_env)->eabi) {
6960 struct target_eabi_stat64 *target_st;
6961
6962 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
6963 return -TARGET_EFAULT;
6964 memset(target_st, 0, sizeof(struct target_eabi_stat64));
6965 __put_user(host_st->st_dev, &target_st->st_dev);
6966 __put_user(host_st->st_ino, &target_st->st_ino);
6967#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
6968 __put_user(host_st->st_ino, &target_st->__st_ino);
6969#endif
6970 __put_user(host_st->st_mode, &target_st->st_mode);
6971 __put_user(host_st->st_nlink, &target_st->st_nlink);
6972 __put_user(host_st->st_uid, &target_st->st_uid);
6973 __put_user(host_st->st_gid, &target_st->st_gid);
6974 __put_user(host_st->st_rdev, &target_st->st_rdev);
6975 __put_user(host_st->st_size, &target_st->st_size);
6976 __put_user(host_st->st_blksize, &target_st->st_blksize);
6977 __put_user(host_st->st_blocks, &target_st->st_blocks);
6978 __put_user(host_st->st_atime, &target_st->target_st_atime);
6979 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
6980 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5f992db6
CYT
6981#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
6982 __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
6983 __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
6984 __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
6985#endif
6a24a778
AZ
6986 unlock_user_struct(target_st, target_addr, 1);
6987 } else
6988#endif
6989 {
20d155bc 6990#if defined(TARGET_HAS_STRUCT_STAT64)
6a24a778 6991 struct target_stat64 *target_st;
20d155bc
SW
6992#else
6993 struct target_stat *target_st;
9d33b76b 6994#endif
6a24a778
AZ
6995
6996 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
6997 return -TARGET_EFAULT;
9d33b76b 6998 memset(target_st, 0, sizeof(*target_st));
6a24a778
AZ
6999 __put_user(host_st->st_dev, &target_st->st_dev);
7000 __put_user(host_st->st_ino, &target_st->st_ino);
7001#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
7002 __put_user(host_st->st_ino, &target_st->__st_ino);
7003#endif
7004 __put_user(host_st->st_mode, &target_st->st_mode);
7005 __put_user(host_st->st_nlink, &target_st->st_nlink);
7006 __put_user(host_st->st_uid, &target_st->st_uid);
7007 __put_user(host_st->st_gid, &target_st->st_gid);
7008 __put_user(host_st->st_rdev, &target_st->st_rdev);
7009 /* XXX: better use of kernel struct */
7010 __put_user(host_st->st_size, &target_st->st_size);
7011 __put_user(host_st->st_blksize, &target_st->st_blksize);
7012 __put_user(host_st->st_blocks, &target_st->st_blocks);
7013 __put_user(host_st->st_atime, &target_st->target_st_atime);
7014 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
7015 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5f992db6
CYT
7016#if _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
7017 __put_user(host_st->st_atim.tv_nsec, &target_st->target_st_atime_nsec);
7018 __put_user(host_st->st_mtim.tv_nsec, &target_st->target_st_mtime_nsec);
7019 __put_user(host_st->st_ctim.tv_nsec, &target_st->target_st_ctime_nsec);
7020#endif
6a24a778
AZ
7021 unlock_user_struct(target_st, target_addr, 1);
7022 }
7023
7024 return 0;
7025}
4f7f8924 7026#endif
6a24a778 7027
efa92184
AR
7028#if defined(TARGET_NR_statx) && defined(__NR_statx)
7029static inline abi_long host_to_target_statx(struct target_statx *host_stx,
7030 abi_ulong target_addr)
7031{
7032 struct target_statx *target_stx;
7033
7034 if (!lock_user_struct(VERIFY_WRITE, target_stx, target_addr, 0)) {
7035 return -TARGET_EFAULT;
7036 }
7037 memset(target_stx, 0, sizeof(*target_stx));
7038
7039 __put_user(host_stx->stx_mask, &target_stx->stx_mask);
7040 __put_user(host_stx->stx_blksize, &target_stx->stx_blksize);
7041 __put_user(host_stx->stx_attributes, &target_stx->stx_attributes);
7042 __put_user(host_stx->stx_nlink, &target_stx->stx_nlink);
7043 __put_user(host_stx->stx_uid, &target_stx->stx_uid);
7044 __put_user(host_stx->stx_gid, &target_stx->stx_gid);
7045 __put_user(host_stx->stx_mode, &target_stx->stx_mode);
7046 __put_user(host_stx->stx_ino, &target_stx->stx_ino);
7047 __put_user(host_stx->stx_size, &target_stx->stx_size);
7048 __put_user(host_stx->stx_blocks, &target_stx->stx_blocks);
7049 __put_user(host_stx->stx_attributes_mask, &target_stx->stx_attributes_mask);
7050 __put_user(host_stx->stx_atime.tv_sec, &target_stx->stx_atime.tv_sec);
7051 __put_user(host_stx->stx_atime.tv_nsec, &target_stx->stx_atime.tv_nsec);
d1e26707
AC
7052 __put_user(host_stx->stx_btime.tv_sec, &target_stx->stx_btime.tv_sec);
7053 __put_user(host_stx->stx_btime.tv_nsec, &target_stx->stx_btime.tv_nsec);
7054 __put_user(host_stx->stx_ctime.tv_sec, &target_stx->stx_ctime.tv_sec);
7055 __put_user(host_stx->stx_ctime.tv_nsec, &target_stx->stx_ctime.tv_nsec);
7056 __put_user(host_stx->stx_mtime.tv_sec, &target_stx->stx_mtime.tv_sec);
7057 __put_user(host_stx->stx_mtime.tv_nsec, &target_stx->stx_mtime.tv_nsec);
efa92184
AR
7058 __put_user(host_stx->stx_rdev_major, &target_stx->stx_rdev_major);
7059 __put_user(host_stx->stx_rdev_minor, &target_stx->stx_rdev_minor);
7060 __put_user(host_stx->stx_dev_major, &target_stx->stx_dev_major);
7061 __put_user(host_stx->stx_dev_minor, &target_stx->stx_dev_minor);
7062
7063 unlock_user_struct(target_stx, target_addr, 1);
7064
7065 return 0;
7066}
7067#endif
7068
14690296
AF
7069static int do_sys_futex(int *uaddr, int op, int val,
7070 const struct timespec *timeout, int *uaddr2,
7071 int val3)
7072{
7073#if HOST_LONG_BITS == 64
7074#if defined(__NR_futex)
7075 /* always a 64-bit time_t, it doesn't define _time64 version */
7076 return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
7077
7078#endif
7079#else /* HOST_LONG_BITS == 64 */
7080#if defined(__NR_futex_time64)
7081 if (sizeof(timeout->tv_sec) == 8) {
7082 /* _time64 function on 32bit arch */
7083 return sys_futex_time64(uaddr, op, val, timeout, uaddr2, val3);
7084 }
7085#endif
7086#if defined(__NR_futex)
7087 /* old function on 32bit arch */
7088 return sys_futex(uaddr, op, val, timeout, uaddr2, val3);
7089#endif
7090#endif /* HOST_LONG_BITS == 64 */
7091 g_assert_not_reached();
7092}
7093
7094static int do_safe_futex(int *uaddr, int op, int val,
7095 const struct timespec *timeout, int *uaddr2,
7096 int val3)
7097{
7098#if HOST_LONG_BITS == 64
7099#if defined(__NR_futex)
7100 /* always a 64-bit time_t, it doesn't define _time64 version */
7101 return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
7102#endif
7103#else /* HOST_LONG_BITS == 64 */
7104#if defined(__NR_futex_time64)
7105 if (sizeof(timeout->tv_sec) == 8) {
7106 /* _time64 function on 32bit arch */
7107 return get_errno(safe_futex_time64(uaddr, op, val, timeout, uaddr2,
7108 val3));
7109 }
7110#endif
7111#if defined(__NR_futex)
7112 /* old function on 32bit arch */
7113 return get_errno(safe_futex(uaddr, op, val, timeout, uaddr2, val3));
7114#endif
7115#endif /* HOST_LONG_BITS == 64 */
7116 return -TARGET_ENOSYS;
7117}
efa92184 7118
bd0c5661
PB
7119/* ??? Using host futex calls even when target atomic operations
7120 are not really atomic probably breaks things. However implementing
7121 futexes locally would make futexes shared between multiple processes
7122 tricky. However they're probably useless because guest atomic
7123 operations won't work either. */
859e8a89 7124#if defined(TARGET_NR_futex)
8fcd3692
BS
7125static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
7126 target_ulong uaddr2, int val3)
bd0c5661
PB
7127{
7128 struct timespec ts, *pts;
a16aae0c 7129 int base_op;
bd0c5661
PB
7130
7131 /* ??? We assume FUTEX_* constants are the same on both host
7132 and target. */
a29ccd63 7133#ifdef FUTEX_CMD_MASK
a16aae0c 7134 base_op = op & FUTEX_CMD_MASK;
a29ccd63 7135#else
a16aae0c 7136 base_op = op;
a29ccd63 7137#endif
a16aae0c 7138 switch (base_op) {
bd0c5661 7139 case FUTEX_WAIT:
cce246e0 7140 case FUTEX_WAIT_BITSET:
bd0c5661
PB
7141 if (timeout) {
7142 pts = &ts;
7143 target_to_host_timespec(pts, timeout);
7144 } else {
7145 pts = NULL;
7146 }
14690296 7147 return do_safe_futex(g2h(uaddr), op, tswap32(val), pts, NULL, val3);
bd0c5661 7148 case FUTEX_WAKE:
14690296 7149 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
bd0c5661 7150 case FUTEX_FD:
14690296 7151 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
bd0c5661 7152 case FUTEX_REQUEUE:
bd0c5661 7153 case FUTEX_CMP_REQUEUE:
a16aae0c
NF
7154 case FUTEX_WAKE_OP:
7155 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
7156 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
7157 But the prototype takes a `struct timespec *'; insert casts
7158 to satisfy the compiler. We do not need to tswap TIMEOUT
7159 since it's not compared to guest memory. */
7160 pts = (struct timespec *)(uintptr_t) timeout;
14690296
AF
7161 return do_safe_futex(g2h(uaddr), op, val, pts, g2h(uaddr2),
7162 (base_op == FUTEX_CMP_REQUEUE
7163 ? tswap32(val3)
7164 : val3));
bd0c5661
PB
7165 default:
7166 return -TARGET_ENOSYS;
7167 }
7168}
859e8a89 7169#endif
14690296
AF
7170
7171#if defined(TARGET_NR_futex_time64)
7172static int do_futex_time64(target_ulong uaddr, int op, int val, target_ulong timeout,
7173 target_ulong uaddr2, int val3)
7174{
7175 struct timespec ts, *pts;
7176 int base_op;
7177
7178 /* ??? We assume FUTEX_* constants are the same on both host
7179 and target. */
7180#ifdef FUTEX_CMD_MASK
7181 base_op = op & FUTEX_CMD_MASK;
7182#else
7183 base_op = op;
7184#endif
7185 switch (base_op) {
7186 case FUTEX_WAIT:
7187 case FUTEX_WAIT_BITSET:
7188 if (timeout) {
7189 pts = &ts;
7190 target_to_host_timespec64(pts, timeout);
7191 } else {
7192 pts = NULL;
7193 }
7194 return do_safe_futex(g2h(uaddr), op, tswap32(val), pts, NULL, val3);
7195 case FUTEX_WAKE:
7196 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
7197 case FUTEX_FD:
7198 return do_safe_futex(g2h(uaddr), op, val, NULL, NULL, 0);
7199 case FUTEX_REQUEUE:
7200 case FUTEX_CMP_REQUEUE:
7201 case FUTEX_WAKE_OP:
7202 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
7203 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
7204 But the prototype takes a `struct timespec *'; insert casts
7205 to satisfy the compiler. We do not need to tswap TIMEOUT
7206 since it's not compared to guest memory. */
7207 pts = (struct timespec *)(uintptr_t) timeout;
7208 return do_safe_futex(g2h(uaddr), op, val, pts, g2h(uaddr2),
7209 (base_op == FUTEX_CMP_REQUEUE
7210 ? tswap32(val3)
7211 : val3));
7212 default:
7213 return -TARGET_ENOSYS;
7214 }
7215}
7216#endif
7217
0f0426f3
LV
7218#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7219static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
7220 abi_long handle, abi_long mount_id,
7221 abi_long flags)
7222{
7223 struct file_handle *target_fh;
7224 struct file_handle *fh;
7225 int mid = 0;
7226 abi_long ret;
7227 char *name;
7228 unsigned int size, total_size;
7229
7230 if (get_user_s32(size, handle)) {
7231 return -TARGET_EFAULT;
7232 }
7233
7234 name = lock_user_string(pathname);
7235 if (!name) {
7236 return -TARGET_EFAULT;
7237 }
7238
7239 total_size = sizeof(struct file_handle) + size;
7240 target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
7241 if (!target_fh) {
7242 unlock_user(name, pathname, 0);
7243 return -TARGET_EFAULT;
7244 }
7245
7246 fh = g_malloc0(total_size);
7247 fh->handle_bytes = size;
7248
7249 ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
7250 unlock_user(name, pathname, 0);
7251
7252 /* man name_to_handle_at(2):
7253 * Other than the use of the handle_bytes field, the caller should treat
7254 * the file_handle structure as an opaque data type
7255 */
7256
7257 memcpy(target_fh, fh, total_size);
7258 target_fh->handle_bytes = tswap32(fh->handle_bytes);
7259 target_fh->handle_type = tswap32(fh->handle_type);
7260 g_free(fh);
7261 unlock_user(target_fh, handle, total_size);
7262
7263 if (put_user_s32(mid, mount_id)) {
7264 return -TARGET_EFAULT;
7265 }
7266
7267 return ret;
7268
7269}
7270#endif
7271
7272#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7273static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
7274 abi_long flags)
7275{
7276 struct file_handle *target_fh;
7277 struct file_handle *fh;
7278 unsigned int size, total_size;
7279 abi_long ret;
7280
7281 if (get_user_s32(size, handle)) {
7282 return -TARGET_EFAULT;
7283 }
7284
7285 total_size = sizeof(struct file_handle) + size;
7286 target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
7287 if (!target_fh) {
7288 return -TARGET_EFAULT;
7289 }
7290
e9d49d51 7291 fh = g_memdup(target_fh, total_size);
0f0426f3
LV
7292 fh->handle_bytes = size;
7293 fh->handle_type = tswap32(target_fh->handle_type);
7294
7295 ret = get_errno(open_by_handle_at(mount_fd, fh,
7296 target_to_host_bitmask(flags, fcntl_flags_tbl)));
7297
7298 g_free(fh);
7299
7300 unlock_user(target_fh, handle, total_size);
7301
7302 return ret;
7303}
7304#endif
bd0c5661 7305
e36800c9
LV
7306#if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
7307
e36800c9
LV
7308static abi_long do_signalfd4(int fd, abi_long mask, int flags)
7309{
7310 int host_flags;
7311 target_sigset_t *target_mask;
7312 sigset_t host_mask;
7313 abi_long ret;
7314
7315 if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
7316 return -TARGET_EINVAL;
7317 }
7318 if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
7319 return -TARGET_EFAULT;
7320 }
7321
7322 target_to_host_sigset(&host_mask, target_mask);
7323
7324 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
7325
7326 ret = get_errno(signalfd(fd, &host_mask, host_flags));
7327 if (ret >= 0) {
7328 fd_trans_register(ret, &target_signalfd_trans);
7329 }
7330
7331 unlock_user_struct(target_mask, mask, 0);
7332
7333 return ret;
7334}
7335#endif
7336
1d9d8b55
PB
7337/* Map host to target signal numbers for the wait family of syscalls.
7338 Assume all other status bits are the same. */
a05c6409 7339int host_to_target_waitstatus(int status)
1d9d8b55
PB
7340{
7341 if (WIFSIGNALED(status)) {
7342 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
7343 }
7344 if (WIFSTOPPED(status)) {
7345 return (host_to_target_signal(WSTOPSIG(status)) << 8)
7346 | (status & 0xff);
7347 }
7348 return status;
7349}
7350
76b94245
WVS
7351static int open_self_cmdline(void *cpu_env, int fd)
7352{
29a0af61 7353 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
58de8b96
AS
7354 struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
7355 int i;
76b94245 7356
58de8b96
AS
7357 for (i = 0; i < bprm->argc; i++) {
7358 size_t len = strlen(bprm->argv[i]) + 1;
76b94245 7359
58de8b96 7360 if (write(fd, bprm->argv[i], len) != len) {
76b94245 7361 return -1;
76b94245
WVS
7362 }
7363 }
7364
58de8b96 7365 return 0;
76b94245
WVS
7366}
7367
36c08d49
AG
7368static int open_self_maps(void *cpu_env, int fd)
7369{
29a0af61 7370 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7371 TaskState *ts = cpu->opaque;
01ef6b9e
AB
7372 GSList *map_info = read_self_maps();
7373 GSList *s;
bb55173c 7374 int count;
1a49ef2a 7375
01ef6b9e
AB
7376 for (s = map_info; s; s = g_slist_next(s)) {
7377 MapInfo *e = (MapInfo *) s->data;
1a49ef2a 7378
01ef6b9e
AB
7379 if (h2g_valid(e->start)) {
7380 unsigned long min = e->start;
7381 unsigned long max = e->end;
d67f4aaa 7382 int flags = page_get_flags(h2g(min));
01ef6b9e
AB
7383 const char *path;
7384
7385 max = h2g_valid(max - 1) ?
7386 max : (uintptr_t) g2h(GUEST_ADDR_MAX) + 1;
7387
d67f4aaa
MI
7388 if (page_check_range(h2g(min), max - min, flags) == -1) {
7389 continue;
7390 }
01ef6b9e 7391
d67f4aaa 7392 if (h2g(min) == ts->info->stack_limit) {
bb55173c 7393 path = "[stack]";
01ef6b9e
AB
7394 } else {
7395 path = e->path;
d67f4aaa 7396 }
01ef6b9e 7397
bb55173c
AB
7398 count = dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr
7399 " %c%c%c%c %08" PRIx64 " %s %"PRId64,
7400 h2g(min), h2g(max - 1) + 1,
7401 e->is_read ? 'r' : '-',
7402 e->is_write ? 'w' : '-',
7403 e->is_exec ? 'x' : '-',
7404 e->is_priv ? 'p' : '-',
7405 (uint64_t) e->offset, e->dev, e->inode);
7406 if (path) {
7407 dprintf(fd, "%*s%s\n", 73 - count, "", path);
7408 } else {
7409 dprintf(fd, "\n");
7410 }
1a49ef2a
AG
7411 }
7412 }
7413
01ef6b9e
AB
7414 free_self_maps(map_info);
7415
bf02adcd
RH
7416#ifdef TARGET_VSYSCALL_PAGE
7417 /*
7418 * We only support execution from the vsyscall page.
7419 * This is as if CONFIG_LEGACY_VSYSCALL_XONLY=y from v5.3.
7420 */
bb55173c
AB
7421 count = dprintf(fd, TARGET_FMT_lx "-" TARGET_FMT_lx
7422 " --xp 00000000 00:00 0",
7423 TARGET_VSYSCALL_PAGE, TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE);
7424 dprintf(fd, "%*s%s\n", 73 - count, "", "[vsyscall]");
bf02adcd
RH
7425#endif
7426
36c08d49
AG
7427 return 0;
7428}
7429
480b8e7d
AG
7430static int open_self_stat(void *cpu_env, int fd)
7431{
29a0af61 7432 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7433 TaskState *ts = cpu->opaque;
7ad4d5a4 7434 g_autoptr(GString) buf = g_string_new(NULL);
480b8e7d
AG
7435 int i;
7436
7437 for (i = 0; i < 44; i++) {
7ad4d5a4
AB
7438 if (i == 0) {
7439 /* pid */
7440 g_string_printf(buf, FMT_pid " ", getpid());
7441 } else if (i == 1) {
7442 /* app name */
7443 gchar *bin = g_strrstr(ts->bprm->argv[0], "/");
7444 bin = bin ? bin + 1 : ts->bprm->argv[0];
7445 g_string_printf(buf, "(%.15s) ", bin);
7446 } else if (i == 27) {
7447 /* stack bottom */
7448 g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
7449 } else {
7450 /* for the rest, there is MasterCard */
7451 g_string_printf(buf, "0%c", i == 43 ? '\n' : ' ');
7452 }
7453
7454 if (write(fd, buf->str, buf->len) != buf->len) {
7455 return -1;
7456 }
480b8e7d
AG
7457 }
7458
7459 return 0;
7460}
7461
257450ee
AG
7462static int open_self_auxv(void *cpu_env, int fd)
7463{
29a0af61 7464 CPUState *cpu = env_cpu((CPUArchState *)cpu_env);
0429a971 7465 TaskState *ts = cpu->opaque;
257450ee
AG
7466 abi_ulong auxv = ts->info->saved_auxv;
7467 abi_ulong len = ts->info->auxv_len;
7468 char *ptr;
7469
7470 /*
7471 * Auxiliary vector is stored in target process stack.
7472 * read in whole auxv vector and copy it to file
7473 */
7474 ptr = lock_user(VERIFY_READ, auxv, len, 0);
7475 if (ptr != NULL) {
7476 while (len > 0) {
7477 ssize_t r;
7478 r = write(fd, ptr, len);
7479 if (r <= 0) {
7480 break;
7481 }
7482 len -= r;
7483 ptr += r;
7484 }
7485 lseek(fd, 0, SEEK_SET);
7486 unlock_user(ptr, auxv, len);
7487 }
7488
7489 return 0;
7490}
7491
463d8e73
AS
7492static int is_proc_myself(const char *filename, const char *entry)
7493{
7494 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
7495 filename += strlen("/proc/");
7496 if (!strncmp(filename, "self/", strlen("self/"))) {
7497 filename += strlen("self/");
7498 } else if (*filename >= '1' && *filename <= '9') {
7499 char myself[80];
7500 snprintf(myself, sizeof(myself), "%d/", getpid());
7501 if (!strncmp(filename, myself, strlen(myself))) {
7502 filename += strlen(myself);
7503 } else {
7504 return 0;
7505 }
7506 } else {
7507 return 0;
7508 }
7509 if (!strcmp(filename, entry)) {
7510 return 1;
7511 }
7512 }
7513 return 0;
7514}
7515
fff69382 7516#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \
93a5661d 7517 defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA)
de6b9933
LV
7518static int is_proc(const char *filename, const char *entry)
7519{
7520 return strcmp(filename, entry) == 0;
7521}
fff69382 7522#endif
de6b9933 7523
fff69382 7524#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
de6b9933
LV
7525static int open_net_route(void *cpu_env, int fd)
7526{
7527 FILE *fp;
7528 char *line = NULL;
7529 size_t len = 0;
7530 ssize_t read;
7531
7532 fp = fopen("/proc/net/route", "r");
7533 if (fp == NULL) {
a3ca7bb2 7534 return -1;
de6b9933
LV
7535 }
7536
7537 /* read header */
7538
7539 read = getline(&line, &len, fp);
7540 dprintf(fd, "%s", line);
7541
7542 /* read routes */
7543
7544 while ((read = getline(&line, &len, fp)) != -1) {
7545 char iface[16];
7546 uint32_t dest, gw, mask;
7547 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
9d0bd0cd
PM
7548 int fields;
7549
7550 fields = sscanf(line,
7551 "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
7552 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
7553 &mask, &mtu, &window, &irtt);
7554 if (fields != 11) {
7555 continue;
7556 }
de6b9933
LV
7557 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
7558 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
7559 metric, tswap32(mask), mtu, window, irtt);
7560 }
7561
7562 free(line);
7563 fclose(fp);
7564
7565 return 0;
7566}
7567#endif
7568
fff69382
LV
7569#if defined(TARGET_SPARC)
7570static int open_cpuinfo(void *cpu_env, int fd)
7571{
7572 dprintf(fd, "type\t\t: sun4u\n");
7573 return 0;
7574}
7575#endif
7576
93a5661d
HD
7577#if defined(TARGET_HPPA)
7578static int open_cpuinfo(void *cpu_env, int fd)
7579{
7580 dprintf(fd, "cpu family\t: PA-RISC 1.1e\n");
7581 dprintf(fd, "cpu\t\t: PA7300LC (PCX-L2)\n");
7582 dprintf(fd, "capabilities\t: os32\n");
7583 dprintf(fd, "model\t\t: 9000/778/B160L\n");
7584 dprintf(fd, "model name\t: Merlin L2 160 QEMU (9000/778/B160L)\n");
7585 return 0;
7586}
7587#endif
7588
4ab6713e
LV
7589#if defined(TARGET_M68K)
7590static int open_hardware(void *cpu_env, int fd)
7591{
7592 dprintf(fd, "Model:\t\tqemu-m68k\n");
7593 return 0;
7594}
7595#endif
7596
0b2effd7 7597static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
3be14d05
AG
7598{
7599 struct fake_open {
7600 const char *filename;
7601 int (*fill)(void *cpu_env, int fd);
de6b9933 7602 int (*cmp)(const char *s1, const char *s2);
3be14d05
AG
7603 };
7604 const struct fake_open *fake_open;
7605 static const struct fake_open fakes[] = {
de6b9933
LV
7606 { "maps", open_self_maps, is_proc_myself },
7607 { "stat", open_self_stat, is_proc_myself },
7608 { "auxv", open_self_auxv, is_proc_myself },
76b94245 7609 { "cmdline", open_self_cmdline, is_proc_myself },
de6b9933
LV
7610#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
7611 { "/proc/net/route", open_net_route, is_proc },
fff69382 7612#endif
93a5661d 7613#if defined(TARGET_SPARC) || defined(TARGET_HPPA)
fff69382 7614 { "/proc/cpuinfo", open_cpuinfo, is_proc },
4ab6713e
LV
7615#endif
7616#if defined(TARGET_M68K)
7617 { "/proc/hardware", open_hardware, is_proc },
de6b9933
LV
7618#endif
7619 { NULL, NULL, NULL }
3be14d05
AG
7620 };
7621
aa07f5ec
MO
7622 if (is_proc_myself(pathname, "exe")) {
7623 int execfd = qemu_getauxval(AT_EXECFD);
c10a0738 7624 return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
aa07f5ec
MO
7625 }
7626
3be14d05 7627 for (fake_open = fakes; fake_open->filename; fake_open++) {
de6b9933 7628 if (fake_open->cmp(pathname, fake_open->filename)) {
3be14d05
AG
7629 break;
7630 }
7631 }
7632
7633 if (fake_open->filename) {
7634 const char *tmpdir;
7635 char filename[PATH_MAX];
7636 int fd, r;
7637
7638 /* create temporary file to map stat to */
7639 tmpdir = getenv("TMPDIR");
7640 if (!tmpdir)
7641 tmpdir = "/tmp";
7642 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
7643 fd = mkstemp(filename);
7644 if (fd < 0) {
7645 return fd;
7646 }
7647 unlink(filename);
7648
7649 if ((r = fake_open->fill(cpu_env, fd))) {
a3ca7bb2 7650 int e = errno;
3be14d05 7651 close(fd);
a3ca7bb2 7652 errno = e;
3be14d05
AG
7653 return r;
7654 }
7655 lseek(fd, 0, SEEK_SET);
7656
7657 return fd;
7658 }
7659
c10a0738 7660 return safe_openat(dirfd, path(pathname), flags, mode);
3be14d05
AG
7661}
7662
aecc8861
AG
7663#define TIMER_MAGIC 0x0caf0000
7664#define TIMER_MAGIC_MASK 0xffff0000
7665
7666/* Convert QEMU provided timer ID back to internal 16bit index format */
7667static target_timer_t get_timer_id(abi_long arg)
7668{
7669 target_timer_t timerid = arg;
7670
7671 if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
7672 return -TARGET_EINVAL;
7673 }
7674
7675 timerid &= 0xffff;
7676
7677 if (timerid >= ARRAY_SIZE(g_posix_timers)) {
7678 return -TARGET_EINVAL;
7679 }
7680
7681 return timerid;
7682}
7683
2e0a8713
ST
7684static int target_to_host_cpu_mask(unsigned long *host_mask,
7685 size_t host_size,
7686 abi_ulong target_addr,
7687 size_t target_size)
7688{
7689 unsigned target_bits = sizeof(abi_ulong) * 8;
7690 unsigned host_bits = sizeof(*host_mask) * 8;
7691 abi_ulong *target_mask;
7692 unsigned i, j;
7693
7694 assert(host_size >= target_size);
7695
7696 target_mask = lock_user(VERIFY_READ, target_addr, target_size, 1);
7697 if (!target_mask) {
7698 return -TARGET_EFAULT;
7699 }
7700 memset(host_mask, 0, host_size);
7701
7702 for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
7703 unsigned bit = i * target_bits;
7704 abi_ulong val;
7705
7706 __get_user(val, &target_mask[i]);
7707 for (j = 0; j < target_bits; j++, bit++) {
7708 if (val & (1UL << j)) {
7709 host_mask[bit / host_bits] |= 1UL << (bit % host_bits);
7710 }
7711 }
7712 }
7713
7714 unlock_user(target_mask, target_addr, 0);
7715 return 0;
7716}
7717
7718static int host_to_target_cpu_mask(const unsigned long *host_mask,
7719 size_t host_size,
7720 abi_ulong target_addr,
7721 size_t target_size)
7722{
7723 unsigned target_bits = sizeof(abi_ulong) * 8;
7724 unsigned host_bits = sizeof(*host_mask) * 8;
7725 abi_ulong *target_mask;
7726 unsigned i, j;
7727
7728 assert(host_size >= target_size);
7729
7730 target_mask = lock_user(VERIFY_WRITE, target_addr, target_size, 0);
7731 if (!target_mask) {
7732 return -TARGET_EFAULT;
7733 }
7734
7735 for (i = 0 ; i < target_size / sizeof(abi_ulong); i++) {
7736 unsigned bit = i * target_bits;
7737 abi_ulong val = 0;
7738
7739 for (j = 0; j < target_bits; j++, bit++) {
7740 if (host_mask[bit / host_bits] & (1UL << (bit % host_bits))) {
7741 val |= 1UL << j;
7742 }
7743 }
7744 __put_user(val, &target_mask[i]);
7745 }
7746
7747 unlock_user(target_mask, target_addr, target_size);
7748 return 0;
7749}
7750
dc1ce18b
RH
7751/* This is an internal helper for do_syscall so that it is easier
7752 * to have a single return point, so that actions, such as logging
7753 * of syscall results, can be performed.
7754 * All errnos that do_syscall() returns must be -TARGET_<errcode>.
7755 */
7756static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
7757 abi_long arg2, abi_long arg3, abi_long arg4,
7758 abi_long arg5, abi_long arg6, abi_long arg7,
7759 abi_long arg8)
31e31b8a 7760{
29a0af61 7761 CPUState *cpu = env_cpu(cpu_env);
992f48a0 7762 abi_long ret;
4f7f8924
AR
7763#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
7764 || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
efa92184
AR
7765 || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \
7766 || defined(TARGET_NR_statx)
31e31b8a 7767 struct stat st;
4f7f8924
AR
7768#endif
7769#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
7770 || defined(TARGET_NR_fstatfs)
56c8f68f 7771 struct statfs stfs;
4f7f8924 7772#endif
53a5960a 7773 void *p;
3b46e624 7774
31e31b8a
FB
7775 switch(num) {
7776 case TARGET_NR_exit:
9b056fcc
AF
7777 /* In old applications this may be used to implement _exit(2).
7778 However in threaded applictions it is used for thread termination,
7779 and _exit_group is used for application termination.
7780 Do thread termination if we have more then one thread. */
a0995886
TB
7781
7782 if (block_signals()) {
72eb7ea8 7783 return -TARGET_ERESTARTSYS;
a0995886
TB
7784 }
7785
1f81ce90 7786 pthread_mutex_lock(&clone_lock);
dd1f6349 7787
bdc44640 7788 if (CPU_NEXT(first_cpu)) {
1f81ce90 7789 TaskState *ts = cpu->opaque;
9b056fcc 7790
5325cc34 7791 object_property_set_bool(OBJECT(cpu), "realized", false, NULL);
1f81ce90
AB
7792 object_unref(OBJECT(cpu));
7793 /*
7794 * At this point the CPU should be unrealized and removed
7795 * from cpu lists. We can clean-up the rest of the thread
7796 * data without the lock held.
7797 */
dd1f6349 7798
1f81ce90 7799 pthread_mutex_unlock(&clone_lock);
dd1f6349 7800
9b056fcc
AF
7801 if (ts->child_tidptr) {
7802 put_user_u32(0, ts->child_tidptr);
14690296 7803 do_sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
9b056fcc
AF
7804 NULL, NULL, 0);
7805 }
a2247f8e 7806 thread_cpu = NULL;
9b056fcc 7807 g_free(ts);
70903763 7808 rcu_unregister_thread();
9b056fcc
AF
7809 pthread_exit(NULL);
7810 }
dd1f6349 7811
1f81ce90 7812 pthread_mutex_unlock(&clone_lock);
708b6a64 7813 preexit_cleanup(cpu_env, arg1);
c2764719 7814 _exit(arg1);
72eb7ea8 7815 return 0; /* avoid warning */
31e31b8a 7816 case TARGET_NR_read:
ba584f1d
AS
7817 if (arg2 == 0 && arg3 == 0) {
7818 return get_errno(safe_read(arg1, 0, 0));
72eb7ea8 7819 } else {
38d840e6 7820 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
2852aafd 7821 return -TARGET_EFAULT;
50afd02b 7822 ret = get_errno(safe_read(arg1, p, arg3));
e36800c9 7823 if (ret >= 0 &&
5d4d3665
LV
7824 fd_trans_host_to_target_data(arg1)) {
7825 ret = fd_trans_host_to_target_data(arg1)(p, ret);
e36800c9 7826 }
38d840e6
AJ
7827 unlock_user(p, arg2, ret);
7828 }
72eb7ea8 7829 return ret;
31e31b8a 7830 case TARGET_NR_write:
58cfa6c2
TGJ
7831 if (arg2 == 0 && arg3 == 0) {
7832 return get_errno(safe_write(arg1, 0, 0));
7833 }
579a97f7 7834 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
2852aafd 7835 return -TARGET_EFAULT;
04b9bcf9
LV
7836 if (fd_trans_target_to_host_data(arg1)) {
7837 void *copy = g_malloc(arg3);
7838 memcpy(copy, p, arg3);
7839 ret = fd_trans_target_to_host_data(arg1)(copy, arg3);
7840 if (ret >= 0) {
7841 ret = get_errno(safe_write(arg1, copy, ret));
7842 }
7843 g_free(copy);
7844 } else {
7845 ret = get_errno(safe_write(arg1, p, arg3));
7846 }
53a5960a 7847 unlock_user(p, arg2, 0);
72eb7ea8
RH
7848 return ret;
7849
704eff6c 7850#ifdef TARGET_NR_open
31e31b8a 7851 case TARGET_NR_open:
2f619698 7852 if (!(p = lock_user_string(arg1)))
2852aafd 7853 return -TARGET_EFAULT;
0b2effd7
RV
7854 ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
7855 target_to_host_bitmask(arg2, fcntl_flags_tbl),
7856 arg3));
e36800c9 7857 fd_trans_unregister(ret);
53a5960a 7858 unlock_user(p, arg1, 0);
72eb7ea8 7859 return ret;
704eff6c 7860#endif
82424832 7861 case TARGET_NR_openat:
579a97f7 7862 if (!(p = lock_user_string(arg2)))
2852aafd 7863 return -TARGET_EFAULT;
0b2effd7
RV
7864 ret = get_errno(do_openat(cpu_env, arg1, p,
7865 target_to_host_bitmask(arg3, fcntl_flags_tbl),
7866 arg4));
e36800c9 7867 fd_trans_unregister(ret);
579a97f7 7868 unlock_user(p, arg2, 0);
72eb7ea8 7869 return ret;
0f0426f3
LV
7870#if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7871 case TARGET_NR_name_to_handle_at:
7872 ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
72eb7ea8 7873 return ret;
0f0426f3
LV
7874#endif
7875#if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
7876 case TARGET_NR_open_by_handle_at:
7877 ret = do_open_by_handle_at(arg1, arg2, arg3);
e36800c9 7878 fd_trans_unregister(ret);
72eb7ea8 7879 return ret;
0f0426f3 7880#endif
31e31b8a 7881 case TARGET_NR_close:
e36800c9 7882 fd_trans_unregister(arg1);
72eb7ea8
RH
7883 return get_errno(close(arg1));
7884
31e31b8a 7885 case TARGET_NR_brk:
72eb7ea8 7886 return do_brk(arg1);
704eff6c 7887#ifdef TARGET_NR_fork
31e31b8a 7888 case TARGET_NR_fork:
72eb7ea8 7889 return get_errno(do_fork(cpu_env, TARGET_SIGCHLD, 0, 0, 0, 0));
704eff6c 7890#endif
e5febef5 7891#ifdef TARGET_NR_waitpid
31e31b8a
FB
7892 case TARGET_NR_waitpid:
7893 {
53a5960a 7894 int status;
4af80a37 7895 ret = get_errno(safe_wait4(arg1, &status, arg3, 0));
5379557b 7896 if (!is_error(ret) && arg2 && ret
1d9d8b55 7897 && put_user_s32(host_to_target_waitstatus(status), arg2))
2852aafd 7898 return -TARGET_EFAULT;
31e31b8a 7899 }
72eb7ea8 7900 return ret;
e5febef5 7901#endif
f0cbb613
PB
7902#ifdef TARGET_NR_waitid
7903 case TARGET_NR_waitid:
7904 {
7905 siginfo_t info;
7906 info.si_pid = 0;
4af80a37 7907 ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
f0cbb613 7908 if (!is_error(ret) && arg3 && info.si_pid != 0) {
c227f099 7909 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
2852aafd 7910 return -TARGET_EFAULT;
f0cbb613 7911 host_to_target_siginfo(p, &info);
c227f099 7912 unlock_user(p, arg3, sizeof(target_siginfo_t));
f0cbb613
PB
7913 }
7914 }
72eb7ea8 7915 return ret;
f0cbb613 7916#endif
7a3148a9 7917#ifdef TARGET_NR_creat /* not on alpha */
31e31b8a 7918 case TARGET_NR_creat:
579a97f7 7919 if (!(p = lock_user_string(arg1)))
2852aafd 7920 return -TARGET_EFAULT;
53a5960a 7921 ret = get_errno(creat(p, arg2));
e36800c9 7922 fd_trans_unregister(ret);
53a5960a 7923 unlock_user(p, arg1, 0);
72eb7ea8 7924 return ret;
7a3148a9 7925#endif
704eff6c 7926#ifdef TARGET_NR_link
31e31b8a 7927 case TARGET_NR_link:
53a5960a
PB
7928 {
7929 void * p2;
7930 p = lock_user_string(arg1);
7931 p2 = lock_user_string(arg2);
579a97f7
FB
7932 if (!p || !p2)
7933 ret = -TARGET_EFAULT;
7934 else
7935 ret = get_errno(link(p, p2));
53a5960a
PB
7936 unlock_user(p2, arg2, 0);
7937 unlock_user(p, arg1, 0);
7938 }
72eb7ea8 7939 return ret;
704eff6c 7940#endif
c0d472b1 7941#if defined(TARGET_NR_linkat)
64f0ce4c 7942 case TARGET_NR_linkat:
64f0ce4c
TS
7943 {
7944 void * p2 = NULL;
579a97f7 7945 if (!arg2 || !arg4)
2852aafd 7946 return -TARGET_EFAULT;
64f0ce4c
TS
7947 p = lock_user_string(arg2);
7948 p2 = lock_user_string(arg4);
579a97f7 7949 if (!p || !p2)
0da46a6e 7950 ret = -TARGET_EFAULT;
64f0ce4c 7951 else
c0d472b1 7952 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
579a97f7
FB
7953 unlock_user(p, arg2, 0);
7954 unlock_user(p2, arg4, 0);
64f0ce4c 7955 }
72eb7ea8 7956 return ret;
64f0ce4c 7957#endif
704eff6c 7958#ifdef TARGET_NR_unlink
31e31b8a 7959 case TARGET_NR_unlink:
579a97f7 7960 if (!(p = lock_user_string(arg1)))
2852aafd 7961 return -TARGET_EFAULT;
53a5960a
PB
7962 ret = get_errno(unlink(p));
7963 unlock_user(p, arg1, 0);
72eb7ea8 7964 return ret;
704eff6c 7965#endif
c0d472b1 7966#if defined(TARGET_NR_unlinkat)
8170f56b 7967 case TARGET_NR_unlinkat:
579a97f7 7968 if (!(p = lock_user_string(arg2)))
2852aafd 7969 return -TARGET_EFAULT;
c0d472b1 7970 ret = get_errno(unlinkat(arg1, p, arg3));
579a97f7 7971 unlock_user(p, arg2, 0);
72eb7ea8 7972 return ret;
b7d35e65 7973#endif
31e31b8a 7974 case TARGET_NR_execve:
7854b056
FB
7975 {
7976 char **argp, **envp;
f7341ff4 7977 int argc, envc;
992f48a0
BS
7978 abi_ulong gp;
7979 abi_ulong guest_argp;
7980 abi_ulong guest_envp;
7981 abi_ulong addr;
7854b056 7982 char **q;
a6f79cc9 7983 int total_size = 0;
7854b056 7984
f7341ff4 7985 argc = 0;
53a5960a 7986 guest_argp = arg2;
da94d263 7987 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
03aa1976 7988 if (get_user_ual(addr, gp))
2852aafd 7989 return -TARGET_EFAULT;
03aa1976 7990 if (!addr)
2f619698 7991 break;
7854b056 7992 argc++;
2f619698 7993 }
f7341ff4 7994 envc = 0;
53a5960a 7995 guest_envp = arg3;
da94d263 7996 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
03aa1976 7997 if (get_user_ual(addr, gp))
2852aafd 7998 return -TARGET_EFAULT;
03aa1976 7999 if (!addr)
2f619698 8000 break;
7854b056 8001 envc++;
2f619698 8002 }
7854b056 8003
b936cb50
PP
8004 argp = g_new0(char *, argc + 1);
8005 envp = g_new0(char *, envc + 1);
7854b056 8006
da94d263 8007 for (gp = guest_argp, q = argp; gp;
992f48a0 8008 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8009 if (get_user_ual(addr, gp))
8010 goto execve_efault;
53a5960a
PB
8011 if (!addr)
8012 break;
2f619698
FB
8013 if (!(*q = lock_user_string(addr)))
8014 goto execve_efault;
a6f79cc9 8015 total_size += strlen(*q) + 1;
53a5960a 8016 }
f7341ff4
FB
8017 *q = NULL;
8018
da94d263 8019 for (gp = guest_envp, q = envp; gp;
992f48a0 8020 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8021 if (get_user_ual(addr, gp))
8022 goto execve_efault;
53a5960a
PB
8023 if (!addr)
8024 break;
2f619698
FB
8025 if (!(*q = lock_user_string(addr)))
8026 goto execve_efault;
a6f79cc9 8027 total_size += strlen(*q) + 1;
53a5960a 8028 }
f7341ff4 8029 *q = NULL;
7854b056 8030
2f619698
FB
8031 if (!(p = lock_user_string(arg1)))
8032 goto execve_efault;
ffdcbe22
TB
8033 /* Although execve() is not an interruptible syscall it is
8034 * a special case where we must use the safe_syscall wrapper:
8035 * if we allow a signal to happen before we make the host
8036 * syscall then we will 'lose' it, because at the point of
8037 * execve the process leaves QEMU's control. So we use the
8038 * safe syscall wrapper to ensure that we either take the
8039 * signal as a guest signal, or else it does not happen
8040 * before the execve completes and makes it the other
8041 * program's problem.
8042 */
8043 ret = get_errno(safe_execve(p, argp, envp));
53a5960a
PB
8044 unlock_user(p, arg1, 0);
8045
2f619698
FB
8046 goto execve_end;
8047
8048 execve_efault:
8049 ret = -TARGET_EFAULT;
8050
8051 execve_end:
53a5960a 8052 for (gp = guest_argp, q = argp; *q;
992f48a0 8053 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8054 if (get_user_ual(addr, gp)
8055 || !addr)
8056 break;
53a5960a
PB
8057 unlock_user(*q, addr, 0);
8058 }
8059 for (gp = guest_envp, q = envp; *q;
992f48a0 8060 gp += sizeof(abi_ulong), q++) {
2f619698
FB
8061 if (get_user_ual(addr, gp)
8062 || !addr)
8063 break;
53a5960a
PB
8064 unlock_user(*q, addr, 0);
8065 }
b936cb50
PP
8066
8067 g_free(argp);
8068 g_free(envp);
7854b056 8069 }
72eb7ea8 8070 return ret;
31e31b8a 8071 case TARGET_NR_chdir:
579a97f7 8072 if (!(p = lock_user_string(arg1)))
2852aafd 8073 return -TARGET_EFAULT;
53a5960a
PB
8074 ret = get_errno(chdir(p));
8075 unlock_user(p, arg1, 0);
72eb7ea8 8076 return ret;
a315a145 8077#ifdef TARGET_NR_time
31e31b8a
FB
8078 case TARGET_NR_time:
8079 {
53a5960a
PB
8080 time_t host_time;
8081 ret = get_errno(time(&host_time));
2f619698
FB
8082 if (!is_error(ret)
8083 && arg1
8084 && put_user_sal(host_time, arg1))
2852aafd 8085 return -TARGET_EFAULT;
31e31b8a 8086 }
72eb7ea8 8087 return ret;
a315a145 8088#endif
704eff6c 8089#ifdef TARGET_NR_mknod
31e31b8a 8090 case TARGET_NR_mknod:
579a97f7 8091 if (!(p = lock_user_string(arg1)))
2852aafd 8092 return -TARGET_EFAULT;
53a5960a
PB
8093 ret = get_errno(mknod(p, arg2, arg3));
8094 unlock_user(p, arg1, 0);
72eb7ea8 8095 return ret;
704eff6c 8096#endif
c0d472b1 8097#if defined(TARGET_NR_mknodat)
75ac37a0 8098 case TARGET_NR_mknodat:
579a97f7 8099 if (!(p = lock_user_string(arg2)))
2852aafd 8100 return -TARGET_EFAULT;
c0d472b1 8101 ret = get_errno(mknodat(arg1, p, arg3, arg4));
579a97f7 8102 unlock_user(p, arg2, 0);
72eb7ea8 8103 return ret;
75ac37a0 8104#endif
704eff6c 8105#ifdef TARGET_NR_chmod
31e31b8a 8106 case TARGET_NR_chmod:
579a97f7 8107 if (!(p = lock_user_string(arg1)))
2852aafd 8108 return -TARGET_EFAULT;
53a5960a
PB
8109 ret = get_errno(chmod(p, arg2));
8110 unlock_user(p, arg1, 0);
72eb7ea8 8111 return ret;
704eff6c 8112#endif
4f7f8924 8113#ifdef TARGET_NR_lseek
31e31b8a 8114 case TARGET_NR_lseek:
72eb7ea8 8115 return get_errno(lseek(arg1, arg2, arg3));
4f7f8924 8116#endif
9231733a
RH
8117#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
8118 /* Alpha specific */
7a3148a9 8119 case TARGET_NR_getxpid:
9231733a 8120 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
72eb7ea8 8121 return get_errno(getpid());
7a3148a9 8122#endif
9231733a
RH
8123#ifdef TARGET_NR_getpid
8124 case TARGET_NR_getpid:
72eb7ea8 8125 return get_errno(getpid());
9231733a 8126#endif
31e31b8a 8127 case TARGET_NR_mount:
356d771b
PB
8128 {
8129 /* need to look at the data field */
8130 void *p2, *p3;
8131
8132 if (arg1) {
8133 p = lock_user_string(arg1);
8134 if (!p) {
2852aafd 8135 return -TARGET_EFAULT;
356d771b
PB
8136 }
8137 } else {
8138 p = NULL;
8139 }
8140
8141 p2 = lock_user_string(arg2);
8142 if (!p2) {
8143 if (arg1) {
8144 unlock_user(p, arg1, 0);
8145 }
2852aafd 8146 return -TARGET_EFAULT;
356d771b
PB
8147 }
8148
8149 if (arg3) {
8150 p3 = lock_user_string(arg3);
8151 if (!p3) {
8152 if (arg1) {
579a97f7 8153 unlock_user(p, arg1, 0);
356d771b
PB
8154 }
8155 unlock_user(p2, arg2, 0);
2852aafd 8156 return -TARGET_EFAULT;
356d771b
PB
8157 }
8158 } else {
8159 p3 = NULL;
8160 }
8161
8162 /* FIXME - arg5 should be locked, but it isn't clear how to
8163 * do that since it's not guaranteed to be a NULL-terminated
8164 * string.
8165 */
8166 if (!arg5) {
8167 ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
8168 } else {
8169 ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
8170 }
8171 ret = get_errno(ret);
8172
8173 if (arg1) {
8174 unlock_user(p, arg1, 0);
8175 }
8176 unlock_user(p2, arg2, 0);
8177 if (arg3) {
8178 unlock_user(p3, arg3, 0);
8179 }
8180 }
72eb7ea8 8181 return ret;
6eb9dbf6
LV
8182#if defined(TARGET_NR_umount) || defined(TARGET_NR_oldumount)
8183#if defined(TARGET_NR_umount)
31e31b8a 8184 case TARGET_NR_umount:
6eb9dbf6
LV
8185#endif
8186#if defined(TARGET_NR_oldumount)
8187 case TARGET_NR_oldumount:
8188#endif
579a97f7 8189 if (!(p = lock_user_string(arg1)))
2852aafd 8190 return -TARGET_EFAULT;
53a5960a
PB
8191 ret = get_errno(umount(p));
8192 unlock_user(p, arg1, 0);
72eb7ea8 8193 return ret;
e5febef5 8194#endif
7a3148a9 8195#ifdef TARGET_NR_stime /* not on alpha */
31e31b8a
FB
8196 case TARGET_NR_stime:
8197 {
0f1f2d45
LV
8198 struct timespec ts;
8199 ts.tv_nsec = 0;
8200 if (get_user_sal(ts.tv_sec, arg1)) {
2852aafd 8201 return -TARGET_EFAULT;
0f1f2d45
LV
8202 }
8203 return get_errno(clock_settime(CLOCK_REALTIME, &ts));
31e31b8a 8204 }
7a3148a9 8205#endif
7a3148a9 8206#ifdef TARGET_NR_alarm /* not on alpha */
31e31b8a 8207 case TARGET_NR_alarm:
72eb7ea8 8208 return alarm(arg1);
7a3148a9 8209#endif
7a3148a9 8210#ifdef TARGET_NR_pause /* not on alpha */
31e31b8a 8211 case TARGET_NR_pause:
f59ec606
TB
8212 if (!block_signals()) {
8213 sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
8214 }
72eb7ea8 8215 return -TARGET_EINTR;
7a3148a9 8216#endif
e5febef5 8217#ifdef TARGET_NR_utime
31e31b8a 8218 case TARGET_NR_utime:
ebc05488 8219 {
53a5960a
PB
8220 struct utimbuf tbuf, *host_tbuf;
8221 struct target_utimbuf *target_tbuf;
8222 if (arg2) {
579a97f7 8223 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
2852aafd 8224 return -TARGET_EFAULT;
cbb21eed
MB
8225 tbuf.actime = tswapal(target_tbuf->actime);
8226 tbuf.modtime = tswapal(target_tbuf->modtime);
53a5960a
PB
8227 unlock_user_struct(target_tbuf, arg2, 0);
8228 host_tbuf = &tbuf;
f72e8ff4 8229 } else {
53a5960a 8230 host_tbuf = NULL;
f72e8ff4 8231 }
579a97f7 8232 if (!(p = lock_user_string(arg1)))
2852aafd 8233 return -TARGET_EFAULT;
53a5960a
PB
8234 ret = get_errno(utime(p, host_tbuf));
8235 unlock_user(p, arg1, 0);
ebc05488 8236 }
72eb7ea8 8237 return ret;
e5febef5 8238#endif
704eff6c 8239#ifdef TARGET_NR_utimes
978a66ff
FB
8240 case TARGET_NR_utimes:
8241 {
978a66ff 8242 struct timeval *tvp, tv[2];
53a5960a 8243 if (arg2) {
788f5ec4
TS
8244 if (copy_from_user_timeval(&tv[0], arg2)
8245 || copy_from_user_timeval(&tv[1],
8246 arg2 + sizeof(struct target_timeval)))
2852aafd 8247 return -TARGET_EFAULT;
978a66ff
FB
8248 tvp = tv;
8249 } else {
8250 tvp = NULL;
8251 }
579a97f7 8252 if (!(p = lock_user_string(arg1)))
2852aafd 8253 return -TARGET_EFAULT;
53a5960a
PB
8254 ret = get_errno(utimes(p, tvp));
8255 unlock_user(p, arg1, 0);
978a66ff 8256 }
72eb7ea8 8257 return ret;
704eff6c 8258#endif
c0d472b1 8259#if defined(TARGET_NR_futimesat)
ac8a6556
AZ
8260 case TARGET_NR_futimesat:
8261 {
8262 struct timeval *tvp, tv[2];
8263 if (arg3) {
8264 if (copy_from_user_timeval(&tv[0], arg3)
8265 || copy_from_user_timeval(&tv[1],
8266 arg3 + sizeof(struct target_timeval)))
2852aafd 8267 return -TARGET_EFAULT;
ac8a6556
AZ
8268 tvp = tv;
8269 } else {
8270 tvp = NULL;
8271 }
2852aafd
RH
8272 if (!(p = lock_user_string(arg2))) {
8273 return -TARGET_EFAULT;
8274 }
c0d472b1 8275 ret = get_errno(futimesat(arg1, path(p), tvp));
ac8a6556
AZ
8276 unlock_user(p, arg2, 0);
8277 }
72eb7ea8 8278 return ret;
ac8a6556 8279#endif
704eff6c 8280#ifdef TARGET_NR_access
31e31b8a 8281 case TARGET_NR_access:
2852aafd
RH
8282 if (!(p = lock_user_string(arg1))) {
8283 return -TARGET_EFAULT;
8284 }
719f908e 8285 ret = get_errno(access(path(p), arg2));
53a5960a 8286 unlock_user(p, arg1, 0);
72eb7ea8 8287 return ret;
704eff6c 8288#endif
92a34c10
TS
8289#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
8290 case TARGET_NR_faccessat:
2852aafd
RH
8291 if (!(p = lock_user_string(arg2))) {
8292 return -TARGET_EFAULT;
8293 }
c0d472b1 8294 ret = get_errno(faccessat(arg1, p, arg3, 0));
579a97f7 8295 unlock_user(p, arg2, 0);
72eb7ea8 8296 return ret;
92a34c10 8297#endif
7a3148a9 8298#ifdef TARGET_NR_nice /* not on alpha */
31e31b8a 8299 case TARGET_NR_nice:
72eb7ea8 8300 return get_errno(nice(arg1));
ebc05488 8301#endif
31e31b8a 8302 case TARGET_NR_sync:
04369ff2 8303 sync();
72eb7ea8 8304 return 0;
5a03cd00
AM
8305#if defined(TARGET_NR_syncfs) && defined(CONFIG_SYNCFS)
8306 case TARGET_NR_syncfs:
72eb7ea8 8307 return get_errno(syncfs(arg1));
5a03cd00 8308#endif
31e31b8a 8309 case TARGET_NR_kill:
72eb7ea8 8310 return get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
704eff6c 8311#ifdef TARGET_NR_rename
31e31b8a 8312 case TARGET_NR_rename:
53a5960a
PB
8313 {
8314 void *p2;
8315 p = lock_user_string(arg1);
8316 p2 = lock_user_string(arg2);
579a97f7
FB
8317 if (!p || !p2)
8318 ret = -TARGET_EFAULT;
8319 else
8320 ret = get_errno(rename(p, p2));
53a5960a
PB
8321 unlock_user(p2, arg2, 0);
8322 unlock_user(p, arg1, 0);
8323 }
72eb7ea8 8324 return ret;
704eff6c 8325#endif
c0d472b1 8326#if defined(TARGET_NR_renameat)
722183f6 8327 case TARGET_NR_renameat:
722183f6 8328 {
579a97f7 8329 void *p2;
722183f6
TS
8330 p = lock_user_string(arg2);
8331 p2 = lock_user_string(arg4);
579a97f7 8332 if (!p || !p2)
0da46a6e 8333 ret = -TARGET_EFAULT;
722183f6 8334 else
c0d472b1 8335 ret = get_errno(renameat(arg1, p, arg3, p2));
579a97f7
FB
8336 unlock_user(p2, arg4, 0);
8337 unlock_user(p, arg2, 0);
722183f6 8338 }
72eb7ea8 8339 return ret;
95d0307c
AS
8340#endif
8341#if defined(TARGET_NR_renameat2)
8342 case TARGET_NR_renameat2:
8343 {
8344 void *p2;
8345 p = lock_user_string(arg2);
8346 p2 = lock_user_string(arg4);
8347 if (!p || !p2) {
8348 ret = -TARGET_EFAULT;
8349 } else {
8350 ret = get_errno(sys_renameat2(arg1, p, arg3, p2, arg5));
8351 }
8352 unlock_user(p2, arg4, 0);
8353 unlock_user(p, arg2, 0);
8354 }
72eb7ea8 8355 return ret;
722183f6 8356#endif
704eff6c 8357#ifdef TARGET_NR_mkdir
31e31b8a 8358 case TARGET_NR_mkdir:
579a97f7 8359 if (!(p = lock_user_string(arg1)))
2852aafd 8360 return -TARGET_EFAULT;
53a5960a
PB
8361 ret = get_errno(mkdir(p, arg2));
8362 unlock_user(p, arg1, 0);
72eb7ea8 8363 return ret;
704eff6c 8364#endif
c0d472b1 8365#if defined(TARGET_NR_mkdirat)
4472ad0d 8366 case TARGET_NR_mkdirat:
579a97f7 8367 if (!(p = lock_user_string(arg2)))
2852aafd 8368 return -TARGET_EFAULT;
c0d472b1 8369 ret = get_errno(mkdirat(arg1, p, arg3));
579a97f7 8370 unlock_user(p, arg2, 0);
72eb7ea8 8371 return ret;
4472ad0d 8372#endif
704eff6c 8373#ifdef TARGET_NR_rmdir
31e31b8a 8374 case TARGET_NR_rmdir:
579a97f7 8375 if (!(p = lock_user_string(arg1)))
2852aafd 8376 return -TARGET_EFAULT;
53a5960a
PB
8377 ret = get_errno(rmdir(p));
8378 unlock_user(p, arg1, 0);
72eb7ea8 8379 return ret;
704eff6c 8380#endif
31e31b8a
FB
8381 case TARGET_NR_dup:
8382 ret = get_errno(dup(arg1));
e36800c9
LV
8383 if (ret >= 0) {
8384 fd_trans_dup(arg1, ret);
8385 }
72eb7ea8 8386 return ret;
704eff6c 8387#ifdef TARGET_NR_pipe
31e31b8a 8388 case TARGET_NR_pipe:
72eb7ea8 8389 return do_pipe(cpu_env, arg1, 0, 0);
704eff6c 8390#endif
099d6b0f
RV
8391#ifdef TARGET_NR_pipe2
8392 case TARGET_NR_pipe2:
72eb7ea8
RH
8393 return do_pipe(cpu_env, arg1,
8394 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
099d6b0f 8395#endif
31e31b8a 8396 case TARGET_NR_times:
32f36bce 8397 {
53a5960a 8398 struct target_tms *tmsp;
32f36bce
FB
8399 struct tms tms;
8400 ret = get_errno(times(&tms));
53a5960a 8401 if (arg1) {
579a97f7
FB
8402 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
8403 if (!tmsp)
2852aafd 8404 return -TARGET_EFAULT;
cbb21eed
MB
8405 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
8406 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
8407 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
8408 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
32f36bce 8409 }
c596ed17
FB
8410 if (!is_error(ret))
8411 ret = host_to_target_clock_t(ret);
32f36bce 8412 }
72eb7ea8 8413 return ret;
31e31b8a 8414 case TARGET_NR_acct:
38d840e6
AJ
8415 if (arg1 == 0) {
8416 ret = get_errno(acct(NULL));
8417 } else {
2852aafd
RH
8418 if (!(p = lock_user_string(arg1))) {
8419 return -TARGET_EFAULT;
8420 }
38d840e6
AJ
8421 ret = get_errno(acct(path(p)));
8422 unlock_user(p, arg1, 0);
8423 }
72eb7ea8 8424 return ret;
8070e7be 8425#ifdef TARGET_NR_umount2
31e31b8a 8426 case TARGET_NR_umount2:
579a97f7 8427 if (!(p = lock_user_string(arg1)))
2852aafd 8428 return -TARGET_EFAULT;
53a5960a
PB
8429 ret = get_errno(umount2(p, arg2));
8430 unlock_user(p, arg1, 0);
72eb7ea8 8431 return ret;
ebc05488 8432#endif
31e31b8a 8433 case TARGET_NR_ioctl:
72eb7ea8 8434 return do_ioctl(arg1, arg2, arg3);
47ae93cd 8435#ifdef TARGET_NR_fcntl
31e31b8a 8436 case TARGET_NR_fcntl:
72eb7ea8 8437 return do_fcntl(arg1, arg2, arg3);
ebc05488 8438#endif
31e31b8a 8439 case TARGET_NR_setpgid:
72eb7ea8 8440 return get_errno(setpgid(arg1, arg2));
31e31b8a 8441 case TARGET_NR_umask:
72eb7ea8 8442 return get_errno(umask(arg1));
31e31b8a 8443 case TARGET_NR_chroot:
579a97f7 8444 if (!(p = lock_user_string(arg1)))
2852aafd 8445 return -TARGET_EFAULT;
53a5960a
PB
8446 ret = get_errno(chroot(p));
8447 unlock_user(p, arg1, 0);
72eb7ea8 8448 return ret;
704eff6c 8449#ifdef TARGET_NR_dup2
31e31b8a
FB
8450 case TARGET_NR_dup2:
8451 ret = get_errno(dup2(arg1, arg2));
e36800c9
LV
8452 if (ret >= 0) {
8453 fd_trans_dup(arg1, arg2);
8454 }
72eb7ea8 8455 return ret;
704eff6c 8456#endif
d0927938
UH
8457#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
8458 case TARGET_NR_dup3:
10fa993a
PM
8459 {
8460 int host_flags;
8461
8462 if ((arg3 & ~TARGET_O_CLOEXEC) != 0) {
8463 return -EINVAL;
8464 }
8465 host_flags = target_to_host_bitmask(arg3, fcntl_flags_tbl);
8466 ret = get_errno(dup3(arg1, arg2, host_flags));
e36800c9
LV
8467 if (ret >= 0) {
8468 fd_trans_dup(arg1, arg2);
8469 }
72eb7ea8 8470 return ret;
10fa993a 8471 }
d0927938 8472#endif
7a3148a9 8473#ifdef TARGET_NR_getppid /* not on alpha */
31e31b8a 8474 case TARGET_NR_getppid:
72eb7ea8 8475 return get_errno(getppid());
7a3148a9 8476#endif
704eff6c 8477#ifdef TARGET_NR_getpgrp
31e31b8a 8478 case TARGET_NR_getpgrp:
72eb7ea8 8479 return get_errno(getpgrp());
704eff6c 8480#endif
31e31b8a 8481 case TARGET_NR_setsid:
72eb7ea8 8482 return get_errno(setsid());
e5febef5 8483#ifdef TARGET_NR_sigaction
31e31b8a 8484 case TARGET_NR_sigaction:
31e31b8a 8485 {
6049f4f8
RH
8486#if defined(TARGET_ALPHA)
8487 struct target_sigaction act, oact, *pact = 0;
53a5960a 8488 struct target_old_sigaction *old_act;
53a5960a 8489 if (arg2) {
579a97f7 8490 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 8491 return -TARGET_EFAULT;
66fb9763
FB
8492 act._sa_handler = old_act->_sa_handler;
8493 target_siginitset(&act.sa_mask, old_act->sa_mask);
8494 act.sa_flags = old_act->sa_flags;
6049f4f8 8495 act.sa_restorer = 0;
53a5960a 8496 unlock_user_struct(old_act, arg2, 0);
66fb9763 8497 pact = &act;
66fb9763
FB
8498 }
8499 ret = get_errno(do_sigaction(arg1, pact, &oact));
53a5960a 8500 if (!is_error(ret) && arg3) {
579a97f7 8501 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 8502 return -TARGET_EFAULT;
53a5960a
PB
8503 old_act->_sa_handler = oact._sa_handler;
8504 old_act->sa_mask = oact.sa_mask.sig[0];
8505 old_act->sa_flags = oact.sa_flags;
53a5960a 8506 unlock_user_struct(old_act, arg3, 1);
66fb9763 8507 }
6049f4f8 8508#elif defined(TARGET_MIPS)
106ec879
FB
8509 struct target_sigaction act, oact, *pact, *old_act;
8510
8511 if (arg2) {
579a97f7 8512 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 8513 return -TARGET_EFAULT;
106ec879
FB
8514 act._sa_handler = old_act->_sa_handler;
8515 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
8516 act.sa_flags = old_act->sa_flags;
8517 unlock_user_struct(old_act, arg2, 0);
8518 pact = &act;
8519 } else {
8520 pact = NULL;
8521 }
8522
8523 ret = get_errno(do_sigaction(arg1, pact, &oact));
8524
8525 if (!is_error(ret) && arg3) {
579a97f7 8526 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 8527 return -TARGET_EFAULT;
106ec879
FB
8528 old_act->_sa_handler = oact._sa_handler;
8529 old_act->sa_flags = oact.sa_flags;
8530 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
8531 old_act->sa_mask.sig[1] = 0;
8532 old_act->sa_mask.sig[2] = 0;
8533 old_act->sa_mask.sig[3] = 0;
8534 unlock_user_struct(old_act, arg3, 1);
8535 }
6049f4f8
RH
8536#else
8537 struct target_old_sigaction *old_act;
8538 struct target_sigaction act, oact, *pact;
8539 if (arg2) {
8540 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
2852aafd 8541 return -TARGET_EFAULT;
6049f4f8
RH
8542 act._sa_handler = old_act->_sa_handler;
8543 target_siginitset(&act.sa_mask, old_act->sa_mask);
8544 act.sa_flags = old_act->sa_flags;
8545 act.sa_restorer = old_act->sa_restorer;
5de154e8
LV
8546#ifdef TARGET_ARCH_HAS_KA_RESTORER
8547 act.ka_restorer = 0;
8548#endif
6049f4f8
RH
8549 unlock_user_struct(old_act, arg2, 0);
8550 pact = &act;
8551 } else {
8552 pact = NULL;
8553 }
8554 ret = get_errno(do_sigaction(arg1, pact, &oact));
8555 if (!is_error(ret) && arg3) {
8556 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
2852aafd 8557 return -TARGET_EFAULT;
6049f4f8
RH
8558 old_act->_sa_handler = oact._sa_handler;
8559 old_act->sa_mask = oact.sa_mask.sig[0];
8560 old_act->sa_flags = oact.sa_flags;
8561 old_act->sa_restorer = oact.sa_restorer;
8562 unlock_user_struct(old_act, arg3, 1);
8563 }
388bb21a 8564#endif
31e31b8a 8565 }
72eb7ea8 8566 return ret;
e5febef5 8567#endif
66fb9763 8568 case TARGET_NR_rt_sigaction:
53a5960a 8569 {
6049f4f8 8570#if defined(TARGET_ALPHA)
78bfef72
PM
8571 /* For Alpha and SPARC this is a 5 argument syscall, with
8572 * a 'restorer' parameter which must be copied into the
8573 * sa_restorer field of the sigaction struct.
8574 * For Alpha that 'restorer' is arg5; for SPARC it is arg4,
8575 * and arg5 is the sigsetsize.
8576 * Alpha also has a separate rt_sigaction struct that it uses
8577 * here; SPARC uses the usual sigaction struct.
8578 */
6049f4f8 8579 struct target_rt_sigaction *rt_act;
78bfef72 8580 struct target_sigaction act, oact, *pact = 0;
c815701e
PM
8581
8582 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 8583 return -TARGET_EINVAL;
c815701e 8584 }
6049f4f8
RH
8585 if (arg2) {
8586 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
2852aafd 8587 return -TARGET_EFAULT;
6049f4f8
RH
8588 act._sa_handler = rt_act->_sa_handler;
8589 act.sa_mask = rt_act->sa_mask;
8590 act.sa_flags = rt_act->sa_flags;
8591 act.sa_restorer = arg5;
8592 unlock_user_struct(rt_act, arg2, 0);
8593 pact = &act;
8594 }
8595 ret = get_errno(do_sigaction(arg1, pact, &oact));
8596 if (!is_error(ret) && arg3) {
8597 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
2852aafd 8598 return -TARGET_EFAULT;
6049f4f8
RH
8599 rt_act->_sa_handler = oact._sa_handler;
8600 rt_act->sa_mask = oact.sa_mask;
8601 rt_act->sa_flags = oact.sa_flags;
8602 unlock_user_struct(rt_act, arg3, 1);
8603 }
8604#else
78bfef72
PM
8605#ifdef TARGET_SPARC
8606 target_ulong restorer = arg4;
8607 target_ulong sigsetsize = arg5;
8608#else
8609 target_ulong sigsetsize = arg4;
8610#endif
53a5960a
PB
8611 struct target_sigaction *act;
8612 struct target_sigaction *oact;
8613
78bfef72 8614 if (sigsetsize != sizeof(target_sigset_t)) {
72eb7ea8 8615 return -TARGET_EINVAL;
c815701e 8616 }
579a97f7 8617 if (arg2) {
78bfef72 8618 if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
2852aafd 8619 return -TARGET_EFAULT;
78bfef72 8620 }
5de154e8
LV
8621#ifdef TARGET_ARCH_HAS_KA_RESTORER
8622 act->ka_restorer = restorer;
78bfef72
PM
8623#endif
8624 } else {
53a5960a 8625 act = NULL;
78bfef72 8626 }
579a97f7
FB
8627 if (arg3) {
8628 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
8629 ret = -TARGET_EFAULT;
8630 goto rt_sigaction_fail;
8631 }
8632 } else
53a5960a
PB
8633 oact = NULL;
8634 ret = get_errno(do_sigaction(arg1, act, oact));
579a97f7
FB
8635 rt_sigaction_fail:
8636 if (act)
53a5960a 8637 unlock_user_struct(act, arg2, 0);
579a97f7 8638 if (oact)
53a5960a 8639 unlock_user_struct(oact, arg3, 1);
6049f4f8 8640#endif
53a5960a 8641 }
72eb7ea8 8642 return ret;
7a3148a9 8643#ifdef TARGET_NR_sgetmask /* not on alpha */
31e31b8a 8644 case TARGET_NR_sgetmask:
66fb9763
FB
8645 {
8646 sigset_t cur_set;
992f48a0 8647 abi_ulong target_set;
3d3efba0
PM
8648 ret = do_sigprocmask(0, NULL, &cur_set);
8649 if (!ret) {
8650 host_to_target_old_sigset(&target_set, &cur_set);
8651 ret = target_set;
8652 }
66fb9763 8653 }
72eb7ea8 8654 return ret;
7a3148a9
JM
8655#endif
8656#ifdef TARGET_NR_ssetmask /* not on alpha */
31e31b8a 8657 case TARGET_NR_ssetmask:
66fb9763 8658 {
a8617d8c 8659 sigset_t set, oset;
992f48a0 8660 abi_ulong target_set = arg1;
66fb9763 8661 target_to_host_old_sigset(&set, &target_set);
3d3efba0
PM
8662 ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
8663 if (!ret) {
8664 host_to_target_old_sigset(&target_set, &oset);
8665 ret = target_set;
8666 }
66fb9763 8667 }
72eb7ea8 8668 return ret;
7a3148a9 8669#endif
e5febef5 8670#ifdef TARGET_NR_sigprocmask
66fb9763
FB
8671 case TARGET_NR_sigprocmask:
8672 {
a5b3b13b
RH
8673#if defined(TARGET_ALPHA)
8674 sigset_t set, oldset;
8675 abi_ulong mask;
8676 int how;
8677
8678 switch (arg1) {
8679 case TARGET_SIG_BLOCK:
8680 how = SIG_BLOCK;
8681 break;
8682 case TARGET_SIG_UNBLOCK:
8683 how = SIG_UNBLOCK;
8684 break;
8685 case TARGET_SIG_SETMASK:
8686 how = SIG_SETMASK;
8687 break;
8688 default:
259841c1 8689 return -TARGET_EINVAL;
a5b3b13b
RH
8690 }
8691 mask = arg2;
8692 target_to_host_old_sigset(&set, &mask);
8693
3d3efba0 8694 ret = do_sigprocmask(how, &set, &oldset);
a5b3b13b
RH
8695 if (!is_error(ret)) {
8696 host_to_target_old_sigset(&mask, &oldset);
8697 ret = mask;
0229f5a3 8698 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
a5b3b13b
RH
8699 }
8700#else
66fb9763 8701 sigset_t set, oldset, *set_ptr;
a5b3b13b 8702 int how;
3b46e624 8703
53a5960a 8704 if (arg2) {
a5b3b13b 8705 switch (arg1) {
66fb9763
FB
8706 case TARGET_SIG_BLOCK:
8707 how = SIG_BLOCK;
8708 break;
8709 case TARGET_SIG_UNBLOCK:
8710 how = SIG_UNBLOCK;
8711 break;
8712 case TARGET_SIG_SETMASK:
8713 how = SIG_SETMASK;
8714 break;
8715 default:
259841c1 8716 return -TARGET_EINVAL;
66fb9763 8717 }
c227f099 8718 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
2852aafd 8719 return -TARGET_EFAULT;
53a5960a
PB
8720 target_to_host_old_sigset(&set, p);
8721 unlock_user(p, arg2, 0);
66fb9763
FB
8722 set_ptr = &set;
8723 } else {
8724 how = 0;
8725 set_ptr = NULL;
8726 }
3d3efba0 8727 ret = do_sigprocmask(how, set_ptr, &oldset);
53a5960a 8728 if (!is_error(ret) && arg3) {
c227f099 8729 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
2852aafd 8730 return -TARGET_EFAULT;
53a5960a 8731 host_to_target_old_sigset(p, &oldset);
c227f099 8732 unlock_user(p, arg3, sizeof(target_sigset_t));
66fb9763 8733 }
a5b3b13b 8734#endif
66fb9763 8735 }
72eb7ea8 8736 return ret;
e5febef5 8737#endif
66fb9763
FB
8738 case TARGET_NR_rt_sigprocmask:
8739 {
8740 int how = arg1;
8741 sigset_t set, oldset, *set_ptr;
3b46e624 8742
c815701e 8743 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 8744 return -TARGET_EINVAL;
c815701e
PM
8745 }
8746
53a5960a 8747 if (arg2) {
66fb9763
FB
8748 switch(how) {
8749 case TARGET_SIG_BLOCK:
8750 how = SIG_BLOCK;
8751 break;
8752 case TARGET_SIG_UNBLOCK:
8753 how = SIG_UNBLOCK;
8754 break;
8755 case TARGET_SIG_SETMASK:
8756 how = SIG_SETMASK;
8757 break;
8758 default:
259841c1 8759 return -TARGET_EINVAL;
66fb9763 8760 }
c227f099 8761 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
2852aafd 8762 return -TARGET_EFAULT;
53a5960a
PB
8763 target_to_host_sigset(&set, p);
8764 unlock_user(p, arg2, 0);
66fb9763
FB
8765 set_ptr = &set;
8766 } else {
8767 how = 0;
8768 set_ptr = NULL;
8769 }
3d3efba0 8770 ret = do_sigprocmask(how, set_ptr, &oldset);
53a5960a 8771 if (!is_error(ret) && arg3) {
c227f099 8772 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
2852aafd 8773 return -TARGET_EFAULT;
53a5960a 8774 host_to_target_sigset(p, &oldset);
c227f099 8775 unlock_user(p, arg3, sizeof(target_sigset_t));
66fb9763
FB
8776 }
8777 }
72eb7ea8 8778 return ret;
e5febef5 8779#ifdef TARGET_NR_sigpending
66fb9763
FB
8780 case TARGET_NR_sigpending:
8781 {
8782 sigset_t set;
8783 ret = get_errno(sigpending(&set));
8784 if (!is_error(ret)) {
c227f099 8785 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
2852aafd 8786 return -TARGET_EFAULT;
53a5960a 8787 host_to_target_old_sigset(p, &set);
c227f099 8788 unlock_user(p, arg1, sizeof(target_sigset_t));
66fb9763
FB
8789 }
8790 }
72eb7ea8 8791 return ret;
e5febef5 8792#endif
66fb9763
FB
8793 case TARGET_NR_rt_sigpending:
8794 {
8795 sigset_t set;
c815701e
PM
8796
8797 /* Yes, this check is >, not != like most. We follow the kernel's
8798 * logic and it does it like this because it implements
8799 * NR_sigpending through the same code path, and in that case
8800 * the old_sigset_t is smaller in size.
8801 */
8802 if (arg2 > sizeof(target_sigset_t)) {
72eb7ea8 8803 return -TARGET_EINVAL;
c815701e
PM
8804 }
8805
66fb9763
FB
8806 ret = get_errno(sigpending(&set));
8807 if (!is_error(ret)) {
c227f099 8808 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
2852aafd 8809 return -TARGET_EFAULT;
53a5960a 8810 host_to_target_sigset(p, &set);
c227f099 8811 unlock_user(p, arg1, sizeof(target_sigset_t));
66fb9763
FB
8812 }
8813 }
72eb7ea8 8814 return ret;
e5febef5 8815#ifdef TARGET_NR_sigsuspend
66fb9763
FB
8816 case TARGET_NR_sigsuspend:
8817 {
3d3efba0 8818 TaskState *ts = cpu->opaque;
f43ce12b
RH
8819#if defined(TARGET_ALPHA)
8820 abi_ulong mask = arg1;
3d3efba0 8821 target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
f43ce12b 8822#else
c227f099 8823 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 8824 return -TARGET_EFAULT;
3d3efba0 8825 target_to_host_old_sigset(&ts->sigsuspend_mask, p);
53a5960a 8826 unlock_user(p, arg1, 0);
f43ce12b 8827#endif
3d3efba0
PM
8828 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
8829 SIGSET_T_SIZE));
8830 if (ret != -TARGET_ERESTARTSYS) {
8831 ts->in_sigsuspend = 1;
8832 }
66fb9763 8833 }
72eb7ea8 8834 return ret;
e5febef5 8835#endif
66fb9763
FB
8836 case TARGET_NR_rt_sigsuspend:
8837 {
3d3efba0 8838 TaskState *ts = cpu->opaque;
c815701e
PM
8839
8840 if (arg2 != sizeof(target_sigset_t)) {
72eb7ea8 8841 return -TARGET_EINVAL;
c815701e 8842 }
c227f099 8843 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 8844 return -TARGET_EFAULT;
3d3efba0 8845 target_to_host_sigset(&ts->sigsuspend_mask, p);
53a5960a 8846 unlock_user(p, arg1, 0);
3d3efba0
PM
8847 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
8848 SIGSET_T_SIZE));
8849 if (ret != -TARGET_ERESTARTSYS) {
8850 ts->in_sigsuspend = 1;
8851 }
66fb9763 8852 }
72eb7ea8 8853 return ret;
859e8a89 8854#ifdef TARGET_NR_rt_sigtimedwait
66fb9763
FB
8855 case TARGET_NR_rt_sigtimedwait:
8856 {
66fb9763
FB
8857 sigset_t set;
8858 struct timespec uts, *puts;
8859 siginfo_t uinfo;
3b46e624 8860
c815701e 8861 if (arg4 != sizeof(target_sigset_t)) {
72eb7ea8 8862 return -TARGET_EINVAL;
c815701e
PM
8863 }
8864
c227f099 8865 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
2852aafd 8866 return -TARGET_EFAULT;
53a5960a
PB
8867 target_to_host_sigset(&set, p);
8868 unlock_user(p, arg1, 0);
8869 if (arg3) {
66fb9763 8870 puts = &uts;
53a5960a 8871 target_to_host_timespec(puts, arg3);
66fb9763
FB
8872 } else {
8873 puts = NULL;
8874 }
b3f82330
PM
8875 ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
8876 SIGSET_T_SIZE));
974a196d
PJ
8877 if (!is_error(ret)) {
8878 if (arg2) {
8879 p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
8880 0);
8881 if (!p) {
2852aafd 8882 return -TARGET_EFAULT;
974a196d
PJ
8883 }
8884 host_to_target_siginfo(p, &uinfo);
8885 unlock_user(p, arg2, sizeof(target_siginfo_t));
8886 }
8887 ret = host_to_target_signal(ret);
66fb9763
FB
8888 }
8889 }
72eb7ea8 8890 return ret;
859e8a89 8891#endif
66fb9763
FB
8892 case TARGET_NR_rt_sigqueueinfo:
8893 {
8894 siginfo_t uinfo;
4debae6f
PM
8895
8896 p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1);
8897 if (!p) {
2852aafd 8898 return -TARGET_EFAULT;
4debae6f 8899 }
53a5960a 8900 target_to_host_siginfo(&uinfo, p);
d8b6d892 8901 unlock_user(p, arg3, 0);
66fb9763
FB
8902 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
8903 }
72eb7ea8 8904 return ret;
cf8b8bfc
MS
8905 case TARGET_NR_rt_tgsigqueueinfo:
8906 {
8907 siginfo_t uinfo;
8908
8909 p = lock_user(VERIFY_READ, arg4, sizeof(target_siginfo_t), 1);
8910 if (!p) {
2852aafd 8911 return -TARGET_EFAULT;
cf8b8bfc
MS
8912 }
8913 target_to_host_siginfo(&uinfo, p);
8914 unlock_user(p, arg4, 0);
8915 ret = get_errno(sys_rt_tgsigqueueinfo(arg1, arg2, arg3, &uinfo));
8916 }
72eb7ea8 8917 return ret;
e5febef5 8918#ifdef TARGET_NR_sigreturn
66fb9763 8919 case TARGET_NR_sigreturn:
3d3efba0 8920 if (block_signals()) {
72eb7ea8 8921 return -TARGET_ERESTARTSYS;
3d3efba0 8922 }
72eb7ea8 8923 return do_sigreturn(cpu_env);
e5febef5 8924#endif
66fb9763 8925 case TARGET_NR_rt_sigreturn:
3d3efba0 8926 if (block_signals()) {
72eb7ea8 8927 return -TARGET_ERESTARTSYS;
3d3efba0 8928 }
72eb7ea8 8929 return do_rt_sigreturn(cpu_env);
31e31b8a 8930 case TARGET_NR_sethostname:
579a97f7 8931 if (!(p = lock_user_string(arg1)))
2852aafd 8932 return -TARGET_EFAULT;
53a5960a
PB
8933 ret = get_errno(sethostname(p, arg2));
8934 unlock_user(p, arg1, 0);
72eb7ea8 8935 return ret;
4f7f8924 8936#ifdef TARGET_NR_setrlimit
31e31b8a 8937 case TARGET_NR_setrlimit:
9de5e440 8938 {
e22b7015 8939 int resource = target_to_host_resource(arg1);
53a5960a 8940 struct target_rlimit *target_rlim;
9de5e440 8941 struct rlimit rlim;
579a97f7 8942 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
2852aafd 8943 return -TARGET_EFAULT;
81bbe906
TY
8944 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
8945 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
53a5960a 8946 unlock_user_struct(target_rlim, arg2, 0);
5dfa88f7
MF
8947 /*
8948 * If we just passed through resource limit settings for memory then
8949 * they would also apply to QEMU's own allocations, and QEMU will
8950 * crash or hang or die if its allocations fail. Ideally we would
8951 * track the guest allocations in QEMU and apply the limits ourselves.
8952 * For now, just tell the guest the call succeeded but don't actually
8953 * limit anything.
8954 */
8955 if (resource != RLIMIT_AS &&
8956 resource != RLIMIT_DATA &&
8957 resource != RLIMIT_STACK) {
8958 return get_errno(setrlimit(resource, &rlim));
8959 } else {
8960 return 0;
8961 }
9de5e440 8962 }
4f7f8924
AR
8963#endif
8964#ifdef TARGET_NR_getrlimit
31e31b8a 8965 case TARGET_NR_getrlimit:
9de5e440 8966 {
e22b7015 8967 int resource = target_to_host_resource(arg1);
53a5960a 8968 struct target_rlimit *target_rlim;
9de5e440 8969 struct rlimit rlim;
3b46e624 8970
9de5e440
FB
8971 ret = get_errno(getrlimit(resource, &rlim));
8972 if (!is_error(ret)) {
579a97f7 8973 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
2852aafd 8974 return -TARGET_EFAULT;
81bbe906
TY
8975 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
8976 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
53a5960a 8977 unlock_user_struct(target_rlim, arg2, 1);
9de5e440
FB
8978 }
8979 }
72eb7ea8 8980 return ret;
4f7f8924 8981#endif
31e31b8a 8982 case TARGET_NR_getrusage:
b409186b
FB
8983 {
8984 struct rusage rusage;
b409186b
FB
8985 ret = get_errno(getrusage(arg1, &rusage));
8986 if (!is_error(ret)) {
a39fb273 8987 ret = host_to_target_rusage(arg2, &rusage);
b409186b
FB
8988 }
8989 }
72eb7ea8 8990 return ret;
859e8a89 8991#if defined(TARGET_NR_gettimeofday)
31e31b8a
FB
8992 case TARGET_NR_gettimeofday:
8993 {
31e31b8a 8994 struct timeval tv;
a52f5f87
RH
8995 struct timezone tz;
8996
8997 ret = get_errno(gettimeofday(&tv, &tz));
31e31b8a 8998 if (!is_error(ret)) {
a52f5f87
RH
8999 if (arg1 && copy_to_user_timeval(arg1, &tv)) {
9000 return -TARGET_EFAULT;
9001 }
9002 if (arg2 && copy_to_user_timezone(arg2, &tz)) {
2852aafd 9003 return -TARGET_EFAULT;
a52f5f87 9004 }
31e31b8a
FB
9005 }
9006 }
72eb7ea8 9007 return ret;
859e8a89
AF
9008#endif
9009#if defined(TARGET_NR_settimeofday)
31e31b8a
FB
9010 case TARGET_NR_settimeofday:
9011 {
b67d8031 9012 struct timeval tv, *ptv = NULL;
ef4467e9
PB
9013 struct timezone tz, *ptz = NULL;
9014
b67d8031
PB
9015 if (arg1) {
9016 if (copy_from_user_timeval(&tv, arg1)) {
2852aafd 9017 return -TARGET_EFAULT;
b67d8031
PB
9018 }
9019 ptv = &tv;
9020 }
ef4467e9
PB
9021
9022 if (arg2) {
9023 if (copy_from_user_timezone(&tz, arg2)) {
2852aafd 9024 return -TARGET_EFAULT;
ef4467e9
PB
9025 }
9026 ptz = &tz;
9027 }
9028
72eb7ea8 9029 return get_errno(settimeofday(ptv, ptz));
31e31b8a 9030 }
859e8a89 9031#endif
9468a5d4 9032#if defined(TARGET_NR_select)
31e31b8a 9033 case TARGET_NR_select:
5457dc9e
LV
9034#if defined(TARGET_WANT_NI_OLD_SELECT)
9035 /* some architectures used to have old_select here
9036 * but now ENOSYS it.
9037 */
9038 ret = -TARGET_ENOSYS;
9039#elif defined(TARGET_WANT_OLD_SYS_SELECT)
9040 ret = do_old_select(arg1);
9468a5d4 9041#else
5457dc9e 9042 ret = do_select(arg1, arg2, arg3, arg4, arg5);
9468a5d4 9043#endif
72eb7ea8 9044 return ret;
9e42382f
RV
9045#endif
9046#ifdef TARGET_NR_pselect6
9047 case TARGET_NR_pselect6:
055e0906
MF
9048 {
9049 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
9050 fd_set rfds, wfds, efds;
9051 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
9052 struct timespec ts, *ts_ptr;
9053
9054 /*
9055 * The 6th arg is actually two args smashed together,
9056 * so we cannot use the C library.
9057 */
9058 sigset_t set;
9059 struct {
9060 sigset_t *set;
9061 size_t size;
9062 } sig, *sig_ptr;
9063
9064 abi_ulong arg_sigset, arg_sigsize, *arg7;
9065 target_sigset_t *target_sigset;
9066
9067 n = arg1;
9068 rfd_addr = arg2;
9069 wfd_addr = arg3;
9070 efd_addr = arg4;
9071 ts_addr = arg5;
9072
9073 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
9074 if (ret) {
259841c1 9075 return ret;
055e0906
MF
9076 }
9077 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
9078 if (ret) {
259841c1 9079 return ret;
055e0906
MF
9080 }
9081 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
9082 if (ret) {
259841c1 9083 return ret;
055e0906
MF
9084 }
9085
9086 /*
9087 * This takes a timespec, and not a timeval, so we cannot
9088 * use the do_select() helper ...
9089 */
9090 if (ts_addr) {
9091 if (target_to_host_timespec(&ts, ts_addr)) {
2852aafd 9092 return -TARGET_EFAULT;
055e0906
MF
9093 }
9094 ts_ptr = &ts;
9095 } else {
9096 ts_ptr = NULL;
9097 }
9098
9099 /* Extract the two packed args for the sigset */
9100 if (arg6) {
9101 sig_ptr = &sig;
b28a1f33 9102 sig.size = SIGSET_T_SIZE;
055e0906
MF
9103
9104 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
9105 if (!arg7) {
2852aafd 9106 return -TARGET_EFAULT;
055e0906 9107 }
cbb21eed
MB
9108 arg_sigset = tswapal(arg7[0]);
9109 arg_sigsize = tswapal(arg7[1]);
055e0906
MF
9110 unlock_user(arg7, arg6, 0);
9111
9112 if (arg_sigset) {
9113 sig.set = &set;
8f04eeb3
PM
9114 if (arg_sigsize != sizeof(*target_sigset)) {
9115 /* Like the kernel, we enforce correct size sigsets */
259841c1 9116 return -TARGET_EINVAL;
8f04eeb3 9117 }
055e0906
MF
9118 target_sigset = lock_user(VERIFY_READ, arg_sigset,
9119 sizeof(*target_sigset), 1);
9120 if (!target_sigset) {
2852aafd 9121 return -TARGET_EFAULT;
055e0906
MF
9122 }
9123 target_to_host_sigset(&set, target_sigset);
9124 unlock_user(target_sigset, arg_sigset, 0);
9125 } else {
9126 sig.set = NULL;
9127 }
9128 } else {
9129 sig_ptr = NULL;
9130 }
9131
6df9d38d
PM
9132 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
9133 ts_ptr, sig_ptr));
055e0906
MF
9134
9135 if (!is_error(ret)) {
9136 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
2852aafd 9137 return -TARGET_EFAULT;
055e0906 9138 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
2852aafd 9139 return -TARGET_EFAULT;
055e0906 9140 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
2852aafd 9141 return -TARGET_EFAULT;
055e0906
MF
9142
9143 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
2852aafd 9144 return -TARGET_EFAULT;
055e0906
MF
9145 }
9146 }
72eb7ea8 9147 return ret;
048f6b4d 9148#endif
704eff6c 9149#ifdef TARGET_NR_symlink
31e31b8a 9150 case TARGET_NR_symlink:
53a5960a
PB
9151 {
9152 void *p2;
9153 p = lock_user_string(arg1);
9154 p2 = lock_user_string(arg2);
579a97f7
FB
9155 if (!p || !p2)
9156 ret = -TARGET_EFAULT;
9157 else
9158 ret = get_errno(symlink(p, p2));
53a5960a
PB
9159 unlock_user(p2, arg2, 0);
9160 unlock_user(p, arg1, 0);
9161 }
72eb7ea8 9162 return ret;
704eff6c 9163#endif
c0d472b1 9164#if defined(TARGET_NR_symlinkat)
f0b6243d 9165 case TARGET_NR_symlinkat:
f0b6243d 9166 {
579a97f7 9167 void *p2;
f0b6243d
TS
9168 p = lock_user_string(arg1);
9169 p2 = lock_user_string(arg3);
579a97f7 9170 if (!p || !p2)
0da46a6e 9171 ret = -TARGET_EFAULT;
f0b6243d 9172 else
c0d472b1 9173 ret = get_errno(symlinkat(p, arg2, p2));
579a97f7
FB
9174 unlock_user(p2, arg3, 0);
9175 unlock_user(p, arg1, 0);
f0b6243d 9176 }
72eb7ea8 9177 return ret;
f0b6243d 9178#endif
704eff6c 9179#ifdef TARGET_NR_readlink
31e31b8a 9180 case TARGET_NR_readlink:
53a5960a 9181 {
463d8e73 9182 void *p2;
53a5960a 9183 p = lock_user_string(arg1);
579a97f7 9184 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
463d8e73 9185 if (!p || !p2) {
579a97f7 9186 ret = -TARGET_EFAULT;
f17f4989
MF
9187 } else if (!arg3) {
9188 /* Short circuit this for the magic exe check. */
9189 ret = -TARGET_EINVAL;
463d8e73
AS
9190 } else if (is_proc_myself((const char *)p, "exe")) {
9191 char real[PATH_MAX], *temp;
9192 temp = realpath(exec_path, real);
f17f4989
MF
9193 /* Return value is # of bytes that we wrote to the buffer. */
9194 if (temp == NULL) {
9195 ret = get_errno(-1);
9196 } else {
9197 /* Don't worry about sign mismatch as earlier mapping
9198 * logic would have thrown a bad address error. */
9199 ret = MIN(strlen(real), arg3);
9200 /* We cannot NUL terminate the string. */
9201 memcpy(p2, real, ret);
9202 }
463d8e73
AS
9203 } else {
9204 ret = get_errno(readlink(path(p), p2, arg3));
d088d664 9205 }
53a5960a
PB
9206 unlock_user(p2, arg2, ret);
9207 unlock_user(p, arg1, 0);
9208 }
72eb7ea8 9209 return ret;
704eff6c 9210#endif
c0d472b1 9211#if defined(TARGET_NR_readlinkat)
5e0ccb18 9212 case TARGET_NR_readlinkat:
5e0ccb18 9213 {
579a97f7 9214 void *p2;
5e0ccb18 9215 p = lock_user_string(arg2);
579a97f7 9216 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
463d8e73
AS
9217 if (!p || !p2) {
9218 ret = -TARGET_EFAULT;
9219 } else if (is_proc_myself((const char *)p, "exe")) {
9220 char real[PATH_MAX], *temp;
9221 temp = realpath(exec_path, real);
9222 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
9223 snprintf((char *)p2, arg4, "%s", real);
9224 } else {
c0d472b1 9225 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
463d8e73 9226 }
579a97f7
FB
9227 unlock_user(p2, arg3, ret);
9228 unlock_user(p, arg2, 0);
5e0ccb18 9229 }
72eb7ea8 9230 return ret;
5e0ccb18 9231#endif
e5febef5 9232#ifdef TARGET_NR_swapon
31e31b8a 9233 case TARGET_NR_swapon:
579a97f7 9234 if (!(p = lock_user_string(arg1)))
2852aafd 9235 return -TARGET_EFAULT;
53a5960a
PB
9236 ret = get_errno(swapon(p, arg2));
9237 unlock_user(p, arg1, 0);
72eb7ea8 9238 return ret;
e5febef5 9239#endif
31e31b8a 9240 case TARGET_NR_reboot:
c07ecc68
LV
9241 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
9242 /* arg4 must be ignored in all other cases */
9243 p = lock_user_string(arg4);
9244 if (!p) {
2852aafd 9245 return -TARGET_EFAULT;
c07ecc68
LV
9246 }
9247 ret = get_errno(reboot(arg1, arg2, arg3, p));
9248 unlock_user(p, arg4, 0);
9249 } else {
9250 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
9251 }
72eb7ea8 9252 return ret;
e5febef5 9253#ifdef TARGET_NR_mmap
31e31b8a 9254 case TARGET_NR_mmap:
09701199
AG
9255#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
9256 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
a4c075f1
UH
9257 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
9258 || defined(TARGET_S390X)
31e31b8a 9259 {
992f48a0
BS
9260 abi_ulong *v;
9261 abi_ulong v1, v2, v3, v4, v5, v6;
579a97f7 9262 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
2852aafd 9263 return -TARGET_EFAULT;
cbb21eed
MB
9264 v1 = tswapal(v[0]);
9265 v2 = tswapal(v[1]);
9266 v3 = tswapal(v[2]);
9267 v4 = tswapal(v[3]);
9268 v5 = tswapal(v[4]);
9269 v6 = tswapal(v[5]);
53a5960a 9270 unlock_user(v, arg1, 0);
5fafdf24 9271 ret = get_errno(target_mmap(v1, v2, v3,
5286db75
FB
9272 target_to_host_bitmask(v4, mmap_flags_tbl),
9273 v5, v6));
31e31b8a 9274 }
31e31b8a 9275#else
5fafdf24
TS
9276 ret = get_errno(target_mmap(arg1, arg2, arg3,
9277 target_to_host_bitmask(arg4, mmap_flags_tbl),
6fb883e8
FB
9278 arg5,
9279 arg6));
31e31b8a 9280#endif
72eb7ea8 9281 return ret;
e5febef5 9282#endif
a315a145 9283#ifdef TARGET_NR_mmap2
6fb883e8 9284 case TARGET_NR_mmap2:
bb7ec043 9285#ifndef MMAP_SHIFT
c573ff67 9286#define MMAP_SHIFT 12
c573ff67 9287#endif
72eb7ea8
RH
9288 ret = target_mmap(arg1, arg2, arg3,
9289 target_to_host_bitmask(arg4, mmap_flags_tbl),
9290 arg5, arg6 << MMAP_SHIFT);
9291 return get_errno(ret);
a315a145 9292#endif
31e31b8a 9293 case TARGET_NR_munmap:
72eb7ea8 9294 return get_errno(target_munmap(arg1, arg2));
9de5e440 9295 case TARGET_NR_mprotect:
97374d38 9296 {
0429a971 9297 TaskState *ts = cpu->opaque;
97374d38
PB
9298 /* Special hack to detect libc making the stack executable. */
9299 if ((arg3 & PROT_GROWSDOWN)
9300 && arg1 >= ts->info->stack_limit
9301 && arg1 <= ts->info->start_stack) {
9302 arg3 &= ~PROT_GROWSDOWN;
9303 arg2 = arg2 + arg1 - ts->info->stack_limit;
9304 arg1 = ts->info->stack_limit;
9305 }
9306 }
72eb7ea8 9307 return get_errno(target_mprotect(arg1, arg2, arg3));
e5febef5 9308#ifdef TARGET_NR_mremap
9de5e440 9309 case TARGET_NR_mremap:
72eb7ea8 9310 return get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
e5febef5 9311#endif
53a5960a 9312 /* ??? msync/mlock/munlock are broken for softmmu. */
e5febef5 9313#ifdef TARGET_NR_msync
9de5e440 9314 case TARGET_NR_msync:
72eb7ea8 9315 return get_errno(msync(g2h(arg1), arg2, arg3));
e5febef5
TS
9316#endif
9317#ifdef TARGET_NR_mlock
9de5e440 9318 case TARGET_NR_mlock:
72eb7ea8 9319 return get_errno(mlock(g2h(arg1), arg2));
e5febef5
TS
9320#endif
9321#ifdef TARGET_NR_munlock
9de5e440 9322 case TARGET_NR_munlock:
72eb7ea8 9323 return get_errno(munlock(g2h(arg1), arg2));
e5febef5
TS
9324#endif
9325#ifdef TARGET_NR_mlockall
9de5e440 9326 case TARGET_NR_mlockall:
72eb7ea8 9327 return get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
e5febef5
TS
9328#endif
9329#ifdef TARGET_NR_munlockall
9de5e440 9330 case TARGET_NR_munlockall:
72eb7ea8 9331 return get_errno(munlockall());
e5febef5 9332#endif
4f7f8924 9333#ifdef TARGET_NR_truncate
31e31b8a 9334 case TARGET_NR_truncate:
579a97f7 9335 if (!(p = lock_user_string(arg1)))
2852aafd 9336 return -TARGET_EFAULT;
53a5960a
PB
9337 ret = get_errno(truncate(p, arg2));
9338 unlock_user(p, arg1, 0);
72eb7ea8 9339 return ret;
4f7f8924
AR
9340#endif
9341#ifdef TARGET_NR_ftruncate
31e31b8a 9342 case TARGET_NR_ftruncate:
72eb7ea8 9343 return get_errno(ftruncate(arg1, arg2));
4f7f8924 9344#endif
31e31b8a 9345 case TARGET_NR_fchmod:
72eb7ea8 9346 return get_errno(fchmod(arg1, arg2));
c0d472b1 9347#if defined(TARGET_NR_fchmodat)
814d7977 9348 case TARGET_NR_fchmodat:
579a97f7 9349 if (!(p = lock_user_string(arg2)))
2852aafd 9350 return -TARGET_EFAULT;
c0d472b1 9351 ret = get_errno(fchmodat(arg1, p, arg3, 0));
579a97f7 9352 unlock_user(p, arg2, 0);
72eb7ea8 9353 return ret;
814d7977 9354#endif
31e31b8a 9355 case TARGET_NR_getpriority:
95c09828
RH
9356 /* Note that negative values are valid for getpriority, so we must
9357 differentiate based on errno settings. */
9358 errno = 0;
9359 ret = getpriority(arg1, arg2);
9360 if (ret == -1 && errno != 0) {
72eb7ea8 9361 return -host_to_target_errno(errno);
95c09828
RH
9362 }
9363#ifdef TARGET_ALPHA
9364 /* Return value is the unbiased priority. Signal no error. */
9365 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
9366#else
9367 /* Return value is a biased priority to avoid negative numbers. */
9368 ret = 20 - ret;
9369#endif
72eb7ea8 9370 return ret;
31e31b8a 9371 case TARGET_NR_setpriority:
72eb7ea8 9372 return get_errno(setpriority(arg1, arg2, arg3));
4f7f8924 9373#ifdef TARGET_NR_statfs
31e31b8a 9374 case TARGET_NR_statfs:
2852aafd
RH
9375 if (!(p = lock_user_string(arg1))) {
9376 return -TARGET_EFAULT;
9377 }
53a5960a
PB
9378 ret = get_errno(statfs(path(p), &stfs));
9379 unlock_user(p, arg1, 0);
31e31b8a
FB
9380 convert_statfs:
9381 if (!is_error(ret)) {
53a5960a 9382 struct target_statfs *target_stfs;
3b46e624 9383
579a97f7 9384 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
2852aafd 9385 return -TARGET_EFAULT;
579a97f7
FB
9386 __put_user(stfs.f_type, &target_stfs->f_type);
9387 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
9388 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
9389 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
9390 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
9391 __put_user(stfs.f_files, &target_stfs->f_files);
9392 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
9393 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
9394 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
9395 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
229d3376 9396 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
d4247ec2
SL
9397#ifdef _STATFS_F_FLAGS
9398 __put_user(stfs.f_flags, &target_stfs->f_flags);
9399#else
9400 __put_user(0, &target_stfs->f_flags);
9401#endif
229d3376 9402 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
53a5960a 9403 unlock_user_struct(target_stfs, arg2, 1);
31e31b8a 9404 }
72eb7ea8 9405 return ret;
4f7f8924
AR
9406#endif
9407#ifdef TARGET_NR_fstatfs
31e31b8a 9408 case TARGET_NR_fstatfs:
56c8f68f 9409 ret = get_errno(fstatfs(arg1, &stfs));
31e31b8a 9410 goto convert_statfs;
4f7f8924 9411#endif
56c8f68f
FB
9412#ifdef TARGET_NR_statfs64
9413 case TARGET_NR_statfs64:
2852aafd
RH
9414 if (!(p = lock_user_string(arg1))) {
9415 return -TARGET_EFAULT;
9416 }
53a5960a
PB
9417 ret = get_errno(statfs(path(p), &stfs));
9418 unlock_user(p, arg1, 0);
56c8f68f
FB
9419 convert_statfs64:
9420 if (!is_error(ret)) {
53a5960a 9421 struct target_statfs64 *target_stfs;
3b46e624 9422
579a97f7 9423 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
2852aafd 9424 return -TARGET_EFAULT;
579a97f7
FB
9425 __put_user(stfs.f_type, &target_stfs->f_type);
9426 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
9427 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
9428 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
9429 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
9430 __put_user(stfs.f_files, &target_stfs->f_files);
9431 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
9432 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
9433 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
9434 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
229d3376
AG
9435 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
9436 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
579a97f7 9437 unlock_user_struct(target_stfs, arg3, 1);
56c8f68f 9438 }
72eb7ea8 9439 return ret;
56c8f68f
FB
9440 case TARGET_NR_fstatfs64:
9441 ret = get_errno(fstatfs(arg1, &stfs));
9442 goto convert_statfs64;
9443#endif
e5febef5 9444#ifdef TARGET_NR_socketcall
31e31b8a 9445 case TARGET_NR_socketcall:
72eb7ea8 9446 return do_socketcall(arg1, arg2);
e5febef5 9447#endif
3532fa74
FB
9448#ifdef TARGET_NR_accept
9449 case TARGET_NR_accept:
72eb7ea8 9450 return do_accept4(arg1, arg2, arg3, 0);
a94b4987
PM
9451#endif
9452#ifdef TARGET_NR_accept4
9453 case TARGET_NR_accept4:
72eb7ea8 9454 return do_accept4(arg1, arg2, arg3, arg4);
3532fa74
FB
9455#endif
9456#ifdef TARGET_NR_bind
9457 case TARGET_NR_bind:
72eb7ea8 9458 return do_bind(arg1, arg2, arg3);
3532fa74
FB
9459#endif
9460#ifdef TARGET_NR_connect
9461 case TARGET_NR_connect:
72eb7ea8 9462 return do_connect(arg1, arg2, arg3);
3532fa74
FB
9463#endif
9464#ifdef TARGET_NR_getpeername
9465 case TARGET_NR_getpeername:
72eb7ea8 9466 return do_getpeername(arg1, arg2, arg3);
3532fa74
FB
9467#endif
9468#ifdef TARGET_NR_getsockname
9469 case TARGET_NR_getsockname:
72eb7ea8 9470 return do_getsockname(arg1, arg2, arg3);
3532fa74
FB
9471#endif
9472#ifdef TARGET_NR_getsockopt
9473 case TARGET_NR_getsockopt:
72eb7ea8 9474 return do_getsockopt(arg1, arg2, arg3, arg4, arg5);
3532fa74
FB
9475#endif
9476#ifdef TARGET_NR_listen
9477 case TARGET_NR_listen:
72eb7ea8 9478 return get_errno(listen(arg1, arg2));
3532fa74
FB
9479#endif
9480#ifdef TARGET_NR_recv
9481 case TARGET_NR_recv:
72eb7ea8 9482 return do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
3532fa74
FB
9483#endif
9484#ifdef TARGET_NR_recvfrom
9485 case TARGET_NR_recvfrom:
72eb7ea8 9486 return do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
3532fa74
FB
9487#endif
9488#ifdef TARGET_NR_recvmsg
9489 case TARGET_NR_recvmsg:
72eb7ea8 9490 return do_sendrecvmsg(arg1, arg2, arg3, 0);
3532fa74
FB
9491#endif
9492#ifdef TARGET_NR_send
9493 case TARGET_NR_send:
72eb7ea8 9494 return do_sendto(arg1, arg2, arg3, arg4, 0, 0);
3532fa74
FB
9495#endif
9496#ifdef TARGET_NR_sendmsg
9497 case TARGET_NR_sendmsg:
72eb7ea8 9498 return do_sendrecvmsg(arg1, arg2, arg3, 1);
3532fa74 9499#endif
f19e00d7
AG
9500#ifdef TARGET_NR_sendmmsg
9501 case TARGET_NR_sendmmsg:
72eb7ea8 9502 return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
859e8a89
AF
9503#endif
9504#ifdef TARGET_NR_recvmmsg
f19e00d7 9505 case TARGET_NR_recvmmsg:
72eb7ea8 9506 return do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
f19e00d7 9507#endif
3532fa74
FB
9508#ifdef TARGET_NR_sendto
9509 case TARGET_NR_sendto:
72eb7ea8 9510 return do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
3532fa74
FB
9511#endif
9512#ifdef TARGET_NR_shutdown
9513 case TARGET_NR_shutdown:
72eb7ea8 9514 return get_errno(shutdown(arg1, arg2));
3532fa74 9515#endif
f894efd1
LV
9516#if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
9517 case TARGET_NR_getrandom:
9518 p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9519 if (!p) {
2852aafd 9520 return -TARGET_EFAULT;
f894efd1
LV
9521 }
9522 ret = get_errno(getrandom(p, arg2, arg3));
9523 unlock_user(p, arg1, ret);
72eb7ea8 9524 return ret;
f894efd1 9525#endif
3532fa74
FB
9526#ifdef TARGET_NR_socket
9527 case TARGET_NR_socket:
72eb7ea8 9528 return do_socket(arg1, arg2, arg3);
3532fa74
FB
9529#endif
9530#ifdef TARGET_NR_socketpair
9531 case TARGET_NR_socketpair:
72eb7ea8 9532 return do_socketpair(arg1, arg2, arg3, arg4);
3532fa74
FB
9533#endif
9534#ifdef TARGET_NR_setsockopt
9535 case TARGET_NR_setsockopt:
72eb7ea8 9536 return do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
3532fa74 9537#endif
da2c8ad7 9538#if defined(TARGET_NR_syslog)
31e31b8a 9539 case TARGET_NR_syslog:
da2c8ad7
AM
9540 {
9541 int len = arg2;
7494b0f9 9542
da2c8ad7
AM
9543 switch (arg1) {
9544 case TARGET_SYSLOG_ACTION_CLOSE: /* Close log */
9545 case TARGET_SYSLOG_ACTION_OPEN: /* Open log */
9546 case TARGET_SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
9547 case TARGET_SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging */
9548 case TARGET_SYSLOG_ACTION_CONSOLE_ON: /* Enable logging */
9549 case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: /* Set messages level */
9550 case TARGET_SYSLOG_ACTION_SIZE_UNREAD: /* Number of chars */
9551 case TARGET_SYSLOG_ACTION_SIZE_BUFFER: /* Size of the buffer */
72eb7ea8 9552 return get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
da2c8ad7
AM
9553 case TARGET_SYSLOG_ACTION_READ: /* Read from log */
9554 case TARGET_SYSLOG_ACTION_READ_CLEAR: /* Read/clear msgs */
9555 case TARGET_SYSLOG_ACTION_READ_ALL: /* Read last messages */
9556 {
da2c8ad7 9557 if (len < 0) {
259841c1 9558 return -TARGET_EINVAL;
da2c8ad7 9559 }
da2c8ad7 9560 if (len == 0) {
72eb7ea8 9561 return 0;
da2c8ad7
AM
9562 }
9563 p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
9564 if (!p) {
259841c1 9565 return -TARGET_EFAULT;
da2c8ad7
AM
9566 }
9567 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
9568 unlock_user(p, arg2, arg3);
9569 }
72eb7ea8 9570 return ret;
da2c8ad7 9571 default:
72eb7ea8 9572 return -TARGET_EINVAL;
da2c8ad7
AM
9573 }
9574 }
9575 break;
9576#endif
31e31b8a 9577 case TARGET_NR_setitimer:
66fb9763 9578 {
66fb9763
FB
9579 struct itimerval value, ovalue, *pvalue;
9580
53a5960a 9581 if (arg2) {
66fb9763 9582 pvalue = &value;
788f5ec4
TS
9583 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
9584 || copy_from_user_timeval(&pvalue->it_value,
9585 arg2 + sizeof(struct target_timeval)))
2852aafd 9586 return -TARGET_EFAULT;
66fb9763
FB
9587 } else {
9588 pvalue = NULL;
9589 }
9590 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
53a5960a 9591 if (!is_error(ret) && arg3) {
788f5ec4
TS
9592 if (copy_to_user_timeval(arg3,
9593 &ovalue.it_interval)
9594 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
9595 &ovalue.it_value))
2852aafd 9596 return -TARGET_EFAULT;
66fb9763
FB
9597 }
9598 }
72eb7ea8 9599 return ret;
31e31b8a 9600 case TARGET_NR_getitimer:
66fb9763 9601 {
66fb9763 9602 struct itimerval value;
3b46e624 9603
66fb9763 9604 ret = get_errno(getitimer(arg1, &value));
53a5960a 9605 if (!is_error(ret) && arg2) {
788f5ec4
TS
9606 if (copy_to_user_timeval(arg2,
9607 &value.it_interval)
9608 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
9609 &value.it_value))
2852aafd 9610 return -TARGET_EFAULT;
66fb9763
FB
9611 }
9612 }
72eb7ea8 9613 return ret;
704eff6c 9614#ifdef TARGET_NR_stat
31e31b8a 9615 case TARGET_NR_stat:
2852aafd
RH
9616 if (!(p = lock_user_string(arg1))) {
9617 return -TARGET_EFAULT;
9618 }
53a5960a
PB
9619 ret = get_errno(stat(path(p), &st));
9620 unlock_user(p, arg1, 0);
31e31b8a 9621 goto do_stat;
704eff6c
CG
9622#endif
9623#ifdef TARGET_NR_lstat
31e31b8a 9624 case TARGET_NR_lstat:
2852aafd
RH
9625 if (!(p = lock_user_string(arg1))) {
9626 return -TARGET_EFAULT;
9627 }
53a5960a
PB
9628 ret = get_errno(lstat(path(p), &st));
9629 unlock_user(p, arg1, 0);
31e31b8a 9630 goto do_stat;
704eff6c 9631#endif
4f7f8924 9632#ifdef TARGET_NR_fstat
31e31b8a
FB
9633 case TARGET_NR_fstat:
9634 {
9635 ret = get_errno(fstat(arg1, &st));
704eff6c 9636#if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat)
31e31b8a 9637 do_stat:
704eff6c 9638#endif
31e31b8a 9639 if (!is_error(ret)) {
53a5960a 9640 struct target_stat *target_st;
e3584658 9641
579a97f7 9642 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
2852aafd 9643 return -TARGET_EFAULT;
12727917 9644 memset(target_st, 0, sizeof(*target_st));
d2fd1af7
FB
9645 __put_user(st.st_dev, &target_st->st_dev);
9646 __put_user(st.st_ino, &target_st->st_ino);
9647 __put_user(st.st_mode, &target_st->st_mode);
9648 __put_user(st.st_uid, &target_st->st_uid);
9649 __put_user(st.st_gid, &target_st->st_gid);
9650 __put_user(st.st_nlink, &target_st->st_nlink);
9651 __put_user(st.st_rdev, &target_st->st_rdev);
9652 __put_user(st.st_size, &target_st->st_size);
9653 __put_user(st.st_blksize, &target_st->st_blksize);
9654 __put_user(st.st_blocks, &target_st->st_blocks);
9655 __put_user(st.st_atime, &target_st->target_st_atime);
9656 __put_user(st.st_mtime, &target_st->target_st_mtime);
9657 __put_user(st.st_ctime, &target_st->target_st_ctime);
5f992db6
CYT
9658#if (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) && \
9659 defined(TARGET_STAT_HAVE_NSEC)
9660 __put_user(st.st_atim.tv_nsec,
9661 &target_st->target_st_atime_nsec);
9662 __put_user(st.st_mtim.tv_nsec,
9663 &target_st->target_st_mtime_nsec);
9664 __put_user(st.st_ctim.tv_nsec,
9665 &target_st->target_st_ctime_nsec);
9666#endif
53a5960a 9667 unlock_user_struct(target_st, arg2, 1);
31e31b8a
FB
9668 }
9669 }
72eb7ea8 9670 return ret;
ebc05488 9671#endif
31e31b8a 9672 case TARGET_NR_vhangup:
72eb7ea8 9673 return get_errno(vhangup());
42ad6ae9
FB
9674#ifdef TARGET_NR_syscall
9675 case TARGET_NR_syscall:
72eb7ea8
RH
9676 return do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
9677 arg6, arg7, arg8, 0);
ebc05488 9678#endif
859e8a89 9679#if defined(TARGET_NR_wait4)
31e31b8a
FB
9680 case TARGET_NR_wait4:
9681 {
9682 int status;
992f48a0 9683 abi_long status_ptr = arg2;
31e31b8a 9684 struct rusage rusage, *rusage_ptr;
992f48a0 9685 abi_ulong target_rusage = arg4;
a39fb273 9686 abi_long rusage_err;
31e31b8a
FB
9687 if (target_rusage)
9688 rusage_ptr = &rusage;
9689 else
9690 rusage_ptr = NULL;
4af80a37 9691 ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr));
31e31b8a 9692 if (!is_error(ret)) {
5379557b 9693 if (status_ptr && ret) {
1d9d8b55 9694 status = host_to_target_waitstatus(status);
2f619698 9695 if (put_user_s32(status, status_ptr))
2852aafd 9696 return -TARGET_EFAULT;
31e31b8a 9697 }
a39fb273
PJ
9698 if (target_rusage) {
9699 rusage_err = host_to_target_rusage(target_rusage, &rusage);
9700 if (rusage_err) {
9701 ret = rusage_err;
9702 }
9703 }
31e31b8a
FB
9704 }
9705 }
72eb7ea8 9706 return ret;
859e8a89 9707#endif
e5febef5 9708#ifdef TARGET_NR_swapoff
31e31b8a 9709 case TARGET_NR_swapoff:
579a97f7 9710 if (!(p = lock_user_string(arg1)))
2852aafd 9711 return -TARGET_EFAULT;
53a5960a
PB
9712 ret = get_errno(swapoff(p));
9713 unlock_user(p, arg1, 0);
72eb7ea8 9714 return ret;
e5febef5 9715#endif
31e31b8a 9716 case TARGET_NR_sysinfo:
a5448a7d 9717 {
53a5960a 9718 struct target_sysinfo *target_value;
a5448a7d
FB
9719 struct sysinfo value;
9720 ret = get_errno(sysinfo(&value));
53a5960a 9721 if (!is_error(ret) && arg1)
a5448a7d 9722 {
579a97f7 9723 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
2852aafd 9724 return -TARGET_EFAULT;
a5448a7d
FB
9725 __put_user(value.uptime, &target_value->uptime);
9726 __put_user(value.loads[0], &target_value->loads[0]);
9727 __put_user(value.loads[1], &target_value->loads[1]);
9728 __put_user(value.loads[2], &target_value->loads[2]);
9729 __put_user(value.totalram, &target_value->totalram);
9730 __put_user(value.freeram, &target_value->freeram);
9731 __put_user(value.sharedram, &target_value->sharedram);
9732 __put_user(value.bufferram, &target_value->bufferram);
9733 __put_user(value.totalswap, &target_value->totalswap);
9734 __put_user(value.freeswap, &target_value->freeswap);
9735 __put_user(value.procs, &target_value->procs);
9736 __put_user(value.totalhigh, &target_value->totalhigh);
9737 __put_user(value.freehigh, &target_value->freehigh);
9738 __put_user(value.mem_unit, &target_value->mem_unit);
53a5960a 9739 unlock_user_struct(target_value, arg1, 1);
a5448a7d
FB
9740 }
9741 }
72eb7ea8 9742 return ret;
e5febef5 9743#ifdef TARGET_NR_ipc
31e31b8a 9744 case TARGET_NR_ipc:
72eb7ea8 9745 return do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
e5febef5 9746#endif
e5289087
AJ
9747#ifdef TARGET_NR_semget
9748 case TARGET_NR_semget:
72eb7ea8 9749 return get_errno(semget(arg1, arg2, arg3));
e5289087
AJ
9750#endif
9751#ifdef TARGET_NR_semop
9752 case TARGET_NR_semop:
d8c08b1e
MK
9753 return do_semtimedop(arg1, arg2, arg3, 0);
9754#endif
9755#ifdef TARGET_NR_semtimedop
9756 case TARGET_NR_semtimedop:
9757 return do_semtimedop(arg1, arg2, arg3, arg4);
e5289087
AJ
9758#endif
9759#ifdef TARGET_NR_semctl
9760 case TARGET_NR_semctl:
72eb7ea8 9761 return do_semctl(arg1, arg2, arg3, arg4);
e5289087 9762#endif
eeb438c1
AJ
9763#ifdef TARGET_NR_msgctl
9764 case TARGET_NR_msgctl:
72eb7ea8 9765 return do_msgctl(arg1, arg2, arg3);
eeb438c1
AJ
9766#endif
9767#ifdef TARGET_NR_msgget
9768 case TARGET_NR_msgget:
72eb7ea8 9769 return get_errno(msgget(arg1, arg2));
eeb438c1
AJ
9770#endif
9771#ifdef TARGET_NR_msgrcv
9772 case TARGET_NR_msgrcv:
72eb7ea8 9773 return do_msgrcv(arg1, arg2, arg3, arg4, arg5);
eeb438c1
AJ
9774#endif
9775#ifdef TARGET_NR_msgsnd
9776 case TARGET_NR_msgsnd:
72eb7ea8 9777 return do_msgsnd(arg1, arg2, arg3, arg4);
88a8c984
RV
9778#endif
9779#ifdef TARGET_NR_shmget
9780 case TARGET_NR_shmget:
72eb7ea8 9781 return get_errno(shmget(arg1, arg2, arg3));
88a8c984
RV
9782#endif
9783#ifdef TARGET_NR_shmctl
9784 case TARGET_NR_shmctl:
72eb7ea8 9785 return do_shmctl(arg1, arg2, arg3);
88a8c984
RV
9786#endif
9787#ifdef TARGET_NR_shmat
9788 case TARGET_NR_shmat:
72eb7ea8 9789 return do_shmat(cpu_env, arg1, arg2, arg3);
88a8c984
RV
9790#endif
9791#ifdef TARGET_NR_shmdt
9792 case TARGET_NR_shmdt:
72eb7ea8 9793 return do_shmdt(arg1);
eeb438c1 9794#endif
31e31b8a 9795 case TARGET_NR_fsync:
72eb7ea8 9796 return get_errno(fsync(arg1));
31e31b8a 9797 case TARGET_NR_clone:
4ce6243d
PM
9798 /* Linux manages to have three different orderings for its
9799 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
9800 * match the kernel's CONFIG_CLONE_* settings.
9801 * Microblaze is further special in that it uses a sixth
9802 * implicit argument to clone for the TLS pointer.
9803 */
9804#if defined(TARGET_MICROBLAZE)
a5b3bdcb 9805 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
4ce6243d
PM
9806#elif defined(TARGET_CLONE_BACKWARDS)
9807 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
9808#elif defined(TARGET_CLONE_BACKWARDS2)
a4c075f1 9809 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
0b6d3ae0 9810#else
4ce6243d 9811 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
0b6d3ae0 9812#endif
72eb7ea8 9813 return ret;
ec86b0fb
FB
9814#ifdef __NR_exit_group
9815 /* new thread calls */
9816 case TARGET_NR_exit_group:
708b6a64 9817 preexit_cleanup(cpu_env, arg1);
72eb7ea8 9818 return get_errno(exit_group(arg1));
ec86b0fb 9819#endif
31e31b8a 9820 case TARGET_NR_setdomainname:
579a97f7 9821 if (!(p = lock_user_string(arg1)))
2852aafd 9822 return -TARGET_EFAULT;
53a5960a
PB
9823 ret = get_errno(setdomainname(p, arg2));
9824 unlock_user(p, arg1, 0);
72eb7ea8 9825 return ret;
31e31b8a
FB
9826 case TARGET_NR_uname:
9827 /* no need to transcode because we use the linux syscall */
29e619b1
FB
9828 {
9829 struct new_utsname * buf;
3b46e624 9830
579a97f7 9831 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
2852aafd 9832 return -TARGET_EFAULT;
29e619b1
FB
9833 ret = get_errno(sys_uname(buf));
9834 if (!is_error(ret)) {
332c9781 9835 /* Overwrite the native machine name with whatever is being
29e619b1 9836 emulated. */
871f95c6
PMD
9837 g_strlcpy(buf->machine, cpu_to_uname_machine(cpu_env),
9838 sizeof(buf->machine));
c5937220 9839 /* Allow the user to override the reported release. */
332c9781
PM
9840 if (qemu_uname_release && *qemu_uname_release) {
9841 g_strlcpy(buf->release, qemu_uname_release,
9842 sizeof(buf->release));
9843 }
29e619b1 9844 }
53a5960a 9845 unlock_user_struct(buf, arg1, 1);
29e619b1 9846 }
72eb7ea8 9847 return ret;
6dbad63e 9848#ifdef TARGET_I386
31e31b8a 9849 case TARGET_NR_modify_ldt:
72eb7ea8 9850 return do_modify_ldt(cpu_env, arg1, arg2, arg3);
84409ddb 9851#if !defined(TARGET_X86_64)
5cd4393b 9852 case TARGET_NR_vm86:
72eb7ea8 9853 return do_vm86(cpu_env, arg1, arg2);
84409ddb 9854#endif
6dbad63e 9855#endif
859e8a89 9856#if defined(TARGET_NR_adjtimex)
31e31b8a 9857 case TARGET_NR_adjtimex:
19f59bce
AM
9858 {
9859 struct timex host_buf;
9860
9861 if (target_to_host_timex(&host_buf, arg1) != 0) {
2852aafd 9862 return -TARGET_EFAULT;
19f59bce
AM
9863 }
9864 ret = get_errno(adjtimex(&host_buf));
9865 if (!is_error(ret)) {
9866 if (host_to_target_timex(arg1, &host_buf) != 0) {
2852aafd 9867 return -TARGET_EFAULT;
19f59bce
AM
9868 }
9869 }
9870 }
72eb7ea8 9871 return ret;
859e8a89 9872#endif
38860a03
AM
9873#if defined(TARGET_NR_clock_adjtime) && defined(CONFIG_CLOCK_ADJTIME)
9874 case TARGET_NR_clock_adjtime:
9875 {
9876 struct timex htx, *phtx = &htx;
9877
9878 if (target_to_host_timex(phtx, arg2) != 0) {
2852aafd 9879 return -TARGET_EFAULT;
38860a03
AM
9880 }
9881 ret = get_errno(clock_adjtime(arg1, phtx));
9882 if (!is_error(ret) && phtx) {
9883 if (host_to_target_timex(arg2, phtx) != 0) {
2852aafd 9884 return -TARGET_EFAULT;
38860a03
AM
9885 }
9886 }
9887 }
72eb7ea8 9888 return ret;
38860a03 9889#endif
31e31b8a 9890 case TARGET_NR_getpgid:
72eb7ea8 9891 return get_errno(getpgid(arg1));
31e31b8a 9892 case TARGET_NR_fchdir:
72eb7ea8 9893 return get_errno(fchdir(arg1));
31e31b8a 9894 case TARGET_NR_personality:
72eb7ea8 9895 return get_errno(personality(arg1));
7a3148a9 9896#ifdef TARGET_NR__llseek /* Not on alpha */
31e31b8a
FB
9897 case TARGET_NR__llseek:
9898 {
0c1592d9 9899 int64_t res;
d35b261c 9900#if !defined(__NR_llseek)
9fea273c 9901 res = lseek(arg1, ((uint64_t)arg2 << 32) | (abi_ulong)arg3, arg5);
0c1592d9
PM
9902 if (res == -1) {
9903 ret = get_errno(res);
9904 } else {
9905 ret = 0;
9906 }
4f2ac237 9907#else
31e31b8a 9908 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
4f2ac237 9909#endif
0c1592d9 9910 if ((ret == 0) && put_user_s64(res, arg4)) {
2852aafd 9911 return -TARGET_EFAULT;
0c1592d9 9912 }
31e31b8a 9913 }
72eb7ea8 9914 return ret;
7a3148a9 9915#endif
704eff6c 9916#ifdef TARGET_NR_getdents
31e31b8a 9917 case TARGET_NR_getdents:
2b3f64cb 9918#ifdef EMULATE_GETDENTS_WITH_GETDENTS
d83c8733 9919#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4add45b4 9920 {
53a5960a 9921 struct target_dirent *target_dirp;
6556a833 9922 struct linux_dirent *dirp;
992f48a0 9923 abi_long count = arg3;
4add45b4 9924
0e173b24
HK
9925 dirp = g_try_malloc(count);
9926 if (!dirp) {
259841c1 9927 return -TARGET_ENOMEM;
0da46a6e 9928 }
3b46e624 9929
4add45b4
FB
9930 ret = get_errno(sys_getdents(arg1, dirp, count));
9931 if (!is_error(ret)) {
6556a833 9932 struct linux_dirent *de;
4add45b4
FB
9933 struct target_dirent *tde;
9934 int len = ret;
9935 int reclen, treclen;
9936 int count1, tnamelen;
9937
9938 count1 = 0;
9939 de = dirp;
579a97f7 9940 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
2852aafd 9941 return -TARGET_EFAULT;
4add45b4
FB
9942 tde = target_dirp;
9943 while (len > 0) {
9944 reclen = de->d_reclen;
333858b7
DL
9945 tnamelen = reclen - offsetof(struct linux_dirent, d_name);
9946 assert(tnamelen >= 0);
9947 treclen = tnamelen + offsetof(struct target_dirent, d_name);
9948 assert(count1 + treclen <= count);
4add45b4 9949 tde->d_reclen = tswap16(treclen);
cbb21eed
MB
9950 tde->d_ino = tswapal(de->d_ino);
9951 tde->d_off = tswapal(de->d_off);
333858b7 9952 memcpy(tde->d_name, de->d_name, tnamelen);
6556a833 9953 de = (struct linux_dirent *)((char *)de + reclen);
4add45b4 9954 len -= reclen;
1c5bf3bf 9955 tde = (struct target_dirent *)((char *)tde + treclen);
4add45b4
FB
9956 count1 += treclen;
9957 }
9958 ret = count1;
579a97f7 9959 unlock_user(target_dirp, arg2, ret);
4add45b4 9960 }
0e173b24 9961 g_free(dirp);
4add45b4
FB
9962 }
9963#else
31e31b8a 9964 {
6556a833 9965 struct linux_dirent *dirp;
992f48a0 9966 abi_long count = arg3;
dab2ed99 9967
579a97f7 9968 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
2852aafd 9969 return -TARGET_EFAULT;
72f03900 9970 ret = get_errno(sys_getdents(arg1, dirp, count));
31e31b8a 9971 if (!is_error(ret)) {
6556a833 9972 struct linux_dirent *de;
31e31b8a
FB
9973 int len = ret;
9974 int reclen;
9975 de = dirp;
9976 while (len > 0) {
8083a3e5 9977 reclen = de->d_reclen;
31e31b8a
FB
9978 if (reclen > len)
9979 break;
8083a3e5 9980 de->d_reclen = tswap16(reclen);
31e31b8a
FB
9981 tswapls(&de->d_ino);
9982 tswapls(&de->d_off);
6556a833 9983 de = (struct linux_dirent *)((char *)de + reclen);
31e31b8a
FB
9984 len -= reclen;
9985 }
9986 }
53a5960a 9987 unlock_user(dirp, arg2, ret);
3307e236
PM
9988 }
9989#endif
9990#else
9991 /* Implement getdents in terms of getdents64 */
9992 {
9993 struct linux_dirent64 *dirp;
9994 abi_long count = arg3;
9995
9996 dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
9997 if (!dirp) {
2852aafd 9998 return -TARGET_EFAULT;
3307e236
PM
9999 }
10000 ret = get_errno(sys_getdents64(arg1, dirp, count));
10001 if (!is_error(ret)) {
10002 /* Convert the dirent64 structs to target dirent. We do this
10003 * in-place, since we can guarantee that a target_dirent is no
10004 * larger than a dirent64; however this means we have to be
10005 * careful to read everything before writing in the new format.
10006 */
10007 struct linux_dirent64 *de;
10008 struct target_dirent *tde;
10009 int len = ret;
10010 int tlen = 0;
10011
10012 de = dirp;
10013 tde = (struct target_dirent *)dirp;
10014 while (len > 0) {
10015 int namelen, treclen;
10016 int reclen = de->d_reclen;
10017 uint64_t ino = de->d_ino;
10018 int64_t off = de->d_off;
10019 uint8_t type = de->d_type;
10020
10021 namelen = strlen(de->d_name);
10022 treclen = offsetof(struct target_dirent, d_name)
10023 + namelen + 2;
10024 treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
10025
10026 memmove(tde->d_name, de->d_name, namelen + 1);
10027 tde->d_ino = tswapal(ino);
10028 tde->d_off = tswapal(off);
10029 tde->d_reclen = tswap16(treclen);
10030 /* The target_dirent type is in what was formerly a padding
10031 * byte at the end of the structure:
10032 */
10033 *(((char *)tde) + treclen - 1) = type;
10034
10035 de = (struct linux_dirent64 *)((char *)de + reclen);
10036 tde = (struct target_dirent *)((char *)tde + treclen);
10037 len -= reclen;
10038 tlen += treclen;
10039 }
10040 ret = tlen;
10041 }
10042 unlock_user(dirp, arg2, ret);
31e31b8a 10043 }
4add45b4 10044#endif
72eb7ea8 10045 return ret;
704eff6c 10046#endif /* TARGET_NR_getdents */
3ae43202 10047#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
dab2ed99
FB
10048 case TARGET_NR_getdents64:
10049 {
6556a833 10050 struct linux_dirent64 *dirp;
992f48a0 10051 abi_long count = arg3;
579a97f7 10052 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
2852aafd 10053 return -TARGET_EFAULT;
dab2ed99
FB
10054 ret = get_errno(sys_getdents64(arg1, dirp, count));
10055 if (!is_error(ret)) {
6556a833 10056 struct linux_dirent64 *de;
dab2ed99
FB
10057 int len = ret;
10058 int reclen;
10059 de = dirp;
10060 while (len > 0) {
8083a3e5 10061 reclen = de->d_reclen;
dab2ed99
FB
10062 if (reclen > len)
10063 break;
8083a3e5 10064 de->d_reclen = tswap16(reclen);
8582a53a
FB
10065 tswap64s((uint64_t *)&de->d_ino);
10066 tswap64s((uint64_t *)&de->d_off);
6556a833 10067 de = (struct linux_dirent64 *)((char *)de + reclen);
dab2ed99
FB
10068 len -= reclen;
10069 }
10070 }
53a5960a 10071 unlock_user(dirp, arg2, ret);
dab2ed99 10072 }
72eb7ea8 10073 return ret;
a541f297 10074#endif /* TARGET_NR_getdents64 */
9468a5d4 10075#if defined(TARGET_NR__newselect)
31e31b8a 10076 case TARGET_NR__newselect:
72eb7ea8 10077 return do_select(arg1, arg2, arg3, arg4, arg5);
e5febef5 10078#endif
d8035d4c
MF
10079#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
10080# ifdef TARGET_NR_poll
9de5e440 10081 case TARGET_NR_poll:
d8035d4c
MF
10082# endif
10083# ifdef TARGET_NR_ppoll
10084 case TARGET_NR_ppoll:
10085# endif
9de5e440 10086 {
53a5960a 10087 struct target_pollfd *target_pfd;
9de5e440 10088 unsigned int nfds = arg2;
9de5e440 10089 struct pollfd *pfd;
7854b056 10090 unsigned int i;
9de5e440 10091
3e24bb3f
LV
10092 pfd = NULL;
10093 target_pfd = NULL;
10094 if (nfds) {
ce9c139d 10095 if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
72eb7ea8 10096 return -TARGET_EINVAL;
ce9c139d
PM
10097 }
10098
3e24bb3f
LV
10099 target_pfd = lock_user(VERIFY_WRITE, arg1,
10100 sizeof(struct target_pollfd) * nfds, 1);
10101 if (!target_pfd) {
2852aafd 10102 return -TARGET_EFAULT;
3e24bb3f 10103 }
d8035d4c 10104
3e24bb3f
LV
10105 pfd = alloca(sizeof(struct pollfd) * nfds);
10106 for (i = 0; i < nfds; i++) {
10107 pfd[i].fd = tswap32(target_pfd[i].fd);
10108 pfd[i].events = tswap16(target_pfd[i].events);
10109 }
9de5e440 10110 }
d8035d4c 10111
a6130237 10112 switch (num) {
d8035d4c 10113# ifdef TARGET_NR_ppoll
a6130237
PM
10114 case TARGET_NR_ppoll:
10115 {
d8035d4c
MF
10116 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
10117 target_sigset_t *target_set;
10118 sigset_t _set, *set = &_set;
10119
10120 if (arg3) {
10121 if (target_to_host_timespec(timeout_ts, arg3)) {
10122 unlock_user(target_pfd, arg1, 0);
2852aafd 10123 return -TARGET_EFAULT;
d8035d4c
MF
10124 }
10125 } else {
10126 timeout_ts = NULL;
10127 }
10128
10129 if (arg4) {
c815701e
PM
10130 if (arg5 != sizeof(target_sigset_t)) {
10131 unlock_user(target_pfd, arg1, 0);
72eb7ea8 10132 return -TARGET_EINVAL;
c815701e
PM
10133 }
10134
d8035d4c
MF
10135 target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
10136 if (!target_set) {
10137 unlock_user(target_pfd, arg1, 0);
2852aafd 10138 return -TARGET_EFAULT;
d8035d4c
MF
10139 }
10140 target_to_host_sigset(set, target_set);
10141 } else {
10142 set = NULL;
10143 }
10144
a6130237
PM
10145 ret = get_errno(safe_ppoll(pfd, nfds, timeout_ts,
10146 set, SIGSET_T_SIZE));
d8035d4c
MF
10147
10148 if (!is_error(ret) && arg3) {
10149 host_to_target_timespec(arg3, timeout_ts);
10150 }
10151 if (arg4) {
10152 unlock_user(target_set, arg4, 0);
10153 }
a6130237
PM
10154 break;
10155 }
d8035d4c 10156# endif
a6130237
PM
10157# ifdef TARGET_NR_poll
10158 case TARGET_NR_poll:
10159 {
10160 struct timespec ts, *pts;
10161
10162 if (arg3 >= 0) {
10163 /* Convert ms to secs, ns */
10164 ts.tv_sec = arg3 / 1000;
10165 ts.tv_nsec = (arg3 % 1000) * 1000000LL;
10166 pts = &ts;
10167 } else {
10168 /* -ve poll() timeout means "infinite" */
10169 pts = NULL;
10170 }
10171 ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
10172 break;
10173 }
d8035d4c 10174# endif
a6130237
PM
10175 default:
10176 g_assert_not_reached();
10177 }
d8035d4c 10178
9de5e440
FB
10179 if (!is_error(ret)) {
10180 for(i = 0; i < nfds; i++) {
5cd4393b 10181 target_pfd[i].revents = tswap16(pfd[i].revents);
9de5e440
FB
10182 }
10183 }
30cb4cde 10184 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
9de5e440 10185 }
72eb7ea8 10186 return ret;
e5febef5 10187#endif
31e31b8a 10188 case TARGET_NR_flock:
9de5e440
FB
10189 /* NOTE: the flock constant seems to be the same for every
10190 Linux platform */
72eb7ea8 10191 return get_errno(safe_flock(arg1, arg2));
31e31b8a
FB
10192 case TARGET_NR_readv:
10193 {
f287b2c2
RH
10194 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
10195 if (vec != NULL) {
918c03ed 10196 ret = get_errno(safe_readv(arg1, vec, arg3));
f287b2c2
RH
10197 unlock_iovec(vec, arg2, arg3, 1);
10198 } else {
10199 ret = -host_to_target_errno(errno);
10200 }
31e31b8a 10201 }
72eb7ea8 10202 return ret;
31e31b8a
FB
10203 case TARGET_NR_writev:
10204 {
f287b2c2
RH
10205 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10206 if (vec != NULL) {
918c03ed 10207 ret = get_errno(safe_writev(arg1, vec, arg3));
f287b2c2
RH
10208 unlock_iovec(vec, arg2, arg3, 0);
10209 } else {
10210 ret = -host_to_target_errno(errno);
10211 }
31e31b8a 10212 }
72eb7ea8 10213 return ret;
0f26386c
DJ
10214#if defined(TARGET_NR_preadv)
10215 case TARGET_NR_preadv:
10216 {
10217 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
10218 if (vec != NULL) {
9ac22517
MF
10219 unsigned long low, high;
10220
10221 target_to_host_low_high(arg4, arg5, &low, &high);
10222 ret = get_errno(safe_preadv(arg1, vec, arg3, low, high));
0f26386c
DJ
10223 unlock_iovec(vec, arg2, arg3, 1);
10224 } else {
10225 ret = -host_to_target_errno(errno);
f8d00fba
DJ
10226 }
10227 }
72eb7ea8 10228 return ret;
f8d00fba
DJ
10229#endif
10230#if defined(TARGET_NR_pwritev)
10231 case TARGET_NR_pwritev:
10232 {
10233 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10234 if (vec != NULL) {
9ac22517
MF
10235 unsigned long low, high;
10236
10237 target_to_host_low_high(arg4, arg5, &low, &high);
10238 ret = get_errno(safe_pwritev(arg1, vec, arg3, low, high));
f8d00fba
DJ
10239 unlock_iovec(vec, arg2, arg3, 0);
10240 } else {
10241 ret = -host_to_target_errno(errno);
0f26386c
DJ
10242 }
10243 }
72eb7ea8 10244 return ret;
0f26386c 10245#endif
31e31b8a 10246 case TARGET_NR_getsid:
72eb7ea8 10247 return get_errno(getsid(arg1));
7a3148a9 10248#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
31e31b8a 10249 case TARGET_NR_fdatasync:
72eb7ea8 10250 return get_errno(fdatasync(arg1));
7a3148a9 10251#endif
704eff6c 10252#ifdef TARGET_NR__sysctl
31e31b8a 10253 case TARGET_NR__sysctl:
0da46a6e 10254 /* We don't implement this, but ENOTDIR is always a safe
29e619b1 10255 return value. */
72eb7ea8 10256 return -TARGET_ENOTDIR;
704eff6c 10257#endif
737de1d1
MF
10258 case TARGET_NR_sched_getaffinity:
10259 {
10260 unsigned int mask_size;
10261 unsigned long *mask;
10262
10263 /*
10264 * sched_getaffinity needs multiples of ulong, so need to take
10265 * care of mismatches between target ulong and host ulong sizes.
10266 */
10267 if (arg2 & (sizeof(abi_ulong) - 1)) {
72eb7ea8 10268 return -TARGET_EINVAL;
737de1d1
MF
10269 }
10270 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
10271
10272 mask = alloca(mask_size);
2e0a8713 10273 memset(mask, 0, mask_size);
737de1d1
MF
10274 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
10275
10276 if (!is_error(ret)) {
be3bd286
PM
10277 if (ret > arg2) {
10278 /* More data returned than the caller's buffer will fit.
10279 * This only happens if sizeof(abi_long) < sizeof(long)
10280 * and the caller passed us a buffer holding an odd number
10281 * of abi_longs. If the host kernel is actually using the
10282 * extra 4 bytes then fail EINVAL; otherwise we can just
10283 * ignore them and only copy the interesting part.
10284 */
10285 int numcpus = sysconf(_SC_NPROCESSORS_CONF);
10286 if (numcpus > arg2 * 8) {
72eb7ea8 10287 return -TARGET_EINVAL;
be3bd286
PM
10288 }
10289 ret = arg2;
10290 }
10291
5fdefcf8 10292 if (host_to_target_cpu_mask(mask, mask_size, arg3, ret)) {
2852aafd 10293 return -TARGET_EFAULT;
5fdefcf8 10294 }
737de1d1
MF
10295 }
10296 }
72eb7ea8 10297 return ret;
737de1d1
MF
10298 case TARGET_NR_sched_setaffinity:
10299 {
10300 unsigned int mask_size;
10301 unsigned long *mask;
10302
10303 /*
10304 * sched_setaffinity needs multiples of ulong, so need to take
10305 * care of mismatches between target ulong and host ulong sizes.
10306 */
10307 if (arg2 & (sizeof(abi_ulong) - 1)) {
72eb7ea8 10308 return -TARGET_EINVAL;
737de1d1
MF
10309 }
10310 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
737de1d1 10311 mask = alloca(mask_size);
2e0a8713
ST
10312
10313 ret = target_to_host_cpu_mask(mask, mask_size, arg3, arg2);
10314 if (ret) {
72eb7ea8 10315 return ret;
737de1d1 10316 }
737de1d1 10317
72eb7ea8 10318 return get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
737de1d1 10319 }
b827c3ed
ST
10320 case TARGET_NR_getcpu:
10321 {
10322 unsigned cpu, node;
10323 ret = get_errno(sys_getcpu(arg1 ? &cpu : NULL,
10324 arg2 ? &node : NULL,
10325 NULL));
10326 if (is_error(ret)) {
259841c1 10327 return ret;
b827c3ed
ST
10328 }
10329 if (arg1 && put_user_u32(cpu, arg1)) {
2852aafd 10330 return -TARGET_EFAULT;
b827c3ed
ST
10331 }
10332 if (arg2 && put_user_u32(node, arg2)) {
2852aafd 10333 return -TARGET_EFAULT;
b827c3ed
ST
10334 }
10335 }
72eb7ea8 10336 return ret;
31e31b8a 10337 case TARGET_NR_sched_setparam:
5cd4393b 10338 {
53a5960a 10339 struct sched_param *target_schp;
5cd4393b 10340 struct sched_param schp;
53a5960a 10341
a1d5c5b2
TM
10342 if (arg2 == 0) {
10343 return -TARGET_EINVAL;
10344 }
579a97f7 10345 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
2852aafd 10346 return -TARGET_EFAULT;
5cd4393b 10347 schp.sched_priority = tswap32(target_schp->sched_priority);
53a5960a 10348 unlock_user_struct(target_schp, arg2, 0);
72eb7ea8 10349 return get_errno(sched_setparam(arg1, &schp));
5cd4393b 10350 }
31e31b8a 10351 case TARGET_NR_sched_getparam:
5cd4393b 10352 {
53a5960a 10353 struct sched_param *target_schp;
5cd4393b 10354 struct sched_param schp;
a1d5c5b2
TM
10355
10356 if (arg2 == 0) {
10357 return -TARGET_EINVAL;
10358 }
5cd4393b
FB
10359 ret = get_errno(sched_getparam(arg1, &schp));
10360 if (!is_error(ret)) {
579a97f7 10361 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
2852aafd 10362 return -TARGET_EFAULT;
5cd4393b 10363 target_schp->sched_priority = tswap32(schp.sched_priority);
53a5960a 10364 unlock_user_struct(target_schp, arg2, 1);
5cd4393b
FB
10365 }
10366 }
72eb7ea8 10367 return ret;
31e31b8a 10368 case TARGET_NR_sched_setscheduler:
5cd4393b 10369 {
53a5960a 10370 struct sched_param *target_schp;
5cd4393b 10371 struct sched_param schp;
a1d5c5b2
TM
10372 if (arg3 == 0) {
10373 return -TARGET_EINVAL;
10374 }
579a97f7 10375 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
2852aafd 10376 return -TARGET_EFAULT;
5cd4393b 10377 schp.sched_priority = tswap32(target_schp->sched_priority);
53a5960a 10378 unlock_user_struct(target_schp, arg3, 0);
72eb7ea8 10379 return get_errno(sched_setscheduler(arg1, arg2, &schp));
5cd4393b 10380 }
31e31b8a 10381 case TARGET_NR_sched_getscheduler:
72eb7ea8 10382 return get_errno(sched_getscheduler(arg1));
31e31b8a 10383 case TARGET_NR_sched_yield:
72eb7ea8 10384 return get_errno(sched_yield());
31e31b8a 10385 case TARGET_NR_sched_get_priority_max:
72eb7ea8 10386 return get_errno(sched_get_priority_max(arg1));
31e31b8a 10387 case TARGET_NR_sched_get_priority_min:
72eb7ea8 10388 return get_errno(sched_get_priority_min(arg1));
859e8a89 10389#ifdef TARGET_NR_sched_rr_get_interval
31e31b8a 10390 case TARGET_NR_sched_rr_get_interval:
5cd4393b 10391 {
5cd4393b
FB
10392 struct timespec ts;
10393 ret = get_errno(sched_rr_get_interval(arg1, &ts));
10394 if (!is_error(ret)) {
d4290c40 10395 ret = host_to_target_timespec(arg2, &ts);
5cd4393b
FB
10396 }
10397 }
72eb7ea8 10398 return ret;
859e8a89
AF
10399#endif
10400#if defined(TARGET_NR_nanosleep)
31e31b8a 10401 case TARGET_NR_nanosleep:
1b6b029e 10402 {
1b6b029e 10403 struct timespec req, rem;
53a5960a 10404 target_to_host_timespec(&req, arg1);
9e518226 10405 ret = get_errno(safe_nanosleep(&req, &rem));
53a5960a
PB
10406 if (is_error(ret) && arg2) {
10407 host_to_target_timespec(arg2, &rem);
1b6b029e
FB
10408 }
10409 }
72eb7ea8 10410 return ret;
859e8a89 10411#endif
31e31b8a 10412 case TARGET_NR_prctl:
1e6722f8
PM
10413 switch (arg1) {
10414 case PR_GET_PDEATHSIG:
10415 {
10416 int deathsig;
10417 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
10418 if (!is_error(ret) && arg2
10419 && put_user_ual(deathsig, arg2)) {
2852aafd 10420 return -TARGET_EFAULT;
e5574487 10421 }
72eb7ea8 10422 return ret;
1e6722f8 10423 }
db9526b1
PM
10424#ifdef PR_GET_NAME
10425 case PR_GET_NAME:
10426 {
10427 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
10428 if (!name) {
2852aafd 10429 return -TARGET_EFAULT;
db9526b1
PM
10430 }
10431 ret = get_errno(prctl(arg1, (unsigned long)name,
10432 arg3, arg4, arg5));
10433 unlock_user(name, arg2, 16);
72eb7ea8 10434 return ret;
db9526b1
PM
10435 }
10436 case PR_SET_NAME:
10437 {
10438 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
10439 if (!name) {
2852aafd 10440 return -TARGET_EFAULT;
db9526b1
PM
10441 }
10442 ret = get_errno(prctl(arg1, (unsigned long)name,
10443 arg3, arg4, arg5));
10444 unlock_user(name, arg2, 0);
72eb7ea8 10445 return ret;
db9526b1
PM
10446 }
10447#endif
5b702ffd
SM
10448#ifdef TARGET_MIPS
10449 case TARGET_PR_GET_FP_MODE:
64ea3d67
SM
10450 {
10451 CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
10452 ret = 0;
10453 if (env->CP0_Status & (1 << CP0St_FR)) {
10454 ret |= TARGET_PR_FP_MODE_FR;
10455 }
10456 if (env->CP0_Config5 & (1 << CP0C5_FRE)) {
10457 ret |= TARGET_PR_FP_MODE_FRE;
10458 }
10459 return ret;
10460 }
5b702ffd 10461 case TARGET_PR_SET_FP_MODE:
64ea3d67
SM
10462 {
10463 CPUMIPSState *env = ((CPUMIPSState *)cpu_env);
10464 bool old_fr = env->CP0_Status & (1 << CP0St_FR);
6456c510 10465 bool old_fre = env->CP0_Config5 & (1 << CP0C5_FRE);
64ea3d67
SM
10466 bool new_fr = arg2 & TARGET_PR_FP_MODE_FR;
10467 bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE;
10468
6456c510
SM
10469 const unsigned int known_bits = TARGET_PR_FP_MODE_FR |
10470 TARGET_PR_FP_MODE_FRE;
10471
10472 /* If nothing to change, return right away, successfully. */
10473 if (old_fr == new_fr && old_fre == new_fre) {
10474 return 0;
10475 }
10476 /* Check the value is valid */
10477 if (arg2 & ~known_bits) {
10478 return -TARGET_EOPNOTSUPP;
10479 }
10480 /* Setting FRE without FR is not supported. */
10481 if (new_fre && !new_fr) {
10482 return -TARGET_EOPNOTSUPP;
10483 }
64ea3d67
SM
10484 if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) {
10485 /* FR1 is not supported */
10486 return -TARGET_EOPNOTSUPP;
10487 }
10488 if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64))
10489 && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
10490 /* cannot set FR=0 */
10491 return -TARGET_EOPNOTSUPP;
10492 }
10493 if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) {
10494 /* Cannot set FRE=1 */
10495 return -TARGET_EOPNOTSUPP;
10496 }
10497
10498 int i;
10499 fpr_t *fpr = env->active_fpu.fpr;
10500 for (i = 0; i < 32 ; i += 2) {
10501 if (!old_fr && new_fr) {
10502 fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX];
10503 } else if (old_fr && !new_fr) {
10504 fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX];
10505 }
10506 }
10507
10508 if (new_fr) {
10509 env->CP0_Status |= (1 << CP0St_FR);
10510 env->hflags |= MIPS_HFLAG_F64;
10511 } else {
10512 env->CP0_Status &= ~(1 << CP0St_FR);
6456c510 10513 env->hflags &= ~MIPS_HFLAG_F64;
64ea3d67
SM
10514 }
10515 if (new_fre) {
10516 env->CP0_Config5 |= (1 << CP0C5_FRE);
10517 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
10518 env->hflags |= MIPS_HFLAG_FRE;
10519 }
10520 } else {
10521 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
6456c510 10522 env->hflags &= ~MIPS_HFLAG_FRE;
64ea3d67
SM
10523 }
10524
10525 return 0;
10526 }
5b702ffd 10527#endif /* MIPS */
85fc7167
RH
10528#ifdef TARGET_AARCH64
10529 case TARGET_PR_SVE_SET_VL:
adf92eab
RH
10530 /*
10531 * We cannot support either PR_SVE_SET_VL_ONEXEC or
10532 * PR_SVE_VL_INHERIT. Note the kernel definition
10533 * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
10534 * even though the current architectural maximum is VQ=16.
10535 */
85fc7167 10536 ret = -TARGET_EINVAL;
2fc0cc0e 10537 if (cpu_isar_feature(aa64_sve, env_archcpu(cpu_env))
adf92eab 10538 && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
85fc7167 10539 CPUARMState *env = cpu_env;
2fc0cc0e 10540 ARMCPU *cpu = env_archcpu(env);
adf92eab
RH
10541 uint32_t vq, old_vq;
10542
10543 old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
10544 vq = MAX(arg2 / 16, 1);
10545 vq = MIN(vq, cpu->sve_max_vq);
85fc7167
RH
10546
10547 if (vq < old_vq) {
10548 aarch64_sve_narrow_vq(env, vq);
10549 }
10550 env->vfp.zcr_el[1] = vq - 1;
a8a79c7a 10551 arm_rebuild_hflags(env);
85fc7167
RH
10552 ret = vq * 16;
10553 }
72eb7ea8 10554 return ret;
85fc7167
RH
10555 case TARGET_PR_SVE_GET_VL:
10556 ret = -TARGET_EINVAL;
cd208a1c 10557 {
2fc0cc0e 10558 ARMCPU *cpu = env_archcpu(cpu_env);
cd208a1c
RH
10559 if (cpu_isar_feature(aa64_sve, cpu)) {
10560 ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
10561 }
85fc7167 10562 }
72eb7ea8 10563 return ret;
bff63fbf
RH
10564 case TARGET_PR_PAC_RESET_KEYS:
10565 {
10566 CPUARMState *env = cpu_env;
2fc0cc0e 10567 ARMCPU *cpu = env_archcpu(env);
bff63fbf
RH
10568
10569 if (arg3 || arg4 || arg5) {
10570 return -TARGET_EINVAL;
10571 }
10572 if (cpu_isar_feature(aa64_pauth, cpu)) {
10573 int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY |
10574 TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY |
10575 TARGET_PR_PAC_APGAKEY);
51977e25
RH
10576 int ret = 0;
10577 Error *err = NULL;
10578
bff63fbf
RH
10579 if (arg2 == 0) {
10580 arg2 = all;
10581 } else if (arg2 & ~all) {
10582 return -TARGET_EINVAL;
10583 }
10584 if (arg2 & TARGET_PR_PAC_APIAKEY) {
108b3ba8 10585 ret |= qemu_guest_getrandom(&env->keys.apia,
51977e25 10586 sizeof(ARMPACKey), &err);
bff63fbf
RH
10587 }
10588 if (arg2 & TARGET_PR_PAC_APIBKEY) {
108b3ba8 10589 ret |= qemu_guest_getrandom(&env->keys.apib,
51977e25 10590 sizeof(ARMPACKey), &err);
bff63fbf
RH
10591 }
10592 if (arg2 & TARGET_PR_PAC_APDAKEY) {
108b3ba8 10593 ret |= qemu_guest_getrandom(&env->keys.apda,
51977e25 10594 sizeof(ARMPACKey), &err);
bff63fbf
RH
10595 }
10596 if (arg2 & TARGET_PR_PAC_APDBKEY) {
108b3ba8 10597 ret |= qemu_guest_getrandom(&env->keys.apdb,
51977e25 10598 sizeof(ARMPACKey), &err);
bff63fbf
RH
10599 }
10600 if (arg2 & TARGET_PR_PAC_APGAKEY) {
108b3ba8 10601 ret |= qemu_guest_getrandom(&env->keys.apga,
51977e25
RH
10602 sizeof(ARMPACKey), &err);
10603 }
10604 if (ret != 0) {
10605 /*
10606 * Some unknown failure in the crypto. The best
10607 * we can do is log it and fail the syscall.
10608 * The real syscall cannot fail this way.
10609 */
10610 qemu_log_mask(LOG_UNIMP,
10611 "PR_PAC_RESET_KEYS: Crypto failure: %s",
10612 error_get_pretty(err));
10613 error_free(err);
10614 return -TARGET_EIO;
bff63fbf
RH
10615 }
10616 return 0;
10617 }
10618 }
10619 return -TARGET_EINVAL;
85fc7167 10620#endif /* AARCH64 */
a8b154a6
JC
10621 case PR_GET_SECCOMP:
10622 case PR_SET_SECCOMP:
10623 /* Disable seccomp to prevent the target disabling syscalls we
10624 * need. */
72eb7ea8 10625 return -TARGET_EINVAL;
1e6722f8
PM
10626 default:
10627 /* Most prctl options have no pointer arguments */
72eb7ea8 10628 return get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
1e6722f8 10629 }
39b9aae1 10630 break;
d2fd1af7
FB
10631#ifdef TARGET_NR_arch_prctl
10632 case TARGET_NR_arch_prctl:
72eb7ea8 10633 return do_arch_prctl(cpu_env, arg1, arg2);
d2fd1af7 10634#endif
f2c7ba15
AJ
10635#ifdef TARGET_NR_pread64
10636 case TARGET_NR_pread64:
8bf8e9df 10637 if (regpairs_aligned(cpu_env, num)) {
ae017a5b
AG
10638 arg4 = arg5;
10639 arg5 = arg6;
10640 }
2bd3f899
PM
10641 if (arg2 == 0 && arg3 == 0) {
10642 /* Special-case NULL buffer and zero length, which should succeed */
10643 p = 0;
10644 } else {
10645 p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
10646 if (!p) {
10647 return -TARGET_EFAULT;
10648 }
10649 }
f2c7ba15
AJ
10650 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
10651 unlock_user(p, arg2, ret);
72eb7ea8 10652 return ret;
f2c7ba15 10653 case TARGET_NR_pwrite64:
8bf8e9df 10654 if (regpairs_aligned(cpu_env, num)) {
ae017a5b
AG
10655 arg4 = arg5;
10656 arg5 = arg6;
10657 }
2bd3f899
PM
10658 if (arg2 == 0 && arg3 == 0) {
10659 /* Special-case NULL buffer and zero length, which should succeed */
10660 p = 0;
10661 } else {
10662 p = lock_user(VERIFY_READ, arg2, arg3, 1);
10663 if (!p) {
10664 return -TARGET_EFAULT;
10665 }
10666 }
f2c7ba15
AJ
10667 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
10668 unlock_user(p, arg2, 0);
72eb7ea8 10669 return ret;
67867308 10670#endif
31e31b8a 10671 case TARGET_NR_getcwd:
579a97f7 10672 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
2852aafd 10673 return -TARGET_EFAULT;
53a5960a
PB
10674 ret = get_errno(sys_getcwd1(p, arg2));
10675 unlock_user(p, arg1, ret);
72eb7ea8 10676 return ret;
31e31b8a
FB
10677 case TARGET_NR_capget:
10678 case TARGET_NR_capset:
e0eb210e
PM
10679 {
10680 struct target_user_cap_header *target_header;
10681 struct target_user_cap_data *target_data = NULL;
10682 struct __user_cap_header_struct header;
10683 struct __user_cap_data_struct data[2];
10684 struct __user_cap_data_struct *dataptr = NULL;
10685 int i, target_datalen;
10686 int data_items = 1;
10687
10688 if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
2852aafd 10689 return -TARGET_EFAULT;
e0eb210e
PM
10690 }
10691 header.version = tswap32(target_header->version);
10692 header.pid = tswap32(target_header->pid);
10693
ec864874 10694 if (header.version != _LINUX_CAPABILITY_VERSION) {
e0eb210e
PM
10695 /* Version 2 and up takes pointer to two user_data structs */
10696 data_items = 2;
10697 }
10698
10699 target_datalen = sizeof(*target_data) * data_items;
10700
10701 if (arg2) {
10702 if (num == TARGET_NR_capget) {
10703 target_data = lock_user(VERIFY_WRITE, arg2, target_datalen, 0);
10704 } else {
10705 target_data = lock_user(VERIFY_READ, arg2, target_datalen, 1);
10706 }
10707 if (!target_data) {
10708 unlock_user_struct(target_header, arg1, 0);
2852aafd 10709 return -TARGET_EFAULT;
e0eb210e
PM
10710 }
10711
10712 if (num == TARGET_NR_capset) {
10713 for (i = 0; i < data_items; i++) {
10714 data[i].effective = tswap32(target_data[i].effective);
10715 data[i].permitted = tswap32(target_data[i].permitted);
10716 data[i].inheritable = tswap32(target_data[i].inheritable);
10717 }
10718 }
10719
10720 dataptr = data;
10721 }
10722
10723 if (num == TARGET_NR_capget) {
10724 ret = get_errno(capget(&header, dataptr));
10725 } else {
10726 ret = get_errno(capset(&header, dataptr));
10727 }
10728
10729 /* The kernel always updates version for both capget and capset */
10730 target_header->version = tswap32(header.version);
10731 unlock_user_struct(target_header, arg1, 1);
10732
10733 if (arg2) {
10734 if (num == TARGET_NR_capget) {
10735 for (i = 0; i < data_items; i++) {
10736 target_data[i].effective = tswap32(data[i].effective);
10737 target_data[i].permitted = tswap32(data[i].permitted);
10738 target_data[i].inheritable = tswap32(data[i].inheritable);
10739 }
10740 unlock_user(target_data, arg2, target_datalen);
10741 } else {
10742 unlock_user(target_data, arg2, 0);
10743 }
10744 }
72eb7ea8 10745 return ret;
e0eb210e 10746 }
31e31b8a 10747 case TARGET_NR_sigaltstack:
72eb7ea8
RH
10748 return do_sigaltstack(arg1, arg2,
10749 get_sp_from_cpustate((CPUArchState *)cpu_env));
a8fd1aba
PM
10750
10751#ifdef CONFIG_SENDFILE
4f7f8924 10752#ifdef TARGET_NR_sendfile
a8fd1aba
PM
10753 case TARGET_NR_sendfile:
10754 {
10755 off_t *offp = NULL;
10756 off_t off;
10757 if (arg3) {
10758 ret = get_user_sal(off, arg3);
10759 if (is_error(ret)) {
72eb7ea8 10760 return ret;
a8fd1aba
PM
10761 }
10762 offp = &off;
10763 }
10764 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
10765 if (!is_error(ret) && arg3) {
10766 abi_long ret2 = put_user_sal(off, arg3);
10767 if (is_error(ret2)) {
10768 ret = ret2;
10769 }
10770 }
72eb7ea8 10771 return ret;
a8fd1aba 10772 }
4f7f8924 10773#endif
a8fd1aba
PM
10774#ifdef TARGET_NR_sendfile64
10775 case TARGET_NR_sendfile64:
10776 {
10777 off_t *offp = NULL;
10778 off_t off;
10779 if (arg3) {
10780 ret = get_user_s64(off, arg3);
10781 if (is_error(ret)) {
72eb7ea8 10782 return ret;
a8fd1aba
PM
10783 }
10784 offp = &off;
10785 }
10786 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
10787 if (!is_error(ret) && arg3) {
10788 abi_long ret2 = put_user_s64(off, arg3);
10789 if (is_error(ret2)) {
10790 ret = ret2;
10791 }
10792 }
72eb7ea8 10793 return ret;
a8fd1aba
PM
10794 }
10795#endif
ebc05488 10796#endif
048f6b4d 10797#ifdef TARGET_NR_vfork
31e31b8a 10798 case TARGET_NR_vfork:
72eb7ea8
RH
10799 return get_errno(do_fork(cpu_env,
10800 CLONE_VFORK | CLONE_VM | TARGET_SIGCHLD,
10801 0, 0, 0, 0));
048f6b4d 10802#endif
ebc05488 10803#ifdef TARGET_NR_ugetrlimit
31e31b8a 10804 case TARGET_NR_ugetrlimit:
728584be
FB
10805 {
10806 struct rlimit rlim;
e22b7015
WT
10807 int resource = target_to_host_resource(arg1);
10808 ret = get_errno(getrlimit(resource, &rlim));
728584be 10809 if (!is_error(ret)) {
53a5960a 10810 struct target_rlimit *target_rlim;
579a97f7 10811 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
2852aafd 10812 return -TARGET_EFAULT;
81bbe906
TY
10813 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
10814 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
53a5960a 10815 unlock_user_struct(target_rlim, arg2, 1);
728584be 10816 }
72eb7ea8 10817 return ret;
728584be 10818 }
ebc05488 10819#endif
a315a145 10820#ifdef TARGET_NR_truncate64
31e31b8a 10821 case TARGET_NR_truncate64:
579a97f7 10822 if (!(p = lock_user_string(arg1)))
2852aafd 10823 return -TARGET_EFAULT;
53a5960a
PB
10824 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
10825 unlock_user(p, arg1, 0);
72eb7ea8 10826 return ret;
a315a145
FB
10827#endif
10828#ifdef TARGET_NR_ftruncate64
31e31b8a 10829 case TARGET_NR_ftruncate64:
72eb7ea8 10830 return target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
a315a145
FB
10831#endif
10832#ifdef TARGET_NR_stat64
31e31b8a 10833 case TARGET_NR_stat64:
2852aafd
RH
10834 if (!(p = lock_user_string(arg1))) {
10835 return -TARGET_EFAULT;
10836 }
53a5960a
PB
10837 ret = get_errno(stat(path(p), &st));
10838 unlock_user(p, arg1, 0);
6a24a778
AZ
10839 if (!is_error(ret))
10840 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 10841 return ret;
a315a145
FB
10842#endif
10843#ifdef TARGET_NR_lstat64
31e31b8a 10844 case TARGET_NR_lstat64:
2852aafd
RH
10845 if (!(p = lock_user_string(arg1))) {
10846 return -TARGET_EFAULT;
10847 }
53a5960a
PB
10848 ret = get_errno(lstat(path(p), &st));
10849 unlock_user(p, arg1, 0);
6a24a778
AZ
10850 if (!is_error(ret))
10851 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 10852 return ret;
a315a145
FB
10853#endif
10854#ifdef TARGET_NR_fstat64
31e31b8a 10855 case TARGET_NR_fstat64:
6a24a778
AZ
10856 ret = get_errno(fstat(arg1, &st));
10857 if (!is_error(ret))
10858 ret = host_to_target_stat64(cpu_env, arg2, &st);
72eb7ea8 10859 return ret;
ce4defa0 10860#endif
c0d472b1 10861#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
9d33b76b 10862#ifdef TARGET_NR_fstatat64
6a24a778 10863 case TARGET_NR_fstatat64:
9d33b76b
AJ
10864#endif
10865#ifdef TARGET_NR_newfstatat
10866 case TARGET_NR_newfstatat:
10867#endif
2852aafd
RH
10868 if (!(p = lock_user_string(arg2))) {
10869 return -TARGET_EFAULT;
10870 }
c0d472b1 10871 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
2852aafd 10872 unlock_user(p, arg2, 0);
6a24a778
AZ
10873 if (!is_error(ret))
10874 ret = host_to_target_stat64(cpu_env, arg3, &st);
72eb7ea8 10875 return ret;
a315a145 10876#endif
efa92184
AR
10877#if defined(TARGET_NR_statx)
10878 case TARGET_NR_statx:
10879 {
10880 struct target_statx *target_stx;
10881 int dirfd = arg1;
10882 int flags = arg3;
10883
10884 p = lock_user_string(arg2);
10885 if (p == NULL) {
10886 return -TARGET_EFAULT;
10887 }
10888#if defined(__NR_statx)
10889 {
10890 /*
10891 * It is assumed that struct statx is architecture independent.
10892 */
10893 struct target_statx host_stx;
10894 int mask = arg4;
10895
10896 ret = get_errno(sys_statx(dirfd, p, flags, mask, &host_stx));
10897 if (!is_error(ret)) {
10898 if (host_to_target_statx(&host_stx, arg5) != 0) {
10899 unlock_user(p, arg2, 0);
10900 return -TARGET_EFAULT;
10901 }
10902 }
10903
10904 if (ret != -TARGET_ENOSYS) {
10905 unlock_user(p, arg2, 0);
10906 return ret;
10907 }
10908 }
10909#endif
10910 ret = get_errno(fstatat(dirfd, path(p), &st, flags));
10911 unlock_user(p, arg2, 0);
10912
10913 if (!is_error(ret)) {
10914 if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
10915 return -TARGET_EFAULT;
10916 }
10917 memset(target_stx, 0, sizeof(*target_stx));
10918 __put_user(major(st.st_dev), &target_stx->stx_dev_major);
10919 __put_user(minor(st.st_dev), &target_stx->stx_dev_minor);
10920 __put_user(st.st_ino, &target_stx->stx_ino);
10921 __put_user(st.st_mode, &target_stx->stx_mode);
10922 __put_user(st.st_uid, &target_stx->stx_uid);
10923 __put_user(st.st_gid, &target_stx->stx_gid);
10924 __put_user(st.st_nlink, &target_stx->stx_nlink);
10925 __put_user(major(st.st_rdev), &target_stx->stx_rdev_major);
10926 __put_user(minor(st.st_rdev), &target_stx->stx_rdev_minor);
10927 __put_user(st.st_size, &target_stx->stx_size);
10928 __put_user(st.st_blksize, &target_stx->stx_blksize);
10929 __put_user(st.st_blocks, &target_stx->stx_blocks);
10930 __put_user(st.st_atime, &target_stx->stx_atime.tv_sec);
10931 __put_user(st.st_mtime, &target_stx->stx_mtime.tv_sec);
10932 __put_user(st.st_ctime, &target_stx->stx_ctime.tv_sec);
10933 unlock_user_struct(target_stx, arg5, 1);
10934 }
10935 }
10936 return ret;
10937#endif
704eff6c 10938#ifdef TARGET_NR_lchown
67867308 10939 case TARGET_NR_lchown:
579a97f7 10940 if (!(p = lock_user_string(arg1)))
2852aafd 10941 return -TARGET_EFAULT;
53a5960a
PB
10942 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
10943 unlock_user(p, arg1, 0);
72eb7ea8 10944 return ret;
704eff6c 10945#endif
0c866a7e 10946#ifdef TARGET_NR_getuid
67867308 10947 case TARGET_NR_getuid:
72eb7ea8 10948 return get_errno(high2lowuid(getuid()));
0c866a7e
RV
10949#endif
10950#ifdef TARGET_NR_getgid
67867308 10951 case TARGET_NR_getgid:
72eb7ea8 10952 return get_errno(high2lowgid(getgid()));
0c866a7e
RV
10953#endif
10954#ifdef TARGET_NR_geteuid
67867308 10955 case TARGET_NR_geteuid:
72eb7ea8 10956 return get_errno(high2lowuid(geteuid()));
0c866a7e
RV
10957#endif
10958#ifdef TARGET_NR_getegid
67867308 10959 case TARGET_NR_getegid:
72eb7ea8 10960 return get_errno(high2lowgid(getegid()));
0c866a7e 10961#endif
67867308 10962 case TARGET_NR_setreuid:
72eb7ea8 10963 return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
67867308 10964 case TARGET_NR_setregid:
72eb7ea8 10965 return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
67867308
FB
10966 case TARGET_NR_getgroups:
10967 {
10968 int gidsetsize = arg1;
0c866a7e 10969 target_id *target_grouplist;
67867308
FB
10970 gid_t *grouplist;
10971 int i;
10972
10973 grouplist = alloca(gidsetsize * sizeof(gid_t));
10974 ret = get_errno(getgroups(gidsetsize, grouplist));
cb3bc233 10975 if (gidsetsize == 0)
72eb7ea8 10976 return ret;
67867308 10977 if (!is_error(ret)) {
03903ffc 10978 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
579a97f7 10979 if (!target_grouplist)
2852aafd 10980 return -TARGET_EFAULT;
a2155fcc 10981 for(i = 0;i < ret; i++)
0c866a7e 10982 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
03903ffc 10983 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
67867308
FB
10984 }
10985 }
72eb7ea8 10986 return ret;
67867308
FB
10987 case TARGET_NR_setgroups:
10988 {
10989 int gidsetsize = arg1;
0c866a7e 10990 target_id *target_grouplist;
f2b79ce9 10991 gid_t *grouplist = NULL;
67867308 10992 int i;
f2b79ce9
DA
10993 if (gidsetsize) {
10994 grouplist = alloca(gidsetsize * sizeof(gid_t));
03903ffc 10995 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
f2b79ce9 10996 if (!target_grouplist) {
259841c1 10997 return -TARGET_EFAULT;
f2b79ce9
DA
10998 }
10999 for (i = 0; i < gidsetsize; i++) {
11000 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
11001 }
11002 unlock_user(target_grouplist, arg2, 0);
579a97f7 11003 }
72eb7ea8 11004 return get_errno(setgroups(gidsetsize, grouplist));
67867308 11005 }
67867308 11006 case TARGET_NR_fchown:
72eb7ea8 11007 return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
c0d472b1 11008#if defined(TARGET_NR_fchownat)
ccfa72b7 11009 case TARGET_NR_fchownat:
579a97f7 11010 if (!(p = lock_user_string(arg2)))
2852aafd 11011 return -TARGET_EFAULT;
c0d472b1
PM
11012 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
11013 low2highgid(arg4), arg5));
579a97f7 11014 unlock_user(p, arg2, 0);
72eb7ea8 11015 return ret;
ccfa72b7 11016#endif
67867308
FB
11017#ifdef TARGET_NR_setresuid
11018 case TARGET_NR_setresuid:
72eb7ea8
RH
11019 return get_errno(sys_setresuid(low2highuid(arg1),
11020 low2highuid(arg2),
11021 low2highuid(arg3)));
67867308
FB
11022#endif
11023#ifdef TARGET_NR_getresuid
11024 case TARGET_NR_getresuid:
11025 {
53a5960a 11026 uid_t ruid, euid, suid;
67867308
FB
11027 ret = get_errno(getresuid(&ruid, &euid, &suid));
11028 if (!is_error(ret)) {
76ca310a
PM
11029 if (put_user_id(high2lowuid(ruid), arg1)
11030 || put_user_id(high2lowuid(euid), arg2)
11031 || put_user_id(high2lowuid(suid), arg3))
2852aafd 11032 return -TARGET_EFAULT;
67867308
FB
11033 }
11034 }
72eb7ea8 11035 return ret;
67867308
FB
11036#endif
11037#ifdef TARGET_NR_getresgid
11038 case TARGET_NR_setresgid:
72eb7ea8
RH
11039 return get_errno(sys_setresgid(low2highgid(arg1),
11040 low2highgid(arg2),
11041 low2highgid(arg3)));
67867308
FB
11042#endif
11043#ifdef TARGET_NR_getresgid
11044 case TARGET_NR_getresgid:
11045 {
53a5960a 11046 gid_t rgid, egid, sgid;
67867308
FB
11047 ret = get_errno(getresgid(&rgid, &egid, &sgid));
11048 if (!is_error(ret)) {
76ca310a
PM
11049 if (put_user_id(high2lowgid(rgid), arg1)
11050 || put_user_id(high2lowgid(egid), arg2)
11051 || put_user_id(high2lowgid(sgid), arg3))
2852aafd 11052 return -TARGET_EFAULT;
67867308
FB
11053 }
11054 }
72eb7ea8 11055 return ret;
67867308 11056#endif
704eff6c 11057#ifdef TARGET_NR_chown
67867308 11058 case TARGET_NR_chown:
579a97f7 11059 if (!(p = lock_user_string(arg1)))
2852aafd 11060 return -TARGET_EFAULT;
53a5960a
PB
11061 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
11062 unlock_user(p, arg1, 0);
72eb7ea8 11063 return ret;
704eff6c 11064#endif
67867308 11065 case TARGET_NR_setuid:
72eb7ea8 11066 return get_errno(sys_setuid(low2highuid(arg1)));
67867308 11067 case TARGET_NR_setgid:
72eb7ea8 11068 return get_errno(sys_setgid(low2highgid(arg1)));
67867308 11069 case TARGET_NR_setfsuid:
72eb7ea8 11070 return get_errno(setfsuid(arg1));
67867308 11071 case TARGET_NR_setfsgid:
72eb7ea8 11072 return get_errno(setfsgid(arg1));
67867308 11073
a315a145 11074#ifdef TARGET_NR_lchown32
31e31b8a 11075 case TARGET_NR_lchown32:
579a97f7 11076 if (!(p = lock_user_string(arg1)))
2852aafd 11077 return -TARGET_EFAULT;
53a5960a
PB
11078 ret = get_errno(lchown(p, arg2, arg3));
11079 unlock_user(p, arg1, 0);
72eb7ea8 11080 return ret;
a315a145
FB
11081#endif
11082#ifdef TARGET_NR_getuid32
31e31b8a 11083 case TARGET_NR_getuid32:
72eb7ea8 11084 return get_errno(getuid());
a315a145 11085#endif
64b4d28c
AJ
11086
11087#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
11088 /* Alpha specific */
11089 case TARGET_NR_getxuid:
ba0e276d
RH
11090 {
11091 uid_t euid;
11092 euid=geteuid();
11093 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
11094 }
72eb7ea8 11095 return get_errno(getuid());
64b4d28c
AJ
11096#endif
11097#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
11098 /* Alpha specific */
11099 case TARGET_NR_getxgid:
ba0e276d
RH
11100 {
11101 uid_t egid;
11102 egid=getegid();
11103 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
11104 }
72eb7ea8 11105 return get_errno(getgid());
64b4d28c 11106#endif
ba0e276d
RH
11107#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
11108 /* Alpha specific */
11109 case TARGET_NR_osf_getsysinfo:
11110 ret = -TARGET_EOPNOTSUPP;
11111 switch (arg1) {
11112 case TARGET_GSI_IEEE_FP_CONTROL:
11113 {
21ba8564
RH
11114 uint64_t fpcr = cpu_alpha_load_fpcr(cpu_env);
11115 uint64_t swcr = ((CPUAlphaState *)cpu_env)->swcr;
11116
11117 swcr &= ~SWCR_STATUS_MASK;
11118 swcr |= (fpcr >> 35) & SWCR_STATUS_MASK;
ba0e276d
RH
11119
11120 if (put_user_u64 (swcr, arg2))
2852aafd 11121 return -TARGET_EFAULT;
ba0e276d
RH
11122 ret = 0;
11123 }
11124 break;
11125
11126 /* case GSI_IEEE_STATE_AT_SIGNAL:
11127 -- Not implemented in linux kernel.
11128 case GSI_UACPROC:
11129 -- Retrieves current unaligned access state; not much used.
11130 case GSI_PROC_TYPE:
11131 -- Retrieves implver information; surely not used.
11132 case GSI_GET_HWRPB:
11133 -- Grabs a copy of the HWRPB; surely not used.
11134 */
11135 }
72eb7ea8 11136 return ret;
ba0e276d
RH
11137#endif
11138#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
11139 /* Alpha specific */
11140 case TARGET_NR_osf_setsysinfo:
11141 ret = -TARGET_EOPNOTSUPP;
11142 switch (arg1) {
11143 case TARGET_SSI_IEEE_FP_CONTROL:
ba0e276d 11144 {
21ba8564 11145 uint64_t swcr, fpcr;
ba0e276d 11146
6e06d515 11147 if (get_user_u64 (swcr, arg2)) {
2852aafd 11148 return -TARGET_EFAULT;
6e06d515 11149 }
ba0e276d 11150
21ba8564
RH
11151 /*
11152 * The kernel calls swcr_update_status to update the
11153 * status bits from the fpcr at every point that it
11154 * could be queried. Therefore, we store the status
11155 * bits only in FPCR.
11156 */
11157 ((CPUAlphaState *)cpu_env)->swcr
11158 = swcr & (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK);
11159
11160 fpcr = cpu_alpha_load_fpcr(cpu_env);
11161 fpcr &= ((uint64_t)FPCR_DYN_MASK << 32);
11162 fpcr |= alpha_ieee_swcr_to_fpcr(swcr);
6e06d515 11163 cpu_alpha_store_fpcr(cpu_env, fpcr);
ba0e276d 11164 ret = 0;
6e06d515
RH
11165 }
11166 break;
11167
11168 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
11169 {
21ba8564 11170 uint64_t exc, fpcr, fex;
6e06d515
RH
11171
11172 if (get_user_u64(exc, arg2)) {
2852aafd 11173 return -TARGET_EFAULT;
6e06d515 11174 }
21ba8564
RH
11175 exc &= SWCR_STATUS_MASK;
11176 fpcr = cpu_alpha_load_fpcr(cpu_env);
ba0e276d 11177
21ba8564
RH
11178 /* Old exceptions are not signaled. */
11179 fex = alpha_ieee_fpcr_to_swcr(fpcr);
11180 fex = exc & ~fex;
11181 fex >>= SWCR_STATUS_TO_EXCSUM_SHIFT;
11182 fex &= ((CPUArchState *)cpu_env)->swcr;
6e06d515 11183
21ba8564
RH
11184 /* Update the hardware fpcr. */
11185 fpcr |= alpha_ieee_swcr_to_fpcr(exc);
6e06d515 11186 cpu_alpha_store_fpcr(cpu_env, fpcr);
6e06d515 11187
21ba8564
RH
11188 if (fex) {
11189 int si_code = TARGET_FPE_FLTUNK;
6e06d515 11190 target_siginfo_t info;
21ba8564
RH
11191
11192 if (fex & SWCR_TRAP_ENABLE_DNO) {
11193 si_code = TARGET_FPE_FLTUND;
11194 }
11195 if (fex & SWCR_TRAP_ENABLE_INE) {
11196 si_code = TARGET_FPE_FLTRES;
11197 }
11198 if (fex & SWCR_TRAP_ENABLE_UNF) {
11199 si_code = TARGET_FPE_FLTUND;
11200 }
11201 if (fex & SWCR_TRAP_ENABLE_OVF) {
11202 si_code = TARGET_FPE_FLTOVF;
11203 }
11204 if (fex & SWCR_TRAP_ENABLE_DZE) {
11205 si_code = TARGET_FPE_FLTDIV;
11206 }
11207 if (fex & SWCR_TRAP_ENABLE_INV) {
11208 si_code = TARGET_FPE_FLTINV;
11209 }
11210
6e06d515
RH
11211 info.si_signo = SIGFPE;
11212 info.si_errno = 0;
11213 info.si_code = si_code;
11214 info._sifields._sigfault._addr
11215 = ((CPUArchState *)cpu_env)->pc;
9d2803f7
PM
11216 queue_signal((CPUArchState *)cpu_env, info.si_signo,
11217 QEMU_SI_FAULT, &info);
ba0e276d 11218 }
21ba8564 11219 ret = 0;
ba0e276d
RH
11220 }
11221 break;
11222
11223 /* case SSI_NVPAIRS:
11224 -- Used with SSIN_UACPROC to enable unaligned accesses.
11225 case SSI_IEEE_STATE_AT_SIGNAL:
11226 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
11227 -- Not implemented in linux kernel
11228 */
11229 }
72eb7ea8 11230 return ret;
ba0e276d
RH
11231#endif
11232#ifdef TARGET_NR_osf_sigprocmask
11233 /* Alpha specific. */
11234 case TARGET_NR_osf_sigprocmask:
11235 {
11236 abi_ulong mask;
bc088ba1 11237 int how;
ba0e276d
RH
11238 sigset_t set, oldset;
11239
11240 switch(arg1) {
11241 case TARGET_SIG_BLOCK:
11242 how = SIG_BLOCK;
11243 break;
11244 case TARGET_SIG_UNBLOCK:
11245 how = SIG_UNBLOCK;
11246 break;
11247 case TARGET_SIG_SETMASK:
11248 how = SIG_SETMASK;
11249 break;
11250 default:
259841c1 11251 return -TARGET_EINVAL;
ba0e276d
RH
11252 }
11253 mask = arg2;
11254 target_to_host_old_sigset(&set, &mask);
3d3efba0
PM
11255 ret = do_sigprocmask(how, &set, &oldset);
11256 if (!ret) {
11257 host_to_target_old_sigset(&mask, &oldset);
11258 ret = mask;
11259 }
ba0e276d 11260 }
72eb7ea8 11261 return ret;
ba0e276d 11262#endif
64b4d28c 11263
a315a145 11264#ifdef TARGET_NR_getgid32
31e31b8a 11265 case TARGET_NR_getgid32:
72eb7ea8 11266 return get_errno(getgid());
a315a145
FB
11267#endif
11268#ifdef TARGET_NR_geteuid32
31e31b8a 11269 case TARGET_NR_geteuid32:
72eb7ea8 11270 return get_errno(geteuid());
a315a145
FB
11271#endif
11272#ifdef TARGET_NR_getegid32
31e31b8a 11273 case TARGET_NR_getegid32:
72eb7ea8 11274 return get_errno(getegid());
a315a145
FB
11275#endif
11276#ifdef TARGET_NR_setreuid32
31e31b8a 11277 case TARGET_NR_setreuid32:
72eb7ea8 11278 return get_errno(setreuid(arg1, arg2));
a315a145
FB
11279#endif
11280#ifdef TARGET_NR_setregid32
31e31b8a 11281 case TARGET_NR_setregid32:
72eb7ea8 11282 return get_errno(setregid(arg1, arg2));
a315a145
FB
11283#endif
11284#ifdef TARGET_NR_getgroups32
31e31b8a 11285 case TARGET_NR_getgroups32:
99c475ab
FB
11286 {
11287 int gidsetsize = arg1;
53a5960a 11288 uint32_t *target_grouplist;
99c475ab
FB
11289 gid_t *grouplist;
11290 int i;
11291
11292 grouplist = alloca(gidsetsize * sizeof(gid_t));
11293 ret = get_errno(getgroups(gidsetsize, grouplist));
cb3bc233 11294 if (gidsetsize == 0)
72eb7ea8 11295 return ret;
99c475ab 11296 if (!is_error(ret)) {
579a97f7
FB
11297 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
11298 if (!target_grouplist) {
259841c1 11299 return -TARGET_EFAULT;
579a97f7 11300 }
a2155fcc 11301 for(i = 0;i < ret; i++)
53a5960a
PB
11302 target_grouplist[i] = tswap32(grouplist[i]);
11303 unlock_user(target_grouplist, arg2, gidsetsize * 4);
99c475ab
FB
11304 }
11305 }
72eb7ea8 11306 return ret;
a315a145
FB
11307#endif
11308#ifdef TARGET_NR_setgroups32
31e31b8a 11309 case TARGET_NR_setgroups32:
99c475ab
FB
11310 {
11311 int gidsetsize = arg1;
53a5960a 11312 uint32_t *target_grouplist;
99c475ab
FB
11313 gid_t *grouplist;
11314 int i;
3b46e624 11315
99c475ab 11316 grouplist = alloca(gidsetsize * sizeof(gid_t));
579a97f7
FB
11317 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
11318 if (!target_grouplist) {
259841c1 11319 return -TARGET_EFAULT;
579a97f7 11320 }
99c475ab 11321 for(i = 0;i < gidsetsize; i++)
53a5960a
PB
11322 grouplist[i] = tswap32(target_grouplist[i]);
11323 unlock_user(target_grouplist, arg2, 0);
72eb7ea8 11324 return get_errno(setgroups(gidsetsize, grouplist));
99c475ab 11325 }
a315a145
FB
11326#endif
11327#ifdef TARGET_NR_fchown32
31e31b8a 11328 case TARGET_NR_fchown32:
72eb7ea8 11329 return get_errno(fchown(arg1, arg2, arg3));
a315a145
FB
11330#endif
11331#ifdef TARGET_NR_setresuid32
31e31b8a 11332 case TARGET_NR_setresuid32:
72eb7ea8 11333 return get_errno(sys_setresuid(arg1, arg2, arg3));
a315a145
FB
11334#endif
11335#ifdef TARGET_NR_getresuid32
31e31b8a 11336 case TARGET_NR_getresuid32:
b03c60f3 11337 {
53a5960a 11338 uid_t ruid, euid, suid;
b03c60f3
FB
11339 ret = get_errno(getresuid(&ruid, &euid, &suid));
11340 if (!is_error(ret)) {
2f619698
FB
11341 if (put_user_u32(ruid, arg1)
11342 || put_user_u32(euid, arg2)
11343 || put_user_u32(suid, arg3))
2852aafd 11344 return -TARGET_EFAULT;
b03c60f3
FB
11345 }
11346 }
72eb7ea8 11347 return ret;
a315a145
FB
11348#endif
11349#ifdef TARGET_NR_setresgid32
31e31b8a 11350 case TARGET_NR_setresgid32:
72eb7ea8 11351 return get_errno(sys_setresgid(arg1, arg2, arg3));
a315a145
FB
11352#endif
11353#ifdef TARGET_NR_getresgid32
31e31b8a 11354 case TARGET_NR_getresgid32:
b03c60f3 11355 {
53a5960a 11356 gid_t rgid, egid, sgid;
b03c60f3
FB
11357 ret = get_errno(getresgid(&rgid, &egid, &sgid));
11358 if (!is_error(ret)) {
2f619698
FB
11359 if (put_user_u32(rgid, arg1)
11360 || put_user_u32(egid, arg2)
11361 || put_user_u32(sgid, arg3))
2852aafd 11362 return -TARGET_EFAULT;
b03c60f3
FB
11363 }
11364 }
72eb7ea8 11365 return ret;
a315a145
FB
11366#endif
11367#ifdef TARGET_NR_chown32
31e31b8a 11368 case TARGET_NR_chown32:
579a97f7 11369 if (!(p = lock_user_string(arg1)))
2852aafd 11370 return -TARGET_EFAULT;
53a5960a
PB
11371 ret = get_errno(chown(p, arg2, arg3));
11372 unlock_user(p, arg1, 0);
72eb7ea8 11373 return ret;
a315a145
FB
11374#endif
11375#ifdef TARGET_NR_setuid32
31e31b8a 11376 case TARGET_NR_setuid32:
72eb7ea8 11377 return get_errno(sys_setuid(arg1));
a315a145
FB
11378#endif
11379#ifdef TARGET_NR_setgid32
31e31b8a 11380 case TARGET_NR_setgid32:
72eb7ea8 11381 return get_errno(sys_setgid(arg1));
a315a145
FB
11382#endif
11383#ifdef TARGET_NR_setfsuid32
31e31b8a 11384 case TARGET_NR_setfsuid32:
72eb7ea8 11385 return get_errno(setfsuid(arg1));
a315a145
FB
11386#endif
11387#ifdef TARGET_NR_setfsgid32
31e31b8a 11388 case TARGET_NR_setfsgid32:
72eb7ea8 11389 return get_errno(setfsgid(arg1));
a315a145 11390#endif
ffa65c3b 11391#ifdef TARGET_NR_mincore
31e31b8a 11392 case TARGET_NR_mincore:
04bb9ace 11393 {
259841c1 11394 void *a = lock_user(VERIFY_READ, arg1, arg2, 0);
98a3331a 11395 if (!a) {
259841c1 11396 return -TARGET_ENOMEM;
98a3331a 11397 }
98a3331a
FSM
11398 p = lock_user_string(arg3);
11399 if (!p) {
259841c1
RH
11400 ret = -TARGET_EFAULT;
11401 } else {
11402 ret = get_errno(mincore(a, arg2, p));
11403 unlock_user(p, arg3, ret);
98a3331a 11404 }
04bb9ace
AJ
11405 unlock_user(a, arg1, 0);
11406 }
72eb7ea8 11407 return ret;
ffa65c3b 11408#endif
408321b6
AJ
11409#ifdef TARGET_NR_arm_fadvise64_64
11410 case TARGET_NR_arm_fadvise64_64:
e0156a9d
PM
11411 /* arm_fadvise64_64 looks like fadvise64_64 but
11412 * with different argument order: fd, advice, offset, len
11413 * rather than the usual fd, offset, len, advice.
11414 * Note that offset and len are both 64-bit so appear as
11415 * pairs of 32-bit registers.
11416 */
11417 ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
11418 target_offset64(arg5, arg6), arg2);
72eb7ea8 11419 return -host_to_target_errno(ret);
408321b6 11420#endif
badd3cd8
PM
11421
11422#if TARGET_ABI_BITS == 32
11423
11424#ifdef TARGET_NR_fadvise64_64
11425 case TARGET_NR_fadvise64_64:
64a563dd 11426#if defined(TARGET_PPC) || defined(TARGET_XTENSA)
43046b5a
LV
11427 /* 6 args: fd, advice, offset (high, low), len (high, low) */
11428 ret = arg2;
11429 arg2 = arg3;
11430 arg3 = arg4;
11431 arg4 = arg5;
11432 arg5 = arg6;
11433 arg6 = ret;
11434#else
badd3cd8 11435 /* 6 args: fd, offset (high, low), len (high, low), advice */
8bf8e9df 11436 if (regpairs_aligned(cpu_env, num)) {
badd3cd8
PM
11437 /* offset is in (3,4), len in (5,6) and advice in 7 */
11438 arg2 = arg3;
11439 arg3 = arg4;
11440 arg4 = arg5;
11441 arg5 = arg6;
11442 arg6 = arg7;
11443 }
43046b5a 11444#endif
72eb7ea8
RH
11445 ret = posix_fadvise(arg1, target_offset64(arg2, arg3),
11446 target_offset64(arg4, arg5), arg6);
11447 return -host_to_target_errno(ret);
badd3cd8
PM
11448#endif
11449
11450#ifdef TARGET_NR_fadvise64
11451 case TARGET_NR_fadvise64:
11452 /* 5 args: fd, offset (high, low), len, advice */
8bf8e9df 11453 if (regpairs_aligned(cpu_env, num)) {
badd3cd8
PM
11454 /* offset is in (3,4), len in 5 and advice in 6 */
11455 arg2 = arg3;
11456 arg3 = arg4;
11457 arg4 = arg5;
11458 arg5 = arg6;
11459 }
72eb7ea8
RH
11460 ret = posix_fadvise(arg1, target_offset64(arg2, arg3), arg4, arg5);
11461 return -host_to_target_errno(ret);
408321b6 11462#endif
badd3cd8
PM
11463
11464#else /* not a 32-bit ABI */
e0156a9d 11465#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64)
408321b6
AJ
11466#ifdef TARGET_NR_fadvise64_64
11467 case TARGET_NR_fadvise64_64:
11468#endif
e72d2cc7
UH
11469#ifdef TARGET_NR_fadvise64
11470 case TARGET_NR_fadvise64:
11471#endif
11472#ifdef TARGET_S390X
11473 switch (arg4) {
11474 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
11475 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
11476 case 6: arg4 = POSIX_FADV_DONTNEED; break;
11477 case 7: arg4 = POSIX_FADV_NOREUSE; break;
11478 default: break;
11479 }
11480#endif
72eb7ea8 11481 return -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
408321b6 11482#endif
badd3cd8
PM
11483#endif /* end of 64-bit ABI fadvise handling */
11484
ffa65c3b 11485#ifdef TARGET_NR_madvise
31e31b8a 11486 case TARGET_NR_madvise:
24836689 11487 /* A straight passthrough may not be safe because qemu sometimes
d2d6b857 11488 turns private file-backed mappings into anonymous mappings.
24836689
PB
11489 This will break MADV_DONTNEED.
11490 This is a hint, so ignoring and returning success is ok. */
72eb7ea8 11491 return 0;
ffa65c3b 11492#endif
bbf5f2a1 11493#ifdef TARGET_NR_fcntl64
31e31b8a 11494 case TARGET_NR_fcntl64:
77e4672d 11495 {
bbf5f2a1
AB
11496 int cmd;
11497 struct flock64 fl;
213d3e9e
PM
11498 from_flock64_fn *copyfrom = copy_from_user_flock64;
11499 to_flock64_fn *copyto = copy_to_user_flock64;
11500
ce4defa0 11501#ifdef TARGET_ARM
7f254c5c
LV
11502 if (!((CPUARMState *)cpu_env)->eabi) {
11503 copyfrom = copy_from_user_oabi_flock64;
11504 copyto = copy_to_user_oabi_flock64;
213d3e9e 11505 }
ce4defa0 11506#endif
77e4672d 11507
bbf5f2a1 11508 cmd = target_to_host_fcntl_cmd(arg2);
31b63193 11509 if (cmd == -TARGET_EINVAL) {
72eb7ea8 11510 return cmd;
31b63193 11511 }
b1e341eb 11512
60cd49d5 11513 switch(arg2) {
b1e341eb 11514 case TARGET_F_GETLK64:
213d3e9e
PM
11515 ret = copyfrom(&fl, arg3);
11516 if (ret) {
11517 break;
5813427b 11518 }
af8ab2bf 11519 ret = get_errno(safe_fcntl(arg1, cmd, &fl));
213d3e9e
PM
11520 if (ret == 0) {
11521 ret = copyto(arg3, &fl);
11522 }
77e4672d
FB
11523 break;
11524
b1e341eb
TS
11525 case TARGET_F_SETLK64:
11526 case TARGET_F_SETLKW64:
213d3e9e
PM
11527 ret = copyfrom(&fl, arg3);
11528 if (ret) {
11529 break;
ce4defa0 11530 }
435da5e7 11531 ret = get_errno(safe_fcntl(arg1, cmd, &fl));
77e4672d 11532 break;
60cd49d5 11533 default:
5f106811 11534 ret = do_fcntl(arg1, arg2, arg3);
60cd49d5
FB
11535 break;
11536 }
72eb7ea8 11537 return ret;
77e4672d 11538 }
60cd49d5 11539#endif
7d600c80
TS
11540#ifdef TARGET_NR_cacheflush
11541 case TARGET_NR_cacheflush:
11542 /* self-modifying code is handled automatically, so nothing needed */
72eb7ea8 11543 return 0;
7d600c80 11544#endif
c573ff67
FB
11545#ifdef TARGET_NR_getpagesize
11546 case TARGET_NR_getpagesize:
72eb7ea8 11547 return TARGET_PAGE_SIZE;
ebc05488 11548#endif
31e31b8a 11549 case TARGET_NR_gettid:
71ba74f6 11550 return get_errno(sys_gettid());
e5febef5 11551#ifdef TARGET_NR_readahead
31e31b8a 11552 case TARGET_NR_readahead:
2054ac9b 11553#if TARGET_ABI_BITS == 32
8bf8e9df 11554 if (regpairs_aligned(cpu_env, num)) {
2054ac9b
AJ
11555 arg2 = arg3;
11556 arg3 = arg4;
11557 arg4 = arg5;
11558 }
77c6850f 11559 ret = get_errno(readahead(arg1, target_offset64(arg2, arg3) , arg4));
2054ac9b
AJ
11560#else
11561 ret = get_errno(readahead(arg1, arg2, arg3));
11562#endif
72eb7ea8 11563 return ret;
e5febef5 11564#endif
a790ae38 11565#ifdef CONFIG_ATTR
ebc05488 11566#ifdef TARGET_NR_setxattr
31e31b8a
FB
11567 case TARGET_NR_listxattr:
11568 case TARGET_NR_llistxattr:
fb5590f7
PM
11569 {
11570 void *p, *b = 0;
11571 if (arg2) {
11572 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
11573 if (!b) {
72eb7ea8 11574 return -TARGET_EFAULT;
fb5590f7
PM
11575 }
11576 }
11577 p = lock_user_string(arg1);
11578 if (p) {
11579 if (num == TARGET_NR_listxattr) {
11580 ret = get_errno(listxattr(p, b, arg3));
11581 } else {
11582 ret = get_errno(llistxattr(p, b, arg3));
11583 }
11584 } else {
11585 ret = -TARGET_EFAULT;
11586 }
11587 unlock_user(p, arg1, 0);
11588 unlock_user(b, arg2, arg3);
72eb7ea8 11589 return ret;
fb5590f7 11590 }
31e31b8a 11591 case TARGET_NR_flistxattr:
fb5590f7
PM
11592 {
11593 void *b = 0;
11594 if (arg2) {
11595 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
11596 if (!b) {
72eb7ea8 11597 return -TARGET_EFAULT;
fb5590f7
PM
11598 }
11599 }
11600 ret = get_errno(flistxattr(arg1, b, arg3));
11601 unlock_user(b, arg2, arg3);
72eb7ea8 11602 return ret;
fb5590f7 11603 }
a790ae38 11604 case TARGET_NR_setxattr:
30297b55 11605 case TARGET_NR_lsetxattr:
a790ae38 11606 {
e3c33ec6
PM
11607 void *p, *n, *v = 0;
11608 if (arg3) {
11609 v = lock_user(VERIFY_READ, arg3, arg4, 1);
11610 if (!v) {
72eb7ea8 11611 return -TARGET_EFAULT;
e3c33ec6
PM
11612 }
11613 }
a790ae38
ACH
11614 p = lock_user_string(arg1);
11615 n = lock_user_string(arg2);
e3c33ec6 11616 if (p && n) {
30297b55
PM
11617 if (num == TARGET_NR_setxattr) {
11618 ret = get_errno(setxattr(p, n, v, arg4, arg5));
11619 } else {
11620 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
11621 }
a790ae38
ACH
11622 } else {
11623 ret = -TARGET_EFAULT;
11624 }
11625 unlock_user(p, arg1, 0);
11626 unlock_user(n, arg2, 0);
11627 unlock_user(v, arg3, 0);
11628 }
72eb7ea8 11629 return ret;
30297b55
PM
11630 case TARGET_NR_fsetxattr:
11631 {
11632 void *n, *v = 0;
11633 if (arg3) {
11634 v = lock_user(VERIFY_READ, arg3, arg4, 1);
11635 if (!v) {
72eb7ea8 11636 return -TARGET_EFAULT;
30297b55
PM
11637 }
11638 }
11639 n = lock_user_string(arg2);
11640 if (n) {
11641 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
11642 } else {
11643 ret = -TARGET_EFAULT;
11644 }
11645 unlock_user(n, arg2, 0);
11646 unlock_user(v, arg3, 0);
11647 }
72eb7ea8 11648 return ret;
a790ae38 11649 case TARGET_NR_getxattr:
30297b55 11650 case TARGET_NR_lgetxattr:
a790ae38 11651 {
e3c33ec6
PM
11652 void *p, *n, *v = 0;
11653 if (arg3) {
11654 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
11655 if (!v) {
72eb7ea8 11656 return -TARGET_EFAULT;
e3c33ec6
PM
11657 }
11658 }
a790ae38
ACH
11659 p = lock_user_string(arg1);
11660 n = lock_user_string(arg2);
e3c33ec6 11661 if (p && n) {
30297b55
PM
11662 if (num == TARGET_NR_getxattr) {
11663 ret = get_errno(getxattr(p, n, v, arg4));
11664 } else {
11665 ret = get_errno(lgetxattr(p, n, v, arg4));
11666 }
a790ae38
ACH
11667 } else {
11668 ret = -TARGET_EFAULT;
11669 }
11670 unlock_user(p, arg1, 0);
11671 unlock_user(n, arg2, 0);
11672 unlock_user(v, arg3, arg4);
11673 }
72eb7ea8 11674 return ret;
30297b55
PM
11675 case TARGET_NR_fgetxattr:
11676 {
11677 void *n, *v = 0;
11678 if (arg3) {
11679 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
11680 if (!v) {
72eb7ea8 11681 return -TARGET_EFAULT;
30297b55
PM
11682 }
11683 }
11684 n = lock_user_string(arg2);
11685 if (n) {
11686 ret = get_errno(fgetxattr(arg1, n, v, arg4));
11687 } else {
11688 ret = -TARGET_EFAULT;
11689 }
11690 unlock_user(n, arg2, 0);
11691 unlock_user(v, arg3, arg4);
11692 }
72eb7ea8 11693 return ret;
a790ae38 11694 case TARGET_NR_removexattr:
30297b55 11695 case TARGET_NR_lremovexattr:
a790ae38
ACH
11696 {
11697 void *p, *n;
11698 p = lock_user_string(arg1);
11699 n = lock_user_string(arg2);
11700 if (p && n) {
30297b55
PM
11701 if (num == TARGET_NR_removexattr) {
11702 ret = get_errno(removexattr(p, n));
11703 } else {
11704 ret = get_errno(lremovexattr(p, n));
11705 }
a790ae38
ACH
11706 } else {
11707 ret = -TARGET_EFAULT;
11708 }
11709 unlock_user(p, arg1, 0);
11710 unlock_user(n, arg2, 0);
11711 }
72eb7ea8 11712 return ret;
30297b55
PM
11713 case TARGET_NR_fremovexattr:
11714 {
11715 void *n;
11716 n = lock_user_string(arg2);
11717 if (n) {
11718 ret = get_errno(fremovexattr(arg1, n));
11719 } else {
11720 ret = -TARGET_EFAULT;
11721 }
11722 unlock_user(n, arg2, 0);
11723 }
72eb7ea8 11724 return ret;
ebc05488 11725#endif
a790ae38 11726#endif /* CONFIG_ATTR */
ebc05488 11727#ifdef TARGET_NR_set_thread_area
5cd4393b 11728 case TARGET_NR_set_thread_area:
8d18e893 11729#if defined(TARGET_MIPS)
d279279e 11730 ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
72eb7ea8 11731 return 0;
ef96779b
EI
11732#elif defined(TARGET_CRIS)
11733 if (arg1 & 0xff)
11734 ret = -TARGET_EINVAL;
11735 else {
11736 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
11737 ret = 0;
11738 }
72eb7ea8 11739 return ret;
8d18e893 11740#elif defined(TARGET_I386) && defined(TARGET_ABI32)
72eb7ea8 11741 return do_set_thread_area(cpu_env, arg1);
1ccd9374
PM
11742#elif defined(TARGET_M68K)
11743 {
0429a971 11744 TaskState *ts = cpu->opaque;
1ccd9374 11745 ts->tp_value = arg1;
72eb7ea8 11746 return 0;
1ccd9374 11747 }
6f5b89a0 11748#else
10f45d98 11749 return -TARGET_ENOSYS;
6f5b89a0
TS
11750#endif
11751#endif
11752#ifdef TARGET_NR_get_thread_area
5cd4393b 11753 case TARGET_NR_get_thread_area:
8d18e893 11754#if defined(TARGET_I386) && defined(TARGET_ABI32)
72eb7ea8 11755 return do_get_thread_area(cpu_env, arg1);
1ccd9374
PM
11756#elif defined(TARGET_M68K)
11757 {
0429a971 11758 TaskState *ts = cpu->opaque;
72eb7ea8 11759 return ts->tp_value;
1ccd9374 11760 }
8d18e893 11761#else
10f45d98 11762 return -TARGET_ENOSYS;
48dc41eb 11763#endif
8d18e893 11764#endif
48dc41eb
FB
11765#ifdef TARGET_NR_getdomainname
11766 case TARGET_NR_getdomainname:
10f45d98 11767 return -TARGET_ENOSYS;
ebc05488 11768#endif
6f5b89a0 11769
12e3340c
MF
11770#ifdef TARGET_NR_clock_settime
11771 case TARGET_NR_clock_settime:
11772 {
11773 struct timespec ts;
11774
11775 ret = target_to_host_timespec(&ts, arg2);
11776 if (!is_error(ret)) {
11777 ret = get_errno(clock_settime(arg1, &ts));
11778 }
72eb7ea8 11779 return ret;
12e3340c
MF
11780 }
11781#endif
c6c8d102
AF
11782#ifdef TARGET_NR_clock_settime64
11783 case TARGET_NR_clock_settime64:
11784 {
11785 struct timespec ts;
11786
11787 ret = target_to_host_timespec64(&ts, arg2);
11788 if (!is_error(ret)) {
11789 ret = get_errno(clock_settime(arg1, &ts));
11790 }
11791 return ret;
11792 }
11793#endif
b5906f95
TS
11794#ifdef TARGET_NR_clock_gettime
11795 case TARGET_NR_clock_gettime:
11796 {
11797 struct timespec ts;
11798 ret = get_errno(clock_gettime(arg1, &ts));
11799 if (!is_error(ret)) {
b9f9908e 11800 ret = host_to_target_timespec(arg2, &ts);
b5906f95 11801 }
72eb7ea8 11802 return ret;
b5906f95
TS
11803 }
11804#endif
c6c8d102
AF
11805#ifdef TARGET_NR_clock_gettime64
11806 case TARGET_NR_clock_gettime64:
11807 {
11808 struct timespec ts;
11809 ret = get_errno(clock_gettime(arg1, &ts));
11810 if (!is_error(ret)) {
11811 ret = host_to_target_timespec64(arg2, &ts);
11812 }
11813 return ret;
11814 }
11815#endif
b5906f95
TS
11816#ifdef TARGET_NR_clock_getres
11817 case TARGET_NR_clock_getres:
11818 {
11819 struct timespec ts;
11820 ret = get_errno(clock_getres(arg1, &ts));
11821 if (!is_error(ret)) {
11822 host_to_target_timespec(arg2, &ts);
11823 }
72eb7ea8 11824 return ret;
b5906f95
TS
11825 }
11826#endif
63d7651b
PB
11827#ifdef TARGET_NR_clock_nanosleep
11828 case TARGET_NR_clock_nanosleep:
11829 {
11830 struct timespec ts;
11831 target_to_host_timespec(&ts, arg3);
9e518226
PM
11832 ret = get_errno(safe_clock_nanosleep(arg1, arg2,
11833 &ts, arg4 ? &ts : NULL));
63d7651b
PB
11834 if (arg4)
11835 host_to_target_timespec(arg4, &ts);
8fbe8fdf
TM
11836
11837#if defined(TARGET_PPC)
11838 /* clock_nanosleep is odd in that it returns positive errno values.
11839 * On PPC, CR0 bit 3 should be set in such a situation. */
9e518226 11840 if (ret && ret != -TARGET_ERESTARTSYS) {
8fbe8fdf
TM
11841 ((CPUPPCState *)cpu_env)->crf[0] |= 1;
11842 }
11843#endif
72eb7ea8 11844 return ret;
63d7651b
PB
11845 }
11846#endif
b5906f95 11847
6f5b89a0
TS
11848#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
11849 case TARGET_NR_set_tid_address:
72eb7ea8 11850 return get_errno(set_tid_address((int *)g2h(arg1)));
6f5b89a0
TS
11851#endif
11852
4cae1d16 11853 case TARGET_NR_tkill:
72eb7ea8 11854 return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
4cae1d16 11855
71455574 11856 case TARGET_NR_tgkill:
72eb7ea8
RH
11857 return get_errno(safe_tgkill((int)arg1, (int)arg2,
11858 target_to_host_signal(arg3)));
71455574 11859
4f2b1fe8
TS
11860#ifdef TARGET_NR_set_robust_list
11861 case TARGET_NR_set_robust_list:
e9a970a8
PM
11862 case TARGET_NR_get_robust_list:
11863 /* The ABI for supporting robust futexes has userspace pass
11864 * the kernel a pointer to a linked list which is updated by
11865 * userspace after the syscall; the list is walked by the kernel
11866 * when the thread exits. Since the linked list in QEMU guest
11867 * memory isn't a valid linked list for the host and we have
11868 * no way to reliably intercept the thread-death event, we can't
11869 * support these. Silently return ENOSYS so that guest userspace
11870 * falls back to a non-robust futex implementation (which should
11871 * be OK except in the corner case of the guest crashing while
11872 * holding a mutex that is shared with another process via
11873 * shared memory).
11874 */
10f45d98 11875 return -TARGET_ENOSYS;
4f2b1fe8
TS
11876#endif
11877
1acae9f2 11878#if defined(TARGET_NR_utimensat)
9007f0ef
TS
11879 case TARGET_NR_utimensat:
11880 {
ebc996f3
RV
11881 struct timespec *tsp, ts[2];
11882 if (!arg3) {
11883 tsp = NULL;
11884 } else {
11885 target_to_host_timespec(ts, arg3);
11886 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
11887 tsp = ts;
11888 }
9007f0ef 11889 if (!arg2)
ebc996f3 11890 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
9007f0ef 11891 else {
579a97f7 11892 if (!(p = lock_user_string(arg2))) {
259841c1 11893 return -TARGET_EFAULT;
579a97f7 11894 }
ebc996f3 11895 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
579a97f7 11896 unlock_user(p, arg2, 0);
9007f0ef
TS
11897 }
11898 }
72eb7ea8 11899 return ret;
9007f0ef 11900#endif
859e8a89 11901#ifdef TARGET_NR_futex
bd0c5661 11902 case TARGET_NR_futex:
72eb7ea8 11903 return do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
859e8a89 11904#endif
14690296
AF
11905#ifdef TARGET_NR_futex_time64
11906 case TARGET_NR_futex_time64:
11907 return do_futex_time64(arg1, arg2, arg3, arg4, arg5, arg6);
11908#endif
dbfe4c36 11909#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
39b59763
AJ
11910 case TARGET_NR_inotify_init:
11911 ret = get_errno(sys_inotify_init());
b929f7e5
PMD
11912 if (ret >= 0) {
11913 fd_trans_register(ret, &target_inotify_trans);
11914 }
72eb7ea8 11915 return ret;
39b59763 11916#endif
a1606b0b 11917#ifdef CONFIG_INOTIFY1
c05c7a73
RV
11918#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
11919 case TARGET_NR_inotify_init1:
fea243e9
LD
11920 ret = get_errno(sys_inotify_init1(target_to_host_bitmask(arg1,
11921 fcntl_flags_tbl)));
b929f7e5
PMD
11922 if (ret >= 0) {
11923 fd_trans_register(ret, &target_inotify_trans);
11924 }
72eb7ea8 11925 return ret;
c05c7a73 11926#endif
a1606b0b 11927#endif
dbfe4c36 11928#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
39b59763
AJ
11929 case TARGET_NR_inotify_add_watch:
11930 p = lock_user_string(arg2);
11931 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
11932 unlock_user(p, arg2, 0);
72eb7ea8 11933 return ret;
39b59763 11934#endif
dbfe4c36 11935#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
39b59763 11936 case TARGET_NR_inotify_rm_watch:
72eb7ea8 11937 return get_errno(sys_inotify_rm_watch(arg1, arg2));
39b59763 11938#endif
9007f0ef 11939
8ec9cf89 11940#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
24e1003a
AJ
11941 case TARGET_NR_mq_open:
11942 {
c7536ab6 11943 struct mq_attr posix_mq_attr;
26400775 11944 struct mq_attr *pposix_mq_attr;
c7536ab6 11945 int host_flags;
24e1003a 11946
c7536ab6 11947 host_flags = target_to_host_bitmask(arg2, fcntl_flags_tbl);
26400775
LD
11948 pposix_mq_attr = NULL;
11949 if (arg4) {
11950 if (copy_from_user_mq_attr(&posix_mq_attr, arg4) != 0) {
2852aafd 11951 return -TARGET_EFAULT;
26400775
LD
11952 }
11953 pposix_mq_attr = &posix_mq_attr;
c7536ab6 11954 }
24e1003a 11955 p = lock_user_string(arg1 - 1);
c7536ab6 11956 if (!p) {
2852aafd 11957 return -TARGET_EFAULT;
b6ce1f6b 11958 }
26400775 11959 ret = get_errno(mq_open(p, host_flags, arg3, pposix_mq_attr));
24e1003a
AJ
11960 unlock_user (p, arg1, 0);
11961 }
72eb7ea8 11962 return ret;
24e1003a
AJ
11963
11964 case TARGET_NR_mq_unlink:
11965 p = lock_user_string(arg1 - 1);
3211215e 11966 if (!p) {
72eb7ea8 11967 return -TARGET_EFAULT;
3211215e 11968 }
24e1003a
AJ
11969 ret = get_errno(mq_unlink(p));
11970 unlock_user (p, arg1, 0);
72eb7ea8 11971 return ret;
24e1003a 11972
859e8a89 11973#ifdef TARGET_NR_mq_timedsend
24e1003a
AJ
11974 case TARGET_NR_mq_timedsend:
11975 {
11976 struct timespec ts;
11977
11978 p = lock_user (VERIFY_READ, arg2, arg3, 1);
11979 if (arg5 != 0) {
11980 target_to_host_timespec(&ts, arg5);
d40ecd66 11981 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
24e1003a 11982 host_to_target_timespec(arg5, &ts);
d40ecd66
PM
11983 } else {
11984 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
24e1003a 11985 }
24e1003a
AJ
11986 unlock_user (p, arg2, arg3);
11987 }
72eb7ea8 11988 return ret;
859e8a89 11989#endif
24e1003a 11990
859e8a89 11991#ifdef TARGET_NR_mq_timedreceive
24e1003a
AJ
11992 case TARGET_NR_mq_timedreceive:
11993 {
11994 struct timespec ts;
11995 unsigned int prio;
11996
11997 p = lock_user (VERIFY_READ, arg2, arg3, 1);
11998 if (arg5 != 0) {
11999 target_to_host_timespec(&ts, arg5);
d40ecd66
PM
12000 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12001 &prio, &ts));
24e1003a 12002 host_to_target_timespec(arg5, &ts);
d40ecd66
PM
12003 } else {
12004 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
12005 &prio, NULL));
24e1003a 12006 }
24e1003a
AJ
12007 unlock_user (p, arg2, arg3);
12008 if (arg4 != 0)
12009 put_user_u32(prio, arg4);
12010 }
72eb7ea8 12011 return ret;
859e8a89 12012#endif
24e1003a
AJ
12013
12014 /* Not implemented for now... */
12015/* case TARGET_NR_mq_notify: */
12016/* break; */
12017
12018 case TARGET_NR_mq_getsetattr:
12019 {
12020 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
12021 ret = 0;
24e1003a
AJ
12022 if (arg2 != 0) {
12023 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
a23ea409
MF
12024 ret = get_errno(mq_setattr(arg1, &posix_mq_attr_in,
12025 &posix_mq_attr_out));
12026 } else if (arg3 != 0) {
12027 ret = get_errno(mq_getattr(arg1, &posix_mq_attr_out));
12028 }
12029 if (ret == 0 && arg3 != 0) {
12030 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
24e1003a 12031 }
24e1003a 12032 }
72eb7ea8 12033 return ret;
24e1003a
AJ
12034#endif
12035
3ce34dfb
VS
12036#ifdef CONFIG_SPLICE
12037#ifdef TARGET_NR_tee
12038 case TARGET_NR_tee:
12039 {
12040 ret = get_errno(tee(arg1,arg2,arg3,arg4));
12041 }
72eb7ea8 12042 return ret;
3ce34dfb
VS
12043#endif
12044#ifdef TARGET_NR_splice
12045 case TARGET_NR_splice:
12046 {
12047 loff_t loff_in, loff_out;
12048 loff_t *ploff_in = NULL, *ploff_out = NULL;
17644b36
AS
12049 if (arg2) {
12050 if (get_user_u64(loff_in, arg2)) {
2852aafd 12051 return -TARGET_EFAULT;
17644b36 12052 }
3ce34dfb
VS
12053 ploff_in = &loff_in;
12054 }
17644b36
AS
12055 if (arg4) {
12056 if (get_user_u64(loff_out, arg4)) {
2852aafd 12057 return -TARGET_EFAULT;
17644b36 12058 }
3ce34dfb
VS
12059 ploff_out = &loff_out;
12060 }
12061 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
17644b36
AS
12062 if (arg2) {
12063 if (put_user_u64(loff_in, arg2)) {
2852aafd 12064 return -TARGET_EFAULT;
17644b36
AS
12065 }
12066 }
12067 if (arg4) {
12068 if (put_user_u64(loff_out, arg4)) {
2852aafd 12069 return -TARGET_EFAULT;
17644b36
AS
12070 }
12071 }
3ce34dfb 12072 }
72eb7ea8 12073 return ret;
3ce34dfb
VS
12074#endif
12075#ifdef TARGET_NR_vmsplice
12076 case TARGET_NR_vmsplice:
12077 {
f287b2c2
RH
12078 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
12079 if (vec != NULL) {
12080 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
12081 unlock_iovec(vec, arg2, arg3, 0);
12082 } else {
12083 ret = -host_to_target_errno(errno);
12084 }
3ce34dfb 12085 }
72eb7ea8 12086 return ret;
3ce34dfb
VS
12087#endif
12088#endif /* CONFIG_SPLICE */
c2882b96
RV
12089#ifdef CONFIG_EVENTFD
12090#if defined(TARGET_NR_eventfd)
12091 case TARGET_NR_eventfd:
12092 ret = get_errno(eventfd(arg1, 0));
b929f7e5
PMD
12093 if (ret >= 0) {
12094 fd_trans_register(ret, &target_eventfd_trans);
12095 }
72eb7ea8 12096 return ret;
c2882b96
RV
12097#endif
12098#if defined(TARGET_NR_eventfd2)
12099 case TARGET_NR_eventfd2:
5947c697
PJ
12100 {
12101 int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
12102 if (arg2 & TARGET_O_NONBLOCK) {
12103 host_flags |= O_NONBLOCK;
12104 }
12105 if (arg2 & TARGET_O_CLOEXEC) {
12106 host_flags |= O_CLOEXEC;
12107 }
12108 ret = get_errno(eventfd(arg1, host_flags));
b929f7e5
PMD
12109 if (ret >= 0) {
12110 fd_trans_register(ret, &target_eventfd_trans);
12111 }
72eb7ea8 12112 return ret;
5947c697 12113 }
c2882b96
RV
12114#endif
12115#endif /* CONFIG_EVENTFD */
d0927938
UH
12116#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
12117 case TARGET_NR_fallocate:
20249ae1
AG
12118#if TARGET_ABI_BITS == 32
12119 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
12120 target_offset64(arg5, arg6)));
12121#else
d0927938 12122 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
20249ae1 12123#endif
72eb7ea8 12124 return ret;
c727f47d
PM
12125#endif
12126#if defined(CONFIG_SYNC_FILE_RANGE)
12127#if defined(TARGET_NR_sync_file_range)
12128 case TARGET_NR_sync_file_range:
12129#if TARGET_ABI_BITS == 32
bfcedc57
RV
12130#if defined(TARGET_MIPS)
12131 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
12132 target_offset64(arg5, arg6), arg7));
12133#else
c727f47d
PM
12134 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
12135 target_offset64(arg4, arg5), arg6));
bfcedc57 12136#endif /* !TARGET_MIPS */
c727f47d
PM
12137#else
12138 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
12139#endif
72eb7ea8 12140 return ret;
c727f47d 12141#endif
5bcb4986
LV
12142#if defined(TARGET_NR_sync_file_range2) || \
12143 defined(TARGET_NR_arm_sync_file_range)
c727f47d
PM
12144#if defined(TARGET_NR_sync_file_range2)
12145 case TARGET_NR_sync_file_range2:
5bcb4986
LV
12146#endif
12147#if defined(TARGET_NR_arm_sync_file_range)
12148 case TARGET_NR_arm_sync_file_range:
12149#endif
c727f47d
PM
12150 /* This is like sync_file_range but the arguments are reordered */
12151#if TARGET_ABI_BITS == 32
12152 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
12153 target_offset64(arg5, arg6), arg2));
12154#else
12155 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
12156#endif
72eb7ea8 12157 return ret;
c727f47d 12158#endif
3b6edd16 12159#endif
e36800c9
LV
12160#if defined(TARGET_NR_signalfd4)
12161 case TARGET_NR_signalfd4:
72eb7ea8 12162 return do_signalfd4(arg1, arg2, arg4);
e36800c9
LV
12163#endif
12164#if defined(TARGET_NR_signalfd)
12165 case TARGET_NR_signalfd:
72eb7ea8 12166 return do_signalfd4(arg1, arg2, 0);
e36800c9 12167#endif
3b6edd16
PM
12168#if defined(CONFIG_EPOLL)
12169#if defined(TARGET_NR_epoll_create)
12170 case TARGET_NR_epoll_create:
72eb7ea8 12171 return get_errno(epoll_create(arg1));
3b6edd16
PM
12172#endif
12173#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
12174 case TARGET_NR_epoll_create1:
386d3865 12175 return get_errno(epoll_create1(target_to_host_bitmask(arg1, fcntl_flags_tbl)));
3b6edd16
PM
12176#endif
12177#if defined(TARGET_NR_epoll_ctl)
12178 case TARGET_NR_epoll_ctl:
12179 {
12180 struct epoll_event ep;
12181 struct epoll_event *epp = 0;
12182 if (arg4) {
12183 struct target_epoll_event *target_ep;
12184 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
2852aafd 12185 return -TARGET_EFAULT;
3b6edd16
PM
12186 }
12187 ep.events = tswap32(target_ep->events);
12188 /* The epoll_data_t union is just opaque data to the kernel,
12189 * so we transfer all 64 bits across and need not worry what
12190 * actual data type it is.
12191 */
12192 ep.data.u64 = tswap64(target_ep->data.u64);
12193 unlock_user_struct(target_ep, arg4, 0);
12194 epp = &ep;
12195 }
72eb7ea8 12196 return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
3b6edd16
PM
12197 }
12198#endif
12199
227f0214 12200#if defined(TARGET_NR_epoll_wait) || defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12201#if defined(TARGET_NR_epoll_wait)
12202 case TARGET_NR_epoll_wait:
12203#endif
227f0214 12204#if defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12205 case TARGET_NR_epoll_pwait:
12206#endif
12207 {
12208 struct target_epoll_event *target_ep;
12209 struct epoll_event *ep;
12210 int epfd = arg1;
12211 int maxevents = arg3;
12212 int timeout = arg4;
12213
2ba7fae3 12214 if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
72eb7ea8 12215 return -TARGET_EINVAL;
2ba7fae3
PM
12216 }
12217
3b6edd16
PM
12218 target_ep = lock_user(VERIFY_WRITE, arg2,
12219 maxevents * sizeof(struct target_epoll_event), 1);
12220 if (!target_ep) {
2852aafd 12221 return -TARGET_EFAULT;
3b6edd16
PM
12222 }
12223
04c95f4d
PM
12224 ep = g_try_new(struct epoll_event, maxevents);
12225 if (!ep) {
12226 unlock_user(target_ep, arg2, 0);
72eb7ea8 12227 return -TARGET_ENOMEM;
04c95f4d 12228 }
3b6edd16
PM
12229
12230 switch (num) {
227f0214 12231#if defined(TARGET_NR_epoll_pwait)
3b6edd16
PM
12232 case TARGET_NR_epoll_pwait:
12233 {
12234 target_sigset_t *target_set;
12235 sigset_t _set, *set = &_set;
12236
12237 if (arg5) {
c815701e
PM
12238 if (arg6 != sizeof(target_sigset_t)) {
12239 ret = -TARGET_EINVAL;
12240 break;
12241 }
12242
3b6edd16
PM
12243 target_set = lock_user(VERIFY_READ, arg5,
12244 sizeof(target_sigset_t), 1);
12245 if (!target_set) {
04c95f4d
PM
12246 ret = -TARGET_EFAULT;
12247 break;
3b6edd16
PM
12248 }
12249 target_to_host_sigset(set, target_set);
12250 unlock_user(target_set, arg5, 0);
12251 } else {
12252 set = NULL;
12253 }
12254
227f0214
PM
12255 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
12256 set, SIGSET_T_SIZE));
3b6edd16
PM
12257 break;
12258 }
12259#endif
12260#if defined(TARGET_NR_epoll_wait)
12261 case TARGET_NR_epoll_wait:
227f0214
PM
12262 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
12263 NULL, 0));
3b6edd16
PM
12264 break;
12265#endif
12266 default:
12267 ret = -TARGET_ENOSYS;
12268 }
12269 if (!is_error(ret)) {
12270 int i;
12271 for (i = 0; i < ret; i++) {
12272 target_ep[i].events = tswap32(ep[i].events);
12273 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
12274 }
04c95f4d
PM
12275 unlock_user(target_ep, arg2,
12276 ret * sizeof(struct target_epoll_event));
12277 } else {
12278 unlock_user(target_ep, arg2, 0);
3b6edd16 12279 }
04c95f4d 12280 g_free(ep);
72eb7ea8 12281 return ret;
3b6edd16
PM
12282 }
12283#endif
163a05a8
PM
12284#endif
12285#ifdef TARGET_NR_prlimit64
12286 case TARGET_NR_prlimit64:
12287 {
12288 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
12289 struct target_rlimit64 *target_rnew, *target_rold;
12290 struct host_rlimit64 rnew, rold, *rnewp = 0;
95018018 12291 int resource = target_to_host_resource(arg2);
055d92f8
TK
12292
12293 if (arg3 && (resource != RLIMIT_AS &&
12294 resource != RLIMIT_DATA &&
12295 resource != RLIMIT_STACK)) {
163a05a8 12296 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
2852aafd 12297 return -TARGET_EFAULT;
163a05a8
PM
12298 }
12299 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
12300 rnew.rlim_max = tswap64(target_rnew->rlim_max);
12301 unlock_user_struct(target_rnew, arg3, 0);
12302 rnewp = &rnew;
12303 }
12304
95018018 12305 ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
163a05a8
PM
12306 if (!is_error(ret) && arg4) {
12307 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
2852aafd 12308 return -TARGET_EFAULT;
163a05a8
PM
12309 }
12310 target_rold->rlim_cur = tswap64(rold.rlim_cur);
12311 target_rold->rlim_max = tswap64(rold.rlim_max);
12312 unlock_user_struct(target_rold, arg4, 1);
12313 }
72eb7ea8 12314 return ret;
163a05a8 12315 }
3d21d29c
RH
12316#endif
12317#ifdef TARGET_NR_gethostname
12318 case TARGET_NR_gethostname:
12319 {
12320 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
12321 if (name) {
12322 ret = get_errno(gethostname(name, arg2));
12323 unlock_user(name, arg1, arg2);
12324 } else {
12325 ret = -TARGET_EFAULT;
12326 }
72eb7ea8 12327 return ret;
3d21d29c 12328 }
89aaf1a6
RV
12329#endif
12330#ifdef TARGET_NR_atomic_cmpxchg_32
12331 case TARGET_NR_atomic_cmpxchg_32:
12332 {
12333 /* should use start_exclusive from main.c */
12334 abi_ulong mem_value;
12335 if (get_user_u32(mem_value, arg6)) {
12336 target_siginfo_t info;
12337 info.si_signo = SIGSEGV;
12338 info.si_errno = 0;
12339 info.si_code = TARGET_SEGV_MAPERR;
12340 info._sifields._sigfault._addr = arg6;
9d2803f7
PM
12341 queue_signal((CPUArchState *)cpu_env, info.si_signo,
12342 QEMU_SI_FAULT, &info);
89aaf1a6
RV
12343 ret = 0xdeadbeef;
12344
12345 }
12346 if (mem_value == arg2)
12347 put_user_u32(arg1, arg6);
72eb7ea8 12348 return mem_value;
89aaf1a6
RV
12349 }
12350#endif
12351#ifdef TARGET_NR_atomic_barrier
12352 case TARGET_NR_atomic_barrier:
72eb7ea8
RH
12353 /* Like the kernel implementation and the
12354 qemu arm barrier, no-op this? */
12355 return 0;
d0927938 12356#endif
f4f1e10a
ECL
12357
12358#ifdef TARGET_NR_timer_create
12359 case TARGET_NR_timer_create:
12360 {
12361 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
12362
12363 struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
f4f1e10a
ECL
12364
12365 int clkid = arg1;
12366 int timer_index = next_free_host_timer();
12367
12368 if (timer_index < 0) {
12369 ret = -TARGET_EAGAIN;
12370 } else {
12371 timer_t *phtimer = g_posix_timers + timer_index;
12372
12373 if (arg2) {
f4f1e10a 12374 phost_sevp = &host_sevp;
c065976f
PM
12375 ret = target_to_host_sigevent(phost_sevp, arg2);
12376 if (ret != 0) {
72eb7ea8 12377 return ret;
c065976f 12378 }
f4f1e10a
ECL
12379 }
12380
12381 ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
12382 if (ret) {
12383 phtimer = NULL;
12384 } else {
aecc8861 12385 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
2852aafd 12386 return -TARGET_EFAULT;
f4f1e10a 12387 }
f4f1e10a
ECL
12388 }
12389 }
72eb7ea8 12390 return ret;
f4f1e10a
ECL
12391 }
12392#endif
12393
12394#ifdef TARGET_NR_timer_settime
12395 case TARGET_NR_timer_settime:
12396 {
12397 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
12398 * struct itimerspec * old_value */
aecc8861 12399 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12400
aecc8861
AG
12401 if (timerid < 0) {
12402 ret = timerid;
12403 } else if (arg3 == 0) {
f4f1e10a
ECL
12404 ret = -TARGET_EINVAL;
12405 } else {
e52a99f7 12406 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12407 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
12408
40c80b5e 12409 if (target_to_host_itimerspec(&hspec_new, arg3)) {
2852aafd 12410 return -TARGET_EFAULT;
40c80b5e 12411 }
f4f1e10a
ECL
12412 ret = get_errno(
12413 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
40c80b5e 12414 if (arg4 && host_to_target_itimerspec(arg4, &hspec_old)) {
2852aafd 12415 return -TARGET_EFAULT;
40c80b5e 12416 }
f4f1e10a 12417 }
72eb7ea8 12418 return ret;
f4f1e10a
ECL
12419 }
12420#endif
12421
12422#ifdef TARGET_NR_timer_gettime
12423 case TARGET_NR_timer_gettime:
12424 {
12425 /* args: timer_t timerid, struct itimerspec *curr_value */
aecc8861 12426 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12427
aecc8861
AG
12428 if (timerid < 0) {
12429 ret = timerid;
12430 } else if (!arg2) {
12431 ret = -TARGET_EFAULT;
f4f1e10a 12432 } else {
e52a99f7 12433 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12434 struct itimerspec hspec;
12435 ret = get_errno(timer_gettime(htimer, &hspec));
12436
12437 if (host_to_target_itimerspec(arg2, &hspec)) {
12438 ret = -TARGET_EFAULT;
12439 }
12440 }
72eb7ea8 12441 return ret;
f4f1e10a
ECL
12442 }
12443#endif
12444
12445#ifdef TARGET_NR_timer_getoverrun
12446 case TARGET_NR_timer_getoverrun:
12447 {
12448 /* args: timer_t timerid */
aecc8861 12449 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12450
aecc8861
AG
12451 if (timerid < 0) {
12452 ret = timerid;
f4f1e10a 12453 } else {
e52a99f7 12454 timer_t htimer = g_posix_timers[timerid];
f4f1e10a
ECL
12455 ret = get_errno(timer_getoverrun(htimer));
12456 }
72eb7ea8 12457 return ret;
f4f1e10a
ECL
12458 }
12459#endif
12460
12461#ifdef TARGET_NR_timer_delete
12462 case TARGET_NR_timer_delete:
12463 {
12464 /* args: timer_t timerid */
aecc8861 12465 target_timer_t timerid = get_timer_id(arg1);
e52a99f7 12466
aecc8861
AG
12467 if (timerid < 0) {
12468 ret = timerid;
f4f1e10a 12469 } else {
e52a99f7 12470 timer_t htimer = g_posix_timers[timerid];
f4f1e10a 12471 ret = get_errno(timer_delete(htimer));
e52a99f7 12472 g_posix_timers[timerid] = 0;
f4f1e10a 12473 }
72eb7ea8 12474 return ret;
f4f1e10a
ECL
12475 }
12476#endif
12477
51834341
RV
12478#if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
12479 case TARGET_NR_timerfd_create:
72eb7ea8
RH
12480 return get_errno(timerfd_create(arg1,
12481 target_to_host_bitmask(arg2, fcntl_flags_tbl)));
51834341
RV
12482#endif
12483
12484#if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
12485 case TARGET_NR_timerfd_gettime:
12486 {
12487 struct itimerspec its_curr;
12488
12489 ret = get_errno(timerfd_gettime(arg1, &its_curr));
12490
12491 if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
2852aafd 12492 return -TARGET_EFAULT;
51834341
RV
12493 }
12494 }
72eb7ea8 12495 return ret;
51834341
RV
12496#endif
12497
12498#if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
12499 case TARGET_NR_timerfd_settime:
12500 {
12501 struct itimerspec its_new, its_old, *p_new;
12502
12503 if (arg3) {
12504 if (target_to_host_itimerspec(&its_new, arg3)) {
2852aafd 12505 return -TARGET_EFAULT;
51834341
RV
12506 }
12507 p_new = &its_new;
12508 } else {
12509 p_new = NULL;
12510 }
12511
12512 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
12513
12514 if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
2852aafd 12515 return -TARGET_EFAULT;
51834341
RV
12516 }
12517 }
72eb7ea8 12518 return ret;
51834341
RV
12519#endif
12520
ab31cda3
PB
12521#if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
12522 case TARGET_NR_ioprio_get:
72eb7ea8 12523 return get_errno(ioprio_get(arg1, arg2));
ab31cda3
PB
12524#endif
12525
12526#if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
12527 case TARGET_NR_ioprio_set:
72eb7ea8 12528 return get_errno(ioprio_set(arg1, arg2, arg3));
ab31cda3
PB
12529#endif
12530
9af5c906
RV
12531#if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
12532 case TARGET_NR_setns:
72eb7ea8 12533 return get_errno(setns(arg1, arg2));
9af5c906
RV
12534#endif
12535#if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
12536 case TARGET_NR_unshare:
72eb7ea8 12537 return get_errno(unshare(arg1));
9af5c906 12538#endif
2f14788c
LV
12539#if defined(TARGET_NR_kcmp) && defined(__NR_kcmp)
12540 case TARGET_NR_kcmp:
72eb7ea8 12541 return get_errno(kcmp(arg1, arg2, arg3, arg4, arg5));
2f14788c 12542#endif
fa97e38e
RH
12543#ifdef TARGET_NR_swapcontext
12544 case TARGET_NR_swapcontext:
12545 /* PowerPC specific. */
72eb7ea8 12546 return do_swapcontext(cpu_env, arg1, arg2, arg3);
fa97e38e 12547#endif
9bdfa4d2
SCW
12548#ifdef TARGET_NR_memfd_create
12549 case TARGET_NR_memfd_create:
12550 p = lock_user_string(arg1);
12551 if (!p) {
12552 return -TARGET_EFAULT;
12553 }
12554 ret = get_errno(memfd_create(p, arg2));
12555 fd_trans_unregister(ret);
12556 unlock_user(p, arg1, 0);
12557 return ret;
12558#endif
8500476f
AS
12559#if defined TARGET_NR_membarrier && defined __NR_membarrier
12560 case TARGET_NR_membarrier:
12561 return get_errno(membarrier(arg1, arg2));
12562#endif
9af5c906 12563
31e31b8a 12564 default:
122f9c83 12565 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
72eb7ea8 12566 return -TARGET_ENOSYS;
31e31b8a 12567 }
31e31b8a
FB
12568 return ret;
12569}
dc1ce18b
RH
12570
12571abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
12572 abi_long arg2, abi_long arg3, abi_long arg4,
12573 abi_long arg5, abi_long arg6, abi_long arg7,
12574 abi_long arg8)
12575{
29a0af61 12576 CPUState *cpu = env_cpu(cpu_env);
dc1ce18b
RH
12577 abi_long ret;
12578
12579#ifdef DEBUG_ERESTARTSYS
12580 /* Debug-only code for exercising the syscall-restart code paths
12581 * in the per-architecture cpu main loops: restart every syscall
12582 * the guest makes once before letting it through.
12583 */
12584 {
12585 static bool flag;
12586 flag = !flag;
12587 if (flag) {
12588 return -TARGET_ERESTARTSYS;
12589 }
12590 }
12591#endif
12592
c36f7a64
EC
12593 record_syscall_start(cpu, num, arg1,
12594 arg2, arg3, arg4, arg5, arg6, arg7, arg8);
dc1ce18b 12595
4b25a506 12596 if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
dc1ce18b 12597 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4b25a506
JK
12598 }
12599
12600 ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
12601 arg5, arg6, arg7, arg8);
12602
12603 if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
c84be71f 12604 print_syscall_ret(num, ret, arg1, arg2, arg3, arg4, arg5, arg6);
dc1ce18b
RH
12605 }
12606
c36f7a64 12607 record_syscall_return(cpu, num, ret);
dc1ce18b
RH
12608 return ret;
12609}