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