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