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