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