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