gus: use IsaDma interface instead of global DMA_* functions
[qemu/kevin.git] / linux-user / syscall.c
blob54ce14a6113151ba925f50cd90b4343ab9b052d7
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 <elf.h>
22 #include <endian.h>
23 #include <grp.h>
24 #include <sys/ipc.h>
25 #include <sys/msg.h>
26 #include <sys/wait.h>
27 #include <sys/mount.h>
28 #include <sys/file.h>
29 #include <sys/fsuid.h>
30 #include <sys/personality.h>
31 #include <sys/prctl.h>
32 #include <sys/resource.h>
33 #include <sys/mman.h>
34 #include <sys/swap.h>
35 #include <linux/capability.h>
36 #include <sched.h>
37 #ifdef __ia64__
38 int __clone2(int (*fn)(void *), void *child_stack_base,
39 size_t stack_size, int flags, void *arg, ...);
40 #endif
41 #include <sys/socket.h>
42 #include <sys/un.h>
43 #include <sys/uio.h>
44 #include <sys/poll.h>
45 #include <sys/times.h>
46 #include <sys/shm.h>
47 #include <sys/sem.h>
48 #include <sys/statfs.h>
49 #include <utime.h>
50 #include <sys/sysinfo.h>
51 #include <sys/signalfd.h>
52 //#include <sys/user.h>
53 #include <netinet/ip.h>
54 #include <netinet/tcp.h>
55 #include <linux/wireless.h>
56 #include <linux/icmp.h>
57 #include "qemu-common.h"
58 #ifdef CONFIG_TIMERFD
59 #include <sys/timerfd.h>
60 #endif
61 #ifdef TARGET_GPROF
62 #include <sys/gmon.h>
63 #endif
64 #ifdef CONFIG_EVENTFD
65 #include <sys/eventfd.h>
66 #endif
67 #ifdef CONFIG_EPOLL
68 #include <sys/epoll.h>
69 #endif
70 #ifdef CONFIG_ATTR
71 #include "qemu/xattr.h"
72 #endif
73 #ifdef CONFIG_SENDFILE
74 #include <sys/sendfile.h>
75 #endif
77 #define termios host_termios
78 #define winsize host_winsize
79 #define termio host_termio
80 #define sgttyb host_sgttyb /* same as target */
81 #define tchars host_tchars /* same as target */
82 #define ltchars host_ltchars /* same as target */
84 #include <linux/termios.h>
85 #include <linux/unistd.h>
86 #include <linux/cdrom.h>
87 #include <linux/hdreg.h>
88 #include <linux/soundcard.h>
89 #include <linux/kd.h>
90 #include <linux/mtio.h>
91 #include <linux/fs.h>
92 #if defined(CONFIG_FIEMAP)
93 #include <linux/fiemap.h>
94 #endif
95 #include <linux/fb.h>
96 #include <linux/vt.h>
97 #include <linux/dm-ioctl.h>
98 #include <linux/reboot.h>
99 #include <linux/route.h>
100 #include <linux/filter.h>
101 #include <linux/blkpg.h>
102 #include "linux_loop.h"
103 #include "uname.h"
105 #include "qemu.h"
107 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
108 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
110 //#define DEBUG
112 //#include <linux/msdos_fs.h>
113 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
114 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
117 #undef _syscall0
118 #undef _syscall1
119 #undef _syscall2
120 #undef _syscall3
121 #undef _syscall4
122 #undef _syscall5
123 #undef _syscall6
125 #define _syscall0(type,name) \
126 static type name (void) \
128 return syscall(__NR_##name); \
131 #define _syscall1(type,name,type1,arg1) \
132 static type name (type1 arg1) \
134 return syscall(__NR_##name, arg1); \
137 #define _syscall2(type,name,type1,arg1,type2,arg2) \
138 static type name (type1 arg1,type2 arg2) \
140 return syscall(__NR_##name, arg1, arg2); \
143 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
144 static type name (type1 arg1,type2 arg2,type3 arg3) \
146 return syscall(__NR_##name, arg1, arg2, arg3); \
149 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
150 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
152 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
155 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
156 type5,arg5) \
157 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
159 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
163 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
164 type5,arg5,type6,arg6) \
165 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
166 type6 arg6) \
168 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
172 #define __NR_sys_uname __NR_uname
173 #define __NR_sys_getcwd1 __NR_getcwd
174 #define __NR_sys_getdents __NR_getdents
175 #define __NR_sys_getdents64 __NR_getdents64
176 #define __NR_sys_getpriority __NR_getpriority
177 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
178 #define __NR_sys_syslog __NR_syslog
179 #define __NR_sys_tgkill __NR_tgkill
180 #define __NR_sys_tkill __NR_tkill
181 #define __NR_sys_futex __NR_futex
182 #define __NR_sys_inotify_init __NR_inotify_init
183 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
184 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
186 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
187 defined(__s390x__)
188 #define __NR__llseek __NR_lseek
189 #endif
191 /* Newer kernel ports have llseek() instead of _llseek() */
192 #if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
193 #define TARGET_NR__llseek TARGET_NR_llseek
194 #endif
196 #ifdef __NR_gettid
197 _syscall0(int, gettid)
198 #else
199 /* This is a replacement for the host gettid() and must return a host
200 errno. */
201 static int gettid(void) {
202 return -ENOSYS;
204 #endif
205 #if defined(TARGET_NR_getdents) && defined(__NR_getdents)
206 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
207 #endif
208 #if !defined(__NR_getdents) || \
209 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
210 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
211 #endif
212 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
213 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
214 loff_t *, res, uint, wh);
215 #endif
216 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
217 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
218 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
219 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
220 #endif
221 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
222 _syscall2(int,sys_tkill,int,tid,int,sig)
223 #endif
224 #ifdef __NR_exit_group
225 _syscall1(int,exit_group,int,error_code)
226 #endif
227 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
228 _syscall1(int,set_tid_address,int *,tidptr)
229 #endif
230 #if defined(TARGET_NR_futex) && defined(__NR_futex)
231 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
232 const struct timespec *,timeout,int *,uaddr2,int,val3)
233 #endif
234 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
235 _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
236 unsigned long *, user_mask_ptr);
237 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
238 _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
239 unsigned long *, user_mask_ptr);
240 _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
241 void *, arg);
242 _syscall2(int, capget, struct __user_cap_header_struct *, header,
243 struct __user_cap_data_struct *, data);
244 _syscall2(int, capset, struct __user_cap_header_struct *, header,
245 struct __user_cap_data_struct *, data);
246 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
247 _syscall2(int, ioprio_get, int, which, int, who)
248 #endif
249 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
250 _syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
251 #endif
253 static bitmask_transtbl fcntl_flags_tbl[] = {
254 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
255 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
256 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
257 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
258 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
259 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
260 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
261 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
262 { TARGET_O_SYNC, TARGET_O_DSYNC, O_SYNC, O_DSYNC, },
263 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
264 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
265 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
266 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
267 #if defined(O_DIRECT)
268 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
269 #endif
270 #if defined(O_NOATIME)
271 { TARGET_O_NOATIME, TARGET_O_NOATIME, O_NOATIME, O_NOATIME },
272 #endif
273 #if defined(O_CLOEXEC)
274 { TARGET_O_CLOEXEC, TARGET_O_CLOEXEC, O_CLOEXEC, O_CLOEXEC },
275 #endif
276 #if defined(O_PATH)
277 { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
278 #endif
279 /* Don't terminate the list prematurely on 64-bit host+guest. */
280 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
281 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
282 #endif
283 { 0, 0, 0, 0 }
286 typedef abi_long (*TargetFdDataFunc)(void *, size_t);
287 typedef abi_long (*TargetFdAddrFunc)(void *, abi_ulong, socklen_t);
288 typedef struct TargetFdTrans {
289 TargetFdDataFunc host_to_target_data;
290 TargetFdDataFunc target_to_host_data;
291 TargetFdAddrFunc target_to_host_addr;
292 } TargetFdTrans;
294 static TargetFdTrans **target_fd_trans;
296 static unsigned int target_fd_max;
298 static TargetFdDataFunc fd_trans_host_to_target_data(int fd)
300 if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
301 return target_fd_trans[fd]->host_to_target_data;
303 return NULL;
306 static TargetFdAddrFunc fd_trans_target_to_host_addr(int fd)
308 if (fd >= 0 && fd < target_fd_max && target_fd_trans[fd]) {
309 return target_fd_trans[fd]->target_to_host_addr;
311 return NULL;
314 static void fd_trans_register(int fd, TargetFdTrans *trans)
316 unsigned int oldmax;
318 if (fd >= target_fd_max) {
319 oldmax = target_fd_max;
320 target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */
321 target_fd_trans = g_realloc(target_fd_trans,
322 target_fd_max * sizeof(TargetFdTrans));
323 memset((void *)(target_fd_trans + oldmax), 0,
324 (target_fd_max - oldmax) * sizeof(TargetFdTrans *));
326 target_fd_trans[fd] = trans;
329 static void fd_trans_unregister(int fd)
331 if (fd >= 0 && fd < target_fd_max) {
332 target_fd_trans[fd] = NULL;
336 static void fd_trans_dup(int oldfd, int newfd)
338 fd_trans_unregister(newfd);
339 if (oldfd < target_fd_max && target_fd_trans[oldfd]) {
340 fd_trans_register(newfd, target_fd_trans[oldfd]);
344 static int sys_getcwd1(char *buf, size_t size)
346 if (getcwd(buf, size) == NULL) {
347 /* getcwd() sets errno */
348 return (-1);
350 return strlen(buf)+1;
353 static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
356 * open(2) has extra parameter 'mode' when called with
357 * flag O_CREAT.
359 if ((flags & O_CREAT) != 0) {
360 return (openat(dirfd, pathname, flags, mode));
362 return (openat(dirfd, pathname, flags));
365 #ifdef TARGET_NR_utimensat
366 #ifdef CONFIG_UTIMENSAT
367 static int sys_utimensat(int dirfd, const char *pathname,
368 const struct timespec times[2], int flags)
370 if (pathname == NULL)
371 return futimens(dirfd, times);
372 else
373 return utimensat(dirfd, pathname, times, flags);
375 #elif defined(__NR_utimensat)
376 #define __NR_sys_utimensat __NR_utimensat
377 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
378 const struct timespec *,tsp,int,flags)
379 #else
380 static int sys_utimensat(int dirfd, const char *pathname,
381 const struct timespec times[2], int flags)
383 errno = ENOSYS;
384 return -1;
386 #endif
387 #endif /* TARGET_NR_utimensat */
389 #ifdef CONFIG_INOTIFY
390 #include <sys/inotify.h>
392 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
393 static int sys_inotify_init(void)
395 return (inotify_init());
397 #endif
398 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
399 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
401 return (inotify_add_watch(fd, pathname, mask));
403 #endif
404 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
405 static int sys_inotify_rm_watch(int fd, int32_t wd)
407 return (inotify_rm_watch(fd, wd));
409 #endif
410 #ifdef CONFIG_INOTIFY1
411 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
412 static int sys_inotify_init1(int flags)
414 return (inotify_init1(flags));
416 #endif
417 #endif
418 #else
419 /* Userspace can usually survive runtime without inotify */
420 #undef TARGET_NR_inotify_init
421 #undef TARGET_NR_inotify_init1
422 #undef TARGET_NR_inotify_add_watch
423 #undef TARGET_NR_inotify_rm_watch
424 #endif /* CONFIG_INOTIFY */
426 #if defined(TARGET_NR_ppoll)
427 #ifndef __NR_ppoll
428 # define __NR_ppoll -1
429 #endif
430 #define __NR_sys_ppoll __NR_ppoll
431 _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
432 struct timespec *, timeout, const sigset_t *, sigmask,
433 size_t, sigsetsize)
434 #endif
436 #if defined(TARGET_NR_pselect6)
437 #ifndef __NR_pselect6
438 # define __NR_pselect6 -1
439 #endif
440 #define __NR_sys_pselect6 __NR_pselect6
441 _syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
442 fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
443 #endif
445 #if defined(TARGET_NR_prlimit64)
446 #ifndef __NR_prlimit64
447 # define __NR_prlimit64 -1
448 #endif
449 #define __NR_sys_prlimit64 __NR_prlimit64
450 /* The glibc rlimit structure may not be that used by the underlying syscall */
451 struct host_rlimit64 {
452 uint64_t rlim_cur;
453 uint64_t rlim_max;
455 _syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
456 const struct host_rlimit64 *, new_limit,
457 struct host_rlimit64 *, old_limit)
458 #endif
461 #if defined(TARGET_NR_timer_create)
462 /* Maxiumum of 32 active POSIX timers allowed at any one time. */
463 static timer_t g_posix_timers[32] = { 0, } ;
465 static inline int next_free_host_timer(void)
467 int k ;
468 /* FIXME: Does finding the next free slot require a lock? */
469 for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
470 if (g_posix_timers[k] == 0) {
471 g_posix_timers[k] = (timer_t) 1;
472 return k;
475 return -1;
477 #endif
479 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
480 #ifdef TARGET_ARM
481 static inline int regpairs_aligned(void *cpu_env) {
482 return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
484 #elif defined(TARGET_MIPS)
485 static inline int regpairs_aligned(void *cpu_env) { return 1; }
486 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
487 /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
488 * of registers which translates to the same as ARM/MIPS, because we start with
489 * r3 as arg1 */
490 static inline int regpairs_aligned(void *cpu_env) { return 1; }
491 #else
492 static inline int regpairs_aligned(void *cpu_env) { return 0; }
493 #endif
495 #define ERRNO_TABLE_SIZE 1200
497 /* target_to_host_errno_table[] is initialized from
498 * host_to_target_errno_table[] in syscall_init(). */
499 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
503 * This list is the union of errno values overridden in asm-<arch>/errno.h
504 * minus the errnos that are not actually generic to all archs.
506 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
507 [EAGAIN] = TARGET_EAGAIN,
508 [EIDRM] = TARGET_EIDRM,
509 [ECHRNG] = TARGET_ECHRNG,
510 [EL2NSYNC] = TARGET_EL2NSYNC,
511 [EL3HLT] = TARGET_EL3HLT,
512 [EL3RST] = TARGET_EL3RST,
513 [ELNRNG] = TARGET_ELNRNG,
514 [EUNATCH] = TARGET_EUNATCH,
515 [ENOCSI] = TARGET_ENOCSI,
516 [EL2HLT] = TARGET_EL2HLT,
517 [EDEADLK] = TARGET_EDEADLK,
518 [ENOLCK] = TARGET_ENOLCK,
519 [EBADE] = TARGET_EBADE,
520 [EBADR] = TARGET_EBADR,
521 [EXFULL] = TARGET_EXFULL,
522 [ENOANO] = TARGET_ENOANO,
523 [EBADRQC] = TARGET_EBADRQC,
524 [EBADSLT] = TARGET_EBADSLT,
525 [EBFONT] = TARGET_EBFONT,
526 [ENOSTR] = TARGET_ENOSTR,
527 [ENODATA] = TARGET_ENODATA,
528 [ETIME] = TARGET_ETIME,
529 [ENOSR] = TARGET_ENOSR,
530 [ENONET] = TARGET_ENONET,
531 [ENOPKG] = TARGET_ENOPKG,
532 [EREMOTE] = TARGET_EREMOTE,
533 [ENOLINK] = TARGET_ENOLINK,
534 [EADV] = TARGET_EADV,
535 [ESRMNT] = TARGET_ESRMNT,
536 [ECOMM] = TARGET_ECOMM,
537 [EPROTO] = TARGET_EPROTO,
538 [EDOTDOT] = TARGET_EDOTDOT,
539 [EMULTIHOP] = TARGET_EMULTIHOP,
540 [EBADMSG] = TARGET_EBADMSG,
541 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
542 [EOVERFLOW] = TARGET_EOVERFLOW,
543 [ENOTUNIQ] = TARGET_ENOTUNIQ,
544 [EBADFD] = TARGET_EBADFD,
545 [EREMCHG] = TARGET_EREMCHG,
546 [ELIBACC] = TARGET_ELIBACC,
547 [ELIBBAD] = TARGET_ELIBBAD,
548 [ELIBSCN] = TARGET_ELIBSCN,
549 [ELIBMAX] = TARGET_ELIBMAX,
550 [ELIBEXEC] = TARGET_ELIBEXEC,
551 [EILSEQ] = TARGET_EILSEQ,
552 [ENOSYS] = TARGET_ENOSYS,
553 [ELOOP] = TARGET_ELOOP,
554 [ERESTART] = TARGET_ERESTART,
555 [ESTRPIPE] = TARGET_ESTRPIPE,
556 [ENOTEMPTY] = TARGET_ENOTEMPTY,
557 [EUSERS] = TARGET_EUSERS,
558 [ENOTSOCK] = TARGET_ENOTSOCK,
559 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
560 [EMSGSIZE] = TARGET_EMSGSIZE,
561 [EPROTOTYPE] = TARGET_EPROTOTYPE,
562 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
563 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
564 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
565 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
566 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
567 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
568 [EADDRINUSE] = TARGET_EADDRINUSE,
569 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
570 [ENETDOWN] = TARGET_ENETDOWN,
571 [ENETUNREACH] = TARGET_ENETUNREACH,
572 [ENETRESET] = TARGET_ENETRESET,
573 [ECONNABORTED] = TARGET_ECONNABORTED,
574 [ECONNRESET] = TARGET_ECONNRESET,
575 [ENOBUFS] = TARGET_ENOBUFS,
576 [EISCONN] = TARGET_EISCONN,
577 [ENOTCONN] = TARGET_ENOTCONN,
578 [EUCLEAN] = TARGET_EUCLEAN,
579 [ENOTNAM] = TARGET_ENOTNAM,
580 [ENAVAIL] = TARGET_ENAVAIL,
581 [EISNAM] = TARGET_EISNAM,
582 [EREMOTEIO] = TARGET_EREMOTEIO,
583 [ESHUTDOWN] = TARGET_ESHUTDOWN,
584 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
585 [ETIMEDOUT] = TARGET_ETIMEDOUT,
586 [ECONNREFUSED] = TARGET_ECONNREFUSED,
587 [EHOSTDOWN] = TARGET_EHOSTDOWN,
588 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
589 [EALREADY] = TARGET_EALREADY,
590 [EINPROGRESS] = TARGET_EINPROGRESS,
591 [ESTALE] = TARGET_ESTALE,
592 [ECANCELED] = TARGET_ECANCELED,
593 [ENOMEDIUM] = TARGET_ENOMEDIUM,
594 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
595 #ifdef ENOKEY
596 [ENOKEY] = TARGET_ENOKEY,
597 #endif
598 #ifdef EKEYEXPIRED
599 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
600 #endif
601 #ifdef EKEYREVOKED
602 [EKEYREVOKED] = TARGET_EKEYREVOKED,
603 #endif
604 #ifdef EKEYREJECTED
605 [EKEYREJECTED] = TARGET_EKEYREJECTED,
606 #endif
607 #ifdef EOWNERDEAD
608 [EOWNERDEAD] = TARGET_EOWNERDEAD,
609 #endif
610 #ifdef ENOTRECOVERABLE
611 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
612 #endif
615 static inline int host_to_target_errno(int err)
617 if(host_to_target_errno_table[err])
618 return host_to_target_errno_table[err];
619 return err;
622 static inline int target_to_host_errno(int err)
624 if (target_to_host_errno_table[err])
625 return target_to_host_errno_table[err];
626 return err;
629 static inline abi_long get_errno(abi_long ret)
631 if (ret == -1)
632 return -host_to_target_errno(errno);
633 else
634 return ret;
637 static inline int is_error(abi_long ret)
639 return (abi_ulong)ret >= (abi_ulong)(-4096);
642 char *target_strerror(int err)
644 if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
645 return NULL;
647 return strerror(target_to_host_errno(err));
650 static inline int host_to_target_sock_type(int host_type)
652 int target_type;
654 switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
655 case SOCK_DGRAM:
656 target_type = TARGET_SOCK_DGRAM;
657 break;
658 case SOCK_STREAM:
659 target_type = TARGET_SOCK_STREAM;
660 break;
661 default:
662 target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
663 break;
666 #if defined(SOCK_CLOEXEC)
667 if (host_type & SOCK_CLOEXEC) {
668 target_type |= TARGET_SOCK_CLOEXEC;
670 #endif
672 #if defined(SOCK_NONBLOCK)
673 if (host_type & SOCK_NONBLOCK) {
674 target_type |= TARGET_SOCK_NONBLOCK;
676 #endif
678 return target_type;
681 static abi_ulong target_brk;
682 static abi_ulong target_original_brk;
683 static abi_ulong brk_page;
685 void target_set_brk(abi_ulong new_brk)
687 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
688 brk_page = HOST_PAGE_ALIGN(target_brk);
691 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
692 #define DEBUGF_BRK(message, args...)
694 /* do_brk() must return target values and target errnos. */
695 abi_long do_brk(abi_ulong new_brk)
697 abi_long mapped_addr;
698 int new_alloc_size;
700 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
702 if (!new_brk) {
703 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
704 return target_brk;
706 if (new_brk < target_original_brk) {
707 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
708 target_brk);
709 return target_brk;
712 /* If the new brk is less than the highest page reserved to the
713 * target heap allocation, set it and we're almost done... */
714 if (new_brk <= brk_page) {
715 /* Heap contents are initialized to zero, as for anonymous
716 * mapped pages. */
717 if (new_brk > target_brk) {
718 memset(g2h(target_brk), 0, new_brk - target_brk);
720 target_brk = new_brk;
721 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
722 return target_brk;
725 /* We need to allocate more memory after the brk... Note that
726 * we don't use MAP_FIXED because that will map over the top of
727 * any existing mapping (like the one with the host libc or qemu
728 * itself); instead we treat "mapped but at wrong address" as
729 * a failure and unmap again.
731 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
732 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
733 PROT_READ|PROT_WRITE,
734 MAP_ANON|MAP_PRIVATE, 0, 0));
736 if (mapped_addr == brk_page) {
737 /* Heap contents are initialized to zero, as for anonymous
738 * mapped pages. Technically the new pages are already
739 * initialized to zero since they *are* anonymous mapped
740 * pages, however we have to take care with the contents that
741 * come from the remaining part of the previous page: it may
742 * contains garbage data due to a previous heap usage (grown
743 * then shrunken). */
744 memset(g2h(target_brk), 0, brk_page - target_brk);
746 target_brk = new_brk;
747 brk_page = HOST_PAGE_ALIGN(target_brk);
748 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
749 target_brk);
750 return target_brk;
751 } else if (mapped_addr != -1) {
752 /* Mapped but at wrong address, meaning there wasn't actually
753 * enough space for this brk.
755 target_munmap(mapped_addr, new_alloc_size);
756 mapped_addr = -1;
757 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
759 else {
760 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
763 #if defined(TARGET_ALPHA)
764 /* We (partially) emulate OSF/1 on Alpha, which requires we
765 return a proper errno, not an unchanged brk value. */
766 return -TARGET_ENOMEM;
767 #endif
768 /* For everything else, return the previous break. */
769 return target_brk;
772 static inline abi_long copy_from_user_fdset(fd_set *fds,
773 abi_ulong target_fds_addr,
774 int n)
776 int i, nw, j, k;
777 abi_ulong b, *target_fds;
779 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
780 if (!(target_fds = lock_user(VERIFY_READ,
781 target_fds_addr,
782 sizeof(abi_ulong) * nw,
783 1)))
784 return -TARGET_EFAULT;
786 FD_ZERO(fds);
787 k = 0;
788 for (i = 0; i < nw; i++) {
789 /* grab the abi_ulong */
790 __get_user(b, &target_fds[i]);
791 for (j = 0; j < TARGET_ABI_BITS; j++) {
792 /* check the bit inside the abi_ulong */
793 if ((b >> j) & 1)
794 FD_SET(k, fds);
795 k++;
799 unlock_user(target_fds, target_fds_addr, 0);
801 return 0;
804 static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
805 abi_ulong target_fds_addr,
806 int n)
808 if (target_fds_addr) {
809 if (copy_from_user_fdset(fds, target_fds_addr, n))
810 return -TARGET_EFAULT;
811 *fds_ptr = fds;
812 } else {
813 *fds_ptr = NULL;
815 return 0;
818 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
819 const fd_set *fds,
820 int n)
822 int i, nw, j, k;
823 abi_long v;
824 abi_ulong *target_fds;
826 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
827 if (!(target_fds = lock_user(VERIFY_WRITE,
828 target_fds_addr,
829 sizeof(abi_ulong) * nw,
830 0)))
831 return -TARGET_EFAULT;
833 k = 0;
834 for (i = 0; i < nw; i++) {
835 v = 0;
836 for (j = 0; j < TARGET_ABI_BITS; j++) {
837 v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
838 k++;
840 __put_user(v, &target_fds[i]);
843 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
845 return 0;
848 #if defined(__alpha__)
849 #define HOST_HZ 1024
850 #else
851 #define HOST_HZ 100
852 #endif
854 static inline abi_long host_to_target_clock_t(long ticks)
856 #if HOST_HZ == TARGET_HZ
857 return ticks;
858 #else
859 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
860 #endif
863 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
864 const struct rusage *rusage)
866 struct target_rusage *target_rusage;
868 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
869 return -TARGET_EFAULT;
870 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
871 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
872 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
873 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
874 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
875 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
876 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
877 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
878 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
879 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
880 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
881 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
882 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
883 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
884 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
885 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
886 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
887 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
888 unlock_user_struct(target_rusage, target_addr, 1);
890 return 0;
893 static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
895 abi_ulong target_rlim_swap;
896 rlim_t result;
898 target_rlim_swap = tswapal(target_rlim);
899 if (target_rlim_swap == TARGET_RLIM_INFINITY)
900 return RLIM_INFINITY;
902 result = target_rlim_swap;
903 if (target_rlim_swap != (rlim_t)result)
904 return RLIM_INFINITY;
906 return result;
909 static inline abi_ulong host_to_target_rlim(rlim_t rlim)
911 abi_ulong target_rlim_swap;
912 abi_ulong result;
914 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
915 target_rlim_swap = TARGET_RLIM_INFINITY;
916 else
917 target_rlim_swap = rlim;
918 result = tswapal(target_rlim_swap);
920 return result;
923 static inline int target_to_host_resource(int code)
925 switch (code) {
926 case TARGET_RLIMIT_AS:
927 return RLIMIT_AS;
928 case TARGET_RLIMIT_CORE:
929 return RLIMIT_CORE;
930 case TARGET_RLIMIT_CPU:
931 return RLIMIT_CPU;
932 case TARGET_RLIMIT_DATA:
933 return RLIMIT_DATA;
934 case TARGET_RLIMIT_FSIZE:
935 return RLIMIT_FSIZE;
936 case TARGET_RLIMIT_LOCKS:
937 return RLIMIT_LOCKS;
938 case TARGET_RLIMIT_MEMLOCK:
939 return RLIMIT_MEMLOCK;
940 case TARGET_RLIMIT_MSGQUEUE:
941 return RLIMIT_MSGQUEUE;
942 case TARGET_RLIMIT_NICE:
943 return RLIMIT_NICE;
944 case TARGET_RLIMIT_NOFILE:
945 return RLIMIT_NOFILE;
946 case TARGET_RLIMIT_NPROC:
947 return RLIMIT_NPROC;
948 case TARGET_RLIMIT_RSS:
949 return RLIMIT_RSS;
950 case TARGET_RLIMIT_RTPRIO:
951 return RLIMIT_RTPRIO;
952 case TARGET_RLIMIT_SIGPENDING:
953 return RLIMIT_SIGPENDING;
954 case TARGET_RLIMIT_STACK:
955 return RLIMIT_STACK;
956 default:
957 return code;
961 static inline abi_long copy_from_user_timeval(struct timeval *tv,
962 abi_ulong target_tv_addr)
964 struct target_timeval *target_tv;
966 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
967 return -TARGET_EFAULT;
969 __get_user(tv->tv_sec, &target_tv->tv_sec);
970 __get_user(tv->tv_usec, &target_tv->tv_usec);
972 unlock_user_struct(target_tv, target_tv_addr, 0);
974 return 0;
977 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
978 const struct timeval *tv)
980 struct target_timeval *target_tv;
982 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
983 return -TARGET_EFAULT;
985 __put_user(tv->tv_sec, &target_tv->tv_sec);
986 __put_user(tv->tv_usec, &target_tv->tv_usec);
988 unlock_user_struct(target_tv, target_tv_addr, 1);
990 return 0;
993 static inline abi_long copy_from_user_timezone(struct timezone *tz,
994 abi_ulong target_tz_addr)
996 struct target_timezone *target_tz;
998 if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
999 return -TARGET_EFAULT;
1002 __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
1003 __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
1005 unlock_user_struct(target_tz, target_tz_addr, 0);
1007 return 0;
1010 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
1011 #include <mqueue.h>
1013 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
1014 abi_ulong target_mq_attr_addr)
1016 struct target_mq_attr *target_mq_attr;
1018 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1019 target_mq_attr_addr, 1))
1020 return -TARGET_EFAULT;
1022 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1023 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1024 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1025 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1027 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1029 return 0;
1032 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1033 const struct mq_attr *attr)
1035 struct target_mq_attr *target_mq_attr;
1037 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1038 target_mq_attr_addr, 0))
1039 return -TARGET_EFAULT;
1041 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1042 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1043 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1044 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1046 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1048 return 0;
1050 #endif
1052 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1053 /* do_select() must return target values and target errnos. */
1054 static abi_long do_select(int n,
1055 abi_ulong rfd_addr, abi_ulong wfd_addr,
1056 abi_ulong efd_addr, abi_ulong target_tv_addr)
1058 fd_set rfds, wfds, efds;
1059 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1060 struct timeval tv, *tv_ptr;
1061 abi_long ret;
1063 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1064 if (ret) {
1065 return ret;
1067 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1068 if (ret) {
1069 return ret;
1071 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1072 if (ret) {
1073 return ret;
1076 if (target_tv_addr) {
1077 if (copy_from_user_timeval(&tv, target_tv_addr))
1078 return -TARGET_EFAULT;
1079 tv_ptr = &tv;
1080 } else {
1081 tv_ptr = NULL;
1084 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1086 if (!is_error(ret)) {
1087 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1088 return -TARGET_EFAULT;
1089 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1090 return -TARGET_EFAULT;
1091 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1092 return -TARGET_EFAULT;
1094 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1095 return -TARGET_EFAULT;
1098 return ret;
1100 #endif
1102 static abi_long do_pipe2(int host_pipe[], int flags)
1104 #ifdef CONFIG_PIPE2
1105 return pipe2(host_pipe, flags);
1106 #else
1107 return -ENOSYS;
1108 #endif
1111 static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1112 int flags, int is_pipe2)
1114 int host_pipe[2];
1115 abi_long ret;
1116 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1118 if (is_error(ret))
1119 return get_errno(ret);
1121 /* Several targets have special calling conventions for the original
1122 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1123 if (!is_pipe2) {
1124 #if defined(TARGET_ALPHA)
1125 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1126 return host_pipe[0];
1127 #elif defined(TARGET_MIPS)
1128 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1129 return host_pipe[0];
1130 #elif defined(TARGET_SH4)
1131 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1132 return host_pipe[0];
1133 #elif defined(TARGET_SPARC)
1134 ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1135 return host_pipe[0];
1136 #endif
1139 if (put_user_s32(host_pipe[0], pipedes)
1140 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1141 return -TARGET_EFAULT;
1142 return get_errno(ret);
1145 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1146 abi_ulong target_addr,
1147 socklen_t len)
1149 struct target_ip_mreqn *target_smreqn;
1151 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1152 if (!target_smreqn)
1153 return -TARGET_EFAULT;
1154 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1155 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1156 if (len == sizeof(struct target_ip_mreqn))
1157 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1158 unlock_user(target_smreqn, target_addr, 0);
1160 return 0;
1163 static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
1164 abi_ulong target_addr,
1165 socklen_t len)
1167 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1168 sa_family_t sa_family;
1169 struct target_sockaddr *target_saddr;
1171 if (fd_trans_target_to_host_addr(fd)) {
1172 return fd_trans_target_to_host_addr(fd)(addr, target_addr, len);
1175 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1176 if (!target_saddr)
1177 return -TARGET_EFAULT;
1179 sa_family = tswap16(target_saddr->sa_family);
1181 /* Oops. The caller might send a incomplete sun_path; sun_path
1182 * must be terminated by \0 (see the manual page), but
1183 * unfortunately it is quite common to specify sockaddr_un
1184 * length as "strlen(x->sun_path)" while it should be
1185 * "strlen(...) + 1". We'll fix that here if needed.
1186 * Linux kernel has a similar feature.
1189 if (sa_family == AF_UNIX) {
1190 if (len < unix_maxlen && len > 0) {
1191 char *cp = (char*)target_saddr;
1193 if ( cp[len-1] && !cp[len] )
1194 len++;
1196 if (len > unix_maxlen)
1197 len = unix_maxlen;
1200 memcpy(addr, target_saddr, len);
1201 addr->sa_family = sa_family;
1202 if (sa_family == AF_PACKET) {
1203 struct target_sockaddr_ll *lladdr;
1205 lladdr = (struct target_sockaddr_ll *)addr;
1206 lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
1207 lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
1209 unlock_user(target_saddr, target_addr, 0);
1211 return 0;
1214 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1215 struct sockaddr *addr,
1216 socklen_t len)
1218 struct target_sockaddr *target_saddr;
1220 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1221 if (!target_saddr)
1222 return -TARGET_EFAULT;
1223 memcpy(target_saddr, addr, len);
1224 target_saddr->sa_family = tswap16(addr->sa_family);
1225 unlock_user(target_saddr, target_addr, len);
1227 return 0;
1230 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1231 struct target_msghdr *target_msgh)
1233 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1234 abi_long msg_controllen;
1235 abi_ulong target_cmsg_addr;
1236 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
1237 socklen_t space = 0;
1239 msg_controllen = tswapal(target_msgh->msg_controllen);
1240 if (msg_controllen < sizeof (struct target_cmsghdr))
1241 goto the_end;
1242 target_cmsg_addr = tswapal(target_msgh->msg_control);
1243 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1244 target_cmsg_start = target_cmsg;
1245 if (!target_cmsg)
1246 return -TARGET_EFAULT;
1248 while (cmsg && target_cmsg) {
1249 void *data = CMSG_DATA(cmsg);
1250 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1252 int len = tswapal(target_cmsg->cmsg_len)
1253 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1255 space += CMSG_SPACE(len);
1256 if (space > msgh->msg_controllen) {
1257 space -= CMSG_SPACE(len);
1258 /* This is a QEMU bug, since we allocated the payload
1259 * area ourselves (unlike overflow in host-to-target
1260 * conversion, which is just the guest giving us a buffer
1261 * that's too small). It can't happen for the payload types
1262 * we currently support; if it becomes an issue in future
1263 * we would need to improve our allocation strategy to
1264 * something more intelligent than "twice the size of the
1265 * target buffer we're reading from".
1267 gemu_log("Host cmsg overflow\n");
1268 break;
1271 if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1272 cmsg->cmsg_level = SOL_SOCKET;
1273 } else {
1274 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1276 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1277 cmsg->cmsg_len = CMSG_LEN(len);
1279 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
1280 int *fd = (int *)data;
1281 int *target_fd = (int *)target_data;
1282 int i, numfds = len / sizeof(int);
1284 for (i = 0; i < numfds; i++) {
1285 __get_user(fd[i], target_fd + i);
1287 } else if (cmsg->cmsg_level == SOL_SOCKET
1288 && cmsg->cmsg_type == SCM_CREDENTIALS) {
1289 struct ucred *cred = (struct ucred *)data;
1290 struct target_ucred *target_cred =
1291 (struct target_ucred *)target_data;
1293 __get_user(cred->pid, &target_cred->pid);
1294 __get_user(cred->uid, &target_cred->uid);
1295 __get_user(cred->gid, &target_cred->gid);
1296 } else {
1297 gemu_log("Unsupported ancillary data: %d/%d\n",
1298 cmsg->cmsg_level, cmsg->cmsg_type);
1299 memcpy(data, target_data, len);
1302 cmsg = CMSG_NXTHDR(msgh, cmsg);
1303 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1304 target_cmsg_start);
1306 unlock_user(target_cmsg, target_cmsg_addr, 0);
1307 the_end:
1308 msgh->msg_controllen = space;
1309 return 0;
1312 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1313 struct msghdr *msgh)
1315 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1316 abi_long msg_controllen;
1317 abi_ulong target_cmsg_addr;
1318 struct target_cmsghdr *target_cmsg, *target_cmsg_start;
1319 socklen_t space = 0;
1321 msg_controllen = tswapal(target_msgh->msg_controllen);
1322 if (msg_controllen < sizeof (struct target_cmsghdr))
1323 goto the_end;
1324 target_cmsg_addr = tswapal(target_msgh->msg_control);
1325 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1326 target_cmsg_start = target_cmsg;
1327 if (!target_cmsg)
1328 return -TARGET_EFAULT;
1330 while (cmsg && target_cmsg) {
1331 void *data = CMSG_DATA(cmsg);
1332 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1334 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1335 int tgt_len, tgt_space;
1337 /* We never copy a half-header but may copy half-data;
1338 * this is Linux's behaviour in put_cmsg(). Note that
1339 * truncation here is a guest problem (which we report
1340 * to the guest via the CTRUNC bit), unlike truncation
1341 * in target_to_host_cmsg, which is a QEMU bug.
1343 if (msg_controllen < sizeof(struct cmsghdr)) {
1344 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
1345 break;
1348 if (cmsg->cmsg_level == SOL_SOCKET) {
1349 target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1350 } else {
1351 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1353 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1355 tgt_len = TARGET_CMSG_LEN(len);
1357 /* Payload types which need a different size of payload on
1358 * the target must adjust tgt_len here.
1360 switch (cmsg->cmsg_level) {
1361 case SOL_SOCKET:
1362 switch (cmsg->cmsg_type) {
1363 case SO_TIMESTAMP:
1364 tgt_len = sizeof(struct target_timeval);
1365 break;
1366 default:
1367 break;
1369 default:
1370 break;
1373 if (msg_controllen < tgt_len) {
1374 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
1375 tgt_len = msg_controllen;
1378 /* We must now copy-and-convert len bytes of payload
1379 * into tgt_len bytes of destination space. Bear in mind
1380 * that in both source and destination we may be dealing
1381 * with a truncated value!
1383 switch (cmsg->cmsg_level) {
1384 case SOL_SOCKET:
1385 switch (cmsg->cmsg_type) {
1386 case SCM_RIGHTS:
1388 int *fd = (int *)data;
1389 int *target_fd = (int *)target_data;
1390 int i, numfds = tgt_len / sizeof(int);
1392 for (i = 0; i < numfds; i++) {
1393 __put_user(fd[i], target_fd + i);
1395 break;
1397 case SO_TIMESTAMP:
1399 struct timeval *tv = (struct timeval *)data;
1400 struct target_timeval *target_tv =
1401 (struct target_timeval *)target_data;
1403 if (len != sizeof(struct timeval) ||
1404 tgt_len != sizeof(struct target_timeval)) {
1405 goto unimplemented;
1408 /* copy struct timeval to target */
1409 __put_user(tv->tv_sec, &target_tv->tv_sec);
1410 __put_user(tv->tv_usec, &target_tv->tv_usec);
1411 break;
1413 case SCM_CREDENTIALS:
1415 struct ucred *cred = (struct ucred *)data;
1416 struct target_ucred *target_cred =
1417 (struct target_ucred *)target_data;
1419 __put_user(cred->pid, &target_cred->pid);
1420 __put_user(cred->uid, &target_cred->uid);
1421 __put_user(cred->gid, &target_cred->gid);
1422 break;
1424 default:
1425 goto unimplemented;
1427 break;
1429 default:
1430 unimplemented:
1431 gemu_log("Unsupported ancillary data: %d/%d\n",
1432 cmsg->cmsg_level, cmsg->cmsg_type);
1433 memcpy(target_data, data, MIN(len, tgt_len));
1434 if (tgt_len > len) {
1435 memset(target_data + len, 0, tgt_len - len);
1439 target_cmsg->cmsg_len = tswapal(tgt_len);
1440 tgt_space = TARGET_CMSG_SPACE(len);
1441 if (msg_controllen < tgt_space) {
1442 tgt_space = msg_controllen;
1444 msg_controllen -= tgt_space;
1445 space += tgt_space;
1446 cmsg = CMSG_NXTHDR(msgh, cmsg);
1447 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg,
1448 target_cmsg_start);
1450 unlock_user(target_cmsg, target_cmsg_addr, space);
1451 the_end:
1452 target_msgh->msg_controllen = tswapal(space);
1453 return 0;
1456 /* do_setsockopt() Must return target values and target errnos. */
1457 static abi_long do_setsockopt(int sockfd, int level, int optname,
1458 abi_ulong optval_addr, socklen_t optlen)
1460 abi_long ret;
1461 int val;
1462 struct ip_mreqn *ip_mreq;
1463 struct ip_mreq_source *ip_mreq_source;
1465 switch(level) {
1466 case SOL_TCP:
1467 /* TCP options all take an 'int' value. */
1468 if (optlen < sizeof(uint32_t))
1469 return -TARGET_EINVAL;
1471 if (get_user_u32(val, optval_addr))
1472 return -TARGET_EFAULT;
1473 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1474 break;
1475 case SOL_IP:
1476 switch(optname) {
1477 case IP_TOS:
1478 case IP_TTL:
1479 case IP_HDRINCL:
1480 case IP_ROUTER_ALERT:
1481 case IP_RECVOPTS:
1482 case IP_RETOPTS:
1483 case IP_PKTINFO:
1484 case IP_MTU_DISCOVER:
1485 case IP_RECVERR:
1486 case IP_RECVTOS:
1487 #ifdef IP_FREEBIND
1488 case IP_FREEBIND:
1489 #endif
1490 case IP_MULTICAST_TTL:
1491 case IP_MULTICAST_LOOP:
1492 val = 0;
1493 if (optlen >= sizeof(uint32_t)) {
1494 if (get_user_u32(val, optval_addr))
1495 return -TARGET_EFAULT;
1496 } else if (optlen >= 1) {
1497 if (get_user_u8(val, optval_addr))
1498 return -TARGET_EFAULT;
1500 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1501 break;
1502 case IP_ADD_MEMBERSHIP:
1503 case IP_DROP_MEMBERSHIP:
1504 if (optlen < sizeof (struct target_ip_mreq) ||
1505 optlen > sizeof (struct target_ip_mreqn))
1506 return -TARGET_EINVAL;
1508 ip_mreq = (struct ip_mreqn *) alloca(optlen);
1509 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1510 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1511 break;
1513 case IP_BLOCK_SOURCE:
1514 case IP_UNBLOCK_SOURCE:
1515 case IP_ADD_SOURCE_MEMBERSHIP:
1516 case IP_DROP_SOURCE_MEMBERSHIP:
1517 if (optlen != sizeof (struct target_ip_mreq_source))
1518 return -TARGET_EINVAL;
1520 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1521 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1522 unlock_user (ip_mreq_source, optval_addr, 0);
1523 break;
1525 default:
1526 goto unimplemented;
1528 break;
1529 case SOL_IPV6:
1530 switch (optname) {
1531 case IPV6_MTU_DISCOVER:
1532 case IPV6_MTU:
1533 case IPV6_V6ONLY:
1534 case IPV6_RECVPKTINFO:
1535 val = 0;
1536 if (optlen < sizeof(uint32_t)) {
1537 return -TARGET_EINVAL;
1539 if (get_user_u32(val, optval_addr)) {
1540 return -TARGET_EFAULT;
1542 ret = get_errno(setsockopt(sockfd, level, optname,
1543 &val, sizeof(val)));
1544 break;
1545 default:
1546 goto unimplemented;
1548 break;
1549 case SOL_RAW:
1550 switch (optname) {
1551 case ICMP_FILTER:
1552 /* struct icmp_filter takes an u32 value */
1553 if (optlen < sizeof(uint32_t)) {
1554 return -TARGET_EINVAL;
1557 if (get_user_u32(val, optval_addr)) {
1558 return -TARGET_EFAULT;
1560 ret = get_errno(setsockopt(sockfd, level, optname,
1561 &val, sizeof(val)));
1562 break;
1564 default:
1565 goto unimplemented;
1567 break;
1568 case TARGET_SOL_SOCKET:
1569 switch (optname) {
1570 case TARGET_SO_RCVTIMEO:
1572 struct timeval tv;
1574 optname = SO_RCVTIMEO;
1576 set_timeout:
1577 if (optlen != sizeof(struct target_timeval)) {
1578 return -TARGET_EINVAL;
1581 if (copy_from_user_timeval(&tv, optval_addr)) {
1582 return -TARGET_EFAULT;
1585 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
1586 &tv, sizeof(tv)));
1587 return ret;
1589 case TARGET_SO_SNDTIMEO:
1590 optname = SO_SNDTIMEO;
1591 goto set_timeout;
1592 case TARGET_SO_ATTACH_FILTER:
1594 struct target_sock_fprog *tfprog;
1595 struct target_sock_filter *tfilter;
1596 struct sock_fprog fprog;
1597 struct sock_filter *filter;
1598 int i;
1600 if (optlen != sizeof(*tfprog)) {
1601 return -TARGET_EINVAL;
1603 if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
1604 return -TARGET_EFAULT;
1606 if (!lock_user_struct(VERIFY_READ, tfilter,
1607 tswapal(tfprog->filter), 0)) {
1608 unlock_user_struct(tfprog, optval_addr, 1);
1609 return -TARGET_EFAULT;
1612 fprog.len = tswap16(tfprog->len);
1613 filter = g_try_new(struct sock_filter, fprog.len);
1614 if (filter == NULL) {
1615 unlock_user_struct(tfilter, tfprog->filter, 1);
1616 unlock_user_struct(tfprog, optval_addr, 1);
1617 return -TARGET_ENOMEM;
1619 for (i = 0; i < fprog.len; i++) {
1620 filter[i].code = tswap16(tfilter[i].code);
1621 filter[i].jt = tfilter[i].jt;
1622 filter[i].jf = tfilter[i].jf;
1623 filter[i].k = tswap32(tfilter[i].k);
1625 fprog.filter = filter;
1627 ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
1628 SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
1629 g_free(filter);
1631 unlock_user_struct(tfilter, tfprog->filter, 1);
1632 unlock_user_struct(tfprog, optval_addr, 1);
1633 return ret;
1635 case TARGET_SO_BINDTODEVICE:
1637 char *dev_ifname, *addr_ifname;
1639 if (optlen > IFNAMSIZ - 1) {
1640 optlen = IFNAMSIZ - 1;
1642 dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1643 if (!dev_ifname) {
1644 return -TARGET_EFAULT;
1646 optname = SO_BINDTODEVICE;
1647 addr_ifname = alloca(IFNAMSIZ);
1648 memcpy(addr_ifname, dev_ifname, optlen);
1649 addr_ifname[optlen] = 0;
1650 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
1651 addr_ifname, optlen));
1652 unlock_user (dev_ifname, optval_addr, 0);
1653 return ret;
1655 /* Options with 'int' argument. */
1656 case TARGET_SO_DEBUG:
1657 optname = SO_DEBUG;
1658 break;
1659 case TARGET_SO_REUSEADDR:
1660 optname = SO_REUSEADDR;
1661 break;
1662 case TARGET_SO_TYPE:
1663 optname = SO_TYPE;
1664 break;
1665 case TARGET_SO_ERROR:
1666 optname = SO_ERROR;
1667 break;
1668 case TARGET_SO_DONTROUTE:
1669 optname = SO_DONTROUTE;
1670 break;
1671 case TARGET_SO_BROADCAST:
1672 optname = SO_BROADCAST;
1673 break;
1674 case TARGET_SO_SNDBUF:
1675 optname = SO_SNDBUF;
1676 break;
1677 case TARGET_SO_SNDBUFFORCE:
1678 optname = SO_SNDBUFFORCE;
1679 break;
1680 case TARGET_SO_RCVBUF:
1681 optname = SO_RCVBUF;
1682 break;
1683 case TARGET_SO_RCVBUFFORCE:
1684 optname = SO_RCVBUFFORCE;
1685 break;
1686 case TARGET_SO_KEEPALIVE:
1687 optname = SO_KEEPALIVE;
1688 break;
1689 case TARGET_SO_OOBINLINE:
1690 optname = SO_OOBINLINE;
1691 break;
1692 case TARGET_SO_NO_CHECK:
1693 optname = SO_NO_CHECK;
1694 break;
1695 case TARGET_SO_PRIORITY:
1696 optname = SO_PRIORITY;
1697 break;
1698 #ifdef SO_BSDCOMPAT
1699 case TARGET_SO_BSDCOMPAT:
1700 optname = SO_BSDCOMPAT;
1701 break;
1702 #endif
1703 case TARGET_SO_PASSCRED:
1704 optname = SO_PASSCRED;
1705 break;
1706 case TARGET_SO_PASSSEC:
1707 optname = SO_PASSSEC;
1708 break;
1709 case TARGET_SO_TIMESTAMP:
1710 optname = SO_TIMESTAMP;
1711 break;
1712 case TARGET_SO_RCVLOWAT:
1713 optname = SO_RCVLOWAT;
1714 break;
1715 break;
1716 default:
1717 goto unimplemented;
1719 if (optlen < sizeof(uint32_t))
1720 return -TARGET_EINVAL;
1722 if (get_user_u32(val, optval_addr))
1723 return -TARGET_EFAULT;
1724 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1725 break;
1726 default:
1727 unimplemented:
1728 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1729 ret = -TARGET_ENOPROTOOPT;
1731 return ret;
1734 /* do_getsockopt() Must return target values and target errnos. */
1735 static abi_long do_getsockopt(int sockfd, int level, int optname,
1736 abi_ulong optval_addr, abi_ulong optlen)
1738 abi_long ret;
1739 int len, val;
1740 socklen_t lv;
1742 switch(level) {
1743 case TARGET_SOL_SOCKET:
1744 level = SOL_SOCKET;
1745 switch (optname) {
1746 /* These don't just return a single integer */
1747 case TARGET_SO_LINGER:
1748 case TARGET_SO_RCVTIMEO:
1749 case TARGET_SO_SNDTIMEO:
1750 case TARGET_SO_PEERNAME:
1751 goto unimplemented;
1752 case TARGET_SO_PEERCRED: {
1753 struct ucred cr;
1754 socklen_t crlen;
1755 struct target_ucred *tcr;
1757 if (get_user_u32(len, optlen)) {
1758 return -TARGET_EFAULT;
1760 if (len < 0) {
1761 return -TARGET_EINVAL;
1764 crlen = sizeof(cr);
1765 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
1766 &cr, &crlen));
1767 if (ret < 0) {
1768 return ret;
1770 if (len > crlen) {
1771 len = crlen;
1773 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
1774 return -TARGET_EFAULT;
1776 __put_user(cr.pid, &tcr->pid);
1777 __put_user(cr.uid, &tcr->uid);
1778 __put_user(cr.gid, &tcr->gid);
1779 unlock_user_struct(tcr, optval_addr, 1);
1780 if (put_user_u32(len, optlen)) {
1781 return -TARGET_EFAULT;
1783 break;
1785 /* Options with 'int' argument. */
1786 case TARGET_SO_DEBUG:
1787 optname = SO_DEBUG;
1788 goto int_case;
1789 case TARGET_SO_REUSEADDR:
1790 optname = SO_REUSEADDR;
1791 goto int_case;
1792 case TARGET_SO_TYPE:
1793 optname = SO_TYPE;
1794 goto int_case;
1795 case TARGET_SO_ERROR:
1796 optname = SO_ERROR;
1797 goto int_case;
1798 case TARGET_SO_DONTROUTE:
1799 optname = SO_DONTROUTE;
1800 goto int_case;
1801 case TARGET_SO_BROADCAST:
1802 optname = SO_BROADCAST;
1803 goto int_case;
1804 case TARGET_SO_SNDBUF:
1805 optname = SO_SNDBUF;
1806 goto int_case;
1807 case TARGET_SO_RCVBUF:
1808 optname = SO_RCVBUF;
1809 goto int_case;
1810 case TARGET_SO_KEEPALIVE:
1811 optname = SO_KEEPALIVE;
1812 goto int_case;
1813 case TARGET_SO_OOBINLINE:
1814 optname = SO_OOBINLINE;
1815 goto int_case;
1816 case TARGET_SO_NO_CHECK:
1817 optname = SO_NO_CHECK;
1818 goto int_case;
1819 case TARGET_SO_PRIORITY:
1820 optname = SO_PRIORITY;
1821 goto int_case;
1822 #ifdef SO_BSDCOMPAT
1823 case TARGET_SO_BSDCOMPAT:
1824 optname = SO_BSDCOMPAT;
1825 goto int_case;
1826 #endif
1827 case TARGET_SO_PASSCRED:
1828 optname = SO_PASSCRED;
1829 goto int_case;
1830 case TARGET_SO_TIMESTAMP:
1831 optname = SO_TIMESTAMP;
1832 goto int_case;
1833 case TARGET_SO_RCVLOWAT:
1834 optname = SO_RCVLOWAT;
1835 goto int_case;
1836 case TARGET_SO_ACCEPTCONN:
1837 optname = SO_ACCEPTCONN;
1838 goto int_case;
1839 default:
1840 goto int_case;
1842 break;
1843 case SOL_TCP:
1844 /* TCP options all take an 'int' value. */
1845 int_case:
1846 if (get_user_u32(len, optlen))
1847 return -TARGET_EFAULT;
1848 if (len < 0)
1849 return -TARGET_EINVAL;
1850 lv = sizeof(lv);
1851 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1852 if (ret < 0)
1853 return ret;
1854 if (optname == SO_TYPE) {
1855 val = host_to_target_sock_type(val);
1857 if (len > lv)
1858 len = lv;
1859 if (len == 4) {
1860 if (put_user_u32(val, optval_addr))
1861 return -TARGET_EFAULT;
1862 } else {
1863 if (put_user_u8(val, optval_addr))
1864 return -TARGET_EFAULT;
1866 if (put_user_u32(len, optlen))
1867 return -TARGET_EFAULT;
1868 break;
1869 case SOL_IP:
1870 switch(optname) {
1871 case IP_TOS:
1872 case IP_TTL:
1873 case IP_HDRINCL:
1874 case IP_ROUTER_ALERT:
1875 case IP_RECVOPTS:
1876 case IP_RETOPTS:
1877 case IP_PKTINFO:
1878 case IP_MTU_DISCOVER:
1879 case IP_RECVERR:
1880 case IP_RECVTOS:
1881 #ifdef IP_FREEBIND
1882 case IP_FREEBIND:
1883 #endif
1884 case IP_MULTICAST_TTL:
1885 case IP_MULTICAST_LOOP:
1886 if (get_user_u32(len, optlen))
1887 return -TARGET_EFAULT;
1888 if (len < 0)
1889 return -TARGET_EINVAL;
1890 lv = sizeof(lv);
1891 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1892 if (ret < 0)
1893 return ret;
1894 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1895 len = 1;
1896 if (put_user_u32(len, optlen)
1897 || put_user_u8(val, optval_addr))
1898 return -TARGET_EFAULT;
1899 } else {
1900 if (len > sizeof(int))
1901 len = sizeof(int);
1902 if (put_user_u32(len, optlen)
1903 || put_user_u32(val, optval_addr))
1904 return -TARGET_EFAULT;
1906 break;
1907 default:
1908 ret = -TARGET_ENOPROTOOPT;
1909 break;
1911 break;
1912 default:
1913 unimplemented:
1914 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1915 level, optname);
1916 ret = -TARGET_EOPNOTSUPP;
1917 break;
1919 return ret;
1922 static struct iovec *lock_iovec(int type, abi_ulong target_addr,
1923 int count, int copy)
1925 struct target_iovec *target_vec;
1926 struct iovec *vec;
1927 abi_ulong total_len, max_len;
1928 int i;
1929 int err = 0;
1930 bool bad_address = false;
1932 if (count == 0) {
1933 errno = 0;
1934 return NULL;
1936 if (count < 0 || count > IOV_MAX) {
1937 errno = EINVAL;
1938 return NULL;
1941 vec = g_try_new0(struct iovec, count);
1942 if (vec == NULL) {
1943 errno = ENOMEM;
1944 return NULL;
1947 target_vec = lock_user(VERIFY_READ, target_addr,
1948 count * sizeof(struct target_iovec), 1);
1949 if (target_vec == NULL) {
1950 err = EFAULT;
1951 goto fail2;
1954 /* ??? If host page size > target page size, this will result in a
1955 value larger than what we can actually support. */
1956 max_len = 0x7fffffff & TARGET_PAGE_MASK;
1957 total_len = 0;
1959 for (i = 0; i < count; i++) {
1960 abi_ulong base = tswapal(target_vec[i].iov_base);
1961 abi_long len = tswapal(target_vec[i].iov_len);
1963 if (len < 0) {
1964 err = EINVAL;
1965 goto fail;
1966 } else if (len == 0) {
1967 /* Zero length pointer is ignored. */
1968 vec[i].iov_base = 0;
1969 } else {
1970 vec[i].iov_base = lock_user(type, base, len, copy);
1971 /* If the first buffer pointer is bad, this is a fault. But
1972 * subsequent bad buffers will result in a partial write; this
1973 * is realized by filling the vector with null pointers and
1974 * zero lengths. */
1975 if (!vec[i].iov_base) {
1976 if (i == 0) {
1977 err = EFAULT;
1978 goto fail;
1979 } else {
1980 bad_address = true;
1983 if (bad_address) {
1984 len = 0;
1986 if (len > max_len - total_len) {
1987 len = max_len - total_len;
1990 vec[i].iov_len = len;
1991 total_len += len;
1994 unlock_user(target_vec, target_addr, 0);
1995 return vec;
1997 fail:
1998 while (--i >= 0) {
1999 if (tswapal(target_vec[i].iov_len) > 0) {
2000 unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
2003 unlock_user(target_vec, target_addr, 0);
2004 fail2:
2005 g_free(vec);
2006 errno = err;
2007 return NULL;
2010 static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
2011 int count, int copy)
2013 struct target_iovec *target_vec;
2014 int i;
2016 target_vec = lock_user(VERIFY_READ, target_addr,
2017 count * sizeof(struct target_iovec), 1);
2018 if (target_vec) {
2019 for (i = 0; i < count; i++) {
2020 abi_ulong base = tswapal(target_vec[i].iov_base);
2021 abi_long len = tswapal(target_vec[i].iov_len);
2022 if (len < 0) {
2023 break;
2025 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
2027 unlock_user(target_vec, target_addr, 0);
2030 g_free(vec);
2033 static inline int target_to_host_sock_type(int *type)
2035 int host_type = 0;
2036 int target_type = *type;
2038 switch (target_type & TARGET_SOCK_TYPE_MASK) {
2039 case TARGET_SOCK_DGRAM:
2040 host_type = SOCK_DGRAM;
2041 break;
2042 case TARGET_SOCK_STREAM:
2043 host_type = SOCK_STREAM;
2044 break;
2045 default:
2046 host_type = target_type & TARGET_SOCK_TYPE_MASK;
2047 break;
2049 if (target_type & TARGET_SOCK_CLOEXEC) {
2050 #if defined(SOCK_CLOEXEC)
2051 host_type |= SOCK_CLOEXEC;
2052 #else
2053 return -TARGET_EINVAL;
2054 #endif
2056 if (target_type & TARGET_SOCK_NONBLOCK) {
2057 #if defined(SOCK_NONBLOCK)
2058 host_type |= SOCK_NONBLOCK;
2059 #elif !defined(O_NONBLOCK)
2060 return -TARGET_EINVAL;
2061 #endif
2063 *type = host_type;
2064 return 0;
2067 /* Try to emulate socket type flags after socket creation. */
2068 static int sock_flags_fixup(int fd, int target_type)
2070 #if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
2071 if (target_type & TARGET_SOCK_NONBLOCK) {
2072 int flags = fcntl(fd, F_GETFL);
2073 if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
2074 close(fd);
2075 return -TARGET_EINVAL;
2078 #endif
2079 return fd;
2082 static abi_long packet_target_to_host_sockaddr(void *host_addr,
2083 abi_ulong target_addr,
2084 socklen_t len)
2086 struct sockaddr *addr = host_addr;
2087 struct target_sockaddr *target_saddr;
2089 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
2090 if (!target_saddr) {
2091 return -TARGET_EFAULT;
2094 memcpy(addr, target_saddr, len);
2095 addr->sa_family = tswap16(target_saddr->sa_family);
2096 /* spkt_protocol is big-endian */
2098 unlock_user(target_saddr, target_addr, 0);
2099 return 0;
2102 static TargetFdTrans target_packet_trans = {
2103 .target_to_host_addr = packet_target_to_host_sockaddr,
2106 /* do_socket() Must return target values and target errnos. */
2107 static abi_long do_socket(int domain, int type, int protocol)
2109 int target_type = type;
2110 int ret;
2112 ret = target_to_host_sock_type(&type);
2113 if (ret) {
2114 return ret;
2117 if (domain == PF_NETLINK)
2118 return -TARGET_EAFNOSUPPORT;
2120 if (domain == AF_PACKET ||
2121 (domain == AF_INET && type == SOCK_PACKET)) {
2122 protocol = tswap16(protocol);
2125 ret = get_errno(socket(domain, type, protocol));
2126 if (ret >= 0) {
2127 ret = sock_flags_fixup(ret, target_type);
2128 if (type == SOCK_PACKET) {
2129 /* Manage an obsolete case :
2130 * if socket type is SOCK_PACKET, bind by name
2132 fd_trans_register(ret, &target_packet_trans);
2135 return ret;
2138 /* do_bind() Must return target values and target errnos. */
2139 static abi_long do_bind(int sockfd, abi_ulong target_addr,
2140 socklen_t addrlen)
2142 void *addr;
2143 abi_long ret;
2145 if ((int)addrlen < 0) {
2146 return -TARGET_EINVAL;
2149 addr = alloca(addrlen+1);
2151 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
2152 if (ret)
2153 return ret;
2155 return get_errno(bind(sockfd, addr, addrlen));
2158 /* do_connect() Must return target values and target errnos. */
2159 static abi_long do_connect(int sockfd, abi_ulong target_addr,
2160 socklen_t addrlen)
2162 void *addr;
2163 abi_long ret;
2165 if ((int)addrlen < 0) {
2166 return -TARGET_EINVAL;
2169 addr = alloca(addrlen+1);
2171 ret = target_to_host_sockaddr(sockfd, addr, target_addr, addrlen);
2172 if (ret)
2173 return ret;
2175 return get_errno(connect(sockfd, addr, addrlen));
2178 /* do_sendrecvmsg_locked() Must return target values and target errnos. */
2179 static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
2180 int flags, int send)
2182 abi_long ret, len;
2183 struct msghdr msg;
2184 int count;
2185 struct iovec *vec;
2186 abi_ulong target_vec;
2188 if (msgp->msg_name) {
2189 msg.msg_namelen = tswap32(msgp->msg_namelen);
2190 msg.msg_name = alloca(msg.msg_namelen+1);
2191 ret = target_to_host_sockaddr(fd, msg.msg_name,
2192 tswapal(msgp->msg_name),
2193 msg.msg_namelen);
2194 if (ret) {
2195 goto out2;
2197 } else {
2198 msg.msg_name = NULL;
2199 msg.msg_namelen = 0;
2201 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
2202 msg.msg_control = alloca(msg.msg_controllen);
2203 msg.msg_flags = tswap32(msgp->msg_flags);
2205 count = tswapal(msgp->msg_iovlen);
2206 target_vec = tswapal(msgp->msg_iov);
2207 vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
2208 target_vec, count, send);
2209 if (vec == NULL) {
2210 ret = -host_to_target_errno(errno);
2211 goto out2;
2213 msg.msg_iovlen = count;
2214 msg.msg_iov = vec;
2216 if (send) {
2217 ret = target_to_host_cmsg(&msg, msgp);
2218 if (ret == 0)
2219 ret = get_errno(sendmsg(fd, &msg, flags));
2220 } else {
2221 ret = get_errno(recvmsg(fd, &msg, flags));
2222 if (!is_error(ret)) {
2223 len = ret;
2224 ret = host_to_target_cmsg(msgp, &msg);
2225 if (!is_error(ret)) {
2226 msgp->msg_namelen = tswap32(msg.msg_namelen);
2227 if (msg.msg_name != NULL) {
2228 ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
2229 msg.msg_name, msg.msg_namelen);
2230 if (ret) {
2231 goto out;
2235 ret = len;
2240 out:
2241 unlock_iovec(vec, target_vec, count, !send);
2242 out2:
2243 return ret;
2246 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
2247 int flags, int send)
2249 abi_long ret;
2250 struct target_msghdr *msgp;
2252 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
2253 msgp,
2254 target_msg,
2255 send ? 1 : 0)) {
2256 return -TARGET_EFAULT;
2258 ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
2259 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
2260 return ret;
2263 /* We don't rely on the C library to have sendmmsg/recvmmsg support,
2264 * so it might not have this *mmsg-specific flag either.
2266 #ifndef MSG_WAITFORONE
2267 #define MSG_WAITFORONE 0x10000
2268 #endif
2270 static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
2271 unsigned int vlen, unsigned int flags,
2272 int send)
2274 struct target_mmsghdr *mmsgp;
2275 abi_long ret = 0;
2276 int i;
2278 if (vlen > UIO_MAXIOV) {
2279 vlen = UIO_MAXIOV;
2282 mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
2283 if (!mmsgp) {
2284 return -TARGET_EFAULT;
2287 for (i = 0; i < vlen; i++) {
2288 ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
2289 if (is_error(ret)) {
2290 break;
2292 mmsgp[i].msg_len = tswap32(ret);
2293 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
2294 if (flags & MSG_WAITFORONE) {
2295 flags |= MSG_DONTWAIT;
2299 unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
2301 /* Return number of datagrams sent if we sent any at all;
2302 * otherwise return the error.
2304 if (i) {
2305 return i;
2307 return ret;
2310 /* If we don't have a system accept4() then just call accept.
2311 * The callsites to do_accept4() will ensure that they don't
2312 * pass a non-zero flags argument in this config.
2314 #ifndef CONFIG_ACCEPT4
2315 static inline int accept4(int sockfd, struct sockaddr *addr,
2316 socklen_t *addrlen, int flags)
2318 assert(flags == 0);
2319 return accept(sockfd, addr, addrlen);
2321 #endif
2323 /* do_accept4() Must return target values and target errnos. */
2324 static abi_long do_accept4(int fd, abi_ulong target_addr,
2325 abi_ulong target_addrlen_addr, int flags)
2327 socklen_t addrlen;
2328 void *addr;
2329 abi_long ret;
2330 int host_flags;
2332 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
2334 if (target_addr == 0) {
2335 return get_errno(accept4(fd, NULL, NULL, host_flags));
2338 /* linux returns EINVAL if addrlen pointer is invalid */
2339 if (get_user_u32(addrlen, target_addrlen_addr))
2340 return -TARGET_EINVAL;
2342 if ((int)addrlen < 0) {
2343 return -TARGET_EINVAL;
2346 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2347 return -TARGET_EINVAL;
2349 addr = alloca(addrlen);
2351 ret = get_errno(accept4(fd, addr, &addrlen, host_flags));
2352 if (!is_error(ret)) {
2353 host_to_target_sockaddr(target_addr, addr, addrlen);
2354 if (put_user_u32(addrlen, target_addrlen_addr))
2355 ret = -TARGET_EFAULT;
2357 return ret;
2360 /* do_getpeername() Must return target values and target errnos. */
2361 static abi_long do_getpeername(int fd, abi_ulong target_addr,
2362 abi_ulong target_addrlen_addr)
2364 socklen_t addrlen;
2365 void *addr;
2366 abi_long ret;
2368 if (get_user_u32(addrlen, target_addrlen_addr))
2369 return -TARGET_EFAULT;
2371 if ((int)addrlen < 0) {
2372 return -TARGET_EINVAL;
2375 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2376 return -TARGET_EFAULT;
2378 addr = alloca(addrlen);
2380 ret = get_errno(getpeername(fd, addr, &addrlen));
2381 if (!is_error(ret)) {
2382 host_to_target_sockaddr(target_addr, addr, addrlen);
2383 if (put_user_u32(addrlen, target_addrlen_addr))
2384 ret = -TARGET_EFAULT;
2386 return ret;
2389 /* do_getsockname() Must return target values and target errnos. */
2390 static abi_long do_getsockname(int fd, abi_ulong target_addr,
2391 abi_ulong target_addrlen_addr)
2393 socklen_t addrlen;
2394 void *addr;
2395 abi_long ret;
2397 if (get_user_u32(addrlen, target_addrlen_addr))
2398 return -TARGET_EFAULT;
2400 if ((int)addrlen < 0) {
2401 return -TARGET_EINVAL;
2404 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2405 return -TARGET_EFAULT;
2407 addr = alloca(addrlen);
2409 ret = get_errno(getsockname(fd, addr, &addrlen));
2410 if (!is_error(ret)) {
2411 host_to_target_sockaddr(target_addr, addr, addrlen);
2412 if (put_user_u32(addrlen, target_addrlen_addr))
2413 ret = -TARGET_EFAULT;
2415 return ret;
2418 /* do_socketpair() Must return target values and target errnos. */
2419 static abi_long do_socketpair(int domain, int type, int protocol,
2420 abi_ulong target_tab_addr)
2422 int tab[2];
2423 abi_long ret;
2425 target_to_host_sock_type(&type);
2427 ret = get_errno(socketpair(domain, type, protocol, tab));
2428 if (!is_error(ret)) {
2429 if (put_user_s32(tab[0], target_tab_addr)
2430 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
2431 ret = -TARGET_EFAULT;
2433 return ret;
2436 /* do_sendto() Must return target values and target errnos. */
2437 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
2438 abi_ulong target_addr, socklen_t addrlen)
2440 void *addr;
2441 void *host_msg;
2442 abi_long ret;
2444 if ((int)addrlen < 0) {
2445 return -TARGET_EINVAL;
2448 host_msg = lock_user(VERIFY_READ, msg, len, 1);
2449 if (!host_msg)
2450 return -TARGET_EFAULT;
2451 if (target_addr) {
2452 addr = alloca(addrlen+1);
2453 ret = target_to_host_sockaddr(fd, addr, target_addr, addrlen);
2454 if (ret) {
2455 unlock_user(host_msg, msg, 0);
2456 return ret;
2458 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2459 } else {
2460 ret = get_errno(send(fd, host_msg, len, flags));
2462 unlock_user(host_msg, msg, 0);
2463 return ret;
2466 /* do_recvfrom() Must return target values and target errnos. */
2467 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2468 abi_ulong target_addr,
2469 abi_ulong target_addrlen)
2471 socklen_t addrlen;
2472 void *addr;
2473 void *host_msg;
2474 abi_long ret;
2476 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2477 if (!host_msg)
2478 return -TARGET_EFAULT;
2479 if (target_addr) {
2480 if (get_user_u32(addrlen, target_addrlen)) {
2481 ret = -TARGET_EFAULT;
2482 goto fail;
2484 if ((int)addrlen < 0) {
2485 ret = -TARGET_EINVAL;
2486 goto fail;
2488 addr = alloca(addrlen);
2489 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2490 } else {
2491 addr = NULL; /* To keep compiler quiet. */
2492 ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2494 if (!is_error(ret)) {
2495 if (target_addr) {
2496 host_to_target_sockaddr(target_addr, addr, addrlen);
2497 if (put_user_u32(addrlen, target_addrlen)) {
2498 ret = -TARGET_EFAULT;
2499 goto fail;
2502 unlock_user(host_msg, msg, len);
2503 } else {
2504 fail:
2505 unlock_user(host_msg, msg, 0);
2507 return ret;
2510 #ifdef TARGET_NR_socketcall
2511 /* do_socketcall() Must return target values and target errnos. */
2512 static abi_long do_socketcall(int num, abi_ulong vptr)
2514 static const unsigned ac[] = { /* number of arguments per call */
2515 [SOCKOP_socket] = 3, /* domain, type, protocol */
2516 [SOCKOP_bind] = 3, /* sockfd, addr, addrlen */
2517 [SOCKOP_connect] = 3, /* sockfd, addr, addrlen */
2518 [SOCKOP_listen] = 2, /* sockfd, backlog */
2519 [SOCKOP_accept] = 3, /* sockfd, addr, addrlen */
2520 [SOCKOP_accept4] = 4, /* sockfd, addr, addrlen, flags */
2521 [SOCKOP_getsockname] = 3, /* sockfd, addr, addrlen */
2522 [SOCKOP_getpeername] = 3, /* sockfd, addr, addrlen */
2523 [SOCKOP_socketpair] = 4, /* domain, type, protocol, tab */
2524 [SOCKOP_send] = 4, /* sockfd, msg, len, flags */
2525 [SOCKOP_recv] = 4, /* sockfd, msg, len, flags */
2526 [SOCKOP_sendto] = 6, /* sockfd, msg, len, flags, addr, addrlen */
2527 [SOCKOP_recvfrom] = 6, /* sockfd, msg, len, flags, addr, addrlen */
2528 [SOCKOP_shutdown] = 2, /* sockfd, how */
2529 [SOCKOP_sendmsg] = 3, /* sockfd, msg, flags */
2530 [SOCKOP_recvmsg] = 3, /* sockfd, msg, flags */
2531 [SOCKOP_sendmmsg] = 4, /* sockfd, msgvec, vlen, flags */
2532 [SOCKOP_recvmmsg] = 4, /* sockfd, msgvec, vlen, flags */
2533 [SOCKOP_setsockopt] = 5, /* sockfd, level, optname, optval, optlen */
2534 [SOCKOP_getsockopt] = 5, /* sockfd, level, optname, optval, optlen */
2536 abi_long a[6]; /* max 6 args */
2538 /* first, collect the arguments in a[] according to ac[] */
2539 if (num >= 0 && num < ARRAY_SIZE(ac)) {
2540 unsigned i;
2541 assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
2542 for (i = 0; i < ac[num]; ++i) {
2543 if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
2544 return -TARGET_EFAULT;
2549 /* now when we have the args, actually handle the call */
2550 switch (num) {
2551 case SOCKOP_socket: /* domain, type, protocol */
2552 return do_socket(a[0], a[1], a[2]);
2553 case SOCKOP_bind: /* sockfd, addr, addrlen */
2554 return do_bind(a[0], a[1], a[2]);
2555 case SOCKOP_connect: /* sockfd, addr, addrlen */
2556 return do_connect(a[0], a[1], a[2]);
2557 case SOCKOP_listen: /* sockfd, backlog */
2558 return get_errno(listen(a[0], a[1]));
2559 case SOCKOP_accept: /* sockfd, addr, addrlen */
2560 return do_accept4(a[0], a[1], a[2], 0);
2561 case SOCKOP_accept4: /* sockfd, addr, addrlen, flags */
2562 return do_accept4(a[0], a[1], a[2], a[3]);
2563 case SOCKOP_getsockname: /* sockfd, addr, addrlen */
2564 return do_getsockname(a[0], a[1], a[2]);
2565 case SOCKOP_getpeername: /* sockfd, addr, addrlen */
2566 return do_getpeername(a[0], a[1], a[2]);
2567 case SOCKOP_socketpair: /* domain, type, protocol, tab */
2568 return do_socketpair(a[0], a[1], a[2], a[3]);
2569 case SOCKOP_send: /* sockfd, msg, len, flags */
2570 return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
2571 case SOCKOP_recv: /* sockfd, msg, len, flags */
2572 return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
2573 case SOCKOP_sendto: /* sockfd, msg, len, flags, addr, addrlen */
2574 return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
2575 case SOCKOP_recvfrom: /* sockfd, msg, len, flags, addr, addrlen */
2576 return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
2577 case SOCKOP_shutdown: /* sockfd, how */
2578 return get_errno(shutdown(a[0], a[1]));
2579 case SOCKOP_sendmsg: /* sockfd, msg, flags */
2580 return do_sendrecvmsg(a[0], a[1], a[2], 1);
2581 case SOCKOP_recvmsg: /* sockfd, msg, flags */
2582 return do_sendrecvmsg(a[0], a[1], a[2], 0);
2583 case SOCKOP_sendmmsg: /* sockfd, msgvec, vlen, flags */
2584 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);
2585 case SOCKOP_recvmmsg: /* sockfd, msgvec, vlen, flags */
2586 return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);
2587 case SOCKOP_setsockopt: /* sockfd, level, optname, optval, optlen */
2588 return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
2589 case SOCKOP_getsockopt: /* sockfd, level, optname, optval, optlen */
2590 return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
2591 default:
2592 gemu_log("Unsupported socketcall: %d\n", num);
2593 return -TARGET_ENOSYS;
2596 #endif
2598 #define N_SHM_REGIONS 32
2600 static struct shm_region {
2601 abi_ulong start;
2602 abi_ulong size;
2603 } shm_regions[N_SHM_REGIONS];
2605 struct target_semid_ds
2607 struct target_ipc_perm sem_perm;
2608 abi_ulong sem_otime;
2609 #if !defined(TARGET_PPC64)
2610 abi_ulong __unused1;
2611 #endif
2612 abi_ulong sem_ctime;
2613 #if !defined(TARGET_PPC64)
2614 abi_ulong __unused2;
2615 #endif
2616 abi_ulong sem_nsems;
2617 abi_ulong __unused3;
2618 abi_ulong __unused4;
2621 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2622 abi_ulong target_addr)
2624 struct target_ipc_perm *target_ip;
2625 struct target_semid_ds *target_sd;
2627 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2628 return -TARGET_EFAULT;
2629 target_ip = &(target_sd->sem_perm);
2630 host_ip->__key = tswap32(target_ip->__key);
2631 host_ip->uid = tswap32(target_ip->uid);
2632 host_ip->gid = tswap32(target_ip->gid);
2633 host_ip->cuid = tswap32(target_ip->cuid);
2634 host_ip->cgid = tswap32(target_ip->cgid);
2635 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2636 host_ip->mode = tswap32(target_ip->mode);
2637 #else
2638 host_ip->mode = tswap16(target_ip->mode);
2639 #endif
2640 #if defined(TARGET_PPC)
2641 host_ip->__seq = tswap32(target_ip->__seq);
2642 #else
2643 host_ip->__seq = tswap16(target_ip->__seq);
2644 #endif
2645 unlock_user_struct(target_sd, target_addr, 0);
2646 return 0;
2649 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2650 struct ipc_perm *host_ip)
2652 struct target_ipc_perm *target_ip;
2653 struct target_semid_ds *target_sd;
2655 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2656 return -TARGET_EFAULT;
2657 target_ip = &(target_sd->sem_perm);
2658 target_ip->__key = tswap32(host_ip->__key);
2659 target_ip->uid = tswap32(host_ip->uid);
2660 target_ip->gid = tswap32(host_ip->gid);
2661 target_ip->cuid = tswap32(host_ip->cuid);
2662 target_ip->cgid = tswap32(host_ip->cgid);
2663 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2664 target_ip->mode = tswap32(host_ip->mode);
2665 #else
2666 target_ip->mode = tswap16(host_ip->mode);
2667 #endif
2668 #if defined(TARGET_PPC)
2669 target_ip->__seq = tswap32(host_ip->__seq);
2670 #else
2671 target_ip->__seq = tswap16(host_ip->__seq);
2672 #endif
2673 unlock_user_struct(target_sd, target_addr, 1);
2674 return 0;
2677 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2678 abi_ulong target_addr)
2680 struct target_semid_ds *target_sd;
2682 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2683 return -TARGET_EFAULT;
2684 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2685 return -TARGET_EFAULT;
2686 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2687 host_sd->sem_otime = tswapal(target_sd->sem_otime);
2688 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2689 unlock_user_struct(target_sd, target_addr, 0);
2690 return 0;
2693 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2694 struct semid_ds *host_sd)
2696 struct target_semid_ds *target_sd;
2698 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2699 return -TARGET_EFAULT;
2700 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2701 return -TARGET_EFAULT;
2702 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2703 target_sd->sem_otime = tswapal(host_sd->sem_otime);
2704 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2705 unlock_user_struct(target_sd, target_addr, 1);
2706 return 0;
2709 struct target_seminfo {
2710 int semmap;
2711 int semmni;
2712 int semmns;
2713 int semmnu;
2714 int semmsl;
2715 int semopm;
2716 int semume;
2717 int semusz;
2718 int semvmx;
2719 int semaem;
2722 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2723 struct seminfo *host_seminfo)
2725 struct target_seminfo *target_seminfo;
2726 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2727 return -TARGET_EFAULT;
2728 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2729 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2730 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2731 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2732 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2733 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2734 __put_user(host_seminfo->semume, &target_seminfo->semume);
2735 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2736 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2737 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2738 unlock_user_struct(target_seminfo, target_addr, 1);
2739 return 0;
2742 union semun {
2743 int val;
2744 struct semid_ds *buf;
2745 unsigned short *array;
2746 struct seminfo *__buf;
2749 union target_semun {
2750 int val;
2751 abi_ulong buf;
2752 abi_ulong array;
2753 abi_ulong __buf;
2756 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2757 abi_ulong target_addr)
2759 int nsems;
2760 unsigned short *array;
2761 union semun semun;
2762 struct semid_ds semid_ds;
2763 int i, ret;
2765 semun.buf = &semid_ds;
2767 ret = semctl(semid, 0, IPC_STAT, semun);
2768 if (ret == -1)
2769 return get_errno(ret);
2771 nsems = semid_ds.sem_nsems;
2773 *host_array = g_try_new(unsigned short, nsems);
2774 if (!*host_array) {
2775 return -TARGET_ENOMEM;
2777 array = lock_user(VERIFY_READ, target_addr,
2778 nsems*sizeof(unsigned short), 1);
2779 if (!array) {
2780 g_free(*host_array);
2781 return -TARGET_EFAULT;
2784 for(i=0; i<nsems; i++) {
2785 __get_user((*host_array)[i], &array[i]);
2787 unlock_user(array, target_addr, 0);
2789 return 0;
2792 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2793 unsigned short **host_array)
2795 int nsems;
2796 unsigned short *array;
2797 union semun semun;
2798 struct semid_ds semid_ds;
2799 int i, ret;
2801 semun.buf = &semid_ds;
2803 ret = semctl(semid, 0, IPC_STAT, semun);
2804 if (ret == -1)
2805 return get_errno(ret);
2807 nsems = semid_ds.sem_nsems;
2809 array = lock_user(VERIFY_WRITE, target_addr,
2810 nsems*sizeof(unsigned short), 0);
2811 if (!array)
2812 return -TARGET_EFAULT;
2814 for(i=0; i<nsems; i++) {
2815 __put_user((*host_array)[i], &array[i]);
2817 g_free(*host_array);
2818 unlock_user(array, target_addr, 1);
2820 return 0;
2823 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2824 abi_ulong target_arg)
2826 union target_semun target_su = { .buf = target_arg };
2827 union semun arg;
2828 struct semid_ds dsarg;
2829 unsigned short *array = NULL;
2830 struct seminfo seminfo;
2831 abi_long ret = -TARGET_EINVAL;
2832 abi_long err;
2833 cmd &= 0xff;
2835 switch( cmd ) {
2836 case GETVAL:
2837 case SETVAL:
2838 /* In 64 bit cross-endian situations, we will erroneously pick up
2839 * the wrong half of the union for the "val" element. To rectify
2840 * this, the entire 8-byte structure is byteswapped, followed by
2841 * a swap of the 4 byte val field. In other cases, the data is
2842 * already in proper host byte order. */
2843 if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
2844 target_su.buf = tswapal(target_su.buf);
2845 arg.val = tswap32(target_su.val);
2846 } else {
2847 arg.val = target_su.val;
2849 ret = get_errno(semctl(semid, semnum, cmd, arg));
2850 break;
2851 case GETALL:
2852 case SETALL:
2853 err = target_to_host_semarray(semid, &array, target_su.array);
2854 if (err)
2855 return err;
2856 arg.array = array;
2857 ret = get_errno(semctl(semid, semnum, cmd, arg));
2858 err = host_to_target_semarray(semid, target_su.array, &array);
2859 if (err)
2860 return err;
2861 break;
2862 case IPC_STAT:
2863 case IPC_SET:
2864 case SEM_STAT:
2865 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2866 if (err)
2867 return err;
2868 arg.buf = &dsarg;
2869 ret = get_errno(semctl(semid, semnum, cmd, arg));
2870 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2871 if (err)
2872 return err;
2873 break;
2874 case IPC_INFO:
2875 case SEM_INFO:
2876 arg.__buf = &seminfo;
2877 ret = get_errno(semctl(semid, semnum, cmd, arg));
2878 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2879 if (err)
2880 return err;
2881 break;
2882 case IPC_RMID:
2883 case GETPID:
2884 case GETNCNT:
2885 case GETZCNT:
2886 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2887 break;
2890 return ret;
2893 struct target_sembuf {
2894 unsigned short sem_num;
2895 short sem_op;
2896 short sem_flg;
2899 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2900 abi_ulong target_addr,
2901 unsigned nsops)
2903 struct target_sembuf *target_sembuf;
2904 int i;
2906 target_sembuf = lock_user(VERIFY_READ, target_addr,
2907 nsops*sizeof(struct target_sembuf), 1);
2908 if (!target_sembuf)
2909 return -TARGET_EFAULT;
2911 for(i=0; i<nsops; i++) {
2912 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2913 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2914 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2917 unlock_user(target_sembuf, target_addr, 0);
2919 return 0;
2922 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2924 struct sembuf sops[nsops];
2926 if (target_to_host_sembuf(sops, ptr, nsops))
2927 return -TARGET_EFAULT;
2929 return get_errno(semop(semid, sops, nsops));
2932 struct target_msqid_ds
2934 struct target_ipc_perm msg_perm;
2935 abi_ulong msg_stime;
2936 #if TARGET_ABI_BITS == 32
2937 abi_ulong __unused1;
2938 #endif
2939 abi_ulong msg_rtime;
2940 #if TARGET_ABI_BITS == 32
2941 abi_ulong __unused2;
2942 #endif
2943 abi_ulong msg_ctime;
2944 #if TARGET_ABI_BITS == 32
2945 abi_ulong __unused3;
2946 #endif
2947 abi_ulong __msg_cbytes;
2948 abi_ulong msg_qnum;
2949 abi_ulong msg_qbytes;
2950 abi_ulong msg_lspid;
2951 abi_ulong msg_lrpid;
2952 abi_ulong __unused4;
2953 abi_ulong __unused5;
2956 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2957 abi_ulong target_addr)
2959 struct target_msqid_ds *target_md;
2961 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2962 return -TARGET_EFAULT;
2963 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2964 return -TARGET_EFAULT;
2965 host_md->msg_stime = tswapal(target_md->msg_stime);
2966 host_md->msg_rtime = tswapal(target_md->msg_rtime);
2967 host_md->msg_ctime = tswapal(target_md->msg_ctime);
2968 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2969 host_md->msg_qnum = tswapal(target_md->msg_qnum);
2970 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2971 host_md->msg_lspid = tswapal(target_md->msg_lspid);
2972 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2973 unlock_user_struct(target_md, target_addr, 0);
2974 return 0;
2977 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2978 struct msqid_ds *host_md)
2980 struct target_msqid_ds *target_md;
2982 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2983 return -TARGET_EFAULT;
2984 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2985 return -TARGET_EFAULT;
2986 target_md->msg_stime = tswapal(host_md->msg_stime);
2987 target_md->msg_rtime = tswapal(host_md->msg_rtime);
2988 target_md->msg_ctime = tswapal(host_md->msg_ctime);
2989 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2990 target_md->msg_qnum = tswapal(host_md->msg_qnum);
2991 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2992 target_md->msg_lspid = tswapal(host_md->msg_lspid);
2993 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2994 unlock_user_struct(target_md, target_addr, 1);
2995 return 0;
2998 struct target_msginfo {
2999 int msgpool;
3000 int msgmap;
3001 int msgmax;
3002 int msgmnb;
3003 int msgmni;
3004 int msgssz;
3005 int msgtql;
3006 unsigned short int msgseg;
3009 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
3010 struct msginfo *host_msginfo)
3012 struct target_msginfo *target_msginfo;
3013 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
3014 return -TARGET_EFAULT;
3015 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
3016 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
3017 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
3018 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
3019 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
3020 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
3021 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
3022 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
3023 unlock_user_struct(target_msginfo, target_addr, 1);
3024 return 0;
3027 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
3029 struct msqid_ds dsarg;
3030 struct msginfo msginfo;
3031 abi_long ret = -TARGET_EINVAL;
3033 cmd &= 0xff;
3035 switch (cmd) {
3036 case IPC_STAT:
3037 case IPC_SET:
3038 case MSG_STAT:
3039 if (target_to_host_msqid_ds(&dsarg,ptr))
3040 return -TARGET_EFAULT;
3041 ret = get_errno(msgctl(msgid, cmd, &dsarg));
3042 if (host_to_target_msqid_ds(ptr,&dsarg))
3043 return -TARGET_EFAULT;
3044 break;
3045 case IPC_RMID:
3046 ret = get_errno(msgctl(msgid, cmd, NULL));
3047 break;
3048 case IPC_INFO:
3049 case MSG_INFO:
3050 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
3051 if (host_to_target_msginfo(ptr, &msginfo))
3052 return -TARGET_EFAULT;
3053 break;
3056 return ret;
3059 struct target_msgbuf {
3060 abi_long mtype;
3061 char mtext[1];
3064 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
3065 ssize_t msgsz, int msgflg)
3067 struct target_msgbuf *target_mb;
3068 struct msgbuf *host_mb;
3069 abi_long ret = 0;
3071 if (msgsz < 0) {
3072 return -TARGET_EINVAL;
3075 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
3076 return -TARGET_EFAULT;
3077 host_mb = g_try_malloc(msgsz + sizeof(long));
3078 if (!host_mb) {
3079 unlock_user_struct(target_mb, msgp, 0);
3080 return -TARGET_ENOMEM;
3082 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
3083 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
3084 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
3085 g_free(host_mb);
3086 unlock_user_struct(target_mb, msgp, 0);
3088 return ret;
3091 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
3092 unsigned int msgsz, abi_long msgtyp,
3093 int msgflg)
3095 struct target_msgbuf *target_mb;
3096 char *target_mtext;
3097 struct msgbuf *host_mb;
3098 abi_long ret = 0;
3100 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
3101 return -TARGET_EFAULT;
3103 host_mb = g_malloc(msgsz+sizeof(long));
3104 ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
3106 if (ret > 0) {
3107 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
3108 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
3109 if (!target_mtext) {
3110 ret = -TARGET_EFAULT;
3111 goto end;
3113 memcpy(target_mb->mtext, host_mb->mtext, ret);
3114 unlock_user(target_mtext, target_mtext_addr, ret);
3117 target_mb->mtype = tswapal(host_mb->mtype);
3119 end:
3120 if (target_mb)
3121 unlock_user_struct(target_mb, msgp, 1);
3122 g_free(host_mb);
3123 return ret;
3126 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
3127 abi_ulong target_addr)
3129 struct target_shmid_ds *target_sd;
3131 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3132 return -TARGET_EFAULT;
3133 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
3134 return -TARGET_EFAULT;
3135 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
3136 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
3137 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
3138 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
3139 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
3140 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
3141 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
3142 unlock_user_struct(target_sd, target_addr, 0);
3143 return 0;
3146 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
3147 struct shmid_ds *host_sd)
3149 struct target_shmid_ds *target_sd;
3151 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3152 return -TARGET_EFAULT;
3153 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
3154 return -TARGET_EFAULT;
3155 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
3156 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
3157 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
3158 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
3159 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
3160 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
3161 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
3162 unlock_user_struct(target_sd, target_addr, 1);
3163 return 0;
3166 struct target_shminfo {
3167 abi_ulong shmmax;
3168 abi_ulong shmmin;
3169 abi_ulong shmmni;
3170 abi_ulong shmseg;
3171 abi_ulong shmall;
3174 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
3175 struct shminfo *host_shminfo)
3177 struct target_shminfo *target_shminfo;
3178 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
3179 return -TARGET_EFAULT;
3180 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
3181 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
3182 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
3183 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
3184 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
3185 unlock_user_struct(target_shminfo, target_addr, 1);
3186 return 0;
3189 struct target_shm_info {
3190 int used_ids;
3191 abi_ulong shm_tot;
3192 abi_ulong shm_rss;
3193 abi_ulong shm_swp;
3194 abi_ulong swap_attempts;
3195 abi_ulong swap_successes;
3198 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
3199 struct shm_info *host_shm_info)
3201 struct target_shm_info *target_shm_info;
3202 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
3203 return -TARGET_EFAULT;
3204 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
3205 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
3206 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
3207 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
3208 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
3209 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
3210 unlock_user_struct(target_shm_info, target_addr, 1);
3211 return 0;
3214 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3216 struct shmid_ds dsarg;
3217 struct shminfo shminfo;
3218 struct shm_info shm_info;
3219 abi_long ret = -TARGET_EINVAL;
3221 cmd &= 0xff;
3223 switch(cmd) {
3224 case IPC_STAT:
3225 case IPC_SET:
3226 case SHM_STAT:
3227 if (target_to_host_shmid_ds(&dsarg, buf))
3228 return -TARGET_EFAULT;
3229 ret = get_errno(shmctl(shmid, cmd, &dsarg));
3230 if (host_to_target_shmid_ds(buf, &dsarg))
3231 return -TARGET_EFAULT;
3232 break;
3233 case IPC_INFO:
3234 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3235 if (host_to_target_shminfo(buf, &shminfo))
3236 return -TARGET_EFAULT;
3237 break;
3238 case SHM_INFO:
3239 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3240 if (host_to_target_shm_info(buf, &shm_info))
3241 return -TARGET_EFAULT;
3242 break;
3243 case IPC_RMID:
3244 case SHM_LOCK:
3245 case SHM_UNLOCK:
3246 ret = get_errno(shmctl(shmid, cmd, NULL));
3247 break;
3250 return ret;
3253 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3255 abi_long raddr;
3256 void *host_raddr;
3257 struct shmid_ds shm_info;
3258 int i,ret;
3260 /* find out the length of the shared memory segment */
3261 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3262 if (is_error(ret)) {
3263 /* can't get length, bail out */
3264 return ret;
3267 mmap_lock();
3269 if (shmaddr)
3270 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3271 else {
3272 abi_ulong mmap_start;
3274 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3276 if (mmap_start == -1) {
3277 errno = ENOMEM;
3278 host_raddr = (void *)-1;
3279 } else
3280 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3283 if (host_raddr == (void *)-1) {
3284 mmap_unlock();
3285 return get_errno((long)host_raddr);
3287 raddr=h2g((unsigned long)host_raddr);
3289 page_set_flags(raddr, raddr + shm_info.shm_segsz,
3290 PAGE_VALID | PAGE_READ |
3291 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3293 for (i = 0; i < N_SHM_REGIONS; i++) {
3294 if (shm_regions[i].start == 0) {
3295 shm_regions[i].start = raddr;
3296 shm_regions[i].size = shm_info.shm_segsz;
3297 break;
3301 mmap_unlock();
3302 return raddr;
3306 static inline abi_long do_shmdt(abi_ulong shmaddr)
3308 int i;
3310 for (i = 0; i < N_SHM_REGIONS; ++i) {
3311 if (shm_regions[i].start == shmaddr) {
3312 shm_regions[i].start = 0;
3313 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3314 break;
3318 return get_errno(shmdt(g2h(shmaddr)));
3321 #ifdef TARGET_NR_ipc
3322 /* ??? This only works with linear mappings. */
3323 /* do_ipc() must return target values and target errnos. */
3324 static abi_long do_ipc(unsigned int call, abi_long first,
3325 abi_long second, abi_long third,
3326 abi_long ptr, abi_long fifth)
3328 int version;
3329 abi_long ret = 0;
3331 version = call >> 16;
3332 call &= 0xffff;
3334 switch (call) {
3335 case IPCOP_semop:
3336 ret = do_semop(first, ptr, second);
3337 break;
3339 case IPCOP_semget:
3340 ret = get_errno(semget(first, second, third));
3341 break;
3343 case IPCOP_semctl: {
3344 /* The semun argument to semctl is passed by value, so dereference the
3345 * ptr argument. */
3346 abi_ulong atptr;
3347 get_user_ual(atptr, ptr);
3348 ret = do_semctl(first, second, third, atptr);
3349 break;
3352 case IPCOP_msgget:
3353 ret = get_errno(msgget(first, second));
3354 break;
3356 case IPCOP_msgsnd:
3357 ret = do_msgsnd(first, ptr, second, third);
3358 break;
3360 case IPCOP_msgctl:
3361 ret = do_msgctl(first, second, ptr);
3362 break;
3364 case IPCOP_msgrcv:
3365 switch (version) {
3366 case 0:
3368 struct target_ipc_kludge {
3369 abi_long msgp;
3370 abi_long msgtyp;
3371 } *tmp;
3373 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3374 ret = -TARGET_EFAULT;
3375 break;
3378 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
3380 unlock_user_struct(tmp, ptr, 0);
3381 break;
3383 default:
3384 ret = do_msgrcv(first, ptr, second, fifth, third);
3386 break;
3388 case IPCOP_shmat:
3389 switch (version) {
3390 default:
3392 abi_ulong raddr;
3393 raddr = do_shmat(first, ptr, second);
3394 if (is_error(raddr))
3395 return get_errno(raddr);
3396 if (put_user_ual(raddr, third))
3397 return -TARGET_EFAULT;
3398 break;
3400 case 1:
3401 ret = -TARGET_EINVAL;
3402 break;
3404 break;
3405 case IPCOP_shmdt:
3406 ret = do_shmdt(ptr);
3407 break;
3409 case IPCOP_shmget:
3410 /* IPC_* flag values are the same on all linux platforms */
3411 ret = get_errno(shmget(first, second, third));
3412 break;
3414 /* IPC_* and SHM_* command values are the same on all linux platforms */
3415 case IPCOP_shmctl:
3416 ret = do_shmctl(first, second, ptr);
3417 break;
3418 default:
3419 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3420 ret = -TARGET_ENOSYS;
3421 break;
3423 return ret;
3425 #endif
3427 /* kernel structure types definitions */
3429 #define STRUCT(name, ...) STRUCT_ ## name,
3430 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
3431 enum {
3432 #include "syscall_types.h"
3433 STRUCT_MAX
3435 #undef STRUCT
3436 #undef STRUCT_SPECIAL
3438 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3439 #define STRUCT_SPECIAL(name)
3440 #include "syscall_types.h"
3441 #undef STRUCT
3442 #undef STRUCT_SPECIAL
3444 typedef struct IOCTLEntry IOCTLEntry;
3446 typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3447 int fd, int cmd, abi_long arg);
3449 struct IOCTLEntry {
3450 int target_cmd;
3451 unsigned int host_cmd;
3452 const char *name;
3453 int access;
3454 do_ioctl_fn *do_ioctl;
3455 const argtype arg_type[5];
3458 #define IOC_R 0x0001
3459 #define IOC_W 0x0002
3460 #define IOC_RW (IOC_R | IOC_W)
3462 #define MAX_STRUCT_SIZE 4096
3464 #ifdef CONFIG_FIEMAP
3465 /* So fiemap access checks don't overflow on 32 bit systems.
3466 * This is very slightly smaller than the limit imposed by
3467 * the underlying kernel.
3469 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3470 / sizeof(struct fiemap_extent))
3472 static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3473 int fd, int cmd, abi_long arg)
3475 /* The parameter for this ioctl is a struct fiemap followed
3476 * by an array of struct fiemap_extent whose size is set
3477 * in fiemap->fm_extent_count. The array is filled in by the
3478 * ioctl.
3480 int target_size_in, target_size_out;
3481 struct fiemap *fm;
3482 const argtype *arg_type = ie->arg_type;
3483 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3484 void *argptr, *p;
3485 abi_long ret;
3486 int i, extent_size = thunk_type_size(extent_arg_type, 0);
3487 uint32_t outbufsz;
3488 int free_fm = 0;
3490 assert(arg_type[0] == TYPE_PTR);
3491 assert(ie->access == IOC_RW);
3492 arg_type++;
3493 target_size_in = thunk_type_size(arg_type, 0);
3494 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3495 if (!argptr) {
3496 return -TARGET_EFAULT;
3498 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3499 unlock_user(argptr, arg, 0);
3500 fm = (struct fiemap *)buf_temp;
3501 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3502 return -TARGET_EINVAL;
3505 outbufsz = sizeof (*fm) +
3506 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3508 if (outbufsz > MAX_STRUCT_SIZE) {
3509 /* We can't fit all the extents into the fixed size buffer.
3510 * Allocate one that is large enough and use it instead.
3512 fm = g_try_malloc(outbufsz);
3513 if (!fm) {
3514 return -TARGET_ENOMEM;
3516 memcpy(fm, buf_temp, sizeof(struct fiemap));
3517 free_fm = 1;
3519 ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3520 if (!is_error(ret)) {
3521 target_size_out = target_size_in;
3522 /* An extent_count of 0 means we were only counting the extents
3523 * so there are no structs to copy
3525 if (fm->fm_extent_count != 0) {
3526 target_size_out += fm->fm_mapped_extents * extent_size;
3528 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3529 if (!argptr) {
3530 ret = -TARGET_EFAULT;
3531 } else {
3532 /* Convert the struct fiemap */
3533 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3534 if (fm->fm_extent_count != 0) {
3535 p = argptr + target_size_in;
3536 /* ...and then all the struct fiemap_extents */
3537 for (i = 0; i < fm->fm_mapped_extents; i++) {
3538 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3539 THUNK_TARGET);
3540 p += extent_size;
3543 unlock_user(argptr, arg, target_size_out);
3546 if (free_fm) {
3547 g_free(fm);
3549 return ret;
3551 #endif
3553 static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3554 int fd, int cmd, abi_long arg)
3556 const argtype *arg_type = ie->arg_type;
3557 int target_size;
3558 void *argptr;
3559 int ret;
3560 struct ifconf *host_ifconf;
3561 uint32_t outbufsz;
3562 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3563 int target_ifreq_size;
3564 int nb_ifreq;
3565 int free_buf = 0;
3566 int i;
3567 int target_ifc_len;
3568 abi_long target_ifc_buf;
3569 int host_ifc_len;
3570 char *host_ifc_buf;
3572 assert(arg_type[0] == TYPE_PTR);
3573 assert(ie->access == IOC_RW);
3575 arg_type++;
3576 target_size = thunk_type_size(arg_type, 0);
3578 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3579 if (!argptr)
3580 return -TARGET_EFAULT;
3581 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3582 unlock_user(argptr, arg, 0);
3584 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3585 target_ifc_len = host_ifconf->ifc_len;
3586 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3588 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3589 nb_ifreq = target_ifc_len / target_ifreq_size;
3590 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3592 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3593 if (outbufsz > MAX_STRUCT_SIZE) {
3594 /* We can't fit all the extents into the fixed size buffer.
3595 * Allocate one that is large enough and use it instead.
3597 host_ifconf = malloc(outbufsz);
3598 if (!host_ifconf) {
3599 return -TARGET_ENOMEM;
3601 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3602 free_buf = 1;
3604 host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3606 host_ifconf->ifc_len = host_ifc_len;
3607 host_ifconf->ifc_buf = host_ifc_buf;
3609 ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3610 if (!is_error(ret)) {
3611 /* convert host ifc_len to target ifc_len */
3613 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3614 target_ifc_len = nb_ifreq * target_ifreq_size;
3615 host_ifconf->ifc_len = target_ifc_len;
3617 /* restore target ifc_buf */
3619 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3621 /* copy struct ifconf to target user */
3623 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3624 if (!argptr)
3625 return -TARGET_EFAULT;
3626 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3627 unlock_user(argptr, arg, target_size);
3629 /* copy ifreq[] to target user */
3631 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3632 for (i = 0; i < nb_ifreq ; i++) {
3633 thunk_convert(argptr + i * target_ifreq_size,
3634 host_ifc_buf + i * sizeof(struct ifreq),
3635 ifreq_arg_type, THUNK_TARGET);
3637 unlock_user(argptr, target_ifc_buf, target_ifc_len);
3640 if (free_buf) {
3641 free(host_ifconf);
3644 return ret;
3647 static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3648 int cmd, abi_long arg)
3650 void *argptr;
3651 struct dm_ioctl *host_dm;
3652 abi_long guest_data;
3653 uint32_t guest_data_size;
3654 int target_size;
3655 const argtype *arg_type = ie->arg_type;
3656 abi_long ret;
3657 void *big_buf = NULL;
3658 char *host_data;
3660 arg_type++;
3661 target_size = thunk_type_size(arg_type, 0);
3662 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3663 if (!argptr) {
3664 ret = -TARGET_EFAULT;
3665 goto out;
3667 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3668 unlock_user(argptr, arg, 0);
3670 /* buf_temp is too small, so fetch things into a bigger buffer */
3671 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3672 memcpy(big_buf, buf_temp, target_size);
3673 buf_temp = big_buf;
3674 host_dm = big_buf;
3676 guest_data = arg + host_dm->data_start;
3677 if ((guest_data - arg) < 0) {
3678 ret = -EINVAL;
3679 goto out;
3681 guest_data_size = host_dm->data_size - host_dm->data_start;
3682 host_data = (char*)host_dm + host_dm->data_start;
3684 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3685 switch (ie->host_cmd) {
3686 case DM_REMOVE_ALL:
3687 case DM_LIST_DEVICES:
3688 case DM_DEV_CREATE:
3689 case DM_DEV_REMOVE:
3690 case DM_DEV_SUSPEND:
3691 case DM_DEV_STATUS:
3692 case DM_DEV_WAIT:
3693 case DM_TABLE_STATUS:
3694 case DM_TABLE_CLEAR:
3695 case DM_TABLE_DEPS:
3696 case DM_LIST_VERSIONS:
3697 /* no input data */
3698 break;
3699 case DM_DEV_RENAME:
3700 case DM_DEV_SET_GEOMETRY:
3701 /* data contains only strings */
3702 memcpy(host_data, argptr, guest_data_size);
3703 break;
3704 case DM_TARGET_MSG:
3705 memcpy(host_data, argptr, guest_data_size);
3706 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3707 break;
3708 case DM_TABLE_LOAD:
3710 void *gspec = argptr;
3711 void *cur_data = host_data;
3712 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3713 int spec_size = thunk_type_size(arg_type, 0);
3714 int i;
3716 for (i = 0; i < host_dm->target_count; i++) {
3717 struct dm_target_spec *spec = cur_data;
3718 uint32_t next;
3719 int slen;
3721 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3722 slen = strlen((char*)gspec + spec_size) + 1;
3723 next = spec->next;
3724 spec->next = sizeof(*spec) + slen;
3725 strcpy((char*)&spec[1], gspec + spec_size);
3726 gspec += next;
3727 cur_data += spec->next;
3729 break;
3731 default:
3732 ret = -TARGET_EINVAL;
3733 unlock_user(argptr, guest_data, 0);
3734 goto out;
3736 unlock_user(argptr, guest_data, 0);
3738 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3739 if (!is_error(ret)) {
3740 guest_data = arg + host_dm->data_start;
3741 guest_data_size = host_dm->data_size - host_dm->data_start;
3742 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3743 switch (ie->host_cmd) {
3744 case DM_REMOVE_ALL:
3745 case DM_DEV_CREATE:
3746 case DM_DEV_REMOVE:
3747 case DM_DEV_RENAME:
3748 case DM_DEV_SUSPEND:
3749 case DM_DEV_STATUS:
3750 case DM_TABLE_LOAD:
3751 case DM_TABLE_CLEAR:
3752 case DM_TARGET_MSG:
3753 case DM_DEV_SET_GEOMETRY:
3754 /* no return data */
3755 break;
3756 case DM_LIST_DEVICES:
3758 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3759 uint32_t remaining_data = guest_data_size;
3760 void *cur_data = argptr;
3761 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3762 int nl_size = 12; /* can't use thunk_size due to alignment */
3764 while (1) {
3765 uint32_t next = nl->next;
3766 if (next) {
3767 nl->next = nl_size + (strlen(nl->name) + 1);
3769 if (remaining_data < nl->next) {
3770 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3771 break;
3773 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3774 strcpy(cur_data + nl_size, nl->name);
3775 cur_data += nl->next;
3776 remaining_data -= nl->next;
3777 if (!next) {
3778 break;
3780 nl = (void*)nl + next;
3782 break;
3784 case DM_DEV_WAIT:
3785 case DM_TABLE_STATUS:
3787 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3788 void *cur_data = argptr;
3789 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3790 int spec_size = thunk_type_size(arg_type, 0);
3791 int i;
3793 for (i = 0; i < host_dm->target_count; i++) {
3794 uint32_t next = spec->next;
3795 int slen = strlen((char*)&spec[1]) + 1;
3796 spec->next = (cur_data - argptr) + spec_size + slen;
3797 if (guest_data_size < spec->next) {
3798 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3799 break;
3801 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3802 strcpy(cur_data + spec_size, (char*)&spec[1]);
3803 cur_data = argptr + spec->next;
3804 spec = (void*)host_dm + host_dm->data_start + next;
3806 break;
3808 case DM_TABLE_DEPS:
3810 void *hdata = (void*)host_dm + host_dm->data_start;
3811 int count = *(uint32_t*)hdata;
3812 uint64_t *hdev = hdata + 8;
3813 uint64_t *gdev = argptr + 8;
3814 int i;
3816 *(uint32_t*)argptr = tswap32(count);
3817 for (i = 0; i < count; i++) {
3818 *gdev = tswap64(*hdev);
3819 gdev++;
3820 hdev++;
3822 break;
3824 case DM_LIST_VERSIONS:
3826 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3827 uint32_t remaining_data = guest_data_size;
3828 void *cur_data = argptr;
3829 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3830 int vers_size = thunk_type_size(arg_type, 0);
3832 while (1) {
3833 uint32_t next = vers->next;
3834 if (next) {
3835 vers->next = vers_size + (strlen(vers->name) + 1);
3837 if (remaining_data < vers->next) {
3838 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3839 break;
3841 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3842 strcpy(cur_data + vers_size, vers->name);
3843 cur_data += vers->next;
3844 remaining_data -= vers->next;
3845 if (!next) {
3846 break;
3848 vers = (void*)vers + next;
3850 break;
3852 default:
3853 unlock_user(argptr, guest_data, 0);
3854 ret = -TARGET_EINVAL;
3855 goto out;
3857 unlock_user(argptr, guest_data, guest_data_size);
3859 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3860 if (!argptr) {
3861 ret = -TARGET_EFAULT;
3862 goto out;
3864 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3865 unlock_user(argptr, arg, target_size);
3867 out:
3868 g_free(big_buf);
3869 return ret;
3872 static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3873 int cmd, abi_long arg)
3875 void *argptr;
3876 int target_size;
3877 const argtype *arg_type = ie->arg_type;
3878 const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
3879 abi_long ret;
3881 struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
3882 struct blkpg_partition host_part;
3884 /* Read and convert blkpg */
3885 arg_type++;
3886 target_size = thunk_type_size(arg_type, 0);
3887 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3888 if (!argptr) {
3889 ret = -TARGET_EFAULT;
3890 goto out;
3892 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3893 unlock_user(argptr, arg, 0);
3895 switch (host_blkpg->op) {
3896 case BLKPG_ADD_PARTITION:
3897 case BLKPG_DEL_PARTITION:
3898 /* payload is struct blkpg_partition */
3899 break;
3900 default:
3901 /* Unknown opcode */
3902 ret = -TARGET_EINVAL;
3903 goto out;
3906 /* Read and convert blkpg->data */
3907 arg = (abi_long)(uintptr_t)host_blkpg->data;
3908 target_size = thunk_type_size(part_arg_type, 0);
3909 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3910 if (!argptr) {
3911 ret = -TARGET_EFAULT;
3912 goto out;
3914 thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
3915 unlock_user(argptr, arg, 0);
3917 /* Swizzle the data pointer to our local copy and call! */
3918 host_blkpg->data = &host_part;
3919 ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));
3921 out:
3922 return ret;
3925 static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
3926 int fd, int cmd, abi_long arg)
3928 const argtype *arg_type = ie->arg_type;
3929 const StructEntry *se;
3930 const argtype *field_types;
3931 const int *dst_offsets, *src_offsets;
3932 int target_size;
3933 void *argptr;
3934 abi_ulong *target_rt_dev_ptr;
3935 unsigned long *host_rt_dev_ptr;
3936 abi_long ret;
3937 int i;
3939 assert(ie->access == IOC_W);
3940 assert(*arg_type == TYPE_PTR);
3941 arg_type++;
3942 assert(*arg_type == TYPE_STRUCT);
3943 target_size = thunk_type_size(arg_type, 0);
3944 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3945 if (!argptr) {
3946 return -TARGET_EFAULT;
3948 arg_type++;
3949 assert(*arg_type == (int)STRUCT_rtentry);
3950 se = struct_entries + *arg_type++;
3951 assert(se->convert[0] == NULL);
3952 /* convert struct here to be able to catch rt_dev string */
3953 field_types = se->field_types;
3954 dst_offsets = se->field_offsets[THUNK_HOST];
3955 src_offsets = se->field_offsets[THUNK_TARGET];
3956 for (i = 0; i < se->nb_fields; i++) {
3957 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
3958 assert(*field_types == TYPE_PTRVOID);
3959 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
3960 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
3961 if (*target_rt_dev_ptr != 0) {
3962 *host_rt_dev_ptr = (unsigned long)lock_user_string(
3963 tswapal(*target_rt_dev_ptr));
3964 if (!*host_rt_dev_ptr) {
3965 unlock_user(argptr, arg, 0);
3966 return -TARGET_EFAULT;
3968 } else {
3969 *host_rt_dev_ptr = 0;
3971 field_types++;
3972 continue;
3974 field_types = thunk_convert(buf_temp + dst_offsets[i],
3975 argptr + src_offsets[i],
3976 field_types, THUNK_HOST);
3978 unlock_user(argptr, arg, 0);
3980 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3981 if (*host_rt_dev_ptr != 0) {
3982 unlock_user((void *)*host_rt_dev_ptr,
3983 *target_rt_dev_ptr, 0);
3985 return ret;
3988 static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
3989 int fd, int cmd, abi_long arg)
3991 int sig = target_to_host_signal(arg);
3992 return get_errno(ioctl(fd, ie->host_cmd, sig));
3995 static IOCTLEntry ioctl_entries[] = {
3996 #define IOCTL(cmd, access, ...) \
3997 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3998 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3999 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
4000 #include "ioctls.h"
4001 { 0, 0, },
4004 /* ??? Implement proper locking for ioctls. */
4005 /* do_ioctl() Must return target values and target errnos. */
4006 static abi_long do_ioctl(int fd, int cmd, abi_long arg)
4008 const IOCTLEntry *ie;
4009 const argtype *arg_type;
4010 abi_long ret;
4011 uint8_t buf_temp[MAX_STRUCT_SIZE];
4012 int target_size;
4013 void *argptr;
4015 ie = ioctl_entries;
4016 for(;;) {
4017 if (ie->target_cmd == 0) {
4018 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
4019 return -TARGET_ENOSYS;
4021 if (ie->target_cmd == cmd)
4022 break;
4023 ie++;
4025 arg_type = ie->arg_type;
4026 #if defined(DEBUG)
4027 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
4028 #endif
4029 if (ie->do_ioctl) {
4030 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
4033 switch(arg_type[0]) {
4034 case TYPE_NULL:
4035 /* no argument */
4036 ret = get_errno(ioctl(fd, ie->host_cmd));
4037 break;
4038 case TYPE_PTRVOID:
4039 case TYPE_INT:
4040 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
4041 break;
4042 case TYPE_PTR:
4043 arg_type++;
4044 target_size = thunk_type_size(arg_type, 0);
4045 switch(ie->access) {
4046 case IOC_R:
4047 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
4048 if (!is_error(ret)) {
4049 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4050 if (!argptr)
4051 return -TARGET_EFAULT;
4052 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
4053 unlock_user(argptr, arg, target_size);
4055 break;
4056 case IOC_W:
4057 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4058 if (!argptr)
4059 return -TARGET_EFAULT;
4060 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4061 unlock_user(argptr, arg, 0);
4062 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
4063 break;
4064 default:
4065 case IOC_RW:
4066 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
4067 if (!argptr)
4068 return -TARGET_EFAULT;
4069 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
4070 unlock_user(argptr, arg, 0);
4071 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
4072 if (!is_error(ret)) {
4073 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
4074 if (!argptr)
4075 return -TARGET_EFAULT;
4076 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
4077 unlock_user(argptr, arg, target_size);
4079 break;
4081 break;
4082 default:
4083 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
4084 (long)cmd, arg_type[0]);
4085 ret = -TARGET_ENOSYS;
4086 break;
4088 return ret;
4091 static const bitmask_transtbl iflag_tbl[] = {
4092 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
4093 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
4094 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
4095 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
4096 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
4097 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
4098 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
4099 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
4100 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
4101 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
4102 { TARGET_IXON, TARGET_IXON, IXON, IXON },
4103 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
4104 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
4105 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
4106 { 0, 0, 0, 0 }
4109 static const bitmask_transtbl oflag_tbl[] = {
4110 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
4111 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
4112 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
4113 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
4114 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
4115 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
4116 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
4117 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
4118 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
4119 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
4120 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
4121 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
4122 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
4123 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
4124 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
4125 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
4126 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
4127 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
4128 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
4129 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
4130 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
4131 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
4132 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
4133 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
4134 { 0, 0, 0, 0 }
4137 static const bitmask_transtbl cflag_tbl[] = {
4138 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
4139 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
4140 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
4141 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
4142 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
4143 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
4144 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
4145 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
4146 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
4147 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
4148 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
4149 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
4150 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
4151 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
4152 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
4153 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
4154 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
4155 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
4156 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
4157 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
4158 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
4159 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
4160 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
4161 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
4162 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
4163 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
4164 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
4165 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
4166 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
4167 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
4168 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
4169 { 0, 0, 0, 0 }
4172 static const bitmask_transtbl lflag_tbl[] = {
4173 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
4174 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
4175 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
4176 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
4177 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
4178 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
4179 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
4180 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
4181 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
4182 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
4183 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
4184 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
4185 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
4186 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
4187 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
4188 { 0, 0, 0, 0 }
4191 static void target_to_host_termios (void *dst, const void *src)
4193 struct host_termios *host = dst;
4194 const struct target_termios *target = src;
4196 host->c_iflag =
4197 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
4198 host->c_oflag =
4199 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
4200 host->c_cflag =
4201 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
4202 host->c_lflag =
4203 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
4204 host->c_line = target->c_line;
4206 memset(host->c_cc, 0, sizeof(host->c_cc));
4207 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
4208 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
4209 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
4210 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
4211 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
4212 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
4213 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
4214 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
4215 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
4216 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
4217 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
4218 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
4219 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
4220 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
4221 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
4222 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
4223 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
4226 static void host_to_target_termios (void *dst, const void *src)
4228 struct target_termios *target = dst;
4229 const struct host_termios *host = src;
4231 target->c_iflag =
4232 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
4233 target->c_oflag =
4234 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
4235 target->c_cflag =
4236 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
4237 target->c_lflag =
4238 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
4239 target->c_line = host->c_line;
4241 memset(target->c_cc, 0, sizeof(target->c_cc));
4242 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
4243 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
4244 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
4245 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
4246 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
4247 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
4248 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
4249 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
4250 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
4251 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
4252 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
4253 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
4254 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
4255 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
4256 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
4257 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
4258 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
4261 static const StructEntry struct_termios_def = {
4262 .convert = { host_to_target_termios, target_to_host_termios },
4263 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
4264 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
4267 static bitmask_transtbl mmap_flags_tbl[] = {
4268 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
4269 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
4270 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
4271 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
4272 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
4273 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
4274 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
4275 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
4276 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, MAP_NORESERVE,
4277 MAP_NORESERVE },
4278 { 0, 0, 0, 0 }
4281 #if defined(TARGET_I386)
4283 /* NOTE: there is really one LDT for all the threads */
4284 static uint8_t *ldt_table;
4286 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
4288 int size;
4289 void *p;
4291 if (!ldt_table)
4292 return 0;
4293 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
4294 if (size > bytecount)
4295 size = bytecount;
4296 p = lock_user(VERIFY_WRITE, ptr, size, 0);
4297 if (!p)
4298 return -TARGET_EFAULT;
4299 /* ??? Should this by byteswapped? */
4300 memcpy(p, ldt_table, size);
4301 unlock_user(p, ptr, size);
4302 return size;
4305 /* XXX: add locking support */
4306 static abi_long write_ldt(CPUX86State *env,
4307 abi_ulong ptr, unsigned long bytecount, int oldmode)
4309 struct target_modify_ldt_ldt_s ldt_info;
4310 struct target_modify_ldt_ldt_s *target_ldt_info;
4311 int seg_32bit, contents, read_exec_only, limit_in_pages;
4312 int seg_not_present, useable, lm;
4313 uint32_t *lp, entry_1, entry_2;
4315 if (bytecount != sizeof(ldt_info))
4316 return -TARGET_EINVAL;
4317 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
4318 return -TARGET_EFAULT;
4319 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4320 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4321 ldt_info.limit = tswap32(target_ldt_info->limit);
4322 ldt_info.flags = tswap32(target_ldt_info->flags);
4323 unlock_user_struct(target_ldt_info, ptr, 0);
4325 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
4326 return -TARGET_EINVAL;
4327 seg_32bit = ldt_info.flags & 1;
4328 contents = (ldt_info.flags >> 1) & 3;
4329 read_exec_only = (ldt_info.flags >> 3) & 1;
4330 limit_in_pages = (ldt_info.flags >> 4) & 1;
4331 seg_not_present = (ldt_info.flags >> 5) & 1;
4332 useable = (ldt_info.flags >> 6) & 1;
4333 #ifdef TARGET_ABI32
4334 lm = 0;
4335 #else
4336 lm = (ldt_info.flags >> 7) & 1;
4337 #endif
4338 if (contents == 3) {
4339 if (oldmode)
4340 return -TARGET_EINVAL;
4341 if (seg_not_present == 0)
4342 return -TARGET_EINVAL;
4344 /* allocate the LDT */
4345 if (!ldt_table) {
4346 env->ldt.base = target_mmap(0,
4347 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
4348 PROT_READ|PROT_WRITE,
4349 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4350 if (env->ldt.base == -1)
4351 return -TARGET_ENOMEM;
4352 memset(g2h(env->ldt.base), 0,
4353 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
4354 env->ldt.limit = 0xffff;
4355 ldt_table = g2h(env->ldt.base);
4358 /* NOTE: same code as Linux kernel */
4359 /* Allow LDTs to be cleared by the user. */
4360 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4361 if (oldmode ||
4362 (contents == 0 &&
4363 read_exec_only == 1 &&
4364 seg_32bit == 0 &&
4365 limit_in_pages == 0 &&
4366 seg_not_present == 1 &&
4367 useable == 0 )) {
4368 entry_1 = 0;
4369 entry_2 = 0;
4370 goto install;
4374 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4375 (ldt_info.limit & 0x0ffff);
4376 entry_2 = (ldt_info.base_addr & 0xff000000) |
4377 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4378 (ldt_info.limit & 0xf0000) |
4379 ((read_exec_only ^ 1) << 9) |
4380 (contents << 10) |
4381 ((seg_not_present ^ 1) << 15) |
4382 (seg_32bit << 22) |
4383 (limit_in_pages << 23) |
4384 (lm << 21) |
4385 0x7000;
4386 if (!oldmode)
4387 entry_2 |= (useable << 20);
4389 /* Install the new entry ... */
4390 install:
4391 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4392 lp[0] = tswap32(entry_1);
4393 lp[1] = tswap32(entry_2);
4394 return 0;
4397 /* specific and weird i386 syscalls */
4398 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4399 unsigned long bytecount)
4401 abi_long ret;
4403 switch (func) {
4404 case 0:
4405 ret = read_ldt(ptr, bytecount);
4406 break;
4407 case 1:
4408 ret = write_ldt(env, ptr, bytecount, 1);
4409 break;
4410 case 0x11:
4411 ret = write_ldt(env, ptr, bytecount, 0);
4412 break;
4413 default:
4414 ret = -TARGET_ENOSYS;
4415 break;
4417 return ret;
4420 #if defined(TARGET_I386) && defined(TARGET_ABI32)
4421 abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4423 uint64_t *gdt_table = g2h(env->gdt.base);
4424 struct target_modify_ldt_ldt_s ldt_info;
4425 struct target_modify_ldt_ldt_s *target_ldt_info;
4426 int seg_32bit, contents, read_exec_only, limit_in_pages;
4427 int seg_not_present, useable, lm;
4428 uint32_t *lp, entry_1, entry_2;
4429 int i;
4431 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4432 if (!target_ldt_info)
4433 return -TARGET_EFAULT;
4434 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4435 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4436 ldt_info.limit = tswap32(target_ldt_info->limit);
4437 ldt_info.flags = tswap32(target_ldt_info->flags);
4438 if (ldt_info.entry_number == -1) {
4439 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4440 if (gdt_table[i] == 0) {
4441 ldt_info.entry_number = i;
4442 target_ldt_info->entry_number = tswap32(i);
4443 break;
4447 unlock_user_struct(target_ldt_info, ptr, 1);
4449 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
4450 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4451 return -TARGET_EINVAL;
4452 seg_32bit = ldt_info.flags & 1;
4453 contents = (ldt_info.flags >> 1) & 3;
4454 read_exec_only = (ldt_info.flags >> 3) & 1;
4455 limit_in_pages = (ldt_info.flags >> 4) & 1;
4456 seg_not_present = (ldt_info.flags >> 5) & 1;
4457 useable = (ldt_info.flags >> 6) & 1;
4458 #ifdef TARGET_ABI32
4459 lm = 0;
4460 #else
4461 lm = (ldt_info.flags >> 7) & 1;
4462 #endif
4464 if (contents == 3) {
4465 if (seg_not_present == 0)
4466 return -TARGET_EINVAL;
4469 /* NOTE: same code as Linux kernel */
4470 /* Allow LDTs to be cleared by the user. */
4471 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4472 if ((contents == 0 &&
4473 read_exec_only == 1 &&
4474 seg_32bit == 0 &&
4475 limit_in_pages == 0 &&
4476 seg_not_present == 1 &&
4477 useable == 0 )) {
4478 entry_1 = 0;
4479 entry_2 = 0;
4480 goto install;
4484 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4485 (ldt_info.limit & 0x0ffff);
4486 entry_2 = (ldt_info.base_addr & 0xff000000) |
4487 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4488 (ldt_info.limit & 0xf0000) |
4489 ((read_exec_only ^ 1) << 9) |
4490 (contents << 10) |
4491 ((seg_not_present ^ 1) << 15) |
4492 (seg_32bit << 22) |
4493 (limit_in_pages << 23) |
4494 (useable << 20) |
4495 (lm << 21) |
4496 0x7000;
4498 /* Install the new entry ... */
4499 install:
4500 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4501 lp[0] = tswap32(entry_1);
4502 lp[1] = tswap32(entry_2);
4503 return 0;
4506 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4508 struct target_modify_ldt_ldt_s *target_ldt_info;
4509 uint64_t *gdt_table = g2h(env->gdt.base);
4510 uint32_t base_addr, limit, flags;
4511 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4512 int seg_not_present, useable, lm;
4513 uint32_t *lp, entry_1, entry_2;
4515 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4516 if (!target_ldt_info)
4517 return -TARGET_EFAULT;
4518 idx = tswap32(target_ldt_info->entry_number);
4519 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4520 idx > TARGET_GDT_ENTRY_TLS_MAX) {
4521 unlock_user_struct(target_ldt_info, ptr, 1);
4522 return -TARGET_EINVAL;
4524 lp = (uint32_t *)(gdt_table + idx);
4525 entry_1 = tswap32(lp[0]);
4526 entry_2 = tswap32(lp[1]);
4528 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4529 contents = (entry_2 >> 10) & 3;
4530 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4531 seg_32bit = (entry_2 >> 22) & 1;
4532 limit_in_pages = (entry_2 >> 23) & 1;
4533 useable = (entry_2 >> 20) & 1;
4534 #ifdef TARGET_ABI32
4535 lm = 0;
4536 #else
4537 lm = (entry_2 >> 21) & 1;
4538 #endif
4539 flags = (seg_32bit << 0) | (contents << 1) |
4540 (read_exec_only << 3) | (limit_in_pages << 4) |
4541 (seg_not_present << 5) | (useable << 6) | (lm << 7);
4542 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
4543 base_addr = (entry_1 >> 16) |
4544 (entry_2 & 0xff000000) |
4545 ((entry_2 & 0xff) << 16);
4546 target_ldt_info->base_addr = tswapal(base_addr);
4547 target_ldt_info->limit = tswap32(limit);
4548 target_ldt_info->flags = tswap32(flags);
4549 unlock_user_struct(target_ldt_info, ptr, 1);
4550 return 0;
4552 #endif /* TARGET_I386 && TARGET_ABI32 */
4554 #ifndef TARGET_ABI32
4555 abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4557 abi_long ret = 0;
4558 abi_ulong val;
4559 int idx;
4561 switch(code) {
4562 case TARGET_ARCH_SET_GS:
4563 case TARGET_ARCH_SET_FS:
4564 if (code == TARGET_ARCH_SET_GS)
4565 idx = R_GS;
4566 else
4567 idx = R_FS;
4568 cpu_x86_load_seg(env, idx, 0);
4569 env->segs[idx].base = addr;
4570 break;
4571 case TARGET_ARCH_GET_GS:
4572 case TARGET_ARCH_GET_FS:
4573 if (code == TARGET_ARCH_GET_GS)
4574 idx = R_GS;
4575 else
4576 idx = R_FS;
4577 val = env->segs[idx].base;
4578 if (put_user(val, addr, abi_ulong))
4579 ret = -TARGET_EFAULT;
4580 break;
4581 default:
4582 ret = -TARGET_EINVAL;
4583 break;
4585 return ret;
4587 #endif
4589 #endif /* defined(TARGET_I386) */
4591 #define NEW_STACK_SIZE 0x40000
4594 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4595 typedef struct {
4596 CPUArchState *env;
4597 pthread_mutex_t mutex;
4598 pthread_cond_t cond;
4599 pthread_t thread;
4600 uint32_t tid;
4601 abi_ulong child_tidptr;
4602 abi_ulong parent_tidptr;
4603 sigset_t sigmask;
4604 } new_thread_info;
4606 static void *clone_func(void *arg)
4608 new_thread_info *info = arg;
4609 CPUArchState *env;
4610 CPUState *cpu;
4611 TaskState *ts;
4613 rcu_register_thread();
4614 env = info->env;
4615 cpu = ENV_GET_CPU(env);
4616 thread_cpu = cpu;
4617 ts = (TaskState *)cpu->opaque;
4618 info->tid = gettid();
4619 cpu->host_tid = info->tid;
4620 task_settid(ts);
4621 if (info->child_tidptr)
4622 put_user_u32(info->tid, info->child_tidptr);
4623 if (info->parent_tidptr)
4624 put_user_u32(info->tid, info->parent_tidptr);
4625 /* Enable signals. */
4626 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4627 /* Signal to the parent that we're ready. */
4628 pthread_mutex_lock(&info->mutex);
4629 pthread_cond_broadcast(&info->cond);
4630 pthread_mutex_unlock(&info->mutex);
4631 /* Wait until the parent has finshed initializing the tls state. */
4632 pthread_mutex_lock(&clone_lock);
4633 pthread_mutex_unlock(&clone_lock);
4634 cpu_loop(env);
4635 /* never exits */
4636 return NULL;
4639 /* do_fork() Must return host values and target errnos (unlike most
4640 do_*() functions). */
4641 static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4642 abi_ulong parent_tidptr, target_ulong newtls,
4643 abi_ulong child_tidptr)
4645 CPUState *cpu = ENV_GET_CPU(env);
4646 int ret;
4647 TaskState *ts;
4648 CPUState *new_cpu;
4649 CPUArchState *new_env;
4650 unsigned int nptl_flags;
4651 sigset_t sigmask;
4653 /* Emulate vfork() with fork() */
4654 if (flags & CLONE_VFORK)
4655 flags &= ~(CLONE_VFORK | CLONE_VM);
4657 if (flags & CLONE_VM) {
4658 TaskState *parent_ts = (TaskState *)cpu->opaque;
4659 new_thread_info info;
4660 pthread_attr_t attr;
4662 ts = g_new0(TaskState, 1);
4663 init_task_state(ts);
4664 /* we create a new CPU instance. */
4665 new_env = cpu_copy(env);
4666 /* Init regs that differ from the parent. */
4667 cpu_clone_regs(new_env, newsp);
4668 new_cpu = ENV_GET_CPU(new_env);
4669 new_cpu->opaque = ts;
4670 ts->bprm = parent_ts->bprm;
4671 ts->info = parent_ts->info;
4672 nptl_flags = flags;
4673 flags &= ~CLONE_NPTL_FLAGS2;
4675 if (nptl_flags & CLONE_CHILD_CLEARTID) {
4676 ts->child_tidptr = child_tidptr;
4679 if (nptl_flags & CLONE_SETTLS)
4680 cpu_set_tls (new_env, newtls);
4682 /* Grab a mutex so that thread setup appears atomic. */
4683 pthread_mutex_lock(&clone_lock);
4685 memset(&info, 0, sizeof(info));
4686 pthread_mutex_init(&info.mutex, NULL);
4687 pthread_mutex_lock(&info.mutex);
4688 pthread_cond_init(&info.cond, NULL);
4689 info.env = new_env;
4690 if (nptl_flags & CLONE_CHILD_SETTID)
4691 info.child_tidptr = child_tidptr;
4692 if (nptl_flags & CLONE_PARENT_SETTID)
4693 info.parent_tidptr = parent_tidptr;
4695 ret = pthread_attr_init(&attr);
4696 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4697 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4698 /* It is not safe to deliver signals until the child has finished
4699 initializing, so temporarily block all signals. */
4700 sigfillset(&sigmask);
4701 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4703 ret = pthread_create(&info.thread, &attr, clone_func, &info);
4704 /* TODO: Free new CPU state if thread creation failed. */
4706 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4707 pthread_attr_destroy(&attr);
4708 if (ret == 0) {
4709 /* Wait for the child to initialize. */
4710 pthread_cond_wait(&info.cond, &info.mutex);
4711 ret = info.tid;
4712 if (flags & CLONE_PARENT_SETTID)
4713 put_user_u32(ret, parent_tidptr);
4714 } else {
4715 ret = -1;
4717 pthread_mutex_unlock(&info.mutex);
4718 pthread_cond_destroy(&info.cond);
4719 pthread_mutex_destroy(&info.mutex);
4720 pthread_mutex_unlock(&clone_lock);
4721 } else {
4722 /* if no CLONE_VM, we consider it is a fork */
4723 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
4724 return -TARGET_EINVAL;
4726 fork_start();
4727 ret = fork();
4728 if (ret == 0) {
4729 /* Child Process. */
4730 rcu_after_fork();
4731 cpu_clone_regs(env, newsp);
4732 fork_end(1);
4733 /* There is a race condition here. The parent process could
4734 theoretically read the TID in the child process before the child
4735 tid is set. This would require using either ptrace
4736 (not implemented) or having *_tidptr to point at a shared memory
4737 mapping. We can't repeat the spinlock hack used above because
4738 the child process gets its own copy of the lock. */
4739 if (flags & CLONE_CHILD_SETTID)
4740 put_user_u32(gettid(), child_tidptr);
4741 if (flags & CLONE_PARENT_SETTID)
4742 put_user_u32(gettid(), parent_tidptr);
4743 ts = (TaskState *)cpu->opaque;
4744 if (flags & CLONE_SETTLS)
4745 cpu_set_tls (env, newtls);
4746 if (flags & CLONE_CHILD_CLEARTID)
4747 ts->child_tidptr = child_tidptr;
4748 } else {
4749 fork_end(0);
4752 return ret;
4755 /* warning : doesn't handle linux specific flags... */
4756 static int target_to_host_fcntl_cmd(int cmd)
4758 switch(cmd) {
4759 case TARGET_F_DUPFD:
4760 case TARGET_F_GETFD:
4761 case TARGET_F_SETFD:
4762 case TARGET_F_GETFL:
4763 case TARGET_F_SETFL:
4764 return cmd;
4765 case TARGET_F_GETLK:
4766 return F_GETLK;
4767 case TARGET_F_SETLK:
4768 return F_SETLK;
4769 case TARGET_F_SETLKW:
4770 return F_SETLKW;
4771 case TARGET_F_GETOWN:
4772 return F_GETOWN;
4773 case TARGET_F_SETOWN:
4774 return F_SETOWN;
4775 case TARGET_F_GETSIG:
4776 return F_GETSIG;
4777 case TARGET_F_SETSIG:
4778 return F_SETSIG;
4779 #if TARGET_ABI_BITS == 32
4780 case TARGET_F_GETLK64:
4781 return F_GETLK64;
4782 case TARGET_F_SETLK64:
4783 return F_SETLK64;
4784 case TARGET_F_SETLKW64:
4785 return F_SETLKW64;
4786 #endif
4787 case TARGET_F_SETLEASE:
4788 return F_SETLEASE;
4789 case TARGET_F_GETLEASE:
4790 return F_GETLEASE;
4791 #ifdef F_DUPFD_CLOEXEC
4792 case TARGET_F_DUPFD_CLOEXEC:
4793 return F_DUPFD_CLOEXEC;
4794 #endif
4795 case TARGET_F_NOTIFY:
4796 return F_NOTIFY;
4797 #ifdef F_GETOWN_EX
4798 case TARGET_F_GETOWN_EX:
4799 return F_GETOWN_EX;
4800 #endif
4801 #ifdef F_SETOWN_EX
4802 case TARGET_F_SETOWN_EX:
4803 return F_SETOWN_EX;
4804 #endif
4805 default:
4806 return -TARGET_EINVAL;
4808 return -TARGET_EINVAL;
4811 #define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4812 static const bitmask_transtbl flock_tbl[] = {
4813 TRANSTBL_CONVERT(F_RDLCK),
4814 TRANSTBL_CONVERT(F_WRLCK),
4815 TRANSTBL_CONVERT(F_UNLCK),
4816 TRANSTBL_CONVERT(F_EXLCK),
4817 TRANSTBL_CONVERT(F_SHLCK),
4818 { 0, 0, 0, 0 }
4821 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4823 struct flock fl;
4824 struct target_flock *target_fl;
4825 struct flock64 fl64;
4826 struct target_flock64 *target_fl64;
4827 #ifdef F_GETOWN_EX
4828 struct f_owner_ex fox;
4829 struct target_f_owner_ex *target_fox;
4830 #endif
4831 abi_long ret;
4832 int host_cmd = target_to_host_fcntl_cmd(cmd);
4834 if (host_cmd == -TARGET_EINVAL)
4835 return host_cmd;
4837 switch(cmd) {
4838 case TARGET_F_GETLK:
4839 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4840 return -TARGET_EFAULT;
4841 fl.l_type =
4842 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4843 fl.l_whence = tswap16(target_fl->l_whence);
4844 fl.l_start = tswapal(target_fl->l_start);
4845 fl.l_len = tswapal(target_fl->l_len);
4846 fl.l_pid = tswap32(target_fl->l_pid);
4847 unlock_user_struct(target_fl, arg, 0);
4848 ret = get_errno(fcntl(fd, host_cmd, &fl));
4849 if (ret == 0) {
4850 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4851 return -TARGET_EFAULT;
4852 target_fl->l_type =
4853 host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
4854 target_fl->l_whence = tswap16(fl.l_whence);
4855 target_fl->l_start = tswapal(fl.l_start);
4856 target_fl->l_len = tswapal(fl.l_len);
4857 target_fl->l_pid = tswap32(fl.l_pid);
4858 unlock_user_struct(target_fl, arg, 1);
4860 break;
4862 case TARGET_F_SETLK:
4863 case TARGET_F_SETLKW:
4864 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4865 return -TARGET_EFAULT;
4866 fl.l_type =
4867 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4868 fl.l_whence = tswap16(target_fl->l_whence);
4869 fl.l_start = tswapal(target_fl->l_start);
4870 fl.l_len = tswapal(target_fl->l_len);
4871 fl.l_pid = tswap32(target_fl->l_pid);
4872 unlock_user_struct(target_fl, arg, 0);
4873 ret = get_errno(fcntl(fd, host_cmd, &fl));
4874 break;
4876 case TARGET_F_GETLK64:
4877 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4878 return -TARGET_EFAULT;
4879 fl64.l_type =
4880 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4881 fl64.l_whence = tswap16(target_fl64->l_whence);
4882 fl64.l_start = tswap64(target_fl64->l_start);
4883 fl64.l_len = tswap64(target_fl64->l_len);
4884 fl64.l_pid = tswap32(target_fl64->l_pid);
4885 unlock_user_struct(target_fl64, arg, 0);
4886 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4887 if (ret == 0) {
4888 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4889 return -TARGET_EFAULT;
4890 target_fl64->l_type =
4891 host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
4892 target_fl64->l_whence = tswap16(fl64.l_whence);
4893 target_fl64->l_start = tswap64(fl64.l_start);
4894 target_fl64->l_len = tswap64(fl64.l_len);
4895 target_fl64->l_pid = tswap32(fl64.l_pid);
4896 unlock_user_struct(target_fl64, arg, 1);
4898 break;
4899 case TARGET_F_SETLK64:
4900 case TARGET_F_SETLKW64:
4901 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4902 return -TARGET_EFAULT;
4903 fl64.l_type =
4904 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4905 fl64.l_whence = tswap16(target_fl64->l_whence);
4906 fl64.l_start = tswap64(target_fl64->l_start);
4907 fl64.l_len = tswap64(target_fl64->l_len);
4908 fl64.l_pid = tswap32(target_fl64->l_pid);
4909 unlock_user_struct(target_fl64, arg, 0);
4910 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4911 break;
4913 case TARGET_F_GETFL:
4914 ret = get_errno(fcntl(fd, host_cmd, arg));
4915 if (ret >= 0) {
4916 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4918 break;
4920 case TARGET_F_SETFL:
4921 ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4922 break;
4924 #ifdef F_GETOWN_EX
4925 case TARGET_F_GETOWN_EX:
4926 ret = get_errno(fcntl(fd, host_cmd, &fox));
4927 if (ret >= 0) {
4928 if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
4929 return -TARGET_EFAULT;
4930 target_fox->type = tswap32(fox.type);
4931 target_fox->pid = tswap32(fox.pid);
4932 unlock_user_struct(target_fox, arg, 1);
4934 break;
4935 #endif
4937 #ifdef F_SETOWN_EX
4938 case TARGET_F_SETOWN_EX:
4939 if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1))
4940 return -TARGET_EFAULT;
4941 fox.type = tswap32(target_fox->type);
4942 fox.pid = tswap32(target_fox->pid);
4943 unlock_user_struct(target_fox, arg, 0);
4944 ret = get_errno(fcntl(fd, host_cmd, &fox));
4945 break;
4946 #endif
4948 case TARGET_F_SETOWN:
4949 case TARGET_F_GETOWN:
4950 case TARGET_F_SETSIG:
4951 case TARGET_F_GETSIG:
4952 case TARGET_F_SETLEASE:
4953 case TARGET_F_GETLEASE:
4954 ret = get_errno(fcntl(fd, host_cmd, arg));
4955 break;
4957 default:
4958 ret = get_errno(fcntl(fd, cmd, arg));
4959 break;
4961 return ret;
4964 #ifdef USE_UID16
4966 static inline int high2lowuid(int uid)
4968 if (uid > 65535)
4969 return 65534;
4970 else
4971 return uid;
4974 static inline int high2lowgid(int gid)
4976 if (gid > 65535)
4977 return 65534;
4978 else
4979 return gid;
4982 static inline int low2highuid(int uid)
4984 if ((int16_t)uid == -1)
4985 return -1;
4986 else
4987 return uid;
4990 static inline int low2highgid(int gid)
4992 if ((int16_t)gid == -1)
4993 return -1;
4994 else
4995 return gid;
4997 static inline int tswapid(int id)
4999 return tswap16(id);
5002 #define put_user_id(x, gaddr) put_user_u16(x, gaddr)
5004 #else /* !USE_UID16 */
5005 static inline int high2lowuid(int uid)
5007 return uid;
5009 static inline int high2lowgid(int gid)
5011 return gid;
5013 static inline int low2highuid(int uid)
5015 return uid;
5017 static inline int low2highgid(int gid)
5019 return gid;
5021 static inline int tswapid(int id)
5023 return tswap32(id);
5026 #define put_user_id(x, gaddr) put_user_u32(x, gaddr)
5028 #endif /* USE_UID16 */
5030 void syscall_init(void)
5032 IOCTLEntry *ie;
5033 const argtype *arg_type;
5034 int size;
5035 int i;
5037 thunk_init(STRUCT_MAX);
5039 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
5040 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
5041 #include "syscall_types.h"
5042 #undef STRUCT
5043 #undef STRUCT_SPECIAL
5045 /* Build target_to_host_errno_table[] table from
5046 * host_to_target_errno_table[]. */
5047 for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
5048 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
5051 /* we patch the ioctl size if necessary. We rely on the fact that
5052 no ioctl has all the bits at '1' in the size field */
5053 ie = ioctl_entries;
5054 while (ie->target_cmd != 0) {
5055 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
5056 TARGET_IOC_SIZEMASK) {
5057 arg_type = ie->arg_type;
5058 if (arg_type[0] != TYPE_PTR) {
5059 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
5060 ie->target_cmd);
5061 exit(1);
5063 arg_type++;
5064 size = thunk_type_size(arg_type, 0);
5065 ie->target_cmd = (ie->target_cmd &
5066 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
5067 (size << TARGET_IOC_SIZESHIFT);
5070 /* automatic consistency check if same arch */
5071 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
5072 (defined(__x86_64__) && defined(TARGET_X86_64))
5073 if (unlikely(ie->target_cmd != ie->host_cmd)) {
5074 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
5075 ie->name, ie->target_cmd, ie->host_cmd);
5077 #endif
5078 ie++;
5082 #if TARGET_ABI_BITS == 32
5083 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
5085 #ifdef TARGET_WORDS_BIGENDIAN
5086 return ((uint64_t)word0 << 32) | word1;
5087 #else
5088 return ((uint64_t)word1 << 32) | word0;
5089 #endif
5091 #else /* TARGET_ABI_BITS == 32 */
5092 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
5094 return word0;
5096 #endif /* TARGET_ABI_BITS != 32 */
5098 #ifdef TARGET_NR_truncate64
5099 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
5100 abi_long arg2,
5101 abi_long arg3,
5102 abi_long arg4)
5104 if (regpairs_aligned(cpu_env)) {
5105 arg2 = arg3;
5106 arg3 = arg4;
5108 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
5110 #endif
5112 #ifdef TARGET_NR_ftruncate64
5113 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
5114 abi_long arg2,
5115 abi_long arg3,
5116 abi_long arg4)
5118 if (regpairs_aligned(cpu_env)) {
5119 arg2 = arg3;
5120 arg3 = arg4;
5122 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
5124 #endif
5126 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
5127 abi_ulong target_addr)
5129 struct target_timespec *target_ts;
5131 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
5132 return -TARGET_EFAULT;
5133 host_ts->tv_sec = tswapal(target_ts->tv_sec);
5134 host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
5135 unlock_user_struct(target_ts, target_addr, 0);
5136 return 0;
5139 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
5140 struct timespec *host_ts)
5142 struct target_timespec *target_ts;
5144 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
5145 return -TARGET_EFAULT;
5146 target_ts->tv_sec = tswapal(host_ts->tv_sec);
5147 target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
5148 unlock_user_struct(target_ts, target_addr, 1);
5149 return 0;
5152 static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec,
5153 abi_ulong target_addr)
5155 struct target_itimerspec *target_itspec;
5157 if (!lock_user_struct(VERIFY_READ, target_itspec, target_addr, 1)) {
5158 return -TARGET_EFAULT;
5161 host_itspec->it_interval.tv_sec =
5162 tswapal(target_itspec->it_interval.tv_sec);
5163 host_itspec->it_interval.tv_nsec =
5164 tswapal(target_itspec->it_interval.tv_nsec);
5165 host_itspec->it_value.tv_sec = tswapal(target_itspec->it_value.tv_sec);
5166 host_itspec->it_value.tv_nsec = tswapal(target_itspec->it_value.tv_nsec);
5168 unlock_user_struct(target_itspec, target_addr, 1);
5169 return 0;
5172 static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
5173 struct itimerspec *host_its)
5175 struct target_itimerspec *target_itspec;
5177 if (!lock_user_struct(VERIFY_WRITE, target_itspec, target_addr, 0)) {
5178 return -TARGET_EFAULT;
5181 target_itspec->it_interval.tv_sec = tswapal(host_its->it_interval.tv_sec);
5182 target_itspec->it_interval.tv_nsec = tswapal(host_its->it_interval.tv_nsec);
5184 target_itspec->it_value.tv_sec = tswapal(host_its->it_value.tv_sec);
5185 target_itspec->it_value.tv_nsec = tswapal(host_its->it_value.tv_nsec);
5187 unlock_user_struct(target_itspec, target_addr, 0);
5188 return 0;
5191 static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
5192 abi_ulong target_addr)
5194 struct target_sigevent *target_sevp;
5196 if (!lock_user_struct(VERIFY_READ, target_sevp, target_addr, 1)) {
5197 return -TARGET_EFAULT;
5200 /* This union is awkward on 64 bit systems because it has a 32 bit
5201 * integer and a pointer in it; we follow the conversion approach
5202 * used for handling sigval types in signal.c so the guest should get
5203 * the correct value back even if we did a 64 bit byteswap and it's
5204 * using the 32 bit integer.
5206 host_sevp->sigev_value.sival_ptr =
5207 (void *)(uintptr_t)tswapal(target_sevp->sigev_value.sival_ptr);
5208 host_sevp->sigev_signo =
5209 target_to_host_signal(tswap32(target_sevp->sigev_signo));
5210 host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
5211 host_sevp->_sigev_un._tid = tswap32(target_sevp->_sigev_un._tid);
5213 unlock_user_struct(target_sevp, target_addr, 1);
5214 return 0;
5217 #if defined(TARGET_NR_mlockall)
5218 static inline int target_to_host_mlockall_arg(int arg)
5220 int result = 0;
5222 if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
5223 result |= MCL_CURRENT;
5225 if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
5226 result |= MCL_FUTURE;
5228 return result;
5230 #endif
5232 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
5233 static inline abi_long host_to_target_stat64(void *cpu_env,
5234 abi_ulong target_addr,
5235 struct stat *host_st)
5237 #if defined(TARGET_ARM) && defined(TARGET_ABI32)
5238 if (((CPUARMState *)cpu_env)->eabi) {
5239 struct target_eabi_stat64 *target_st;
5241 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
5242 return -TARGET_EFAULT;
5243 memset(target_st, 0, sizeof(struct target_eabi_stat64));
5244 __put_user(host_st->st_dev, &target_st->st_dev);
5245 __put_user(host_st->st_ino, &target_st->st_ino);
5246 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5247 __put_user(host_st->st_ino, &target_st->__st_ino);
5248 #endif
5249 __put_user(host_st->st_mode, &target_st->st_mode);
5250 __put_user(host_st->st_nlink, &target_st->st_nlink);
5251 __put_user(host_st->st_uid, &target_st->st_uid);
5252 __put_user(host_st->st_gid, &target_st->st_gid);
5253 __put_user(host_st->st_rdev, &target_st->st_rdev);
5254 __put_user(host_st->st_size, &target_st->st_size);
5255 __put_user(host_st->st_blksize, &target_st->st_blksize);
5256 __put_user(host_st->st_blocks, &target_st->st_blocks);
5257 __put_user(host_st->st_atime, &target_st->target_st_atime);
5258 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
5259 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5260 unlock_user_struct(target_st, target_addr, 1);
5261 } else
5262 #endif
5264 #if defined(TARGET_HAS_STRUCT_STAT64)
5265 struct target_stat64 *target_st;
5266 #else
5267 struct target_stat *target_st;
5268 #endif
5270 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
5271 return -TARGET_EFAULT;
5272 memset(target_st, 0, sizeof(*target_st));
5273 __put_user(host_st->st_dev, &target_st->st_dev);
5274 __put_user(host_st->st_ino, &target_st->st_ino);
5275 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5276 __put_user(host_st->st_ino, &target_st->__st_ino);
5277 #endif
5278 __put_user(host_st->st_mode, &target_st->st_mode);
5279 __put_user(host_st->st_nlink, &target_st->st_nlink);
5280 __put_user(host_st->st_uid, &target_st->st_uid);
5281 __put_user(host_st->st_gid, &target_st->st_gid);
5282 __put_user(host_st->st_rdev, &target_st->st_rdev);
5283 /* XXX: better use of kernel struct */
5284 __put_user(host_st->st_size, &target_st->st_size);
5285 __put_user(host_st->st_blksize, &target_st->st_blksize);
5286 __put_user(host_st->st_blocks, &target_st->st_blocks);
5287 __put_user(host_st->st_atime, &target_st->target_st_atime);
5288 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
5289 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5290 unlock_user_struct(target_st, target_addr, 1);
5293 return 0;
5295 #endif
5297 /* ??? Using host futex calls even when target atomic operations
5298 are not really atomic probably breaks things. However implementing
5299 futexes locally would make futexes shared between multiple processes
5300 tricky. However they're probably useless because guest atomic
5301 operations won't work either. */
5302 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
5303 target_ulong uaddr2, int val3)
5305 struct timespec ts, *pts;
5306 int base_op;
5308 /* ??? We assume FUTEX_* constants are the same on both host
5309 and target. */
5310 #ifdef FUTEX_CMD_MASK
5311 base_op = op & FUTEX_CMD_MASK;
5312 #else
5313 base_op = op;
5314 #endif
5315 switch (base_op) {
5316 case FUTEX_WAIT:
5317 case FUTEX_WAIT_BITSET:
5318 if (timeout) {
5319 pts = &ts;
5320 target_to_host_timespec(pts, timeout);
5321 } else {
5322 pts = NULL;
5324 return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
5325 pts, NULL, val3));
5326 case FUTEX_WAKE:
5327 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
5328 case FUTEX_FD:
5329 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
5330 case FUTEX_REQUEUE:
5331 case FUTEX_CMP_REQUEUE:
5332 case FUTEX_WAKE_OP:
5333 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
5334 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
5335 But the prototype takes a `struct timespec *'; insert casts
5336 to satisfy the compiler. We do not need to tswap TIMEOUT
5337 since it's not compared to guest memory. */
5338 pts = (struct timespec *)(uintptr_t) timeout;
5339 return get_errno(sys_futex(g2h(uaddr), op, val, pts,
5340 g2h(uaddr2),
5341 (base_op == FUTEX_CMP_REQUEUE
5342 ? tswap32(val3)
5343 : val3)));
5344 default:
5345 return -TARGET_ENOSYS;
5348 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
5349 static abi_long do_name_to_handle_at(abi_long dirfd, abi_long pathname,
5350 abi_long handle, abi_long mount_id,
5351 abi_long flags)
5353 struct file_handle *target_fh;
5354 struct file_handle *fh;
5355 int mid = 0;
5356 abi_long ret;
5357 char *name;
5358 unsigned int size, total_size;
5360 if (get_user_s32(size, handle)) {
5361 return -TARGET_EFAULT;
5364 name = lock_user_string(pathname);
5365 if (!name) {
5366 return -TARGET_EFAULT;
5369 total_size = sizeof(struct file_handle) + size;
5370 target_fh = lock_user(VERIFY_WRITE, handle, total_size, 0);
5371 if (!target_fh) {
5372 unlock_user(name, pathname, 0);
5373 return -TARGET_EFAULT;
5376 fh = g_malloc0(total_size);
5377 fh->handle_bytes = size;
5379 ret = get_errno(name_to_handle_at(dirfd, path(name), fh, &mid, flags));
5380 unlock_user(name, pathname, 0);
5382 /* man name_to_handle_at(2):
5383 * Other than the use of the handle_bytes field, the caller should treat
5384 * the file_handle structure as an opaque data type
5387 memcpy(target_fh, fh, total_size);
5388 target_fh->handle_bytes = tswap32(fh->handle_bytes);
5389 target_fh->handle_type = tswap32(fh->handle_type);
5390 g_free(fh);
5391 unlock_user(target_fh, handle, total_size);
5393 if (put_user_s32(mid, mount_id)) {
5394 return -TARGET_EFAULT;
5397 return ret;
5400 #endif
5402 #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
5403 static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
5404 abi_long flags)
5406 struct file_handle *target_fh;
5407 struct file_handle *fh;
5408 unsigned int size, total_size;
5409 abi_long ret;
5411 if (get_user_s32(size, handle)) {
5412 return -TARGET_EFAULT;
5415 total_size = sizeof(struct file_handle) + size;
5416 target_fh = lock_user(VERIFY_READ, handle, total_size, 1);
5417 if (!target_fh) {
5418 return -TARGET_EFAULT;
5421 fh = g_memdup(target_fh, total_size);
5422 fh->handle_bytes = size;
5423 fh->handle_type = tswap32(target_fh->handle_type);
5425 ret = get_errno(open_by_handle_at(mount_fd, fh,
5426 target_to_host_bitmask(flags, fcntl_flags_tbl)));
5428 g_free(fh);
5430 unlock_user(target_fh, handle, total_size);
5432 return ret;
5434 #endif
5436 #if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
5438 /* signalfd siginfo conversion */
5440 static void
5441 host_to_target_signalfd_siginfo(struct signalfd_siginfo *tinfo,
5442 const struct signalfd_siginfo *info)
5444 int sig = host_to_target_signal(info->ssi_signo);
5446 /* linux/signalfd.h defines a ssi_addr_lsb
5447 * not defined in sys/signalfd.h but used by some kernels
5450 #ifdef BUS_MCEERR_AO
5451 if (tinfo->ssi_signo == SIGBUS &&
5452 (tinfo->ssi_code == BUS_MCEERR_AR ||
5453 tinfo->ssi_code == BUS_MCEERR_AO)) {
5454 uint16_t *ssi_addr_lsb = (uint16_t *)(&info->ssi_addr + 1);
5455 uint16_t *tssi_addr_lsb = (uint16_t *)(&tinfo->ssi_addr + 1);
5456 *tssi_addr_lsb = tswap16(*ssi_addr_lsb);
5458 #endif
5460 tinfo->ssi_signo = tswap32(sig);
5461 tinfo->ssi_errno = tswap32(tinfo->ssi_errno);
5462 tinfo->ssi_code = tswap32(info->ssi_code);
5463 tinfo->ssi_pid = tswap32(info->ssi_pid);
5464 tinfo->ssi_uid = tswap32(info->ssi_uid);
5465 tinfo->ssi_fd = tswap32(info->ssi_fd);
5466 tinfo->ssi_tid = tswap32(info->ssi_tid);
5467 tinfo->ssi_band = tswap32(info->ssi_band);
5468 tinfo->ssi_overrun = tswap32(info->ssi_overrun);
5469 tinfo->ssi_trapno = tswap32(info->ssi_trapno);
5470 tinfo->ssi_status = tswap32(info->ssi_status);
5471 tinfo->ssi_int = tswap32(info->ssi_int);
5472 tinfo->ssi_ptr = tswap64(info->ssi_ptr);
5473 tinfo->ssi_utime = tswap64(info->ssi_utime);
5474 tinfo->ssi_stime = tswap64(info->ssi_stime);
5475 tinfo->ssi_addr = tswap64(info->ssi_addr);
5478 static abi_long host_to_target_data_signalfd(void *buf, size_t len)
5480 int i;
5482 for (i = 0; i < len; i += sizeof(struct signalfd_siginfo)) {
5483 host_to_target_signalfd_siginfo(buf + i, buf + i);
5486 return len;
5489 static TargetFdTrans target_signalfd_trans = {
5490 .host_to_target_data = host_to_target_data_signalfd,
5493 static abi_long do_signalfd4(int fd, abi_long mask, int flags)
5495 int host_flags;
5496 target_sigset_t *target_mask;
5497 sigset_t host_mask;
5498 abi_long ret;
5500 if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
5501 return -TARGET_EINVAL;
5503 if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
5504 return -TARGET_EFAULT;
5507 target_to_host_sigset(&host_mask, target_mask);
5509 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
5511 ret = get_errno(signalfd(fd, &host_mask, host_flags));
5512 if (ret >= 0) {
5513 fd_trans_register(ret, &target_signalfd_trans);
5516 unlock_user_struct(target_mask, mask, 0);
5518 return ret;
5520 #endif
5522 /* Map host to target signal numbers for the wait family of syscalls.
5523 Assume all other status bits are the same. */
5524 int host_to_target_waitstatus(int status)
5526 if (WIFSIGNALED(status)) {
5527 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
5529 if (WIFSTOPPED(status)) {
5530 return (host_to_target_signal(WSTOPSIG(status)) << 8)
5531 | (status & 0xff);
5533 return status;
5536 static int open_self_cmdline(void *cpu_env, int fd)
5538 int fd_orig = -1;
5539 bool word_skipped = false;
5541 fd_orig = open("/proc/self/cmdline", O_RDONLY);
5542 if (fd_orig < 0) {
5543 return fd_orig;
5546 while (true) {
5547 ssize_t nb_read;
5548 char buf[128];
5549 char *cp_buf = buf;
5551 nb_read = read(fd_orig, buf, sizeof(buf));
5552 if (nb_read < 0) {
5553 fd_orig = close(fd_orig);
5554 return -1;
5555 } else if (nb_read == 0) {
5556 break;
5559 if (!word_skipped) {
5560 /* Skip the first string, which is the path to qemu-*-static
5561 instead of the actual command. */
5562 cp_buf = memchr(buf, 0, sizeof(buf));
5563 if (cp_buf) {
5564 /* Null byte found, skip one string */
5565 cp_buf++;
5566 nb_read -= cp_buf - buf;
5567 word_skipped = true;
5571 if (word_skipped) {
5572 if (write(fd, cp_buf, nb_read) != nb_read) {
5573 close(fd_orig);
5574 return -1;
5579 return close(fd_orig);
5582 static int open_self_maps(void *cpu_env, int fd)
5584 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
5585 TaskState *ts = cpu->opaque;
5586 FILE *fp;
5587 char *line = NULL;
5588 size_t len = 0;
5589 ssize_t read;
5591 fp = fopen("/proc/self/maps", "r");
5592 if (fp == NULL) {
5593 return -EACCES;
5596 while ((read = getline(&line, &len, fp)) != -1) {
5597 int fields, dev_maj, dev_min, inode;
5598 uint64_t min, max, offset;
5599 char flag_r, flag_w, flag_x, flag_p;
5600 char path[512] = "";
5601 fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
5602 " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
5603 &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
5605 if ((fields < 10) || (fields > 11)) {
5606 continue;
5608 if (h2g_valid(min)) {
5609 int flags = page_get_flags(h2g(min));
5610 max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX);
5611 if (page_check_range(h2g(min), max - min, flags) == -1) {
5612 continue;
5614 if (h2g(min) == ts->info->stack_limit) {
5615 pstrcpy(path, sizeof(path), " [stack]");
5617 dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
5618 " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
5619 h2g(min), h2g(max - 1) + 1, flag_r, flag_w,
5620 flag_x, flag_p, offset, dev_maj, dev_min, inode,
5621 path[0] ? " " : "", path);
5625 free(line);
5626 fclose(fp);
5628 return 0;
5631 static int open_self_stat(void *cpu_env, int fd)
5633 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
5634 TaskState *ts = cpu->opaque;
5635 abi_ulong start_stack = ts->info->start_stack;
5636 int i;
5638 for (i = 0; i < 44; i++) {
5639 char buf[128];
5640 int len;
5641 uint64_t val = 0;
5643 if (i == 0) {
5644 /* pid */
5645 val = getpid();
5646 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5647 } else if (i == 1) {
5648 /* app name */
5649 snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5650 } else if (i == 27) {
5651 /* stack bottom */
5652 val = start_stack;
5653 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5654 } else {
5655 /* for the rest, there is MasterCard */
5656 snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5659 len = strlen(buf);
5660 if (write(fd, buf, len) != len) {
5661 return -1;
5665 return 0;
5668 static int open_self_auxv(void *cpu_env, int fd)
5670 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
5671 TaskState *ts = cpu->opaque;
5672 abi_ulong auxv = ts->info->saved_auxv;
5673 abi_ulong len = ts->info->auxv_len;
5674 char *ptr;
5677 * Auxiliary vector is stored in target process stack.
5678 * read in whole auxv vector and copy it to file
5680 ptr = lock_user(VERIFY_READ, auxv, len, 0);
5681 if (ptr != NULL) {
5682 while (len > 0) {
5683 ssize_t r;
5684 r = write(fd, ptr, len);
5685 if (r <= 0) {
5686 break;
5688 len -= r;
5689 ptr += r;
5691 lseek(fd, 0, SEEK_SET);
5692 unlock_user(ptr, auxv, len);
5695 return 0;
5698 static int is_proc_myself(const char *filename, const char *entry)
5700 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5701 filename += strlen("/proc/");
5702 if (!strncmp(filename, "self/", strlen("self/"))) {
5703 filename += strlen("self/");
5704 } else if (*filename >= '1' && *filename <= '9') {
5705 char myself[80];
5706 snprintf(myself, sizeof(myself), "%d/", getpid());
5707 if (!strncmp(filename, myself, strlen(myself))) {
5708 filename += strlen(myself);
5709 } else {
5710 return 0;
5712 } else {
5713 return 0;
5715 if (!strcmp(filename, entry)) {
5716 return 1;
5719 return 0;
5722 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5723 static int is_proc(const char *filename, const char *entry)
5725 return strcmp(filename, entry) == 0;
5728 static int open_net_route(void *cpu_env, int fd)
5730 FILE *fp;
5731 char *line = NULL;
5732 size_t len = 0;
5733 ssize_t read;
5735 fp = fopen("/proc/net/route", "r");
5736 if (fp == NULL) {
5737 return -EACCES;
5740 /* read header */
5742 read = getline(&line, &len, fp);
5743 dprintf(fd, "%s", line);
5745 /* read routes */
5747 while ((read = getline(&line, &len, fp)) != -1) {
5748 char iface[16];
5749 uint32_t dest, gw, mask;
5750 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
5751 sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5752 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
5753 &mask, &mtu, &window, &irtt);
5754 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5755 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
5756 metric, tswap32(mask), mtu, window, irtt);
5759 free(line);
5760 fclose(fp);
5762 return 0;
5764 #endif
5766 static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
5768 struct fake_open {
5769 const char *filename;
5770 int (*fill)(void *cpu_env, int fd);
5771 int (*cmp)(const char *s1, const char *s2);
5773 const struct fake_open *fake_open;
5774 static const struct fake_open fakes[] = {
5775 { "maps", open_self_maps, is_proc_myself },
5776 { "stat", open_self_stat, is_proc_myself },
5777 { "auxv", open_self_auxv, is_proc_myself },
5778 { "cmdline", open_self_cmdline, is_proc_myself },
5779 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5780 { "/proc/net/route", open_net_route, is_proc },
5781 #endif
5782 { NULL, NULL, NULL }
5785 if (is_proc_myself(pathname, "exe")) {
5786 int execfd = qemu_getauxval(AT_EXECFD);
5787 return execfd ? execfd : get_errno(sys_openat(dirfd, exec_path, flags, mode));
5790 for (fake_open = fakes; fake_open->filename; fake_open++) {
5791 if (fake_open->cmp(pathname, fake_open->filename)) {
5792 break;
5796 if (fake_open->filename) {
5797 const char *tmpdir;
5798 char filename[PATH_MAX];
5799 int fd, r;
5801 /* create temporary file to map stat to */
5802 tmpdir = getenv("TMPDIR");
5803 if (!tmpdir)
5804 tmpdir = "/tmp";
5805 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5806 fd = mkstemp(filename);
5807 if (fd < 0) {
5808 return fd;
5810 unlink(filename);
5812 if ((r = fake_open->fill(cpu_env, fd))) {
5813 close(fd);
5814 return r;
5816 lseek(fd, 0, SEEK_SET);
5818 return fd;
5821 return get_errno(sys_openat(dirfd, path(pathname), flags, mode));
5824 #define TIMER_MAGIC 0x0caf0000
5825 #define TIMER_MAGIC_MASK 0xffff0000
5827 /* Convert QEMU provided timer ID back to internal 16bit index format */
5828 static target_timer_t get_timer_id(abi_long arg)
5830 target_timer_t timerid = arg;
5832 if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
5833 return -TARGET_EINVAL;
5836 timerid &= 0xffff;
5838 if (timerid >= ARRAY_SIZE(g_posix_timers)) {
5839 return -TARGET_EINVAL;
5842 return timerid;
5845 /* do_syscall() should always have a single exit point at the end so
5846 that actions, such as logging of syscall results, can be performed.
5847 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5848 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5849 abi_long arg2, abi_long arg3, abi_long arg4,
5850 abi_long arg5, abi_long arg6, abi_long arg7,
5851 abi_long arg8)
5853 CPUState *cpu = ENV_GET_CPU(cpu_env);
5854 abi_long ret;
5855 struct stat st;
5856 struct statfs stfs;
5857 void *p;
5859 #ifdef DEBUG
5860 gemu_log("syscall %d", num);
5861 #endif
5862 if(do_strace)
5863 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5865 switch(num) {
5866 case TARGET_NR_exit:
5867 /* In old applications this may be used to implement _exit(2).
5868 However in threaded applictions it is used for thread termination,
5869 and _exit_group is used for application termination.
5870 Do thread termination if we have more then one thread. */
5871 /* FIXME: This probably breaks if a signal arrives. We should probably
5872 be disabling signals. */
5873 if (CPU_NEXT(first_cpu)) {
5874 TaskState *ts;
5876 cpu_list_lock();
5877 /* Remove the CPU from the list. */
5878 QTAILQ_REMOVE(&cpus, cpu, node);
5879 cpu_list_unlock();
5880 ts = cpu->opaque;
5881 if (ts->child_tidptr) {
5882 put_user_u32(0, ts->child_tidptr);
5883 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5884 NULL, NULL, 0);
5886 thread_cpu = NULL;
5887 object_unref(OBJECT(cpu));
5888 g_free(ts);
5889 rcu_unregister_thread();
5890 pthread_exit(NULL);
5892 #ifdef TARGET_GPROF
5893 _mcleanup();
5894 #endif
5895 gdb_exit(cpu_env, arg1);
5896 _exit(arg1);
5897 ret = 0; /* avoid warning */
5898 break;
5899 case TARGET_NR_read:
5900 if (arg3 == 0)
5901 ret = 0;
5902 else {
5903 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5904 goto efault;
5905 ret = get_errno(read(arg1, p, arg3));
5906 if (ret >= 0 &&
5907 fd_trans_host_to_target_data(arg1)) {
5908 ret = fd_trans_host_to_target_data(arg1)(p, ret);
5910 unlock_user(p, arg2, ret);
5912 break;
5913 case TARGET_NR_write:
5914 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5915 goto efault;
5916 ret = get_errno(write(arg1, p, arg3));
5917 unlock_user(p, arg2, 0);
5918 break;
5919 #ifdef TARGET_NR_open
5920 case TARGET_NR_open:
5921 if (!(p = lock_user_string(arg1)))
5922 goto efault;
5923 ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
5924 target_to_host_bitmask(arg2, fcntl_flags_tbl),
5925 arg3));
5926 fd_trans_unregister(ret);
5927 unlock_user(p, arg1, 0);
5928 break;
5929 #endif
5930 case TARGET_NR_openat:
5931 if (!(p = lock_user_string(arg2)))
5932 goto efault;
5933 ret = get_errno(do_openat(cpu_env, arg1, p,
5934 target_to_host_bitmask(arg3, fcntl_flags_tbl),
5935 arg4));
5936 fd_trans_unregister(ret);
5937 unlock_user(p, arg2, 0);
5938 break;
5939 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
5940 case TARGET_NR_name_to_handle_at:
5941 ret = do_name_to_handle_at(arg1, arg2, arg3, arg4, arg5);
5942 break;
5943 #endif
5944 #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
5945 case TARGET_NR_open_by_handle_at:
5946 ret = do_open_by_handle_at(arg1, arg2, arg3);
5947 fd_trans_unregister(ret);
5948 break;
5949 #endif
5950 case TARGET_NR_close:
5951 fd_trans_unregister(arg1);
5952 ret = get_errno(close(arg1));
5953 break;
5954 case TARGET_NR_brk:
5955 ret = do_brk(arg1);
5956 break;
5957 #ifdef TARGET_NR_fork
5958 case TARGET_NR_fork:
5959 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5960 break;
5961 #endif
5962 #ifdef TARGET_NR_waitpid
5963 case TARGET_NR_waitpid:
5965 int status;
5966 ret = get_errno(waitpid(arg1, &status, arg3));
5967 if (!is_error(ret) && arg2 && ret
5968 && put_user_s32(host_to_target_waitstatus(status), arg2))
5969 goto efault;
5971 break;
5972 #endif
5973 #ifdef TARGET_NR_waitid
5974 case TARGET_NR_waitid:
5976 siginfo_t info;
5977 info.si_pid = 0;
5978 ret = get_errno(waitid(arg1, arg2, &info, arg4));
5979 if (!is_error(ret) && arg3 && info.si_pid != 0) {
5980 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5981 goto efault;
5982 host_to_target_siginfo(p, &info);
5983 unlock_user(p, arg3, sizeof(target_siginfo_t));
5986 break;
5987 #endif
5988 #ifdef TARGET_NR_creat /* not on alpha */
5989 case TARGET_NR_creat:
5990 if (!(p = lock_user_string(arg1)))
5991 goto efault;
5992 ret = get_errno(creat(p, arg2));
5993 fd_trans_unregister(ret);
5994 unlock_user(p, arg1, 0);
5995 break;
5996 #endif
5997 #ifdef TARGET_NR_link
5998 case TARGET_NR_link:
6000 void * p2;
6001 p = lock_user_string(arg1);
6002 p2 = lock_user_string(arg2);
6003 if (!p || !p2)
6004 ret = -TARGET_EFAULT;
6005 else
6006 ret = get_errno(link(p, p2));
6007 unlock_user(p2, arg2, 0);
6008 unlock_user(p, arg1, 0);
6010 break;
6011 #endif
6012 #if defined(TARGET_NR_linkat)
6013 case TARGET_NR_linkat:
6015 void * p2 = NULL;
6016 if (!arg2 || !arg4)
6017 goto efault;
6018 p = lock_user_string(arg2);
6019 p2 = lock_user_string(arg4);
6020 if (!p || !p2)
6021 ret = -TARGET_EFAULT;
6022 else
6023 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
6024 unlock_user(p, arg2, 0);
6025 unlock_user(p2, arg4, 0);
6027 break;
6028 #endif
6029 #ifdef TARGET_NR_unlink
6030 case TARGET_NR_unlink:
6031 if (!(p = lock_user_string(arg1)))
6032 goto efault;
6033 ret = get_errno(unlink(p));
6034 unlock_user(p, arg1, 0);
6035 break;
6036 #endif
6037 #if defined(TARGET_NR_unlinkat)
6038 case TARGET_NR_unlinkat:
6039 if (!(p = lock_user_string(arg2)))
6040 goto efault;
6041 ret = get_errno(unlinkat(arg1, p, arg3));
6042 unlock_user(p, arg2, 0);
6043 break;
6044 #endif
6045 case TARGET_NR_execve:
6047 char **argp, **envp;
6048 int argc, envc;
6049 abi_ulong gp;
6050 abi_ulong guest_argp;
6051 abi_ulong guest_envp;
6052 abi_ulong addr;
6053 char **q;
6054 int total_size = 0;
6056 argc = 0;
6057 guest_argp = arg2;
6058 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
6059 if (get_user_ual(addr, gp))
6060 goto efault;
6061 if (!addr)
6062 break;
6063 argc++;
6065 envc = 0;
6066 guest_envp = arg3;
6067 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
6068 if (get_user_ual(addr, gp))
6069 goto efault;
6070 if (!addr)
6071 break;
6072 envc++;
6075 argp = alloca((argc + 1) * sizeof(void *));
6076 envp = alloca((envc + 1) * sizeof(void *));
6078 for (gp = guest_argp, q = argp; gp;
6079 gp += sizeof(abi_ulong), q++) {
6080 if (get_user_ual(addr, gp))
6081 goto execve_efault;
6082 if (!addr)
6083 break;
6084 if (!(*q = lock_user_string(addr)))
6085 goto execve_efault;
6086 total_size += strlen(*q) + 1;
6088 *q = NULL;
6090 for (gp = guest_envp, q = envp; gp;
6091 gp += sizeof(abi_ulong), q++) {
6092 if (get_user_ual(addr, gp))
6093 goto execve_efault;
6094 if (!addr)
6095 break;
6096 if (!(*q = lock_user_string(addr)))
6097 goto execve_efault;
6098 total_size += strlen(*q) + 1;
6100 *q = NULL;
6102 if (!(p = lock_user_string(arg1)))
6103 goto execve_efault;
6104 ret = get_errno(execve(p, argp, envp));
6105 unlock_user(p, arg1, 0);
6107 goto execve_end;
6109 execve_efault:
6110 ret = -TARGET_EFAULT;
6112 execve_end:
6113 for (gp = guest_argp, q = argp; *q;
6114 gp += sizeof(abi_ulong), q++) {
6115 if (get_user_ual(addr, gp)
6116 || !addr)
6117 break;
6118 unlock_user(*q, addr, 0);
6120 for (gp = guest_envp, q = envp; *q;
6121 gp += sizeof(abi_ulong), q++) {
6122 if (get_user_ual(addr, gp)
6123 || !addr)
6124 break;
6125 unlock_user(*q, addr, 0);
6128 break;
6129 case TARGET_NR_chdir:
6130 if (!(p = lock_user_string(arg1)))
6131 goto efault;
6132 ret = get_errno(chdir(p));
6133 unlock_user(p, arg1, 0);
6134 break;
6135 #ifdef TARGET_NR_time
6136 case TARGET_NR_time:
6138 time_t host_time;
6139 ret = get_errno(time(&host_time));
6140 if (!is_error(ret)
6141 && arg1
6142 && put_user_sal(host_time, arg1))
6143 goto efault;
6145 break;
6146 #endif
6147 #ifdef TARGET_NR_mknod
6148 case TARGET_NR_mknod:
6149 if (!(p = lock_user_string(arg1)))
6150 goto efault;
6151 ret = get_errno(mknod(p, arg2, arg3));
6152 unlock_user(p, arg1, 0);
6153 break;
6154 #endif
6155 #if defined(TARGET_NR_mknodat)
6156 case TARGET_NR_mknodat:
6157 if (!(p = lock_user_string(arg2)))
6158 goto efault;
6159 ret = get_errno(mknodat(arg1, p, arg3, arg4));
6160 unlock_user(p, arg2, 0);
6161 break;
6162 #endif
6163 #ifdef TARGET_NR_chmod
6164 case TARGET_NR_chmod:
6165 if (!(p = lock_user_string(arg1)))
6166 goto efault;
6167 ret = get_errno(chmod(p, arg2));
6168 unlock_user(p, arg1, 0);
6169 break;
6170 #endif
6171 #ifdef TARGET_NR_break
6172 case TARGET_NR_break:
6173 goto unimplemented;
6174 #endif
6175 #ifdef TARGET_NR_oldstat
6176 case TARGET_NR_oldstat:
6177 goto unimplemented;
6178 #endif
6179 case TARGET_NR_lseek:
6180 ret = get_errno(lseek(arg1, arg2, arg3));
6181 break;
6182 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
6183 /* Alpha specific */
6184 case TARGET_NR_getxpid:
6185 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
6186 ret = get_errno(getpid());
6187 break;
6188 #endif
6189 #ifdef TARGET_NR_getpid
6190 case TARGET_NR_getpid:
6191 ret = get_errno(getpid());
6192 break;
6193 #endif
6194 case TARGET_NR_mount:
6196 /* need to look at the data field */
6197 void *p2, *p3;
6199 if (arg1) {
6200 p = lock_user_string(arg1);
6201 if (!p) {
6202 goto efault;
6204 } else {
6205 p = NULL;
6208 p2 = lock_user_string(arg2);
6209 if (!p2) {
6210 if (arg1) {
6211 unlock_user(p, arg1, 0);
6213 goto efault;
6216 if (arg3) {
6217 p3 = lock_user_string(arg3);
6218 if (!p3) {
6219 if (arg1) {
6220 unlock_user(p, arg1, 0);
6222 unlock_user(p2, arg2, 0);
6223 goto efault;
6225 } else {
6226 p3 = NULL;
6229 /* FIXME - arg5 should be locked, but it isn't clear how to
6230 * do that since it's not guaranteed to be a NULL-terminated
6231 * string.
6233 if (!arg5) {
6234 ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
6235 } else {
6236 ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
6238 ret = get_errno(ret);
6240 if (arg1) {
6241 unlock_user(p, arg1, 0);
6243 unlock_user(p2, arg2, 0);
6244 if (arg3) {
6245 unlock_user(p3, arg3, 0);
6248 break;
6249 #ifdef TARGET_NR_umount
6250 case TARGET_NR_umount:
6251 if (!(p = lock_user_string(arg1)))
6252 goto efault;
6253 ret = get_errno(umount(p));
6254 unlock_user(p, arg1, 0);
6255 break;
6256 #endif
6257 #ifdef TARGET_NR_stime /* not on alpha */
6258 case TARGET_NR_stime:
6260 time_t host_time;
6261 if (get_user_sal(host_time, arg1))
6262 goto efault;
6263 ret = get_errno(stime(&host_time));
6265 break;
6266 #endif
6267 case TARGET_NR_ptrace:
6268 goto unimplemented;
6269 #ifdef TARGET_NR_alarm /* not on alpha */
6270 case TARGET_NR_alarm:
6271 ret = alarm(arg1);
6272 break;
6273 #endif
6274 #ifdef TARGET_NR_oldfstat
6275 case TARGET_NR_oldfstat:
6276 goto unimplemented;
6277 #endif
6278 #ifdef TARGET_NR_pause /* not on alpha */
6279 case TARGET_NR_pause:
6280 ret = get_errno(pause());
6281 break;
6282 #endif
6283 #ifdef TARGET_NR_utime
6284 case TARGET_NR_utime:
6286 struct utimbuf tbuf, *host_tbuf;
6287 struct target_utimbuf *target_tbuf;
6288 if (arg2) {
6289 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
6290 goto efault;
6291 tbuf.actime = tswapal(target_tbuf->actime);
6292 tbuf.modtime = tswapal(target_tbuf->modtime);
6293 unlock_user_struct(target_tbuf, arg2, 0);
6294 host_tbuf = &tbuf;
6295 } else {
6296 host_tbuf = NULL;
6298 if (!(p = lock_user_string(arg1)))
6299 goto efault;
6300 ret = get_errno(utime(p, host_tbuf));
6301 unlock_user(p, arg1, 0);
6303 break;
6304 #endif
6305 #ifdef TARGET_NR_utimes
6306 case TARGET_NR_utimes:
6308 struct timeval *tvp, tv[2];
6309 if (arg2) {
6310 if (copy_from_user_timeval(&tv[0], arg2)
6311 || copy_from_user_timeval(&tv[1],
6312 arg2 + sizeof(struct target_timeval)))
6313 goto efault;
6314 tvp = tv;
6315 } else {
6316 tvp = NULL;
6318 if (!(p = lock_user_string(arg1)))
6319 goto efault;
6320 ret = get_errno(utimes(p, tvp));
6321 unlock_user(p, arg1, 0);
6323 break;
6324 #endif
6325 #if defined(TARGET_NR_futimesat)
6326 case TARGET_NR_futimesat:
6328 struct timeval *tvp, tv[2];
6329 if (arg3) {
6330 if (copy_from_user_timeval(&tv[0], arg3)
6331 || copy_from_user_timeval(&tv[1],
6332 arg3 + sizeof(struct target_timeval)))
6333 goto efault;
6334 tvp = tv;
6335 } else {
6336 tvp = NULL;
6338 if (!(p = lock_user_string(arg2)))
6339 goto efault;
6340 ret = get_errno(futimesat(arg1, path(p), tvp));
6341 unlock_user(p, arg2, 0);
6343 break;
6344 #endif
6345 #ifdef TARGET_NR_stty
6346 case TARGET_NR_stty:
6347 goto unimplemented;
6348 #endif
6349 #ifdef TARGET_NR_gtty
6350 case TARGET_NR_gtty:
6351 goto unimplemented;
6352 #endif
6353 #ifdef TARGET_NR_access
6354 case TARGET_NR_access:
6355 if (!(p = lock_user_string(arg1)))
6356 goto efault;
6357 ret = get_errno(access(path(p), arg2));
6358 unlock_user(p, arg1, 0);
6359 break;
6360 #endif
6361 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
6362 case TARGET_NR_faccessat:
6363 if (!(p = lock_user_string(arg2)))
6364 goto efault;
6365 ret = get_errno(faccessat(arg1, p, arg3, 0));
6366 unlock_user(p, arg2, 0);
6367 break;
6368 #endif
6369 #ifdef TARGET_NR_nice /* not on alpha */
6370 case TARGET_NR_nice:
6371 ret = get_errno(nice(arg1));
6372 break;
6373 #endif
6374 #ifdef TARGET_NR_ftime
6375 case TARGET_NR_ftime:
6376 goto unimplemented;
6377 #endif
6378 case TARGET_NR_sync:
6379 sync();
6380 ret = 0;
6381 break;
6382 case TARGET_NR_kill:
6383 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
6384 break;
6385 #ifdef TARGET_NR_rename
6386 case TARGET_NR_rename:
6388 void *p2;
6389 p = lock_user_string(arg1);
6390 p2 = lock_user_string(arg2);
6391 if (!p || !p2)
6392 ret = -TARGET_EFAULT;
6393 else
6394 ret = get_errno(rename(p, p2));
6395 unlock_user(p2, arg2, 0);
6396 unlock_user(p, arg1, 0);
6398 break;
6399 #endif
6400 #if defined(TARGET_NR_renameat)
6401 case TARGET_NR_renameat:
6403 void *p2;
6404 p = lock_user_string(arg2);
6405 p2 = lock_user_string(arg4);
6406 if (!p || !p2)
6407 ret = -TARGET_EFAULT;
6408 else
6409 ret = get_errno(renameat(arg1, p, arg3, p2));
6410 unlock_user(p2, arg4, 0);
6411 unlock_user(p, arg2, 0);
6413 break;
6414 #endif
6415 #ifdef TARGET_NR_mkdir
6416 case TARGET_NR_mkdir:
6417 if (!(p = lock_user_string(arg1)))
6418 goto efault;
6419 ret = get_errno(mkdir(p, arg2));
6420 unlock_user(p, arg1, 0);
6421 break;
6422 #endif
6423 #if defined(TARGET_NR_mkdirat)
6424 case TARGET_NR_mkdirat:
6425 if (!(p = lock_user_string(arg2)))
6426 goto efault;
6427 ret = get_errno(mkdirat(arg1, p, arg3));
6428 unlock_user(p, arg2, 0);
6429 break;
6430 #endif
6431 #ifdef TARGET_NR_rmdir
6432 case TARGET_NR_rmdir:
6433 if (!(p = lock_user_string(arg1)))
6434 goto efault;
6435 ret = get_errno(rmdir(p));
6436 unlock_user(p, arg1, 0);
6437 break;
6438 #endif
6439 case TARGET_NR_dup:
6440 ret = get_errno(dup(arg1));
6441 if (ret >= 0) {
6442 fd_trans_dup(arg1, ret);
6444 break;
6445 #ifdef TARGET_NR_pipe
6446 case TARGET_NR_pipe:
6447 ret = do_pipe(cpu_env, arg1, 0, 0);
6448 break;
6449 #endif
6450 #ifdef TARGET_NR_pipe2
6451 case TARGET_NR_pipe2:
6452 ret = do_pipe(cpu_env, arg1,
6453 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
6454 break;
6455 #endif
6456 case TARGET_NR_times:
6458 struct target_tms *tmsp;
6459 struct tms tms;
6460 ret = get_errno(times(&tms));
6461 if (arg1) {
6462 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
6463 if (!tmsp)
6464 goto efault;
6465 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
6466 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
6467 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
6468 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
6470 if (!is_error(ret))
6471 ret = host_to_target_clock_t(ret);
6473 break;
6474 #ifdef TARGET_NR_prof
6475 case TARGET_NR_prof:
6476 goto unimplemented;
6477 #endif
6478 #ifdef TARGET_NR_signal
6479 case TARGET_NR_signal:
6480 goto unimplemented;
6481 #endif
6482 case TARGET_NR_acct:
6483 if (arg1 == 0) {
6484 ret = get_errno(acct(NULL));
6485 } else {
6486 if (!(p = lock_user_string(arg1)))
6487 goto efault;
6488 ret = get_errno(acct(path(p)));
6489 unlock_user(p, arg1, 0);
6491 break;
6492 #ifdef TARGET_NR_umount2
6493 case TARGET_NR_umount2:
6494 if (!(p = lock_user_string(arg1)))
6495 goto efault;
6496 ret = get_errno(umount2(p, arg2));
6497 unlock_user(p, arg1, 0);
6498 break;
6499 #endif
6500 #ifdef TARGET_NR_lock
6501 case TARGET_NR_lock:
6502 goto unimplemented;
6503 #endif
6504 case TARGET_NR_ioctl:
6505 ret = do_ioctl(arg1, arg2, arg3);
6506 break;
6507 case TARGET_NR_fcntl:
6508 ret = do_fcntl(arg1, arg2, arg3);
6509 break;
6510 #ifdef TARGET_NR_mpx
6511 case TARGET_NR_mpx:
6512 goto unimplemented;
6513 #endif
6514 case TARGET_NR_setpgid:
6515 ret = get_errno(setpgid(arg1, arg2));
6516 break;
6517 #ifdef TARGET_NR_ulimit
6518 case TARGET_NR_ulimit:
6519 goto unimplemented;
6520 #endif
6521 #ifdef TARGET_NR_oldolduname
6522 case TARGET_NR_oldolduname:
6523 goto unimplemented;
6524 #endif
6525 case TARGET_NR_umask:
6526 ret = get_errno(umask(arg1));
6527 break;
6528 case TARGET_NR_chroot:
6529 if (!(p = lock_user_string(arg1)))
6530 goto efault;
6531 ret = get_errno(chroot(p));
6532 unlock_user(p, arg1, 0);
6533 break;
6534 #ifdef TARGET_NR_ustat
6535 case TARGET_NR_ustat:
6536 goto unimplemented;
6537 #endif
6538 #ifdef TARGET_NR_dup2
6539 case TARGET_NR_dup2:
6540 ret = get_errno(dup2(arg1, arg2));
6541 if (ret >= 0) {
6542 fd_trans_dup(arg1, arg2);
6544 break;
6545 #endif
6546 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
6547 case TARGET_NR_dup3:
6548 ret = get_errno(dup3(arg1, arg2, arg3));
6549 if (ret >= 0) {
6550 fd_trans_dup(arg1, arg2);
6552 break;
6553 #endif
6554 #ifdef TARGET_NR_getppid /* not on alpha */
6555 case TARGET_NR_getppid:
6556 ret = get_errno(getppid());
6557 break;
6558 #endif
6559 #ifdef TARGET_NR_getpgrp
6560 case TARGET_NR_getpgrp:
6561 ret = get_errno(getpgrp());
6562 break;
6563 #endif
6564 case TARGET_NR_setsid:
6565 ret = get_errno(setsid());
6566 break;
6567 #ifdef TARGET_NR_sigaction
6568 case TARGET_NR_sigaction:
6570 #if defined(TARGET_ALPHA)
6571 struct target_sigaction act, oact, *pact = 0;
6572 struct target_old_sigaction *old_act;
6573 if (arg2) {
6574 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
6575 goto efault;
6576 act._sa_handler = old_act->_sa_handler;
6577 target_siginitset(&act.sa_mask, old_act->sa_mask);
6578 act.sa_flags = old_act->sa_flags;
6579 act.sa_restorer = 0;
6580 unlock_user_struct(old_act, arg2, 0);
6581 pact = &act;
6583 ret = get_errno(do_sigaction(arg1, pact, &oact));
6584 if (!is_error(ret) && arg3) {
6585 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
6586 goto efault;
6587 old_act->_sa_handler = oact._sa_handler;
6588 old_act->sa_mask = oact.sa_mask.sig[0];
6589 old_act->sa_flags = oact.sa_flags;
6590 unlock_user_struct(old_act, arg3, 1);
6592 #elif defined(TARGET_MIPS)
6593 struct target_sigaction act, oact, *pact, *old_act;
6595 if (arg2) {
6596 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
6597 goto efault;
6598 act._sa_handler = old_act->_sa_handler;
6599 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
6600 act.sa_flags = old_act->sa_flags;
6601 unlock_user_struct(old_act, arg2, 0);
6602 pact = &act;
6603 } else {
6604 pact = NULL;
6607 ret = get_errno(do_sigaction(arg1, pact, &oact));
6609 if (!is_error(ret) && arg3) {
6610 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
6611 goto efault;
6612 old_act->_sa_handler = oact._sa_handler;
6613 old_act->sa_flags = oact.sa_flags;
6614 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
6615 old_act->sa_mask.sig[1] = 0;
6616 old_act->sa_mask.sig[2] = 0;
6617 old_act->sa_mask.sig[3] = 0;
6618 unlock_user_struct(old_act, arg3, 1);
6620 #else
6621 struct target_old_sigaction *old_act;
6622 struct target_sigaction act, oact, *pact;
6623 if (arg2) {
6624 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
6625 goto efault;
6626 act._sa_handler = old_act->_sa_handler;
6627 target_siginitset(&act.sa_mask, old_act->sa_mask);
6628 act.sa_flags = old_act->sa_flags;
6629 act.sa_restorer = old_act->sa_restorer;
6630 unlock_user_struct(old_act, arg2, 0);
6631 pact = &act;
6632 } else {
6633 pact = NULL;
6635 ret = get_errno(do_sigaction(arg1, pact, &oact));
6636 if (!is_error(ret) && arg3) {
6637 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
6638 goto efault;
6639 old_act->_sa_handler = oact._sa_handler;
6640 old_act->sa_mask = oact.sa_mask.sig[0];
6641 old_act->sa_flags = oact.sa_flags;
6642 old_act->sa_restorer = oact.sa_restorer;
6643 unlock_user_struct(old_act, arg3, 1);
6645 #endif
6647 break;
6648 #endif
6649 case TARGET_NR_rt_sigaction:
6651 #if defined(TARGET_ALPHA)
6652 struct target_sigaction act, oact, *pact = 0;
6653 struct target_rt_sigaction *rt_act;
6654 /* ??? arg4 == sizeof(sigset_t). */
6655 if (arg2) {
6656 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
6657 goto efault;
6658 act._sa_handler = rt_act->_sa_handler;
6659 act.sa_mask = rt_act->sa_mask;
6660 act.sa_flags = rt_act->sa_flags;
6661 act.sa_restorer = arg5;
6662 unlock_user_struct(rt_act, arg2, 0);
6663 pact = &act;
6665 ret = get_errno(do_sigaction(arg1, pact, &oact));
6666 if (!is_error(ret) && arg3) {
6667 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
6668 goto efault;
6669 rt_act->_sa_handler = oact._sa_handler;
6670 rt_act->sa_mask = oact.sa_mask;
6671 rt_act->sa_flags = oact.sa_flags;
6672 unlock_user_struct(rt_act, arg3, 1);
6674 #else
6675 struct target_sigaction *act;
6676 struct target_sigaction *oact;
6678 if (arg2) {
6679 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
6680 goto efault;
6681 } else
6682 act = NULL;
6683 if (arg3) {
6684 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
6685 ret = -TARGET_EFAULT;
6686 goto rt_sigaction_fail;
6688 } else
6689 oact = NULL;
6690 ret = get_errno(do_sigaction(arg1, act, oact));
6691 rt_sigaction_fail:
6692 if (act)
6693 unlock_user_struct(act, arg2, 0);
6694 if (oact)
6695 unlock_user_struct(oact, arg3, 1);
6696 #endif
6698 break;
6699 #ifdef TARGET_NR_sgetmask /* not on alpha */
6700 case TARGET_NR_sgetmask:
6702 sigset_t cur_set;
6703 abi_ulong target_set;
6704 do_sigprocmask(0, NULL, &cur_set);
6705 host_to_target_old_sigset(&target_set, &cur_set);
6706 ret = target_set;
6708 break;
6709 #endif
6710 #ifdef TARGET_NR_ssetmask /* not on alpha */
6711 case TARGET_NR_ssetmask:
6713 sigset_t set, oset, cur_set;
6714 abi_ulong target_set = arg1;
6715 do_sigprocmask(0, NULL, &cur_set);
6716 target_to_host_old_sigset(&set, &target_set);
6717 sigorset(&set, &set, &cur_set);
6718 do_sigprocmask(SIG_SETMASK, &set, &oset);
6719 host_to_target_old_sigset(&target_set, &oset);
6720 ret = target_set;
6722 break;
6723 #endif
6724 #ifdef TARGET_NR_sigprocmask
6725 case TARGET_NR_sigprocmask:
6727 #if defined(TARGET_ALPHA)
6728 sigset_t set, oldset;
6729 abi_ulong mask;
6730 int how;
6732 switch (arg1) {
6733 case TARGET_SIG_BLOCK:
6734 how = SIG_BLOCK;
6735 break;
6736 case TARGET_SIG_UNBLOCK:
6737 how = SIG_UNBLOCK;
6738 break;
6739 case TARGET_SIG_SETMASK:
6740 how = SIG_SETMASK;
6741 break;
6742 default:
6743 ret = -TARGET_EINVAL;
6744 goto fail;
6746 mask = arg2;
6747 target_to_host_old_sigset(&set, &mask);
6749 ret = get_errno(do_sigprocmask(how, &set, &oldset));
6750 if (!is_error(ret)) {
6751 host_to_target_old_sigset(&mask, &oldset);
6752 ret = mask;
6753 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
6755 #else
6756 sigset_t set, oldset, *set_ptr;
6757 int how;
6759 if (arg2) {
6760 switch (arg1) {
6761 case TARGET_SIG_BLOCK:
6762 how = SIG_BLOCK;
6763 break;
6764 case TARGET_SIG_UNBLOCK:
6765 how = SIG_UNBLOCK;
6766 break;
6767 case TARGET_SIG_SETMASK:
6768 how = SIG_SETMASK;
6769 break;
6770 default:
6771 ret = -TARGET_EINVAL;
6772 goto fail;
6774 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6775 goto efault;
6776 target_to_host_old_sigset(&set, p);
6777 unlock_user(p, arg2, 0);
6778 set_ptr = &set;
6779 } else {
6780 how = 0;
6781 set_ptr = NULL;
6783 ret = get_errno(do_sigprocmask(how, set_ptr, &oldset));
6784 if (!is_error(ret) && arg3) {
6785 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6786 goto efault;
6787 host_to_target_old_sigset(p, &oldset);
6788 unlock_user(p, arg3, sizeof(target_sigset_t));
6790 #endif
6792 break;
6793 #endif
6794 case TARGET_NR_rt_sigprocmask:
6796 int how = arg1;
6797 sigset_t set, oldset, *set_ptr;
6799 if (arg2) {
6800 switch(how) {
6801 case TARGET_SIG_BLOCK:
6802 how = SIG_BLOCK;
6803 break;
6804 case TARGET_SIG_UNBLOCK:
6805 how = SIG_UNBLOCK;
6806 break;
6807 case TARGET_SIG_SETMASK:
6808 how = SIG_SETMASK;
6809 break;
6810 default:
6811 ret = -TARGET_EINVAL;
6812 goto fail;
6814 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6815 goto efault;
6816 target_to_host_sigset(&set, p);
6817 unlock_user(p, arg2, 0);
6818 set_ptr = &set;
6819 } else {
6820 how = 0;
6821 set_ptr = NULL;
6823 ret = get_errno(do_sigprocmask(how, set_ptr, &oldset));
6824 if (!is_error(ret) && arg3) {
6825 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6826 goto efault;
6827 host_to_target_sigset(p, &oldset);
6828 unlock_user(p, arg3, sizeof(target_sigset_t));
6831 break;
6832 #ifdef TARGET_NR_sigpending
6833 case TARGET_NR_sigpending:
6835 sigset_t set;
6836 ret = get_errno(sigpending(&set));
6837 if (!is_error(ret)) {
6838 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6839 goto efault;
6840 host_to_target_old_sigset(p, &set);
6841 unlock_user(p, arg1, sizeof(target_sigset_t));
6844 break;
6845 #endif
6846 case TARGET_NR_rt_sigpending:
6848 sigset_t set;
6849 ret = get_errno(sigpending(&set));
6850 if (!is_error(ret)) {
6851 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6852 goto efault;
6853 host_to_target_sigset(p, &set);
6854 unlock_user(p, arg1, sizeof(target_sigset_t));
6857 break;
6858 #ifdef TARGET_NR_sigsuspend
6859 case TARGET_NR_sigsuspend:
6861 sigset_t set;
6862 #if defined(TARGET_ALPHA)
6863 abi_ulong mask = arg1;
6864 target_to_host_old_sigset(&set, &mask);
6865 #else
6866 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6867 goto efault;
6868 target_to_host_old_sigset(&set, p);
6869 unlock_user(p, arg1, 0);
6870 #endif
6871 ret = get_errno(sigsuspend(&set));
6873 break;
6874 #endif
6875 case TARGET_NR_rt_sigsuspend:
6877 sigset_t set;
6878 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6879 goto efault;
6880 target_to_host_sigset(&set, p);
6881 unlock_user(p, arg1, 0);
6882 ret = get_errno(sigsuspend(&set));
6884 break;
6885 case TARGET_NR_rt_sigtimedwait:
6887 sigset_t set;
6888 struct timespec uts, *puts;
6889 siginfo_t uinfo;
6891 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6892 goto efault;
6893 target_to_host_sigset(&set, p);
6894 unlock_user(p, arg1, 0);
6895 if (arg3) {
6896 puts = &uts;
6897 target_to_host_timespec(puts, arg3);
6898 } else {
6899 puts = NULL;
6901 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6902 if (!is_error(ret)) {
6903 if (arg2) {
6904 p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
6906 if (!p) {
6907 goto efault;
6909 host_to_target_siginfo(p, &uinfo);
6910 unlock_user(p, arg2, sizeof(target_siginfo_t));
6912 ret = host_to_target_signal(ret);
6915 break;
6916 case TARGET_NR_rt_sigqueueinfo:
6918 siginfo_t uinfo;
6919 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6920 goto efault;
6921 target_to_host_siginfo(&uinfo, p);
6922 unlock_user(p, arg1, 0);
6923 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6925 break;
6926 #ifdef TARGET_NR_sigreturn
6927 case TARGET_NR_sigreturn:
6928 /* NOTE: ret is eax, so not transcoding must be done */
6929 ret = do_sigreturn(cpu_env);
6930 break;
6931 #endif
6932 case TARGET_NR_rt_sigreturn:
6933 /* NOTE: ret is eax, so not transcoding must be done */
6934 ret = do_rt_sigreturn(cpu_env);
6935 break;
6936 case TARGET_NR_sethostname:
6937 if (!(p = lock_user_string(arg1)))
6938 goto efault;
6939 ret = get_errno(sethostname(p, arg2));
6940 unlock_user(p, arg1, 0);
6941 break;
6942 case TARGET_NR_setrlimit:
6944 int resource = target_to_host_resource(arg1);
6945 struct target_rlimit *target_rlim;
6946 struct rlimit rlim;
6947 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6948 goto efault;
6949 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6950 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6951 unlock_user_struct(target_rlim, arg2, 0);
6952 ret = get_errno(setrlimit(resource, &rlim));
6954 break;
6955 case TARGET_NR_getrlimit:
6957 int resource = target_to_host_resource(arg1);
6958 struct target_rlimit *target_rlim;
6959 struct rlimit rlim;
6961 ret = get_errno(getrlimit(resource, &rlim));
6962 if (!is_error(ret)) {
6963 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6964 goto efault;
6965 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6966 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6967 unlock_user_struct(target_rlim, arg2, 1);
6970 break;
6971 case TARGET_NR_getrusage:
6973 struct rusage rusage;
6974 ret = get_errno(getrusage(arg1, &rusage));
6975 if (!is_error(ret)) {
6976 ret = host_to_target_rusage(arg2, &rusage);
6979 break;
6980 case TARGET_NR_gettimeofday:
6982 struct timeval tv;
6983 ret = get_errno(gettimeofday(&tv, NULL));
6984 if (!is_error(ret)) {
6985 if (copy_to_user_timeval(arg1, &tv))
6986 goto efault;
6989 break;
6990 case TARGET_NR_settimeofday:
6992 struct timeval tv, *ptv = NULL;
6993 struct timezone tz, *ptz = NULL;
6995 if (arg1) {
6996 if (copy_from_user_timeval(&tv, arg1)) {
6997 goto efault;
6999 ptv = &tv;
7002 if (arg2) {
7003 if (copy_from_user_timezone(&tz, arg2)) {
7004 goto efault;
7006 ptz = &tz;
7009 ret = get_errno(settimeofday(ptv, ptz));
7011 break;
7012 #if defined(TARGET_NR_select)
7013 case TARGET_NR_select:
7014 #if defined(TARGET_S390X) || defined(TARGET_ALPHA)
7015 ret = do_select(arg1, arg2, arg3, arg4, arg5);
7016 #else
7018 struct target_sel_arg_struct *sel;
7019 abi_ulong inp, outp, exp, tvp;
7020 long nsel;
7022 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
7023 goto efault;
7024 nsel = tswapal(sel->n);
7025 inp = tswapal(sel->inp);
7026 outp = tswapal(sel->outp);
7027 exp = tswapal(sel->exp);
7028 tvp = tswapal(sel->tvp);
7029 unlock_user_struct(sel, arg1, 0);
7030 ret = do_select(nsel, inp, outp, exp, tvp);
7032 #endif
7033 break;
7034 #endif
7035 #ifdef TARGET_NR_pselect6
7036 case TARGET_NR_pselect6:
7038 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
7039 fd_set rfds, wfds, efds;
7040 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
7041 struct timespec ts, *ts_ptr;
7044 * The 6th arg is actually two args smashed together,
7045 * so we cannot use the C library.
7047 sigset_t set;
7048 struct {
7049 sigset_t *set;
7050 size_t size;
7051 } sig, *sig_ptr;
7053 abi_ulong arg_sigset, arg_sigsize, *arg7;
7054 target_sigset_t *target_sigset;
7056 n = arg1;
7057 rfd_addr = arg2;
7058 wfd_addr = arg3;
7059 efd_addr = arg4;
7060 ts_addr = arg5;
7062 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
7063 if (ret) {
7064 goto fail;
7066 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
7067 if (ret) {
7068 goto fail;
7070 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
7071 if (ret) {
7072 goto fail;
7076 * This takes a timespec, and not a timeval, so we cannot
7077 * use the do_select() helper ...
7079 if (ts_addr) {
7080 if (target_to_host_timespec(&ts, ts_addr)) {
7081 goto efault;
7083 ts_ptr = &ts;
7084 } else {
7085 ts_ptr = NULL;
7088 /* Extract the two packed args for the sigset */
7089 if (arg6) {
7090 sig_ptr = &sig;
7091 sig.size = _NSIG / 8;
7093 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
7094 if (!arg7) {
7095 goto efault;
7097 arg_sigset = tswapal(arg7[0]);
7098 arg_sigsize = tswapal(arg7[1]);
7099 unlock_user(arg7, arg6, 0);
7101 if (arg_sigset) {
7102 sig.set = &set;
7103 if (arg_sigsize != sizeof(*target_sigset)) {
7104 /* Like the kernel, we enforce correct size sigsets */
7105 ret = -TARGET_EINVAL;
7106 goto fail;
7108 target_sigset = lock_user(VERIFY_READ, arg_sigset,
7109 sizeof(*target_sigset), 1);
7110 if (!target_sigset) {
7111 goto efault;
7113 target_to_host_sigset(&set, target_sigset);
7114 unlock_user(target_sigset, arg_sigset, 0);
7115 } else {
7116 sig.set = NULL;
7118 } else {
7119 sig_ptr = NULL;
7122 ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
7123 ts_ptr, sig_ptr));
7125 if (!is_error(ret)) {
7126 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
7127 goto efault;
7128 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
7129 goto efault;
7130 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
7131 goto efault;
7133 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
7134 goto efault;
7137 break;
7138 #endif
7139 #ifdef TARGET_NR_symlink
7140 case TARGET_NR_symlink:
7142 void *p2;
7143 p = lock_user_string(arg1);
7144 p2 = lock_user_string(arg2);
7145 if (!p || !p2)
7146 ret = -TARGET_EFAULT;
7147 else
7148 ret = get_errno(symlink(p, p2));
7149 unlock_user(p2, arg2, 0);
7150 unlock_user(p, arg1, 0);
7152 break;
7153 #endif
7154 #if defined(TARGET_NR_symlinkat)
7155 case TARGET_NR_symlinkat:
7157 void *p2;
7158 p = lock_user_string(arg1);
7159 p2 = lock_user_string(arg3);
7160 if (!p || !p2)
7161 ret = -TARGET_EFAULT;
7162 else
7163 ret = get_errno(symlinkat(p, arg2, p2));
7164 unlock_user(p2, arg3, 0);
7165 unlock_user(p, arg1, 0);
7167 break;
7168 #endif
7169 #ifdef TARGET_NR_oldlstat
7170 case TARGET_NR_oldlstat:
7171 goto unimplemented;
7172 #endif
7173 #ifdef TARGET_NR_readlink
7174 case TARGET_NR_readlink:
7176 void *p2;
7177 p = lock_user_string(arg1);
7178 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
7179 if (!p || !p2) {
7180 ret = -TARGET_EFAULT;
7181 } else if (!arg3) {
7182 /* Short circuit this for the magic exe check. */
7183 ret = -TARGET_EINVAL;
7184 } else if (is_proc_myself((const char *)p, "exe")) {
7185 char real[PATH_MAX], *temp;
7186 temp = realpath(exec_path, real);
7187 /* Return value is # of bytes that we wrote to the buffer. */
7188 if (temp == NULL) {
7189 ret = get_errno(-1);
7190 } else {
7191 /* Don't worry about sign mismatch as earlier mapping
7192 * logic would have thrown a bad address error. */
7193 ret = MIN(strlen(real), arg3);
7194 /* We cannot NUL terminate the string. */
7195 memcpy(p2, real, ret);
7197 } else {
7198 ret = get_errno(readlink(path(p), p2, arg3));
7200 unlock_user(p2, arg2, ret);
7201 unlock_user(p, arg1, 0);
7203 break;
7204 #endif
7205 #if defined(TARGET_NR_readlinkat)
7206 case TARGET_NR_readlinkat:
7208 void *p2;
7209 p = lock_user_string(arg2);
7210 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
7211 if (!p || !p2) {
7212 ret = -TARGET_EFAULT;
7213 } else if (is_proc_myself((const char *)p, "exe")) {
7214 char real[PATH_MAX], *temp;
7215 temp = realpath(exec_path, real);
7216 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
7217 snprintf((char *)p2, arg4, "%s", real);
7218 } else {
7219 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
7221 unlock_user(p2, arg3, ret);
7222 unlock_user(p, arg2, 0);
7224 break;
7225 #endif
7226 #ifdef TARGET_NR_uselib
7227 case TARGET_NR_uselib:
7228 goto unimplemented;
7229 #endif
7230 #ifdef TARGET_NR_swapon
7231 case TARGET_NR_swapon:
7232 if (!(p = lock_user_string(arg1)))
7233 goto efault;
7234 ret = get_errno(swapon(p, arg2));
7235 unlock_user(p, arg1, 0);
7236 break;
7237 #endif
7238 case TARGET_NR_reboot:
7239 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
7240 /* arg4 must be ignored in all other cases */
7241 p = lock_user_string(arg4);
7242 if (!p) {
7243 goto efault;
7245 ret = get_errno(reboot(arg1, arg2, arg3, p));
7246 unlock_user(p, arg4, 0);
7247 } else {
7248 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
7250 break;
7251 #ifdef TARGET_NR_readdir
7252 case TARGET_NR_readdir:
7253 goto unimplemented;
7254 #endif
7255 #ifdef TARGET_NR_mmap
7256 case TARGET_NR_mmap:
7257 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
7258 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
7259 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
7260 || defined(TARGET_S390X)
7262 abi_ulong *v;
7263 abi_ulong v1, v2, v3, v4, v5, v6;
7264 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
7265 goto efault;
7266 v1 = tswapal(v[0]);
7267 v2 = tswapal(v[1]);
7268 v3 = tswapal(v[2]);
7269 v4 = tswapal(v[3]);
7270 v5 = tswapal(v[4]);
7271 v6 = tswapal(v[5]);
7272 unlock_user(v, arg1, 0);
7273 ret = get_errno(target_mmap(v1, v2, v3,
7274 target_to_host_bitmask(v4, mmap_flags_tbl),
7275 v5, v6));
7277 #else
7278 ret = get_errno(target_mmap(arg1, arg2, arg3,
7279 target_to_host_bitmask(arg4, mmap_flags_tbl),
7280 arg5,
7281 arg6));
7282 #endif
7283 break;
7284 #endif
7285 #ifdef TARGET_NR_mmap2
7286 case TARGET_NR_mmap2:
7287 #ifndef MMAP_SHIFT
7288 #define MMAP_SHIFT 12
7289 #endif
7290 ret = get_errno(target_mmap(arg1, arg2, arg3,
7291 target_to_host_bitmask(arg4, mmap_flags_tbl),
7292 arg5,
7293 arg6 << MMAP_SHIFT));
7294 break;
7295 #endif
7296 case TARGET_NR_munmap:
7297 ret = get_errno(target_munmap(arg1, arg2));
7298 break;
7299 case TARGET_NR_mprotect:
7301 TaskState *ts = cpu->opaque;
7302 /* Special hack to detect libc making the stack executable. */
7303 if ((arg3 & PROT_GROWSDOWN)
7304 && arg1 >= ts->info->stack_limit
7305 && arg1 <= ts->info->start_stack) {
7306 arg3 &= ~PROT_GROWSDOWN;
7307 arg2 = arg2 + arg1 - ts->info->stack_limit;
7308 arg1 = ts->info->stack_limit;
7311 ret = get_errno(target_mprotect(arg1, arg2, arg3));
7312 break;
7313 #ifdef TARGET_NR_mremap
7314 case TARGET_NR_mremap:
7315 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
7316 break;
7317 #endif
7318 /* ??? msync/mlock/munlock are broken for softmmu. */
7319 #ifdef TARGET_NR_msync
7320 case TARGET_NR_msync:
7321 ret = get_errno(msync(g2h(arg1), arg2, arg3));
7322 break;
7323 #endif
7324 #ifdef TARGET_NR_mlock
7325 case TARGET_NR_mlock:
7326 ret = get_errno(mlock(g2h(arg1), arg2));
7327 break;
7328 #endif
7329 #ifdef TARGET_NR_munlock
7330 case TARGET_NR_munlock:
7331 ret = get_errno(munlock(g2h(arg1), arg2));
7332 break;
7333 #endif
7334 #ifdef TARGET_NR_mlockall
7335 case TARGET_NR_mlockall:
7336 ret = get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
7337 break;
7338 #endif
7339 #ifdef TARGET_NR_munlockall
7340 case TARGET_NR_munlockall:
7341 ret = get_errno(munlockall());
7342 break;
7343 #endif
7344 case TARGET_NR_truncate:
7345 if (!(p = lock_user_string(arg1)))
7346 goto efault;
7347 ret = get_errno(truncate(p, arg2));
7348 unlock_user(p, arg1, 0);
7349 break;
7350 case TARGET_NR_ftruncate:
7351 ret = get_errno(ftruncate(arg1, arg2));
7352 break;
7353 case TARGET_NR_fchmod:
7354 ret = get_errno(fchmod(arg1, arg2));
7355 break;
7356 #if defined(TARGET_NR_fchmodat)
7357 case TARGET_NR_fchmodat:
7358 if (!(p = lock_user_string(arg2)))
7359 goto efault;
7360 ret = get_errno(fchmodat(arg1, p, arg3, 0));
7361 unlock_user(p, arg2, 0);
7362 break;
7363 #endif
7364 case TARGET_NR_getpriority:
7365 /* Note that negative values are valid for getpriority, so we must
7366 differentiate based on errno settings. */
7367 errno = 0;
7368 ret = getpriority(arg1, arg2);
7369 if (ret == -1 && errno != 0) {
7370 ret = -host_to_target_errno(errno);
7371 break;
7373 #ifdef TARGET_ALPHA
7374 /* Return value is the unbiased priority. Signal no error. */
7375 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
7376 #else
7377 /* Return value is a biased priority to avoid negative numbers. */
7378 ret = 20 - ret;
7379 #endif
7380 break;
7381 case TARGET_NR_setpriority:
7382 ret = get_errno(setpriority(arg1, arg2, arg3));
7383 break;
7384 #ifdef TARGET_NR_profil
7385 case TARGET_NR_profil:
7386 goto unimplemented;
7387 #endif
7388 case TARGET_NR_statfs:
7389 if (!(p = lock_user_string(arg1)))
7390 goto efault;
7391 ret = get_errno(statfs(path(p), &stfs));
7392 unlock_user(p, arg1, 0);
7393 convert_statfs:
7394 if (!is_error(ret)) {
7395 struct target_statfs *target_stfs;
7397 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
7398 goto efault;
7399 __put_user(stfs.f_type, &target_stfs->f_type);
7400 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
7401 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
7402 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
7403 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
7404 __put_user(stfs.f_files, &target_stfs->f_files);
7405 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
7406 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
7407 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
7408 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
7409 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
7410 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
7411 unlock_user_struct(target_stfs, arg2, 1);
7413 break;
7414 case TARGET_NR_fstatfs:
7415 ret = get_errno(fstatfs(arg1, &stfs));
7416 goto convert_statfs;
7417 #ifdef TARGET_NR_statfs64
7418 case TARGET_NR_statfs64:
7419 if (!(p = lock_user_string(arg1)))
7420 goto efault;
7421 ret = get_errno(statfs(path(p), &stfs));
7422 unlock_user(p, arg1, 0);
7423 convert_statfs64:
7424 if (!is_error(ret)) {
7425 struct target_statfs64 *target_stfs;
7427 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
7428 goto efault;
7429 __put_user(stfs.f_type, &target_stfs->f_type);
7430 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
7431 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
7432 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
7433 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
7434 __put_user(stfs.f_files, &target_stfs->f_files);
7435 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
7436 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
7437 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
7438 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
7439 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
7440 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
7441 unlock_user_struct(target_stfs, arg3, 1);
7443 break;
7444 case TARGET_NR_fstatfs64:
7445 ret = get_errno(fstatfs(arg1, &stfs));
7446 goto convert_statfs64;
7447 #endif
7448 #ifdef TARGET_NR_ioperm
7449 case TARGET_NR_ioperm:
7450 goto unimplemented;
7451 #endif
7452 #ifdef TARGET_NR_socketcall
7453 case TARGET_NR_socketcall:
7454 ret = do_socketcall(arg1, arg2);
7455 break;
7456 #endif
7457 #ifdef TARGET_NR_accept
7458 case TARGET_NR_accept:
7459 ret = do_accept4(arg1, arg2, arg3, 0);
7460 break;
7461 #endif
7462 #ifdef TARGET_NR_accept4
7463 case TARGET_NR_accept4:
7464 #ifdef CONFIG_ACCEPT4
7465 ret = do_accept4(arg1, arg2, arg3, arg4);
7466 #else
7467 goto unimplemented;
7468 #endif
7469 break;
7470 #endif
7471 #ifdef TARGET_NR_bind
7472 case TARGET_NR_bind:
7473 ret = do_bind(arg1, arg2, arg3);
7474 break;
7475 #endif
7476 #ifdef TARGET_NR_connect
7477 case TARGET_NR_connect:
7478 ret = do_connect(arg1, arg2, arg3);
7479 break;
7480 #endif
7481 #ifdef TARGET_NR_getpeername
7482 case TARGET_NR_getpeername:
7483 ret = do_getpeername(arg1, arg2, arg3);
7484 break;
7485 #endif
7486 #ifdef TARGET_NR_getsockname
7487 case TARGET_NR_getsockname:
7488 ret = do_getsockname(arg1, arg2, arg3);
7489 break;
7490 #endif
7491 #ifdef TARGET_NR_getsockopt
7492 case TARGET_NR_getsockopt:
7493 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
7494 break;
7495 #endif
7496 #ifdef TARGET_NR_listen
7497 case TARGET_NR_listen:
7498 ret = get_errno(listen(arg1, arg2));
7499 break;
7500 #endif
7501 #ifdef TARGET_NR_recv
7502 case TARGET_NR_recv:
7503 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
7504 break;
7505 #endif
7506 #ifdef TARGET_NR_recvfrom
7507 case TARGET_NR_recvfrom:
7508 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
7509 break;
7510 #endif
7511 #ifdef TARGET_NR_recvmsg
7512 case TARGET_NR_recvmsg:
7513 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
7514 break;
7515 #endif
7516 #ifdef TARGET_NR_send
7517 case TARGET_NR_send:
7518 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
7519 break;
7520 #endif
7521 #ifdef TARGET_NR_sendmsg
7522 case TARGET_NR_sendmsg:
7523 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
7524 break;
7525 #endif
7526 #ifdef TARGET_NR_sendmmsg
7527 case TARGET_NR_sendmmsg:
7528 ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
7529 break;
7530 case TARGET_NR_recvmmsg:
7531 ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
7532 break;
7533 #endif
7534 #ifdef TARGET_NR_sendto
7535 case TARGET_NR_sendto:
7536 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
7537 break;
7538 #endif
7539 #ifdef TARGET_NR_shutdown
7540 case TARGET_NR_shutdown:
7541 ret = get_errno(shutdown(arg1, arg2));
7542 break;
7543 #endif
7544 #ifdef TARGET_NR_socket
7545 case TARGET_NR_socket:
7546 ret = do_socket(arg1, arg2, arg3);
7547 fd_trans_unregister(ret);
7548 break;
7549 #endif
7550 #ifdef TARGET_NR_socketpair
7551 case TARGET_NR_socketpair:
7552 ret = do_socketpair(arg1, arg2, arg3, arg4);
7553 break;
7554 #endif
7555 #ifdef TARGET_NR_setsockopt
7556 case TARGET_NR_setsockopt:
7557 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
7558 break;
7559 #endif
7561 case TARGET_NR_syslog:
7562 if (!(p = lock_user_string(arg2)))
7563 goto efault;
7564 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
7565 unlock_user(p, arg2, 0);
7566 break;
7568 case TARGET_NR_setitimer:
7570 struct itimerval value, ovalue, *pvalue;
7572 if (arg2) {
7573 pvalue = &value;
7574 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
7575 || copy_from_user_timeval(&pvalue->it_value,
7576 arg2 + sizeof(struct target_timeval)))
7577 goto efault;
7578 } else {
7579 pvalue = NULL;
7581 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
7582 if (!is_error(ret) && arg3) {
7583 if (copy_to_user_timeval(arg3,
7584 &ovalue.it_interval)
7585 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
7586 &ovalue.it_value))
7587 goto efault;
7590 break;
7591 case TARGET_NR_getitimer:
7593 struct itimerval value;
7595 ret = get_errno(getitimer(arg1, &value));
7596 if (!is_error(ret) && arg2) {
7597 if (copy_to_user_timeval(arg2,
7598 &value.it_interval)
7599 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
7600 &value.it_value))
7601 goto efault;
7604 break;
7605 #ifdef TARGET_NR_stat
7606 case TARGET_NR_stat:
7607 if (!(p = lock_user_string(arg1)))
7608 goto efault;
7609 ret = get_errno(stat(path(p), &st));
7610 unlock_user(p, arg1, 0);
7611 goto do_stat;
7612 #endif
7613 #ifdef TARGET_NR_lstat
7614 case TARGET_NR_lstat:
7615 if (!(p = lock_user_string(arg1)))
7616 goto efault;
7617 ret = get_errno(lstat(path(p), &st));
7618 unlock_user(p, arg1, 0);
7619 goto do_stat;
7620 #endif
7621 case TARGET_NR_fstat:
7623 ret = get_errno(fstat(arg1, &st));
7624 #if defined(TARGET_NR_stat) || defined(TARGET_NR_lstat)
7625 do_stat:
7626 #endif
7627 if (!is_error(ret)) {
7628 struct target_stat *target_st;
7630 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
7631 goto efault;
7632 memset(target_st, 0, sizeof(*target_st));
7633 __put_user(st.st_dev, &target_st->st_dev);
7634 __put_user(st.st_ino, &target_st->st_ino);
7635 __put_user(st.st_mode, &target_st->st_mode);
7636 __put_user(st.st_uid, &target_st->st_uid);
7637 __put_user(st.st_gid, &target_st->st_gid);
7638 __put_user(st.st_nlink, &target_st->st_nlink);
7639 __put_user(st.st_rdev, &target_st->st_rdev);
7640 __put_user(st.st_size, &target_st->st_size);
7641 __put_user(st.st_blksize, &target_st->st_blksize);
7642 __put_user(st.st_blocks, &target_st->st_blocks);
7643 __put_user(st.st_atime, &target_st->target_st_atime);
7644 __put_user(st.st_mtime, &target_st->target_st_mtime);
7645 __put_user(st.st_ctime, &target_st->target_st_ctime);
7646 unlock_user_struct(target_st, arg2, 1);
7649 break;
7650 #ifdef TARGET_NR_olduname
7651 case TARGET_NR_olduname:
7652 goto unimplemented;
7653 #endif
7654 #ifdef TARGET_NR_iopl
7655 case TARGET_NR_iopl:
7656 goto unimplemented;
7657 #endif
7658 case TARGET_NR_vhangup:
7659 ret = get_errno(vhangup());
7660 break;
7661 #ifdef TARGET_NR_idle
7662 case TARGET_NR_idle:
7663 goto unimplemented;
7664 #endif
7665 #ifdef TARGET_NR_syscall
7666 case TARGET_NR_syscall:
7667 ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
7668 arg6, arg7, arg8, 0);
7669 break;
7670 #endif
7671 case TARGET_NR_wait4:
7673 int status;
7674 abi_long status_ptr = arg2;
7675 struct rusage rusage, *rusage_ptr;
7676 abi_ulong target_rusage = arg4;
7677 abi_long rusage_err;
7678 if (target_rusage)
7679 rusage_ptr = &rusage;
7680 else
7681 rusage_ptr = NULL;
7682 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
7683 if (!is_error(ret)) {
7684 if (status_ptr && ret) {
7685 status = host_to_target_waitstatus(status);
7686 if (put_user_s32(status, status_ptr))
7687 goto efault;
7689 if (target_rusage) {
7690 rusage_err = host_to_target_rusage(target_rusage, &rusage);
7691 if (rusage_err) {
7692 ret = rusage_err;
7697 break;
7698 #ifdef TARGET_NR_swapoff
7699 case TARGET_NR_swapoff:
7700 if (!(p = lock_user_string(arg1)))
7701 goto efault;
7702 ret = get_errno(swapoff(p));
7703 unlock_user(p, arg1, 0);
7704 break;
7705 #endif
7706 case TARGET_NR_sysinfo:
7708 struct target_sysinfo *target_value;
7709 struct sysinfo value;
7710 ret = get_errno(sysinfo(&value));
7711 if (!is_error(ret) && arg1)
7713 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
7714 goto efault;
7715 __put_user(value.uptime, &target_value->uptime);
7716 __put_user(value.loads[0], &target_value->loads[0]);
7717 __put_user(value.loads[1], &target_value->loads[1]);
7718 __put_user(value.loads[2], &target_value->loads[2]);
7719 __put_user(value.totalram, &target_value->totalram);
7720 __put_user(value.freeram, &target_value->freeram);
7721 __put_user(value.sharedram, &target_value->sharedram);
7722 __put_user(value.bufferram, &target_value->bufferram);
7723 __put_user(value.totalswap, &target_value->totalswap);
7724 __put_user(value.freeswap, &target_value->freeswap);
7725 __put_user(value.procs, &target_value->procs);
7726 __put_user(value.totalhigh, &target_value->totalhigh);
7727 __put_user(value.freehigh, &target_value->freehigh);
7728 __put_user(value.mem_unit, &target_value->mem_unit);
7729 unlock_user_struct(target_value, arg1, 1);
7732 break;
7733 #ifdef TARGET_NR_ipc
7734 case TARGET_NR_ipc:
7735 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
7736 break;
7737 #endif
7738 #ifdef TARGET_NR_semget
7739 case TARGET_NR_semget:
7740 ret = get_errno(semget(arg1, arg2, arg3));
7741 break;
7742 #endif
7743 #ifdef TARGET_NR_semop
7744 case TARGET_NR_semop:
7745 ret = do_semop(arg1, arg2, arg3);
7746 break;
7747 #endif
7748 #ifdef TARGET_NR_semctl
7749 case TARGET_NR_semctl:
7750 ret = do_semctl(arg1, arg2, arg3, arg4);
7751 break;
7752 #endif
7753 #ifdef TARGET_NR_msgctl
7754 case TARGET_NR_msgctl:
7755 ret = do_msgctl(arg1, arg2, arg3);
7756 break;
7757 #endif
7758 #ifdef TARGET_NR_msgget
7759 case TARGET_NR_msgget:
7760 ret = get_errno(msgget(arg1, arg2));
7761 break;
7762 #endif
7763 #ifdef TARGET_NR_msgrcv
7764 case TARGET_NR_msgrcv:
7765 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
7766 break;
7767 #endif
7768 #ifdef TARGET_NR_msgsnd
7769 case TARGET_NR_msgsnd:
7770 ret = do_msgsnd(arg1, arg2, arg3, arg4);
7771 break;
7772 #endif
7773 #ifdef TARGET_NR_shmget
7774 case TARGET_NR_shmget:
7775 ret = get_errno(shmget(arg1, arg2, arg3));
7776 break;
7777 #endif
7778 #ifdef TARGET_NR_shmctl
7779 case TARGET_NR_shmctl:
7780 ret = do_shmctl(arg1, arg2, arg3);
7781 break;
7782 #endif
7783 #ifdef TARGET_NR_shmat
7784 case TARGET_NR_shmat:
7785 ret = do_shmat(arg1, arg2, arg3);
7786 break;
7787 #endif
7788 #ifdef TARGET_NR_shmdt
7789 case TARGET_NR_shmdt:
7790 ret = do_shmdt(arg1);
7791 break;
7792 #endif
7793 case TARGET_NR_fsync:
7794 ret = get_errno(fsync(arg1));
7795 break;
7796 case TARGET_NR_clone:
7797 /* Linux manages to have three different orderings for its
7798 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
7799 * match the kernel's CONFIG_CLONE_* settings.
7800 * Microblaze is further special in that it uses a sixth
7801 * implicit argument to clone for the TLS pointer.
7803 #if defined(TARGET_MICROBLAZE)
7804 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
7805 #elif defined(TARGET_CLONE_BACKWARDS)
7806 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
7807 #elif defined(TARGET_CLONE_BACKWARDS2)
7808 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
7809 #else
7810 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
7811 #endif
7812 break;
7813 #ifdef __NR_exit_group
7814 /* new thread calls */
7815 case TARGET_NR_exit_group:
7816 #ifdef TARGET_GPROF
7817 _mcleanup();
7818 #endif
7819 gdb_exit(cpu_env, arg1);
7820 ret = get_errno(exit_group(arg1));
7821 break;
7822 #endif
7823 case TARGET_NR_setdomainname:
7824 if (!(p = lock_user_string(arg1)))
7825 goto efault;
7826 ret = get_errno(setdomainname(p, arg2));
7827 unlock_user(p, arg1, 0);
7828 break;
7829 case TARGET_NR_uname:
7830 /* no need to transcode because we use the linux syscall */
7832 struct new_utsname * buf;
7834 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
7835 goto efault;
7836 ret = get_errno(sys_uname(buf));
7837 if (!is_error(ret)) {
7838 /* Overrite the native machine name with whatever is being
7839 emulated. */
7840 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
7841 /* Allow the user to override the reported release. */
7842 if (qemu_uname_release && *qemu_uname_release)
7843 strcpy (buf->release, qemu_uname_release);
7845 unlock_user_struct(buf, arg1, 1);
7847 break;
7848 #ifdef TARGET_I386
7849 case TARGET_NR_modify_ldt:
7850 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
7851 break;
7852 #if !defined(TARGET_X86_64)
7853 case TARGET_NR_vm86old:
7854 goto unimplemented;
7855 case TARGET_NR_vm86:
7856 ret = do_vm86(cpu_env, arg1, arg2);
7857 break;
7858 #endif
7859 #endif
7860 case TARGET_NR_adjtimex:
7861 goto unimplemented;
7862 #ifdef TARGET_NR_create_module
7863 case TARGET_NR_create_module:
7864 #endif
7865 case TARGET_NR_init_module:
7866 case TARGET_NR_delete_module:
7867 #ifdef TARGET_NR_get_kernel_syms
7868 case TARGET_NR_get_kernel_syms:
7869 #endif
7870 goto unimplemented;
7871 case TARGET_NR_quotactl:
7872 goto unimplemented;
7873 case TARGET_NR_getpgid:
7874 ret = get_errno(getpgid(arg1));
7875 break;
7876 case TARGET_NR_fchdir:
7877 ret = get_errno(fchdir(arg1));
7878 break;
7879 #ifdef TARGET_NR_bdflush /* not on x86_64 */
7880 case TARGET_NR_bdflush:
7881 goto unimplemented;
7882 #endif
7883 #ifdef TARGET_NR_sysfs
7884 case TARGET_NR_sysfs:
7885 goto unimplemented;
7886 #endif
7887 case TARGET_NR_personality:
7888 ret = get_errno(personality(arg1));
7889 break;
7890 #ifdef TARGET_NR_afs_syscall
7891 case TARGET_NR_afs_syscall:
7892 goto unimplemented;
7893 #endif
7894 #ifdef TARGET_NR__llseek /* Not on alpha */
7895 case TARGET_NR__llseek:
7897 int64_t res;
7898 #if !defined(__NR_llseek)
7899 res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7900 if (res == -1) {
7901 ret = get_errno(res);
7902 } else {
7903 ret = 0;
7905 #else
7906 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7907 #endif
7908 if ((ret == 0) && put_user_s64(res, arg4)) {
7909 goto efault;
7912 break;
7913 #endif
7914 #ifdef TARGET_NR_getdents
7915 case TARGET_NR_getdents:
7916 #ifdef __NR_getdents
7917 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7919 struct target_dirent *target_dirp;
7920 struct linux_dirent *dirp;
7921 abi_long count = arg3;
7923 dirp = g_try_malloc(count);
7924 if (!dirp) {
7925 ret = -TARGET_ENOMEM;
7926 goto fail;
7929 ret = get_errno(sys_getdents(arg1, dirp, count));
7930 if (!is_error(ret)) {
7931 struct linux_dirent *de;
7932 struct target_dirent *tde;
7933 int len = ret;
7934 int reclen, treclen;
7935 int count1, tnamelen;
7937 count1 = 0;
7938 de = dirp;
7939 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7940 goto efault;
7941 tde = target_dirp;
7942 while (len > 0) {
7943 reclen = de->d_reclen;
7944 tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7945 assert(tnamelen >= 0);
7946 treclen = tnamelen + offsetof(struct target_dirent, d_name);
7947 assert(count1 + treclen <= count);
7948 tde->d_reclen = tswap16(treclen);
7949 tde->d_ino = tswapal(de->d_ino);
7950 tde->d_off = tswapal(de->d_off);
7951 memcpy(tde->d_name, de->d_name, tnamelen);
7952 de = (struct linux_dirent *)((char *)de + reclen);
7953 len -= reclen;
7954 tde = (struct target_dirent *)((char *)tde + treclen);
7955 count1 += treclen;
7957 ret = count1;
7958 unlock_user(target_dirp, arg2, ret);
7960 g_free(dirp);
7962 #else
7964 struct linux_dirent *dirp;
7965 abi_long count = arg3;
7967 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7968 goto efault;
7969 ret = get_errno(sys_getdents(arg1, dirp, count));
7970 if (!is_error(ret)) {
7971 struct linux_dirent *de;
7972 int len = ret;
7973 int reclen;
7974 de = dirp;
7975 while (len > 0) {
7976 reclen = de->d_reclen;
7977 if (reclen > len)
7978 break;
7979 de->d_reclen = tswap16(reclen);
7980 tswapls(&de->d_ino);
7981 tswapls(&de->d_off);
7982 de = (struct linux_dirent *)((char *)de + reclen);
7983 len -= reclen;
7986 unlock_user(dirp, arg2, ret);
7988 #endif
7989 #else
7990 /* Implement getdents in terms of getdents64 */
7992 struct linux_dirent64 *dirp;
7993 abi_long count = arg3;
7995 dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7996 if (!dirp) {
7997 goto efault;
7999 ret = get_errno(sys_getdents64(arg1, dirp, count));
8000 if (!is_error(ret)) {
8001 /* Convert the dirent64 structs to target dirent. We do this
8002 * in-place, since we can guarantee that a target_dirent is no
8003 * larger than a dirent64; however this means we have to be
8004 * careful to read everything before writing in the new format.
8006 struct linux_dirent64 *de;
8007 struct target_dirent *tde;
8008 int len = ret;
8009 int tlen = 0;
8011 de = dirp;
8012 tde = (struct target_dirent *)dirp;
8013 while (len > 0) {
8014 int namelen, treclen;
8015 int reclen = de->d_reclen;
8016 uint64_t ino = de->d_ino;
8017 int64_t off = de->d_off;
8018 uint8_t type = de->d_type;
8020 namelen = strlen(de->d_name);
8021 treclen = offsetof(struct target_dirent, d_name)
8022 + namelen + 2;
8023 treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
8025 memmove(tde->d_name, de->d_name, namelen + 1);
8026 tde->d_ino = tswapal(ino);
8027 tde->d_off = tswapal(off);
8028 tde->d_reclen = tswap16(treclen);
8029 /* The target_dirent type is in what was formerly a padding
8030 * byte at the end of the structure:
8032 *(((char *)tde) + treclen - 1) = type;
8034 de = (struct linux_dirent64 *)((char *)de + reclen);
8035 tde = (struct target_dirent *)((char *)tde + treclen);
8036 len -= reclen;
8037 tlen += treclen;
8039 ret = tlen;
8041 unlock_user(dirp, arg2, ret);
8043 #endif
8044 break;
8045 #endif /* TARGET_NR_getdents */
8046 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
8047 case TARGET_NR_getdents64:
8049 struct linux_dirent64 *dirp;
8050 abi_long count = arg3;
8051 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
8052 goto efault;
8053 ret = get_errno(sys_getdents64(arg1, dirp, count));
8054 if (!is_error(ret)) {
8055 struct linux_dirent64 *de;
8056 int len = ret;
8057 int reclen;
8058 de = dirp;
8059 while (len > 0) {
8060 reclen = de->d_reclen;
8061 if (reclen > len)
8062 break;
8063 de->d_reclen = tswap16(reclen);
8064 tswap64s((uint64_t *)&de->d_ino);
8065 tswap64s((uint64_t *)&de->d_off);
8066 de = (struct linux_dirent64 *)((char *)de + reclen);
8067 len -= reclen;
8070 unlock_user(dirp, arg2, ret);
8072 break;
8073 #endif /* TARGET_NR_getdents64 */
8074 #if defined(TARGET_NR__newselect)
8075 case TARGET_NR__newselect:
8076 ret = do_select(arg1, arg2, arg3, arg4, arg5);
8077 break;
8078 #endif
8079 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
8080 # ifdef TARGET_NR_poll
8081 case TARGET_NR_poll:
8082 # endif
8083 # ifdef TARGET_NR_ppoll
8084 case TARGET_NR_ppoll:
8085 # endif
8087 struct target_pollfd *target_pfd;
8088 unsigned int nfds = arg2;
8089 int timeout = arg3;
8090 struct pollfd *pfd;
8091 unsigned int i;
8093 pfd = NULL;
8094 target_pfd = NULL;
8095 if (nfds) {
8096 target_pfd = lock_user(VERIFY_WRITE, arg1,
8097 sizeof(struct target_pollfd) * nfds, 1);
8098 if (!target_pfd) {
8099 goto efault;
8102 pfd = alloca(sizeof(struct pollfd) * nfds);
8103 for (i = 0; i < nfds; i++) {
8104 pfd[i].fd = tswap32(target_pfd[i].fd);
8105 pfd[i].events = tswap16(target_pfd[i].events);
8109 # ifdef TARGET_NR_ppoll
8110 if (num == TARGET_NR_ppoll) {
8111 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
8112 target_sigset_t *target_set;
8113 sigset_t _set, *set = &_set;
8115 if (arg3) {
8116 if (target_to_host_timespec(timeout_ts, arg3)) {
8117 unlock_user(target_pfd, arg1, 0);
8118 goto efault;
8120 } else {
8121 timeout_ts = NULL;
8124 if (arg4) {
8125 target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
8126 if (!target_set) {
8127 unlock_user(target_pfd, arg1, 0);
8128 goto efault;
8130 target_to_host_sigset(set, target_set);
8131 } else {
8132 set = NULL;
8135 ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
8137 if (!is_error(ret) && arg3) {
8138 host_to_target_timespec(arg3, timeout_ts);
8140 if (arg4) {
8141 unlock_user(target_set, arg4, 0);
8143 } else
8144 # endif
8145 ret = get_errno(poll(pfd, nfds, timeout));
8147 if (!is_error(ret)) {
8148 for(i = 0; i < nfds; i++) {
8149 target_pfd[i].revents = tswap16(pfd[i].revents);
8152 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
8154 break;
8155 #endif
8156 case TARGET_NR_flock:
8157 /* NOTE: the flock constant seems to be the same for every
8158 Linux platform */
8159 ret = get_errno(flock(arg1, arg2));
8160 break;
8161 case TARGET_NR_readv:
8163 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
8164 if (vec != NULL) {
8165 ret = get_errno(readv(arg1, vec, arg3));
8166 unlock_iovec(vec, arg2, arg3, 1);
8167 } else {
8168 ret = -host_to_target_errno(errno);
8171 break;
8172 case TARGET_NR_writev:
8174 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
8175 if (vec != NULL) {
8176 ret = get_errno(writev(arg1, vec, arg3));
8177 unlock_iovec(vec, arg2, arg3, 0);
8178 } else {
8179 ret = -host_to_target_errno(errno);
8182 break;
8183 case TARGET_NR_getsid:
8184 ret = get_errno(getsid(arg1));
8185 break;
8186 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
8187 case TARGET_NR_fdatasync:
8188 ret = get_errno(fdatasync(arg1));
8189 break;
8190 #endif
8191 #ifdef TARGET_NR__sysctl
8192 case TARGET_NR__sysctl:
8193 /* We don't implement this, but ENOTDIR is always a safe
8194 return value. */
8195 ret = -TARGET_ENOTDIR;
8196 break;
8197 #endif
8198 case TARGET_NR_sched_getaffinity:
8200 unsigned int mask_size;
8201 unsigned long *mask;
8204 * sched_getaffinity needs multiples of ulong, so need to take
8205 * care of mismatches between target ulong and host ulong sizes.
8207 if (arg2 & (sizeof(abi_ulong) - 1)) {
8208 ret = -TARGET_EINVAL;
8209 break;
8211 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
8213 mask = alloca(mask_size);
8214 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
8216 if (!is_error(ret)) {
8217 if (ret > arg2) {
8218 /* More data returned than the caller's buffer will fit.
8219 * This only happens if sizeof(abi_long) < sizeof(long)
8220 * and the caller passed us a buffer holding an odd number
8221 * of abi_longs. If the host kernel is actually using the
8222 * extra 4 bytes then fail EINVAL; otherwise we can just
8223 * ignore them and only copy the interesting part.
8225 int numcpus = sysconf(_SC_NPROCESSORS_CONF);
8226 if (numcpus > arg2 * 8) {
8227 ret = -TARGET_EINVAL;
8228 break;
8230 ret = arg2;
8233 if (copy_to_user(arg3, mask, ret)) {
8234 goto efault;
8238 break;
8239 case TARGET_NR_sched_setaffinity:
8241 unsigned int mask_size;
8242 unsigned long *mask;
8245 * sched_setaffinity needs multiples of ulong, so need to take
8246 * care of mismatches between target ulong and host ulong sizes.
8248 if (arg2 & (sizeof(abi_ulong) - 1)) {
8249 ret = -TARGET_EINVAL;
8250 break;
8252 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
8254 mask = alloca(mask_size);
8255 if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
8256 goto efault;
8258 memcpy(mask, p, arg2);
8259 unlock_user_struct(p, arg2, 0);
8261 ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
8263 break;
8264 case TARGET_NR_sched_setparam:
8266 struct sched_param *target_schp;
8267 struct sched_param schp;
8269 if (arg2 == 0) {
8270 return -TARGET_EINVAL;
8272 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
8273 goto efault;
8274 schp.sched_priority = tswap32(target_schp->sched_priority);
8275 unlock_user_struct(target_schp, arg2, 0);
8276 ret = get_errno(sched_setparam(arg1, &schp));
8278 break;
8279 case TARGET_NR_sched_getparam:
8281 struct sched_param *target_schp;
8282 struct sched_param schp;
8284 if (arg2 == 0) {
8285 return -TARGET_EINVAL;
8287 ret = get_errno(sched_getparam(arg1, &schp));
8288 if (!is_error(ret)) {
8289 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
8290 goto efault;
8291 target_schp->sched_priority = tswap32(schp.sched_priority);
8292 unlock_user_struct(target_schp, arg2, 1);
8295 break;
8296 case TARGET_NR_sched_setscheduler:
8298 struct sched_param *target_schp;
8299 struct sched_param schp;
8300 if (arg3 == 0) {
8301 return -TARGET_EINVAL;
8303 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
8304 goto efault;
8305 schp.sched_priority = tswap32(target_schp->sched_priority);
8306 unlock_user_struct(target_schp, arg3, 0);
8307 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
8309 break;
8310 case TARGET_NR_sched_getscheduler:
8311 ret = get_errno(sched_getscheduler(arg1));
8312 break;
8313 case TARGET_NR_sched_yield:
8314 ret = get_errno(sched_yield());
8315 break;
8316 case TARGET_NR_sched_get_priority_max:
8317 ret = get_errno(sched_get_priority_max(arg1));
8318 break;
8319 case TARGET_NR_sched_get_priority_min:
8320 ret = get_errno(sched_get_priority_min(arg1));
8321 break;
8322 case TARGET_NR_sched_rr_get_interval:
8324 struct timespec ts;
8325 ret = get_errno(sched_rr_get_interval(arg1, &ts));
8326 if (!is_error(ret)) {
8327 ret = host_to_target_timespec(arg2, &ts);
8330 break;
8331 case TARGET_NR_nanosleep:
8333 struct timespec req, rem;
8334 target_to_host_timespec(&req, arg1);
8335 ret = get_errno(nanosleep(&req, &rem));
8336 if (is_error(ret) && arg2) {
8337 host_to_target_timespec(arg2, &rem);
8340 break;
8341 #ifdef TARGET_NR_query_module
8342 case TARGET_NR_query_module:
8343 goto unimplemented;
8344 #endif
8345 #ifdef TARGET_NR_nfsservctl
8346 case TARGET_NR_nfsservctl:
8347 goto unimplemented;
8348 #endif
8349 case TARGET_NR_prctl:
8350 switch (arg1) {
8351 case PR_GET_PDEATHSIG:
8353 int deathsig;
8354 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
8355 if (!is_error(ret) && arg2
8356 && put_user_ual(deathsig, arg2)) {
8357 goto efault;
8359 break;
8361 #ifdef PR_GET_NAME
8362 case PR_GET_NAME:
8364 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
8365 if (!name) {
8366 goto efault;
8368 ret = get_errno(prctl(arg1, (unsigned long)name,
8369 arg3, arg4, arg5));
8370 unlock_user(name, arg2, 16);
8371 break;
8373 case PR_SET_NAME:
8375 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
8376 if (!name) {
8377 goto efault;
8379 ret = get_errno(prctl(arg1, (unsigned long)name,
8380 arg3, arg4, arg5));
8381 unlock_user(name, arg2, 0);
8382 break;
8384 #endif
8385 default:
8386 /* Most prctl options have no pointer arguments */
8387 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
8388 break;
8390 break;
8391 #ifdef TARGET_NR_arch_prctl
8392 case TARGET_NR_arch_prctl:
8393 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
8394 ret = do_arch_prctl(cpu_env, arg1, arg2);
8395 break;
8396 #else
8397 goto unimplemented;
8398 #endif
8399 #endif
8400 #ifdef TARGET_NR_pread64
8401 case TARGET_NR_pread64:
8402 if (regpairs_aligned(cpu_env)) {
8403 arg4 = arg5;
8404 arg5 = arg6;
8406 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
8407 goto efault;
8408 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
8409 unlock_user(p, arg2, ret);
8410 break;
8411 case TARGET_NR_pwrite64:
8412 if (regpairs_aligned(cpu_env)) {
8413 arg4 = arg5;
8414 arg5 = arg6;
8416 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
8417 goto efault;
8418 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
8419 unlock_user(p, arg2, 0);
8420 break;
8421 #endif
8422 case TARGET_NR_getcwd:
8423 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
8424 goto efault;
8425 ret = get_errno(sys_getcwd1(p, arg2));
8426 unlock_user(p, arg1, ret);
8427 break;
8428 case TARGET_NR_capget:
8429 case TARGET_NR_capset:
8431 struct target_user_cap_header *target_header;
8432 struct target_user_cap_data *target_data = NULL;
8433 struct __user_cap_header_struct header;
8434 struct __user_cap_data_struct data[2];
8435 struct __user_cap_data_struct *dataptr = NULL;
8436 int i, target_datalen;
8437 int data_items = 1;
8439 if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
8440 goto efault;
8442 header.version = tswap32(target_header->version);
8443 header.pid = tswap32(target_header->pid);
8445 if (header.version != _LINUX_CAPABILITY_VERSION) {
8446 /* Version 2 and up takes pointer to two user_data structs */
8447 data_items = 2;
8450 target_datalen = sizeof(*target_data) * data_items;
8452 if (arg2) {
8453 if (num == TARGET_NR_capget) {
8454 target_data = lock_user(VERIFY_WRITE, arg2, target_datalen, 0);
8455 } else {
8456 target_data = lock_user(VERIFY_READ, arg2, target_datalen, 1);
8458 if (!target_data) {
8459 unlock_user_struct(target_header, arg1, 0);
8460 goto efault;
8463 if (num == TARGET_NR_capset) {
8464 for (i = 0; i < data_items; i++) {
8465 data[i].effective = tswap32(target_data[i].effective);
8466 data[i].permitted = tswap32(target_data[i].permitted);
8467 data[i].inheritable = tswap32(target_data[i].inheritable);
8471 dataptr = data;
8474 if (num == TARGET_NR_capget) {
8475 ret = get_errno(capget(&header, dataptr));
8476 } else {
8477 ret = get_errno(capset(&header, dataptr));
8480 /* The kernel always updates version for both capget and capset */
8481 target_header->version = tswap32(header.version);
8482 unlock_user_struct(target_header, arg1, 1);
8484 if (arg2) {
8485 if (num == TARGET_NR_capget) {
8486 for (i = 0; i < data_items; i++) {
8487 target_data[i].effective = tswap32(data[i].effective);
8488 target_data[i].permitted = tswap32(data[i].permitted);
8489 target_data[i].inheritable = tswap32(data[i].inheritable);
8491 unlock_user(target_data, arg2, target_datalen);
8492 } else {
8493 unlock_user(target_data, arg2, 0);
8496 break;
8498 case TARGET_NR_sigaltstack:
8499 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
8500 break;
8502 #ifdef CONFIG_SENDFILE
8503 case TARGET_NR_sendfile:
8505 off_t *offp = NULL;
8506 off_t off;
8507 if (arg3) {
8508 ret = get_user_sal(off, arg3);
8509 if (is_error(ret)) {
8510 break;
8512 offp = &off;
8514 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
8515 if (!is_error(ret) && arg3) {
8516 abi_long ret2 = put_user_sal(off, arg3);
8517 if (is_error(ret2)) {
8518 ret = ret2;
8521 break;
8523 #ifdef TARGET_NR_sendfile64
8524 case TARGET_NR_sendfile64:
8526 off_t *offp = NULL;
8527 off_t off;
8528 if (arg3) {
8529 ret = get_user_s64(off, arg3);
8530 if (is_error(ret)) {
8531 break;
8533 offp = &off;
8535 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
8536 if (!is_error(ret) && arg3) {
8537 abi_long ret2 = put_user_s64(off, arg3);
8538 if (is_error(ret2)) {
8539 ret = ret2;
8542 break;
8544 #endif
8545 #else
8546 case TARGET_NR_sendfile:
8547 #ifdef TARGET_NR_sendfile64
8548 case TARGET_NR_sendfile64:
8549 #endif
8550 goto unimplemented;
8551 #endif
8553 #ifdef TARGET_NR_getpmsg
8554 case TARGET_NR_getpmsg:
8555 goto unimplemented;
8556 #endif
8557 #ifdef TARGET_NR_putpmsg
8558 case TARGET_NR_putpmsg:
8559 goto unimplemented;
8560 #endif
8561 #ifdef TARGET_NR_vfork
8562 case TARGET_NR_vfork:
8563 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
8564 0, 0, 0, 0));
8565 break;
8566 #endif
8567 #ifdef TARGET_NR_ugetrlimit
8568 case TARGET_NR_ugetrlimit:
8570 struct rlimit rlim;
8571 int resource = target_to_host_resource(arg1);
8572 ret = get_errno(getrlimit(resource, &rlim));
8573 if (!is_error(ret)) {
8574 struct target_rlimit *target_rlim;
8575 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
8576 goto efault;
8577 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
8578 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
8579 unlock_user_struct(target_rlim, arg2, 1);
8581 break;
8583 #endif
8584 #ifdef TARGET_NR_truncate64
8585 case TARGET_NR_truncate64:
8586 if (!(p = lock_user_string(arg1)))
8587 goto efault;
8588 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
8589 unlock_user(p, arg1, 0);
8590 break;
8591 #endif
8592 #ifdef TARGET_NR_ftruncate64
8593 case TARGET_NR_ftruncate64:
8594 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
8595 break;
8596 #endif
8597 #ifdef TARGET_NR_stat64
8598 case TARGET_NR_stat64:
8599 if (!(p = lock_user_string(arg1)))
8600 goto efault;
8601 ret = get_errno(stat(path(p), &st));
8602 unlock_user(p, arg1, 0);
8603 if (!is_error(ret))
8604 ret = host_to_target_stat64(cpu_env, arg2, &st);
8605 break;
8606 #endif
8607 #ifdef TARGET_NR_lstat64
8608 case TARGET_NR_lstat64:
8609 if (!(p = lock_user_string(arg1)))
8610 goto efault;
8611 ret = get_errno(lstat(path(p), &st));
8612 unlock_user(p, arg1, 0);
8613 if (!is_error(ret))
8614 ret = host_to_target_stat64(cpu_env, arg2, &st);
8615 break;
8616 #endif
8617 #ifdef TARGET_NR_fstat64
8618 case TARGET_NR_fstat64:
8619 ret = get_errno(fstat(arg1, &st));
8620 if (!is_error(ret))
8621 ret = host_to_target_stat64(cpu_env, arg2, &st);
8622 break;
8623 #endif
8624 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
8625 #ifdef TARGET_NR_fstatat64
8626 case TARGET_NR_fstatat64:
8627 #endif
8628 #ifdef TARGET_NR_newfstatat
8629 case TARGET_NR_newfstatat:
8630 #endif
8631 if (!(p = lock_user_string(arg2)))
8632 goto efault;
8633 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
8634 if (!is_error(ret))
8635 ret = host_to_target_stat64(cpu_env, arg3, &st);
8636 break;
8637 #endif
8638 #ifdef TARGET_NR_lchown
8639 case TARGET_NR_lchown:
8640 if (!(p = lock_user_string(arg1)))
8641 goto efault;
8642 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
8643 unlock_user(p, arg1, 0);
8644 break;
8645 #endif
8646 #ifdef TARGET_NR_getuid
8647 case TARGET_NR_getuid:
8648 ret = get_errno(high2lowuid(getuid()));
8649 break;
8650 #endif
8651 #ifdef TARGET_NR_getgid
8652 case TARGET_NR_getgid:
8653 ret = get_errno(high2lowgid(getgid()));
8654 break;
8655 #endif
8656 #ifdef TARGET_NR_geteuid
8657 case TARGET_NR_geteuid:
8658 ret = get_errno(high2lowuid(geteuid()));
8659 break;
8660 #endif
8661 #ifdef TARGET_NR_getegid
8662 case TARGET_NR_getegid:
8663 ret = get_errno(high2lowgid(getegid()));
8664 break;
8665 #endif
8666 case TARGET_NR_setreuid:
8667 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
8668 break;
8669 case TARGET_NR_setregid:
8670 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
8671 break;
8672 case TARGET_NR_getgroups:
8674 int gidsetsize = arg1;
8675 target_id *target_grouplist;
8676 gid_t *grouplist;
8677 int i;
8679 grouplist = alloca(gidsetsize * sizeof(gid_t));
8680 ret = get_errno(getgroups(gidsetsize, grouplist));
8681 if (gidsetsize == 0)
8682 break;
8683 if (!is_error(ret)) {
8684 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
8685 if (!target_grouplist)
8686 goto efault;
8687 for(i = 0;i < ret; i++)
8688 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
8689 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
8692 break;
8693 case TARGET_NR_setgroups:
8695 int gidsetsize = arg1;
8696 target_id *target_grouplist;
8697 gid_t *grouplist = NULL;
8698 int i;
8699 if (gidsetsize) {
8700 grouplist = alloca(gidsetsize * sizeof(gid_t));
8701 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
8702 if (!target_grouplist) {
8703 ret = -TARGET_EFAULT;
8704 goto fail;
8706 for (i = 0; i < gidsetsize; i++) {
8707 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
8709 unlock_user(target_grouplist, arg2, 0);
8711 ret = get_errno(setgroups(gidsetsize, grouplist));
8713 break;
8714 case TARGET_NR_fchown:
8715 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
8716 break;
8717 #if defined(TARGET_NR_fchownat)
8718 case TARGET_NR_fchownat:
8719 if (!(p = lock_user_string(arg2)))
8720 goto efault;
8721 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
8722 low2highgid(arg4), arg5));
8723 unlock_user(p, arg2, 0);
8724 break;
8725 #endif
8726 #ifdef TARGET_NR_setresuid
8727 case TARGET_NR_setresuid:
8728 ret = get_errno(setresuid(low2highuid(arg1),
8729 low2highuid(arg2),
8730 low2highuid(arg3)));
8731 break;
8732 #endif
8733 #ifdef TARGET_NR_getresuid
8734 case TARGET_NR_getresuid:
8736 uid_t ruid, euid, suid;
8737 ret = get_errno(getresuid(&ruid, &euid, &suid));
8738 if (!is_error(ret)) {
8739 if (put_user_id(high2lowuid(ruid), arg1)
8740 || put_user_id(high2lowuid(euid), arg2)
8741 || put_user_id(high2lowuid(suid), arg3))
8742 goto efault;
8745 break;
8746 #endif
8747 #ifdef TARGET_NR_getresgid
8748 case TARGET_NR_setresgid:
8749 ret = get_errno(setresgid(low2highgid(arg1),
8750 low2highgid(arg2),
8751 low2highgid(arg3)));
8752 break;
8753 #endif
8754 #ifdef TARGET_NR_getresgid
8755 case TARGET_NR_getresgid:
8757 gid_t rgid, egid, sgid;
8758 ret = get_errno(getresgid(&rgid, &egid, &sgid));
8759 if (!is_error(ret)) {
8760 if (put_user_id(high2lowgid(rgid), arg1)
8761 || put_user_id(high2lowgid(egid), arg2)
8762 || put_user_id(high2lowgid(sgid), arg3))
8763 goto efault;
8766 break;
8767 #endif
8768 #ifdef TARGET_NR_chown
8769 case TARGET_NR_chown:
8770 if (!(p = lock_user_string(arg1)))
8771 goto efault;
8772 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
8773 unlock_user(p, arg1, 0);
8774 break;
8775 #endif
8776 case TARGET_NR_setuid:
8777 ret = get_errno(setuid(low2highuid(arg1)));
8778 break;
8779 case TARGET_NR_setgid:
8780 ret = get_errno(setgid(low2highgid(arg1)));
8781 break;
8782 case TARGET_NR_setfsuid:
8783 ret = get_errno(setfsuid(arg1));
8784 break;
8785 case TARGET_NR_setfsgid:
8786 ret = get_errno(setfsgid(arg1));
8787 break;
8789 #ifdef TARGET_NR_lchown32
8790 case TARGET_NR_lchown32:
8791 if (!(p = lock_user_string(arg1)))
8792 goto efault;
8793 ret = get_errno(lchown(p, arg2, arg3));
8794 unlock_user(p, arg1, 0);
8795 break;
8796 #endif
8797 #ifdef TARGET_NR_getuid32
8798 case TARGET_NR_getuid32:
8799 ret = get_errno(getuid());
8800 break;
8801 #endif
8803 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
8804 /* Alpha specific */
8805 case TARGET_NR_getxuid:
8807 uid_t euid;
8808 euid=geteuid();
8809 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
8811 ret = get_errno(getuid());
8812 break;
8813 #endif
8814 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
8815 /* Alpha specific */
8816 case TARGET_NR_getxgid:
8818 uid_t egid;
8819 egid=getegid();
8820 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
8822 ret = get_errno(getgid());
8823 break;
8824 #endif
8825 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
8826 /* Alpha specific */
8827 case TARGET_NR_osf_getsysinfo:
8828 ret = -TARGET_EOPNOTSUPP;
8829 switch (arg1) {
8830 case TARGET_GSI_IEEE_FP_CONTROL:
8832 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
8834 /* Copied from linux ieee_fpcr_to_swcr. */
8835 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
8836 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
8837 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
8838 | SWCR_TRAP_ENABLE_DZE
8839 | SWCR_TRAP_ENABLE_OVF);
8840 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
8841 | SWCR_TRAP_ENABLE_INE);
8842 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
8843 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
8845 if (put_user_u64 (swcr, arg2))
8846 goto efault;
8847 ret = 0;
8849 break;
8851 /* case GSI_IEEE_STATE_AT_SIGNAL:
8852 -- Not implemented in linux kernel.
8853 case GSI_UACPROC:
8854 -- Retrieves current unaligned access state; not much used.
8855 case GSI_PROC_TYPE:
8856 -- Retrieves implver information; surely not used.
8857 case GSI_GET_HWRPB:
8858 -- Grabs a copy of the HWRPB; surely not used.
8861 break;
8862 #endif
8863 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8864 /* Alpha specific */
8865 case TARGET_NR_osf_setsysinfo:
8866 ret = -TARGET_EOPNOTSUPP;
8867 switch (arg1) {
8868 case TARGET_SSI_IEEE_FP_CONTROL:
8870 uint64_t swcr, fpcr, orig_fpcr;
8872 if (get_user_u64 (swcr, arg2)) {
8873 goto efault;
8875 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8876 fpcr = orig_fpcr & FPCR_DYN_MASK;
8878 /* Copied from linux ieee_swcr_to_fpcr. */
8879 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
8880 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
8881 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
8882 | SWCR_TRAP_ENABLE_DZE
8883 | SWCR_TRAP_ENABLE_OVF)) << 48;
8884 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
8885 | SWCR_TRAP_ENABLE_INE)) << 57;
8886 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
8887 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
8889 cpu_alpha_store_fpcr(cpu_env, fpcr);
8890 ret = 0;
8892 break;
8894 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
8896 uint64_t exc, fpcr, orig_fpcr;
8897 int si_code;
8899 if (get_user_u64(exc, arg2)) {
8900 goto efault;
8903 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8905 /* We only add to the exception status here. */
8906 fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
8908 cpu_alpha_store_fpcr(cpu_env, fpcr);
8909 ret = 0;
8911 /* Old exceptions are not signaled. */
8912 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
8914 /* If any exceptions set by this call,
8915 and are unmasked, send a signal. */
8916 si_code = 0;
8917 if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
8918 si_code = TARGET_FPE_FLTRES;
8920 if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
8921 si_code = TARGET_FPE_FLTUND;
8923 if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
8924 si_code = TARGET_FPE_FLTOVF;
8926 if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
8927 si_code = TARGET_FPE_FLTDIV;
8929 if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
8930 si_code = TARGET_FPE_FLTINV;
8932 if (si_code != 0) {
8933 target_siginfo_t info;
8934 info.si_signo = SIGFPE;
8935 info.si_errno = 0;
8936 info.si_code = si_code;
8937 info._sifields._sigfault._addr
8938 = ((CPUArchState *)cpu_env)->pc;
8939 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
8942 break;
8944 /* case SSI_NVPAIRS:
8945 -- Used with SSIN_UACPROC to enable unaligned accesses.
8946 case SSI_IEEE_STATE_AT_SIGNAL:
8947 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
8948 -- Not implemented in linux kernel
8951 break;
8952 #endif
8953 #ifdef TARGET_NR_osf_sigprocmask
8954 /* Alpha specific. */
8955 case TARGET_NR_osf_sigprocmask:
8957 abi_ulong mask;
8958 int how;
8959 sigset_t set, oldset;
8961 switch(arg1) {
8962 case TARGET_SIG_BLOCK:
8963 how = SIG_BLOCK;
8964 break;
8965 case TARGET_SIG_UNBLOCK:
8966 how = SIG_UNBLOCK;
8967 break;
8968 case TARGET_SIG_SETMASK:
8969 how = SIG_SETMASK;
8970 break;
8971 default:
8972 ret = -TARGET_EINVAL;
8973 goto fail;
8975 mask = arg2;
8976 target_to_host_old_sigset(&set, &mask);
8977 do_sigprocmask(how, &set, &oldset);
8978 host_to_target_old_sigset(&mask, &oldset);
8979 ret = mask;
8981 break;
8982 #endif
8984 #ifdef TARGET_NR_getgid32
8985 case TARGET_NR_getgid32:
8986 ret = get_errno(getgid());
8987 break;
8988 #endif
8989 #ifdef TARGET_NR_geteuid32
8990 case TARGET_NR_geteuid32:
8991 ret = get_errno(geteuid());
8992 break;
8993 #endif
8994 #ifdef TARGET_NR_getegid32
8995 case TARGET_NR_getegid32:
8996 ret = get_errno(getegid());
8997 break;
8998 #endif
8999 #ifdef TARGET_NR_setreuid32
9000 case TARGET_NR_setreuid32:
9001 ret = get_errno(setreuid(arg1, arg2));
9002 break;
9003 #endif
9004 #ifdef TARGET_NR_setregid32
9005 case TARGET_NR_setregid32:
9006 ret = get_errno(setregid(arg1, arg2));
9007 break;
9008 #endif
9009 #ifdef TARGET_NR_getgroups32
9010 case TARGET_NR_getgroups32:
9012 int gidsetsize = arg1;
9013 uint32_t *target_grouplist;
9014 gid_t *grouplist;
9015 int i;
9017 grouplist = alloca(gidsetsize * sizeof(gid_t));
9018 ret = get_errno(getgroups(gidsetsize, grouplist));
9019 if (gidsetsize == 0)
9020 break;
9021 if (!is_error(ret)) {
9022 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
9023 if (!target_grouplist) {
9024 ret = -TARGET_EFAULT;
9025 goto fail;
9027 for(i = 0;i < ret; i++)
9028 target_grouplist[i] = tswap32(grouplist[i]);
9029 unlock_user(target_grouplist, arg2, gidsetsize * 4);
9032 break;
9033 #endif
9034 #ifdef TARGET_NR_setgroups32
9035 case TARGET_NR_setgroups32:
9037 int gidsetsize = arg1;
9038 uint32_t *target_grouplist;
9039 gid_t *grouplist;
9040 int i;
9042 grouplist = alloca(gidsetsize * sizeof(gid_t));
9043 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
9044 if (!target_grouplist) {
9045 ret = -TARGET_EFAULT;
9046 goto fail;
9048 for(i = 0;i < gidsetsize; i++)
9049 grouplist[i] = tswap32(target_grouplist[i]);
9050 unlock_user(target_grouplist, arg2, 0);
9051 ret = get_errno(setgroups(gidsetsize, grouplist));
9053 break;
9054 #endif
9055 #ifdef TARGET_NR_fchown32
9056 case TARGET_NR_fchown32:
9057 ret = get_errno(fchown(arg1, arg2, arg3));
9058 break;
9059 #endif
9060 #ifdef TARGET_NR_setresuid32
9061 case TARGET_NR_setresuid32:
9062 ret = get_errno(setresuid(arg1, arg2, arg3));
9063 break;
9064 #endif
9065 #ifdef TARGET_NR_getresuid32
9066 case TARGET_NR_getresuid32:
9068 uid_t ruid, euid, suid;
9069 ret = get_errno(getresuid(&ruid, &euid, &suid));
9070 if (!is_error(ret)) {
9071 if (put_user_u32(ruid, arg1)
9072 || put_user_u32(euid, arg2)
9073 || put_user_u32(suid, arg3))
9074 goto efault;
9077 break;
9078 #endif
9079 #ifdef TARGET_NR_setresgid32
9080 case TARGET_NR_setresgid32:
9081 ret = get_errno(setresgid(arg1, arg2, arg3));
9082 break;
9083 #endif
9084 #ifdef TARGET_NR_getresgid32
9085 case TARGET_NR_getresgid32:
9087 gid_t rgid, egid, sgid;
9088 ret = get_errno(getresgid(&rgid, &egid, &sgid));
9089 if (!is_error(ret)) {
9090 if (put_user_u32(rgid, arg1)
9091 || put_user_u32(egid, arg2)
9092 || put_user_u32(sgid, arg3))
9093 goto efault;
9096 break;
9097 #endif
9098 #ifdef TARGET_NR_chown32
9099 case TARGET_NR_chown32:
9100 if (!(p = lock_user_string(arg1)))
9101 goto efault;
9102 ret = get_errno(chown(p, arg2, arg3));
9103 unlock_user(p, arg1, 0);
9104 break;
9105 #endif
9106 #ifdef TARGET_NR_setuid32
9107 case TARGET_NR_setuid32:
9108 ret = get_errno(setuid(arg1));
9109 break;
9110 #endif
9111 #ifdef TARGET_NR_setgid32
9112 case TARGET_NR_setgid32:
9113 ret = get_errno(setgid(arg1));
9114 break;
9115 #endif
9116 #ifdef TARGET_NR_setfsuid32
9117 case TARGET_NR_setfsuid32:
9118 ret = get_errno(setfsuid(arg1));
9119 break;
9120 #endif
9121 #ifdef TARGET_NR_setfsgid32
9122 case TARGET_NR_setfsgid32:
9123 ret = get_errno(setfsgid(arg1));
9124 break;
9125 #endif
9127 case TARGET_NR_pivot_root:
9128 goto unimplemented;
9129 #ifdef TARGET_NR_mincore
9130 case TARGET_NR_mincore:
9132 void *a;
9133 ret = -TARGET_EFAULT;
9134 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
9135 goto efault;
9136 if (!(p = lock_user_string(arg3)))
9137 goto mincore_fail;
9138 ret = get_errno(mincore(a, arg2, p));
9139 unlock_user(p, arg3, ret);
9140 mincore_fail:
9141 unlock_user(a, arg1, 0);
9143 break;
9144 #endif
9145 #ifdef TARGET_NR_arm_fadvise64_64
9146 case TARGET_NR_arm_fadvise64_64:
9149 * arm_fadvise64_64 looks like fadvise64_64 but
9150 * with different argument order
9152 abi_long temp;
9153 temp = arg3;
9154 arg3 = arg4;
9155 arg4 = temp;
9157 #endif
9158 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
9159 #ifdef TARGET_NR_fadvise64_64
9160 case TARGET_NR_fadvise64_64:
9161 #endif
9162 #ifdef TARGET_NR_fadvise64
9163 case TARGET_NR_fadvise64:
9164 #endif
9165 #ifdef TARGET_S390X
9166 switch (arg4) {
9167 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
9168 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
9169 case 6: arg4 = POSIX_FADV_DONTNEED; break;
9170 case 7: arg4 = POSIX_FADV_NOREUSE; break;
9171 default: break;
9173 #endif
9174 ret = -posix_fadvise(arg1, arg2, arg3, arg4);
9175 break;
9176 #endif
9177 #ifdef TARGET_NR_madvise
9178 case TARGET_NR_madvise:
9179 /* A straight passthrough may not be safe because qemu sometimes
9180 turns private file-backed mappings into anonymous mappings.
9181 This will break MADV_DONTNEED.
9182 This is a hint, so ignoring and returning success is ok. */
9183 ret = get_errno(0);
9184 break;
9185 #endif
9186 #if TARGET_ABI_BITS == 32
9187 case TARGET_NR_fcntl64:
9189 int cmd;
9190 struct flock64 fl;
9191 struct target_flock64 *target_fl;
9192 #ifdef TARGET_ARM
9193 struct target_eabi_flock64 *target_efl;
9194 #endif
9196 cmd = target_to_host_fcntl_cmd(arg2);
9197 if (cmd == -TARGET_EINVAL) {
9198 ret = cmd;
9199 break;
9202 switch(arg2) {
9203 case TARGET_F_GETLK64:
9204 #ifdef TARGET_ARM
9205 if (((CPUARMState *)cpu_env)->eabi) {
9206 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
9207 goto efault;
9208 fl.l_type = tswap16(target_efl->l_type);
9209 fl.l_whence = tswap16(target_efl->l_whence);
9210 fl.l_start = tswap64(target_efl->l_start);
9211 fl.l_len = tswap64(target_efl->l_len);
9212 fl.l_pid = tswap32(target_efl->l_pid);
9213 unlock_user_struct(target_efl, arg3, 0);
9214 } else
9215 #endif
9217 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
9218 goto efault;
9219 fl.l_type = tswap16(target_fl->l_type);
9220 fl.l_whence = tswap16(target_fl->l_whence);
9221 fl.l_start = tswap64(target_fl->l_start);
9222 fl.l_len = tswap64(target_fl->l_len);
9223 fl.l_pid = tswap32(target_fl->l_pid);
9224 unlock_user_struct(target_fl, arg3, 0);
9226 ret = get_errno(fcntl(arg1, cmd, &fl));
9227 if (ret == 0) {
9228 #ifdef TARGET_ARM
9229 if (((CPUARMState *)cpu_env)->eabi) {
9230 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
9231 goto efault;
9232 target_efl->l_type = tswap16(fl.l_type);
9233 target_efl->l_whence = tswap16(fl.l_whence);
9234 target_efl->l_start = tswap64(fl.l_start);
9235 target_efl->l_len = tswap64(fl.l_len);
9236 target_efl->l_pid = tswap32(fl.l_pid);
9237 unlock_user_struct(target_efl, arg3, 1);
9238 } else
9239 #endif
9241 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
9242 goto efault;
9243 target_fl->l_type = tswap16(fl.l_type);
9244 target_fl->l_whence = tswap16(fl.l_whence);
9245 target_fl->l_start = tswap64(fl.l_start);
9246 target_fl->l_len = tswap64(fl.l_len);
9247 target_fl->l_pid = tswap32(fl.l_pid);
9248 unlock_user_struct(target_fl, arg3, 1);
9251 break;
9253 case TARGET_F_SETLK64:
9254 case TARGET_F_SETLKW64:
9255 #ifdef TARGET_ARM
9256 if (((CPUARMState *)cpu_env)->eabi) {
9257 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
9258 goto efault;
9259 fl.l_type = tswap16(target_efl->l_type);
9260 fl.l_whence = tswap16(target_efl->l_whence);
9261 fl.l_start = tswap64(target_efl->l_start);
9262 fl.l_len = tswap64(target_efl->l_len);
9263 fl.l_pid = tswap32(target_efl->l_pid);
9264 unlock_user_struct(target_efl, arg3, 0);
9265 } else
9266 #endif
9268 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
9269 goto efault;
9270 fl.l_type = tswap16(target_fl->l_type);
9271 fl.l_whence = tswap16(target_fl->l_whence);
9272 fl.l_start = tswap64(target_fl->l_start);
9273 fl.l_len = tswap64(target_fl->l_len);
9274 fl.l_pid = tswap32(target_fl->l_pid);
9275 unlock_user_struct(target_fl, arg3, 0);
9277 ret = get_errno(fcntl(arg1, cmd, &fl));
9278 break;
9279 default:
9280 ret = do_fcntl(arg1, arg2, arg3);
9281 break;
9283 break;
9285 #endif
9286 #ifdef TARGET_NR_cacheflush
9287 case TARGET_NR_cacheflush:
9288 /* self-modifying code is handled automatically, so nothing needed */
9289 ret = 0;
9290 break;
9291 #endif
9292 #ifdef TARGET_NR_security
9293 case TARGET_NR_security:
9294 goto unimplemented;
9295 #endif
9296 #ifdef TARGET_NR_getpagesize
9297 case TARGET_NR_getpagesize:
9298 ret = TARGET_PAGE_SIZE;
9299 break;
9300 #endif
9301 case TARGET_NR_gettid:
9302 ret = get_errno(gettid());
9303 break;
9304 #ifdef TARGET_NR_readahead
9305 case TARGET_NR_readahead:
9306 #if TARGET_ABI_BITS == 32
9307 if (regpairs_aligned(cpu_env)) {
9308 arg2 = arg3;
9309 arg3 = arg4;
9310 arg4 = arg5;
9312 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
9313 #else
9314 ret = get_errno(readahead(arg1, arg2, arg3));
9315 #endif
9316 break;
9317 #endif
9318 #ifdef CONFIG_ATTR
9319 #ifdef TARGET_NR_setxattr
9320 case TARGET_NR_listxattr:
9321 case TARGET_NR_llistxattr:
9323 void *p, *b = 0;
9324 if (arg2) {
9325 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
9326 if (!b) {
9327 ret = -TARGET_EFAULT;
9328 break;
9331 p = lock_user_string(arg1);
9332 if (p) {
9333 if (num == TARGET_NR_listxattr) {
9334 ret = get_errno(listxattr(p, b, arg3));
9335 } else {
9336 ret = get_errno(llistxattr(p, b, arg3));
9338 } else {
9339 ret = -TARGET_EFAULT;
9341 unlock_user(p, arg1, 0);
9342 unlock_user(b, arg2, arg3);
9343 break;
9345 case TARGET_NR_flistxattr:
9347 void *b = 0;
9348 if (arg2) {
9349 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
9350 if (!b) {
9351 ret = -TARGET_EFAULT;
9352 break;
9355 ret = get_errno(flistxattr(arg1, b, arg3));
9356 unlock_user(b, arg2, arg3);
9357 break;
9359 case TARGET_NR_setxattr:
9360 case TARGET_NR_lsetxattr:
9362 void *p, *n, *v = 0;
9363 if (arg3) {
9364 v = lock_user(VERIFY_READ, arg3, arg4, 1);
9365 if (!v) {
9366 ret = -TARGET_EFAULT;
9367 break;
9370 p = lock_user_string(arg1);
9371 n = lock_user_string(arg2);
9372 if (p && n) {
9373 if (num == TARGET_NR_setxattr) {
9374 ret = get_errno(setxattr(p, n, v, arg4, arg5));
9375 } else {
9376 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
9378 } else {
9379 ret = -TARGET_EFAULT;
9381 unlock_user(p, arg1, 0);
9382 unlock_user(n, arg2, 0);
9383 unlock_user(v, arg3, 0);
9385 break;
9386 case TARGET_NR_fsetxattr:
9388 void *n, *v = 0;
9389 if (arg3) {
9390 v = lock_user(VERIFY_READ, arg3, arg4, 1);
9391 if (!v) {
9392 ret = -TARGET_EFAULT;
9393 break;
9396 n = lock_user_string(arg2);
9397 if (n) {
9398 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
9399 } else {
9400 ret = -TARGET_EFAULT;
9402 unlock_user(n, arg2, 0);
9403 unlock_user(v, arg3, 0);
9405 break;
9406 case TARGET_NR_getxattr:
9407 case TARGET_NR_lgetxattr:
9409 void *p, *n, *v = 0;
9410 if (arg3) {
9411 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9412 if (!v) {
9413 ret = -TARGET_EFAULT;
9414 break;
9417 p = lock_user_string(arg1);
9418 n = lock_user_string(arg2);
9419 if (p && n) {
9420 if (num == TARGET_NR_getxattr) {
9421 ret = get_errno(getxattr(p, n, v, arg4));
9422 } else {
9423 ret = get_errno(lgetxattr(p, n, v, arg4));
9425 } else {
9426 ret = -TARGET_EFAULT;
9428 unlock_user(p, arg1, 0);
9429 unlock_user(n, arg2, 0);
9430 unlock_user(v, arg3, arg4);
9432 break;
9433 case TARGET_NR_fgetxattr:
9435 void *n, *v = 0;
9436 if (arg3) {
9437 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9438 if (!v) {
9439 ret = -TARGET_EFAULT;
9440 break;
9443 n = lock_user_string(arg2);
9444 if (n) {
9445 ret = get_errno(fgetxattr(arg1, n, v, arg4));
9446 } else {
9447 ret = -TARGET_EFAULT;
9449 unlock_user(n, arg2, 0);
9450 unlock_user(v, arg3, arg4);
9452 break;
9453 case TARGET_NR_removexattr:
9454 case TARGET_NR_lremovexattr:
9456 void *p, *n;
9457 p = lock_user_string(arg1);
9458 n = lock_user_string(arg2);
9459 if (p && n) {
9460 if (num == TARGET_NR_removexattr) {
9461 ret = get_errno(removexattr(p, n));
9462 } else {
9463 ret = get_errno(lremovexattr(p, n));
9465 } else {
9466 ret = -TARGET_EFAULT;
9468 unlock_user(p, arg1, 0);
9469 unlock_user(n, arg2, 0);
9471 break;
9472 case TARGET_NR_fremovexattr:
9474 void *n;
9475 n = lock_user_string(arg2);
9476 if (n) {
9477 ret = get_errno(fremovexattr(arg1, n));
9478 } else {
9479 ret = -TARGET_EFAULT;
9481 unlock_user(n, arg2, 0);
9483 break;
9484 #endif
9485 #endif /* CONFIG_ATTR */
9486 #ifdef TARGET_NR_set_thread_area
9487 case TARGET_NR_set_thread_area:
9488 #if defined(TARGET_MIPS)
9489 ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
9490 ret = 0;
9491 break;
9492 #elif defined(TARGET_CRIS)
9493 if (arg1 & 0xff)
9494 ret = -TARGET_EINVAL;
9495 else {
9496 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
9497 ret = 0;
9499 break;
9500 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
9501 ret = do_set_thread_area(cpu_env, arg1);
9502 break;
9503 #elif defined(TARGET_M68K)
9505 TaskState *ts = cpu->opaque;
9506 ts->tp_value = arg1;
9507 ret = 0;
9508 break;
9510 #else
9511 goto unimplemented_nowarn;
9512 #endif
9513 #endif
9514 #ifdef TARGET_NR_get_thread_area
9515 case TARGET_NR_get_thread_area:
9516 #if defined(TARGET_I386) && defined(TARGET_ABI32)
9517 ret = do_get_thread_area(cpu_env, arg1);
9518 break;
9519 #elif defined(TARGET_M68K)
9521 TaskState *ts = cpu->opaque;
9522 ret = ts->tp_value;
9523 break;
9525 #else
9526 goto unimplemented_nowarn;
9527 #endif
9528 #endif
9529 #ifdef TARGET_NR_getdomainname
9530 case TARGET_NR_getdomainname:
9531 goto unimplemented_nowarn;
9532 #endif
9534 #ifdef TARGET_NR_clock_gettime
9535 case TARGET_NR_clock_gettime:
9537 struct timespec ts;
9538 ret = get_errno(clock_gettime(arg1, &ts));
9539 if (!is_error(ret)) {
9540 host_to_target_timespec(arg2, &ts);
9542 break;
9544 #endif
9545 #ifdef TARGET_NR_clock_getres
9546 case TARGET_NR_clock_getres:
9548 struct timespec ts;
9549 ret = get_errno(clock_getres(arg1, &ts));
9550 if (!is_error(ret)) {
9551 host_to_target_timespec(arg2, &ts);
9553 break;
9555 #endif
9556 #ifdef TARGET_NR_clock_nanosleep
9557 case TARGET_NR_clock_nanosleep:
9559 struct timespec ts;
9560 target_to_host_timespec(&ts, arg3);
9561 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
9562 if (arg4)
9563 host_to_target_timespec(arg4, &ts);
9565 #if defined(TARGET_PPC)
9566 /* clock_nanosleep is odd in that it returns positive errno values.
9567 * On PPC, CR0 bit 3 should be set in such a situation. */
9568 if (ret) {
9569 ((CPUPPCState *)cpu_env)->crf[0] |= 1;
9571 #endif
9572 break;
9574 #endif
9576 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
9577 case TARGET_NR_set_tid_address:
9578 ret = get_errno(set_tid_address((int *)g2h(arg1)));
9579 break;
9580 #endif
9582 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
9583 case TARGET_NR_tkill:
9584 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
9585 break;
9586 #endif
9588 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
9589 case TARGET_NR_tgkill:
9590 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
9591 target_to_host_signal(arg3)));
9592 break;
9593 #endif
9595 #ifdef TARGET_NR_set_robust_list
9596 case TARGET_NR_set_robust_list:
9597 case TARGET_NR_get_robust_list:
9598 /* The ABI for supporting robust futexes has userspace pass
9599 * the kernel a pointer to a linked list which is updated by
9600 * userspace after the syscall; the list is walked by the kernel
9601 * when the thread exits. Since the linked list in QEMU guest
9602 * memory isn't a valid linked list for the host and we have
9603 * no way to reliably intercept the thread-death event, we can't
9604 * support these. Silently return ENOSYS so that guest userspace
9605 * falls back to a non-robust futex implementation (which should
9606 * be OK except in the corner case of the guest crashing while
9607 * holding a mutex that is shared with another process via
9608 * shared memory).
9610 goto unimplemented_nowarn;
9611 #endif
9613 #if defined(TARGET_NR_utimensat)
9614 case TARGET_NR_utimensat:
9616 struct timespec *tsp, ts[2];
9617 if (!arg3) {
9618 tsp = NULL;
9619 } else {
9620 target_to_host_timespec(ts, arg3);
9621 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
9622 tsp = ts;
9624 if (!arg2)
9625 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
9626 else {
9627 if (!(p = lock_user_string(arg2))) {
9628 ret = -TARGET_EFAULT;
9629 goto fail;
9631 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
9632 unlock_user(p, arg2, 0);
9635 break;
9636 #endif
9637 case TARGET_NR_futex:
9638 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
9639 break;
9640 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
9641 case TARGET_NR_inotify_init:
9642 ret = get_errno(sys_inotify_init());
9643 break;
9644 #endif
9645 #ifdef CONFIG_INOTIFY1
9646 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
9647 case TARGET_NR_inotify_init1:
9648 ret = get_errno(sys_inotify_init1(arg1));
9649 break;
9650 #endif
9651 #endif
9652 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
9653 case TARGET_NR_inotify_add_watch:
9654 p = lock_user_string(arg2);
9655 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
9656 unlock_user(p, arg2, 0);
9657 break;
9658 #endif
9659 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
9660 case TARGET_NR_inotify_rm_watch:
9661 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
9662 break;
9663 #endif
9665 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
9666 case TARGET_NR_mq_open:
9668 struct mq_attr posix_mq_attr, *attrp;
9670 p = lock_user_string(arg1 - 1);
9671 if (arg4 != 0) {
9672 copy_from_user_mq_attr (&posix_mq_attr, arg4);
9673 attrp = &posix_mq_attr;
9674 } else {
9675 attrp = 0;
9677 ret = get_errno(mq_open(p, arg2, arg3, attrp));
9678 unlock_user (p, arg1, 0);
9680 break;
9682 case TARGET_NR_mq_unlink:
9683 p = lock_user_string(arg1 - 1);
9684 ret = get_errno(mq_unlink(p));
9685 unlock_user (p, arg1, 0);
9686 break;
9688 case TARGET_NR_mq_timedsend:
9690 struct timespec ts;
9692 p = lock_user (VERIFY_READ, arg2, arg3, 1);
9693 if (arg5 != 0) {
9694 target_to_host_timespec(&ts, arg5);
9695 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
9696 host_to_target_timespec(arg5, &ts);
9698 else
9699 ret = get_errno(mq_send(arg1, p, arg3, arg4));
9700 unlock_user (p, arg2, arg3);
9702 break;
9704 case TARGET_NR_mq_timedreceive:
9706 struct timespec ts;
9707 unsigned int prio;
9709 p = lock_user (VERIFY_READ, arg2, arg3, 1);
9710 if (arg5 != 0) {
9711 target_to_host_timespec(&ts, arg5);
9712 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
9713 host_to_target_timespec(arg5, &ts);
9715 else
9716 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
9717 unlock_user (p, arg2, arg3);
9718 if (arg4 != 0)
9719 put_user_u32(prio, arg4);
9721 break;
9723 /* Not implemented for now... */
9724 /* case TARGET_NR_mq_notify: */
9725 /* break; */
9727 case TARGET_NR_mq_getsetattr:
9729 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
9730 ret = 0;
9731 if (arg3 != 0) {
9732 ret = mq_getattr(arg1, &posix_mq_attr_out);
9733 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
9735 if (arg2 != 0) {
9736 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
9737 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
9741 break;
9742 #endif
9744 #ifdef CONFIG_SPLICE
9745 #ifdef TARGET_NR_tee
9746 case TARGET_NR_tee:
9748 ret = get_errno(tee(arg1,arg2,arg3,arg4));
9750 break;
9751 #endif
9752 #ifdef TARGET_NR_splice
9753 case TARGET_NR_splice:
9755 loff_t loff_in, loff_out;
9756 loff_t *ploff_in = NULL, *ploff_out = NULL;
9757 if (arg2) {
9758 if (get_user_u64(loff_in, arg2)) {
9759 goto efault;
9761 ploff_in = &loff_in;
9763 if (arg4) {
9764 if (get_user_u64(loff_out, arg4)) {
9765 goto efault;
9767 ploff_out = &loff_out;
9769 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
9770 if (arg2) {
9771 if (put_user_u64(loff_in, arg2)) {
9772 goto efault;
9775 if (arg4) {
9776 if (put_user_u64(loff_out, arg4)) {
9777 goto efault;
9781 break;
9782 #endif
9783 #ifdef TARGET_NR_vmsplice
9784 case TARGET_NR_vmsplice:
9786 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
9787 if (vec != NULL) {
9788 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
9789 unlock_iovec(vec, arg2, arg3, 0);
9790 } else {
9791 ret = -host_to_target_errno(errno);
9794 break;
9795 #endif
9796 #endif /* CONFIG_SPLICE */
9797 #ifdef CONFIG_EVENTFD
9798 #if defined(TARGET_NR_eventfd)
9799 case TARGET_NR_eventfd:
9800 ret = get_errno(eventfd(arg1, 0));
9801 fd_trans_unregister(ret);
9802 break;
9803 #endif
9804 #if defined(TARGET_NR_eventfd2)
9805 case TARGET_NR_eventfd2:
9807 int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
9808 if (arg2 & TARGET_O_NONBLOCK) {
9809 host_flags |= O_NONBLOCK;
9811 if (arg2 & TARGET_O_CLOEXEC) {
9812 host_flags |= O_CLOEXEC;
9814 ret = get_errno(eventfd(arg1, host_flags));
9815 fd_trans_unregister(ret);
9816 break;
9818 #endif
9819 #endif /* CONFIG_EVENTFD */
9820 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
9821 case TARGET_NR_fallocate:
9822 #if TARGET_ABI_BITS == 32
9823 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
9824 target_offset64(arg5, arg6)));
9825 #else
9826 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
9827 #endif
9828 break;
9829 #endif
9830 #if defined(CONFIG_SYNC_FILE_RANGE)
9831 #if defined(TARGET_NR_sync_file_range)
9832 case TARGET_NR_sync_file_range:
9833 #if TARGET_ABI_BITS == 32
9834 #if defined(TARGET_MIPS)
9835 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9836 target_offset64(arg5, arg6), arg7));
9837 #else
9838 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
9839 target_offset64(arg4, arg5), arg6));
9840 #endif /* !TARGET_MIPS */
9841 #else
9842 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
9843 #endif
9844 break;
9845 #endif
9846 #if defined(TARGET_NR_sync_file_range2)
9847 case TARGET_NR_sync_file_range2:
9848 /* This is like sync_file_range but the arguments are reordered */
9849 #if TARGET_ABI_BITS == 32
9850 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9851 target_offset64(arg5, arg6), arg2));
9852 #else
9853 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
9854 #endif
9855 break;
9856 #endif
9857 #endif
9858 #if defined(TARGET_NR_signalfd4)
9859 case TARGET_NR_signalfd4:
9860 ret = do_signalfd4(arg1, arg2, arg4);
9861 break;
9862 #endif
9863 #if defined(TARGET_NR_signalfd)
9864 case TARGET_NR_signalfd:
9865 ret = do_signalfd4(arg1, arg2, 0);
9866 break;
9867 #endif
9868 #if defined(CONFIG_EPOLL)
9869 #if defined(TARGET_NR_epoll_create)
9870 case TARGET_NR_epoll_create:
9871 ret = get_errno(epoll_create(arg1));
9872 break;
9873 #endif
9874 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
9875 case TARGET_NR_epoll_create1:
9876 ret = get_errno(epoll_create1(arg1));
9877 break;
9878 #endif
9879 #if defined(TARGET_NR_epoll_ctl)
9880 case TARGET_NR_epoll_ctl:
9882 struct epoll_event ep;
9883 struct epoll_event *epp = 0;
9884 if (arg4) {
9885 struct target_epoll_event *target_ep;
9886 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
9887 goto efault;
9889 ep.events = tswap32(target_ep->events);
9890 /* The epoll_data_t union is just opaque data to the kernel,
9891 * so we transfer all 64 bits across and need not worry what
9892 * actual data type it is.
9894 ep.data.u64 = tswap64(target_ep->data.u64);
9895 unlock_user_struct(target_ep, arg4, 0);
9896 epp = &ep;
9898 ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
9899 break;
9901 #endif
9903 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9904 #define IMPLEMENT_EPOLL_PWAIT
9905 #endif
9906 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9907 #if defined(TARGET_NR_epoll_wait)
9908 case TARGET_NR_epoll_wait:
9909 #endif
9910 #if defined(IMPLEMENT_EPOLL_PWAIT)
9911 case TARGET_NR_epoll_pwait:
9912 #endif
9914 struct target_epoll_event *target_ep;
9915 struct epoll_event *ep;
9916 int epfd = arg1;
9917 int maxevents = arg3;
9918 int timeout = arg4;
9920 target_ep = lock_user(VERIFY_WRITE, arg2,
9921 maxevents * sizeof(struct target_epoll_event), 1);
9922 if (!target_ep) {
9923 goto efault;
9926 ep = alloca(maxevents * sizeof(struct epoll_event));
9928 switch (num) {
9929 #if defined(IMPLEMENT_EPOLL_PWAIT)
9930 case TARGET_NR_epoll_pwait:
9932 target_sigset_t *target_set;
9933 sigset_t _set, *set = &_set;
9935 if (arg5) {
9936 target_set = lock_user(VERIFY_READ, arg5,
9937 sizeof(target_sigset_t), 1);
9938 if (!target_set) {
9939 unlock_user(target_ep, arg2, 0);
9940 goto efault;
9942 target_to_host_sigset(set, target_set);
9943 unlock_user(target_set, arg5, 0);
9944 } else {
9945 set = NULL;
9948 ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
9949 break;
9951 #endif
9952 #if defined(TARGET_NR_epoll_wait)
9953 case TARGET_NR_epoll_wait:
9954 ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
9955 break;
9956 #endif
9957 default:
9958 ret = -TARGET_ENOSYS;
9960 if (!is_error(ret)) {
9961 int i;
9962 for (i = 0; i < ret; i++) {
9963 target_ep[i].events = tswap32(ep[i].events);
9964 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
9967 unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
9968 break;
9970 #endif
9971 #endif
9972 #ifdef TARGET_NR_prlimit64
9973 case TARGET_NR_prlimit64:
9975 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
9976 struct target_rlimit64 *target_rnew, *target_rold;
9977 struct host_rlimit64 rnew, rold, *rnewp = 0;
9978 int resource = target_to_host_resource(arg2);
9979 if (arg3) {
9980 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
9981 goto efault;
9983 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
9984 rnew.rlim_max = tswap64(target_rnew->rlim_max);
9985 unlock_user_struct(target_rnew, arg3, 0);
9986 rnewp = &rnew;
9989 ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
9990 if (!is_error(ret) && arg4) {
9991 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
9992 goto efault;
9994 target_rold->rlim_cur = tswap64(rold.rlim_cur);
9995 target_rold->rlim_max = tswap64(rold.rlim_max);
9996 unlock_user_struct(target_rold, arg4, 1);
9998 break;
10000 #endif
10001 #ifdef TARGET_NR_gethostname
10002 case TARGET_NR_gethostname:
10004 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
10005 if (name) {
10006 ret = get_errno(gethostname(name, arg2));
10007 unlock_user(name, arg1, arg2);
10008 } else {
10009 ret = -TARGET_EFAULT;
10011 break;
10013 #endif
10014 #ifdef TARGET_NR_atomic_cmpxchg_32
10015 case TARGET_NR_atomic_cmpxchg_32:
10017 /* should use start_exclusive from main.c */
10018 abi_ulong mem_value;
10019 if (get_user_u32(mem_value, arg6)) {
10020 target_siginfo_t info;
10021 info.si_signo = SIGSEGV;
10022 info.si_errno = 0;
10023 info.si_code = TARGET_SEGV_MAPERR;
10024 info._sifields._sigfault._addr = arg6;
10025 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
10026 ret = 0xdeadbeef;
10029 if (mem_value == arg2)
10030 put_user_u32(arg1, arg6);
10031 ret = mem_value;
10032 break;
10034 #endif
10035 #ifdef TARGET_NR_atomic_barrier
10036 case TARGET_NR_atomic_barrier:
10038 /* Like the kernel implementation and the qemu arm barrier, no-op this? */
10039 ret = 0;
10040 break;
10042 #endif
10044 #ifdef TARGET_NR_timer_create
10045 case TARGET_NR_timer_create:
10047 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
10049 struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
10051 int clkid = arg1;
10052 int timer_index = next_free_host_timer();
10054 if (timer_index < 0) {
10055 ret = -TARGET_EAGAIN;
10056 } else {
10057 timer_t *phtimer = g_posix_timers + timer_index;
10059 if (arg2) {
10060 phost_sevp = &host_sevp;
10061 ret = target_to_host_sigevent(phost_sevp, arg2);
10062 if (ret != 0) {
10063 break;
10067 ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
10068 if (ret) {
10069 phtimer = NULL;
10070 } else {
10071 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
10072 goto efault;
10076 break;
10078 #endif
10080 #ifdef TARGET_NR_timer_settime
10081 case TARGET_NR_timer_settime:
10083 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
10084 * struct itimerspec * old_value */
10085 target_timer_t timerid = get_timer_id(arg1);
10087 if (timerid < 0) {
10088 ret = timerid;
10089 } else if (arg3 == 0) {
10090 ret = -TARGET_EINVAL;
10091 } else {
10092 timer_t htimer = g_posix_timers[timerid];
10093 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
10095 target_to_host_itimerspec(&hspec_new, arg3);
10096 ret = get_errno(
10097 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
10098 host_to_target_itimerspec(arg2, &hspec_old);
10100 break;
10102 #endif
10104 #ifdef TARGET_NR_timer_gettime
10105 case TARGET_NR_timer_gettime:
10107 /* args: timer_t timerid, struct itimerspec *curr_value */
10108 target_timer_t timerid = get_timer_id(arg1);
10110 if (timerid < 0) {
10111 ret = timerid;
10112 } else if (!arg2) {
10113 ret = -TARGET_EFAULT;
10114 } else {
10115 timer_t htimer = g_posix_timers[timerid];
10116 struct itimerspec hspec;
10117 ret = get_errno(timer_gettime(htimer, &hspec));
10119 if (host_to_target_itimerspec(arg2, &hspec)) {
10120 ret = -TARGET_EFAULT;
10123 break;
10125 #endif
10127 #ifdef TARGET_NR_timer_getoverrun
10128 case TARGET_NR_timer_getoverrun:
10130 /* args: timer_t timerid */
10131 target_timer_t timerid = get_timer_id(arg1);
10133 if (timerid < 0) {
10134 ret = timerid;
10135 } else {
10136 timer_t htimer = g_posix_timers[timerid];
10137 ret = get_errno(timer_getoverrun(htimer));
10139 fd_trans_unregister(ret);
10140 break;
10142 #endif
10144 #ifdef TARGET_NR_timer_delete
10145 case TARGET_NR_timer_delete:
10147 /* args: timer_t timerid */
10148 target_timer_t timerid = get_timer_id(arg1);
10150 if (timerid < 0) {
10151 ret = timerid;
10152 } else {
10153 timer_t htimer = g_posix_timers[timerid];
10154 ret = get_errno(timer_delete(htimer));
10155 g_posix_timers[timerid] = 0;
10157 break;
10159 #endif
10161 #if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
10162 case TARGET_NR_timerfd_create:
10163 ret = get_errno(timerfd_create(arg1,
10164 target_to_host_bitmask(arg2, fcntl_flags_tbl)));
10165 break;
10166 #endif
10168 #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
10169 case TARGET_NR_timerfd_gettime:
10171 struct itimerspec its_curr;
10173 ret = get_errno(timerfd_gettime(arg1, &its_curr));
10175 if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
10176 goto efault;
10179 break;
10180 #endif
10182 #if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
10183 case TARGET_NR_timerfd_settime:
10185 struct itimerspec its_new, its_old, *p_new;
10187 if (arg3) {
10188 if (target_to_host_itimerspec(&its_new, arg3)) {
10189 goto efault;
10191 p_new = &its_new;
10192 } else {
10193 p_new = NULL;
10196 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
10198 if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
10199 goto efault;
10202 break;
10203 #endif
10205 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
10206 case TARGET_NR_ioprio_get:
10207 ret = get_errno(ioprio_get(arg1, arg2));
10208 break;
10209 #endif
10211 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
10212 case TARGET_NR_ioprio_set:
10213 ret = get_errno(ioprio_set(arg1, arg2, arg3));
10214 break;
10215 #endif
10217 #if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
10218 case TARGET_NR_setns:
10219 ret = get_errno(setns(arg1, arg2));
10220 break;
10221 #endif
10222 #if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
10223 case TARGET_NR_unshare:
10224 ret = get_errno(unshare(arg1));
10225 break;
10226 #endif
10228 default:
10229 unimplemented:
10230 gemu_log("qemu: Unsupported syscall: %d\n", num);
10231 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
10232 unimplemented_nowarn:
10233 #endif
10234 ret = -TARGET_ENOSYS;
10235 break;
10237 fail:
10238 #ifdef DEBUG
10239 gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
10240 #endif
10241 if(do_strace)
10242 print_syscall_ret(num, ret);
10243 return ret;
10244 efault:
10245 ret = -TARGET_EFAULT;
10246 goto fail;