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