target-arm: Suppress EPD for S2, EL2 and EL3 translations
[qemu/ar7.git] / linux-user / syscall.c
blobc0fabf7fc2babe66ba09854f1cbb6746fe48eedf
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 <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <elf.h>
25 #include <endian.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <time.h>
30 #include <limits.h>
31 #include <grp.h>
32 #include <sys/types.h>
33 #include <sys/ipc.h>
34 #include <sys/msg.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <sys/mount.h>
39 #include <sys/file.h>
40 #include <sys/fsuid.h>
41 #include <sys/personality.h>
42 #include <sys/prctl.h>
43 #include <sys/resource.h>
44 #include <sys/mman.h>
45 #include <sys/swap.h>
46 #include <linux/capability.h>
47 #include <signal.h>
48 #include <sched.h>
49 #ifdef __ia64__
50 int __clone2(int (*fn)(void *), void *child_stack_base,
51 size_t stack_size, int flags, void *arg, ...);
52 #endif
53 #include <sys/socket.h>
54 #include <sys/un.h>
55 #include <sys/uio.h>
56 #include <sys/poll.h>
57 #include <sys/times.h>
58 #include <sys/shm.h>
59 #include <sys/sem.h>
60 #include <sys/statfs.h>
61 #include <utime.h>
62 #include <sys/sysinfo.h>
63 //#include <sys/user.h>
64 #include <netinet/ip.h>
65 #include <netinet/tcp.h>
66 #include <linux/wireless.h>
67 #include <linux/icmp.h>
68 #include "qemu-common.h"
69 #ifdef CONFIG_TIMERFD
70 #include <sys/timerfd.h>
71 #endif
72 #ifdef TARGET_GPROF
73 #include <sys/gmon.h>
74 #endif
75 #ifdef CONFIG_EVENTFD
76 #include <sys/eventfd.h>
77 #endif
78 #ifdef CONFIG_EPOLL
79 #include <sys/epoll.h>
80 #endif
81 #ifdef CONFIG_ATTR
82 #include "qemu/xattr.h"
83 #endif
84 #ifdef CONFIG_SENDFILE
85 #include <sys/sendfile.h>
86 #endif
88 #define termios host_termios
89 #define winsize host_winsize
90 #define termio host_termio
91 #define sgttyb host_sgttyb /* same as target */
92 #define tchars host_tchars /* same as target */
93 #define ltchars host_ltchars /* same as target */
95 #include <linux/termios.h>
96 #include <linux/unistd.h>
97 #include <linux/cdrom.h>
98 #include <linux/hdreg.h>
99 #include <linux/soundcard.h>
100 #include <linux/kd.h>
101 #include <linux/mtio.h>
102 #include <linux/fs.h>
103 #if defined(CONFIG_FIEMAP)
104 #include <linux/fiemap.h>
105 #endif
106 #include <linux/fb.h>
107 #include <linux/vt.h>
108 #include <linux/dm-ioctl.h>
109 #include <linux/reboot.h>
110 #include <linux/route.h>
111 #include <linux/filter.h>
112 #include <linux/blkpg.h>
113 #include "linux_loop.h"
114 #include "uname.h"
116 #include "qemu.h"
118 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
119 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
121 //#define DEBUG
123 //#include <linux/msdos_fs.h>
124 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
125 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
128 #undef _syscall0
129 #undef _syscall1
130 #undef _syscall2
131 #undef _syscall3
132 #undef _syscall4
133 #undef _syscall5
134 #undef _syscall6
136 #define _syscall0(type,name) \
137 static type name (void) \
139 return syscall(__NR_##name); \
142 #define _syscall1(type,name,type1,arg1) \
143 static type name (type1 arg1) \
145 return syscall(__NR_##name, arg1); \
148 #define _syscall2(type,name,type1,arg1,type2,arg2) \
149 static type name (type1 arg1,type2 arg2) \
151 return syscall(__NR_##name, arg1, arg2); \
154 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
155 static type name (type1 arg1,type2 arg2,type3 arg3) \
157 return syscall(__NR_##name, arg1, arg2, arg3); \
160 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
161 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
163 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
166 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
167 type5,arg5) \
168 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
170 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
174 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
175 type5,arg5,type6,arg6) \
176 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
177 type6 arg6) \
179 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
183 #define __NR_sys_uname __NR_uname
184 #define __NR_sys_getcwd1 __NR_getcwd
185 #define __NR_sys_getdents __NR_getdents
186 #define __NR_sys_getdents64 __NR_getdents64
187 #define __NR_sys_getpriority __NR_getpriority
188 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
189 #define __NR_sys_syslog __NR_syslog
190 #define __NR_sys_tgkill __NR_tgkill
191 #define __NR_sys_tkill __NR_tkill
192 #define __NR_sys_futex __NR_futex
193 #define __NR_sys_inotify_init __NR_inotify_init
194 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
195 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
197 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
198 defined(__s390x__)
199 #define __NR__llseek __NR_lseek
200 #endif
202 /* Newer kernel ports have llseek() instead of _llseek() */
203 #if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
204 #define TARGET_NR__llseek TARGET_NR_llseek
205 #endif
207 #ifdef __NR_gettid
208 _syscall0(int, gettid)
209 #else
210 /* This is a replacement for the host gettid() and must return a host
211 errno. */
212 static int gettid(void) {
213 return -ENOSYS;
215 #endif
216 #ifdef __NR_getdents
217 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
218 #endif
219 #if !defined(__NR_getdents) || \
220 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
221 _syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
222 #endif
223 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
224 _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
225 loff_t *, res, uint, wh);
226 #endif
227 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
228 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
229 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
230 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
231 #endif
232 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
233 _syscall2(int,sys_tkill,int,tid,int,sig)
234 #endif
235 #ifdef __NR_exit_group
236 _syscall1(int,exit_group,int,error_code)
237 #endif
238 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
239 _syscall1(int,set_tid_address,int *,tidptr)
240 #endif
241 #if defined(TARGET_NR_futex) && defined(__NR_futex)
242 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
243 const struct timespec *,timeout,int *,uaddr2,int,val3)
244 #endif
245 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
246 _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
247 unsigned long *, user_mask_ptr);
248 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
249 _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
250 unsigned long *, user_mask_ptr);
251 _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
252 void *, arg);
253 _syscall2(int, capget, struct __user_cap_header_struct *, header,
254 struct __user_cap_data_struct *, data);
255 _syscall2(int, capset, struct __user_cap_header_struct *, header,
256 struct __user_cap_data_struct *, data);
257 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
258 _syscall2(int, ioprio_get, int, which, int, who)
259 #endif
260 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
261 _syscall3(int, ioprio_set, int, which, int, who, int, ioprio)
262 #endif
264 static bitmask_transtbl fcntl_flags_tbl[] = {
265 { TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
266 { TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
267 { TARGET_O_CREAT, TARGET_O_CREAT, O_CREAT, O_CREAT, },
268 { TARGET_O_EXCL, TARGET_O_EXCL, O_EXCL, O_EXCL, },
269 { TARGET_O_NOCTTY, TARGET_O_NOCTTY, O_NOCTTY, O_NOCTTY, },
270 { TARGET_O_TRUNC, TARGET_O_TRUNC, O_TRUNC, O_TRUNC, },
271 { TARGET_O_APPEND, TARGET_O_APPEND, O_APPEND, O_APPEND, },
272 { TARGET_O_NONBLOCK, TARGET_O_NONBLOCK, O_NONBLOCK, O_NONBLOCK, },
273 { TARGET_O_SYNC, TARGET_O_DSYNC, O_SYNC, O_DSYNC, },
274 { TARGET_O_SYNC, TARGET_O_SYNC, O_SYNC, O_SYNC, },
275 { TARGET_FASYNC, TARGET_FASYNC, FASYNC, FASYNC, },
276 { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
277 { TARGET_O_NOFOLLOW, TARGET_O_NOFOLLOW, O_NOFOLLOW, O_NOFOLLOW, },
278 #if defined(O_DIRECT)
279 { TARGET_O_DIRECT, TARGET_O_DIRECT, O_DIRECT, O_DIRECT, },
280 #endif
281 #if defined(O_NOATIME)
282 { TARGET_O_NOATIME, TARGET_O_NOATIME, O_NOATIME, O_NOATIME },
283 #endif
284 #if defined(O_CLOEXEC)
285 { TARGET_O_CLOEXEC, TARGET_O_CLOEXEC, O_CLOEXEC, O_CLOEXEC },
286 #endif
287 #if defined(O_PATH)
288 { TARGET_O_PATH, TARGET_O_PATH, O_PATH, O_PATH },
289 #endif
290 /* Don't terminate the list prematurely on 64-bit host+guest. */
291 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
292 { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
293 #endif
294 { 0, 0, 0, 0 }
297 static int sys_getcwd1(char *buf, size_t size)
299 if (getcwd(buf, size) == NULL) {
300 /* getcwd() sets errno */
301 return (-1);
303 return strlen(buf)+1;
306 static int sys_openat(int dirfd, const char *pathname, int flags, mode_t mode)
309 * open(2) has extra parameter 'mode' when called with
310 * flag O_CREAT.
312 if ((flags & O_CREAT) != 0) {
313 return (openat(dirfd, pathname, flags, mode));
315 return (openat(dirfd, pathname, flags));
318 #ifdef TARGET_NR_utimensat
319 #ifdef CONFIG_UTIMENSAT
320 static int sys_utimensat(int dirfd, const char *pathname,
321 const struct timespec times[2], int flags)
323 if (pathname == NULL)
324 return futimens(dirfd, times);
325 else
326 return utimensat(dirfd, pathname, times, flags);
328 #elif defined(__NR_utimensat)
329 #define __NR_sys_utimensat __NR_utimensat
330 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
331 const struct timespec *,tsp,int,flags)
332 #else
333 static int sys_utimensat(int dirfd, const char *pathname,
334 const struct timespec times[2], int flags)
336 errno = ENOSYS;
337 return -1;
339 #endif
340 #endif /* TARGET_NR_utimensat */
342 #ifdef CONFIG_INOTIFY
343 #include <sys/inotify.h>
345 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
346 static int sys_inotify_init(void)
348 return (inotify_init());
350 #endif
351 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
352 static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
354 return (inotify_add_watch(fd, pathname, mask));
356 #endif
357 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
358 static int sys_inotify_rm_watch(int fd, int32_t wd)
360 return (inotify_rm_watch(fd, wd));
362 #endif
363 #ifdef CONFIG_INOTIFY1
364 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
365 static int sys_inotify_init1(int flags)
367 return (inotify_init1(flags));
369 #endif
370 #endif
371 #else
372 /* Userspace can usually survive runtime without inotify */
373 #undef TARGET_NR_inotify_init
374 #undef TARGET_NR_inotify_init1
375 #undef TARGET_NR_inotify_add_watch
376 #undef TARGET_NR_inotify_rm_watch
377 #endif /* CONFIG_INOTIFY */
379 #if defined(TARGET_NR_ppoll)
380 #ifndef __NR_ppoll
381 # define __NR_ppoll -1
382 #endif
383 #define __NR_sys_ppoll __NR_ppoll
384 _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
385 struct timespec *, timeout, const sigset_t *, sigmask,
386 size_t, sigsetsize)
387 #endif
389 #if defined(TARGET_NR_pselect6)
390 #ifndef __NR_pselect6
391 # define __NR_pselect6 -1
392 #endif
393 #define __NR_sys_pselect6 __NR_pselect6
394 _syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
395 fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
396 #endif
398 #if defined(TARGET_NR_prlimit64)
399 #ifndef __NR_prlimit64
400 # define __NR_prlimit64 -1
401 #endif
402 #define __NR_sys_prlimit64 __NR_prlimit64
403 /* The glibc rlimit structure may not be that used by the underlying syscall */
404 struct host_rlimit64 {
405 uint64_t rlim_cur;
406 uint64_t rlim_max;
408 _syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
409 const struct host_rlimit64 *, new_limit,
410 struct host_rlimit64 *, old_limit)
411 #endif
414 #if defined(TARGET_NR_timer_create)
415 /* Maxiumum of 32 active POSIX timers allowed at any one time. */
416 static timer_t g_posix_timers[32] = { 0, } ;
418 static inline int next_free_host_timer(void)
420 int k ;
421 /* FIXME: Does finding the next free slot require a lock? */
422 for (k = 0; k < ARRAY_SIZE(g_posix_timers); k++) {
423 if (g_posix_timers[k] == 0) {
424 g_posix_timers[k] = (timer_t) 1;
425 return k;
428 return -1;
430 #endif
432 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
433 #ifdef TARGET_ARM
434 static inline int regpairs_aligned(void *cpu_env) {
435 return ((((CPUARMState *)cpu_env)->eabi) == 1) ;
437 #elif defined(TARGET_MIPS)
438 static inline int regpairs_aligned(void *cpu_env) { return 1; }
439 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
440 /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
441 * of registers which translates to the same as ARM/MIPS, because we start with
442 * r3 as arg1 */
443 static inline int regpairs_aligned(void *cpu_env) { return 1; }
444 #else
445 static inline int regpairs_aligned(void *cpu_env) { return 0; }
446 #endif
448 #define ERRNO_TABLE_SIZE 1200
450 /* target_to_host_errno_table[] is initialized from
451 * host_to_target_errno_table[] in syscall_init(). */
452 static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
456 * This list is the union of errno values overridden in asm-<arch>/errno.h
457 * minus the errnos that are not actually generic to all archs.
459 static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
460 [EIDRM] = TARGET_EIDRM,
461 [ECHRNG] = TARGET_ECHRNG,
462 [EL2NSYNC] = TARGET_EL2NSYNC,
463 [EL3HLT] = TARGET_EL3HLT,
464 [EL3RST] = TARGET_EL3RST,
465 [ELNRNG] = TARGET_ELNRNG,
466 [EUNATCH] = TARGET_EUNATCH,
467 [ENOCSI] = TARGET_ENOCSI,
468 [EL2HLT] = TARGET_EL2HLT,
469 [EDEADLK] = TARGET_EDEADLK,
470 [ENOLCK] = TARGET_ENOLCK,
471 [EBADE] = TARGET_EBADE,
472 [EBADR] = TARGET_EBADR,
473 [EXFULL] = TARGET_EXFULL,
474 [ENOANO] = TARGET_ENOANO,
475 [EBADRQC] = TARGET_EBADRQC,
476 [EBADSLT] = TARGET_EBADSLT,
477 [EBFONT] = TARGET_EBFONT,
478 [ENOSTR] = TARGET_ENOSTR,
479 [ENODATA] = TARGET_ENODATA,
480 [ETIME] = TARGET_ETIME,
481 [ENOSR] = TARGET_ENOSR,
482 [ENONET] = TARGET_ENONET,
483 [ENOPKG] = TARGET_ENOPKG,
484 [EREMOTE] = TARGET_EREMOTE,
485 [ENOLINK] = TARGET_ENOLINK,
486 [EADV] = TARGET_EADV,
487 [ESRMNT] = TARGET_ESRMNT,
488 [ECOMM] = TARGET_ECOMM,
489 [EPROTO] = TARGET_EPROTO,
490 [EDOTDOT] = TARGET_EDOTDOT,
491 [EMULTIHOP] = TARGET_EMULTIHOP,
492 [EBADMSG] = TARGET_EBADMSG,
493 [ENAMETOOLONG] = TARGET_ENAMETOOLONG,
494 [EOVERFLOW] = TARGET_EOVERFLOW,
495 [ENOTUNIQ] = TARGET_ENOTUNIQ,
496 [EBADFD] = TARGET_EBADFD,
497 [EREMCHG] = TARGET_EREMCHG,
498 [ELIBACC] = TARGET_ELIBACC,
499 [ELIBBAD] = TARGET_ELIBBAD,
500 [ELIBSCN] = TARGET_ELIBSCN,
501 [ELIBMAX] = TARGET_ELIBMAX,
502 [ELIBEXEC] = TARGET_ELIBEXEC,
503 [EILSEQ] = TARGET_EILSEQ,
504 [ENOSYS] = TARGET_ENOSYS,
505 [ELOOP] = TARGET_ELOOP,
506 [ERESTART] = TARGET_ERESTART,
507 [ESTRPIPE] = TARGET_ESTRPIPE,
508 [ENOTEMPTY] = TARGET_ENOTEMPTY,
509 [EUSERS] = TARGET_EUSERS,
510 [ENOTSOCK] = TARGET_ENOTSOCK,
511 [EDESTADDRREQ] = TARGET_EDESTADDRREQ,
512 [EMSGSIZE] = TARGET_EMSGSIZE,
513 [EPROTOTYPE] = TARGET_EPROTOTYPE,
514 [ENOPROTOOPT] = TARGET_ENOPROTOOPT,
515 [EPROTONOSUPPORT] = TARGET_EPROTONOSUPPORT,
516 [ESOCKTNOSUPPORT] = TARGET_ESOCKTNOSUPPORT,
517 [EOPNOTSUPP] = TARGET_EOPNOTSUPP,
518 [EPFNOSUPPORT] = TARGET_EPFNOSUPPORT,
519 [EAFNOSUPPORT] = TARGET_EAFNOSUPPORT,
520 [EADDRINUSE] = TARGET_EADDRINUSE,
521 [EADDRNOTAVAIL] = TARGET_EADDRNOTAVAIL,
522 [ENETDOWN] = TARGET_ENETDOWN,
523 [ENETUNREACH] = TARGET_ENETUNREACH,
524 [ENETRESET] = TARGET_ENETRESET,
525 [ECONNABORTED] = TARGET_ECONNABORTED,
526 [ECONNRESET] = TARGET_ECONNRESET,
527 [ENOBUFS] = TARGET_ENOBUFS,
528 [EISCONN] = TARGET_EISCONN,
529 [ENOTCONN] = TARGET_ENOTCONN,
530 [EUCLEAN] = TARGET_EUCLEAN,
531 [ENOTNAM] = TARGET_ENOTNAM,
532 [ENAVAIL] = TARGET_ENAVAIL,
533 [EISNAM] = TARGET_EISNAM,
534 [EREMOTEIO] = TARGET_EREMOTEIO,
535 [ESHUTDOWN] = TARGET_ESHUTDOWN,
536 [ETOOMANYREFS] = TARGET_ETOOMANYREFS,
537 [ETIMEDOUT] = TARGET_ETIMEDOUT,
538 [ECONNREFUSED] = TARGET_ECONNREFUSED,
539 [EHOSTDOWN] = TARGET_EHOSTDOWN,
540 [EHOSTUNREACH] = TARGET_EHOSTUNREACH,
541 [EALREADY] = TARGET_EALREADY,
542 [EINPROGRESS] = TARGET_EINPROGRESS,
543 [ESTALE] = TARGET_ESTALE,
544 [ECANCELED] = TARGET_ECANCELED,
545 [ENOMEDIUM] = TARGET_ENOMEDIUM,
546 [EMEDIUMTYPE] = TARGET_EMEDIUMTYPE,
547 #ifdef ENOKEY
548 [ENOKEY] = TARGET_ENOKEY,
549 #endif
550 #ifdef EKEYEXPIRED
551 [EKEYEXPIRED] = TARGET_EKEYEXPIRED,
552 #endif
553 #ifdef EKEYREVOKED
554 [EKEYREVOKED] = TARGET_EKEYREVOKED,
555 #endif
556 #ifdef EKEYREJECTED
557 [EKEYREJECTED] = TARGET_EKEYREJECTED,
558 #endif
559 #ifdef EOWNERDEAD
560 [EOWNERDEAD] = TARGET_EOWNERDEAD,
561 #endif
562 #ifdef ENOTRECOVERABLE
563 [ENOTRECOVERABLE] = TARGET_ENOTRECOVERABLE,
564 #endif
567 static inline int host_to_target_errno(int err)
569 if(host_to_target_errno_table[err])
570 return host_to_target_errno_table[err];
571 return err;
574 static inline int target_to_host_errno(int err)
576 if (target_to_host_errno_table[err])
577 return target_to_host_errno_table[err];
578 return err;
581 static inline abi_long get_errno(abi_long ret)
583 if (ret == -1)
584 return -host_to_target_errno(errno);
585 else
586 return ret;
589 static inline int is_error(abi_long ret)
591 return (abi_ulong)ret >= (abi_ulong)(-4096);
594 char *target_strerror(int err)
596 if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
597 return NULL;
599 return strerror(target_to_host_errno(err));
602 static inline int host_to_target_sock_type(int host_type)
604 int target_type;
606 switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
607 case SOCK_DGRAM:
608 target_type = TARGET_SOCK_DGRAM;
609 break;
610 case SOCK_STREAM:
611 target_type = TARGET_SOCK_STREAM;
612 break;
613 default:
614 target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
615 break;
618 #if defined(SOCK_CLOEXEC)
619 if (host_type & SOCK_CLOEXEC) {
620 target_type |= TARGET_SOCK_CLOEXEC;
622 #endif
624 #if defined(SOCK_NONBLOCK)
625 if (host_type & SOCK_NONBLOCK) {
626 target_type |= TARGET_SOCK_NONBLOCK;
628 #endif
630 return target_type;
633 static abi_ulong target_brk;
634 static abi_ulong target_original_brk;
635 static abi_ulong brk_page;
637 void target_set_brk(abi_ulong new_brk)
639 target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
640 brk_page = HOST_PAGE_ALIGN(target_brk);
643 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
644 #define DEBUGF_BRK(message, args...)
646 /* do_brk() must return target values and target errnos. */
647 abi_long do_brk(abi_ulong new_brk)
649 abi_long mapped_addr;
650 int new_alloc_size;
652 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx ") -> ", new_brk);
654 if (!new_brk) {
655 DEBUGF_BRK(TARGET_ABI_FMT_lx " (!new_brk)\n", target_brk);
656 return target_brk;
658 if (new_brk < target_original_brk) {
659 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk < target_original_brk)\n",
660 target_brk);
661 return target_brk;
664 /* If the new brk is less than the highest page reserved to the
665 * target heap allocation, set it and we're almost done... */
666 if (new_brk <= brk_page) {
667 /* Heap contents are initialized to zero, as for anonymous
668 * mapped pages. */
669 if (new_brk > target_brk) {
670 memset(g2h(target_brk), 0, new_brk - target_brk);
672 target_brk = new_brk;
673 DEBUGF_BRK(TARGET_ABI_FMT_lx " (new_brk <= brk_page)\n", target_brk);
674 return target_brk;
677 /* We need to allocate more memory after the brk... Note that
678 * we don't use MAP_FIXED because that will map over the top of
679 * any existing mapping (like the one with the host libc or qemu
680 * itself); instead we treat "mapped but at wrong address" as
681 * a failure and unmap again.
683 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
684 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
685 PROT_READ|PROT_WRITE,
686 MAP_ANON|MAP_PRIVATE, 0, 0));
688 if (mapped_addr == brk_page) {
689 /* Heap contents are initialized to zero, as for anonymous
690 * mapped pages. Technically the new pages are already
691 * initialized to zero since they *are* anonymous mapped
692 * pages, however we have to take care with the contents that
693 * come from the remaining part of the previous page: it may
694 * contains garbage data due to a previous heap usage (grown
695 * then shrunken). */
696 memset(g2h(target_brk), 0, brk_page - target_brk);
698 target_brk = new_brk;
699 brk_page = HOST_PAGE_ALIGN(target_brk);
700 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr == brk_page)\n",
701 target_brk);
702 return target_brk;
703 } else if (mapped_addr != -1) {
704 /* Mapped but at wrong address, meaning there wasn't actually
705 * enough space for this brk.
707 target_munmap(mapped_addr, new_alloc_size);
708 mapped_addr = -1;
709 DEBUGF_BRK(TARGET_ABI_FMT_lx " (mapped_addr != -1)\n", target_brk);
711 else {
712 DEBUGF_BRK(TARGET_ABI_FMT_lx " (otherwise)\n", target_brk);
715 #if defined(TARGET_ALPHA)
716 /* We (partially) emulate OSF/1 on Alpha, which requires we
717 return a proper errno, not an unchanged brk value. */
718 return -TARGET_ENOMEM;
719 #endif
720 /* For everything else, return the previous break. */
721 return target_brk;
724 static inline abi_long copy_from_user_fdset(fd_set *fds,
725 abi_ulong target_fds_addr,
726 int n)
728 int i, nw, j, k;
729 abi_ulong b, *target_fds;
731 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
732 if (!(target_fds = lock_user(VERIFY_READ,
733 target_fds_addr,
734 sizeof(abi_ulong) * nw,
735 1)))
736 return -TARGET_EFAULT;
738 FD_ZERO(fds);
739 k = 0;
740 for (i = 0; i < nw; i++) {
741 /* grab the abi_ulong */
742 __get_user(b, &target_fds[i]);
743 for (j = 0; j < TARGET_ABI_BITS; j++) {
744 /* check the bit inside the abi_ulong */
745 if ((b >> j) & 1)
746 FD_SET(k, fds);
747 k++;
751 unlock_user(target_fds, target_fds_addr, 0);
753 return 0;
756 static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
757 abi_ulong target_fds_addr,
758 int n)
760 if (target_fds_addr) {
761 if (copy_from_user_fdset(fds, target_fds_addr, n))
762 return -TARGET_EFAULT;
763 *fds_ptr = fds;
764 } else {
765 *fds_ptr = NULL;
767 return 0;
770 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
771 const fd_set *fds,
772 int n)
774 int i, nw, j, k;
775 abi_long v;
776 abi_ulong *target_fds;
778 nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
779 if (!(target_fds = lock_user(VERIFY_WRITE,
780 target_fds_addr,
781 sizeof(abi_ulong) * nw,
782 0)))
783 return -TARGET_EFAULT;
785 k = 0;
786 for (i = 0; i < nw; i++) {
787 v = 0;
788 for (j = 0; j < TARGET_ABI_BITS; j++) {
789 v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
790 k++;
792 __put_user(v, &target_fds[i]);
795 unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
797 return 0;
800 #if defined(__alpha__)
801 #define HOST_HZ 1024
802 #else
803 #define HOST_HZ 100
804 #endif
806 static inline abi_long host_to_target_clock_t(long ticks)
808 #if HOST_HZ == TARGET_HZ
809 return ticks;
810 #else
811 return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
812 #endif
815 static inline abi_long host_to_target_rusage(abi_ulong target_addr,
816 const struct rusage *rusage)
818 struct target_rusage *target_rusage;
820 if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
821 return -TARGET_EFAULT;
822 target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec);
823 target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec);
824 target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec);
825 target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec);
826 target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss);
827 target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss);
828 target_rusage->ru_idrss = tswapal(rusage->ru_idrss);
829 target_rusage->ru_isrss = tswapal(rusage->ru_isrss);
830 target_rusage->ru_minflt = tswapal(rusage->ru_minflt);
831 target_rusage->ru_majflt = tswapal(rusage->ru_majflt);
832 target_rusage->ru_nswap = tswapal(rusage->ru_nswap);
833 target_rusage->ru_inblock = tswapal(rusage->ru_inblock);
834 target_rusage->ru_oublock = tswapal(rusage->ru_oublock);
835 target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd);
836 target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv);
837 target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals);
838 target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw);
839 target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw);
840 unlock_user_struct(target_rusage, target_addr, 1);
842 return 0;
845 static inline rlim_t target_to_host_rlim(abi_ulong target_rlim)
847 abi_ulong target_rlim_swap;
848 rlim_t result;
850 target_rlim_swap = tswapal(target_rlim);
851 if (target_rlim_swap == TARGET_RLIM_INFINITY)
852 return RLIM_INFINITY;
854 result = target_rlim_swap;
855 if (target_rlim_swap != (rlim_t)result)
856 return RLIM_INFINITY;
858 return result;
861 static inline abi_ulong host_to_target_rlim(rlim_t rlim)
863 abi_ulong target_rlim_swap;
864 abi_ulong result;
866 if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
867 target_rlim_swap = TARGET_RLIM_INFINITY;
868 else
869 target_rlim_swap = rlim;
870 result = tswapal(target_rlim_swap);
872 return result;
875 static inline int target_to_host_resource(int code)
877 switch (code) {
878 case TARGET_RLIMIT_AS:
879 return RLIMIT_AS;
880 case TARGET_RLIMIT_CORE:
881 return RLIMIT_CORE;
882 case TARGET_RLIMIT_CPU:
883 return RLIMIT_CPU;
884 case TARGET_RLIMIT_DATA:
885 return RLIMIT_DATA;
886 case TARGET_RLIMIT_FSIZE:
887 return RLIMIT_FSIZE;
888 case TARGET_RLIMIT_LOCKS:
889 return RLIMIT_LOCKS;
890 case TARGET_RLIMIT_MEMLOCK:
891 return RLIMIT_MEMLOCK;
892 case TARGET_RLIMIT_MSGQUEUE:
893 return RLIMIT_MSGQUEUE;
894 case TARGET_RLIMIT_NICE:
895 return RLIMIT_NICE;
896 case TARGET_RLIMIT_NOFILE:
897 return RLIMIT_NOFILE;
898 case TARGET_RLIMIT_NPROC:
899 return RLIMIT_NPROC;
900 case TARGET_RLIMIT_RSS:
901 return RLIMIT_RSS;
902 case TARGET_RLIMIT_RTPRIO:
903 return RLIMIT_RTPRIO;
904 case TARGET_RLIMIT_SIGPENDING:
905 return RLIMIT_SIGPENDING;
906 case TARGET_RLIMIT_STACK:
907 return RLIMIT_STACK;
908 default:
909 return code;
913 static inline abi_long copy_from_user_timeval(struct timeval *tv,
914 abi_ulong target_tv_addr)
916 struct target_timeval *target_tv;
918 if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
919 return -TARGET_EFAULT;
921 __get_user(tv->tv_sec, &target_tv->tv_sec);
922 __get_user(tv->tv_usec, &target_tv->tv_usec);
924 unlock_user_struct(target_tv, target_tv_addr, 0);
926 return 0;
929 static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
930 const struct timeval *tv)
932 struct target_timeval *target_tv;
934 if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
935 return -TARGET_EFAULT;
937 __put_user(tv->tv_sec, &target_tv->tv_sec);
938 __put_user(tv->tv_usec, &target_tv->tv_usec);
940 unlock_user_struct(target_tv, target_tv_addr, 1);
942 return 0;
945 static inline abi_long copy_from_user_timezone(struct timezone *tz,
946 abi_ulong target_tz_addr)
948 struct target_timezone *target_tz;
950 if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
951 return -TARGET_EFAULT;
954 __get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
955 __get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
957 unlock_user_struct(target_tz, target_tz_addr, 0);
959 return 0;
962 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
963 #include <mqueue.h>
965 static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
966 abi_ulong target_mq_attr_addr)
968 struct target_mq_attr *target_mq_attr;
970 if (!lock_user_struct(VERIFY_READ, target_mq_attr,
971 target_mq_attr_addr, 1))
972 return -TARGET_EFAULT;
974 __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
975 __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
976 __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
977 __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
979 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
981 return 0;
984 static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
985 const struct mq_attr *attr)
987 struct target_mq_attr *target_mq_attr;
989 if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
990 target_mq_attr_addr, 0))
991 return -TARGET_EFAULT;
993 __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
994 __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
995 __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
996 __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
998 unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1000 return 0;
1002 #endif
1004 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1005 /* do_select() must return target values and target errnos. */
1006 static abi_long do_select(int n,
1007 abi_ulong rfd_addr, abi_ulong wfd_addr,
1008 abi_ulong efd_addr, abi_ulong target_tv_addr)
1010 fd_set rfds, wfds, efds;
1011 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1012 struct timeval tv, *tv_ptr;
1013 abi_long ret;
1015 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1016 if (ret) {
1017 return ret;
1019 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1020 if (ret) {
1021 return ret;
1023 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1024 if (ret) {
1025 return ret;
1028 if (target_tv_addr) {
1029 if (copy_from_user_timeval(&tv, target_tv_addr))
1030 return -TARGET_EFAULT;
1031 tv_ptr = &tv;
1032 } else {
1033 tv_ptr = NULL;
1036 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1038 if (!is_error(ret)) {
1039 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1040 return -TARGET_EFAULT;
1041 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1042 return -TARGET_EFAULT;
1043 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1044 return -TARGET_EFAULT;
1046 if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1047 return -TARGET_EFAULT;
1050 return ret;
1052 #endif
1054 static abi_long do_pipe2(int host_pipe[], int flags)
1056 #ifdef CONFIG_PIPE2
1057 return pipe2(host_pipe, flags);
1058 #else
1059 return -ENOSYS;
1060 #endif
1063 static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1064 int flags, int is_pipe2)
1066 int host_pipe[2];
1067 abi_long ret;
1068 ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1070 if (is_error(ret))
1071 return get_errno(ret);
1073 /* Several targets have special calling conventions for the original
1074 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1075 if (!is_pipe2) {
1076 #if defined(TARGET_ALPHA)
1077 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1078 return host_pipe[0];
1079 #elif defined(TARGET_MIPS)
1080 ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1081 return host_pipe[0];
1082 #elif defined(TARGET_SH4)
1083 ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1084 return host_pipe[0];
1085 #elif defined(TARGET_SPARC)
1086 ((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
1087 return host_pipe[0];
1088 #endif
1091 if (put_user_s32(host_pipe[0], pipedes)
1092 || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1093 return -TARGET_EFAULT;
1094 return get_errno(ret);
1097 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1098 abi_ulong target_addr,
1099 socklen_t len)
1101 struct target_ip_mreqn *target_smreqn;
1103 target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1104 if (!target_smreqn)
1105 return -TARGET_EFAULT;
1106 mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1107 mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1108 if (len == sizeof(struct target_ip_mreqn))
1109 mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex);
1110 unlock_user(target_smreqn, target_addr, 0);
1112 return 0;
1115 static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1116 abi_ulong target_addr,
1117 socklen_t len)
1119 const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1120 sa_family_t sa_family;
1121 struct target_sockaddr *target_saddr;
1123 target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1124 if (!target_saddr)
1125 return -TARGET_EFAULT;
1127 sa_family = tswap16(target_saddr->sa_family);
1129 /* Oops. The caller might send a incomplete sun_path; sun_path
1130 * must be terminated by \0 (see the manual page), but
1131 * unfortunately it is quite common to specify sockaddr_un
1132 * length as "strlen(x->sun_path)" while it should be
1133 * "strlen(...) + 1". We'll fix that here if needed.
1134 * Linux kernel has a similar feature.
1137 if (sa_family == AF_UNIX) {
1138 if (len < unix_maxlen && len > 0) {
1139 char *cp = (char*)target_saddr;
1141 if ( cp[len-1] && !cp[len] )
1142 len++;
1144 if (len > unix_maxlen)
1145 len = unix_maxlen;
1148 memcpy(addr, target_saddr, len);
1149 addr->sa_family = sa_family;
1150 if (sa_family == AF_PACKET) {
1151 struct target_sockaddr_ll *lladdr;
1153 lladdr = (struct target_sockaddr_ll *)addr;
1154 lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
1155 lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
1157 unlock_user(target_saddr, target_addr, 0);
1159 return 0;
1162 static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1163 struct sockaddr *addr,
1164 socklen_t len)
1166 struct target_sockaddr *target_saddr;
1168 target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1169 if (!target_saddr)
1170 return -TARGET_EFAULT;
1171 memcpy(target_saddr, addr, len);
1172 target_saddr->sa_family = tswap16(addr->sa_family);
1173 unlock_user(target_saddr, target_addr, len);
1175 return 0;
1178 static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1179 struct target_msghdr *target_msgh)
1181 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1182 abi_long msg_controllen;
1183 abi_ulong target_cmsg_addr;
1184 struct target_cmsghdr *target_cmsg;
1185 socklen_t space = 0;
1187 msg_controllen = tswapal(target_msgh->msg_controllen);
1188 if (msg_controllen < sizeof (struct target_cmsghdr))
1189 goto the_end;
1190 target_cmsg_addr = tswapal(target_msgh->msg_control);
1191 target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1192 if (!target_cmsg)
1193 return -TARGET_EFAULT;
1195 while (cmsg && target_cmsg) {
1196 void *data = CMSG_DATA(cmsg);
1197 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1199 int len = tswapal(target_cmsg->cmsg_len)
1200 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1202 space += CMSG_SPACE(len);
1203 if (space > msgh->msg_controllen) {
1204 space -= CMSG_SPACE(len);
1205 /* This is a QEMU bug, since we allocated the payload
1206 * area ourselves (unlike overflow in host-to-target
1207 * conversion, which is just the guest giving us a buffer
1208 * that's too small). It can't happen for the payload types
1209 * we currently support; if it becomes an issue in future
1210 * we would need to improve our allocation strategy to
1211 * something more intelligent than "twice the size of the
1212 * target buffer we're reading from".
1214 gemu_log("Host cmsg overflow\n");
1215 break;
1218 if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {
1219 cmsg->cmsg_level = SOL_SOCKET;
1220 } else {
1221 cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1223 cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1224 cmsg->cmsg_len = CMSG_LEN(len);
1226 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
1227 int *fd = (int *)data;
1228 int *target_fd = (int *)target_data;
1229 int i, numfds = len / sizeof(int);
1231 for (i = 0; i < numfds; i++) {
1232 __get_user(fd[i], target_fd + i);
1234 } else if (cmsg->cmsg_level == SOL_SOCKET
1235 && cmsg->cmsg_type == SCM_CREDENTIALS) {
1236 struct ucred *cred = (struct ucred *)data;
1237 struct target_ucred *target_cred =
1238 (struct target_ucred *)target_data;
1240 __get_user(cred->pid, &target_cred->pid);
1241 __get_user(cred->uid, &target_cred->uid);
1242 __get_user(cred->gid, &target_cred->gid);
1243 } else {
1244 gemu_log("Unsupported ancillary data: %d/%d\n",
1245 cmsg->cmsg_level, cmsg->cmsg_type);
1246 memcpy(data, target_data, len);
1249 cmsg = CMSG_NXTHDR(msgh, cmsg);
1250 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1252 unlock_user(target_cmsg, target_cmsg_addr, 0);
1253 the_end:
1254 msgh->msg_controllen = space;
1255 return 0;
1258 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1259 struct msghdr *msgh)
1261 struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1262 abi_long msg_controllen;
1263 abi_ulong target_cmsg_addr;
1264 struct target_cmsghdr *target_cmsg;
1265 socklen_t space = 0;
1267 msg_controllen = tswapal(target_msgh->msg_controllen);
1268 if (msg_controllen < sizeof (struct target_cmsghdr))
1269 goto the_end;
1270 target_cmsg_addr = tswapal(target_msgh->msg_control);
1271 target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1272 if (!target_cmsg)
1273 return -TARGET_EFAULT;
1275 while (cmsg && target_cmsg) {
1276 void *data = CMSG_DATA(cmsg);
1277 void *target_data = TARGET_CMSG_DATA(target_cmsg);
1279 int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1280 int tgt_len, tgt_space;
1282 /* We never copy a half-header but may copy half-data;
1283 * this is Linux's behaviour in put_cmsg(). Note that
1284 * truncation here is a guest problem (which we report
1285 * to the guest via the CTRUNC bit), unlike truncation
1286 * in target_to_host_cmsg, which is a QEMU bug.
1288 if (msg_controllen < sizeof(struct cmsghdr)) {
1289 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
1290 break;
1293 if (cmsg->cmsg_level == SOL_SOCKET) {
1294 target_cmsg->cmsg_level = tswap32(TARGET_SOL_SOCKET);
1295 } else {
1296 target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1298 target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1300 tgt_len = TARGET_CMSG_LEN(len);
1302 /* Payload types which need a different size of payload on
1303 * the target must adjust tgt_len here.
1305 switch (cmsg->cmsg_level) {
1306 case SOL_SOCKET:
1307 switch (cmsg->cmsg_type) {
1308 case SO_TIMESTAMP:
1309 tgt_len = sizeof(struct target_timeval);
1310 break;
1311 default:
1312 break;
1314 default:
1315 break;
1318 if (msg_controllen < tgt_len) {
1319 target_msgh->msg_flags |= tswap32(MSG_CTRUNC);
1320 tgt_len = msg_controllen;
1323 /* We must now copy-and-convert len bytes of payload
1324 * into tgt_len bytes of destination space. Bear in mind
1325 * that in both source and destination we may be dealing
1326 * with a truncated value!
1328 switch (cmsg->cmsg_level) {
1329 case SOL_SOCKET:
1330 switch (cmsg->cmsg_type) {
1331 case SCM_RIGHTS:
1333 int *fd = (int *)data;
1334 int *target_fd = (int *)target_data;
1335 int i, numfds = tgt_len / sizeof(int);
1337 for (i = 0; i < numfds; i++) {
1338 __put_user(fd[i], target_fd + i);
1340 break;
1342 case SO_TIMESTAMP:
1344 struct timeval *tv = (struct timeval *)data;
1345 struct target_timeval *target_tv =
1346 (struct target_timeval *)target_data;
1348 if (len != sizeof(struct timeval) ||
1349 tgt_len != sizeof(struct target_timeval)) {
1350 goto unimplemented;
1353 /* copy struct timeval to target */
1354 __put_user(tv->tv_sec, &target_tv->tv_sec);
1355 __put_user(tv->tv_usec, &target_tv->tv_usec);
1356 break;
1358 case SCM_CREDENTIALS:
1360 struct ucred *cred = (struct ucred *)data;
1361 struct target_ucred *target_cred =
1362 (struct target_ucred *)target_data;
1364 __put_user(cred->pid, &target_cred->pid);
1365 __put_user(cred->uid, &target_cred->uid);
1366 __put_user(cred->gid, &target_cred->gid);
1367 break;
1369 default:
1370 goto unimplemented;
1372 break;
1374 default:
1375 unimplemented:
1376 gemu_log("Unsupported ancillary data: %d/%d\n",
1377 cmsg->cmsg_level, cmsg->cmsg_type);
1378 memcpy(target_data, data, MIN(len, tgt_len));
1379 if (tgt_len > len) {
1380 memset(target_data + len, 0, tgt_len - len);
1384 target_cmsg->cmsg_len = tswapal(tgt_len);
1385 tgt_space = TARGET_CMSG_SPACE(tgt_len);
1386 if (msg_controllen < tgt_space) {
1387 tgt_space = msg_controllen;
1389 msg_controllen -= tgt_space;
1390 space += tgt_space;
1391 cmsg = CMSG_NXTHDR(msgh, cmsg);
1392 target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1394 unlock_user(target_cmsg, target_cmsg_addr, space);
1395 the_end:
1396 target_msgh->msg_controllen = tswapal(space);
1397 return 0;
1400 /* do_setsockopt() Must return target values and target errnos. */
1401 static abi_long do_setsockopt(int sockfd, int level, int optname,
1402 abi_ulong optval_addr, socklen_t optlen)
1404 abi_long ret;
1405 int val;
1406 struct ip_mreqn *ip_mreq;
1407 struct ip_mreq_source *ip_mreq_source;
1409 switch(level) {
1410 case SOL_TCP:
1411 /* TCP options all take an 'int' value. */
1412 if (optlen < sizeof(uint32_t))
1413 return -TARGET_EINVAL;
1415 if (get_user_u32(val, optval_addr))
1416 return -TARGET_EFAULT;
1417 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1418 break;
1419 case SOL_IP:
1420 switch(optname) {
1421 case IP_TOS:
1422 case IP_TTL:
1423 case IP_HDRINCL:
1424 case IP_ROUTER_ALERT:
1425 case IP_RECVOPTS:
1426 case IP_RETOPTS:
1427 case IP_PKTINFO:
1428 case IP_MTU_DISCOVER:
1429 case IP_RECVERR:
1430 case IP_RECVTOS:
1431 #ifdef IP_FREEBIND
1432 case IP_FREEBIND:
1433 #endif
1434 case IP_MULTICAST_TTL:
1435 case IP_MULTICAST_LOOP:
1436 val = 0;
1437 if (optlen >= sizeof(uint32_t)) {
1438 if (get_user_u32(val, optval_addr))
1439 return -TARGET_EFAULT;
1440 } else if (optlen >= 1) {
1441 if (get_user_u8(val, optval_addr))
1442 return -TARGET_EFAULT;
1444 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1445 break;
1446 case IP_ADD_MEMBERSHIP:
1447 case IP_DROP_MEMBERSHIP:
1448 if (optlen < sizeof (struct target_ip_mreq) ||
1449 optlen > sizeof (struct target_ip_mreqn))
1450 return -TARGET_EINVAL;
1452 ip_mreq = (struct ip_mreqn *) alloca(optlen);
1453 target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1454 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1455 break;
1457 case IP_BLOCK_SOURCE:
1458 case IP_UNBLOCK_SOURCE:
1459 case IP_ADD_SOURCE_MEMBERSHIP:
1460 case IP_DROP_SOURCE_MEMBERSHIP:
1461 if (optlen != sizeof (struct target_ip_mreq_source))
1462 return -TARGET_EINVAL;
1464 ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1465 ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1466 unlock_user (ip_mreq_source, optval_addr, 0);
1467 break;
1469 default:
1470 goto unimplemented;
1472 break;
1473 case SOL_IPV6:
1474 switch (optname) {
1475 case IPV6_MTU_DISCOVER:
1476 case IPV6_MTU:
1477 case IPV6_V6ONLY:
1478 case IPV6_RECVPKTINFO:
1479 val = 0;
1480 if (optlen < sizeof(uint32_t)) {
1481 return -TARGET_EINVAL;
1483 if (get_user_u32(val, optval_addr)) {
1484 return -TARGET_EFAULT;
1486 ret = get_errno(setsockopt(sockfd, level, optname,
1487 &val, sizeof(val)));
1488 break;
1489 default:
1490 goto unimplemented;
1492 break;
1493 case SOL_RAW:
1494 switch (optname) {
1495 case ICMP_FILTER:
1496 /* struct icmp_filter takes an u32 value */
1497 if (optlen < sizeof(uint32_t)) {
1498 return -TARGET_EINVAL;
1501 if (get_user_u32(val, optval_addr)) {
1502 return -TARGET_EFAULT;
1504 ret = get_errno(setsockopt(sockfd, level, optname,
1505 &val, sizeof(val)));
1506 break;
1508 default:
1509 goto unimplemented;
1511 break;
1512 case TARGET_SOL_SOCKET:
1513 switch (optname) {
1514 case TARGET_SO_RCVTIMEO:
1516 struct timeval tv;
1518 optname = SO_RCVTIMEO;
1520 set_timeout:
1521 if (optlen != sizeof(struct target_timeval)) {
1522 return -TARGET_EINVAL;
1525 if (copy_from_user_timeval(&tv, optval_addr)) {
1526 return -TARGET_EFAULT;
1529 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname,
1530 &tv, sizeof(tv)));
1531 return ret;
1533 case TARGET_SO_SNDTIMEO:
1534 optname = SO_SNDTIMEO;
1535 goto set_timeout;
1536 case TARGET_SO_ATTACH_FILTER:
1538 struct target_sock_fprog *tfprog;
1539 struct target_sock_filter *tfilter;
1540 struct sock_fprog fprog;
1541 struct sock_filter *filter;
1542 int i;
1544 if (optlen != sizeof(*tfprog)) {
1545 return -TARGET_EINVAL;
1547 if (!lock_user_struct(VERIFY_READ, tfprog, optval_addr, 0)) {
1548 return -TARGET_EFAULT;
1550 if (!lock_user_struct(VERIFY_READ, tfilter,
1551 tswapal(tfprog->filter), 0)) {
1552 unlock_user_struct(tfprog, optval_addr, 1);
1553 return -TARGET_EFAULT;
1556 fprog.len = tswap16(tfprog->len);
1557 filter = malloc(fprog.len * sizeof(*filter));
1558 if (filter == NULL) {
1559 unlock_user_struct(tfilter, tfprog->filter, 1);
1560 unlock_user_struct(tfprog, optval_addr, 1);
1561 return -TARGET_ENOMEM;
1563 for (i = 0; i < fprog.len; i++) {
1564 filter[i].code = tswap16(tfilter[i].code);
1565 filter[i].jt = tfilter[i].jt;
1566 filter[i].jf = tfilter[i].jf;
1567 filter[i].k = tswap32(tfilter[i].k);
1569 fprog.filter = filter;
1571 ret = get_errno(setsockopt(sockfd, SOL_SOCKET,
1572 SO_ATTACH_FILTER, &fprog, sizeof(fprog)));
1573 free(filter);
1575 unlock_user_struct(tfilter, tfprog->filter, 1);
1576 unlock_user_struct(tfprog, optval_addr, 1);
1577 return ret;
1579 case TARGET_SO_BINDTODEVICE:
1581 char *dev_ifname, *addr_ifname;
1583 if (optlen > IFNAMSIZ - 1) {
1584 optlen = IFNAMSIZ - 1;
1586 dev_ifname = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1587 if (!dev_ifname) {
1588 return -TARGET_EFAULT;
1590 optname = SO_BINDTODEVICE;
1591 addr_ifname = alloca(IFNAMSIZ);
1592 memcpy(addr_ifname, dev_ifname, optlen);
1593 addr_ifname[optlen] = 0;
1594 ret = get_errno(setsockopt(sockfd, level, optname, addr_ifname, optlen));
1595 unlock_user (dev_ifname, optval_addr, 0);
1596 return ret;
1598 /* Options with 'int' argument. */
1599 case TARGET_SO_DEBUG:
1600 optname = SO_DEBUG;
1601 break;
1602 case TARGET_SO_REUSEADDR:
1603 optname = SO_REUSEADDR;
1604 break;
1605 case TARGET_SO_TYPE:
1606 optname = SO_TYPE;
1607 break;
1608 case TARGET_SO_ERROR:
1609 optname = SO_ERROR;
1610 break;
1611 case TARGET_SO_DONTROUTE:
1612 optname = SO_DONTROUTE;
1613 break;
1614 case TARGET_SO_BROADCAST:
1615 optname = SO_BROADCAST;
1616 break;
1617 case TARGET_SO_SNDBUF:
1618 optname = SO_SNDBUF;
1619 break;
1620 case TARGET_SO_SNDBUFFORCE:
1621 optname = SO_SNDBUFFORCE;
1622 break;
1623 case TARGET_SO_RCVBUF:
1624 optname = SO_RCVBUF;
1625 break;
1626 case TARGET_SO_RCVBUFFORCE:
1627 optname = SO_RCVBUFFORCE;
1628 break;
1629 case TARGET_SO_KEEPALIVE:
1630 optname = SO_KEEPALIVE;
1631 break;
1632 case TARGET_SO_OOBINLINE:
1633 optname = SO_OOBINLINE;
1634 break;
1635 case TARGET_SO_NO_CHECK:
1636 optname = SO_NO_CHECK;
1637 break;
1638 case TARGET_SO_PRIORITY:
1639 optname = SO_PRIORITY;
1640 break;
1641 #ifdef SO_BSDCOMPAT
1642 case TARGET_SO_BSDCOMPAT:
1643 optname = SO_BSDCOMPAT;
1644 break;
1645 #endif
1646 case TARGET_SO_PASSCRED:
1647 optname = SO_PASSCRED;
1648 break;
1649 case TARGET_SO_PASSSEC:
1650 optname = SO_PASSSEC;
1651 break;
1652 case TARGET_SO_TIMESTAMP:
1653 optname = SO_TIMESTAMP;
1654 break;
1655 case TARGET_SO_RCVLOWAT:
1656 optname = SO_RCVLOWAT;
1657 break;
1658 break;
1659 default:
1660 goto unimplemented;
1662 if (optlen < sizeof(uint32_t))
1663 return -TARGET_EINVAL;
1665 if (get_user_u32(val, optval_addr))
1666 return -TARGET_EFAULT;
1667 ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1668 break;
1669 default:
1670 unimplemented:
1671 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level, optname);
1672 ret = -TARGET_ENOPROTOOPT;
1674 return ret;
1677 /* do_getsockopt() Must return target values and target errnos. */
1678 static abi_long do_getsockopt(int sockfd, int level, int optname,
1679 abi_ulong optval_addr, abi_ulong optlen)
1681 abi_long ret;
1682 int len, val;
1683 socklen_t lv;
1685 switch(level) {
1686 case TARGET_SOL_SOCKET:
1687 level = SOL_SOCKET;
1688 switch (optname) {
1689 /* These don't just return a single integer */
1690 case TARGET_SO_LINGER:
1691 case TARGET_SO_RCVTIMEO:
1692 case TARGET_SO_SNDTIMEO:
1693 case TARGET_SO_PEERNAME:
1694 goto unimplemented;
1695 case TARGET_SO_PEERCRED: {
1696 struct ucred cr;
1697 socklen_t crlen;
1698 struct target_ucred *tcr;
1700 if (get_user_u32(len, optlen)) {
1701 return -TARGET_EFAULT;
1703 if (len < 0) {
1704 return -TARGET_EINVAL;
1707 crlen = sizeof(cr);
1708 ret = get_errno(getsockopt(sockfd, level, SO_PEERCRED,
1709 &cr, &crlen));
1710 if (ret < 0) {
1711 return ret;
1713 if (len > crlen) {
1714 len = crlen;
1716 if (!lock_user_struct(VERIFY_WRITE, tcr, optval_addr, 0)) {
1717 return -TARGET_EFAULT;
1719 __put_user(cr.pid, &tcr->pid);
1720 __put_user(cr.uid, &tcr->uid);
1721 __put_user(cr.gid, &tcr->gid);
1722 unlock_user_struct(tcr, optval_addr, 1);
1723 if (put_user_u32(len, optlen)) {
1724 return -TARGET_EFAULT;
1726 break;
1728 /* Options with 'int' argument. */
1729 case TARGET_SO_DEBUG:
1730 optname = SO_DEBUG;
1731 goto int_case;
1732 case TARGET_SO_REUSEADDR:
1733 optname = SO_REUSEADDR;
1734 goto int_case;
1735 case TARGET_SO_TYPE:
1736 optname = SO_TYPE;
1737 goto int_case;
1738 case TARGET_SO_ERROR:
1739 optname = SO_ERROR;
1740 goto int_case;
1741 case TARGET_SO_DONTROUTE:
1742 optname = SO_DONTROUTE;
1743 goto int_case;
1744 case TARGET_SO_BROADCAST:
1745 optname = SO_BROADCAST;
1746 goto int_case;
1747 case TARGET_SO_SNDBUF:
1748 optname = SO_SNDBUF;
1749 goto int_case;
1750 case TARGET_SO_RCVBUF:
1751 optname = SO_RCVBUF;
1752 goto int_case;
1753 case TARGET_SO_KEEPALIVE:
1754 optname = SO_KEEPALIVE;
1755 goto int_case;
1756 case TARGET_SO_OOBINLINE:
1757 optname = SO_OOBINLINE;
1758 goto int_case;
1759 case TARGET_SO_NO_CHECK:
1760 optname = SO_NO_CHECK;
1761 goto int_case;
1762 case TARGET_SO_PRIORITY:
1763 optname = SO_PRIORITY;
1764 goto int_case;
1765 #ifdef SO_BSDCOMPAT
1766 case TARGET_SO_BSDCOMPAT:
1767 optname = SO_BSDCOMPAT;
1768 goto int_case;
1769 #endif
1770 case TARGET_SO_PASSCRED:
1771 optname = SO_PASSCRED;
1772 goto int_case;
1773 case TARGET_SO_TIMESTAMP:
1774 optname = SO_TIMESTAMP;
1775 goto int_case;
1776 case TARGET_SO_RCVLOWAT:
1777 optname = SO_RCVLOWAT;
1778 goto int_case;
1779 case TARGET_SO_ACCEPTCONN:
1780 optname = SO_ACCEPTCONN;
1781 goto int_case;
1782 default:
1783 goto int_case;
1785 break;
1786 case SOL_TCP:
1787 /* TCP options all take an 'int' value. */
1788 int_case:
1789 if (get_user_u32(len, optlen))
1790 return -TARGET_EFAULT;
1791 if (len < 0)
1792 return -TARGET_EINVAL;
1793 lv = sizeof(lv);
1794 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1795 if (ret < 0)
1796 return ret;
1797 if (optname == SO_TYPE) {
1798 val = host_to_target_sock_type(val);
1800 if (len > lv)
1801 len = lv;
1802 if (len == 4) {
1803 if (put_user_u32(val, optval_addr))
1804 return -TARGET_EFAULT;
1805 } else {
1806 if (put_user_u8(val, optval_addr))
1807 return -TARGET_EFAULT;
1809 if (put_user_u32(len, optlen))
1810 return -TARGET_EFAULT;
1811 break;
1812 case SOL_IP:
1813 switch(optname) {
1814 case IP_TOS:
1815 case IP_TTL:
1816 case IP_HDRINCL:
1817 case IP_ROUTER_ALERT:
1818 case IP_RECVOPTS:
1819 case IP_RETOPTS:
1820 case IP_PKTINFO:
1821 case IP_MTU_DISCOVER:
1822 case IP_RECVERR:
1823 case IP_RECVTOS:
1824 #ifdef IP_FREEBIND
1825 case IP_FREEBIND:
1826 #endif
1827 case IP_MULTICAST_TTL:
1828 case IP_MULTICAST_LOOP:
1829 if (get_user_u32(len, optlen))
1830 return -TARGET_EFAULT;
1831 if (len < 0)
1832 return -TARGET_EINVAL;
1833 lv = sizeof(lv);
1834 ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1835 if (ret < 0)
1836 return ret;
1837 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1838 len = 1;
1839 if (put_user_u32(len, optlen)
1840 || put_user_u8(val, optval_addr))
1841 return -TARGET_EFAULT;
1842 } else {
1843 if (len > sizeof(int))
1844 len = sizeof(int);
1845 if (put_user_u32(len, optlen)
1846 || put_user_u32(val, optval_addr))
1847 return -TARGET_EFAULT;
1849 break;
1850 default:
1851 ret = -TARGET_ENOPROTOOPT;
1852 break;
1854 break;
1855 default:
1856 unimplemented:
1857 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1858 level, optname);
1859 ret = -TARGET_EOPNOTSUPP;
1860 break;
1862 return ret;
1865 static struct iovec *lock_iovec(int type, abi_ulong target_addr,
1866 int count, int copy)
1868 struct target_iovec *target_vec;
1869 struct iovec *vec;
1870 abi_ulong total_len, max_len;
1871 int i;
1872 int err = 0;
1873 bool bad_address = false;
1875 if (count == 0) {
1876 errno = 0;
1877 return NULL;
1879 if (count < 0 || count > IOV_MAX) {
1880 errno = EINVAL;
1881 return NULL;
1884 vec = calloc(count, sizeof(struct iovec));
1885 if (vec == NULL) {
1886 errno = ENOMEM;
1887 return NULL;
1890 target_vec = lock_user(VERIFY_READ, target_addr,
1891 count * sizeof(struct target_iovec), 1);
1892 if (target_vec == NULL) {
1893 err = EFAULT;
1894 goto fail2;
1897 /* ??? If host page size > target page size, this will result in a
1898 value larger than what we can actually support. */
1899 max_len = 0x7fffffff & TARGET_PAGE_MASK;
1900 total_len = 0;
1902 for (i = 0; i < count; i++) {
1903 abi_ulong base = tswapal(target_vec[i].iov_base);
1904 abi_long len = tswapal(target_vec[i].iov_len);
1906 if (len < 0) {
1907 err = EINVAL;
1908 goto fail;
1909 } else if (len == 0) {
1910 /* Zero length pointer is ignored. */
1911 vec[i].iov_base = 0;
1912 } else {
1913 vec[i].iov_base = lock_user(type, base, len, copy);
1914 /* If the first buffer pointer is bad, this is a fault. But
1915 * subsequent bad buffers will result in a partial write; this
1916 * is realized by filling the vector with null pointers and
1917 * zero lengths. */
1918 if (!vec[i].iov_base) {
1919 if (i == 0) {
1920 err = EFAULT;
1921 goto fail;
1922 } else {
1923 bad_address = true;
1926 if (bad_address) {
1927 len = 0;
1929 if (len > max_len - total_len) {
1930 len = max_len - total_len;
1933 vec[i].iov_len = len;
1934 total_len += len;
1937 unlock_user(target_vec, target_addr, 0);
1938 return vec;
1940 fail:
1941 while (--i >= 0) {
1942 if (tswapal(target_vec[i].iov_len) > 0) {
1943 unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
1946 unlock_user(target_vec, target_addr, 0);
1947 fail2:
1948 free(vec);
1949 errno = err;
1950 return NULL;
1953 static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1954 int count, int copy)
1956 struct target_iovec *target_vec;
1957 int i;
1959 target_vec = lock_user(VERIFY_READ, target_addr,
1960 count * sizeof(struct target_iovec), 1);
1961 if (target_vec) {
1962 for (i = 0; i < count; i++) {
1963 abi_ulong base = tswapal(target_vec[i].iov_base);
1964 abi_long len = tswapal(target_vec[i].iov_len);
1965 if (len < 0) {
1966 break;
1968 unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1970 unlock_user(target_vec, target_addr, 0);
1973 free(vec);
1976 static inline int target_to_host_sock_type(int *type)
1978 int host_type = 0;
1979 int target_type = *type;
1981 switch (target_type & TARGET_SOCK_TYPE_MASK) {
1982 case TARGET_SOCK_DGRAM:
1983 host_type = SOCK_DGRAM;
1984 break;
1985 case TARGET_SOCK_STREAM:
1986 host_type = SOCK_STREAM;
1987 break;
1988 default:
1989 host_type = target_type & TARGET_SOCK_TYPE_MASK;
1990 break;
1992 if (target_type & TARGET_SOCK_CLOEXEC) {
1993 #if defined(SOCK_CLOEXEC)
1994 host_type |= SOCK_CLOEXEC;
1995 #else
1996 return -TARGET_EINVAL;
1997 #endif
1999 if (target_type & TARGET_SOCK_NONBLOCK) {
2000 #if defined(SOCK_NONBLOCK)
2001 host_type |= SOCK_NONBLOCK;
2002 #elif !defined(O_NONBLOCK)
2003 return -TARGET_EINVAL;
2004 #endif
2006 *type = host_type;
2007 return 0;
2010 /* Try to emulate socket type flags after socket creation. */
2011 static int sock_flags_fixup(int fd, int target_type)
2013 #if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
2014 if (target_type & TARGET_SOCK_NONBLOCK) {
2015 int flags = fcntl(fd, F_GETFL);
2016 if (fcntl(fd, F_SETFL, O_NONBLOCK | flags) == -1) {
2017 close(fd);
2018 return -TARGET_EINVAL;
2021 #endif
2022 return fd;
2025 /* do_socket() Must return target values and target errnos. */
2026 static abi_long do_socket(int domain, int type, int protocol)
2028 int target_type = type;
2029 int ret;
2031 ret = target_to_host_sock_type(&type);
2032 if (ret) {
2033 return ret;
2036 if (domain == PF_NETLINK)
2037 return -TARGET_EAFNOSUPPORT;
2038 ret = get_errno(socket(domain, type, protocol));
2039 if (ret >= 0) {
2040 ret = sock_flags_fixup(ret, target_type);
2042 return ret;
2045 /* do_bind() Must return target values and target errnos. */
2046 static abi_long do_bind(int sockfd, abi_ulong target_addr,
2047 socklen_t addrlen)
2049 void *addr;
2050 abi_long ret;
2052 if ((int)addrlen < 0) {
2053 return -TARGET_EINVAL;
2056 addr = alloca(addrlen+1);
2058 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2059 if (ret)
2060 return ret;
2062 return get_errno(bind(sockfd, addr, addrlen));
2065 /* do_connect() Must return target values and target errnos. */
2066 static abi_long do_connect(int sockfd, abi_ulong target_addr,
2067 socklen_t addrlen)
2069 void *addr;
2070 abi_long ret;
2072 if ((int)addrlen < 0) {
2073 return -TARGET_EINVAL;
2076 addr = alloca(addrlen+1);
2078 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2079 if (ret)
2080 return ret;
2082 return get_errno(connect(sockfd, addr, addrlen));
2085 /* do_sendrecvmsg_locked() Must return target values and target errnos. */
2086 static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
2087 int flags, int send)
2089 abi_long ret, len;
2090 struct msghdr msg;
2091 int count;
2092 struct iovec *vec;
2093 abi_ulong target_vec;
2095 if (msgp->msg_name) {
2096 msg.msg_namelen = tswap32(msgp->msg_namelen);
2097 msg.msg_name = alloca(msg.msg_namelen+1);
2098 ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name),
2099 msg.msg_namelen);
2100 if (ret) {
2101 goto out2;
2103 } else {
2104 msg.msg_name = NULL;
2105 msg.msg_namelen = 0;
2107 msg.msg_controllen = 2 * tswapal(msgp->msg_controllen);
2108 msg.msg_control = alloca(msg.msg_controllen);
2109 msg.msg_flags = tswap32(msgp->msg_flags);
2111 count = tswapal(msgp->msg_iovlen);
2112 target_vec = tswapal(msgp->msg_iov);
2113 vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
2114 target_vec, count, send);
2115 if (vec == NULL) {
2116 ret = -host_to_target_errno(errno);
2117 goto out2;
2119 msg.msg_iovlen = count;
2120 msg.msg_iov = vec;
2122 if (send) {
2123 ret = target_to_host_cmsg(&msg, msgp);
2124 if (ret == 0)
2125 ret = get_errno(sendmsg(fd, &msg, flags));
2126 } else {
2127 ret = get_errno(recvmsg(fd, &msg, flags));
2128 if (!is_error(ret)) {
2129 len = ret;
2130 ret = host_to_target_cmsg(msgp, &msg);
2131 if (!is_error(ret)) {
2132 msgp->msg_namelen = tswap32(msg.msg_namelen);
2133 if (msg.msg_name != NULL) {
2134 ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
2135 msg.msg_name, msg.msg_namelen);
2136 if (ret) {
2137 goto out;
2141 ret = len;
2146 out:
2147 unlock_iovec(vec, target_vec, count, !send);
2148 out2:
2149 return ret;
2152 static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
2153 int flags, int send)
2155 abi_long ret;
2156 struct target_msghdr *msgp;
2158 if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
2159 msgp,
2160 target_msg,
2161 send ? 1 : 0)) {
2162 return -TARGET_EFAULT;
2164 ret = do_sendrecvmsg_locked(fd, msgp, flags, send);
2165 unlock_user_struct(msgp, target_msg, send ? 0 : 1);
2166 return ret;
2169 #ifdef TARGET_NR_sendmmsg
2170 /* We don't rely on the C library to have sendmmsg/recvmmsg support,
2171 * so it might not have this *mmsg-specific flag either.
2173 #ifndef MSG_WAITFORONE
2174 #define MSG_WAITFORONE 0x10000
2175 #endif
2177 static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec,
2178 unsigned int vlen, unsigned int flags,
2179 int send)
2181 struct target_mmsghdr *mmsgp;
2182 abi_long ret = 0;
2183 int i;
2185 if (vlen > UIO_MAXIOV) {
2186 vlen = UIO_MAXIOV;
2189 mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1);
2190 if (!mmsgp) {
2191 return -TARGET_EFAULT;
2194 for (i = 0; i < vlen; i++) {
2195 ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send);
2196 if (is_error(ret)) {
2197 break;
2199 mmsgp[i].msg_len = tswap32(ret);
2200 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
2201 if (flags & MSG_WAITFORONE) {
2202 flags |= MSG_DONTWAIT;
2206 unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i);
2208 /* Return number of datagrams sent if we sent any at all;
2209 * otherwise return the error.
2211 if (i) {
2212 return i;
2214 return ret;
2216 #endif
2218 /* If we don't have a system accept4() then just call accept.
2219 * The callsites to do_accept4() will ensure that they don't
2220 * pass a non-zero flags argument in this config.
2222 #ifndef CONFIG_ACCEPT4
2223 static inline int accept4(int sockfd, struct sockaddr *addr,
2224 socklen_t *addrlen, int flags)
2226 assert(flags == 0);
2227 return accept(sockfd, addr, addrlen);
2229 #endif
2231 /* do_accept4() Must return target values and target errnos. */
2232 static abi_long do_accept4(int fd, abi_ulong target_addr,
2233 abi_ulong target_addrlen_addr, int flags)
2235 socklen_t addrlen;
2236 void *addr;
2237 abi_long ret;
2238 int host_flags;
2240 host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
2242 if (target_addr == 0) {
2243 return get_errno(accept4(fd, NULL, NULL, host_flags));
2246 /* linux returns EINVAL if addrlen pointer is invalid */
2247 if (get_user_u32(addrlen, target_addrlen_addr))
2248 return -TARGET_EINVAL;
2250 if ((int)addrlen < 0) {
2251 return -TARGET_EINVAL;
2254 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2255 return -TARGET_EINVAL;
2257 addr = alloca(addrlen);
2259 ret = get_errno(accept4(fd, addr, &addrlen, host_flags));
2260 if (!is_error(ret)) {
2261 host_to_target_sockaddr(target_addr, addr, addrlen);
2262 if (put_user_u32(addrlen, target_addrlen_addr))
2263 ret = -TARGET_EFAULT;
2265 return ret;
2268 /* do_getpeername() Must return target values and target errnos. */
2269 static abi_long do_getpeername(int fd, abi_ulong target_addr,
2270 abi_ulong target_addrlen_addr)
2272 socklen_t addrlen;
2273 void *addr;
2274 abi_long ret;
2276 if (get_user_u32(addrlen, target_addrlen_addr))
2277 return -TARGET_EFAULT;
2279 if ((int)addrlen < 0) {
2280 return -TARGET_EINVAL;
2283 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2284 return -TARGET_EFAULT;
2286 addr = alloca(addrlen);
2288 ret = get_errno(getpeername(fd, addr, &addrlen));
2289 if (!is_error(ret)) {
2290 host_to_target_sockaddr(target_addr, addr, addrlen);
2291 if (put_user_u32(addrlen, target_addrlen_addr))
2292 ret = -TARGET_EFAULT;
2294 return ret;
2297 /* do_getsockname() Must return target values and target errnos. */
2298 static abi_long do_getsockname(int fd, abi_ulong target_addr,
2299 abi_ulong target_addrlen_addr)
2301 socklen_t addrlen;
2302 void *addr;
2303 abi_long ret;
2305 if (get_user_u32(addrlen, target_addrlen_addr))
2306 return -TARGET_EFAULT;
2308 if ((int)addrlen < 0) {
2309 return -TARGET_EINVAL;
2312 if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
2313 return -TARGET_EFAULT;
2315 addr = alloca(addrlen);
2317 ret = get_errno(getsockname(fd, addr, &addrlen));
2318 if (!is_error(ret)) {
2319 host_to_target_sockaddr(target_addr, addr, addrlen);
2320 if (put_user_u32(addrlen, target_addrlen_addr))
2321 ret = -TARGET_EFAULT;
2323 return ret;
2326 /* do_socketpair() Must return target values and target errnos. */
2327 static abi_long do_socketpair(int domain, int type, int protocol,
2328 abi_ulong target_tab_addr)
2330 int tab[2];
2331 abi_long ret;
2333 target_to_host_sock_type(&type);
2335 ret = get_errno(socketpair(domain, type, protocol, tab));
2336 if (!is_error(ret)) {
2337 if (put_user_s32(tab[0], target_tab_addr)
2338 || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
2339 ret = -TARGET_EFAULT;
2341 return ret;
2344 /* do_sendto() Must return target values and target errnos. */
2345 static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
2346 abi_ulong target_addr, socklen_t addrlen)
2348 void *addr;
2349 void *host_msg;
2350 abi_long ret;
2352 if ((int)addrlen < 0) {
2353 return -TARGET_EINVAL;
2356 host_msg = lock_user(VERIFY_READ, msg, len, 1);
2357 if (!host_msg)
2358 return -TARGET_EFAULT;
2359 if (target_addr) {
2360 addr = alloca(addrlen+1);
2361 ret = target_to_host_sockaddr(addr, target_addr, addrlen);
2362 if (ret) {
2363 unlock_user(host_msg, msg, 0);
2364 return ret;
2366 ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
2367 } else {
2368 ret = get_errno(send(fd, host_msg, len, flags));
2370 unlock_user(host_msg, msg, 0);
2371 return ret;
2374 /* do_recvfrom() Must return target values and target errnos. */
2375 static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
2376 abi_ulong target_addr,
2377 abi_ulong target_addrlen)
2379 socklen_t addrlen;
2380 void *addr;
2381 void *host_msg;
2382 abi_long ret;
2384 host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
2385 if (!host_msg)
2386 return -TARGET_EFAULT;
2387 if (target_addr) {
2388 if (get_user_u32(addrlen, target_addrlen)) {
2389 ret = -TARGET_EFAULT;
2390 goto fail;
2392 if ((int)addrlen < 0) {
2393 ret = -TARGET_EINVAL;
2394 goto fail;
2396 addr = alloca(addrlen);
2397 ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
2398 } else {
2399 addr = NULL; /* To keep compiler quiet. */
2400 ret = get_errno(qemu_recv(fd, host_msg, len, flags));
2402 if (!is_error(ret)) {
2403 if (target_addr) {
2404 host_to_target_sockaddr(target_addr, addr, addrlen);
2405 if (put_user_u32(addrlen, target_addrlen)) {
2406 ret = -TARGET_EFAULT;
2407 goto fail;
2410 unlock_user(host_msg, msg, len);
2411 } else {
2412 fail:
2413 unlock_user(host_msg, msg, 0);
2415 return ret;
2418 #ifdef TARGET_NR_socketcall
2419 /* do_socketcall() Must return target values and target errnos. */
2420 static abi_long do_socketcall(int num, abi_ulong vptr)
2422 static const unsigned ac[] = { /* number of arguments per call */
2423 [SOCKOP_socket] = 3, /* domain, type, protocol */
2424 [SOCKOP_bind] = 3, /* sockfd, addr, addrlen */
2425 [SOCKOP_connect] = 3, /* sockfd, addr, addrlen */
2426 [SOCKOP_listen] = 2, /* sockfd, backlog */
2427 [SOCKOP_accept] = 3, /* sockfd, addr, addrlen */
2428 [SOCKOP_accept4] = 4, /* sockfd, addr, addrlen, flags */
2429 [SOCKOP_getsockname] = 3, /* sockfd, addr, addrlen */
2430 [SOCKOP_getpeername] = 3, /* sockfd, addr, addrlen */
2431 [SOCKOP_socketpair] = 4, /* domain, type, protocol, tab */
2432 [SOCKOP_send] = 4, /* sockfd, msg, len, flags */
2433 [SOCKOP_recv] = 4, /* sockfd, msg, len, flags */
2434 [SOCKOP_sendto] = 6, /* sockfd, msg, len, flags, addr, addrlen */
2435 [SOCKOP_recvfrom] = 6, /* sockfd, msg, len, flags, addr, addrlen */
2436 [SOCKOP_shutdown] = 2, /* sockfd, how */
2437 [SOCKOP_sendmsg] = 3, /* sockfd, msg, flags */
2438 [SOCKOP_recvmsg] = 3, /* sockfd, msg, flags */
2439 [SOCKOP_setsockopt] = 5, /* sockfd, level, optname, optval, optlen */
2440 [SOCKOP_getsockopt] = 5, /* sockfd, level, optname, optval, optlen */
2442 abi_long a[6]; /* max 6 args */
2444 /* first, collect the arguments in a[] according to ac[] */
2445 if (num >= 0 && num < ARRAY_SIZE(ac)) {
2446 unsigned i;
2447 assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
2448 for (i = 0; i < ac[num]; ++i) {
2449 if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
2450 return -TARGET_EFAULT;
2455 /* now when we have the args, actually handle the call */
2456 switch (num) {
2457 case SOCKOP_socket: /* domain, type, protocol */
2458 return do_socket(a[0], a[1], a[2]);
2459 case SOCKOP_bind: /* sockfd, addr, addrlen */
2460 return do_bind(a[0], a[1], a[2]);
2461 case SOCKOP_connect: /* sockfd, addr, addrlen */
2462 return do_connect(a[0], a[1], a[2]);
2463 case SOCKOP_listen: /* sockfd, backlog */
2464 return get_errno(listen(a[0], a[1]));
2465 case SOCKOP_accept: /* sockfd, addr, addrlen */
2466 return do_accept4(a[0], a[1], a[2], 0);
2467 case SOCKOP_accept4: /* sockfd, addr, addrlen, flags */
2468 return do_accept4(a[0], a[1], a[2], a[3]);
2469 case SOCKOP_getsockname: /* sockfd, addr, addrlen */
2470 return do_getsockname(a[0], a[1], a[2]);
2471 case SOCKOP_getpeername: /* sockfd, addr, addrlen */
2472 return do_getpeername(a[0], a[1], a[2]);
2473 case SOCKOP_socketpair: /* domain, type, protocol, tab */
2474 return do_socketpair(a[0], a[1], a[2], a[3]);
2475 case SOCKOP_send: /* sockfd, msg, len, flags */
2476 return do_sendto(a[0], a[1], a[2], a[3], 0, 0);
2477 case SOCKOP_recv: /* sockfd, msg, len, flags */
2478 return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);
2479 case SOCKOP_sendto: /* sockfd, msg, len, flags, addr, addrlen */
2480 return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);
2481 case SOCKOP_recvfrom: /* sockfd, msg, len, flags, addr, addrlen */
2482 return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);
2483 case SOCKOP_shutdown: /* sockfd, how */
2484 return get_errno(shutdown(a[0], a[1]));
2485 case SOCKOP_sendmsg: /* sockfd, msg, flags */
2486 return do_sendrecvmsg(a[0], a[1], a[2], 1);
2487 case SOCKOP_recvmsg: /* sockfd, msg, flags */
2488 return do_sendrecvmsg(a[0], a[1], a[2], 0);
2489 case SOCKOP_setsockopt: /* sockfd, level, optname, optval, optlen */
2490 return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);
2491 case SOCKOP_getsockopt: /* sockfd, level, optname, optval, optlen */
2492 return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
2493 default:
2494 gemu_log("Unsupported socketcall: %d\n", num);
2495 return -TARGET_ENOSYS;
2498 #endif
2500 #define N_SHM_REGIONS 32
2502 static struct shm_region {
2503 abi_ulong start;
2504 abi_ulong size;
2505 } shm_regions[N_SHM_REGIONS];
2507 struct target_semid_ds
2509 struct target_ipc_perm sem_perm;
2510 abi_ulong sem_otime;
2511 #if !defined(TARGET_PPC64)
2512 abi_ulong __unused1;
2513 #endif
2514 abi_ulong sem_ctime;
2515 #if !defined(TARGET_PPC64)
2516 abi_ulong __unused2;
2517 #endif
2518 abi_ulong sem_nsems;
2519 abi_ulong __unused3;
2520 abi_ulong __unused4;
2523 static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2524 abi_ulong target_addr)
2526 struct target_ipc_perm *target_ip;
2527 struct target_semid_ds *target_sd;
2529 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2530 return -TARGET_EFAULT;
2531 target_ip = &(target_sd->sem_perm);
2532 host_ip->__key = tswap32(target_ip->__key);
2533 host_ip->uid = tswap32(target_ip->uid);
2534 host_ip->gid = tswap32(target_ip->gid);
2535 host_ip->cuid = tswap32(target_ip->cuid);
2536 host_ip->cgid = tswap32(target_ip->cgid);
2537 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2538 host_ip->mode = tswap32(target_ip->mode);
2539 #else
2540 host_ip->mode = tswap16(target_ip->mode);
2541 #endif
2542 #if defined(TARGET_PPC)
2543 host_ip->__seq = tswap32(target_ip->__seq);
2544 #else
2545 host_ip->__seq = tswap16(target_ip->__seq);
2546 #endif
2547 unlock_user_struct(target_sd, target_addr, 0);
2548 return 0;
2551 static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2552 struct ipc_perm *host_ip)
2554 struct target_ipc_perm *target_ip;
2555 struct target_semid_ds *target_sd;
2557 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2558 return -TARGET_EFAULT;
2559 target_ip = &(target_sd->sem_perm);
2560 target_ip->__key = tswap32(host_ip->__key);
2561 target_ip->uid = tswap32(host_ip->uid);
2562 target_ip->gid = tswap32(host_ip->gid);
2563 target_ip->cuid = tswap32(host_ip->cuid);
2564 target_ip->cgid = tswap32(host_ip->cgid);
2565 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2566 target_ip->mode = tswap32(host_ip->mode);
2567 #else
2568 target_ip->mode = tswap16(host_ip->mode);
2569 #endif
2570 #if defined(TARGET_PPC)
2571 target_ip->__seq = tswap32(host_ip->__seq);
2572 #else
2573 target_ip->__seq = tswap16(host_ip->__seq);
2574 #endif
2575 unlock_user_struct(target_sd, target_addr, 1);
2576 return 0;
2579 static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2580 abi_ulong target_addr)
2582 struct target_semid_ds *target_sd;
2584 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2585 return -TARGET_EFAULT;
2586 if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2587 return -TARGET_EFAULT;
2588 host_sd->sem_nsems = tswapal(target_sd->sem_nsems);
2589 host_sd->sem_otime = tswapal(target_sd->sem_otime);
2590 host_sd->sem_ctime = tswapal(target_sd->sem_ctime);
2591 unlock_user_struct(target_sd, target_addr, 0);
2592 return 0;
2595 static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2596 struct semid_ds *host_sd)
2598 struct target_semid_ds *target_sd;
2600 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2601 return -TARGET_EFAULT;
2602 if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2603 return -TARGET_EFAULT;
2604 target_sd->sem_nsems = tswapal(host_sd->sem_nsems);
2605 target_sd->sem_otime = tswapal(host_sd->sem_otime);
2606 target_sd->sem_ctime = tswapal(host_sd->sem_ctime);
2607 unlock_user_struct(target_sd, target_addr, 1);
2608 return 0;
2611 struct target_seminfo {
2612 int semmap;
2613 int semmni;
2614 int semmns;
2615 int semmnu;
2616 int semmsl;
2617 int semopm;
2618 int semume;
2619 int semusz;
2620 int semvmx;
2621 int semaem;
2624 static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2625 struct seminfo *host_seminfo)
2627 struct target_seminfo *target_seminfo;
2628 if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2629 return -TARGET_EFAULT;
2630 __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2631 __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2632 __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2633 __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2634 __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2635 __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2636 __put_user(host_seminfo->semume, &target_seminfo->semume);
2637 __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2638 __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2639 __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2640 unlock_user_struct(target_seminfo, target_addr, 1);
2641 return 0;
2644 union semun {
2645 int val;
2646 struct semid_ds *buf;
2647 unsigned short *array;
2648 struct seminfo *__buf;
2651 union target_semun {
2652 int val;
2653 abi_ulong buf;
2654 abi_ulong array;
2655 abi_ulong __buf;
2658 static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2659 abi_ulong target_addr)
2661 int nsems;
2662 unsigned short *array;
2663 union semun semun;
2664 struct semid_ds semid_ds;
2665 int i, ret;
2667 semun.buf = &semid_ds;
2669 ret = semctl(semid, 0, IPC_STAT, semun);
2670 if (ret == -1)
2671 return get_errno(ret);
2673 nsems = semid_ds.sem_nsems;
2675 *host_array = malloc(nsems*sizeof(unsigned short));
2676 if (!*host_array) {
2677 return -TARGET_ENOMEM;
2679 array = lock_user(VERIFY_READ, target_addr,
2680 nsems*sizeof(unsigned short), 1);
2681 if (!array) {
2682 free(*host_array);
2683 return -TARGET_EFAULT;
2686 for(i=0; i<nsems; i++) {
2687 __get_user((*host_array)[i], &array[i]);
2689 unlock_user(array, target_addr, 0);
2691 return 0;
2694 static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2695 unsigned short **host_array)
2697 int nsems;
2698 unsigned short *array;
2699 union semun semun;
2700 struct semid_ds semid_ds;
2701 int i, ret;
2703 semun.buf = &semid_ds;
2705 ret = semctl(semid, 0, IPC_STAT, semun);
2706 if (ret == -1)
2707 return get_errno(ret);
2709 nsems = semid_ds.sem_nsems;
2711 array = lock_user(VERIFY_WRITE, target_addr,
2712 nsems*sizeof(unsigned short), 0);
2713 if (!array)
2714 return -TARGET_EFAULT;
2716 for(i=0; i<nsems; i++) {
2717 __put_user((*host_array)[i], &array[i]);
2719 free(*host_array);
2720 unlock_user(array, target_addr, 1);
2722 return 0;
2725 static inline abi_long do_semctl(int semid, int semnum, int cmd,
2726 union target_semun target_su)
2728 union semun arg;
2729 struct semid_ds dsarg;
2730 unsigned short *array = NULL;
2731 struct seminfo seminfo;
2732 abi_long ret = -TARGET_EINVAL;
2733 abi_long err;
2734 cmd &= 0xff;
2736 switch( cmd ) {
2737 case GETVAL:
2738 case SETVAL:
2739 /* In 64 bit cross-endian situations, we will erroneously pick up
2740 * the wrong half of the union for the "val" element. To rectify
2741 * this, the entire 8-byte structure is byteswapped, followed by
2742 * a swap of the 4 byte val field. In other cases, the data is
2743 * already in proper host byte order. */
2744 if (sizeof(target_su.val) != (sizeof(target_su.buf))) {
2745 target_su.buf = tswapal(target_su.buf);
2746 arg.val = tswap32(target_su.val);
2747 } else {
2748 arg.val = target_su.val;
2750 ret = get_errno(semctl(semid, semnum, cmd, arg));
2751 break;
2752 case GETALL:
2753 case SETALL:
2754 err = target_to_host_semarray(semid, &array, target_su.array);
2755 if (err)
2756 return err;
2757 arg.array = array;
2758 ret = get_errno(semctl(semid, semnum, cmd, arg));
2759 err = host_to_target_semarray(semid, target_su.array, &array);
2760 if (err)
2761 return err;
2762 break;
2763 case IPC_STAT:
2764 case IPC_SET:
2765 case SEM_STAT:
2766 err = target_to_host_semid_ds(&dsarg, target_su.buf);
2767 if (err)
2768 return err;
2769 arg.buf = &dsarg;
2770 ret = get_errno(semctl(semid, semnum, cmd, arg));
2771 err = host_to_target_semid_ds(target_su.buf, &dsarg);
2772 if (err)
2773 return err;
2774 break;
2775 case IPC_INFO:
2776 case SEM_INFO:
2777 arg.__buf = &seminfo;
2778 ret = get_errno(semctl(semid, semnum, cmd, arg));
2779 err = host_to_target_seminfo(target_su.__buf, &seminfo);
2780 if (err)
2781 return err;
2782 break;
2783 case IPC_RMID:
2784 case GETPID:
2785 case GETNCNT:
2786 case GETZCNT:
2787 ret = get_errno(semctl(semid, semnum, cmd, NULL));
2788 break;
2791 return ret;
2794 struct target_sembuf {
2795 unsigned short sem_num;
2796 short sem_op;
2797 short sem_flg;
2800 static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2801 abi_ulong target_addr,
2802 unsigned nsops)
2804 struct target_sembuf *target_sembuf;
2805 int i;
2807 target_sembuf = lock_user(VERIFY_READ, target_addr,
2808 nsops*sizeof(struct target_sembuf), 1);
2809 if (!target_sembuf)
2810 return -TARGET_EFAULT;
2812 for(i=0; i<nsops; i++) {
2813 __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2814 __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2815 __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2818 unlock_user(target_sembuf, target_addr, 0);
2820 return 0;
2823 static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2825 struct sembuf sops[nsops];
2827 if (target_to_host_sembuf(sops, ptr, nsops))
2828 return -TARGET_EFAULT;
2830 return get_errno(semop(semid, sops, nsops));
2833 struct target_msqid_ds
2835 struct target_ipc_perm msg_perm;
2836 abi_ulong msg_stime;
2837 #if TARGET_ABI_BITS == 32
2838 abi_ulong __unused1;
2839 #endif
2840 abi_ulong msg_rtime;
2841 #if TARGET_ABI_BITS == 32
2842 abi_ulong __unused2;
2843 #endif
2844 abi_ulong msg_ctime;
2845 #if TARGET_ABI_BITS == 32
2846 abi_ulong __unused3;
2847 #endif
2848 abi_ulong __msg_cbytes;
2849 abi_ulong msg_qnum;
2850 abi_ulong msg_qbytes;
2851 abi_ulong msg_lspid;
2852 abi_ulong msg_lrpid;
2853 abi_ulong __unused4;
2854 abi_ulong __unused5;
2857 static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2858 abi_ulong target_addr)
2860 struct target_msqid_ds *target_md;
2862 if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2863 return -TARGET_EFAULT;
2864 if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2865 return -TARGET_EFAULT;
2866 host_md->msg_stime = tswapal(target_md->msg_stime);
2867 host_md->msg_rtime = tswapal(target_md->msg_rtime);
2868 host_md->msg_ctime = tswapal(target_md->msg_ctime);
2869 host_md->__msg_cbytes = tswapal(target_md->__msg_cbytes);
2870 host_md->msg_qnum = tswapal(target_md->msg_qnum);
2871 host_md->msg_qbytes = tswapal(target_md->msg_qbytes);
2872 host_md->msg_lspid = tswapal(target_md->msg_lspid);
2873 host_md->msg_lrpid = tswapal(target_md->msg_lrpid);
2874 unlock_user_struct(target_md, target_addr, 0);
2875 return 0;
2878 static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2879 struct msqid_ds *host_md)
2881 struct target_msqid_ds *target_md;
2883 if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2884 return -TARGET_EFAULT;
2885 if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2886 return -TARGET_EFAULT;
2887 target_md->msg_stime = tswapal(host_md->msg_stime);
2888 target_md->msg_rtime = tswapal(host_md->msg_rtime);
2889 target_md->msg_ctime = tswapal(host_md->msg_ctime);
2890 target_md->__msg_cbytes = tswapal(host_md->__msg_cbytes);
2891 target_md->msg_qnum = tswapal(host_md->msg_qnum);
2892 target_md->msg_qbytes = tswapal(host_md->msg_qbytes);
2893 target_md->msg_lspid = tswapal(host_md->msg_lspid);
2894 target_md->msg_lrpid = tswapal(host_md->msg_lrpid);
2895 unlock_user_struct(target_md, target_addr, 1);
2896 return 0;
2899 struct target_msginfo {
2900 int msgpool;
2901 int msgmap;
2902 int msgmax;
2903 int msgmnb;
2904 int msgmni;
2905 int msgssz;
2906 int msgtql;
2907 unsigned short int msgseg;
2910 static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2911 struct msginfo *host_msginfo)
2913 struct target_msginfo *target_msginfo;
2914 if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2915 return -TARGET_EFAULT;
2916 __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2917 __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2918 __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2919 __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2920 __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2921 __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2922 __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2923 __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2924 unlock_user_struct(target_msginfo, target_addr, 1);
2925 return 0;
2928 static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2930 struct msqid_ds dsarg;
2931 struct msginfo msginfo;
2932 abi_long ret = -TARGET_EINVAL;
2934 cmd &= 0xff;
2936 switch (cmd) {
2937 case IPC_STAT:
2938 case IPC_SET:
2939 case MSG_STAT:
2940 if (target_to_host_msqid_ds(&dsarg,ptr))
2941 return -TARGET_EFAULT;
2942 ret = get_errno(msgctl(msgid, cmd, &dsarg));
2943 if (host_to_target_msqid_ds(ptr,&dsarg))
2944 return -TARGET_EFAULT;
2945 break;
2946 case IPC_RMID:
2947 ret = get_errno(msgctl(msgid, cmd, NULL));
2948 break;
2949 case IPC_INFO:
2950 case MSG_INFO:
2951 ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2952 if (host_to_target_msginfo(ptr, &msginfo))
2953 return -TARGET_EFAULT;
2954 break;
2957 return ret;
2960 struct target_msgbuf {
2961 abi_long mtype;
2962 char mtext[1];
2965 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2966 ssize_t msgsz, int msgflg)
2968 struct target_msgbuf *target_mb;
2969 struct msgbuf *host_mb;
2970 abi_long ret = 0;
2972 if (msgsz < 0) {
2973 return -TARGET_EINVAL;
2976 if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2977 return -TARGET_EFAULT;
2978 host_mb = malloc(msgsz+sizeof(long));
2979 if (!host_mb) {
2980 unlock_user_struct(target_mb, msgp, 0);
2981 return -TARGET_ENOMEM;
2983 host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
2984 memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2985 ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2986 free(host_mb);
2987 unlock_user_struct(target_mb, msgp, 0);
2989 return ret;
2992 static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2993 unsigned int msgsz, abi_long msgtyp,
2994 int msgflg)
2996 struct target_msgbuf *target_mb;
2997 char *target_mtext;
2998 struct msgbuf *host_mb;
2999 abi_long ret = 0;
3001 if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
3002 return -TARGET_EFAULT;
3004 host_mb = g_malloc(msgsz+sizeof(long));
3005 ret = get_errno(msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
3007 if (ret > 0) {
3008 abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
3009 target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
3010 if (!target_mtext) {
3011 ret = -TARGET_EFAULT;
3012 goto end;
3014 memcpy(target_mb->mtext, host_mb->mtext, ret);
3015 unlock_user(target_mtext, target_mtext_addr, ret);
3018 target_mb->mtype = tswapal(host_mb->mtype);
3020 end:
3021 if (target_mb)
3022 unlock_user_struct(target_mb, msgp, 1);
3023 g_free(host_mb);
3024 return ret;
3027 static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
3028 abi_ulong target_addr)
3030 struct target_shmid_ds *target_sd;
3032 if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
3033 return -TARGET_EFAULT;
3034 if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
3035 return -TARGET_EFAULT;
3036 __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
3037 __get_user(host_sd->shm_atime, &target_sd->shm_atime);
3038 __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
3039 __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
3040 __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
3041 __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
3042 __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
3043 unlock_user_struct(target_sd, target_addr, 0);
3044 return 0;
3047 static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
3048 struct shmid_ds *host_sd)
3050 struct target_shmid_ds *target_sd;
3052 if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
3053 return -TARGET_EFAULT;
3054 if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
3055 return -TARGET_EFAULT;
3056 __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
3057 __put_user(host_sd->shm_atime, &target_sd->shm_atime);
3058 __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
3059 __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
3060 __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
3061 __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
3062 __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
3063 unlock_user_struct(target_sd, target_addr, 1);
3064 return 0;
3067 struct target_shminfo {
3068 abi_ulong shmmax;
3069 abi_ulong shmmin;
3070 abi_ulong shmmni;
3071 abi_ulong shmseg;
3072 abi_ulong shmall;
3075 static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
3076 struct shminfo *host_shminfo)
3078 struct target_shminfo *target_shminfo;
3079 if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
3080 return -TARGET_EFAULT;
3081 __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
3082 __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
3083 __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
3084 __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
3085 __put_user(host_shminfo->shmall, &target_shminfo->shmall);
3086 unlock_user_struct(target_shminfo, target_addr, 1);
3087 return 0;
3090 struct target_shm_info {
3091 int used_ids;
3092 abi_ulong shm_tot;
3093 abi_ulong shm_rss;
3094 abi_ulong shm_swp;
3095 abi_ulong swap_attempts;
3096 abi_ulong swap_successes;
3099 static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
3100 struct shm_info *host_shm_info)
3102 struct target_shm_info *target_shm_info;
3103 if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
3104 return -TARGET_EFAULT;
3105 __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
3106 __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
3107 __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
3108 __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
3109 __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
3110 __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
3111 unlock_user_struct(target_shm_info, target_addr, 1);
3112 return 0;
3115 static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
3117 struct shmid_ds dsarg;
3118 struct shminfo shminfo;
3119 struct shm_info shm_info;
3120 abi_long ret = -TARGET_EINVAL;
3122 cmd &= 0xff;
3124 switch(cmd) {
3125 case IPC_STAT:
3126 case IPC_SET:
3127 case SHM_STAT:
3128 if (target_to_host_shmid_ds(&dsarg, buf))
3129 return -TARGET_EFAULT;
3130 ret = get_errno(shmctl(shmid, cmd, &dsarg));
3131 if (host_to_target_shmid_ds(buf, &dsarg))
3132 return -TARGET_EFAULT;
3133 break;
3134 case IPC_INFO:
3135 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
3136 if (host_to_target_shminfo(buf, &shminfo))
3137 return -TARGET_EFAULT;
3138 break;
3139 case SHM_INFO:
3140 ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
3141 if (host_to_target_shm_info(buf, &shm_info))
3142 return -TARGET_EFAULT;
3143 break;
3144 case IPC_RMID:
3145 case SHM_LOCK:
3146 case SHM_UNLOCK:
3147 ret = get_errno(shmctl(shmid, cmd, NULL));
3148 break;
3151 return ret;
3154 static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
3156 abi_long raddr;
3157 void *host_raddr;
3158 struct shmid_ds shm_info;
3159 int i,ret;
3161 /* find out the length of the shared memory segment */
3162 ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
3163 if (is_error(ret)) {
3164 /* can't get length, bail out */
3165 return ret;
3168 mmap_lock();
3170 if (shmaddr)
3171 host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
3172 else {
3173 abi_ulong mmap_start;
3175 mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
3177 if (mmap_start == -1) {
3178 errno = ENOMEM;
3179 host_raddr = (void *)-1;
3180 } else
3181 host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
3184 if (host_raddr == (void *)-1) {
3185 mmap_unlock();
3186 return get_errno((long)host_raddr);
3188 raddr=h2g((unsigned long)host_raddr);
3190 page_set_flags(raddr, raddr + shm_info.shm_segsz,
3191 PAGE_VALID | PAGE_READ |
3192 ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
3194 for (i = 0; i < N_SHM_REGIONS; i++) {
3195 if (shm_regions[i].start == 0) {
3196 shm_regions[i].start = raddr;
3197 shm_regions[i].size = shm_info.shm_segsz;
3198 break;
3202 mmap_unlock();
3203 return raddr;
3207 static inline abi_long do_shmdt(abi_ulong shmaddr)
3209 int i;
3211 for (i = 0; i < N_SHM_REGIONS; ++i) {
3212 if (shm_regions[i].start == shmaddr) {
3213 shm_regions[i].start = 0;
3214 page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
3215 break;
3219 return get_errno(shmdt(g2h(shmaddr)));
3222 #ifdef TARGET_NR_ipc
3223 /* ??? This only works with linear mappings. */
3224 /* do_ipc() must return target values and target errnos. */
3225 static abi_long do_ipc(unsigned int call, abi_long first,
3226 abi_long second, abi_long third,
3227 abi_long ptr, abi_long fifth)
3229 int version;
3230 abi_long ret = 0;
3232 version = call >> 16;
3233 call &= 0xffff;
3235 switch (call) {
3236 case IPCOP_semop:
3237 ret = do_semop(first, ptr, second);
3238 break;
3240 case IPCOP_semget:
3241 ret = get_errno(semget(first, second, third));
3242 break;
3244 case IPCOP_semctl: {
3245 /* The semun argument to semctl is passed by value, so dereference the
3246 * ptr argument. */
3247 abi_ulong atptr;
3248 get_user_ual(atptr, ptr);
3249 ret = do_semctl(first, second, third,
3250 (union target_semun) atptr);
3251 break;
3254 case IPCOP_msgget:
3255 ret = get_errno(msgget(first, second));
3256 break;
3258 case IPCOP_msgsnd:
3259 ret = do_msgsnd(first, ptr, second, third);
3260 break;
3262 case IPCOP_msgctl:
3263 ret = do_msgctl(first, second, ptr);
3264 break;
3266 case IPCOP_msgrcv:
3267 switch (version) {
3268 case 0:
3270 struct target_ipc_kludge {
3271 abi_long msgp;
3272 abi_long msgtyp;
3273 } *tmp;
3275 if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
3276 ret = -TARGET_EFAULT;
3277 break;
3280 ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
3282 unlock_user_struct(tmp, ptr, 0);
3283 break;
3285 default:
3286 ret = do_msgrcv(first, ptr, second, fifth, third);
3288 break;
3290 case IPCOP_shmat:
3291 switch (version) {
3292 default:
3294 abi_ulong raddr;
3295 raddr = do_shmat(first, ptr, second);
3296 if (is_error(raddr))
3297 return get_errno(raddr);
3298 if (put_user_ual(raddr, third))
3299 return -TARGET_EFAULT;
3300 break;
3302 case 1:
3303 ret = -TARGET_EINVAL;
3304 break;
3306 break;
3307 case IPCOP_shmdt:
3308 ret = do_shmdt(ptr);
3309 break;
3311 case IPCOP_shmget:
3312 /* IPC_* flag values are the same on all linux platforms */
3313 ret = get_errno(shmget(first, second, third));
3314 break;
3316 /* IPC_* and SHM_* command values are the same on all linux platforms */
3317 case IPCOP_shmctl:
3318 ret = do_shmctl(first, second, ptr);
3319 break;
3320 default:
3321 gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3322 ret = -TARGET_ENOSYS;
3323 break;
3325 return ret;
3327 #endif
3329 /* kernel structure types definitions */
3331 #define STRUCT(name, ...) STRUCT_ ## name,
3332 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
3333 enum {
3334 #include "syscall_types.h"
3335 STRUCT_MAX
3337 #undef STRUCT
3338 #undef STRUCT_SPECIAL
3340 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3341 #define STRUCT_SPECIAL(name)
3342 #include "syscall_types.h"
3343 #undef STRUCT
3344 #undef STRUCT_SPECIAL
3346 typedef struct IOCTLEntry IOCTLEntry;
3348 typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3349 int fd, int cmd, abi_long arg);
3351 struct IOCTLEntry {
3352 int target_cmd;
3353 unsigned int host_cmd;
3354 const char *name;
3355 int access;
3356 do_ioctl_fn *do_ioctl;
3357 const argtype arg_type[5];
3360 #define IOC_R 0x0001
3361 #define IOC_W 0x0002
3362 #define IOC_RW (IOC_R | IOC_W)
3364 #define MAX_STRUCT_SIZE 4096
3366 #ifdef CONFIG_FIEMAP
3367 /* So fiemap access checks don't overflow on 32 bit systems.
3368 * This is very slightly smaller than the limit imposed by
3369 * the underlying kernel.
3371 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3372 / sizeof(struct fiemap_extent))
3374 static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3375 int fd, int cmd, abi_long arg)
3377 /* The parameter for this ioctl is a struct fiemap followed
3378 * by an array of struct fiemap_extent whose size is set
3379 * in fiemap->fm_extent_count. The array is filled in by the
3380 * ioctl.
3382 int target_size_in, target_size_out;
3383 struct fiemap *fm;
3384 const argtype *arg_type = ie->arg_type;
3385 const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3386 void *argptr, *p;
3387 abi_long ret;
3388 int i, extent_size = thunk_type_size(extent_arg_type, 0);
3389 uint32_t outbufsz;
3390 int free_fm = 0;
3392 assert(arg_type[0] == TYPE_PTR);
3393 assert(ie->access == IOC_RW);
3394 arg_type++;
3395 target_size_in = thunk_type_size(arg_type, 0);
3396 argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3397 if (!argptr) {
3398 return -TARGET_EFAULT;
3400 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3401 unlock_user(argptr, arg, 0);
3402 fm = (struct fiemap *)buf_temp;
3403 if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3404 return -TARGET_EINVAL;
3407 outbufsz = sizeof (*fm) +
3408 (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3410 if (outbufsz > MAX_STRUCT_SIZE) {
3411 /* We can't fit all the extents into the fixed size buffer.
3412 * Allocate one that is large enough and use it instead.
3414 fm = malloc(outbufsz);
3415 if (!fm) {
3416 return -TARGET_ENOMEM;
3418 memcpy(fm, buf_temp, sizeof(struct fiemap));
3419 free_fm = 1;
3421 ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3422 if (!is_error(ret)) {
3423 target_size_out = target_size_in;
3424 /* An extent_count of 0 means we were only counting the extents
3425 * so there are no structs to copy
3427 if (fm->fm_extent_count != 0) {
3428 target_size_out += fm->fm_mapped_extents * extent_size;
3430 argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3431 if (!argptr) {
3432 ret = -TARGET_EFAULT;
3433 } else {
3434 /* Convert the struct fiemap */
3435 thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3436 if (fm->fm_extent_count != 0) {
3437 p = argptr + target_size_in;
3438 /* ...and then all the struct fiemap_extents */
3439 for (i = 0; i < fm->fm_mapped_extents; i++) {
3440 thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3441 THUNK_TARGET);
3442 p += extent_size;
3445 unlock_user(argptr, arg, target_size_out);
3448 if (free_fm) {
3449 free(fm);
3451 return ret;
3453 #endif
3455 static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3456 int fd, int cmd, abi_long arg)
3458 const argtype *arg_type = ie->arg_type;
3459 int target_size;
3460 void *argptr;
3461 int ret;
3462 struct ifconf *host_ifconf;
3463 uint32_t outbufsz;
3464 const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3465 int target_ifreq_size;
3466 int nb_ifreq;
3467 int free_buf = 0;
3468 int i;
3469 int target_ifc_len;
3470 abi_long target_ifc_buf;
3471 int host_ifc_len;
3472 char *host_ifc_buf;
3474 assert(arg_type[0] == TYPE_PTR);
3475 assert(ie->access == IOC_RW);
3477 arg_type++;
3478 target_size = thunk_type_size(arg_type, 0);
3480 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3481 if (!argptr)
3482 return -TARGET_EFAULT;
3483 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3484 unlock_user(argptr, arg, 0);
3486 host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3487 target_ifc_len = host_ifconf->ifc_len;
3488 target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3490 target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3491 nb_ifreq = target_ifc_len / target_ifreq_size;
3492 host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3494 outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3495 if (outbufsz > MAX_STRUCT_SIZE) {
3496 /* We can't fit all the extents into the fixed size buffer.
3497 * Allocate one that is large enough and use it instead.
3499 host_ifconf = malloc(outbufsz);
3500 if (!host_ifconf) {
3501 return -TARGET_ENOMEM;
3503 memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3504 free_buf = 1;
3506 host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3508 host_ifconf->ifc_len = host_ifc_len;
3509 host_ifconf->ifc_buf = host_ifc_buf;
3511 ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3512 if (!is_error(ret)) {
3513 /* convert host ifc_len to target ifc_len */
3515 nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3516 target_ifc_len = nb_ifreq * target_ifreq_size;
3517 host_ifconf->ifc_len = target_ifc_len;
3519 /* restore target ifc_buf */
3521 host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3523 /* copy struct ifconf to target user */
3525 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3526 if (!argptr)
3527 return -TARGET_EFAULT;
3528 thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3529 unlock_user(argptr, arg, target_size);
3531 /* copy ifreq[] to target user */
3533 argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3534 for (i = 0; i < nb_ifreq ; i++) {
3535 thunk_convert(argptr + i * target_ifreq_size,
3536 host_ifc_buf + i * sizeof(struct ifreq),
3537 ifreq_arg_type, THUNK_TARGET);
3539 unlock_user(argptr, target_ifc_buf, target_ifc_len);
3542 if (free_buf) {
3543 free(host_ifconf);
3546 return ret;
3549 static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3550 int cmd, abi_long arg)
3552 void *argptr;
3553 struct dm_ioctl *host_dm;
3554 abi_long guest_data;
3555 uint32_t guest_data_size;
3556 int target_size;
3557 const argtype *arg_type = ie->arg_type;
3558 abi_long ret;
3559 void *big_buf = NULL;
3560 char *host_data;
3562 arg_type++;
3563 target_size = thunk_type_size(arg_type, 0);
3564 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3565 if (!argptr) {
3566 ret = -TARGET_EFAULT;
3567 goto out;
3569 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3570 unlock_user(argptr, arg, 0);
3572 /* buf_temp is too small, so fetch things into a bigger buffer */
3573 big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
3574 memcpy(big_buf, buf_temp, target_size);
3575 buf_temp = big_buf;
3576 host_dm = big_buf;
3578 guest_data = arg + host_dm->data_start;
3579 if ((guest_data - arg) < 0) {
3580 ret = -EINVAL;
3581 goto out;
3583 guest_data_size = host_dm->data_size - host_dm->data_start;
3584 host_data = (char*)host_dm + host_dm->data_start;
3586 argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
3587 switch (ie->host_cmd) {
3588 case DM_REMOVE_ALL:
3589 case DM_LIST_DEVICES:
3590 case DM_DEV_CREATE:
3591 case DM_DEV_REMOVE:
3592 case DM_DEV_SUSPEND:
3593 case DM_DEV_STATUS:
3594 case DM_DEV_WAIT:
3595 case DM_TABLE_STATUS:
3596 case DM_TABLE_CLEAR:
3597 case DM_TABLE_DEPS:
3598 case DM_LIST_VERSIONS:
3599 /* no input data */
3600 break;
3601 case DM_DEV_RENAME:
3602 case DM_DEV_SET_GEOMETRY:
3603 /* data contains only strings */
3604 memcpy(host_data, argptr, guest_data_size);
3605 break;
3606 case DM_TARGET_MSG:
3607 memcpy(host_data, argptr, guest_data_size);
3608 *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
3609 break;
3610 case DM_TABLE_LOAD:
3612 void *gspec = argptr;
3613 void *cur_data = host_data;
3614 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3615 int spec_size = thunk_type_size(arg_type, 0);
3616 int i;
3618 for (i = 0; i < host_dm->target_count; i++) {
3619 struct dm_target_spec *spec = cur_data;
3620 uint32_t next;
3621 int slen;
3623 thunk_convert(spec, gspec, arg_type, THUNK_HOST);
3624 slen = strlen((char*)gspec + spec_size) + 1;
3625 next = spec->next;
3626 spec->next = sizeof(*spec) + slen;
3627 strcpy((char*)&spec[1], gspec + spec_size);
3628 gspec += next;
3629 cur_data += spec->next;
3631 break;
3633 default:
3634 ret = -TARGET_EINVAL;
3635 unlock_user(argptr, guest_data, 0);
3636 goto out;
3638 unlock_user(argptr, guest_data, 0);
3640 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3641 if (!is_error(ret)) {
3642 guest_data = arg + host_dm->data_start;
3643 guest_data_size = host_dm->data_size - host_dm->data_start;
3644 argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
3645 switch (ie->host_cmd) {
3646 case DM_REMOVE_ALL:
3647 case DM_DEV_CREATE:
3648 case DM_DEV_REMOVE:
3649 case DM_DEV_RENAME:
3650 case DM_DEV_SUSPEND:
3651 case DM_DEV_STATUS:
3652 case DM_TABLE_LOAD:
3653 case DM_TABLE_CLEAR:
3654 case DM_TARGET_MSG:
3655 case DM_DEV_SET_GEOMETRY:
3656 /* no return data */
3657 break;
3658 case DM_LIST_DEVICES:
3660 struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
3661 uint32_t remaining_data = guest_data_size;
3662 void *cur_data = argptr;
3663 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
3664 int nl_size = 12; /* can't use thunk_size due to alignment */
3666 while (1) {
3667 uint32_t next = nl->next;
3668 if (next) {
3669 nl->next = nl_size + (strlen(nl->name) + 1);
3671 if (remaining_data < nl->next) {
3672 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3673 break;
3675 thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
3676 strcpy(cur_data + nl_size, nl->name);
3677 cur_data += nl->next;
3678 remaining_data -= nl->next;
3679 if (!next) {
3680 break;
3682 nl = (void*)nl + next;
3684 break;
3686 case DM_DEV_WAIT:
3687 case DM_TABLE_STATUS:
3689 struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
3690 void *cur_data = argptr;
3691 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
3692 int spec_size = thunk_type_size(arg_type, 0);
3693 int i;
3695 for (i = 0; i < host_dm->target_count; i++) {
3696 uint32_t next = spec->next;
3697 int slen = strlen((char*)&spec[1]) + 1;
3698 spec->next = (cur_data - argptr) + spec_size + slen;
3699 if (guest_data_size < spec->next) {
3700 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3701 break;
3703 thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
3704 strcpy(cur_data + spec_size, (char*)&spec[1]);
3705 cur_data = argptr + spec->next;
3706 spec = (void*)host_dm + host_dm->data_start + next;
3708 break;
3710 case DM_TABLE_DEPS:
3712 void *hdata = (void*)host_dm + host_dm->data_start;
3713 int count = *(uint32_t*)hdata;
3714 uint64_t *hdev = hdata + 8;
3715 uint64_t *gdev = argptr + 8;
3716 int i;
3718 *(uint32_t*)argptr = tswap32(count);
3719 for (i = 0; i < count; i++) {
3720 *gdev = tswap64(*hdev);
3721 gdev++;
3722 hdev++;
3724 break;
3726 case DM_LIST_VERSIONS:
3728 struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
3729 uint32_t remaining_data = guest_data_size;
3730 void *cur_data = argptr;
3731 const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
3732 int vers_size = thunk_type_size(arg_type, 0);
3734 while (1) {
3735 uint32_t next = vers->next;
3736 if (next) {
3737 vers->next = vers_size + (strlen(vers->name) + 1);
3739 if (remaining_data < vers->next) {
3740 host_dm->flags |= DM_BUFFER_FULL_FLAG;
3741 break;
3743 thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
3744 strcpy(cur_data + vers_size, vers->name);
3745 cur_data += vers->next;
3746 remaining_data -= vers->next;
3747 if (!next) {
3748 break;
3750 vers = (void*)vers + next;
3752 break;
3754 default:
3755 unlock_user(argptr, guest_data, 0);
3756 ret = -TARGET_EINVAL;
3757 goto out;
3759 unlock_user(argptr, guest_data, guest_data_size);
3761 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3762 if (!argptr) {
3763 ret = -TARGET_EFAULT;
3764 goto out;
3766 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3767 unlock_user(argptr, arg, target_size);
3769 out:
3770 g_free(big_buf);
3771 return ret;
3774 static abi_long do_ioctl_blkpg(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
3775 int cmd, abi_long arg)
3777 void *argptr;
3778 int target_size;
3779 const argtype *arg_type = ie->arg_type;
3780 const argtype part_arg_type[] = { MK_STRUCT(STRUCT_blkpg_partition) };
3781 abi_long ret;
3783 struct blkpg_ioctl_arg *host_blkpg = (void*)buf_temp;
3784 struct blkpg_partition host_part;
3786 /* Read and convert blkpg */
3787 arg_type++;
3788 target_size = thunk_type_size(arg_type, 0);
3789 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3790 if (!argptr) {
3791 ret = -TARGET_EFAULT;
3792 goto out;
3794 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3795 unlock_user(argptr, arg, 0);
3797 switch (host_blkpg->op) {
3798 case BLKPG_ADD_PARTITION:
3799 case BLKPG_DEL_PARTITION:
3800 /* payload is struct blkpg_partition */
3801 break;
3802 default:
3803 /* Unknown opcode */
3804 ret = -TARGET_EINVAL;
3805 goto out;
3808 /* Read and convert blkpg->data */
3809 arg = (abi_long)(uintptr_t)host_blkpg->data;
3810 target_size = thunk_type_size(part_arg_type, 0);
3811 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3812 if (!argptr) {
3813 ret = -TARGET_EFAULT;
3814 goto out;
3816 thunk_convert(&host_part, argptr, part_arg_type, THUNK_HOST);
3817 unlock_user(argptr, arg, 0);
3819 /* Swizzle the data pointer to our local copy and call! */
3820 host_blkpg->data = &host_part;
3821 ret = get_errno(ioctl(fd, ie->host_cmd, host_blkpg));
3823 out:
3824 return ret;
3827 static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
3828 int fd, int cmd, abi_long arg)
3830 const argtype *arg_type = ie->arg_type;
3831 const StructEntry *se;
3832 const argtype *field_types;
3833 const int *dst_offsets, *src_offsets;
3834 int target_size;
3835 void *argptr;
3836 abi_ulong *target_rt_dev_ptr;
3837 unsigned long *host_rt_dev_ptr;
3838 abi_long ret;
3839 int i;
3841 assert(ie->access == IOC_W);
3842 assert(*arg_type == TYPE_PTR);
3843 arg_type++;
3844 assert(*arg_type == TYPE_STRUCT);
3845 target_size = thunk_type_size(arg_type, 0);
3846 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3847 if (!argptr) {
3848 return -TARGET_EFAULT;
3850 arg_type++;
3851 assert(*arg_type == (int)STRUCT_rtentry);
3852 se = struct_entries + *arg_type++;
3853 assert(se->convert[0] == NULL);
3854 /* convert struct here to be able to catch rt_dev string */
3855 field_types = se->field_types;
3856 dst_offsets = se->field_offsets[THUNK_HOST];
3857 src_offsets = se->field_offsets[THUNK_TARGET];
3858 for (i = 0; i < se->nb_fields; i++) {
3859 if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
3860 assert(*field_types == TYPE_PTRVOID);
3861 target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
3862 host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
3863 if (*target_rt_dev_ptr != 0) {
3864 *host_rt_dev_ptr = (unsigned long)lock_user_string(
3865 tswapal(*target_rt_dev_ptr));
3866 if (!*host_rt_dev_ptr) {
3867 unlock_user(argptr, arg, 0);
3868 return -TARGET_EFAULT;
3870 } else {
3871 *host_rt_dev_ptr = 0;
3873 field_types++;
3874 continue;
3876 field_types = thunk_convert(buf_temp + dst_offsets[i],
3877 argptr + src_offsets[i],
3878 field_types, THUNK_HOST);
3880 unlock_user(argptr, arg, 0);
3882 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3883 if (*host_rt_dev_ptr != 0) {
3884 unlock_user((void *)*host_rt_dev_ptr,
3885 *target_rt_dev_ptr, 0);
3887 return ret;
3890 static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
3891 int fd, int cmd, abi_long arg)
3893 int sig = target_to_host_signal(arg);
3894 return get_errno(ioctl(fd, ie->host_cmd, sig));
3897 static IOCTLEntry ioctl_entries[] = {
3898 #define IOCTL(cmd, access, ...) \
3899 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3900 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3901 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3902 #include "ioctls.h"
3903 { 0, 0, },
3906 /* ??? Implement proper locking for ioctls. */
3907 /* do_ioctl() Must return target values and target errnos. */
3908 static abi_long do_ioctl(int fd, int cmd, abi_long arg)
3910 const IOCTLEntry *ie;
3911 const argtype *arg_type;
3912 abi_long ret;
3913 uint8_t buf_temp[MAX_STRUCT_SIZE];
3914 int target_size;
3915 void *argptr;
3917 ie = ioctl_entries;
3918 for(;;) {
3919 if (ie->target_cmd == 0) {
3920 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3921 return -TARGET_ENOSYS;
3923 if (ie->target_cmd == cmd)
3924 break;
3925 ie++;
3927 arg_type = ie->arg_type;
3928 #if defined(DEBUG)
3929 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3930 #endif
3931 if (ie->do_ioctl) {
3932 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3935 switch(arg_type[0]) {
3936 case TYPE_NULL:
3937 /* no argument */
3938 ret = get_errno(ioctl(fd, ie->host_cmd));
3939 break;
3940 case TYPE_PTRVOID:
3941 case TYPE_INT:
3942 ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3943 break;
3944 case TYPE_PTR:
3945 arg_type++;
3946 target_size = thunk_type_size(arg_type, 0);
3947 switch(ie->access) {
3948 case IOC_R:
3949 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3950 if (!is_error(ret)) {
3951 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3952 if (!argptr)
3953 return -TARGET_EFAULT;
3954 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3955 unlock_user(argptr, arg, target_size);
3957 break;
3958 case IOC_W:
3959 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3960 if (!argptr)
3961 return -TARGET_EFAULT;
3962 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3963 unlock_user(argptr, arg, 0);
3964 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3965 break;
3966 default:
3967 case IOC_RW:
3968 argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3969 if (!argptr)
3970 return -TARGET_EFAULT;
3971 thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3972 unlock_user(argptr, arg, 0);
3973 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3974 if (!is_error(ret)) {
3975 argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3976 if (!argptr)
3977 return -TARGET_EFAULT;
3978 thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3979 unlock_user(argptr, arg, target_size);
3981 break;
3983 break;
3984 default:
3985 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3986 (long)cmd, arg_type[0]);
3987 ret = -TARGET_ENOSYS;
3988 break;
3990 return ret;
3993 static const bitmask_transtbl iflag_tbl[] = {
3994 { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3995 { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3996 { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3997 { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3998 { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3999 { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
4000 { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
4001 { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
4002 { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
4003 { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
4004 { TARGET_IXON, TARGET_IXON, IXON, IXON },
4005 { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
4006 { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
4007 { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
4008 { 0, 0, 0, 0 }
4011 static const bitmask_transtbl oflag_tbl[] = {
4012 { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
4013 { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
4014 { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
4015 { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
4016 { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
4017 { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
4018 { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
4019 { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
4020 { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
4021 { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
4022 { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
4023 { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
4024 { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
4025 { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
4026 { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
4027 { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
4028 { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
4029 { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
4030 { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
4031 { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
4032 { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
4033 { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
4034 { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
4035 { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
4036 { 0, 0, 0, 0 }
4039 static const bitmask_transtbl cflag_tbl[] = {
4040 { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
4041 { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
4042 { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
4043 { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
4044 { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
4045 { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
4046 { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
4047 { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
4048 { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
4049 { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
4050 { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
4051 { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
4052 { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
4053 { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
4054 { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
4055 { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
4056 { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
4057 { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
4058 { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
4059 { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
4060 { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
4061 { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
4062 { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
4063 { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
4064 { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
4065 { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
4066 { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
4067 { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
4068 { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
4069 { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
4070 { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
4071 { 0, 0, 0, 0 }
4074 static const bitmask_transtbl lflag_tbl[] = {
4075 { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
4076 { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
4077 { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
4078 { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
4079 { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
4080 { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
4081 { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
4082 { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
4083 { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
4084 { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
4085 { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
4086 { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
4087 { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
4088 { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
4089 { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
4090 { 0, 0, 0, 0 }
4093 static void target_to_host_termios (void *dst, const void *src)
4095 struct host_termios *host = dst;
4096 const struct target_termios *target = src;
4098 host->c_iflag =
4099 target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
4100 host->c_oflag =
4101 target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
4102 host->c_cflag =
4103 target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
4104 host->c_lflag =
4105 target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
4106 host->c_line = target->c_line;
4108 memset(host->c_cc, 0, sizeof(host->c_cc));
4109 host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
4110 host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
4111 host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
4112 host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
4113 host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
4114 host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
4115 host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
4116 host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
4117 host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
4118 host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
4119 host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
4120 host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
4121 host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
4122 host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
4123 host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
4124 host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
4125 host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
4128 static void host_to_target_termios (void *dst, const void *src)
4130 struct target_termios *target = dst;
4131 const struct host_termios *host = src;
4133 target->c_iflag =
4134 tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
4135 target->c_oflag =
4136 tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
4137 target->c_cflag =
4138 tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
4139 target->c_lflag =
4140 tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
4141 target->c_line = host->c_line;
4143 memset(target->c_cc, 0, sizeof(target->c_cc));
4144 target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
4145 target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
4146 target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
4147 target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
4148 target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
4149 target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
4150 target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
4151 target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
4152 target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
4153 target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
4154 target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
4155 target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
4156 target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
4157 target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
4158 target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
4159 target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
4160 target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
4163 static const StructEntry struct_termios_def = {
4164 .convert = { host_to_target_termios, target_to_host_termios },
4165 .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
4166 .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
4169 static bitmask_transtbl mmap_flags_tbl[] = {
4170 { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
4171 { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
4172 { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
4173 { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
4174 { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
4175 { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
4176 { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
4177 { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
4178 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, MAP_NORESERVE,
4179 MAP_NORESERVE },
4180 { 0, 0, 0, 0 }
4183 #if defined(TARGET_I386)
4185 /* NOTE: there is really one LDT for all the threads */
4186 static uint8_t *ldt_table;
4188 static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
4190 int size;
4191 void *p;
4193 if (!ldt_table)
4194 return 0;
4195 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
4196 if (size > bytecount)
4197 size = bytecount;
4198 p = lock_user(VERIFY_WRITE, ptr, size, 0);
4199 if (!p)
4200 return -TARGET_EFAULT;
4201 /* ??? Should this by byteswapped? */
4202 memcpy(p, ldt_table, size);
4203 unlock_user(p, ptr, size);
4204 return size;
4207 /* XXX: add locking support */
4208 static abi_long write_ldt(CPUX86State *env,
4209 abi_ulong ptr, unsigned long bytecount, int oldmode)
4211 struct target_modify_ldt_ldt_s ldt_info;
4212 struct target_modify_ldt_ldt_s *target_ldt_info;
4213 int seg_32bit, contents, read_exec_only, limit_in_pages;
4214 int seg_not_present, useable, lm;
4215 uint32_t *lp, entry_1, entry_2;
4217 if (bytecount != sizeof(ldt_info))
4218 return -TARGET_EINVAL;
4219 if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
4220 return -TARGET_EFAULT;
4221 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4222 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4223 ldt_info.limit = tswap32(target_ldt_info->limit);
4224 ldt_info.flags = tswap32(target_ldt_info->flags);
4225 unlock_user_struct(target_ldt_info, ptr, 0);
4227 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
4228 return -TARGET_EINVAL;
4229 seg_32bit = ldt_info.flags & 1;
4230 contents = (ldt_info.flags >> 1) & 3;
4231 read_exec_only = (ldt_info.flags >> 3) & 1;
4232 limit_in_pages = (ldt_info.flags >> 4) & 1;
4233 seg_not_present = (ldt_info.flags >> 5) & 1;
4234 useable = (ldt_info.flags >> 6) & 1;
4235 #ifdef TARGET_ABI32
4236 lm = 0;
4237 #else
4238 lm = (ldt_info.flags >> 7) & 1;
4239 #endif
4240 if (contents == 3) {
4241 if (oldmode)
4242 return -TARGET_EINVAL;
4243 if (seg_not_present == 0)
4244 return -TARGET_EINVAL;
4246 /* allocate the LDT */
4247 if (!ldt_table) {
4248 env->ldt.base = target_mmap(0,
4249 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
4250 PROT_READ|PROT_WRITE,
4251 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
4252 if (env->ldt.base == -1)
4253 return -TARGET_ENOMEM;
4254 memset(g2h(env->ldt.base), 0,
4255 TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
4256 env->ldt.limit = 0xffff;
4257 ldt_table = g2h(env->ldt.base);
4260 /* NOTE: same code as Linux kernel */
4261 /* Allow LDTs to be cleared by the user. */
4262 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4263 if (oldmode ||
4264 (contents == 0 &&
4265 read_exec_only == 1 &&
4266 seg_32bit == 0 &&
4267 limit_in_pages == 0 &&
4268 seg_not_present == 1 &&
4269 useable == 0 )) {
4270 entry_1 = 0;
4271 entry_2 = 0;
4272 goto install;
4276 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4277 (ldt_info.limit & 0x0ffff);
4278 entry_2 = (ldt_info.base_addr & 0xff000000) |
4279 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4280 (ldt_info.limit & 0xf0000) |
4281 ((read_exec_only ^ 1) << 9) |
4282 (contents << 10) |
4283 ((seg_not_present ^ 1) << 15) |
4284 (seg_32bit << 22) |
4285 (limit_in_pages << 23) |
4286 (lm << 21) |
4287 0x7000;
4288 if (!oldmode)
4289 entry_2 |= (useable << 20);
4291 /* Install the new entry ... */
4292 install:
4293 lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
4294 lp[0] = tswap32(entry_1);
4295 lp[1] = tswap32(entry_2);
4296 return 0;
4299 /* specific and weird i386 syscalls */
4300 static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
4301 unsigned long bytecount)
4303 abi_long ret;
4305 switch (func) {
4306 case 0:
4307 ret = read_ldt(ptr, bytecount);
4308 break;
4309 case 1:
4310 ret = write_ldt(env, ptr, bytecount, 1);
4311 break;
4312 case 0x11:
4313 ret = write_ldt(env, ptr, bytecount, 0);
4314 break;
4315 default:
4316 ret = -TARGET_ENOSYS;
4317 break;
4319 return ret;
4322 #if defined(TARGET_I386) && defined(TARGET_ABI32)
4323 abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
4325 uint64_t *gdt_table = g2h(env->gdt.base);
4326 struct target_modify_ldt_ldt_s ldt_info;
4327 struct target_modify_ldt_ldt_s *target_ldt_info;
4328 int seg_32bit, contents, read_exec_only, limit_in_pages;
4329 int seg_not_present, useable, lm;
4330 uint32_t *lp, entry_1, entry_2;
4331 int i;
4333 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4334 if (!target_ldt_info)
4335 return -TARGET_EFAULT;
4336 ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
4337 ldt_info.base_addr = tswapal(target_ldt_info->base_addr);
4338 ldt_info.limit = tswap32(target_ldt_info->limit);
4339 ldt_info.flags = tswap32(target_ldt_info->flags);
4340 if (ldt_info.entry_number == -1) {
4341 for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
4342 if (gdt_table[i] == 0) {
4343 ldt_info.entry_number = i;
4344 target_ldt_info->entry_number = tswap32(i);
4345 break;
4349 unlock_user_struct(target_ldt_info, ptr, 1);
4351 if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
4352 ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
4353 return -TARGET_EINVAL;
4354 seg_32bit = ldt_info.flags & 1;
4355 contents = (ldt_info.flags >> 1) & 3;
4356 read_exec_only = (ldt_info.flags >> 3) & 1;
4357 limit_in_pages = (ldt_info.flags >> 4) & 1;
4358 seg_not_present = (ldt_info.flags >> 5) & 1;
4359 useable = (ldt_info.flags >> 6) & 1;
4360 #ifdef TARGET_ABI32
4361 lm = 0;
4362 #else
4363 lm = (ldt_info.flags >> 7) & 1;
4364 #endif
4366 if (contents == 3) {
4367 if (seg_not_present == 0)
4368 return -TARGET_EINVAL;
4371 /* NOTE: same code as Linux kernel */
4372 /* Allow LDTs to be cleared by the user. */
4373 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
4374 if ((contents == 0 &&
4375 read_exec_only == 1 &&
4376 seg_32bit == 0 &&
4377 limit_in_pages == 0 &&
4378 seg_not_present == 1 &&
4379 useable == 0 )) {
4380 entry_1 = 0;
4381 entry_2 = 0;
4382 goto install;
4386 entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
4387 (ldt_info.limit & 0x0ffff);
4388 entry_2 = (ldt_info.base_addr & 0xff000000) |
4389 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
4390 (ldt_info.limit & 0xf0000) |
4391 ((read_exec_only ^ 1) << 9) |
4392 (contents << 10) |
4393 ((seg_not_present ^ 1) << 15) |
4394 (seg_32bit << 22) |
4395 (limit_in_pages << 23) |
4396 (useable << 20) |
4397 (lm << 21) |
4398 0x7000;
4400 /* Install the new entry ... */
4401 install:
4402 lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
4403 lp[0] = tswap32(entry_1);
4404 lp[1] = tswap32(entry_2);
4405 return 0;
4408 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
4410 struct target_modify_ldt_ldt_s *target_ldt_info;
4411 uint64_t *gdt_table = g2h(env->gdt.base);
4412 uint32_t base_addr, limit, flags;
4413 int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
4414 int seg_not_present, useable, lm;
4415 uint32_t *lp, entry_1, entry_2;
4417 lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
4418 if (!target_ldt_info)
4419 return -TARGET_EFAULT;
4420 idx = tswap32(target_ldt_info->entry_number);
4421 if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
4422 idx > TARGET_GDT_ENTRY_TLS_MAX) {
4423 unlock_user_struct(target_ldt_info, ptr, 1);
4424 return -TARGET_EINVAL;
4426 lp = (uint32_t *)(gdt_table + idx);
4427 entry_1 = tswap32(lp[0]);
4428 entry_2 = tswap32(lp[1]);
4430 read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
4431 contents = (entry_2 >> 10) & 3;
4432 seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
4433 seg_32bit = (entry_2 >> 22) & 1;
4434 limit_in_pages = (entry_2 >> 23) & 1;
4435 useable = (entry_2 >> 20) & 1;
4436 #ifdef TARGET_ABI32
4437 lm = 0;
4438 #else
4439 lm = (entry_2 >> 21) & 1;
4440 #endif
4441 flags = (seg_32bit << 0) | (contents << 1) |
4442 (read_exec_only << 3) | (limit_in_pages << 4) |
4443 (seg_not_present << 5) | (useable << 6) | (lm << 7);
4444 limit = (entry_1 & 0xffff) | (entry_2 & 0xf0000);
4445 base_addr = (entry_1 >> 16) |
4446 (entry_2 & 0xff000000) |
4447 ((entry_2 & 0xff) << 16);
4448 target_ldt_info->base_addr = tswapal(base_addr);
4449 target_ldt_info->limit = tswap32(limit);
4450 target_ldt_info->flags = tswap32(flags);
4451 unlock_user_struct(target_ldt_info, ptr, 1);
4452 return 0;
4454 #endif /* TARGET_I386 && TARGET_ABI32 */
4456 #ifndef TARGET_ABI32
4457 abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
4459 abi_long ret = 0;
4460 abi_ulong val;
4461 int idx;
4463 switch(code) {
4464 case TARGET_ARCH_SET_GS:
4465 case TARGET_ARCH_SET_FS:
4466 if (code == TARGET_ARCH_SET_GS)
4467 idx = R_GS;
4468 else
4469 idx = R_FS;
4470 cpu_x86_load_seg(env, idx, 0);
4471 env->segs[idx].base = addr;
4472 break;
4473 case TARGET_ARCH_GET_GS:
4474 case TARGET_ARCH_GET_FS:
4475 if (code == TARGET_ARCH_GET_GS)
4476 idx = R_GS;
4477 else
4478 idx = R_FS;
4479 val = env->segs[idx].base;
4480 if (put_user(val, addr, abi_ulong))
4481 ret = -TARGET_EFAULT;
4482 break;
4483 default:
4484 ret = -TARGET_EINVAL;
4485 break;
4487 return ret;
4489 #endif
4491 #endif /* defined(TARGET_I386) */
4493 #define NEW_STACK_SIZE 0x40000
4496 static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
4497 typedef struct {
4498 CPUArchState *env;
4499 pthread_mutex_t mutex;
4500 pthread_cond_t cond;
4501 pthread_t thread;
4502 uint32_t tid;
4503 abi_ulong child_tidptr;
4504 abi_ulong parent_tidptr;
4505 sigset_t sigmask;
4506 } new_thread_info;
4508 static void *clone_func(void *arg)
4510 new_thread_info *info = arg;
4511 CPUArchState *env;
4512 CPUState *cpu;
4513 TaskState *ts;
4515 env = info->env;
4516 cpu = ENV_GET_CPU(env);
4517 thread_cpu = cpu;
4518 ts = (TaskState *)cpu->opaque;
4519 info->tid = gettid();
4520 cpu->host_tid = info->tid;
4521 task_settid(ts);
4522 if (info->child_tidptr)
4523 put_user_u32(info->tid, info->child_tidptr);
4524 if (info->parent_tidptr)
4525 put_user_u32(info->tid, info->parent_tidptr);
4526 /* Enable signals. */
4527 sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
4528 /* Signal to the parent that we're ready. */
4529 pthread_mutex_lock(&info->mutex);
4530 pthread_cond_broadcast(&info->cond);
4531 pthread_mutex_unlock(&info->mutex);
4532 /* Wait until the parent has finshed initializing the tls state. */
4533 pthread_mutex_lock(&clone_lock);
4534 pthread_mutex_unlock(&clone_lock);
4535 cpu_loop(env);
4536 /* never exits */
4537 return NULL;
4540 /* do_fork() Must return host values and target errnos (unlike most
4541 do_*() functions). */
4542 static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
4543 abi_ulong parent_tidptr, target_ulong newtls,
4544 abi_ulong child_tidptr)
4546 CPUState *cpu = ENV_GET_CPU(env);
4547 int ret;
4548 TaskState *ts;
4549 CPUState *new_cpu;
4550 CPUArchState *new_env;
4551 unsigned int nptl_flags;
4552 sigset_t sigmask;
4554 /* Emulate vfork() with fork() */
4555 if (flags & CLONE_VFORK)
4556 flags &= ~(CLONE_VFORK | CLONE_VM);
4558 if (flags & CLONE_VM) {
4559 TaskState *parent_ts = (TaskState *)cpu->opaque;
4560 new_thread_info info;
4561 pthread_attr_t attr;
4563 ts = g_malloc0(sizeof(TaskState));
4564 init_task_state(ts);
4565 /* we create a new CPU instance. */
4566 new_env = cpu_copy(env);
4567 /* Init regs that differ from the parent. */
4568 cpu_clone_regs(new_env, newsp);
4569 new_cpu = ENV_GET_CPU(new_env);
4570 new_cpu->opaque = ts;
4571 ts->bprm = parent_ts->bprm;
4572 ts->info = parent_ts->info;
4573 nptl_flags = flags;
4574 flags &= ~CLONE_NPTL_FLAGS2;
4576 if (nptl_flags & CLONE_CHILD_CLEARTID) {
4577 ts->child_tidptr = child_tidptr;
4580 if (nptl_flags & CLONE_SETTLS)
4581 cpu_set_tls (new_env, newtls);
4583 /* Grab a mutex so that thread setup appears atomic. */
4584 pthread_mutex_lock(&clone_lock);
4586 memset(&info, 0, sizeof(info));
4587 pthread_mutex_init(&info.mutex, NULL);
4588 pthread_mutex_lock(&info.mutex);
4589 pthread_cond_init(&info.cond, NULL);
4590 info.env = new_env;
4591 if (nptl_flags & CLONE_CHILD_SETTID)
4592 info.child_tidptr = child_tidptr;
4593 if (nptl_flags & CLONE_PARENT_SETTID)
4594 info.parent_tidptr = parent_tidptr;
4596 ret = pthread_attr_init(&attr);
4597 ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
4598 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4599 /* It is not safe to deliver signals until the child has finished
4600 initializing, so temporarily block all signals. */
4601 sigfillset(&sigmask);
4602 sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
4604 ret = pthread_create(&info.thread, &attr, clone_func, &info);
4605 /* TODO: Free new CPU state if thread creation failed. */
4607 sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
4608 pthread_attr_destroy(&attr);
4609 if (ret == 0) {
4610 /* Wait for the child to initialize. */
4611 pthread_cond_wait(&info.cond, &info.mutex);
4612 ret = info.tid;
4613 if (flags & CLONE_PARENT_SETTID)
4614 put_user_u32(ret, parent_tidptr);
4615 } else {
4616 ret = -1;
4618 pthread_mutex_unlock(&info.mutex);
4619 pthread_cond_destroy(&info.cond);
4620 pthread_mutex_destroy(&info.mutex);
4621 pthread_mutex_unlock(&clone_lock);
4622 } else {
4623 /* if no CLONE_VM, we consider it is a fork */
4624 if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4625 return -EINVAL;
4626 fork_start();
4627 ret = fork();
4628 if (ret == 0) {
4629 /* Child Process. */
4630 rcu_after_fork();
4631 cpu_clone_regs(env, newsp);
4632 fork_end(1);
4633 /* There is a race condition here. The parent process could
4634 theoretically read the TID in the child process before the child
4635 tid is set. This would require using either ptrace
4636 (not implemented) or having *_tidptr to point at a shared memory
4637 mapping. We can't repeat the spinlock hack used above because
4638 the child process gets its own copy of the lock. */
4639 if (flags & CLONE_CHILD_SETTID)
4640 put_user_u32(gettid(), child_tidptr);
4641 if (flags & CLONE_PARENT_SETTID)
4642 put_user_u32(gettid(), parent_tidptr);
4643 ts = (TaskState *)cpu->opaque;
4644 if (flags & CLONE_SETTLS)
4645 cpu_set_tls (env, newtls);
4646 if (flags & CLONE_CHILD_CLEARTID)
4647 ts->child_tidptr = child_tidptr;
4648 } else {
4649 fork_end(0);
4652 return ret;
4655 /* warning : doesn't handle linux specific flags... */
4656 static int target_to_host_fcntl_cmd(int cmd)
4658 switch(cmd) {
4659 case TARGET_F_DUPFD:
4660 case TARGET_F_GETFD:
4661 case TARGET_F_SETFD:
4662 case TARGET_F_GETFL:
4663 case TARGET_F_SETFL:
4664 return cmd;
4665 case TARGET_F_GETLK:
4666 return F_GETLK;
4667 case TARGET_F_SETLK:
4668 return F_SETLK;
4669 case TARGET_F_SETLKW:
4670 return F_SETLKW;
4671 case TARGET_F_GETOWN:
4672 return F_GETOWN;
4673 case TARGET_F_SETOWN:
4674 return F_SETOWN;
4675 case TARGET_F_GETSIG:
4676 return F_GETSIG;
4677 case TARGET_F_SETSIG:
4678 return F_SETSIG;
4679 #if TARGET_ABI_BITS == 32
4680 case TARGET_F_GETLK64:
4681 return F_GETLK64;
4682 case TARGET_F_SETLK64:
4683 return F_SETLK64;
4684 case TARGET_F_SETLKW64:
4685 return F_SETLKW64;
4686 #endif
4687 case TARGET_F_SETLEASE:
4688 return F_SETLEASE;
4689 case TARGET_F_GETLEASE:
4690 return F_GETLEASE;
4691 #ifdef F_DUPFD_CLOEXEC
4692 case TARGET_F_DUPFD_CLOEXEC:
4693 return F_DUPFD_CLOEXEC;
4694 #endif
4695 case TARGET_F_NOTIFY:
4696 return F_NOTIFY;
4697 #ifdef F_GETOWN_EX
4698 case TARGET_F_GETOWN_EX:
4699 return F_GETOWN_EX;
4700 #endif
4701 #ifdef F_SETOWN_EX
4702 case TARGET_F_SETOWN_EX:
4703 return F_SETOWN_EX;
4704 #endif
4705 default:
4706 return -TARGET_EINVAL;
4708 return -TARGET_EINVAL;
4711 #define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4712 static const bitmask_transtbl flock_tbl[] = {
4713 TRANSTBL_CONVERT(F_RDLCK),
4714 TRANSTBL_CONVERT(F_WRLCK),
4715 TRANSTBL_CONVERT(F_UNLCK),
4716 TRANSTBL_CONVERT(F_EXLCK),
4717 TRANSTBL_CONVERT(F_SHLCK),
4718 { 0, 0, 0, 0 }
4721 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4723 struct flock fl;
4724 struct target_flock *target_fl;
4725 struct flock64 fl64;
4726 struct target_flock64 *target_fl64;
4727 #ifdef F_GETOWN_EX
4728 struct f_owner_ex fox;
4729 struct target_f_owner_ex *target_fox;
4730 #endif
4731 abi_long ret;
4732 int host_cmd = target_to_host_fcntl_cmd(cmd);
4734 if (host_cmd == -TARGET_EINVAL)
4735 return host_cmd;
4737 switch(cmd) {
4738 case TARGET_F_GETLK:
4739 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4740 return -TARGET_EFAULT;
4741 fl.l_type =
4742 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4743 fl.l_whence = tswap16(target_fl->l_whence);
4744 fl.l_start = tswapal(target_fl->l_start);
4745 fl.l_len = tswapal(target_fl->l_len);
4746 fl.l_pid = tswap32(target_fl->l_pid);
4747 unlock_user_struct(target_fl, arg, 0);
4748 ret = get_errno(fcntl(fd, host_cmd, &fl));
4749 if (ret == 0) {
4750 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4751 return -TARGET_EFAULT;
4752 target_fl->l_type =
4753 host_to_target_bitmask(tswap16(fl.l_type), flock_tbl);
4754 target_fl->l_whence = tswap16(fl.l_whence);
4755 target_fl->l_start = tswapal(fl.l_start);
4756 target_fl->l_len = tswapal(fl.l_len);
4757 target_fl->l_pid = tswap32(fl.l_pid);
4758 unlock_user_struct(target_fl, arg, 1);
4760 break;
4762 case TARGET_F_SETLK:
4763 case TARGET_F_SETLKW:
4764 if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4765 return -TARGET_EFAULT;
4766 fl.l_type =
4767 target_to_host_bitmask(tswap16(target_fl->l_type), flock_tbl);
4768 fl.l_whence = tswap16(target_fl->l_whence);
4769 fl.l_start = tswapal(target_fl->l_start);
4770 fl.l_len = tswapal(target_fl->l_len);
4771 fl.l_pid = tswap32(target_fl->l_pid);
4772 unlock_user_struct(target_fl, arg, 0);
4773 ret = get_errno(fcntl(fd, host_cmd, &fl));
4774 break;
4776 case TARGET_F_GETLK64:
4777 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4778 return -TARGET_EFAULT;
4779 fl64.l_type =
4780 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4781 fl64.l_whence = tswap16(target_fl64->l_whence);
4782 fl64.l_start = tswap64(target_fl64->l_start);
4783 fl64.l_len = tswap64(target_fl64->l_len);
4784 fl64.l_pid = tswap32(target_fl64->l_pid);
4785 unlock_user_struct(target_fl64, arg, 0);
4786 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4787 if (ret == 0) {
4788 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4789 return -TARGET_EFAULT;
4790 target_fl64->l_type =
4791 host_to_target_bitmask(tswap16(fl64.l_type), flock_tbl) >> 1;
4792 target_fl64->l_whence = tswap16(fl64.l_whence);
4793 target_fl64->l_start = tswap64(fl64.l_start);
4794 target_fl64->l_len = tswap64(fl64.l_len);
4795 target_fl64->l_pid = tswap32(fl64.l_pid);
4796 unlock_user_struct(target_fl64, arg, 1);
4798 break;
4799 case TARGET_F_SETLK64:
4800 case TARGET_F_SETLKW64:
4801 if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4802 return -TARGET_EFAULT;
4803 fl64.l_type =
4804 target_to_host_bitmask(tswap16(target_fl64->l_type), flock_tbl) >> 1;
4805 fl64.l_whence = tswap16(target_fl64->l_whence);
4806 fl64.l_start = tswap64(target_fl64->l_start);
4807 fl64.l_len = tswap64(target_fl64->l_len);
4808 fl64.l_pid = tswap32(target_fl64->l_pid);
4809 unlock_user_struct(target_fl64, arg, 0);
4810 ret = get_errno(fcntl(fd, host_cmd, &fl64));
4811 break;
4813 case TARGET_F_GETFL:
4814 ret = get_errno(fcntl(fd, host_cmd, arg));
4815 if (ret >= 0) {
4816 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4818 break;
4820 case TARGET_F_SETFL:
4821 ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4822 break;
4824 #ifdef F_GETOWN_EX
4825 case TARGET_F_GETOWN_EX:
4826 ret = get_errno(fcntl(fd, host_cmd, &fox));
4827 if (ret >= 0) {
4828 if (!lock_user_struct(VERIFY_WRITE, target_fox, arg, 0))
4829 return -TARGET_EFAULT;
4830 target_fox->type = tswap32(fox.type);
4831 target_fox->pid = tswap32(fox.pid);
4832 unlock_user_struct(target_fox, arg, 1);
4834 break;
4835 #endif
4837 #ifdef F_SETOWN_EX
4838 case TARGET_F_SETOWN_EX:
4839 if (!lock_user_struct(VERIFY_READ, target_fox, arg, 1))
4840 return -TARGET_EFAULT;
4841 fox.type = tswap32(target_fox->type);
4842 fox.pid = tswap32(target_fox->pid);
4843 unlock_user_struct(target_fox, arg, 0);
4844 ret = get_errno(fcntl(fd, host_cmd, &fox));
4845 break;
4846 #endif
4848 case TARGET_F_SETOWN:
4849 case TARGET_F_GETOWN:
4850 case TARGET_F_SETSIG:
4851 case TARGET_F_GETSIG:
4852 case TARGET_F_SETLEASE:
4853 case TARGET_F_GETLEASE:
4854 ret = get_errno(fcntl(fd, host_cmd, arg));
4855 break;
4857 default:
4858 ret = get_errno(fcntl(fd, cmd, arg));
4859 break;
4861 return ret;
4864 #ifdef USE_UID16
4866 static inline int high2lowuid(int uid)
4868 if (uid > 65535)
4869 return 65534;
4870 else
4871 return uid;
4874 static inline int high2lowgid(int gid)
4876 if (gid > 65535)
4877 return 65534;
4878 else
4879 return gid;
4882 static inline int low2highuid(int uid)
4884 if ((int16_t)uid == -1)
4885 return -1;
4886 else
4887 return uid;
4890 static inline int low2highgid(int gid)
4892 if ((int16_t)gid == -1)
4893 return -1;
4894 else
4895 return gid;
4897 static inline int tswapid(int id)
4899 return tswap16(id);
4902 #define put_user_id(x, gaddr) put_user_u16(x, gaddr)
4904 #else /* !USE_UID16 */
4905 static inline int high2lowuid(int uid)
4907 return uid;
4909 static inline int high2lowgid(int gid)
4911 return gid;
4913 static inline int low2highuid(int uid)
4915 return uid;
4917 static inline int low2highgid(int gid)
4919 return gid;
4921 static inline int tswapid(int id)
4923 return tswap32(id);
4926 #define put_user_id(x, gaddr) put_user_u32(x, gaddr)
4928 #endif /* USE_UID16 */
4930 void syscall_init(void)
4932 IOCTLEntry *ie;
4933 const argtype *arg_type;
4934 int size;
4935 int i;
4937 thunk_init(STRUCT_MAX);
4939 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4940 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4941 #include "syscall_types.h"
4942 #undef STRUCT
4943 #undef STRUCT_SPECIAL
4945 /* Build target_to_host_errno_table[] table from
4946 * host_to_target_errno_table[]. */
4947 for (i = 0; i < ERRNO_TABLE_SIZE; i++) {
4948 target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4951 /* we patch the ioctl size if necessary. We rely on the fact that
4952 no ioctl has all the bits at '1' in the size field */
4953 ie = ioctl_entries;
4954 while (ie->target_cmd != 0) {
4955 if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4956 TARGET_IOC_SIZEMASK) {
4957 arg_type = ie->arg_type;
4958 if (arg_type[0] != TYPE_PTR) {
4959 fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4960 ie->target_cmd);
4961 exit(1);
4963 arg_type++;
4964 size = thunk_type_size(arg_type, 0);
4965 ie->target_cmd = (ie->target_cmd &
4966 ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4967 (size << TARGET_IOC_SIZESHIFT);
4970 /* automatic consistency check if same arch */
4971 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4972 (defined(__x86_64__) && defined(TARGET_X86_64))
4973 if (unlikely(ie->target_cmd != ie->host_cmd)) {
4974 fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4975 ie->name, ie->target_cmd, ie->host_cmd);
4977 #endif
4978 ie++;
4982 #if TARGET_ABI_BITS == 32
4983 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4985 #ifdef TARGET_WORDS_BIGENDIAN
4986 return ((uint64_t)word0 << 32) | word1;
4987 #else
4988 return ((uint64_t)word1 << 32) | word0;
4989 #endif
4991 #else /* TARGET_ABI_BITS == 32 */
4992 static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4994 return word0;
4996 #endif /* TARGET_ABI_BITS != 32 */
4998 #ifdef TARGET_NR_truncate64
4999 static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
5000 abi_long arg2,
5001 abi_long arg3,
5002 abi_long arg4)
5004 if (regpairs_aligned(cpu_env)) {
5005 arg2 = arg3;
5006 arg3 = arg4;
5008 return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
5010 #endif
5012 #ifdef TARGET_NR_ftruncate64
5013 static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
5014 abi_long arg2,
5015 abi_long arg3,
5016 abi_long arg4)
5018 if (regpairs_aligned(cpu_env)) {
5019 arg2 = arg3;
5020 arg3 = arg4;
5022 return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
5024 #endif
5026 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
5027 abi_ulong target_addr)
5029 struct target_timespec *target_ts;
5031 if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
5032 return -TARGET_EFAULT;
5033 host_ts->tv_sec = tswapal(target_ts->tv_sec);
5034 host_ts->tv_nsec = tswapal(target_ts->tv_nsec);
5035 unlock_user_struct(target_ts, target_addr, 0);
5036 return 0;
5039 static inline abi_long host_to_target_timespec(abi_ulong target_addr,
5040 struct timespec *host_ts)
5042 struct target_timespec *target_ts;
5044 if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
5045 return -TARGET_EFAULT;
5046 target_ts->tv_sec = tswapal(host_ts->tv_sec);
5047 target_ts->tv_nsec = tswapal(host_ts->tv_nsec);
5048 unlock_user_struct(target_ts, target_addr, 1);
5049 return 0;
5052 static inline abi_long target_to_host_itimerspec(struct itimerspec *host_itspec,
5053 abi_ulong target_addr)
5055 struct target_itimerspec *target_itspec;
5057 if (!lock_user_struct(VERIFY_READ, target_itspec, target_addr, 1)) {
5058 return -TARGET_EFAULT;
5061 host_itspec->it_interval.tv_sec =
5062 tswapal(target_itspec->it_interval.tv_sec);
5063 host_itspec->it_interval.tv_nsec =
5064 tswapal(target_itspec->it_interval.tv_nsec);
5065 host_itspec->it_value.tv_sec = tswapal(target_itspec->it_value.tv_sec);
5066 host_itspec->it_value.tv_nsec = tswapal(target_itspec->it_value.tv_nsec);
5068 unlock_user_struct(target_itspec, target_addr, 1);
5069 return 0;
5072 static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
5073 struct itimerspec *host_its)
5075 struct target_itimerspec *target_itspec;
5077 if (!lock_user_struct(VERIFY_WRITE, target_itspec, target_addr, 0)) {
5078 return -TARGET_EFAULT;
5081 target_itspec->it_interval.tv_sec = tswapal(host_its->it_interval.tv_sec);
5082 target_itspec->it_interval.tv_nsec = tswapal(host_its->it_interval.tv_nsec);
5084 target_itspec->it_value.tv_sec = tswapal(host_its->it_value.tv_sec);
5085 target_itspec->it_value.tv_nsec = tswapal(host_its->it_value.tv_nsec);
5087 unlock_user_struct(target_itspec, target_addr, 0);
5088 return 0;
5091 static inline abi_long target_to_host_sigevent(struct sigevent *host_sevp,
5092 abi_ulong target_addr)
5094 struct target_sigevent *target_sevp;
5096 if (!lock_user_struct(VERIFY_READ, target_sevp, target_addr, 1)) {
5097 return -TARGET_EFAULT;
5100 /* This union is awkward on 64 bit systems because it has a 32 bit
5101 * integer and a pointer in it; we follow the conversion approach
5102 * used for handling sigval types in signal.c so the guest should get
5103 * the correct value back even if we did a 64 bit byteswap and it's
5104 * using the 32 bit integer.
5106 host_sevp->sigev_value.sival_ptr =
5107 (void *)(uintptr_t)tswapal(target_sevp->sigev_value.sival_ptr);
5108 host_sevp->sigev_signo =
5109 target_to_host_signal(tswap32(target_sevp->sigev_signo));
5110 host_sevp->sigev_notify = tswap32(target_sevp->sigev_notify);
5111 host_sevp->_sigev_un._tid = tswap32(target_sevp->_sigev_un._tid);
5113 unlock_user_struct(target_sevp, target_addr, 1);
5114 return 0;
5117 #if defined(TARGET_NR_mlockall)
5118 static inline int target_to_host_mlockall_arg(int arg)
5120 int result = 0;
5122 if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
5123 result |= MCL_CURRENT;
5125 if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
5126 result |= MCL_FUTURE;
5128 return result;
5130 #endif
5132 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
5133 static inline abi_long host_to_target_stat64(void *cpu_env,
5134 abi_ulong target_addr,
5135 struct stat *host_st)
5137 #if defined(TARGET_ARM) && defined(TARGET_ABI32)
5138 if (((CPUARMState *)cpu_env)->eabi) {
5139 struct target_eabi_stat64 *target_st;
5141 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
5142 return -TARGET_EFAULT;
5143 memset(target_st, 0, sizeof(struct target_eabi_stat64));
5144 __put_user(host_st->st_dev, &target_st->st_dev);
5145 __put_user(host_st->st_ino, &target_st->st_ino);
5146 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5147 __put_user(host_st->st_ino, &target_st->__st_ino);
5148 #endif
5149 __put_user(host_st->st_mode, &target_st->st_mode);
5150 __put_user(host_st->st_nlink, &target_st->st_nlink);
5151 __put_user(host_st->st_uid, &target_st->st_uid);
5152 __put_user(host_st->st_gid, &target_st->st_gid);
5153 __put_user(host_st->st_rdev, &target_st->st_rdev);
5154 __put_user(host_st->st_size, &target_st->st_size);
5155 __put_user(host_st->st_blksize, &target_st->st_blksize);
5156 __put_user(host_st->st_blocks, &target_st->st_blocks);
5157 __put_user(host_st->st_atime, &target_st->target_st_atime);
5158 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
5159 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5160 unlock_user_struct(target_st, target_addr, 1);
5161 } else
5162 #endif
5164 #if defined(TARGET_HAS_STRUCT_STAT64)
5165 struct target_stat64 *target_st;
5166 #else
5167 struct target_stat *target_st;
5168 #endif
5170 if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
5171 return -TARGET_EFAULT;
5172 memset(target_st, 0, sizeof(*target_st));
5173 __put_user(host_st->st_dev, &target_st->st_dev);
5174 __put_user(host_st->st_ino, &target_st->st_ino);
5175 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5176 __put_user(host_st->st_ino, &target_st->__st_ino);
5177 #endif
5178 __put_user(host_st->st_mode, &target_st->st_mode);
5179 __put_user(host_st->st_nlink, &target_st->st_nlink);
5180 __put_user(host_st->st_uid, &target_st->st_uid);
5181 __put_user(host_st->st_gid, &target_st->st_gid);
5182 __put_user(host_st->st_rdev, &target_st->st_rdev);
5183 /* XXX: better use of kernel struct */
5184 __put_user(host_st->st_size, &target_st->st_size);
5185 __put_user(host_st->st_blksize, &target_st->st_blksize);
5186 __put_user(host_st->st_blocks, &target_st->st_blocks);
5187 __put_user(host_st->st_atime, &target_st->target_st_atime);
5188 __put_user(host_st->st_mtime, &target_st->target_st_mtime);
5189 __put_user(host_st->st_ctime, &target_st->target_st_ctime);
5190 unlock_user_struct(target_st, target_addr, 1);
5193 return 0;
5195 #endif
5197 /* ??? Using host futex calls even when target atomic operations
5198 are not really atomic probably breaks things. However implementing
5199 futexes locally would make futexes shared between multiple processes
5200 tricky. However they're probably useless because guest atomic
5201 operations won't work either. */
5202 static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
5203 target_ulong uaddr2, int val3)
5205 struct timespec ts, *pts;
5206 int base_op;
5208 /* ??? We assume FUTEX_* constants are the same on both host
5209 and target. */
5210 #ifdef FUTEX_CMD_MASK
5211 base_op = op & FUTEX_CMD_MASK;
5212 #else
5213 base_op = op;
5214 #endif
5215 switch (base_op) {
5216 case FUTEX_WAIT:
5217 case FUTEX_WAIT_BITSET:
5218 if (timeout) {
5219 pts = &ts;
5220 target_to_host_timespec(pts, timeout);
5221 } else {
5222 pts = NULL;
5224 return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
5225 pts, NULL, val3));
5226 case FUTEX_WAKE:
5227 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
5228 case FUTEX_FD:
5229 return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
5230 case FUTEX_REQUEUE:
5231 case FUTEX_CMP_REQUEUE:
5232 case FUTEX_WAKE_OP:
5233 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
5234 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
5235 But the prototype takes a `struct timespec *'; insert casts
5236 to satisfy the compiler. We do not need to tswap TIMEOUT
5237 since it's not compared to guest memory. */
5238 pts = (struct timespec *)(uintptr_t) timeout;
5239 return get_errno(sys_futex(g2h(uaddr), op, val, pts,
5240 g2h(uaddr2),
5241 (base_op == FUTEX_CMP_REQUEUE
5242 ? tswap32(val3)
5243 : val3)));
5244 default:
5245 return -TARGET_ENOSYS;
5249 /* Map host to target signal numbers for the wait family of syscalls.
5250 Assume all other status bits are the same. */
5251 int host_to_target_waitstatus(int status)
5253 if (WIFSIGNALED(status)) {
5254 return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
5256 if (WIFSTOPPED(status)) {
5257 return (host_to_target_signal(WSTOPSIG(status)) << 8)
5258 | (status & 0xff);
5260 return status;
5263 static int open_self_cmdline(void *cpu_env, int fd)
5265 int fd_orig = -1;
5266 bool word_skipped = false;
5268 fd_orig = open("/proc/self/cmdline", O_RDONLY);
5269 if (fd_orig < 0) {
5270 return fd_orig;
5273 while (true) {
5274 ssize_t nb_read;
5275 char buf[128];
5276 char *cp_buf = buf;
5278 nb_read = read(fd_orig, buf, sizeof(buf));
5279 if (nb_read < 0) {
5280 fd_orig = close(fd_orig);
5281 return -1;
5282 } else if (nb_read == 0) {
5283 break;
5286 if (!word_skipped) {
5287 /* Skip the first string, which is the path to qemu-*-static
5288 instead of the actual command. */
5289 cp_buf = memchr(buf, 0, sizeof(buf));
5290 if (cp_buf) {
5291 /* Null byte found, skip one string */
5292 cp_buf++;
5293 nb_read -= cp_buf - buf;
5294 word_skipped = true;
5298 if (word_skipped) {
5299 if (write(fd, cp_buf, nb_read) != nb_read) {
5300 close(fd_orig);
5301 return -1;
5306 return close(fd_orig);
5309 static int open_self_maps(void *cpu_env, int fd)
5311 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
5312 TaskState *ts = cpu->opaque;
5313 FILE *fp;
5314 char *line = NULL;
5315 size_t len = 0;
5316 ssize_t read;
5318 fp = fopen("/proc/self/maps", "r");
5319 if (fp == NULL) {
5320 return -EACCES;
5323 while ((read = getline(&line, &len, fp)) != -1) {
5324 int fields, dev_maj, dev_min, inode;
5325 uint64_t min, max, offset;
5326 char flag_r, flag_w, flag_x, flag_p;
5327 char path[512] = "";
5328 fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
5329 " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
5330 &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
5332 if ((fields < 10) || (fields > 11)) {
5333 continue;
5335 if (h2g_valid(min)) {
5336 int flags = page_get_flags(h2g(min));
5337 max = h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_MAX);
5338 if (page_check_range(h2g(min), max - min, flags) == -1) {
5339 continue;
5341 if (h2g(min) == ts->info->stack_limit) {
5342 pstrcpy(path, sizeof(path), " [stack]");
5344 dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
5345 " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n",
5346 h2g(min), h2g(max - 1) + 1, flag_r, flag_w,
5347 flag_x, flag_p, offset, dev_maj, dev_min, inode,
5348 path[0] ? " " : "", path);
5352 free(line);
5353 fclose(fp);
5355 return 0;
5358 static int open_self_stat(void *cpu_env, int fd)
5360 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
5361 TaskState *ts = cpu->opaque;
5362 abi_ulong start_stack = ts->info->start_stack;
5363 int i;
5365 for (i = 0; i < 44; i++) {
5366 char buf[128];
5367 int len;
5368 uint64_t val = 0;
5370 if (i == 0) {
5371 /* pid */
5372 val = getpid();
5373 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5374 } else if (i == 1) {
5375 /* app name */
5376 snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
5377 } else if (i == 27) {
5378 /* stack bottom */
5379 val = start_stack;
5380 snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
5381 } else {
5382 /* for the rest, there is MasterCard */
5383 snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
5386 len = strlen(buf);
5387 if (write(fd, buf, len) != len) {
5388 return -1;
5392 return 0;
5395 static int open_self_auxv(void *cpu_env, int fd)
5397 CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
5398 TaskState *ts = cpu->opaque;
5399 abi_ulong auxv = ts->info->saved_auxv;
5400 abi_ulong len = ts->info->auxv_len;
5401 char *ptr;
5404 * Auxiliary vector is stored in target process stack.
5405 * read in whole auxv vector and copy it to file
5407 ptr = lock_user(VERIFY_READ, auxv, len, 0);
5408 if (ptr != NULL) {
5409 while (len > 0) {
5410 ssize_t r;
5411 r = write(fd, ptr, len);
5412 if (r <= 0) {
5413 break;
5415 len -= r;
5416 ptr += r;
5418 lseek(fd, 0, SEEK_SET);
5419 unlock_user(ptr, auxv, len);
5422 return 0;
5425 static int is_proc_myself(const char *filename, const char *entry)
5427 if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
5428 filename += strlen("/proc/");
5429 if (!strncmp(filename, "self/", strlen("self/"))) {
5430 filename += strlen("self/");
5431 } else if (*filename >= '1' && *filename <= '9') {
5432 char myself[80];
5433 snprintf(myself, sizeof(myself), "%d/", getpid());
5434 if (!strncmp(filename, myself, strlen(myself))) {
5435 filename += strlen(myself);
5436 } else {
5437 return 0;
5439 } else {
5440 return 0;
5442 if (!strcmp(filename, entry)) {
5443 return 1;
5446 return 0;
5449 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5450 static int is_proc(const char *filename, const char *entry)
5452 return strcmp(filename, entry) == 0;
5455 static int open_net_route(void *cpu_env, int fd)
5457 FILE *fp;
5458 char *line = NULL;
5459 size_t len = 0;
5460 ssize_t read;
5462 fp = fopen("/proc/net/route", "r");
5463 if (fp == NULL) {
5464 return -EACCES;
5467 /* read header */
5469 read = getline(&line, &len, fp);
5470 dprintf(fd, "%s", line);
5472 /* read routes */
5474 while ((read = getline(&line, &len, fp)) != -1) {
5475 char iface[16];
5476 uint32_t dest, gw, mask;
5477 unsigned int flags, refcnt, use, metric, mtu, window, irtt;
5478 sscanf(line, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5479 iface, &dest, &gw, &flags, &refcnt, &use, &metric,
5480 &mask, &mtu, &window, &irtt);
5481 dprintf(fd, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5482 iface, tswap32(dest), tswap32(gw), flags, refcnt, use,
5483 metric, tswap32(mask), mtu, window, irtt);
5486 free(line);
5487 fclose(fp);
5489 return 0;
5491 #endif
5493 static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, mode_t mode)
5495 struct fake_open {
5496 const char *filename;
5497 int (*fill)(void *cpu_env, int fd);
5498 int (*cmp)(const char *s1, const char *s2);
5500 const struct fake_open *fake_open;
5501 static const struct fake_open fakes[] = {
5502 { "maps", open_self_maps, is_proc_myself },
5503 { "stat", open_self_stat, is_proc_myself },
5504 { "auxv", open_self_auxv, is_proc_myself },
5505 { "cmdline", open_self_cmdline, is_proc_myself },
5506 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5507 { "/proc/net/route", open_net_route, is_proc },
5508 #endif
5509 { NULL, NULL, NULL }
5512 if (is_proc_myself(pathname, "exe")) {
5513 int execfd = qemu_getauxval(AT_EXECFD);
5514 return execfd ? execfd : get_errno(sys_openat(dirfd, exec_path, flags, mode));
5517 for (fake_open = fakes; fake_open->filename; fake_open++) {
5518 if (fake_open->cmp(pathname, fake_open->filename)) {
5519 break;
5523 if (fake_open->filename) {
5524 const char *tmpdir;
5525 char filename[PATH_MAX];
5526 int fd, r;
5528 /* create temporary file to map stat to */
5529 tmpdir = getenv("TMPDIR");
5530 if (!tmpdir)
5531 tmpdir = "/tmp";
5532 snprintf(filename, sizeof(filename), "%s/qemu-open.XXXXXX", tmpdir);
5533 fd = mkstemp(filename);
5534 if (fd < 0) {
5535 return fd;
5537 unlink(filename);
5539 if ((r = fake_open->fill(cpu_env, fd))) {
5540 close(fd);
5541 return r;
5543 lseek(fd, 0, SEEK_SET);
5545 return fd;
5548 return get_errno(sys_openat(dirfd, path(pathname), flags, mode));
5551 #define TIMER_MAGIC 0x0caf0000
5552 #define TIMER_MAGIC_MASK 0xffff0000
5554 /* Convert QEMU provided timer ID back to internal 16bit index format */
5555 static target_timer_t get_timer_id(abi_long arg)
5557 target_timer_t timerid = arg;
5559 if ((timerid & TIMER_MAGIC_MASK) != TIMER_MAGIC) {
5560 return -TARGET_EINVAL;
5563 timerid &= 0xffff;
5565 if (timerid >= ARRAY_SIZE(g_posix_timers)) {
5566 return -TARGET_EINVAL;
5569 return timerid;
5572 /* do_syscall() should always have a single exit point at the end so
5573 that actions, such as logging of syscall results, can be performed.
5574 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5575 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5576 abi_long arg2, abi_long arg3, abi_long arg4,
5577 abi_long arg5, abi_long arg6, abi_long arg7,
5578 abi_long arg8)
5580 CPUState *cpu = ENV_GET_CPU(cpu_env);
5581 abi_long ret;
5582 struct stat st;
5583 struct statfs stfs;
5584 void *p;
5586 #ifdef DEBUG
5587 gemu_log("syscall %d", num);
5588 #endif
5589 if(do_strace)
5590 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
5592 switch(num) {
5593 case TARGET_NR_exit:
5594 /* In old applications this may be used to implement _exit(2).
5595 However in threaded applictions it is used for thread termination,
5596 and _exit_group is used for application termination.
5597 Do thread termination if we have more then one thread. */
5598 /* FIXME: This probably breaks if a signal arrives. We should probably
5599 be disabling signals. */
5600 if (CPU_NEXT(first_cpu)) {
5601 TaskState *ts;
5603 cpu_list_lock();
5604 /* Remove the CPU from the list. */
5605 QTAILQ_REMOVE(&cpus, cpu, node);
5606 cpu_list_unlock();
5607 ts = cpu->opaque;
5608 if (ts->child_tidptr) {
5609 put_user_u32(0, ts->child_tidptr);
5610 sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
5611 NULL, NULL, 0);
5613 thread_cpu = NULL;
5614 object_unref(OBJECT(cpu));
5615 g_free(ts);
5616 pthread_exit(NULL);
5618 #ifdef TARGET_GPROF
5619 _mcleanup();
5620 #endif
5621 gdb_exit(cpu_env, arg1);
5622 _exit(arg1);
5623 ret = 0; /* avoid warning */
5624 break;
5625 case TARGET_NR_read:
5626 if (arg3 == 0)
5627 ret = 0;
5628 else {
5629 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
5630 goto efault;
5631 ret = get_errno(read(arg1, p, arg3));
5632 unlock_user(p, arg2, ret);
5634 break;
5635 case TARGET_NR_write:
5636 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
5637 goto efault;
5638 ret = get_errno(write(arg1, p, arg3));
5639 unlock_user(p, arg2, 0);
5640 break;
5641 case TARGET_NR_open:
5642 if (!(p = lock_user_string(arg1)))
5643 goto efault;
5644 ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
5645 target_to_host_bitmask(arg2, fcntl_flags_tbl),
5646 arg3));
5647 unlock_user(p, arg1, 0);
5648 break;
5649 case TARGET_NR_openat:
5650 if (!(p = lock_user_string(arg2)))
5651 goto efault;
5652 ret = get_errno(do_openat(cpu_env, arg1, p,
5653 target_to_host_bitmask(arg3, fcntl_flags_tbl),
5654 arg4));
5655 unlock_user(p, arg2, 0);
5656 break;
5657 case TARGET_NR_close:
5658 ret = get_errno(close(arg1));
5659 break;
5660 case TARGET_NR_brk:
5661 ret = do_brk(arg1);
5662 break;
5663 case TARGET_NR_fork:
5664 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
5665 break;
5666 #ifdef TARGET_NR_waitpid
5667 case TARGET_NR_waitpid:
5669 int status;
5670 ret = get_errno(waitpid(arg1, &status, arg3));
5671 if (!is_error(ret) && arg2 && ret
5672 && put_user_s32(host_to_target_waitstatus(status), arg2))
5673 goto efault;
5675 break;
5676 #endif
5677 #ifdef TARGET_NR_waitid
5678 case TARGET_NR_waitid:
5680 siginfo_t info;
5681 info.si_pid = 0;
5682 ret = get_errno(waitid(arg1, arg2, &info, arg4));
5683 if (!is_error(ret) && arg3 && info.si_pid != 0) {
5684 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
5685 goto efault;
5686 host_to_target_siginfo(p, &info);
5687 unlock_user(p, arg3, sizeof(target_siginfo_t));
5690 break;
5691 #endif
5692 #ifdef TARGET_NR_creat /* not on alpha */
5693 case TARGET_NR_creat:
5694 if (!(p = lock_user_string(arg1)))
5695 goto efault;
5696 ret = get_errno(creat(p, arg2));
5697 unlock_user(p, arg1, 0);
5698 break;
5699 #endif
5700 case TARGET_NR_link:
5702 void * p2;
5703 p = lock_user_string(arg1);
5704 p2 = lock_user_string(arg2);
5705 if (!p || !p2)
5706 ret = -TARGET_EFAULT;
5707 else
5708 ret = get_errno(link(p, p2));
5709 unlock_user(p2, arg2, 0);
5710 unlock_user(p, arg1, 0);
5712 break;
5713 #if defined(TARGET_NR_linkat)
5714 case TARGET_NR_linkat:
5716 void * p2 = NULL;
5717 if (!arg2 || !arg4)
5718 goto efault;
5719 p = lock_user_string(arg2);
5720 p2 = lock_user_string(arg4);
5721 if (!p || !p2)
5722 ret = -TARGET_EFAULT;
5723 else
5724 ret = get_errno(linkat(arg1, p, arg3, p2, arg5));
5725 unlock_user(p, arg2, 0);
5726 unlock_user(p2, arg4, 0);
5728 break;
5729 #endif
5730 case TARGET_NR_unlink:
5731 if (!(p = lock_user_string(arg1)))
5732 goto efault;
5733 ret = get_errno(unlink(p));
5734 unlock_user(p, arg1, 0);
5735 break;
5736 #if defined(TARGET_NR_unlinkat)
5737 case TARGET_NR_unlinkat:
5738 if (!(p = lock_user_string(arg2)))
5739 goto efault;
5740 ret = get_errno(unlinkat(arg1, p, arg3));
5741 unlock_user(p, arg2, 0);
5742 break;
5743 #endif
5744 case TARGET_NR_execve:
5746 char **argp, **envp;
5747 int argc, envc;
5748 abi_ulong gp;
5749 abi_ulong guest_argp;
5750 abi_ulong guest_envp;
5751 abi_ulong addr;
5752 char **q;
5753 int total_size = 0;
5755 argc = 0;
5756 guest_argp = arg2;
5757 for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
5758 if (get_user_ual(addr, gp))
5759 goto efault;
5760 if (!addr)
5761 break;
5762 argc++;
5764 envc = 0;
5765 guest_envp = arg3;
5766 for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
5767 if (get_user_ual(addr, gp))
5768 goto efault;
5769 if (!addr)
5770 break;
5771 envc++;
5774 argp = alloca((argc + 1) * sizeof(void *));
5775 envp = alloca((envc + 1) * sizeof(void *));
5777 for (gp = guest_argp, q = argp; gp;
5778 gp += sizeof(abi_ulong), q++) {
5779 if (get_user_ual(addr, gp))
5780 goto execve_efault;
5781 if (!addr)
5782 break;
5783 if (!(*q = lock_user_string(addr)))
5784 goto execve_efault;
5785 total_size += strlen(*q) + 1;
5787 *q = NULL;
5789 for (gp = guest_envp, q = envp; gp;
5790 gp += sizeof(abi_ulong), q++) {
5791 if (get_user_ual(addr, gp))
5792 goto execve_efault;
5793 if (!addr)
5794 break;
5795 if (!(*q = lock_user_string(addr)))
5796 goto execve_efault;
5797 total_size += strlen(*q) + 1;
5799 *q = NULL;
5801 /* This case will not be caught by the host's execve() if its
5802 page size is bigger than the target's. */
5803 if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) {
5804 ret = -TARGET_E2BIG;
5805 goto execve_end;
5807 if (!(p = lock_user_string(arg1)))
5808 goto execve_efault;
5809 ret = get_errno(execve(p, argp, envp));
5810 unlock_user(p, arg1, 0);
5812 goto execve_end;
5814 execve_efault:
5815 ret = -TARGET_EFAULT;
5817 execve_end:
5818 for (gp = guest_argp, q = argp; *q;
5819 gp += sizeof(abi_ulong), q++) {
5820 if (get_user_ual(addr, gp)
5821 || !addr)
5822 break;
5823 unlock_user(*q, addr, 0);
5825 for (gp = guest_envp, q = envp; *q;
5826 gp += sizeof(abi_ulong), q++) {
5827 if (get_user_ual(addr, gp)
5828 || !addr)
5829 break;
5830 unlock_user(*q, addr, 0);
5833 break;
5834 case TARGET_NR_chdir:
5835 if (!(p = lock_user_string(arg1)))
5836 goto efault;
5837 ret = get_errno(chdir(p));
5838 unlock_user(p, arg1, 0);
5839 break;
5840 #ifdef TARGET_NR_time
5841 case TARGET_NR_time:
5843 time_t host_time;
5844 ret = get_errno(time(&host_time));
5845 if (!is_error(ret)
5846 && arg1
5847 && put_user_sal(host_time, arg1))
5848 goto efault;
5850 break;
5851 #endif
5852 case TARGET_NR_mknod:
5853 if (!(p = lock_user_string(arg1)))
5854 goto efault;
5855 ret = get_errno(mknod(p, arg2, arg3));
5856 unlock_user(p, arg1, 0);
5857 break;
5858 #if defined(TARGET_NR_mknodat)
5859 case TARGET_NR_mknodat:
5860 if (!(p = lock_user_string(arg2)))
5861 goto efault;
5862 ret = get_errno(mknodat(arg1, p, arg3, arg4));
5863 unlock_user(p, arg2, 0);
5864 break;
5865 #endif
5866 case TARGET_NR_chmod:
5867 if (!(p = lock_user_string(arg1)))
5868 goto efault;
5869 ret = get_errno(chmod(p, arg2));
5870 unlock_user(p, arg1, 0);
5871 break;
5872 #ifdef TARGET_NR_break
5873 case TARGET_NR_break:
5874 goto unimplemented;
5875 #endif
5876 #ifdef TARGET_NR_oldstat
5877 case TARGET_NR_oldstat:
5878 goto unimplemented;
5879 #endif
5880 case TARGET_NR_lseek:
5881 ret = get_errno(lseek(arg1, arg2, arg3));
5882 break;
5883 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5884 /* Alpha specific */
5885 case TARGET_NR_getxpid:
5886 ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
5887 ret = get_errno(getpid());
5888 break;
5889 #endif
5890 #ifdef TARGET_NR_getpid
5891 case TARGET_NR_getpid:
5892 ret = get_errno(getpid());
5893 break;
5894 #endif
5895 case TARGET_NR_mount:
5897 /* need to look at the data field */
5898 void *p2, *p3;
5900 if (arg1) {
5901 p = lock_user_string(arg1);
5902 if (!p) {
5903 goto efault;
5905 } else {
5906 p = NULL;
5909 p2 = lock_user_string(arg2);
5910 if (!p2) {
5911 if (arg1) {
5912 unlock_user(p, arg1, 0);
5914 goto efault;
5917 if (arg3) {
5918 p3 = lock_user_string(arg3);
5919 if (!p3) {
5920 if (arg1) {
5921 unlock_user(p, arg1, 0);
5923 unlock_user(p2, arg2, 0);
5924 goto efault;
5926 } else {
5927 p3 = NULL;
5930 /* FIXME - arg5 should be locked, but it isn't clear how to
5931 * do that since it's not guaranteed to be a NULL-terminated
5932 * string.
5934 if (!arg5) {
5935 ret = mount(p, p2, p3, (unsigned long)arg4, NULL);
5936 } else {
5937 ret = mount(p, p2, p3, (unsigned long)arg4, g2h(arg5));
5939 ret = get_errno(ret);
5941 if (arg1) {
5942 unlock_user(p, arg1, 0);
5944 unlock_user(p2, arg2, 0);
5945 if (arg3) {
5946 unlock_user(p3, arg3, 0);
5949 break;
5950 #ifdef TARGET_NR_umount
5951 case TARGET_NR_umount:
5952 if (!(p = lock_user_string(arg1)))
5953 goto efault;
5954 ret = get_errno(umount(p));
5955 unlock_user(p, arg1, 0);
5956 break;
5957 #endif
5958 #ifdef TARGET_NR_stime /* not on alpha */
5959 case TARGET_NR_stime:
5961 time_t host_time;
5962 if (get_user_sal(host_time, arg1))
5963 goto efault;
5964 ret = get_errno(stime(&host_time));
5966 break;
5967 #endif
5968 case TARGET_NR_ptrace:
5969 goto unimplemented;
5970 #ifdef TARGET_NR_alarm /* not on alpha */
5971 case TARGET_NR_alarm:
5972 ret = alarm(arg1);
5973 break;
5974 #endif
5975 #ifdef TARGET_NR_oldfstat
5976 case TARGET_NR_oldfstat:
5977 goto unimplemented;
5978 #endif
5979 #ifdef TARGET_NR_pause /* not on alpha */
5980 case TARGET_NR_pause:
5981 ret = get_errno(pause());
5982 break;
5983 #endif
5984 #ifdef TARGET_NR_utime
5985 case TARGET_NR_utime:
5987 struct utimbuf tbuf, *host_tbuf;
5988 struct target_utimbuf *target_tbuf;
5989 if (arg2) {
5990 if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
5991 goto efault;
5992 tbuf.actime = tswapal(target_tbuf->actime);
5993 tbuf.modtime = tswapal(target_tbuf->modtime);
5994 unlock_user_struct(target_tbuf, arg2, 0);
5995 host_tbuf = &tbuf;
5996 } else {
5997 host_tbuf = NULL;
5999 if (!(p = lock_user_string(arg1)))
6000 goto efault;
6001 ret = get_errno(utime(p, host_tbuf));
6002 unlock_user(p, arg1, 0);
6004 break;
6005 #endif
6006 case TARGET_NR_utimes:
6008 struct timeval *tvp, tv[2];
6009 if (arg2) {
6010 if (copy_from_user_timeval(&tv[0], arg2)
6011 || copy_from_user_timeval(&tv[1],
6012 arg2 + sizeof(struct target_timeval)))
6013 goto efault;
6014 tvp = tv;
6015 } else {
6016 tvp = NULL;
6018 if (!(p = lock_user_string(arg1)))
6019 goto efault;
6020 ret = get_errno(utimes(p, tvp));
6021 unlock_user(p, arg1, 0);
6023 break;
6024 #if defined(TARGET_NR_futimesat)
6025 case TARGET_NR_futimesat:
6027 struct timeval *tvp, tv[2];
6028 if (arg3) {
6029 if (copy_from_user_timeval(&tv[0], arg3)
6030 || copy_from_user_timeval(&tv[1],
6031 arg3 + sizeof(struct target_timeval)))
6032 goto efault;
6033 tvp = tv;
6034 } else {
6035 tvp = NULL;
6037 if (!(p = lock_user_string(arg2)))
6038 goto efault;
6039 ret = get_errno(futimesat(arg1, path(p), tvp));
6040 unlock_user(p, arg2, 0);
6042 break;
6043 #endif
6044 #ifdef TARGET_NR_stty
6045 case TARGET_NR_stty:
6046 goto unimplemented;
6047 #endif
6048 #ifdef TARGET_NR_gtty
6049 case TARGET_NR_gtty:
6050 goto unimplemented;
6051 #endif
6052 case TARGET_NR_access:
6053 if (!(p = lock_user_string(arg1)))
6054 goto efault;
6055 ret = get_errno(access(path(p), arg2));
6056 unlock_user(p, arg1, 0);
6057 break;
6058 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
6059 case TARGET_NR_faccessat:
6060 if (!(p = lock_user_string(arg2)))
6061 goto efault;
6062 ret = get_errno(faccessat(arg1, p, arg3, 0));
6063 unlock_user(p, arg2, 0);
6064 break;
6065 #endif
6066 #ifdef TARGET_NR_nice /* not on alpha */
6067 case TARGET_NR_nice:
6068 ret = get_errno(nice(arg1));
6069 break;
6070 #endif
6071 #ifdef TARGET_NR_ftime
6072 case TARGET_NR_ftime:
6073 goto unimplemented;
6074 #endif
6075 case TARGET_NR_sync:
6076 sync();
6077 ret = 0;
6078 break;
6079 case TARGET_NR_kill:
6080 ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
6081 break;
6082 case TARGET_NR_rename:
6084 void *p2;
6085 p = lock_user_string(arg1);
6086 p2 = lock_user_string(arg2);
6087 if (!p || !p2)
6088 ret = -TARGET_EFAULT;
6089 else
6090 ret = get_errno(rename(p, p2));
6091 unlock_user(p2, arg2, 0);
6092 unlock_user(p, arg1, 0);
6094 break;
6095 #if defined(TARGET_NR_renameat)
6096 case TARGET_NR_renameat:
6098 void *p2;
6099 p = lock_user_string(arg2);
6100 p2 = lock_user_string(arg4);
6101 if (!p || !p2)
6102 ret = -TARGET_EFAULT;
6103 else
6104 ret = get_errno(renameat(arg1, p, arg3, p2));
6105 unlock_user(p2, arg4, 0);
6106 unlock_user(p, arg2, 0);
6108 break;
6109 #endif
6110 case TARGET_NR_mkdir:
6111 if (!(p = lock_user_string(arg1)))
6112 goto efault;
6113 ret = get_errno(mkdir(p, arg2));
6114 unlock_user(p, arg1, 0);
6115 break;
6116 #if defined(TARGET_NR_mkdirat)
6117 case TARGET_NR_mkdirat:
6118 if (!(p = lock_user_string(arg2)))
6119 goto efault;
6120 ret = get_errno(mkdirat(arg1, p, arg3));
6121 unlock_user(p, arg2, 0);
6122 break;
6123 #endif
6124 case TARGET_NR_rmdir:
6125 if (!(p = lock_user_string(arg1)))
6126 goto efault;
6127 ret = get_errno(rmdir(p));
6128 unlock_user(p, arg1, 0);
6129 break;
6130 case TARGET_NR_dup:
6131 ret = get_errno(dup(arg1));
6132 break;
6133 case TARGET_NR_pipe:
6134 ret = do_pipe(cpu_env, arg1, 0, 0);
6135 break;
6136 #ifdef TARGET_NR_pipe2
6137 case TARGET_NR_pipe2:
6138 ret = do_pipe(cpu_env, arg1,
6139 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1);
6140 break;
6141 #endif
6142 case TARGET_NR_times:
6144 struct target_tms *tmsp;
6145 struct tms tms;
6146 ret = get_errno(times(&tms));
6147 if (arg1) {
6148 tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
6149 if (!tmsp)
6150 goto efault;
6151 tmsp->tms_utime = tswapal(host_to_target_clock_t(tms.tms_utime));
6152 tmsp->tms_stime = tswapal(host_to_target_clock_t(tms.tms_stime));
6153 tmsp->tms_cutime = tswapal(host_to_target_clock_t(tms.tms_cutime));
6154 tmsp->tms_cstime = tswapal(host_to_target_clock_t(tms.tms_cstime));
6156 if (!is_error(ret))
6157 ret = host_to_target_clock_t(ret);
6159 break;
6160 #ifdef TARGET_NR_prof
6161 case TARGET_NR_prof:
6162 goto unimplemented;
6163 #endif
6164 #ifdef TARGET_NR_signal
6165 case TARGET_NR_signal:
6166 goto unimplemented;
6167 #endif
6168 case TARGET_NR_acct:
6169 if (arg1 == 0) {
6170 ret = get_errno(acct(NULL));
6171 } else {
6172 if (!(p = lock_user_string(arg1)))
6173 goto efault;
6174 ret = get_errno(acct(path(p)));
6175 unlock_user(p, arg1, 0);
6177 break;
6178 #ifdef TARGET_NR_umount2
6179 case TARGET_NR_umount2:
6180 if (!(p = lock_user_string(arg1)))
6181 goto efault;
6182 ret = get_errno(umount2(p, arg2));
6183 unlock_user(p, arg1, 0);
6184 break;
6185 #endif
6186 #ifdef TARGET_NR_lock
6187 case TARGET_NR_lock:
6188 goto unimplemented;
6189 #endif
6190 case TARGET_NR_ioctl:
6191 ret = do_ioctl(arg1, arg2, arg3);
6192 break;
6193 case TARGET_NR_fcntl:
6194 ret = do_fcntl(arg1, arg2, arg3);
6195 break;
6196 #ifdef TARGET_NR_mpx
6197 case TARGET_NR_mpx:
6198 goto unimplemented;
6199 #endif
6200 case TARGET_NR_setpgid:
6201 ret = get_errno(setpgid(arg1, arg2));
6202 break;
6203 #ifdef TARGET_NR_ulimit
6204 case TARGET_NR_ulimit:
6205 goto unimplemented;
6206 #endif
6207 #ifdef TARGET_NR_oldolduname
6208 case TARGET_NR_oldolduname:
6209 goto unimplemented;
6210 #endif
6211 case TARGET_NR_umask:
6212 ret = get_errno(umask(arg1));
6213 break;
6214 case TARGET_NR_chroot:
6215 if (!(p = lock_user_string(arg1)))
6216 goto efault;
6217 ret = get_errno(chroot(p));
6218 unlock_user(p, arg1, 0);
6219 break;
6220 case TARGET_NR_ustat:
6221 goto unimplemented;
6222 case TARGET_NR_dup2:
6223 ret = get_errno(dup2(arg1, arg2));
6224 break;
6225 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
6226 case TARGET_NR_dup3:
6227 ret = get_errno(dup3(arg1, arg2, arg3));
6228 break;
6229 #endif
6230 #ifdef TARGET_NR_getppid /* not on alpha */
6231 case TARGET_NR_getppid:
6232 ret = get_errno(getppid());
6233 break;
6234 #endif
6235 case TARGET_NR_getpgrp:
6236 ret = get_errno(getpgrp());
6237 break;
6238 case TARGET_NR_setsid:
6239 ret = get_errno(setsid());
6240 break;
6241 #ifdef TARGET_NR_sigaction
6242 case TARGET_NR_sigaction:
6244 #if defined(TARGET_ALPHA)
6245 struct target_sigaction act, oact, *pact = 0;
6246 struct target_old_sigaction *old_act;
6247 if (arg2) {
6248 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
6249 goto efault;
6250 act._sa_handler = old_act->_sa_handler;
6251 target_siginitset(&act.sa_mask, old_act->sa_mask);
6252 act.sa_flags = old_act->sa_flags;
6253 act.sa_restorer = 0;
6254 unlock_user_struct(old_act, arg2, 0);
6255 pact = &act;
6257 ret = get_errno(do_sigaction(arg1, pact, &oact));
6258 if (!is_error(ret) && arg3) {
6259 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
6260 goto efault;
6261 old_act->_sa_handler = oact._sa_handler;
6262 old_act->sa_mask = oact.sa_mask.sig[0];
6263 old_act->sa_flags = oact.sa_flags;
6264 unlock_user_struct(old_act, arg3, 1);
6266 #elif defined(TARGET_MIPS)
6267 struct target_sigaction act, oact, *pact, *old_act;
6269 if (arg2) {
6270 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
6271 goto efault;
6272 act._sa_handler = old_act->_sa_handler;
6273 target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
6274 act.sa_flags = old_act->sa_flags;
6275 unlock_user_struct(old_act, arg2, 0);
6276 pact = &act;
6277 } else {
6278 pact = NULL;
6281 ret = get_errno(do_sigaction(arg1, pact, &oact));
6283 if (!is_error(ret) && arg3) {
6284 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
6285 goto efault;
6286 old_act->_sa_handler = oact._sa_handler;
6287 old_act->sa_flags = oact.sa_flags;
6288 old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
6289 old_act->sa_mask.sig[1] = 0;
6290 old_act->sa_mask.sig[2] = 0;
6291 old_act->sa_mask.sig[3] = 0;
6292 unlock_user_struct(old_act, arg3, 1);
6294 #else
6295 struct target_old_sigaction *old_act;
6296 struct target_sigaction act, oact, *pact;
6297 if (arg2) {
6298 if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
6299 goto efault;
6300 act._sa_handler = old_act->_sa_handler;
6301 target_siginitset(&act.sa_mask, old_act->sa_mask);
6302 act.sa_flags = old_act->sa_flags;
6303 act.sa_restorer = old_act->sa_restorer;
6304 unlock_user_struct(old_act, arg2, 0);
6305 pact = &act;
6306 } else {
6307 pact = NULL;
6309 ret = get_errno(do_sigaction(arg1, pact, &oact));
6310 if (!is_error(ret) && arg3) {
6311 if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
6312 goto efault;
6313 old_act->_sa_handler = oact._sa_handler;
6314 old_act->sa_mask = oact.sa_mask.sig[0];
6315 old_act->sa_flags = oact.sa_flags;
6316 old_act->sa_restorer = oact.sa_restorer;
6317 unlock_user_struct(old_act, arg3, 1);
6319 #endif
6321 break;
6322 #endif
6323 case TARGET_NR_rt_sigaction:
6325 #if defined(TARGET_ALPHA)
6326 struct target_sigaction act, oact, *pact = 0;
6327 struct target_rt_sigaction *rt_act;
6328 /* ??? arg4 == sizeof(sigset_t). */
6329 if (arg2) {
6330 if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
6331 goto efault;
6332 act._sa_handler = rt_act->_sa_handler;
6333 act.sa_mask = rt_act->sa_mask;
6334 act.sa_flags = rt_act->sa_flags;
6335 act.sa_restorer = arg5;
6336 unlock_user_struct(rt_act, arg2, 0);
6337 pact = &act;
6339 ret = get_errno(do_sigaction(arg1, pact, &oact));
6340 if (!is_error(ret) && arg3) {
6341 if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
6342 goto efault;
6343 rt_act->_sa_handler = oact._sa_handler;
6344 rt_act->sa_mask = oact.sa_mask;
6345 rt_act->sa_flags = oact.sa_flags;
6346 unlock_user_struct(rt_act, arg3, 1);
6348 #else
6349 struct target_sigaction *act;
6350 struct target_sigaction *oact;
6352 if (arg2) {
6353 if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
6354 goto efault;
6355 } else
6356 act = NULL;
6357 if (arg3) {
6358 if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
6359 ret = -TARGET_EFAULT;
6360 goto rt_sigaction_fail;
6362 } else
6363 oact = NULL;
6364 ret = get_errno(do_sigaction(arg1, act, oact));
6365 rt_sigaction_fail:
6366 if (act)
6367 unlock_user_struct(act, arg2, 0);
6368 if (oact)
6369 unlock_user_struct(oact, arg3, 1);
6370 #endif
6372 break;
6373 #ifdef TARGET_NR_sgetmask /* not on alpha */
6374 case TARGET_NR_sgetmask:
6376 sigset_t cur_set;
6377 abi_ulong target_set;
6378 do_sigprocmask(0, NULL, &cur_set);
6379 host_to_target_old_sigset(&target_set, &cur_set);
6380 ret = target_set;
6382 break;
6383 #endif
6384 #ifdef TARGET_NR_ssetmask /* not on alpha */
6385 case TARGET_NR_ssetmask:
6387 sigset_t set, oset, cur_set;
6388 abi_ulong target_set = arg1;
6389 do_sigprocmask(0, NULL, &cur_set);
6390 target_to_host_old_sigset(&set, &target_set);
6391 sigorset(&set, &set, &cur_set);
6392 do_sigprocmask(SIG_SETMASK, &set, &oset);
6393 host_to_target_old_sigset(&target_set, &oset);
6394 ret = target_set;
6396 break;
6397 #endif
6398 #ifdef TARGET_NR_sigprocmask
6399 case TARGET_NR_sigprocmask:
6401 #if defined(TARGET_ALPHA)
6402 sigset_t set, oldset;
6403 abi_ulong mask;
6404 int how;
6406 switch (arg1) {
6407 case TARGET_SIG_BLOCK:
6408 how = SIG_BLOCK;
6409 break;
6410 case TARGET_SIG_UNBLOCK:
6411 how = SIG_UNBLOCK;
6412 break;
6413 case TARGET_SIG_SETMASK:
6414 how = SIG_SETMASK;
6415 break;
6416 default:
6417 ret = -TARGET_EINVAL;
6418 goto fail;
6420 mask = arg2;
6421 target_to_host_old_sigset(&set, &mask);
6423 ret = get_errno(do_sigprocmask(how, &set, &oldset));
6424 if (!is_error(ret)) {
6425 host_to_target_old_sigset(&mask, &oldset);
6426 ret = mask;
6427 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
6429 #else
6430 sigset_t set, oldset, *set_ptr;
6431 int how;
6433 if (arg2) {
6434 switch (arg1) {
6435 case TARGET_SIG_BLOCK:
6436 how = SIG_BLOCK;
6437 break;
6438 case TARGET_SIG_UNBLOCK:
6439 how = SIG_UNBLOCK;
6440 break;
6441 case TARGET_SIG_SETMASK:
6442 how = SIG_SETMASK;
6443 break;
6444 default:
6445 ret = -TARGET_EINVAL;
6446 goto fail;
6448 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6449 goto efault;
6450 target_to_host_old_sigset(&set, p);
6451 unlock_user(p, arg2, 0);
6452 set_ptr = &set;
6453 } else {
6454 how = 0;
6455 set_ptr = NULL;
6457 ret = get_errno(do_sigprocmask(how, set_ptr, &oldset));
6458 if (!is_error(ret) && arg3) {
6459 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6460 goto efault;
6461 host_to_target_old_sigset(p, &oldset);
6462 unlock_user(p, arg3, sizeof(target_sigset_t));
6464 #endif
6466 break;
6467 #endif
6468 case TARGET_NR_rt_sigprocmask:
6470 int how = arg1;
6471 sigset_t set, oldset, *set_ptr;
6473 if (arg2) {
6474 switch(how) {
6475 case TARGET_SIG_BLOCK:
6476 how = SIG_BLOCK;
6477 break;
6478 case TARGET_SIG_UNBLOCK:
6479 how = SIG_UNBLOCK;
6480 break;
6481 case TARGET_SIG_SETMASK:
6482 how = SIG_SETMASK;
6483 break;
6484 default:
6485 ret = -TARGET_EINVAL;
6486 goto fail;
6488 if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
6489 goto efault;
6490 target_to_host_sigset(&set, p);
6491 unlock_user(p, arg2, 0);
6492 set_ptr = &set;
6493 } else {
6494 how = 0;
6495 set_ptr = NULL;
6497 ret = get_errno(do_sigprocmask(how, set_ptr, &oldset));
6498 if (!is_error(ret) && arg3) {
6499 if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
6500 goto efault;
6501 host_to_target_sigset(p, &oldset);
6502 unlock_user(p, arg3, sizeof(target_sigset_t));
6505 break;
6506 #ifdef TARGET_NR_sigpending
6507 case TARGET_NR_sigpending:
6509 sigset_t set;
6510 ret = get_errno(sigpending(&set));
6511 if (!is_error(ret)) {
6512 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6513 goto efault;
6514 host_to_target_old_sigset(p, &set);
6515 unlock_user(p, arg1, sizeof(target_sigset_t));
6518 break;
6519 #endif
6520 case TARGET_NR_rt_sigpending:
6522 sigset_t set;
6523 ret = get_errno(sigpending(&set));
6524 if (!is_error(ret)) {
6525 if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
6526 goto efault;
6527 host_to_target_sigset(p, &set);
6528 unlock_user(p, arg1, sizeof(target_sigset_t));
6531 break;
6532 #ifdef TARGET_NR_sigsuspend
6533 case TARGET_NR_sigsuspend:
6535 sigset_t set;
6536 #if defined(TARGET_ALPHA)
6537 abi_ulong mask = arg1;
6538 target_to_host_old_sigset(&set, &mask);
6539 #else
6540 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6541 goto efault;
6542 target_to_host_old_sigset(&set, p);
6543 unlock_user(p, arg1, 0);
6544 #endif
6545 ret = get_errno(sigsuspend(&set));
6547 break;
6548 #endif
6549 case TARGET_NR_rt_sigsuspend:
6551 sigset_t set;
6552 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6553 goto efault;
6554 target_to_host_sigset(&set, p);
6555 unlock_user(p, arg1, 0);
6556 ret = get_errno(sigsuspend(&set));
6558 break;
6559 case TARGET_NR_rt_sigtimedwait:
6561 sigset_t set;
6562 struct timespec uts, *puts;
6563 siginfo_t uinfo;
6565 if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
6566 goto efault;
6567 target_to_host_sigset(&set, p);
6568 unlock_user(p, arg1, 0);
6569 if (arg3) {
6570 puts = &uts;
6571 target_to_host_timespec(puts, arg3);
6572 } else {
6573 puts = NULL;
6575 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
6576 if (!is_error(ret)) {
6577 if (arg2) {
6578 p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t),
6580 if (!p) {
6581 goto efault;
6583 host_to_target_siginfo(p, &uinfo);
6584 unlock_user(p, arg2, sizeof(target_siginfo_t));
6586 ret = host_to_target_signal(ret);
6589 break;
6590 case TARGET_NR_rt_sigqueueinfo:
6592 siginfo_t uinfo;
6593 if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
6594 goto efault;
6595 target_to_host_siginfo(&uinfo, p);
6596 unlock_user(p, arg1, 0);
6597 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
6599 break;
6600 #ifdef TARGET_NR_sigreturn
6601 case TARGET_NR_sigreturn:
6602 /* NOTE: ret is eax, so not transcoding must be done */
6603 ret = do_sigreturn(cpu_env);
6604 break;
6605 #endif
6606 case TARGET_NR_rt_sigreturn:
6607 /* NOTE: ret is eax, so not transcoding must be done */
6608 ret = do_rt_sigreturn(cpu_env);
6609 break;
6610 case TARGET_NR_sethostname:
6611 if (!(p = lock_user_string(arg1)))
6612 goto efault;
6613 ret = get_errno(sethostname(p, arg2));
6614 unlock_user(p, arg1, 0);
6615 break;
6616 case TARGET_NR_setrlimit:
6618 int resource = target_to_host_resource(arg1);
6619 struct target_rlimit *target_rlim;
6620 struct rlimit rlim;
6621 if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
6622 goto efault;
6623 rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
6624 rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
6625 unlock_user_struct(target_rlim, arg2, 0);
6626 ret = get_errno(setrlimit(resource, &rlim));
6628 break;
6629 case TARGET_NR_getrlimit:
6631 int resource = target_to_host_resource(arg1);
6632 struct target_rlimit *target_rlim;
6633 struct rlimit rlim;
6635 ret = get_errno(getrlimit(resource, &rlim));
6636 if (!is_error(ret)) {
6637 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6638 goto efault;
6639 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6640 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6641 unlock_user_struct(target_rlim, arg2, 1);
6644 break;
6645 case TARGET_NR_getrusage:
6647 struct rusage rusage;
6648 ret = get_errno(getrusage(arg1, &rusage));
6649 if (!is_error(ret)) {
6650 ret = host_to_target_rusage(arg2, &rusage);
6653 break;
6654 case TARGET_NR_gettimeofday:
6656 struct timeval tv;
6657 ret = get_errno(gettimeofday(&tv, NULL));
6658 if (!is_error(ret)) {
6659 if (copy_to_user_timeval(arg1, &tv))
6660 goto efault;
6663 break;
6664 case TARGET_NR_settimeofday:
6666 struct timeval tv, *ptv = NULL;
6667 struct timezone tz, *ptz = NULL;
6669 if (arg1) {
6670 if (copy_from_user_timeval(&tv, arg1)) {
6671 goto efault;
6673 ptv = &tv;
6676 if (arg2) {
6677 if (copy_from_user_timezone(&tz, arg2)) {
6678 goto efault;
6680 ptz = &tz;
6683 ret = get_errno(settimeofday(ptv, ptz));
6685 break;
6686 #if defined(TARGET_NR_select)
6687 case TARGET_NR_select:
6688 #if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6689 ret = do_select(arg1, arg2, arg3, arg4, arg5);
6690 #else
6692 struct target_sel_arg_struct *sel;
6693 abi_ulong inp, outp, exp, tvp;
6694 long nsel;
6696 if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
6697 goto efault;
6698 nsel = tswapal(sel->n);
6699 inp = tswapal(sel->inp);
6700 outp = tswapal(sel->outp);
6701 exp = tswapal(sel->exp);
6702 tvp = tswapal(sel->tvp);
6703 unlock_user_struct(sel, arg1, 0);
6704 ret = do_select(nsel, inp, outp, exp, tvp);
6706 #endif
6707 break;
6708 #endif
6709 #ifdef TARGET_NR_pselect6
6710 case TARGET_NR_pselect6:
6712 abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
6713 fd_set rfds, wfds, efds;
6714 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
6715 struct timespec ts, *ts_ptr;
6718 * The 6th arg is actually two args smashed together,
6719 * so we cannot use the C library.
6721 sigset_t set;
6722 struct {
6723 sigset_t *set;
6724 size_t size;
6725 } sig, *sig_ptr;
6727 abi_ulong arg_sigset, arg_sigsize, *arg7;
6728 target_sigset_t *target_sigset;
6730 n = arg1;
6731 rfd_addr = arg2;
6732 wfd_addr = arg3;
6733 efd_addr = arg4;
6734 ts_addr = arg5;
6736 ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
6737 if (ret) {
6738 goto fail;
6740 ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
6741 if (ret) {
6742 goto fail;
6744 ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
6745 if (ret) {
6746 goto fail;
6750 * This takes a timespec, and not a timeval, so we cannot
6751 * use the do_select() helper ...
6753 if (ts_addr) {
6754 if (target_to_host_timespec(&ts, ts_addr)) {
6755 goto efault;
6757 ts_ptr = &ts;
6758 } else {
6759 ts_ptr = NULL;
6762 /* Extract the two packed args for the sigset */
6763 if (arg6) {
6764 sig_ptr = &sig;
6765 sig.size = _NSIG / 8;
6767 arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
6768 if (!arg7) {
6769 goto efault;
6771 arg_sigset = tswapal(arg7[0]);
6772 arg_sigsize = tswapal(arg7[1]);
6773 unlock_user(arg7, arg6, 0);
6775 if (arg_sigset) {
6776 sig.set = &set;
6777 if (arg_sigsize != sizeof(*target_sigset)) {
6778 /* Like the kernel, we enforce correct size sigsets */
6779 ret = -TARGET_EINVAL;
6780 goto fail;
6782 target_sigset = lock_user(VERIFY_READ, arg_sigset,
6783 sizeof(*target_sigset), 1);
6784 if (!target_sigset) {
6785 goto efault;
6787 target_to_host_sigset(&set, target_sigset);
6788 unlock_user(target_sigset, arg_sigset, 0);
6789 } else {
6790 sig.set = NULL;
6792 } else {
6793 sig_ptr = NULL;
6796 ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
6797 ts_ptr, sig_ptr));
6799 if (!is_error(ret)) {
6800 if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
6801 goto efault;
6802 if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
6803 goto efault;
6804 if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
6805 goto efault;
6807 if (ts_addr && host_to_target_timespec(ts_addr, &ts))
6808 goto efault;
6811 break;
6812 #endif
6813 case TARGET_NR_symlink:
6815 void *p2;
6816 p = lock_user_string(arg1);
6817 p2 = lock_user_string(arg2);
6818 if (!p || !p2)
6819 ret = -TARGET_EFAULT;
6820 else
6821 ret = get_errno(symlink(p, p2));
6822 unlock_user(p2, arg2, 0);
6823 unlock_user(p, arg1, 0);
6825 break;
6826 #if defined(TARGET_NR_symlinkat)
6827 case TARGET_NR_symlinkat:
6829 void *p2;
6830 p = lock_user_string(arg1);
6831 p2 = lock_user_string(arg3);
6832 if (!p || !p2)
6833 ret = -TARGET_EFAULT;
6834 else
6835 ret = get_errno(symlinkat(p, arg2, p2));
6836 unlock_user(p2, arg3, 0);
6837 unlock_user(p, arg1, 0);
6839 break;
6840 #endif
6841 #ifdef TARGET_NR_oldlstat
6842 case TARGET_NR_oldlstat:
6843 goto unimplemented;
6844 #endif
6845 case TARGET_NR_readlink:
6847 void *p2;
6848 p = lock_user_string(arg1);
6849 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
6850 if (!p || !p2) {
6851 ret = -TARGET_EFAULT;
6852 } else if (!arg3) {
6853 /* Short circuit this for the magic exe check. */
6854 ret = -TARGET_EINVAL;
6855 } else if (is_proc_myself((const char *)p, "exe")) {
6856 char real[PATH_MAX], *temp;
6857 temp = realpath(exec_path, real);
6858 /* Return value is # of bytes that we wrote to the buffer. */
6859 if (temp == NULL) {
6860 ret = get_errno(-1);
6861 } else {
6862 /* Don't worry about sign mismatch as earlier mapping
6863 * logic would have thrown a bad address error. */
6864 ret = MIN(strlen(real), arg3);
6865 /* We cannot NUL terminate the string. */
6866 memcpy(p2, real, ret);
6868 } else {
6869 ret = get_errno(readlink(path(p), p2, arg3));
6871 unlock_user(p2, arg2, ret);
6872 unlock_user(p, arg1, 0);
6874 break;
6875 #if defined(TARGET_NR_readlinkat)
6876 case TARGET_NR_readlinkat:
6878 void *p2;
6879 p = lock_user_string(arg2);
6880 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
6881 if (!p || !p2) {
6882 ret = -TARGET_EFAULT;
6883 } else if (is_proc_myself((const char *)p, "exe")) {
6884 char real[PATH_MAX], *temp;
6885 temp = realpath(exec_path, real);
6886 ret = temp == NULL ? get_errno(-1) : strlen(real) ;
6887 snprintf((char *)p2, arg4, "%s", real);
6888 } else {
6889 ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
6891 unlock_user(p2, arg3, ret);
6892 unlock_user(p, arg2, 0);
6894 break;
6895 #endif
6896 #ifdef TARGET_NR_uselib
6897 case TARGET_NR_uselib:
6898 goto unimplemented;
6899 #endif
6900 #ifdef TARGET_NR_swapon
6901 case TARGET_NR_swapon:
6902 if (!(p = lock_user_string(arg1)))
6903 goto efault;
6904 ret = get_errno(swapon(p, arg2));
6905 unlock_user(p, arg1, 0);
6906 break;
6907 #endif
6908 case TARGET_NR_reboot:
6909 if (arg3 == LINUX_REBOOT_CMD_RESTART2) {
6910 /* arg4 must be ignored in all other cases */
6911 p = lock_user_string(arg4);
6912 if (!p) {
6913 goto efault;
6915 ret = get_errno(reboot(arg1, arg2, arg3, p));
6916 unlock_user(p, arg4, 0);
6917 } else {
6918 ret = get_errno(reboot(arg1, arg2, arg3, NULL));
6920 break;
6921 #ifdef TARGET_NR_readdir
6922 case TARGET_NR_readdir:
6923 goto unimplemented;
6924 #endif
6925 #ifdef TARGET_NR_mmap
6926 case TARGET_NR_mmap:
6927 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6928 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
6929 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6930 || defined(TARGET_S390X)
6932 abi_ulong *v;
6933 abi_ulong v1, v2, v3, v4, v5, v6;
6934 if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
6935 goto efault;
6936 v1 = tswapal(v[0]);
6937 v2 = tswapal(v[1]);
6938 v3 = tswapal(v[2]);
6939 v4 = tswapal(v[3]);
6940 v5 = tswapal(v[4]);
6941 v6 = tswapal(v[5]);
6942 unlock_user(v, arg1, 0);
6943 ret = get_errno(target_mmap(v1, v2, v3,
6944 target_to_host_bitmask(v4, mmap_flags_tbl),
6945 v5, v6));
6947 #else
6948 ret = get_errno(target_mmap(arg1, arg2, arg3,
6949 target_to_host_bitmask(arg4, mmap_flags_tbl),
6950 arg5,
6951 arg6));
6952 #endif
6953 break;
6954 #endif
6955 #ifdef TARGET_NR_mmap2
6956 case TARGET_NR_mmap2:
6957 #ifndef MMAP_SHIFT
6958 #define MMAP_SHIFT 12
6959 #endif
6960 ret = get_errno(target_mmap(arg1, arg2, arg3,
6961 target_to_host_bitmask(arg4, mmap_flags_tbl),
6962 arg5,
6963 arg6 << MMAP_SHIFT));
6964 break;
6965 #endif
6966 case TARGET_NR_munmap:
6967 ret = get_errno(target_munmap(arg1, arg2));
6968 break;
6969 case TARGET_NR_mprotect:
6971 TaskState *ts = cpu->opaque;
6972 /* Special hack to detect libc making the stack executable. */
6973 if ((arg3 & PROT_GROWSDOWN)
6974 && arg1 >= ts->info->stack_limit
6975 && arg1 <= ts->info->start_stack) {
6976 arg3 &= ~PROT_GROWSDOWN;
6977 arg2 = arg2 + arg1 - ts->info->stack_limit;
6978 arg1 = ts->info->stack_limit;
6981 ret = get_errno(target_mprotect(arg1, arg2, arg3));
6982 break;
6983 #ifdef TARGET_NR_mremap
6984 case TARGET_NR_mremap:
6985 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
6986 break;
6987 #endif
6988 /* ??? msync/mlock/munlock are broken for softmmu. */
6989 #ifdef TARGET_NR_msync
6990 case TARGET_NR_msync:
6991 ret = get_errno(msync(g2h(arg1), arg2, arg3));
6992 break;
6993 #endif
6994 #ifdef TARGET_NR_mlock
6995 case TARGET_NR_mlock:
6996 ret = get_errno(mlock(g2h(arg1), arg2));
6997 break;
6998 #endif
6999 #ifdef TARGET_NR_munlock
7000 case TARGET_NR_munlock:
7001 ret = get_errno(munlock(g2h(arg1), arg2));
7002 break;
7003 #endif
7004 #ifdef TARGET_NR_mlockall
7005 case TARGET_NR_mlockall:
7006 ret = get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
7007 break;
7008 #endif
7009 #ifdef TARGET_NR_munlockall
7010 case TARGET_NR_munlockall:
7011 ret = get_errno(munlockall());
7012 break;
7013 #endif
7014 case TARGET_NR_truncate:
7015 if (!(p = lock_user_string(arg1)))
7016 goto efault;
7017 ret = get_errno(truncate(p, arg2));
7018 unlock_user(p, arg1, 0);
7019 break;
7020 case TARGET_NR_ftruncate:
7021 ret = get_errno(ftruncate(arg1, arg2));
7022 break;
7023 case TARGET_NR_fchmod:
7024 ret = get_errno(fchmod(arg1, arg2));
7025 break;
7026 #if defined(TARGET_NR_fchmodat)
7027 case TARGET_NR_fchmodat:
7028 if (!(p = lock_user_string(arg2)))
7029 goto efault;
7030 ret = get_errno(fchmodat(arg1, p, arg3, 0));
7031 unlock_user(p, arg2, 0);
7032 break;
7033 #endif
7034 case TARGET_NR_getpriority:
7035 /* Note that negative values are valid for getpriority, so we must
7036 differentiate based on errno settings. */
7037 errno = 0;
7038 ret = getpriority(arg1, arg2);
7039 if (ret == -1 && errno != 0) {
7040 ret = -host_to_target_errno(errno);
7041 break;
7043 #ifdef TARGET_ALPHA
7044 /* Return value is the unbiased priority. Signal no error. */
7045 ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0;
7046 #else
7047 /* Return value is a biased priority to avoid negative numbers. */
7048 ret = 20 - ret;
7049 #endif
7050 break;
7051 case TARGET_NR_setpriority:
7052 ret = get_errno(setpriority(arg1, arg2, arg3));
7053 break;
7054 #ifdef TARGET_NR_profil
7055 case TARGET_NR_profil:
7056 goto unimplemented;
7057 #endif
7058 case TARGET_NR_statfs:
7059 if (!(p = lock_user_string(arg1)))
7060 goto efault;
7061 ret = get_errno(statfs(path(p), &stfs));
7062 unlock_user(p, arg1, 0);
7063 convert_statfs:
7064 if (!is_error(ret)) {
7065 struct target_statfs *target_stfs;
7067 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
7068 goto efault;
7069 __put_user(stfs.f_type, &target_stfs->f_type);
7070 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
7071 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
7072 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
7073 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
7074 __put_user(stfs.f_files, &target_stfs->f_files);
7075 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
7076 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
7077 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
7078 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
7079 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
7080 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
7081 unlock_user_struct(target_stfs, arg2, 1);
7083 break;
7084 case TARGET_NR_fstatfs:
7085 ret = get_errno(fstatfs(arg1, &stfs));
7086 goto convert_statfs;
7087 #ifdef TARGET_NR_statfs64
7088 case TARGET_NR_statfs64:
7089 if (!(p = lock_user_string(arg1)))
7090 goto efault;
7091 ret = get_errno(statfs(path(p), &stfs));
7092 unlock_user(p, arg1, 0);
7093 convert_statfs64:
7094 if (!is_error(ret)) {
7095 struct target_statfs64 *target_stfs;
7097 if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
7098 goto efault;
7099 __put_user(stfs.f_type, &target_stfs->f_type);
7100 __put_user(stfs.f_bsize, &target_stfs->f_bsize);
7101 __put_user(stfs.f_blocks, &target_stfs->f_blocks);
7102 __put_user(stfs.f_bfree, &target_stfs->f_bfree);
7103 __put_user(stfs.f_bavail, &target_stfs->f_bavail);
7104 __put_user(stfs.f_files, &target_stfs->f_files);
7105 __put_user(stfs.f_ffree, &target_stfs->f_ffree);
7106 __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
7107 __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
7108 __put_user(stfs.f_namelen, &target_stfs->f_namelen);
7109 __put_user(stfs.f_frsize, &target_stfs->f_frsize);
7110 memset(target_stfs->f_spare, 0, sizeof(target_stfs->f_spare));
7111 unlock_user_struct(target_stfs, arg3, 1);
7113 break;
7114 case TARGET_NR_fstatfs64:
7115 ret = get_errno(fstatfs(arg1, &stfs));
7116 goto convert_statfs64;
7117 #endif
7118 #ifdef TARGET_NR_ioperm
7119 case TARGET_NR_ioperm:
7120 goto unimplemented;
7121 #endif
7122 #ifdef TARGET_NR_socketcall
7123 case TARGET_NR_socketcall:
7124 ret = do_socketcall(arg1, arg2);
7125 break;
7126 #endif
7127 #ifdef TARGET_NR_accept
7128 case TARGET_NR_accept:
7129 ret = do_accept4(arg1, arg2, arg3, 0);
7130 break;
7131 #endif
7132 #ifdef TARGET_NR_accept4
7133 case TARGET_NR_accept4:
7134 #ifdef CONFIG_ACCEPT4
7135 ret = do_accept4(arg1, arg2, arg3, arg4);
7136 #else
7137 goto unimplemented;
7138 #endif
7139 break;
7140 #endif
7141 #ifdef TARGET_NR_bind
7142 case TARGET_NR_bind:
7143 ret = do_bind(arg1, arg2, arg3);
7144 break;
7145 #endif
7146 #ifdef TARGET_NR_connect
7147 case TARGET_NR_connect:
7148 ret = do_connect(arg1, arg2, arg3);
7149 break;
7150 #endif
7151 #ifdef TARGET_NR_getpeername
7152 case TARGET_NR_getpeername:
7153 ret = do_getpeername(arg1, arg2, arg3);
7154 break;
7155 #endif
7156 #ifdef TARGET_NR_getsockname
7157 case TARGET_NR_getsockname:
7158 ret = do_getsockname(arg1, arg2, arg3);
7159 break;
7160 #endif
7161 #ifdef TARGET_NR_getsockopt
7162 case TARGET_NR_getsockopt:
7163 ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
7164 break;
7165 #endif
7166 #ifdef TARGET_NR_listen
7167 case TARGET_NR_listen:
7168 ret = get_errno(listen(arg1, arg2));
7169 break;
7170 #endif
7171 #ifdef TARGET_NR_recv
7172 case TARGET_NR_recv:
7173 ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
7174 break;
7175 #endif
7176 #ifdef TARGET_NR_recvfrom
7177 case TARGET_NR_recvfrom:
7178 ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
7179 break;
7180 #endif
7181 #ifdef TARGET_NR_recvmsg
7182 case TARGET_NR_recvmsg:
7183 ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
7184 break;
7185 #endif
7186 #ifdef TARGET_NR_send
7187 case TARGET_NR_send:
7188 ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
7189 break;
7190 #endif
7191 #ifdef TARGET_NR_sendmsg
7192 case TARGET_NR_sendmsg:
7193 ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
7194 break;
7195 #endif
7196 #ifdef TARGET_NR_sendmmsg
7197 case TARGET_NR_sendmmsg:
7198 ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1);
7199 break;
7200 case TARGET_NR_recvmmsg:
7201 ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0);
7202 break;
7203 #endif
7204 #ifdef TARGET_NR_sendto
7205 case TARGET_NR_sendto:
7206 ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
7207 break;
7208 #endif
7209 #ifdef TARGET_NR_shutdown
7210 case TARGET_NR_shutdown:
7211 ret = get_errno(shutdown(arg1, arg2));
7212 break;
7213 #endif
7214 #ifdef TARGET_NR_socket
7215 case TARGET_NR_socket:
7216 ret = do_socket(arg1, arg2, arg3);
7217 break;
7218 #endif
7219 #ifdef TARGET_NR_socketpair
7220 case TARGET_NR_socketpair:
7221 ret = do_socketpair(arg1, arg2, arg3, arg4);
7222 break;
7223 #endif
7224 #ifdef TARGET_NR_setsockopt
7225 case TARGET_NR_setsockopt:
7226 ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
7227 break;
7228 #endif
7230 case TARGET_NR_syslog:
7231 if (!(p = lock_user_string(arg2)))
7232 goto efault;
7233 ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
7234 unlock_user(p, arg2, 0);
7235 break;
7237 case TARGET_NR_setitimer:
7239 struct itimerval value, ovalue, *pvalue;
7241 if (arg2) {
7242 pvalue = &value;
7243 if (copy_from_user_timeval(&pvalue->it_interval, arg2)
7244 || copy_from_user_timeval(&pvalue->it_value,
7245 arg2 + sizeof(struct target_timeval)))
7246 goto efault;
7247 } else {
7248 pvalue = NULL;
7250 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
7251 if (!is_error(ret) && arg3) {
7252 if (copy_to_user_timeval(arg3,
7253 &ovalue.it_interval)
7254 || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
7255 &ovalue.it_value))
7256 goto efault;
7259 break;
7260 case TARGET_NR_getitimer:
7262 struct itimerval value;
7264 ret = get_errno(getitimer(arg1, &value));
7265 if (!is_error(ret) && arg2) {
7266 if (copy_to_user_timeval(arg2,
7267 &value.it_interval)
7268 || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
7269 &value.it_value))
7270 goto efault;
7273 break;
7274 case TARGET_NR_stat:
7275 if (!(p = lock_user_string(arg1)))
7276 goto efault;
7277 ret = get_errno(stat(path(p), &st));
7278 unlock_user(p, arg1, 0);
7279 goto do_stat;
7280 case TARGET_NR_lstat:
7281 if (!(p = lock_user_string(arg1)))
7282 goto efault;
7283 ret = get_errno(lstat(path(p), &st));
7284 unlock_user(p, arg1, 0);
7285 goto do_stat;
7286 case TARGET_NR_fstat:
7288 ret = get_errno(fstat(arg1, &st));
7289 do_stat:
7290 if (!is_error(ret)) {
7291 struct target_stat *target_st;
7293 if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
7294 goto efault;
7295 memset(target_st, 0, sizeof(*target_st));
7296 __put_user(st.st_dev, &target_st->st_dev);
7297 __put_user(st.st_ino, &target_st->st_ino);
7298 __put_user(st.st_mode, &target_st->st_mode);
7299 __put_user(st.st_uid, &target_st->st_uid);
7300 __put_user(st.st_gid, &target_st->st_gid);
7301 __put_user(st.st_nlink, &target_st->st_nlink);
7302 __put_user(st.st_rdev, &target_st->st_rdev);
7303 __put_user(st.st_size, &target_st->st_size);
7304 __put_user(st.st_blksize, &target_st->st_blksize);
7305 __put_user(st.st_blocks, &target_st->st_blocks);
7306 __put_user(st.st_atime, &target_st->target_st_atime);
7307 __put_user(st.st_mtime, &target_st->target_st_mtime);
7308 __put_user(st.st_ctime, &target_st->target_st_ctime);
7309 unlock_user_struct(target_st, arg2, 1);
7312 break;
7313 #ifdef TARGET_NR_olduname
7314 case TARGET_NR_olduname:
7315 goto unimplemented;
7316 #endif
7317 #ifdef TARGET_NR_iopl
7318 case TARGET_NR_iopl:
7319 goto unimplemented;
7320 #endif
7321 case TARGET_NR_vhangup:
7322 ret = get_errno(vhangup());
7323 break;
7324 #ifdef TARGET_NR_idle
7325 case TARGET_NR_idle:
7326 goto unimplemented;
7327 #endif
7328 #ifdef TARGET_NR_syscall
7329 case TARGET_NR_syscall:
7330 ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
7331 arg6, arg7, arg8, 0);
7332 break;
7333 #endif
7334 case TARGET_NR_wait4:
7336 int status;
7337 abi_long status_ptr = arg2;
7338 struct rusage rusage, *rusage_ptr;
7339 abi_ulong target_rusage = arg4;
7340 abi_long rusage_err;
7341 if (target_rusage)
7342 rusage_ptr = &rusage;
7343 else
7344 rusage_ptr = NULL;
7345 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
7346 if (!is_error(ret)) {
7347 if (status_ptr && ret) {
7348 status = host_to_target_waitstatus(status);
7349 if (put_user_s32(status, status_ptr))
7350 goto efault;
7352 if (target_rusage) {
7353 rusage_err = host_to_target_rusage(target_rusage, &rusage);
7354 if (rusage_err) {
7355 ret = rusage_err;
7360 break;
7361 #ifdef TARGET_NR_swapoff
7362 case TARGET_NR_swapoff:
7363 if (!(p = lock_user_string(arg1)))
7364 goto efault;
7365 ret = get_errno(swapoff(p));
7366 unlock_user(p, arg1, 0);
7367 break;
7368 #endif
7369 case TARGET_NR_sysinfo:
7371 struct target_sysinfo *target_value;
7372 struct sysinfo value;
7373 ret = get_errno(sysinfo(&value));
7374 if (!is_error(ret) && arg1)
7376 if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
7377 goto efault;
7378 __put_user(value.uptime, &target_value->uptime);
7379 __put_user(value.loads[0], &target_value->loads[0]);
7380 __put_user(value.loads[1], &target_value->loads[1]);
7381 __put_user(value.loads[2], &target_value->loads[2]);
7382 __put_user(value.totalram, &target_value->totalram);
7383 __put_user(value.freeram, &target_value->freeram);
7384 __put_user(value.sharedram, &target_value->sharedram);
7385 __put_user(value.bufferram, &target_value->bufferram);
7386 __put_user(value.totalswap, &target_value->totalswap);
7387 __put_user(value.freeswap, &target_value->freeswap);
7388 __put_user(value.procs, &target_value->procs);
7389 __put_user(value.totalhigh, &target_value->totalhigh);
7390 __put_user(value.freehigh, &target_value->freehigh);
7391 __put_user(value.mem_unit, &target_value->mem_unit);
7392 unlock_user_struct(target_value, arg1, 1);
7395 break;
7396 #ifdef TARGET_NR_ipc
7397 case TARGET_NR_ipc:
7398 ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
7399 break;
7400 #endif
7401 #ifdef TARGET_NR_semget
7402 case TARGET_NR_semget:
7403 ret = get_errno(semget(arg1, arg2, arg3));
7404 break;
7405 #endif
7406 #ifdef TARGET_NR_semop
7407 case TARGET_NR_semop:
7408 ret = do_semop(arg1, arg2, arg3);
7409 break;
7410 #endif
7411 #ifdef TARGET_NR_semctl
7412 case TARGET_NR_semctl:
7413 ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
7414 break;
7415 #endif
7416 #ifdef TARGET_NR_msgctl
7417 case TARGET_NR_msgctl:
7418 ret = do_msgctl(arg1, arg2, arg3);
7419 break;
7420 #endif
7421 #ifdef TARGET_NR_msgget
7422 case TARGET_NR_msgget:
7423 ret = get_errno(msgget(arg1, arg2));
7424 break;
7425 #endif
7426 #ifdef TARGET_NR_msgrcv
7427 case TARGET_NR_msgrcv:
7428 ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
7429 break;
7430 #endif
7431 #ifdef TARGET_NR_msgsnd
7432 case TARGET_NR_msgsnd:
7433 ret = do_msgsnd(arg1, arg2, arg3, arg4);
7434 break;
7435 #endif
7436 #ifdef TARGET_NR_shmget
7437 case TARGET_NR_shmget:
7438 ret = get_errno(shmget(arg1, arg2, arg3));
7439 break;
7440 #endif
7441 #ifdef TARGET_NR_shmctl
7442 case TARGET_NR_shmctl:
7443 ret = do_shmctl(arg1, arg2, arg3);
7444 break;
7445 #endif
7446 #ifdef TARGET_NR_shmat
7447 case TARGET_NR_shmat:
7448 ret = do_shmat(arg1, arg2, arg3);
7449 break;
7450 #endif
7451 #ifdef TARGET_NR_shmdt
7452 case TARGET_NR_shmdt:
7453 ret = do_shmdt(arg1);
7454 break;
7455 #endif
7456 case TARGET_NR_fsync:
7457 ret = get_errno(fsync(arg1));
7458 break;
7459 case TARGET_NR_clone:
7460 /* Linux manages to have three different orderings for its
7461 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
7462 * match the kernel's CONFIG_CLONE_* settings.
7463 * Microblaze is further special in that it uses a sixth
7464 * implicit argument to clone for the TLS pointer.
7466 #if defined(TARGET_MICROBLAZE)
7467 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
7468 #elif defined(TARGET_CLONE_BACKWARDS)
7469 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
7470 #elif defined(TARGET_CLONE_BACKWARDS2)
7471 ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
7472 #else
7473 ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
7474 #endif
7475 break;
7476 #ifdef __NR_exit_group
7477 /* new thread calls */
7478 case TARGET_NR_exit_group:
7479 #ifdef TARGET_GPROF
7480 _mcleanup();
7481 #endif
7482 gdb_exit(cpu_env, arg1);
7483 ret = get_errno(exit_group(arg1));
7484 break;
7485 #endif
7486 case TARGET_NR_setdomainname:
7487 if (!(p = lock_user_string(arg1)))
7488 goto efault;
7489 ret = get_errno(setdomainname(p, arg2));
7490 unlock_user(p, arg1, 0);
7491 break;
7492 case TARGET_NR_uname:
7493 /* no need to transcode because we use the linux syscall */
7495 struct new_utsname * buf;
7497 if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
7498 goto efault;
7499 ret = get_errno(sys_uname(buf));
7500 if (!is_error(ret)) {
7501 /* Overrite the native machine name with whatever is being
7502 emulated. */
7503 strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
7504 /* Allow the user to override the reported release. */
7505 if (qemu_uname_release && *qemu_uname_release)
7506 strcpy (buf->release, qemu_uname_release);
7508 unlock_user_struct(buf, arg1, 1);
7510 break;
7511 #ifdef TARGET_I386
7512 case TARGET_NR_modify_ldt:
7513 ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
7514 break;
7515 #if !defined(TARGET_X86_64)
7516 case TARGET_NR_vm86old:
7517 goto unimplemented;
7518 case TARGET_NR_vm86:
7519 ret = do_vm86(cpu_env, arg1, arg2);
7520 break;
7521 #endif
7522 #endif
7523 case TARGET_NR_adjtimex:
7524 goto unimplemented;
7525 #ifdef TARGET_NR_create_module
7526 case TARGET_NR_create_module:
7527 #endif
7528 case TARGET_NR_init_module:
7529 case TARGET_NR_delete_module:
7530 #ifdef TARGET_NR_get_kernel_syms
7531 case TARGET_NR_get_kernel_syms:
7532 #endif
7533 goto unimplemented;
7534 case TARGET_NR_quotactl:
7535 goto unimplemented;
7536 case TARGET_NR_getpgid:
7537 ret = get_errno(getpgid(arg1));
7538 break;
7539 case TARGET_NR_fchdir:
7540 ret = get_errno(fchdir(arg1));
7541 break;
7542 #ifdef TARGET_NR_bdflush /* not on x86_64 */
7543 case TARGET_NR_bdflush:
7544 goto unimplemented;
7545 #endif
7546 #ifdef TARGET_NR_sysfs
7547 case TARGET_NR_sysfs:
7548 goto unimplemented;
7549 #endif
7550 case TARGET_NR_personality:
7551 ret = get_errno(personality(arg1));
7552 break;
7553 #ifdef TARGET_NR_afs_syscall
7554 case TARGET_NR_afs_syscall:
7555 goto unimplemented;
7556 #endif
7557 #ifdef TARGET_NR__llseek /* Not on alpha */
7558 case TARGET_NR__llseek:
7560 int64_t res;
7561 #if !defined(__NR_llseek)
7562 res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
7563 if (res == -1) {
7564 ret = get_errno(res);
7565 } else {
7566 ret = 0;
7568 #else
7569 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
7570 #endif
7571 if ((ret == 0) && put_user_s64(res, arg4)) {
7572 goto efault;
7575 break;
7576 #endif
7577 case TARGET_NR_getdents:
7578 #ifdef __NR_getdents
7579 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7581 struct target_dirent *target_dirp;
7582 struct linux_dirent *dirp;
7583 abi_long count = arg3;
7585 dirp = malloc(count);
7586 if (!dirp) {
7587 ret = -TARGET_ENOMEM;
7588 goto fail;
7591 ret = get_errno(sys_getdents(arg1, dirp, count));
7592 if (!is_error(ret)) {
7593 struct linux_dirent *de;
7594 struct target_dirent *tde;
7595 int len = ret;
7596 int reclen, treclen;
7597 int count1, tnamelen;
7599 count1 = 0;
7600 de = dirp;
7601 if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7602 goto efault;
7603 tde = target_dirp;
7604 while (len > 0) {
7605 reclen = de->d_reclen;
7606 tnamelen = reclen - offsetof(struct linux_dirent, d_name);
7607 assert(tnamelen >= 0);
7608 treclen = tnamelen + offsetof(struct target_dirent, d_name);
7609 assert(count1 + treclen <= count);
7610 tde->d_reclen = tswap16(treclen);
7611 tde->d_ino = tswapal(de->d_ino);
7612 tde->d_off = tswapal(de->d_off);
7613 memcpy(tde->d_name, de->d_name, tnamelen);
7614 de = (struct linux_dirent *)((char *)de + reclen);
7615 len -= reclen;
7616 tde = (struct target_dirent *)((char *)tde + treclen);
7617 count1 += treclen;
7619 ret = count1;
7620 unlock_user(target_dirp, arg2, ret);
7622 free(dirp);
7624 #else
7626 struct linux_dirent *dirp;
7627 abi_long count = arg3;
7629 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7630 goto efault;
7631 ret = get_errno(sys_getdents(arg1, dirp, count));
7632 if (!is_error(ret)) {
7633 struct linux_dirent *de;
7634 int len = ret;
7635 int reclen;
7636 de = dirp;
7637 while (len > 0) {
7638 reclen = de->d_reclen;
7639 if (reclen > len)
7640 break;
7641 de->d_reclen = tswap16(reclen);
7642 tswapls(&de->d_ino);
7643 tswapls(&de->d_off);
7644 de = (struct linux_dirent *)((char *)de + reclen);
7645 len -= reclen;
7648 unlock_user(dirp, arg2, ret);
7650 #endif
7651 #else
7652 /* Implement getdents in terms of getdents64 */
7654 struct linux_dirent64 *dirp;
7655 abi_long count = arg3;
7657 dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
7658 if (!dirp) {
7659 goto efault;
7661 ret = get_errno(sys_getdents64(arg1, dirp, count));
7662 if (!is_error(ret)) {
7663 /* Convert the dirent64 structs to target dirent. We do this
7664 * in-place, since we can guarantee that a target_dirent is no
7665 * larger than a dirent64; however this means we have to be
7666 * careful to read everything before writing in the new format.
7668 struct linux_dirent64 *de;
7669 struct target_dirent *tde;
7670 int len = ret;
7671 int tlen = 0;
7673 de = dirp;
7674 tde = (struct target_dirent *)dirp;
7675 while (len > 0) {
7676 int namelen, treclen;
7677 int reclen = de->d_reclen;
7678 uint64_t ino = de->d_ino;
7679 int64_t off = de->d_off;
7680 uint8_t type = de->d_type;
7682 namelen = strlen(de->d_name);
7683 treclen = offsetof(struct target_dirent, d_name)
7684 + namelen + 2;
7685 treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
7687 memmove(tde->d_name, de->d_name, namelen + 1);
7688 tde->d_ino = tswapal(ino);
7689 tde->d_off = tswapal(off);
7690 tde->d_reclen = tswap16(treclen);
7691 /* The target_dirent type is in what was formerly a padding
7692 * byte at the end of the structure:
7694 *(((char *)tde) + treclen - 1) = type;
7696 de = (struct linux_dirent64 *)((char *)de + reclen);
7697 tde = (struct target_dirent *)((char *)tde + treclen);
7698 len -= reclen;
7699 tlen += treclen;
7701 ret = tlen;
7703 unlock_user(dirp, arg2, ret);
7705 #endif
7706 break;
7707 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7708 case TARGET_NR_getdents64:
7710 struct linux_dirent64 *dirp;
7711 abi_long count = arg3;
7712 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
7713 goto efault;
7714 ret = get_errno(sys_getdents64(arg1, dirp, count));
7715 if (!is_error(ret)) {
7716 struct linux_dirent64 *de;
7717 int len = ret;
7718 int reclen;
7719 de = dirp;
7720 while (len > 0) {
7721 reclen = de->d_reclen;
7722 if (reclen > len)
7723 break;
7724 de->d_reclen = tswap16(reclen);
7725 tswap64s((uint64_t *)&de->d_ino);
7726 tswap64s((uint64_t *)&de->d_off);
7727 de = (struct linux_dirent64 *)((char *)de + reclen);
7728 len -= reclen;
7731 unlock_user(dirp, arg2, ret);
7733 break;
7734 #endif /* TARGET_NR_getdents64 */
7735 #if defined(TARGET_NR__newselect)
7736 case TARGET_NR__newselect:
7737 ret = do_select(arg1, arg2, arg3, arg4, arg5);
7738 break;
7739 #endif
7740 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7741 # ifdef TARGET_NR_poll
7742 case TARGET_NR_poll:
7743 # endif
7744 # ifdef TARGET_NR_ppoll
7745 case TARGET_NR_ppoll:
7746 # endif
7748 struct target_pollfd *target_pfd;
7749 unsigned int nfds = arg2;
7750 int timeout = arg3;
7751 struct pollfd *pfd;
7752 unsigned int i;
7754 target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
7755 if (!target_pfd)
7756 goto efault;
7758 pfd = alloca(sizeof(struct pollfd) * nfds);
7759 for(i = 0; i < nfds; i++) {
7760 pfd[i].fd = tswap32(target_pfd[i].fd);
7761 pfd[i].events = tswap16(target_pfd[i].events);
7764 # ifdef TARGET_NR_ppoll
7765 if (num == TARGET_NR_ppoll) {
7766 struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
7767 target_sigset_t *target_set;
7768 sigset_t _set, *set = &_set;
7770 if (arg3) {
7771 if (target_to_host_timespec(timeout_ts, arg3)) {
7772 unlock_user(target_pfd, arg1, 0);
7773 goto efault;
7775 } else {
7776 timeout_ts = NULL;
7779 if (arg4) {
7780 target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
7781 if (!target_set) {
7782 unlock_user(target_pfd, arg1, 0);
7783 goto efault;
7785 target_to_host_sigset(set, target_set);
7786 } else {
7787 set = NULL;
7790 ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
7792 if (!is_error(ret) && arg3) {
7793 host_to_target_timespec(arg3, timeout_ts);
7795 if (arg4) {
7796 unlock_user(target_set, arg4, 0);
7798 } else
7799 # endif
7800 ret = get_errno(poll(pfd, nfds, timeout));
7802 if (!is_error(ret)) {
7803 for(i = 0; i < nfds; i++) {
7804 target_pfd[i].revents = tswap16(pfd[i].revents);
7807 unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
7809 break;
7810 #endif
7811 case TARGET_NR_flock:
7812 /* NOTE: the flock constant seems to be the same for every
7813 Linux platform */
7814 ret = get_errno(flock(arg1, arg2));
7815 break;
7816 case TARGET_NR_readv:
7818 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
7819 if (vec != NULL) {
7820 ret = get_errno(readv(arg1, vec, arg3));
7821 unlock_iovec(vec, arg2, arg3, 1);
7822 } else {
7823 ret = -host_to_target_errno(errno);
7826 break;
7827 case TARGET_NR_writev:
7829 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
7830 if (vec != NULL) {
7831 ret = get_errno(writev(arg1, vec, arg3));
7832 unlock_iovec(vec, arg2, arg3, 0);
7833 } else {
7834 ret = -host_to_target_errno(errno);
7837 break;
7838 case TARGET_NR_getsid:
7839 ret = get_errno(getsid(arg1));
7840 break;
7841 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7842 case TARGET_NR_fdatasync:
7843 ret = get_errno(fdatasync(arg1));
7844 break;
7845 #endif
7846 case TARGET_NR__sysctl:
7847 /* We don't implement this, but ENOTDIR is always a safe
7848 return value. */
7849 ret = -TARGET_ENOTDIR;
7850 break;
7851 case TARGET_NR_sched_getaffinity:
7853 unsigned int mask_size;
7854 unsigned long *mask;
7857 * sched_getaffinity needs multiples of ulong, so need to take
7858 * care of mismatches between target ulong and host ulong sizes.
7860 if (arg2 & (sizeof(abi_ulong) - 1)) {
7861 ret = -TARGET_EINVAL;
7862 break;
7864 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7866 mask = alloca(mask_size);
7867 ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
7869 if (!is_error(ret)) {
7870 if (ret > arg2) {
7871 /* More data returned than the caller's buffer will fit.
7872 * This only happens if sizeof(abi_long) < sizeof(long)
7873 * and the caller passed us a buffer holding an odd number
7874 * of abi_longs. If the host kernel is actually using the
7875 * extra 4 bytes then fail EINVAL; otherwise we can just
7876 * ignore them and only copy the interesting part.
7878 int numcpus = sysconf(_SC_NPROCESSORS_CONF);
7879 if (numcpus > arg2 * 8) {
7880 ret = -TARGET_EINVAL;
7881 break;
7883 ret = arg2;
7886 if (copy_to_user(arg3, mask, ret)) {
7887 goto efault;
7891 break;
7892 case TARGET_NR_sched_setaffinity:
7894 unsigned int mask_size;
7895 unsigned long *mask;
7898 * sched_setaffinity needs multiples of ulong, so need to take
7899 * care of mismatches between target ulong and host ulong sizes.
7901 if (arg2 & (sizeof(abi_ulong) - 1)) {
7902 ret = -TARGET_EINVAL;
7903 break;
7905 mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
7907 mask = alloca(mask_size);
7908 if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
7909 goto efault;
7911 memcpy(mask, p, arg2);
7912 unlock_user_struct(p, arg2, 0);
7914 ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
7916 break;
7917 case TARGET_NR_sched_setparam:
7919 struct sched_param *target_schp;
7920 struct sched_param schp;
7922 if (arg2 == 0) {
7923 return -TARGET_EINVAL;
7925 if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
7926 goto efault;
7927 schp.sched_priority = tswap32(target_schp->sched_priority);
7928 unlock_user_struct(target_schp, arg2, 0);
7929 ret = get_errno(sched_setparam(arg1, &schp));
7931 break;
7932 case TARGET_NR_sched_getparam:
7934 struct sched_param *target_schp;
7935 struct sched_param schp;
7937 if (arg2 == 0) {
7938 return -TARGET_EINVAL;
7940 ret = get_errno(sched_getparam(arg1, &schp));
7941 if (!is_error(ret)) {
7942 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
7943 goto efault;
7944 target_schp->sched_priority = tswap32(schp.sched_priority);
7945 unlock_user_struct(target_schp, arg2, 1);
7948 break;
7949 case TARGET_NR_sched_setscheduler:
7951 struct sched_param *target_schp;
7952 struct sched_param schp;
7953 if (arg3 == 0) {
7954 return -TARGET_EINVAL;
7956 if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
7957 goto efault;
7958 schp.sched_priority = tswap32(target_schp->sched_priority);
7959 unlock_user_struct(target_schp, arg3, 0);
7960 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
7962 break;
7963 case TARGET_NR_sched_getscheduler:
7964 ret = get_errno(sched_getscheduler(arg1));
7965 break;
7966 case TARGET_NR_sched_yield:
7967 ret = get_errno(sched_yield());
7968 break;
7969 case TARGET_NR_sched_get_priority_max:
7970 ret = get_errno(sched_get_priority_max(arg1));
7971 break;
7972 case TARGET_NR_sched_get_priority_min:
7973 ret = get_errno(sched_get_priority_min(arg1));
7974 break;
7975 case TARGET_NR_sched_rr_get_interval:
7977 struct timespec ts;
7978 ret = get_errno(sched_rr_get_interval(arg1, &ts));
7979 if (!is_error(ret)) {
7980 ret = host_to_target_timespec(arg2, &ts);
7983 break;
7984 case TARGET_NR_nanosleep:
7986 struct timespec req, rem;
7987 target_to_host_timespec(&req, arg1);
7988 ret = get_errno(nanosleep(&req, &rem));
7989 if (is_error(ret) && arg2) {
7990 host_to_target_timespec(arg2, &rem);
7993 break;
7994 #ifdef TARGET_NR_query_module
7995 case TARGET_NR_query_module:
7996 goto unimplemented;
7997 #endif
7998 #ifdef TARGET_NR_nfsservctl
7999 case TARGET_NR_nfsservctl:
8000 goto unimplemented;
8001 #endif
8002 case TARGET_NR_prctl:
8003 switch (arg1) {
8004 case PR_GET_PDEATHSIG:
8006 int deathsig;
8007 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
8008 if (!is_error(ret) && arg2
8009 && put_user_ual(deathsig, arg2)) {
8010 goto efault;
8012 break;
8014 #ifdef PR_GET_NAME
8015 case PR_GET_NAME:
8017 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
8018 if (!name) {
8019 goto efault;
8021 ret = get_errno(prctl(arg1, (unsigned long)name,
8022 arg3, arg4, arg5));
8023 unlock_user(name, arg2, 16);
8024 break;
8026 case PR_SET_NAME:
8028 void *name = lock_user(VERIFY_READ, arg2, 16, 1);
8029 if (!name) {
8030 goto efault;
8032 ret = get_errno(prctl(arg1, (unsigned long)name,
8033 arg3, arg4, arg5));
8034 unlock_user(name, arg2, 0);
8035 break;
8037 #endif
8038 default:
8039 /* Most prctl options have no pointer arguments */
8040 ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
8041 break;
8043 break;
8044 #ifdef TARGET_NR_arch_prctl
8045 case TARGET_NR_arch_prctl:
8046 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
8047 ret = do_arch_prctl(cpu_env, arg1, arg2);
8048 break;
8049 #else
8050 goto unimplemented;
8051 #endif
8052 #endif
8053 #ifdef TARGET_NR_pread64
8054 case TARGET_NR_pread64:
8055 if (regpairs_aligned(cpu_env)) {
8056 arg4 = arg5;
8057 arg5 = arg6;
8059 if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
8060 goto efault;
8061 ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
8062 unlock_user(p, arg2, ret);
8063 break;
8064 case TARGET_NR_pwrite64:
8065 if (regpairs_aligned(cpu_env)) {
8066 arg4 = arg5;
8067 arg5 = arg6;
8069 if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
8070 goto efault;
8071 ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
8072 unlock_user(p, arg2, 0);
8073 break;
8074 #endif
8075 case TARGET_NR_getcwd:
8076 if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
8077 goto efault;
8078 ret = get_errno(sys_getcwd1(p, arg2));
8079 unlock_user(p, arg1, ret);
8080 break;
8081 case TARGET_NR_capget:
8082 case TARGET_NR_capset:
8084 struct target_user_cap_header *target_header;
8085 struct target_user_cap_data *target_data = NULL;
8086 struct __user_cap_header_struct header;
8087 struct __user_cap_data_struct data[2];
8088 struct __user_cap_data_struct *dataptr = NULL;
8089 int i, target_datalen;
8090 int data_items = 1;
8092 if (!lock_user_struct(VERIFY_WRITE, target_header, arg1, 1)) {
8093 goto efault;
8095 header.version = tswap32(target_header->version);
8096 header.pid = tswap32(target_header->pid);
8098 if (header.version != _LINUX_CAPABILITY_VERSION) {
8099 /* Version 2 and up takes pointer to two user_data structs */
8100 data_items = 2;
8103 target_datalen = sizeof(*target_data) * data_items;
8105 if (arg2) {
8106 if (num == TARGET_NR_capget) {
8107 target_data = lock_user(VERIFY_WRITE, arg2, target_datalen, 0);
8108 } else {
8109 target_data = lock_user(VERIFY_READ, arg2, target_datalen, 1);
8111 if (!target_data) {
8112 unlock_user_struct(target_header, arg1, 0);
8113 goto efault;
8116 if (num == TARGET_NR_capset) {
8117 for (i = 0; i < data_items; i++) {
8118 data[i].effective = tswap32(target_data[i].effective);
8119 data[i].permitted = tswap32(target_data[i].permitted);
8120 data[i].inheritable = tswap32(target_data[i].inheritable);
8124 dataptr = data;
8127 if (num == TARGET_NR_capget) {
8128 ret = get_errno(capget(&header, dataptr));
8129 } else {
8130 ret = get_errno(capset(&header, dataptr));
8133 /* The kernel always updates version for both capget and capset */
8134 target_header->version = tswap32(header.version);
8135 unlock_user_struct(target_header, arg1, 1);
8137 if (arg2) {
8138 if (num == TARGET_NR_capget) {
8139 for (i = 0; i < data_items; i++) {
8140 target_data[i].effective = tswap32(data[i].effective);
8141 target_data[i].permitted = tswap32(data[i].permitted);
8142 target_data[i].inheritable = tswap32(data[i].inheritable);
8144 unlock_user(target_data, arg2, target_datalen);
8145 } else {
8146 unlock_user(target_data, arg2, 0);
8149 break;
8151 case TARGET_NR_sigaltstack:
8152 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
8153 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
8154 defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
8155 ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUArchState *)cpu_env));
8156 break;
8157 #else
8158 goto unimplemented;
8159 #endif
8161 #ifdef CONFIG_SENDFILE
8162 case TARGET_NR_sendfile:
8164 off_t *offp = NULL;
8165 off_t off;
8166 if (arg3) {
8167 ret = get_user_sal(off, arg3);
8168 if (is_error(ret)) {
8169 break;
8171 offp = &off;
8173 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
8174 if (!is_error(ret) && arg3) {
8175 abi_long ret2 = put_user_sal(off, arg3);
8176 if (is_error(ret2)) {
8177 ret = ret2;
8180 break;
8182 #ifdef TARGET_NR_sendfile64
8183 case TARGET_NR_sendfile64:
8185 off_t *offp = NULL;
8186 off_t off;
8187 if (arg3) {
8188 ret = get_user_s64(off, arg3);
8189 if (is_error(ret)) {
8190 break;
8192 offp = &off;
8194 ret = get_errno(sendfile(arg1, arg2, offp, arg4));
8195 if (!is_error(ret) && arg3) {
8196 abi_long ret2 = put_user_s64(off, arg3);
8197 if (is_error(ret2)) {
8198 ret = ret2;
8201 break;
8203 #endif
8204 #else
8205 case TARGET_NR_sendfile:
8206 #ifdef TARGET_NR_sendfile64
8207 case TARGET_NR_sendfile64:
8208 #endif
8209 goto unimplemented;
8210 #endif
8212 #ifdef TARGET_NR_getpmsg
8213 case TARGET_NR_getpmsg:
8214 goto unimplemented;
8215 #endif
8216 #ifdef TARGET_NR_putpmsg
8217 case TARGET_NR_putpmsg:
8218 goto unimplemented;
8219 #endif
8220 #ifdef TARGET_NR_vfork
8221 case TARGET_NR_vfork:
8222 ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
8223 0, 0, 0, 0));
8224 break;
8225 #endif
8226 #ifdef TARGET_NR_ugetrlimit
8227 case TARGET_NR_ugetrlimit:
8229 struct rlimit rlim;
8230 int resource = target_to_host_resource(arg1);
8231 ret = get_errno(getrlimit(resource, &rlim));
8232 if (!is_error(ret)) {
8233 struct target_rlimit *target_rlim;
8234 if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
8235 goto efault;
8236 target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
8237 target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
8238 unlock_user_struct(target_rlim, arg2, 1);
8240 break;
8242 #endif
8243 #ifdef TARGET_NR_truncate64
8244 case TARGET_NR_truncate64:
8245 if (!(p = lock_user_string(arg1)))
8246 goto efault;
8247 ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
8248 unlock_user(p, arg1, 0);
8249 break;
8250 #endif
8251 #ifdef TARGET_NR_ftruncate64
8252 case TARGET_NR_ftruncate64:
8253 ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
8254 break;
8255 #endif
8256 #ifdef TARGET_NR_stat64
8257 case TARGET_NR_stat64:
8258 if (!(p = lock_user_string(arg1)))
8259 goto efault;
8260 ret = get_errno(stat(path(p), &st));
8261 unlock_user(p, arg1, 0);
8262 if (!is_error(ret))
8263 ret = host_to_target_stat64(cpu_env, arg2, &st);
8264 break;
8265 #endif
8266 #ifdef TARGET_NR_lstat64
8267 case TARGET_NR_lstat64:
8268 if (!(p = lock_user_string(arg1)))
8269 goto efault;
8270 ret = get_errno(lstat(path(p), &st));
8271 unlock_user(p, arg1, 0);
8272 if (!is_error(ret))
8273 ret = host_to_target_stat64(cpu_env, arg2, &st);
8274 break;
8275 #endif
8276 #ifdef TARGET_NR_fstat64
8277 case TARGET_NR_fstat64:
8278 ret = get_errno(fstat(arg1, &st));
8279 if (!is_error(ret))
8280 ret = host_to_target_stat64(cpu_env, arg2, &st);
8281 break;
8282 #endif
8283 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
8284 #ifdef TARGET_NR_fstatat64
8285 case TARGET_NR_fstatat64:
8286 #endif
8287 #ifdef TARGET_NR_newfstatat
8288 case TARGET_NR_newfstatat:
8289 #endif
8290 if (!(p = lock_user_string(arg2)))
8291 goto efault;
8292 ret = get_errno(fstatat(arg1, path(p), &st, arg4));
8293 if (!is_error(ret))
8294 ret = host_to_target_stat64(cpu_env, arg3, &st);
8295 break;
8296 #endif
8297 case TARGET_NR_lchown:
8298 if (!(p = lock_user_string(arg1)))
8299 goto efault;
8300 ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
8301 unlock_user(p, arg1, 0);
8302 break;
8303 #ifdef TARGET_NR_getuid
8304 case TARGET_NR_getuid:
8305 ret = get_errno(high2lowuid(getuid()));
8306 break;
8307 #endif
8308 #ifdef TARGET_NR_getgid
8309 case TARGET_NR_getgid:
8310 ret = get_errno(high2lowgid(getgid()));
8311 break;
8312 #endif
8313 #ifdef TARGET_NR_geteuid
8314 case TARGET_NR_geteuid:
8315 ret = get_errno(high2lowuid(geteuid()));
8316 break;
8317 #endif
8318 #ifdef TARGET_NR_getegid
8319 case TARGET_NR_getegid:
8320 ret = get_errno(high2lowgid(getegid()));
8321 break;
8322 #endif
8323 case TARGET_NR_setreuid:
8324 ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
8325 break;
8326 case TARGET_NR_setregid:
8327 ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
8328 break;
8329 case TARGET_NR_getgroups:
8331 int gidsetsize = arg1;
8332 target_id *target_grouplist;
8333 gid_t *grouplist;
8334 int i;
8336 grouplist = alloca(gidsetsize * sizeof(gid_t));
8337 ret = get_errno(getgroups(gidsetsize, grouplist));
8338 if (gidsetsize == 0)
8339 break;
8340 if (!is_error(ret)) {
8341 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
8342 if (!target_grouplist)
8343 goto efault;
8344 for(i = 0;i < ret; i++)
8345 target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
8346 unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
8349 break;
8350 case TARGET_NR_setgroups:
8352 int gidsetsize = arg1;
8353 target_id *target_grouplist;
8354 gid_t *grouplist = NULL;
8355 int i;
8356 if (gidsetsize) {
8357 grouplist = alloca(gidsetsize * sizeof(gid_t));
8358 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
8359 if (!target_grouplist) {
8360 ret = -TARGET_EFAULT;
8361 goto fail;
8363 for (i = 0; i < gidsetsize; i++) {
8364 grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
8366 unlock_user(target_grouplist, arg2, 0);
8368 ret = get_errno(setgroups(gidsetsize, grouplist));
8370 break;
8371 case TARGET_NR_fchown:
8372 ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
8373 break;
8374 #if defined(TARGET_NR_fchownat)
8375 case TARGET_NR_fchownat:
8376 if (!(p = lock_user_string(arg2)))
8377 goto efault;
8378 ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
8379 low2highgid(arg4), arg5));
8380 unlock_user(p, arg2, 0);
8381 break;
8382 #endif
8383 #ifdef TARGET_NR_setresuid
8384 case TARGET_NR_setresuid:
8385 ret = get_errno(setresuid(low2highuid(arg1),
8386 low2highuid(arg2),
8387 low2highuid(arg3)));
8388 break;
8389 #endif
8390 #ifdef TARGET_NR_getresuid
8391 case TARGET_NR_getresuid:
8393 uid_t ruid, euid, suid;
8394 ret = get_errno(getresuid(&ruid, &euid, &suid));
8395 if (!is_error(ret)) {
8396 if (put_user_id(high2lowuid(ruid), arg1)
8397 || put_user_id(high2lowuid(euid), arg2)
8398 || put_user_id(high2lowuid(suid), arg3))
8399 goto efault;
8402 break;
8403 #endif
8404 #ifdef TARGET_NR_getresgid
8405 case TARGET_NR_setresgid:
8406 ret = get_errno(setresgid(low2highgid(arg1),
8407 low2highgid(arg2),
8408 low2highgid(arg3)));
8409 break;
8410 #endif
8411 #ifdef TARGET_NR_getresgid
8412 case TARGET_NR_getresgid:
8414 gid_t rgid, egid, sgid;
8415 ret = get_errno(getresgid(&rgid, &egid, &sgid));
8416 if (!is_error(ret)) {
8417 if (put_user_id(high2lowgid(rgid), arg1)
8418 || put_user_id(high2lowgid(egid), arg2)
8419 || put_user_id(high2lowgid(sgid), arg3))
8420 goto efault;
8423 break;
8424 #endif
8425 case TARGET_NR_chown:
8426 if (!(p = lock_user_string(arg1)))
8427 goto efault;
8428 ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
8429 unlock_user(p, arg1, 0);
8430 break;
8431 case TARGET_NR_setuid:
8432 ret = get_errno(setuid(low2highuid(arg1)));
8433 break;
8434 case TARGET_NR_setgid:
8435 ret = get_errno(setgid(low2highgid(arg1)));
8436 break;
8437 case TARGET_NR_setfsuid:
8438 ret = get_errno(setfsuid(arg1));
8439 break;
8440 case TARGET_NR_setfsgid:
8441 ret = get_errno(setfsgid(arg1));
8442 break;
8444 #ifdef TARGET_NR_lchown32
8445 case TARGET_NR_lchown32:
8446 if (!(p = lock_user_string(arg1)))
8447 goto efault;
8448 ret = get_errno(lchown(p, arg2, arg3));
8449 unlock_user(p, arg1, 0);
8450 break;
8451 #endif
8452 #ifdef TARGET_NR_getuid32
8453 case TARGET_NR_getuid32:
8454 ret = get_errno(getuid());
8455 break;
8456 #endif
8458 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
8459 /* Alpha specific */
8460 case TARGET_NR_getxuid:
8462 uid_t euid;
8463 euid=geteuid();
8464 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
8466 ret = get_errno(getuid());
8467 break;
8468 #endif
8469 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
8470 /* Alpha specific */
8471 case TARGET_NR_getxgid:
8473 uid_t egid;
8474 egid=getegid();
8475 ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
8477 ret = get_errno(getgid());
8478 break;
8479 #endif
8480 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
8481 /* Alpha specific */
8482 case TARGET_NR_osf_getsysinfo:
8483 ret = -TARGET_EOPNOTSUPP;
8484 switch (arg1) {
8485 case TARGET_GSI_IEEE_FP_CONTROL:
8487 uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
8489 /* Copied from linux ieee_fpcr_to_swcr. */
8490 swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
8491 swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
8492 swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
8493 | SWCR_TRAP_ENABLE_DZE
8494 | SWCR_TRAP_ENABLE_OVF);
8495 swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
8496 | SWCR_TRAP_ENABLE_INE);
8497 swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
8498 swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
8500 if (put_user_u64 (swcr, arg2))
8501 goto efault;
8502 ret = 0;
8504 break;
8506 /* case GSI_IEEE_STATE_AT_SIGNAL:
8507 -- Not implemented in linux kernel.
8508 case GSI_UACPROC:
8509 -- Retrieves current unaligned access state; not much used.
8510 case GSI_PROC_TYPE:
8511 -- Retrieves implver information; surely not used.
8512 case GSI_GET_HWRPB:
8513 -- Grabs a copy of the HWRPB; surely not used.
8516 break;
8517 #endif
8518 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8519 /* Alpha specific */
8520 case TARGET_NR_osf_setsysinfo:
8521 ret = -TARGET_EOPNOTSUPP;
8522 switch (arg1) {
8523 case TARGET_SSI_IEEE_FP_CONTROL:
8525 uint64_t swcr, fpcr, orig_fpcr;
8527 if (get_user_u64 (swcr, arg2)) {
8528 goto efault;
8530 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8531 fpcr = orig_fpcr & FPCR_DYN_MASK;
8533 /* Copied from linux ieee_swcr_to_fpcr. */
8534 fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
8535 fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
8536 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
8537 | SWCR_TRAP_ENABLE_DZE
8538 | SWCR_TRAP_ENABLE_OVF)) << 48;
8539 fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
8540 | SWCR_TRAP_ENABLE_INE)) << 57;
8541 fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
8542 fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
8544 cpu_alpha_store_fpcr(cpu_env, fpcr);
8545 ret = 0;
8547 break;
8549 case TARGET_SSI_IEEE_RAISE_EXCEPTION:
8551 uint64_t exc, fpcr, orig_fpcr;
8552 int si_code;
8554 if (get_user_u64(exc, arg2)) {
8555 goto efault;
8558 orig_fpcr = cpu_alpha_load_fpcr(cpu_env);
8560 /* We only add to the exception status here. */
8561 fpcr = orig_fpcr | ((exc & SWCR_STATUS_MASK) << 35);
8563 cpu_alpha_store_fpcr(cpu_env, fpcr);
8564 ret = 0;
8566 /* Old exceptions are not signaled. */
8567 fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
8569 /* If any exceptions set by this call,
8570 and are unmasked, send a signal. */
8571 si_code = 0;
8572 if ((fpcr & (FPCR_INE | FPCR_INED)) == FPCR_INE) {
8573 si_code = TARGET_FPE_FLTRES;
8575 if ((fpcr & (FPCR_UNF | FPCR_UNFD)) == FPCR_UNF) {
8576 si_code = TARGET_FPE_FLTUND;
8578 if ((fpcr & (FPCR_OVF | FPCR_OVFD)) == FPCR_OVF) {
8579 si_code = TARGET_FPE_FLTOVF;
8581 if ((fpcr & (FPCR_DZE | FPCR_DZED)) == FPCR_DZE) {
8582 si_code = TARGET_FPE_FLTDIV;
8584 if ((fpcr & (FPCR_INV | FPCR_INVD)) == FPCR_INV) {
8585 si_code = TARGET_FPE_FLTINV;
8587 if (si_code != 0) {
8588 target_siginfo_t info;
8589 info.si_signo = SIGFPE;
8590 info.si_errno = 0;
8591 info.si_code = si_code;
8592 info._sifields._sigfault._addr
8593 = ((CPUArchState *)cpu_env)->pc;
8594 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
8597 break;
8599 /* case SSI_NVPAIRS:
8600 -- Used with SSIN_UACPROC to enable unaligned accesses.
8601 case SSI_IEEE_STATE_AT_SIGNAL:
8602 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
8603 -- Not implemented in linux kernel
8606 break;
8607 #endif
8608 #ifdef TARGET_NR_osf_sigprocmask
8609 /* Alpha specific. */
8610 case TARGET_NR_osf_sigprocmask:
8612 abi_ulong mask;
8613 int how;
8614 sigset_t set, oldset;
8616 switch(arg1) {
8617 case TARGET_SIG_BLOCK:
8618 how = SIG_BLOCK;
8619 break;
8620 case TARGET_SIG_UNBLOCK:
8621 how = SIG_UNBLOCK;
8622 break;
8623 case TARGET_SIG_SETMASK:
8624 how = SIG_SETMASK;
8625 break;
8626 default:
8627 ret = -TARGET_EINVAL;
8628 goto fail;
8630 mask = arg2;
8631 target_to_host_old_sigset(&set, &mask);
8632 do_sigprocmask(how, &set, &oldset);
8633 host_to_target_old_sigset(&mask, &oldset);
8634 ret = mask;
8636 break;
8637 #endif
8639 #ifdef TARGET_NR_getgid32
8640 case TARGET_NR_getgid32:
8641 ret = get_errno(getgid());
8642 break;
8643 #endif
8644 #ifdef TARGET_NR_geteuid32
8645 case TARGET_NR_geteuid32:
8646 ret = get_errno(geteuid());
8647 break;
8648 #endif
8649 #ifdef TARGET_NR_getegid32
8650 case TARGET_NR_getegid32:
8651 ret = get_errno(getegid());
8652 break;
8653 #endif
8654 #ifdef TARGET_NR_setreuid32
8655 case TARGET_NR_setreuid32:
8656 ret = get_errno(setreuid(arg1, arg2));
8657 break;
8658 #endif
8659 #ifdef TARGET_NR_setregid32
8660 case TARGET_NR_setregid32:
8661 ret = get_errno(setregid(arg1, arg2));
8662 break;
8663 #endif
8664 #ifdef TARGET_NR_getgroups32
8665 case TARGET_NR_getgroups32:
8667 int gidsetsize = arg1;
8668 uint32_t *target_grouplist;
8669 gid_t *grouplist;
8670 int i;
8672 grouplist = alloca(gidsetsize * sizeof(gid_t));
8673 ret = get_errno(getgroups(gidsetsize, grouplist));
8674 if (gidsetsize == 0)
8675 break;
8676 if (!is_error(ret)) {
8677 target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
8678 if (!target_grouplist) {
8679 ret = -TARGET_EFAULT;
8680 goto fail;
8682 for(i = 0;i < ret; i++)
8683 target_grouplist[i] = tswap32(grouplist[i]);
8684 unlock_user(target_grouplist, arg2, gidsetsize * 4);
8687 break;
8688 #endif
8689 #ifdef TARGET_NR_setgroups32
8690 case TARGET_NR_setgroups32:
8692 int gidsetsize = arg1;
8693 uint32_t *target_grouplist;
8694 gid_t *grouplist;
8695 int i;
8697 grouplist = alloca(gidsetsize * sizeof(gid_t));
8698 target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
8699 if (!target_grouplist) {
8700 ret = -TARGET_EFAULT;
8701 goto fail;
8703 for(i = 0;i < gidsetsize; i++)
8704 grouplist[i] = tswap32(target_grouplist[i]);
8705 unlock_user(target_grouplist, arg2, 0);
8706 ret = get_errno(setgroups(gidsetsize, grouplist));
8708 break;
8709 #endif
8710 #ifdef TARGET_NR_fchown32
8711 case TARGET_NR_fchown32:
8712 ret = get_errno(fchown(arg1, arg2, arg3));
8713 break;
8714 #endif
8715 #ifdef TARGET_NR_setresuid32
8716 case TARGET_NR_setresuid32:
8717 ret = get_errno(setresuid(arg1, arg2, arg3));
8718 break;
8719 #endif
8720 #ifdef TARGET_NR_getresuid32
8721 case TARGET_NR_getresuid32:
8723 uid_t ruid, euid, suid;
8724 ret = get_errno(getresuid(&ruid, &euid, &suid));
8725 if (!is_error(ret)) {
8726 if (put_user_u32(ruid, arg1)
8727 || put_user_u32(euid, arg2)
8728 || put_user_u32(suid, arg3))
8729 goto efault;
8732 break;
8733 #endif
8734 #ifdef TARGET_NR_setresgid32
8735 case TARGET_NR_setresgid32:
8736 ret = get_errno(setresgid(arg1, arg2, arg3));
8737 break;
8738 #endif
8739 #ifdef TARGET_NR_getresgid32
8740 case TARGET_NR_getresgid32:
8742 gid_t rgid, egid, sgid;
8743 ret = get_errno(getresgid(&rgid, &egid, &sgid));
8744 if (!is_error(ret)) {
8745 if (put_user_u32(rgid, arg1)
8746 || put_user_u32(egid, arg2)
8747 || put_user_u32(sgid, arg3))
8748 goto efault;
8751 break;
8752 #endif
8753 #ifdef TARGET_NR_chown32
8754 case TARGET_NR_chown32:
8755 if (!(p = lock_user_string(arg1)))
8756 goto efault;
8757 ret = get_errno(chown(p, arg2, arg3));
8758 unlock_user(p, arg1, 0);
8759 break;
8760 #endif
8761 #ifdef TARGET_NR_setuid32
8762 case TARGET_NR_setuid32:
8763 ret = get_errno(setuid(arg1));
8764 break;
8765 #endif
8766 #ifdef TARGET_NR_setgid32
8767 case TARGET_NR_setgid32:
8768 ret = get_errno(setgid(arg1));
8769 break;
8770 #endif
8771 #ifdef TARGET_NR_setfsuid32
8772 case TARGET_NR_setfsuid32:
8773 ret = get_errno(setfsuid(arg1));
8774 break;
8775 #endif
8776 #ifdef TARGET_NR_setfsgid32
8777 case TARGET_NR_setfsgid32:
8778 ret = get_errno(setfsgid(arg1));
8779 break;
8780 #endif
8782 case TARGET_NR_pivot_root:
8783 goto unimplemented;
8784 #ifdef TARGET_NR_mincore
8785 case TARGET_NR_mincore:
8787 void *a;
8788 ret = -TARGET_EFAULT;
8789 if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
8790 goto efault;
8791 if (!(p = lock_user_string(arg3)))
8792 goto mincore_fail;
8793 ret = get_errno(mincore(a, arg2, p));
8794 unlock_user(p, arg3, ret);
8795 mincore_fail:
8796 unlock_user(a, arg1, 0);
8798 break;
8799 #endif
8800 #ifdef TARGET_NR_arm_fadvise64_64
8801 case TARGET_NR_arm_fadvise64_64:
8804 * arm_fadvise64_64 looks like fadvise64_64 but
8805 * with different argument order
8807 abi_long temp;
8808 temp = arg3;
8809 arg3 = arg4;
8810 arg4 = temp;
8812 #endif
8813 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8814 #ifdef TARGET_NR_fadvise64_64
8815 case TARGET_NR_fadvise64_64:
8816 #endif
8817 #ifdef TARGET_NR_fadvise64
8818 case TARGET_NR_fadvise64:
8819 #endif
8820 #ifdef TARGET_S390X
8821 switch (arg4) {
8822 case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
8823 case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
8824 case 6: arg4 = POSIX_FADV_DONTNEED; break;
8825 case 7: arg4 = POSIX_FADV_NOREUSE; break;
8826 default: break;
8828 #endif
8829 ret = -posix_fadvise(arg1, arg2, arg3, arg4);
8830 break;
8831 #endif
8832 #ifdef TARGET_NR_madvise
8833 case TARGET_NR_madvise:
8834 /* A straight passthrough may not be safe because qemu sometimes
8835 turns private file-backed mappings into anonymous mappings.
8836 This will break MADV_DONTNEED.
8837 This is a hint, so ignoring and returning success is ok. */
8838 ret = get_errno(0);
8839 break;
8840 #endif
8841 #if TARGET_ABI_BITS == 32
8842 case TARGET_NR_fcntl64:
8844 int cmd;
8845 struct flock64 fl;
8846 struct target_flock64 *target_fl;
8847 #ifdef TARGET_ARM
8848 struct target_eabi_flock64 *target_efl;
8849 #endif
8851 cmd = target_to_host_fcntl_cmd(arg2);
8852 if (cmd == -TARGET_EINVAL) {
8853 ret = cmd;
8854 break;
8857 switch(arg2) {
8858 case TARGET_F_GETLK64:
8859 #ifdef TARGET_ARM
8860 if (((CPUARMState *)cpu_env)->eabi) {
8861 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
8862 goto efault;
8863 fl.l_type = tswap16(target_efl->l_type);
8864 fl.l_whence = tswap16(target_efl->l_whence);
8865 fl.l_start = tswap64(target_efl->l_start);
8866 fl.l_len = tswap64(target_efl->l_len);
8867 fl.l_pid = tswap32(target_efl->l_pid);
8868 unlock_user_struct(target_efl, arg3, 0);
8869 } else
8870 #endif
8872 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
8873 goto efault;
8874 fl.l_type = tswap16(target_fl->l_type);
8875 fl.l_whence = tswap16(target_fl->l_whence);
8876 fl.l_start = tswap64(target_fl->l_start);
8877 fl.l_len = tswap64(target_fl->l_len);
8878 fl.l_pid = tswap32(target_fl->l_pid);
8879 unlock_user_struct(target_fl, arg3, 0);
8881 ret = get_errno(fcntl(arg1, cmd, &fl));
8882 if (ret == 0) {
8883 #ifdef TARGET_ARM
8884 if (((CPUARMState *)cpu_env)->eabi) {
8885 if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0))
8886 goto efault;
8887 target_efl->l_type = tswap16(fl.l_type);
8888 target_efl->l_whence = tswap16(fl.l_whence);
8889 target_efl->l_start = tswap64(fl.l_start);
8890 target_efl->l_len = tswap64(fl.l_len);
8891 target_efl->l_pid = tswap32(fl.l_pid);
8892 unlock_user_struct(target_efl, arg3, 1);
8893 } else
8894 #endif
8896 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0))
8897 goto efault;
8898 target_fl->l_type = tswap16(fl.l_type);
8899 target_fl->l_whence = tswap16(fl.l_whence);
8900 target_fl->l_start = tswap64(fl.l_start);
8901 target_fl->l_len = tswap64(fl.l_len);
8902 target_fl->l_pid = tswap32(fl.l_pid);
8903 unlock_user_struct(target_fl, arg3, 1);
8906 break;
8908 case TARGET_F_SETLK64:
8909 case TARGET_F_SETLKW64:
8910 #ifdef TARGET_ARM
8911 if (((CPUARMState *)cpu_env)->eabi) {
8912 if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1))
8913 goto efault;
8914 fl.l_type = tswap16(target_efl->l_type);
8915 fl.l_whence = tswap16(target_efl->l_whence);
8916 fl.l_start = tswap64(target_efl->l_start);
8917 fl.l_len = tswap64(target_efl->l_len);
8918 fl.l_pid = tswap32(target_efl->l_pid);
8919 unlock_user_struct(target_efl, arg3, 0);
8920 } else
8921 #endif
8923 if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1))
8924 goto efault;
8925 fl.l_type = tswap16(target_fl->l_type);
8926 fl.l_whence = tswap16(target_fl->l_whence);
8927 fl.l_start = tswap64(target_fl->l_start);
8928 fl.l_len = tswap64(target_fl->l_len);
8929 fl.l_pid = tswap32(target_fl->l_pid);
8930 unlock_user_struct(target_fl, arg3, 0);
8932 ret = get_errno(fcntl(arg1, cmd, &fl));
8933 break;
8934 default:
8935 ret = do_fcntl(arg1, arg2, arg3);
8936 break;
8938 break;
8940 #endif
8941 #ifdef TARGET_NR_cacheflush
8942 case TARGET_NR_cacheflush:
8943 /* self-modifying code is handled automatically, so nothing needed */
8944 ret = 0;
8945 break;
8946 #endif
8947 #ifdef TARGET_NR_security
8948 case TARGET_NR_security:
8949 goto unimplemented;
8950 #endif
8951 #ifdef TARGET_NR_getpagesize
8952 case TARGET_NR_getpagesize:
8953 ret = TARGET_PAGE_SIZE;
8954 break;
8955 #endif
8956 case TARGET_NR_gettid:
8957 ret = get_errno(gettid());
8958 break;
8959 #ifdef TARGET_NR_readahead
8960 case TARGET_NR_readahead:
8961 #if TARGET_ABI_BITS == 32
8962 if (regpairs_aligned(cpu_env)) {
8963 arg2 = arg3;
8964 arg3 = arg4;
8965 arg4 = arg5;
8967 ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
8968 #else
8969 ret = get_errno(readahead(arg1, arg2, arg3));
8970 #endif
8971 break;
8972 #endif
8973 #ifdef CONFIG_ATTR
8974 #ifdef TARGET_NR_setxattr
8975 case TARGET_NR_listxattr:
8976 case TARGET_NR_llistxattr:
8978 void *p, *b = 0;
8979 if (arg2) {
8980 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
8981 if (!b) {
8982 ret = -TARGET_EFAULT;
8983 break;
8986 p = lock_user_string(arg1);
8987 if (p) {
8988 if (num == TARGET_NR_listxattr) {
8989 ret = get_errno(listxattr(p, b, arg3));
8990 } else {
8991 ret = get_errno(llistxattr(p, b, arg3));
8993 } else {
8994 ret = -TARGET_EFAULT;
8996 unlock_user(p, arg1, 0);
8997 unlock_user(b, arg2, arg3);
8998 break;
9000 case TARGET_NR_flistxattr:
9002 void *b = 0;
9003 if (arg2) {
9004 b = lock_user(VERIFY_WRITE, arg2, arg3, 0);
9005 if (!b) {
9006 ret = -TARGET_EFAULT;
9007 break;
9010 ret = get_errno(flistxattr(arg1, b, arg3));
9011 unlock_user(b, arg2, arg3);
9012 break;
9014 case TARGET_NR_setxattr:
9015 case TARGET_NR_lsetxattr:
9017 void *p, *n, *v = 0;
9018 if (arg3) {
9019 v = lock_user(VERIFY_READ, arg3, arg4, 1);
9020 if (!v) {
9021 ret = -TARGET_EFAULT;
9022 break;
9025 p = lock_user_string(arg1);
9026 n = lock_user_string(arg2);
9027 if (p && n) {
9028 if (num == TARGET_NR_setxattr) {
9029 ret = get_errno(setxattr(p, n, v, arg4, arg5));
9030 } else {
9031 ret = get_errno(lsetxattr(p, n, v, arg4, arg5));
9033 } else {
9034 ret = -TARGET_EFAULT;
9036 unlock_user(p, arg1, 0);
9037 unlock_user(n, arg2, 0);
9038 unlock_user(v, arg3, 0);
9040 break;
9041 case TARGET_NR_fsetxattr:
9043 void *n, *v = 0;
9044 if (arg3) {
9045 v = lock_user(VERIFY_READ, arg3, arg4, 1);
9046 if (!v) {
9047 ret = -TARGET_EFAULT;
9048 break;
9051 n = lock_user_string(arg2);
9052 if (n) {
9053 ret = get_errno(fsetxattr(arg1, n, v, arg4, arg5));
9054 } else {
9055 ret = -TARGET_EFAULT;
9057 unlock_user(n, arg2, 0);
9058 unlock_user(v, arg3, 0);
9060 break;
9061 case TARGET_NR_getxattr:
9062 case TARGET_NR_lgetxattr:
9064 void *p, *n, *v = 0;
9065 if (arg3) {
9066 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9067 if (!v) {
9068 ret = -TARGET_EFAULT;
9069 break;
9072 p = lock_user_string(arg1);
9073 n = lock_user_string(arg2);
9074 if (p && n) {
9075 if (num == TARGET_NR_getxattr) {
9076 ret = get_errno(getxattr(p, n, v, arg4));
9077 } else {
9078 ret = get_errno(lgetxattr(p, n, v, arg4));
9080 } else {
9081 ret = -TARGET_EFAULT;
9083 unlock_user(p, arg1, 0);
9084 unlock_user(n, arg2, 0);
9085 unlock_user(v, arg3, arg4);
9087 break;
9088 case TARGET_NR_fgetxattr:
9090 void *n, *v = 0;
9091 if (arg3) {
9092 v = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9093 if (!v) {
9094 ret = -TARGET_EFAULT;
9095 break;
9098 n = lock_user_string(arg2);
9099 if (n) {
9100 ret = get_errno(fgetxattr(arg1, n, v, arg4));
9101 } else {
9102 ret = -TARGET_EFAULT;
9104 unlock_user(n, arg2, 0);
9105 unlock_user(v, arg3, arg4);
9107 break;
9108 case TARGET_NR_removexattr:
9109 case TARGET_NR_lremovexattr:
9111 void *p, *n;
9112 p = lock_user_string(arg1);
9113 n = lock_user_string(arg2);
9114 if (p && n) {
9115 if (num == TARGET_NR_removexattr) {
9116 ret = get_errno(removexattr(p, n));
9117 } else {
9118 ret = get_errno(lremovexattr(p, n));
9120 } else {
9121 ret = -TARGET_EFAULT;
9123 unlock_user(p, arg1, 0);
9124 unlock_user(n, arg2, 0);
9126 break;
9127 case TARGET_NR_fremovexattr:
9129 void *n;
9130 n = lock_user_string(arg2);
9131 if (n) {
9132 ret = get_errno(fremovexattr(arg1, n));
9133 } else {
9134 ret = -TARGET_EFAULT;
9136 unlock_user(n, arg2, 0);
9138 break;
9139 #endif
9140 #endif /* CONFIG_ATTR */
9141 #ifdef TARGET_NR_set_thread_area
9142 case TARGET_NR_set_thread_area:
9143 #if defined(TARGET_MIPS)
9144 ((CPUMIPSState *) cpu_env)->active_tc.CP0_UserLocal = arg1;
9145 ret = 0;
9146 break;
9147 #elif defined(TARGET_CRIS)
9148 if (arg1 & 0xff)
9149 ret = -TARGET_EINVAL;
9150 else {
9151 ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
9152 ret = 0;
9154 break;
9155 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
9156 ret = do_set_thread_area(cpu_env, arg1);
9157 break;
9158 #elif defined(TARGET_M68K)
9160 TaskState *ts = cpu->opaque;
9161 ts->tp_value = arg1;
9162 ret = 0;
9163 break;
9165 #else
9166 goto unimplemented_nowarn;
9167 #endif
9168 #endif
9169 #ifdef TARGET_NR_get_thread_area
9170 case TARGET_NR_get_thread_area:
9171 #if defined(TARGET_I386) && defined(TARGET_ABI32)
9172 ret = do_get_thread_area(cpu_env, arg1);
9173 break;
9174 #elif defined(TARGET_M68K)
9176 TaskState *ts = cpu->opaque;
9177 ret = ts->tp_value;
9178 break;
9180 #else
9181 goto unimplemented_nowarn;
9182 #endif
9183 #endif
9184 #ifdef TARGET_NR_getdomainname
9185 case TARGET_NR_getdomainname:
9186 goto unimplemented_nowarn;
9187 #endif
9189 #ifdef TARGET_NR_clock_gettime
9190 case TARGET_NR_clock_gettime:
9192 struct timespec ts;
9193 ret = get_errno(clock_gettime(arg1, &ts));
9194 if (!is_error(ret)) {
9195 host_to_target_timespec(arg2, &ts);
9197 break;
9199 #endif
9200 #ifdef TARGET_NR_clock_getres
9201 case TARGET_NR_clock_getres:
9203 struct timespec ts;
9204 ret = get_errno(clock_getres(arg1, &ts));
9205 if (!is_error(ret)) {
9206 host_to_target_timespec(arg2, &ts);
9208 break;
9210 #endif
9211 #ifdef TARGET_NR_clock_nanosleep
9212 case TARGET_NR_clock_nanosleep:
9214 struct timespec ts;
9215 target_to_host_timespec(&ts, arg3);
9216 ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
9217 if (arg4)
9218 host_to_target_timespec(arg4, &ts);
9220 #if defined(TARGET_PPC)
9221 /* clock_nanosleep is odd in that it returns positive errno values.
9222 * On PPC, CR0 bit 3 should be set in such a situation. */
9223 if (ret) {
9224 ((CPUPPCState *)cpu_env)->crf[0] |= 1;
9226 #endif
9227 break;
9229 #endif
9231 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
9232 case TARGET_NR_set_tid_address:
9233 ret = get_errno(set_tid_address((int *)g2h(arg1)));
9234 break;
9235 #endif
9237 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
9238 case TARGET_NR_tkill:
9239 ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
9240 break;
9241 #endif
9243 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
9244 case TARGET_NR_tgkill:
9245 ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
9246 target_to_host_signal(arg3)));
9247 break;
9248 #endif
9250 #ifdef TARGET_NR_set_robust_list
9251 case TARGET_NR_set_robust_list:
9252 case TARGET_NR_get_robust_list:
9253 /* The ABI for supporting robust futexes has userspace pass
9254 * the kernel a pointer to a linked list which is updated by
9255 * userspace after the syscall; the list is walked by the kernel
9256 * when the thread exits. Since the linked list in QEMU guest
9257 * memory isn't a valid linked list for the host and we have
9258 * no way to reliably intercept the thread-death event, we can't
9259 * support these. Silently return ENOSYS so that guest userspace
9260 * falls back to a non-robust futex implementation (which should
9261 * be OK except in the corner case of the guest crashing while
9262 * holding a mutex that is shared with another process via
9263 * shared memory).
9265 goto unimplemented_nowarn;
9266 #endif
9268 #if defined(TARGET_NR_utimensat)
9269 case TARGET_NR_utimensat:
9271 struct timespec *tsp, ts[2];
9272 if (!arg3) {
9273 tsp = NULL;
9274 } else {
9275 target_to_host_timespec(ts, arg3);
9276 target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
9277 tsp = ts;
9279 if (!arg2)
9280 ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
9281 else {
9282 if (!(p = lock_user_string(arg2))) {
9283 ret = -TARGET_EFAULT;
9284 goto fail;
9286 ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
9287 unlock_user(p, arg2, 0);
9290 break;
9291 #endif
9292 case TARGET_NR_futex:
9293 ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
9294 break;
9295 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
9296 case TARGET_NR_inotify_init:
9297 ret = get_errno(sys_inotify_init());
9298 break;
9299 #endif
9300 #ifdef CONFIG_INOTIFY1
9301 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
9302 case TARGET_NR_inotify_init1:
9303 ret = get_errno(sys_inotify_init1(arg1));
9304 break;
9305 #endif
9306 #endif
9307 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
9308 case TARGET_NR_inotify_add_watch:
9309 p = lock_user_string(arg2);
9310 ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
9311 unlock_user(p, arg2, 0);
9312 break;
9313 #endif
9314 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
9315 case TARGET_NR_inotify_rm_watch:
9316 ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
9317 break;
9318 #endif
9320 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
9321 case TARGET_NR_mq_open:
9323 struct mq_attr posix_mq_attr, *attrp;
9325 p = lock_user_string(arg1 - 1);
9326 if (arg4 != 0) {
9327 copy_from_user_mq_attr (&posix_mq_attr, arg4);
9328 attrp = &posix_mq_attr;
9329 } else {
9330 attrp = 0;
9332 ret = get_errno(mq_open(p, arg2, arg3, attrp));
9333 unlock_user (p, arg1, 0);
9335 break;
9337 case TARGET_NR_mq_unlink:
9338 p = lock_user_string(arg1 - 1);
9339 ret = get_errno(mq_unlink(p));
9340 unlock_user (p, arg1, 0);
9341 break;
9343 case TARGET_NR_mq_timedsend:
9345 struct timespec ts;
9347 p = lock_user (VERIFY_READ, arg2, arg3, 1);
9348 if (arg5 != 0) {
9349 target_to_host_timespec(&ts, arg5);
9350 ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
9351 host_to_target_timespec(arg5, &ts);
9353 else
9354 ret = get_errno(mq_send(arg1, p, arg3, arg4));
9355 unlock_user (p, arg2, arg3);
9357 break;
9359 case TARGET_NR_mq_timedreceive:
9361 struct timespec ts;
9362 unsigned int prio;
9364 p = lock_user (VERIFY_READ, arg2, arg3, 1);
9365 if (arg5 != 0) {
9366 target_to_host_timespec(&ts, arg5);
9367 ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
9368 host_to_target_timespec(arg5, &ts);
9370 else
9371 ret = get_errno(mq_receive(arg1, p, arg3, &prio));
9372 unlock_user (p, arg2, arg3);
9373 if (arg4 != 0)
9374 put_user_u32(prio, arg4);
9376 break;
9378 /* Not implemented for now... */
9379 /* case TARGET_NR_mq_notify: */
9380 /* break; */
9382 case TARGET_NR_mq_getsetattr:
9384 struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
9385 ret = 0;
9386 if (arg3 != 0) {
9387 ret = mq_getattr(arg1, &posix_mq_attr_out);
9388 copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
9390 if (arg2 != 0) {
9391 copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
9392 ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
9396 break;
9397 #endif
9399 #ifdef CONFIG_SPLICE
9400 #ifdef TARGET_NR_tee
9401 case TARGET_NR_tee:
9403 ret = get_errno(tee(arg1,arg2,arg3,arg4));
9405 break;
9406 #endif
9407 #ifdef TARGET_NR_splice
9408 case TARGET_NR_splice:
9410 loff_t loff_in, loff_out;
9411 loff_t *ploff_in = NULL, *ploff_out = NULL;
9412 if (arg2) {
9413 if (get_user_u64(loff_in, arg2)) {
9414 goto efault;
9416 ploff_in = &loff_in;
9418 if (arg4) {
9419 if (get_user_u64(loff_out, arg4)) {
9420 goto efault;
9422 ploff_out = &loff_out;
9424 ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
9425 if (arg2) {
9426 if (put_user_u64(loff_in, arg2)) {
9427 goto efault;
9430 if (arg4) {
9431 if (put_user_u64(loff_out, arg4)) {
9432 goto efault;
9436 break;
9437 #endif
9438 #ifdef TARGET_NR_vmsplice
9439 case TARGET_NR_vmsplice:
9441 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
9442 if (vec != NULL) {
9443 ret = get_errno(vmsplice(arg1, vec, arg3, arg4));
9444 unlock_iovec(vec, arg2, arg3, 0);
9445 } else {
9446 ret = -host_to_target_errno(errno);
9449 break;
9450 #endif
9451 #endif /* CONFIG_SPLICE */
9452 #ifdef CONFIG_EVENTFD
9453 #if defined(TARGET_NR_eventfd)
9454 case TARGET_NR_eventfd:
9455 ret = get_errno(eventfd(arg1, 0));
9456 break;
9457 #endif
9458 #if defined(TARGET_NR_eventfd2)
9459 case TARGET_NR_eventfd2:
9461 int host_flags = arg2 & (~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC));
9462 if (arg2 & TARGET_O_NONBLOCK) {
9463 host_flags |= O_NONBLOCK;
9465 if (arg2 & TARGET_O_CLOEXEC) {
9466 host_flags |= O_CLOEXEC;
9468 ret = get_errno(eventfd(arg1, host_flags));
9469 break;
9471 #endif
9472 #endif /* CONFIG_EVENTFD */
9473 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
9474 case TARGET_NR_fallocate:
9475 #if TARGET_ABI_BITS == 32
9476 ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
9477 target_offset64(arg5, arg6)));
9478 #else
9479 ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
9480 #endif
9481 break;
9482 #endif
9483 #if defined(CONFIG_SYNC_FILE_RANGE)
9484 #if defined(TARGET_NR_sync_file_range)
9485 case TARGET_NR_sync_file_range:
9486 #if TARGET_ABI_BITS == 32
9487 #if defined(TARGET_MIPS)
9488 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9489 target_offset64(arg5, arg6), arg7));
9490 #else
9491 ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
9492 target_offset64(arg4, arg5), arg6));
9493 #endif /* !TARGET_MIPS */
9494 #else
9495 ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
9496 #endif
9497 break;
9498 #endif
9499 #if defined(TARGET_NR_sync_file_range2)
9500 case TARGET_NR_sync_file_range2:
9501 /* This is like sync_file_range but the arguments are reordered */
9502 #if TARGET_ABI_BITS == 32
9503 ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
9504 target_offset64(arg5, arg6), arg2));
9505 #else
9506 ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
9507 #endif
9508 break;
9509 #endif
9510 #endif
9511 #if defined(CONFIG_EPOLL)
9512 #if defined(TARGET_NR_epoll_create)
9513 case TARGET_NR_epoll_create:
9514 ret = get_errno(epoll_create(arg1));
9515 break;
9516 #endif
9517 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
9518 case TARGET_NR_epoll_create1:
9519 ret = get_errno(epoll_create1(arg1));
9520 break;
9521 #endif
9522 #if defined(TARGET_NR_epoll_ctl)
9523 case TARGET_NR_epoll_ctl:
9525 struct epoll_event ep;
9526 struct epoll_event *epp = 0;
9527 if (arg4) {
9528 struct target_epoll_event *target_ep;
9529 if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
9530 goto efault;
9532 ep.events = tswap32(target_ep->events);
9533 /* The epoll_data_t union is just opaque data to the kernel,
9534 * so we transfer all 64 bits across and need not worry what
9535 * actual data type it is.
9537 ep.data.u64 = tswap64(target_ep->data.u64);
9538 unlock_user_struct(target_ep, arg4, 0);
9539 epp = &ep;
9541 ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
9542 break;
9544 #endif
9546 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9547 #define IMPLEMENT_EPOLL_PWAIT
9548 #endif
9549 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9550 #if defined(TARGET_NR_epoll_wait)
9551 case TARGET_NR_epoll_wait:
9552 #endif
9553 #if defined(IMPLEMENT_EPOLL_PWAIT)
9554 case TARGET_NR_epoll_pwait:
9555 #endif
9557 struct target_epoll_event *target_ep;
9558 struct epoll_event *ep;
9559 int epfd = arg1;
9560 int maxevents = arg3;
9561 int timeout = arg4;
9563 target_ep = lock_user(VERIFY_WRITE, arg2,
9564 maxevents * sizeof(struct target_epoll_event), 1);
9565 if (!target_ep) {
9566 goto efault;
9569 ep = alloca(maxevents * sizeof(struct epoll_event));
9571 switch (num) {
9572 #if defined(IMPLEMENT_EPOLL_PWAIT)
9573 case TARGET_NR_epoll_pwait:
9575 target_sigset_t *target_set;
9576 sigset_t _set, *set = &_set;
9578 if (arg5) {
9579 target_set = lock_user(VERIFY_READ, arg5,
9580 sizeof(target_sigset_t), 1);
9581 if (!target_set) {
9582 unlock_user(target_ep, arg2, 0);
9583 goto efault;
9585 target_to_host_sigset(set, target_set);
9586 unlock_user(target_set, arg5, 0);
9587 } else {
9588 set = NULL;
9591 ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
9592 break;
9594 #endif
9595 #if defined(TARGET_NR_epoll_wait)
9596 case TARGET_NR_epoll_wait:
9597 ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
9598 break;
9599 #endif
9600 default:
9601 ret = -TARGET_ENOSYS;
9603 if (!is_error(ret)) {
9604 int i;
9605 for (i = 0; i < ret; i++) {
9606 target_ep[i].events = tswap32(ep[i].events);
9607 target_ep[i].data.u64 = tswap64(ep[i].data.u64);
9610 unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
9611 break;
9613 #endif
9614 #endif
9615 #ifdef TARGET_NR_prlimit64
9616 case TARGET_NR_prlimit64:
9618 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
9619 struct target_rlimit64 *target_rnew, *target_rold;
9620 struct host_rlimit64 rnew, rold, *rnewp = 0;
9621 int resource = target_to_host_resource(arg2);
9622 if (arg3) {
9623 if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
9624 goto efault;
9626 rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
9627 rnew.rlim_max = tswap64(target_rnew->rlim_max);
9628 unlock_user_struct(target_rnew, arg3, 0);
9629 rnewp = &rnew;
9632 ret = get_errno(sys_prlimit64(arg1, resource, rnewp, arg4 ? &rold : 0));
9633 if (!is_error(ret) && arg4) {
9634 if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
9635 goto efault;
9637 target_rold->rlim_cur = tswap64(rold.rlim_cur);
9638 target_rold->rlim_max = tswap64(rold.rlim_max);
9639 unlock_user_struct(target_rold, arg4, 1);
9641 break;
9643 #endif
9644 #ifdef TARGET_NR_gethostname
9645 case TARGET_NR_gethostname:
9647 char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0);
9648 if (name) {
9649 ret = get_errno(gethostname(name, arg2));
9650 unlock_user(name, arg1, arg2);
9651 } else {
9652 ret = -TARGET_EFAULT;
9654 break;
9656 #endif
9657 #ifdef TARGET_NR_atomic_cmpxchg_32
9658 case TARGET_NR_atomic_cmpxchg_32:
9660 /* should use start_exclusive from main.c */
9661 abi_ulong mem_value;
9662 if (get_user_u32(mem_value, arg6)) {
9663 target_siginfo_t info;
9664 info.si_signo = SIGSEGV;
9665 info.si_errno = 0;
9666 info.si_code = TARGET_SEGV_MAPERR;
9667 info._sifields._sigfault._addr = arg6;
9668 queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
9669 ret = 0xdeadbeef;
9672 if (mem_value == arg2)
9673 put_user_u32(arg1, arg6);
9674 ret = mem_value;
9675 break;
9677 #endif
9678 #ifdef TARGET_NR_atomic_barrier
9679 case TARGET_NR_atomic_barrier:
9681 /* Like the kernel implementation and the qemu arm barrier, no-op this? */
9682 ret = 0;
9683 break;
9685 #endif
9687 #ifdef TARGET_NR_timer_create
9688 case TARGET_NR_timer_create:
9690 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
9692 struct sigevent host_sevp = { {0}, }, *phost_sevp = NULL;
9694 int clkid = arg1;
9695 int timer_index = next_free_host_timer();
9697 if (timer_index < 0) {
9698 ret = -TARGET_EAGAIN;
9699 } else {
9700 timer_t *phtimer = g_posix_timers + timer_index;
9702 if (arg2) {
9703 phost_sevp = &host_sevp;
9704 ret = target_to_host_sigevent(phost_sevp, arg2);
9705 if (ret != 0) {
9706 break;
9710 ret = get_errno(timer_create(clkid, phost_sevp, phtimer));
9711 if (ret) {
9712 phtimer = NULL;
9713 } else {
9714 if (put_user(TIMER_MAGIC | timer_index, arg3, target_timer_t)) {
9715 goto efault;
9719 break;
9721 #endif
9723 #ifdef TARGET_NR_timer_settime
9724 case TARGET_NR_timer_settime:
9726 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
9727 * struct itimerspec * old_value */
9728 target_timer_t timerid = get_timer_id(arg1);
9730 if (timerid < 0) {
9731 ret = timerid;
9732 } else if (arg3 == 0) {
9733 ret = -TARGET_EINVAL;
9734 } else {
9735 timer_t htimer = g_posix_timers[timerid];
9736 struct itimerspec hspec_new = {{0},}, hspec_old = {{0},};
9738 target_to_host_itimerspec(&hspec_new, arg3);
9739 ret = get_errno(
9740 timer_settime(htimer, arg2, &hspec_new, &hspec_old));
9741 host_to_target_itimerspec(arg2, &hspec_old);
9743 break;
9745 #endif
9747 #ifdef TARGET_NR_timer_gettime
9748 case TARGET_NR_timer_gettime:
9750 /* args: timer_t timerid, struct itimerspec *curr_value */
9751 target_timer_t timerid = get_timer_id(arg1);
9753 if (timerid < 0) {
9754 ret = timerid;
9755 } else if (!arg2) {
9756 ret = -TARGET_EFAULT;
9757 } else {
9758 timer_t htimer = g_posix_timers[timerid];
9759 struct itimerspec hspec;
9760 ret = get_errno(timer_gettime(htimer, &hspec));
9762 if (host_to_target_itimerspec(arg2, &hspec)) {
9763 ret = -TARGET_EFAULT;
9766 break;
9768 #endif
9770 #ifdef TARGET_NR_timer_getoverrun
9771 case TARGET_NR_timer_getoverrun:
9773 /* args: timer_t timerid */
9774 target_timer_t timerid = get_timer_id(arg1);
9776 if (timerid < 0) {
9777 ret = timerid;
9778 } else {
9779 timer_t htimer = g_posix_timers[timerid];
9780 ret = get_errno(timer_getoverrun(htimer));
9782 break;
9784 #endif
9786 #ifdef TARGET_NR_timer_delete
9787 case TARGET_NR_timer_delete:
9789 /* args: timer_t timerid */
9790 target_timer_t timerid = get_timer_id(arg1);
9792 if (timerid < 0) {
9793 ret = timerid;
9794 } else {
9795 timer_t htimer = g_posix_timers[timerid];
9796 ret = get_errno(timer_delete(htimer));
9797 g_posix_timers[timerid] = 0;
9799 break;
9801 #endif
9803 #if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
9804 case TARGET_NR_timerfd_create:
9805 ret = get_errno(timerfd_create(arg1,
9806 target_to_host_bitmask(arg2, fcntl_flags_tbl)));
9807 break;
9808 #endif
9810 #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
9811 case TARGET_NR_timerfd_gettime:
9813 struct itimerspec its_curr;
9815 ret = get_errno(timerfd_gettime(arg1, &its_curr));
9817 if (arg2 && host_to_target_itimerspec(arg2, &its_curr)) {
9818 goto efault;
9821 break;
9822 #endif
9824 #if defined(TARGET_NR_timerfd_settime) && defined(CONFIG_TIMERFD)
9825 case TARGET_NR_timerfd_settime:
9827 struct itimerspec its_new, its_old, *p_new;
9829 if (arg3) {
9830 if (target_to_host_itimerspec(&its_new, arg3)) {
9831 goto efault;
9833 p_new = &its_new;
9834 } else {
9835 p_new = NULL;
9838 ret = get_errno(timerfd_settime(arg1, arg2, p_new, &its_old));
9840 if (arg4 && host_to_target_itimerspec(arg4, &its_old)) {
9841 goto efault;
9844 break;
9845 #endif
9847 #if defined(TARGET_NR_ioprio_get) && defined(__NR_ioprio_get)
9848 case TARGET_NR_ioprio_get:
9849 ret = get_errno(ioprio_get(arg1, arg2));
9850 break;
9851 #endif
9853 #if defined(TARGET_NR_ioprio_set) && defined(__NR_ioprio_set)
9854 case TARGET_NR_ioprio_set:
9855 ret = get_errno(ioprio_set(arg1, arg2, arg3));
9856 break;
9857 #endif
9859 #if defined(TARGET_NR_setns) && defined(CONFIG_SETNS)
9860 case TARGET_NR_setns:
9861 ret = get_errno(setns(arg1, arg2));
9862 break;
9863 #endif
9864 #if defined(TARGET_NR_unshare) && defined(CONFIG_SETNS)
9865 case TARGET_NR_unshare:
9866 ret = get_errno(unshare(arg1));
9867 break;
9868 #endif
9870 default:
9871 unimplemented:
9872 gemu_log("qemu: Unsupported syscall: %d\n", num);
9873 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
9874 unimplemented_nowarn:
9875 #endif
9876 ret = -TARGET_ENOSYS;
9877 break;
9879 fail:
9880 #ifdef DEBUG
9881 gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
9882 #endif
9883 if(do_strace)
9884 print_syscall_ret(num, ret);
9885 return ret;
9886 efault:
9887 ret = -TARGET_EFAULT;
9888 goto fail;