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