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