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