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
32 #include <sys/types.h>
38 #include <sys/mount.h>
40 #include <sys/fsuid.h>
41 #include <sys/personality.h>
42 #include <sys/prctl.h>
43 #include <sys/resource.h>
49 int __clone2(int (*fn
)(void *), void *child_stack_base
,
50 size_t stack_size
, int flags
, void *arg
, ...);
52 #include <sys/socket.h>
56 #include <sys/times.h>
59 #include <sys/statfs.h>
61 #include <sys/sysinfo.h>
62 #include <sys/utsname.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"
73 #include <sys/eventfd.h>
76 #include <sys/epoll.h>
79 #include "qemu/xattr.h"
81 #ifdef CONFIG_SENDFILE
82 #include <sys/sendfile.h>
85 #define termios host_termios
86 #define winsize host_winsize
87 #define termio host_termio
88 #define sgttyb host_sgttyb /* same as target */
89 #define tchars host_tchars /* same as target */
90 #define ltchars host_ltchars /* same as target */
92 #include <linux/termios.h>
93 #include <linux/unistd.h>
94 #include <linux/utsname.h>
95 #include <linux/cdrom.h>
96 #include <linux/hdreg.h>
97 #include <linux/soundcard.h>
99 #include <linux/mtio.h>
100 #include <linux/fs.h>
101 #if defined(CONFIG_FIEMAP)
102 #include <linux/fiemap.h>
104 #include <linux/fb.h>
105 #include <linux/vt.h>
106 #include <linux/dm-ioctl.h>
107 #include <linux/reboot.h>
108 #include <linux/route.h>
109 #include <linux/filter.h>
110 #include "linux_loop.h"
111 #include "cpu-uname.h"
115 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
116 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
120 //#include <linux/msdos_fs.h>
121 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
122 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
133 #define _syscall0(type,name) \
134 static type name (void) \
136 return syscall(__NR_##name); \
139 #define _syscall1(type,name,type1,arg1) \
140 static type name (type1 arg1) \
142 return syscall(__NR_##name, arg1); \
145 #define _syscall2(type,name,type1,arg1,type2,arg2) \
146 static type name (type1 arg1,type2 arg2) \
148 return syscall(__NR_##name, arg1, arg2); \
151 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
152 static type name (type1 arg1,type2 arg2,type3 arg3) \
154 return syscall(__NR_##name, arg1, arg2, arg3); \
157 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
158 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
160 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
163 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
165 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
167 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
171 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
172 type5,arg5,type6,arg6) \
173 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
176 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
180 #define __NR_sys_uname __NR_uname
181 #define __NR_sys_getcwd1 __NR_getcwd
182 #define __NR_sys_getdents __NR_getdents
183 #define __NR_sys_getdents64 __NR_getdents64
184 #define __NR_sys_getpriority __NR_getpriority
185 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
186 #define __NR_sys_syslog __NR_syslog
187 #define __NR_sys_tgkill __NR_tgkill
188 #define __NR_sys_tkill __NR_tkill
189 #define __NR_sys_futex __NR_futex
190 #define __NR_sys_inotify_init __NR_inotify_init
191 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
192 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
194 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
196 #define __NR__llseek __NR_lseek
200 _syscall0(int, gettid
)
202 /* This is a replacement for the host gettid() and must return a host
204 static int gettid(void) {
209 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
211 #if !defined(__NR_getdents) || \
212 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
213 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
215 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
216 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
217 loff_t
*, res
, uint
, wh
);
219 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
220 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
221 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
222 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
224 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
225 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
227 #ifdef __NR_exit_group
228 _syscall1(int,exit_group
,int,error_code
)
230 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
231 _syscall1(int,set_tid_address
,int *,tidptr
)
233 #if defined(TARGET_NR_futex) && defined(__NR_futex)
234 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
235 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
237 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
238 _syscall3(int, sys_sched_getaffinity
, pid_t
, pid
, unsigned int, len
,
239 unsigned long *, user_mask_ptr
);
240 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
241 _syscall3(int, sys_sched_setaffinity
, pid_t
, pid
, unsigned int, len
,
242 unsigned long *, user_mask_ptr
);
243 _syscall4(int, reboot
, int, magic1
, int, magic2
, unsigned int, cmd
,
246 static bitmask_transtbl fcntl_flags_tbl
[] = {
247 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
248 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
249 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
250 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
251 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
252 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
253 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
254 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
255 { TARGET_O_SYNC
, TARGET_O_DSYNC
, O_SYNC
, O_DSYNC
, },
256 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
257 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
258 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
259 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
260 #if defined(O_DIRECT)
261 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
263 #if defined(O_NOATIME)
264 { TARGET_O_NOATIME
, TARGET_O_NOATIME
, O_NOATIME
, O_NOATIME
},
266 #if defined(O_CLOEXEC)
267 { TARGET_O_CLOEXEC
, TARGET_O_CLOEXEC
, O_CLOEXEC
, O_CLOEXEC
},
270 { TARGET_O_PATH
, TARGET_O_PATH
, O_PATH
, O_PATH
},
272 /* Don't terminate the list prematurely on 64-bit host+guest. */
273 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
274 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
279 #define COPY_UTSNAME_FIELD(dest, src) \
281 /* __NEW_UTS_LEN doesn't include terminating null */ \
282 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
283 (dest)[__NEW_UTS_LEN] = '\0'; \
286 static int sys_uname(struct new_utsname
*buf
)
288 struct utsname uts_buf
;
290 if (uname(&uts_buf
) < 0)
294 * Just in case these have some differences, we
295 * translate utsname to new_utsname (which is the
296 * struct linux kernel uses).
299 memset(buf
, 0, sizeof(*buf
));
300 COPY_UTSNAME_FIELD(buf
->sysname
, uts_buf
.sysname
);
301 COPY_UTSNAME_FIELD(buf
->nodename
, uts_buf
.nodename
);
302 COPY_UTSNAME_FIELD(buf
->release
, uts_buf
.release
);
303 COPY_UTSNAME_FIELD(buf
->version
, uts_buf
.version
);
304 COPY_UTSNAME_FIELD(buf
->machine
, uts_buf
.machine
);
306 COPY_UTSNAME_FIELD(buf
->domainname
, uts_buf
.domainname
);
310 #undef COPY_UTSNAME_FIELD
313 static int sys_getcwd1(char *buf
, size_t size
)
315 if (getcwd(buf
, size
) == NULL
) {
316 /* getcwd() sets errno */
319 return strlen(buf
)+1;
322 #ifdef TARGET_NR_openat
323 static int sys_openat(int dirfd
, const char *pathname
, int flags
, mode_t mode
)
326 * open(2) has extra parameter 'mode' when called with
329 if ((flags
& O_CREAT
) != 0) {
330 return (openat(dirfd
, pathname
, flags
, mode
));
332 return (openat(dirfd
, pathname
, flags
));
336 #ifdef TARGET_NR_utimensat
337 #ifdef CONFIG_UTIMENSAT
338 static int sys_utimensat(int dirfd
, const char *pathname
,
339 const struct timespec times
[2], int flags
)
341 if (pathname
== NULL
)
342 return futimens(dirfd
, times
);
344 return utimensat(dirfd
, pathname
, times
, flags
);
346 #elif defined(__NR_utimensat)
347 #define __NR_sys_utimensat __NR_utimensat
348 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
349 const struct timespec
*,tsp
,int,flags
)
351 static int sys_utimensat(int dirfd
, const char *pathname
,
352 const struct timespec times
[2], int flags
)
358 #endif /* TARGET_NR_utimensat */
360 #ifdef CONFIG_INOTIFY
361 #include <sys/inotify.h>
363 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
364 static int sys_inotify_init(void)
366 return (inotify_init());
369 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
370 static int sys_inotify_add_watch(int fd
,const char *pathname
, int32_t mask
)
372 return (inotify_add_watch(fd
, pathname
, mask
));
375 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
376 static int sys_inotify_rm_watch(int fd
, int32_t wd
)
378 return (inotify_rm_watch(fd
, wd
));
381 #ifdef CONFIG_INOTIFY1
382 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
383 static int sys_inotify_init1(int flags
)
385 return (inotify_init1(flags
));
390 /* Userspace can usually survive runtime without inotify */
391 #undef TARGET_NR_inotify_init
392 #undef TARGET_NR_inotify_init1
393 #undef TARGET_NR_inotify_add_watch
394 #undef TARGET_NR_inotify_rm_watch
395 #endif /* CONFIG_INOTIFY */
397 #if defined(TARGET_NR_ppoll)
399 # define __NR_ppoll -1
401 #define __NR_sys_ppoll __NR_ppoll
402 _syscall5(int, sys_ppoll
, struct pollfd
*, fds
, nfds_t
, nfds
,
403 struct timespec
*, timeout
, const __sigset_t
*, sigmask
,
407 #if defined(TARGET_NR_pselect6)
408 #ifndef __NR_pselect6
409 # define __NR_pselect6 -1
411 #define __NR_sys_pselect6 __NR_pselect6
412 _syscall6(int, sys_pselect6
, int, nfds
, fd_set
*, readfds
, fd_set
*, writefds
,
413 fd_set
*, exceptfds
, struct timespec
*, timeout
, void *, sig
);
416 #if defined(TARGET_NR_prlimit64)
417 #ifndef __NR_prlimit64
418 # define __NR_prlimit64 -1
420 #define __NR_sys_prlimit64 __NR_prlimit64
421 /* The glibc rlimit structure may not be that used by the underlying syscall */
422 struct host_rlimit64
{
426 _syscall4(int, sys_prlimit64
, pid_t
, pid
, int, resource
,
427 const struct host_rlimit64
*, new_limit
,
428 struct host_rlimit64
*, old_limit
)
432 #if defined(TARGET_NR_timer_create)
433 /* Maxiumum of 32 active POSIX timers allowed at any one time. */
434 static timer_t g_posix_timers
[32] = { 0, } ;
436 static inline int next_free_host_timer(void)
439 /* FIXME: Does finding the next free slot require a lock? */
440 for (k
= 0; k
< ARRAY_SIZE(g_posix_timers
); k
++) {
441 if (g_posix_timers
[k
] == 0) {
442 g_posix_timers
[k
] = (timer_t
) 1;
450 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
452 static inline int regpairs_aligned(void *cpu_env
) {
453 return ((((CPUARMState
*)cpu_env
)->eabi
) == 1) ;
455 #elif defined(TARGET_MIPS)
456 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
457 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
458 /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
459 * of registers which translates to the same as ARM/MIPS, because we start with
461 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
463 static inline int regpairs_aligned(void *cpu_env
) { return 0; }
466 #define ERRNO_TABLE_SIZE 1200
468 /* target_to_host_errno_table[] is initialized from
469 * host_to_target_errno_table[] in syscall_init(). */
470 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
474 * This list is the union of errno values overridden in asm-<arch>/errno.h
475 * minus the errnos that are not actually generic to all archs.
477 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
478 [EIDRM
] = TARGET_EIDRM
,
479 [ECHRNG
] = TARGET_ECHRNG
,
480 [EL2NSYNC
] = TARGET_EL2NSYNC
,
481 [EL3HLT
] = TARGET_EL3HLT
,
482 [EL3RST
] = TARGET_EL3RST
,
483 [ELNRNG
] = TARGET_ELNRNG
,
484 [EUNATCH
] = TARGET_EUNATCH
,
485 [ENOCSI
] = TARGET_ENOCSI
,
486 [EL2HLT
] = TARGET_EL2HLT
,
487 [EDEADLK
] = TARGET_EDEADLK
,
488 [ENOLCK
] = TARGET_ENOLCK
,
489 [EBADE
] = TARGET_EBADE
,
490 [EBADR
] = TARGET_EBADR
,
491 [EXFULL
] = TARGET_EXFULL
,
492 [ENOANO
] = TARGET_ENOANO
,
493 [EBADRQC
] = TARGET_EBADRQC
,
494 [EBADSLT
] = TARGET_EBADSLT
,
495 [EBFONT
] = TARGET_EBFONT
,
496 [ENOSTR
] = TARGET_ENOSTR
,
497 [ENODATA
] = TARGET_ENODATA
,
498 [ETIME
] = TARGET_ETIME
,
499 [ENOSR
] = TARGET_ENOSR
,
500 [ENONET
] = TARGET_ENONET
,
501 [ENOPKG
] = TARGET_ENOPKG
,
502 [EREMOTE
] = TARGET_EREMOTE
,
503 [ENOLINK
] = TARGET_ENOLINK
,
504 [EADV
] = TARGET_EADV
,
505 [ESRMNT
] = TARGET_ESRMNT
,
506 [ECOMM
] = TARGET_ECOMM
,
507 [EPROTO
] = TARGET_EPROTO
,
508 [EDOTDOT
] = TARGET_EDOTDOT
,
509 [EMULTIHOP
] = TARGET_EMULTIHOP
,
510 [EBADMSG
] = TARGET_EBADMSG
,
511 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
512 [EOVERFLOW
] = TARGET_EOVERFLOW
,
513 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
514 [EBADFD
] = TARGET_EBADFD
,
515 [EREMCHG
] = TARGET_EREMCHG
,
516 [ELIBACC
] = TARGET_ELIBACC
,
517 [ELIBBAD
] = TARGET_ELIBBAD
,
518 [ELIBSCN
] = TARGET_ELIBSCN
,
519 [ELIBMAX
] = TARGET_ELIBMAX
,
520 [ELIBEXEC
] = TARGET_ELIBEXEC
,
521 [EILSEQ
] = TARGET_EILSEQ
,
522 [ENOSYS
] = TARGET_ENOSYS
,
523 [ELOOP
] = TARGET_ELOOP
,
524 [ERESTART
] = TARGET_ERESTART
,
525 [ESTRPIPE
] = TARGET_ESTRPIPE
,
526 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
527 [EUSERS
] = TARGET_EUSERS
,
528 [ENOTSOCK
] = TARGET_ENOTSOCK
,
529 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
530 [EMSGSIZE
] = TARGET_EMSGSIZE
,
531 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
532 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
533 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
534 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
535 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
536 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
537 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
538 [EADDRINUSE
] = TARGET_EADDRINUSE
,
539 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
540 [ENETDOWN
] = TARGET_ENETDOWN
,
541 [ENETUNREACH
] = TARGET_ENETUNREACH
,
542 [ENETRESET
] = TARGET_ENETRESET
,
543 [ECONNABORTED
] = TARGET_ECONNABORTED
,
544 [ECONNRESET
] = TARGET_ECONNRESET
,
545 [ENOBUFS
] = TARGET_ENOBUFS
,
546 [EISCONN
] = TARGET_EISCONN
,
547 [ENOTCONN
] = TARGET_ENOTCONN
,
548 [EUCLEAN
] = TARGET_EUCLEAN
,
549 [ENOTNAM
] = TARGET_ENOTNAM
,
550 [ENAVAIL
] = TARGET_ENAVAIL
,
551 [EISNAM
] = TARGET_EISNAM
,
552 [EREMOTEIO
] = TARGET_EREMOTEIO
,
553 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
554 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
555 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
556 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
557 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
558 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
559 [EALREADY
] = TARGET_EALREADY
,
560 [EINPROGRESS
] = TARGET_EINPROGRESS
,
561 [ESTALE
] = TARGET_ESTALE
,
562 [ECANCELED
] = TARGET_ECANCELED
,
563 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
564 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
566 [ENOKEY
] = TARGET_ENOKEY
,
569 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
572 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
575 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
578 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
580 #ifdef ENOTRECOVERABLE
581 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
585 static inline int host_to_target_errno(int err
)
587 if(host_to_target_errno_table
[err
])
588 return host_to_target_errno_table
[err
];
592 static inline int target_to_host_errno(int err
)
594 if (target_to_host_errno_table
[err
])
595 return target_to_host_errno_table
[err
];
599 static inline abi_long
get_errno(abi_long ret
)
602 return -host_to_target_errno(errno
);
607 static inline int is_error(abi_long ret
)
609 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
612 char *target_strerror(int err
)
614 if ((err
>= ERRNO_TABLE_SIZE
) || (err
< 0)) {
617 return strerror(target_to_host_errno(err
));
620 static abi_ulong target_brk
;
621 static abi_ulong target_original_brk
;
622 static abi_ulong brk_page
;
624 void target_set_brk(abi_ulong new_brk
)
626 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
627 brk_page
= HOST_PAGE_ALIGN(target_brk
);
630 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
631 #define DEBUGF_BRK(message, args...)
633 /* do_brk() must return target values and target errnos. */
634 abi_long
do_brk(abi_ulong new_brk
)
636 abi_long mapped_addr
;
639 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx
") -> ", new_brk
);
642 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (!new_brk)\n", target_brk
);
645 if (new_brk
< target_original_brk
) {
646 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk < target_original_brk)\n",
651 /* If the new brk is less than the highest page reserved to the
652 * target heap allocation, set it and we're almost done... */
653 if (new_brk
<= brk_page
) {
654 /* Heap contents are initialized to zero, as for anonymous
656 if (new_brk
> target_brk
) {
657 memset(g2h(target_brk
), 0, new_brk
- target_brk
);
659 target_brk
= new_brk
;
660 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk <= brk_page)\n", target_brk
);
664 /* We need to allocate more memory after the brk... Note that
665 * we don't use MAP_FIXED because that will map over the top of
666 * any existing mapping (like the one with the host libc or qemu
667 * itself); instead we treat "mapped but at wrong address" as
668 * a failure and unmap again.
670 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
);
671 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
672 PROT_READ
|PROT_WRITE
,
673 MAP_ANON
|MAP_PRIVATE
, 0, 0));
675 if (mapped_addr
== brk_page
) {
676 /* Heap contents are initialized to zero, as for anonymous
677 * mapped pages. Technically the new pages are already
678 * initialized to zero since they *are* anonymous mapped
679 * pages, however we have to take care with the contents that
680 * come from the remaining part of the previous page: it may
681 * contains garbage data due to a previous heap usage (grown
683 memset(g2h(target_brk
), 0, brk_page
- target_brk
);
685 target_brk
= new_brk
;
686 brk_page
= HOST_PAGE_ALIGN(target_brk
);
687 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr == brk_page)\n",
690 } else if (mapped_addr
!= -1) {
691 /* Mapped but at wrong address, meaning there wasn't actually
692 * enough space for this brk.
694 target_munmap(mapped_addr
, new_alloc_size
);
696 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr != -1)\n", target_brk
);
699 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (otherwise)\n", target_brk
);
702 #if defined(TARGET_ALPHA)
703 /* We (partially) emulate OSF/1 on Alpha, which requires we
704 return a proper errno, not an unchanged brk value. */
705 return -TARGET_ENOMEM
;
707 /* For everything else, return the previous break. */
711 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
712 abi_ulong target_fds_addr
,
716 abi_ulong b
, *target_fds
;
718 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
719 if (!(target_fds
= lock_user(VERIFY_READ
,
721 sizeof(abi_ulong
) * nw
,
723 return -TARGET_EFAULT
;
727 for (i
= 0; i
< nw
; i
++) {
728 /* grab the abi_ulong */
729 __get_user(b
, &target_fds
[i
]);
730 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
731 /* check the bit inside the abi_ulong */
738 unlock_user(target_fds
, target_fds_addr
, 0);
743 static inline abi_ulong
copy_from_user_fdset_ptr(fd_set
*fds
, fd_set
**fds_ptr
,
744 abi_ulong target_fds_addr
,
747 if (target_fds_addr
) {
748 if (copy_from_user_fdset(fds
, target_fds_addr
, n
))
749 return -TARGET_EFAULT
;
757 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
763 abi_ulong
*target_fds
;
765 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
766 if (!(target_fds
= lock_user(VERIFY_WRITE
,
768 sizeof(abi_ulong
) * nw
,
770 return -TARGET_EFAULT
;
773 for (i
= 0; i
< nw
; i
++) {
775 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
776 v
|= ((abi_ulong
)(FD_ISSET(k
, fds
) != 0) << j
);
779 __put_user(v
, &target_fds
[i
]);
782 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
787 #if defined(__alpha__)
793 static inline abi_long
host_to_target_clock_t(long ticks
)
795 #if HOST_HZ == TARGET_HZ
798 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
802 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
803 const struct rusage
*rusage
)
805 struct target_rusage
*target_rusage
;
807 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
808 return -TARGET_EFAULT
;
809 target_rusage
->ru_utime
.tv_sec
= tswapal(rusage
->ru_utime
.tv_sec
);
810 target_rusage
->ru_utime
.tv_usec
= tswapal(rusage
->ru_utime
.tv_usec
);
811 target_rusage
->ru_stime
.tv_sec
= tswapal(rusage
->ru_stime
.tv_sec
);
812 target_rusage
->ru_stime
.tv_usec
= tswapal(rusage
->ru_stime
.tv_usec
);
813 target_rusage
->ru_maxrss
= tswapal(rusage
->ru_maxrss
);
814 target_rusage
->ru_ixrss
= tswapal(rusage
->ru_ixrss
);
815 target_rusage
->ru_idrss
= tswapal(rusage
->ru_idrss
);
816 target_rusage
->ru_isrss
= tswapal(rusage
->ru_isrss
);
817 target_rusage
->ru_minflt
= tswapal(rusage
->ru_minflt
);
818 target_rusage
->ru_majflt
= tswapal(rusage
->ru_majflt
);
819 target_rusage
->ru_nswap
= tswapal(rusage
->ru_nswap
);
820 target_rusage
->ru_inblock
= tswapal(rusage
->ru_inblock
);
821 target_rusage
->ru_oublock
= tswapal(rusage
->ru_oublock
);
822 target_rusage
->ru_msgsnd
= tswapal(rusage
->ru_msgsnd
);
823 target_rusage
->ru_msgrcv
= tswapal(rusage
->ru_msgrcv
);
824 target_rusage
->ru_nsignals
= tswapal(rusage
->ru_nsignals
);
825 target_rusage
->ru_nvcsw
= tswapal(rusage
->ru_nvcsw
);
826 target_rusage
->ru_nivcsw
= tswapal(rusage
->ru_nivcsw
);
827 unlock_user_struct(target_rusage
, target_addr
, 1);
832 static inline rlim_t
target_to_host_rlim(abi_ulong target_rlim
)
834 abi_ulong target_rlim_swap
;
837 target_rlim_swap
= tswapal(target_rlim
);
838 if (target_rlim_swap
== TARGET_RLIM_INFINITY
)
839 return RLIM_INFINITY
;
841 result
= target_rlim_swap
;
842 if (target_rlim_swap
!= (rlim_t
)result
)
843 return RLIM_INFINITY
;
848 static inline abi_ulong
host_to_target_rlim(rlim_t rlim
)
850 abi_ulong target_rlim_swap
;
853 if (rlim
== RLIM_INFINITY
|| rlim
!= (abi_long
)rlim
)
854 target_rlim_swap
= TARGET_RLIM_INFINITY
;
856 target_rlim_swap
= rlim
;
857 result
= tswapal(target_rlim_swap
);
862 static inline int target_to_host_resource(int code
)
865 case TARGET_RLIMIT_AS
:
867 case TARGET_RLIMIT_CORE
:
869 case TARGET_RLIMIT_CPU
:
871 case TARGET_RLIMIT_DATA
:
873 case TARGET_RLIMIT_FSIZE
:
875 case TARGET_RLIMIT_LOCKS
:
877 case TARGET_RLIMIT_MEMLOCK
:
878 return RLIMIT_MEMLOCK
;
879 case TARGET_RLIMIT_MSGQUEUE
:
880 return RLIMIT_MSGQUEUE
;
881 case TARGET_RLIMIT_NICE
:
883 case TARGET_RLIMIT_NOFILE
:
884 return RLIMIT_NOFILE
;
885 case TARGET_RLIMIT_NPROC
:
887 case TARGET_RLIMIT_RSS
:
889 case TARGET_RLIMIT_RTPRIO
:
890 return RLIMIT_RTPRIO
;
891 case TARGET_RLIMIT_SIGPENDING
:
892 return RLIMIT_SIGPENDING
;
893 case TARGET_RLIMIT_STACK
:
900 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
901 abi_ulong target_tv_addr
)
903 struct target_timeval
*target_tv
;
905 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
906 return -TARGET_EFAULT
;
908 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
909 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
911 unlock_user_struct(target_tv
, target_tv_addr
, 0);
916 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
917 const struct timeval
*tv
)
919 struct target_timeval
*target_tv
;
921 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
922 return -TARGET_EFAULT
;
924 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
925 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
927 unlock_user_struct(target_tv
, target_tv_addr
, 1);
932 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
935 static inline abi_long
copy_from_user_mq_attr(struct mq_attr
*attr
,
936 abi_ulong target_mq_attr_addr
)
938 struct target_mq_attr
*target_mq_attr
;
940 if (!lock_user_struct(VERIFY_READ
, target_mq_attr
,
941 target_mq_attr_addr
, 1))
942 return -TARGET_EFAULT
;
944 __get_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
945 __get_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
946 __get_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
947 __get_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
949 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 0);
954 static inline abi_long
copy_to_user_mq_attr(abi_ulong target_mq_attr_addr
,
955 const struct mq_attr
*attr
)
957 struct target_mq_attr
*target_mq_attr
;
959 if (!lock_user_struct(VERIFY_WRITE
, target_mq_attr
,
960 target_mq_attr_addr
, 0))
961 return -TARGET_EFAULT
;
963 __put_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
964 __put_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
965 __put_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
966 __put_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
968 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 1);
974 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
975 /* do_select() must return target values and target errnos. */
976 static abi_long
do_select(int n
,
977 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
978 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
980 fd_set rfds
, wfds
, efds
;
981 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
982 struct timeval tv
, *tv_ptr
;
985 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
989 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
993 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
998 if (target_tv_addr
) {
999 if (copy_from_user_timeval(&tv
, target_tv_addr
))
1000 return -TARGET_EFAULT
;
1006 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
1008 if (!is_error(ret
)) {
1009 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
1010 return -TARGET_EFAULT
;
1011 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
1012 return -TARGET_EFAULT
;
1013 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
1014 return -TARGET_EFAULT
;
1016 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
1017 return -TARGET_EFAULT
;
1024 static abi_long
do_pipe2(int host_pipe
[], int flags
)
1027 return pipe2(host_pipe
, flags
);
1033 static abi_long
do_pipe(void *cpu_env
, abi_ulong pipedes
,
1034 int flags
, int is_pipe2
)
1038 ret
= flags
? do_pipe2(host_pipe
, flags
) : pipe(host_pipe
);
1041 return get_errno(ret
);
1043 /* Several targets have special calling conventions for the original
1044 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1046 #if defined(TARGET_ALPHA)
1047 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = host_pipe
[1];
1048 return host_pipe
[0];
1049 #elif defined(TARGET_MIPS)
1050 ((CPUMIPSState
*)cpu_env
)->active_tc
.gpr
[3] = host_pipe
[1];
1051 return host_pipe
[0];
1052 #elif defined(TARGET_SH4)
1053 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
1054 return host_pipe
[0];
1055 #elif defined(TARGET_SPARC)
1056 ((CPUSPARCState
*)cpu_env
)->regwptr
[1] = host_pipe
[1];
1057 return host_pipe
[0];
1061 if (put_user_s32(host_pipe
[0], pipedes
)
1062 || put_user_s32(host_pipe
[1], pipedes
+ sizeof(host_pipe
[0])))
1063 return -TARGET_EFAULT
;
1064 return get_errno(ret
);
1067 static inline abi_long
target_to_host_ip_mreq(struct ip_mreqn
*mreqn
,
1068 abi_ulong target_addr
,
1071 struct target_ip_mreqn
*target_smreqn
;
1073 target_smreqn
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1075 return -TARGET_EFAULT
;
1076 mreqn
->imr_multiaddr
.s_addr
= target_smreqn
->imr_multiaddr
.s_addr
;
1077 mreqn
->imr_address
.s_addr
= target_smreqn
->imr_address
.s_addr
;
1078 if (len
== sizeof(struct target_ip_mreqn
))
1079 mreqn
->imr_ifindex
= tswapal(target_smreqn
->imr_ifindex
);
1080 unlock_user(target_smreqn
, target_addr
, 0);
1085 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
1086 abi_ulong target_addr
,
1089 const socklen_t unix_maxlen
= sizeof (struct sockaddr_un
);
1090 sa_family_t sa_family
;
1091 struct target_sockaddr
*target_saddr
;
1093 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1095 return -TARGET_EFAULT
;
1097 sa_family
= tswap16(target_saddr
->sa_family
);
1099 /* Oops. The caller might send a incomplete sun_path; sun_path
1100 * must be terminated by \0 (see the manual page), but
1101 * unfortunately it is quite common to specify sockaddr_un
1102 * length as "strlen(x->sun_path)" while it should be
1103 * "strlen(...) + 1". We'll fix that here if needed.
1104 * Linux kernel has a similar feature.
1107 if (sa_family
== AF_UNIX
) {
1108 if (len
< unix_maxlen
&& len
> 0) {
1109 char *cp
= (char*)target_saddr
;
1111 if ( cp
[len
-1] && !cp
[len
] )
1114 if (len
> unix_maxlen
)
1118 memcpy(addr
, target_saddr
, len
);
1119 addr
->sa_family
= sa_family
;
1120 unlock_user(target_saddr
, target_addr
, 0);
1125 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
1126 struct sockaddr
*addr
,
1129 struct target_sockaddr
*target_saddr
;
1131 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
1133 return -TARGET_EFAULT
;
1134 memcpy(target_saddr
, addr
, len
);
1135 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
1136 unlock_user(target_saddr
, target_addr
, len
);
1141 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
1142 struct target_msghdr
*target_msgh
)
1144 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1145 abi_long msg_controllen
;
1146 abi_ulong target_cmsg_addr
;
1147 struct target_cmsghdr
*target_cmsg
;
1148 socklen_t space
= 0;
1150 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1151 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1153 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1154 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
1156 return -TARGET_EFAULT
;
1158 while (cmsg
&& target_cmsg
) {
1159 void *data
= CMSG_DATA(cmsg
);
1160 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1162 int len
= tswapal(target_cmsg
->cmsg_len
)
1163 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
1165 space
+= CMSG_SPACE(len
);
1166 if (space
> msgh
->msg_controllen
) {
1167 space
-= CMSG_SPACE(len
);
1168 gemu_log("Host cmsg overflow\n");
1172 if (tswap32(target_cmsg
->cmsg_level
) == TARGET_SOL_SOCKET
) {
1173 cmsg
->cmsg_level
= SOL_SOCKET
;
1175 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
1177 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
1178 cmsg
->cmsg_len
= CMSG_LEN(len
);
1180 if (cmsg
->cmsg_level
!= SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1181 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1182 memcpy(data
, target_data
, len
);
1184 int *fd
= (int *)data
;
1185 int *target_fd
= (int *)target_data
;
1186 int i
, numfds
= len
/ sizeof(int);
1188 for (i
= 0; i
< numfds
; i
++)
1189 fd
[i
] = tswap32(target_fd
[i
]);
1192 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1193 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1195 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
1197 msgh
->msg_controllen
= space
;
1201 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
1202 struct msghdr
*msgh
)
1204 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1205 abi_long msg_controllen
;
1206 abi_ulong target_cmsg_addr
;
1207 struct target_cmsghdr
*target_cmsg
;
1208 socklen_t space
= 0;
1210 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1211 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1213 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1214 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
1216 return -TARGET_EFAULT
;
1218 while (cmsg
&& target_cmsg
) {
1219 void *data
= CMSG_DATA(cmsg
);
1220 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1222 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
1224 space
+= TARGET_CMSG_SPACE(len
);
1225 if (space
> msg_controllen
) {
1226 space
-= TARGET_CMSG_SPACE(len
);
1227 gemu_log("Target cmsg overflow\n");
1231 if (cmsg
->cmsg_level
== SOL_SOCKET
) {
1232 target_cmsg
->cmsg_level
= tswap32(TARGET_SOL_SOCKET
);
1234 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
1236 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
1237 target_cmsg
->cmsg_len
= tswapal(TARGET_CMSG_LEN(len
));
1239 if ((cmsg
->cmsg_level
== SOL_SOCKET
) &&
1240 (cmsg
->cmsg_type
== SCM_RIGHTS
)) {
1241 int *fd
= (int *)data
;
1242 int *target_fd
= (int *)target_data
;
1243 int i
, numfds
= len
/ sizeof(int);
1245 for (i
= 0; i
< numfds
; i
++)
1246 target_fd
[i
] = tswap32(fd
[i
]);
1247 } else if ((cmsg
->cmsg_level
== SOL_SOCKET
) &&
1248 (cmsg
->cmsg_type
== SO_TIMESTAMP
) &&
1249 (len
== sizeof(struct timeval
))) {
1250 /* copy struct timeval to target */
1251 struct timeval
*tv
= (struct timeval
*)data
;
1252 struct target_timeval
*target_tv
=
1253 (struct target_timeval
*)target_data
;
1255 target_tv
->tv_sec
= tswapal(tv
->tv_sec
);
1256 target_tv
->tv_usec
= tswapal(tv
->tv_usec
);
1258 gemu_log("Unsupported ancillary data: %d/%d\n",
1259 cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1260 memcpy(target_data
, data
, len
);
1263 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1264 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1266 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
1268 target_msgh
->msg_controllen
= tswapal(space
);
1272 /* do_setsockopt() Must return target values and target errnos. */
1273 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
1274 abi_ulong optval_addr
, socklen_t optlen
)
1278 struct ip_mreqn
*ip_mreq
;
1279 struct ip_mreq_source
*ip_mreq_source
;
1283 /* TCP options all take an 'int' value. */
1284 if (optlen
< sizeof(uint32_t))
1285 return -TARGET_EINVAL
;
1287 if (get_user_u32(val
, optval_addr
))
1288 return -TARGET_EFAULT
;
1289 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1296 case IP_ROUTER_ALERT
:
1300 case IP_MTU_DISCOVER
:
1306 case IP_MULTICAST_TTL
:
1307 case IP_MULTICAST_LOOP
:
1309 if (optlen
>= sizeof(uint32_t)) {
1310 if (get_user_u32(val
, optval_addr
))
1311 return -TARGET_EFAULT
;
1312 } else if (optlen
>= 1) {
1313 if (get_user_u8(val
, optval_addr
))
1314 return -TARGET_EFAULT
;
1316 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1318 case IP_ADD_MEMBERSHIP
:
1319 case IP_DROP_MEMBERSHIP
:
1320 if (optlen
< sizeof (struct target_ip_mreq
) ||
1321 optlen
> sizeof (struct target_ip_mreqn
))
1322 return -TARGET_EINVAL
;
1324 ip_mreq
= (struct ip_mreqn
*) alloca(optlen
);
1325 target_to_host_ip_mreq(ip_mreq
, optval_addr
, optlen
);
1326 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq
, optlen
));
1329 case IP_BLOCK_SOURCE
:
1330 case IP_UNBLOCK_SOURCE
:
1331 case IP_ADD_SOURCE_MEMBERSHIP
:
1332 case IP_DROP_SOURCE_MEMBERSHIP
:
1333 if (optlen
!= sizeof (struct target_ip_mreq_source
))
1334 return -TARGET_EINVAL
;
1336 ip_mreq_source
= lock_user(VERIFY_READ
, optval_addr
, optlen
, 1);
1337 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq_source
, optlen
));
1338 unlock_user (ip_mreq_source
, optval_addr
, 0);
1347 case IPV6_MTU_DISCOVER
:
1350 case IPV6_RECVPKTINFO
:
1352 if (optlen
< sizeof(uint32_t)) {
1353 return -TARGET_EINVAL
;
1355 if (get_user_u32(val
, optval_addr
)) {
1356 return -TARGET_EFAULT
;
1358 ret
= get_errno(setsockopt(sockfd
, level
, optname
,
1359 &val
, sizeof(val
)));
1368 /* struct icmp_filter takes an u32 value */
1369 if (optlen
< sizeof(uint32_t)) {
1370 return -TARGET_EINVAL
;
1373 if (get_user_u32(val
, optval_addr
)) {
1374 return -TARGET_EFAULT
;
1376 ret
= get_errno(setsockopt(sockfd
, level
, optname
,
1377 &val
, sizeof(val
)));
1384 case TARGET_SOL_SOCKET
:
1386 case TARGET_SO_RCVTIMEO
:
1390 optname
= SO_RCVTIMEO
;
1393 if (optlen
!= sizeof(struct target_timeval
)) {
1394 return -TARGET_EINVAL
;
1397 if (copy_from_user_timeval(&tv
, optval_addr
)) {
1398 return -TARGET_EFAULT
;
1401 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
,
1405 case TARGET_SO_SNDTIMEO
:
1406 optname
= SO_SNDTIMEO
;
1408 case TARGET_SO_ATTACH_FILTER
:
1410 struct target_sock_fprog
*tfprog
;
1411 struct target_sock_filter
*tfilter
;
1412 struct sock_fprog fprog
;
1413 struct sock_filter
*filter
;
1416 if (optlen
!= sizeof(*tfprog
)) {
1417 return -TARGET_EINVAL
;
1419 if (!lock_user_struct(VERIFY_READ
, tfprog
, optval_addr
, 0)) {
1420 return -TARGET_EFAULT
;
1422 if (!lock_user_struct(VERIFY_READ
, tfilter
,
1423 tswapal(tfprog
->filter
), 0)) {
1424 unlock_user_struct(tfprog
, optval_addr
, 1);
1425 return -TARGET_EFAULT
;
1428 fprog
.len
= tswap16(tfprog
->len
);
1429 filter
= malloc(fprog
.len
* sizeof(*filter
));
1430 if (filter
== NULL
) {
1431 unlock_user_struct(tfilter
, tfprog
->filter
, 1);
1432 unlock_user_struct(tfprog
, optval_addr
, 1);
1433 return -TARGET_ENOMEM
;
1435 for (i
= 0; i
< fprog
.len
; i
++) {
1436 filter
[i
].code
= tswap16(tfilter
[i
].code
);
1437 filter
[i
].jt
= tfilter
[i
].jt
;
1438 filter
[i
].jf
= tfilter
[i
].jf
;
1439 filter
[i
].k
= tswap32(tfilter
[i
].k
);
1441 fprog
.filter
= filter
;
1443 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
,
1444 SO_ATTACH_FILTER
, &fprog
, sizeof(fprog
)));
1447 unlock_user_struct(tfilter
, tfprog
->filter
, 1);
1448 unlock_user_struct(tfprog
, optval_addr
, 1);
1451 /* Options with 'int' argument. */
1452 case TARGET_SO_DEBUG
:
1455 case TARGET_SO_REUSEADDR
:
1456 optname
= SO_REUSEADDR
;
1458 case TARGET_SO_TYPE
:
1461 case TARGET_SO_ERROR
:
1464 case TARGET_SO_DONTROUTE
:
1465 optname
= SO_DONTROUTE
;
1467 case TARGET_SO_BROADCAST
:
1468 optname
= SO_BROADCAST
;
1470 case TARGET_SO_SNDBUF
:
1471 optname
= SO_SNDBUF
;
1473 case TARGET_SO_RCVBUF
:
1474 optname
= SO_RCVBUF
;
1476 case TARGET_SO_KEEPALIVE
:
1477 optname
= SO_KEEPALIVE
;
1479 case TARGET_SO_OOBINLINE
:
1480 optname
= SO_OOBINLINE
;
1482 case TARGET_SO_NO_CHECK
:
1483 optname
= SO_NO_CHECK
;
1485 case TARGET_SO_PRIORITY
:
1486 optname
= SO_PRIORITY
;
1489 case TARGET_SO_BSDCOMPAT
:
1490 optname
= SO_BSDCOMPAT
;
1493 case TARGET_SO_PASSCRED
:
1494 optname
= SO_PASSCRED
;
1496 case TARGET_SO_TIMESTAMP
:
1497 optname
= SO_TIMESTAMP
;
1499 case TARGET_SO_RCVLOWAT
:
1500 optname
= SO_RCVLOWAT
;
1506 if (optlen
< sizeof(uint32_t))
1507 return -TARGET_EINVAL
;
1509 if (get_user_u32(val
, optval_addr
))
1510 return -TARGET_EFAULT
;
1511 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
1515 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level
, optname
);
1516 ret
= -TARGET_ENOPROTOOPT
;
1521 /* do_getsockopt() Must return target values and target errnos. */
1522 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
1523 abi_ulong optval_addr
, abi_ulong optlen
)
1530 case TARGET_SOL_SOCKET
:
1533 /* These don't just return a single integer */
1534 case TARGET_SO_LINGER
:
1535 case TARGET_SO_RCVTIMEO
:
1536 case TARGET_SO_SNDTIMEO
:
1537 case TARGET_SO_PEERNAME
:
1539 case TARGET_SO_PEERCRED
: {
1542 struct target_ucred
*tcr
;
1544 if (get_user_u32(len
, optlen
)) {
1545 return -TARGET_EFAULT
;
1548 return -TARGET_EINVAL
;
1552 ret
= get_errno(getsockopt(sockfd
, level
, SO_PEERCRED
,
1560 if (!lock_user_struct(VERIFY_WRITE
, tcr
, optval_addr
, 0)) {
1561 return -TARGET_EFAULT
;
1563 __put_user(cr
.pid
, &tcr
->pid
);
1564 __put_user(cr
.uid
, &tcr
->uid
);
1565 __put_user(cr
.gid
, &tcr
->gid
);
1566 unlock_user_struct(tcr
, optval_addr
, 1);
1567 if (put_user_u32(len
, optlen
)) {
1568 return -TARGET_EFAULT
;
1572 /* Options with 'int' argument. */
1573 case TARGET_SO_DEBUG
:
1576 case TARGET_SO_REUSEADDR
:
1577 optname
= SO_REUSEADDR
;
1579 case TARGET_SO_TYPE
:
1582 case TARGET_SO_ERROR
:
1585 case TARGET_SO_DONTROUTE
:
1586 optname
= SO_DONTROUTE
;
1588 case TARGET_SO_BROADCAST
:
1589 optname
= SO_BROADCAST
;
1591 case TARGET_SO_SNDBUF
:
1592 optname
= SO_SNDBUF
;
1594 case TARGET_SO_RCVBUF
:
1595 optname
= SO_RCVBUF
;
1597 case TARGET_SO_KEEPALIVE
:
1598 optname
= SO_KEEPALIVE
;
1600 case TARGET_SO_OOBINLINE
:
1601 optname
= SO_OOBINLINE
;
1603 case TARGET_SO_NO_CHECK
:
1604 optname
= SO_NO_CHECK
;
1606 case TARGET_SO_PRIORITY
:
1607 optname
= SO_PRIORITY
;
1610 case TARGET_SO_BSDCOMPAT
:
1611 optname
= SO_BSDCOMPAT
;
1614 case TARGET_SO_PASSCRED
:
1615 optname
= SO_PASSCRED
;
1617 case TARGET_SO_TIMESTAMP
:
1618 optname
= SO_TIMESTAMP
;
1620 case TARGET_SO_RCVLOWAT
:
1621 optname
= SO_RCVLOWAT
;
1628 /* TCP options all take an 'int' value. */
1630 if (get_user_u32(len
, optlen
))
1631 return -TARGET_EFAULT
;
1633 return -TARGET_EINVAL
;
1635 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1641 if (put_user_u32(val
, optval_addr
))
1642 return -TARGET_EFAULT
;
1644 if (put_user_u8(val
, optval_addr
))
1645 return -TARGET_EFAULT
;
1647 if (put_user_u32(len
, optlen
))
1648 return -TARGET_EFAULT
;
1655 case IP_ROUTER_ALERT
:
1659 case IP_MTU_DISCOVER
:
1665 case IP_MULTICAST_TTL
:
1666 case IP_MULTICAST_LOOP
:
1667 if (get_user_u32(len
, optlen
))
1668 return -TARGET_EFAULT
;
1670 return -TARGET_EINVAL
;
1672 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1675 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1677 if (put_user_u32(len
, optlen
)
1678 || put_user_u8(val
, optval_addr
))
1679 return -TARGET_EFAULT
;
1681 if (len
> sizeof(int))
1683 if (put_user_u32(len
, optlen
)
1684 || put_user_u32(val
, optval_addr
))
1685 return -TARGET_EFAULT
;
1689 ret
= -TARGET_ENOPROTOOPT
;
1695 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1697 ret
= -TARGET_EOPNOTSUPP
;
1703 static struct iovec
*lock_iovec(int type
, abi_ulong target_addr
,
1704 int count
, int copy
)
1706 struct target_iovec
*target_vec
;
1708 abi_ulong total_len
, max_len
;
1715 if (count
< 0 || count
> IOV_MAX
) {
1720 vec
= calloc(count
, sizeof(struct iovec
));
1726 target_vec
= lock_user(VERIFY_READ
, target_addr
,
1727 count
* sizeof(struct target_iovec
), 1);
1728 if (target_vec
== NULL
) {
1733 /* ??? If host page size > target page size, this will result in a
1734 value larger than what we can actually support. */
1735 max_len
= 0x7fffffff & TARGET_PAGE_MASK
;
1738 for (i
= 0; i
< count
; i
++) {
1739 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
1740 abi_long len
= tswapal(target_vec
[i
].iov_len
);
1745 } else if (len
== 0) {
1746 /* Zero length pointer is ignored. */
1747 vec
[i
].iov_base
= 0;
1749 vec
[i
].iov_base
= lock_user(type
, base
, len
, copy
);
1750 if (!vec
[i
].iov_base
) {
1754 if (len
> max_len
- total_len
) {
1755 len
= max_len
- total_len
;
1758 vec
[i
].iov_len
= len
;
1762 unlock_user(target_vec
, target_addr
, 0);
1768 unlock_user(target_vec
, target_addr
, 0);
1772 static void unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1773 int count
, int copy
)
1775 struct target_iovec
*target_vec
;
1778 target_vec
= lock_user(VERIFY_READ
, target_addr
,
1779 count
* sizeof(struct target_iovec
), 1);
1781 for (i
= 0; i
< count
; i
++) {
1782 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
1783 abi_long len
= tswapal(target_vec
[i
].iov_base
);
1787 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
1789 unlock_user(target_vec
, target_addr
, 0);
1795 static inline int target_to_host_sock_type(int *type
)
1798 int target_type
= *type
;
1800 switch (target_type
& TARGET_SOCK_TYPE_MASK
) {
1801 case TARGET_SOCK_DGRAM
:
1802 host_type
= SOCK_DGRAM
;
1804 case TARGET_SOCK_STREAM
:
1805 host_type
= SOCK_STREAM
;
1808 host_type
= target_type
& TARGET_SOCK_TYPE_MASK
;
1811 if (target_type
& TARGET_SOCK_CLOEXEC
) {
1812 #if defined(SOCK_CLOEXEC)
1813 host_type
|= SOCK_CLOEXEC
;
1815 return -TARGET_EINVAL
;
1818 if (target_type
& TARGET_SOCK_NONBLOCK
) {
1819 #if defined(SOCK_NONBLOCK)
1820 host_type
|= SOCK_NONBLOCK
;
1821 #elif !defined(O_NONBLOCK)
1822 return -TARGET_EINVAL
;
1829 /* Try to emulate socket type flags after socket creation. */
1830 static int sock_flags_fixup(int fd
, int target_type
)
1832 #if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
1833 if (target_type
& TARGET_SOCK_NONBLOCK
) {
1834 int flags
= fcntl(fd
, F_GETFL
);
1835 if (fcntl(fd
, F_SETFL
, O_NONBLOCK
| flags
) == -1) {
1837 return -TARGET_EINVAL
;
1844 /* do_socket() Must return target values and target errnos. */
1845 static abi_long
do_socket(int domain
, int type
, int protocol
)
1847 int target_type
= type
;
1850 ret
= target_to_host_sock_type(&type
);
1855 if (domain
== PF_NETLINK
)
1856 return -EAFNOSUPPORT
; /* do not NETLINK socket connections possible */
1857 ret
= get_errno(socket(domain
, type
, protocol
));
1859 ret
= sock_flags_fixup(ret
, target_type
);
1864 /* do_bind() Must return target values and target errnos. */
1865 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1871 if ((int)addrlen
< 0) {
1872 return -TARGET_EINVAL
;
1875 addr
= alloca(addrlen
+1);
1877 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1881 return get_errno(bind(sockfd
, addr
, addrlen
));
1884 /* do_connect() Must return target values and target errnos. */
1885 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1891 if ((int)addrlen
< 0) {
1892 return -TARGET_EINVAL
;
1895 addr
= alloca(addrlen
);
1897 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1901 return get_errno(connect(sockfd
, addr
, addrlen
));
1904 /* do_sendrecvmsg() Must return target values and target errnos. */
1905 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
1906 int flags
, int send
)
1909 struct target_msghdr
*msgp
;
1913 abi_ulong target_vec
;
1916 if (!lock_user_struct(send
? VERIFY_READ
: VERIFY_WRITE
,
1920 return -TARGET_EFAULT
;
1921 if (msgp
->msg_name
) {
1922 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
1923 msg
.msg_name
= alloca(msg
.msg_namelen
);
1924 ret
= target_to_host_sockaddr(msg
.msg_name
, tswapal(msgp
->msg_name
),
1930 msg
.msg_name
= NULL
;
1931 msg
.msg_namelen
= 0;
1933 msg
.msg_controllen
= 2 * tswapal(msgp
->msg_controllen
);
1934 msg
.msg_control
= alloca(msg
.msg_controllen
);
1935 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
1937 count
= tswapal(msgp
->msg_iovlen
);
1938 target_vec
= tswapal(msgp
->msg_iov
);
1939 vec
= lock_iovec(send
? VERIFY_READ
: VERIFY_WRITE
,
1940 target_vec
, count
, send
);
1942 ret
= -host_to_target_errno(errno
);
1945 msg
.msg_iovlen
= count
;
1949 ret
= target_to_host_cmsg(&msg
, msgp
);
1951 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
1953 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
1954 if (!is_error(ret
)) {
1956 ret
= host_to_target_cmsg(msgp
, &msg
);
1957 if (!is_error(ret
)) {
1958 msgp
->msg_namelen
= tswap32(msg
.msg_namelen
);
1959 if (msg
.msg_name
!= NULL
) {
1960 ret
= host_to_target_sockaddr(tswapal(msgp
->msg_name
),
1961 msg
.msg_name
, msg
.msg_namelen
);
1973 unlock_iovec(vec
, target_vec
, count
, !send
);
1975 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1979 /* If we don't have a system accept4() then just call accept.
1980 * The callsites to do_accept4() will ensure that they don't
1981 * pass a non-zero flags argument in this config.
1983 #ifndef CONFIG_ACCEPT4
1984 static inline int accept4(int sockfd
, struct sockaddr
*addr
,
1985 socklen_t
*addrlen
, int flags
)
1988 return accept(sockfd
, addr
, addrlen
);
1992 /* do_accept4() Must return target values and target errnos. */
1993 static abi_long
do_accept4(int fd
, abi_ulong target_addr
,
1994 abi_ulong target_addrlen_addr
, int flags
)
2000 if (target_addr
== 0) {
2001 return get_errno(accept4(fd
, NULL
, NULL
, flags
));
2004 /* linux returns EINVAL if addrlen pointer is invalid */
2005 if (get_user_u32(addrlen
, target_addrlen_addr
))
2006 return -TARGET_EINVAL
;
2008 if ((int)addrlen
< 0) {
2009 return -TARGET_EINVAL
;
2012 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2013 return -TARGET_EINVAL
;
2015 addr
= alloca(addrlen
);
2017 ret
= get_errno(accept4(fd
, addr
, &addrlen
, flags
));
2018 if (!is_error(ret
)) {
2019 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2020 if (put_user_u32(addrlen
, target_addrlen_addr
))
2021 ret
= -TARGET_EFAULT
;
2026 /* do_getpeername() Must return target values and target errnos. */
2027 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
2028 abi_ulong target_addrlen_addr
)
2034 if (get_user_u32(addrlen
, target_addrlen_addr
))
2035 return -TARGET_EFAULT
;
2037 if ((int)addrlen
< 0) {
2038 return -TARGET_EINVAL
;
2041 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2042 return -TARGET_EFAULT
;
2044 addr
= alloca(addrlen
);
2046 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
2047 if (!is_error(ret
)) {
2048 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2049 if (put_user_u32(addrlen
, target_addrlen_addr
))
2050 ret
= -TARGET_EFAULT
;
2055 /* do_getsockname() Must return target values and target errnos. */
2056 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
2057 abi_ulong target_addrlen_addr
)
2063 if (get_user_u32(addrlen
, target_addrlen_addr
))
2064 return -TARGET_EFAULT
;
2066 if ((int)addrlen
< 0) {
2067 return -TARGET_EINVAL
;
2070 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2071 return -TARGET_EFAULT
;
2073 addr
= alloca(addrlen
);
2075 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
2076 if (!is_error(ret
)) {
2077 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2078 if (put_user_u32(addrlen
, target_addrlen_addr
))
2079 ret
= -TARGET_EFAULT
;
2084 /* do_socketpair() Must return target values and target errnos. */
2085 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
2086 abi_ulong target_tab_addr
)
2091 target_to_host_sock_type(&type
);
2093 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
2094 if (!is_error(ret
)) {
2095 if (put_user_s32(tab
[0], target_tab_addr
)
2096 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
2097 ret
= -TARGET_EFAULT
;
2102 /* do_sendto() Must return target values and target errnos. */
2103 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
2104 abi_ulong target_addr
, socklen_t addrlen
)
2110 if ((int)addrlen
< 0) {
2111 return -TARGET_EINVAL
;
2114 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
2116 return -TARGET_EFAULT
;
2118 addr
= alloca(addrlen
);
2119 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
2121 unlock_user(host_msg
, msg
, 0);
2124 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
2126 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
2128 unlock_user(host_msg
, msg
, 0);
2132 /* do_recvfrom() Must return target values and target errnos. */
2133 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
2134 abi_ulong target_addr
,
2135 abi_ulong target_addrlen
)
2142 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
2144 return -TARGET_EFAULT
;
2146 if (get_user_u32(addrlen
, target_addrlen
)) {
2147 ret
= -TARGET_EFAULT
;
2150 if ((int)addrlen
< 0) {
2151 ret
= -TARGET_EINVAL
;
2154 addr
= alloca(addrlen
);
2155 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
2157 addr
= NULL
; /* To keep compiler quiet. */
2158 ret
= get_errno(qemu_recv(fd
, host_msg
, len
, flags
));
2160 if (!is_error(ret
)) {
2162 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2163 if (put_user_u32(addrlen
, target_addrlen
)) {
2164 ret
= -TARGET_EFAULT
;
2168 unlock_user(host_msg
, msg
, len
);
2171 unlock_user(host_msg
, msg
, 0);
2176 #ifdef TARGET_NR_socketcall
2177 /* do_socketcall() Must return target values and target errnos. */
2178 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
2181 const int n
= sizeof(abi_ulong
);
2186 abi_ulong domain
, type
, protocol
;
2188 if (get_user_ual(domain
, vptr
)
2189 || get_user_ual(type
, vptr
+ n
)
2190 || get_user_ual(protocol
, vptr
+ 2 * n
))
2191 return -TARGET_EFAULT
;
2193 ret
= do_socket(domain
, type
, protocol
);
2199 abi_ulong target_addr
;
2202 if (get_user_ual(sockfd
, vptr
)
2203 || get_user_ual(target_addr
, vptr
+ n
)
2204 || get_user_ual(addrlen
, vptr
+ 2 * n
))
2205 return -TARGET_EFAULT
;
2207 ret
= do_bind(sockfd
, target_addr
, addrlen
);
2210 case SOCKOP_connect
:
2213 abi_ulong target_addr
;
2216 if (get_user_ual(sockfd
, vptr
)
2217 || get_user_ual(target_addr
, vptr
+ n
)
2218 || get_user_ual(addrlen
, vptr
+ 2 * n
))
2219 return -TARGET_EFAULT
;
2221 ret
= do_connect(sockfd
, target_addr
, addrlen
);
2226 abi_ulong sockfd
, backlog
;
2228 if (get_user_ual(sockfd
, vptr
)
2229 || get_user_ual(backlog
, vptr
+ n
))
2230 return -TARGET_EFAULT
;
2232 ret
= get_errno(listen(sockfd
, backlog
));
2238 abi_ulong target_addr
, target_addrlen
;
2240 if (get_user_ual(sockfd
, vptr
)
2241 || get_user_ual(target_addr
, vptr
+ n
)
2242 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2243 return -TARGET_EFAULT
;
2245 ret
= do_accept4(sockfd
, target_addr
, target_addrlen
, 0);
2248 case SOCKOP_getsockname
:
2251 abi_ulong target_addr
, target_addrlen
;
2253 if (get_user_ual(sockfd
, vptr
)
2254 || get_user_ual(target_addr
, vptr
+ n
)
2255 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2256 return -TARGET_EFAULT
;
2258 ret
= do_getsockname(sockfd
, target_addr
, target_addrlen
);
2261 case SOCKOP_getpeername
:
2264 abi_ulong target_addr
, target_addrlen
;
2266 if (get_user_ual(sockfd
, vptr
)
2267 || get_user_ual(target_addr
, vptr
+ n
)
2268 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2269 return -TARGET_EFAULT
;
2271 ret
= do_getpeername(sockfd
, target_addr
, target_addrlen
);
2274 case SOCKOP_socketpair
:
2276 abi_ulong domain
, type
, protocol
;
2279 if (get_user_ual(domain
, vptr
)
2280 || get_user_ual(type
, vptr
+ n
)
2281 || get_user_ual(protocol
, vptr
+ 2 * n
)
2282 || get_user_ual(tab
, vptr
+ 3 * n
))
2283 return -TARGET_EFAULT
;
2285 ret
= do_socketpair(domain
, type
, protocol
, tab
);
2295 if (get_user_ual(sockfd
, vptr
)
2296 || get_user_ual(msg
, vptr
+ n
)
2297 || get_user_ual(len
, vptr
+ 2 * n
)
2298 || get_user_ual(flags
, vptr
+ 3 * n
))
2299 return -TARGET_EFAULT
;
2301 ret
= do_sendto(sockfd
, msg
, len
, flags
, 0, 0);
2311 if (get_user_ual(sockfd
, vptr
)
2312 || get_user_ual(msg
, vptr
+ n
)
2313 || get_user_ual(len
, vptr
+ 2 * n
)
2314 || get_user_ual(flags
, vptr
+ 3 * n
))
2315 return -TARGET_EFAULT
;
2317 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, 0, 0);
2329 if (get_user_ual(sockfd
, vptr
)
2330 || get_user_ual(msg
, vptr
+ n
)
2331 || get_user_ual(len
, vptr
+ 2 * n
)
2332 || get_user_ual(flags
, vptr
+ 3 * n
)
2333 || get_user_ual(addr
, vptr
+ 4 * n
)
2334 || get_user_ual(addrlen
, vptr
+ 5 * n
))
2335 return -TARGET_EFAULT
;
2337 ret
= do_sendto(sockfd
, msg
, len
, flags
, addr
, addrlen
);
2340 case SOCKOP_recvfrom
:
2349 if (get_user_ual(sockfd
, vptr
)
2350 || get_user_ual(msg
, vptr
+ n
)
2351 || get_user_ual(len
, vptr
+ 2 * n
)
2352 || get_user_ual(flags
, vptr
+ 3 * n
)
2353 || get_user_ual(addr
, vptr
+ 4 * n
)
2354 || get_user_ual(addrlen
, vptr
+ 5 * n
))
2355 return -TARGET_EFAULT
;
2357 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, addr
, addrlen
);
2360 case SOCKOP_shutdown
:
2362 abi_ulong sockfd
, how
;
2364 if (get_user_ual(sockfd
, vptr
)
2365 || get_user_ual(how
, vptr
+ n
))
2366 return -TARGET_EFAULT
;
2368 ret
= get_errno(shutdown(sockfd
, how
));
2371 case SOCKOP_sendmsg
:
2372 case SOCKOP_recvmsg
:
2375 abi_ulong target_msg
;
2378 if (get_user_ual(fd
, vptr
)
2379 || get_user_ual(target_msg
, vptr
+ n
)
2380 || get_user_ual(flags
, vptr
+ 2 * n
))
2381 return -TARGET_EFAULT
;
2383 ret
= do_sendrecvmsg(fd
, target_msg
, flags
,
2384 (num
== SOCKOP_sendmsg
));
2387 case SOCKOP_setsockopt
:
2395 if (get_user_ual(sockfd
, vptr
)
2396 || get_user_ual(level
, vptr
+ n
)
2397 || get_user_ual(optname
, vptr
+ 2 * n
)
2398 || get_user_ual(optval
, vptr
+ 3 * n
)
2399 || get_user_ual(optlen
, vptr
+ 4 * n
))
2400 return -TARGET_EFAULT
;
2402 ret
= do_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
2405 case SOCKOP_getsockopt
:
2413 if (get_user_ual(sockfd
, vptr
)
2414 || get_user_ual(level
, vptr
+ n
)
2415 || get_user_ual(optname
, vptr
+ 2 * n
)
2416 || get_user_ual(optval
, vptr
+ 3 * n
)
2417 || get_user_ual(optlen
, vptr
+ 4 * n
))
2418 return -TARGET_EFAULT
;
2420 ret
= do_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
2424 gemu_log("Unsupported socketcall: %d\n", num
);
2425 ret
= -TARGET_ENOSYS
;
2432 #define N_SHM_REGIONS 32
2434 static struct shm_region
{
2437 } shm_regions
[N_SHM_REGIONS
];
2439 struct target_semid_ds
2441 struct target_ipc_perm sem_perm
;
2442 abi_ulong sem_otime
;
2443 abi_ulong __unused1
;
2444 abi_ulong sem_ctime
;
2445 abi_ulong __unused2
;
2446 abi_ulong sem_nsems
;
2447 abi_ulong __unused3
;
2448 abi_ulong __unused4
;
2451 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
2452 abi_ulong target_addr
)
2454 struct target_ipc_perm
*target_ip
;
2455 struct target_semid_ds
*target_sd
;
2457 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2458 return -TARGET_EFAULT
;
2459 target_ip
= &(target_sd
->sem_perm
);
2460 host_ip
->__key
= tswap32(target_ip
->__key
);
2461 host_ip
->uid
= tswap32(target_ip
->uid
);
2462 host_ip
->gid
= tswap32(target_ip
->gid
);
2463 host_ip
->cuid
= tswap32(target_ip
->cuid
);
2464 host_ip
->cgid
= tswap32(target_ip
->cgid
);
2465 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2466 host_ip
->mode
= tswap32(target_ip
->mode
);
2468 host_ip
->mode
= tswap16(target_ip
->mode
);
2470 #if defined(TARGET_PPC)
2471 host_ip
->__seq
= tswap32(target_ip
->__seq
);
2473 host_ip
->__seq
= tswap16(target_ip
->__seq
);
2475 unlock_user_struct(target_sd
, target_addr
, 0);
2479 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
2480 struct ipc_perm
*host_ip
)
2482 struct target_ipc_perm
*target_ip
;
2483 struct target_semid_ds
*target_sd
;
2485 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2486 return -TARGET_EFAULT
;
2487 target_ip
= &(target_sd
->sem_perm
);
2488 target_ip
->__key
= tswap32(host_ip
->__key
);
2489 target_ip
->uid
= tswap32(host_ip
->uid
);
2490 target_ip
->gid
= tswap32(host_ip
->gid
);
2491 target_ip
->cuid
= tswap32(host_ip
->cuid
);
2492 target_ip
->cgid
= tswap32(host_ip
->cgid
);
2493 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2494 target_ip
->mode
= tswap32(host_ip
->mode
);
2496 target_ip
->mode
= tswap16(host_ip
->mode
);
2498 #if defined(TARGET_PPC)
2499 target_ip
->__seq
= tswap32(host_ip
->__seq
);
2501 target_ip
->__seq
= tswap16(host_ip
->__seq
);
2503 unlock_user_struct(target_sd
, target_addr
, 1);
2507 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
2508 abi_ulong target_addr
)
2510 struct target_semid_ds
*target_sd
;
2512 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2513 return -TARGET_EFAULT
;
2514 if (target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
))
2515 return -TARGET_EFAULT
;
2516 host_sd
->sem_nsems
= tswapal(target_sd
->sem_nsems
);
2517 host_sd
->sem_otime
= tswapal(target_sd
->sem_otime
);
2518 host_sd
->sem_ctime
= tswapal(target_sd
->sem_ctime
);
2519 unlock_user_struct(target_sd
, target_addr
, 0);
2523 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
2524 struct semid_ds
*host_sd
)
2526 struct target_semid_ds
*target_sd
;
2528 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2529 return -TARGET_EFAULT
;
2530 if (host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
)))
2531 return -TARGET_EFAULT
;
2532 target_sd
->sem_nsems
= tswapal(host_sd
->sem_nsems
);
2533 target_sd
->sem_otime
= tswapal(host_sd
->sem_otime
);
2534 target_sd
->sem_ctime
= tswapal(host_sd
->sem_ctime
);
2535 unlock_user_struct(target_sd
, target_addr
, 1);
2539 struct target_seminfo
{
2552 static inline abi_long
host_to_target_seminfo(abi_ulong target_addr
,
2553 struct seminfo
*host_seminfo
)
2555 struct target_seminfo
*target_seminfo
;
2556 if (!lock_user_struct(VERIFY_WRITE
, target_seminfo
, target_addr
, 0))
2557 return -TARGET_EFAULT
;
2558 __put_user(host_seminfo
->semmap
, &target_seminfo
->semmap
);
2559 __put_user(host_seminfo
->semmni
, &target_seminfo
->semmni
);
2560 __put_user(host_seminfo
->semmns
, &target_seminfo
->semmns
);
2561 __put_user(host_seminfo
->semmnu
, &target_seminfo
->semmnu
);
2562 __put_user(host_seminfo
->semmsl
, &target_seminfo
->semmsl
);
2563 __put_user(host_seminfo
->semopm
, &target_seminfo
->semopm
);
2564 __put_user(host_seminfo
->semume
, &target_seminfo
->semume
);
2565 __put_user(host_seminfo
->semusz
, &target_seminfo
->semusz
);
2566 __put_user(host_seminfo
->semvmx
, &target_seminfo
->semvmx
);
2567 __put_user(host_seminfo
->semaem
, &target_seminfo
->semaem
);
2568 unlock_user_struct(target_seminfo
, target_addr
, 1);
2574 struct semid_ds
*buf
;
2575 unsigned short *array
;
2576 struct seminfo
*__buf
;
2579 union target_semun
{
2586 static inline abi_long
target_to_host_semarray(int semid
, unsigned short **host_array
,
2587 abi_ulong target_addr
)
2590 unsigned short *array
;
2592 struct semid_ds semid_ds
;
2595 semun
.buf
= &semid_ds
;
2597 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2599 return get_errno(ret
);
2601 nsems
= semid_ds
.sem_nsems
;
2603 *host_array
= malloc(nsems
*sizeof(unsigned short));
2604 array
= lock_user(VERIFY_READ
, target_addr
,
2605 nsems
*sizeof(unsigned short), 1);
2607 return -TARGET_EFAULT
;
2609 for(i
=0; i
<nsems
; i
++) {
2610 __get_user((*host_array
)[i
], &array
[i
]);
2612 unlock_user(array
, target_addr
, 0);
2617 static inline abi_long
host_to_target_semarray(int semid
, abi_ulong target_addr
,
2618 unsigned short **host_array
)
2621 unsigned short *array
;
2623 struct semid_ds semid_ds
;
2626 semun
.buf
= &semid_ds
;
2628 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2630 return get_errno(ret
);
2632 nsems
= semid_ds
.sem_nsems
;
2634 array
= lock_user(VERIFY_WRITE
, target_addr
,
2635 nsems
*sizeof(unsigned short), 0);
2637 return -TARGET_EFAULT
;
2639 for(i
=0; i
<nsems
; i
++) {
2640 __put_user((*host_array
)[i
], &array
[i
]);
2643 unlock_user(array
, target_addr
, 1);
2648 static inline abi_long
do_semctl(int semid
, int semnum
, int cmd
,
2649 union target_semun target_su
)
2652 struct semid_ds dsarg
;
2653 unsigned short *array
= NULL
;
2654 struct seminfo seminfo
;
2655 abi_long ret
= -TARGET_EINVAL
;
2662 arg
.val
= tswap32(target_su
.val
);
2663 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2664 target_su
.val
= tswap32(arg
.val
);
2668 err
= target_to_host_semarray(semid
, &array
, target_su
.array
);
2672 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2673 err
= host_to_target_semarray(semid
, target_su
.array
, &array
);
2680 err
= target_to_host_semid_ds(&dsarg
, target_su
.buf
);
2684 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2685 err
= host_to_target_semid_ds(target_su
.buf
, &dsarg
);
2691 arg
.__buf
= &seminfo
;
2692 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2693 err
= host_to_target_seminfo(target_su
.__buf
, &seminfo
);
2701 ret
= get_errno(semctl(semid
, semnum
, cmd
, NULL
));
2708 struct target_sembuf
{
2709 unsigned short sem_num
;
2714 static inline abi_long
target_to_host_sembuf(struct sembuf
*host_sembuf
,
2715 abi_ulong target_addr
,
2718 struct target_sembuf
*target_sembuf
;
2721 target_sembuf
= lock_user(VERIFY_READ
, target_addr
,
2722 nsops
*sizeof(struct target_sembuf
), 1);
2724 return -TARGET_EFAULT
;
2726 for(i
=0; i
<nsops
; i
++) {
2727 __get_user(host_sembuf
[i
].sem_num
, &target_sembuf
[i
].sem_num
);
2728 __get_user(host_sembuf
[i
].sem_op
, &target_sembuf
[i
].sem_op
);
2729 __get_user(host_sembuf
[i
].sem_flg
, &target_sembuf
[i
].sem_flg
);
2732 unlock_user(target_sembuf
, target_addr
, 0);
2737 static inline abi_long
do_semop(int semid
, abi_long ptr
, unsigned nsops
)
2739 struct sembuf sops
[nsops
];
2741 if (target_to_host_sembuf(sops
, ptr
, nsops
))
2742 return -TARGET_EFAULT
;
2744 return get_errno(semop(semid
, sops
, nsops
));
2747 struct target_msqid_ds
2749 struct target_ipc_perm msg_perm
;
2750 abi_ulong msg_stime
;
2751 #if TARGET_ABI_BITS == 32
2752 abi_ulong __unused1
;
2754 abi_ulong msg_rtime
;
2755 #if TARGET_ABI_BITS == 32
2756 abi_ulong __unused2
;
2758 abi_ulong msg_ctime
;
2759 #if TARGET_ABI_BITS == 32
2760 abi_ulong __unused3
;
2762 abi_ulong __msg_cbytes
;
2764 abi_ulong msg_qbytes
;
2765 abi_ulong msg_lspid
;
2766 abi_ulong msg_lrpid
;
2767 abi_ulong __unused4
;
2768 abi_ulong __unused5
;
2771 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
2772 abi_ulong target_addr
)
2774 struct target_msqid_ds
*target_md
;
2776 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
2777 return -TARGET_EFAULT
;
2778 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
2779 return -TARGET_EFAULT
;
2780 host_md
->msg_stime
= tswapal(target_md
->msg_stime
);
2781 host_md
->msg_rtime
= tswapal(target_md
->msg_rtime
);
2782 host_md
->msg_ctime
= tswapal(target_md
->msg_ctime
);
2783 host_md
->__msg_cbytes
= tswapal(target_md
->__msg_cbytes
);
2784 host_md
->msg_qnum
= tswapal(target_md
->msg_qnum
);
2785 host_md
->msg_qbytes
= tswapal(target_md
->msg_qbytes
);
2786 host_md
->msg_lspid
= tswapal(target_md
->msg_lspid
);
2787 host_md
->msg_lrpid
= tswapal(target_md
->msg_lrpid
);
2788 unlock_user_struct(target_md
, target_addr
, 0);
2792 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
2793 struct msqid_ds
*host_md
)
2795 struct target_msqid_ds
*target_md
;
2797 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
2798 return -TARGET_EFAULT
;
2799 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
2800 return -TARGET_EFAULT
;
2801 target_md
->msg_stime
= tswapal(host_md
->msg_stime
);
2802 target_md
->msg_rtime
= tswapal(host_md
->msg_rtime
);
2803 target_md
->msg_ctime
= tswapal(host_md
->msg_ctime
);
2804 target_md
->__msg_cbytes
= tswapal(host_md
->__msg_cbytes
);
2805 target_md
->msg_qnum
= tswapal(host_md
->msg_qnum
);
2806 target_md
->msg_qbytes
= tswapal(host_md
->msg_qbytes
);
2807 target_md
->msg_lspid
= tswapal(host_md
->msg_lspid
);
2808 target_md
->msg_lrpid
= tswapal(host_md
->msg_lrpid
);
2809 unlock_user_struct(target_md
, target_addr
, 1);
2813 struct target_msginfo
{
2821 unsigned short int msgseg
;
2824 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
2825 struct msginfo
*host_msginfo
)
2827 struct target_msginfo
*target_msginfo
;
2828 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
2829 return -TARGET_EFAULT
;
2830 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
2831 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
2832 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
2833 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
2834 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
2835 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
2836 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
2837 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
2838 unlock_user_struct(target_msginfo
, target_addr
, 1);
2842 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
2844 struct msqid_ds dsarg
;
2845 struct msginfo msginfo
;
2846 abi_long ret
= -TARGET_EINVAL
;
2854 if (target_to_host_msqid_ds(&dsarg
,ptr
))
2855 return -TARGET_EFAULT
;
2856 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
2857 if (host_to_target_msqid_ds(ptr
,&dsarg
))
2858 return -TARGET_EFAULT
;
2861 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2865 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2866 if (host_to_target_msginfo(ptr
, &msginfo
))
2867 return -TARGET_EFAULT
;
2874 struct target_msgbuf
{
2879 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2880 unsigned int msgsz
, int msgflg
)
2882 struct target_msgbuf
*target_mb
;
2883 struct msgbuf
*host_mb
;
2886 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2887 return -TARGET_EFAULT
;
2888 host_mb
= malloc(msgsz
+sizeof(long));
2889 host_mb
->mtype
= (abi_long
) tswapal(target_mb
->mtype
);
2890 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2891 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2893 unlock_user_struct(target_mb
, msgp
, 0);
2898 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2899 unsigned int msgsz
, abi_long msgtyp
,
2902 struct target_msgbuf
*target_mb
;
2904 struct msgbuf
*host_mb
;
2907 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2908 return -TARGET_EFAULT
;
2910 host_mb
= g_malloc(msgsz
+sizeof(long));
2911 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, msgtyp
, msgflg
));
2914 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2915 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2916 if (!target_mtext
) {
2917 ret
= -TARGET_EFAULT
;
2920 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2921 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2924 target_mb
->mtype
= tswapal(host_mb
->mtype
);
2928 unlock_user_struct(target_mb
, msgp
, 1);
2933 static inline abi_long
target_to_host_shmid_ds(struct shmid_ds
*host_sd
,
2934 abi_ulong target_addr
)
2936 struct target_shmid_ds
*target_sd
;
2938 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2939 return -TARGET_EFAULT
;
2940 if (target_to_host_ipc_perm(&(host_sd
->shm_perm
), target_addr
))
2941 return -TARGET_EFAULT
;
2942 __get_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2943 __get_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2944 __get_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2945 __get_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2946 __get_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2947 __get_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2948 __get_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2949 unlock_user_struct(target_sd
, target_addr
, 0);
2953 static inline abi_long
host_to_target_shmid_ds(abi_ulong target_addr
,
2954 struct shmid_ds
*host_sd
)
2956 struct target_shmid_ds
*target_sd
;
2958 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2959 return -TARGET_EFAULT
;
2960 if (host_to_target_ipc_perm(target_addr
, &(host_sd
->shm_perm
)))
2961 return -TARGET_EFAULT
;
2962 __put_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2963 __put_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2964 __put_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2965 __put_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2966 __put_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2967 __put_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2968 __put_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2969 unlock_user_struct(target_sd
, target_addr
, 1);
2973 struct target_shminfo
{
2981 static inline abi_long
host_to_target_shminfo(abi_ulong target_addr
,
2982 struct shminfo
*host_shminfo
)
2984 struct target_shminfo
*target_shminfo
;
2985 if (!lock_user_struct(VERIFY_WRITE
, target_shminfo
, target_addr
, 0))
2986 return -TARGET_EFAULT
;
2987 __put_user(host_shminfo
->shmmax
, &target_shminfo
->shmmax
);
2988 __put_user(host_shminfo
->shmmin
, &target_shminfo
->shmmin
);
2989 __put_user(host_shminfo
->shmmni
, &target_shminfo
->shmmni
);
2990 __put_user(host_shminfo
->shmseg
, &target_shminfo
->shmseg
);
2991 __put_user(host_shminfo
->shmall
, &target_shminfo
->shmall
);
2992 unlock_user_struct(target_shminfo
, target_addr
, 1);
2996 struct target_shm_info
{
3001 abi_ulong swap_attempts
;
3002 abi_ulong swap_successes
;
3005 static inline abi_long
host_to_target_shm_info(abi_ulong target_addr
,
3006 struct shm_info
*host_shm_info
)
3008 struct target_shm_info
*target_shm_info
;
3009 if (!lock_user_struct(VERIFY_WRITE
, target_shm_info
, target_addr
, 0))
3010 return -TARGET_EFAULT
;
3011 __put_user(host_shm_info
->used_ids
, &target_shm_info
->used_ids
);
3012 __put_user(host_shm_info
->shm_tot
, &target_shm_info
->shm_tot
);
3013 __put_user(host_shm_info
->shm_rss
, &target_shm_info
->shm_rss
);
3014 __put_user(host_shm_info
->shm_swp
, &target_shm_info
->shm_swp
);
3015 __put_user(host_shm_info
->swap_attempts
, &target_shm_info
->swap_attempts
);
3016 __put_user(host_shm_info
->swap_successes
, &target_shm_info
->swap_successes
);
3017 unlock_user_struct(target_shm_info
, target_addr
, 1);
3021 static inline abi_long
do_shmctl(int shmid
, int cmd
, abi_long buf
)
3023 struct shmid_ds dsarg
;
3024 struct shminfo shminfo
;
3025 struct shm_info shm_info
;
3026 abi_long ret
= -TARGET_EINVAL
;
3034 if (target_to_host_shmid_ds(&dsarg
, buf
))
3035 return -TARGET_EFAULT
;
3036 ret
= get_errno(shmctl(shmid
, cmd
, &dsarg
));
3037 if (host_to_target_shmid_ds(buf
, &dsarg
))
3038 return -TARGET_EFAULT
;
3041 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shminfo
));
3042 if (host_to_target_shminfo(buf
, &shminfo
))
3043 return -TARGET_EFAULT
;
3046 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shm_info
));
3047 if (host_to_target_shm_info(buf
, &shm_info
))
3048 return -TARGET_EFAULT
;
3053 ret
= get_errno(shmctl(shmid
, cmd
, NULL
));
3060 static inline abi_ulong
do_shmat(int shmid
, abi_ulong shmaddr
, int shmflg
)
3064 struct shmid_ds shm_info
;
3067 /* find out the length of the shared memory segment */
3068 ret
= get_errno(shmctl(shmid
, IPC_STAT
, &shm_info
));
3069 if (is_error(ret
)) {
3070 /* can't get length, bail out */
3077 host_raddr
= shmat(shmid
, (void *)g2h(shmaddr
), shmflg
);
3079 abi_ulong mmap_start
;
3081 mmap_start
= mmap_find_vma(0, shm_info
.shm_segsz
);
3083 if (mmap_start
== -1) {
3085 host_raddr
= (void *)-1;
3087 host_raddr
= shmat(shmid
, g2h(mmap_start
), shmflg
| SHM_REMAP
);
3090 if (host_raddr
== (void *)-1) {
3092 return get_errno((long)host_raddr
);
3094 raddr
=h2g((unsigned long)host_raddr
);
3096 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
3097 PAGE_VALID
| PAGE_READ
|
3098 ((shmflg
& SHM_RDONLY
)? 0 : PAGE_WRITE
));
3100 for (i
= 0; i
< N_SHM_REGIONS
; i
++) {
3101 if (shm_regions
[i
].start
== 0) {
3102 shm_regions
[i
].start
= raddr
;
3103 shm_regions
[i
].size
= shm_info
.shm_segsz
;
3113 static inline abi_long
do_shmdt(abi_ulong shmaddr
)
3117 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
3118 if (shm_regions
[i
].start
== shmaddr
) {
3119 shm_regions
[i
].start
= 0;
3120 page_set_flags(shmaddr
, shmaddr
+ shm_regions
[i
].size
, 0);
3125 return get_errno(shmdt(g2h(shmaddr
)));
3128 #ifdef TARGET_NR_ipc
3129 /* ??? This only works with linear mappings. */
3130 /* do_ipc() must return target values and target errnos. */
3131 static abi_long
do_ipc(unsigned int call
, int first
,
3132 int second
, int third
,
3133 abi_long ptr
, abi_long fifth
)
3138 version
= call
>> 16;
3143 ret
= do_semop(first
, ptr
, second
);
3147 ret
= get_errno(semget(first
, second
, third
));
3151 ret
= do_semctl(first
, second
, third
, (union target_semun
)(abi_ulong
) ptr
);
3155 ret
= get_errno(msgget(first
, second
));
3159 ret
= do_msgsnd(first
, ptr
, second
, third
);
3163 ret
= do_msgctl(first
, second
, ptr
);
3170 struct target_ipc_kludge
{
3175 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
3176 ret
= -TARGET_EFAULT
;
3180 ret
= do_msgrcv(first
, tswapal(tmp
->msgp
), second
, tswapal(tmp
->msgtyp
), third
);
3182 unlock_user_struct(tmp
, ptr
, 0);
3186 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
3195 raddr
= do_shmat(first
, ptr
, second
);
3196 if (is_error(raddr
))
3197 return get_errno(raddr
);
3198 if (put_user_ual(raddr
, third
))
3199 return -TARGET_EFAULT
;
3203 ret
= -TARGET_EINVAL
;
3208 ret
= do_shmdt(ptr
);
3212 /* IPC_* flag values are the same on all linux platforms */
3213 ret
= get_errno(shmget(first
, second
, third
));
3216 /* IPC_* and SHM_* command values are the same on all linux platforms */
3218 ret
= do_shmctl(first
, second
, ptr
);
3221 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
3222 ret
= -TARGET_ENOSYS
;
3229 /* kernel structure types definitions */
3231 #define STRUCT(name, ...) STRUCT_ ## name,
3232 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
3234 #include "syscall_types.h"
3237 #undef STRUCT_SPECIAL
3239 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3240 #define STRUCT_SPECIAL(name)
3241 #include "syscall_types.h"
3243 #undef STRUCT_SPECIAL
3245 typedef struct IOCTLEntry IOCTLEntry
;
3247 typedef abi_long
do_ioctl_fn(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3248 int fd
, abi_long cmd
, abi_long arg
);
3251 unsigned int target_cmd
;
3252 unsigned int host_cmd
;
3255 do_ioctl_fn
*do_ioctl
;
3256 const argtype arg_type
[5];
3259 #define IOC_R 0x0001
3260 #define IOC_W 0x0002
3261 #define IOC_RW (IOC_R | IOC_W)
3263 #define MAX_STRUCT_SIZE 4096
3265 #ifdef CONFIG_FIEMAP
3266 /* So fiemap access checks don't overflow on 32 bit systems.
3267 * This is very slightly smaller than the limit imposed by
3268 * the underlying kernel.
3270 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3271 / sizeof(struct fiemap_extent))
3273 static abi_long
do_ioctl_fs_ioc_fiemap(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3274 int fd
, abi_long cmd
, abi_long arg
)
3276 /* The parameter for this ioctl is a struct fiemap followed
3277 * by an array of struct fiemap_extent whose size is set
3278 * in fiemap->fm_extent_count. The array is filled in by the
3281 int target_size_in
, target_size_out
;
3283 const argtype
*arg_type
= ie
->arg_type
;
3284 const argtype extent_arg_type
[] = { MK_STRUCT(STRUCT_fiemap_extent
) };
3287 int i
, extent_size
= thunk_type_size(extent_arg_type
, 0);
3291 assert(arg_type
[0] == TYPE_PTR
);
3292 assert(ie
->access
== IOC_RW
);
3294 target_size_in
= thunk_type_size(arg_type
, 0);
3295 argptr
= lock_user(VERIFY_READ
, arg
, target_size_in
, 1);
3297 return -TARGET_EFAULT
;
3299 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3300 unlock_user(argptr
, arg
, 0);
3301 fm
= (struct fiemap
*)buf_temp
;
3302 if (fm
->fm_extent_count
> FIEMAP_MAX_EXTENTS
) {
3303 return -TARGET_EINVAL
;
3306 outbufsz
= sizeof (*fm
) +
3307 (sizeof(struct fiemap_extent
) * fm
->fm_extent_count
);
3309 if (outbufsz
> MAX_STRUCT_SIZE
) {
3310 /* We can't fit all the extents into the fixed size buffer.
3311 * Allocate one that is large enough and use it instead.
3313 fm
= malloc(outbufsz
);
3315 return -TARGET_ENOMEM
;
3317 memcpy(fm
, buf_temp
, sizeof(struct fiemap
));
3320 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, fm
));
3321 if (!is_error(ret
)) {
3322 target_size_out
= target_size_in
;
3323 /* An extent_count of 0 means we were only counting the extents
3324 * so there are no structs to copy
3326 if (fm
->fm_extent_count
!= 0) {
3327 target_size_out
+= fm
->fm_mapped_extents
* extent_size
;
3329 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size_out
, 0);
3331 ret
= -TARGET_EFAULT
;
3333 /* Convert the struct fiemap */
3334 thunk_convert(argptr
, fm
, arg_type
, THUNK_TARGET
);
3335 if (fm
->fm_extent_count
!= 0) {
3336 p
= argptr
+ target_size_in
;
3337 /* ...and then all the struct fiemap_extents */
3338 for (i
= 0; i
< fm
->fm_mapped_extents
; i
++) {
3339 thunk_convert(p
, &fm
->fm_extents
[i
], extent_arg_type
,
3344 unlock_user(argptr
, arg
, target_size_out
);
3354 static abi_long
do_ioctl_ifconf(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3355 int fd
, abi_long cmd
, abi_long arg
)
3357 const argtype
*arg_type
= ie
->arg_type
;
3361 struct ifconf
*host_ifconf
;
3363 const argtype ifreq_arg_type
[] = { MK_STRUCT(STRUCT_sockaddr_ifreq
) };
3364 int target_ifreq_size
;
3369 abi_long target_ifc_buf
;
3373 assert(arg_type
[0] == TYPE_PTR
);
3374 assert(ie
->access
== IOC_RW
);
3377 target_size
= thunk_type_size(arg_type
, 0);
3379 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3381 return -TARGET_EFAULT
;
3382 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3383 unlock_user(argptr
, arg
, 0);
3385 host_ifconf
= (struct ifconf
*)(unsigned long)buf_temp
;
3386 target_ifc_len
= host_ifconf
->ifc_len
;
3387 target_ifc_buf
= (abi_long
)(unsigned long)host_ifconf
->ifc_buf
;
3389 target_ifreq_size
= thunk_type_size(ifreq_arg_type
, 0);
3390 nb_ifreq
= target_ifc_len
/ target_ifreq_size
;
3391 host_ifc_len
= nb_ifreq
* sizeof(struct ifreq
);
3393 outbufsz
= sizeof(*host_ifconf
) + host_ifc_len
;
3394 if (outbufsz
> MAX_STRUCT_SIZE
) {
3395 /* We can't fit all the extents into the fixed size buffer.
3396 * Allocate one that is large enough and use it instead.
3398 host_ifconf
= malloc(outbufsz
);
3400 return -TARGET_ENOMEM
;
3402 memcpy(host_ifconf
, buf_temp
, sizeof(*host_ifconf
));
3405 host_ifc_buf
= (char*)host_ifconf
+ sizeof(*host_ifconf
);
3407 host_ifconf
->ifc_len
= host_ifc_len
;
3408 host_ifconf
->ifc_buf
= host_ifc_buf
;
3410 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, host_ifconf
));
3411 if (!is_error(ret
)) {
3412 /* convert host ifc_len to target ifc_len */
3414 nb_ifreq
= host_ifconf
->ifc_len
/ sizeof(struct ifreq
);
3415 target_ifc_len
= nb_ifreq
* target_ifreq_size
;
3416 host_ifconf
->ifc_len
= target_ifc_len
;
3418 /* restore target ifc_buf */
3420 host_ifconf
->ifc_buf
= (char *)(unsigned long)target_ifc_buf
;
3422 /* copy struct ifconf to target user */
3424 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3426 return -TARGET_EFAULT
;
3427 thunk_convert(argptr
, host_ifconf
, arg_type
, THUNK_TARGET
);
3428 unlock_user(argptr
, arg
, target_size
);
3430 /* copy ifreq[] to target user */
3432 argptr
= lock_user(VERIFY_WRITE
, target_ifc_buf
, target_ifc_len
, 0);
3433 for (i
= 0; i
< nb_ifreq
; i
++) {
3434 thunk_convert(argptr
+ i
* target_ifreq_size
,
3435 host_ifc_buf
+ i
* sizeof(struct ifreq
),
3436 ifreq_arg_type
, THUNK_TARGET
);
3438 unlock_user(argptr
, target_ifc_buf
, target_ifc_len
);
3448 static abi_long
do_ioctl_dm(const IOCTLEntry
*ie
, uint8_t *buf_temp
, int fd
,
3449 abi_long cmd
, abi_long arg
)
3452 struct dm_ioctl
*host_dm
;
3453 abi_long guest_data
;
3454 uint32_t guest_data_size
;
3456 const argtype
*arg_type
= ie
->arg_type
;
3458 void *big_buf
= NULL
;
3462 target_size
= thunk_type_size(arg_type
, 0);
3463 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3465 ret
= -TARGET_EFAULT
;
3468 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3469 unlock_user(argptr
, arg
, 0);
3471 /* buf_temp is too small, so fetch things into a bigger buffer */
3472 big_buf
= g_malloc0(((struct dm_ioctl
*)buf_temp
)->data_size
* 2);
3473 memcpy(big_buf
, buf_temp
, target_size
);
3477 guest_data
= arg
+ host_dm
->data_start
;
3478 if ((guest_data
- arg
) < 0) {
3482 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3483 host_data
= (char*)host_dm
+ host_dm
->data_start
;
3485 argptr
= lock_user(VERIFY_READ
, guest_data
, guest_data_size
, 1);
3486 switch (ie
->host_cmd
) {
3488 case DM_LIST_DEVICES
:
3491 case DM_DEV_SUSPEND
:
3494 case DM_TABLE_STATUS
:
3495 case DM_TABLE_CLEAR
:
3497 case DM_LIST_VERSIONS
:
3501 case DM_DEV_SET_GEOMETRY
:
3502 /* data contains only strings */
3503 memcpy(host_data
, argptr
, guest_data_size
);
3506 memcpy(host_data
, argptr
, guest_data_size
);
3507 *(uint64_t*)host_data
= tswap64(*(uint64_t*)argptr
);
3511 void *gspec
= argptr
;
3512 void *cur_data
= host_data
;
3513 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3514 int spec_size
= thunk_type_size(arg_type
, 0);
3517 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3518 struct dm_target_spec
*spec
= cur_data
;
3522 thunk_convert(spec
, gspec
, arg_type
, THUNK_HOST
);
3523 slen
= strlen((char*)gspec
+ spec_size
) + 1;
3525 spec
->next
= sizeof(*spec
) + slen
;
3526 strcpy((char*)&spec
[1], gspec
+ spec_size
);
3528 cur_data
+= spec
->next
;
3533 ret
= -TARGET_EINVAL
;
3536 unlock_user(argptr
, guest_data
, 0);
3538 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3539 if (!is_error(ret
)) {
3540 guest_data
= arg
+ host_dm
->data_start
;
3541 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3542 argptr
= lock_user(VERIFY_WRITE
, guest_data
, guest_data_size
, 0);
3543 switch (ie
->host_cmd
) {
3548 case DM_DEV_SUSPEND
:
3551 case DM_TABLE_CLEAR
:
3553 case DM_DEV_SET_GEOMETRY
:
3554 /* no return data */
3556 case DM_LIST_DEVICES
:
3558 struct dm_name_list
*nl
= (void*)host_dm
+ host_dm
->data_start
;
3559 uint32_t remaining_data
= guest_data_size
;
3560 void *cur_data
= argptr
;
3561 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_name_list
) };
3562 int nl_size
= 12; /* can't use thunk_size due to alignment */
3565 uint32_t next
= nl
->next
;
3567 nl
->next
= nl_size
+ (strlen(nl
->name
) + 1);
3569 if (remaining_data
< nl
->next
) {
3570 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3573 thunk_convert(cur_data
, nl
, arg_type
, THUNK_TARGET
);
3574 strcpy(cur_data
+ nl_size
, nl
->name
);
3575 cur_data
+= nl
->next
;
3576 remaining_data
-= nl
->next
;
3580 nl
= (void*)nl
+ next
;
3585 case DM_TABLE_STATUS
:
3587 struct dm_target_spec
*spec
= (void*)host_dm
+ host_dm
->data_start
;
3588 void *cur_data
= argptr
;
3589 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3590 int spec_size
= thunk_type_size(arg_type
, 0);
3593 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3594 uint32_t next
= spec
->next
;
3595 int slen
= strlen((char*)&spec
[1]) + 1;
3596 spec
->next
= (cur_data
- argptr
) + spec_size
+ slen
;
3597 if (guest_data_size
< spec
->next
) {
3598 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3601 thunk_convert(cur_data
, spec
, arg_type
, THUNK_TARGET
);
3602 strcpy(cur_data
+ spec_size
, (char*)&spec
[1]);
3603 cur_data
= argptr
+ spec
->next
;
3604 spec
= (void*)host_dm
+ host_dm
->data_start
+ next
;
3610 void *hdata
= (void*)host_dm
+ host_dm
->data_start
;
3611 int count
= *(uint32_t*)hdata
;
3612 uint64_t *hdev
= hdata
+ 8;
3613 uint64_t *gdev
= argptr
+ 8;
3616 *(uint32_t*)argptr
= tswap32(count
);
3617 for (i
= 0; i
< count
; i
++) {
3618 *gdev
= tswap64(*hdev
);
3624 case DM_LIST_VERSIONS
:
3626 struct dm_target_versions
*vers
= (void*)host_dm
+ host_dm
->data_start
;
3627 uint32_t remaining_data
= guest_data_size
;
3628 void *cur_data
= argptr
;
3629 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_versions
) };
3630 int vers_size
= thunk_type_size(arg_type
, 0);
3633 uint32_t next
= vers
->next
;
3635 vers
->next
= vers_size
+ (strlen(vers
->name
) + 1);
3637 if (remaining_data
< vers
->next
) {
3638 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3641 thunk_convert(cur_data
, vers
, arg_type
, THUNK_TARGET
);
3642 strcpy(cur_data
+ vers_size
, vers
->name
);
3643 cur_data
+= vers
->next
;
3644 remaining_data
-= vers
->next
;
3648 vers
= (void*)vers
+ next
;
3653 ret
= -TARGET_EINVAL
;
3656 unlock_user(argptr
, guest_data
, guest_data_size
);
3658 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3660 ret
= -TARGET_EFAULT
;
3663 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3664 unlock_user(argptr
, arg
, target_size
);
3671 static abi_long
do_ioctl_rt(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3672 int fd
, abi_long cmd
, abi_long arg
)
3674 const argtype
*arg_type
= ie
->arg_type
;
3675 const StructEntry
*se
;
3676 const argtype
*field_types
;
3677 const int *dst_offsets
, *src_offsets
;
3680 abi_ulong
*target_rt_dev_ptr
;
3681 unsigned long *host_rt_dev_ptr
;
3685 assert(ie
->access
== IOC_W
);
3686 assert(*arg_type
== TYPE_PTR
);
3688 assert(*arg_type
== TYPE_STRUCT
);
3689 target_size
= thunk_type_size(arg_type
, 0);
3690 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3692 return -TARGET_EFAULT
;
3695 assert(*arg_type
== (int)STRUCT_rtentry
);
3696 se
= struct_entries
+ *arg_type
++;
3697 assert(se
->convert
[0] == NULL
);
3698 /* convert struct here to be able to catch rt_dev string */
3699 field_types
= se
->field_types
;
3700 dst_offsets
= se
->field_offsets
[THUNK_HOST
];
3701 src_offsets
= se
->field_offsets
[THUNK_TARGET
];
3702 for (i
= 0; i
< se
->nb_fields
; i
++) {
3703 if (dst_offsets
[i
] == offsetof(struct rtentry
, rt_dev
)) {
3704 assert(*field_types
== TYPE_PTRVOID
);
3705 target_rt_dev_ptr
= (abi_ulong
*)(argptr
+ src_offsets
[i
]);
3706 host_rt_dev_ptr
= (unsigned long *)(buf_temp
+ dst_offsets
[i
]);
3707 if (*target_rt_dev_ptr
!= 0) {
3708 *host_rt_dev_ptr
= (unsigned long)lock_user_string(
3709 tswapal(*target_rt_dev_ptr
));
3710 if (!*host_rt_dev_ptr
) {
3711 unlock_user(argptr
, arg
, 0);
3712 return -TARGET_EFAULT
;
3715 *host_rt_dev_ptr
= 0;
3720 field_types
= thunk_convert(buf_temp
+ dst_offsets
[i
],
3721 argptr
+ src_offsets
[i
],
3722 field_types
, THUNK_HOST
);
3724 unlock_user(argptr
, arg
, 0);
3726 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3727 if (*host_rt_dev_ptr
!= 0) {
3728 unlock_user((void *)*host_rt_dev_ptr
,
3729 *target_rt_dev_ptr
, 0);
3734 static IOCTLEntry ioctl_entries
[] = {
3735 #define IOCTL(cmd, access, ...) \
3736 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3737 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3738 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3743 /* ??? Implement proper locking for ioctls. */
3744 /* do_ioctl() Must return target values and target errnos. */
3745 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
3747 const IOCTLEntry
*ie
;
3748 const argtype
*arg_type
;
3750 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
3756 if (ie
->target_cmd
== 0) {
3757 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
3758 return -TARGET_ENOSYS
;
3760 if (ie
->target_cmd
== cmd
)
3764 arg_type
= ie
->arg_type
;
3766 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
3769 return ie
->do_ioctl(ie
, buf_temp
, fd
, cmd
, arg
);
3772 switch(arg_type
[0]) {
3775 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
3780 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
3784 target_size
= thunk_type_size(arg_type
, 0);
3785 switch(ie
->access
) {
3787 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3788 if (!is_error(ret
)) {
3789 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3791 return -TARGET_EFAULT
;
3792 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3793 unlock_user(argptr
, arg
, target_size
);
3797 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3799 return -TARGET_EFAULT
;
3800 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3801 unlock_user(argptr
, arg
, 0);
3802 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3806 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3808 return -TARGET_EFAULT
;
3809 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3810 unlock_user(argptr
, arg
, 0);
3811 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3812 if (!is_error(ret
)) {
3813 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3815 return -TARGET_EFAULT
;
3816 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3817 unlock_user(argptr
, arg
, target_size
);
3823 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3824 (long)cmd
, arg_type
[0]);
3825 ret
= -TARGET_ENOSYS
;
3831 static const bitmask_transtbl iflag_tbl
[] = {
3832 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
3833 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
3834 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
3835 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
3836 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
3837 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
3838 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
3839 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
3840 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
3841 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
3842 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
3843 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
3844 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
3845 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
3849 static const bitmask_transtbl oflag_tbl
[] = {
3850 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
3851 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
3852 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
3853 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
3854 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
3855 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
3856 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
3857 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
3858 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
3859 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
3860 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
3861 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
3862 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
3863 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
3864 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
3865 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
3866 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
3867 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
3868 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
3869 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
3870 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
3871 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
3872 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
3873 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
3877 static const bitmask_transtbl cflag_tbl
[] = {
3878 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
3879 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
3880 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
3881 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
3882 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
3883 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
3884 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
3885 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
3886 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
3887 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
3888 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
3889 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
3890 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
3891 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
3892 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
3893 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
3894 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
3895 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
3896 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
3897 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
3898 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
3899 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
3900 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
3901 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
3902 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
3903 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
3904 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
3905 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
3906 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
3907 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
3908 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
3912 static const bitmask_transtbl lflag_tbl
[] = {
3913 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
3914 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
3915 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
3916 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
3917 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
3918 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
3919 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
3920 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
3921 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
3922 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
3923 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
3924 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
3925 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
3926 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
3927 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
3931 static void target_to_host_termios (void *dst
, const void *src
)
3933 struct host_termios
*host
= dst
;
3934 const struct target_termios
*target
= src
;
3937 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
3939 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
3941 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
3943 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
3944 host
->c_line
= target
->c_line
;
3946 memset(host
->c_cc
, 0, sizeof(host
->c_cc
));
3947 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
3948 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
3949 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
3950 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
3951 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
3952 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
3953 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
3954 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
3955 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
3956 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
3957 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
3958 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
3959 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
3960 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
3961 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
3962 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
3963 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
3966 static void host_to_target_termios (void *dst
, const void *src
)
3968 struct target_termios
*target
= dst
;
3969 const struct host_termios
*host
= src
;
3972 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
3974 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
3976 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
3978 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
3979 target
->c_line
= host
->c_line
;
3981 memset(target
->c_cc
, 0, sizeof(target
->c_cc
));
3982 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
3983 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
3984 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
3985 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
3986 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
3987 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
3988 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
3989 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
3990 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
3991 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
3992 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
3993 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
3994 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
3995 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
3996 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
3997 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
3998 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
4001 static const StructEntry struct_termios_def
= {
4002 .convert
= { host_to_target_termios
, target_to_host_termios
},
4003 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
4004 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
4007 static bitmask_transtbl mmap_flags_tbl
[] = {
4008 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
4009 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
4010 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
4011 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
4012 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
4013 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
4014 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
4015 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
4019 #if defined(TARGET_I386)
4021 /* NOTE: there is really one LDT for all the threads */
4022 static uint8_t *ldt_table
;
4024 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
4031 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
4032 if (size
> bytecount
)
4034 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
4036 return -TARGET_EFAULT
;
4037 /* ??? Should this by byteswapped? */
4038 memcpy(p
, ldt_table
, size
);
4039 unlock_user(p
, ptr
, size
);
4043 /* XXX: add locking support */
4044 static abi_long
write_ldt(CPUX86State
*env
,
4045 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
4047 struct target_modify_ldt_ldt_s ldt_info
;
4048 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4049 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
4050 int seg_not_present
, useable
, lm
;
4051 uint32_t *lp
, entry_1
, entry_2
;
4053 if (bytecount
!= sizeof(ldt_info
))
4054 return -TARGET_EINVAL
;
4055 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
4056 return -TARGET_EFAULT
;
4057 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
4058 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
4059 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
4060 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
4061 unlock_user_struct(target_ldt_info
, ptr
, 0);
4063 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
4064 return -TARGET_EINVAL
;
4065 seg_32bit
= ldt_info
.flags
& 1;
4066 contents
= (ldt_info
.flags
>> 1) & 3;
4067 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
4068 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
4069 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
4070 useable
= (ldt_info
.flags
>> 6) & 1;
4074 lm
= (ldt_info
.flags
>> 7) & 1;
4076 if (contents
== 3) {
4078 return -TARGET_EINVAL
;
4079 if (seg_not_present
== 0)
4080 return -TARGET_EINVAL
;
4082 /* allocate the LDT */
4084 env
->ldt
.base
= target_mmap(0,
4085 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
4086 PROT_READ
|PROT_WRITE
,
4087 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
4088 if (env
->ldt
.base
== -1)
4089 return -TARGET_ENOMEM
;
4090 memset(g2h(env
->ldt
.base
), 0,
4091 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
4092 env
->ldt
.limit
= 0xffff;
4093 ldt_table
= g2h(env
->ldt
.base
);
4096 /* NOTE: same code as Linux kernel */
4097 /* Allow LDTs to be cleared by the user. */
4098 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4101 read_exec_only
== 1 &&
4103 limit_in_pages
== 0 &&
4104 seg_not_present
== 1 &&
4112 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4113 (ldt_info
.limit
& 0x0ffff);
4114 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4115 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4116 (ldt_info
.limit
& 0xf0000) |
4117 ((read_exec_only
^ 1) << 9) |
4119 ((seg_not_present
^ 1) << 15) |
4121 (limit_in_pages
<< 23) |
4125 entry_2
|= (useable
<< 20);
4127 /* Install the new entry ... */
4129 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
4130 lp
[0] = tswap32(entry_1
);
4131 lp
[1] = tswap32(entry_2
);
4135 /* specific and weird i386 syscalls */
4136 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
4137 unsigned long bytecount
)
4143 ret
= read_ldt(ptr
, bytecount
);
4146 ret
= write_ldt(env
, ptr
, bytecount
, 1);
4149 ret
= write_ldt(env
, ptr
, bytecount
, 0);
4152 ret
= -TARGET_ENOSYS
;
4158 #if defined(TARGET_I386) && defined(TARGET_ABI32)
4159 abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4161 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4162 struct target_modify_ldt_ldt_s ldt_info
;
4163 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4164 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
4165 int seg_not_present
, useable
, lm
;
4166 uint32_t *lp
, entry_1
, entry_2
;
4169 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4170 if (!target_ldt_info
)
4171 return -TARGET_EFAULT
;
4172 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
4173 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
4174 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
4175 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
4176 if (ldt_info
.entry_number
== -1) {
4177 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
4178 if (gdt_table
[i
] == 0) {
4179 ldt_info
.entry_number
= i
;
4180 target_ldt_info
->entry_number
= tswap32(i
);
4185 unlock_user_struct(target_ldt_info
, ptr
, 1);
4187 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
4188 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
4189 return -TARGET_EINVAL
;
4190 seg_32bit
= ldt_info
.flags
& 1;
4191 contents
= (ldt_info
.flags
>> 1) & 3;
4192 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
4193 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
4194 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
4195 useable
= (ldt_info
.flags
>> 6) & 1;
4199 lm
= (ldt_info
.flags
>> 7) & 1;
4202 if (contents
== 3) {
4203 if (seg_not_present
== 0)
4204 return -TARGET_EINVAL
;
4207 /* NOTE: same code as Linux kernel */
4208 /* Allow LDTs to be cleared by the user. */
4209 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4210 if ((contents
== 0 &&
4211 read_exec_only
== 1 &&
4213 limit_in_pages
== 0 &&
4214 seg_not_present
== 1 &&
4222 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4223 (ldt_info
.limit
& 0x0ffff);
4224 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4225 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4226 (ldt_info
.limit
& 0xf0000) |
4227 ((read_exec_only
^ 1) << 9) |
4229 ((seg_not_present
^ 1) << 15) |
4231 (limit_in_pages
<< 23) |
4236 /* Install the new entry ... */
4238 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
4239 lp
[0] = tswap32(entry_1
);
4240 lp
[1] = tswap32(entry_2
);
4244 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4246 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4247 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4248 uint32_t base_addr
, limit
, flags
;
4249 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
4250 int seg_not_present
, useable
, lm
;
4251 uint32_t *lp
, entry_1
, entry_2
;
4253 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4254 if (!target_ldt_info
)
4255 return -TARGET_EFAULT
;
4256 idx
= tswap32(target_ldt_info
->entry_number
);
4257 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
4258 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
4259 unlock_user_struct(target_ldt_info
, ptr
, 1);
4260 return -TARGET_EINVAL
;
4262 lp
= (uint32_t *)(gdt_table
+ idx
);
4263 entry_1
= tswap32(lp
[0]);
4264 entry_2
= tswap32(lp
[1]);
4266 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
4267 contents
= (entry_2
>> 10) & 3;
4268 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
4269 seg_32bit
= (entry_2
>> 22) & 1;
4270 limit_in_pages
= (entry_2
>> 23) & 1;
4271 useable
= (entry_2
>> 20) & 1;
4275 lm
= (entry_2
>> 21) & 1;
4277 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
4278 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
4279 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
4280 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
4281 base_addr
= (entry_1
>> 16) |
4282 (entry_2
& 0xff000000) |
4283 ((entry_2
& 0xff) << 16);
4284 target_ldt_info
->base_addr
= tswapal(base_addr
);
4285 target_ldt_info
->limit
= tswap32(limit
);
4286 target_ldt_info
->flags
= tswap32(flags
);
4287 unlock_user_struct(target_ldt_info
, ptr
, 1);
4290 #endif /* TARGET_I386 && TARGET_ABI32 */
4292 #ifndef TARGET_ABI32
4293 abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
4300 case TARGET_ARCH_SET_GS
:
4301 case TARGET_ARCH_SET_FS
:
4302 if (code
== TARGET_ARCH_SET_GS
)
4306 cpu_x86_load_seg(env
, idx
, 0);
4307 env
->segs
[idx
].base
= addr
;
4309 case TARGET_ARCH_GET_GS
:
4310 case TARGET_ARCH_GET_FS
:
4311 if (code
== TARGET_ARCH_GET_GS
)
4315 val
= env
->segs
[idx
].base
;
4316 if (put_user(val
, addr
, abi_ulong
))
4317 ret
= -TARGET_EFAULT
;
4320 ret
= -TARGET_EINVAL
;
4327 #endif /* defined(TARGET_I386) */
4329 #define NEW_STACK_SIZE 0x40000
4332 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
4335 pthread_mutex_t mutex
;
4336 pthread_cond_t cond
;
4339 abi_ulong child_tidptr
;
4340 abi_ulong parent_tidptr
;
4344 static void *clone_func(void *arg
)
4346 new_thread_info
*info
= arg
;
4352 cpu
= ENV_GET_CPU(env
);
4354 ts
= (TaskState
*)env
->opaque
;
4355 info
->tid
= gettid();
4356 cpu
->host_tid
= info
->tid
;
4358 if (info
->child_tidptr
)
4359 put_user_u32(info
->tid
, info
->child_tidptr
);
4360 if (info
->parent_tidptr
)
4361 put_user_u32(info
->tid
, info
->parent_tidptr
);
4362 /* Enable signals. */
4363 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
4364 /* Signal to the parent that we're ready. */
4365 pthread_mutex_lock(&info
->mutex
);
4366 pthread_cond_broadcast(&info
->cond
);
4367 pthread_mutex_unlock(&info
->mutex
);
4368 /* Wait until the parent has finshed initializing the tls state. */
4369 pthread_mutex_lock(&clone_lock
);
4370 pthread_mutex_unlock(&clone_lock
);
4376 /* do_fork() Must return host values and target errnos (unlike most
4377 do_*() functions). */
4378 static int do_fork(CPUArchState
*env
, unsigned int flags
, abi_ulong newsp
,
4379 abi_ulong parent_tidptr
, target_ulong newtls
,
4380 abi_ulong child_tidptr
)
4384 CPUArchState
*new_env
;
4385 unsigned int nptl_flags
;
4388 /* Emulate vfork() with fork() */
4389 if (flags
& CLONE_VFORK
)
4390 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
4392 if (flags
& CLONE_VM
) {
4393 TaskState
*parent_ts
= (TaskState
*)env
->opaque
;
4394 new_thread_info info
;
4395 pthread_attr_t attr
;
4397 ts
= g_malloc0(sizeof(TaskState
));
4398 init_task_state(ts
);
4399 /* we create a new CPU instance. */
4400 new_env
= cpu_copy(env
);
4401 /* Init regs that differ from the parent. */
4402 cpu_clone_regs(new_env
, newsp
);
4403 new_env
->opaque
= ts
;
4404 ts
->bprm
= parent_ts
->bprm
;
4405 ts
->info
= parent_ts
->info
;
4407 flags
&= ~CLONE_NPTL_FLAGS2
;
4409 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
4410 ts
->child_tidptr
= child_tidptr
;
4413 if (nptl_flags
& CLONE_SETTLS
)
4414 cpu_set_tls (new_env
, newtls
);
4416 /* Grab a mutex so that thread setup appears atomic. */
4417 pthread_mutex_lock(&clone_lock
);
4419 memset(&info
, 0, sizeof(info
));
4420 pthread_mutex_init(&info
.mutex
, NULL
);
4421 pthread_mutex_lock(&info
.mutex
);
4422 pthread_cond_init(&info
.cond
, NULL
);
4424 if (nptl_flags
& CLONE_CHILD_SETTID
)
4425 info
.child_tidptr
= child_tidptr
;
4426 if (nptl_flags
& CLONE_PARENT_SETTID
)
4427 info
.parent_tidptr
= parent_tidptr
;
4429 ret
= pthread_attr_init(&attr
);
4430 ret
= pthread_attr_setstacksize(&attr
, NEW_STACK_SIZE
);
4431 ret
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
4432 /* It is not safe to deliver signals until the child has finished
4433 initializing, so temporarily block all signals. */
4434 sigfillset(&sigmask
);
4435 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
4437 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
4438 /* TODO: Free new CPU state if thread creation failed. */
4440 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
4441 pthread_attr_destroy(&attr
);
4443 /* Wait for the child to initialize. */
4444 pthread_cond_wait(&info
.cond
, &info
.mutex
);
4446 if (flags
& CLONE_PARENT_SETTID
)
4447 put_user_u32(ret
, parent_tidptr
);
4451 pthread_mutex_unlock(&info
.mutex
);
4452 pthread_cond_destroy(&info
.cond
);
4453 pthread_mutex_destroy(&info
.mutex
);
4454 pthread_mutex_unlock(&clone_lock
);
4456 /* if no CLONE_VM, we consider it is a fork */
4457 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
4462 /* Child Process. */
4463 cpu_clone_regs(env
, newsp
);
4465 /* There is a race condition here. The parent process could
4466 theoretically read the TID in the child process before the child
4467 tid is set. This would require using either ptrace
4468 (not implemented) or having *_tidptr to point at a shared memory
4469 mapping. We can't repeat the spinlock hack used above because
4470 the child process gets its own copy of the lock. */
4471 if (flags
& CLONE_CHILD_SETTID
)
4472 put_user_u32(gettid(), child_tidptr
);
4473 if (flags
& CLONE_PARENT_SETTID
)
4474 put_user_u32(gettid(), parent_tidptr
);
4475 ts
= (TaskState
*)env
->opaque
;
4476 if (flags
& CLONE_SETTLS
)
4477 cpu_set_tls (env
, newtls
);
4478 if (flags
& CLONE_CHILD_CLEARTID
)
4479 ts
->child_tidptr
= child_tidptr
;
4487 /* warning : doesn't handle linux specific flags... */
4488 static int target_to_host_fcntl_cmd(int cmd
)
4491 case TARGET_F_DUPFD
:
4492 case TARGET_F_GETFD
:
4493 case TARGET_F_SETFD
:
4494 case TARGET_F_GETFL
:
4495 case TARGET_F_SETFL
:
4497 case TARGET_F_GETLK
:
4499 case TARGET_F_SETLK
:
4501 case TARGET_F_SETLKW
:
4503 case TARGET_F_GETOWN
:
4505 case TARGET_F_SETOWN
:
4507 case TARGET_F_GETSIG
:
4509 case TARGET_F_SETSIG
:
4511 #if TARGET_ABI_BITS == 32
4512 case TARGET_F_GETLK64
:
4514 case TARGET_F_SETLK64
:
4516 case TARGET_F_SETLKW64
:
4519 case TARGET_F_SETLEASE
:
4521 case TARGET_F_GETLEASE
:
4523 #ifdef F_DUPFD_CLOEXEC
4524 case TARGET_F_DUPFD_CLOEXEC
:
4525 return F_DUPFD_CLOEXEC
;
4527 case TARGET_F_NOTIFY
:
4530 return -TARGET_EINVAL
;
4532 return -TARGET_EINVAL
;
4535 #define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4536 static const bitmask_transtbl flock_tbl
[] = {
4537 TRANSTBL_CONVERT(F_RDLCK
),
4538 TRANSTBL_CONVERT(F_WRLCK
),
4539 TRANSTBL_CONVERT(F_UNLCK
),
4540 TRANSTBL_CONVERT(F_EXLCK
),
4541 TRANSTBL_CONVERT(F_SHLCK
),
4545 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
4548 struct target_flock
*target_fl
;
4549 struct flock64 fl64
;
4550 struct target_flock64
*target_fl64
;
4552 int host_cmd
= target_to_host_fcntl_cmd(cmd
);
4554 if (host_cmd
== -TARGET_EINVAL
)
4558 case TARGET_F_GETLK
:
4559 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4560 return -TARGET_EFAULT
;
4562 target_to_host_bitmask(tswap16(target_fl
->l_type
), flock_tbl
);
4563 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4564 fl
.l_start
= tswapal(target_fl
->l_start
);
4565 fl
.l_len
= tswapal(target_fl
->l_len
);
4566 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4567 unlock_user_struct(target_fl
, arg
, 0);
4568 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4570 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
4571 return -TARGET_EFAULT
;
4573 host_to_target_bitmask(tswap16(fl
.l_type
), flock_tbl
);
4574 target_fl
->l_whence
= tswap16(fl
.l_whence
);
4575 target_fl
->l_start
= tswapal(fl
.l_start
);
4576 target_fl
->l_len
= tswapal(fl
.l_len
);
4577 target_fl
->l_pid
= tswap32(fl
.l_pid
);
4578 unlock_user_struct(target_fl
, arg
, 1);
4582 case TARGET_F_SETLK
:
4583 case TARGET_F_SETLKW
:
4584 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4585 return -TARGET_EFAULT
;
4587 target_to_host_bitmask(tswap16(target_fl
->l_type
), flock_tbl
);
4588 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4589 fl
.l_start
= tswapal(target_fl
->l_start
);
4590 fl
.l_len
= tswapal(target_fl
->l_len
);
4591 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4592 unlock_user_struct(target_fl
, arg
, 0);
4593 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4596 case TARGET_F_GETLK64
:
4597 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4598 return -TARGET_EFAULT
;
4600 target_to_host_bitmask(tswap16(target_fl64
->l_type
), flock_tbl
) >> 1;
4601 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4602 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4603 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4604 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4605 unlock_user_struct(target_fl64
, arg
, 0);
4606 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4608 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
4609 return -TARGET_EFAULT
;
4610 target_fl64
->l_type
=
4611 host_to_target_bitmask(tswap16(fl64
.l_type
), flock_tbl
) >> 1;
4612 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
4613 target_fl64
->l_start
= tswap64(fl64
.l_start
);
4614 target_fl64
->l_len
= tswap64(fl64
.l_len
);
4615 target_fl64
->l_pid
= tswap32(fl64
.l_pid
);
4616 unlock_user_struct(target_fl64
, arg
, 1);
4619 case TARGET_F_SETLK64
:
4620 case TARGET_F_SETLKW64
:
4621 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4622 return -TARGET_EFAULT
;
4624 target_to_host_bitmask(tswap16(target_fl64
->l_type
), flock_tbl
) >> 1;
4625 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4626 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4627 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4628 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4629 unlock_user_struct(target_fl64
, arg
, 0);
4630 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4633 case TARGET_F_GETFL
:
4634 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4636 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
4640 case TARGET_F_SETFL
:
4641 ret
= get_errno(fcntl(fd
, host_cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
4644 case TARGET_F_SETOWN
:
4645 case TARGET_F_GETOWN
:
4646 case TARGET_F_SETSIG
:
4647 case TARGET_F_GETSIG
:
4648 case TARGET_F_SETLEASE
:
4649 case TARGET_F_GETLEASE
:
4650 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4654 ret
= get_errno(fcntl(fd
, cmd
, arg
));
4662 static inline int high2lowuid(int uid
)
4670 static inline int high2lowgid(int gid
)
4678 static inline int low2highuid(int uid
)
4680 if ((int16_t)uid
== -1)
4686 static inline int low2highgid(int gid
)
4688 if ((int16_t)gid
== -1)
4693 static inline int tswapid(int id
)
4697 #else /* !USE_UID16 */
4698 static inline int high2lowuid(int uid
)
4702 static inline int high2lowgid(int gid
)
4706 static inline int low2highuid(int uid
)
4710 static inline int low2highgid(int gid
)
4714 static inline int tswapid(int id
)
4718 #endif /* USE_UID16 */
4720 void syscall_init(void)
4723 const argtype
*arg_type
;
4727 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4728 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4729 #include "syscall_types.h"
4731 #undef STRUCT_SPECIAL
4733 /* Build target_to_host_errno_table[] table from
4734 * host_to_target_errno_table[]. */
4735 for (i
= 0; i
< ERRNO_TABLE_SIZE
; i
++) {
4736 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
4739 /* we patch the ioctl size if necessary. We rely on the fact that
4740 no ioctl has all the bits at '1' in the size field */
4742 while (ie
->target_cmd
!= 0) {
4743 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
4744 TARGET_IOC_SIZEMASK
) {
4745 arg_type
= ie
->arg_type
;
4746 if (arg_type
[0] != TYPE_PTR
) {
4747 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
4752 size
= thunk_type_size(arg_type
, 0);
4753 ie
->target_cmd
= (ie
->target_cmd
&
4754 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
4755 (size
<< TARGET_IOC_SIZESHIFT
);
4758 /* automatic consistency check if same arch */
4759 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4760 (defined(__x86_64__) && defined(TARGET_X86_64))
4761 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
4762 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4763 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
4770 #if TARGET_ABI_BITS == 32
4771 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
4773 #ifdef TARGET_WORDS_BIGENDIAN
4774 return ((uint64_t)word0
<< 32) | word1
;
4776 return ((uint64_t)word1
<< 32) | word0
;
4779 #else /* TARGET_ABI_BITS == 32 */
4780 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
4784 #endif /* TARGET_ABI_BITS != 32 */
4786 #ifdef TARGET_NR_truncate64
4787 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
4792 if (regpairs_aligned(cpu_env
)) {
4796 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
4800 #ifdef TARGET_NR_ftruncate64
4801 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
4806 if (regpairs_aligned(cpu_env
)) {
4810 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
4814 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
4815 abi_ulong target_addr
)
4817 struct target_timespec
*target_ts
;
4819 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
4820 return -TARGET_EFAULT
;
4821 host_ts
->tv_sec
= tswapal(target_ts
->tv_sec
);
4822 host_ts
->tv_nsec
= tswapal(target_ts
->tv_nsec
);
4823 unlock_user_struct(target_ts
, target_addr
, 0);
4827 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
4828 struct timespec
*host_ts
)
4830 struct target_timespec
*target_ts
;
4832 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
4833 return -TARGET_EFAULT
;
4834 target_ts
->tv_sec
= tswapal(host_ts
->tv_sec
);
4835 target_ts
->tv_nsec
= tswapal(host_ts
->tv_nsec
);
4836 unlock_user_struct(target_ts
, target_addr
, 1);
4840 static inline abi_long
target_to_host_itimerspec(struct itimerspec
*host_itspec
,
4841 abi_ulong target_addr
)
4843 struct target_itimerspec
*target_itspec
;
4845 if (!lock_user_struct(VERIFY_READ
, target_itspec
, target_addr
, 1)) {
4846 return -TARGET_EFAULT
;
4849 host_itspec
->it_interval
.tv_sec
=
4850 tswapal(target_itspec
->it_interval
.tv_sec
);
4851 host_itspec
->it_interval
.tv_nsec
=
4852 tswapal(target_itspec
->it_interval
.tv_nsec
);
4853 host_itspec
->it_value
.tv_sec
= tswapal(target_itspec
->it_value
.tv_sec
);
4854 host_itspec
->it_value
.tv_nsec
= tswapal(target_itspec
->it_value
.tv_nsec
);
4856 unlock_user_struct(target_itspec
, target_addr
, 1);
4860 static inline abi_long
host_to_target_itimerspec(abi_ulong target_addr
,
4861 struct itimerspec
*host_its
)
4863 struct target_itimerspec
*target_itspec
;
4865 if (!lock_user_struct(VERIFY_WRITE
, target_itspec
, target_addr
, 0)) {
4866 return -TARGET_EFAULT
;
4869 target_itspec
->it_interval
.tv_sec
= tswapal(host_its
->it_interval
.tv_sec
);
4870 target_itspec
->it_interval
.tv_nsec
= tswapal(host_its
->it_interval
.tv_nsec
);
4872 target_itspec
->it_value
.tv_sec
= tswapal(host_its
->it_value
.tv_sec
);
4873 target_itspec
->it_value
.tv_nsec
= tswapal(host_its
->it_value
.tv_nsec
);
4875 unlock_user_struct(target_itspec
, target_addr
, 0);
4879 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4880 static inline abi_long
host_to_target_stat64(void *cpu_env
,
4881 abi_ulong target_addr
,
4882 struct stat
*host_st
)
4884 #if defined(TARGET_ARM) && defined(TARGET_ABI32)
4885 if (((CPUARMState
*)cpu_env
)->eabi
) {
4886 struct target_eabi_stat64
*target_st
;
4888 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4889 return -TARGET_EFAULT
;
4890 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
4891 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4892 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4893 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4894 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4896 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4897 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4898 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4899 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4900 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4901 __put_user(host_st
->st_size
, &target_st
->st_size
);
4902 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4903 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4904 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4905 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4906 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4907 unlock_user_struct(target_st
, target_addr
, 1);
4911 #if defined(TARGET_HAS_STRUCT_STAT64)
4912 struct target_stat64
*target_st
;
4914 struct target_stat
*target_st
;
4917 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4918 return -TARGET_EFAULT
;
4919 memset(target_st
, 0, sizeof(*target_st
));
4920 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4921 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4922 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4923 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4925 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4926 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4927 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4928 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4929 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4930 /* XXX: better use of kernel struct */
4931 __put_user(host_st
->st_size
, &target_st
->st_size
);
4932 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4933 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4934 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4935 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4936 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4937 unlock_user_struct(target_st
, target_addr
, 1);
4944 /* ??? Using host futex calls even when target atomic operations
4945 are not really atomic probably breaks things. However implementing
4946 futexes locally would make futexes shared between multiple processes
4947 tricky. However they're probably useless because guest atomic
4948 operations won't work either. */
4949 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
4950 target_ulong uaddr2
, int val3
)
4952 struct timespec ts
, *pts
;
4955 /* ??? We assume FUTEX_* constants are the same on both host
4957 #ifdef FUTEX_CMD_MASK
4958 base_op
= op
& FUTEX_CMD_MASK
;
4964 case FUTEX_WAIT_BITSET
:
4967 target_to_host_timespec(pts
, timeout
);
4971 return get_errno(sys_futex(g2h(uaddr
), op
, tswap32(val
),
4974 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4976 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4978 case FUTEX_CMP_REQUEUE
:
4980 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4981 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4982 But the prototype takes a `struct timespec *'; insert casts
4983 to satisfy the compiler. We do not need to tswap TIMEOUT
4984 since it's not compared to guest memory. */
4985 pts
= (struct timespec
*)(uintptr_t) timeout
;
4986 return get_errno(sys_futex(g2h(uaddr
), op
, val
, pts
,
4988 (base_op
== FUTEX_CMP_REQUEUE
4992 return -TARGET_ENOSYS
;
4996 /* Map host to target signal numbers for the wait family of syscalls.
4997 Assume all other status bits are the same. */
4998 int host_to_target_waitstatus(int status
)
5000 if (WIFSIGNALED(status
)) {
5001 return host_to_target_signal(WTERMSIG(status
)) | (status
& ~0x7f);
5003 if (WIFSTOPPED(status
)) {
5004 return (host_to_target_signal(WSTOPSIG(status
)) << 8)
5010 static int relstr_to_int(const char *s
)
5012 /* Convert a uname release string like "2.6.18" to an integer
5013 * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.)
5018 for (i
= 0; i
< 3; i
++) {
5020 while (*s
>= '0' && *s
<= '9') {
5025 tmp
= (tmp
<< 8) + n
;
5033 int get_osversion(void)
5035 static int osversion
;
5036 struct new_utsname buf
;
5041 if (qemu_uname_release
&& *qemu_uname_release
) {
5042 s
= qemu_uname_release
;
5044 if (sys_uname(&buf
))
5048 osversion
= relstr_to_int(s
);
5052 void init_qemu_uname_release(void)
5054 /* Initialize qemu_uname_release for later use.
5055 * If the host kernel is too old and the user hasn't asked for
5056 * a specific fake version number, we might want to fake a minimum
5057 * target kernel version.
5059 #ifdef UNAME_MINIMUM_RELEASE
5060 struct new_utsname buf
;
5062 if (qemu_uname_release
&& *qemu_uname_release
) {
5066 if (sys_uname(&buf
)) {
5070 if (relstr_to_int(buf
.release
) < relstr_to_int(UNAME_MINIMUM_RELEASE
)) {
5071 qemu_uname_release
= UNAME_MINIMUM_RELEASE
;
5076 static int open_self_maps(void *cpu_env
, int fd
)
5078 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5079 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5086 fp
= fopen("/proc/self/maps", "r");
5091 while ((read
= getline(&line
, &len
, fp
)) != -1) {
5092 int fields
, dev_maj
, dev_min
, inode
;
5093 uint64_t min
, max
, offset
;
5094 char flag_r
, flag_w
, flag_x
, flag_p
;
5095 char path
[512] = "";
5096 fields
= sscanf(line
, "%"PRIx64
"-%"PRIx64
" %c%c%c%c %"PRIx64
" %x:%x %d"
5097 " %512s", &min
, &max
, &flag_r
, &flag_w
, &flag_x
,
5098 &flag_p
, &offset
, &dev_maj
, &dev_min
, &inode
, path
);
5100 if ((fields
< 10) || (fields
> 11)) {
5103 if (!strncmp(path
, "[stack]", 7)) {
5106 if (h2g_valid(min
) && h2g_valid(max
)) {
5107 dprintf(fd
, TARGET_ABI_FMT_lx
"-" TARGET_ABI_FMT_lx
5108 " %c%c%c%c %08" PRIx64
" %02x:%02x %d %s%s\n",
5109 h2g(min
), h2g(max
), flag_r
, flag_w
,
5110 flag_x
, flag_p
, offset
, dev_maj
, dev_min
, inode
,
5111 path
[0] ? " " : "", path
);
5118 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
5119 dprintf(fd
, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
5120 (unsigned long long)ts
->info
->stack_limit
,
5121 (unsigned long long)(ts
->info
->start_stack
+
5122 (TARGET_PAGE_SIZE
- 1)) & TARGET_PAGE_MASK
,
5123 (unsigned long long)0);
5129 static int open_self_stat(void *cpu_env
, int fd
)
5131 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5132 abi_ulong start_stack
= ts
->info
->start_stack
;
5135 for (i
= 0; i
< 44; i
++) {
5143 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
5144 } else if (i
== 1) {
5146 snprintf(buf
, sizeof(buf
), "(%s) ", ts
->bprm
->argv
[0]);
5147 } else if (i
== 27) {
5150 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
5152 /* for the rest, there is MasterCard */
5153 snprintf(buf
, sizeof(buf
), "0%c", i
== 43 ? '\n' : ' ');
5157 if (write(fd
, buf
, len
) != len
) {
5165 static int open_self_auxv(void *cpu_env
, int fd
)
5167 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5168 abi_ulong auxv
= ts
->info
->saved_auxv
;
5169 abi_ulong len
= ts
->info
->auxv_len
;
5173 * Auxiliary vector is stored in target process stack.
5174 * read in whole auxv vector and copy it to file
5176 ptr
= lock_user(VERIFY_READ
, auxv
, len
, 0);
5180 r
= write(fd
, ptr
, len
);
5187 lseek(fd
, 0, SEEK_SET
);
5188 unlock_user(ptr
, auxv
, len
);
5194 static int is_proc_myself(const char *filename
, const char *entry
)
5196 if (!strncmp(filename
, "/proc/", strlen("/proc/"))) {
5197 filename
+= strlen("/proc/");
5198 if (!strncmp(filename
, "self/", strlen("self/"))) {
5199 filename
+= strlen("self/");
5200 } else if (*filename
>= '1' && *filename
<= '9') {
5202 snprintf(myself
, sizeof(myself
), "%d/", getpid());
5203 if (!strncmp(filename
, myself
, strlen(myself
))) {
5204 filename
+= strlen(myself
);
5211 if (!strcmp(filename
, entry
)) {
5218 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5219 static int is_proc(const char *filename
, const char *entry
)
5221 return strcmp(filename
, entry
) == 0;
5224 static int open_net_route(void *cpu_env
, int fd
)
5231 fp
= fopen("/proc/net/route", "r");
5238 read
= getline(&line
, &len
, fp
);
5239 dprintf(fd
, "%s", line
);
5243 while ((read
= getline(&line
, &len
, fp
)) != -1) {
5245 uint32_t dest
, gw
, mask
;
5246 unsigned int flags
, refcnt
, use
, metric
, mtu
, window
, irtt
;
5247 sscanf(line
, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5248 iface
, &dest
, &gw
, &flags
, &refcnt
, &use
, &metric
,
5249 &mask
, &mtu
, &window
, &irtt
);
5250 dprintf(fd
, "%s\t%08x\t%08x\t%04x\t%d\t%d\t%d\t%08x\t%d\t%u\t%u\n",
5251 iface
, tswap32(dest
), tswap32(gw
), flags
, refcnt
, use
,
5252 metric
, tswap32(mask
), mtu
, window
, irtt
);
5262 static int do_open(void *cpu_env
, const char *pathname
, int flags
, mode_t mode
)
5265 const char *filename
;
5266 int (*fill
)(void *cpu_env
, int fd
);
5267 int (*cmp
)(const char *s1
, const char *s2
);
5269 const struct fake_open
*fake_open
;
5270 static const struct fake_open fakes
[] = {
5271 { "maps", open_self_maps
, is_proc_myself
},
5272 { "stat", open_self_stat
, is_proc_myself
},
5273 { "auxv", open_self_auxv
, is_proc_myself
},
5274 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
5275 { "/proc/net/route", open_net_route
, is_proc
},
5277 { NULL
, NULL
, NULL
}
5280 for (fake_open
= fakes
; fake_open
->filename
; fake_open
++) {
5281 if (fake_open
->cmp(pathname
, fake_open
->filename
)) {
5286 if (fake_open
->filename
) {
5288 char filename
[PATH_MAX
];
5291 /* create temporary file to map stat to */
5292 tmpdir
= getenv("TMPDIR");
5295 snprintf(filename
, sizeof(filename
), "%s/qemu-open.XXXXXX", tmpdir
);
5296 fd
= mkstemp(filename
);
5302 if ((r
= fake_open
->fill(cpu_env
, fd
))) {
5306 lseek(fd
, 0, SEEK_SET
);
5311 return get_errno(open(path(pathname
), flags
, mode
));
5314 /* do_syscall() should always have a single exit point at the end so
5315 that actions, such as logging of syscall results, can be performed.
5316 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5317 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
5318 abi_long arg2
, abi_long arg3
, abi_long arg4
,
5319 abi_long arg5
, abi_long arg6
, abi_long arg7
,
5322 CPUState
*cpu
= ENV_GET_CPU(cpu_env
);
5329 gemu_log("syscall %d", num
);
5332 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5335 case TARGET_NR_exit
:
5336 /* In old applications this may be used to implement _exit(2).
5337 However in threaded applictions it is used for thread termination,
5338 and _exit_group is used for application termination.
5339 Do thread termination if we have more then one thread. */
5340 /* FIXME: This probably breaks if a signal arrives. We should probably
5341 be disabling signals. */
5342 if (CPU_NEXT(first_cpu
)) {
5346 /* Remove the CPU from the list. */
5347 QTAILQ_REMOVE(&cpus
, cpu
, node
);
5349 ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5350 if (ts
->child_tidptr
) {
5351 put_user_u32(0, ts
->child_tidptr
);
5352 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
5356 object_unref(OBJECT(ENV_GET_CPU(cpu_env
)));
5363 gdb_exit(cpu_env
, arg1
);
5365 ret
= 0; /* avoid warning */
5367 case TARGET_NR_read
:
5371 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5373 ret
= get_errno(read(arg1
, p
, arg3
));
5374 unlock_user(p
, arg2
, ret
);
5377 case TARGET_NR_write
:
5378 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5380 ret
= get_errno(write(arg1
, p
, arg3
));
5381 unlock_user(p
, arg2
, 0);
5383 case TARGET_NR_open
:
5384 if (!(p
= lock_user_string(arg1
)))
5386 ret
= get_errno(do_open(cpu_env
, p
,
5387 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
5389 unlock_user(p
, arg1
, 0);
5391 #if defined(TARGET_NR_openat) && defined(__NR_openat)
5392 case TARGET_NR_openat
:
5393 if (!(p
= lock_user_string(arg2
)))
5395 ret
= get_errno(sys_openat(arg1
,
5397 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
5399 unlock_user(p
, arg2
, 0);
5402 case TARGET_NR_close
:
5403 ret
= get_errno(close(arg1
));
5408 case TARGET_NR_fork
:
5409 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
5411 #ifdef TARGET_NR_waitpid
5412 case TARGET_NR_waitpid
:
5415 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
5416 if (!is_error(ret
) && arg2
&& ret
5417 && put_user_s32(host_to_target_waitstatus(status
), arg2
))
5422 #ifdef TARGET_NR_waitid
5423 case TARGET_NR_waitid
:
5427 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
5428 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
5429 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
5431 host_to_target_siginfo(p
, &info
);
5432 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
5437 #ifdef TARGET_NR_creat /* not on alpha */
5438 case TARGET_NR_creat
:
5439 if (!(p
= lock_user_string(arg1
)))
5441 ret
= get_errno(creat(p
, arg2
));
5442 unlock_user(p
, arg1
, 0);
5445 case TARGET_NR_link
:
5448 p
= lock_user_string(arg1
);
5449 p2
= lock_user_string(arg2
);
5451 ret
= -TARGET_EFAULT
;
5453 ret
= get_errno(link(p
, p2
));
5454 unlock_user(p2
, arg2
, 0);
5455 unlock_user(p
, arg1
, 0);
5458 #if defined(TARGET_NR_linkat)
5459 case TARGET_NR_linkat
:
5464 p
= lock_user_string(arg2
);
5465 p2
= lock_user_string(arg4
);
5467 ret
= -TARGET_EFAULT
;
5469 ret
= get_errno(linkat(arg1
, p
, arg3
, p2
, arg5
));
5470 unlock_user(p
, arg2
, 0);
5471 unlock_user(p2
, arg4
, 0);
5475 case TARGET_NR_unlink
:
5476 if (!(p
= lock_user_string(arg1
)))
5478 ret
= get_errno(unlink(p
));
5479 unlock_user(p
, arg1
, 0);
5481 #if defined(TARGET_NR_unlinkat)
5482 case TARGET_NR_unlinkat
:
5483 if (!(p
= lock_user_string(arg2
)))
5485 ret
= get_errno(unlinkat(arg1
, p
, arg3
));
5486 unlock_user(p
, arg2
, 0);
5489 case TARGET_NR_execve
:
5491 char **argp
, **envp
;
5494 abi_ulong guest_argp
;
5495 abi_ulong guest_envp
;
5502 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
5503 if (get_user_ual(addr
, gp
))
5511 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
5512 if (get_user_ual(addr
, gp
))
5519 argp
= alloca((argc
+ 1) * sizeof(void *));
5520 envp
= alloca((envc
+ 1) * sizeof(void *));
5522 for (gp
= guest_argp
, q
= argp
; gp
;
5523 gp
+= sizeof(abi_ulong
), q
++) {
5524 if (get_user_ual(addr
, gp
))
5528 if (!(*q
= lock_user_string(addr
)))
5530 total_size
+= strlen(*q
) + 1;
5534 for (gp
= guest_envp
, q
= envp
; gp
;
5535 gp
+= sizeof(abi_ulong
), q
++) {
5536 if (get_user_ual(addr
, gp
))
5540 if (!(*q
= lock_user_string(addr
)))
5542 total_size
+= strlen(*q
) + 1;
5546 /* This case will not be caught by the host's execve() if its
5547 page size is bigger than the target's. */
5548 if (total_size
> MAX_ARG_PAGES
* TARGET_PAGE_SIZE
) {
5549 ret
= -TARGET_E2BIG
;
5552 if (!(p
= lock_user_string(arg1
)))
5554 ret
= get_errno(execve(p
, argp
, envp
));
5555 unlock_user(p
, arg1
, 0);
5560 ret
= -TARGET_EFAULT
;
5563 for (gp
= guest_argp
, q
= argp
; *q
;
5564 gp
+= sizeof(abi_ulong
), q
++) {
5565 if (get_user_ual(addr
, gp
)
5568 unlock_user(*q
, addr
, 0);
5570 for (gp
= guest_envp
, q
= envp
; *q
;
5571 gp
+= sizeof(abi_ulong
), q
++) {
5572 if (get_user_ual(addr
, gp
)
5575 unlock_user(*q
, addr
, 0);
5579 case TARGET_NR_chdir
:
5580 if (!(p
= lock_user_string(arg1
)))
5582 ret
= get_errno(chdir(p
));
5583 unlock_user(p
, arg1
, 0);
5585 #ifdef TARGET_NR_time
5586 case TARGET_NR_time
:
5589 ret
= get_errno(time(&host_time
));
5592 && put_user_sal(host_time
, arg1
))
5597 case TARGET_NR_mknod
:
5598 if (!(p
= lock_user_string(arg1
)))
5600 ret
= get_errno(mknod(p
, arg2
, arg3
));
5601 unlock_user(p
, arg1
, 0);
5603 #if defined(TARGET_NR_mknodat)
5604 case TARGET_NR_mknodat
:
5605 if (!(p
= lock_user_string(arg2
)))
5607 ret
= get_errno(mknodat(arg1
, p
, arg3
, arg4
));
5608 unlock_user(p
, arg2
, 0);
5611 case TARGET_NR_chmod
:
5612 if (!(p
= lock_user_string(arg1
)))
5614 ret
= get_errno(chmod(p
, arg2
));
5615 unlock_user(p
, arg1
, 0);
5617 #ifdef TARGET_NR_break
5618 case TARGET_NR_break
:
5621 #ifdef TARGET_NR_oldstat
5622 case TARGET_NR_oldstat
:
5625 case TARGET_NR_lseek
:
5626 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
5628 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5629 /* Alpha specific */
5630 case TARGET_NR_getxpid
:
5631 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = getppid();
5632 ret
= get_errno(getpid());
5635 #ifdef TARGET_NR_getpid
5636 case TARGET_NR_getpid
:
5637 ret
= get_errno(getpid());
5640 case TARGET_NR_mount
:
5642 /* need to look at the data field */
5644 p
= lock_user_string(arg1
);
5645 p2
= lock_user_string(arg2
);
5646 p3
= lock_user_string(arg3
);
5647 if (!p
|| !p2
|| !p3
)
5648 ret
= -TARGET_EFAULT
;
5650 /* FIXME - arg5 should be locked, but it isn't clear how to
5651 * do that since it's not guaranteed to be a NULL-terminated
5655 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, NULL
));
5657 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
5659 unlock_user(p
, arg1
, 0);
5660 unlock_user(p2
, arg2
, 0);
5661 unlock_user(p3
, arg3
, 0);
5664 #ifdef TARGET_NR_umount
5665 case TARGET_NR_umount
:
5666 if (!(p
= lock_user_string(arg1
)))
5668 ret
= get_errno(umount(p
));
5669 unlock_user(p
, arg1
, 0);
5672 #ifdef TARGET_NR_stime /* not on alpha */
5673 case TARGET_NR_stime
:
5676 if (get_user_sal(host_time
, arg1
))
5678 ret
= get_errno(stime(&host_time
));
5682 case TARGET_NR_ptrace
:
5684 #ifdef TARGET_NR_alarm /* not on alpha */
5685 case TARGET_NR_alarm
:
5689 #ifdef TARGET_NR_oldfstat
5690 case TARGET_NR_oldfstat
:
5693 #ifdef TARGET_NR_pause /* not on alpha */
5694 case TARGET_NR_pause
:
5695 ret
= get_errno(pause());
5698 #ifdef TARGET_NR_utime
5699 case TARGET_NR_utime
:
5701 struct utimbuf tbuf
, *host_tbuf
;
5702 struct target_utimbuf
*target_tbuf
;
5704 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
5706 tbuf
.actime
= tswapal(target_tbuf
->actime
);
5707 tbuf
.modtime
= tswapal(target_tbuf
->modtime
);
5708 unlock_user_struct(target_tbuf
, arg2
, 0);
5713 if (!(p
= lock_user_string(arg1
)))
5715 ret
= get_errno(utime(p
, host_tbuf
));
5716 unlock_user(p
, arg1
, 0);
5720 case TARGET_NR_utimes
:
5722 struct timeval
*tvp
, tv
[2];
5724 if (copy_from_user_timeval(&tv
[0], arg2
)
5725 || copy_from_user_timeval(&tv
[1],
5726 arg2
+ sizeof(struct target_timeval
)))
5732 if (!(p
= lock_user_string(arg1
)))
5734 ret
= get_errno(utimes(p
, tvp
));
5735 unlock_user(p
, arg1
, 0);
5738 #if defined(TARGET_NR_futimesat)
5739 case TARGET_NR_futimesat
:
5741 struct timeval
*tvp
, tv
[2];
5743 if (copy_from_user_timeval(&tv
[0], arg3
)
5744 || copy_from_user_timeval(&tv
[1],
5745 arg3
+ sizeof(struct target_timeval
)))
5751 if (!(p
= lock_user_string(arg2
)))
5753 ret
= get_errno(futimesat(arg1
, path(p
), tvp
));
5754 unlock_user(p
, arg2
, 0);
5758 #ifdef TARGET_NR_stty
5759 case TARGET_NR_stty
:
5762 #ifdef TARGET_NR_gtty
5763 case TARGET_NR_gtty
:
5766 case TARGET_NR_access
:
5767 if (!(p
= lock_user_string(arg1
)))
5769 ret
= get_errno(access(path(p
), arg2
));
5770 unlock_user(p
, arg1
, 0);
5772 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5773 case TARGET_NR_faccessat
:
5774 if (!(p
= lock_user_string(arg2
)))
5776 ret
= get_errno(faccessat(arg1
, p
, arg3
, 0));
5777 unlock_user(p
, arg2
, 0);
5780 #ifdef TARGET_NR_nice /* not on alpha */
5781 case TARGET_NR_nice
:
5782 ret
= get_errno(nice(arg1
));
5785 #ifdef TARGET_NR_ftime
5786 case TARGET_NR_ftime
:
5789 case TARGET_NR_sync
:
5793 case TARGET_NR_kill
:
5794 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
5796 case TARGET_NR_rename
:
5799 p
= lock_user_string(arg1
);
5800 p2
= lock_user_string(arg2
);
5802 ret
= -TARGET_EFAULT
;
5804 ret
= get_errno(rename(p
, p2
));
5805 unlock_user(p2
, arg2
, 0);
5806 unlock_user(p
, arg1
, 0);
5809 #if defined(TARGET_NR_renameat)
5810 case TARGET_NR_renameat
:
5813 p
= lock_user_string(arg2
);
5814 p2
= lock_user_string(arg4
);
5816 ret
= -TARGET_EFAULT
;
5818 ret
= get_errno(renameat(arg1
, p
, arg3
, p2
));
5819 unlock_user(p2
, arg4
, 0);
5820 unlock_user(p
, arg2
, 0);
5824 case TARGET_NR_mkdir
:
5825 if (!(p
= lock_user_string(arg1
)))
5827 ret
= get_errno(mkdir(p
, arg2
));
5828 unlock_user(p
, arg1
, 0);
5830 #if defined(TARGET_NR_mkdirat)
5831 case TARGET_NR_mkdirat
:
5832 if (!(p
= lock_user_string(arg2
)))
5834 ret
= get_errno(mkdirat(arg1
, p
, arg3
));
5835 unlock_user(p
, arg2
, 0);
5838 case TARGET_NR_rmdir
:
5839 if (!(p
= lock_user_string(arg1
)))
5841 ret
= get_errno(rmdir(p
));
5842 unlock_user(p
, arg1
, 0);
5845 ret
= get_errno(dup(arg1
));
5847 case TARGET_NR_pipe
:
5848 ret
= do_pipe(cpu_env
, arg1
, 0, 0);
5850 #ifdef TARGET_NR_pipe2
5851 case TARGET_NR_pipe2
:
5852 ret
= do_pipe(cpu_env
, arg1
,
5853 target_to_host_bitmask(arg2
, fcntl_flags_tbl
), 1);
5856 case TARGET_NR_times
:
5858 struct target_tms
*tmsp
;
5860 ret
= get_errno(times(&tms
));
5862 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
5865 tmsp
->tms_utime
= tswapal(host_to_target_clock_t(tms
.tms_utime
));
5866 tmsp
->tms_stime
= tswapal(host_to_target_clock_t(tms
.tms_stime
));
5867 tmsp
->tms_cutime
= tswapal(host_to_target_clock_t(tms
.tms_cutime
));
5868 tmsp
->tms_cstime
= tswapal(host_to_target_clock_t(tms
.tms_cstime
));
5871 ret
= host_to_target_clock_t(ret
);
5874 #ifdef TARGET_NR_prof
5875 case TARGET_NR_prof
:
5878 #ifdef TARGET_NR_signal
5879 case TARGET_NR_signal
:
5882 case TARGET_NR_acct
:
5884 ret
= get_errno(acct(NULL
));
5886 if (!(p
= lock_user_string(arg1
)))
5888 ret
= get_errno(acct(path(p
)));
5889 unlock_user(p
, arg1
, 0);
5892 #ifdef TARGET_NR_umount2
5893 case TARGET_NR_umount2
:
5894 if (!(p
= lock_user_string(arg1
)))
5896 ret
= get_errno(umount2(p
, arg2
));
5897 unlock_user(p
, arg1
, 0);
5900 #ifdef TARGET_NR_lock
5901 case TARGET_NR_lock
:
5904 case TARGET_NR_ioctl
:
5905 ret
= do_ioctl(arg1
, arg2
, arg3
);
5907 case TARGET_NR_fcntl
:
5908 ret
= do_fcntl(arg1
, arg2
, arg3
);
5910 #ifdef TARGET_NR_mpx
5914 case TARGET_NR_setpgid
:
5915 ret
= get_errno(setpgid(arg1
, arg2
));
5917 #ifdef TARGET_NR_ulimit
5918 case TARGET_NR_ulimit
:
5921 #ifdef TARGET_NR_oldolduname
5922 case TARGET_NR_oldolduname
:
5925 case TARGET_NR_umask
:
5926 ret
= get_errno(umask(arg1
));
5928 case TARGET_NR_chroot
:
5929 if (!(p
= lock_user_string(arg1
)))
5931 ret
= get_errno(chroot(p
));
5932 unlock_user(p
, arg1
, 0);
5934 case TARGET_NR_ustat
:
5936 case TARGET_NR_dup2
:
5937 ret
= get_errno(dup2(arg1
, arg2
));
5939 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5940 case TARGET_NR_dup3
:
5941 ret
= get_errno(dup3(arg1
, arg2
, arg3
));
5944 #ifdef TARGET_NR_getppid /* not on alpha */
5945 case TARGET_NR_getppid
:
5946 ret
= get_errno(getppid());
5949 case TARGET_NR_getpgrp
:
5950 ret
= get_errno(getpgrp());
5952 case TARGET_NR_setsid
:
5953 ret
= get_errno(setsid());
5955 #ifdef TARGET_NR_sigaction
5956 case TARGET_NR_sigaction
:
5958 #if defined(TARGET_ALPHA)
5959 struct target_sigaction act
, oact
, *pact
= 0;
5960 struct target_old_sigaction
*old_act
;
5962 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5964 act
._sa_handler
= old_act
->_sa_handler
;
5965 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5966 act
.sa_flags
= old_act
->sa_flags
;
5967 act
.sa_restorer
= 0;
5968 unlock_user_struct(old_act
, arg2
, 0);
5971 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5972 if (!is_error(ret
) && arg3
) {
5973 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5975 old_act
->_sa_handler
= oact
._sa_handler
;
5976 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5977 old_act
->sa_flags
= oact
.sa_flags
;
5978 unlock_user_struct(old_act
, arg3
, 1);
5980 #elif defined(TARGET_MIPS)
5981 struct target_sigaction act
, oact
, *pact
, *old_act
;
5984 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5986 act
._sa_handler
= old_act
->_sa_handler
;
5987 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
5988 act
.sa_flags
= old_act
->sa_flags
;
5989 unlock_user_struct(old_act
, arg2
, 0);
5995 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5997 if (!is_error(ret
) && arg3
) {
5998 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
6000 old_act
->_sa_handler
= oact
._sa_handler
;
6001 old_act
->sa_flags
= oact
.sa_flags
;
6002 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
6003 old_act
->sa_mask
.sig
[1] = 0;
6004 old_act
->sa_mask
.sig
[2] = 0;
6005 old_act
->sa_mask
.sig
[3] = 0;
6006 unlock_user_struct(old_act
, arg3
, 1);
6009 struct target_old_sigaction
*old_act
;
6010 struct target_sigaction act
, oact
, *pact
;
6012 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
6014 act
._sa_handler
= old_act
->_sa_handler
;
6015 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
6016 act
.sa_flags
= old_act
->sa_flags
;
6017 act
.sa_restorer
= old_act
->sa_restorer
;
6018 unlock_user_struct(old_act
, arg2
, 0);
6023 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
6024 if (!is_error(ret
) && arg3
) {
6025 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
6027 old_act
->_sa_handler
= oact
._sa_handler
;
6028 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
6029 old_act
->sa_flags
= oact
.sa_flags
;
6030 old_act
->sa_restorer
= oact
.sa_restorer
;
6031 unlock_user_struct(old_act
, arg3
, 1);
6037 case TARGET_NR_rt_sigaction
:
6039 #if defined(TARGET_ALPHA)
6040 struct target_sigaction act
, oact
, *pact
= 0;
6041 struct target_rt_sigaction
*rt_act
;
6042 /* ??? arg4 == sizeof(sigset_t). */
6044 if (!lock_user_struct(VERIFY_READ
, rt_act
, arg2
, 1))
6046 act
._sa_handler
= rt_act
->_sa_handler
;
6047 act
.sa_mask
= rt_act
->sa_mask
;
6048 act
.sa_flags
= rt_act
->sa_flags
;
6049 act
.sa_restorer
= arg5
;
6050 unlock_user_struct(rt_act
, arg2
, 0);
6053 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
6054 if (!is_error(ret
) && arg3
) {
6055 if (!lock_user_struct(VERIFY_WRITE
, rt_act
, arg3
, 0))
6057 rt_act
->_sa_handler
= oact
._sa_handler
;
6058 rt_act
->sa_mask
= oact
.sa_mask
;
6059 rt_act
->sa_flags
= oact
.sa_flags
;
6060 unlock_user_struct(rt_act
, arg3
, 1);
6063 struct target_sigaction
*act
;
6064 struct target_sigaction
*oact
;
6067 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
6072 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
6073 ret
= -TARGET_EFAULT
;
6074 goto rt_sigaction_fail
;
6078 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
6081 unlock_user_struct(act
, arg2
, 0);
6083 unlock_user_struct(oact
, arg3
, 1);
6087 #ifdef TARGET_NR_sgetmask /* not on alpha */
6088 case TARGET_NR_sgetmask
:
6091 abi_ulong target_set
;
6092 sigprocmask(0, NULL
, &cur_set
);
6093 host_to_target_old_sigset(&target_set
, &cur_set
);
6098 #ifdef TARGET_NR_ssetmask /* not on alpha */
6099 case TARGET_NR_ssetmask
:
6101 sigset_t set
, oset
, cur_set
;
6102 abi_ulong target_set
= arg1
;
6103 sigprocmask(0, NULL
, &cur_set
);
6104 target_to_host_old_sigset(&set
, &target_set
);
6105 sigorset(&set
, &set
, &cur_set
);
6106 sigprocmask(SIG_SETMASK
, &set
, &oset
);
6107 host_to_target_old_sigset(&target_set
, &oset
);
6112 #ifdef TARGET_NR_sigprocmask
6113 case TARGET_NR_sigprocmask
:
6115 #if defined(TARGET_ALPHA)
6116 sigset_t set
, oldset
;
6121 case TARGET_SIG_BLOCK
:
6124 case TARGET_SIG_UNBLOCK
:
6127 case TARGET_SIG_SETMASK
:
6131 ret
= -TARGET_EINVAL
;
6135 target_to_host_old_sigset(&set
, &mask
);
6137 ret
= get_errno(sigprocmask(how
, &set
, &oldset
));
6138 if (!is_error(ret
)) {
6139 host_to_target_old_sigset(&mask
, &oldset
);
6141 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0; /* force no error */
6144 sigset_t set
, oldset
, *set_ptr
;
6149 case TARGET_SIG_BLOCK
:
6152 case TARGET_SIG_UNBLOCK
:
6155 case TARGET_SIG_SETMASK
:
6159 ret
= -TARGET_EINVAL
;
6162 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
6164 target_to_host_old_sigset(&set
, p
);
6165 unlock_user(p
, arg2
, 0);
6171 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
6172 if (!is_error(ret
) && arg3
) {
6173 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
6175 host_to_target_old_sigset(p
, &oldset
);
6176 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
6182 case TARGET_NR_rt_sigprocmask
:
6185 sigset_t set
, oldset
, *set_ptr
;
6189 case TARGET_SIG_BLOCK
:
6192 case TARGET_SIG_UNBLOCK
:
6195 case TARGET_SIG_SETMASK
:
6199 ret
= -TARGET_EINVAL
;
6202 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
6204 target_to_host_sigset(&set
, p
);
6205 unlock_user(p
, arg2
, 0);
6211 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
6212 if (!is_error(ret
) && arg3
) {
6213 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
6215 host_to_target_sigset(p
, &oldset
);
6216 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
6220 #ifdef TARGET_NR_sigpending
6221 case TARGET_NR_sigpending
:
6224 ret
= get_errno(sigpending(&set
));
6225 if (!is_error(ret
)) {
6226 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
6228 host_to_target_old_sigset(p
, &set
);
6229 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
6234 case TARGET_NR_rt_sigpending
:
6237 ret
= get_errno(sigpending(&set
));
6238 if (!is_error(ret
)) {
6239 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
6241 host_to_target_sigset(p
, &set
);
6242 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
6246 #ifdef TARGET_NR_sigsuspend
6247 case TARGET_NR_sigsuspend
:
6250 #if defined(TARGET_ALPHA)
6251 abi_ulong mask
= arg1
;
6252 target_to_host_old_sigset(&set
, &mask
);
6254 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6256 target_to_host_old_sigset(&set
, p
);
6257 unlock_user(p
, arg1
, 0);
6259 ret
= get_errno(sigsuspend(&set
));
6263 case TARGET_NR_rt_sigsuspend
:
6266 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6268 target_to_host_sigset(&set
, p
);
6269 unlock_user(p
, arg1
, 0);
6270 ret
= get_errno(sigsuspend(&set
));
6273 case TARGET_NR_rt_sigtimedwait
:
6276 struct timespec uts
, *puts
;
6279 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6281 target_to_host_sigset(&set
, p
);
6282 unlock_user(p
, arg1
, 0);
6285 target_to_host_timespec(puts
, arg3
);
6289 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
6290 if (!is_error(ret
) && arg2
) {
6291 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
6293 host_to_target_siginfo(p
, &uinfo
);
6294 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
6298 case TARGET_NR_rt_sigqueueinfo
:
6301 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
6303 target_to_host_siginfo(&uinfo
, p
);
6304 unlock_user(p
, arg1
, 0);
6305 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
6308 #ifdef TARGET_NR_sigreturn
6309 case TARGET_NR_sigreturn
:
6310 /* NOTE: ret is eax, so not transcoding must be done */
6311 ret
= do_sigreturn(cpu_env
);
6314 case TARGET_NR_rt_sigreturn
:
6315 /* NOTE: ret is eax, so not transcoding must be done */
6316 ret
= do_rt_sigreturn(cpu_env
);
6318 case TARGET_NR_sethostname
:
6319 if (!(p
= lock_user_string(arg1
)))
6321 ret
= get_errno(sethostname(p
, arg2
));
6322 unlock_user(p
, arg1
, 0);
6324 case TARGET_NR_setrlimit
:
6326 int resource
= target_to_host_resource(arg1
);
6327 struct target_rlimit
*target_rlim
;
6329 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
6331 rlim
.rlim_cur
= target_to_host_rlim(target_rlim
->rlim_cur
);
6332 rlim
.rlim_max
= target_to_host_rlim(target_rlim
->rlim_max
);
6333 unlock_user_struct(target_rlim
, arg2
, 0);
6334 ret
= get_errno(setrlimit(resource
, &rlim
));
6337 case TARGET_NR_getrlimit
:
6339 int resource
= target_to_host_resource(arg1
);
6340 struct target_rlimit
*target_rlim
;
6343 ret
= get_errno(getrlimit(resource
, &rlim
));
6344 if (!is_error(ret
)) {
6345 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
6347 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
6348 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
6349 unlock_user_struct(target_rlim
, arg2
, 1);
6353 case TARGET_NR_getrusage
:
6355 struct rusage rusage
;
6356 ret
= get_errno(getrusage(arg1
, &rusage
));
6357 if (!is_error(ret
)) {
6358 host_to_target_rusage(arg2
, &rusage
);
6362 case TARGET_NR_gettimeofday
:
6365 ret
= get_errno(gettimeofday(&tv
, NULL
));
6366 if (!is_error(ret
)) {
6367 if (copy_to_user_timeval(arg1
, &tv
))
6372 case TARGET_NR_settimeofday
:
6375 if (copy_from_user_timeval(&tv
, arg1
))
6377 ret
= get_errno(settimeofday(&tv
, NULL
));
6380 #if defined(TARGET_NR_select)
6381 case TARGET_NR_select
:
6382 #if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6383 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
6386 struct target_sel_arg_struct
*sel
;
6387 abi_ulong inp
, outp
, exp
, tvp
;
6390 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
6392 nsel
= tswapal(sel
->n
);
6393 inp
= tswapal(sel
->inp
);
6394 outp
= tswapal(sel
->outp
);
6395 exp
= tswapal(sel
->exp
);
6396 tvp
= tswapal(sel
->tvp
);
6397 unlock_user_struct(sel
, arg1
, 0);
6398 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
6403 #ifdef TARGET_NR_pselect6
6404 case TARGET_NR_pselect6
:
6406 abi_long rfd_addr
, wfd_addr
, efd_addr
, n
, ts_addr
;
6407 fd_set rfds
, wfds
, efds
;
6408 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
6409 struct timespec ts
, *ts_ptr
;
6412 * The 6th arg is actually two args smashed together,
6413 * so we cannot use the C library.
6421 abi_ulong arg_sigset
, arg_sigsize
, *arg7
;
6422 target_sigset_t
*target_sigset
;
6430 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
6434 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
6438 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
6444 * This takes a timespec, and not a timeval, so we cannot
6445 * use the do_select() helper ...
6448 if (target_to_host_timespec(&ts
, ts_addr
)) {
6456 /* Extract the two packed args for the sigset */
6459 sig
.size
= _NSIG
/ 8;
6461 arg7
= lock_user(VERIFY_READ
, arg6
, sizeof(*arg7
) * 2, 1);
6465 arg_sigset
= tswapal(arg7
[0]);
6466 arg_sigsize
= tswapal(arg7
[1]);
6467 unlock_user(arg7
, arg6
, 0);
6471 if (arg_sigsize
!= sizeof(*target_sigset
)) {
6472 /* Like the kernel, we enforce correct size sigsets */
6473 ret
= -TARGET_EINVAL
;
6476 target_sigset
= lock_user(VERIFY_READ
, arg_sigset
,
6477 sizeof(*target_sigset
), 1);
6478 if (!target_sigset
) {
6481 target_to_host_sigset(&set
, target_sigset
);
6482 unlock_user(target_sigset
, arg_sigset
, 0);
6490 ret
= get_errno(sys_pselect6(n
, rfds_ptr
, wfds_ptr
, efds_ptr
,
6493 if (!is_error(ret
)) {
6494 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
6496 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
6498 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
6501 if (ts_addr
&& host_to_target_timespec(ts_addr
, &ts
))
6507 case TARGET_NR_symlink
:
6510 p
= lock_user_string(arg1
);
6511 p2
= lock_user_string(arg2
);
6513 ret
= -TARGET_EFAULT
;
6515 ret
= get_errno(symlink(p
, p2
));
6516 unlock_user(p2
, arg2
, 0);
6517 unlock_user(p
, arg1
, 0);
6520 #if defined(TARGET_NR_symlinkat)
6521 case TARGET_NR_symlinkat
:
6524 p
= lock_user_string(arg1
);
6525 p2
= lock_user_string(arg3
);
6527 ret
= -TARGET_EFAULT
;
6529 ret
= get_errno(symlinkat(p
, arg2
, p2
));
6530 unlock_user(p2
, arg3
, 0);
6531 unlock_user(p
, arg1
, 0);
6535 #ifdef TARGET_NR_oldlstat
6536 case TARGET_NR_oldlstat
:
6539 case TARGET_NR_readlink
:
6542 p
= lock_user_string(arg1
);
6543 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
6545 ret
= -TARGET_EFAULT
;
6546 } else if (is_proc_myself((const char *)p
, "exe")) {
6547 char real
[PATH_MAX
], *temp
;
6548 temp
= realpath(exec_path
, real
);
6549 ret
= temp
== NULL
? get_errno(-1) : strlen(real
) ;
6550 snprintf((char *)p2
, arg3
, "%s", real
);
6552 ret
= get_errno(readlink(path(p
), p2
, arg3
));
6554 unlock_user(p2
, arg2
, ret
);
6555 unlock_user(p
, arg1
, 0);
6558 #if defined(TARGET_NR_readlinkat)
6559 case TARGET_NR_readlinkat
:
6562 p
= lock_user_string(arg2
);
6563 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
6565 ret
= -TARGET_EFAULT
;
6566 } else if (is_proc_myself((const char *)p
, "exe")) {
6567 char real
[PATH_MAX
], *temp
;
6568 temp
= realpath(exec_path
, real
);
6569 ret
= temp
== NULL
? get_errno(-1) : strlen(real
) ;
6570 snprintf((char *)p2
, arg4
, "%s", real
);
6572 ret
= get_errno(readlinkat(arg1
, path(p
), p2
, arg4
));
6574 unlock_user(p2
, arg3
, ret
);
6575 unlock_user(p
, arg2
, 0);
6579 #ifdef TARGET_NR_uselib
6580 case TARGET_NR_uselib
:
6583 #ifdef TARGET_NR_swapon
6584 case TARGET_NR_swapon
:
6585 if (!(p
= lock_user_string(arg1
)))
6587 ret
= get_errno(swapon(p
, arg2
));
6588 unlock_user(p
, arg1
, 0);
6591 case TARGET_NR_reboot
:
6592 if (arg3
== LINUX_REBOOT_CMD_RESTART2
) {
6593 /* arg4 must be ignored in all other cases */
6594 p
= lock_user_string(arg4
);
6598 ret
= get_errno(reboot(arg1
, arg2
, arg3
, p
));
6599 unlock_user(p
, arg4
, 0);
6601 ret
= get_errno(reboot(arg1
, arg2
, arg3
, NULL
));
6604 #ifdef TARGET_NR_readdir
6605 case TARGET_NR_readdir
:
6608 #ifdef TARGET_NR_mmap
6609 case TARGET_NR_mmap
:
6610 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || \
6611 (defined(TARGET_ARM) && defined(TARGET_ABI32)) || \
6612 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6613 || defined(TARGET_S390X)
6616 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
6617 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
6625 unlock_user(v
, arg1
, 0);
6626 ret
= get_errno(target_mmap(v1
, v2
, v3
,
6627 target_to_host_bitmask(v4
, mmap_flags_tbl
),
6631 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6632 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6638 #ifdef TARGET_NR_mmap2
6639 case TARGET_NR_mmap2
:
6641 #define MMAP_SHIFT 12
6643 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6644 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6646 arg6
<< MMAP_SHIFT
));
6649 case TARGET_NR_munmap
:
6650 ret
= get_errno(target_munmap(arg1
, arg2
));
6652 case TARGET_NR_mprotect
:
6654 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
6655 /* Special hack to detect libc making the stack executable. */
6656 if ((arg3
& PROT_GROWSDOWN
)
6657 && arg1
>= ts
->info
->stack_limit
6658 && arg1
<= ts
->info
->start_stack
) {
6659 arg3
&= ~PROT_GROWSDOWN
;
6660 arg2
= arg2
+ arg1
- ts
->info
->stack_limit
;
6661 arg1
= ts
->info
->stack_limit
;
6664 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
6666 #ifdef TARGET_NR_mremap
6667 case TARGET_NR_mremap
:
6668 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
6671 /* ??? msync/mlock/munlock are broken for softmmu. */
6672 #ifdef TARGET_NR_msync
6673 case TARGET_NR_msync
:
6674 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
6677 #ifdef TARGET_NR_mlock
6678 case TARGET_NR_mlock
:
6679 ret
= get_errno(mlock(g2h(arg1
), arg2
));
6682 #ifdef TARGET_NR_munlock
6683 case TARGET_NR_munlock
:
6684 ret
= get_errno(munlock(g2h(arg1
), arg2
));
6687 #ifdef TARGET_NR_mlockall
6688 case TARGET_NR_mlockall
:
6689 ret
= get_errno(mlockall(arg1
));
6692 #ifdef TARGET_NR_munlockall
6693 case TARGET_NR_munlockall
:
6694 ret
= get_errno(munlockall());
6697 case TARGET_NR_truncate
:
6698 if (!(p
= lock_user_string(arg1
)))
6700 ret
= get_errno(truncate(p
, arg2
));
6701 unlock_user(p
, arg1
, 0);
6703 case TARGET_NR_ftruncate
:
6704 ret
= get_errno(ftruncate(arg1
, arg2
));
6706 case TARGET_NR_fchmod
:
6707 ret
= get_errno(fchmod(arg1
, arg2
));
6709 #if defined(TARGET_NR_fchmodat)
6710 case TARGET_NR_fchmodat
:
6711 if (!(p
= lock_user_string(arg2
)))
6713 ret
= get_errno(fchmodat(arg1
, p
, arg3
, 0));
6714 unlock_user(p
, arg2
, 0);
6717 case TARGET_NR_getpriority
:
6718 /* Note that negative values are valid for getpriority, so we must
6719 differentiate based on errno settings. */
6721 ret
= getpriority(arg1
, arg2
);
6722 if (ret
== -1 && errno
!= 0) {
6723 ret
= -host_to_target_errno(errno
);
6727 /* Return value is the unbiased priority. Signal no error. */
6728 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0;
6730 /* Return value is a biased priority to avoid negative numbers. */
6734 case TARGET_NR_setpriority
:
6735 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
6737 #ifdef TARGET_NR_profil
6738 case TARGET_NR_profil
:
6741 case TARGET_NR_statfs
:
6742 if (!(p
= lock_user_string(arg1
)))
6744 ret
= get_errno(statfs(path(p
), &stfs
));
6745 unlock_user(p
, arg1
, 0);
6747 if (!is_error(ret
)) {
6748 struct target_statfs
*target_stfs
;
6750 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
6752 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6753 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6754 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6755 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6756 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6757 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6758 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6759 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6760 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6761 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6762 __put_user(stfs
.f_frsize
, &target_stfs
->f_frsize
);
6763 memset(target_stfs
->f_spare
, 0, sizeof(target_stfs
->f_spare
));
6764 unlock_user_struct(target_stfs
, arg2
, 1);
6767 case TARGET_NR_fstatfs
:
6768 ret
= get_errno(fstatfs(arg1
, &stfs
));
6769 goto convert_statfs
;
6770 #ifdef TARGET_NR_statfs64
6771 case TARGET_NR_statfs64
:
6772 if (!(p
= lock_user_string(arg1
)))
6774 ret
= get_errno(statfs(path(p
), &stfs
));
6775 unlock_user(p
, arg1
, 0);
6777 if (!is_error(ret
)) {
6778 struct target_statfs64
*target_stfs
;
6780 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
6782 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6783 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6784 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6785 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6786 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6787 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6788 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6789 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6790 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6791 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6792 __put_user(stfs
.f_frsize
, &target_stfs
->f_frsize
);
6793 memset(target_stfs
->f_spare
, 0, sizeof(target_stfs
->f_spare
));
6794 unlock_user_struct(target_stfs
, arg3
, 1);
6797 case TARGET_NR_fstatfs64
:
6798 ret
= get_errno(fstatfs(arg1
, &stfs
));
6799 goto convert_statfs64
;
6801 #ifdef TARGET_NR_ioperm
6802 case TARGET_NR_ioperm
:
6805 #ifdef TARGET_NR_socketcall
6806 case TARGET_NR_socketcall
:
6807 ret
= do_socketcall(arg1
, arg2
);
6810 #ifdef TARGET_NR_accept
6811 case TARGET_NR_accept
:
6812 ret
= do_accept4(arg1
, arg2
, arg3
, 0);
6815 #ifdef TARGET_NR_accept4
6816 case TARGET_NR_accept4
:
6817 #ifdef CONFIG_ACCEPT4
6818 ret
= do_accept4(arg1
, arg2
, arg3
, arg4
);
6824 #ifdef TARGET_NR_bind
6825 case TARGET_NR_bind
:
6826 ret
= do_bind(arg1
, arg2
, arg3
);
6829 #ifdef TARGET_NR_connect
6830 case TARGET_NR_connect
:
6831 ret
= do_connect(arg1
, arg2
, arg3
);
6834 #ifdef TARGET_NR_getpeername
6835 case TARGET_NR_getpeername
:
6836 ret
= do_getpeername(arg1
, arg2
, arg3
);
6839 #ifdef TARGET_NR_getsockname
6840 case TARGET_NR_getsockname
:
6841 ret
= do_getsockname(arg1
, arg2
, arg3
);
6844 #ifdef TARGET_NR_getsockopt
6845 case TARGET_NR_getsockopt
:
6846 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
6849 #ifdef TARGET_NR_listen
6850 case TARGET_NR_listen
:
6851 ret
= get_errno(listen(arg1
, arg2
));
6854 #ifdef TARGET_NR_recv
6855 case TARGET_NR_recv
:
6856 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
6859 #ifdef TARGET_NR_recvfrom
6860 case TARGET_NR_recvfrom
:
6861 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6864 #ifdef TARGET_NR_recvmsg
6865 case TARGET_NR_recvmsg
:
6866 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
6869 #ifdef TARGET_NR_send
6870 case TARGET_NR_send
:
6871 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
6874 #ifdef TARGET_NR_sendmsg
6875 case TARGET_NR_sendmsg
:
6876 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
6879 #ifdef TARGET_NR_sendto
6880 case TARGET_NR_sendto
:
6881 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6884 #ifdef TARGET_NR_shutdown
6885 case TARGET_NR_shutdown
:
6886 ret
= get_errno(shutdown(arg1
, arg2
));
6889 #ifdef TARGET_NR_socket
6890 case TARGET_NR_socket
:
6891 ret
= do_socket(arg1
, arg2
, arg3
);
6894 #ifdef TARGET_NR_socketpair
6895 case TARGET_NR_socketpair
:
6896 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
6899 #ifdef TARGET_NR_setsockopt
6900 case TARGET_NR_setsockopt
:
6901 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
6905 case TARGET_NR_syslog
:
6906 if (!(p
= lock_user_string(arg2
)))
6908 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
6909 unlock_user(p
, arg2
, 0);
6912 case TARGET_NR_setitimer
:
6914 struct itimerval value
, ovalue
, *pvalue
;
6918 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
6919 || copy_from_user_timeval(&pvalue
->it_value
,
6920 arg2
+ sizeof(struct target_timeval
)))
6925 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
6926 if (!is_error(ret
) && arg3
) {
6927 if (copy_to_user_timeval(arg3
,
6928 &ovalue
.it_interval
)
6929 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
6935 case TARGET_NR_getitimer
:
6937 struct itimerval value
;
6939 ret
= get_errno(getitimer(arg1
, &value
));
6940 if (!is_error(ret
) && arg2
) {
6941 if (copy_to_user_timeval(arg2
,
6943 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
6949 case TARGET_NR_stat
:
6950 if (!(p
= lock_user_string(arg1
)))
6952 ret
= get_errno(stat(path(p
), &st
));
6953 unlock_user(p
, arg1
, 0);
6955 case TARGET_NR_lstat
:
6956 if (!(p
= lock_user_string(arg1
)))
6958 ret
= get_errno(lstat(path(p
), &st
));
6959 unlock_user(p
, arg1
, 0);
6961 case TARGET_NR_fstat
:
6963 ret
= get_errno(fstat(arg1
, &st
));
6965 if (!is_error(ret
)) {
6966 struct target_stat
*target_st
;
6968 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
6970 memset(target_st
, 0, sizeof(*target_st
));
6971 __put_user(st
.st_dev
, &target_st
->st_dev
);
6972 __put_user(st
.st_ino
, &target_st
->st_ino
);
6973 __put_user(st
.st_mode
, &target_st
->st_mode
);
6974 __put_user(st
.st_uid
, &target_st
->st_uid
);
6975 __put_user(st
.st_gid
, &target_st
->st_gid
);
6976 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
6977 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
6978 __put_user(st
.st_size
, &target_st
->st_size
);
6979 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
6980 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
6981 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
6982 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
6983 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
6984 unlock_user_struct(target_st
, arg2
, 1);
6988 #ifdef TARGET_NR_olduname
6989 case TARGET_NR_olduname
:
6992 #ifdef TARGET_NR_iopl
6993 case TARGET_NR_iopl
:
6996 case TARGET_NR_vhangup
:
6997 ret
= get_errno(vhangup());
6999 #ifdef TARGET_NR_idle
7000 case TARGET_NR_idle
:
7003 #ifdef TARGET_NR_syscall
7004 case TARGET_NR_syscall
:
7005 ret
= do_syscall(cpu_env
, arg1
& 0xffff, arg2
, arg3
, arg4
, arg5
,
7006 arg6
, arg7
, arg8
, 0);
7009 case TARGET_NR_wait4
:
7012 abi_long status_ptr
= arg2
;
7013 struct rusage rusage
, *rusage_ptr
;
7014 abi_ulong target_rusage
= arg4
;
7016 rusage_ptr
= &rusage
;
7019 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
7020 if (!is_error(ret
)) {
7021 if (status_ptr
&& ret
) {
7022 status
= host_to_target_waitstatus(status
);
7023 if (put_user_s32(status
, status_ptr
))
7027 host_to_target_rusage(target_rusage
, &rusage
);
7031 #ifdef TARGET_NR_swapoff
7032 case TARGET_NR_swapoff
:
7033 if (!(p
= lock_user_string(arg1
)))
7035 ret
= get_errno(swapoff(p
));
7036 unlock_user(p
, arg1
, 0);
7039 case TARGET_NR_sysinfo
:
7041 struct target_sysinfo
*target_value
;
7042 struct sysinfo value
;
7043 ret
= get_errno(sysinfo(&value
));
7044 if (!is_error(ret
) && arg1
)
7046 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
7048 __put_user(value
.uptime
, &target_value
->uptime
);
7049 __put_user(value
.loads
[0], &target_value
->loads
[0]);
7050 __put_user(value
.loads
[1], &target_value
->loads
[1]);
7051 __put_user(value
.loads
[2], &target_value
->loads
[2]);
7052 __put_user(value
.totalram
, &target_value
->totalram
);
7053 __put_user(value
.freeram
, &target_value
->freeram
);
7054 __put_user(value
.sharedram
, &target_value
->sharedram
);
7055 __put_user(value
.bufferram
, &target_value
->bufferram
);
7056 __put_user(value
.totalswap
, &target_value
->totalswap
);
7057 __put_user(value
.freeswap
, &target_value
->freeswap
);
7058 __put_user(value
.procs
, &target_value
->procs
);
7059 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
7060 __put_user(value
.freehigh
, &target_value
->freehigh
);
7061 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
7062 unlock_user_struct(target_value
, arg1
, 1);
7066 #ifdef TARGET_NR_ipc
7068 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
7071 #ifdef TARGET_NR_semget
7072 case TARGET_NR_semget
:
7073 ret
= get_errno(semget(arg1
, arg2
, arg3
));
7076 #ifdef TARGET_NR_semop
7077 case TARGET_NR_semop
:
7078 ret
= do_semop(arg1
, arg2
, arg3
);
7081 #ifdef TARGET_NR_semctl
7082 case TARGET_NR_semctl
:
7083 ret
= do_semctl(arg1
, arg2
, arg3
, (union target_semun
)(abi_ulong
)arg4
);
7086 #ifdef TARGET_NR_msgctl
7087 case TARGET_NR_msgctl
:
7088 ret
= do_msgctl(arg1
, arg2
, arg3
);
7091 #ifdef TARGET_NR_msgget
7092 case TARGET_NR_msgget
:
7093 ret
= get_errno(msgget(arg1
, arg2
));
7096 #ifdef TARGET_NR_msgrcv
7097 case TARGET_NR_msgrcv
:
7098 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
7101 #ifdef TARGET_NR_msgsnd
7102 case TARGET_NR_msgsnd
:
7103 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
7106 #ifdef TARGET_NR_shmget
7107 case TARGET_NR_shmget
:
7108 ret
= get_errno(shmget(arg1
, arg2
, arg3
));
7111 #ifdef TARGET_NR_shmctl
7112 case TARGET_NR_shmctl
:
7113 ret
= do_shmctl(arg1
, arg2
, arg3
);
7116 #ifdef TARGET_NR_shmat
7117 case TARGET_NR_shmat
:
7118 ret
= do_shmat(arg1
, arg2
, arg3
);
7121 #ifdef TARGET_NR_shmdt
7122 case TARGET_NR_shmdt
:
7123 ret
= do_shmdt(arg1
);
7126 case TARGET_NR_fsync
:
7127 ret
= get_errno(fsync(arg1
));
7129 case TARGET_NR_clone
:
7130 /* Linux manages to have three different orderings for its
7131 * arguments to clone(); the BACKWARDS and BACKWARDS2 defines
7132 * match the kernel's CONFIG_CLONE_* settings.
7133 * Microblaze is further special in that it uses a sixth
7134 * implicit argument to clone for the TLS pointer.
7136 #if defined(TARGET_MICROBLAZE)
7137 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg4
, arg6
, arg5
));
7138 #elif defined(TARGET_CLONE_BACKWARDS)
7139 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
7140 #elif defined(TARGET_CLONE_BACKWARDS2)
7141 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg5
, arg4
));
7143 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
7146 #ifdef __NR_exit_group
7147 /* new thread calls */
7148 case TARGET_NR_exit_group
:
7152 gdb_exit(cpu_env
, arg1
);
7153 ret
= get_errno(exit_group(arg1
));
7156 case TARGET_NR_setdomainname
:
7157 if (!(p
= lock_user_string(arg1
)))
7159 ret
= get_errno(setdomainname(p
, arg2
));
7160 unlock_user(p
, arg1
, 0);
7162 case TARGET_NR_uname
:
7163 /* no need to transcode because we use the linux syscall */
7165 struct new_utsname
* buf
;
7167 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
7169 ret
= get_errno(sys_uname(buf
));
7170 if (!is_error(ret
)) {
7171 /* Overrite the native machine name with whatever is being
7173 strcpy (buf
->machine
, cpu_to_uname_machine(cpu_env
));
7174 /* Allow the user to override the reported release. */
7175 if (qemu_uname_release
&& *qemu_uname_release
)
7176 strcpy (buf
->release
, qemu_uname_release
);
7178 unlock_user_struct(buf
, arg1
, 1);
7182 case TARGET_NR_modify_ldt
:
7183 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
7185 #if !defined(TARGET_X86_64)
7186 case TARGET_NR_vm86old
:
7188 case TARGET_NR_vm86
:
7189 ret
= do_vm86(cpu_env
, arg1
, arg2
);
7193 case TARGET_NR_adjtimex
:
7195 #ifdef TARGET_NR_create_module
7196 case TARGET_NR_create_module
:
7198 case TARGET_NR_init_module
:
7199 case TARGET_NR_delete_module
:
7200 #ifdef TARGET_NR_get_kernel_syms
7201 case TARGET_NR_get_kernel_syms
:
7204 case TARGET_NR_quotactl
:
7206 case TARGET_NR_getpgid
:
7207 ret
= get_errno(getpgid(arg1
));
7209 case TARGET_NR_fchdir
:
7210 ret
= get_errno(fchdir(arg1
));
7212 #ifdef TARGET_NR_bdflush /* not on x86_64 */
7213 case TARGET_NR_bdflush
:
7216 #ifdef TARGET_NR_sysfs
7217 case TARGET_NR_sysfs
:
7220 case TARGET_NR_personality
:
7221 ret
= get_errno(personality(arg1
));
7223 #ifdef TARGET_NR_afs_syscall
7224 case TARGET_NR_afs_syscall
:
7227 #ifdef TARGET_NR__llseek /* Not on alpha */
7228 case TARGET_NR__llseek
:
7231 #if !defined(__NR_llseek)
7232 res
= lseek(arg1
, ((uint64_t)arg2
<< 32) | arg3
, arg5
);
7234 ret
= get_errno(res
);
7239 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
7241 if ((ret
== 0) && put_user_s64(res
, arg4
)) {
7247 case TARGET_NR_getdents
:
7248 #ifdef __NR_getdents
7249 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
7251 struct target_dirent
*target_dirp
;
7252 struct linux_dirent
*dirp
;
7253 abi_long count
= arg3
;
7255 dirp
= malloc(count
);
7257 ret
= -TARGET_ENOMEM
;
7261 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7262 if (!is_error(ret
)) {
7263 struct linux_dirent
*de
;
7264 struct target_dirent
*tde
;
7266 int reclen
, treclen
;
7267 int count1
, tnamelen
;
7271 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7275 reclen
= de
->d_reclen
;
7276 tnamelen
= reclen
- offsetof(struct linux_dirent
, d_name
);
7277 assert(tnamelen
>= 0);
7278 treclen
= tnamelen
+ offsetof(struct target_dirent
, d_name
);
7279 assert(count1
+ treclen
<= count
);
7280 tde
->d_reclen
= tswap16(treclen
);
7281 tde
->d_ino
= tswapal(de
->d_ino
);
7282 tde
->d_off
= tswapal(de
->d_off
);
7283 memcpy(tde
->d_name
, de
->d_name
, tnamelen
);
7284 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7286 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
7290 unlock_user(target_dirp
, arg2
, ret
);
7296 struct linux_dirent
*dirp
;
7297 abi_long count
= arg3
;
7299 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7301 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7302 if (!is_error(ret
)) {
7303 struct linux_dirent
*de
;
7308 reclen
= de
->d_reclen
;
7311 de
->d_reclen
= tswap16(reclen
);
7312 tswapls(&de
->d_ino
);
7313 tswapls(&de
->d_off
);
7314 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7318 unlock_user(dirp
, arg2
, ret
);
7322 /* Implement getdents in terms of getdents64 */
7324 struct linux_dirent64
*dirp
;
7325 abi_long count
= arg3
;
7327 dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0);
7331 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
7332 if (!is_error(ret
)) {
7333 /* Convert the dirent64 structs to target dirent. We do this
7334 * in-place, since we can guarantee that a target_dirent is no
7335 * larger than a dirent64; however this means we have to be
7336 * careful to read everything before writing in the new format.
7338 struct linux_dirent64
*de
;
7339 struct target_dirent
*tde
;
7344 tde
= (struct target_dirent
*)dirp
;
7346 int namelen
, treclen
;
7347 int reclen
= de
->d_reclen
;
7348 uint64_t ino
= de
->d_ino
;
7349 int64_t off
= de
->d_off
;
7350 uint8_t type
= de
->d_type
;
7352 namelen
= strlen(de
->d_name
);
7353 treclen
= offsetof(struct target_dirent
, d_name
)
7355 treclen
= QEMU_ALIGN_UP(treclen
, sizeof(abi_long
));
7357 memmove(tde
->d_name
, de
->d_name
, namelen
+ 1);
7358 tde
->d_ino
= tswapal(ino
);
7359 tde
->d_off
= tswapal(off
);
7360 tde
->d_reclen
= tswap16(treclen
);
7361 /* The target_dirent type is in what was formerly a padding
7362 * byte at the end of the structure:
7364 *(((char *)tde
) + treclen
- 1) = type
;
7366 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
7367 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
7373 unlock_user(dirp
, arg2
, ret
);
7377 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7378 case TARGET_NR_getdents64
:
7380 struct linux_dirent64
*dirp
;
7381 abi_long count
= arg3
;
7382 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7384 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
7385 if (!is_error(ret
)) {
7386 struct linux_dirent64
*de
;
7391 reclen
= de
->d_reclen
;
7394 de
->d_reclen
= tswap16(reclen
);
7395 tswap64s((uint64_t *)&de
->d_ino
);
7396 tswap64s((uint64_t *)&de
->d_off
);
7397 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
7401 unlock_user(dirp
, arg2
, ret
);
7404 #endif /* TARGET_NR_getdents64 */
7405 #if defined(TARGET_NR__newselect)
7406 case TARGET_NR__newselect
:
7407 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
7410 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7411 # ifdef TARGET_NR_poll
7412 case TARGET_NR_poll
:
7414 # ifdef TARGET_NR_ppoll
7415 case TARGET_NR_ppoll
:
7418 struct target_pollfd
*target_pfd
;
7419 unsigned int nfds
= arg2
;
7424 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
7428 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
7429 for(i
= 0; i
< nfds
; i
++) {
7430 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
7431 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
7434 # ifdef TARGET_NR_ppoll
7435 if (num
== TARGET_NR_ppoll
) {
7436 struct timespec _timeout_ts
, *timeout_ts
= &_timeout_ts
;
7437 target_sigset_t
*target_set
;
7438 sigset_t _set
, *set
= &_set
;
7441 if (target_to_host_timespec(timeout_ts
, arg3
)) {
7442 unlock_user(target_pfd
, arg1
, 0);
7450 target_set
= lock_user(VERIFY_READ
, arg4
, sizeof(target_sigset_t
), 1);
7452 unlock_user(target_pfd
, arg1
, 0);
7455 target_to_host_sigset(set
, target_set
);
7460 ret
= get_errno(sys_ppoll(pfd
, nfds
, timeout_ts
, set
, _NSIG
/8));
7462 if (!is_error(ret
) && arg3
) {
7463 host_to_target_timespec(arg3
, timeout_ts
);
7466 unlock_user(target_set
, arg4
, 0);
7470 ret
= get_errno(poll(pfd
, nfds
, timeout
));
7472 if (!is_error(ret
)) {
7473 for(i
= 0; i
< nfds
; i
++) {
7474 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
7477 unlock_user(target_pfd
, arg1
, sizeof(struct target_pollfd
) * nfds
);
7481 case TARGET_NR_flock
:
7482 /* NOTE: the flock constant seems to be the same for every
7484 ret
= get_errno(flock(arg1
, arg2
));
7486 case TARGET_NR_readv
:
7488 struct iovec
*vec
= lock_iovec(VERIFY_WRITE
, arg2
, arg3
, 0);
7490 ret
= get_errno(readv(arg1
, vec
, arg3
));
7491 unlock_iovec(vec
, arg2
, arg3
, 1);
7493 ret
= -host_to_target_errno(errno
);
7497 case TARGET_NR_writev
:
7499 struct iovec
*vec
= lock_iovec(VERIFY_READ
, arg2
, arg3
, 1);
7501 ret
= get_errno(writev(arg1
, vec
, arg3
));
7502 unlock_iovec(vec
, arg2
, arg3
, 0);
7504 ret
= -host_to_target_errno(errno
);
7508 case TARGET_NR_getsid
:
7509 ret
= get_errno(getsid(arg1
));
7511 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7512 case TARGET_NR_fdatasync
:
7513 ret
= get_errno(fdatasync(arg1
));
7516 case TARGET_NR__sysctl
:
7517 /* We don't implement this, but ENOTDIR is always a safe
7519 ret
= -TARGET_ENOTDIR
;
7521 case TARGET_NR_sched_getaffinity
:
7523 unsigned int mask_size
;
7524 unsigned long *mask
;
7527 * sched_getaffinity needs multiples of ulong, so need to take
7528 * care of mismatches between target ulong and host ulong sizes.
7530 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7531 ret
= -TARGET_EINVAL
;
7534 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7536 mask
= alloca(mask_size
);
7537 ret
= get_errno(sys_sched_getaffinity(arg1
, mask_size
, mask
));
7539 if (!is_error(ret
)) {
7540 if (copy_to_user(arg3
, mask
, ret
)) {
7546 case TARGET_NR_sched_setaffinity
:
7548 unsigned int mask_size
;
7549 unsigned long *mask
;
7552 * sched_setaffinity needs multiples of ulong, so need to take
7553 * care of mismatches between target ulong and host ulong sizes.
7555 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7556 ret
= -TARGET_EINVAL
;
7559 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7561 mask
= alloca(mask_size
);
7562 if (!lock_user_struct(VERIFY_READ
, p
, arg3
, 1)) {
7565 memcpy(mask
, p
, arg2
);
7566 unlock_user_struct(p
, arg2
, 0);
7568 ret
= get_errno(sys_sched_setaffinity(arg1
, mask_size
, mask
));
7571 case TARGET_NR_sched_setparam
:
7573 struct sched_param
*target_schp
;
7574 struct sched_param schp
;
7576 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
7578 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7579 unlock_user_struct(target_schp
, arg2
, 0);
7580 ret
= get_errno(sched_setparam(arg1
, &schp
));
7583 case TARGET_NR_sched_getparam
:
7585 struct sched_param
*target_schp
;
7586 struct sched_param schp
;
7587 ret
= get_errno(sched_getparam(arg1
, &schp
));
7588 if (!is_error(ret
)) {
7589 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
7591 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
7592 unlock_user_struct(target_schp
, arg2
, 1);
7596 case TARGET_NR_sched_setscheduler
:
7598 struct sched_param
*target_schp
;
7599 struct sched_param schp
;
7600 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
7602 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7603 unlock_user_struct(target_schp
, arg3
, 0);
7604 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
7607 case TARGET_NR_sched_getscheduler
:
7608 ret
= get_errno(sched_getscheduler(arg1
));
7610 case TARGET_NR_sched_yield
:
7611 ret
= get_errno(sched_yield());
7613 case TARGET_NR_sched_get_priority_max
:
7614 ret
= get_errno(sched_get_priority_max(arg1
));
7616 case TARGET_NR_sched_get_priority_min
:
7617 ret
= get_errno(sched_get_priority_min(arg1
));
7619 case TARGET_NR_sched_rr_get_interval
:
7622 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
7623 if (!is_error(ret
)) {
7624 host_to_target_timespec(arg2
, &ts
);
7628 case TARGET_NR_nanosleep
:
7630 struct timespec req
, rem
;
7631 target_to_host_timespec(&req
, arg1
);
7632 ret
= get_errno(nanosleep(&req
, &rem
));
7633 if (is_error(ret
) && arg2
) {
7634 host_to_target_timespec(arg2
, &rem
);
7638 #ifdef TARGET_NR_query_module
7639 case TARGET_NR_query_module
:
7642 #ifdef TARGET_NR_nfsservctl
7643 case TARGET_NR_nfsservctl
:
7646 case TARGET_NR_prctl
:
7648 case PR_GET_PDEATHSIG
:
7651 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
7652 if (!is_error(ret
) && arg2
7653 && put_user_ual(deathsig
, arg2
)) {
7661 void *name
= lock_user(VERIFY_WRITE
, arg2
, 16, 1);
7665 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7667 unlock_user(name
, arg2
, 16);
7672 void *name
= lock_user(VERIFY_READ
, arg2
, 16, 1);
7676 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7678 unlock_user(name
, arg2
, 0);
7683 /* Most prctl options have no pointer arguments */
7684 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
7688 #ifdef TARGET_NR_arch_prctl
7689 case TARGET_NR_arch_prctl
:
7690 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
7691 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
7697 #ifdef TARGET_NR_pread64
7698 case TARGET_NR_pread64
:
7699 if (regpairs_aligned(cpu_env
)) {
7703 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
7705 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7706 unlock_user(p
, arg2
, ret
);
7708 case TARGET_NR_pwrite64
:
7709 if (regpairs_aligned(cpu_env
)) {
7713 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
7715 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7716 unlock_user(p
, arg2
, 0);
7719 case TARGET_NR_getcwd
:
7720 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
7722 ret
= get_errno(sys_getcwd1(p
, arg2
));
7723 unlock_user(p
, arg1
, ret
);
7725 case TARGET_NR_capget
:
7727 case TARGET_NR_capset
:
7729 case TARGET_NR_sigaltstack
:
7730 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7731 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7732 defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7733 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUArchState
*)cpu_env
));
7739 #ifdef CONFIG_SENDFILE
7740 case TARGET_NR_sendfile
:
7745 ret
= get_user_sal(off
, arg3
);
7746 if (is_error(ret
)) {
7751 ret
= get_errno(sendfile(arg1
, arg2
, offp
, arg4
));
7752 if (!is_error(ret
) && arg3
) {
7753 abi_long ret2
= put_user_sal(off
, arg3
);
7754 if (is_error(ret2
)) {
7760 #ifdef TARGET_NR_sendfile64
7761 case TARGET_NR_sendfile64
:
7766 ret
= get_user_s64(off
, arg3
);
7767 if (is_error(ret
)) {
7772 ret
= get_errno(sendfile(arg1
, arg2
, offp
, arg4
));
7773 if (!is_error(ret
) && arg3
) {
7774 abi_long ret2
= put_user_s64(off
, arg3
);
7775 if (is_error(ret2
)) {
7783 case TARGET_NR_sendfile
:
7784 #ifdef TARGET_NR_sendfile64
7785 case TARGET_NR_sendfile64
:
7790 #ifdef TARGET_NR_getpmsg
7791 case TARGET_NR_getpmsg
:
7794 #ifdef TARGET_NR_putpmsg
7795 case TARGET_NR_putpmsg
:
7798 #ifdef TARGET_NR_vfork
7799 case TARGET_NR_vfork
:
7800 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
7804 #ifdef TARGET_NR_ugetrlimit
7805 case TARGET_NR_ugetrlimit
:
7808 int resource
= target_to_host_resource(arg1
);
7809 ret
= get_errno(getrlimit(resource
, &rlim
));
7810 if (!is_error(ret
)) {
7811 struct target_rlimit
*target_rlim
;
7812 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
7814 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
7815 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
7816 unlock_user_struct(target_rlim
, arg2
, 1);
7821 #ifdef TARGET_NR_truncate64
7822 case TARGET_NR_truncate64
:
7823 if (!(p
= lock_user_string(arg1
)))
7825 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
7826 unlock_user(p
, arg1
, 0);
7829 #ifdef TARGET_NR_ftruncate64
7830 case TARGET_NR_ftruncate64
:
7831 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
7834 #ifdef TARGET_NR_stat64
7835 case TARGET_NR_stat64
:
7836 if (!(p
= lock_user_string(arg1
)))
7838 ret
= get_errno(stat(path(p
), &st
));
7839 unlock_user(p
, arg1
, 0);
7841 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7844 #ifdef TARGET_NR_lstat64
7845 case TARGET_NR_lstat64
:
7846 if (!(p
= lock_user_string(arg1
)))
7848 ret
= get_errno(lstat(path(p
), &st
));
7849 unlock_user(p
, arg1
, 0);
7851 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7854 #ifdef TARGET_NR_fstat64
7855 case TARGET_NR_fstat64
:
7856 ret
= get_errno(fstat(arg1
, &st
));
7858 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7861 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7862 #ifdef TARGET_NR_fstatat64
7863 case TARGET_NR_fstatat64
:
7865 #ifdef TARGET_NR_newfstatat
7866 case TARGET_NR_newfstatat
:
7868 if (!(p
= lock_user_string(arg2
)))
7870 ret
= get_errno(fstatat(arg1
, path(p
), &st
, arg4
));
7872 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
7875 case TARGET_NR_lchown
:
7876 if (!(p
= lock_user_string(arg1
)))
7878 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7879 unlock_user(p
, arg1
, 0);
7881 #ifdef TARGET_NR_getuid
7882 case TARGET_NR_getuid
:
7883 ret
= get_errno(high2lowuid(getuid()));
7886 #ifdef TARGET_NR_getgid
7887 case TARGET_NR_getgid
:
7888 ret
= get_errno(high2lowgid(getgid()));
7891 #ifdef TARGET_NR_geteuid
7892 case TARGET_NR_geteuid
:
7893 ret
= get_errno(high2lowuid(geteuid()));
7896 #ifdef TARGET_NR_getegid
7897 case TARGET_NR_getegid
:
7898 ret
= get_errno(high2lowgid(getegid()));
7901 case TARGET_NR_setreuid
:
7902 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
7904 case TARGET_NR_setregid
:
7905 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
7907 case TARGET_NR_getgroups
:
7909 int gidsetsize
= arg1
;
7910 target_id
*target_grouplist
;
7914 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7915 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7916 if (gidsetsize
== 0)
7918 if (!is_error(ret
)) {
7919 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* sizeof(target_id
), 0);
7920 if (!target_grouplist
)
7922 for(i
= 0;i
< ret
; i
++)
7923 target_grouplist
[i
] = tswapid(high2lowgid(grouplist
[i
]));
7924 unlock_user(target_grouplist
, arg2
, gidsetsize
* sizeof(target_id
));
7928 case TARGET_NR_setgroups
:
7930 int gidsetsize
= arg1
;
7931 target_id
*target_grouplist
;
7932 gid_t
*grouplist
= NULL
;
7935 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7936 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* sizeof(target_id
), 1);
7937 if (!target_grouplist
) {
7938 ret
= -TARGET_EFAULT
;
7941 for (i
= 0; i
< gidsetsize
; i
++) {
7942 grouplist
[i
] = low2highgid(tswapid(target_grouplist
[i
]));
7944 unlock_user(target_grouplist
, arg2
, 0);
7946 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
7949 case TARGET_NR_fchown
:
7950 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
7952 #if defined(TARGET_NR_fchownat)
7953 case TARGET_NR_fchownat
:
7954 if (!(p
= lock_user_string(arg2
)))
7956 ret
= get_errno(fchownat(arg1
, p
, low2highuid(arg3
),
7957 low2highgid(arg4
), arg5
));
7958 unlock_user(p
, arg2
, 0);
7961 #ifdef TARGET_NR_setresuid
7962 case TARGET_NR_setresuid
:
7963 ret
= get_errno(setresuid(low2highuid(arg1
),
7965 low2highuid(arg3
)));
7968 #ifdef TARGET_NR_getresuid
7969 case TARGET_NR_getresuid
:
7971 uid_t ruid
, euid
, suid
;
7972 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
7973 if (!is_error(ret
)) {
7974 if (put_user_u16(high2lowuid(ruid
), arg1
)
7975 || put_user_u16(high2lowuid(euid
), arg2
)
7976 || put_user_u16(high2lowuid(suid
), arg3
))
7982 #ifdef TARGET_NR_getresgid
7983 case TARGET_NR_setresgid
:
7984 ret
= get_errno(setresgid(low2highgid(arg1
),
7986 low2highgid(arg3
)));
7989 #ifdef TARGET_NR_getresgid
7990 case TARGET_NR_getresgid
:
7992 gid_t rgid
, egid
, sgid
;
7993 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
7994 if (!is_error(ret
)) {
7995 if (put_user_u16(high2lowgid(rgid
), arg1
)
7996 || put_user_u16(high2lowgid(egid
), arg2
)
7997 || put_user_u16(high2lowgid(sgid
), arg3
))
8003 case TARGET_NR_chown
:
8004 if (!(p
= lock_user_string(arg1
)))
8006 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
8007 unlock_user(p
, arg1
, 0);
8009 case TARGET_NR_setuid
:
8010 ret
= get_errno(setuid(low2highuid(arg1
)));
8012 case TARGET_NR_setgid
:
8013 ret
= get_errno(setgid(low2highgid(arg1
)));
8015 case TARGET_NR_setfsuid
:
8016 ret
= get_errno(setfsuid(arg1
));
8018 case TARGET_NR_setfsgid
:
8019 ret
= get_errno(setfsgid(arg1
));
8022 #ifdef TARGET_NR_lchown32
8023 case TARGET_NR_lchown32
:
8024 if (!(p
= lock_user_string(arg1
)))
8026 ret
= get_errno(lchown(p
, arg2
, arg3
));
8027 unlock_user(p
, arg1
, 0);
8030 #ifdef TARGET_NR_getuid32
8031 case TARGET_NR_getuid32
:
8032 ret
= get_errno(getuid());
8036 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
8037 /* Alpha specific */
8038 case TARGET_NR_getxuid
:
8042 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
8044 ret
= get_errno(getuid());
8047 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
8048 /* Alpha specific */
8049 case TARGET_NR_getxgid
:
8053 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
8055 ret
= get_errno(getgid());
8058 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
8059 /* Alpha specific */
8060 case TARGET_NR_osf_getsysinfo
:
8061 ret
= -TARGET_EOPNOTSUPP
;
8063 case TARGET_GSI_IEEE_FP_CONTROL
:
8065 uint64_t swcr
, fpcr
= cpu_alpha_load_fpcr (cpu_env
);
8067 /* Copied from linux ieee_fpcr_to_swcr. */
8068 swcr
= (fpcr
>> 35) & SWCR_STATUS_MASK
;
8069 swcr
|= (fpcr
>> 36) & SWCR_MAP_DMZ
;
8070 swcr
|= (~fpcr
>> 48) & (SWCR_TRAP_ENABLE_INV
8071 | SWCR_TRAP_ENABLE_DZE
8072 | SWCR_TRAP_ENABLE_OVF
);
8073 swcr
|= (~fpcr
>> 57) & (SWCR_TRAP_ENABLE_UNF
8074 | SWCR_TRAP_ENABLE_INE
);
8075 swcr
|= (fpcr
>> 47) & SWCR_MAP_UMZ
;
8076 swcr
|= (~fpcr
>> 41) & SWCR_TRAP_ENABLE_DNO
;
8078 if (put_user_u64 (swcr
, arg2
))
8084 /* case GSI_IEEE_STATE_AT_SIGNAL:
8085 -- Not implemented in linux kernel.
8087 -- Retrieves current unaligned access state; not much used.
8089 -- Retrieves implver information; surely not used.
8091 -- Grabs a copy of the HWRPB; surely not used.
8096 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
8097 /* Alpha specific */
8098 case TARGET_NR_osf_setsysinfo
:
8099 ret
= -TARGET_EOPNOTSUPP
;
8101 case TARGET_SSI_IEEE_FP_CONTROL
:
8103 uint64_t swcr
, fpcr
, orig_fpcr
;
8105 if (get_user_u64 (swcr
, arg2
)) {
8108 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
8109 fpcr
= orig_fpcr
& FPCR_DYN_MASK
;
8111 /* Copied from linux ieee_swcr_to_fpcr. */
8112 fpcr
|= (swcr
& SWCR_STATUS_MASK
) << 35;
8113 fpcr
|= (swcr
& SWCR_MAP_DMZ
) << 36;
8114 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_INV
8115 | SWCR_TRAP_ENABLE_DZE
8116 | SWCR_TRAP_ENABLE_OVF
)) << 48;
8117 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_UNF
8118 | SWCR_TRAP_ENABLE_INE
)) << 57;
8119 fpcr
|= (swcr
& SWCR_MAP_UMZ
? FPCR_UNDZ
| FPCR_UNFD
: 0);
8120 fpcr
|= (~swcr
& SWCR_TRAP_ENABLE_DNO
) << 41;
8122 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
8127 case TARGET_SSI_IEEE_RAISE_EXCEPTION
:
8129 uint64_t exc
, fpcr
, orig_fpcr
;
8132 if (get_user_u64(exc
, arg2
)) {
8136 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
8138 /* We only add to the exception status here. */
8139 fpcr
= orig_fpcr
| ((exc
& SWCR_STATUS_MASK
) << 35);
8141 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
8144 /* Old exceptions are not signaled. */
8145 fpcr
&= ~(orig_fpcr
& FPCR_STATUS_MASK
);
8147 /* If any exceptions set by this call,
8148 and are unmasked, send a signal. */
8150 if ((fpcr
& (FPCR_INE
| FPCR_INED
)) == FPCR_INE
) {
8151 si_code
= TARGET_FPE_FLTRES
;
8153 if ((fpcr
& (FPCR_UNF
| FPCR_UNFD
)) == FPCR_UNF
) {
8154 si_code
= TARGET_FPE_FLTUND
;
8156 if ((fpcr
& (FPCR_OVF
| FPCR_OVFD
)) == FPCR_OVF
) {
8157 si_code
= TARGET_FPE_FLTOVF
;
8159 if ((fpcr
& (FPCR_DZE
| FPCR_DZED
)) == FPCR_DZE
) {
8160 si_code
= TARGET_FPE_FLTDIV
;
8162 if ((fpcr
& (FPCR_INV
| FPCR_INVD
)) == FPCR_INV
) {
8163 si_code
= TARGET_FPE_FLTINV
;
8166 target_siginfo_t info
;
8167 info
.si_signo
= SIGFPE
;
8169 info
.si_code
= si_code
;
8170 info
._sifields
._sigfault
._addr
8171 = ((CPUArchState
*)cpu_env
)->pc
;
8172 queue_signal((CPUArchState
*)cpu_env
, info
.si_signo
, &info
);
8177 /* case SSI_NVPAIRS:
8178 -- Used with SSIN_UACPROC to enable unaligned accesses.
8179 case SSI_IEEE_STATE_AT_SIGNAL:
8180 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
8181 -- Not implemented in linux kernel
8186 #ifdef TARGET_NR_osf_sigprocmask
8187 /* Alpha specific. */
8188 case TARGET_NR_osf_sigprocmask
:
8192 sigset_t set
, oldset
;
8195 case TARGET_SIG_BLOCK
:
8198 case TARGET_SIG_UNBLOCK
:
8201 case TARGET_SIG_SETMASK
:
8205 ret
= -TARGET_EINVAL
;
8209 target_to_host_old_sigset(&set
, &mask
);
8210 sigprocmask(how
, &set
, &oldset
);
8211 host_to_target_old_sigset(&mask
, &oldset
);
8217 #ifdef TARGET_NR_getgid32
8218 case TARGET_NR_getgid32
:
8219 ret
= get_errno(getgid());
8222 #ifdef TARGET_NR_geteuid32
8223 case TARGET_NR_geteuid32
:
8224 ret
= get_errno(geteuid());
8227 #ifdef TARGET_NR_getegid32
8228 case TARGET_NR_getegid32
:
8229 ret
= get_errno(getegid());
8232 #ifdef TARGET_NR_setreuid32
8233 case TARGET_NR_setreuid32
:
8234 ret
= get_errno(setreuid(arg1
, arg2
));
8237 #ifdef TARGET_NR_setregid32
8238 case TARGET_NR_setregid32
:
8239 ret
= get_errno(setregid(arg1
, arg2
));
8242 #ifdef TARGET_NR_getgroups32
8243 case TARGET_NR_getgroups32
:
8245 int gidsetsize
= arg1
;
8246 uint32_t *target_grouplist
;
8250 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
8251 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
8252 if (gidsetsize
== 0)
8254 if (!is_error(ret
)) {
8255 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
8256 if (!target_grouplist
) {
8257 ret
= -TARGET_EFAULT
;
8260 for(i
= 0;i
< ret
; i
++)
8261 target_grouplist
[i
] = tswap32(grouplist
[i
]);
8262 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
8267 #ifdef TARGET_NR_setgroups32
8268 case TARGET_NR_setgroups32
:
8270 int gidsetsize
= arg1
;
8271 uint32_t *target_grouplist
;
8275 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
8276 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
8277 if (!target_grouplist
) {
8278 ret
= -TARGET_EFAULT
;
8281 for(i
= 0;i
< gidsetsize
; i
++)
8282 grouplist
[i
] = tswap32(target_grouplist
[i
]);
8283 unlock_user(target_grouplist
, arg2
, 0);
8284 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
8288 #ifdef TARGET_NR_fchown32
8289 case TARGET_NR_fchown32
:
8290 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
8293 #ifdef TARGET_NR_setresuid32
8294 case TARGET_NR_setresuid32
:
8295 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
8298 #ifdef TARGET_NR_getresuid32
8299 case TARGET_NR_getresuid32
:
8301 uid_t ruid
, euid
, suid
;
8302 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
8303 if (!is_error(ret
)) {
8304 if (put_user_u32(ruid
, arg1
)
8305 || put_user_u32(euid
, arg2
)
8306 || put_user_u32(suid
, arg3
))
8312 #ifdef TARGET_NR_setresgid32
8313 case TARGET_NR_setresgid32
:
8314 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
8317 #ifdef TARGET_NR_getresgid32
8318 case TARGET_NR_getresgid32
:
8320 gid_t rgid
, egid
, sgid
;
8321 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
8322 if (!is_error(ret
)) {
8323 if (put_user_u32(rgid
, arg1
)
8324 || put_user_u32(egid
, arg2
)
8325 || put_user_u32(sgid
, arg3
))
8331 #ifdef TARGET_NR_chown32
8332 case TARGET_NR_chown32
:
8333 if (!(p
= lock_user_string(arg1
)))
8335 ret
= get_errno(chown(p
, arg2
, arg3
));
8336 unlock_user(p
, arg1
, 0);
8339 #ifdef TARGET_NR_setuid32
8340 case TARGET_NR_setuid32
:
8341 ret
= get_errno(setuid(arg1
));
8344 #ifdef TARGET_NR_setgid32
8345 case TARGET_NR_setgid32
:
8346 ret
= get_errno(setgid(arg1
));
8349 #ifdef TARGET_NR_setfsuid32
8350 case TARGET_NR_setfsuid32
:
8351 ret
= get_errno(setfsuid(arg1
));
8354 #ifdef TARGET_NR_setfsgid32
8355 case TARGET_NR_setfsgid32
:
8356 ret
= get_errno(setfsgid(arg1
));
8360 case TARGET_NR_pivot_root
:
8362 #ifdef TARGET_NR_mincore
8363 case TARGET_NR_mincore
:
8366 ret
= -TARGET_EFAULT
;
8367 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
8369 if (!(p
= lock_user_string(arg3
)))
8371 ret
= get_errno(mincore(a
, arg2
, p
));
8372 unlock_user(p
, arg3
, ret
);
8374 unlock_user(a
, arg1
, 0);
8378 #ifdef TARGET_NR_arm_fadvise64_64
8379 case TARGET_NR_arm_fadvise64_64
:
8382 * arm_fadvise64_64 looks like fadvise64_64 but
8383 * with different argument order
8391 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8392 #ifdef TARGET_NR_fadvise64_64
8393 case TARGET_NR_fadvise64_64
:
8395 #ifdef TARGET_NR_fadvise64
8396 case TARGET_NR_fadvise64
:
8400 case 4: arg4
= POSIX_FADV_NOREUSE
+ 1; break; /* make sure it's an invalid value */
8401 case 5: arg4
= POSIX_FADV_NOREUSE
+ 2; break; /* ditto */
8402 case 6: arg4
= POSIX_FADV_DONTNEED
; break;
8403 case 7: arg4
= POSIX_FADV_NOREUSE
; break;
8407 ret
= -posix_fadvise(arg1
, arg2
, arg3
, arg4
);
8410 #ifdef TARGET_NR_madvise
8411 case TARGET_NR_madvise
:
8412 /* A straight passthrough may not be safe because qemu sometimes
8413 turns private file-backed mappings into anonymous mappings.
8414 This will break MADV_DONTNEED.
8415 This is a hint, so ignoring and returning success is ok. */
8419 #if TARGET_ABI_BITS == 32
8420 case TARGET_NR_fcntl64
:
8424 struct target_flock64
*target_fl
;
8426 struct target_eabi_flock64
*target_efl
;
8429 cmd
= target_to_host_fcntl_cmd(arg2
);
8430 if (cmd
== -TARGET_EINVAL
) {
8436 case TARGET_F_GETLK64
:
8438 if (((CPUARMState
*)cpu_env
)->eabi
) {
8439 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8441 fl
.l_type
= tswap16(target_efl
->l_type
);
8442 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8443 fl
.l_start
= tswap64(target_efl
->l_start
);
8444 fl
.l_len
= tswap64(target_efl
->l_len
);
8445 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8446 unlock_user_struct(target_efl
, arg3
, 0);
8450 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8452 fl
.l_type
= tswap16(target_fl
->l_type
);
8453 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8454 fl
.l_start
= tswap64(target_fl
->l_start
);
8455 fl
.l_len
= tswap64(target_fl
->l_len
);
8456 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8457 unlock_user_struct(target_fl
, arg3
, 0);
8459 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8462 if (((CPUARMState
*)cpu_env
)->eabi
) {
8463 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
8465 target_efl
->l_type
= tswap16(fl
.l_type
);
8466 target_efl
->l_whence
= tswap16(fl
.l_whence
);
8467 target_efl
->l_start
= tswap64(fl
.l_start
);
8468 target_efl
->l_len
= tswap64(fl
.l_len
);
8469 target_efl
->l_pid
= tswap32(fl
.l_pid
);
8470 unlock_user_struct(target_efl
, arg3
, 1);
8474 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
8476 target_fl
->l_type
= tswap16(fl
.l_type
);
8477 target_fl
->l_whence
= tswap16(fl
.l_whence
);
8478 target_fl
->l_start
= tswap64(fl
.l_start
);
8479 target_fl
->l_len
= tswap64(fl
.l_len
);
8480 target_fl
->l_pid
= tswap32(fl
.l_pid
);
8481 unlock_user_struct(target_fl
, arg3
, 1);
8486 case TARGET_F_SETLK64
:
8487 case TARGET_F_SETLKW64
:
8489 if (((CPUARMState
*)cpu_env
)->eabi
) {
8490 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8492 fl
.l_type
= tswap16(target_efl
->l_type
);
8493 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8494 fl
.l_start
= tswap64(target_efl
->l_start
);
8495 fl
.l_len
= tswap64(target_efl
->l_len
);
8496 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8497 unlock_user_struct(target_efl
, arg3
, 0);
8501 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8503 fl
.l_type
= tswap16(target_fl
->l_type
);
8504 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8505 fl
.l_start
= tswap64(target_fl
->l_start
);
8506 fl
.l_len
= tswap64(target_fl
->l_len
);
8507 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8508 unlock_user_struct(target_fl
, arg3
, 0);
8510 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8513 ret
= do_fcntl(arg1
, arg2
, arg3
);
8519 #ifdef TARGET_NR_cacheflush
8520 case TARGET_NR_cacheflush
:
8521 /* self-modifying code is handled automatically, so nothing needed */
8525 #ifdef TARGET_NR_security
8526 case TARGET_NR_security
:
8529 #ifdef TARGET_NR_getpagesize
8530 case TARGET_NR_getpagesize
:
8531 ret
= TARGET_PAGE_SIZE
;
8534 case TARGET_NR_gettid
:
8535 ret
= get_errno(gettid());
8537 #ifdef TARGET_NR_readahead
8538 case TARGET_NR_readahead
:
8539 #if TARGET_ABI_BITS == 32
8540 if (regpairs_aligned(cpu_env
)) {
8545 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
8547 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
8552 #ifdef TARGET_NR_setxattr
8553 case TARGET_NR_listxattr
:
8554 case TARGET_NR_llistxattr
:
8558 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8560 ret
= -TARGET_EFAULT
;
8564 p
= lock_user_string(arg1
);
8566 if (num
== TARGET_NR_listxattr
) {
8567 ret
= get_errno(listxattr(p
, b
, arg3
));
8569 ret
= get_errno(llistxattr(p
, b
, arg3
));
8572 ret
= -TARGET_EFAULT
;
8574 unlock_user(p
, arg1
, 0);
8575 unlock_user(b
, arg2
, arg3
);
8578 case TARGET_NR_flistxattr
:
8582 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8584 ret
= -TARGET_EFAULT
;
8588 ret
= get_errno(flistxattr(arg1
, b
, arg3
));
8589 unlock_user(b
, arg2
, arg3
);
8592 case TARGET_NR_setxattr
:
8593 case TARGET_NR_lsetxattr
:
8595 void *p
, *n
, *v
= 0;
8597 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8599 ret
= -TARGET_EFAULT
;
8603 p
= lock_user_string(arg1
);
8604 n
= lock_user_string(arg2
);
8606 if (num
== TARGET_NR_setxattr
) {
8607 ret
= get_errno(setxattr(p
, n
, v
, arg4
, arg5
));
8609 ret
= get_errno(lsetxattr(p
, n
, v
, arg4
, arg5
));
8612 ret
= -TARGET_EFAULT
;
8614 unlock_user(p
, arg1
, 0);
8615 unlock_user(n
, arg2
, 0);
8616 unlock_user(v
, arg3
, 0);
8619 case TARGET_NR_fsetxattr
:
8623 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8625 ret
= -TARGET_EFAULT
;
8629 n
= lock_user_string(arg2
);
8631 ret
= get_errno(fsetxattr(arg1
, n
, v
, arg4
, arg5
));
8633 ret
= -TARGET_EFAULT
;
8635 unlock_user(n
, arg2
, 0);
8636 unlock_user(v
, arg3
, 0);
8639 case TARGET_NR_getxattr
:
8640 case TARGET_NR_lgetxattr
:
8642 void *p
, *n
, *v
= 0;
8644 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8646 ret
= -TARGET_EFAULT
;
8650 p
= lock_user_string(arg1
);
8651 n
= lock_user_string(arg2
);
8653 if (num
== TARGET_NR_getxattr
) {
8654 ret
= get_errno(getxattr(p
, n
, v
, arg4
));
8656 ret
= get_errno(lgetxattr(p
, n
, v
, arg4
));
8659 ret
= -TARGET_EFAULT
;
8661 unlock_user(p
, arg1
, 0);
8662 unlock_user(n
, arg2
, 0);
8663 unlock_user(v
, arg3
, arg4
);
8666 case TARGET_NR_fgetxattr
:
8670 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8672 ret
= -TARGET_EFAULT
;
8676 n
= lock_user_string(arg2
);
8678 ret
= get_errno(fgetxattr(arg1
, n
, v
, arg4
));
8680 ret
= -TARGET_EFAULT
;
8682 unlock_user(n
, arg2
, 0);
8683 unlock_user(v
, arg3
, arg4
);
8686 case TARGET_NR_removexattr
:
8687 case TARGET_NR_lremovexattr
:
8690 p
= lock_user_string(arg1
);
8691 n
= lock_user_string(arg2
);
8693 if (num
== TARGET_NR_removexattr
) {
8694 ret
= get_errno(removexattr(p
, n
));
8696 ret
= get_errno(lremovexattr(p
, n
));
8699 ret
= -TARGET_EFAULT
;
8701 unlock_user(p
, arg1
, 0);
8702 unlock_user(n
, arg2
, 0);
8705 case TARGET_NR_fremovexattr
:
8708 n
= lock_user_string(arg2
);
8710 ret
= get_errno(fremovexattr(arg1
, n
));
8712 ret
= -TARGET_EFAULT
;
8714 unlock_user(n
, arg2
, 0);
8718 #endif /* CONFIG_ATTR */
8719 #ifdef TARGET_NR_set_thread_area
8720 case TARGET_NR_set_thread_area
:
8721 #if defined(TARGET_MIPS)
8722 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
8725 #elif defined(TARGET_CRIS)
8727 ret
= -TARGET_EINVAL
;
8729 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
8733 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
8734 ret
= do_set_thread_area(cpu_env
, arg1
);
8736 #elif defined(TARGET_M68K)
8738 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
8739 ts
->tp_value
= arg1
;
8744 goto unimplemented_nowarn
;
8747 #ifdef TARGET_NR_get_thread_area
8748 case TARGET_NR_get_thread_area
:
8749 #if defined(TARGET_I386) && defined(TARGET_ABI32)
8750 ret
= do_get_thread_area(cpu_env
, arg1
);
8752 #elif defined(TARGET_M68K)
8754 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
8759 goto unimplemented_nowarn
;
8762 #ifdef TARGET_NR_getdomainname
8763 case TARGET_NR_getdomainname
:
8764 goto unimplemented_nowarn
;
8767 #ifdef TARGET_NR_clock_gettime
8768 case TARGET_NR_clock_gettime
:
8771 ret
= get_errno(clock_gettime(arg1
, &ts
));
8772 if (!is_error(ret
)) {
8773 host_to_target_timespec(arg2
, &ts
);
8778 #ifdef TARGET_NR_clock_getres
8779 case TARGET_NR_clock_getres
:
8782 ret
= get_errno(clock_getres(arg1
, &ts
));
8783 if (!is_error(ret
)) {
8784 host_to_target_timespec(arg2
, &ts
);
8789 #ifdef TARGET_NR_clock_nanosleep
8790 case TARGET_NR_clock_nanosleep
:
8793 target_to_host_timespec(&ts
, arg3
);
8794 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
8796 host_to_target_timespec(arg4
, &ts
);
8801 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8802 case TARGET_NR_set_tid_address
:
8803 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
8807 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8808 case TARGET_NR_tkill
:
8809 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
8813 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8814 case TARGET_NR_tgkill
:
8815 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
8816 target_to_host_signal(arg3
)));
8820 #ifdef TARGET_NR_set_robust_list
8821 case TARGET_NR_set_robust_list
:
8822 case TARGET_NR_get_robust_list
:
8823 /* The ABI for supporting robust futexes has userspace pass
8824 * the kernel a pointer to a linked list which is updated by
8825 * userspace after the syscall; the list is walked by the kernel
8826 * when the thread exits. Since the linked list in QEMU guest
8827 * memory isn't a valid linked list for the host and we have
8828 * no way to reliably intercept the thread-death event, we can't
8829 * support these. Silently return ENOSYS so that guest userspace
8830 * falls back to a non-robust futex implementation (which should
8831 * be OK except in the corner case of the guest crashing while
8832 * holding a mutex that is shared with another process via
8835 goto unimplemented_nowarn
;
8838 #if defined(TARGET_NR_utimensat)
8839 case TARGET_NR_utimensat
:
8841 struct timespec
*tsp
, ts
[2];
8845 target_to_host_timespec(ts
, arg3
);
8846 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
8850 ret
= get_errno(sys_utimensat(arg1
, NULL
, tsp
, arg4
));
8852 if (!(p
= lock_user_string(arg2
))) {
8853 ret
= -TARGET_EFAULT
;
8856 ret
= get_errno(sys_utimensat(arg1
, path(p
), tsp
, arg4
));
8857 unlock_user(p
, arg2
, 0);
8862 case TARGET_NR_futex
:
8863 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
8865 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8866 case TARGET_NR_inotify_init
:
8867 ret
= get_errno(sys_inotify_init());
8870 #ifdef CONFIG_INOTIFY1
8871 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8872 case TARGET_NR_inotify_init1
:
8873 ret
= get_errno(sys_inotify_init1(arg1
));
8877 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8878 case TARGET_NR_inotify_add_watch
:
8879 p
= lock_user_string(arg2
);
8880 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
8881 unlock_user(p
, arg2
, 0);
8884 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8885 case TARGET_NR_inotify_rm_watch
:
8886 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
8890 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8891 case TARGET_NR_mq_open
:
8893 struct mq_attr posix_mq_attr
;
8895 p
= lock_user_string(arg1
- 1);
8897 copy_from_user_mq_attr (&posix_mq_attr
, arg4
);
8898 ret
= get_errno(mq_open(p
, arg2
, arg3
, &posix_mq_attr
));
8899 unlock_user (p
, arg1
, 0);
8903 case TARGET_NR_mq_unlink
:
8904 p
= lock_user_string(arg1
- 1);
8905 ret
= get_errno(mq_unlink(p
));
8906 unlock_user (p
, arg1
, 0);
8909 case TARGET_NR_mq_timedsend
:
8913 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8915 target_to_host_timespec(&ts
, arg5
);
8916 ret
= get_errno(mq_timedsend(arg1
, p
, arg3
, arg4
, &ts
));
8917 host_to_target_timespec(arg5
, &ts
);
8920 ret
= get_errno(mq_send(arg1
, p
, arg3
, arg4
));
8921 unlock_user (p
, arg2
, arg3
);
8925 case TARGET_NR_mq_timedreceive
:
8930 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8932 target_to_host_timespec(&ts
, arg5
);
8933 ret
= get_errno(mq_timedreceive(arg1
, p
, arg3
, &prio
, &ts
));
8934 host_to_target_timespec(arg5
, &ts
);
8937 ret
= get_errno(mq_receive(arg1
, p
, arg3
, &prio
));
8938 unlock_user (p
, arg2
, arg3
);
8940 put_user_u32(prio
, arg4
);
8944 /* Not implemented for now... */
8945 /* case TARGET_NR_mq_notify: */
8948 case TARGET_NR_mq_getsetattr
:
8950 struct mq_attr posix_mq_attr_in
, posix_mq_attr_out
;
8953 ret
= mq_getattr(arg1
, &posix_mq_attr_out
);
8954 copy_to_user_mq_attr(arg3
, &posix_mq_attr_out
);
8957 copy_from_user_mq_attr(&posix_mq_attr_in
, arg2
);
8958 ret
|= mq_setattr(arg1
, &posix_mq_attr_in
, &posix_mq_attr_out
);
8965 #ifdef CONFIG_SPLICE
8966 #ifdef TARGET_NR_tee
8969 ret
= get_errno(tee(arg1
,arg2
,arg3
,arg4
));
8973 #ifdef TARGET_NR_splice
8974 case TARGET_NR_splice
:
8976 loff_t loff_in
, loff_out
;
8977 loff_t
*ploff_in
= NULL
, *ploff_out
= NULL
;
8979 get_user_u64(loff_in
, arg2
);
8980 ploff_in
= &loff_in
;
8983 get_user_u64(loff_out
, arg2
);
8984 ploff_out
= &loff_out
;
8986 ret
= get_errno(splice(arg1
, ploff_in
, arg3
, ploff_out
, arg5
, arg6
));
8990 #ifdef TARGET_NR_vmsplice
8991 case TARGET_NR_vmsplice
:
8993 struct iovec
*vec
= lock_iovec(VERIFY_READ
, arg2
, arg3
, 1);
8995 ret
= get_errno(vmsplice(arg1
, vec
, arg3
, arg4
));
8996 unlock_iovec(vec
, arg2
, arg3
, 0);
8998 ret
= -host_to_target_errno(errno
);
9003 #endif /* CONFIG_SPLICE */
9004 #ifdef CONFIG_EVENTFD
9005 #if defined(TARGET_NR_eventfd)
9006 case TARGET_NR_eventfd
:
9007 ret
= get_errno(eventfd(arg1
, 0));
9010 #if defined(TARGET_NR_eventfd2)
9011 case TARGET_NR_eventfd2
:
9013 int host_flags
= arg2
& (~(TARGET_O_NONBLOCK
| TARGET_O_CLOEXEC
));
9014 if (arg2
& TARGET_O_NONBLOCK
) {
9015 host_flags
|= O_NONBLOCK
;
9017 if (arg2
& TARGET_O_CLOEXEC
) {
9018 host_flags
|= O_CLOEXEC
;
9020 ret
= get_errno(eventfd(arg1
, host_flags
));
9024 #endif /* CONFIG_EVENTFD */
9025 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
9026 case TARGET_NR_fallocate
:
9027 #if TARGET_ABI_BITS == 32
9028 ret
= get_errno(fallocate(arg1
, arg2
, target_offset64(arg3
, arg4
),
9029 target_offset64(arg5
, arg6
)));
9031 ret
= get_errno(fallocate(arg1
, arg2
, arg3
, arg4
));
9035 #if defined(CONFIG_SYNC_FILE_RANGE)
9036 #if defined(TARGET_NR_sync_file_range)
9037 case TARGET_NR_sync_file_range
:
9038 #if TARGET_ABI_BITS == 32
9039 #if defined(TARGET_MIPS)
9040 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
9041 target_offset64(arg5
, arg6
), arg7
));
9043 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg2
, arg3
),
9044 target_offset64(arg4
, arg5
), arg6
));
9045 #endif /* !TARGET_MIPS */
9047 ret
= get_errno(sync_file_range(arg1
, arg2
, arg3
, arg4
));
9051 #if defined(TARGET_NR_sync_file_range2)
9052 case TARGET_NR_sync_file_range2
:
9053 /* This is like sync_file_range but the arguments are reordered */
9054 #if TARGET_ABI_BITS == 32
9055 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
9056 target_offset64(arg5
, arg6
), arg2
));
9058 ret
= get_errno(sync_file_range(arg1
, arg3
, arg4
, arg2
));
9063 #if defined(CONFIG_EPOLL)
9064 #if defined(TARGET_NR_epoll_create)
9065 case TARGET_NR_epoll_create
:
9066 ret
= get_errno(epoll_create(arg1
));
9069 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
9070 case TARGET_NR_epoll_create1
:
9071 ret
= get_errno(epoll_create1(arg1
));
9074 #if defined(TARGET_NR_epoll_ctl)
9075 case TARGET_NR_epoll_ctl
:
9077 struct epoll_event ep
;
9078 struct epoll_event
*epp
= 0;
9080 struct target_epoll_event
*target_ep
;
9081 if (!lock_user_struct(VERIFY_READ
, target_ep
, arg4
, 1)) {
9084 ep
.events
= tswap32(target_ep
->events
);
9085 /* The epoll_data_t union is just opaque data to the kernel,
9086 * so we transfer all 64 bits across and need not worry what
9087 * actual data type it is.
9089 ep
.data
.u64
= tswap64(target_ep
->data
.u64
);
9090 unlock_user_struct(target_ep
, arg4
, 0);
9093 ret
= get_errno(epoll_ctl(arg1
, arg2
, arg3
, epp
));
9098 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
9099 #define IMPLEMENT_EPOLL_PWAIT
9101 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
9102 #if defined(TARGET_NR_epoll_wait)
9103 case TARGET_NR_epoll_wait
:
9105 #if defined(IMPLEMENT_EPOLL_PWAIT)
9106 case TARGET_NR_epoll_pwait
:
9109 struct target_epoll_event
*target_ep
;
9110 struct epoll_event
*ep
;
9112 int maxevents
= arg3
;
9115 target_ep
= lock_user(VERIFY_WRITE
, arg2
,
9116 maxevents
* sizeof(struct target_epoll_event
), 1);
9121 ep
= alloca(maxevents
* sizeof(struct epoll_event
));
9124 #if defined(IMPLEMENT_EPOLL_PWAIT)
9125 case TARGET_NR_epoll_pwait
:
9127 target_sigset_t
*target_set
;
9128 sigset_t _set
, *set
= &_set
;
9131 target_set
= lock_user(VERIFY_READ
, arg5
,
9132 sizeof(target_sigset_t
), 1);
9134 unlock_user(target_ep
, arg2
, 0);
9137 target_to_host_sigset(set
, target_set
);
9138 unlock_user(target_set
, arg5
, 0);
9143 ret
= get_errno(epoll_pwait(epfd
, ep
, maxevents
, timeout
, set
));
9147 #if defined(TARGET_NR_epoll_wait)
9148 case TARGET_NR_epoll_wait
:
9149 ret
= get_errno(epoll_wait(epfd
, ep
, maxevents
, timeout
));
9153 ret
= -TARGET_ENOSYS
;
9155 if (!is_error(ret
)) {
9157 for (i
= 0; i
< ret
; i
++) {
9158 target_ep
[i
].events
= tswap32(ep
[i
].events
);
9159 target_ep
[i
].data
.u64
= tswap64(ep
[i
].data
.u64
);
9162 unlock_user(target_ep
, arg2
, ret
* sizeof(struct target_epoll_event
));
9167 #ifdef TARGET_NR_prlimit64
9168 case TARGET_NR_prlimit64
:
9170 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
9171 struct target_rlimit64
*target_rnew
, *target_rold
;
9172 struct host_rlimit64 rnew
, rold
, *rnewp
= 0;
9174 if (!lock_user_struct(VERIFY_READ
, target_rnew
, arg3
, 1)) {
9177 rnew
.rlim_cur
= tswap64(target_rnew
->rlim_cur
);
9178 rnew
.rlim_max
= tswap64(target_rnew
->rlim_max
);
9179 unlock_user_struct(target_rnew
, arg3
, 0);
9183 ret
= get_errno(sys_prlimit64(arg1
, arg2
, rnewp
, arg4
? &rold
: 0));
9184 if (!is_error(ret
) && arg4
) {
9185 if (!lock_user_struct(VERIFY_WRITE
, target_rold
, arg4
, 1)) {
9188 target_rold
->rlim_cur
= tswap64(rold
.rlim_cur
);
9189 target_rold
->rlim_max
= tswap64(rold
.rlim_max
);
9190 unlock_user_struct(target_rold
, arg4
, 1);
9195 #ifdef TARGET_NR_gethostname
9196 case TARGET_NR_gethostname
:
9198 char *name
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0);
9200 ret
= get_errno(gethostname(name
, arg2
));
9201 unlock_user(name
, arg1
, arg2
);
9203 ret
= -TARGET_EFAULT
;
9208 #ifdef TARGET_NR_atomic_cmpxchg_32
9209 case TARGET_NR_atomic_cmpxchg_32
:
9211 /* should use start_exclusive from main.c */
9212 abi_ulong mem_value
;
9213 if (get_user_u32(mem_value
, arg6
)) {
9214 target_siginfo_t info
;
9215 info
.si_signo
= SIGSEGV
;
9217 info
.si_code
= TARGET_SEGV_MAPERR
;
9218 info
._sifields
._sigfault
._addr
= arg6
;
9219 queue_signal((CPUArchState
*)cpu_env
, info
.si_signo
, &info
);
9223 if (mem_value
== arg2
)
9224 put_user_u32(arg1
, arg6
);
9229 #ifdef TARGET_NR_atomic_barrier
9230 case TARGET_NR_atomic_barrier
:
9232 /* Like the kernel implementation and the qemu arm barrier, no-op this? */
9237 #ifdef TARGET_NR_timer_create
9238 case TARGET_NR_timer_create
:
9240 /* args: clockid_t clockid, struct sigevent *sevp, timer_t *timerid */
9242 struct sigevent host_sevp
= { {0}, }, *phost_sevp
= NULL
;
9243 struct target_sigevent
*ptarget_sevp
;
9244 struct target_timer_t
*ptarget_timer
;
9247 int timer_index
= next_free_host_timer();
9249 if (timer_index
< 0) {
9250 ret
= -TARGET_EAGAIN
;
9252 timer_t
*phtimer
= g_posix_timers
+ timer_index
;
9255 if (!lock_user_struct(VERIFY_READ
, ptarget_sevp
, arg2
, 1)) {
9259 host_sevp
.sigev_signo
= tswap32(ptarget_sevp
->sigev_signo
);
9260 host_sevp
.sigev_notify
= tswap32(ptarget_sevp
->sigev_notify
);
9262 phost_sevp
= &host_sevp
;
9265 ret
= get_errno(timer_create(clkid
, phost_sevp
, phtimer
));
9269 if (!lock_user_struct(VERIFY_WRITE
, ptarget_timer
, arg3
, 1)) {
9272 ptarget_timer
->ptr
= tswap32(0xcafe0000 | timer_index
);
9273 unlock_user_struct(ptarget_timer
, arg3
, 1);
9280 #ifdef TARGET_NR_timer_settime
9281 case TARGET_NR_timer_settime
:
9283 /* args: timer_t timerid, int flags, const struct itimerspec *new_value,
9284 * struct itimerspec * old_value */
9286 if (arg3
== 0 || arg1
< 0 || arg1
>= ARRAY_SIZE(g_posix_timers
)) {
9287 ret
= -TARGET_EINVAL
;
9289 timer_t htimer
= g_posix_timers
[arg1
];
9290 struct itimerspec hspec_new
= {{0},}, hspec_old
= {{0},};
9292 target_to_host_itimerspec(&hspec_new
, arg3
);
9294 timer_settime(htimer
, arg2
, &hspec_new
, &hspec_old
));
9295 host_to_target_itimerspec(arg2
, &hspec_old
);
9301 #ifdef TARGET_NR_timer_gettime
9302 case TARGET_NR_timer_gettime
:
9304 /* args: timer_t timerid, struct itimerspec *curr_value */
9307 return -TARGET_EFAULT
;
9308 } else if (arg1
< 0 || arg1
>= ARRAY_SIZE(g_posix_timers
)) {
9309 ret
= -TARGET_EINVAL
;
9311 timer_t htimer
= g_posix_timers
[arg1
];
9312 struct itimerspec hspec
;
9313 ret
= get_errno(timer_gettime(htimer
, &hspec
));
9315 if (host_to_target_itimerspec(arg2
, &hspec
)) {
9316 ret
= -TARGET_EFAULT
;
9323 #ifdef TARGET_NR_timer_getoverrun
9324 case TARGET_NR_timer_getoverrun
:
9326 /* args: timer_t timerid */
9328 if (arg1
< 0 || arg1
>= ARRAY_SIZE(g_posix_timers
)) {
9329 ret
= -TARGET_EINVAL
;
9331 timer_t htimer
= g_posix_timers
[arg1
];
9332 ret
= get_errno(timer_getoverrun(htimer
));
9338 #ifdef TARGET_NR_timer_delete
9339 case TARGET_NR_timer_delete
:
9341 /* args: timer_t timerid */
9343 if (arg1
< 0 || arg1
>= ARRAY_SIZE(g_posix_timers
)) {
9344 ret
= -TARGET_EINVAL
;
9346 timer_t htimer
= g_posix_timers
[arg1
];
9347 ret
= get_errno(timer_delete(htimer
));
9348 g_posix_timers
[arg1
] = 0;
9356 gemu_log("qemu: Unsupported syscall: %d\n", num
);
9357 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
9358 unimplemented_nowarn
:
9360 ret
= -TARGET_ENOSYS
;
9365 gemu_log(" = " TARGET_ABI_FMT_ld
"\n", ret
);
9368 print_syscall_ret(num
, ret
);
9371 ret
= -TARGET_EFAULT
;