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