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