pci core: assert ENOSPC when add capability
[qemu/ar7.git] / linux-user / syscall.c
blob71ccbd9c5e30bc7e101a6df1bcafa05ea815f100
1 /*
2 * Linux syscalls
4 * Copyright (c) 2003 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
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__
40 int __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 //#include <sys/user.h>
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
79 #define termios host_termios
80 #define winsize host_winsize
81 #define termio host_termio
82 #define sgttyb host_sgttyb /* same as target */
83 #define tchars host_tchars /* same as target */
84 #define ltchars host_ltchars /* same as target */
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/netlink.h>
105 #ifdef CONFIG_RTNETLINK
106 #include <linux/rtnetlink.h>
107 #endif
108 #include <linux/audit.h>
109 #include "linux_loop.h"
110 #include "uname.h"
112 #include "qemu.h"
114 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
115 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
117 //#define DEBUG
118 /* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
119 * once. This exercises the codepaths for restart.
121 //#define DEBUG_ERESTARTSYS
123 //#include <linux/msdos_fs.h>
124 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
125 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
127 /* This is the size of the host kernel's sigset_t, needed where we make
128 * direct system calls that take a sigset_t pointer and a size.
130 #define SIGSET_T_SIZE (_NSIG / 8)
132 #undef _syscall0
133 #undef _syscall1
134 #undef _syscall2
135 #undef _syscall3
136 #undef _syscall4
137 #undef _syscall5
138 #undef _syscall6
140 #define _syscall0(type,name) \
141 static type name (void) \
143 return syscall(__NR_##name); \
146 #define _syscall1(type,name,type1,arg1) \
147 static type name (type1 arg1) \
149 return syscall(__NR_##name, arg1); \
152 #define _syscall2(type,name,type1,arg1,type2,arg2) \
153 static type name (type1 arg1,type2 arg2) \
155 return syscall(__NR_##name, arg1, arg2); \
158 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
159 static type name (type1 arg1,type2 arg2,type3 arg3) \
161 return syscall(__NR_##name, arg1, arg2, arg3); \
164 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
165 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
167 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
170 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
171 type5,arg5) \
172 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
174 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
178 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
179 type5,arg5,type6,arg6) \
180 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
181 type6 arg6) \
183 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
187 #define __NR_sys_uname __NR_uname
188 #define __NR_sys_getcwd1 __NR_getcwd
189 #define __NR_sys_getdents __NR_getdents
190 #define __NR_sys_getdents64 __NR_getdents64
191 #define __NR_sys_getpriority __NR_getpriority
192 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
193 #define __NR_sys_syslog __NR_syslog
194 #define __NR_sys_futex __NR_futex
195 #define __NR_sys_inotify_init __NR_inotify_init
196 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
197 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
199 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
200 defined(__s390x__)
201 #define __NR__llseek __NR_lseek
202 #endif
204 /* Newer kernel ports have llseek() instead of _llseek() */
205 #if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
206 #define TARGET_NR__llseek TARGET_NR_llseek
207 #endif
209 #ifdef __NR_gettid
210 _syscall0(int, gettid)
211 #else
212 /* This is a replacement for the host gettid() and must return a host
213 errno. */
214 static int gettid(void) {
215 return -ENOSYS;
217 #endif
218 #if defined(TARGET_NR_getdents) && defined(__NR_getdents)
219 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
220 #endif
221 #if !defined(__NR_getdents) || \
222 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
223 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
224 #endif
225 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
226 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
227 loff_t *, res, uint, wh);
228 #endif
229 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
230 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
231 #ifdef __NR_exit_group
232 _syscall1(int,exit_group,int,error_code)
233 #endif
234 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
235 _syscall1(int,set_tid_address,int *,tidptr)
236 #endif
237 #if defined(TARGET_NR_futex) && defined(__NR_futex)
238 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
239 const struct timespec *,timeout,int *,uaddr2,int,val3)
240 #endif
241 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
242 _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
243 unsigned long *, user_mask_ptr);
244 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
245 _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
246 unsigned long *, user_mask_ptr);
247 _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
248 void *, arg);
249 _syscall2(int, capget, struct __user_cap_header_struct *, header,
250 struct __user_cap_data_struct *, data);
251 _syscall2(int, capset, struct __user_cap_header_struct *, header,
252 struct __user_cap_data_struct *, data);
253 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
254 _syscall2(int, ioprio_get, int, which, int, who)
255 #endif
256 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
257 _syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
258 #endif
259 #if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
260 _syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags)
261 #endif
263 static bitmask_transtbl fcntl_flags_tbl[] = {
264 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
265 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
266 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
267 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
268 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
269 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
270 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
271 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
272 { TARGET_O_SYNC, TARGET_O_DSYNC, O_SYNC, O_DSYNC, },
273 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
274 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
275 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
276 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
277 #if defined(O_DIRECT)
278 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
279 #endif
280 #if defined(O_NOATIME)
281 { TARGET_O_NOATIME, TARGET_O_NOATIME, O_NOATIME, O_NOATIME },
282 #endif
283 #if defined(O_CLOEXEC)
284 { TARGET_O_CLOEXEC, TARGET_O_CLOEXEC, O_CLOEXEC, O_CLOEXEC },
285 #endif
286 #if defined(O_PATH)
287 { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
288 #endif
289 /* Don't terminate the list prematurely on 64-bit host+guest. */
290 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
291 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
292 #endif
293 { 0, 0, 0, 0 }
296 typedef abi_long (*TargetFdDataFunc)(void *, size_t);
297 typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
298 typedef struct TargetFdTrans {
299 TargetFdDataFunc host_to_target_data;
300 TargetFdDataFunc target_to_host_data;
301 TargetFdAddrFunc target_to_host_addr;
302 } TargetFdTrans;
304 static TargetFdTrans **target_fd_trans;
306 static unsigned int target_fd_max;
308 static TargetFdDataFunc fd_trans_target_to_host_data(int fd)
310 if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
311 return target_fd_trans[fd]->target_to_host_data;
313 return NULL;
316 static TargetFdDataFunc fd_trans_host_to_target_data(int fd)
318 if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
319 return target_fd_trans[fd]->host_to_target_data;
321 return NULL;
324 static TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
326 if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
327 return target_fd_trans[fd]->target_to_host_addr;
329 return NULL;
332 static void fd_trans_register(int fd, TargetFdTrans *trans)
334 unsigned int oldmax;
336 if (fd >= target_fd_max) {
337 oldmax = target_fd_max;
338 target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */
339 target_fd_trans = g_renew(TargetFdTrans *,
340 target_fd_trans, target_fd_max);
341 memset((void *)(target_fd_trans + oldmax), 0,
342 (target_fd_max - oldmax) * sizeof(TargetFdTrans *));
344 target_fd_trans[fd] = trans;
347 static void fd_trans_unregister(int fd)
349 if (fd >= 0 && fd < target_fd_max) {
350 target_fd_trans[fd] = NULL;
354 static void fd_trans_dup(int oldfd, int newfd)
356 fd_trans_unregister(newfd);
357 if (oldfd < target_fd_max && target_fd_trans[oldfd]) {
358 fd_trans_register(newfd, target_fd_trans[oldfd]);
362 static int sys_getcwd1(char *buf, size_t size)
364 if (getcwd(buf, size) == NULL) {
365 /* getcwd() sets errno */
366 return (-1);
368 return strlen(buf)+1;
371 #ifdef TARGET_NR_utimensat
372 #ifdef CONFIG_UTIMENSAT
373 static int sys_utimensat(int dirfd, const char *pathname,
374 const struct timespec times[2], int flags)
376 if (pathname == NULL)
377 return futimens(dirfd, times);
378 else
379 return utimensat(dirfd, pathname, times, flags);
381 #elif defined(__NR_utimensat)
382 #define __NR_sys_utimensat __NR_utimensat
383 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
384 const struct timespec *,tsp,int,flags)
385 #else
386 static int sys_utimensat(int dirfd, const char *pathname,
387 const struct timespec times[2], int flags)
389 errno = ENOSYS;
390 return -1;
392 #endif
393 #endif /* TARGET_NR_utimensat */
395 #ifdef CONFIG_INOTIFY
396 #include <sys/inotify.h>
398 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
399 static int sys_inotify_init(void)
401 return (inotify_init());
403 #endif
404 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
405 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
407 return (inotify_add_watch(fd, pathname, mask));
409 #endif
410 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
411 static int sys_inotify_rm_watch(int fd, int32_t wd)
413 return (inotify_rm_watch(fd, wd));
415 #endif
416 #ifdef CONFIG_INOTIFY1
417 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
418 static int sys_inotify_init1(int flags)
420 return (inotify_init1(flags));
422 #endif
423 #endif
424 #else
425 /* Userspace can usually survive runtime without inotify */
426 #undef TARGET_NR_inotify_init
427 #undef TARGET_NR_inotify_init1
428 #undef TARGET_NR_inotify_add_watch
429 #undef TARGET_NR_inotify_rm_watch
430 #endif /* CONFIG_INOTIFY */
432 #if defined(TARGET_NR_prlimit64)
433 #ifndef __NR_prlimit64
434 # define __NR_prlimit64 -1
435 #endif
436 #define __NR_sys_prlimit64 __NR_prlimit64
437 /* The glibc rlimit structure may not be that used by the underlying syscall */
438 struct host_rlimit64 {
439 uint64_t rlim_cur;
440 uint64_t rlim_max;
442 _syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
443 const struct host_rlimit64 *, new_limit,
444 struct host_rlimit64 *, old_limit)
445 #endif
448 #if defined(TARGET_NR_timer_create)
449 /* Maxiumum of 32 active POSIX timers allowed at any one time. */
450 static timer_t g_posix_timers[32] = { 0, } ;
452 static inline int next_free_host_timer(void)
454 int k ;
455 /* FIXME: Does finding the next free slot require a lock? */
456 for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
457 if (g_posix_timers[k] == 0) {
458 g_posix_timers[k] = (timer_t) 1;
459 return k;
462 return -1;
464 #endif
466 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
467 #ifdef TARGET_ARM
468 static inline int regpairs_aligned(void *cpu_env) {
469 return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
471 #elif defined(TARGET_MIPS)
472 static inline int regpairs_aligned(void *cpu_env) { return 1; }
473 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
474 /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
475 * of registers which translates to the same as ARM/MIPS, because we start with
476 * r3 as arg1 */
477 static inline int regpairs_aligned(void *cpu_env) { return 1; }
478 #else
479 static inline int regpairs_aligned(void *cpu_env) { return 0; }
480 #endif
482 #define ERRNO_TABLE_SIZE 1200
484 /* target_to_host_errno_table[] is initialized from
485 * host_to_target_errno_table[] in syscall_init(). */
486 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
490 * This list is the union of errno values overridden in asm-<arch>/errno.h
491 * minus the errnos that are not actually generic to all archs.
493 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
494 [EAGAIN] = TARGET_EAGAIN,
495 [EIDRM] = TARGET_EIDRM,
496 [ECHRNG] = TARGET_ECHRNG,
497 [EL2NSYNC] = TARGET_EL2NSYNC,
498 [EL3HLT] = TARGET_EL3HLT,
499 [EL3RST] = TARGET_EL3RST,
500 [ELNRNG] = TARGET_ELNRNG,
501 [EUNATCH] = TARGET_EUNATCH,
502 [ENOCSI] = TARGET_ENOCSI,
503 [EL2HLT] = TARGET_EL2HLT,
504 [EDEADLK] = TARGET_EDEADLK,
505 [ENOLCK] = TARGET_ENOLCK,
506 [EBADE] = TARGET_EBADE,
507 [EBADR] = TARGET_EBADR,
508 [EXFULL] = TARGET_EXFULL,
509 [ENOANO] = TARGET_ENOANO,
510 [EBADRQC] = TARGET_EBADRQC,
511 [EBADSLT] = TARGET_EBADSLT,
512 [EBFONT] = TARGET_EBFONT,
513 [ENOSTR] = TARGET_ENOSTR,
514 [ENODATA] = TARGET_ENODATA,
515 [ETIME] = TARGET_ETIME,
516 [ENOSR] = TARGET_ENOSR,
517 [ENONET] = TARGET_ENONET,
518 [ENOPKG] = TARGET_ENOPKG,
519 [EREMOTE] = TARGET_EREMOTE,
520 [ENOLINK] = TARGET_ENOLINK,
521 [EADV] = TARGET_EADV,
522 [ESRMNT] = TARGET_ESRMNT,
523 [ECOMM] = TARGET_ECOMM,
524 [EPROTO] = TARGET_EPROTO,
525 [EDOTDOT] = TARGET_EDOTDOT,
526 [EMULTIHOP] = TARGET_EMULTIHOP,
527 [EBADMSG] = TARGET_EBADMSG,
528 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
529 [EOVERFLOW] = TARGET_EOVERFLOW,
530 [ENOTUNIQ] = TARGET_ENOTUNIQ,
531 [EBADFD] = TARGET_EBADFD,
532 [EREMCHG] = TARGET_EREMCHG,
533 [ELIBACC] = TARGET_ELIBACC,
534 [ELIBBAD] = TARGET_ELIBBAD,
535 [ELIBSCN] = TARGET_ELIBSCN,
536 [ELIBMAX] = TARGET_ELIBMAX,
537 [ELIBEXEC] = TARGET_ELIBEXEC,
538 [EILSEQ] = TARGET_EILSEQ,
539 [ENOSYS] = TARGET_ENOSYS,
540 [ELOOP] = TARGET_ELOOP,
541 [ERESTART] = TARGET_ERESTART,
542 [ESTRPIPE] = TARGET_ESTRPIPE,
543 [ENOTEMPTY] = TARGET_ENOTEMPTY,
544 [EUSERS] = TARGET_EUSERS,
545 [ENOTSOCK] = TARGET_ENOTSOCK,
546 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
547 [EMSGSIZE] = TARGET_EMSGSIZE,
548 [EPROTOTYPE] = TARGET_EPROTOTYPE,
549 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
550 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
551 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
552 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
553 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
554 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
555 [EADDRINUSE] = TARGET_EADDRINUSE,
556 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
557 [ENETDOWN] = TARGET_ENETDOWN,
558 [ENETUNREACH] = TARGET_ENETUNREACH,
559 [ENETRESET] = TARGET_ENETRESET,
560 [ECONNABORTED] = TARGET_ECONNABORTED,
561 [ECONNRESET] = TARGET_ECONNRESET,
562 [ENOBUFS] = TARGET_ENOBUFS,
563 [EISCONN] = TARGET_EISCONN,
564 [ENOTCONN] = TARGET_ENOTCONN,
565 [EUCLEAN] = TARGET_EUCLEAN,
566 [ENOTNAM] = TARGET_ENOTNAM,
567 [ENAVAIL] = TARGET_ENAVAIL,
568 [EISNAM] = TARGET_EISNAM,
569 [EREMOTEIO] = TARGET_EREMOTEIO,
570 [ESHUTDOWN] = TARGET_ESHUTDOWN,
571 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
572 [ETIMEDOUT] = TARGET_ETIMEDOUT,
573 [ECONNREFUSED] = TARGET_ECONNREFUSED,
574 [EHOSTDOWN] = TARGET_EHOSTDOWN,
575 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
576 [EALREADY] = TARGET_EALREADY,
577 [EINPROGRESS] = TARGET_EINPROGRESS,
578 [ESTALE] = TARGET_ESTALE,
579 [ECANCELED] = TARGET_ECANCELED,
580 [ENOMEDIUM] = TARGET_ENOMEDIUM,
581 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
582 #ifdef ENOKEY
583 [ENOKEY] = TARGET_ENOKEY,
584 #endif
585 #ifdef EKEYEXPIRED
586 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
587 #endif
588 #ifdef EKEYREVOKED
589 [EKEYREVOKED] = TARGET_EKEYREVOKED,
590 #endif
591 #ifdef EKEYREJECTED
592 [EKEYREJECTED] = TARGET_EKEYREJECTED,
593 #endif
594 #ifdef EOWNERDEAD
595 [EOWNERDEAD] = TARGET_EOWNERDEAD,
596 #endif
597 #ifdef ENOTRECOVERABLE
598 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
599 #endif
602 static inline int host_to_target_errno(int err)
604 if (err >= 0 && err < ERRNO_TABLE_SIZE &&
605 host_to_target_errno_table[err]) {
606 return host_to_target_errno_table[err];
608 return err;
611 static inline int target_to_host_errno(int err)
613 if (err >= 0 && err < ERRNO_TABLE_SIZE &&
614 target_to_host_errno_table[err]) {
615 return target_to_host_errno_table[err];
617 return err;
620 static inline abi_long get_errno(abi_long ret)
622 if (ret == -1)
623 return -host_to_target_errno(errno);
624 else
625 return ret;
628 static inline int is_error(abi_long ret)
630 return (abi_ulong)ret >= (abi_ulong)(-4096);
633 const char *target_strerror(int err)
635 if (err == TARGET_ERESTARTSYS) {
636 return "To be restarted";
638 if (err == TARGET_QEMU_ESIGRETURN) {
639 return "Successful exit from sigreturn";
642 if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
643 return NULL;
645 return strerror(target_to_host_errno(err));
648 #define safe_syscall0(type, name) \
649 static type safe_##name(void) \
651 return safe_syscall(__NR_##name); \
654 #define safe_syscall1(type, name, type1, arg1) \
655 static type safe_##name(type1 arg1) \
657 return safe_syscall(__NR_##name, arg1); \
660 #define safe_syscall2(type, name, type1, arg1, type2, arg2) \
661 static type safe_##name(type1 arg1, type2 arg2) \
663 return safe_syscall(__NR_##name, arg1, arg2); \
666 #define safe_syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
667 static type safe_##name(type1 arg1, type2 arg2, type3 arg3) \
669 return safe_syscall(__NR_##name, arg1, arg2, arg3); \
672 #define safe_syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \
673 type4, arg4) \
674 static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
676 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4); \
679 #define safe_syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \
680 type4, arg4, type5, arg5) \
681 static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
682 type5 arg5) \
684 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
687 #define safe_syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \
688 type4, arg4, type5, arg5, type6, arg6) \
689 static type safe_##name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
690 type5 arg5, type6 arg6) \
692 return safe_syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
695 safe_syscall3(ssize_t, read, int, fd, void *, buff, size_t, count)
696 safe_syscall3(ssize_t, write, int, fd, const void *, buff, size_t, count)
697 safe_syscall4(int, openat, int, dirfd, const char *, pathname, \
698 int, flags, mode_t, mode)
699 safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
700 struct rusage *, rusage)
701 safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
702 int, options, struct rusage *, rusage)
703 safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
704 safe_syscall6(int, pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, \
705 fd_set *, exceptfds, struct timespec *, timeout, void *, sig)
706 safe_syscall5(int, ppoll, struct pollfd *, ufds, unsigned int, nfds,
707 struct timespec *, tsp, const sigset_t *, sigmask,
708 size_t, sigsetsize)
709 safe_syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, events,
710 int, maxevents, int, timeout, const sigset_t *, sigmask,
711 size_t, sigsetsize)
712 safe_syscall6(int,futex,int *,uaddr,int,op,int,val, \
713 const struct timespec *,timeout,int *,uaddr2,int,val3)
714 safe_syscall2(int, rt_sigsuspend, sigset_t *, newset, size_t, sigsetsize)
715 safe_syscall2(int, kill, pid_t, pid, int, sig)
716 safe_syscall2(int, tkill, int, tid, int, sig)
717 safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
718 safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt)
719 safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt)
720 safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
721 socklen_t, addrlen)
722 safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
723 int, flags, const struct sockaddr *, addr, socklen_t, addrlen)
724 safe_syscall6(ssize_t, recvfrom, int, fd, void *, buf, size_t, len,
725 int, flags, struct sockaddr *, addr, socklen_t *, addrlen)
726 safe_syscall3(ssize_t, sendmsg, int, fd, const struct msghdr *, msg, int, flags)
727 safe_syscall3(ssize_t, recvmsg, int, fd, struct msghdr *, msg, int, flags)
728 safe_syscall2(int, flock, int, fd, int, operation)
729 safe_syscall4(int, rt_sigtimedwait, const sigset_t *, these, siginfo_t *, uinfo,
730 const struct timespec *, uts, size_t, sigsetsize)
731 safe_syscall4(int, accept4, int, fd, struct sockaddr *, addr, socklen_t *, len,
732 int, flags)
733 safe_syscall2(int, nanosleep, const struct timespec *, req,
734 struct timespec *, rem)
735 #ifdef TARGET_NR_clock_nanosleep
736 safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
737 const struct timespec *, req, struct timespec *, rem)
738 #endif
739 #ifdef __NR_msgsnd
740 safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
741 int, flags)
742 safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
743 long, msgtype, int, flags)
744 safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
745 unsigned, nsops, const struct timespec *, timeout)
746 #else
747 /* This host kernel architecture uses a single ipc syscall; fake up
748 * wrappers for the sub-operations to hide this implementation detail.
749 * Annoyingly we can't include linux/ipc.h to get the constant definitions
750 * for the call parameter because some structs in there conflict with the
751 * sys/ipc.h ones. So we just define them here, and rely on them being
752 * the same for all host architectures.
754 #define Q_SEMTIMEDOP 4
755 #define Q_MSGSND 11
756 #define Q_MSGRCV 12
757 #define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP))
759 safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
760 void *, ptr, long, fifth)
761 static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
763 return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
765 static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
767 return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
769 static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
770 const struct timespec *timeout)
772 return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops,
773 (long)timeout);
775 #endif
776 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
777 safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
778 size_t, len, unsigned, prio, const struct timespec *, timeout)
779 safe_syscall5(int, mq_timedreceive, int, mqdes, char *, msg_ptr,
780 size_t, len, unsigned *, prio, const struct timespec *, timeout)
781 #endif
782 /* We do ioctl like this rather than via safe_syscall3 to preserve the
783 * "third argument might be integer or pointer or not present" behaviour of
784 * the libc function.
786 #define safe_ioctl(...) safe_syscall(__NR_ioctl, __VA_ARGS__)
788 static inline int host_to_target_sock_type(int host_type)
790 int target_type;
792 switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
793 case SOCK_DGRAM:
794 target_type = TARGET_SOCK_DGRAM;
795 break;
796 case SOCK_STREAM:
797 target_type = TARGET_SOCK_STREAM;
798 break;
799 default:
800 target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
801 break;
804 #if defined(SOCK_CLOEXEC)
805 if (host_type & SOCK_CLOEXEC) {
806 target_type |= TARGET_SOCK_CLOEXEC;
808 #endif
810 #if defined(SOCK_NONBLOCK)
811 if (host_type & SOCK_NONBLOCK) {
812 target_type |= TARGET_SOCK_NONBLOCK;
814 #endif
816 return target_type;
819 static abi_ulong target_brk;
820 static abi_ulong target_original_brk;
821 static abi_ulong brk_page;
823 void target_set_brk(abi_ulong new_brk)
825 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
826 brk_page = HOST_PAGE_ALIGN(target_brk);
829 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
830 #define DEBUGF_BRK(message, args...)
832 /* do_brk() must return target values and target errnos. */
833 abi_long do_brk(abi_ulong new_brk)
835 abi_long mapped_addr;
836 int new_alloc_size;
838 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
840 if (!new_brk) {
841 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
842 return target_brk;
844 if (new_brk < target_original_brk) {
845 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
846 target_brk);
847 return target_brk;
850 /* If the new brk is less than the highest page reserved to the
851 * target heap allocation, set it and we're almost done... */
852 if (new_brk <= brk_page) {
853 /* Heap contents are initialized to zero, as for anonymous
854 * mapped pages. */
855 if (new_brk > target_brk) {
856 memset(g2h(target_brk), 0, new_brk - target_brk);
858 target_brk = new_brk;
859 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
860 return target_brk;
863 /* We need to allocate more memory after the brk... Note that
864 * we don't use MAP_FIXED because that will map over the top of
865 * any existing mapping (like the one with the host libc or qemu
866 * itself); instead we treat "mapped but at wrong address" as
867 * a failure and unmap again.
869 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
870 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
871 PROT_READ|PROT_WRITE,
872 MAP_ANON|MAP_PRIVATE, 0, 0));
874 if (mapped_addr == brk_page) {
875 /* Heap contents are initialized to zero, as for anonymous
876 * mapped pages. Technically the new pages are already
877 * initialized to zero since they *are* anonymous mapped
878 * pages, however we have to take care with the contents that
879 * come from the remaining part of the previous page: it may
880 * contains garbage data due to a previous heap usage (grown
881 * then shrunken). */
882 memset(g2h(target_brk), 0, brk_page - target_brk);
884 target_brk = new_brk;
885 brk_page = HOST_PAGE_ALIGN(target_brk);
886 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
887 target_brk);
888 return target_brk;
889 } else if (mapped_addr != -1) {
890 /* Mapped but at wrong address, meaning there wasn't actually
891 * enough space for this brk.
893 target_munmap(mapped_addr, new_alloc_size);
894 mapped_addr = -1;
895 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
897 else {
898 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
901 #if defined(TARGET_ALPHA)
902 /* We (partially) emulate OSF/1 on Alpha, which requires we
903 return a proper errno, not an unchanged brk value. */
904 return -TARGET_ENOMEM;
905 #endif
906 /* For everything else, return the previous break. */
907 return target_brk;
910 static inline abi_long copy_from_user_fdset(fd_set *fds,
911 abi_ulong target_fds_addr,
912 int n)
914 int i, nw, j, k;
915 abi_ulong b, *target_fds;
917 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
918 if (!(target_fds = lock_user(VERIFY_READ,
919 target_fds_addr,
920 sizeof(abi_ulong) * nw,
921 1)))
922 return -TARGET_EFAULT;
924 FD_ZERO(fds);
925 k = 0;
926 for (i = 0; i < nw; i++) {
927 /* grab the abi_ulong */
928 __get_user(b, &target_fds[i]);
929 for (j = 0; j < TARGET_ABI_BITS; j++) {
930 /* check the bit inside the abi_ulong */
931 if ((b >> j) & 1)
932 FD_SET(k, fds);
933 k++;
937 unlock_user(target_fds, target_fds_addr, 0);
939 return 0;
942 static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
943 abi_ulong target_fds_addr,
944 int n)
946 if (target_fds_addr) {
947 if (copy_from_user_fdset(fds, target_fds_addr, n))
948 return -TARGET_EFAULT;
949 *fds_ptr = fds;
950 } else {
951 *fds_ptr = NULL;
953 return 0;
956 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
957 const fd_set *fds,
958 int n)
960 int i, nw, j, k;
961 abi_long v;
962 abi_ulong *target_fds;
964 nw = DIV_ROUND_UP(n, TARGET_ABI_BITS);
965 if (!(target_fds = lock_user(VERIFY_WRITE,
966 target_fds_addr,
967 sizeof(abi_ulong) * nw,
968 0)))
969 return -TARGET_EFAULT;
971 k = 0;
972 for (i = 0; i < nw; i++) {
973 v = 0;
974 for (j = 0; j < TARGET_ABI_BITS; j++) {
975 v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
976 k++;
978 __put_user(v, &target_fds[i]);
981 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
983 return 0;
986 #if defined(__alpha__)
987 #define HOST_HZ 1024
988 #else
989 #define HOST_HZ 100
990 #endif
992 static inline abi_long host_to_target_clock_t(long ticks)
994 #if HOST_HZ == TARGET_HZ
995 return ticks;
996 #else
997 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
998 #endif
1001 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
1002 const struct rusage *rusage)
1004 struct target_rusage *target_rusage;
1006 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
1007 return -TARGET_EFAULT;
1008 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
1009 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
1010 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
1011 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
1012 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
1013 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
1014 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
1015 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
1016 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
1017 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
1018 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
1019 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
1020 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
1021 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
1022 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
1023 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
1024 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
1025 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
1026 unlock_user_struct(target_rusage, target_addr, 1);
1028 return 0;
1031 static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
1033 abi_ulong target_rlim_swap;
1034 rlim_t result;
1036 target_rlim_swap = tswapal(target_rlim);
1037 if (target_rlim_swap == TARGET_RLIM_INFINITY)
1038 return RLIM_INFINITY;
1040 result = target_rlim_swap;
1041 if (target_rlim_swap != (rlim_t)result)
1042 return RLIM_INFINITY;
1044 return result;
1047 static inline abi_ulong host_to_target_rlim(rlim_t rlim)
1049 abi_ulong target_rlim_swap;
1050 abi_ulong result;
1052 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
1053 target_rlim_swap = TARGET_RLIM_INFINITY;
1054 else
1055 target_rlim_swap = rlim;
1056 result = tswapal(target_rlim_swap);
1058 return result;
1061 static inline int target_to_host_resource(int code)
1063 switch (code) {
1064 case TARGET_RLIMIT_AS:
1065 return RLIMIT_AS;
1066 case TARGET_RLIMIT_CORE:
1067 return RLIMIT_CORE;
1068 case TARGET_RLIMIT_CPU:
1069 return RLIMIT_CPU;
1070 case TARGET_RLIMIT_DATA:
1071 return RLIMIT_DATA;
1072 case TARGET_RLIMIT_FSIZE:
1073 return RLIMIT_FSIZE;
1074 case TARGET_RLIMIT_LOCKS:
1075 return RLIMIT_LOCKS;
1076 case TARGET_RLIMIT_MEMLOCK:
1077 return RLIMIT_MEMLOCK;
1078 case TARGET_RLIMIT_MSGQUEUE:
1079 return RLIMIT_MSGQUEUE;
1080 case TARGET_RLIMIT_NICE:
1081 return RLIMIT_NICE;
1082 case TARGET_RLIMIT_NOFILE:
1083 return RLIMIT_NOFILE;
1084 case TARGET_RLIMIT_NPROC:
1085 return RLIMIT_NPROC;
1086 case TARGET_RLIMIT_RSS:
1087 return RLIMIT_RSS;
1088 case TARGET_RLIMIT_RTPRIO:
1089 return RLIMIT_RTPRIO;
1090 case TARGET_RLIMIT_SIGPENDING:
1091 return RLIMIT_SIGPENDING;
1092 case TARGET_RLIMIT_STACK:
1093 return RLIMIT_STACK;
1094 default:
1095 return code;
1099 static inline abi_long copy_from_user_timeval(struct timeval *tv,
1100 abi_ulong target_tv_addr)
1102 struct target_timeval *target_tv;
1104 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
1105 return -TARGET_EFAULT;
1107 __get_user(tv->tv_sec, &target_tv->tv_sec);
1108 __get_user(tv->tv_usec, &target_tv->tv_usec);
1110 unlock_user_struct(target_tv, target_tv_addr, 0);
1112 return 0;
1115 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
1116 const struct timeval *tv)
1118 struct target_timeval *target_tv;
1120 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
1121 return -TARGET_EFAULT;
1123 __put_user(tv->tv_sec, &target_tv->tv_sec);
1124 __put_user(tv->tv_usec, &target_tv->tv_usec);
1126 unlock_user_struct(target_tv, target_tv_addr, 1);
1128 return 0;
1131 static inline abi_long copy_from_user_timezone(struct timezone *tz,
1132 abi_ulong target_tz_addr)
1134 struct target_timezone *target_tz;
1136 if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
1137 return -TARGET_EFAULT;
1140 __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1141 __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1143 unlock_user_struct(target_tz, target_tz_addr, 0);
1145 return 0;
1148 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1149 #include <mqueue.h>
1151 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1152 abi_ulong target_mq_attr_addr)
1154 struct target_mq_attr *target_mq_attr;
1156 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1157 target_mq_attr_addr, 1))
1158 return -TARGET_EFAULT;
1160 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1161 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1162 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1163 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1165 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1167 return 0;
1170 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1171 const struct mq_attr *attr)
1173 struct target_mq_attr *target_mq_attr;
1175 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1176 target_mq_attr_addr, 0))
1177 return -TARGET_EFAULT;
1179 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1180 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1181 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1182 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1184 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1186 return 0;
1188 #endif
1190 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1191 /* do_select() must return target values and target errnos. */
1192 static abi_long do_select(int n,
1193 abi_ulong rfd_addr, abi_ulong wfd_addr,
1194 abi_ulong efd_addr, abi_ulong target_tv_addr)
1196 fd_set rfds, wfds, efds;
1197 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1198 struct timeval tv;
1199 struct timespec ts, *ts_ptr;
1200 abi_long ret;
1202 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1203 if (ret) {
1204 return ret;
1206 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1207 if (ret) {
1208 return ret;
1210 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1211 if (ret) {
1212 return ret;
1215 if (target_tv_addr) {
1216 if (copy_from_user_timeval(&tv, target_tv_addr))
1217 return -TARGET_EFAULT;
1218 ts.tv_sec = tv.tv_sec;
1219 ts.tv_nsec = tv.tv_usec * 1000;
1220 ts_ptr = &ts;
1221 } else {
1222 ts_ptr = NULL;
1225 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
1226 ts_ptr, NULL));
1228 if (!is_error(ret)) {
1229 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1230 return -TARGET_EFAULT;
1231 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1232 return -TARGET_EFAULT;
1233 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1234 return -TARGET_EFAULT;
1236 if (target_tv_addr) {
1237 tv.tv_sec = ts.tv_sec;
1238 tv.tv_usec = ts.tv_nsec / 1000;
1239 if (copy_to_user_timeval(target_tv_addr, &tv)) {
1240 return -TARGET_EFAULT;
1245 return ret;
1247 #endif
1249 static abi_long do_pipe2(int host_pipe[], int flags)
1251 #ifdef CONFIG_PIPE2
1252 return pipe2(host_pipe, flags);
1253 #else
1254 return -ENOSYS;
1255 #endif
1258 static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1259 int flags, int is_pipe2)
1261 int host_pipe[2];
1262 abi_long ret;
1263 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1265 if (is_error(ret))
1266 return get_errno(ret);
1268 /* Several targets have special calling conventions for the original
1269 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1270 if (!is_pipe2) {
1271 #if defined(TARGET_ALPHA)
1272 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1273 return host_pipe[0];
1274 #elif defined(TARGET_MIPS)
1275 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1276 return host_pipe[0];
1277 #elif defined(TARGET_SH4)
1278 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1279 return host_pipe[0];
1280 #elif defined(TARGET_SPARC)
1281 ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1282 return host_pipe[0];
1283 #endif
1286 if (put_user_s32(host_pipe[0], pipedes)
1287 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1288 return -TARGET_EFAULT;
1289 return get_errno(ret);
1292 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1293 abi_ulong target_addr,
1294 socklen_t len)
1296 struct target_ip_mreqn *target_smreqn;
1298 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1299 if (!target_smreqn)
1300 return -TARGET_EFAULT;
1301 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1302 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1303 if (len == sizeof(struct target_ip_mreqn))
1304 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1305 unlock_user(target_smreqn, target_addr, 0);
1307 return 0;
1310 static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
1311 abi_ulong target_addr,
1312 socklen_t len)
1314 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1315 sa_family_t sa_family;
1316 struct target_sockaddr *target_saddr;
1318 if (fd_trans_target_to_host_addr(fd)) {
1319 return fd_trans_target_to_host_addr(fd)(addr, target_addr, len);
1322 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1323 if (!target_saddr)
1324 return -TARGET_EFAULT;
1326 sa_family = tswap16(target_saddr->sa_family);
1328 /* Oops. The caller might send a incomplete sun_path; sun_path
1329 * must be terminated by \0 (see the manual page), but
1330 * unfortunately it is quite common to specify sockaddr_un
1331 * length as "strlen(x->sun_path)" while it should be
1332 * "strlen(...) + 1". We'll fix that here if needed.
1333 * Linux kernel has a similar feature.
1336 if (sa_family == AF_UNIX) {
1337 if (len < unix_maxlen && len > 0) {
1338 char *cp = (char*)target_saddr;
1340 if ( cp[len-1] && !cp[len] )
1341 len++;
1343 if (len > unix_maxlen)
1344 len = unix_maxlen;
1347 memcpy(addr, target_saddr, len);
1348 addr->sa_family = sa_family;
1349 if (sa_family == AF_NETLINK) {
1350 struct sockaddr_nl *nladdr;
1352 nladdr = (struct sockaddr_nl *)addr;
1353 nladdr->nl_pid = tswap32(nladdr->nl_pid);
1354 nladdr->nl_groups = tswap32(nladdr->nl_groups);
1355 } else if (sa_family == AF_PACKET) {
1356 struct target_sockaddr_ll *lladdr;
1358 lladdr = (struct target_sockaddr_ll *)addr;
1359 lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
1360 lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
1362 unlock_user(target_saddr, target_addr, 0);
1364 return 0;
1367 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1368 struct sockaddr *addr,
1369 socklen_t len)
1371 struct target_sockaddr *target_saddr;
1373 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1374 if (!target_saddr)
1375 return -TARGET_EFAULT;
1376 memcpy(target_saddr, addr, len);
1377 target_saddr->sa_family = tswap16(addr->sa_family);
1378 if (addr->sa_family == AF_NETLINK) {
1379 struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
1380 target_nl->nl_pid = tswap32(target_nl->nl_pid);
1381 target_nl->nl_groups = tswap32(target_nl->nl_groups);
1383 unlock_user(target_saddr, target_addr, len);
1385 return 0;
1388 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1389 struct target_msghdr *target_msgh)
1391 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1392 abi_long msg_controllen;
1393 abi_ulong target_cmsg_addr;
1394 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
1395 socklen_t space = 0;
1397 msg_controllen = tswapal(target_msgh->msg_controllen);
1398 if (msg_controllen < sizeof (struct target_cmsghdr))
1399 goto the_end;
1400 target_cmsg_addr = tswapal(target_msgh->msg_control);
1401 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1402 target_cmsg_start = target_cmsg;
1403 if (!target_cmsg)
1404 return -TARGET_EFAULT;
1406 while (cmsg && target_cmsg) {
1407 void *data = CMSG_DATA(cmsg);
1408 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1410 int len = tswapal(target_cmsg->cmsg_len)
1411 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1413 space += CMSG_SPACE(len);
1414 if (space > msgh->msg_controllen) {
1415 space -= CMSG_SPACE(len);
1416 /* This is a QEMU bug, since we allocated the payload
1417 * area ourselves (unlike overflow in host-to-target
1418 * conversion, which is just the guest giving us a buffer
1419 * that's too small). It can't happen for the payload types
1420 * we currently support; if it becomes an issue in future
1421 * we would need to improve our allocation strategy to
1422 * something more intelligent than "twice the size of the
1423 * target buffer we're reading from".
1425 gemu_log("Host cmsg overflow\n");
1426 break;
1429 if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1430 cmsg->cmsg_level = SOL_SOCKET;
1431 } else {
1432 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1434 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1435 cmsg->cmsg_len = CMSG_LEN(len);
1437 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
1438 int *fd = (int *)data;
1439 int *target_fd = (int *)target_data;
1440 int i, numfds = len / sizeof(int);
1442 for (i = 0; i < numfds; i++) {
1443 __get_user(fd[i], target_fd + i);
1445 } else if (cmsg->cmsg_level == SOL_SOCKET
1446 && cmsg->cmsg_type == SCM_CREDENTIALS) {
1447 struct ucred *cred = (struct ucred *)data;
1448 struct target_ucred *target_cred =
1449 (struct target_ucred *)target_data;
1451 __get_user(cred->pid, &target_cred->pid);
1452 __get_user(cred->uid, &target_cred->uid);
1453 __get_user(cred->gid, &target_cred->gid);
1454 } else {
1455 gemu_log("Unsupported ancillary data: %d/%d\n",
1456 cmsg->cmsg_level, cmsg->cmsg_type);
1457 memcpy(data, target_data, len);
1460 cmsg = CMSG_NXTHDR(msgh, cmsg);
1461 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1462 target_cmsg_start);
1464 unlock_user(target_cmsg, target_cmsg_addr, 0);
1465 the_end:
1466 msgh->msg_controllen = space;
1467 return 0;
1470 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1471 struct msghdr *msgh)
1473 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1474 abi_long msg_controllen;
1475 abi_ulong target_cmsg_addr;
1476 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
1477 socklen_t space = 0;
1479 msg_controllen = tswapal(target_msgh->msg_controllen);
1480 if (msg_controllen < sizeof (struct target_cmsghdr))
1481 goto the_end;
1482 target_cmsg_addr = tswapal(target_msgh->msg_control);
1483 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1484 target_cmsg_start = target_cmsg;
1485 if (!target_cmsg)
1486 return -TARGET_EFAULT;
1488 while (cmsg && target_cmsg) {
1489 void *data = CMSG_DATA(cmsg);
1490 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1492 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1493 int tgt_len, tgt_space;
1495 /* We never copy a half-header but may copy half-data;
1496 * this is Linux's behaviour in put_cmsg(). Note that
1497 * truncation here is a guest problem (which we report
1498 * to the guest via the CTRUNC bit), unlike truncation
1499 * in target_to_host_cmsg, which is a QEMU bug.
1501 if (msg_controllen < sizeof(struct cmsghdr)) {
1502 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
1503 break;
1506 if (cmsg->cmsg_level == SOL_SOCKET) {
1507 target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1508 } else {
1509 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1511 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1513 tgt_len = TARGET_CMSG_LEN(len);
1515 /* Payload types which need a different size of payload on
1516 * the target must adjust tgt_len here.
1518 switch (cmsg->cmsg_level) {
1519 case SOL_SOCKET:
1520 switch (cmsg->cmsg_type) {
1521 case SO_TIMESTAMP:
1522 tgt_len = sizeof(struct target_timeval);
1523 break;
1524 default:
1525 break;
1527 default:
1528 break;
1531 if (msg_controllen < tgt_len) {
1532 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
1533 tgt_len = msg_controllen;
1536 /* We must now copy-and-convert len bytes of payload
1537 * into tgt_len bytes of destination space. Bear in mind
1538 * that in both source and destination we may be dealing
1539 * with a truncated value!
1541 switch (cmsg->cmsg_level) {
1542 case SOL_SOCKET:
1543 switch (cmsg->cmsg_type) {
1544 case SCM_RIGHTS:
1546 int *fd = (int *)data;
1547 int *target_fd = (int *)target_data;
1548 int i, numfds = tgt_len / sizeof(int);
1550 for (i = 0; i < numfds; i++) {
1551 __put_user(fd[i], target_fd + i);
1553 break;
1555 case SO_TIMESTAMP:
1557 struct timeval *tv = (struct timeval *)data;
1558 struct target_timeval *target_tv =
1559 (struct target_timeval *)target_data;
1561 if (len != sizeof(struct timeval) ||
1562 tgt_len != sizeof(struct target_timeval)) {
1563 goto unimplemented;
1566 /* copy struct timeval to target */
1567 __put_user(tv->tv_sec, &target_tv->tv_sec);
1568 __put_user(tv->tv_usec, &target_tv->tv_usec);
1569 break;
1571 case SCM_CREDENTIALS:
1573 struct ucred *cred = (struct ucred *)data;
1574 struct target_ucred *target_cred =
1575 (struct target_ucred *)target_data;
1577 __put_user(cred->pid, &target_cred->pid);
1578 __put_user(cred->uid, &target_cred->uid);
1579 __put_user(cred->gid, &target_cred->gid);
1580 break;
1582 default:
1583 goto unimplemented;
1585 break;
1587 default:
1588 unimplemented:
1589 gemu_log("Unsupported ancillary data: %d/%d\n",
1590 cmsg->cmsg_level, cmsg->cmsg_type);
1591 memcpy(target_data, data, MIN(len, tgt_len));
1592 if (tgt_len > len) {
1593 memset(target_data + len, 0, tgt_len - len);
1597 target_cmsg->cmsg_len = tswapal(tgt_len);
1598 tgt_space = TARGET_CMSG_SPACE(len);
1599 if (msg_controllen < tgt_space) {
1600 tgt_space = msg_controllen;
1602 msg_controllen -= tgt_space;
1603 space += tgt_space;
1604 cmsg = CMSG_NXTHDR(msgh, cmsg);
1605 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1606 target_cmsg_start);
1608 unlock_user(target_cmsg, target_cmsg_addr, space);
1609 the_end:
1610 target_msgh->msg_controllen = tswapal(space);
1611 return 0;
1614 static void tswap_nlmsghdr(struct nlmsghdr *nlh)
1616 nlh->nlmsg_len = tswap32(nlh->nlmsg_len);
1617 nlh->nlmsg_type = tswap16(nlh->nlmsg_type);
1618 nlh->nlmsg_flags = tswap16(nlh->nlmsg_flags);
1619 nlh->nlmsg_seq = tswap32(nlh->nlmsg_seq);
1620 nlh->nlmsg_pid = tswap32(nlh->nlmsg_pid);
1623 static abi_long host_to_target_for_each_nlmsg(struct nlmsghdr *nlh,
1624 size_t len,
1625 abi_long (*host_to_target_nlmsg)
1626 (struct nlmsghdr *))
1628 uint32_t nlmsg_len;
1629 abi_long ret;
1631 while (len > sizeof(struct nlmsghdr)) {
1633 nlmsg_len = nlh->nlmsg_len;
1634 if (nlmsg_len < sizeof(struct nlmsghdr) ||
1635 nlmsg_len > len) {
1636 break;
1639 switch (nlh->nlmsg_type) {
1640 case NLMSG_DONE:
1641 tswap_nlmsghdr(nlh);
1642 return 0;
1643 case NLMSG_NOOP:
1644 break;
1645 case NLMSG_ERROR:
1647 struct nlmsgerr *e = NLMSG_DATA(nlh);
1648 e->error = tswap32(e->error);
1649 tswap_nlmsghdr(&e->msg);
1650 tswap_nlmsghdr(nlh);
1651 return 0;
1653 default:
1654 ret = host_to_target_nlmsg(nlh);
1655 if (ret < 0) {
1656 tswap_nlmsghdr(nlh);
1657 return ret;
1659 break;
1661 tswap_nlmsghdr(nlh);
1662 len -= NLMSG_ALIGN(nlmsg_len);
1663 nlh = (struct nlmsghdr *)(((char*)nlh) + NLMSG_ALIGN(nlmsg_len));
1665 return 0;
1668 static abi_long target_to_host_for_each_nlmsg(struct nlmsghdr *nlh,
1669 size_t len,
1670 abi_long (*target_to_host_nlmsg)
1671 (struct nlmsghdr *))
1673 int ret;
1675 while (len > sizeof(struct nlmsghdr)) {
1676 if (tswap32(nlh->nlmsg_len) < sizeof(struct nlmsghdr) ||
1677 tswap32(nlh->nlmsg_len) > len) {
1678 break;
1680 tswap_nlmsghdr(nlh);
1681 switch (nlh->nlmsg_type) {
1682 case NLMSG_DONE:
1683 return 0;
1684 case NLMSG_NOOP:
1685 break;
1686 case NLMSG_ERROR:
1688 struct nlmsgerr *e = NLMSG_DATA(nlh);
1689 e->error = tswap32(e->error);
1690 tswap_nlmsghdr(&e->msg);
1692 default:
1693 ret = target_to_host_nlmsg(nlh);
1694 if (ret < 0) {
1695 return ret;
1698 len -= NLMSG_ALIGN(nlh->nlmsg_len);
1699 nlh = (struct nlmsghdr *)(((char *)nlh) + NLMSG_ALIGN(nlh->nlmsg_len));
1701 return 0;
1704 #ifdef CONFIG_RTNETLINK
1705 static abi_long host_to_target_for_each_rtattr(struct rtattr *rtattr,
1706 size_t len,
1707 abi_long (*host_to_target_rtattr)
1708 (struct rtattr *))
1710 unsigned short rta_len;
1711 abi_long ret;
1713 while (len > sizeof(struct rtattr)) {
1714 rta_len = rtattr->rta_len;
1715 if (rta_len < sizeof(struct rtattr) ||
1716 rta_len > len) {
1717 break;
1719 ret = host_to_target_rtattr(rtattr);
1720 rtattr->rta_len = tswap16(rtattr->rta_len);
1721 rtattr->rta_type = tswap16(rtattr->rta_type);
1722 if (ret < 0) {
1723 return ret;
1725 len -= RTA_ALIGN(rta_len);
1726 rtattr = (struct rtattr *)(((char *)rtattr) + RTA_ALIGN(rta_len));
1728 return 0;
1731 static abi_long host_to_target_data_link_rtattr(struct rtattr *rtattr)
1733 uint32_t *u32;
1734 struct rtnl_link_stats *st;
1735 struct rtnl_link_stats64 *st64;
1736 struct rtnl_link_ifmap *map;
1738 switch (rtattr->rta_type) {
1739 /* binary stream */
1740 case IFLA_ADDRESS:
1741 case IFLA_BROADCAST:
1742 /* string */
1743 case IFLA_IFNAME:
1744 case IFLA_QDISC:
1745 break;
1746 /* uin8_t */
1747 case IFLA_OPERSTATE:
1748 case IFLA_LINKMODE:
1749 case IFLA_CARRIER:
1750 case IFLA_PROTO_DOWN:
1751 break;
1752 /* uint32_t */
1753 case IFLA_MTU:
1754 case IFLA_LINK:
1755 case IFLA_WEIGHT:
1756 case IFLA_TXQLEN:
1757 case IFLA_CARRIER_CHANGES:
1758 case IFLA_NUM_RX_QUEUES:
1759 case IFLA_NUM_TX_QUEUES:
1760 case IFLA_PROMISCUITY:
1761 case IFLA_EXT_MASK:
1762 case IFLA_LINK_NETNSID:
1763 case IFLA_GROUP:
1764 case IFLA_MASTER:
1765 case IFLA_NUM_VF:
1766 u32 = RTA_DATA(rtattr);
1767 *u32 = tswap32(*u32);
1768 break;
1769 /* struct rtnl_link_stats */
1770 case IFLA_STATS:
1771 st = RTA_DATA(rtattr);
1772 st->rx_packets = tswap32(st->rx_packets);
1773 st->tx_packets = tswap32(st->tx_packets);
1774 st->rx_bytes = tswap32(st->rx_bytes);
1775 st->tx_bytes = tswap32(st->tx_bytes);
1776 st->rx_errors = tswap32(st->rx_errors);
1777 st->tx_errors = tswap32(st->tx_errors);
1778 st->rx_dropped = tswap32(st->rx_dropped);
1779 st->tx_dropped = tswap32(st->tx_dropped);
1780 st->multicast = tswap32(st->multicast);
1781 st->collisions = tswap32(st->collisions);
1783 /* detailed rx_errors: */
1784 st->rx_length_errors = tswap32(st->rx_length_errors);
1785 st->rx_over_errors = tswap32(st->rx_over_errors);
1786 st->rx_crc_errors = tswap32(st->rx_crc_errors);
1787 st->rx_frame_errors = tswap32(st->rx_frame_errors);
1788 st->rx_fifo_errors = tswap32(st->rx_fifo_errors);
1789 st->rx_missed_errors = tswap32(st->rx_missed_errors);
1791 /* detailed tx_errors */
1792 st->tx_aborted_errors = tswap32(st->tx_aborted_errors);
1793 st->tx_carrier_errors = tswap32(st->tx_carrier_errors);
1794 st->tx_fifo_errors = tswap32(st->tx_fifo_errors);
1795 st->tx_heartbeat_errors = tswap32(st->tx_heartbeat_errors);
1796 st->tx_window_errors = tswap32(st->tx_window_errors);
1798 /* for cslip etc */
1799 st->rx_compressed = tswap32(st->rx_compressed);
1800 st->tx_compressed = tswap32(st->tx_compressed);
1801 break;
1802 /* struct rtnl_link_stats64 */
1803 case IFLA_STATS64:
1804 st64 = RTA_DATA(rtattr);
1805 st64->rx_packets = tswap64(st64->rx_packets);
1806 st64->tx_packets = tswap64(st64->tx_packets);
1807 st64->rx_bytes = tswap64(st64->rx_bytes);
1808 st64->tx_bytes = tswap64(st64->tx_bytes);
1809 st64->rx_errors = tswap64(st64->rx_errors);
1810 st64->tx_errors = tswap64(st64->tx_errors);
1811 st64->rx_dropped = tswap64(st64->rx_dropped);
1812 st64->tx_dropped = tswap64(st64->tx_dropped);
1813 st64->multicast = tswap64(st64->multicast);
1814 st64->collisions = tswap64(st64->collisions);
1816 /* detailed rx_errors: */
1817 st64->rx_length_errors = tswap64(st64->rx_length_errors);
1818 st64->rx_over_errors = tswap64(st64->rx_over_errors);
1819 st64->rx_crc_errors = tswap64(st64->rx_crc_errors);
1820 st64->rx_frame_errors = tswap64(st64->rx_frame_errors);
1821 st64->rx_fifo_errors = tswap64(st64->rx_fifo_errors);
1822 st64->rx_missed_errors = tswap64(st64->rx_missed_errors);
1824 /* detailed tx_errors */
1825 st64->tx_aborted_errors = tswap64(st64->tx_aborted_errors);
1826 st64->tx_carrier_errors = tswap64(st64->tx_carrier_errors);
1827 st64->tx_fifo_errors = tswap64(st64->tx_fifo_errors);
1828 st64->tx_heartbeat_errors = tswap64(st64->tx_heartbeat_errors);
1829 st64->tx_window_errors = tswap64(st64->tx_window_errors);
1831 /* for cslip etc */
1832 st64->rx_compressed = tswap64(st64->rx_compressed);
1833 st64->tx_compressed = tswap64(st64->tx_compressed);
1834 break;
1835 /* struct rtnl_link_ifmap */
1836 case IFLA_MAP:
1837 map = RTA_DATA(rtattr);
1838 map->mem_start = tswap64(map->mem_start);
1839 map->mem_end = tswap64(map->mem_end);
1840 map->base_addr = tswap64(map->base_addr);
1841 map->irq = tswap16(map->irq);
1842 break;
1843 /* nested */
1844 case IFLA_AF_SPEC:
1845 case IFLA_LINKINFO:
1846 /* FIXME: implement nested type */
1847 gemu_log("Unimplemented nested type %d\n", rtattr->rta_type);
1848 break;
1849 default:
1850 gemu_log("Unknown host IFLA type: %d\n", rtattr->rta_type);
1851 break;
1853 return 0;
1856 static abi_long host_to_target_data_addr_rtattr(struct rtattr *rtattr)
1858 uint32_t *u32;
1859 struct ifa_cacheinfo *ci;
1861 switch (rtattr->rta_type) {
1862 /* binary: depends on family type */
1863 case IFA_ADDRESS:
1864 case IFA_LOCAL:
1865 break;
1866 /* string */
1867 case IFA_LABEL:
1868 break;
1869 /* u32 */
1870 case IFA_FLAGS:
1871 case IFA_BROADCAST:
1872 u32 = RTA_DATA(rtattr);
1873 *u32 = tswap32(*u32);
1874 break;
1875 /* struct ifa_cacheinfo */
1876 case IFA_CACHEINFO:
1877 ci = RTA_DATA(rtattr);
1878 ci->ifa_prefered = tswap32(ci->ifa_prefered);
1879 ci->ifa_valid = tswap32(ci->ifa_valid);
1880 ci->cstamp = tswap32(ci->cstamp);
1881 ci->tstamp = tswap32(ci->tstamp);
1882 break;
1883 default:
1884 gemu_log("Unknown host IFA type: %d\n", rtattr->rta_type);
1885 break;
1887 return 0;
1890 static abi_long host_to_target_data_route_rtattr(struct rtattr *rtattr)
1892 uint32_t *u32;
1893 switch (rtattr->rta_type) {
1894 /* binary: depends on family type */
1895 case RTA_GATEWAY:
1896 case RTA_DST:
1897 case RTA_PREFSRC:
1898 break;
1899 /* u32 */
1900 case RTA_PRIORITY:
1901 case RTA_TABLE:
1902 case RTA_OIF:
1903 u32 = RTA_DATA(rtattr);
1904 *u32 = tswap32(*u32);
1905 break;
1906 default:
1907 gemu_log("Unknown host RTA type: %d\n", rtattr->rta_type);
1908 break;
1910 return 0;
1913 static abi_long host_to_target_link_rtattr(struct rtattr *rtattr,
1914 uint32_t rtattr_len)
1916 return host_to_target_for_each_rtattr(rtattr, rtattr_len,
1917 host_to_target_data_link_rtattr);
1920 static abi_long host_to_target_addr_rtattr(struct rtattr *rtattr,
1921 uint32_t rtattr_len)
1923 return host_to_target_for_each_rtattr(rtattr, rtattr_len,
1924 host_to_target_data_addr_rtattr);
1927 static abi_long host_to_target_route_rtattr(struct rtattr *rtattr,
1928 uint32_t rtattr_len)
1930 return host_to_target_for_each_rtattr(rtattr, rtattr_len,
1931 host_to_target_data_route_rtattr);
1934 static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
1936 uint32_t nlmsg_len;
1937 struct ifinfomsg *ifi;
1938 struct ifaddrmsg *ifa;
1939 struct rtmsg *rtm;
1941 nlmsg_len = nlh->nlmsg_len;
1942 switch (nlh->nlmsg_type) {
1943 case RTM_NEWLINK:
1944 case RTM_DELLINK:
1945 case RTM_GETLINK:
1946 ifi = NLMSG_DATA(nlh);
1947 ifi->ifi_type = tswap16(ifi->ifi_type);
1948 ifi->ifi_index = tswap32(ifi->ifi_index);
1949 ifi->ifi_flags = tswap32(ifi->ifi_flags);
1950 ifi->ifi_change = tswap32(ifi->ifi_change);
1951 host_to_target_link_rtattr(IFLA_RTA(ifi),
1952 nlmsg_len - NLMSG_LENGTH(sizeof(*ifi)));
1953 break;
1954 case RTM_NEWADDR:
1955 case RTM_DELADDR:
1956 case RTM_GETADDR:
1957 ifa = NLMSG_DATA(nlh);
1958 ifa->ifa_index = tswap32(ifa->ifa_index);
1959 host_to_target_addr_rtattr(IFA_RTA(ifa),
1960 nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
1961 break;
1962 case RTM_NEWROUTE:
1963 case RTM_DELROUTE:
1964 case RTM_GETROUTE:
1965 rtm = NLMSG_DATA(nlh);
1966 rtm->rtm_flags = tswap32(rtm->rtm_flags);
1967 host_to_target_route_rtattr(RTM_RTA(rtm),
1968 nlmsg_len - NLMSG_LENGTH(sizeof(*rtm)));
1969 break;
1970 default:
1971 return -TARGET_EINVAL;
1973 return 0;
1976 static inline abi_long host_to_target_nlmsg_route(struct nlmsghdr *nlh,
1977 size_t len)
1979 return host_to_target_for_each_nlmsg(nlh, len, host_to_target_data_route);
1982 static abi_long target_to_host_for_each_rtattr(struct rtattr *rtattr,
1983 size_t len,
1984 abi_long (*target_to_host_rtattr)
1985 (struct rtattr *))
1987 abi_long ret;
1989 while (len >= sizeof(struct rtattr)) {
1990 if (tswap16(rtattr->rta_len) < sizeof(struct rtattr) ||
1991 tswap16(rtattr->rta_len) > len) {
1992 break;
1994 rtattr->rta_len = tswap16(rtattr->rta_len);
1995 rtattr->rta_type = tswap16(rtattr->rta_type);
1996 ret = target_to_host_rtattr(rtattr);
1997 if (ret < 0) {
1998 return ret;
2000 len -= RTA_ALIGN(rtattr->rta_len);
2001 rtattr = (struct rtattr *)(((char *)rtattr) +
2002 RTA_ALIGN(rtattr->rta_len));
2004 return 0;
2007 static abi_long target_to_host_data_link_rtattr(struct rtattr *rtattr)
2009 switch (rtattr->rta_type) {
2010 default:
2011 gemu_log("Unknown target IFLA type: %d\n", rtattr->rta_type);
2012 break;
2014 return 0;
2017 static abi_long target_to_host_data_addr_rtattr(struct rtattr *rtattr)
2019 switch (rtattr->rta_type) {
2020 /* binary: depends on family type */
2021 case IFA_LOCAL:
2022 case IFA_ADDRESS:
2023 break;
2024 default:
2025 gemu_log("Unknown target IFA type: %d\n", rtattr->rta_type);
2026 break;
2028 return 0;
2031 static abi_long target_to_host_data_route_rtattr(struct rtattr *rtattr)
2033 uint32_t *u32;
2034 switch (rtattr->rta_type) {
2035 /* binary: depends on family type */
2036 case RTA_DST:
2037 case RTA_SRC:
2038 case RTA_GATEWAY:
2039 break;
2040 /* u32 */
2041 case RTA_OIF:
2042 u32 = RTA_DATA(rtattr);
2043 *u32 = tswap32(*u32);
2044 break;
2045 default:
2046 gemu_log("Unknown target RTA type: %d\n", rtattr->rta_type);
2047 break;
2049 return 0;
2052 static void target_to_host_link_rtattr(struct rtattr *rtattr,
2053 uint32_t rtattr_len)
2055 target_to_host_for_each_rtattr(rtattr, rtattr_len,
2056 target_to_host_data_link_rtattr);
2059 static void target_to_host_addr_rtattr(struct rtattr *rtattr,
2060 uint32_t rtattr_len)
2062 target_to_host_for_each_rtattr(rtattr, rtattr_len,
2063 target_to_host_data_addr_rtattr);
2066 static void target_to_host_route_rtattr(struct rtattr *rtattr,
2067 uint32_t rtattr_len)
2069 target_to_host_for_each_rtattr(rtattr, rtattr_len,
2070 target_to_host_data_route_rtattr);
2073 static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
2075 struct ifinfomsg *ifi;
2076 struct ifaddrmsg *ifa;
2077 struct rtmsg *rtm;
2079 switch (nlh->nlmsg_type) {
2080 case RTM_GETLINK:
2081 break;
2082 case RTM_NEWLINK:
2083 case RTM_DELLINK:
2084 ifi = NLMSG_DATA(nlh);
2085 ifi->ifi_type = tswap16(ifi->ifi_type);
2086 ifi->ifi_index = tswap32(ifi->ifi_index);
2087 ifi->ifi_flags = tswap32(ifi->ifi_flags);
2088 ifi->ifi_change = tswap32(ifi->ifi_change);
2089 target_to_host_link_rtattr(IFLA_RTA(ifi), nlh->nlmsg_len -
2090 NLMSG_LENGTH(sizeof(*ifi)));
2091 break;
2092 case RTM_GETADDR:
2093 case RTM_NEWADDR:
2094 case RTM_DELADDR:
2095 ifa = NLMSG_DATA(nlh);
2096 ifa->ifa_index = tswap32(ifa->ifa_index);
2097 target_to_host_addr_rtattr(IFA_RTA(ifa), nlh->nlmsg_len -
2098 NLMSG_LENGTH(sizeof(*ifa)));
2099 break;
2100 case RTM_GETROUTE:
2101 break;
2102 case RTM_NEWROUTE:
2103 case RTM_DELROUTE:
2104 rtm = NLMSG_DATA(nlh);
2105 rtm->rtm_flags = tswap32(rtm->rtm_flags);
2106 target_to_host_route_rtattr(RTM_RTA(rtm), nlh->nlmsg_len -
2107 NLMSG_LENGTH(sizeof(*rtm)));
2108 break;
2109 default:
2110 return -TARGET_EOPNOTSUPP;
2112 return 0;
2115 static abi_long target_to_host_nlmsg_route(struct nlmsghdr *nlh, size_t len)
2117 return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_route);
2119 #endif /* CONFIG_RTNETLINK */
2121 static abi_long host_to_target_data_audit(struct nlmsghdr *nlh)
2123 switch (nlh->nlmsg_type) {
2124 default:
2125 gemu_log("Unknown host audit message type %d\n",
2126 nlh->nlmsg_type);
2127 return -TARGET_EINVAL;
2129 return 0;
2132 static inline abi_long host_to_target_nlmsg_audit(struct nlmsghdr *nlh,
2133 size_t len)
2135 return host_to_target_for_each_nlmsg(nlh, len, host_to_target_data_audit);
2138 static abi_long target_to_host_data_audit(struct nlmsghdr *nlh)
2140 switch (nlh->nlmsg_type) {
2141 case AUDIT_USER:
2142 case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
2143 case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
2144 break;
2145 default:
2146 gemu_log("Unknown target audit message type %d\n",
2147 nlh->nlmsg_type);
2148 return -TARGET_EINVAL;
2151 return 0;
2154 static abi_long target_to_host_nlmsg_audit(struct nlmsghdr *nlh, size_t len)
2156 return target_to_host_for_each_nlmsg(nlh, len, target_to_host_data_audit);
2159 /* do_setsockopt() Must return target values and target errnos. */
2160 static abi_long do_setsockopt(int sockfd, int level, int optname,
2161 abi_ulong optval_addr, socklen_t optlen)
2163 abi_long ret;
2164 int val;
2165 struct ip_mreqn *ip_mreq;
2166 struct ip_mreq_source *ip_mreq_source;
2168 switch(level) {
2169 case SOL_TCP:
2170 /* TCP options all take an 'int' value. */
2171 if (optlen < sizeof(uint32_t))
2172 return -TARGET_EINVAL;
2174 if (get_user_u32(val, optval_addr))
2175 return -TARGET_EFAULT;
2176 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
2177 break;
2178 case SOL_IP:
2179 switch(optname) {
2180 case IP_TOS:
2181 case IP_TTL:
2182 case IP_HDRINCL:
2183 case IP_ROUTER_ALERT:
2184 case IP_RECVOPTS:
2185 case IP_RETOPTS:
2186 case IP_PKTINFO:
2187 case IP_MTU_DISCOVER:
2188 case IP_RECVERR:
2189 case IP_RECVTOS:
2190 #ifdef IP_FREEBIND
2191 case IP_FREEBIND:
2192 #endif
2193 case IP_MULTICAST_TTL:
2194 case IP_MULTICAST_LOOP:
2195 val = 0;
2196 if (optlen >= sizeof(uint32_t)) {
2197 if (get_user_u32(val, optval_addr))
2198 return -TARGET_EFAULT;
2199 } else if (optlen >= 1) {
2200 if (get_user_u8(val, optval_addr))
2201 return -TARGET_EFAULT;
2203 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
2204 break;
2205 case IP_ADD_MEMBERSHIP:
2206 case IP_DROP_MEMBERSHIP:
2207 if (optlen < sizeof (struct target_ip_mreq) ||
2208 optlen > sizeof (struct target_ip_mreqn))
2209 return -TARGET_EINVAL;
2211 ip_mreq = (struct ip_mreqn *) alloca(optlen);
2212 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
2213 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
2214 break;
2216 case IP_BLOCK_SOURCE:
2217 case IP_UNBLOCK_SOURCE:
2218 case IP_ADD_SOURCE_MEMBERSHIP:
2219 case IP_DROP_SOURCE_MEMBERSHIP:
2220 if (optlen != sizeof (struct target_ip_mreq_source))
2221 return -TARGET_EINVAL;
2223 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2224 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
2225 unlock_user (ip_mreq_source, optval_addr, 0);
2226 break;
2228 default:
2229 goto unimplemented;
2231 break;
2232 case SOL_IPV6:
2233 switch (optname) {
2234 case IPV6_MTU_DISCOVER:
2235 case IPV6_MTU:
2236 case IPV6_V6ONLY:
2237 case IPV6_RECVPKTINFO:
2238 val = 0;
2239 if (optlen < sizeof(uint32_t)) {
2240 return -TARGET_EINVAL;
2242 if (get_user_u32(val, optval_addr)) {
2243 return -TARGET_EFAULT;
2245 ret = get_errno(setsockopt(sockfd, level, optname,
2246 &val, sizeof(val)));
2247 break;
2248 default:
2249 goto unimplemented;
2251 break;
2252 case SOL_RAW:
2253 switch (optname) {
2254 case ICMP_FILTER:
2255 /* struct icmp_filter takes an u32 value */
2256 if (optlen < sizeof(uint32_t)) {
2257 return -TARGET_EINVAL;
2260 if (get_user_u32(val, optval_addr)) {
2261 return -TARGET_EFAULT;
2263 ret = get_errno(setsockopt(sockfd, level, optname,
2264 &val, sizeof(val)));
2265 break;
2267 default:
2268 goto unimplemented;
2270 break;
2271 case TARGET_SOL_SOCKET:
2272 switch (optname) {
2273 case TARGET_SO_RCVTIMEO:
2275 struct timeval tv;
2277 optname = SO_RCVTIMEO;
2279 set_timeout:
2280 if (optlen != sizeof(struct target_timeval)) {
2281 return -TARGET_EINVAL;
2284 if (copy_from_user_timeval(&tv, optval_addr)) {
2285 return -TARGET_EFAULT;
2288 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2289 &tv, sizeof(tv)));
2290 return ret;
2292 case TARGET_SO_SNDTIMEO:
2293 optname = SO_SNDTIMEO;
2294 goto set_timeout;
2295 case TARGET_SO_ATTACH_FILTER:
2297 struct target_sock_fprog *tfprog;
2298 struct target_sock_filter *tfilter;
2299 struct sock_fprog fprog;
2300 struct sock_filter *filter;
2301 int i;
2303 if (optlen != sizeof(*tfprog)) {
2304 return -TARGET_EINVAL;
2306 if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
2307 return -TARGET_EFAULT;
2309 if (!lock_user_struct(VERIFY_READ, tfilter,
2310 tswapal(tfprog->filter), 0)) {
2311 unlock_user_struct(tfprog, optval_addr, 1);
2312 return -TARGET_EFAULT;
2315 fprog.len = tswap16(tfprog->len);
2316 filter = g_try_new(struct sock_filter, fprog.len);
2317 if (filter == NULL) {
2318 unlock_user_struct(tfilter, tfprog->filter, 1);
2319 unlock_user_struct(tfprog, optval_addr, 1);
2320 return -TARGET_ENOMEM;
2322 for (i = 0; i < fprog.len; i++) {
2323 filter[i].code = tswap16(tfilter[i].code);
2324 filter[i].jt = tfilter[i].jt;
2325 filter[i].jf = tfilter[i].jf;
2326 filter[i].k = tswap32(tfilter[i].k);
2328 fprog.filter = filter;
2330 ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
2331 SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
2332 g_free(filter);
2334 unlock_user_struct(tfilter, tfprog->filter, 1);
2335 unlock_user_struct(tfprog, optval_addr, 1);
2336 return ret;
2338 case TARGET_SO_BINDTODEVICE:
2340 char *dev_ifname, *addr_ifname;
2342 if (optlen > IFNAMSIZ - 1) {
2343 optlen = IFNAMSIZ - 1;
2345 dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
2346 if (!dev_ifname) {
2347 return -TARGET_EFAULT;
2349 optname = SO_BINDTODEVICE;
2350 addr_ifname = alloca(IFNAMSIZ);
2351 memcpy(addr_ifname, dev_ifname, optlen);
2352 addr_ifname[optlen] = 0;
2353 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
2354 addr_ifname, optlen));
2355 unlock_user (dev_ifname, optval_addr, 0);
2356 return ret;
2358 /* Options with 'int' argument. */
2359 case TARGET_SO_DEBUG:
2360 optname = SO_DEBUG;
2361 break;
2362 case TARGET_SO_REUSEADDR:
2363 optname = SO_REUSEADDR;
2364 break;
2365 case TARGET_SO_TYPE:
2366 optname = SO_TYPE;
2367 break;
2368 case TARGET_SO_ERROR:
2369 optname = SO_ERROR;
2370 break;
2371 case TARGET_SO_DONTROUTE:
2372 optname = SO_DONTROUTE;
2373 break;
2374 case TARGET_SO_BROADCAST:
2375 optname = SO_BROADCAST;
2376 break;
2377 case TARGET_SO_SNDBUF:
2378 optname = SO_SNDBUF;
2379 break;
2380 case TARGET_SO_SNDBUFFORCE:
2381 optname = SO_SNDBUFFORCE;
2382 break;
2383 case TARGET_SO_RCVBUF:
2384 optname = SO_RCVBUF;
2385 break;
2386 case TARGET_SO_RCVBUFFORCE:
2387 optname = SO_RCVBUFFORCE;
2388 break;
2389 case TARGET_SO_KEEPALIVE:
2390 optname = SO_KEEPALIVE;
2391 break;
2392 case TARGET_SO_OOBINLINE:
2393 optname = SO_OOBINLINE;
2394 break;
2395 case TARGET_SO_NO_CHECK:
2396 optname = SO_NO_CHECK;
2397 break;
2398 case TARGET_SO_PRIORITY:
2399 optname = SO_PRIORITY;
2400 break;
2401 #ifdef SO_BSDCOMPAT
2402 case TARGET_SO_BSDCOMPAT:
2403 optname = SO_BSDCOMPAT;
2404 break;
2405 #endif
2406 case TARGET_SO_PASSCRED:
2407 optname = SO_PASSCRED;
2408 break;
2409 case TARGET_SO_PASSSEC:
2410 optname = SO_PASSSEC;
2411 break;
2412 case TARGET_SO_TIMESTAMP:
2413 optname = SO_TIMESTAMP;
2414 break;
2415 case TARGET_SO_RCVLOWAT:
2416 optname = SO_RCVLOWAT;
2417 break;
2418 break;
2419 default:
2420 goto unimplemented;
2422 if (optlen < sizeof(uint32_t))
2423 return -TARGET_EINVAL;
2425 if (get_user_u32(val, optval_addr))
2426 return -TARGET_EFAULT;
2427 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
2428 break;
2429 default:
2430 unimplemented:
2431 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
2432 ret = -TARGET_ENOPROTOOPT;
2434 return ret;
2437 /* do_getsockopt() Must return target values and target errnos. */
2438 static abi_long do_getsockopt(int sockfd, int level, int optname,
2439 abi_ulong optval_addr, abi_ulong optlen)
2441 abi_long ret;
2442 int len, val;
2443 socklen_t lv;
2445 switch(level) {
2446 case TARGET_SOL_SOCKET:
2447 level = SOL_SOCKET;
2448 switch (optname) {
2449 /* These don't just return a single integer */
2450 case TARGET_SO_LINGER:
2451 case TARGET_SO_RCVTIMEO:
2452 case TARGET_SO_SNDTIMEO:
2453 case TARGET_SO_PEERNAME:
2454 goto unimplemented;
2455 case TARGET_SO_PEERCRED: {
2456 struct ucred cr;
2457 socklen_t crlen;
2458 struct target_ucred *tcr;
2460 if (get_user_u32(len, optlen)) {
2461 return -TARGET_EFAULT;
2463 if (len < 0) {
2464 return -TARGET_EINVAL;
2467 crlen = sizeof(cr);
2468 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
2469 &cr, &crlen));
2470 if (ret < 0) {
2471 return ret;
2473 if (len > crlen) {
2474 len = crlen;
2476 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
2477 return -TARGET_EFAULT;
2479 __put_user(cr.pid, &tcr->pid);
2480 __put_user(cr.uid, &tcr->uid);
2481 __put_user(cr.gid, &tcr->gid);
2482 unlock_user_struct(tcr, optval_addr, 1);
2483 if (put_user_u32(len, optlen)) {
2484 return -TARGET_EFAULT;
2486 break;
2488 /* Options with 'int' argument. */
2489 case TARGET_SO_DEBUG:
2490 optname = SO_DEBUG;
2491 goto int_case;
2492 case TARGET_SO_REUSEADDR:
2493 optname = SO_REUSEADDR;
2494 goto int_case;
2495 case TARGET_SO_TYPE:
2496 optname = SO_TYPE;
2497 goto int_case;
2498 case TARGET_SO_ERROR:
2499 optname = SO_ERROR;
2500 goto int_case;
2501 case TARGET_SO_DONTROUTE:
2502 optname = SO_DONTROUTE;
2503 goto int_case;
2504 case TARGET_SO_BROADCAST:
2505 optname = SO_BROADCAST;
2506 goto int_case;
2507 case TARGET_SO_SNDBUF:
2508 optname = SO_SNDBUF;
2509 goto int_case;
2510 case TARGET_SO_RCVBUF:
2511 optname = SO_RCVBUF;
2512 goto int_case;
2513 case TARGET_SO_KEEPALIVE:
2514 optname = SO_KEEPALIVE;
2515 goto int_case;
2516 case TARGET_SO_OOBINLINE:
2517 optname = SO_OOBINLINE;
2518 goto int_case;
2519 case TARGET_SO_NO_CHECK:
2520 optname = SO_NO_CHECK;
2521 goto int_case;
2522 case TARGET_SO_PRIORITY:
2523 optname = SO_PRIORITY;
2524 goto int_case;
2525 #ifdef SO_BSDCOMPAT
2526 case TARGET_SO_BSDCOMPAT:
2527 optname = SO_BSDCOMPAT;
2528 goto int_case;
2529 #endif
2530 case TARGET_SO_PASSCRED:
2531 optname = SO_PASSCRED;
2532 goto int_case;
2533 case TARGET_SO_TIMESTAMP:
2534 optname = SO_TIMESTAMP;
2535 goto int_case;
2536 case TARGET_SO_RCVLOWAT:
2537 optname = SO_RCVLOWAT;
2538 goto int_case;
2539 case TARGET_SO_ACCEPTCONN:
2540 optname = SO_ACCEPTCONN;
2541 goto int_case;
2542 default:
2543 goto int_case;
2545 break;
2546 case SOL_TCP:
2547 /* TCP options all take an 'int' value. */
2548 int_case:
2549 if (get_user_u32(len, optlen))
2550 return -TARGET_EFAULT;
2551 if (len < 0)
2552 return -TARGET_EINVAL;
2553 lv = sizeof(lv);
2554 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2555 if (ret < 0)
2556 return ret;
2557 if (optname == SO_TYPE) {
2558 val = host_to_target_sock_type(val);
2560 if (len > lv)
2561 len = lv;
2562 if (len == 4) {
2563 if (put_user_u32(val, optval_addr))
2564 return -TARGET_EFAULT;
2565 } else {
2566 if (put_user_u8(val, optval_addr))
2567 return -TARGET_EFAULT;
2569 if (put_user_u32(len, optlen))
2570 return -TARGET_EFAULT;
2571 break;
2572 case SOL_IP:
2573 switch(optname) {
2574 case IP_TOS:
2575 case IP_TTL:
2576 case IP_HDRINCL:
2577 case IP_ROUTER_ALERT:
2578 case IP_RECVOPTS:
2579 case IP_RETOPTS:
2580 case IP_PKTINFO:
2581 case IP_MTU_DISCOVER:
2582 case IP_RECVERR:
2583 case IP_RECVTOS:
2584 #ifdef IP_FREEBIND
2585 case IP_FREEBIND:
2586 #endif
2587 case IP_MULTICAST_TTL:
2588 case IP_MULTICAST_LOOP:
2589 if (get_user_u32(len, optlen))
2590 return -TARGET_EFAULT;
2591 if (len < 0)
2592 return -TARGET_EINVAL;
2593 lv = sizeof(lv);
2594 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
2595 if (ret < 0)
2596 return ret;
2597 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
2598 len = 1;
2599 if (put_user_u32(len, optlen)
2600 || put_user_u8(val, optval_addr))
2601 return -TARGET_EFAULT;
2602 } else {
2603 if (len > sizeof(int))
2604 len = sizeof(int);
2605 if (put_user_u32(len, optlen)
2606 || put_user_u32(val, optval_addr))
2607 return -TARGET_EFAULT;
2609 break;
2610 default:
2611 ret = -TARGET_ENOPROTOOPT;
2612 break;
2614 break;
2615 default:
2616 unimplemented:
2617 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
2618 level, optname);
2619 ret = -TARGET_EOPNOTSUPP;
2620 break;
2622 return ret;
2625 static struct iovec *lock_iovec(int type, abi_ulong target_addr,
2626 int count, int copy)
2628 struct target_iovec *target_vec;
2629 struct iovec *vec;
2630 abi_ulong total_len, max_len;
2631 int i;
2632 int err = 0;
2633 bool bad_address = false;
2635 if (count == 0) {
2636 errno = 0;
2637 return NULL;
2639 if (count < 0 || count > IOV_MAX) {
2640 errno = EINVAL;
2641 return NULL;
2644 vec = g_try_new0(struct iovec, count);
2645 if (vec == NULL) {
2646 errno = ENOMEM;
2647 return NULL;
2650 target_vec = lock_user(VERIFY_READ, target_addr,
2651 count * sizeof(struct target_iovec), 1);
2652 if (target_vec == NULL) {
2653 err = EFAULT;
2654 goto fail2;
2657 /* ??? If host page size > target page size, this will result in a
2658 value larger than what we can actually support. */
2659 max_len = 0x7fffffff & TARGET_PAGE_MASK;
2660 total_len = 0;
2662 for (i = 0; i < count; i++) {
2663 abi_ulong base = tswapal(target_vec[i].iov_base);
2664 abi_long len = tswapal(target_vec[i].iov_len);
2666 if (len < 0) {
2667 err = EINVAL;
2668 goto fail;
2669 } else if (len == 0) {
2670 /* Zero length pointer is ignored. */
2671 vec[i].iov_base = 0;
2672 } else {
2673 vec[i].iov_base = lock_user(type, base, len, copy);
2674 /* If the first buffer pointer is bad, this is a fault. But
2675 * subsequent bad buffers will result in a partial write; this
2676 * is realized by filling the vector with null pointers and
2677 * zero lengths. */
2678 if (!vec[i].iov_base) {
2679 if (i == 0) {
2680 err = EFAULT;
2681 goto fail;
2682 } else {
2683 bad_address = true;
2686 if (bad_address) {
2687 len = 0;
2689 if (len > max_len - total_len) {
2690 len = max_len - total_len;
2693 vec[i].iov_len = len;
2694 total_len += len;
2697 unlock_user(target_vec, target_addr, 0);
2698 return vec;
2700 fail:
2701 while (--i >= 0) {
2702 if (tswapal(target_vec[i].iov_len) > 0) {
2703 unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
2706 unlock_user(target_vec, target_addr, 0);
2707 fail2:
2708 g_free(vec);
2709 errno = err;
2710 return NULL;
2713 static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
2714 int count, int copy)
2716 struct target_iovec *target_vec;
2717 int i;
2719 target_vec = lock_user(VERIFY_READ, target_addr,
2720 count * sizeof(struct target_iovec), 1);
2721 if (target_vec) {
2722 for (i = 0; i < count; i++) {
2723 abi_ulong base = tswapal(target_vec[i].iov_base);
2724 abi_long len = tswapal(target_vec[i].iov_len);
2725 if (len < 0) {
2726 break;
2728 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
2730 unlock_user(target_vec, target_addr, 0);
2733 g_free(vec);
2736 static inline int target_to_host_sock_type(int *type)
2738 int host_type = 0;
2739 int target_type = *type;
2741 switch (target_type & TARGET_SOCK_TYPE_MASK) {
2742 case TARGET_SOCK_DGRAM:
2743 host_type = SOCK_DGRAM;
2744 break;
2745 case TARGET_SOCK_STREAM:
2746 host_type = SOCK_STREAM;
2747 break;
2748 default:
2749 host_type = target_type & TARGET_SOCK_TYPE_MASK;
2750 break;
2752 if (target_type & TARGET_SOCK_CLOEXEC) {
2753 #if defined(SOCK_CLOEXEC)
2754 host_type |= SOCK_CLOEXEC;
2755 #else
2756 return -TARGET_EINVAL;
2757 #endif
2759 if (target_type & TARGET_SOCK_NONBLOCK) {
2760 #if defined(SOCK_NONBLOCK)
2761 host_type |= SOCK_NONBLOCK;
2762 #elif !defined(O_NONBLOCK)
2763 return -TARGET_EINVAL;
2764 #endif
2766 *type = host_type;
2767 return 0;
2770 /* Try to emulate socket type flags after socket creation. */
2771 static int sock_flags_fixup(int fd, int target_type)
2773 #if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
2774 if (target_type & TARGET_SOCK_NONBLOCK) {
2775 int flags = fcntl(fd, F_GETFL);
2776 if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
2777 close(fd);
2778 return -TARGET_EINVAL;
2781 #endif
2782 return fd;
2785 static abi_long packet_target_to_host_sockaddr(void *host_addr,
2786 abi_ulong target_addr,
2787 socklen_t len)
2789 struct sockaddr *addr = host_addr;
2790 struct target_sockaddr *target_saddr;
2792 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
2793 if (!target_saddr) {
2794 return -TARGET_EFAULT;
2797 memcpy(addr, target_saddr, len);
2798 addr->sa_family = tswap16(target_saddr->sa_family);
2799 /* spkt_protocol is big-endian */
2801 unlock_user(target_saddr, target_addr, 0);
2802 return 0;
2805 static TargetFdTrans target_packet_trans = {
2806 .target_to_host_addr = packet_target_to_host_sockaddr,
2809 #ifdef CONFIG_RTNETLINK
2810 static abi_long netlink_route_target_to_host(void *buf, size_t len)
2812 return target_to_host_nlmsg_route(buf, len);
2815 static abi_long netlink_route_host_to_target(void *buf, size_t len)
2817 return host_to_target_nlmsg_route(buf, len);
2820 static TargetFdTrans target_netlink_route_trans = {
2821 .target_to_host_data = netlink_route_target_to_host,
2822 .host_to_target_data = netlink_route_host_to_target,
2824 #endif /* CONFIG_RTNETLINK */
2826 static abi_long netlink_audit_target_to_host(void *buf, size_t len)
2828 return target_to_host_nlmsg_audit(buf, len);
2831 static abi_long netlink_audit_host_to_target(void *buf, size_t len)
2833 return host_to_target_nlmsg_audit(buf, len);
2836 static TargetFdTrans target_netlink_audit_trans = {
2837 .target_to_host_data = netlink_audit_target_to_host,
2838 .host_to_target_data = netlink_audit_host_to_target,
2841 /* do_socket() Must return target values and target errnos. */
2842 static abi_long do_socket(int domain, int type, int protocol)
2844 int target_type = type;
2845 int ret;
2847 ret = target_to_host_sock_type(&type);
2848 if (ret) {
2849 return ret;
2852 if (domain == PF_NETLINK && !(
2853 #ifdef CONFIG_RTNETLINK
2854 protocol == NETLINK_ROUTE ||
2855 #endif
2856 protocol == NETLINK_KOBJECT_UEVENT ||
2857 protocol == NETLINK_AUDIT)) {
2858 return -EPFNOSUPPORT;
2861 if (domain == AF_PACKET ||
2862 (domain == AF_INET && type == SOCK_PACKET)) {
2863 protocol = tswap16(protocol);
2866 ret = get_errno(socket(domain, type, protocol));
2867 if (ret >= 0) {
2868 ret = sock_flags_fixup(ret, target_type);
2869 if (type == SOCK_PACKET) {
2870 /* Manage an obsolete case :
2871 * if socket type is SOCK_PACKET, bind by name
2873 fd_trans_register(ret, &target_packet_trans);
2874 } else if (domain == PF_NETLINK) {
2875 switch (protocol) {
2876 #ifdef CONFIG_RTNETLINK
2877 case NETLINK_ROUTE:
2878 fd_trans_register(ret, &target_netlink_route_trans);
2879 break;
2880 #endif
2881 case NETLINK_KOBJECT_UEVENT:
2882 /* nothing to do: messages are strings */
2883 break;
2884 case NETLINK_AUDIT:
2885 fd_trans_register(ret, &target_netlink_audit_trans);
2886 break;
2887 default:
2888 g_assert_not_reached();
2892 return ret;
2895 /* do_bind() Must return target values and target errnos. */
2896 static abi_long do_bind(int sockfd, abi_ulong target_addr,
2897 socklen_t addrlen)
2899 void *addr;
2900 abi_long ret;
2902 if ((int)addrlen < 0) {
2903 return -TARGET_EINVAL;
2906 addr = alloca(addrlen+1);
2908 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
2909 if (ret)
2910 return ret;
2912 return get_errno(bind(sockfd, addr, addrlen));
2915 /* do_connect() Must return target values and target errnos. */
2916 static abi_long do_connect(int sockfd, abi_ulong target_addr,
2917 socklen_t addrlen)
2919 void *addr;
2920 abi_long ret;
2922 if ((int)addrlen < 0) {
2923 return -TARGET_EINVAL;
2926 addr = alloca(addrlen+1);
2928 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
2929 if (ret)
2930 return ret;
2932 return get_errno(safe_connect(sockfd, addr, addrlen));
2935 /* do_sendrecvmsg_locked() Must return target values and target errnos. */
2936 static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
2937 int flags, int send)
2939 abi_long ret, len;
2940 struct msghdr msg;
2941 int count;
2942 struct iovec *vec;
2943 abi_ulong target_vec;
2945 if (msgp->msg_name) {
2946 msg.msg_namelen = tswap32(msgp->msg_namelen);
2947 msg.msg_name = alloca(msg.msg_namelen+1);
2948 ret = target_to_host_sockaddr(fd, msg.msg_name,
2949 tswapal(msgp->msg_name),
2950 msg.msg_namelen);
2951 if (ret) {
2952 goto out2;
2954 } else {
2955 msg.msg_name = NULL;
2956 msg.msg_namelen = 0;
2958 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
2959 msg.msg_control = alloca(msg.msg_controllen);
2960 msg.msg_flags = tswap32(msgp->msg_flags);
2962 count = tswapal(msgp->msg_iovlen);
2963 target_vec = tswapal(msgp->msg_iov);
2964 vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
2965 target_vec, count, send);
2966 if (vec == NULL) {
2967 ret = -host_to_target_errno(errno);
2968 goto out2;
2970 msg.msg_iovlen = count;
2971 msg.msg_iov = vec;
2973 if (send) {
2974 if (fd_trans_target_to_host_data(fd)) {
2975 ret = fd_trans_target_to_host_data(fd)(msg.msg_iov->iov_base,
2976 msg.msg_iov->iov_len);
2977 } else {
2978 ret = target_to_host_cmsg(&msg, msgp);
2980 if (ret == 0) {
2981 ret = get_errno(safe_sendmsg(fd, &msg, flags));
2983 } else {
2984 ret = get_errno(safe_recvmsg(fd, &msg, flags));
2985 if (!is_error(ret)) {
2986 len = ret;
2987 if (fd_trans_host_to_target_data(fd)) {
2988 ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base,
2989 msg.msg_iov->iov_len);
2990 } else {
2991 ret = host_to_target_cmsg(msgp, &msg);
2993 if (!is_error(ret)) {
2994 msgp->msg_namelen = tswap32(msg.msg_namelen);
2995 if (msg.msg_name != NULL) {
2996 ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
2997 msg.msg_name, msg.msg_namelen);
2998 if (ret) {
2999 goto out;
3003 ret = len;
3008 out:
3009 unlock_iovec(vec, target_vec, count, !send);
3010 out2:
3011 return ret;
3014 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
3015 int flags, int send)
3017 abi_long ret;
3018 struct target_msghdr *msgp;
3020 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
3021 msgp,
3022 target_msg,
3023 send ? 1 : 0)) {
3024 return -TARGET_EFAULT;
3026 ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
3027 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
3028 return ret;
3031 /* We don't rely on the C library to have sendmmsg/recvmmsg support,
3032 * so it might not have this *mmsg-specific flag either.
3034 #ifndef MSG_WAITFORONE
3035 #define MSG_WAITFORONE 0x10000
3036 #endif
3038 static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
3039 unsigned int vlen, unsigned int flags,
3040 int send)
3042 struct target_mmsghdr *mmsgp;
3043 abi_long ret = 0;
3044 int i;
3046 if (vlen > UIO_MAXIOV) {
3047 vlen = UIO_MAXIOV;
3050 mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
3051 if (!mmsgp) {
3052 return -TARGET_EFAULT;
3055 for (i = 0; i < vlen; i++) {
3056 ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
3057 if (is_error(ret)) {
3058 break;
3060 mmsgp[i].msg_len = tswap32(ret);
3061 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
3062 if (flags & MSG_WAITFORONE) {
3063 flags |= MSG_DONTWAIT;
3067 unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
3069 /* Return number of datagrams sent if we sent any at all;
3070 * otherwise return the error.
3072 if (i) {
3073 return i;
3075 return ret;
3078 /* do_accept4() Must return target values and target errnos. */
3079 static abi_long do_accept4(int fd, abi_ulong target_addr,
3080 abi_ulong target_addrlen_addr, int flags)
3082 socklen_t addrlen;
3083 void *addr;
3084 abi_long ret;
3085 int host_flags;
3087 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
3089 if (target_addr == 0) {
3090 return get_errno(safe_accept4(fd, NULL, NULL, host_flags));
3093 /* linux returns EINVAL if addrlen pointer is invalid */
3094 if (get_user_u32(addrlen, target_addrlen_addr))
3095 return -TARGET_EINVAL;
3097 if ((int)addrlen < 0) {
3098 return -TARGET_EINVAL;
3101 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3102 return -TARGET_EINVAL;
3104 addr = alloca(addrlen);
3106 ret = get_errno(safe_accept4(fd, addr, &addrlen, host_flags));
3107 if (!is_error(ret)) {
3108 host_to_target_sockaddr(target_addr, addr, addrlen);
3109 if (put_user_u32(addrlen, target_addrlen_addr))
3110 ret = -TARGET_EFAULT;
3112 return ret;
3115 /* do_getpeername() Must return target values and target errnos. */
3116 static abi_long do_getpeername(int fd, abi_ulong target_addr,
3117 abi_ulong target_addrlen_addr)
3119 socklen_t addrlen;
3120 void *addr;
3121 abi_long ret;
3123 if (get_user_u32(addrlen, target_addrlen_addr))
3124 return -TARGET_EFAULT;
3126 if ((int)addrlen < 0) {
3127 return -TARGET_EINVAL;
3130 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3131 return -TARGET_EFAULT;
3133 addr = alloca(addrlen);
3135 ret = get_errno(getpeername(fd, addr, &addrlen));
3136 if (!is_error(ret)) {
3137 host_to_target_sockaddr(target_addr, addr, addrlen);
3138 if (put_user_u32(addrlen, target_addrlen_addr))
3139 ret = -TARGET_EFAULT;
3141 return ret;
3144 /* do_getsockname() Must return target values and target errnos. */
3145 static abi_long do_getsockname(int fd, abi_ulong target_addr,
3146 abi_ulong target_addrlen_addr)
3148 socklen_t addrlen;
3149 void *addr;
3150 abi_long ret;
3152 if (get_user_u32(addrlen, target_addrlen_addr))
3153 return -TARGET_EFAULT;
3155 if ((int)addrlen < 0) {
3156 return -TARGET_EINVAL;
3159 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
3160 return -TARGET_EFAULT;
3162 addr = alloca(addrlen);
3164 ret = get_errno(getsockname(fd, addr, &addrlen));
3165 if (!is_error(ret)) {
3166 host_to_target_sockaddr(target_addr, addr, addrlen);
3167 if (put_user_u32(addrlen, target_addrlen_addr))
3168 ret = -TARGET_EFAULT;
3170 return ret;
3173 /* do_socketpair() Must return target values and target errnos. */
3174 static abi_long do_socketpair(int domain, int type, int protocol,
3175 abi_ulong target_tab_addr)
3177 int tab[2];
3178 abi_long ret;
3180 target_to_host_sock_type(&type);
3182 ret = get_errno(socketpair(domain, type, protocol, tab));
3183 if (!is_error(ret)) {
3184 if (put_user_s32(tab[0], target_tab_addr)
3185 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
3186 ret = -TARGET_EFAULT;
3188 return ret;
3191 /* do_sendto() Must return target values and target errnos. */
3192 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
3193 abi_ulong target_addr, socklen_t addrlen)
3195 void *addr;
3196 void *host_msg;
3197 abi_long ret;
3199 if ((int)addrlen < 0) {
3200 return -TARGET_EINVAL;
3203 host_msg = lock_user(VERIFY_READ, msg, len, 1);
3204 if (!host_msg)
3205 return -TARGET_EFAULT;
3206 if (fd_trans_target_to_host_data(fd)) {
3207 ret = fd_trans_target_to_host_data(fd)(host_msg, len);
3208 if (ret < 0) {
3209 unlock_user(host_msg, msg, 0);
3210 return ret;
3213 if (target_addr) {
3214 addr = alloca(addrlen+1);
3215 ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
3216 if (ret) {
3217 unlock_user(host_msg, msg, 0);
3218 return ret;
3220 ret = get_errno(safe_sendto(fd, host_msg, len, flags, addr, addrlen));
3221 } else {
3222 ret = get_errno(safe_sendto(fd, host_msg, len, flags, NULL, 0));
3224 unlock_user(host_msg, msg, 0);
3225 return ret;
3228 /* do_recvfrom() Must return target values and target errnos. */
3229 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
3230 abi_ulong target_addr,
3231 abi_ulong target_addrlen)
3233 socklen_t addrlen;
3234 void *addr;
3235 void *host_msg;
3236 abi_long ret;
3238 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
3239 if (!host_msg)
3240 return -TARGET_EFAULT;
3241 if (target_addr) {
3242 if (get_user_u32(addrlen, target_addrlen)) {
3243 ret = -TARGET_EFAULT;
3244 goto fail;
3246 if ((int)addrlen < 0) {
3247 ret = -TARGET_EINVAL;
3248 goto fail;
3250 addr = alloca(addrlen);
3251 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags,
3252 addr, &addrlen));
3253 } else {
3254 addr = NULL; /* To keep compiler quiet. */
3255 ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, NULL, 0));
3257 if (!is_error(ret)) {
3258 if (target_addr) {
3259 host_to_target_sockaddr(target_addr, addr, addrlen);
3260 if (put_user_u32(addrlen, target_addrlen)) {
3261 ret = -TARGET_EFAULT;
3262 goto fail;
3265 unlock_user(host_msg, msg, len);
3266 } else {
3267 fail:
3268 unlock_user(host_msg, msg, 0);
3270 return ret;
3273 #ifdef TARGET_NR_socketcall
3274 /* do_socketcall() Must return target values and target errnos. */
3275 static abi_long do_socketcall(int num, abi_ulong vptr)
3277 static const unsigned ac[] = { /* number of arguments per call */
3278 [SOCKOP_socket] = 3, /* domain, type, protocol */
3279 [SOCKOP_bind] = 3, /* sockfd, addr, addrlen */
3280 [SOCKOP_connect] = 3, /* sockfd, addr, addrlen */
3281 [SOCKOP_listen] = 2, /* sockfd, backlog */
3282 [SOCKOP_accept] = 3, /* sockfd, addr, addrlen */
3283 [SOCKOP_accept4] = 4, /* sockfd, addr, addrlen, flags */
3284 [SOCKOP_getsockname] = 3, /* sockfd, addr, addrlen */
3285 [SOCKOP_getpeername] = 3, /* sockfd, addr, addrlen */
3286 [SOCKOP_socketpair] = 4, /* domain, type, protocol, tab */
3287 [SOCKOP_send] = 4, /* sockfd, msg, len, flags */
3288 [SOCKOP_recv] = 4, /* sockfd, msg, len, flags */
3289 [SOCKOP_sendto] = 6, /* sockfd, msg, len, flags, addr, addrlen */
3290 [SOCKOP_recvfrom] = 6, /* sockfd, msg, len, flags, addr, addrlen */
3291 [SOCKOP_shutdown] = 2, /* sockfd, how */
3292 [SOCKOP_sendmsg] = 3, /* sockfd, msg, flags */
3293 [SOCKOP_recvmsg] = 3, /* sockfd, msg, flags */
3294 [SOCKOP_sendmmsg] = 4, /* sockfd, msgvec, vlen, flags */
3295 [SOCKOP_recvmmsg] = 4, /* sockfd, msgvec, vlen, flags */
3296 [SOCKOP_setsockopt] = 5, /* sockfd, level, optname, optval, optlen */
3297 [SOCKOP_getsockopt] = 5, /* sockfd, level, optname, optval, optlen */
3299 abi_long a[6]; /* max 6 args */
3301 /* first, collect the arguments in a[] according to ac[] */
3302 if (num >= 0 && num < ARRAY_SIZE(ac)) {
3303 unsigned i;
3304 assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
3305 for (i = 0; i < ac[num]; ++i) {
3306 if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
3307 return -TARGET_EFAULT;
3312 /* now when we have the args, actually handle the call */
3313 switch (num) {
3314 case SOCKOP_socket: /* domain, type, protocol */
3315 return do_socket(a[0], a[1], a[2]);
3316 case SOCKOP_bind: /* sockfd, addr, addrlen */
3317 return do_bind(a[0], a[1], a[2]);
3318 case SOCKOP_connect: /* sockfd, addr, addrlen */
3319 return do_connect(a[0], a[1], a[2]);
3320 case SOCKOP_listen: /* sockfd, backlog */
3321 return get_errno(listen(a[0], a[1]));
3322 case SOCKOP_accept: /* sockfd, addr, addrlen */
3323 return do_accept4(a[0], a[1], a[2], 0);
3324 case SOCKOP_accept4: /* sockfd, addr, addrlen, flags */
3325 return do_accept4(a[0], a[1], a[2], a[3]);
3326 case SOCKOP_getsockname: /* sockfd, addr, addrlen */
3327 return do_getsockname(a[0], a[1], a[2]);
3328 case SOCKOP_getpeername: /* sockfd, addr, addrlen */
3329 return do_getpeername(a[0], a[1], a[2]);
3330 case SOCKOP_socketpair: /* domain, type, protocol, tab */
3331 return do_socketpair(a[0], a[1], a[2], a[3]);
3332 case SOCKOP_send: /* sockfd, msg, len, flags */
3333 return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
3334 case SOCKOP_recv: /* sockfd, msg, len, flags */
3335 return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
3336 case SOCKOP_sendto: /* sockfd, msg, len, flags, addr, addrlen */
3337 return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
3338 case SOCKOP_recvfrom: /* sockfd, msg, len, flags, addr, addrlen */
3339 return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
3340 case SOCKOP_shutdown: /* sockfd, how */
3341 return get_errno(shutdown(a[0], a[1]));
3342 case SOCKOP_sendmsg: /* sockfd, msg, flags */
3343 return do_sendrecvmsg(a[0], a[1], a[2], 1);
3344 case SOCKOP_recvmsg: /* sockfd, msg, flags */
3345 return do_sendrecvmsg(a[0], a[1], a[2], 0);
3346 case SOCKOP_sendmmsg: /* sockfd, msgvec, vlen, flags */
3347 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
3348 case SOCKOP_recvmmsg: /* sockfd, msgvec, vlen, flags */
3349 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
3350 case SOCKOP_setsockopt: /* sockfd, level, optname, optval, optlen */
3351 return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
3352 case SOCKOP_getsockopt: /* sockfd, level, optname, optval, optlen */
3353 return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
3354 default:
3355 gemu_log("Unsupported socketcall: %d\n", num);
3356 return -TARGET_ENOSYS;
3359 #endif
3361 #define N_SHM_REGIONS 32
3363 static struct shm_region {
3364 abi_ulong start;
3365 abi_ulong size;
3366 bool in_use;
3367 } shm_regions[N_SHM_REGIONS];
3369 struct target_semid_ds
3371 struct target_ipc_perm sem_perm;
3372 abi_ulong sem_otime;
3373 #if !defined(TARGET_PPC64)
3374 abi_ulong __unused1;
3375 #endif
3376 abi_ulong sem_ctime;
3377 #if !defined(TARGET_PPC64)
3378 abi_ulong __unused2;
3379 #endif
3380 abi_ulong sem_nsems;
3381 abi_ulong __unused3;
3382 abi_ulong __unused4;
3385 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
3386 abi_ulong target_addr)
3388 struct target_ipc_perm *target_ip;
3389 struct target_semid_ds *target_sd;
3391 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3392 return -TARGET_EFAULT;
3393 target_ip = &(target_sd->sem_perm);
3394 host_ip->__key = tswap32(target_ip->__key);
3395 host_ip->uid = tswap32(target_ip->uid);
3396 host_ip->gid = tswap32(target_ip->gid);
3397 host_ip->cuid = tswap32(target_ip->cuid);
3398 host_ip->cgid = tswap32(target_ip->cgid);
3399 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3400 host_ip->mode = tswap32(target_ip->mode);
3401 #else
3402 host_ip->mode = tswap16(target_ip->mode);
3403 #endif
3404 #if defined(TARGET_PPC)
3405 host_ip->__seq = tswap32(target_ip->__seq);
3406 #else
3407 host_ip->__seq = tswap16(target_ip->__seq);
3408 #endif
3409 unlock_user_struct(target_sd, target_addr, 0);
3410 return 0;
3413 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
3414 struct ipc_perm *host_ip)
3416 struct target_ipc_perm *target_ip;
3417 struct target_semid_ds *target_sd;
3419 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3420 return -TARGET_EFAULT;
3421 target_ip = &(target_sd->sem_perm);
3422 target_ip->__key = tswap32(host_ip->__key);
3423 target_ip->uid = tswap32(host_ip->uid);
3424 target_ip->gid = tswap32(host_ip->gid);
3425 target_ip->cuid = tswap32(host_ip->cuid);
3426 target_ip->cgid = tswap32(host_ip->cgid);
3427 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
3428 target_ip->mode = tswap32(host_ip->mode);
3429 #else
3430 target_ip->mode = tswap16(host_ip->mode);
3431 #endif
3432 #if defined(TARGET_PPC)
3433 target_ip->__seq = tswap32(host_ip->__seq);
3434 #else
3435 target_ip->__seq = tswap16(host_ip->__seq);
3436 #endif
3437 unlock_user_struct(target_sd, target_addr, 1);
3438 return 0;
3441 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
3442 abi_ulong target_addr)
3444 struct target_semid_ds *target_sd;
3446 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3447 return -TARGET_EFAULT;
3448 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
3449 return -TARGET_EFAULT;
3450 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
3451 host_sd->sem_otime = tswapal(target_sd->sem_otime);
3452 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
3453 unlock_user_struct(target_sd, target_addr, 0);
3454 return 0;
3457 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
3458 struct semid_ds *host_sd)
3460 struct target_semid_ds *target_sd;
3462 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3463 return -TARGET_EFAULT;
3464 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
3465 return -TARGET_EFAULT;
3466 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
3467 target_sd->sem_otime = tswapal(host_sd->sem_otime);
3468 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
3469 unlock_user_struct(target_sd, target_addr, 1);
3470 return 0;
3473 struct target_seminfo {
3474 int semmap;
3475 int semmni;
3476 int semmns;
3477 int semmnu;
3478 int semmsl;
3479 int semopm;
3480 int semume;
3481 int semusz;
3482 int semvmx;
3483 int semaem;
3486 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
3487 struct seminfo *host_seminfo)
3489 struct target_seminfo *target_seminfo;
3490 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
3491 return -TARGET_EFAULT;
3492 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
3493 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
3494 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
3495 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
3496 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
3497 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
3498 __put_user(host_seminfo->semume, &target_seminfo->semume);
3499 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
3500 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
3501 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
3502 unlock_user_struct(target_seminfo, target_addr, 1);
3503 return 0;
3506 union semun {
3507 int val;
3508 struct semid_ds *buf;
3509 unsigned short *array;
3510 struct seminfo *__buf;
3513 union target_semun {
3514 int val;
3515 abi_ulong buf;
3516 abi_ulong array;
3517 abi_ulong __buf;
3520 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
3521 abi_ulong target_addr)
3523 int nsems;
3524 unsigned short *array;
3525 union semun semun;
3526 struct semid_ds semid_ds;
3527 int i, ret;
3529 semun.buf = &semid_ds;
3531 ret = semctl(semid, 0, IPC_STAT, semun);
3532 if (ret == -1)
3533 return get_errno(ret);
3535 nsems = semid_ds.sem_nsems;
3537 *host_array = g_try_new(unsigned short, nsems);
3538 if (!*host_array) {
3539 return -TARGET_ENOMEM;
3541 array = lock_user(VERIFY_READ, target_addr,
3542 nsems*sizeof(unsigned short), 1);
3543 if (!array) {
3544 g_free(*host_array);
3545 return -TARGET_EFAULT;
3548 for(i=0; i<nsems; i++) {
3549 __get_user((*host_array)[i], &array[i]);
3551 unlock_user(array, target_addr, 0);
3553 return 0;
3556 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
3557 unsigned short **host_array)
3559 int nsems;
3560 unsigned short *array;
3561 union semun semun;
3562 struct semid_ds semid_ds;
3563 int i, ret;
3565 semun.buf = &semid_ds;
3567 ret = semctl(semid, 0, IPC_STAT, semun);
3568 if (ret == -1)
3569 return get_errno(ret);
3571 nsems = semid_ds.sem_nsems;
3573 array = lock_user(VERIFY_WRITE, target_addr,
3574 nsems*sizeof(unsigned short), 0);
3575 if (!array)
3576 return -TARGET_EFAULT;
3578 for(i=0; i<nsems; i++) {
3579 __put_user((*host_array)[i], &array[i]);
3581 g_free(*host_array);
3582 unlock_user(array, target_addr, 1);
3584 return 0;
3587 static inline abi_long do_semctl(int semid, int semnum, int cmd,
3588 abi_ulong target_arg)
3590 union target_semun target_su = { .buf = target_arg };
3591 union semun arg;
3592 struct semid_ds dsarg;
3593 unsigned short *array = NULL;
3594 struct seminfo seminfo;
3595 abi_long ret = -TARGET_EINVAL;
3596 abi_long err;
3597 cmd &= 0xff;
3599 switch( cmd ) {
3600 case GETVAL:
3601 case SETVAL:
3602 /* In 64 bit cross-endian situations, we will erroneously pick up
3603 * the wrong half of the union for the "val" element. To rectify
3604 * this, the entire 8-byte structure is byteswapped, followed by
3605 * a swap of the 4 byte val field. In other cases, the data is
3606 * already in proper host byte order. */
3607 if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
3608 target_su.buf = tswapal(target_su.buf);
3609 arg.val = tswap32(target_su.val);
3610 } else {
3611 arg.val = target_su.val;
3613 ret = get_errno(semctl(semid, semnum, cmd, arg));
3614 break;
3615 case GETALL:
3616 case SETALL:
3617 err = target_to_host_semarray(semid, &array, target_su.array);
3618 if (err)
3619 return err;
3620 arg.array = array;
3621 ret = get_errno(semctl(semid, semnum, cmd, arg));
3622 err = host_to_target_semarray(semid, target_su.array, &array);
3623 if (err)
3624 return err;
3625 break;
3626 case IPC_STAT:
3627 case IPC_SET:
3628 case SEM_STAT:
3629 err = target_to_host_semid_ds(&dsarg, target_su.buf);
3630 if (err)
3631 return err;
3632 arg.buf = &dsarg;
3633 ret = get_errno(semctl(semid, semnum, cmd, arg));
3634 err = host_to_target_semid_ds(target_su.buf, &dsarg);
3635 if (err)
3636 return err;
3637 break;
3638 case IPC_INFO:
3639 case SEM_INFO:
3640 arg.__buf = &seminfo;
3641 ret = get_errno(semctl(semid, semnum, cmd, arg));
3642 err = host_to_target_seminfo(target_su.__buf, &seminfo);
3643 if (err)
3644 return err;
3645 break;
3646 case IPC_RMID:
3647 case GETPID:
3648 case GETNCNT:
3649 case GETZCNT:
3650 ret = get_errno(semctl(semid, semnum, cmd, NULL));
3651 break;
3654 return ret;
3657 struct target_sembuf {
3658 unsigned short sem_num;
3659 short sem_op;
3660 short sem_flg;
3663 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
3664 abi_ulong target_addr,
3665 unsigned nsops)
3667 struct target_sembuf *target_sembuf;
3668 int i;
3670 target_sembuf = lock_user(VERIFY_READ, target_addr,
3671 nsops*sizeof(struct target_sembuf), 1);
3672 if (!target_sembuf)
3673 return -TARGET_EFAULT;
3675 for(i=0; i<nsops; i++) {
3676 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
3677 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
3678 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
3681 unlock_user(target_sembuf, target_addr, 0);
3683 return 0;
3686 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
3688 struct sembuf sops[nsops];
3690 if (target_to_host_sembuf(sops, ptr, nsops))
3691 return -TARGET_EFAULT;
3693 return get_errno(safe_semtimedop(semid, sops, nsops, NULL));
3696 struct target_msqid_ds
3698 struct target_ipc_perm msg_perm;
3699 abi_ulong msg_stime;
3700 #if TARGET_ABI_BITS == 32
3701 abi_ulong __unused1;
3702 #endif
3703 abi_ulong msg_rtime;
3704 #if TARGET_ABI_BITS == 32
3705 abi_ulong __unused2;
3706 #endif
3707 abi_ulong msg_ctime;
3708 #if TARGET_ABI_BITS == 32
3709 abi_ulong __unused3;
3710 #endif
3711 abi_ulong __msg_cbytes;
3712 abi_ulong msg_qnum;
3713 abi_ulong msg_qbytes;
3714 abi_ulong msg_lspid;
3715 abi_ulong msg_lrpid;
3716 abi_ulong __unused4;
3717 abi_ulong __unused5;
3720 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
3721 abi_ulong target_addr)
3723 struct target_msqid_ds *target_md;
3725 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
3726 return -TARGET_EFAULT;
3727 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
3728 return -TARGET_EFAULT;
3729 host_md->msg_stime = tswapal(target_md->msg_stime);
3730 host_md->msg_rtime = tswapal(target_md->msg_rtime);
3731 host_md->msg_ctime = tswapal(target_md->msg_ctime);
3732 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
3733 host_md->msg_qnum = tswapal(target_md->msg_qnum);
3734 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
3735 host_md->msg_lspid = tswapal(target_md->msg_lspid);
3736 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
3737 unlock_user_struct(target_md, target_addr, 0);
3738 return 0;
3741 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
3742 struct msqid_ds *host_md)
3744 struct target_msqid_ds *target_md;
3746 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
3747 return -TARGET_EFAULT;
3748 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
3749 return -TARGET_EFAULT;
3750 target_md->msg_stime = tswapal(host_md->msg_stime);
3751 target_md->msg_rtime = tswapal(host_md->msg_rtime);
3752 target_md->msg_ctime = tswapal(host_md->msg_ctime);
3753 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
3754 target_md->msg_qnum = tswapal(host_md->msg_qnum);
3755 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
3756 target_md->msg_lspid = tswapal(host_md->msg_lspid);
3757 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
3758 unlock_user_struct(target_md, target_addr, 1);
3759 return 0;
3762 struct target_msginfo {
3763 int msgpool;
3764 int msgmap;
3765 int msgmax;
3766 int msgmnb;
3767 int msgmni;
3768 int msgssz;
3769 int msgtql;
3770 unsigned short int msgseg;
3773 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
3774 struct msginfo *host_msginfo)
3776 struct target_msginfo *target_msginfo;
3777 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
3778 return -TARGET_EFAULT;
3779 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
3780 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
3781 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
3782 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
3783 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
3784 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
3785 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
3786 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
3787 unlock_user_struct(target_msginfo, target_addr, 1);
3788 return 0;
3791 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
3793 struct msqid_ds dsarg;
3794 struct msginfo msginfo;
3795 abi_long ret = -TARGET_EINVAL;
3797 cmd &= 0xff;
3799 switch (cmd) {
3800 case IPC_STAT:
3801 case IPC_SET:
3802 case MSG_STAT:
3803 if (target_to_host_msqid_ds(&dsarg,ptr))
3804 return -TARGET_EFAULT;
3805 ret = get_errno(msgctl(msgid, cmd, &dsarg));
3806 if (host_to_target_msqid_ds(ptr,&dsarg))
3807 return -TARGET_EFAULT;
3808 break;
3809 case IPC_RMID:
3810 ret = get_errno(msgctl(msgid, cmd, NULL));
3811 break;
3812 case IPC_INFO:
3813 case MSG_INFO:
3814 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
3815 if (host_to_target_msginfo(ptr, &msginfo))
3816 return -TARGET_EFAULT;
3817 break;
3820 return ret;
3823 struct target_msgbuf {
3824 abi_long mtype;
3825 char mtext[1];
3828 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
3829 ssize_t msgsz, int msgflg)
3831 struct target_msgbuf *target_mb;
3832 struct msgbuf *host_mb;
3833 abi_long ret = 0;
3835 if (msgsz < 0) {
3836 return -TARGET_EINVAL;
3839 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
3840 return -TARGET_EFAULT;
3841 host_mb = g_try_malloc(msgsz + sizeof(long));
3842 if (!host_mb) {
3843 unlock_user_struct(target_mb, msgp, 0);
3844 return -TARGET_ENOMEM;
3846 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
3847 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
3848 ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
3849 g_free(host_mb);
3850 unlock_user_struct(target_mb, msgp, 0);
3852 return ret;
3855 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
3856 ssize_t msgsz, abi_long msgtyp,
3857 int msgflg)
3859 struct target_msgbuf *target_mb;
3860 char *target_mtext;
3861 struct msgbuf *host_mb;
3862 abi_long ret = 0;
3864 if (msgsz < 0) {
3865 return -TARGET_EINVAL;
3868 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
3869 return -TARGET_EFAULT;
3871 host_mb = g_try_malloc(msgsz + sizeof(long));
3872 if (!host_mb) {
3873 ret = -TARGET_ENOMEM;
3874 goto end;
3876 ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
3878 if (ret > 0) {
3879 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
3880 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
3881 if (!target_mtext) {
3882 ret = -TARGET_EFAULT;
3883 goto end;
3885 memcpy(target_mb->mtext, host_mb->mtext, ret);
3886 unlock_user(target_mtext, target_mtext_addr, ret);
3889 target_mb->mtype = tswapal(host_mb->mtype);
3891 end:
3892 if (target_mb)
3893 unlock_user_struct(target_mb, msgp, 1);
3894 g_free(host_mb);
3895 return ret;
3898 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
3899 abi_ulong target_addr)
3901 struct target_shmid_ds *target_sd;
3903 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3904 return -TARGET_EFAULT;
3905 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
3906 return -TARGET_EFAULT;
3907 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
3908 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
3909 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
3910 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
3911 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
3912 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
3913 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
3914 unlock_user_struct(target_sd, target_addr, 0);
3915 return 0;
3918 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
3919 struct shmid_ds *host_sd)
3921 struct target_shmid_ds *target_sd;
3923 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3924 return -TARGET_EFAULT;
3925 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
3926 return -TARGET_EFAULT;
3927 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
3928 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
3929 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
3930 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
3931 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
3932 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
3933 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
3934 unlock_user_struct(target_sd, target_addr, 1);
3935 return 0;
3938 struct target_shminfo {
3939 abi_ulong shmmax;
3940 abi_ulong shmmin;
3941 abi_ulong shmmni;
3942 abi_ulong shmseg;
3943 abi_ulong shmall;
3946 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
3947 struct shminfo *host_shminfo)
3949 struct target_shminfo *target_shminfo;
3950 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
3951 return -TARGET_EFAULT;
3952 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
3953 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
3954 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
3955 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
3956 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
3957 unlock_user_struct(target_shminfo, target_addr, 1);
3958 return 0;
3961 struct target_shm_info {
3962 int used_ids;
3963 abi_ulong shm_tot;
3964 abi_ulong shm_rss;
3965 abi_ulong shm_swp;
3966 abi_ulong swap_attempts;
3967 abi_ulong swap_successes;
3970 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
3971 struct shm_info *host_shm_info)
3973 struct target_shm_info *target_shm_info;
3974 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
3975 return -TARGET_EFAULT;
3976 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
3977 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
3978 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
3979 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
3980 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
3981 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
3982 unlock_user_struct(target_shm_info, target_addr, 1);
3983 return 0;
3986 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3988 struct shmid_ds dsarg;
3989 struct shminfo shminfo;
3990 struct shm_info shm_info;
3991 abi_long ret = -TARGET_EINVAL;
3993 cmd &= 0xff;
3995 switch(cmd) {
3996 case IPC_STAT:
3997 case IPC_SET:
3998 case SHM_STAT:
3999 if (target_to_host_shmid_ds(&dsarg, buf))
4000 return -TARGET_EFAULT;
4001 ret = get_errno(shmctl(shmid, cmd, &dsarg));
4002 if (host_to_target_shmid_ds(buf, &dsarg))
4003 return -TARGET_EFAULT;
4004 break;
4005 case IPC_INFO:
4006 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
4007 if (host_to_target_shminfo(buf, &shminfo))
4008 return -TARGET_EFAULT;
4009 break;
4010 case SHM_INFO:
4011 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
4012 if (host_to_target_shm_info(buf, &shm_info))
4013 return -TARGET_EFAULT;
4014 break;
4015 case IPC_RMID:
4016 case SHM_LOCK:
4017 case SHM_UNLOCK:
4018 ret = get_errno(shmctl(shmid, cmd, NULL));
4019 break;
4022 return ret;
4025 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
4027 abi_long raddr;
4028 void *host_raddr;
4029 struct shmid_ds shm_info;
4030 int i,ret;
4032 /* find out the length of the shared memory segment */
4033 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
4034 if (is_error(ret)) {
4035 /* can't get length, bail out */
4036 return ret;
4039 mmap_lock();
4041 if (shmaddr)
4042 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
4043 else {
4044 abi_ulong mmap_start;
4046 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
4048 if (mmap_start == -1) {
4049 errno = ENOMEM;
4050 host_raddr = (void *)-1;
4051 } else
4052 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
4055 if (host_raddr == (void *)-1) {
4056 mmap_unlock();
4057 return get_errno((long)host_raddr);
4059 raddr=h2g((unsigned long)host_raddr);
4061 page_set_flags(raddr, raddr + shm_info.shm_segsz,
4062 PAGE_VALID | PAGE_READ |
4063 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
4065 for (i = 0; i < N_SHM_REGIONS; i++) {
4066 if (!shm_regions[i].in_use) {
4067 shm_regions[i].in_use = true;
4068 shm_regions[i].start = raddr;
4069 shm_regions[i].size = shm_info.shm_segsz;
4070 break;
4074 mmap_unlock();
4075 return raddr;
4079 static inline abi_long do_shmdt(abi_ulong shmaddr)
4081 int i;
4083 for (i = 0; i < N_SHM_REGIONS; ++i) {
4084 if (shm_regions[i].in_use && shm_regions[i].start == shmaddr) {
4085 shm_regions[i].in_use = false;
4086 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
4087 break;
4091 return get_errno(shmdt(g2h(shmaddr)));
4094 #ifdef TARGET_NR_ipc
4095 /* ??? This only works with linear mappings. */
4096 /* do_ipc() must return target values and target errnos. */
4097 static abi_long do_ipc(unsigned int call, abi_long first,
4098 abi_long second, abi_long third,
4099 abi_long ptr, abi_long fifth)
4101 int version;
4102 abi_long ret = 0;
4104 version = call >> 16;
4105 call &= 0xffff;
4107 switch (call) {
4108 case IPCOP_semop:
4109 ret = do_semop(first, ptr, second);
4110 break;
4112 case IPCOP_semget:
4113 ret = get_errno(semget(first, second, third));
4114 break;
4116 case IPCOP_semctl: {
4117 /* The semun argument to semctl is passed by value, so dereference the
4118 * ptr argument. */
4119 abi_ulong atptr;
4120 get_user_ual(atptr, ptr);
4121 ret = do_semctl(first, second, third, atptr);
4122 break;
4125 case IPCOP_msgget:
4126 ret = get_errno(msgget(first, second));
4127 break;
4129 case IPCOP_msgsnd:
4130 ret = do_msgsnd(first, ptr, second, third);
4131 break;
4133 case IPCOP_msgctl:
4134 ret = do_msgctl(first, second, ptr);
4135 break;
4137 case IPCOP_msgrcv:
4138 switch (version) {
4139 case 0:
4141 struct target_ipc_kludge {
4142 abi_long msgp;
4143 abi_long msgtyp;
4144 } *tmp;
4146 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
4147 ret = -TARGET_EFAULT;
4148 break;
4151 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
4153 unlock_user_struct(tmp, ptr, 0);
4154 break;
4156 default:
4157 ret = do_msgrcv(first, ptr, second, fifth, third);
4159 break;
4161 case IPCOP_shmat:
4162 switch (version) {
4163 default:
4165 abi_ulong raddr;
4166 raddr = do_shmat(first, ptr, second);
4167 if (is_error(raddr))
4168 return get_errno(raddr);
4169 if (put_user_ual(raddr, third))
4170 return -TARGET_EFAULT;
4171 break;
4173 case 1:
4174 ret = -TARGET_EINVAL;
4175 break;
4177 break;
4178 case IPCOP_shmdt:
4179 ret = do_shmdt(ptr);
4180 break;
4182 case IPCOP_shmget:
4183 /* IPC_* flag values are the same on all linux platforms */
4184 ret = get_errno(shmget(first, second, third));
4185 break;
4187 /* IPC_* and SHM_* command values are the same on all linux platforms */
4188 case IPCOP_shmctl:
4189 ret = do_shmctl(first, second, ptr);
4190 break;
4191 default:
4192 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
4193 ret = -TARGET_ENOSYS;
4194 break;
4196 return ret;
4198 #endif
4200 /* kernel structure types definitions */
4202 #define STRUCT(name, ...) STRUCT_ ## name,
4203 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
4204 enum {
4205 #include "syscall_types.h"
4206 STRUCT_MAX
4208 #undef STRUCT
4209 #undef STRUCT_SPECIAL
4211 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
4212 #define STRUCT_SPECIAL(name)
4213 #include "syscall_types.h"
4214 #undef STRUCT
4215 #undef STRUCT_SPECIAL
4217 typedef struct IOCTLEntry IOCTLEntry;
4219 typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
4220 int fd, int cmd, abi_long arg);
4222 struct IOCTLEntry {
4223 int target_cmd;
4224 unsigned int host_cmd;
4225 const char *name;
4226 int access;
4227 do_ioctl_fn *do_ioctl;
4228 const argtype arg_type[5];
4231 #define IOC_R 0x0001
4232 #define IOC_W 0x0002
4233 #define IOC_RW (IOC_R | IOC_W)
4235 #define MAX_STRUCT_SIZE 4096
4237 #ifdef CONFIG_FIEMAP
4238 /* So fiemap access checks don't overflow on 32 bit systems.
4239 * This is very slightly smaller than the limit imposed by
4240 * the underlying kernel.
4242 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
4243 / sizeof(struct fiemap_extent))
4245 static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
4246 int fd, int cmd, abi_long arg)
4248 /* The parameter for this ioctl is a struct fiemap followed
4249 * by an array of struct fiemap_extent whose size is set
4250 * in fiemap->fm_extent_count. The array is filled in by the
4251 * ioctl.
4253 int target_size_in, target_size_out;
4254 struct fiemap *fm;
4255 const argtype *arg_type = ie->arg_type;
4256 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
4257 void *argptr, *p;
4258 abi_long ret;
4259 int i, extent_size = thunk_type_size(extent_arg_type, 0);
4260 uint32_t outbufsz;
4261 int free_fm = 0;
4263 assert(arg_type[0] == TYPE_PTR);
4264 assert(ie->access == IOC_RW);
4265 arg_type++;
4266 target_size_in = thunk_type_size(arg_type, 0);
4267 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
4268 if (!argptr) {
4269 return -TARGET_EFAULT;
4271 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4272 unlock_user(argptr, arg, 0);
4273 fm = (struct fiemap *)buf_temp;
4274 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
4275 return -TARGET_EINVAL;
4278 outbufsz = sizeof (*fm) +
4279 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
4281 if (outbufsz > MAX_STRUCT_SIZE) {
4282 /* We can't fit all the extents into the fixed size buffer.
4283 * Allocate one that is large enough and use it instead.
4285 fm = g_try_malloc(outbufsz);
4286 if (!fm) {
4287 return -TARGET_ENOMEM;
4289 memcpy(fm, buf_temp, sizeof(struct fiemap));
4290 free_fm = 1;
4292 ret = get_errno(safe_ioctl(fd, ie->host_cmd, fm));
4293 if (!is_error(ret)) {
4294 target_size_out = target_size_in;
4295 /* An extent_count of 0 means we were only counting the extents
4296 * so there are no structs to copy
4298 if (fm->fm_extent_count != 0) {
4299 target_size_out += fm->fm_mapped_extents * extent_size;
4301 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
4302 if (!argptr) {
4303 ret = -TARGET_EFAULT;
4304 } else {
4305 /* Convert the struct fiemap */
4306 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
4307 if (fm->fm_extent_count != 0) {
4308 p = argptr + target_size_in;
4309 /* ...and then all the struct fiemap_extents */
4310 for (i = 0; i < fm->fm_mapped_extents; i++) {
4311 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
4312 THUNK_TARGET);
4313 p += extent_size;
4316 unlock_user(argptr, arg, target_size_out);
4319 if (free_fm) {
4320 g_free(fm);
4322 return ret;
4324 #endif
4326 static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
4327 int fd, int cmd, abi_long arg)
4329 const argtype *arg_type = ie->arg_type;
4330 int target_size;
4331 void *argptr;
4332 int ret;
4333 struct ifconf *host_ifconf;
4334 uint32_t outbufsz;
4335 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
4336 int target_ifreq_size;
4337 int nb_ifreq;
4338 int free_buf = 0;
4339 int i;
4340 int target_ifc_len;
4341 abi_long target_ifc_buf;
4342 int host_ifc_len;
4343 char *host_ifc_buf;
4345 assert(arg_type[0] == TYPE_PTR);
4346 assert(ie->access == IOC_RW);
4348 arg_type++;
4349 target_size = thunk_type_size(arg_type, 0);
4351 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4352 if (!argptr)
4353 return -TARGET_EFAULT;
4354 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4355 unlock_user(argptr, arg, 0);
4357 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
4358 target_ifc_len = host_ifconf->ifc_len;
4359 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
4361 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
4362 nb_ifreq = target_ifc_len / target_ifreq_size;
4363 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
4365 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
4366 if (outbufsz > MAX_STRUCT_SIZE) {
4367 /* We can't fit all the extents into the fixed size buffer.
4368 * Allocate one that is large enough and use it instead.
4370 host_ifconf = malloc(outbufsz);
4371 if (!host_ifconf) {
4372 return -TARGET_ENOMEM;
4374 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
4375 free_buf = 1;
4377 host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
4379 host_ifconf->ifc_len = host_ifc_len;
4380 host_ifconf->ifc_buf = host_ifc_buf;
4382 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf));
4383 if (!is_error(ret)) {
4384 /* convert host ifc_len to target ifc_len */
4386 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
4387 target_ifc_len = nb_ifreq * target_ifreq_size;
4388 host_ifconf->ifc_len = target_ifc_len;
4390 /* restore target ifc_buf */
4392 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
4394 /* copy struct ifconf to target user */
4396 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4397 if (!argptr)
4398 return -TARGET_EFAULT;
4399 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
4400 unlock_user(argptr, arg, target_size);
4402 /* copy ifreq[] to target user */
4404 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
4405 for (i = 0; i < nb_ifreq ; i++) {
4406 thunk_convert(argptr + i * target_ifreq_size,
4407 host_ifc_buf + i * sizeof(struct ifreq),
4408 ifreq_arg_type, THUNK_TARGET);
4410 unlock_user(argptr, target_ifc_buf, target_ifc_len);
4413 if (free_buf) {
4414 free(host_ifconf);
4417 return ret;
4420 static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
4421 int cmd, abi_long arg)
4423 void *argptr;
4424 struct dm_ioctl *host_dm;
4425 abi_long guest_data;
4426 uint32_t guest_data_size;
4427 int target_size;
4428 const argtype *arg_type = ie->arg_type;
4429 abi_long ret;
4430 void *big_buf = NULL;
4431 char *host_data;
4433 arg_type++;
4434 target_size = thunk_type_size(arg_type, 0);
4435 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4436 if (!argptr) {
4437 ret = -TARGET_EFAULT;
4438 goto out;
4440 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4441 unlock_user(argptr, arg, 0);
4443 /* buf_temp is too small, so fetch things into a bigger buffer */
4444 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
4445 memcpy(big_buf, buf_temp, target_size);
4446 buf_temp = big_buf;
4447 host_dm = big_buf;
4449 guest_data = arg + host_dm->data_start;
4450 if ((guest_data - arg) < 0) {
4451 ret = -EINVAL;
4452 goto out;
4454 guest_data_size = host_dm->data_size - host_dm->data_start;
4455 host_data = (char*)host_dm + host_dm->data_start;
4457 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
4458 switch (ie->host_cmd) {
4459 case DM_REMOVE_ALL:
4460 case DM_LIST_DEVICES:
4461 case DM_DEV_CREATE:
4462 case DM_DEV_REMOVE:
4463 case DM_DEV_SUSPEND:
4464 case DM_DEV_STATUS:
4465 case DM_DEV_WAIT:
4466 case DM_TABLE_STATUS:
4467 case DM_TABLE_CLEAR:
4468 case DM_TABLE_DEPS:
4469 case DM_LIST_VERSIONS:
4470 /* no input data */
4471 break;
4472 case DM_DEV_RENAME:
4473 case DM_DEV_SET_GEOMETRY:
4474 /* data contains only strings */
4475 memcpy(host_data, argptr, guest_data_size);
4476 break;
4477 case DM_TARGET_MSG:
4478 memcpy(host_data, argptr, guest_data_size);
4479 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
4480 break;
4481 case DM_TABLE_LOAD:
4483 void *gspec = argptr;
4484 void *cur_data = host_data;
4485 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
4486 int spec_size = thunk_type_size(arg_type, 0);
4487 int i;
4489 for (i = 0; i < host_dm->target_count; i++) {
4490 struct dm_target_spec *spec = cur_data;
4491 uint32_t next;
4492 int slen;
4494 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
4495 slen = strlen((char*)gspec + spec_size) + 1;
4496 next = spec->next;
4497 spec->next = sizeof(*spec) + slen;
4498 strcpy((char*)&spec[1], gspec + spec_size);
4499 gspec += next;
4500 cur_data += spec->next;
4502 break;
4504 default:
4505 ret = -TARGET_EINVAL;
4506 unlock_user(argptr, guest_data, 0);
4507 goto out;
4509 unlock_user(argptr, guest_data, 0);
4511 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4512 if (!is_error(ret)) {
4513 guest_data = arg + host_dm->data_start;
4514 guest_data_size = host_dm->data_size - host_dm->data_start;
4515 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
4516 switch (ie->host_cmd) {
4517 case DM_REMOVE_ALL:
4518 case DM_DEV_CREATE:
4519 case DM_DEV_REMOVE:
4520 case DM_DEV_RENAME:
4521 case DM_DEV_SUSPEND:
4522 case DM_DEV_STATUS:
4523 case DM_TABLE_LOAD:
4524 case DM_TABLE_CLEAR:
4525 case DM_TARGET_MSG:
4526 case DM_DEV_SET_GEOMETRY:
4527 /* no return data */
4528 break;
4529 case DM_LIST_DEVICES:
4531 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
4532 uint32_t remaining_data = guest_data_size;
4533 void *cur_data = argptr;
4534 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
4535 int nl_size = 12; /* can't use thunk_size due to alignment */
4537 while (1) {
4538 uint32_t next = nl->next;
4539 if (next) {
4540 nl->next = nl_size + (strlen(nl->name) + 1);
4542 if (remaining_data < nl->next) {
4543 host_dm->flags |= DM_BUFFER_FULL_FLAG;
4544 break;
4546 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
4547 strcpy(cur_data + nl_size, nl->name);
4548 cur_data += nl->next;
4549 remaining_data -= nl->next;
4550 if (!next) {
4551 break;
4553 nl = (void*)nl + next;
4555 break;
4557 case DM_DEV_WAIT:
4558 case DM_TABLE_STATUS:
4560 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
4561 void *cur_data = argptr;
4562 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
4563 int spec_size = thunk_type_size(arg_type, 0);
4564 int i;
4566 for (i = 0; i < host_dm->target_count; i++) {
4567 uint32_t next = spec->next;
4568 int slen = strlen((char*)&spec[1]) + 1;
4569 spec->next = (cur_data - argptr) + spec_size + slen;
4570 if (guest_data_size < spec->next) {
4571 host_dm->flags |= DM_BUFFER_FULL_FLAG;
4572 break;
4574 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
4575 strcpy(cur_data + spec_size, (char*)&spec[1]);
4576 cur_data = argptr + spec->next;
4577 spec = (void*)host_dm + host_dm->data_start + next;
4579 break;
4581 case DM_TABLE_DEPS:
4583 void *hdata = (void*)host_dm + host_dm->data_start;
4584 int count = *(uint32_t*)hdata;
4585 uint64_t *hdev = hdata + 8;
4586 uint64_t *gdev = argptr + 8;
4587 int i;
4589 *(uint32_t*)argptr = tswap32(count);
4590 for (i = 0; i < count; i++) {
4591 *gdev = tswap64(*hdev);
4592 gdev++;
4593 hdev++;
4595 break;
4597 case DM_LIST_VERSIONS:
4599 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
4600 uint32_t remaining_data = guest_data_size;
4601 void *cur_data = argptr;
4602 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
4603 int vers_size = thunk_type_size(arg_type, 0);
4605 while (1) {
4606 uint32_t next = vers->next;
4607 if (next) {
4608 vers->next = vers_size + (strlen(vers->name) + 1);
4610 if (remaining_data < vers->next) {
4611 host_dm->flags |= DM_BUFFER_FULL_FLAG;
4612 break;
4614 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
4615 strcpy(cur_data + vers_size, vers->name);
4616 cur_data += vers->next;
4617 remaining_data -= vers->next;
4618 if (!next) {
4619 break;
4621 vers = (void*)vers + next;
4623 break;
4625 default:
4626 unlock_user(argptr, guest_data, 0);
4627 ret = -TARGET_EINVAL;
4628 goto out;
4630 unlock_user(argptr, guest_data, guest_data_size);
4632 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4633 if (!argptr) {
4634 ret = -TARGET_EFAULT;
4635 goto out;
4637 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
4638 unlock_user(argptr, arg, target_size);
4640 out:
4641 g_free(big_buf);
4642 return ret;
4645 static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
4646 int cmd, abi_long arg)
4648 void *argptr;
4649 int target_size;
4650 const argtype *arg_type = ie->arg_type;
4651 const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
4652 abi_long ret;
4654 struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
4655 struct blkpg_partition host_part;
4657 /* Read and convert blkpg */
4658 arg_type++;
4659 target_size = thunk_type_size(arg_type, 0);
4660 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4661 if (!argptr) {
4662 ret = -TARGET_EFAULT;
4663 goto out;
4665 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4666 unlock_user(argptr, arg, 0);
4668 switch (host_blkpg->op) {
4669 case BLKPG_ADD_PARTITION:
4670 case BLKPG_DEL_PARTITION:
4671 /* payload is struct blkpg_partition */
4672 break;
4673 default:
4674 /* Unknown opcode */
4675 ret = -TARGET_EINVAL;
4676 goto out;
4679 /* Read and convert blkpg->data */
4680 arg = (abi_long)(uintptr_t)host_blkpg->data;
4681 target_size = thunk_type_size(part_arg_type, 0);
4682 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4683 if (!argptr) {
4684 ret = -TARGET_EFAULT;
4685 goto out;
4687 thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
4688 unlock_user(argptr, arg, 0);
4690 /* Swizzle the data pointer to our local copy and call! */
4691 host_blkpg->data = &host_part;
4692 ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_blkpg));
4694 out:
4695 return ret;
4698 static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
4699 int fd, int cmd, abi_long arg)
4701 const argtype *arg_type = ie->arg_type;
4702 const StructEntry *se;
4703 const argtype *field_types;
4704 const int *dst_offsets, *src_offsets;
4705 int target_size;
4706 void *argptr;
4707 abi_ulong *target_rt_dev_ptr;
4708 unsigned long *host_rt_dev_ptr;
4709 abi_long ret;
4710 int i;
4712 assert(ie->access == IOC_W);
4713 assert(*arg_type == TYPE_PTR);
4714 arg_type++;
4715 assert(*arg_type == TYPE_STRUCT);
4716 target_size = thunk_type_size(arg_type, 0);
4717 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4718 if (!argptr) {
4719 return -TARGET_EFAULT;
4721 arg_type++;
4722 assert(*arg_type == (int)STRUCT_rtentry);
4723 se = struct_entries + *arg_type++;
4724 assert(se->convert[0] == NULL);
4725 /* convert struct here to be able to catch rt_dev string */
4726 field_types = se->field_types;
4727 dst_offsets = se->field_offsets[THUNK_HOST];
4728 src_offsets = se->field_offsets[THUNK_TARGET];
4729 for (i = 0; i < se->nb_fields; i++) {
4730 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
4731 assert(*field_types == TYPE_PTRVOID);
4732 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
4733 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
4734 if (*target_rt_dev_ptr != 0) {
4735 *host_rt_dev_ptr = (unsigned long)lock_user_string(
4736 tswapal(*target_rt_dev_ptr));
4737 if (!*host_rt_dev_ptr) {
4738 unlock_user(argptr, arg, 0);
4739 return -TARGET_EFAULT;
4741 } else {
4742 *host_rt_dev_ptr = 0;
4744 field_types++;
4745 continue;
4747 field_types = thunk_convert(buf_temp + dst_offsets[i],
4748 argptr + src_offsets[i],
4749 field_types, THUNK_HOST);
4751 unlock_user(argptr, arg, 0);
4753 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4754 if (*host_rt_dev_ptr != 0) {
4755 unlock_user((void *)*host_rt_dev_ptr,
4756 *target_rt_dev_ptr, 0);
4758 return ret;
4761 static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
4762 int fd, int cmd, abi_long arg)
4764 int sig = target_to_host_signal(arg);
4765 return get_errno(safe_ioctl(fd, ie->host_cmd, sig));
4768 static IOCTLEntry ioctl_entries[] = {
4769 #define IOCTL(cmd, access, ...) \
4770 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
4771 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
4772 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
4773 #include "ioctls.h"
4774 { 0, 0, },
4777 /* ??? Implement proper locking for ioctls. */
4778 /* do_ioctl() Must return target values and target errnos. */
4779 static abi_long do_ioctl(int fd, int cmd, abi_long arg)
4781 const IOCTLEntry *ie;
4782 const argtype *arg_type;
4783 abi_long ret;
4784 uint8_t buf_temp[MAX_STRUCT_SIZE];
4785 int target_size;
4786 void *argptr;
4788 ie = ioctl_entries;
4789 for(;;) {
4790 if (ie->target_cmd == 0) {
4791 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
4792 return -TARGET_ENOSYS;
4794 if (ie->target_cmd == cmd)
4795 break;
4796 ie++;
4798 arg_type = ie->arg_type;
4799 #if defined(DEBUG)
4800 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
4801 #endif
4802 if (ie->do_ioctl) {
4803 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
4806 switch(arg_type[0]) {
4807 case TYPE_NULL:
4808 /* no argument */
4809 ret = get_errno(safe_ioctl(fd, ie->host_cmd));
4810 break;
4811 case TYPE_PTRVOID:
4812 case TYPE_INT:
4813 ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg));
4814 break;
4815 case TYPE_PTR:
4816 arg_type++;
4817 target_size = thunk_type_size(arg_type, 0);
4818 switch(ie->access) {
4819 case IOC_R:
4820 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4821 if (!is_error(ret)) {
4822 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4823 if (!argptr)
4824 return -TARGET_EFAULT;
4825 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
4826 unlock_user(argptr, arg, target_size);
4828 break;
4829 case IOC_W:
4830 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4831 if (!argptr)
4832 return -TARGET_EFAULT;
4833 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4834 unlock_user(argptr, arg, 0);
4835 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4836 break;
4837 default:
4838 case IOC_RW:
4839 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4840 if (!argptr)
4841 return -TARGET_EFAULT;
4842 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4843 unlock_user(argptr, arg, 0);
4844 ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
4845 if (!is_error(ret)) {
4846 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4847 if (!argptr)
4848 return -TARGET_EFAULT;
4849 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
4850 unlock_user(argptr, arg, target_size);
4852 break;
4854 break;
4855 default:
4856 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
4857 (long)cmd, arg_type[0]);
4858 ret = -TARGET_ENOSYS;
4859 break;
4861 return ret;
4864 static const bitmask_transtbl iflag_tbl[] = {
4865 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
4866 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
4867 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
4868 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
4869 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
4870 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
4871 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
4872 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
4873 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
4874 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
4875 { TARGET_IXON, TARGET_IXON, IXON, IXON },
4876 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
4877 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
4878 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
4879 { 0, 0, 0, 0 }
4882 static const bitmask_transtbl oflag_tbl[] = {
4883 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
4884 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
4885 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
4886 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
4887 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
4888 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
4889 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
4890 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
4891 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
4892 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
4893 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
4894 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
4895 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
4896 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
4897 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
4898 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
4899 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
4900 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
4901 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
4902 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
4903 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
4904 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
4905 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
4906 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
4907 { 0, 0, 0, 0 }
4910 static const bitmask_transtbl cflag_tbl[] = {
4911 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
4912 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
4913 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
4914 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
4915 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
4916 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
4917 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
4918 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
4919 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
4920 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
4921 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
4922 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
4923 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
4924 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
4925 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
4926 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
4927 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
4928 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
4929 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
4930 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
4931 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
4932 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
4933 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
4934 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
4935 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
4936 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
4937 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
4938 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
4939 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
4940 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
4941 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
4942 { 0, 0, 0, 0 }
4945 static const bitmask_transtbl lflag_tbl[] = {
4946 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
4947 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
4948 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
4949 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
4950 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
4951 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
4952 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
4953 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
4954 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
4955 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
4956 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
4957 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
4958 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
4959 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
4960 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
4961 { 0, 0, 0, 0 }
4964 static void target_to_host_termios (void *dst, const void *src)
4966 struct host_termios *host = dst;
4967 const struct target_termios *target = src;
4969 host->c_iflag =
4970 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
4971 host->c_oflag =
4972 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
4973 host->c_cflag =
4974 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
4975 host->c_lflag =
4976 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
4977 host->c_line = target->c_line;
4979 memset(host->c_cc, 0, sizeof(host->c_cc));
4980 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
4981 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
4982 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
4983 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
4984 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
4985 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
4986 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
4987 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
4988 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
4989 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
4990 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
4991 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
4992 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
4993 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
4994 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
4995 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
4996 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
4999 static void host_to_target_termios (void *dst, const void *src)
5001 struct target_termios *target = dst;
5002 const struct host_termios *host = src;
5004 target->c_iflag =
5005 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
5006 target->c_oflag =
5007 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
5008 target->c_cflag =
5009 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
5010 target->c_lflag =
5011 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
5012 target->c_line = host->c_line;
5014 memset(target->c_cc, 0, sizeof(target->c_cc));
5015 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
5016 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
5017 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
5018 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
5019 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
5020 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
5021 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
5022 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
5023 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
5024 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
5025 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
5026 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
5027 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
5028 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
5029 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
5030 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
5031 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
5034 static const StructEntry struct_termios_def = {
5035 .convert = { host_to_target_termios, target_to_host_termios },
5036 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
5037 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
5040 static bitmask_transtbl mmap_flags_tbl[] = {
5041 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
5042 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
5043 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
5044 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
5045 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
5046 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
5047 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
5048 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
5049 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, MAP_NORESERVE,
5050 MAP_NORESERVE },
5051 { 0, 0, 0, 0 }
5054 #if defined(TARGET_I386)
5056 /* NOTE: there is really one LDT for all the threads */
5057 static uint8_t *ldt_table;
5059 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
5061 int size;
5062 void *p;
5064 if (!ldt_table)
5065 return 0;
5066 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
5067 if (size > bytecount)
5068 size = bytecount;
5069 p = lock_user(VERIFY_WRITE, ptr, size, 0);
5070 if (!p)
5071 return -TARGET_EFAULT;
5072 /* ??? Should this by byteswapped? */
5073 memcpy(p, ldt_table, size);
5074 unlock_user(p, ptr, size);
5075 return size;
5078 /* XXX: add locking support */
5079 static abi_long write_ldt(CPUX86State *env,
5080 abi_ulong ptr, unsigned long bytecount, int oldmode)
5082 struct target_modify_ldt_ldt_s ldt_info;
5083 struct target_modify_ldt_ldt_s *target_ldt_info;
5084 int seg_32bit, contents, read_exec_only, limit_in_pages;
5085 int seg_not_present, useable, lm;
5086 uint32_t *lp, entry_1, entry_2;
5088 if (bytecount != sizeof(ldt_info))
5089 return -TARGET_EINVAL;
5090 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
5091 return -TARGET_EFAULT;
5092 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
5093 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
5094 ldt_info.limit = tswap32(target_ldt_info->limit);
5095 ldt_info.flags = tswap32(target_ldt_info->flags);
5096 unlock_user_struct(target_ldt_info, ptr, 0);
5098 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
5099 return -TARGET_EINVAL;
5100 seg_32bit = ldt_info.flags & 1;
5101 contents = (ldt_info.flags >> 1) & 3;
5102 read_exec_only = (ldt_info.flags >> 3) & 1;
5103 limit_in_pages = (ldt_info.flags >> 4) & 1;
5104 seg_not_present = (ldt_info.flags >> 5) & 1;
5105 useable = (ldt_info.flags >> 6) & 1;
5106 #ifdef TARGET_ABI32
5107 lm = 0;
5108 #else
5109 lm = (ldt_info.flags >> 7) & 1;
5110 #endif
5111 if (contents == 3) {
5112 if (oldmode)
5113 return -TARGET_EINVAL;
5114 if (seg_not_present == 0)
5115 return -TARGET_EINVAL;
5117 /* allocate the LDT */
5118 if (!ldt_table) {
5119 env->ldt.base = target_mmap(0,
5120 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
5121 PROT_READ|PROT_WRITE,
5122 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
5123 if (env->ldt.base == -1)
5124 return -TARGET_ENOMEM;
5125 memset(g2h(env->ldt.base), 0,
5126 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
5127 env->ldt.limit = 0xffff;
5128 ldt_table = g2h(env->ldt.base);
5131 /* NOTE: same code as Linux kernel */
5132 /* Allow LDTs to be cleared by the user. */
5133 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
5134 if (oldmode ||
5135 (contents == 0 &&
5136 read_exec_only == 1 &&
5137 seg_32bit == 0 &&
5138 limit_in_pages == 0 &&
5139 seg_not_present == 1 &&
5140 useable == 0 )) {
5141 entry_1 = 0;
5142 entry_2 = 0;
5143 goto install;
5147 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
5148 (ldt_info.limit & 0x0ffff);
5149 entry_2 = (ldt_info.base_addr & 0xff000000) |
5150 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
5151 (ldt_info.limit & 0xf0000) |
5152 ((read_exec_only ^ 1) << 9) |
5153 (contents << 10) |
5154 ((seg_not_present ^ 1) << 15) |
5155 (seg_32bit << 22) |
5156 (limit_in_pages << 23) |
5157 (lm << 21) |
5158 0x7000;
5159 if (!oldmode)
5160 entry_2 |= (useable << 20);
5162 /* Install the new entry ... */
5163 install:
5164 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
5165 lp[0] = tswap32(entry_1);
5166 lp[1] = tswap32(entry_2);
5167 return 0;
5170 /* specific and weird i386 syscalls */
5171 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
5172 unsigned long bytecount)
5174 abi_long ret;
5176 switch (func) {
5177 case 0:
5178 ret = read_ldt(ptr, bytecount);
5179 break;
5180 case 1:
5181 ret = write_ldt(env, ptr, bytecount, 1);
5182 break;
5183 case 0x11:
5184 ret = write_ldt(env, ptr, bytecount, 0);
5185 break;
5186 default:
5187 ret = -TARGET_ENOSYS;
5188 break;
5190 return ret;
5193 #if defined(TARGET_I386) && defined(TARGET_ABI32)
5194 abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
5196 uint64_t *gdt_table = g2h(env->gdt.base);
5197 struct target_modify_ldt_ldt_s ldt_info;
5198 struct target_modify_ldt_ldt_s *target_ldt_info;
5199 int seg_32bit, contents, read_exec_only, limit_in_pages;
5200 int seg_not_present, useable, lm;
5201 uint32_t *lp, entry_1, entry_2;
5202 int i;
5204 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
5205 if (!target_ldt_info)
5206 return -TARGET_EFAULT;
5207 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
5208 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
5209 ldt_info.limit = tswap32(target_ldt_info->limit);
5210 ldt_info.flags = tswap32(target_ldt_info->flags);
5211 if (ldt_info.entry_number == -1) {
5212 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
5213 if (gdt_table[i] == 0) {
5214 ldt_info.entry_number = i;
5215 target_ldt_info->entry_number = tswap32(i);
5216 break;
5220 unlock_user_struct(target_ldt_info, ptr, 1);
5222 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
5223 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
5224 return -TARGET_EINVAL;
5225 seg_32bit = ldt_info.flags & 1;
5226 contents = (ldt_info.flags >> 1) & 3;
5227 read_exec_only = (ldt_info.flags >> 3) & 1;
5228 limit_in_pages = (ldt_info.flags >> 4) & 1;
5229 seg_not_present = (ldt_info.flags >> 5) & 1;
5230 useable = (ldt_info.flags >> 6) & 1;
5231 #ifdef TARGET_ABI32
5232 lm = 0;
5233 #else
5234 lm = (ldt_info.flags >> 7) & 1;
5235 #endif
5237 if (contents == 3) {
5238 if (seg_not_present == 0)
5239 return -TARGET_EINVAL;
5242 /* NOTE: same code as Linux kernel */
5243 /* Allow LDTs to be cleared by the user. */
5244 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
5245 if ((contents == 0 &&
5246 read_exec_only == 1 &&
5247 seg_32bit == 0 &&
5248 limit_in_pages == 0 &&
5249 seg_not_present == 1 &&
5250 useable == 0 )) {
5251 entry_1 = 0;
5252 entry_2 = 0;
5253 goto install;
5257 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
5258 (ldt_info.limit & 0x0ffff);
5259 entry_2 = (ldt_info.base_addr & 0xff000000) |
5260 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
5261 (ldt_info.limit & 0xf0000) |
5262 ((read_exec_only ^ 1) << 9) |
5263 (contents << 10) |
5264 ((seg_not_present ^ 1) << 15) |
5265 (seg_32bit << 22) |
5266 (limit_in_pages << 23) |
5267 (useable << 20) |
5268 (lm << 21) |
5269 0x7000;
5271 /* Install the new entry ... */
5272 install:
5273 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
5274 lp[0] = tswap32(entry_1);
5275 lp[1] = tswap32(entry_2);
5276 return 0;
5279 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
5281 struct target_modify_ldt_ldt_s *target_ldt_info;
5282 uint64_t *gdt_table = g2h(env->gdt.base);
5283 uint32_t base_addr, limit, flags;
5284 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
5285 int seg_not_present, useable, lm;
5286 uint32_t *lp, entry_1, entry_2;
5288 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
5289 if (!target_ldt_info)
5290 return -TARGET_EFAULT;
5291 idx = tswap32(target_ldt_info->entry_number);
5292 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
5293 idx > TARGET_GDT_ENTRY_TLS_MAX) {
5294 unlock_user_struct(target_ldt_info, ptr, 1);
5295 return -TARGET_EINVAL;
5297 lp = (uint32_t *)(gdt_table + idx);
5298 entry_1 = tswap32(lp[0]);
5299 entry_2 = tswap32(lp[1]);
5301 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
5302 contents = (entry_2 >> 10) & 3;
5303 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
5304 seg_32bit = (entry_2 >> 22) & 1;
5305 limit_in_pages = (entry_2 >> 23) & 1;
5306 useable = (entry_2 >> 20) & 1;
5307 #ifdef TARGET_ABI32
5308 lm = 0;
5309 #else
5310 lm = (entry_2 >> 21) & 1;
5311 #endif
5312 flags = (seg_32bit << 0) | (contents << 1) |
5313 (read_exec_only << 3) | (limit_in_pages << 4) |
5314 (seg_not_present << 5) | (useable << 6) | (lm << 7);
5315 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
5316 base_addr = (entry_1 >> 16) |
5317 (entry_2 & 0xff000000) |
5318 ((entry_2 & 0xff) << 16);
5319 target_ldt_info->base_addr = tswapal(base_addr);
5320 target_ldt_info->limit = tswap32(limit);
5321 target_ldt_info->flags = tswap32(flags);
5322 unlock_user_struct(target_ldt_info, ptr, 1);
5323 return 0;
5325 #endif /* TARGET_I386 && TARGET_ABI32 */
5327 #ifndef TARGET_ABI32
5328 abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
5330 abi_long ret = 0;
5331 abi_ulong val;
5332 int idx;
5334 switch(code) {
5335 case TARGET_ARCH_SET_GS:
5336 case TARGET_ARCH_SET_FS:
5337 if (code == TARGET_ARCH_SET_GS)
5338 idx = R_GS;
5339 else
5340 idx = R_FS;
5341 cpu_x86_load_seg(env, idx, 0);
5342 env->segs[idx].base = addr;
5343 break;
5344 case TARGET_ARCH_GET_GS:
5345 case TARGET_ARCH_GET_FS:
5346 if (code == TARGET_ARCH_GET_GS)
5347 idx = R_GS;
5348 else
5349 idx = R_FS;
5350 val = env->segs[idx].base;
5351 if (put_user(val, addr, abi_ulong))
5352 ret = -TARGET_EFAULT;
5353 break;
5354 default:
5355 ret = -TARGET_EINVAL;
5356 break;
5358 return ret;
5360 #endif
5362 #endif /* defined(TARGET_I386) */
5364 #define NEW_STACK_SIZE 0x40000
5367 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
5368 typedef struct {
5369 CPUArchState *env;
5370 pthread_mutex_t mutex;
5371 pthread_cond_t cond;
5372 pthread_t thread;
5373 uint32_t tid;
5374 abi_ulong child_tidptr;
5375 abi_ulong parent_tidptr;
5376 sigset_t sigmask;
5377 } new_thread_info;
5379 static void *clone_func(void *arg)
5381 new_thread_info *info = arg;
5382 CPUArchState *env;
5383 CPUState *cpu;
5384 TaskState *ts;
5386 rcu_register_thread();
5387 env = info->env;
5388 cpu = ENV_GET_CPU(env);
5389 thread_cpu = cpu;
5390 ts = (TaskState *)cpu->opaque;
5391 info->tid = gettid();
5392 cpu->host_tid = info->tid;
5393 task_settid(ts);
5394 if (info->child_tidptr)
5395 put_user_u32(info->tid, info->child_tidptr);
5396 if (info->parent_tidptr)
5397 put_user_u32(info->tid, info->parent_tidptr);
5398 /* Enable signals. */
5399 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
5400 /* Signal to the parent that we're ready. */
5401 pthread_mutex_lock(&info->mutex);
5402 pthread_cond_broadcast(&info->cond);
5403 pthread_mutex_unlock(&info->mutex);
5404 /* Wait until the parent has finshed initializing the tls state. */
5405 pthread_mutex_lock(&clone_lock);
5406 pthread_mutex_unlock(&clone_lock);
5407 cpu_loop(env);
5408 /* never exits */
5409 return NULL;
5412 /* do_fork() Must return host values and target errnos (unlike most
5413 do_*() functions). */
5414 static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
5415 abi_ulong parent_tidptr, target_ulong newtls,
5416 abi_ulong child_tidptr)
5418 CPUState *cpu = ENV_GET_CPU(env);
5419 int ret;
5420 TaskState *ts;
5421 CPUState *new_cpu;
5422 CPUArchState *new_env;
5423 unsigned int nptl_flags;
5424 sigset_t sigmask;
5426 /* Emulate vfork() with fork() */
5427 if (flags & CLONE_VFORK)
5428 flags &= ~(CLONE_VFORK | CLONE_VM);
5430 if (flags & CLONE_VM) {
5431 TaskState *parent_ts = (TaskState *)cpu->opaque;
5432 new_thread_info info;
5433 pthread_attr_t attr;
5435 ts = g_new0(TaskState, 1);
5436 init_task_state(ts);
5437 /* we create a new CPU instance. */
5438 new_env = cpu_copy(env);
5439 /* Init regs that differ from the parent. */
5440 cpu_clone_regs(new_env, newsp);
5441 new_cpu = ENV_GET_CPU(new_env);
5442 new_cpu->opaque = ts;
5443 ts->bprm = parent_ts->bprm;
5444 ts->info = parent_ts->info;
5445 ts->signal_mask = parent_ts->signal_mask;
5446 nptl_flags = flags;
5447 flags &= ~CLONE_NPTL_FLAGS2;
5449 if (nptl_flags & CLONE_CHILD_CLEARTID) {
5450 ts->child_tidptr = child_tidptr;
5453 if (nptl_flags & CLONE_SETTLS)
5454 cpu_set_tls (new_env, newtls);
5456 /* Grab a mutex so that thread setup appears atomic. */
5457 pthread_mutex_lock(&clone_lock);
5459 memset(&info, 0, sizeof(info));
5460 pthread_mutex_init(&info.mutex, NULL);
5461 pthread_mutex_lock(&info.mutex);
5462 pthread_cond_init(&info.cond, NULL);
5463 info.env = new_env;
5464 if (nptl_flags & CLONE_CHILD_SETTID)
5465 info.child_tidptr = child_tidptr;
5466 if (nptl_flags & CLONE_PARENT_SETTID)
5467 info.parent_tidptr = parent_tidptr;
5469 ret = pthread_attr_init(&attr);
5470 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
5471 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
5472 /* It is not safe to deliver signals until the child has finished
5473 initializing, so temporarily block all signals. */
5474 sigfillset(&sigmask);
5475 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
5477 ret = pthread_create(&info.thread, &attr, clone_func, &info);
5478 /* TODO: Free new CPU state if thread creation failed. */
5480 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
5481 pthread_attr_destroy(&attr);
5482 if (ret == 0) {
5483 /* Wait for the child to initialize. */
5484 pthread_cond_wait(&info.cond, &info.mutex);
5485 ret = info.tid;
5486 if (flags & CLONE_PARENT_SETTID)
5487 put_user_u32(ret, parent_tidptr);
5488 } else {
5489 ret = -1;
5491 pthread_mutex_unlock(&info.mutex);
5492 pthread_cond_destroy(&info.cond);
5493 pthread_mutex_destroy(&info.mutex);
5494 pthread_mutex_unlock(&clone_lock);
5495 } else {
5496 /* if no CLONE_VM, we consider it is a fork */
5497 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
5498 return -TARGET_EINVAL;
5501 if (block_signals()) {
5502 return -TARGET_ERESTARTSYS;
5505 fork_start();
5506 ret = fork();
5507 if (ret == 0) {
5508 /* Child Process. */
5509 rcu_after_fork();
5510 cpu_clone_regs(env, newsp);
5511 fork_end(1);
5512 /* There is a race condition here. The parent process could
5513 theoretically read the TID in the child process before the child
5514 tid is set. This would require using either ptrace
5515 (not implemented) or having *_tidptr to point at a shared memory
5516 mapping. We can't repeat the spinlock hack used above because
5517 the child process gets its own copy of the lock. */
5518 if (flags & CLONE_CHILD_SETTID)
5519 put_user_u32(gettid(), child_tidptr);
5520 if (flags & CLONE_PARENT_SETTID)
5521 put_user_u32(gettid(), parent_tidptr);
5522 ts = (TaskState *)cpu->opaque;
5523 if (flags & CLONE_SETTLS)
5524 cpu_set_tls (env, newtls);
5525 if (flags & CLONE_CHILD_CLEARTID)
5526 ts->child_tidptr = child_tidptr;
5527 } else {
5528 fork_end(0);
5531 return ret;
5534 /* warning : doesn't handle linux specific flags... */
5535 static int target_to_host_fcntl_cmd(int cmd)
5537 switch(cmd) {
5538 case TARGET_F_DUPFD:
5539 case TARGET_F_GETFD:
5540 case TARGET_F_SETFD:
5541 case TARGET_F_GETFL:
5542 case TARGET_F_SETFL:
5543 return cmd;
5544 case TARGET_F_GETLK:
5545 return F_GETLK;
5546 case TARGET_F_SETLK:
5547 return F_SETLK;
5548 case TARGET_F_SETLKW:
5549 return F_SETLKW;
5550 case TARGET_F_GETOWN:
5551 return F_GETOWN;
5552 case TARGET_F_SETOWN:
5553 return F_SETOWN;
5554 case TARGET_F_GETSIG:
5555 return F_GETSIG;
5556 case TARGET_F_SETSIG:
5557 return F_SETSIG;
5558 #if TARGET_ABI_BITS == 32
5559 case TARGET_F_GETLK64:
5560 return F_GETLK64;
5561 case TARGET_F_SETLK64:
5562 return F_SETLK64;
5563 case TARGET_F_SETLKW64:
5564 return F_SETLKW64;
5565 #endif
5566 case TARGET_F_SETLEASE:
5567 return F_SETLEASE;
5568 case TARGET_F_GETLEASE:
5569 return F_GETLEASE;
5570 #ifdef F_DUPFD_CLOEXEC
5571 case TARGET_F_DUPFD_CLOEXEC:
5572 return F_DUPFD_CLOEXEC;
5573 #endif
5574 case TARGET_F_NOTIFY:
5575 return F_NOTIFY;
5576 #ifdef F_GETOWN_EX
5577 case TARGET_F_GETOWN_EX:
5578 return F_GETOWN_EX;
5579 #endif
5580 #ifdef F_SETOWN_EX
5581 case TARGET_F_SETOWN_EX:
5582 return F_SETOWN_EX;
5583 #endif
5584 default:
5585 return -TARGET_EINVAL;
5587 return -TARGET_EINVAL;
5590 #define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
5591 static const bitmask_transtbl flock_tbl[] = {
5592 TRANSTBL_CONVERT(F_RDLCK),
5593 TRANSTBL_CONVERT(F_WRLCK),
5594 TRANSTBL_CONVERT(F_UNLCK),
5595 TRANSTBL_CONVERT(F_EXLCK),
5596 TRANSTBL_CONVERT(F_SHLCK),
5597 { 0, 0, 0, 0 }
5600 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
5602 struct flock fl;
5603 struct target_flock *target_fl;
5604 struct flock64 fl64;
5605 struct target_flock64 *target_fl64;
5606 #ifdef F_GETOWN_EX
5607 struct f_owner_ex fox;
5608 struct target_f_owner_ex *target_fox;
5609 #endif
5610 abi_long ret;
5611 int host_cmd = target_to_host_fcntl_cmd(cmd);
5613 if (host_cmd == -TARGET_EINVAL)
5614 return host_cmd;
5616 switch(cmd) {
5617 case TARGET_F_GETLK:
5618 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
5619 return -TARGET_EFAULT;
5620 fl.l_type =
5621 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
5622 fl.l_whence = tswap16(target_fl->l_whence);
5623 fl.l_start = tswapal(target_fl->l_start);
5624 fl.l_len = tswapal(target_fl->l_len);
5625 fl.l_pid = tswap32(target_fl->l_pid);
5626 unlock_user_struct(target_fl, arg, 0);
5627 ret = get_errno(fcntl(fd, host_cmd, &fl));
5628 if (ret == 0) {
5629 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
5630 return -TARGET_EFAULT;
5631 target_fl->l_type =
5632 host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
5633 target_fl->l_whence = tswap16(fl.l_whence);
5634 target_fl->l_start = tswapal(fl.l_start);
5635 target_fl->l_len = tswapal(fl.l_len);
5636 target_fl->l_pid = tswap32(fl.l_pid);
5637 unlock_user_struct(target_fl, arg, 1);
5639 break;
5641 case TARGET_F_SETLK:
5642 case TARGET_F_SETLKW:
5643 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
5644 return -TARGET_EFAULT;
5645 fl.l_type =
5646 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
5647 fl.l_whence = tswap16(target_fl->l_whence);
5648 fl.l_start = tswapal(target_fl->l_start);
5649 fl.l_len = tswapal(target_fl->l_len);
5650 fl.l_pid = tswap32(target_fl->l_pid);
5651 unlock_user_struct(target_fl, arg, 0);
5652 ret = get_errno(fcntl(fd, host_cmd, &fl));
5653 break;
5655 case TARGET_F_GETLK64:
5656 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
5657 return -TARGET_EFAULT;
5658 fl64.l_type =
5659 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
5660 fl64.l_whence = tswap16(target_fl64->l_whence);
5661 fl64.l_start = tswap64(target_fl64->l_start);
5662 fl64.l_len = tswap64(target_fl64->l_len);
5663 fl64.l_pid = tswap32(target_fl64->l_pid);
5664 unlock_user_struct(target_fl64, arg, 0);
5665 ret = get_errno(fcntl(fd, host_cmd, &fl64));
5666 if (ret == 0) {
5667 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
5668 return -TARGET_EFAULT;
5669 target_fl64->l_type =
5670 host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
5671 target_fl64->l_whence = tswap16(fl64.l_whence);
5672 target_fl64->l_start = tswap64(fl64.l_start);
5673 target_fl64->l_len = tswap64(fl64.l_len);
5674 target_fl64->l_pid = tswap32(fl64.l_pid);
5675 unlock_user_struct(target_fl64, arg, 1);
5677 break;
5678 case TARGET_F_SETLK64:
5679 case TARGET_F_SETLKW64:
5680 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
5681 return -TARGET_EFAULT;
5682 fl64.l_type =
5683 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
5684 fl64.l_whence = tswap16(target_fl64->l_whence);
5685 fl64.l_start = tswap64(target_fl64->l_start);
5686 fl64.l_len = tswap64(target_fl64->l_len);
5687 fl64.l_pid = tswap32(target_fl64->l_pid);
5688 unlock_user_struct(target_fl64, arg, 0);
5689 ret = get_errno(fcntl(fd, host_cmd, &fl64));
5690 break;
5692 case TARGET_F_GETFL:
5693 ret = get_errno(fcntl(fd, host_cmd, arg));
5694 if (ret >= 0) {
5695 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
5697 break;
5699 case TARGET_F_SETFL:
5700 ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
5701 break;
5703 #ifdef F_GETOWN_EX
5704 case TARGET_F_GETOWN_EX:
5705 ret = get_errno(fcntl(fd, host_cmd, &fox));
5706 if (ret >= 0) {
5707 if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
5708 return -TARGET_EFAULT;
5709 target_fox->type = tswap32(fox.type);
5710 target_fox->pid = tswap32(fox.pid);
5711 unlock_user_struct(target_fox, arg, 1);
5713 break;
5714 #endif
5716 #ifdef F_SETOWN_EX
5717 case TARGET_F_SETOWN_EX:
5718 if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1))
5719 return -TARGET_EFAULT;
5720 fox.type = tswap32(target_fox->type);
5721 fox.pid = tswap32(target_fox->pid);
5722 unlock_user_struct(target_fox, arg, 0);
5723 ret = get_errno(fcntl(fd, host_cmd, &fox));
5724 break;
5725 #endif
5727 case TARGET_F_SETOWN:
5728 case TARGET_F_GETOWN:
5729 case TARGET_F_SETSIG:
5730 case TARGET_F_GETSIG:
5731 case TARGET_F_SETLEASE:
5732 case TARGET_F_GETLEASE:
5733 ret = get_errno(fcntl(fd, host_cmd, arg));
5734 break;
5736 default:
5737 ret = get_errno(fcntl(fd, cmd, arg));
5738 break;
5740 return ret;
5743 #ifdef USE_UID16
5745 static inline int high2lowuid(int uid)
5747 if (uid > 65535)
5748 return 65534;
5749 else
5750 return uid;
5753 static inline int high2lowgid(int gid)
5755 if (gid > 65535)
5756 return 65534;
5757 else
5758 return gid;
5761 static inline int low2highuid(int uid)
5763 if ((int16_t)uid == -1)
5764 return -1;
5765 else
5766 return uid;
5769 static inline int low2highgid(int gid)
5771 if ((int16_t)gid == -1)
5772 return -1;
5773 else
5774 return gid;
5776 static inline int tswapid(int id)
5778 return tswap16(id);
5781 #define put_user_id(x, gaddr) put_user_u16(x, gaddr)
5783 #else /* !USE_UID16 */
5784 static inline int high2lowuid(int uid)
5786 return uid;
5788 static inline int high2lowgid(int gid)
5790 return gid;
5792 static inline int low2highuid(int uid)
5794 return uid;
5796 static inline int low2highgid(int gid)
5798 return gid;
5800 static inline int tswapid(int id)
5802 return tswap32(id);
5805 #define put_user_id(x, gaddr) put_user_u32(x, gaddr)
5807 #endif /* USE_UID16 */
5809 /* We must do direct syscalls for setting UID/GID, because we want to
5810 * implement the Linux system call semantics of "change only for this thread",
5811 * not the libc/POSIX semantics of "change for all threads in process".
5812 * (See http://ewontfix.com/17/ for more details.)
5813 * We use the 32-bit version of the syscalls if present; if it is not
5814 * then either the host architecture supports 32-bit UIDs natively with
5815 * the standard syscall, or the 16-bit UID is the best we can do.
5817 #ifdef __NR_setuid32
5818 #define __NR_sys_setuid __NR_setuid32
5819 #else
5820 #define __NR_sys_setuid __NR_setuid
5821 #endif
5822 #ifdef __NR_setgid32
5823 #define __NR_sys_setgid __NR_setgid32
5824 #else
5825 #define __NR_sys_setgid __NR_setgid
5826 #endif
5827 #ifdef __NR_setresuid32
5828 #define __NR_sys_setresuid __NR_setresuid32
5829 #else
5830 #define __NR_sys_setresuid __NR_setresuid
5831 #endif
5832 #ifdef __NR_setresgid32
5833 #define __NR_sys_setresgid __NR_setresgid32
5834 #else
5835 #define __NR_sys_setresgid __NR_setresgid
5836 #endif
5838 _syscall1(int, sys_setuid, uid_t, uid)
5839 _syscall1(int, sys_setgid, gid_t, gid)
5840 _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
5841 _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
5843 void syscall_init(void)
5845 IOCTLEntry *ie;
5846 const argtype *arg_type;
5847 int size;
5848 int i;
5850 thunk_init(STRUCT_MAX);
5852 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
5853 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
5854 #include "syscall_types.h"
5855 #undef STRUCT
5856 #undef STRUCT_SPECIAL
5858 /* Build target_to_host_errno_table[] table from
5859 * host_to_target_errno_table[]. */
5860 for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
5861 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
5864 /* we patch the ioctl size if necessary. We rely on the fact that
5865 no ioctl has all the bits at '1' in the size field */
5866 ie = ioctl_entries;
5867 while (ie->target_cmd != 0) {
5868 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
5869 TARGET_IOC_SIZEMASK) {
5870 arg_type = ie->arg_type;
5871 if (arg_type[0] != TYPE_PTR) {
5872 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
5873 ie->target_cmd);
5874 exit(1);
5876 arg_type++;
5877 size = thunk_type_size(arg_type, 0);
5878 ie->target_cmd = (ie->target_cmd &
5879 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
5880 (size << TARGET_IOC_SIZESHIFT);
5883 /* automatic consistency check if same arch */
5884 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
5885 (defined(__x86_64__) && defined(TARGET_X86_64))
5886 if (unlikely(ie->target_cmd != ie->host_cmd)) {
5887 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
5888 ie->name, ie->target_cmd, ie->host_cmd);
5890 #endif
5891 ie++;
5895 #if TARGET_ABI_BITS == 32
5896 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
5898 #ifdef TARGET_WORDS_BIGENDIAN
5899 return ((uint64_t)word0 << 32) | word1;
5900 #else
5901 return ((uint64_t)word1 << 32) | word0;
5902 #endif
5904 #else /* TARGET_ABI_BITS == 32 */
5905 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
5907 return word0;
5909 #endif /* TARGET_ABI_BITS != 32 */
5911 #ifdef TARGET_NR_truncate64
5912 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
5913 abi_long arg2,
5914 abi_long arg3,
5915 abi_long arg4)
5917 if (regpairs_aligned(cpu_env)) {
5918 arg2 = arg3;
5919 arg3 = arg4;
5921 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
5923 #endif
5925 #ifdef TARGET_NR_ftruncate64
5926 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
5927 abi_long arg2,
5928 abi_long arg3,
5929 abi_long arg4)
5931 if (regpairs_aligned(cpu_env)) {
5932 arg2 = arg3;
5933 arg3 = arg4;
5935 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
5937 #endif
5939 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
5940 abi_ulong target_addr)
5942 struct target_timespec *target_ts;
5944 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
5945 return -TARGET_EFAULT;
5946 __get_user(host_ts->tv_sec, &target_ts->tv_sec);
5947 __get_user(host_ts->tv_nsec, &target_ts->tv_nsec);
5948 unlock_user_struct(target_ts, target_addr, 0);
5949 return 0;
5952 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
5953 struct timespec *host_ts)
5955 struct target_timespec *target_ts;
5957 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
5958 return -TARGET_EFAULT;
5959 __put_user(host_ts->tv_sec, &target_ts->tv_sec);
5960 __put_user(host_ts->tv_nsec, &target_ts->tv_nsec);
5961 unlock_user_struct(target_ts, target_addr, 1);
5962 return 0;
5965 static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec,
5966 abi_ulong target_addr)
5968 struct target_itimerspec *target_itspec;
5970 if (!lock_user_struct(VERIFY_READ, target_itspec, target_addr, 1)) {
5971 return -TARGET_EFAULT;
5974 host_itspec->it_interval.tv_sec =
5975 tswapal(target_itspec->it_interval.tv_sec);
5976 host_itspec->it_interval.tv_nsec =
5977 tswapal(target_itspec->it_interval.tv_nsec);
5978 host_itspec->it_value.tv_sec = tswapal(target_itspec->it_value.tv_sec);
5979 host_itspec->it_value.tv_nsec = tswapal(target_itspec->it_value.tv_nsec);
5981 unlock_user_struct(target_itspec, target_addr, 1);
5982 return 0;
5985 static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
5986 struct itimerspec *host_its)
5988 struct target_itimerspec *target_itspec;
5990 if (!lock_user_struct(VERIFY_WRITE, target_itspec, target_addr, 0)) {
5991 return -TARGET_EFAULT;
5994 target_itspec->it_interval.tv_sec = tswapal(host_its->it_interval.tv_sec);
5995 target_itspec->it_interval.tv_nsec = tswapal(host_its->it_interval.tv_nsec);
5997 target_itspec->it_value.tv_sec = tswapal(host_its->it_value.tv_sec);
5998 target_itspec->it_value.tv_nsec = tswapal(host_its->it_value.tv_nsec);
6000 unlock_user_struct(target_itspec, target_addr, 0);
6001 return 0;
6004 static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
6005 abi_ulong target_addr)
6007 struct target_sigevent *target_sevp;
6009 if (!lock_user_struct(VERIFY_READ, target_sevp, target_addr, 1)) {
6010 return -TARGET_EFAULT;
6013 /* This union is awkward on 64 bit systems because it has a 32 bit
6014 * integer and a pointer in it; we follow the conversion approach
6015 * used for handling sigval types in signal.c so the guest should get
6016 * the correct value back even if we did a 64 bit byteswap and it's
6017 * using the 32 bit integer.
6019 host_sevp->sigev_value.sival_ptr =
6020 (void *)(uintptr_t)tswapal(target_sevp->sigev_value.sival_ptr);
6021 host_sevp->sigev_signo =
6022 target_to_host_signal(tswap32(target_sevp->sigev_signo));
6023 host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
6024 host_sevp->_sigev_un._tid = tswap32(target_sevp->_sigev_un._tid);
6026 unlock_user_struct(target_sevp, target_addr, 1);
6027 return 0;
6030 #if defined(TARGET_NR_mlockall)
6031 static inline int target_to_host_mlockall_arg(int arg)
6033 int result = 0;
6035 if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
6036 result |= MCL_CURRENT;
6038 if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
6039 result |= MCL_FUTURE;
6041 return result;
6043 #endif
6045 static inline abi_long host_to_target_stat64(void *cpu_env,
6046 abi_ulong target_addr,
6047 struct stat *host_st)
6049 #if defined(TARGET_ARM) && defined(TARGET_ABI32)
6050 if (((CPUARMState *)cpu_env)->eabi) {
6051 struct target_eabi_stat64 *target_st;
6053 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
6054 return -TARGET_EFAULT;
6055 memset(target_st, 0, sizeof(struct target_eabi_stat64));
6056 __put_user(host_st->st_dev, &target_st->st_dev);
6057 __put_user(host_st->st_ino, &target_st->st_ino);
6058 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
6059 __put_user(host_st->st_ino, &target_st->__st_ino);
6060 #endif
6061 __put_user(host_st->st_mode, &target_st->st_mode);
6062 __put_user(host_st->st_nlink, &target_st->st_nlink);
6063 __put_user(host_st->st_uid, &target_st->st_uid);
6064 __put_user(host_st->st_gid, &target_st->st_gid);
6065 __put_user(host_st->st_rdev, &target_st->st_rdev);
6066 __put_user(host_st->st_size, &target_st->st_size);
6067 __put_user(host_st->st_blksize, &target_st->st_blksize);
6068 __put_user(host_st->st_blocks, &target_st->st_blocks);
6069 __put_user(host_st->st_atime, &target_st->target_st_atime);
6070 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
6071 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
6072 unlock_user_struct(target_st, target_addr, 1);
6073 } else
6074 #endif
6076 #if defined(TARGET_HAS_STRUCT_STAT64)
6077 struct target_stat64 *target_st;
6078 #else
6079 struct target_stat *target_st;
6080 #endif
6082 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
6083 return -TARGET_EFAULT;
6084 memset(target_st, 0, sizeof(*target_st));
6085 __put_user(host_st->st_dev, &target_st->st_dev);
6086 __put_user(host_st->st_ino, &target_st->st_ino);
6087 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
6088 __put_user(host_st->st_ino, &target_st->__st_ino);
6089 #endif
6090 __put_user(host_st->st_mode, &target_st->st_mode);
6091 __put_user(host_st->st_nlink, &target_st->st_nlink);
6092 __put_user(host_st->st_uid, &target_st->st_uid);
6093 __put_user(host_st->st_gid, &target_st->st_gid);
6094 __put_user(host_st->st_rdev, &target_st->st_rdev);
6095 /* XXX: better use of kernel struct */
6096 __put_user(host_st->st_size, &target_st->st_size);
6097 __put_user(host_st->st_blksize, &target_st->st_blksize);
6098 __put_user(host_st->st_blocks, &target_st->st_blocks);
6099 __put_user(host_st->st_atime, &target_st->target_st_atime);
6100 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
6101 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
6102 unlock_user_struct(target_st, target_addr, 1);
6105 return 0;
6108 /* ??? Using host futex calls even when target atomic operations
6109 are not really atomic probably breaks things. However implementing
6110 futexes locally would make futexes shared between multiple processes
6111 tricky. However they're probably useless because guest atomic
6112 operations won't work either. */
6113 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
6114 target_ulong uaddr2, int val3)
6116 struct timespec ts, *pts;
6117 int base_op;
6119 /* ??? We assume FUTEX_* constants are the same on both host
6120 and target. */
6121 #ifdef FUTEX_CMD_MASK
6122 base_op = op & FUTEX_CMD_MASK;
6123 #else
6124 base_op = op;
6125 #endif
6126 switch (base_op) {
6127 case FUTEX_WAIT:
6128 case FUTEX_WAIT_BITSET:
6129 if (timeout) {
6130 pts = &ts;
6131 target_to_host_timespec(pts, timeout);
6132 } else {
6133 pts = NULL;
6135 return get_errno(safe_futex(g2h(uaddr), op, tswap32(val),
6136 pts, NULL, val3));
6137 case FUTEX_WAKE:
6138 return get_errno(safe_futex(g2h(uaddr), op, val, NULL, NULL, 0));
6139 case FUTEX_FD:
6140 return get_errno(safe_futex(g2h(uaddr), op, val, NULL, NULL, 0));
6141 case FUTEX_REQUEUE:
6142 case FUTEX_CMP_REQUEUE:
6143 case FUTEX_WAKE_OP:
6144 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
6145 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
6146 But the prototype takes a `struct timespec *'; insert casts
6147 to satisfy the compiler. We do not need to tswap TIMEOUT
6148 since it's not compared to guest memory. */
6149 pts = (struct timespec *)(uintptr_t) timeout;
6150 return get_errno(safe_futex(g2h(uaddr), op, val, pts,
6151 g2h(uaddr2),
6152 (base_op == FUTEX_CMP_REQUEUE
6153 ? tswap32(val3)
6154 : val3)));
6155 default:
6156 return -TARGET_ENOSYS;
6159 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
6160 static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
6161 abi_long handle, abi_long mount_id,
6162 abi_long flags)
6164 struct file_handle *target_fh;
6165 struct file_handle *fh;
6166 int mid = 0;
6167 abi_long ret;
6168 char *name;
6169 unsigned int size, total_size;
6171 if (get_user_s32(size, handle)) {
6172 return -TARGET_EFAULT;
6175 name = lock_user_string(pathname);
6176 if (!name) {
6177 return -TARGET_EFAULT;
6180 total_size = sizeof(struct file_handle) + size;
6181 target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
6182 if (!target_fh) {
6183 unlock_user(name, pathname, 0);
6184 return -TARGET_EFAULT;
6187 fh = g_malloc0(total_size);
6188 fh->handle_bytes = size;
6190 ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
6191 unlock_user(name, pathname, 0);
6193 /* man name_to_handle_at(2):
6194 * Other than the use of the handle_bytes field, the caller should treat
6195 * the file_handle structure as an opaque data type
6198 memcpy(target_fh, fh, total_size);
6199 target_fh->handle_bytes = tswap32(fh->handle_bytes);
6200 target_fh->handle_type = tswap32(fh->handle_type);
6201 g_free(fh);
6202 unlock_user(target_fh, handle, total_size);
6204 if (put_user_s32(mid, mount_id)) {
6205 return -TARGET_EFAULT;
6208 return ret;
6211 #endif
6213 #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
6214 static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
6215 abi_long flags)
6217 struct file_handle *target_fh;
6218 struct file_handle *fh;
6219 unsigned int size, total_size;
6220 abi_long ret;
6222 if (get_user_s32(size, handle)) {
6223 return -TARGET_EFAULT;
6226 total_size = sizeof(struct file_handle) + size;
6227 target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
6228 if (!target_fh) {
6229 return -TARGET_EFAULT;
6232 fh = g_memdup(target_fh, total_size);
6233 fh->handle_bytes = size;
6234 fh->handle_type = tswap32(target_fh->handle_type);
6236 ret = get_errno(open_by_handle_at(mount_fd, fh,
6237 target_to_host_bitmask(flags, fcntl_flags_tbl)));
6239 g_free(fh);
6241 unlock_user(target_fh, handle, total_size);
6243 return ret;
6245 #endif
6247 #if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
6249 /* signalfd siginfo conversion */
6251 static void
6252 host_to_target_signalfd_siginfo(struct signalfd_siginfo *tinfo,
6253 const struct signalfd_siginfo *info)
6255 int sig = host_to_target_signal(info->ssi_signo);
6257 /* linux/signalfd.h defines a ssi_addr_lsb
6258 * not defined in sys/signalfd.h but used by some kernels
6261 #ifdef BUS_MCEERR_AO
6262 if (tinfo->ssi_signo == SIGBUS &&
6263 (tinfo->ssi_code == BUS_MCEERR_AR ||
6264 tinfo->ssi_code == BUS_MCEERR_AO)) {
6265 uint16_t *ssi_addr_lsb = (uint16_t *)(&info->ssi_addr + 1);
6266 uint16_t *tssi_addr_lsb = (uint16_t *)(&tinfo->ssi_addr + 1);
6267 *tssi_addr_lsb = tswap16(*ssi_addr_lsb);
6269 #endif
6271 tinfo->ssi_signo = tswap32(sig);
6272 tinfo->ssi_errno = tswap32(tinfo->ssi_errno);
6273 tinfo->ssi_code = tswap32(info->ssi_code);
6274 tinfo->ssi_pid = tswap32(info->ssi_pid);
6275 tinfo->ssi_uid = tswap32(info->ssi_uid);
6276 tinfo->ssi_fd = tswap32(info->ssi_fd);
6277 tinfo->ssi_tid = tswap32(info->ssi_tid);
6278 tinfo->ssi_band = tswap32(info->ssi_band);
6279 tinfo->ssi_overrun = tswap32(info->ssi_overrun);
6280 tinfo->ssi_trapno = tswap32(info->ssi_trapno);
6281 tinfo->ssi_status = tswap32(info->ssi_status);
6282 tinfo->ssi_int = tswap32(info->ssi_int);
6283 tinfo->ssi_ptr = tswap64(info->ssi_ptr);
6284 tinfo->ssi_utime = tswap64(info->ssi_utime);
6285 tinfo->ssi_stime = tswap64(info->ssi_stime);
6286 tinfo->ssi_addr = tswap64(info->ssi_addr);
6289 static abi_long host_to_target_data_signalfd(void *buf, size_t len)
6291 int i;
6293 for (i = 0; i < len; i += sizeof(struct signalfd_siginfo)) {
6294 host_to_target_signalfd_siginfo(buf + i, buf + i);
6297 return len;
6300 static TargetFdTrans target_signalfd_trans = {
6301 .host_to_target_data = host_to_target_data_signalfd,
6304 static abi_long do_signalfd4(int fd, abi_long mask, int flags)
6306 int host_flags;
6307 target_sigset_t *target_mask;
6308 sigset_t host_mask;
6309 abi_long ret;
6311 if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
6312 return -TARGET_EINVAL;
6314 if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
6315 return -TARGET_EFAULT;
6318 target_to_host_sigset(&host_mask, target_mask);
6320 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
6322 ret = get_errno(signalfd(fd, &host_mask, host_flags));
6323 if (ret >= 0) {
6324 fd_trans_register(ret, &target_signalfd_trans);
6327 unlock_user_struct(target_mask, mask, 0);
6329 return ret;
6331 #endif
6333 /* Map host to target signal numbers for the wait family of syscalls.
6334 Assume all other status bits are the same. */
6335 int host_to_target_waitstatus(int status)
6337 if (WIFSIGNALED(status)) {
6338 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
6340 if (WIFSTOPPED(status)) {
6341 return (host_to_target_signal(WSTOPSIG(status)) << 8)
6342 | (status & 0xff);
6344 return status;
6347 static int open_self_cmdline(void *cpu_env, int fd)
6349 int fd_orig = -1;
6350 bool word_skipped = false;
6352 fd_orig = open("/proc/self/cmdline", O_RDONLY);
6353 if (fd_orig < 0) {
6354 return fd_orig;
6357 while (true) {
6358 ssize_t nb_read;
6359 char buf[128];
6360 char *cp_buf = buf;
6362 nb_read = read(fd_orig, buf, sizeof(buf));
6363 if (nb_read < 0) {
6364 int e = errno;
6365 fd_orig = close(fd_orig);
6366 errno = e;
6367 return -1;
6368 } else if (nb_read == 0) {
6369 break;
6372 if (!word_skipped) {
6373 /* Skip the first string, which is the path to qemu-*-static
6374 instead of the actual command. */
6375 cp_buf = memchr(buf, 0, sizeof(buf));
6376 if (cp_buf) {
6377 /* Null byte found, skip one string */
6378 cp_buf++;
6379 nb_read -= cp_buf - buf;
6380 word_skipped = true;
6384 if (word_skipped) {
6385 if (write(fd, cp_buf, nb_read) != nb_read) {
6386 int e = errno;
6387 close(fd_orig);
6388 errno = e;
6389 return -1;
6394 return close(fd_orig);
6397 static int open_self_maps(void *cpu_env, int fd)
6399 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
6400 TaskState *ts = cpu->opaque;
6401 FILE *fp;
6402 char *line = NULL;
6403 size_t len = 0;
6404 ssize_t read;
6406 fp = fopen("/proc/self/maps", "r");
6407 if (fp == NULL) {
6408 return -1;
6411 while ((read = getline(&line, &len, fp)) != -1) {
6412 int fields, dev_maj, dev_min, inode;
6413 uint64_t min, max, offset;
6414 char flag_r, flag_w, flag_x, flag_p;
6415 char path[512] = "";
6416 fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
6417 " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
6418 &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
6420 if ((fields < 10) || (fields > 11)) {
6421 continue;
6423 if (h2g_valid(min)) {
6424 int flags = page_get_flags(h2g(min));
6425 max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX);
6426 if (page_check_range(h2g(min), max - min, flags) == -1) {
6427 continue;
6429 if (h2g(min) == ts->info->stack_limit) {
6430 pstrcpy(path, sizeof(path), " [stack]");
6432 dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
6433 " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
6434 h2g(min), h2g(max - 1) + 1, flag_r, flag_w,
6435 flag_x, flag_p, offset, dev_maj, dev_min, inode,
6436 path[0] ? " " : "", path);
6440 free(line);
6441 fclose(fp);
6443 return 0;
6446 static int open_self_stat(void *cpu_env, int fd)
6448 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
6449 TaskState *ts = cpu->opaque;
6450 abi_ulong start_stack = ts->info->start_stack;
6451 int i;
6453 for (i = 0; i < 44; i++) {
6454 char buf[128];
6455 int len;
6456 uint64_t val = 0;
6458 if (i == 0) {
6459 /* pid */
6460 val = getpid();
6461 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
6462 } else if (i == 1) {
6463 /* app name */
6464 snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
6465 } else if (i == 27) {
6466 /* stack bottom */
6467 val = start_stack;
6468 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
6469 } else {
6470 /* for the rest, there is MasterCard */
6471 snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
6474 len = strlen(buf);
6475 if (write(fd, buf, len) != len) {
6476 return -1;
6480 return 0;
6483 static int open_self_auxv(void *cpu_env, int fd)
6485 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
6486 TaskState *ts = cpu->opaque;
6487 abi_ulong auxv = ts->info->saved_auxv;
6488 abi_ulong len = ts->info->auxv_len;
6489 char *ptr;
6492 * Auxiliary vector is stored in target process stack.
6493 * read in whole auxv vector and copy it to file
6495 ptr = lock_user(VERIFY_READ, auxv, len, 0);
6496 if (ptr != NULL) {
6497 while (len > 0) {
6498 ssize_t r;
6499 r = write(fd, ptr, len);
6500 if (r <= 0) {
6501 break;
6503 len -= r;
6504 ptr += r;
6506 lseek(fd, 0, SEEK_SET);
6507 unlock_user(ptr, auxv, len);
6510 return 0;
6513 static int is_proc_myself(const char *filename, const char *entry)
6515 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
6516 filename += strlen("/proc/");
6517 if (!strncmp(filename, "self/", strlen("self/"))) {
6518 filename += strlen("self/");
6519 } else if (*filename >= '1' && *filename <= '9') {
6520 char myself[80];
6521 snprintf(myself, sizeof(myself), "%d/", getpid());
6522 if (!strncmp(filename, myself, strlen(myself))) {
6523 filename += strlen(myself);
6524 } else {
6525 return 0;
6527 } else {
6528 return 0;
6530 if (!strcmp(filename, entry)) {
6531 return 1;
6534 return 0;
6537 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
6538 static int is_proc(const char *filename, const char *entry)
6540 return strcmp(filename, entry) == 0;
6543 static int open_net_route(void *cpu_env, int fd)
6545 FILE *fp;
6546 char *line = NULL;
6547 size_t len = 0;
6548 ssize_t read;
6550 fp = fopen("/proc/net/route", "r");
6551 if (fp == NULL) {
6552 return -1;
6555 /* read header */
6557 read = getline(&line, &len, fp);
6558 dprintf(fd, "%s", line);
6560 /* read routes */
6562 while ((read = getline(&line, &len, fp)) != -1) {
6563 char iface[16];
6564 uint32_t dest, gw, mask;
6565 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
6566 sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
6567 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
6568 &mask, &mtu, &window, &irtt);
6569 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
6570 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
6571 metric, tswap32(mask), mtu, window, irtt);
6574 free(line);
6575 fclose(fp);
6577 return 0;
6579 #endif
6581 static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
6583 struct fake_open {
6584 const char *filename;
6585 int (*fill)(void *cpu_env, int fd);
6586 int (*cmp)(const char *s1, const char *s2);
6588 const struct fake_open *fake_open;
6589 static const struct fake_open fakes[] = {
6590 { "maps", open_self_maps, is_proc_myself },
6591 { "stat", open_self_stat, is_proc_myself },
6592 { "auxv", open_self_auxv, is_proc_myself },
6593 { "cmdline", open_self_cmdline, is_proc_myself },
6594 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
6595 { "/proc/net/route", open_net_route, is_proc },
6596 #endif
6597 { NULL, NULL, NULL }
6600 if (is_proc_myself(pathname, "exe")) {
6601 int execfd = qemu_getauxval(AT_EXECFD);
6602 return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
6605 for (fake_open = fakes; fake_open->filename; fake_open++) {
6606 if (fake_open->cmp(pathname, fake_open->filename)) {
6607 break;
6611 if (fake_open->filename) {
6612 const char *tmpdir;
6613 char filename[PATH_MAX];
6614 int fd, r;
6616 /* create temporary file to map stat to */
6617 tmpdir = getenv("TMPDIR");
6618 if (!tmpdir)
6619 tmpdir = "/tmp";
6620 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
6621 fd = mkstemp(filename);
6622 if (fd < 0) {
6623 return fd;
6625 unlink(filename);
6627 if ((r = fake_open->fill(cpu_env, fd))) {
6628 int e = errno;
6629 close(fd);
6630 errno = e;
6631 return r;
6633 lseek(fd, 0, SEEK_SET);
6635 return fd;
6638 return safe_openat(dirfd, path(pathname), flags, mode);
6641 #define TIMER_MAGIC 0x0caf0000
6642 #define TIMER_MAGIC_MASK 0xffff0000
6644 /* Convert QEMU provided timer ID back to internal 16bit index format */
6645 static target_timer_t get_timer_id(abi_long arg)
6647 target_timer_t timerid = arg;
6649 if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
6650 return -TARGET_EINVAL;
6653 timerid &= 0xffff;
6655 if (timerid >= ARRAY_SIZE(g_posix_timers)) {
6656 return -TARGET_EINVAL;
6659 return timerid;
6662 /* do_syscall() should always have a single exit point at the end so
6663 that actions, such as logging of syscall results, can be performed.
6664 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
6665 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
6666 abi_long arg2, abi_long arg3, abi_long arg4,
6667 abi_long arg5, abi_long arg6, abi_long arg7,
6668 abi_long arg8)
6670 CPUState *cpu = ENV_GET_CPU(cpu_env);
6671 abi_long ret;
6672 struct stat st;
6673 struct statfs stfs;
6674 void *p;
6676 #if defined(DEBUG_ERESTARTSYS)
6677 /* Debug-only code for exercising the syscall-restart code paths
6678 * in the per-architecture cpu main loops: restart every syscall
6679 * the guest makes once before letting it through.
6682 static int flag;
6684 flag = !flag;
6685 if (flag) {
6686 return -TARGET_ERESTARTSYS;
6689 #endif
6691 #ifdef DEBUG
6692 gemu_log("syscall %d", num);
6693 #endif
6694 if(do_strace)
6695 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
6697 switch(num) {
6698 case TARGET_NR_exit:
6699 /* In old applications this may be used to implement _exit(2).
6700 However in threaded applictions it is used for thread termination,
6701 and _exit_group is used for application termination.
6702 Do thread termination if we have more then one thread. */
6704 if (block_signals()) {
6705 ret = -TARGET_ERESTARTSYS;
6706 break;
6709 if (CPU_NEXT(first_cpu)) {
6710 TaskState *ts;
6712 cpu_list_lock();
6713 /* Remove the CPU from the list. */
6714 QTAILQ_REMOVE(&cpus, cpu, node);
6715 cpu_list_unlock();
6716 ts = cpu->opaque;
6717 if (ts->child_tidptr) {
6718 put_user_u32(0, ts->child_tidptr);
6719 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
6720 NULL, NULL, 0);
6722 thread_cpu = NULL;
6723 object_unref(OBJECT(cpu));
6724 g_free(ts);
6725 rcu_unregister_thread();
6726 pthread_exit(NULL);
6728 #ifdef TARGET_GPROF
6729 _mcleanup();
6730 #endif
6731 gdb_exit(cpu_env, arg1);
6732 _exit(arg1);
6733 ret = 0; /* avoid warning */
6734 break;
6735 case TARGET_NR_read:
6736 if (arg3 == 0)
6737 ret = 0;
6738 else {
6739 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6740 goto efault;
6741 ret = get_errno(safe_read(arg1, p, arg3));
6742 if (ret >= 0 &&
6743 fd_trans_host_to_target_data(arg1)) {
6744 ret = fd_trans_host_to_target_data(arg1)(p, ret);
6746 unlock_user(p, arg2, ret);
6748 break;
6749 case TARGET_NR_write:
6750 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6751 goto efault;
6752 ret = get_errno(safe_write(arg1, p, arg3));
6753 unlock_user(p, arg2, 0);
6754 break;
6755 #ifdef TARGET_NR_open
6756 case TARGET_NR_open:
6757 if (!(p = lock_user_string(arg1)))
6758 goto efault;
6759 ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
6760 target_to_host_bitmask(arg2, fcntl_flags_tbl),
6761 arg3));
6762 fd_trans_unregister(ret);
6763 unlock_user(p, arg1, 0);
6764 break;
6765 #endif
6766 case TARGET_NR_openat:
6767 if (!(p = lock_user_string(arg2)))
6768 goto efault;
6769 ret = get_errno(do_openat(cpu_env, arg1, p,
6770 target_to_host_bitmask(arg3, fcntl_flags_tbl),
6771 arg4));
6772 fd_trans_unregister(ret);
6773 unlock_user(p, arg2, 0);
6774 break;
6775 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
6776 case TARGET_NR_name_to_handle_at:
6777 ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
6778 break;
6779 #endif
6780 #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
6781 case TARGET_NR_open_by_handle_at:
6782 ret = do_open_by_handle_at(arg1, arg2, arg3);
6783 fd_trans_unregister(ret);
6784 break;
6785 #endif
6786 case TARGET_NR_close:
6787 fd_trans_unregister(arg1);
6788 ret = get_errno(close(arg1));
6789 break;
6790 case TARGET_NR_brk:
6791 ret = do_brk(arg1);
6792 break;
6793 #ifdef TARGET_NR_fork
6794 case TARGET_NR_fork:
6795 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
6796 break;
6797 #endif
6798 #ifdef TARGET_NR_waitpid
6799 case TARGET_NR_waitpid:
6801 int status;
6802 ret = get_errno(safe_wait4(arg1, &status, arg3, 0));
6803 if (!is_error(ret) && arg2 && ret
6804 && put_user_s32(host_to_target_waitstatus(status), arg2))
6805 goto efault;
6807 break;
6808 #endif
6809 #ifdef TARGET_NR_waitid
6810 case TARGET_NR_waitid:
6812 siginfo_t info;
6813 info.si_pid = 0;
6814 ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
6815 if (!is_error(ret) && arg3 && info.si_pid != 0) {
6816 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
6817 goto efault;
6818 host_to_target_siginfo(p, &info);
6819 unlock_user(p, arg3, sizeof(target_siginfo_t));
6822 break;
6823 #endif
6824 #ifdef TARGET_NR_creat /* not on alpha */
6825 case TARGET_NR_creat:
6826 if (!(p = lock_user_string(arg1)))
6827 goto efault;
6828 ret = get_errno(creat(p, arg2));
6829 fd_trans_unregister(ret);
6830 unlock_user(p, arg1, 0);
6831 break;
6832 #endif
6833 #ifdef TARGET_NR_link
6834 case TARGET_NR_link:
6836 void * p2;
6837 p = lock_user_string(arg1);
6838 p2 = lock_user_string(arg2);
6839 if (!p || !p2)
6840 ret = -TARGET_EFAULT;
6841 else
6842 ret = get_errno(link(p, p2));
6843 unlock_user(p2, arg2, 0);
6844 unlock_user(p, arg1, 0);
6846 break;
6847 #endif
6848 #if defined(TARGET_NR_linkat)
6849 case TARGET_NR_linkat:
6851 void * p2 = NULL;
6852 if (!arg2 || !arg4)
6853 goto efault;
6854 p = lock_user_string(arg2);
6855 p2 = lock_user_string(arg4);
6856 if (!p || !p2)
6857 ret = -TARGET_EFAULT;
6858 else
6859 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
6860 unlock_user(p, arg2, 0);
6861 unlock_user(p2, arg4, 0);
6863 break;
6864 #endif
6865 #ifdef TARGET_NR_unlink
6866 case TARGET_NR_unlink:
6867 if (!(p = lock_user_string(arg1)))
6868 goto efault;
6869 ret = get_errno(unlink(p));
6870 unlock_user(p, arg1, 0);
6871 break;
6872 #endif
6873 #if defined(TARGET_NR_unlinkat)
6874 case TARGET_NR_unlinkat:
6875 if (!(p = lock_user_string(arg2)))
6876 goto efault;
6877 ret = get_errno(unlinkat(arg1, p, arg3));
6878 unlock_user(p, arg2, 0);
6879 break;
6880 #endif
6881 case TARGET_NR_execve:
6883 char **argp, **envp;
6884 int argc, envc;
6885 abi_ulong gp;
6886 abi_ulong guest_argp;
6887 abi_ulong guest_envp;
6888 abi_ulong addr;
6889 char **q;
6890 int total_size = 0;
6892 argc = 0;
6893 guest_argp = arg2;
6894 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
6895 if (get_user_ual(addr, gp))
6896 goto efault;
6897 if (!addr)
6898 break;
6899 argc++;
6901 envc = 0;
6902 guest_envp = arg3;
6903 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
6904 if (get_user_ual(addr, gp))
6905 goto efault;
6906 if (!addr)
6907 break;
6908 envc++;
6911 argp = alloca((argc + 1) * sizeof(void *));
6912 envp = alloca((envc + 1) * sizeof(void *));
6914 for (gp = guest_argp, q = argp; gp;
6915 gp += sizeof(abi_ulong), q++) {
6916 if (get_user_ual(addr, gp))
6917 goto execve_efault;
6918 if (!addr)
6919 break;
6920 if (!(*q = lock_user_string(addr)))
6921 goto execve_efault;
6922 total_size += strlen(*q) + 1;
6924 *q = NULL;
6926 for (gp = guest_envp, q = envp; gp;
6927 gp += sizeof(abi_ulong), q++) {
6928 if (get_user_ual(addr, gp))
6929 goto execve_efault;
6930 if (!addr)
6931 break;
6932 if (!(*q = lock_user_string(addr)))
6933 goto execve_efault;
6934 total_size += strlen(*q) + 1;
6936 *q = NULL;
6938 if (!(p = lock_user_string(arg1)))
6939 goto execve_efault;
6940 /* Although execve() is not an interruptible syscall it is
6941 * a special case where we must use the safe_syscall wrapper:
6942 * if we allow a signal to happen before we make the host
6943 * syscall then we will 'lose' it, because at the point of
6944 * execve the process leaves QEMU's control. So we use the
6945 * safe syscall wrapper to ensure that we either take the
6946 * signal as a guest signal, or else it does not happen
6947 * before the execve completes and makes it the other
6948 * program's problem.
6950 ret = get_errno(safe_execve(p, argp, envp));
6951 unlock_user(p, arg1, 0);
6953 goto execve_end;
6955 execve_efault:
6956 ret = -TARGET_EFAULT;
6958 execve_end:
6959 for (gp = guest_argp, q = argp; *q;
6960 gp += sizeof(abi_ulong), q++) {
6961 if (get_user_ual(addr, gp)
6962 || !addr)
6963 break;
6964 unlock_user(*q, addr, 0);
6966 for (gp = guest_envp, q = envp; *q;
6967 gp += sizeof(abi_ulong), q++) {
6968 if (get_user_ual(addr, gp)
6969 || !addr)
6970 break;
6971 unlock_user(*q, addr, 0);
6974 break;
6975 case TARGET_NR_chdir:
6976 if (!(p = lock_user_string(arg1)))
6977 goto efault;
6978 ret = get_errno(chdir(p));
6979 unlock_user(p, arg1, 0);
6980 break;
6981 #ifdef TARGET_NR_time
6982 case TARGET_NR_time:
6984 time_t host_time;
6985 ret = get_errno(time(&host_time));
6986 if (!is_error(ret)
6987 && arg1
6988 && put_user_sal(host_time, arg1))
6989 goto efault;
6991 break;
6992 #endif
6993 #ifdef TARGET_NR_mknod
6994 case TARGET_NR_mknod:
6995 if (!(p = lock_user_string(arg1)))
6996 goto efault;
6997 ret = get_errno(mknod(p, arg2, arg3));
6998 unlock_user(p, arg1, 0);
6999 break;
7000 #endif
7001 #if defined(TARGET_NR_mknodat)
7002 case TARGET_NR_mknodat:
7003 if (!(p = lock_user_string(arg2)))
7004 goto efault;
7005 ret = get_errno(mknodat(arg1, p, arg3, arg4));
7006 unlock_user(p, arg2, 0);
7007 break;
7008 #endif
7009 #ifdef TARGET_NR_chmod
7010 case TARGET_NR_chmod:
7011 if (!(p = lock_user_string(arg1)))
7012 goto efault;
7013 ret = get_errno(chmod(p, arg2));
7014 unlock_user(p, arg1, 0);
7015 break;
7016 #endif
7017 #ifdef TARGET_NR_break
7018 case TARGET_NR_break:
7019 goto unimplemented;
7020 #endif
7021 #ifdef TARGET_NR_oldstat
7022 case TARGET_NR_oldstat:
7023 goto unimplemented;
7024 #endif
7025 case TARGET_NR_lseek:
7026 ret = get_errno(lseek(arg1, arg2, arg3));
7027 break;
7028 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
7029 /* Alpha specific */
7030 case TARGET_NR_getxpid:
7031 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
7032 ret = get_errno(getpid());
7033 break;
7034 #endif
7035 #ifdef TARGET_NR_getpid
7036 case TARGET_NR_getpid:
7037 ret = get_errno(getpid());
7038 break;
7039 #endif
7040 case TARGET_NR_mount:
7042 /* need to look at the data field */
7043 void *p2, *p3;
7045 if (arg1) {
7046 p = lock_user_string(arg1);
7047 if (!p) {
7048 goto efault;
7050 } else {
7051 p = NULL;
7054 p2 = lock_user_string(arg2);
7055 if (!p2) {
7056 if (arg1) {
7057 unlock_user(p, arg1, 0);
7059 goto efault;
7062 if (arg3) {
7063 p3 = lock_user_string(arg3);
7064 if (!p3) {
7065 if (arg1) {
7066 unlock_user(p, arg1, 0);
7068 unlock_user(p2, arg2, 0);
7069 goto efault;
7071 } else {
7072 p3 = NULL;
7075 /* FIXME - arg5 should be locked, but it isn't clear how to
7076 * do that since it's not guaranteed to be a NULL-terminated
7077 * string.
7079 if (!arg5) {
7080 ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
7081 } else {
7082 ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
7084 ret = get_errno(ret);
7086 if (arg1) {
7087 unlock_user(p, arg1, 0);
7089 unlock_user(p2, arg2, 0);
7090 if (arg3) {
7091 unlock_user(p3, arg3, 0);
7094 break;
7095 #ifdef TARGET_NR_umount
7096 case TARGET_NR_umount:
7097 if (!(p = lock_user_string(arg1)))
7098 goto efault;
7099 ret = get_errno(umount(p));
7100 unlock_user(p, arg1, 0);
7101 break;
7102 #endif
7103 #ifdef TARGET_NR_stime /* not on alpha */
7104 case TARGET_NR_stime:
7106 time_t host_time;
7107 if (get_user_sal(host_time, arg1))
7108 goto efault;
7109 ret = get_errno(stime(&host_time));
7111 break;
7112 #endif
7113 case TARGET_NR_ptrace:
7114 goto unimplemented;
7115 #ifdef TARGET_NR_alarm /* not on alpha */
7116 case TARGET_NR_alarm:
7117 ret = alarm(arg1);
7118 break;
7119 #endif
7120 #ifdef TARGET_NR_oldfstat
7121 case TARGET_NR_oldfstat:
7122 goto unimplemented;
7123 #endif
7124 #ifdef TARGET_NR_pause /* not on alpha */
7125 case TARGET_NR_pause:
7126 if (!block_signals()) {
7127 sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
7129 ret = -TARGET_EINTR;
7130 break;
7131 #endif
7132 #ifdef TARGET_NR_utime
7133 case TARGET_NR_utime:
7135 struct utimbuf tbuf, *host_tbuf;
7136 struct target_utimbuf *target_tbuf;
7137 if (arg2) {
7138 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
7139 goto efault;
7140 tbuf.actime = tswapal(target_tbuf->actime);
7141 tbuf.modtime = tswapal(target_tbuf->modtime);
7142 unlock_user_struct(target_tbuf, arg2, 0);
7143 host_tbuf = &tbuf;
7144 } else {
7145 host_tbuf = NULL;
7147 if (!(p = lock_user_string(arg1)))
7148 goto efault;
7149 ret = get_errno(utime(p, host_tbuf));
7150 unlock_user(p, arg1, 0);
7152 break;
7153 #endif
7154 #ifdef TARGET_NR_utimes
7155 case TARGET_NR_utimes:
7157 struct timeval *tvp, tv[2];
7158 if (arg2) {
7159 if (copy_from_user_timeval(&tv[0], arg2)
7160 || copy_from_user_timeval(&tv[1],
7161 arg2 + sizeof(struct target_timeval)))
7162 goto efault;
7163 tvp = tv;
7164 } else {
7165 tvp = NULL;
7167 if (!(p = lock_user_string(arg1)))
7168 goto efault;
7169 ret = get_errno(utimes(p, tvp));
7170 unlock_user(p, arg1, 0);
7172 break;
7173 #endif
7174 #if defined(TARGET_NR_futimesat)
7175 case TARGET_NR_futimesat:
7177 struct timeval *tvp, tv[2];
7178 if (arg3) {
7179 if (copy_from_user_timeval(&tv[0], arg3)
7180 || copy_from_user_timeval(&tv[1],
7181 arg3 + sizeof(struct target_timeval)))
7182 goto efault;
7183 tvp = tv;
7184 } else {
7185 tvp = NULL;
7187 if (!(p = lock_user_string(arg2)))
7188 goto efault;
7189 ret = get_errno(futimesat(arg1, path(p), tvp));
7190 unlock_user(p, arg2, 0);
7192 break;
7193 #endif
7194 #ifdef TARGET_NR_stty
7195 case TARGET_NR_stty:
7196 goto unimplemented;
7197 #endif
7198 #ifdef TARGET_NR_gtty
7199 case TARGET_NR_gtty:
7200 goto unimplemented;
7201 #endif
7202 #ifdef TARGET_NR_access
7203 case TARGET_NR_access:
7204 if (!(p = lock_user_string(arg1)))
7205 goto efault;
7206 ret = get_errno(access(path(p), arg2));
7207 unlock_user(p, arg1, 0);
7208 break;
7209 #endif
7210 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
7211 case TARGET_NR_faccessat:
7212 if (!(p = lock_user_string(arg2)))
7213 goto efault;
7214 ret = get_errno(faccessat(arg1, p, arg3, 0));
7215 unlock_user(p, arg2, 0);
7216 break;
7217 #endif
7218 #ifdef TARGET_NR_nice /* not on alpha */
7219 case TARGET_NR_nice:
7220 ret = get_errno(nice(arg1));
7221 break;
7222 #endif
7223 #ifdef TARGET_NR_ftime
7224 case TARGET_NR_ftime:
7225 goto unimplemented;
7226 #endif
7227 case TARGET_NR_sync:
7228 sync();
7229 ret = 0;
7230 break;
7231 case TARGET_NR_kill:
7232 ret = get_errno(safe_kill(arg1, target_to_host_signal(arg2)));
7233 break;
7234 #ifdef TARGET_NR_rename
7235 case TARGET_NR_rename:
7237 void *p2;
7238 p = lock_user_string(arg1);
7239 p2 = lock_user_string(arg2);
7240 if (!p || !p2)
7241 ret = -TARGET_EFAULT;
7242 else
7243 ret = get_errno(rename(p, p2));
7244 unlock_user(p2, arg2, 0);
7245 unlock_user(p, arg1, 0);
7247 break;
7248 #endif
7249 #if defined(TARGET_NR_renameat)
7250 case TARGET_NR_renameat:
7252 void *p2;
7253 p = lock_user_string(arg2);
7254 p2 = lock_user_string(arg4);
7255 if (!p || !p2)
7256 ret = -TARGET_EFAULT;
7257 else
7258 ret = get_errno(renameat(arg1, p, arg3, p2));
7259 unlock_user(p2, arg4, 0);
7260 unlock_user(p, arg2, 0);
7262 break;
7263 #endif
7264 #ifdef TARGET_NR_mkdir
7265 case TARGET_NR_mkdir:
7266 if (!(p = lock_user_string(arg1)))
7267 goto efault;
7268 ret = get_errno(mkdir(p, arg2));
7269 unlock_user(p, arg1, 0);
7270 break;
7271 #endif
7272 #if defined(TARGET_NR_mkdirat)
7273 case TARGET_NR_mkdirat:
7274 if (!(p = lock_user_string(arg2)))
7275 goto efault;
7276 ret = get_errno(mkdirat(arg1, p, arg3));
7277 unlock_user(p, arg2, 0);
7278 break;
7279 #endif
7280 #ifdef TARGET_NR_rmdir
7281 case TARGET_NR_rmdir:
7282 if (!(p = lock_user_string(arg1)))
7283 goto efault;
7284 ret = get_errno(rmdir(p));
7285 unlock_user(p, arg1, 0);
7286 break;
7287 #endif
7288 case TARGET_NR_dup:
7289 ret = get_errno(dup(arg1));
7290 if (ret >= 0) {
7291 fd_trans_dup(arg1, ret);
7293 break;
7294 #ifdef TARGET_NR_pipe
7295 case TARGET_NR_pipe:
7296 ret = do_pipe(cpu_env, arg1, 0, 0);
7297 break;
7298 #endif
7299 #ifdef TARGET_NR_pipe2
7300 case TARGET_NR_pipe2:
7301 ret = do_pipe(cpu_env, arg1,
7302 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
7303 break;
7304 #endif
7305 case TARGET_NR_times:
7307 struct target_tms *tmsp;
7308 struct tms tms;
7309 ret = get_errno(times(&tms));
7310 if (arg1) {
7311 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
7312 if (!tmsp)
7313 goto efault;
7314 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
7315 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
7316 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
7317 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
7319 if (!is_error(ret))
7320 ret = host_to_target_clock_t(ret);
7322 break;
7323 #ifdef TARGET_NR_prof
7324 case TARGET_NR_prof:
7325 goto unimplemented;
7326 #endif
7327 #ifdef TARGET_NR_signal
7328 case TARGET_NR_signal:
7329 goto unimplemented;
7330 #endif
7331 case TARGET_NR_acct:
7332 if (arg1 == 0) {
7333 ret = get_errno(acct(NULL));
7334 } else {
7335 if (!(p = lock_user_string(arg1)))
7336 goto efault;
7337 ret = get_errno(acct(path(p)));
7338 unlock_user(p, arg1, 0);
7340 break;
7341 #ifdef TARGET_NR_umount2
7342 case TARGET_NR_umount2:
7343 if (!(p = lock_user_string(arg1)))
7344 goto efault;
7345 ret = get_errno(umount2(p, arg2));
7346 unlock_user(p, arg1, 0);
7347 break;
7348 #endif
7349 #ifdef TARGET_NR_lock
7350 case TARGET_NR_lock:
7351 goto unimplemented;
7352 #endif
7353 case TARGET_NR_ioctl:
7354 ret = do_ioctl(arg1, arg2, arg3);
7355 break;
7356 case TARGET_NR_fcntl:
7357 ret = do_fcntl(arg1, arg2, arg3);
7358 break;
7359 #ifdef TARGET_NR_mpx
7360 case TARGET_NR_mpx:
7361 goto unimplemented;
7362 #endif
7363 case TARGET_NR_setpgid:
7364 ret = get_errno(setpgid(arg1, arg2));
7365 break;
7366 #ifdef TARGET_NR_ulimit
7367 case TARGET_NR_ulimit:
7368 goto unimplemented;
7369 #endif
7370 #ifdef TARGET_NR_oldolduname
7371 case TARGET_NR_oldolduname:
7372 goto unimplemented;
7373 #endif
7374 case TARGET_NR_umask:
7375 ret = get_errno(umask(arg1));
7376 break;
7377 case TARGET_NR_chroot:
7378 if (!(p = lock_user_string(arg1)))
7379 goto efault;
7380 ret = get_errno(chroot(p));
7381 unlock_user(p, arg1, 0);
7382 break;
7383 #ifdef TARGET_NR_ustat
7384 case TARGET_NR_ustat:
7385 goto unimplemented;
7386 #endif
7387 #ifdef TARGET_NR_dup2
7388 case TARGET_NR_dup2:
7389 ret = get_errno(dup2(arg1, arg2));
7390 if (ret >= 0) {
7391 fd_trans_dup(arg1, arg2);
7393 break;
7394 #endif
7395 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
7396 case TARGET_NR_dup3:
7397 ret = get_errno(dup3(arg1, arg2, arg3));
7398 if (ret >= 0) {
7399 fd_trans_dup(arg1, arg2);
7401 break;
7402 #endif
7403 #ifdef TARGET_NR_getppid /* not on alpha */
7404 case TARGET_NR_getppid:
7405 ret = get_errno(getppid());
7406 break;
7407 #endif
7408 #ifdef TARGET_NR_getpgrp
7409 case TARGET_NR_getpgrp:
7410 ret = get_errno(getpgrp());
7411 break;
7412 #endif
7413 case TARGET_NR_setsid:
7414 ret = get_errno(setsid());
7415 break;
7416 #ifdef TARGET_NR_sigaction
7417 case TARGET_NR_sigaction:
7419 #if defined(TARGET_ALPHA)
7420 struct target_sigaction act, oact, *pact = 0;
7421 struct target_old_sigaction *old_act;
7422 if (arg2) {
7423 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
7424 goto efault;
7425 act._sa_handler = old_act->_sa_handler;
7426 target_siginitset(&act.sa_mask, old_act->sa_mask);
7427 act.sa_flags = old_act->sa_flags;
7428 act.sa_restorer = 0;
7429 unlock_user_struct(old_act, arg2, 0);
7430 pact = &act;
7432 ret = get_errno(do_sigaction(arg1, pact, &oact));
7433 if (!is_error(ret) && arg3) {
7434 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
7435 goto efault;
7436 old_act->_sa_handler = oact._sa_handler;
7437 old_act->sa_mask = oact.sa_mask.sig[0];
7438 old_act->sa_flags = oact.sa_flags;
7439 unlock_user_struct(old_act, arg3, 1);
7441 #elif defined(TARGET_MIPS)
7442 struct target_sigaction act, oact, *pact, *old_act;
7444 if (arg2) {
7445 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
7446 goto efault;
7447 act._sa_handler = old_act->_sa_handler;
7448 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
7449 act.sa_flags = old_act->sa_flags;
7450 unlock_user_struct(old_act, arg2, 0);
7451 pact = &act;
7452 } else {
7453 pact = NULL;
7456 ret = get_errno(do_sigaction(arg1, pact, &oact));
7458 if (!is_error(ret) && arg3) {
7459 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
7460 goto efault;
7461 old_act->_sa_handler = oact._sa_handler;
7462 old_act->sa_flags = oact.sa_flags;
7463 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
7464 old_act->sa_mask.sig[1] = 0;
7465 old_act->sa_mask.sig[2] = 0;
7466 old_act->sa_mask.sig[3] = 0;
7467 unlock_user_struct(old_act, arg3, 1);
7469 #else
7470 struct target_old_sigaction *old_act;
7471 struct target_sigaction act, oact, *pact;
7472 if (arg2) {
7473 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
7474 goto efault;
7475 act._sa_handler = old_act->_sa_handler;
7476 target_siginitset(&act.sa_mask, old_act->sa_mask);
7477 act.sa_flags = old_act->sa_flags;
7478 act.sa_restorer = old_act->sa_restorer;
7479 unlock_user_struct(old_act, arg2, 0);
7480 pact = &act;
7481 } else {
7482 pact = NULL;
7484 ret = get_errno(do_sigaction(arg1, pact, &oact));
7485 if (!is_error(ret) && arg3) {
7486 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
7487 goto efault;
7488 old_act->_sa_handler = oact._sa_handler;
7489 old_act->sa_mask = oact.sa_mask.sig[0];
7490 old_act->sa_flags = oact.sa_flags;
7491 old_act->sa_restorer = oact.sa_restorer;
7492 unlock_user_struct(old_act, arg3, 1);
7494 #endif
7496 break;
7497 #endif
7498 case TARGET_NR_rt_sigaction:
7500 #if defined(TARGET_ALPHA)
7501 struct target_sigaction act, oact, *pact = 0;
7502 struct target_rt_sigaction *rt_act;
7503 /* ??? arg4 == sizeof(sigset_t). */
7504 if (arg2) {
7505 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
7506 goto efault;
7507 act._sa_handler = rt_act->_sa_handler;
7508 act.sa_mask = rt_act->sa_mask;
7509 act.sa_flags = rt_act->sa_flags;
7510 act.sa_restorer = arg5;
7511 unlock_user_struct(rt_act, arg2, 0);
7512 pact = &act;
7514 ret = get_errno(do_sigaction(arg1, pact, &oact));
7515 if (!is_error(ret) && arg3) {
7516 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
7517 goto efault;
7518 rt_act->_sa_handler = oact._sa_handler;
7519 rt_act->sa_mask = oact.sa_mask;
7520 rt_act->sa_flags = oact.sa_flags;
7521 unlock_user_struct(rt_act, arg3, 1);
7523 #else
7524 struct target_sigaction *act;
7525 struct target_sigaction *oact;
7527 if (arg2) {
7528 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
7529 goto efault;
7530 } else
7531 act = NULL;
7532 if (arg3) {
7533 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
7534 ret = -TARGET_EFAULT;
7535 goto rt_sigaction_fail;
7537 } else
7538 oact = NULL;
7539 ret = get_errno(do_sigaction(arg1, act, oact));
7540 rt_sigaction_fail:
7541 if (act)
7542 unlock_user_struct(act, arg2, 0);
7543 if (oact)
7544 unlock_user_struct(oact, arg3, 1);
7545 #endif
7547 break;
7548 #ifdef TARGET_NR_sgetmask /* not on alpha */
7549 case TARGET_NR_sgetmask:
7551 sigset_t cur_set;
7552 abi_ulong target_set;
7553 ret = do_sigprocmask(0, NULL, &cur_set);
7554 if (!ret) {
7555 host_to_target_old_sigset(&target_set, &cur_set);
7556 ret = target_set;
7559 break;
7560 #endif
7561 #ifdef TARGET_NR_ssetmask /* not on alpha */
7562 case TARGET_NR_ssetmask:
7564 sigset_t set, oset, cur_set;
7565 abi_ulong target_set = arg1;
7566 /* We only have one word of the new mask so we must read
7567 * the rest of it with do_sigprocmask() and OR in this word.
7568 * We are guaranteed that a do_sigprocmask() that only queries
7569 * the signal mask will not fail.
7571 ret = do_sigprocmask(0, NULL, &cur_set);
7572 assert(!ret);
7573 target_to_host_old_sigset(&set, &target_set);
7574 sigorset(&set, &set, &cur_set);
7575 ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
7576 if (!ret) {
7577 host_to_target_old_sigset(&target_set, &oset);
7578 ret = target_set;
7581 break;
7582 #endif
7583 #ifdef TARGET_NR_sigprocmask
7584 case TARGET_NR_sigprocmask:
7586 #if defined(TARGET_ALPHA)
7587 sigset_t set, oldset;
7588 abi_ulong mask;
7589 int how;
7591 switch (arg1) {
7592 case TARGET_SIG_BLOCK:
7593 how = SIG_BLOCK;
7594 break;
7595 case TARGET_SIG_UNBLOCK:
7596 how = SIG_UNBLOCK;
7597 break;
7598 case TARGET_SIG_SETMASK:
7599 how = SIG_SETMASK;
7600 break;
7601 default:
7602 ret = -TARGET_EINVAL;
7603 goto fail;
7605 mask = arg2;
7606 target_to_host_old_sigset(&set, &mask);
7608 ret = do_sigprocmask(how, &set, &oldset);
7609 if (!is_error(ret)) {
7610 host_to_target_old_sigset(&mask, &oldset);
7611 ret = mask;
7612 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
7614 #else
7615 sigset_t set, oldset, *set_ptr;
7616 int how;
7618 if (arg2) {
7619 switch (arg1) {
7620 case TARGET_SIG_BLOCK:
7621 how = SIG_BLOCK;
7622 break;
7623 case TARGET_SIG_UNBLOCK:
7624 how = SIG_UNBLOCK;
7625 break;
7626 case TARGET_SIG_SETMASK:
7627 how = SIG_SETMASK;
7628 break;
7629 default:
7630 ret = -TARGET_EINVAL;
7631 goto fail;
7633 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
7634 goto efault;
7635 target_to_host_old_sigset(&set, p);
7636 unlock_user(p, arg2, 0);
7637 set_ptr = &set;
7638 } else {
7639 how = 0;
7640 set_ptr = NULL;
7642 ret = do_sigprocmask(how, set_ptr, &oldset);
7643 if (!is_error(ret) && arg3) {
7644 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
7645 goto efault;
7646 host_to_target_old_sigset(p, &oldset);
7647 unlock_user(p, arg3, sizeof(target_sigset_t));
7649 #endif
7651 break;
7652 #endif
7653 case TARGET_NR_rt_sigprocmask:
7655 int how = arg1;
7656 sigset_t set, oldset, *set_ptr;
7658 if (arg2) {
7659 switch(how) {
7660 case TARGET_SIG_BLOCK:
7661 how = SIG_BLOCK;
7662 break;
7663 case TARGET_SIG_UNBLOCK:
7664 how = SIG_UNBLOCK;
7665 break;
7666 case TARGET_SIG_SETMASK:
7667 how = SIG_SETMASK;
7668 break;
7669 default:
7670 ret = -TARGET_EINVAL;
7671 goto fail;
7673 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
7674 goto efault;
7675 target_to_host_sigset(&set, p);
7676 unlock_user(p, arg2, 0);
7677 set_ptr = &set;
7678 } else {
7679 how = 0;
7680 set_ptr = NULL;
7682 ret = do_sigprocmask(how, set_ptr, &oldset);
7683 if (!is_error(ret) && arg3) {
7684 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
7685 goto efault;
7686 host_to_target_sigset(p, &oldset);
7687 unlock_user(p, arg3, sizeof(target_sigset_t));
7690 break;
7691 #ifdef TARGET_NR_sigpending
7692 case TARGET_NR_sigpending:
7694 sigset_t set;
7695 ret = get_errno(sigpending(&set));
7696 if (!is_error(ret)) {
7697 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
7698 goto efault;
7699 host_to_target_old_sigset(p, &set);
7700 unlock_user(p, arg1, sizeof(target_sigset_t));
7703 break;
7704 #endif
7705 case TARGET_NR_rt_sigpending:
7707 sigset_t set;
7708 ret = get_errno(sigpending(&set));
7709 if (!is_error(ret)) {
7710 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
7711 goto efault;
7712 host_to_target_sigset(p, &set);
7713 unlock_user(p, arg1, sizeof(target_sigset_t));
7716 break;
7717 #ifdef TARGET_NR_sigsuspend
7718 case TARGET_NR_sigsuspend:
7720 TaskState *ts = cpu->opaque;
7721 #if defined(TARGET_ALPHA)
7722 abi_ulong mask = arg1;
7723 target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
7724 #else
7725 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
7726 goto efault;
7727 target_to_host_old_sigset(&ts->sigsuspend_mask, p);
7728 unlock_user(p, arg1, 0);
7729 #endif
7730 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
7731 SIGSET_T_SIZE));
7732 if (ret != -TARGET_ERESTARTSYS) {
7733 ts->in_sigsuspend = 1;
7736 break;
7737 #endif
7738 case TARGET_NR_rt_sigsuspend:
7740 TaskState *ts = cpu->opaque;
7741 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
7742 goto efault;
7743 target_to_host_sigset(&ts->sigsuspend_mask, p);
7744 unlock_user(p, arg1, 0);
7745 ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
7746 SIGSET_T_SIZE));
7747 if (ret != -TARGET_ERESTARTSYS) {
7748 ts->in_sigsuspend = 1;
7751 break;
7752 case TARGET_NR_rt_sigtimedwait:
7754 sigset_t set;
7755 struct timespec uts, *puts;
7756 siginfo_t uinfo;
7758 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
7759 goto efault;
7760 target_to_host_sigset(&set, p);
7761 unlock_user(p, arg1, 0);
7762 if (arg3) {
7763 puts = &uts;
7764 target_to_host_timespec(puts, arg3);
7765 } else {
7766 puts = NULL;
7768 ret = get_errno(safe_rt_sigtimedwait(&set, &uinfo, puts,
7769 SIGSET_T_SIZE));
7770 if (!is_error(ret)) {
7771 if (arg2) {
7772 p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
7774 if (!p) {
7775 goto efault;
7777 host_to_target_siginfo(p, &uinfo);
7778 unlock_user(p, arg2, sizeof(target_siginfo_t));
7780 ret = host_to_target_signal(ret);
7783 break;
7784 case TARGET_NR_rt_sigqueueinfo:
7786 siginfo_t uinfo;
7787 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
7788 goto efault;
7789 target_to_host_siginfo(&uinfo, p);
7790 unlock_user(p, arg1, 0);
7791 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
7793 break;
7794 #ifdef TARGET_NR_sigreturn
7795 case TARGET_NR_sigreturn:
7796 if (block_signals()) {
7797 ret = -TARGET_ERESTARTSYS;
7798 } else {
7799 ret = do_sigreturn(cpu_env);
7801 break;
7802 #endif
7803 case TARGET_NR_rt_sigreturn:
7804 if (block_signals()) {
7805 ret = -TARGET_ERESTARTSYS;
7806 } else {
7807 ret = do_rt_sigreturn(cpu_env);
7809 break;
7810 case TARGET_NR_sethostname:
7811 if (!(p = lock_user_string(arg1)))
7812 goto efault;
7813 ret = get_errno(sethostname(p, arg2));
7814 unlock_user(p, arg1, 0);
7815 break;
7816 case TARGET_NR_setrlimit:
7818 int resource = target_to_host_resource(arg1);
7819 struct target_rlimit *target_rlim;
7820 struct rlimit rlim;
7821 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
7822 goto efault;
7823 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
7824 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
7825 unlock_user_struct(target_rlim, arg2, 0);
7826 ret = get_errno(setrlimit(resource, &rlim));
7828 break;
7829 case TARGET_NR_getrlimit:
7831 int resource = target_to_host_resource(arg1);
7832 struct target_rlimit *target_rlim;
7833 struct rlimit rlim;
7835 ret = get_errno(getrlimit(resource, &rlim));
7836 if (!is_error(ret)) {
7837 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
7838 goto efault;
7839 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
7840 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
7841 unlock_user_struct(target_rlim, arg2, 1);
7844 break;
7845 case TARGET_NR_getrusage:
7847 struct rusage rusage;
7848 ret = get_errno(getrusage(arg1, &rusage));
7849 if (!is_error(ret)) {
7850 ret = host_to_target_rusage(arg2, &rusage);
7853 break;
7854 case TARGET_NR_gettimeofday:
7856 struct timeval tv;
7857 ret = get_errno(gettimeofday(&tv, NULL));
7858 if (!is_error(ret)) {
7859 if (copy_to_user_timeval(arg1, &tv))
7860 goto efault;
7863 break;
7864 case TARGET_NR_settimeofday:
7866 struct timeval tv, *ptv = NULL;
7867 struct timezone tz, *ptz = NULL;
7869 if (arg1) {
7870 if (copy_from_user_timeval(&tv, arg1)) {
7871 goto efault;
7873 ptv = &tv;
7876 if (arg2) {
7877 if (copy_from_user_timezone(&tz, arg2)) {
7878 goto efault;
7880 ptz = &tz;
7883 ret = get_errno(settimeofday(ptv, ptz));
7885 break;
7886 #if defined(TARGET_NR_select)
7887 case TARGET_NR_select:
7888 #if defined(TARGET_S390X) || defined(TARGET_ALPHA)
7889 ret = do_select(arg1, arg2, arg3, arg4, arg5);
7890 #else
7892 struct target_sel_arg_struct *sel;
7893 abi_ulong inp, outp, exp, tvp;
7894 long nsel;
7896 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
7897 goto efault;
7898 nsel = tswapal(sel->n);
7899 inp = tswapal(sel->inp);
7900 outp = tswapal(sel->outp);
7901 exp = tswapal(sel->exp);
7902 tvp = tswapal(sel->tvp);
7903 unlock_user_struct(sel, arg1, 0);
7904 ret = do_select(nsel, inp, outp, exp, tvp);
7906 #endif
7907 break;
7908 #endif
7909 #ifdef TARGET_NR_pselect6
7910 case TARGET_NR_pselect6:
7912 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
7913 fd_set rfds, wfds, efds;
7914 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
7915 struct timespec ts, *ts_ptr;
7918 * The 6th arg is actually two args smashed together,
7919 * so we cannot use the C library.
7921 sigset_t set;
7922 struct {
7923 sigset_t *set;
7924 size_t size;
7925 } sig, *sig_ptr;
7927 abi_ulong arg_sigset, arg_sigsize, *arg7;
7928 target_sigset_t *target_sigset;
7930 n = arg1;
7931 rfd_addr = arg2;
7932 wfd_addr = arg3;
7933 efd_addr = arg4;
7934 ts_addr = arg5;
7936 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
7937 if (ret) {
7938 goto fail;
7940 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
7941 if (ret) {
7942 goto fail;
7944 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
7945 if (ret) {
7946 goto fail;
7950 * This takes a timespec, and not a timeval, so we cannot
7951 * use the do_select() helper ...
7953 if (ts_addr) {
7954 if (target_to_host_timespec(&ts, ts_addr)) {
7955 goto efault;
7957 ts_ptr = &ts;
7958 } else {
7959 ts_ptr = NULL;
7962 /* Extract the two packed args for the sigset */
7963 if (arg6) {
7964 sig_ptr = &sig;
7965 sig.size = SIGSET_T_SIZE;
7967 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
7968 if (!arg7) {
7969 goto efault;
7971 arg_sigset = tswapal(arg7[0]);
7972 arg_sigsize = tswapal(arg7[1]);
7973 unlock_user(arg7, arg6, 0);
7975 if (arg_sigset) {
7976 sig.set = &set;
7977 if (arg_sigsize != sizeof(*target_sigset)) {
7978 /* Like the kernel, we enforce correct size sigsets */
7979 ret = -TARGET_EINVAL;
7980 goto fail;
7982 target_sigset = lock_user(VERIFY_READ, arg_sigset,
7983 sizeof(*target_sigset), 1);
7984 if (!target_sigset) {
7985 goto efault;
7987 target_to_host_sigset(&set, target_sigset);
7988 unlock_user(target_sigset, arg_sigset, 0);
7989 } else {
7990 sig.set = NULL;
7992 } else {
7993 sig_ptr = NULL;
7996 ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
7997 ts_ptr, sig_ptr));
7999 if (!is_error(ret)) {
8000 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
8001 goto efault;
8002 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
8003 goto efault;
8004 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
8005 goto efault;
8007 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
8008 goto efault;
8011 break;
8012 #endif
8013 #ifdef TARGET_NR_symlink
8014 case TARGET_NR_symlink:
8016 void *p2;
8017 p = lock_user_string(arg1);
8018 p2 = lock_user_string(arg2);
8019 if (!p || !p2)
8020 ret = -TARGET_EFAULT;
8021 else
8022 ret = get_errno(symlink(p, p2));
8023 unlock_user(p2, arg2, 0);
8024 unlock_user(p, arg1, 0);
8026 break;
8027 #endif
8028 #if defined(TARGET_NR_symlinkat)
8029 case TARGET_NR_symlinkat:
8031 void *p2;
8032 p = lock_user_string(arg1);
8033 p2 = lock_user_string(arg3);
8034 if (!p || !p2)
8035 ret = -TARGET_EFAULT;
8036 else
8037 ret = get_errno(symlinkat(p, arg2, p2));
8038 unlock_user(p2, arg3, 0);
8039 unlock_user(p, arg1, 0);
8041 break;
8042 #endif
8043 #ifdef TARGET_NR_oldlstat
8044 case TARGET_NR_oldlstat:
8045 goto unimplemented;
8046 #endif
8047 #ifdef TARGET_NR_readlink
8048 case TARGET_NR_readlink:
8050 void *p2;
8051 p = lock_user_string(arg1);
8052 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8053 if (!p || !p2) {
8054 ret = -TARGET_EFAULT;
8055 } else if (!arg3) {
8056 /* Short circuit this for the magic exe check. */
8057 ret = -TARGET_EINVAL;
8058 } else if (is_proc_myself((const char *)p, "exe")) {
8059 char real[PATH_MAX], *temp;
8060 temp = realpath(exec_path, real);
8061 /* Return value is # of bytes that we wrote to the buffer. */
8062 if (temp == NULL) {
8063 ret = get_errno(-1);
8064 } else {
8065 /* Don't worry about sign mismatch as earlier mapping
8066 * logic would have thrown a bad address error. */
8067 ret = MIN(strlen(real), arg3);
8068 /* We cannot NUL terminate the string. */
8069 memcpy(p2, real, ret);
8071 } else {
8072 ret = get_errno(readlink(path(p), p2, arg3));
8074 unlock_user(p2, arg2, ret);
8075 unlock_user(p, arg1, 0);
8077 break;
8078 #endif
8079 #if defined(TARGET_NR_readlinkat)
8080 case TARGET_NR_readlinkat:
8082 void *p2;
8083 p = lock_user_string(arg2);
8084 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
8085 if (!p || !p2) {
8086 ret = -TARGET_EFAULT;
8087 } else if (is_proc_myself((const char *)p, "exe")) {
8088 char real[PATH_MAX], *temp;
8089 temp = realpath(exec_path, real);
8090 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
8091 snprintf((char *)p2, arg4, "%s", real);
8092 } else {
8093 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
8095 unlock_user(p2, arg3, ret);
8096 unlock_user(p, arg2, 0);
8098 break;
8099 #endif
8100 #ifdef TARGET_NR_uselib
8101 case TARGET_NR_uselib:
8102 goto unimplemented;
8103 #endif
8104 #ifdef TARGET_NR_swapon
8105 case TARGET_NR_swapon:
8106 if (!(p = lock_user_string(arg1)))
8107 goto efault;
8108 ret = get_errno(swapon(p, arg2));
8109 unlock_user(p, arg1, 0);
8110 break;
8111 #endif
8112 case TARGET_NR_reboot:
8113 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
8114 /* arg4 must be ignored in all other cases */
8115 p = lock_user_string(arg4);
8116 if (!p) {
8117 goto efault;
8119 ret = get_errno(reboot(arg1, arg2, arg3, p));
8120 unlock_user(p, arg4, 0);
8121 } else {
8122 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
8124 break;
8125 #ifdef TARGET_NR_readdir
8126 case TARGET_NR_readdir:
8127 goto unimplemented;
8128 #endif
8129 #ifdef TARGET_NR_mmap
8130 case TARGET_NR_mmap:
8131 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
8132 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
8133 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
8134 || defined(TARGET_S390X)
8136 abi_ulong *v;
8137 abi_ulong v1, v2, v3, v4, v5, v6;
8138 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
8139 goto efault;
8140 v1 = tswapal(v[0]);
8141 v2 = tswapal(v[1]);
8142 v3 = tswapal(v[2]);
8143 v4 = tswapal(v[3]);
8144 v5 = tswapal(v[4]);
8145 v6 = tswapal(v[5]);
8146 unlock_user(v, arg1, 0);
8147 ret = get_errno(target_mmap(v1, v2, v3,
8148 target_to_host_bitmask(v4, mmap_flags_tbl),
8149 v5, v6));
8151 #else
8152 ret = get_errno(target_mmap(arg1, arg2, arg3,
8153 target_to_host_bitmask(arg4, mmap_flags_tbl),
8154 arg5,
8155 arg6));
8156 #endif
8157 break;
8158 #endif
8159 #ifdef TARGET_NR_mmap2
8160 case TARGET_NR_mmap2:
8161 #ifndef MMAP_SHIFT
8162 #define MMAP_SHIFT 12
8163 #endif
8164 ret = get_errno(target_mmap(arg1, arg2, arg3,
8165 target_to_host_bitmask(arg4, mmap_flags_tbl),
8166 arg5,
8167 arg6 << MMAP_SHIFT));
8168 break;
8169 #endif
8170 case TARGET_NR_munmap:
8171 ret = get_errno(target_munmap(arg1, arg2));
8172 break;
8173 case TARGET_NR_mprotect:
8175 TaskState *ts = cpu->opaque;
8176 /* Special hack to detect libc making the stack executable. */
8177 if ((arg3 & PROT_GROWSDOWN)
8178 && arg1 >= ts->info->stack_limit
8179 && arg1 <= ts->info->start_stack) {
8180 arg3 &= ~PROT_GROWSDOWN;
8181 arg2 = arg2 + arg1 - ts->info->stack_limit;
8182 arg1 = ts->info->stack_limit;
8185 ret = get_errno(target_mprotect(arg1, arg2, arg3));
8186 break;
8187 #ifdef TARGET_NR_mremap
8188 case TARGET_NR_mremap:
8189 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
8190 break;
8191 #endif
8192 /* ??? msync/mlock/munlock are broken for softmmu. */
8193 #ifdef TARGET_NR_msync
8194 case TARGET_NR_msync:
8195 ret = get_errno(msync(g2h(arg1), arg2, arg3));
8196 break;
8197 #endif
8198 #ifdef TARGET_NR_mlock
8199 case TARGET_NR_mlock:
8200 ret = get_errno(mlock(g2h(arg1), arg2));
8201 break;
8202 #endif
8203 #ifdef TARGET_NR_munlock
8204 case TARGET_NR_munlock:
8205 ret = get_errno(munlock(g2h(arg1), arg2));
8206 break;
8207 #endif
8208 #ifdef TARGET_NR_mlockall
8209 case TARGET_NR_mlockall:
8210 ret = get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
8211 break;
8212 #endif
8213 #ifdef TARGET_NR_munlockall
8214 case TARGET_NR_munlockall:
8215 ret = get_errno(munlockall());
8216 break;
8217 #endif
8218 case TARGET_NR_truncate:
8219 if (!(p = lock_user_string(arg1)))
8220 goto efault;
8221 ret = get_errno(truncate(p, arg2));
8222 unlock_user(p, arg1, 0);
8223 break;
8224 case TARGET_NR_ftruncate:
8225 ret = get_errno(ftruncate(arg1, arg2));
8226 break;
8227 case TARGET_NR_fchmod:
8228 ret = get_errno(fchmod(arg1, arg2));
8229 break;
8230 #if defined(TARGET_NR_fchmodat)
8231 case TARGET_NR_fchmodat:
8232 if (!(p = lock_user_string(arg2)))
8233 goto efault;
8234 ret = get_errno(fchmodat(arg1, p, arg3, 0));
8235 unlock_user(p, arg2, 0);
8236 break;
8237 #endif
8238 case TARGET_NR_getpriority:
8239 /* Note that negative values are valid for getpriority, so we must
8240 differentiate based on errno settings. */
8241 errno = 0;
8242 ret = getpriority(arg1, arg2);
8243 if (ret == -1 && errno != 0) {
8244 ret = -host_to_target_errno(errno);
8245 break;
8247 #ifdef TARGET_ALPHA
8248 /* Return value is the unbiased priority. Signal no error. */
8249 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
8250 #else
8251 /* Return value is a biased priority to avoid negative numbers. */
8252 ret = 20 - ret;
8253 #endif
8254 break;
8255 case TARGET_NR_setpriority:
8256 ret = get_errno(setpriority(arg1, arg2, arg3));
8257 break;
8258 #ifdef TARGET_NR_profil
8259 case TARGET_NR_profil:
8260 goto unimplemented;
8261 #endif
8262 case TARGET_NR_statfs:
8263 if (!(p = lock_user_string(arg1)))
8264 goto efault;
8265 ret = get_errno(statfs(path(p), &stfs));
8266 unlock_user(p, arg1, 0);
8267 convert_statfs:
8268 if (!is_error(ret)) {
8269 struct target_statfs *target_stfs;
8271 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
8272 goto efault;
8273 __put_user(stfs.f_type, &target_stfs->f_type);
8274 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
8275 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
8276 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
8277 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
8278 __put_user(stfs.f_files, &target_stfs->f_files);
8279 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
8280 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
8281 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
8282 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
8283 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
8284 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
8285 unlock_user_struct(target_stfs, arg2, 1);
8287 break;
8288 case TARGET_NR_fstatfs:
8289 ret = get_errno(fstatfs(arg1, &stfs));
8290 goto convert_statfs;
8291 #ifdef TARGET_NR_statfs64
8292 case TARGET_NR_statfs64:
8293 if (!(p = lock_user_string(arg1)))
8294 goto efault;
8295 ret = get_errno(statfs(path(p), &stfs));
8296 unlock_user(p, arg1, 0);
8297 convert_statfs64:
8298 if (!is_error(ret)) {
8299 struct target_statfs64 *target_stfs;
8301 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
8302 goto efault;
8303 __put_user(stfs.f_type, &target_stfs->f_type);
8304 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
8305 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
8306 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
8307 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
8308 __put_user(stfs.f_files, &target_stfs->f_files);
8309 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
8310 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
8311 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
8312 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
8313 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
8314 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
8315 unlock_user_struct(target_stfs, arg3, 1);
8317 break;
8318 case TARGET_NR_fstatfs64:
8319 ret = get_errno(fstatfs(arg1, &stfs));
8320 goto convert_statfs64;
8321 #endif
8322 #ifdef TARGET_NR_ioperm
8323 case TARGET_NR_ioperm:
8324 goto unimplemented;
8325 #endif
8326 #ifdef TARGET_NR_socketcall
8327 case TARGET_NR_socketcall:
8328 ret = do_socketcall(arg1, arg2);
8329 break;
8330 #endif
8331 #ifdef TARGET_NR_accept
8332 case TARGET_NR_accept:
8333 ret = do_accept4(arg1, arg2, arg3, 0);
8334 break;
8335 #endif
8336 #ifdef TARGET_NR_accept4
8337 case TARGET_NR_accept4:
8338 ret = do_accept4(arg1, arg2, arg3, arg4);
8339 break;
8340 #endif
8341 #ifdef TARGET_NR_bind
8342 case TARGET_NR_bind:
8343 ret = do_bind(arg1, arg2, arg3);
8344 break;
8345 #endif
8346 #ifdef TARGET_NR_connect
8347 case TARGET_NR_connect:
8348 ret = do_connect(arg1, arg2, arg3);
8349 break;
8350 #endif
8351 #ifdef TARGET_NR_getpeername
8352 case TARGET_NR_getpeername:
8353 ret = do_getpeername(arg1, arg2, arg3);
8354 break;
8355 #endif
8356 #ifdef TARGET_NR_getsockname
8357 case TARGET_NR_getsockname:
8358 ret = do_getsockname(arg1, arg2, arg3);
8359 break;
8360 #endif
8361 #ifdef TARGET_NR_getsockopt
8362 case TARGET_NR_getsockopt:
8363 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
8364 break;
8365 #endif
8366 #ifdef TARGET_NR_listen
8367 case TARGET_NR_listen:
8368 ret = get_errno(listen(arg1, arg2));
8369 break;
8370 #endif
8371 #ifdef TARGET_NR_recv
8372 case TARGET_NR_recv:
8373 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
8374 break;
8375 #endif
8376 #ifdef TARGET_NR_recvfrom
8377 case TARGET_NR_recvfrom:
8378 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
8379 break;
8380 #endif
8381 #ifdef TARGET_NR_recvmsg
8382 case TARGET_NR_recvmsg:
8383 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
8384 break;
8385 #endif
8386 #ifdef TARGET_NR_send
8387 case TARGET_NR_send:
8388 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
8389 break;
8390 #endif
8391 #ifdef TARGET_NR_sendmsg
8392 case TARGET_NR_sendmsg:
8393 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
8394 break;
8395 #endif
8396 #ifdef TARGET_NR_sendmmsg
8397 case TARGET_NR_sendmmsg:
8398 ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
8399 break;
8400 case TARGET_NR_recvmmsg:
8401 ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
8402 break;
8403 #endif
8404 #ifdef TARGET_NR_sendto
8405 case TARGET_NR_sendto:
8406 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
8407 break;
8408 #endif
8409 #ifdef TARGET_NR_shutdown
8410 case TARGET_NR_shutdown:
8411 ret = get_errno(shutdown(arg1, arg2));
8412 break;
8413 #endif
8414 #if defined(TARGET_NR_getrandom) && defined(__NR_getrandom)
8415 case TARGET_NR_getrandom:
8416 p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
8417 if (!p) {
8418 goto efault;
8420 ret = get_errno(getrandom(p, arg2, arg3));
8421 unlock_user(p, arg1, ret);
8422 break;
8423 #endif
8424 #ifdef TARGET_NR_socket
8425 case TARGET_NR_socket:
8426 ret = do_socket(arg1, arg2, arg3);
8427 fd_trans_unregister(ret);
8428 break;
8429 #endif
8430 #ifdef TARGET_NR_socketpair
8431 case TARGET_NR_socketpair:
8432 ret = do_socketpair(arg1, arg2, arg3, arg4);
8433 break;
8434 #endif
8435 #ifdef TARGET_NR_setsockopt
8436 case TARGET_NR_setsockopt:
8437 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
8438 break;
8439 #endif
8441 case TARGET_NR_syslog:
8442 if (!(p = lock_user_string(arg2)))
8443 goto efault;
8444 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
8445 unlock_user(p, arg2, 0);
8446 break;
8448 case TARGET_NR_setitimer:
8450 struct itimerval value, ovalue, *pvalue;
8452 if (arg2) {
8453 pvalue = &value;
8454 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
8455 || copy_from_user_timeval(&pvalue->it_value,
8456 arg2 + sizeof(struct target_timeval)))
8457 goto efault;
8458 } else {
8459 pvalue = NULL;
8461 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
8462 if (!is_error(ret) && arg3) {
8463 if (copy_to_user_timeval(arg3,
8464 &ovalue.it_interval)
8465 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
8466 &ovalue.it_value))
8467 goto efault;
8470 break;
8471 case TARGET_NR_getitimer:
8473 struct itimerval value;
8475 ret = get_errno(getitimer(arg1, &value));
8476 if (!is_error(ret) && arg2) {
8477 if (copy_to_user_timeval(arg2,
8478 &value.it_interval)
8479 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
8480 &value.it_value))
8481 goto efault;
8484 break;
8485 #ifdef TARGET_NR_stat
8486 case TARGET_NR_stat:
8487 if (!(p = lock_user_string(arg1)))
8488 goto efault;
8489 ret = get_errno(stat(path(p), &st));
8490 unlock_user(p, arg1, 0);
8491 goto do_stat;
8492 #endif
8493 #ifdef TARGET_NR_lstat
8494 case TARGET_NR_lstat:
8495 if (!(p = lock_user_string(arg1)))
8496 goto efault;
8497 ret = get_errno(lstat(path(p), &st));
8498 unlock_user(p, arg1, 0);
8499 goto do_stat;
8500 #endif
8501 case TARGET_NR_fstat:
8503 ret = get_errno(fstat(arg1, &st));
8504 #if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat)
8505 do_stat:
8506 #endif
8507 if (!is_error(ret)) {
8508 struct target_stat *target_st;
8510 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
8511 goto efault;
8512 memset(target_st, 0, sizeof(*target_st));
8513 __put_user(st.st_dev, &target_st->st_dev);
8514 __put_user(st.st_ino, &target_st->st_ino);
8515 __put_user(st.st_mode, &target_st->st_mode);
8516 __put_user(st.st_uid, &target_st->st_uid);
8517 __put_user(st.st_gid, &target_st->st_gid);
8518 __put_user(st.st_nlink, &target_st->st_nlink);
8519 __put_user(st.st_rdev, &target_st->st_rdev);
8520 __put_user(st.st_size, &target_st->st_size);
8521 __put_user(st.st_blksize, &target_st->st_blksize);
8522 __put_user(st.st_blocks, &target_st->st_blocks);
8523 __put_user(st.st_atime, &target_st->target_st_atime);
8524 __put_user(st.st_mtime, &target_st->target_st_mtime);
8525 __put_user(st.st_ctime, &target_st->target_st_ctime);
8526 unlock_user_struct(target_st, arg2, 1);
8529 break;
8530 #ifdef TARGET_NR_olduname
8531 case TARGET_NR_olduname:
8532 goto unimplemented;
8533 #endif
8534 #ifdef TARGET_NR_iopl
8535 case TARGET_NR_iopl:
8536 goto unimplemented;
8537 #endif
8538 case TARGET_NR_vhangup:
8539 ret = get_errno(vhangup());
8540 break;
8541 #ifdef TARGET_NR_idle
8542 case TARGET_NR_idle:
8543 goto unimplemented;
8544 #endif
8545 #ifdef TARGET_NR_syscall
8546 case TARGET_NR_syscall:
8547 ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
8548 arg6, arg7, arg8, 0);
8549 break;
8550 #endif
8551 case TARGET_NR_wait4:
8553 int status;
8554 abi_long status_ptr = arg2;
8555 struct rusage rusage, *rusage_ptr;
8556 abi_ulong target_rusage = arg4;
8557 abi_long rusage_err;
8558 if (target_rusage)
8559 rusage_ptr = &rusage;
8560 else
8561 rusage_ptr = NULL;
8562 ret = get_errno(safe_wait4(arg1, &status, arg3, rusage_ptr));
8563 if (!is_error(ret)) {
8564 if (status_ptr && ret) {
8565 status = host_to_target_waitstatus(status);
8566 if (put_user_s32(status, status_ptr))
8567 goto efault;
8569 if (target_rusage) {
8570 rusage_err = host_to_target_rusage(target_rusage, &rusage);
8571 if (rusage_err) {
8572 ret = rusage_err;
8577 break;
8578 #ifdef TARGET_NR_swapoff
8579 case TARGET_NR_swapoff:
8580 if (!(p = lock_user_string(arg1)))
8581 goto efault;
8582 ret = get_errno(swapoff(p));
8583 unlock_user(p, arg1, 0);
8584 break;
8585 #endif
8586 case TARGET_NR_sysinfo:
8588 struct target_sysinfo *target_value;
8589 struct sysinfo value;
8590 ret = get_errno(sysinfo(&value));
8591 if (!is_error(ret) && arg1)
8593 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
8594 goto efault;
8595 __put_user(value.uptime, &target_value->uptime);
8596 __put_user(value.loads[0], &target_value->loads[0]);
8597 __put_user(value.loads[1], &target_value->loads[1]);
8598 __put_user(value.loads[2], &target_value->loads[2]);
8599 __put_user(value.totalram, &target_value->totalram);
8600 __put_user(value.freeram, &target_value->freeram);
8601 __put_user(value.sharedram, &target_value->sharedram);
8602 __put_user(value.bufferram, &target_value->bufferram);
8603 __put_user(value.totalswap, &target_value->totalswap);
8604 __put_user(value.freeswap, &target_value->freeswap);
8605 __put_user(value.procs, &target_value->procs);
8606 __put_user(value.totalhigh, &target_value->totalhigh);
8607 __put_user(value.freehigh, &target_value->freehigh);
8608 __put_user(value.mem_unit, &target_value->mem_unit);
8609 unlock_user_struct(target_value, arg1, 1);
8612 break;
8613 #ifdef TARGET_NR_ipc
8614 case TARGET_NR_ipc:
8615 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
8616 break;
8617 #endif
8618 #ifdef TARGET_NR_semget
8619 case TARGET_NR_semget:
8620 ret = get_errno(semget(arg1, arg2, arg3));
8621 break;
8622 #endif
8623 #ifdef TARGET_NR_semop
8624 case TARGET_NR_semop:
8625 ret = do_semop(arg1, arg2, arg3);
8626 break;
8627 #endif
8628 #ifdef TARGET_NR_semctl
8629 case TARGET_NR_semctl:
8630 ret = do_semctl(arg1, arg2, arg3, arg4);
8631 break;
8632 #endif
8633 #ifdef TARGET_NR_msgctl
8634 case TARGET_NR_msgctl:
8635 ret = do_msgctl(arg1, arg2, arg3);
8636 break;
8637 #endif
8638 #ifdef TARGET_NR_msgget
8639 case TARGET_NR_msgget:
8640 ret = get_errno(msgget(arg1, arg2));
8641 break;
8642 #endif
8643 #ifdef TARGET_NR_msgrcv
8644 case TARGET_NR_msgrcv:
8645 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
8646 break;
8647 #endif
8648 #ifdef TARGET_NR_msgsnd
8649 case TARGET_NR_msgsnd:
8650 ret = do_msgsnd(arg1, arg2, arg3, arg4);
8651 break;
8652 #endif
8653 #ifdef TARGET_NR_shmget
8654 case TARGET_NR_shmget:
8655 ret = get_errno(shmget(arg1, arg2, arg3));
8656 break;
8657 #endif
8658 #ifdef TARGET_NR_shmctl
8659 case TARGET_NR_shmctl:
8660 ret = do_shmctl(arg1, arg2, arg3);
8661 break;
8662 #endif
8663 #ifdef TARGET_NR_shmat
8664 case TARGET_NR_shmat:
8665 ret = do_shmat(arg1, arg2, arg3);
8666 break;
8667 #endif
8668 #ifdef TARGET_NR_shmdt
8669 case TARGET_NR_shmdt:
8670 ret = do_shmdt(arg1);
8671 break;
8672 #endif
8673 case TARGET_NR_fsync:
8674 ret = get_errno(fsync(arg1));
8675 break;
8676 case TARGET_NR_clone:
8677 /* Linux manages to have three different orderings for its
8678 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
8679 * match the kernel's CONFIG_CLONE_* settings.
8680 * Microblaze is further special in that it uses a sixth
8681 * implicit argument to clone for the TLS pointer.
8683 #if defined(TARGET_MICROBLAZE)
8684 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
8685 #elif defined(TARGET_CLONE_BACKWARDS)
8686 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
8687 #elif defined(TARGET_CLONE_BACKWARDS2)
8688 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
8689 #else
8690 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
8691 #endif
8692 break;
8693 #ifdef __NR_exit_group
8694 /* new thread calls */
8695 case TARGET_NR_exit_group:
8696 #ifdef TARGET_GPROF
8697 _mcleanup();
8698 #endif
8699 gdb_exit(cpu_env, arg1);
8700 ret = get_errno(exit_group(arg1));
8701 break;
8702 #endif
8703 case TARGET_NR_setdomainname:
8704 if (!(p = lock_user_string(arg1)))
8705 goto efault;
8706 ret = get_errno(setdomainname(p, arg2));
8707 unlock_user(p, arg1, 0);
8708 break;
8709 case TARGET_NR_uname:
8710 /* no need to transcode because we use the linux syscall */
8712 struct new_utsname * buf;
8714 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
8715 goto efault;
8716 ret = get_errno(sys_uname(buf));
8717 if (!is_error(ret)) {
8718 /* Overrite the native machine name with whatever is being
8719 emulated. */
8720 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
8721 /* Allow the user to override the reported release. */
8722 if (qemu_uname_release && *qemu_uname_release)
8723 strcpy (buf->release, qemu_uname_release);
8725 unlock_user_struct(buf, arg1, 1);
8727 break;
8728 #ifdef TARGET_I386
8729 case TARGET_NR_modify_ldt:
8730 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
8731 break;
8732 #if !defined(TARGET_X86_64)
8733 case TARGET_NR_vm86old:
8734 goto unimplemented;
8735 case TARGET_NR_vm86:
8736 ret = do_vm86(cpu_env, arg1, arg2);
8737 break;
8738 #endif
8739 #endif
8740 case TARGET_NR_adjtimex:
8741 goto unimplemented;
8742 #ifdef TARGET_NR_create_module
8743 case TARGET_NR_create_module:
8744 #endif
8745 case TARGET_NR_init_module:
8746 case TARGET_NR_delete_module:
8747 #ifdef TARGET_NR_get_kernel_syms
8748 case TARGET_NR_get_kernel_syms:
8749 #endif
8750 goto unimplemented;
8751 case TARGET_NR_quotactl:
8752 goto unimplemented;
8753 case TARGET_NR_getpgid:
8754 ret = get_errno(getpgid(arg1));
8755 break;
8756 case TARGET_NR_fchdir:
8757 ret = get_errno(fchdir(arg1));
8758 break;
8759 #ifdef TARGET_NR_bdflush /* not on x86_64 */
8760 case TARGET_NR_bdflush:
8761 goto unimplemented;
8762 #endif
8763 #ifdef TARGET_NR_sysfs
8764 case TARGET_NR_sysfs:
8765 goto unimplemented;
8766 #endif
8767 case TARGET_NR_personality:
8768 ret = get_errno(personality(arg1));
8769 break;
8770 #ifdef TARGET_NR_afs_syscall
8771 case TARGET_NR_afs_syscall:
8772 goto unimplemented;
8773 #endif
8774 #ifdef TARGET_NR__llseek /* Not on alpha */
8775 case TARGET_NR__llseek:
8777 int64_t res;
8778 #if !defined(__NR_llseek)
8779 res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
8780 if (res == -1) {
8781 ret = get_errno(res);
8782 } else {
8783 ret = 0;
8785 #else
8786 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
8787 #endif
8788 if ((ret == 0) && put_user_s64(res, arg4)) {
8789 goto efault;
8792 break;
8793 #endif
8794 #ifdef TARGET_NR_getdents
8795 case TARGET_NR_getdents:
8796 #ifdef __NR_getdents
8797 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
8799 struct target_dirent *target_dirp;
8800 struct linux_dirent *dirp;
8801 abi_long count = arg3;
8803 dirp = g_try_malloc(count);
8804 if (!dirp) {
8805 ret = -TARGET_ENOMEM;
8806 goto fail;
8809 ret = get_errno(sys_getdents(arg1, dirp, count));
8810 if (!is_error(ret)) {
8811 struct linux_dirent *de;
8812 struct target_dirent *tde;
8813 int len = ret;
8814 int reclen, treclen;
8815 int count1, tnamelen;
8817 count1 = 0;
8818 de = dirp;
8819 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
8820 goto efault;
8821 tde = target_dirp;
8822 while (len > 0) {
8823 reclen = de->d_reclen;
8824 tnamelen = reclen - offsetof(struct linux_dirent, d_name);
8825 assert(tnamelen >= 0);
8826 treclen = tnamelen + offsetof(struct target_dirent, d_name);
8827 assert(count1 + treclen <= count);
8828 tde->d_reclen = tswap16(treclen);
8829 tde->d_ino = tswapal(de->d_ino);
8830 tde->d_off = tswapal(de->d_off);
8831 memcpy(tde->d_name, de->d_name, tnamelen);
8832 de = (struct linux_dirent *)((char *)de + reclen);
8833 len -= reclen;
8834 tde = (struct target_dirent *)((char *)tde + treclen);
8835 count1 += treclen;
8837 ret = count1;
8838 unlock_user(target_dirp, arg2, ret);
8840 g_free(dirp);
8842 #else
8844 struct linux_dirent *dirp;
8845 abi_long count = arg3;
8847 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
8848 goto efault;
8849 ret = get_errno(sys_getdents(arg1, dirp, count));
8850 if (!is_error(ret)) {
8851 struct linux_dirent *de;
8852 int len = ret;
8853 int reclen;
8854 de = dirp;
8855 while (len > 0) {
8856 reclen = de->d_reclen;
8857 if (reclen > len)
8858 break;
8859 de->d_reclen = tswap16(reclen);
8860 tswapls(&de->d_ino);
8861 tswapls(&de->d_off);
8862 de = (struct linux_dirent *)((char *)de + reclen);
8863 len -= reclen;
8866 unlock_user(dirp, arg2, ret);
8868 #endif
8869 #else
8870 /* Implement getdents in terms of getdents64 */
8872 struct linux_dirent64 *dirp;
8873 abi_long count = arg3;
8875 dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
8876 if (!dirp) {
8877 goto efault;
8879 ret = get_errno(sys_getdents64(arg1, dirp, count));
8880 if (!is_error(ret)) {
8881 /* Convert the dirent64 structs to target dirent. We do this
8882 * in-place, since we can guarantee that a target_dirent is no
8883 * larger than a dirent64; however this means we have to be
8884 * careful to read everything before writing in the new format.
8886 struct linux_dirent64 *de;
8887 struct target_dirent *tde;
8888 int len = ret;
8889 int tlen = 0;
8891 de = dirp;
8892 tde = (struct target_dirent *)dirp;
8893 while (len > 0) {
8894 int namelen, treclen;
8895 int reclen = de->d_reclen;
8896 uint64_t ino = de->d_ino;
8897 int64_t off = de->d_off;
8898 uint8_t type = de->d_type;
8900 namelen = strlen(de->d_name);
8901 treclen = offsetof(struct target_dirent, d_name)
8902 + namelen + 2;
8903 treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
8905 memmove(tde->d_name, de->d_name, namelen + 1);
8906 tde->d_ino = tswapal(ino);
8907 tde->d_off = tswapal(off);
8908 tde->d_reclen = tswap16(treclen);
8909 /* The target_dirent type is in what was formerly a padding
8910 * byte at the end of the structure:
8912 *(((char *)tde) + treclen - 1) = type;
8914 de = (struct linux_dirent64 *)((char *)de + reclen);
8915 tde = (struct target_dirent *)((char *)tde + treclen);
8916 len -= reclen;
8917 tlen += treclen;
8919 ret = tlen;
8921 unlock_user(dirp, arg2, ret);
8923 #endif
8924 break;
8925 #endif /* TARGET_NR_getdents */
8926 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
8927 case TARGET_NR_getdents64:
8929 struct linux_dirent64 *dirp;
8930 abi_long count = arg3;
8931 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
8932 goto efault;
8933 ret = get_errno(sys_getdents64(arg1, dirp, count));
8934 if (!is_error(ret)) {
8935 struct linux_dirent64 *de;
8936 int len = ret;
8937 int reclen;
8938 de = dirp;
8939 while (len > 0) {
8940 reclen = de->d_reclen;
8941 if (reclen > len)
8942 break;
8943 de->d_reclen = tswap16(reclen);
8944 tswap64s((uint64_t *)&de->d_ino);
8945 tswap64s((uint64_t *)&de->d_off);
8946 de = (struct linux_dirent64 *)((char *)de + reclen);
8947 len -= reclen;
8950 unlock_user(dirp, arg2, ret);
8952 break;
8953 #endif /* TARGET_NR_getdents64 */
8954 #if defined(TARGET_NR__newselect)
8955 case TARGET_NR__newselect:
8956 ret = do_select(arg1, arg2, arg3, arg4, arg5);
8957 break;
8958 #endif
8959 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
8960 # ifdef TARGET_NR_poll
8961 case TARGET_NR_poll:
8962 # endif
8963 # ifdef TARGET_NR_ppoll
8964 case TARGET_NR_ppoll:
8965 # endif
8967 struct target_pollfd *target_pfd;
8968 unsigned int nfds = arg2;
8969 struct pollfd *pfd;
8970 unsigned int i;
8972 pfd = NULL;
8973 target_pfd = NULL;
8974 if (nfds) {
8975 target_pfd = lock_user(VERIFY_WRITE, arg1,
8976 sizeof(struct target_pollfd) * nfds, 1);
8977 if (!target_pfd) {
8978 goto efault;
8981 pfd = alloca(sizeof(struct pollfd) * nfds);
8982 for (i = 0; i < nfds; i++) {
8983 pfd[i].fd = tswap32(target_pfd[i].fd);
8984 pfd[i].events = tswap16(target_pfd[i].events);
8988 switch (num) {
8989 # ifdef TARGET_NR_ppoll
8990 case TARGET_NR_ppoll:
8992 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
8993 target_sigset_t *target_set;
8994 sigset_t _set, *set = &_set;
8996 if (arg3) {
8997 if (target_to_host_timespec(timeout_ts, arg3)) {
8998 unlock_user(target_pfd, arg1, 0);
8999 goto efault;
9001 } else {
9002 timeout_ts = NULL;
9005 if (arg4) {
9006 target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
9007 if (!target_set) {
9008 unlock_user(target_pfd, arg1, 0);
9009 goto efault;
9011 target_to_host_sigset(set, target_set);
9012 } else {
9013 set = NULL;
9016 ret = get_errno(safe_ppoll(pfd, nfds, timeout_ts,
9017 set, SIGSET_T_SIZE));
9019 if (!is_error(ret) && arg3) {
9020 host_to_target_timespec(arg3, timeout_ts);
9022 if (arg4) {
9023 unlock_user(target_set, arg4, 0);
9025 break;
9027 # endif
9028 # ifdef TARGET_NR_poll
9029 case TARGET_NR_poll:
9031 struct timespec ts, *pts;
9033 if (arg3 >= 0) {
9034 /* Convert ms to secs, ns */
9035 ts.tv_sec = arg3 / 1000;
9036 ts.tv_nsec = (arg3 % 1000) * 1000000LL;
9037 pts = &ts;
9038 } else {
9039 /* -ve poll() timeout means "infinite" */
9040 pts = NULL;
9042 ret = get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0));
9043 break;
9045 # endif
9046 default:
9047 g_assert_not_reached();
9050 if (!is_error(ret)) {
9051 for(i = 0; i < nfds; i++) {
9052 target_pfd[i].revents = tswap16(pfd[i].revents);
9055 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
9057 break;
9058 #endif
9059 case TARGET_NR_flock:
9060 /* NOTE: the flock constant seems to be the same for every
9061 Linux platform */
9062 ret = get_errno(safe_flock(arg1, arg2));
9063 break;
9064 case TARGET_NR_readv:
9066 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
9067 if (vec != NULL) {
9068 ret = get_errno(safe_readv(arg1, vec, arg3));
9069 unlock_iovec(vec, arg2, arg3, 1);
9070 } else {
9071 ret = -host_to_target_errno(errno);
9074 break;
9075 case TARGET_NR_writev:
9077 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
9078 if (vec != NULL) {
9079 ret = get_errno(safe_writev(arg1, vec, arg3));
9080 unlock_iovec(vec, arg2, arg3, 0);
9081 } else {
9082 ret = -host_to_target_errno(errno);
9085 break;
9086 case TARGET_NR_getsid:
9087 ret = get_errno(getsid(arg1));
9088 break;
9089 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
9090 case TARGET_NR_fdatasync:
9091 ret = get_errno(fdatasync(arg1));
9092 break;
9093 #endif
9094 #ifdef TARGET_NR__sysctl
9095 case TARGET_NR__sysctl:
9096 /* We don't implement this, but ENOTDIR is always a safe
9097 return value. */
9098 ret = -TARGET_ENOTDIR;
9099 break;
9100 #endif
9101 case TARGET_NR_sched_getaffinity:
9103 unsigned int mask_size;
9104 unsigned long *mask;
9107 * sched_getaffinity needs multiples of ulong, so need to take
9108 * care of mismatches between target ulong and host ulong sizes.
9110 if (arg2 & (sizeof(abi_ulong) - 1)) {
9111 ret = -TARGET_EINVAL;
9112 break;
9114 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
9116 mask = alloca(mask_size);
9117 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
9119 if (!is_error(ret)) {
9120 if (ret > arg2) {
9121 /* More data returned than the caller's buffer will fit.
9122 * This only happens if sizeof(abi_long) < sizeof(long)
9123 * and the caller passed us a buffer holding an odd number
9124 * of abi_longs. If the host kernel is actually using the
9125 * extra 4 bytes then fail EINVAL; otherwise we can just
9126 * ignore them and only copy the interesting part.
9128 int numcpus = sysconf(_SC_NPROCESSORS_CONF);
9129 if (numcpus > arg2 * 8) {
9130 ret = -TARGET_EINVAL;
9131 break;
9133 ret = arg2;
9136 if (copy_to_user(arg3, mask, ret)) {
9137 goto efault;
9141 break;
9142 case TARGET_NR_sched_setaffinity:
9144 unsigned int mask_size;
9145 unsigned long *mask;
9148 * sched_setaffinity needs multiples of ulong, so need to take
9149 * care of mismatches between target ulong and host ulong sizes.
9151 if (arg2 & (sizeof(abi_ulong) - 1)) {
9152 ret = -TARGET_EINVAL;
9153 break;
9155 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
9157 mask = alloca(mask_size);
9158 if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
9159 goto efault;
9161 memcpy(mask, p, arg2);
9162 unlock_user_struct(p, arg2, 0);
9164 ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
9166 break;
9167 case TARGET_NR_sched_setparam:
9169 struct sched_param *target_schp;
9170 struct sched_param schp;
9172 if (arg2 == 0) {
9173 return -TARGET_EINVAL;
9175 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
9176 goto efault;
9177 schp.sched_priority = tswap32(target_schp->sched_priority);
9178 unlock_user_struct(target_schp, arg2, 0);
9179 ret = get_errno(sched_setparam(arg1, &schp));
9181 break;
9182 case TARGET_NR_sched_getparam:
9184 struct sched_param *target_schp;
9185 struct sched_param schp;
9187 if (arg2 == 0) {
9188 return -TARGET_EINVAL;
9190 ret = get_errno(sched_getparam(arg1, &schp));
9191 if (!is_error(ret)) {
9192 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
9193 goto efault;
9194 target_schp->sched_priority = tswap32(schp.sched_priority);
9195 unlock_user_struct(target_schp, arg2, 1);
9198 break;
9199 case TARGET_NR_sched_setscheduler:
9201 struct sched_param *target_schp;
9202 struct sched_param schp;
9203 if (arg3 == 0) {
9204 return -TARGET_EINVAL;
9206 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
9207 goto efault;
9208 schp.sched_priority = tswap32(target_schp->sched_priority);
9209 unlock_user_struct(target_schp, arg3, 0);
9210 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
9212 break;
9213 case TARGET_NR_sched_getscheduler:
9214 ret = get_errno(sched_getscheduler(arg1));
9215 break;
9216 case TARGET_NR_sched_yield:
9217 ret = get_errno(sched_yield());
9218 break;
9219 case TARGET_NR_sched_get_priority_max:
9220 ret = get_errno(sched_get_priority_max(arg1));
9221 break;
9222 case TARGET_NR_sched_get_priority_min:
9223 ret = get_errno(sched_get_priority_min(arg1));
9224 break;
9225 case TARGET_NR_sched_rr_get_interval:
9227 struct timespec ts;
9228 ret = get_errno(sched_rr_get_interval(arg1, &ts));
9229 if (!is_error(ret)) {
9230 ret = host_to_target_timespec(arg2, &ts);
9233 break;
9234 case TARGET_NR_nanosleep:
9236 struct timespec req, rem;
9237 target_to_host_timespec(&req, arg1);
9238 ret = get_errno(safe_nanosleep(&req, &rem));
9239 if (is_error(ret) && arg2) {
9240 host_to_target_timespec(arg2, &rem);
9243 break;
9244 #ifdef TARGET_NR_query_module
9245 case TARGET_NR_query_module:
9246 goto unimplemented;
9247 #endif
9248 #ifdef TARGET_NR_nfsservctl
9249 case TARGET_NR_nfsservctl:
9250 goto unimplemented;
9251 #endif
9252 case TARGET_NR_prctl:
9253 switch (arg1) {
9254 case PR_GET_PDEATHSIG:
9256 int deathsig;
9257 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
9258 if (!is_error(ret) && arg2
9259 && put_user_ual(deathsig, arg2)) {
9260 goto efault;
9262 break;
9264 #ifdef PR_GET_NAME
9265 case PR_GET_NAME:
9267 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
9268 if (!name) {
9269 goto efault;
9271 ret = get_errno(prctl(arg1, (unsigned long)name,
9272 arg3, arg4, arg5));
9273 unlock_user(name, arg2, 16);
9274 break;
9276 case PR_SET_NAME:
9278 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
9279 if (!name) {
9280 goto efault;
9282 ret = get_errno(prctl(arg1, (unsigned long)name,
9283 arg3, arg4, arg5));
9284 unlock_user(name, arg2, 0);
9285 break;
9287 #endif
9288 default:
9289 /* Most prctl options have no pointer arguments */
9290 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
9291 break;
9293 break;
9294 #ifdef TARGET_NR_arch_prctl
9295 case TARGET_NR_arch_prctl:
9296 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
9297 ret = do_arch_prctl(cpu_env, arg1, arg2);
9298 break;
9299 #else
9300 goto unimplemented;
9301 #endif
9302 #endif
9303 #ifdef TARGET_NR_pread64
9304 case TARGET_NR_pread64:
9305 if (regpairs_aligned(cpu_env)) {
9306 arg4 = arg5;
9307 arg5 = arg6;
9309 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
9310 goto efault;
9311 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
9312 unlock_user(p, arg2, ret);
9313 break;
9314 case TARGET_NR_pwrite64:
9315 if (regpairs_aligned(cpu_env)) {
9316 arg4 = arg5;
9317 arg5 = arg6;
9319 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
9320 goto efault;
9321 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
9322 unlock_user(p, arg2, 0);
9323 break;
9324 #endif
9325 case TARGET_NR_getcwd:
9326 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
9327 goto efault;
9328 ret = get_errno(sys_getcwd1(p, arg2));
9329 unlock_user(p, arg1, ret);
9330 break;
9331 case TARGET_NR_capget:
9332 case TARGET_NR_capset:
9334 struct target_user_cap_header *target_header;
9335 struct target_user_cap_data *target_data = NULL;
9336 struct __user_cap_header_struct header;
9337 struct __user_cap_data_struct data[2];
9338 struct __user_cap_data_struct *dataptr = NULL;
9339 int i, target_datalen;
9340 int data_items = 1;
9342 if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
9343 goto efault;
9345 header.version = tswap32(target_header->version);
9346 header.pid = tswap32(target_header->pid);
9348 if (header.version != _LINUX_CAPABILITY_VERSION) {
9349 /* Version 2 and up takes pointer to two user_data structs */
9350 data_items = 2;
9353 target_datalen = sizeof(*target_data) * data_items;
9355 if (arg2) {
9356 if (num == TARGET_NR_capget) {
9357 target_data = lock_user(VERIFY_WRITE, arg2, target_datalen, 0);
9358 } else {
9359 target_data = lock_user(VERIFY_READ, arg2, target_datalen, 1);
9361 if (!target_data) {
9362 unlock_user_struct(target_header, arg1, 0);
9363 goto efault;
9366 if (num == TARGET_NR_capset) {
9367 for (i = 0; i < data_items; i++) {
9368 data[i].effective = tswap32(target_data[i].effective);
9369 data[i].permitted = tswap32(target_data[i].permitted);
9370 data[i].inheritable = tswap32(target_data[i].inheritable);
9374 dataptr = data;
9377 if (num == TARGET_NR_capget) {
9378 ret = get_errno(capget(&header, dataptr));
9379 } else {
9380 ret = get_errno(capset(&header, dataptr));
9383 /* The kernel always updates version for both capget and capset */
9384 target_header->version = tswap32(header.version);
9385 unlock_user_struct(target_header, arg1, 1);
9387 if (arg2) {
9388 if (num == TARGET_NR_capget) {
9389 for (i = 0; i < data_items; i++) {
9390 target_data[i].effective = tswap32(data[i].effective);
9391 target_data[i].permitted = tswap32(data[i].permitted);
9392 target_data[i].inheritable = tswap32(data[i].inheritable);
9394 unlock_user(target_data, arg2, target_datalen);
9395 } else {
9396 unlock_user(target_data, arg2, 0);
9399 break;
9401 case TARGET_NR_sigaltstack:
9402 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
9403 break;
9405 #ifdef CONFIG_SENDFILE
9406 case TARGET_NR_sendfile:
9408 off_t *offp = NULL;
9409 off_t off;
9410 if (arg3) {
9411 ret = get_user_sal(off, arg3);
9412 if (is_error(ret)) {
9413 break;
9415 offp = &off;
9417 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
9418 if (!is_error(ret) && arg3) {
9419 abi_long ret2 = put_user_sal(off, arg3);
9420 if (is_error(ret2)) {
9421 ret = ret2;
9424 break;
9426 #ifdef TARGET_NR_sendfile64
9427 case TARGET_NR_sendfile64:
9429 off_t *offp = NULL;
9430 off_t off;
9431 if (arg3) {
9432 ret = get_user_s64(off, arg3);
9433 if (is_error(ret)) {
9434 break;
9436 offp = &off;
9438 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
9439 if (!is_error(ret) && arg3) {
9440 abi_long ret2 = put_user_s64(off, arg3);
9441 if (is_error(ret2)) {
9442 ret = ret2;
9445 break;
9447 #endif
9448 #else
9449 case TARGET_NR_sendfile:
9450 #ifdef TARGET_NR_sendfile64
9451 case TARGET_NR_sendfile64:
9452 #endif
9453 goto unimplemented;
9454 #endif
9456 #ifdef TARGET_NR_getpmsg
9457 case TARGET_NR_getpmsg:
9458 goto unimplemented;
9459 #endif
9460 #ifdef TARGET_NR_putpmsg
9461 case TARGET_NR_putpmsg:
9462 goto unimplemented;
9463 #endif
9464 #ifdef TARGET_NR_vfork
9465 case TARGET_NR_vfork:
9466 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
9467 0, 0, 0, 0));
9468 break;
9469 #endif
9470 #ifdef TARGET_NR_ugetrlimit
9471 case TARGET_NR_ugetrlimit:
9473 struct rlimit rlim;
9474 int resource = target_to_host_resource(arg1);
9475 ret = get_errno(getrlimit(resource, &rlim));
9476 if (!is_error(ret)) {
9477 struct target_rlimit *target_rlim;
9478 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
9479 goto efault;
9480 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
9481 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
9482 unlock_user_struct(target_rlim, arg2, 1);
9484 break;
9486 #endif
9487 #ifdef TARGET_NR_truncate64
9488 case TARGET_NR_truncate64:
9489 if (!(p = lock_user_string(arg1)))
9490 goto efault;
9491 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
9492 unlock_user(p, arg1, 0);
9493 break;
9494 #endif
9495 #ifdef TARGET_NR_ftruncate64
9496 case TARGET_NR_ftruncate64:
9497 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
9498 break;
9499 #endif
9500 #ifdef TARGET_NR_stat64
9501 case TARGET_NR_stat64:
9502 if (!(p = lock_user_string(arg1)))
9503 goto efault;
9504 ret = get_errno(stat(path(p), &st));
9505 unlock_user(p, arg1, 0);
9506 if (!is_error(ret))
9507 ret = host_to_target_stat64(cpu_env, arg2, &st);
9508 break;
9509 #endif
9510 #ifdef TARGET_NR_lstat64
9511 case TARGET_NR_lstat64:
9512 if (!(p = lock_user_string(arg1)))
9513 goto efault;
9514 ret = get_errno(lstat(path(p), &st));
9515 unlock_user(p, arg1, 0);
9516 if (!is_error(ret))
9517 ret = host_to_target_stat64(cpu_env, arg2, &st);
9518 break;
9519 #endif
9520 #ifdef TARGET_NR_fstat64
9521 case TARGET_NR_fstat64:
9522 ret = get_errno(fstat(arg1, &st));
9523 if (!is_error(ret))
9524 ret = host_to_target_stat64(cpu_env, arg2, &st);
9525 break;
9526 #endif
9527 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
9528 #ifdef TARGET_NR_fstatat64
9529 case TARGET_NR_fstatat64:
9530 #endif
9531 #ifdef TARGET_NR_newfstatat
9532 case TARGET_NR_newfstatat:
9533 #endif
9534 if (!(p = lock_user_string(arg2)))
9535 goto efault;
9536 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
9537 if (!is_error(ret))
9538 ret = host_to_target_stat64(cpu_env, arg3, &st);
9539 break;
9540 #endif
9541 #ifdef TARGET_NR_lchown
9542 case TARGET_NR_lchown:
9543 if (!(p = lock_user_string(arg1)))
9544 goto efault;
9545 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
9546 unlock_user(p, arg1, 0);
9547 break;
9548 #endif
9549 #ifdef TARGET_NR_getuid
9550 case TARGET_NR_getuid:
9551 ret = get_errno(high2lowuid(getuid()));
9552 break;
9553 #endif
9554 #ifdef TARGET_NR_getgid
9555 case TARGET_NR_getgid:
9556 ret = get_errno(high2lowgid(getgid()));
9557 break;
9558 #endif
9559 #ifdef TARGET_NR_geteuid
9560 case TARGET_NR_geteuid:
9561 ret = get_errno(high2lowuid(geteuid()));
9562 break;
9563 #endif
9564 #ifdef TARGET_NR_getegid
9565 case TARGET_NR_getegid:
9566 ret = get_errno(high2lowgid(getegid()));
9567 break;
9568 #endif
9569 case TARGET_NR_setreuid:
9570 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
9571 break;
9572 case TARGET_NR_setregid:
9573 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
9574 break;
9575 case TARGET_NR_getgroups:
9577 int gidsetsize = arg1;
9578 target_id *target_grouplist;
9579 gid_t *grouplist;
9580 int i;
9582 grouplist = alloca(gidsetsize * sizeof(gid_t));
9583 ret = get_errno(getgroups(gidsetsize, grouplist));
9584 if (gidsetsize == 0)
9585 break;
9586 if (!is_error(ret)) {
9587 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
9588 if (!target_grouplist)
9589 goto efault;
9590 for(i = 0;i < ret; i++)
9591 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
9592 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
9595 break;
9596 case TARGET_NR_setgroups:
9598 int gidsetsize = arg1;
9599 target_id *target_grouplist;
9600 gid_t *grouplist = NULL;
9601 int i;
9602 if (gidsetsize) {
9603 grouplist = alloca(gidsetsize * sizeof(gid_t));
9604 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
9605 if (!target_grouplist) {
9606 ret = -TARGET_EFAULT;
9607 goto fail;
9609 for (i = 0; i < gidsetsize; i++) {
9610 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
9612 unlock_user(target_grouplist, arg2, 0);
9614 ret = get_errno(setgroups(gidsetsize, grouplist));
9616 break;
9617 case TARGET_NR_fchown:
9618 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
9619 break;
9620 #if defined(TARGET_NR_fchownat)
9621 case TARGET_NR_fchownat:
9622 if (!(p = lock_user_string(arg2)))
9623 goto efault;
9624 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
9625 low2highgid(arg4), arg5));
9626 unlock_user(p, arg2, 0);
9627 break;
9628 #endif
9629 #ifdef TARGET_NR_setresuid
9630 case TARGET_NR_setresuid:
9631 ret = get_errno(sys_setresuid(low2highuid(arg1),
9632 low2highuid(arg2),
9633 low2highuid(arg3)));
9634 break;
9635 #endif
9636 #ifdef TARGET_NR_getresuid
9637 case TARGET_NR_getresuid:
9639 uid_t ruid, euid, suid;
9640 ret = get_errno(getresuid(&ruid, &euid, &suid));
9641 if (!is_error(ret)) {
9642 if (put_user_id(high2lowuid(ruid), arg1)
9643 || put_user_id(high2lowuid(euid), arg2)
9644 || put_user_id(high2lowuid(suid), arg3))
9645 goto efault;
9648 break;
9649 #endif
9650 #ifdef TARGET_NR_getresgid
9651 case TARGET_NR_setresgid:
9652 ret = get_errno(sys_setresgid(low2highgid(arg1),
9653 low2highgid(arg2),
9654 low2highgid(arg3)));
9655 break;
9656 #endif
9657 #ifdef TARGET_NR_getresgid
9658 case TARGET_NR_getresgid:
9660 gid_t rgid, egid, sgid;
9661 ret = get_errno(getresgid(&rgid, &egid, &sgid));
9662 if (!is_error(ret)) {
9663 if (put_user_id(high2lowgid(rgid), arg1)
9664 || put_user_id(high2lowgid(egid), arg2)
9665 || put_user_id(high2lowgid(sgid), arg3))
9666 goto efault;
9669 break;
9670 #endif
9671 #ifdef TARGET_NR_chown
9672 case TARGET_NR_chown:
9673 if (!(p = lock_user_string(arg1)))
9674 goto efault;
9675 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
9676 unlock_user(p, arg1, 0);
9677 break;
9678 #endif
9679 case TARGET_NR_setuid:
9680 ret = get_errno(sys_setuid(low2highuid(arg1)));
9681 break;
9682 case TARGET_NR_setgid:
9683 ret = get_errno(sys_setgid(low2highgid(arg1)));
9684 break;
9685 case TARGET_NR_setfsuid:
9686 ret = get_errno(setfsuid(arg1));
9687 break;
9688 case TARGET_NR_setfsgid:
9689 ret = get_errno(setfsgid(arg1));
9690 break;
9692 #ifdef TARGET_NR_lchown32
9693 case TARGET_NR_lchown32:
9694 if (!(p = lock_user_string(arg1)))
9695 goto efault;
9696 ret = get_errno(lchown(p, arg2, arg3));
9697 unlock_user(p, arg1, 0);
9698 break;
9699 #endif
9700 #ifdef TARGET_NR_getuid32
9701 case TARGET_NR_getuid32:
9702 ret = get_errno(getuid());
9703 break;
9704 #endif
9706 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
9707 /* Alpha specific */
9708 case TARGET_NR_getxuid:
9710 uid_t euid;
9711 euid=geteuid();
9712 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
9714 ret = get_errno(getuid());
9715 break;
9716 #endif
9717 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
9718 /* Alpha specific */
9719 case TARGET_NR_getxgid:
9721 uid_t egid;
9722 egid=getegid();
9723 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
9725 ret = get_errno(getgid());
9726 break;
9727 #endif
9728 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
9729 /* Alpha specific */
9730 case TARGET_NR_osf_getsysinfo:
9731 ret = -TARGET_EOPNOTSUPP;
9732 switch (arg1) {
9733 case TARGET_GSI_IEEE_FP_CONTROL:
9735 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
9737 /* Copied from linux ieee_fpcr_to_swcr. */
9738 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
9739 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
9740 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
9741 | SWCR_TRAP_ENABLE_DZE
9742 | SWCR_TRAP_ENABLE_OVF);
9743 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
9744 | SWCR_TRAP_ENABLE_INE);
9745 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
9746 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
9748 if (put_user_u64 (swcr, arg2))
9749 goto efault;
9750 ret = 0;
9752 break;
9754 /* case GSI_IEEE_STATE_AT_SIGNAL:
9755 -- Not implemented in linux kernel.
9756 case GSI_UACPROC:
9757 -- Retrieves current unaligned access state; not much used.
9758 case GSI_PROC_TYPE:
9759 -- Retrieves implver information; surely not used.
9760 case GSI_GET_HWRPB:
9761 -- Grabs a copy of the HWRPB; surely not used.
9764 break;
9765 #endif
9766 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
9767 /* Alpha specific */
9768 case TARGET_NR_osf_setsysinfo:
9769 ret = -TARGET_EOPNOTSUPP;
9770 switch (arg1) {
9771 case TARGET_SSI_IEEE_FP_CONTROL:
9773 uint64_t swcr, fpcr, orig_fpcr;
9775 if (get_user_u64 (swcr, arg2)) {
9776 goto efault;
9778 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
9779 fpcr = orig_fpcr & FPCR_DYN_MASK;
9781 /* Copied from linux ieee_swcr_to_fpcr. */
9782 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
9783 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
9784 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
9785 | SWCR_TRAP_ENABLE_DZE
9786 | SWCR_TRAP_ENABLE_OVF)) << 48;
9787 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
9788 | SWCR_TRAP_ENABLE_INE)) << 57;
9789 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
9790 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
9792 cpu_alpha_store_fpcr(cpu_env, fpcr);
9793 ret = 0;
9795 break;
9797 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
9799 uint64_t exc, fpcr, orig_fpcr;
9800 int si_code;
9802 if (get_user_u64(exc, arg2)) {
9803 goto efault;
9806 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
9808 /* We only add to the exception status here. */
9809 fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
9811 cpu_alpha_store_fpcr(cpu_env, fpcr);
9812 ret = 0;
9814 /* Old exceptions are not signaled. */
9815 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
9817 /* If any exceptions set by this call,
9818 and are unmasked, send a signal. */
9819 si_code = 0;
9820 if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
9821 si_code = TARGET_FPE_FLTRES;
9823 if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
9824 si_code = TARGET_FPE_FLTUND;
9826 if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
9827 si_code = TARGET_FPE_FLTOVF;
9829 if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
9830 si_code = TARGET_FPE_FLTDIV;
9832 if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
9833 si_code = TARGET_FPE_FLTINV;
9835 if (si_code != 0) {
9836 target_siginfo_t info;
9837 info.si_signo = SIGFPE;
9838 info.si_errno = 0;
9839 info.si_code = si_code;
9840 info._sifields._sigfault._addr
9841 = ((CPUArchState *)cpu_env)->pc;
9842 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
9845 break;
9847 /* case SSI_NVPAIRS:
9848 -- Used with SSIN_UACPROC to enable unaligned accesses.
9849 case SSI_IEEE_STATE_AT_SIGNAL:
9850 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
9851 -- Not implemented in linux kernel
9854 break;
9855 #endif
9856 #ifdef TARGET_NR_osf_sigprocmask
9857 /* Alpha specific. */
9858 case TARGET_NR_osf_sigprocmask:
9860 abi_ulong mask;
9861 int how;
9862 sigset_t set, oldset;
9864 switch(arg1) {
9865 case TARGET_SIG_BLOCK:
9866 how = SIG_BLOCK;
9867 break;
9868 case TARGET_SIG_UNBLOCK:
9869 how = SIG_UNBLOCK;
9870 break;
9871 case TARGET_SIG_SETMASK:
9872 how = SIG_SETMASK;
9873 break;
9874 default:
9875 ret = -TARGET_EINVAL;
9876 goto fail;
9878 mask = arg2;
9879 target_to_host_old_sigset(&set, &mask);
9880 ret = do_sigprocmask(how, &set, &oldset);
9881 if (!ret) {
9882 host_to_target_old_sigset(&mask, &oldset);
9883 ret = mask;
9886 break;
9887 #endif
9889 #ifdef TARGET_NR_getgid32
9890 case TARGET_NR_getgid32:
9891 ret = get_errno(getgid());
9892 break;
9893 #endif
9894 #ifdef TARGET_NR_geteuid32
9895 case TARGET_NR_geteuid32:
9896 ret = get_errno(geteuid());
9897 break;
9898 #endif
9899 #ifdef TARGET_NR_getegid32
9900 case TARGET_NR_getegid32:
9901 ret = get_errno(getegid());
9902 break;
9903 #endif
9904 #ifdef TARGET_NR_setreuid32
9905 case TARGET_NR_setreuid32:
9906 ret = get_errno(setreuid(arg1, arg2));
9907 break;
9908 #endif
9909 #ifdef TARGET_NR_setregid32
9910 case TARGET_NR_setregid32:
9911 ret = get_errno(setregid(arg1, arg2));
9912 break;
9913 #endif
9914 #ifdef TARGET_NR_getgroups32
9915 case TARGET_NR_getgroups32:
9917 int gidsetsize = arg1;
9918 uint32_t *target_grouplist;
9919 gid_t *grouplist;
9920 int i;
9922 grouplist = alloca(gidsetsize * sizeof(gid_t));
9923 ret = get_errno(getgroups(gidsetsize, grouplist));
9924 if (gidsetsize == 0)
9925 break;
9926 if (!is_error(ret)) {
9927 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
9928 if (!target_grouplist) {
9929 ret = -TARGET_EFAULT;
9930 goto fail;
9932 for(i = 0;i < ret; i++)
9933 target_grouplist[i] = tswap32(grouplist[i]);
9934 unlock_user(target_grouplist, arg2, gidsetsize * 4);
9937 break;
9938 #endif
9939 #ifdef TARGET_NR_setgroups32
9940 case TARGET_NR_setgroups32:
9942 int gidsetsize = arg1;
9943 uint32_t *target_grouplist;
9944 gid_t *grouplist;
9945 int i;
9947 grouplist = alloca(gidsetsize * sizeof(gid_t));
9948 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
9949 if (!target_grouplist) {
9950 ret = -TARGET_EFAULT;
9951 goto fail;
9953 for(i = 0;i < gidsetsize; i++)
9954 grouplist[i] = tswap32(target_grouplist[i]);
9955 unlock_user(target_grouplist, arg2, 0);
9956 ret = get_errno(setgroups(gidsetsize, grouplist));
9958 break;
9959 #endif
9960 #ifdef TARGET_NR_fchown32
9961 case TARGET_NR_fchown32:
9962 ret = get_errno(fchown(arg1, arg2, arg3));
9963 break;
9964 #endif
9965 #ifdef TARGET_NR_setresuid32
9966 case TARGET_NR_setresuid32:
9967 ret = get_errno(sys_setresuid(arg1, arg2, arg3));
9968 break;
9969 #endif
9970 #ifdef TARGET_NR_getresuid32
9971 case TARGET_NR_getresuid32:
9973 uid_t ruid, euid, suid;
9974 ret = get_errno(getresuid(&ruid, &euid, &suid));
9975 if (!is_error(ret)) {
9976 if (put_user_u32(ruid, arg1)
9977 || put_user_u32(euid, arg2)
9978 || put_user_u32(suid, arg3))
9979 goto efault;
9982 break;
9983 #endif
9984 #ifdef TARGET_NR_setresgid32
9985 case TARGET_NR_setresgid32:
9986 ret = get_errno(sys_setresgid(arg1, arg2, arg3));
9987 break;
9988 #endif
9989 #ifdef TARGET_NR_getresgid32
9990 case TARGET_NR_getresgid32:
9992 gid_t rgid, egid, sgid;
9993 ret = get_errno(getresgid(&rgid, &egid, &sgid));
9994 if (!is_error(ret)) {
9995 if (put_user_u32(rgid, arg1)
9996 || put_user_u32(egid, arg2)
9997 || put_user_u32(sgid, arg3))
9998 goto efault;
10001 break;
10002 #endif
10003 #ifdef TARGET_NR_chown32
10004 case TARGET_NR_chown32:
10005 if (!(p = lock_user_string(arg1)))
10006 goto efault;
10007 ret = get_errno(chown(p, arg2, arg3));
10008 unlock_user(p, arg1, 0);
10009 break;
10010 #endif
10011 #ifdef TARGET_NR_setuid32
10012 case TARGET_NR_setuid32:
10013 ret = get_errno(sys_setuid(arg1));
10014 break;
10015 #endif
10016 #ifdef TARGET_NR_setgid32
10017 case TARGET_NR_setgid32:
10018 ret = get_errno(sys_setgid(arg1));
10019 break;
10020 #endif
10021 #ifdef TARGET_NR_setfsuid32
10022 case TARGET_NR_setfsuid32:
10023 ret = get_errno(setfsuid(arg1));
10024 break;
10025 #endif
10026 #ifdef TARGET_NR_setfsgid32
10027 case TARGET_NR_setfsgid32:
10028 ret = get_errno(setfsgid(arg1));
10029 break;
10030 #endif
10032 case TARGET_NR_pivot_root:
10033 goto unimplemented;
10034 #ifdef TARGET_NR_mincore
10035 case TARGET_NR_mincore:
10037 void *a;
10038 ret = -TARGET_EFAULT;
10039 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
10040 goto efault;
10041 if (!(p = lock_user_string(arg3)))
10042 goto mincore_fail;
10043 ret = get_errno(mincore(a, arg2, p));
10044 unlock_user(p, arg3, ret);
10045 mincore_fail:
10046 unlock_user(a, arg1, 0);
10048 break;
10049 #endif
10050 #ifdef TARGET_NR_arm_fadvise64_64
10051 case TARGET_NR_arm_fadvise64_64:
10052 /* arm_fadvise64_64 looks like fadvise64_64 but
10053 * with different argument order: fd, advice, offset, len
10054 * rather than the usual fd, offset, len, advice.
10055 * Note that offset and len are both 64-bit so appear as
10056 * pairs of 32-bit registers.
10058 ret = posix_fadvise(arg1, target_offset64(arg3, arg4),
10059 target_offset64(arg5, arg6), arg2);
10060 ret = -host_to_target_errno(ret);
10061 break;
10062 #endif
10064 #if TARGET_ABI_BITS == 32
10066 #ifdef TARGET_NR_fadvise64_64
10067 case TARGET_NR_fadvise64_64:
10068 /* 6 args: fd, offset (high, low), len (high, low), advice */
10069 if (regpairs_aligned(cpu_env)) {
10070 /* offset is in (3,4), len in (5,6) and advice in 7 */
10071 arg2 = arg3;
10072 arg3 = arg4;
10073 arg4 = arg5;
10074 arg5 = arg6;
10075 arg6 = arg7;
10077 ret = -host_to_target_errno(posix_fadvise(arg1,
10078 target_offset64(arg2, arg3),
10079 target_offset64(arg4, arg5),
10080 arg6));
10081 break;
10082 #endif
10084 #ifdef TARGET_NR_fadvise64
10085 case TARGET_NR_fadvise64:
10086 /* 5 args: fd, offset (high, low), len, advice */
10087 if (regpairs_aligned(cpu_env)) {
10088 /* offset is in (3,4), len in 5 and advice in 6 */
10089 arg2 = arg3;
10090 arg3 = arg4;
10091 arg4 = arg5;
10092 arg5 = arg6;
10094 ret = -host_to_target_errno(posix_fadvise(arg1,
10095 target_offset64(arg2, arg3),
10096 arg4, arg5));
10097 break;
10098 #endif
10100 #else /* not a 32-bit ABI */
10101 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_fadvise64)
10102 #ifdef TARGET_NR_fadvise64_64
10103 case TARGET_NR_fadvise64_64:
10104 #endif
10105 #ifdef TARGET_NR_fadvise64
10106 case TARGET_NR_fadvise64:
10107 #endif
10108 #ifdef TARGET_S390X
10109 switch (arg4) {
10110 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
10111 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
10112 case 6: arg4 = POSIX_FADV_DONTNEED; break;
10113 case 7: arg4 = POSIX_FADV_NOREUSE; break;
10114 default: break;
10116 #endif
10117 ret = -host_to_target_errno(posix_fadvise(arg1, arg2, arg3, arg4));
10118 break;
10119 #endif
10120 #endif /* end of 64-bit ABI fadvise handling */
10122 #ifdef TARGET_NR_madvise
10123 case TARGET_NR_madvise:
10124 /* A straight passthrough may not be safe because qemu sometimes
10125 turns private file-backed mappings into anonymous mappings.
10126 This will break MADV_DONTNEED.
10127 This is a hint, so ignoring and returning success is ok. */
10128 ret = get_errno(0);
10129 break;
10130 #endif
10131 #if TARGET_ABI_BITS == 32
10132 case TARGET_NR_fcntl64:
10134 int cmd;
10135 struct flock64 fl;
10136 struct target_flock64 *target_fl;
10137 #ifdef TARGET_ARM
10138 struct target_eabi_flock64 *target_efl;
10139 #endif
10141 cmd = target_to_host_fcntl_cmd(arg2);
10142 if (cmd == -TARGET_EINVAL) {
10143 ret = cmd;
10144 break;
10147 switch(arg2) {
10148 case TARGET_F_GETLK64:
10149 #ifdef TARGET_ARM
10150 if (((CPUARMState *)cpu_env)->eabi) {
10151 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
10152 goto efault;
10153 fl.l_type = tswap16(target_efl->l_type);
10154 fl.l_whence = tswap16(target_efl->l_whence);
10155 fl.l_start = tswap64(target_efl->l_start);
10156 fl.l_len = tswap64(target_efl->l_len);
10157 fl.l_pid = tswap32(target_efl->l_pid);
10158 unlock_user_struct(target_efl, arg3, 0);
10159 } else
10160 #endif
10162 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
10163 goto efault;
10164 fl.l_type = tswap16(target_fl->l_type);
10165 fl.l_whence = tswap16(target_fl->l_whence);
10166 fl.l_start = tswap64(target_fl->l_start);
10167 fl.l_len = tswap64(target_fl->l_len);
10168 fl.l_pid = tswap32(target_fl->l_pid);
10169 unlock_user_struct(target_fl, arg3, 0);
10171 ret = get_errno(fcntl(arg1, cmd, &fl));
10172 if (ret == 0) {
10173 #ifdef TARGET_ARM
10174 if (((CPUARMState *)cpu_env)->eabi) {
10175 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
10176 goto efault;
10177 target_efl->l_type = tswap16(fl.l_type);
10178 target_efl->l_whence = tswap16(fl.l_whence);
10179 target_efl->l_start = tswap64(fl.l_start);
10180 target_efl->l_len = tswap64(fl.l_len);
10181 target_efl->l_pid = tswap32(fl.l_pid);
10182 unlock_user_struct(target_efl, arg3, 1);
10183 } else
10184 #endif
10186 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
10187 goto efault;
10188 target_fl->l_type = tswap16(fl.l_type);
10189 target_fl->l_whence = tswap16(fl.l_whence);
10190 target_fl->l_start = tswap64(fl.l_start);
10191 target_fl->l_len = tswap64(fl.l_len);
10192 target_fl->l_pid = tswap32(fl.l_pid);
10193 unlock_user_struct(target_fl, arg3, 1);
10196 break;
10198 case TARGET_F_SETLK64:
10199 case TARGET_F_SETLKW64:
10200 #ifdef TARGET_ARM
10201 if (((CPUARMState *)cpu_env)->eabi) {
10202 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
10203 goto efault;
10204 fl.l_type = tswap16(target_efl->l_type);
10205 fl.l_whence = tswap16(target_efl->l_whence);
10206 fl.l_start = tswap64(target_efl->l_start);
10207 fl.l_len = tswap64(target_efl->l_len);
10208 fl.l_pid = tswap32(target_efl->l_pid);
10209 unlock_user_struct(target_efl, arg3, 0);
10210 } else
10211 #endif
10213 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
10214 goto efault;
10215 fl.l_type = tswap16(target_fl->l_type);
10216 fl.l_whence = tswap16(target_fl->l_whence);
10217 fl.l_start = tswap64(target_fl->l_start);
10218 fl.l_len = tswap64(target_fl->l_len);
10219 fl.l_pid = tswap32(target_fl->l_pid);
10220 unlock_user_struct(target_fl, arg3, 0);
10222 ret = get_errno(fcntl(arg1, cmd, &fl));
10223 break;
10224 default:
10225 ret = do_fcntl(arg1, arg2, arg3);
10226 break;
10228 break;
10230 #endif
10231 #ifdef TARGET_NR_cacheflush
10232 case TARGET_NR_cacheflush:
10233 /* self-modifying code is handled automatically, so nothing needed */
10234 ret = 0;
10235 break;
10236 #endif
10237 #ifdef TARGET_NR_security
10238 case TARGET_NR_security:
10239 goto unimplemented;
10240 #endif
10241 #ifdef TARGET_NR_getpagesize
10242 case TARGET_NR_getpagesize:
10243 ret = TARGET_PAGE_SIZE;
10244 break;
10245 #endif
10246 case TARGET_NR_gettid:
10247 ret = get_errno(gettid());
10248 break;
10249 #ifdef TARGET_NR_readahead
10250 case TARGET_NR_readahead:
10251 #if TARGET_ABI_BITS == 32
10252 if (regpairs_aligned(cpu_env)) {
10253 arg2 = arg3;
10254 arg3 = arg4;
10255 arg4 = arg5;
10257 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
10258 #else
10259 ret = get_errno(readahead(arg1, arg2, arg3));
10260 #endif
10261 break;
10262 #endif
10263 #ifdef CONFIG_ATTR
10264 #ifdef TARGET_NR_setxattr
10265 case TARGET_NR_listxattr:
10266 case TARGET_NR_llistxattr:
10268 void *p, *b = 0;
10269 if (arg2) {
10270 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
10271 if (!b) {
10272 ret = -TARGET_EFAULT;
10273 break;
10276 p = lock_user_string(arg1);
10277 if (p) {
10278 if (num == TARGET_NR_listxattr) {
10279 ret = get_errno(listxattr(p, b, arg3));
10280 } else {
10281 ret = get_errno(llistxattr(p, b, arg3));
10283 } else {
10284 ret = -TARGET_EFAULT;
10286 unlock_user(p, arg1, 0);
10287 unlock_user(b, arg2, arg3);
10288 break;
10290 case TARGET_NR_flistxattr:
10292 void *b = 0;
10293 if (arg2) {
10294 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
10295 if (!b) {
10296 ret = -TARGET_EFAULT;
10297 break;
10300 ret = get_errno(flistxattr(arg1, b, arg3));
10301 unlock_user(b, arg2, arg3);
10302 break;
10304 case TARGET_NR_setxattr:
10305 case TARGET_NR_lsetxattr:
10307 void *p, *n, *v = 0;
10308 if (arg3) {
10309 v = lock_user(VERIFY_READ, arg3, arg4, 1);
10310 if (!v) {
10311 ret = -TARGET_EFAULT;
10312 break;
10315 p = lock_user_string(arg1);
10316 n = lock_user_string(arg2);
10317 if (p && n) {
10318 if (num == TARGET_NR_setxattr) {
10319 ret = get_errno(setxattr(p, n, v, arg4, arg5));
10320 } else {
10321 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
10323 } else {
10324 ret = -TARGET_EFAULT;
10326 unlock_user(p, arg1, 0);
10327 unlock_user(n, arg2, 0);
10328 unlock_user(v, arg3, 0);
10330 break;
10331 case TARGET_NR_fsetxattr:
10333 void *n, *v = 0;
10334 if (arg3) {
10335 v = lock_user(VERIFY_READ, arg3, arg4, 1);
10336 if (!v) {
10337 ret = -TARGET_EFAULT;
10338 break;
10341 n = lock_user_string(arg2);
10342 if (n) {
10343 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
10344 } else {
10345 ret = -TARGET_EFAULT;
10347 unlock_user(n, arg2, 0);
10348 unlock_user(v, arg3, 0);
10350 break;
10351 case TARGET_NR_getxattr:
10352 case TARGET_NR_lgetxattr:
10354 void *p, *n, *v = 0;
10355 if (arg3) {
10356 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
10357 if (!v) {
10358 ret = -TARGET_EFAULT;
10359 break;
10362 p = lock_user_string(arg1);
10363 n = lock_user_string(arg2);
10364 if (p && n) {
10365 if (num == TARGET_NR_getxattr) {
10366 ret = get_errno(getxattr(p, n, v, arg4));
10367 } else {
10368 ret = get_errno(lgetxattr(p, n, v, arg4));
10370 } else {
10371 ret = -TARGET_EFAULT;
10373 unlock_user(p, arg1, 0);
10374 unlock_user(n, arg2, 0);
10375 unlock_user(v, arg3, arg4);
10377 break;
10378 case TARGET_NR_fgetxattr:
10380 void *n, *v = 0;
10381 if (arg3) {
10382 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
10383 if (!v) {
10384 ret = -TARGET_EFAULT;
10385 break;
10388 n = lock_user_string(arg2);
10389 if (n) {
10390 ret = get_errno(fgetxattr(arg1, n, v, arg4));
10391 } else {
10392 ret = -TARGET_EFAULT;
10394 unlock_user(n, arg2, 0);
10395 unlock_user(v, arg3, arg4);
10397 break;
10398 case TARGET_NR_removexattr:
10399 case TARGET_NR_lremovexattr:
10401 void *p, *n;
10402 p = lock_user_string(arg1);
10403 n = lock_user_string(arg2);
10404 if (p && n) {
10405 if (num == TARGET_NR_removexattr) {
10406 ret = get_errno(removexattr(p, n));
10407 } else {
10408 ret = get_errno(lremovexattr(p, n));
10410 } else {
10411 ret = -TARGET_EFAULT;
10413 unlock_user(p, arg1, 0);
10414 unlock_user(n, arg2, 0);
10416 break;
10417 case TARGET_NR_fremovexattr:
10419 void *n;
10420 n = lock_user_string(arg2);
10421 if (n) {
10422 ret = get_errno(fremovexattr(arg1, n));
10423 } else {
10424 ret = -TARGET_EFAULT;
10426 unlock_user(n, arg2, 0);
10428 break;
10429 #endif
10430 #endif /* CONFIG_ATTR */
10431 #ifdef TARGET_NR_set_thread_area
10432 case TARGET_NR_set_thread_area:
10433 #if defined(TARGET_MIPS)
10434 ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
10435 ret = 0;
10436 break;
10437 #elif defined(TARGET_CRIS)
10438 if (arg1 & 0xff)
10439 ret = -TARGET_EINVAL;
10440 else {
10441 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
10442 ret = 0;
10444 break;
10445 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
10446 ret = do_set_thread_area(cpu_env, arg1);
10447 break;
10448 #elif defined(TARGET_M68K)
10450 TaskState *ts = cpu->opaque;
10451 ts->tp_value = arg1;
10452 ret = 0;
10453 break;
10455 #else
10456 goto unimplemented_nowarn;
10457 #endif
10458 #endif
10459 #ifdef TARGET_NR_get_thread_area
10460 case TARGET_NR_get_thread_area:
10461 #if defined(TARGET_I386) && defined(TARGET_ABI32)
10462 ret = do_get_thread_area(cpu_env, arg1);
10463 break;
10464 #elif defined(TARGET_M68K)
10466 TaskState *ts = cpu->opaque;
10467 ret = ts->tp_value;
10468 break;
10470 #else
10471 goto unimplemented_nowarn;
10472 #endif
10473 #endif
10474 #ifdef TARGET_NR_getdomainname
10475 case TARGET_NR_getdomainname:
10476 goto unimplemented_nowarn;
10477 #endif
10479 #ifdef TARGET_NR_clock_gettime
10480 case TARGET_NR_clock_gettime:
10482 struct timespec ts;
10483 ret = get_errno(clock_gettime(arg1, &ts));
10484 if (!is_error(ret)) {
10485 host_to_target_timespec(arg2, &ts);
10487 break;
10489 #endif
10490 #ifdef TARGET_NR_clock_getres
10491 case TARGET_NR_clock_getres:
10493 struct timespec ts;
10494 ret = get_errno(clock_getres(arg1, &ts));
10495 if (!is_error(ret)) {
10496 host_to_target_timespec(arg2, &ts);
10498 break;
10500 #endif
10501 #ifdef TARGET_NR_clock_nanosleep
10502 case TARGET_NR_clock_nanosleep:
10504 struct timespec ts;
10505 target_to_host_timespec(&ts, arg3);
10506 ret = get_errno(safe_clock_nanosleep(arg1, arg2,
10507 &ts, arg4 ? &ts : NULL));
10508 if (arg4)
10509 host_to_target_timespec(arg4, &ts);
10511 #if defined(TARGET_PPC)
10512 /* clock_nanosleep is odd in that it returns positive errno values.
10513 * On PPC, CR0 bit 3 should be set in such a situation. */
10514 if (ret && ret != -TARGET_ERESTARTSYS) {
10515 ((CPUPPCState *)cpu_env)->crf[0] |= 1;
10517 #endif
10518 break;
10520 #endif
10522 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
10523 case TARGET_NR_set_tid_address:
10524 ret = get_errno(set_tid_address((int *)g2h(arg1)));
10525 break;
10526 #endif
10528 case TARGET_NR_tkill:
10529 ret = get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)));
10530 break;
10532 case TARGET_NR_tgkill:
10533 ret = get_errno(safe_tgkill((int)arg1, (int)arg2,
10534 target_to_host_signal(arg3)));
10535 break;
10537 #ifdef TARGET_NR_set_robust_list
10538 case TARGET_NR_set_robust_list:
10539 case TARGET_NR_get_robust_list:
10540 /* The ABI for supporting robust futexes has userspace pass
10541 * the kernel a pointer to a linked list which is updated by
10542 * userspace after the syscall; the list is walked by the kernel
10543 * when the thread exits. Since the linked list in QEMU guest
10544 * memory isn't a valid linked list for the host and we have
10545 * no way to reliably intercept the thread-death event, we can't
10546 * support these. Silently return ENOSYS so that guest userspace
10547 * falls back to a non-robust futex implementation (which should
10548 * be OK except in the corner case of the guest crashing while
10549 * holding a mutex that is shared with another process via
10550 * shared memory).
10552 goto unimplemented_nowarn;
10553 #endif
10555 #if defined(TARGET_NR_utimensat)
10556 case TARGET_NR_utimensat:
10558 struct timespec *tsp, ts[2];
10559 if (!arg3) {
10560 tsp = NULL;
10561 } else {
10562 target_to_host_timespec(ts, arg3);
10563 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
10564 tsp = ts;
10566 if (!arg2)
10567 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
10568 else {
10569 if (!(p = lock_user_string(arg2))) {
10570 ret = -TARGET_EFAULT;
10571 goto fail;
10573 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
10574 unlock_user(p, arg2, 0);
10577 break;
10578 #endif
10579 case TARGET_NR_futex:
10580 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
10581 break;
10582 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
10583 case TARGET_NR_inotify_init:
10584 ret = get_errno(sys_inotify_init());
10585 break;
10586 #endif
10587 #ifdef CONFIG_INOTIFY1
10588 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
10589 case TARGET_NR_inotify_init1:
10590 ret = get_errno(sys_inotify_init1(arg1));
10591 break;
10592 #endif
10593 #endif
10594 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
10595 case TARGET_NR_inotify_add_watch:
10596 p = lock_user_string(arg2);
10597 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
10598 unlock_user(p, arg2, 0);
10599 break;
10600 #endif
10601 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
10602 case TARGET_NR_inotify_rm_watch:
10603 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
10604 break;
10605 #endif
10607 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
10608 case TARGET_NR_mq_open:
10610 struct mq_attr posix_mq_attr, *attrp;
10612 p = lock_user_string(arg1 - 1);
10613 if (arg4 != 0) {
10614 copy_from_user_mq_attr (&posix_mq_attr, arg4);
10615 attrp = &posix_mq_attr;
10616 } else {
10617 attrp = 0;
10619 ret = get_errno(mq_open(p, arg2, arg3, attrp));
10620 unlock_user (p, arg1, 0);
10622 break;
10624 case TARGET_NR_mq_unlink:
10625 p = lock_user_string(arg1 - 1);
10626 ret = get_errno(mq_unlink(p));
10627 unlock_user (p, arg1, 0);
10628 break;
10630 case TARGET_NR_mq_timedsend:
10632 struct timespec ts;
10634 p = lock_user (VERIFY_READ, arg2, arg3, 1);
10635 if (arg5 != 0) {
10636 target_to_host_timespec(&ts, arg5);
10637 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
10638 host_to_target_timespec(arg5, &ts);
10639 } else {
10640 ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
10642 unlock_user (p, arg2, arg3);
10644 break;
10646 case TARGET_NR_mq_timedreceive:
10648 struct timespec ts;
10649 unsigned int prio;
10651 p = lock_user (VERIFY_READ, arg2, arg3, 1);
10652 if (arg5 != 0) {
10653 target_to_host_timespec(&ts, arg5);
10654 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
10655 &prio, &ts));
10656 host_to_target_timespec(arg5, &ts);
10657 } else {
10658 ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
10659 &prio, NULL));
10661 unlock_user (p, arg2, arg3);
10662 if (arg4 != 0)
10663 put_user_u32(prio, arg4);
10665 break;
10667 /* Not implemented for now... */
10668 /* case TARGET_NR_mq_notify: */
10669 /* break; */
10671 case TARGET_NR_mq_getsetattr:
10673 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
10674 ret = 0;
10675 if (arg3 != 0) {
10676 ret = mq_getattr(arg1, &posix_mq_attr_out);
10677 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
10679 if (arg2 != 0) {
10680 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
10681 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
10685 break;
10686 #endif
10688 #ifdef CONFIG_SPLICE
10689 #ifdef TARGET_NR_tee
10690 case TARGET_NR_tee:
10692 ret = get_errno(tee(arg1,arg2,arg3,arg4));
10694 break;
10695 #endif
10696 #ifdef TARGET_NR_splice
10697 case TARGET_NR_splice:
10699 loff_t loff_in, loff_out;
10700 loff_t *ploff_in = NULL, *ploff_out = NULL;
10701 if (arg2) {
10702 if (get_user_u64(loff_in, arg2)) {
10703 goto efault;
10705 ploff_in = &loff_in;
10707 if (arg4) {
10708 if (get_user_u64(loff_out, arg4)) {
10709 goto efault;
10711 ploff_out = &loff_out;
10713 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
10714 if (arg2) {
10715 if (put_user_u64(loff_in, arg2)) {
10716 goto efault;
10719 if (arg4) {
10720 if (put_user_u64(loff_out, arg4)) {
10721 goto efault;
10725 break;
10726 #endif
10727 #ifdef TARGET_NR_vmsplice
10728 case TARGET_NR_vmsplice:
10730 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
10731 if (vec != NULL) {
10732 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
10733 unlock_iovec(vec, arg2, arg3, 0);
10734 } else {
10735 ret = -host_to_target_errno(errno);
10738 break;
10739 #endif
10740 #endif /* CONFIG_SPLICE */
10741 #ifdef CONFIG_EVENTFD
10742 #if defined(TARGET_NR_eventfd)
10743 case TARGET_NR_eventfd:
10744 ret = get_errno(eventfd(arg1, 0));
10745 fd_trans_unregister(ret);
10746 break;
10747 #endif
10748 #if defined(TARGET_NR_eventfd2)
10749 case TARGET_NR_eventfd2:
10751 int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
10752 if (arg2 & TARGET_O_NONBLOCK) {
10753 host_flags |= O_NONBLOCK;
10755 if (arg2 & TARGET_O_CLOEXEC) {
10756 host_flags |= O_CLOEXEC;
10758 ret = get_errno(eventfd(arg1, host_flags));
10759 fd_trans_unregister(ret);
10760 break;
10762 #endif
10763 #endif /* CONFIG_EVENTFD */
10764 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
10765 case TARGET_NR_fallocate:
10766 #if TARGET_ABI_BITS == 32
10767 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
10768 target_offset64(arg5, arg6)));
10769 #else
10770 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
10771 #endif
10772 break;
10773 #endif
10774 #if defined(CONFIG_SYNC_FILE_RANGE)
10775 #if defined(TARGET_NR_sync_file_range)
10776 case TARGET_NR_sync_file_range:
10777 #if TARGET_ABI_BITS == 32
10778 #if defined(TARGET_MIPS)
10779 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
10780 target_offset64(arg5, arg6), arg7));
10781 #else
10782 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
10783 target_offset64(arg4, arg5), arg6));
10784 #endif /* !TARGET_MIPS */
10785 #else
10786 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
10787 #endif
10788 break;
10789 #endif
10790 #if defined(TARGET_NR_sync_file_range2)
10791 case TARGET_NR_sync_file_range2:
10792 /* This is like sync_file_range but the arguments are reordered */
10793 #if TARGET_ABI_BITS == 32
10794 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
10795 target_offset64(arg5, arg6), arg2));
10796 #else
10797 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
10798 #endif
10799 break;
10800 #endif
10801 #endif
10802 #if defined(TARGET_NR_signalfd4)
10803 case TARGET_NR_signalfd4:
10804 ret = do_signalfd4(arg1, arg2, arg4);
10805 break;
10806 #endif
10807 #if defined(TARGET_NR_signalfd)
10808 case TARGET_NR_signalfd:
10809 ret = do_signalfd4(arg1, arg2, 0);
10810 break;
10811 #endif
10812 #if defined(CONFIG_EPOLL)
10813 #if defined(TARGET_NR_epoll_create)
10814 case TARGET_NR_epoll_create:
10815 ret = get_errno(epoll_create(arg1));
10816 break;
10817 #endif
10818 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
10819 case TARGET_NR_epoll_create1:
10820 ret = get_errno(epoll_create1(arg1));
10821 break;
10822 #endif
10823 #if defined(TARGET_NR_epoll_ctl)
10824 case TARGET_NR_epoll_ctl:
10826 struct epoll_event ep;
10827 struct epoll_event *epp = 0;
10828 if (arg4) {
10829 struct target_epoll_event *target_ep;
10830 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
10831 goto efault;
10833 ep.events = tswap32(target_ep->events);
10834 /* The epoll_data_t union is just opaque data to the kernel,
10835 * so we transfer all 64 bits across and need not worry what
10836 * actual data type it is.
10838 ep.data.u64 = tswap64(target_ep->data.u64);
10839 unlock_user_struct(target_ep, arg4, 0);
10840 epp = &ep;
10842 ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
10843 break;
10845 #endif
10847 #if defined(TARGET_NR_epoll_wait) || defined(TARGET_NR_epoll_pwait)
10848 #if defined(TARGET_NR_epoll_wait)
10849 case TARGET_NR_epoll_wait:
10850 #endif
10851 #if defined(TARGET_NR_epoll_pwait)
10852 case TARGET_NR_epoll_pwait:
10853 #endif
10855 struct target_epoll_event *target_ep;
10856 struct epoll_event *ep;
10857 int epfd = arg1;
10858 int maxevents = arg3;
10859 int timeout = arg4;
10861 target_ep = lock_user(VERIFY_WRITE, arg2,
10862 maxevents * sizeof(struct target_epoll_event), 1);
10863 if (!target_ep) {
10864 goto efault;
10867 ep = alloca(maxevents * sizeof(struct epoll_event));
10869 switch (num) {
10870 #if defined(TARGET_NR_epoll_pwait)
10871 case TARGET_NR_epoll_pwait:
10873 target_sigset_t *target_set;
10874 sigset_t _set, *set = &_set;
10876 if (arg5) {
10877 target_set = lock_user(VERIFY_READ, arg5,
10878 sizeof(target_sigset_t), 1);
10879 if (!target_set) {
10880 unlock_user(target_ep, arg2, 0);
10881 goto efault;
10883 target_to_host_sigset(set, target_set);
10884 unlock_user(target_set, arg5, 0);
10885 } else {
10886 set = NULL;
10889 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
10890 set, SIGSET_T_SIZE));
10891 break;
10893 #endif
10894 #if defined(TARGET_NR_epoll_wait)
10895 case TARGET_NR_epoll_wait:
10896 ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
10897 NULL, 0));
10898 break;
10899 #endif
10900 default:
10901 ret = -TARGET_ENOSYS;
10903 if (!is_error(ret)) {
10904 int i;
10905 for (i = 0; i < ret; i++) {
10906 target_ep[i].events = tswap32(ep[i].events);
10907 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
10910 unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
10911 break;
10913 #endif
10914 #endif
10915 #ifdef TARGET_NR_prlimit64
10916 case TARGET_NR_prlimit64:
10918 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
10919 struct target_rlimit64 *target_rnew, *target_rold;
10920 struct host_rlimit64 rnew, rold, *rnewp = 0;
10921 int resource = target_to_host_resource(arg2);
10922 if (arg3) {
10923 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
10924 goto efault;
10926 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
10927 rnew.rlim_max = tswap64(target_rnew->rlim_max);
10928 unlock_user_struct(target_rnew, arg3, 0);
10929 rnewp = &rnew;
10932 ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
10933 if (!is_error(ret) && arg4) {
10934 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
10935 goto efault;
10937 target_rold->rlim_cur = tswap64(rold.rlim_cur);
10938 target_rold->rlim_max = tswap64(rold.rlim_max);
10939 unlock_user_struct(target_rold, arg4, 1);
10941 break;
10943 #endif
10944 #ifdef TARGET_NR_gethostname
10945 case TARGET_NR_gethostname:
10947 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
10948 if (name) {
10949 ret = get_errno(gethostname(name, arg2));
10950 unlock_user(name, arg1, arg2);
10951 } else {
10952 ret = -TARGET_EFAULT;
10954 break;
10956 #endif
10957 #ifdef TARGET_NR_atomic_cmpxchg_32
10958 case TARGET_NR_atomic_cmpxchg_32:
10960 /* should use start_exclusive from main.c */
10961 abi_ulong mem_value;
10962 if (get_user_u32(mem_value, arg6)) {
10963 target_siginfo_t info;
10964 info.si_signo = SIGSEGV;
10965 info.si_errno = 0;
10966 info.si_code = TARGET_SEGV_MAPERR;
10967 info._sifields._sigfault._addr = arg6;
10968 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
10969 ret = 0xdeadbeef;
10972 if (mem_value == arg2)
10973 put_user_u32(arg1, arg6);
10974 ret = mem_value;
10975 break;
10977 #endif
10978 #ifdef TARGET_NR_atomic_barrier
10979 case TARGET_NR_atomic_barrier:
10981 /* Like the kernel implementation and the qemu arm barrier, no-op this? */
10982 ret = 0;
10983 break;
10985 #endif
10987 #ifdef TARGET_NR_timer_create
10988 case TARGET_NR_timer_create:
10990 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
10992 struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
10994 int clkid = arg1;
10995 int timer_index = next_free_host_timer();
10997 if (timer_index < 0) {
10998 ret = -TARGET_EAGAIN;
10999 } else {
11000 timer_t *phtimer = g_posix_timers + timer_index;
11002 if (arg2) {
11003 phost_sevp = &host_sevp;
11004 ret = target_to_host_sigevent(phost_sevp, arg2);
11005 if (ret != 0) {
11006 break;
11010 ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
11011 if (ret) {
11012 phtimer = NULL;
11013 } else {
11014 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
11015 goto efault;
11019 break;
11021 #endif
11023 #ifdef TARGET_NR_timer_settime
11024 case TARGET_NR_timer_settime:
11026 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
11027 * struct itimerspec * old_value */
11028 target_timer_t timerid = get_timer_id(arg1);
11030 if (timerid < 0) {
11031 ret = timerid;
11032 } else if (arg3 == 0) {
11033 ret = -TARGET_EINVAL;
11034 } else {
11035 timer_t htimer = g_posix_timers[timerid];
11036 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
11038 target_to_host_itimerspec(&hspec_new, arg3);
11039 ret = get_errno(
11040 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
11041 host_to_target_itimerspec(arg2, &hspec_old);
11043 break;
11045 #endif
11047 #ifdef TARGET_NR_timer_gettime
11048 case TARGET_NR_timer_gettime:
11050 /* args: timer_t timerid, struct itimerspec *curr_value */
11051 target_timer_t timerid = get_timer_id(arg1);
11053 if (timerid < 0) {
11054 ret = timerid;
11055 } else if (!arg2) {
11056 ret = -TARGET_EFAULT;
11057 } else {
11058 timer_t htimer = g_posix_timers[timerid];
11059 struct itimerspec hspec;
11060 ret = get_errno(timer_gettime(htimer, &hspec));
11062 if (host_to_target_itimerspec(arg2, &hspec)) {
11063 ret = -TARGET_EFAULT;
11066 break;
11068 #endif
11070 #ifdef TARGET_NR_timer_getoverrun
11071 case TARGET_NR_timer_getoverrun:
11073 /* args: timer_t timerid */
11074 target_timer_t timerid = get_timer_id(arg1);
11076 if (timerid < 0) {
11077 ret = timerid;
11078 } else {
11079 timer_t htimer = g_posix_timers[timerid];
11080 ret = get_errno(timer_getoverrun(htimer));
11082 fd_trans_unregister(ret);
11083 break;
11085 #endif
11087 #ifdef TARGET_NR_timer_delete
11088 case TARGET_NR_timer_delete:
11090 /* args: timer_t timerid */
11091 target_timer_t timerid = get_timer_id(arg1);
11093 if (timerid < 0) {
11094 ret = timerid;
11095 } else {
11096 timer_t htimer = g_posix_timers[timerid];
11097 ret = get_errno(timer_delete(htimer));
11098 g_posix_timers[timerid] = 0;
11100 break;
11102 #endif
11104 #if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
11105 case TARGET_NR_timerfd_create:
11106 ret = get_errno(timerfd_create(arg1,
11107 target_to_host_bitmask(arg2, fcntl_flags_tbl)));
11108 break;
11109 #endif
11111 #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
11112 case TARGET_NR_timerfd_gettime:
11114 struct itimerspec its_curr;
11116 ret = get_errno(timerfd_gettime(arg1, &its_curr));
11118 if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
11119 goto efault;
11122 break;
11123 #endif
11125 #if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
11126 case TARGET_NR_timerfd_settime:
11128 struct itimerspec its_new, its_old, *p_new;
11130 if (arg3) {
11131 if (target_to_host_itimerspec(&its_new, arg3)) {
11132 goto efault;
11134 p_new = &its_new;
11135 } else {
11136 p_new = NULL;
11139 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
11141 if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
11142 goto efault;
11145 break;
11146 #endif
11148 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
11149 case TARGET_NR_ioprio_get:
11150 ret = get_errno(ioprio_get(arg1, arg2));
11151 break;
11152 #endif
11154 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
11155 case TARGET_NR_ioprio_set:
11156 ret = get_errno(ioprio_set(arg1, arg2, arg3));
11157 break;
11158 #endif
11160 #if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
11161 case TARGET_NR_setns:
11162 ret = get_errno(setns(arg1, arg2));
11163 break;
11164 #endif
11165 #if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
11166 case TARGET_NR_unshare:
11167 ret = get_errno(unshare(arg1));
11168 break;
11169 #endif
11171 default:
11172 unimplemented:
11173 gemu_log("qemu: Unsupported syscall: %d\n", num);
11174 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
11175 unimplemented_nowarn:
11176 #endif
11177 ret = -TARGET_ENOSYS;
11178 break;
11180 fail:
11181 #ifdef DEBUG
11182 gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
11183 #endif
11184 if(do_strace)
11185 print_syscall_ret(num, ret);
11186 return ret;
11187 efault:
11188 ret = -TARGET_EFAULT;
11189 goto fail;