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