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>
46 #include <linux/capability.h>
50 int __clone2(int (*fn
)(void *), void *child_stack_base
,
51 size_t stack_size
, int flags
, void *arg
, ...);
53 #include <sys/socket.h>
57 #include <sys/times.h>
60 #include <sys/statfs.h>
62 #include <sys/sysinfo.h>
63 //#include <sys/user.h>
64 #include <netinet/ip.h>
65 #include <netinet/tcp.h>
66 #include <linux/wireless.h>
67 #include <linux/icmp.h>
68 #include "qemu-common.h"
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/cdrom.h>
95 #include <linux/hdreg.h>
96 #include <linux/soundcard.h>
98 #include <linux/mtio.h>
100 #if defined(CONFIG_FIEMAP)
101 #include <linux/fiemap.h>
103 #include <linux/fb.h>
104 #include <linux/vt.h>
105 #include <linux/dm-ioctl.h>
106 #include <linux/reboot.h>
107 #include <linux/route.h>
108 #include <linux/filter.h>
109 #include <linux/blkpg.h>
110 #include "linux_loop.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
199 /* Newer kernel ports have llseek() instead of _llseek() */
200 #if defined(TARGET_NR_llseek) && !defined(TARGET_NR__llseek)
201 #define TARGET_NR__llseek TARGET_NR_llseek
205 _syscall0(int, gettid
)
207 /* This is a replacement for the host gettid() and must return a host
209 static int gettid(void) {
214 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
216 #if !defined(__NR_getdents) || \
217 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
218 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
220 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
221 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
222 loff_t
*, res
, uint
, wh
);
224 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
225 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
226 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
227 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
229 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
230 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
232 #ifdef __NR_exit_group
233 _syscall1(int,exit_group
,int,error_code
)
235 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
236 _syscall1(int,set_tid_address
,int *,tidptr
)
238 #if defined(TARGET_NR_futex) && defined(__NR_futex)
239 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
240 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
242 #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
243 _syscall3(int, sys_sched_getaffinity
, pid_t
, pid
, unsigned int, len
,
244 unsigned long *, user_mask_ptr
);
245 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
246 _syscall3(int, sys_sched_setaffinity
, pid_t
, pid
, unsigned int, len
,
247 unsigned long *, user_mask_ptr
);
248 _syscall4(int, reboot
, int, magic1
, int, magic2
, unsigned int, cmd
,
250 _syscall2(int, capget
, struct __user_cap_header_struct
*, header
,
251 struct __user_cap_data_struct
*, data
);
252 _syscall2(int, capset
, struct __user_cap_header_struct
*, header
,
253 struct __user_cap_data_struct
*, data
);
255 static bitmask_transtbl fcntl_flags_tbl
[] = {
256 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
257 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
258 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
259 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
260 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
261 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
262 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
263 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
264 { TARGET_O_SYNC
, TARGET_O_DSYNC
, O_SYNC
, O_DSYNC
, },
265 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
266 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
267 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
268 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
269 #if defined(O_DIRECT)
270 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
272 #if defined(O_NOATIME)
273 { TARGET_O_NOATIME
, TARGET_O_NOATIME
, O_NOATIME
, O_NOATIME
},
275 #if defined(O_CLOEXEC)
276 { TARGET_O_CLOEXEC
, TARGET_O_CLOEXEC
, O_CLOEXEC
, O_CLOEXEC
},
279 { TARGET_O_PATH
, TARGET_O_PATH
, O_PATH
, O_PATH
},
281 /* Don't terminate the list prematurely on 64-bit host+guest. */
282 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
283 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
288 static int sys_getcwd1(char *buf
, size_t size
)
290 if (getcwd(buf
, size
) == NULL
) {
291 /* getcwd() sets errno */
294 return strlen(buf
)+1;
297 #ifdef TARGET_NR_openat
298 static int sys_openat(int dirfd
, const char *pathname
, int flags
, mode_t mode
)
301 * open(2) has extra parameter 'mode' when called with
304 if ((flags
& O_CREAT
) != 0) {
305 return (openat(dirfd
, pathname
, flags
, mode
));
307 return (openat(dirfd
, pathname
, flags
));
311 #ifdef TARGET_NR_utimensat
312 #ifdef CONFIG_UTIMENSAT
313 static int sys_utimensat(int dirfd
, const char *pathname
,
314 const struct timespec times
[2], int flags
)
316 if (pathname
== NULL
)
317 return futimens(dirfd
, times
);
319 return utimensat(dirfd
, pathname
, times
, flags
);
321 #elif defined(__NR_utimensat)
322 #define __NR_sys_utimensat __NR_utimensat
323 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
324 const struct timespec
*,tsp
,int,flags
)
326 static int sys_utimensat(int dirfd
, const char *pathname
,
327 const struct timespec times
[2], int flags
)
333 #endif /* TARGET_NR_utimensat */
335 #ifdef CONFIG_INOTIFY
336 #include <sys/inotify.h>
338 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
339 static int sys_inotify_init(void)
341 return (inotify_init());
344 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
345 static int sys_inotify_add_watch(int fd
,const char *pathname
, int32_t mask
)
347 return (inotify_add_watch(fd
, pathname
, mask
));
350 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
351 static int sys_inotify_rm_watch(int fd
, int32_t wd
)
353 return (inotify_rm_watch(fd
, wd
));
356 #ifdef CONFIG_INOTIFY1
357 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
358 static int sys_inotify_init1(int flags
)
360 return (inotify_init1(flags
));
365 /* Userspace can usually survive runtime without inotify */
366 #undef TARGET_NR_inotify_init
367 #undef TARGET_NR_inotify_init1
368 #undef TARGET_NR_inotify_add_watch
369 #undef TARGET_NR_inotify_rm_watch
370 #endif /* CONFIG_INOTIFY */
372 #if defined(TARGET_NR_ppoll)
374 # define __NR_ppoll -1
376 #define __NR_sys_ppoll __NR_ppoll
377 _syscall5(int, sys_ppoll
, struct pollfd
*, fds
, nfds_t
, nfds
,
378 struct timespec
*, timeout
, const sigset_t
*, sigmask
,
382 #if defined(TARGET_NR_pselect6)
383 #ifndef __NR_pselect6
384 # define __NR_pselect6 -1
386 #define __NR_sys_pselect6 __NR_pselect6
387 _syscall6(int, sys_pselect6
, int, nfds
, fd_set
*, readfds
, fd_set
*, writefds
,
388 fd_set
*, exceptfds
, struct timespec
*, timeout
, void *, sig
);
391 #if defined(TARGET_NR_prlimit64)
392 #ifndef __NR_prlimit64
393 # define __NR_prlimit64 -1
395 #define __NR_sys_prlimit64 __NR_prlimit64
396 /* The glibc rlimit structure may not be that used by the underlying syscall */
397 struct host_rlimit64
{
401 _syscall4(int, sys_prlimit64
, pid_t
, pid
, int, resource
,
402 const struct host_rlimit64
*, new_limit
,
403 struct host_rlimit64
*, old_limit
)
407 #if defined(TARGET_NR_timer_create)
408 /* Maxiumum of 32 active POSIX timers allowed at any one time. */
409 static timer_t g_posix_timers
[32] = { 0, } ;
411 static inline int next_free_host_timer(void)
414 /* FIXME: Does finding the next free slot require a lock? */
415 for (k
= 0; k
< ARRAY_SIZE(g_posix_timers
); k
++) {
416 if (g_posix_timers
[k
] == 0) {
417 g_posix_timers
[k
] = (timer_t
) 1;
425 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
427 static inline int regpairs_aligned(void *cpu_env
) {
428 return ((((CPUARMState
*)cpu_env
)->eabi
) == 1) ;
430 #elif defined(TARGET_MIPS)
431 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
432 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
433 /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
434 * of registers which translates to the same as ARM/MIPS, because we start with
436 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
438 static inline int regpairs_aligned(void *cpu_env
) { return 0; }
441 #define ERRNO_TABLE_SIZE 1200
443 /* target_to_host_errno_table[] is initialized from
444 * host_to_target_errno_table[] in syscall_init(). */
445 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
449 * This list is the union of errno values overridden in asm-<arch>/errno.h
450 * minus the errnos that are not actually generic to all archs.
452 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
453 [EIDRM
] = TARGET_EIDRM
,
454 [ECHRNG
] = TARGET_ECHRNG
,
455 [EL2NSYNC
] = TARGET_EL2NSYNC
,
456 [EL3HLT
] = TARGET_EL3HLT
,
457 [EL3RST
] = TARGET_EL3RST
,
458 [ELNRNG
] = TARGET_ELNRNG
,
459 [EUNATCH
] = TARGET_EUNATCH
,
460 [ENOCSI
] = TARGET_ENOCSI
,
461 [EL2HLT
] = TARGET_EL2HLT
,
462 [EDEADLK
] = TARGET_EDEADLK
,
463 [ENOLCK
] = TARGET_ENOLCK
,
464 [EBADE
] = TARGET_EBADE
,
465 [EBADR
] = TARGET_EBADR
,
466 [EXFULL
] = TARGET_EXFULL
,
467 [ENOANO
] = TARGET_ENOANO
,
468 [EBADRQC
] = TARGET_EBADRQC
,
469 [EBADSLT
] = TARGET_EBADSLT
,
470 [EBFONT
] = TARGET_EBFONT
,
471 [ENOSTR
] = TARGET_ENOSTR
,
472 [ENODATA
] = TARGET_ENODATA
,
473 [ETIME
] = TARGET_ETIME
,
474 [ENOSR
] = TARGET_ENOSR
,
475 [ENONET
] = TARGET_ENONET
,
476 [ENOPKG
] = TARGET_ENOPKG
,
477 [EREMOTE
] = TARGET_EREMOTE
,
478 [ENOLINK
] = TARGET_ENOLINK
,
479 [EADV
] = TARGET_EADV
,
480 [ESRMNT
] = TARGET_ESRMNT
,
481 [ECOMM
] = TARGET_ECOMM
,
482 [EPROTO
] = TARGET_EPROTO
,
483 [EDOTDOT
] = TARGET_EDOTDOT
,
484 [EMULTIHOP
] = TARGET_EMULTIHOP
,
485 [EBADMSG
] = TARGET_EBADMSG
,
486 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
487 [EOVERFLOW
] = TARGET_EOVERFLOW
,
488 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
489 [EBADFD
] = TARGET_EBADFD
,
490 [EREMCHG
] = TARGET_EREMCHG
,
491 [ELIBACC
] = TARGET_ELIBACC
,
492 [ELIBBAD
] = TARGET_ELIBBAD
,
493 [ELIBSCN
] = TARGET_ELIBSCN
,
494 [ELIBMAX
] = TARGET_ELIBMAX
,
495 [ELIBEXEC
] = TARGET_ELIBEXEC
,
496 [EILSEQ
] = TARGET_EILSEQ
,
497 [ENOSYS
] = TARGET_ENOSYS
,
498 [ELOOP
] = TARGET_ELOOP
,
499 [ERESTART
] = TARGET_ERESTART
,
500 [ESTRPIPE
] = TARGET_ESTRPIPE
,
501 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
502 [EUSERS
] = TARGET_EUSERS
,
503 [ENOTSOCK
] = TARGET_ENOTSOCK
,
504 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
505 [EMSGSIZE
] = TARGET_EMSGSIZE
,
506 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
507 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
508 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
509 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
510 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
511 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
512 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
513 [EADDRINUSE
] = TARGET_EADDRINUSE
,
514 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
515 [ENETDOWN
] = TARGET_ENETDOWN
,
516 [ENETUNREACH
] = TARGET_ENETUNREACH
,
517 [ENETRESET
] = TARGET_ENETRESET
,
518 [ECONNABORTED
] = TARGET_ECONNABORTED
,
519 [ECONNRESET
] = TARGET_ECONNRESET
,
520 [ENOBUFS
] = TARGET_ENOBUFS
,
521 [EISCONN
] = TARGET_EISCONN
,
522 [ENOTCONN
] = TARGET_ENOTCONN
,
523 [EUCLEAN
] = TARGET_EUCLEAN
,
524 [ENOTNAM
] = TARGET_ENOTNAM
,
525 [ENAVAIL
] = TARGET_ENAVAIL
,
526 [EISNAM
] = TARGET_EISNAM
,
527 [EREMOTEIO
] = TARGET_EREMOTEIO
,
528 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
529 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
530 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
531 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
532 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
533 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
534 [EALREADY
] = TARGET_EALREADY
,
535 [EINPROGRESS
] = TARGET_EINPROGRESS
,
536 [ESTALE
] = TARGET_ESTALE
,
537 [ECANCELED
] = TARGET_ECANCELED
,
538 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
539 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
541 [ENOKEY
] = TARGET_ENOKEY
,
544 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
547 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
550 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
553 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
555 #ifdef ENOTRECOVERABLE
556 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
560 static inline int host_to_target_errno(int err
)
562 if(host_to_target_errno_table
[err
])
563 return host_to_target_errno_table
[err
];
567 static inline int target_to_host_errno(int err
)
569 if (target_to_host_errno_table
[err
])
570 return target_to_host_errno_table
[err
];
574 static inline abi_long
get_errno(abi_long ret
)
577 return -host_to_target_errno(errno
);
582 static inline int is_error(abi_long ret
)
584 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
587 char *target_strerror(int err
)
589 if ((err
>= ERRNO_TABLE_SIZE
) || (err
< 0)) {
592 return strerror(target_to_host_errno(err
));
595 static inline int host_to_target_sock_type(int host_type
)
599 switch (host_type
& 0xf /* SOCK_TYPE_MASK */) {
601 target_type
= TARGET_SOCK_DGRAM
;
604 target_type
= TARGET_SOCK_STREAM
;
607 target_type
= host_type
& 0xf /* SOCK_TYPE_MASK */;
611 #if defined(SOCK_CLOEXEC)
612 if (host_type
& SOCK_CLOEXEC
) {
613 target_type
|= TARGET_SOCK_CLOEXEC
;
617 #if defined(SOCK_NONBLOCK)
618 if (host_type
& SOCK_NONBLOCK
) {
619 target_type
|= TARGET_SOCK_NONBLOCK
;
626 static abi_ulong target_brk
;
627 static abi_ulong target_original_brk
;
628 static abi_ulong brk_page
;
630 void target_set_brk(abi_ulong new_brk
)
632 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
633 brk_page
= HOST_PAGE_ALIGN(target_brk
);
636 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
637 #define DEBUGF_BRK(message, args...)
639 /* do_brk() must return target values and target errnos. */
640 abi_long
do_brk(abi_ulong new_brk
)
642 abi_long mapped_addr
;
645 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx
") -> ", new_brk
);
648 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (!new_brk)\n", target_brk
);
651 if (new_brk
< target_original_brk
) {
652 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk < target_original_brk)\n",
657 /* If the new brk is less than the highest page reserved to the
658 * target heap allocation, set it and we're almost done... */
659 if (new_brk
<= brk_page
) {
660 /* Heap contents are initialized to zero, as for anonymous
662 if (new_brk
> target_brk
) {
663 memset(g2h(target_brk
), 0, new_brk
- target_brk
);
665 target_brk
= new_brk
;
666 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk <= brk_page)\n", target_brk
);
670 /* We need to allocate more memory after the brk... Note that
671 * we don't use MAP_FIXED because that will map over the top of
672 * any existing mapping (like the one with the host libc or qemu
673 * itself); instead we treat "mapped but at wrong address" as
674 * a failure and unmap again.
676 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
);
677 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
678 PROT_READ
|PROT_WRITE
,
679 MAP_ANON
|MAP_PRIVATE
, 0, 0));
681 if (mapped_addr
== brk_page
) {
682 /* Heap contents are initialized to zero, as for anonymous
683 * mapped pages. Technically the new pages are already
684 * initialized to zero since they *are* anonymous mapped
685 * pages, however we have to take care with the contents that
686 * come from the remaining part of the previous page: it may
687 * contains garbage data due to a previous heap usage (grown
689 memset(g2h(target_brk
), 0, brk_page
- target_brk
);
691 target_brk
= new_brk
;
692 brk_page
= HOST_PAGE_ALIGN(target_brk
);
693 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr == brk_page)\n",
696 } else if (mapped_addr
!= -1) {
697 /* Mapped but at wrong address, meaning there wasn't actually
698 * enough space for this brk.
700 target_munmap(mapped_addr
, new_alloc_size
);
702 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr != -1)\n", target_brk
);
705 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (otherwise)\n", target_brk
);
708 #if defined(TARGET_ALPHA)
709 /* We (partially) emulate OSF/1 on Alpha, which requires we
710 return a proper errno, not an unchanged brk value. */
711 return -TARGET_ENOMEM
;
713 /* For everything else, return the previous break. */
717 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
718 abi_ulong target_fds_addr
,
722 abi_ulong b
, *target_fds
;
724 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
725 if (!(target_fds
= lock_user(VERIFY_READ
,
727 sizeof(abi_ulong
) * nw
,
729 return -TARGET_EFAULT
;
733 for (i
= 0; i
< nw
; i
++) {
734 /* grab the abi_ulong */
735 __get_user(b
, &target_fds
[i
]);
736 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
737 /* check the bit inside the abi_ulong */
744 unlock_user(target_fds
, target_fds_addr
, 0);
749 static inline abi_ulong
copy_from_user_fdset_ptr(fd_set
*fds
, fd_set
**fds_ptr
,
750 abi_ulong target_fds_addr
,
753 if (target_fds_addr
) {
754 if (copy_from_user_fdset(fds
, target_fds_addr
, n
))
755 return -TARGET_EFAULT
;
763 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
769 abi_ulong
*target_fds
;
771 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
772 if (!(target_fds
= lock_user(VERIFY_WRITE
,
774 sizeof(abi_ulong
) * nw
,
776 return -TARGET_EFAULT
;
779 for (i
= 0; i
< nw
; i
++) {
781 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
782 v
|= ((abi_ulong
)(FD_ISSET(k
, fds
) != 0) << j
);
785 __put_user(v
, &target_fds
[i
]);
788 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
793 #if defined(__alpha__)
799 static inline abi_long
host_to_target_clock_t(long ticks
)
801 #if HOST_HZ == TARGET_HZ
804 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
808 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
809 const struct rusage
*rusage
)
811 struct target_rusage
*target_rusage
;
813 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
814 return -TARGET_EFAULT
;
815 target_rusage
->ru_utime
.tv_sec
= tswapal(rusage
->ru_utime
.tv_sec
);
816 target_rusage
->ru_utime
.tv_usec
= tswapal(rusage
->ru_utime
.tv_usec
);
817 target_rusage
->ru_stime
.tv_sec
= tswapal(rusage
->ru_stime
.tv_sec
);
818 target_rusage
->ru_stime
.tv_usec
= tswapal(rusage
->ru_stime
.tv_usec
);
819 target_rusage
->ru_maxrss
= tswapal(rusage
->ru_maxrss
);
820 target_rusage
->ru_ixrss
= tswapal(rusage
->ru_ixrss
);
821 target_rusage
->ru_idrss
= tswapal(rusage
->ru_idrss
);
822 target_rusage
->ru_isrss
= tswapal(rusage
->ru_isrss
);
823 target_rusage
->ru_minflt
= tswapal(rusage
->ru_minflt
);
824 target_rusage
->ru_majflt
= tswapal(rusage
->ru_majflt
);
825 target_rusage
->ru_nswap
= tswapal(rusage
->ru_nswap
);
826 target_rusage
->ru_inblock
= tswapal(rusage
->ru_inblock
);
827 target_rusage
->ru_oublock
= tswapal(rusage
->ru_oublock
);
828 target_rusage
->ru_msgsnd
= tswapal(rusage
->ru_msgsnd
);
829 target_rusage
->ru_msgrcv
= tswapal(rusage
->ru_msgrcv
);
830 target_rusage
->ru_nsignals
= tswapal(rusage
->ru_nsignals
);
831 target_rusage
->ru_nvcsw
= tswapal(rusage
->ru_nvcsw
);
832 target_rusage
->ru_nivcsw
= tswapal(rusage
->ru_nivcsw
);
833 unlock_user_struct(target_rusage
, target_addr
, 1);
838 static inline rlim_t
target_to_host_rlim(abi_ulong target_rlim
)
840 abi_ulong target_rlim_swap
;
843 target_rlim_swap
= tswapal(target_rlim
);
844 if (target_rlim_swap
== TARGET_RLIM_INFINITY
)
845 return RLIM_INFINITY
;
847 result
= target_rlim_swap
;
848 if (target_rlim_swap
!= (rlim_t
)result
)
849 return RLIM_INFINITY
;
854 static inline abi_ulong
host_to_target_rlim(rlim_t rlim
)
856 abi_ulong target_rlim_swap
;
859 if (rlim
== RLIM_INFINITY
|| rlim
!= (abi_long
)rlim
)
860 target_rlim_swap
= TARGET_RLIM_INFINITY
;
862 target_rlim_swap
= rlim
;
863 result
= tswapal(target_rlim_swap
);
868 static inline int target_to_host_resource(int code
)
871 case TARGET_RLIMIT_AS
:
873 case TARGET_RLIMIT_CORE
:
875 case TARGET_RLIMIT_CPU
:
877 case TARGET_RLIMIT_DATA
:
879 case TARGET_RLIMIT_FSIZE
:
881 case TARGET_RLIMIT_LOCKS
:
883 case TARGET_RLIMIT_MEMLOCK
:
884 return RLIMIT_MEMLOCK
;
885 case TARGET_RLIMIT_MSGQUEUE
:
886 return RLIMIT_MSGQUEUE
;
887 case TARGET_RLIMIT_NICE
:
889 case TARGET_RLIMIT_NOFILE
:
890 return RLIMIT_NOFILE
;
891 case TARGET_RLIMIT_NPROC
:
893 case TARGET_RLIMIT_RSS
:
895 case TARGET_RLIMIT_RTPRIO
:
896 return RLIMIT_RTPRIO
;
897 case TARGET_RLIMIT_SIGPENDING
:
898 return RLIMIT_SIGPENDING
;
899 case TARGET_RLIMIT_STACK
:
906 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
907 abi_ulong target_tv_addr
)
909 struct target_timeval
*target_tv
;
911 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
912 return -TARGET_EFAULT
;
914 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
915 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
917 unlock_user_struct(target_tv
, target_tv_addr
, 0);
922 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
923 const struct timeval
*tv
)
925 struct target_timeval
*target_tv
;
927 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
928 return -TARGET_EFAULT
;
930 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
931 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
933 unlock_user_struct(target_tv
, target_tv_addr
, 1);
938 static inline abi_long
copy_from_user_timezone(struct timezone
*tz
,
939 abi_ulong target_tz_addr
)
941 struct target_timezone
*target_tz
;
943 if (!lock_user_struct(VERIFY_READ
, target_tz
, target_tz_addr
, 1)) {
944 return -TARGET_EFAULT
;
947 __get_user(tz
->tz_minuteswest
, &target_tz
->tz_minuteswest
);
948 __get_user(tz
->tz_dsttime
, &target_tz
->tz_dsttime
);
950 unlock_user_struct(target_tz
, target_tz_addr
, 0);
955 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
958 static inline abi_long
copy_from_user_mq_attr(struct mq_attr
*attr
,
959 abi_ulong target_mq_attr_addr
)
961 struct target_mq_attr
*target_mq_attr
;
963 if (!lock_user_struct(VERIFY_READ
, target_mq_attr
,
964 target_mq_attr_addr
, 1))
965 return -TARGET_EFAULT
;
967 __get_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
968 __get_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
969 __get_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
970 __get_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
972 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 0);
977 static inline abi_long
copy_to_user_mq_attr(abi_ulong target_mq_attr_addr
,
978 const struct mq_attr
*attr
)
980 struct target_mq_attr
*target_mq_attr
;
982 if (!lock_user_struct(VERIFY_WRITE
, target_mq_attr
,
983 target_mq_attr_addr
, 0))
984 return -TARGET_EFAULT
;
986 __put_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
987 __put_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
988 __put_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
989 __put_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
991 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 1);
997 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
998 /* do_select() must return target values and target errnos. */
999 static abi_long
do_select(int n
,
1000 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
1001 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
1003 fd_set rfds
, wfds
, efds
;
1004 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
1005 struct timeval tv
, *tv_ptr
;
1008 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
1012 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
1016 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
1021 if (target_tv_addr
) {
1022 if (copy_from_user_timeval(&tv
, target_tv_addr
))
1023 return -TARGET_EFAULT
;
1029 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
1031 if (!is_error(ret
)) {
1032 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
1033 return -TARGET_EFAULT
;
1034 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
1035 return -TARGET_EFAULT
;
1036 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
1037 return -TARGET_EFAULT
;
1039 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
1040 return -TARGET_EFAULT
;
1047 static abi_long
do_pipe2(int host_pipe
[], int flags
)
1050 return pipe2(host_pipe
, flags
);
1056 static abi_long
do_pipe(void *cpu_env
, abi_ulong pipedes
,
1057 int flags
, int is_pipe2
)
1061 ret
= flags ?
do_pipe2(host_pipe
, flags
) : pipe(host_pipe
);
1064 return get_errno(ret
);
1066 /* Several targets have special calling conventions for the original
1067 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1069 #if defined(TARGET_ALPHA)
1070 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = host_pipe
[1];
1071 return host_pipe
[0];
1072 #elif defined(TARGET_MIPS)
1073 ((CPUMIPSState
*)cpu_env
)->active_tc
.gpr
[3] = host_pipe
[1];
1074 return host_pipe
[0];
1075 #elif defined(TARGET_SH4)
1076 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
1077 return host_pipe
[0];
1078 #elif defined(TARGET_SPARC)
1079 ((CPUSPARCState
*)cpu_env
)->regwptr
[1] = host_pipe
[1];
1080 return host_pipe
[0];
1084 if (put_user_s32(host_pipe
[0], pipedes
)
1085 || put_user_s32(host_pipe
[1], pipedes
+ sizeof(host_pipe
[0])))
1086 return -TARGET_EFAULT
;
1087 return get_errno(ret
);
1090 static inline abi_long
target_to_host_ip_mreq(struct ip_mreqn
*mreqn
,
1091 abi_ulong target_addr
,
1094 struct target_ip_mreqn
*target_smreqn
;
1096 target_smreqn
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1098 return -TARGET_EFAULT
;
1099 mreqn
->imr_multiaddr
.s_addr
= target_smreqn
->imr_multiaddr
.s_addr
;
1100 mreqn
->imr_address
.s_addr
= target_smreqn
->imr_address
.s_addr
;
1101 if (len
== sizeof(struct target_ip_mreqn
))
1102 mreqn
->imr_ifindex
= tswapal(target_smreqn
->imr_ifindex
);
1103 unlock_user(target_smreqn
, target_addr
, 0);
1108 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
1109 abi_ulong target_addr
,
1112 const socklen_t unix_maxlen
= sizeof (struct sockaddr_un
);
1113 sa_family_t sa_family
;
1114 struct target_sockaddr
*target_saddr
;
1116 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1118 return -TARGET_EFAULT
;
1120 sa_family
= tswap16(target_saddr
->sa_family
);
1122 /* Oops. The caller might send a incomplete sun_path; sun_path
1123 * must be terminated by \0 (see the manual page), but
1124 * unfortunately it is quite common to specify sockaddr_un
1125 * length as "strlen(x->sun_path)" while it should be
1126 * "strlen(...) + 1". We'll fix that here if needed.
1127 * Linux kernel has a similar feature.
1130 if (sa_family
== AF_UNIX
) {
1131 if (len
< unix_maxlen
&& len
> 0) {
1132 char *cp
= (char*)target_saddr
;
1134 if ( cp
[len
-1] && !cp
[len
] )
1137 if (len
> unix_maxlen
)
1141 memcpy(addr
, target_saddr
, len
);
1142 addr
->sa_family
= sa_family
;
1143 if (sa_family
== AF_PACKET
) {
1144 struct target_sockaddr_ll
*lladdr
;
1146 lladdr
= (struct target_sockaddr_ll
*)addr
;
1147 lladdr
->sll_ifindex
= tswap32(lladdr
->sll_ifindex
);
1148 lladdr
->sll_hatype
= tswap16(lladdr
->sll_hatype
);
1150 unlock_user(target_saddr
, target_addr
, 0);
1155 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
1156 struct sockaddr
*addr
,
1159 struct target_sockaddr
*target_saddr
;
1161 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
1163 return -TARGET_EFAULT
;
1164 memcpy(target_saddr
, addr
, len
);
1165 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
1166 unlock_user(target_saddr
, target_addr
, len
);
1171 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
1172 struct target_msghdr
*target_msgh
)
1174 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1175 abi_long msg_controllen
;
1176 abi_ulong target_cmsg_addr
;
1177 struct target_cmsghdr
*target_cmsg
;
1178 socklen_t space
= 0;
1180 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1181 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1183 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1184 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
1186 return -TARGET_EFAULT
;
1188 while (cmsg
&& target_cmsg
) {
1189 void *data
= CMSG_DATA(cmsg
);
1190 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1192 int len
= tswapal(target_cmsg
->cmsg_len
)
1193 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
1195 space
+= CMSG_SPACE(len
);
1196 if (space
> msgh
->msg_controllen
) {
1197 space
-= CMSG_SPACE(len
);
1198 gemu_log("Host cmsg overflow\n");
1202 if (tswap32(target_cmsg
->cmsg_level
) == TARGET_SOL_SOCKET
) {
1203 cmsg
->cmsg_level
= SOL_SOCKET
;
1205 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
1207 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
1208 cmsg
->cmsg_len
= CMSG_LEN(len
);
1210 if (cmsg
->cmsg_level
!= SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1211 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1212 memcpy(data
, target_data
, len
);
1214 int *fd
= (int *)data
;
1215 int *target_fd
= (int *)target_data
;
1216 int i
, numfds
= len
/ sizeof(int);
1218 for (i
= 0; i
< numfds
; i
++)
1219 fd
[i
] = tswap32(target_fd
[i
]);
1222 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1223 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1225 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
1227 msgh
->msg_controllen
= space
;
1231 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
1232 struct msghdr
*msgh
)
1234 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1235 abi_long msg_controllen
;
1236 abi_ulong target_cmsg_addr
;
1237 struct target_cmsghdr
*target_cmsg
;
1238 socklen_t space
= 0;
1240 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1241 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1243 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1244 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
1246 return -TARGET_EFAULT
;
1248 while (cmsg
&& target_cmsg
) {
1249 void *data
= CMSG_DATA(cmsg
);
1250 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1252 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
1254 space
+= TARGET_CMSG_SPACE(len
);
1255 if (space
> msg_controllen
) {
1256 space
-= TARGET_CMSG_SPACE(len
);
1257 gemu_log("Target cmsg overflow\n");
1261 if (cmsg
->cmsg_level
== SOL_SOCKET
) {
1262 target_cmsg
->cmsg_level
= tswap32(TARGET_SOL_SOCKET
);
1264 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
1266 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
1267 target_cmsg
->cmsg_len
= tswapal(TARGET_CMSG_LEN(len
));
1269 switch (cmsg
->cmsg_level
) {
1271 switch (cmsg
->cmsg_type
) {
1274 int *fd
= (int *)data
;
1275 int *target_fd
= (int *)target_data
;
1276 int i
, numfds
= len
/ sizeof(int);
1278 for (i
= 0; i
< numfds
; i
++)
1279 target_fd
[i
] = tswap32(fd
[i
]);
1284 struct timeval
*tv
= (struct timeval
*)data
;
1285 struct target_timeval
*target_tv
=
1286 (struct target_timeval
*)target_data
;
1288 if (len
!= sizeof(struct timeval
))
1291 /* copy struct timeval to target */
1292 target_tv
->tv_sec
= tswapal(tv
->tv_sec
);
1293 target_tv
->tv_usec
= tswapal(tv
->tv_usec
);
1296 case SCM_CREDENTIALS
:
1298 struct ucred
*cred
= (struct ucred
*)data
;
1299 struct target_ucred
*target_cred
=
1300 (struct target_ucred
*)target_data
;
1302 __put_user(cred
->pid
, &target_cred
->pid
);
1303 __put_user(cred
->uid
, &target_cred
->uid
);
1304 __put_user(cred
->gid
, &target_cred
->gid
);
1314 gemu_log("Unsupported ancillary data: %d/%d\n",
1315 cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1316 memcpy(target_data
, data
, len
);
1319 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1320 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1322 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
1324 target_msgh
->msg_controllen
= tswapal(space
);
1328 /* do_setsockopt() Must return target values and target errnos. */
1329 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
1330 abi_ulong optval_addr
, socklen_t optlen
)
1334 struct ip_mreqn
*ip_mreq
;
1335 struct ip_mreq_source
*ip_mreq_source
;
1339 /* TCP options all take an 'int' value. */
1340 if (optlen
< sizeof(uint32_t))
1341 return -TARGET_EINVAL
;
1343 if (get_user_u32(val
, optval_addr
))
1344 return -TARGET_EFAULT
;
1345 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1352 case IP_ROUTER_ALERT
:
1356 case IP_MTU_DISCOVER
:
1362 case IP_MULTICAST_TTL
:
1363 case IP_MULTICAST_LOOP
:
1365 if (optlen
>= sizeof(uint32_t)) {
1366 if (get_user_u32(val
, optval_addr
))
1367 return -TARGET_EFAULT
;
1368 } else if (optlen
>= 1) {
1369 if (get_user_u8(val
, optval_addr
))
1370 return -TARGET_EFAULT
;
1372 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1374 case IP_ADD_MEMBERSHIP
:
1375 case IP_DROP_MEMBERSHIP
:
1376 if (optlen
< sizeof (struct target_ip_mreq
) ||
1377 optlen
> sizeof (struct target_ip_mreqn
))
1378 return -TARGET_EINVAL
;
1380 ip_mreq
= (struct ip_mreqn
*) alloca(optlen
);
1381 target_to_host_ip_mreq(ip_mreq
, optval_addr
, optlen
);
1382 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq
, optlen
));
1385 case IP_BLOCK_SOURCE
:
1386 case IP_UNBLOCK_SOURCE
:
1387 case IP_ADD_SOURCE_MEMBERSHIP
:
1388 case IP_DROP_SOURCE_MEMBERSHIP
:
1389 if (optlen
!= sizeof (struct target_ip_mreq_source
))
1390 return -TARGET_EINVAL
;
1392 ip_mreq_source
= lock_user(VERIFY_READ
, optval_addr
, optlen
, 1);
1393 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq_source
, optlen
));
1394 unlock_user (ip_mreq_source
, optval_addr
, 0);
1403 case IPV6_MTU_DISCOVER
:
1406 case IPV6_RECVPKTINFO
:
1408 if (optlen
< sizeof(uint32_t)) {
1409 return -TARGET_EINVAL
;
1411 if (get_user_u32(val
, optval_addr
)) {
1412 return -TARGET_EFAULT
;
1414 ret
= get_errno(setsockopt(sockfd
, level
, optname
,
1415 &val
, sizeof(val
)));
1424 /* struct icmp_filter takes an u32 value */
1425 if (optlen
< sizeof(uint32_t)) {
1426 return -TARGET_EINVAL
;
1429 if (get_user_u32(val
, optval_addr
)) {
1430 return -TARGET_EFAULT
;
1432 ret
= get_errno(setsockopt(sockfd
, level
, optname
,
1433 &val
, sizeof(val
)));
1440 case TARGET_SOL_SOCKET
:
1442 case TARGET_SO_RCVTIMEO
:
1446 optname
= SO_RCVTIMEO
;
1449 if (optlen
!= sizeof(struct target_timeval
)) {
1450 return -TARGET_EINVAL
;
1453 if (copy_from_user_timeval(&tv
, optval_addr
)) {
1454 return -TARGET_EFAULT
;
1457 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
,
1461 case TARGET_SO_SNDTIMEO
:
1462 optname
= SO_SNDTIMEO
;
1464 case TARGET_SO_ATTACH_FILTER
:
1466 struct target_sock_fprog
*tfprog
;
1467 struct target_sock_filter
*tfilter
;
1468 struct sock_fprog fprog
;
1469 struct sock_filter
*filter
;
1472 if (optlen
!= sizeof(*tfprog
)) {
1473 return -TARGET_EINVAL
;
1475 if (!lock_user_struct(VERIFY_READ
, tfprog
, optval_addr
, 0)) {
1476 return -TARGET_EFAULT
;
1478 if (!lock_user_struct(VERIFY_READ
, tfilter
,
1479 tswapal(tfprog
->filter
), 0)) {
1480 unlock_user_struct(tfprog
, optval_addr
, 1);
1481 return -TARGET_EFAULT
;
1484 fprog
.len
= tswap16(tfprog
->len
);
1485 filter
= malloc(fprog
.len
* sizeof(*filter
));
1486 if (filter
== NULL
) {
1487 unlock_user_struct(tfilter
, tfprog
->filter
, 1);
1488 unlock_user_struct(tfprog
, optval_addr
, 1);
1489 return -TARGET_ENOMEM
;
1491 for (i
= 0; i
< fprog
.len
; i
++) {
1492 filter
[i
].code
= tswap16(tfilter
[i
].code
);
1493 filter
[i
].jt
= tfilter
[i
].jt
;
1494 filter
[i
].jf
= tfilter
[i
].jf
;
1495 filter
[i
].k
= tswap32(tfilter
[i
].k
);
1497 fprog
.filter
= filter
;
1499 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
,
1500 SO_ATTACH_FILTER
, &fprog
, sizeof(fprog
)));
1503 unlock_user_struct(tfilter
, tfprog
->filter
, 1);
1504 unlock_user_struct(tfprog
, optval_addr
, 1);
1507 case TARGET_SO_BINDTODEVICE
:
1509 char *dev_ifname
, *addr_ifname
;
1511 if (optlen
> IFNAMSIZ
- 1) {
1512 optlen
= IFNAMSIZ
- 1;
1514 dev_ifname
= lock_user(VERIFY_READ
, optval_addr
, optlen
, 1);
1516 return -TARGET_EFAULT
;
1518 optname
= SO_BINDTODEVICE
;
1519 addr_ifname
= alloca(IFNAMSIZ
);
1520 memcpy(addr_ifname
, dev_ifname
, optlen
);
1521 addr_ifname
[optlen
] = 0;
1522 ret
= get_errno(setsockopt(sockfd
, level
, optname
, addr_ifname
, optlen
));
1523 unlock_user (dev_ifname
, optval_addr
, 0);
1526 /* Options with 'int' argument. */
1527 case TARGET_SO_DEBUG
:
1530 case TARGET_SO_REUSEADDR
:
1531 optname
= SO_REUSEADDR
;
1533 case TARGET_SO_TYPE
:
1536 case TARGET_SO_ERROR
:
1539 case TARGET_SO_DONTROUTE
:
1540 optname
= SO_DONTROUTE
;
1542 case TARGET_SO_BROADCAST
:
1543 optname
= SO_BROADCAST
;
1545 case TARGET_SO_SNDBUF
:
1546 optname
= SO_SNDBUF
;
1548 case TARGET_SO_SNDBUFFORCE
:
1549 optname
= SO_SNDBUFFORCE
;
1551 case TARGET_SO_RCVBUF
:
1552 optname
= SO_RCVBUF
;
1554 case TARGET_SO_RCVBUFFORCE
:
1555 optname
= SO_RCVBUFFORCE
;
1557 case TARGET_SO_KEEPALIVE
:
1558 optname
= SO_KEEPALIVE
;
1560 case TARGET_SO_OOBINLINE
:
1561 optname
= SO_OOBINLINE
;
1563 case TARGET_SO_NO_CHECK
:
1564 optname
= SO_NO_CHECK
;
1566 case TARGET_SO_PRIORITY
:
1567 optname
= SO_PRIORITY
;
1570 case TARGET_SO_BSDCOMPAT
:
1571 optname
= SO_BSDCOMPAT
;
1574 case TARGET_SO_PASSCRED
:
1575 optname
= SO_PASSCRED
;
1577 case TARGET_SO_PASSSEC
:
1578 optname
= SO_PASSSEC
;
1580 case TARGET_SO_TIMESTAMP
:
1581 optname
= SO_TIMESTAMP
;
1583 case TARGET_SO_RCVLOWAT
:
1584 optname
= SO_RCVLOWAT
;
1590 if (optlen
< sizeof(uint32_t))
1591 return -TARGET_EINVAL
;
1593 if (get_user_u32(val
, optval_addr
))
1594 return -TARGET_EFAULT
;
1595 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
1599 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level
, optname
);
1600 ret
= -TARGET_ENOPROTOOPT
;
1605 /* do_getsockopt() Must return target values and target errnos. */
1606 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
1607 abi_ulong optval_addr
, abi_ulong optlen
)
1614 case TARGET_SOL_SOCKET
:
1617 /* These don't just return a single integer */
1618 case TARGET_SO_LINGER
:
1619 case TARGET_SO_RCVTIMEO
:
1620 case TARGET_SO_SNDTIMEO
:
1621 case TARGET_SO_PEERNAME
:
1623 case TARGET_SO_PEERCRED
: {
1626 struct target_ucred
*tcr
;
1628 if (get_user_u32(len
, optlen
)) {
1629 return -TARGET_EFAULT
;
1632 return -TARGET_EINVAL
;
1636 ret
= get_errno(getsockopt(sockfd
, level
, SO_PEERCRED
,
1644 if (!lock_user_struct(VERIFY_WRITE
, tcr
, optval_addr
, 0)) {
1645 return -TARGET_EFAULT
;
1647 __put_user(cr
.pid
, &tcr
->pid
);
1648 __put_user(cr
.uid
, &tcr
->uid
);
1649 __put_user(cr
.gid
, &tcr
->gid
);
1650 unlock_user_struct(tcr
, optval_addr
, 1);
1651 if (put_user_u32(len
, optlen
)) {
1652 return -TARGET_EFAULT
;
1656 /* Options with 'int' argument. */
1657 case TARGET_SO_DEBUG
:
1660 case TARGET_SO_REUSEADDR
:
1661 optname
= SO_REUSEADDR
;
1663 case TARGET_SO_TYPE
:
1666 case TARGET_SO_ERROR
:
1669 case TARGET_SO_DONTROUTE
:
1670 optname
= SO_DONTROUTE
;
1672 case TARGET_SO_BROADCAST
:
1673 optname
= SO_BROADCAST
;
1675 case TARGET_SO_SNDBUF
:
1676 optname
= SO_SNDBUF
;
1678 case TARGET_SO_RCVBUF
:
1679 optname
= SO_RCVBUF
;
1681 case TARGET_SO_KEEPALIVE
:
1682 optname
= SO_KEEPALIVE
;
1684 case TARGET_SO_OOBINLINE
:
1685 optname
= SO_OOBINLINE
;
1687 case TARGET_SO_NO_CHECK
:
1688 optname
= SO_NO_CHECK
;
1690 case TARGET_SO_PRIORITY
:
1691 optname
= SO_PRIORITY
;
1694 case TARGET_SO_BSDCOMPAT
:
1695 optname
= SO_BSDCOMPAT
;
1698 case TARGET_SO_PASSCRED
:
1699 optname
= SO_PASSCRED
;
1701 case TARGET_SO_TIMESTAMP
:
1702 optname
= SO_TIMESTAMP
;
1704 case TARGET_SO_RCVLOWAT
:
1705 optname
= SO_RCVLOWAT
;
1707 case TARGET_SO_ACCEPTCONN
:
1708 optname
= SO_ACCEPTCONN
;
1715 /* TCP options all take an 'int' value. */
1717 if (get_user_u32(len
, optlen
))
1718 return -TARGET_EFAULT
;
1720 return -TARGET_EINVAL
;
1722 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1725 if (optname
== SO_TYPE
) {
1726 val
= host_to_target_sock_type(val
);
1731 if (put_user_u32(val
, optval_addr
))
1732 return -TARGET_EFAULT
;
1734 if (put_user_u8(val
, optval_addr
))
1735 return -TARGET_EFAULT
;
1737 if (put_user_u32(len
, optlen
))
1738 return -TARGET_EFAULT
;
1745 case IP_ROUTER_ALERT
:
1749 case IP_MTU_DISCOVER
:
1755 case IP_MULTICAST_TTL
:
1756 case IP_MULTICAST_LOOP
:
1757 if (get_user_u32(len
, optlen
))
1758 return -TARGET_EFAULT
;
1760 return -TARGET_EINVAL
;
1762 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1765 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1767 if (put_user_u32(len
, optlen
)
1768 || put_user_u8(val
, optval_addr
))
1769 return -TARGET_EFAULT
;
1771 if (len
> sizeof(int))
1773 if (put_user_u32(len
, optlen
)
1774 || put_user_u32(val
, optval_addr
))
1775 return -TARGET_EFAULT
;
1779 ret
= -TARGET_ENOPROTOOPT
;
1785 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1787 ret
= -TARGET_EOPNOTSUPP
;
1793 static struct iovec
*lock_iovec(int type
, abi_ulong target_addr
,
1794 int count
, int copy
)
1796 struct target_iovec
*target_vec
;
1798 abi_ulong total_len
, max_len
;
1806 if (count
< 0 || count
> IOV_MAX
) {
1811 vec
= calloc(count
, sizeof(struct iovec
));
1817 target_vec
= lock_user(VERIFY_READ
, target_addr
,
1818 count
* sizeof(struct target_iovec
), 1);
1819 if (target_vec
== NULL
) {
1824 /* ??? If host page size > target page size, this will result in a
1825 value larger than what we can actually support. */
1826 max_len
= 0x7fffffff & TARGET_PAGE_MASK
;
1829 for (i
= 0; i
< count
; i
++) {
1830 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
1831 abi_long len
= tswapal(target_vec
[i
].iov_len
);
1836 } else if (len
== 0) {
1837 /* Zero length pointer is ignored. */
1838 vec
[i
].iov_base
= 0;
1840 vec
[i
].iov_base
= lock_user(type
, base
, len
, copy
);
1841 if (!vec
[i
].iov_base
) {
1845 if (len
> max_len
- total_len
) {
1846 len
= max_len
- total_len
;
1849 vec
[i
].iov_len
= len
;
1853 unlock_user(target_vec
, target_addr
, 0);
1857 unlock_user(target_vec
, target_addr
, 0);
1864 static void unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1865 int count
, int copy
)
1867 struct target_iovec
*target_vec
;
1870 target_vec
= lock_user(VERIFY_READ
, target_addr
,
1871 count
* sizeof(struct target_iovec
), 1);
1873 for (i
= 0; i
< count
; i
++) {
1874 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
1875 abi_long len
= tswapal(target_vec
[i
].iov_base
);
1879 unlock_user(vec
[i
].iov_base
, base
, copy ? vec
[i
].iov_len
: 0);
1881 unlock_user(target_vec
, target_addr
, 0);
1887 static inline int target_to_host_sock_type(int *type
)
1890 int target_type
= *type
;
1892 switch (target_type
& TARGET_SOCK_TYPE_MASK
) {
1893 case TARGET_SOCK_DGRAM
:
1894 host_type
= SOCK_DGRAM
;
1896 case TARGET_SOCK_STREAM
:
1897 host_type
= SOCK_STREAM
;
1900 host_type
= target_type
& TARGET_SOCK_TYPE_MASK
;
1903 if (target_type
& TARGET_SOCK_CLOEXEC
) {
1904 #if defined(SOCK_CLOEXEC)
1905 host_type
|= SOCK_CLOEXEC
;
1907 return -TARGET_EINVAL
;
1910 if (target_type
& TARGET_SOCK_NONBLOCK
) {
1911 #if defined(SOCK_NONBLOCK)
1912 host_type
|= SOCK_NONBLOCK
;
1913 #elif !defined(O_NONBLOCK)
1914 return -TARGET_EINVAL
;
1921 /* Try to emulate socket type flags after socket creation. */
1922 static int sock_flags_fixup(int fd
, int target_type
)
1924 #if !defined(SOCK_NONBLOCK) && defined(O_NONBLOCK)
1925 if (target_type
& TARGET_SOCK_NONBLOCK
) {
1926 int flags
= fcntl(fd
, F_GETFL
);
1927 if (fcntl(fd
, F_SETFL
, O_NONBLOCK
| flags
) == -1) {
1929 return -TARGET_EINVAL
;
1936 /* do_socket() Must return target values and target errnos. */
1937 static abi_long
do_socket(int domain
, int type
, int protocol
)
1939 int target_type
= type
;
1942 ret
= target_to_host_sock_type(&type
);
1947 if (domain
== PF_NETLINK
)
1948 return -TARGET_EAFNOSUPPORT
;
1949 ret
= get_errno(socket(domain
, type
, protocol
));
1951 ret
= sock_flags_fixup(ret
, target_type
);
1956 /* do_bind() Must return target values and target errnos. */
1957 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1963 if ((int)addrlen
< 0) {
1964 return -TARGET_EINVAL
;
1967 addr
= alloca(addrlen
+1);
1969 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1973 return get_errno(bind(sockfd
, addr
, addrlen
));
1976 /* do_connect() Must return target values and target errnos. */
1977 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1983 if ((int)addrlen
< 0) {
1984 return -TARGET_EINVAL
;
1987 addr
= alloca(addrlen
+1);
1989 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1993 return get_errno(connect(sockfd
, addr
, addrlen
));
1996 /* do_sendrecvmsg_locked() Must return target values and target errnos. */
1997 static abi_long
do_sendrecvmsg_locked(int fd
, struct target_msghdr
*msgp
,
1998 int flags
, int send
)
2004 abi_ulong target_vec
;
2006 if (msgp
->msg_name
) {
2007 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
2008 msg
.msg_name
= alloca(msg
.msg_namelen
+1);
2009 ret
= target_to_host_sockaddr(msg
.msg_name
, tswapal(msgp
->msg_name
),
2015 msg
.msg_name
= NULL
;
2016 msg
.msg_namelen
= 0;
2018 msg
.msg_controllen
= 2 * tswapal(msgp
->msg_controllen
);
2019 msg
.msg_control
= alloca(msg
.msg_controllen
);
2020 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
2022 count
= tswapal(msgp
->msg_iovlen
);
2023 target_vec
= tswapal(msgp
->msg_iov
);
2024 vec
= lock_iovec(send ? VERIFY_READ
: VERIFY_WRITE
,
2025 target_vec
, count
, send
);
2027 ret
= -host_to_target_errno(errno
);
2030 msg
.msg_iovlen
= count
;
2034 ret
= target_to_host_cmsg(&msg
, msgp
);
2036 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
2038 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
2039 if (!is_error(ret
)) {
2041 ret
= host_to_target_cmsg(msgp
, &msg
);
2042 if (!is_error(ret
)) {
2043 msgp
->msg_namelen
= tswap32(msg
.msg_namelen
);
2044 if (msg
.msg_name
!= NULL
) {
2045 ret
= host_to_target_sockaddr(tswapal(msgp
->msg_name
),
2046 msg
.msg_name
, msg
.msg_namelen
);
2058 unlock_iovec(vec
, target_vec
, count
, !send
);
2063 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
2064 int flags
, int send
)
2067 struct target_msghdr
*msgp
;
2069 if (!lock_user_struct(send ? VERIFY_READ
: VERIFY_WRITE
,
2073 return -TARGET_EFAULT
;
2075 ret
= do_sendrecvmsg_locked(fd
, msgp
, flags
, send
);
2076 unlock_user_struct(msgp
, target_msg
, send ?
0 : 1);
2080 #ifdef TARGET_NR_sendmmsg
2081 /* We don't rely on the C library to have sendmmsg/recvmmsg support,
2082 * so it might not have this *mmsg-specific flag either.
2084 #ifndef MSG_WAITFORONE
2085 #define MSG_WAITFORONE 0x10000
2088 static abi_long
do_sendrecvmmsg(int fd
, abi_ulong target_msgvec
,
2089 unsigned int vlen
, unsigned int flags
,
2092 struct target_mmsghdr
*mmsgp
;
2096 if (vlen
> UIO_MAXIOV
) {
2100 mmsgp
= lock_user(VERIFY_WRITE
, target_msgvec
, sizeof(*mmsgp
) * vlen
, 1);
2102 return -TARGET_EFAULT
;
2105 for (i
= 0; i
< vlen
; i
++) {
2106 ret
= do_sendrecvmsg_locked(fd
, &mmsgp
[i
].msg_hdr
, flags
, send
);
2107 if (is_error(ret
)) {
2110 mmsgp
[i
].msg_len
= tswap32(ret
);
2111 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
2112 if (flags
& MSG_WAITFORONE
) {
2113 flags
|= MSG_DONTWAIT
;
2117 unlock_user(mmsgp
, target_msgvec
, sizeof(*mmsgp
) * i
);
2119 /* Return number of datagrams sent if we sent any at all;
2120 * otherwise return the error.
2129 /* If we don't have a system accept4() then just call accept.
2130 * The callsites to do_accept4() will ensure that they don't
2131 * pass a non-zero flags argument in this config.
2133 #ifndef CONFIG_ACCEPT4
2134 static inline int accept4(int sockfd
, struct sockaddr
*addr
,
2135 socklen_t
*addrlen
, int flags
)
2138 return accept(sockfd
, addr
, addrlen
);
2142 /* do_accept4() Must return target values and target errnos. */
2143 static abi_long
do_accept4(int fd
, abi_ulong target_addr
,
2144 abi_ulong target_addrlen_addr
, int flags
)
2151 host_flags
= target_to_host_bitmask(flags
, fcntl_flags_tbl
);
2153 if (target_addr
== 0) {
2154 return get_errno(accept4(fd
, NULL
, NULL
, host_flags
));
2157 /* linux returns EINVAL if addrlen pointer is invalid */
2158 if (get_user_u32(addrlen
, target_addrlen_addr
))
2159 return -TARGET_EINVAL
;
2161 if ((int)addrlen
< 0) {
2162 return -TARGET_EINVAL
;
2165 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2166 return -TARGET_EINVAL
;
2168 addr
= alloca(addrlen
);
2170 ret
= get_errno(accept4(fd
, addr
, &addrlen
, host_flags
));
2171 if (!is_error(ret
)) {
2172 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2173 if (put_user_u32(addrlen
, target_addrlen_addr
))
2174 ret
= -TARGET_EFAULT
;
2179 /* do_getpeername() Must return target values and target errnos. */
2180 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
2181 abi_ulong target_addrlen_addr
)
2187 if (get_user_u32(addrlen
, target_addrlen_addr
))
2188 return -TARGET_EFAULT
;
2190 if ((int)addrlen
< 0) {
2191 return -TARGET_EINVAL
;
2194 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2195 return -TARGET_EFAULT
;
2197 addr
= alloca(addrlen
);
2199 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
2200 if (!is_error(ret
)) {
2201 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2202 if (put_user_u32(addrlen
, target_addrlen_addr
))
2203 ret
= -TARGET_EFAULT
;
2208 /* do_getsockname() Must return target values and target errnos. */
2209 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
2210 abi_ulong target_addrlen_addr
)
2216 if (get_user_u32(addrlen
, target_addrlen_addr
))
2217 return -TARGET_EFAULT
;
2219 if ((int)addrlen
< 0) {
2220 return -TARGET_EINVAL
;
2223 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
2224 return -TARGET_EFAULT
;
2226 addr
= alloca(addrlen
);
2228 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
2229 if (!is_error(ret
)) {
2230 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2231 if (put_user_u32(addrlen
, target_addrlen_addr
))
2232 ret
= -TARGET_EFAULT
;
2237 /* do_socketpair() Must return target values and target errnos. */
2238 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
2239 abi_ulong target_tab_addr
)
2244 target_to_host_sock_type(&type
);
2246 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
2247 if (!is_error(ret
)) {
2248 if (put_user_s32(tab
[0], target_tab_addr
)
2249 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
2250 ret
= -TARGET_EFAULT
;
2255 /* do_sendto() Must return target values and target errnos. */
2256 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
2257 abi_ulong target_addr
, socklen_t addrlen
)
2263 if ((int)addrlen
< 0) {
2264 return -TARGET_EINVAL
;
2267 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
2269 return -TARGET_EFAULT
;
2271 addr
= alloca(addrlen
+1);
2272 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
2274 unlock_user(host_msg
, msg
, 0);
2277 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
2279 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
2281 unlock_user(host_msg
, msg
, 0);
2285 /* do_recvfrom() Must return target values and target errnos. */
2286 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
2287 abi_ulong target_addr
,
2288 abi_ulong target_addrlen
)
2295 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
2297 return -TARGET_EFAULT
;
2299 if (get_user_u32(addrlen
, target_addrlen
)) {
2300 ret
= -TARGET_EFAULT
;
2303 if ((int)addrlen
< 0) {
2304 ret
= -TARGET_EINVAL
;
2307 addr
= alloca(addrlen
);
2308 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
2310 addr
= NULL
; /* To keep compiler quiet. */
2311 ret
= get_errno(qemu_recv(fd
, host_msg
, len
, flags
));
2313 if (!is_error(ret
)) {
2315 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2316 if (put_user_u32(addrlen
, target_addrlen
)) {
2317 ret
= -TARGET_EFAULT
;
2321 unlock_user(host_msg
, msg
, len
);
2324 unlock_user(host_msg
, msg
, 0);
2329 #ifdef TARGET_NR_socketcall
2330 /* do_socketcall() Must return target values and target errnos. */
2331 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
2333 static const unsigned ac
[] = { /* number of arguments per call */
2334 [SOCKOP_socket
] = 3, /* domain, type, protocol */
2335 [SOCKOP_bind
] = 3, /* sockfd, addr, addrlen */
2336 [SOCKOP_connect
] = 3, /* sockfd, addr, addrlen */
2337 [SOCKOP_listen
] = 2, /* sockfd, backlog */
2338 [SOCKOP_accept
] = 3, /* sockfd, addr, addrlen */
2339 [SOCKOP_accept4
] = 4, /* sockfd, addr, addrlen, flags */
2340 [SOCKOP_getsockname
] = 3, /* sockfd, addr, addrlen */
2341 [SOCKOP_getpeername
] = 3, /* sockfd, addr, addrlen */
2342 [SOCKOP_socketpair
] = 4, /* domain, type, protocol, tab */
2343 [SOCKOP_send
] = 4, /* sockfd, msg, len, flags */
2344 [SOCKOP_recv
] = 4, /* sockfd, msg, len, flags */
2345 [SOCKOP_sendto
] = 6, /* sockfd, msg, len, flags, addr, addrlen */
2346 [SOCKOP_recvfrom
] = 6, /* sockfd, msg, len, flags, addr, addrlen */
2347 [SOCKOP_shutdown
] = 2, /* sockfd, how */
2348 [SOCKOP_sendmsg
] = 3, /* sockfd, msg, flags */
2349 [SOCKOP_recvmsg
] = 3, /* sockfd, msg, flags */
2350 [SOCKOP_setsockopt
] = 5, /* sockfd, level, optname, optval, optlen */
2351 [SOCKOP_getsockopt
] = 5, /* sockfd, level, optname, optval, optlen */
2353 abi_long a
[6]; /* max 6 args */
2355 /* first, collect the arguments in a[] according to ac[] */
2356 if (num
>= 0 && num
< ARRAY_SIZE(ac
)) {
2358 assert(ARRAY_SIZE(a
) >= ac
[num
]); /* ensure we have space for args */
2359 for (i
= 0; i
< ac
[num
]; ++i
) {
2360 if (get_user_ual(a
[i
], vptr
+ i
* sizeof(abi_long
)) != 0) {
2361 return -TARGET_EFAULT
;
2366 /* now when we have the args, actually handle the call */
2368 case SOCKOP_socket
: /* domain, type, protocol */
2369 return do_socket(a
[0], a
[1], a
[2]);
2370 case SOCKOP_bind
: /* sockfd, addr, addrlen */
2371 return do_bind(a
[0], a
[1], a
[2]);
2372 case SOCKOP_connect
: /* sockfd, addr, addrlen */
2373 return do_connect(a
[0], a
[1], a
[2]);
2374 case SOCKOP_listen
: /* sockfd, backlog */
2375 return get_errno(listen(a
[0], a
[1]));
2376 case SOCKOP_accept
: /* sockfd, addr, addrlen */
2377 return do_accept4(a
[0], a
[1], a
[2], 0);
2378 case SOCKOP_accept4
: /* sockfd, addr, addrlen, flags */
2379 return do_accept4(a
[0], a
[1], a
[2], a
[3]);
2380 case SOCKOP_getsockname
: /* sockfd, addr, addrlen */
2381 return do_getsockname(a
[0], a
[1], a
[2]);
2382 case SOCKOP_getpeername
: /* sockfd, addr, addrlen */
2383 return do_getpeername(a
[0], a
[1], a
[2]);
2384 case SOCKOP_socketpair
: /* domain, type, protocol, tab */
2385 return do_socketpair(a
[0], a
[1], a
[2], a
[3]);
2386 case SOCKOP_send
: /* sockfd, msg, len, flags */
2387 return do_sendto(a
[0], a
[1], a
[2], a
[3], 0, 0);
2388 case SOCKOP_recv
: /* sockfd, msg, len, flags */
2389 return do_recvfrom(a
[0], a
[1], a
[2], a
[3], 0, 0);
2390 case SOCKOP_sendto
: /* sockfd, msg, len, flags, addr, addrlen */
2391 return do_sendto(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
2392 case SOCKOP_recvfrom
: /* sockfd, msg, len, flags, addr, addrlen */
2393 return do_recvfrom(a
[0], a
[1], a
[2], a
[3], a
[4], a
[5]);
2394 case SOCKOP_shutdown
: /* sockfd, how */
2395 return get_errno(shutdown(a
[0], a
[1]));
2396 case SOCKOP_sendmsg
: /* sockfd, msg, flags */
2397 return do_sendrecvmsg(a
[0], a
[1], a
[2], 1);
2398 case SOCKOP_recvmsg
: /* sockfd, msg, flags */
2399 return do_sendrecvmsg(a
[0], a
[1], a
[2], 0);
2400 case SOCKOP_setsockopt
: /* sockfd, level, optname, optval, optlen */
2401 return do_setsockopt(a
[0], a
[1], a
[2], a
[3], a
[4]);
2402 case SOCKOP_getsockopt
: /* sockfd, level, optname, optval, optlen */
2403 return do_getsockopt(a
[0], a
[1], a
[2], a
[3], a
[4]);
2405 gemu_log("Unsupported socketcall: %d\n", num
);
2406 return -TARGET_ENOSYS
;
2411 #define N_SHM_REGIONS 32
2413 static struct shm_region
{
2416 } shm_regions
[N_SHM_REGIONS
];
2418 struct target_semid_ds
2420 struct target_ipc_perm sem_perm
;
2421 abi_ulong sem_otime
;
2422 abi_ulong __unused1
;
2423 abi_ulong sem_ctime
;
2424 abi_ulong __unused2
;
2425 abi_ulong sem_nsems
;
2426 abi_ulong __unused3
;
2427 abi_ulong __unused4
;
2430 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
2431 abi_ulong target_addr
)
2433 struct target_ipc_perm
*target_ip
;
2434 struct target_semid_ds
*target_sd
;
2436 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2437 return -TARGET_EFAULT
;
2438 target_ip
= &(target_sd
->sem_perm
);
2439 host_ip
->__key
= tswap32(target_ip
->__key
);
2440 host_ip
->uid
= tswap32(target_ip
->uid
);
2441 host_ip
->gid
= tswap32(target_ip
->gid
);
2442 host_ip
->cuid
= tswap32(target_ip
->cuid
);
2443 host_ip
->cgid
= tswap32(target_ip
->cgid
);
2444 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2445 host_ip
->mode
= tswap32(target_ip
->mode
);
2447 host_ip
->mode
= tswap16(target_ip
->mode
);
2449 #if defined(TARGET_PPC)
2450 host_ip
->__seq
= tswap32(target_ip
->__seq
);
2452 host_ip
->__seq
= tswap16(target_ip
->__seq
);
2454 unlock_user_struct(target_sd
, target_addr
, 0);
2458 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
2459 struct ipc_perm
*host_ip
)
2461 struct target_ipc_perm
*target_ip
;
2462 struct target_semid_ds
*target_sd
;
2464 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2465 return -TARGET_EFAULT
;
2466 target_ip
= &(target_sd
->sem_perm
);
2467 target_ip
->__key
= tswap32(host_ip
->__key
);
2468 target_ip
->uid
= tswap32(host_ip
->uid
);
2469 target_ip
->gid
= tswap32(host_ip
->gid
);
2470 target_ip
->cuid
= tswap32(host_ip
->cuid
);
2471 target_ip
->cgid
= tswap32(host_ip
->cgid
);
2472 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_PPC)
2473 target_ip
->mode
= tswap32(host_ip
->mode
);
2475 target_ip
->mode
= tswap16(host_ip
->mode
);
2477 #if defined(TARGET_PPC)
2478 target_ip
->__seq
= tswap32(host_ip
->__seq
);
2480 target_ip
->__seq
= tswap16(host_ip
->__seq
);
2482 unlock_user_struct(target_sd
, target_addr
, 1);
2486 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
2487 abi_ulong target_addr
)
2489 struct target_semid_ds
*target_sd
;
2491 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2492 return -TARGET_EFAULT
;
2493 if (target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
))
2494 return -TARGET_EFAULT
;
2495 host_sd
->sem_nsems
= tswapal(target_sd
->sem_nsems
);
2496 host_sd
->sem_otime
= tswapal(target_sd
->sem_otime
);
2497 host_sd
->sem_ctime
= tswapal(target_sd
->sem_ctime
);
2498 unlock_user_struct(target_sd
, target_addr
, 0);
2502 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
2503 struct semid_ds
*host_sd
)
2505 struct target_semid_ds
*target_sd
;
2507 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2508 return -TARGET_EFAULT
;
2509 if (host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
)))
2510 return -TARGET_EFAULT
;
2511 target_sd
->sem_nsems
= tswapal(host_sd
->sem_nsems
);
2512 target_sd
->sem_otime
= tswapal(host_sd
->sem_otime
);
2513 target_sd
->sem_ctime
= tswapal(host_sd
->sem_ctime
);
2514 unlock_user_struct(target_sd
, target_addr
, 1);
2518 struct target_seminfo
{
2531 static inline abi_long
host_to_target_seminfo(abi_ulong target_addr
,
2532 struct seminfo
*host_seminfo
)
2534 struct target_seminfo
*target_seminfo
;
2535 if (!lock_user_struct(VERIFY_WRITE
, target_seminfo
, target_addr
, 0))
2536 return -TARGET_EFAULT
;
2537 __put_user(host_seminfo
->semmap
, &target_seminfo
->semmap
);
2538 __put_user(host_seminfo
->semmni
, &target_seminfo
->semmni
);
2539 __put_user(host_seminfo
->semmns
, &target_seminfo
->semmns
);
2540 __put_user(host_seminfo
->semmnu
, &target_seminfo
->semmnu
);
2541 __put_user(host_seminfo
->semmsl
, &target_seminfo
->semmsl
);
2542 __put_user(host_seminfo
->semopm
, &target_seminfo
->semopm
);
2543 __put_user(host_seminfo
->semume
, &target_seminfo
->semume
);
2544 __put_user(host_seminfo
->semusz
, &target_seminfo
->semusz
);
2545 __put_user(host_seminfo
->semvmx
, &target_seminfo
->semvmx
);
2546 __put_user(host_seminfo
->semaem
, &target_seminfo
->semaem
);
2547 unlock_user_struct(target_seminfo
, target_addr
, 1);
2553 struct semid_ds
*buf
;
2554 unsigned short *array
;
2555 struct seminfo
*__buf
;
2558 union target_semun
{
2565 static inline abi_long
target_to_host_semarray(int semid
, unsigned short **host_array
,
2566 abi_ulong target_addr
)
2569 unsigned short *array
;
2571 struct semid_ds semid_ds
;
2574 semun
.buf
= &semid_ds
;
2576 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2578 return get_errno(ret
);
2580 nsems
= semid_ds
.sem_nsems
;
2582 *host_array
= malloc(nsems
*sizeof(unsigned short));
2584 return -TARGET_ENOMEM
;
2586 array
= lock_user(VERIFY_READ
, target_addr
,
2587 nsems
*sizeof(unsigned short), 1);
2590 return -TARGET_EFAULT
;
2593 for(i
=0; i
<nsems
; i
++) {
2594 __get_user((*host_array
)[i
], &array
[i
]);
2596 unlock_user(array
, target_addr
, 0);
2601 static inline abi_long
host_to_target_semarray(int semid
, abi_ulong target_addr
,
2602 unsigned short **host_array
)
2605 unsigned short *array
;
2607 struct semid_ds semid_ds
;
2610 semun
.buf
= &semid_ds
;
2612 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2614 return get_errno(ret
);
2616 nsems
= semid_ds
.sem_nsems
;
2618 array
= lock_user(VERIFY_WRITE
, target_addr
,
2619 nsems
*sizeof(unsigned short), 0);
2621 return -TARGET_EFAULT
;
2623 for(i
=0; i
<nsems
; i
++) {
2624 __put_user((*host_array
)[i
], &array
[i
]);
2627 unlock_user(array
, target_addr
, 1);
2632 static inline abi_long
do_semctl(int semid
, int semnum
, int cmd
,
2633 union target_semun target_su
)
2636 struct semid_ds dsarg
;
2637 unsigned short *array
= NULL
;
2638 struct seminfo seminfo
;
2639 abi_long ret
= -TARGET_EINVAL
;
2646 arg
.val
= tswap32(target_su
.val
);
2647 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2648 target_su
.val
= tswap32(arg
.val
);
2652 err
= target_to_host_semarray(semid
, &array
, target_su
.array
);
2656 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2657 err
= host_to_target_semarray(semid
, target_su
.array
, &array
);
2664 err
= target_to_host_semid_ds(&dsarg
, target_su
.buf
);
2668 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2669 err
= host_to_target_semid_ds(target_su
.buf
, &dsarg
);
2675 arg
.__buf
= &seminfo
;
2676 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2677 err
= host_to_target_seminfo(target_su
.__buf
, &seminfo
);
2685 ret
= get_errno(semctl(semid
, semnum
, cmd
, NULL
));
2692 struct target_sembuf
{
2693 unsigned short sem_num
;
2698 static inline abi_long
target_to_host_sembuf(struct sembuf
*host_sembuf
,
2699 abi_ulong target_addr
,
2702 struct target_sembuf
*target_sembuf
;
2705 target_sembuf
= lock_user(VERIFY_READ
, target_addr
,
2706 nsops
*sizeof(struct target_sembuf
), 1);
2708 return -TARGET_EFAULT
;
2710 for(i
=0; i
<nsops
; i
++) {
2711 __get_user(host_sembuf
[i
].sem_num
, &target_sembuf
[i
].sem_num
);
2712 __get_user(host_sembuf
[i
].sem_op
, &target_sembuf
[i
].sem_op
);
2713 __get_user(host_sembuf
[i
].sem_flg
, &target_sembuf
[i
].sem_flg
);
2716 unlock_user(target_sembuf
, target_addr
, 0);
2721 static inline abi_long
do_semop(int semid
, abi_long ptr
, unsigned nsops
)
2723 struct sembuf sops
[nsops
];
2725 if (target_to_host_sembuf(sops
, ptr
, nsops
))
2726 return -TARGET_EFAULT
;
2728 return get_errno(semop(semid
, sops
, nsops
));
2731 struct target_msqid_ds
2733 struct target_ipc_perm msg_perm
;
2734 abi_ulong msg_stime
;
2735 #if TARGET_ABI_BITS == 32
2736 abi_ulong __unused1
;
2738 abi_ulong msg_rtime
;
2739 #if TARGET_ABI_BITS == 32
2740 abi_ulong __unused2
;
2742 abi_ulong msg_ctime
;
2743 #if TARGET_ABI_BITS == 32
2744 abi_ulong __unused3
;
2746 abi_ulong __msg_cbytes
;
2748 abi_ulong msg_qbytes
;
2749 abi_ulong msg_lspid
;
2750 abi_ulong msg_lrpid
;
2751 abi_ulong __unused4
;
2752 abi_ulong __unused5
;
2755 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
2756 abi_ulong target_addr
)
2758 struct target_msqid_ds
*target_md
;
2760 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
2761 return -TARGET_EFAULT
;
2762 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
2763 return -TARGET_EFAULT
;
2764 host_md
->msg_stime
= tswapal(target_md
->msg_stime
);
2765 host_md
->msg_rtime
= tswapal(target_md
->msg_rtime
);
2766 host_md
->msg_ctime
= tswapal(target_md
->msg_ctime
);
2767 host_md
->__msg_cbytes
= tswapal(target_md
->__msg_cbytes
);
2768 host_md
->msg_qnum
= tswapal(target_md
->msg_qnum
);
2769 host_md
->msg_qbytes
= tswapal(target_md
->msg_qbytes
);
2770 host_md
->msg_lspid
= tswapal(target_md
->msg_lspid
);
2771 host_md
->msg_lrpid
= tswapal(target_md
->msg_lrpid
);
2772 unlock_user_struct(target_md
, target_addr
, 0);
2776 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
2777 struct msqid_ds
*host_md
)
2779 struct target_msqid_ds
*target_md
;
2781 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
2782 return -TARGET_EFAULT
;
2783 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
2784 return -TARGET_EFAULT
;
2785 target_md
->msg_stime
= tswapal(host_md
->msg_stime
);
2786 target_md
->msg_rtime
= tswapal(host_md
->msg_rtime
);
2787 target_md
->msg_ctime
= tswapal(host_md
->msg_ctime
);
2788 target_md
->__msg_cbytes
= tswapal(host_md
->__msg_cbytes
);
2789 target_md
->msg_qnum
= tswapal(host_md
->msg_qnum
);
2790 target_md
->msg_qbytes
= tswapal(host_md
->msg_qbytes
);
2791 target_md
->msg_lspid
= tswapal(host_md
->msg_lspid
);
2792 target_md
->msg_lrpid
= tswapal(host_md
->msg_lrpid
);
2793 unlock_user_struct(target_md
, target_addr
, 1);
2797 struct target_msginfo
{
2805 unsigned short int msgseg
;
2808 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
2809 struct msginfo
*host_msginfo
)
2811 struct target_msginfo
*target_msginfo
;
2812 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
2813 return -TARGET_EFAULT
;
2814 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
2815 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
2816 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
2817 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
2818 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
2819 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
2820 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
2821 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
2822 unlock_user_struct(target_msginfo
, target_addr
, 1);
2826 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
2828 struct msqid_ds dsarg
;
2829 struct msginfo msginfo
;
2830 abi_long ret
= -TARGET_EINVAL
;
2838 if (target_to_host_msqid_ds(&dsarg
,ptr
))
2839 return -TARGET_EFAULT
;
2840 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
2841 if (host_to_target_msqid_ds(ptr
,&dsarg
))
2842 return -TARGET_EFAULT
;
2845 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2849 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2850 if (host_to_target_msginfo(ptr
, &msginfo
))
2851 return -TARGET_EFAULT
;
2858 struct target_msgbuf
{
2863 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2864 unsigned int msgsz
, int msgflg
)
2866 struct target_msgbuf
*target_mb
;
2867 struct msgbuf
*host_mb
;
2870 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2871 return -TARGET_EFAULT
;
2872 host_mb
= malloc(msgsz
+sizeof(long));
2873 host_mb
->mtype
= (abi_long
) tswapal(target_mb
->mtype
);
2874 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2875 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2877 unlock_user_struct(target_mb
, msgp
, 0);
2882 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2883 unsigned int msgsz
, abi_long msgtyp
,
2886 struct target_msgbuf
*target_mb
;
2888 struct msgbuf
*host_mb
;
2891 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2892 return -TARGET_EFAULT
;
2894 host_mb
= g_malloc(msgsz
+sizeof(long));
2895 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, msgtyp
, msgflg
));
2898 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2899 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2900 if (!target_mtext
) {
2901 ret
= -TARGET_EFAULT
;
2904 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2905 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2908 target_mb
->mtype
= tswapal(host_mb
->mtype
);
2912 unlock_user_struct(target_mb
, msgp
, 1);
2917 static inline abi_long
target_to_host_shmid_ds(struct shmid_ds
*host_sd
,
2918 abi_ulong target_addr
)
2920 struct target_shmid_ds
*target_sd
;
2922 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2923 return -TARGET_EFAULT
;
2924 if (target_to_host_ipc_perm(&(host_sd
->shm_perm
), target_addr
))
2925 return -TARGET_EFAULT
;
2926 __get_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2927 __get_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2928 __get_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2929 __get_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2930 __get_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2931 __get_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2932 __get_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2933 unlock_user_struct(target_sd
, target_addr
, 0);
2937 static inline abi_long
host_to_target_shmid_ds(abi_ulong target_addr
,
2938 struct shmid_ds
*host_sd
)
2940 struct target_shmid_ds
*target_sd
;
2942 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2943 return -TARGET_EFAULT
;
2944 if (host_to_target_ipc_perm(target_addr
, &(host_sd
->shm_perm
)))
2945 return -TARGET_EFAULT
;
2946 __put_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2947 __put_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2948 __put_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2949 __put_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2950 __put_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2951 __put_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2952 __put_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2953 unlock_user_struct(target_sd
, target_addr
, 1);
2957 struct target_shminfo
{
2965 static inline abi_long
host_to_target_shminfo(abi_ulong target_addr
,
2966 struct shminfo
*host_shminfo
)
2968 struct target_shminfo
*target_shminfo
;
2969 if (!lock_user_struct(VERIFY_WRITE
, target_shminfo
, target_addr
, 0))
2970 return -TARGET_EFAULT
;
2971 __put_user(host_shminfo
->shmmax
, &target_shminfo
->shmmax
);
2972 __put_user(host_shminfo
->shmmin
, &target_shminfo
->shmmin
);
2973 __put_user(host_shminfo
->shmmni
, &target_shminfo
->shmmni
);
2974 __put_user(host_shminfo
->shmseg
, &target_shminfo
->shmseg
);
2975 __put_user(host_shminfo
->shmall
, &target_shminfo
->shmall
);
2976 unlock_user_struct(target_shminfo
, target_addr
, 1);
2980 struct target_shm_info
{
2985 abi_ulong swap_attempts
;
2986 abi_ulong swap_successes
;
2989 static inline abi_long
host_to_target_shm_info(abi_ulong target_addr
,
2990 struct shm_info
*host_shm_info
)
2992 struct target_shm_info
*target_shm_info
;
2993 if (!lock_user_struct(VERIFY_WRITE
, target_shm_info
, target_addr
, 0))
2994 return -TARGET_EFAULT
;
2995 __put_user(host_shm_info
->used_ids
, &target_shm_info
->used_ids
);
2996 __put_user(host_shm_info
->shm_tot
, &target_shm_info
->shm_tot
);
2997 __put_user(host_shm_info
->shm_rss
, &target_shm_info
->shm_rss
);
2998 __put_user(host_shm_info
->shm_swp
, &target_shm_info
->shm_swp
);
2999 __put_user(host_shm_info
->swap_attempts
, &target_shm_info
->swap_attempts
);
3000 __put_user(host_shm_info
->swap_successes
, &target_shm_info
->swap_successes
);
3001 unlock_user_struct(target_shm_info
, target_addr
, 1);
3005 static inline abi_long
do_shmctl(int shmid
, int cmd
, abi_long buf
)
3007 struct shmid_ds dsarg
;
3008 struct shminfo shminfo
;
3009 struct shm_info shm_info
;
3010 abi_long ret
= -TARGET_EINVAL
;
3018 if (target_to_host_shmid_ds(&dsarg
, buf
))
3019 return -TARGET_EFAULT
;
3020 ret
= get_errno(shmctl(shmid
, cmd
, &dsarg
));
3021 if (host_to_target_shmid_ds(buf
, &dsarg
))
3022 return -TARGET_EFAULT
;
3025 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shminfo
));
3026 if (host_to_target_shminfo(buf
, &shminfo
))
3027 return -TARGET_EFAULT
;
3030 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shm_info
));
3031 if (host_to_target_shm_info(buf
, &shm_info
))
3032 return -TARGET_EFAULT
;
3037 ret
= get_errno(shmctl(shmid
, cmd
, NULL
));
3044 static inline abi_ulong
do_shmat(int shmid
, abi_ulong shmaddr
, int shmflg
)
3048 struct shmid_ds shm_info
;
3051 /* find out the length of the shared memory segment */
3052 ret
= get_errno(shmctl(shmid
, IPC_STAT
, &shm_info
));
3053 if (is_error(ret
)) {
3054 /* can't get length, bail out */
3061 host_raddr
= shmat(shmid
, (void *)g2h(shmaddr
), shmflg
);
3063 abi_ulong mmap_start
;
3065 mmap_start
= mmap_find_vma(0, shm_info
.shm_segsz
);
3067 if (mmap_start
== -1) {
3069 host_raddr
= (void *)-1;
3071 host_raddr
= shmat(shmid
, g2h(mmap_start
), shmflg
| SHM_REMAP
);
3074 if (host_raddr
== (void *)-1) {
3076 return get_errno((long)host_raddr
);
3078 raddr
=h2g((unsigned long)host_raddr
);
3080 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
3081 PAGE_VALID
| PAGE_READ
|
3082 ((shmflg
& SHM_RDONLY
)?
0 : PAGE_WRITE
));
3084 for (i
= 0; i
< N_SHM_REGIONS
; i
++) {
3085 if (shm_regions
[i
].start
== 0) {
3086 shm_regions
[i
].start
= raddr
;
3087 shm_regions
[i
].size
= shm_info
.shm_segsz
;
3097 static inline abi_long
do_shmdt(abi_ulong shmaddr
)
3101 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
3102 if (shm_regions
[i
].start
== shmaddr
) {
3103 shm_regions
[i
].start
= 0;
3104 page_set_flags(shmaddr
, shmaddr
+ shm_regions
[i
].size
, 0);
3109 return get_errno(shmdt(g2h(shmaddr
)));
3112 #ifdef TARGET_NR_ipc
3113 /* ??? This only works with linear mappings. */
3114 /* do_ipc() must return target values and target errnos. */
3115 static abi_long
do_ipc(unsigned int call
, int first
,
3116 int second
, int third
,
3117 abi_long ptr
, abi_long fifth
)
3122 version
= call
>> 16;
3127 ret
= do_semop(first
, ptr
, second
);
3131 ret
= get_errno(semget(first
, second
, third
));
3135 ret
= do_semctl(first
, second
, third
, (union target_semun
)(abi_ulong
) ptr
);
3139 ret
= get_errno(msgget(first
, second
));
3143 ret
= do_msgsnd(first
, ptr
, second
, third
);
3147 ret
= do_msgctl(first
, second
, ptr
);
3154 struct target_ipc_kludge
{
3159 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
3160 ret
= -TARGET_EFAULT
;
3164 ret
= do_msgrcv(first
, tswapal(tmp
->msgp
), second
, tswapal(tmp
->msgtyp
), third
);
3166 unlock_user_struct(tmp
, ptr
, 0);
3170 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
3179 raddr
= do_shmat(first
, ptr
, second
);
3180 if (is_error(raddr
))
3181 return get_errno(raddr
);
3182 if (put_user_ual(raddr
, third
))
3183 return -TARGET_EFAULT
;
3187 ret
= -TARGET_EINVAL
;
3192 ret
= do_shmdt(ptr
);
3196 /* IPC_* flag values are the same on all linux platforms */
3197 ret
= get_errno(shmget(first
, second
, third
));
3200 /* IPC_* and SHM_* command values are the same on all linux platforms */
3202 ret
= do_shmctl(first
, second
, ptr
);
3205 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
3206 ret
= -TARGET_ENOSYS
;
3213 /* kernel structure types definitions */
3215 #define STRUCT(name, ...) STRUCT_ ## name,
3216 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
3218 #include "syscall_types.h"
3221 #undef STRUCT_SPECIAL
3223 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3224 #define STRUCT_SPECIAL(name)
3225 #include "syscall_types.h"
3227 #undef STRUCT_SPECIAL
3229 typedef struct IOCTLEntry IOCTLEntry
;
3231 typedef abi_long
do_ioctl_fn(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3232 int fd
, abi_long cmd
, abi_long arg
);
3235 unsigned int target_cmd
;
3236 unsigned int host_cmd
;
3239 do_ioctl_fn
*do_ioctl
;
3240 const argtype arg_type
[5];
3243 #define IOC_R 0x0001
3244 #define IOC_W 0x0002
3245 #define IOC_RW (IOC_R | IOC_W)
3247 #define MAX_STRUCT_SIZE 4096
3249 #ifdef CONFIG_FIEMAP
3250 /* So fiemap access checks don't overflow on 32 bit systems.
3251 * This is very slightly smaller than the limit imposed by
3252 * the underlying kernel.
3254 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3255 / sizeof(struct fiemap_extent))
3257 static abi_long
do_ioctl_fs_ioc_fiemap(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3258 int fd
, abi_long cmd
, abi_long arg
)
3260 /* The parameter for this ioctl is a struct fiemap followed
3261 * by an array of struct fiemap_extent whose size is set
3262 * in fiemap->fm_extent_count. The array is filled in by the
3265 int target_size_in
, target_size_out
;
3267 const argtype
*arg_type
= ie
->arg_type
;
3268 const argtype extent_arg_type
[] = { MK_STRUCT(STRUCT_fiemap_extent
) };
3271 int i
, extent_size
= thunk_type_size(extent_arg_type
, 0);
3275 assert(arg_type
[0] == TYPE_PTR
);
3276 assert(ie
->access
== IOC_RW
);
3278 target_size_in
= thunk_type_size(arg_type
, 0);
3279 argptr
= lock_user(VERIFY_READ
, arg
, target_size_in
, 1);
3281 return -TARGET_EFAULT
;
3283 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3284 unlock_user(argptr
, arg
, 0);
3285 fm
= (struct fiemap
*)buf_temp
;
3286 if (fm
->fm_extent_count
> FIEMAP_MAX_EXTENTS
) {
3287 return -TARGET_EINVAL
;
3290 outbufsz
= sizeof (*fm
) +
3291 (sizeof(struct fiemap_extent
) * fm
->fm_extent_count
);
3293 if (outbufsz
> MAX_STRUCT_SIZE
) {
3294 /* We can't fit all the extents into the fixed size buffer.
3295 * Allocate one that is large enough and use it instead.
3297 fm
= malloc(outbufsz
);
3299 return -TARGET_ENOMEM
;
3301 memcpy(fm
, buf_temp
, sizeof(struct fiemap
));
3304 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, fm
));
3305 if (!is_error(ret
)) {
3306 target_size_out
= target_size_in
;
3307 /* An extent_count of 0 means we were only counting the extents
3308 * so there are no structs to copy
3310 if (fm
->fm_extent_count
!= 0) {
3311 target_size_out
+= fm
->fm_mapped_extents
* extent_size
;
3313 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size_out
, 0);
3315 ret
= -TARGET_EFAULT
;
3317 /* Convert the struct fiemap */
3318 thunk_convert(argptr
, fm
, arg_type
, THUNK_TARGET
);
3319 if (fm
->fm_extent_count
!= 0) {
3320 p
= argptr
+ target_size_in
;
3321 /* ...and then all the struct fiemap_extents */
3322 for (i
= 0; i
< fm
->fm_mapped_extents
; i
++) {
3323 thunk_convert(p
, &fm
->fm_extents
[i
], extent_arg_type
,
3328 unlock_user(argptr
, arg
, target_size_out
);
3338 static abi_long
do_ioctl_ifconf(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3339 int fd
, abi_long cmd
, abi_long arg
)
3341 const argtype
*arg_type
= ie
->arg_type
;
3345 struct ifconf
*host_ifconf
;
3347 const argtype ifreq_arg_type
[] = { MK_STRUCT(STRUCT_sockaddr_ifreq
) };
3348 int target_ifreq_size
;
3353 abi_long target_ifc_buf
;
3357 assert(arg_type
[0] == TYPE_PTR
);
3358 assert(ie
->access
== IOC_RW
);
3361 target_size
= thunk_type_size(arg_type
, 0);
3363 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3365 return -TARGET_EFAULT
;
3366 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3367 unlock_user(argptr
, arg
, 0);
3369 host_ifconf
= (struct ifconf
*)(unsigned long)buf_temp
;
3370 target_ifc_len
= host_ifconf
->ifc_len
;
3371 target_ifc_buf
= (abi_long
)(unsigned long)host_ifconf
->ifc_buf
;
3373 target_ifreq_size
= thunk_type_size(ifreq_arg_type
, 0);
3374 nb_ifreq
= target_ifc_len
/ target_ifreq_size
;
3375 host_ifc_len
= nb_ifreq
* sizeof(struct ifreq
);
3377 outbufsz
= sizeof(*host_ifconf
) + host_ifc_len
;
3378 if (outbufsz
> MAX_STRUCT_SIZE
) {
3379 /* We can't fit all the extents into the fixed size buffer.
3380 * Allocate one that is large enough and use it instead.
3382 host_ifconf
= malloc(outbufsz
);
3384 return -TARGET_ENOMEM
;
3386 memcpy(host_ifconf
, buf_temp
, sizeof(*host_ifconf
));
3389 host_ifc_buf
= (char*)host_ifconf
+ sizeof(*host_ifconf
);
3391 host_ifconf
->ifc_len
= host_ifc_len
;
3392 host_ifconf
->ifc_buf
= host_ifc_buf
;
3394 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, host_ifconf
));
3395 if (!is_error(ret
)) {
3396 /* convert host ifc_len to target ifc_len */
3398 nb_ifreq
= host_ifconf
->ifc_len
/ sizeof(struct ifreq
);
3399 target_ifc_len
= nb_ifreq
* target_ifreq_size
;
3400 host_ifconf
->ifc_len
= target_ifc_len
;
3402 /* restore target ifc_buf */
3404 host_ifconf
->ifc_buf
= (char *)(unsigned long)target_ifc_buf
;
3406 /* copy struct ifconf to target user */
3408 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3410 return -TARGET_EFAULT
;
3411 thunk_convert(argptr
, host_ifconf
, arg_type
, THUNK_TARGET
);
3412 unlock_user(argptr
, arg
, target_size
);
3414 /* copy ifreq[] to target user */
3416 argptr
= lock_user(VERIFY_WRITE
, target_ifc_buf
, target_ifc_len
, 0);
3417 for (i
= 0; i
< nb_ifreq
; i
++) {
3418 thunk_convert(argptr
+ i
* target_ifreq_size
,
3419 host_ifc_buf
+ i
* sizeof(struct ifreq
),
3420 ifreq_arg_type
, THUNK_TARGET
);
3422 unlock_user(argptr
, target_ifc_buf
, target_ifc_len
);
3432 static abi_long
do_ioctl_dm(const IOCTLEntry
*ie
, uint8_t *buf_temp
, int fd
,
3433 abi_long cmd
, abi_long arg
)
3436 struct dm_ioctl
*host_dm
;
3437 abi_long guest_data
;
3438 uint32_t guest_data_size
;
3440 const argtype
*arg_type
= ie
->arg_type
;
3442 void *big_buf
= NULL
;
3446 target_size
= thunk_type_size(arg_type
, 0);
3447 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3449 ret
= -TARGET_EFAULT
;
3452 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3453 unlock_user(argptr
, arg
, 0);
3455 /* buf_temp is too small, so fetch things into a bigger buffer */
3456 big_buf
= g_malloc0(((struct dm_ioctl
*)buf_temp
)->data_size
* 2);
3457 memcpy(big_buf
, buf_temp
, target_size
);
3461 guest_data
= arg
+ host_dm
->data_start
;
3462 if ((guest_data
- arg
) < 0) {
3466 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3467 host_data
= (char*)host_dm
+ host_dm
->data_start
;
3469 argptr
= lock_user(VERIFY_READ
, guest_data
, guest_data_size
, 1);
3470 switch (ie
->host_cmd
) {
3472 case DM_LIST_DEVICES
:
3475 case DM_DEV_SUSPEND
:
3478 case DM_TABLE_STATUS
:
3479 case DM_TABLE_CLEAR
:
3481 case DM_LIST_VERSIONS
:
3485 case DM_DEV_SET_GEOMETRY
:
3486 /* data contains only strings */
3487 memcpy(host_data
, argptr
, guest_data_size
);
3490 memcpy(host_data
, argptr
, guest_data_size
);
3491 *(uint64_t*)host_data
= tswap64(*(uint64_t*)argptr
);
3495 void *gspec
= argptr
;
3496 void *cur_data
= host_data
;
3497 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3498 int spec_size
= thunk_type_size(arg_type
, 0);
3501 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3502 struct dm_target_spec
*spec
= cur_data
;
3506 thunk_convert(spec
, gspec
, arg_type
, THUNK_HOST
);
3507 slen
= strlen((char*)gspec
+ spec_size
) + 1;
3509 spec
->next
= sizeof(*spec
) + slen
;
3510 strcpy((char*)&spec
[1], gspec
+ spec_size
);
3512 cur_data
+= spec
->next
;
3517 ret
= -TARGET_EINVAL
;
3520 unlock_user(argptr
, guest_data
, 0);
3522 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3523 if (!is_error(ret
)) {
3524 guest_data
= arg
+ host_dm
->data_start
;
3525 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3526 argptr
= lock_user(VERIFY_WRITE
, guest_data
, guest_data_size
, 0);
3527 switch (ie
->host_cmd
) {
3532 case DM_DEV_SUSPEND
:
3535 case DM_TABLE_CLEAR
:
3537 case DM_DEV_SET_GEOMETRY
:
3538 /* no return data */
3540 case DM_LIST_DEVICES
:
3542 struct dm_name_list
*nl
= (void*)host_dm
+ host_dm
->data_start
;
3543 uint32_t remaining_data
= guest_data_size
;
3544 void *cur_data
= argptr
;
3545 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_name_list
) };
3546 int nl_size
= 12; /* can't use thunk_size due to alignment */
3549 uint32_t next
= nl
->next
;
3551 nl
->next
= nl_size
+ (strlen(nl
->name
) + 1);
3553 if (remaining_data
< nl
->next
) {
3554 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3557 thunk_convert(cur_data
, nl
, arg_type
, THUNK_TARGET
);
3558 strcpy(cur_data
+ nl_size
, nl
->name
);
3559 cur_data
+= nl
->next
;
3560 remaining_data
-= nl
->next
;
3564 nl
= (void*)nl
+ next
;
3569 case DM_TABLE_STATUS
:
3571 struct dm_target_spec
*spec
= (void*)host_dm
+ host_dm
->data_start
;
3572 void *cur_data
= argptr
;
3573 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3574 int spec_size
= thunk_type_size(arg_type
, 0);
3577 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3578 uint32_t next
= spec
->next
;
3579 int slen
= strlen((char*)&spec
[1]) + 1;
3580 spec
->next
= (cur_data
- argptr
) + spec_size
+ slen
;
3581 if (guest_data_size
< spec
->next
) {
3582 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3585 thunk_convert(cur_data
, spec
, arg_type
, THUNK_TARGET
);
3586 strcpy(cur_data
+ spec_size
, (char*)&spec
[1]);
3587 cur_data
= argptr
+ spec
->next
;
3588 spec
= (void*)host_dm
+ host_dm
->data_start
+ next
;
3594 void *hdata
= (void*)host_dm
+ host_dm
->data_start
;
3595 int count
= *(uint32_t*)hdata
;
3596 uint64_t *hdev
= hdata
+ 8;
3597 uint64_t *gdev
= argptr
+ 8;
3600 *(uint32_t*)argptr
= tswap32(count
);
3601 for (i
= 0; i
< count
; i
++) {
3602 *gdev
= tswap64(*hdev
);
3608 case DM_LIST_VERSIONS
:
3610 struct dm_target_versions
*vers
= (void*)host_dm
+ host_dm
->data_start
;
3611 uint32_t remaining_data
= guest_data_size
;
3612 void *cur_data
= argptr
;
3613 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_versions
) };
3614 int vers_size
= thunk_type_size(arg_type
, 0);
3617 uint32_t next
= vers
->next
;
3619 vers
->next
= vers_size
+ (strlen(vers
->name
) + 1);
3621 if (remaining_data
< vers
->next
) {
3622 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3625 thunk_convert(cur_data
, vers
, arg_type
, THUNK_TARGET
);
3626 strcpy(cur_data
+ vers_size
, vers
->name
);
3627 cur_data
+= vers
->next
;
3628 remaining_data
-= vers
->next
;
3632 vers
= (void*)vers
+ next
;
3637 ret
= -TARGET_EINVAL
;
3640 unlock_user(argptr
, guest_data
, guest_data_size
);
3642 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3644 ret
= -TARGET_EFAULT
;
3647 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3648 unlock_user(argptr
, arg
, target_size
);
3655 static abi_long
do_ioctl_rt(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3656 int fd
, abi_long cmd
, abi_long arg
)
3658 const argtype
*arg_type
= ie
->arg_type
;
3659 const StructEntry
*se
;
3660 const argtype
*field_types
;
3661 const int *dst_offsets
, *src_offsets
;
3664 abi_ulong
*target_rt_dev_ptr
;
3665 unsigned long *host_rt_dev_ptr
;
3669 assert(ie
->access
== IOC_W
);
3670 assert(*arg_type
== TYPE_PTR
);
3672 assert(*arg_type
== TYPE_STRUCT
);
3673 target_size
= thunk_type_size(arg_type
, 0);
3674 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3676 return -TARGET_EFAULT
;
3679 assert(*arg_type
== (int)STRUCT_rtentry
);
3680 se
= struct_entries
+ *arg_type
++;
3681 assert(se
->convert
[0] == NULL
);
3682 /* convert struct here to be able to catch rt_dev string */
3683 field_types
= se
->field_types
;
3684 dst_offsets
= se
->field_offsets
[THUNK_HOST
];
3685 src_offsets
= se
->field_offsets
[THUNK_TARGET
];
3686 for (i
= 0; i
< se
->nb_fields
; i
++) {
3687 if (dst_offsets
[i
] == offsetof(struct rtentry
, rt_dev
)) {
3688 assert(*field_types
== TYPE_PTRVOID
);
3689 target_rt_dev_ptr
= (abi_ulong
*)(argptr
+ src_offsets
[i
]);
3690 host_rt_dev_ptr
= (unsigned long *)(buf_temp
+ dst_offsets
[i
]);
3691 if (*target_rt_dev_ptr
!= 0) {
3692 *host_rt_dev_ptr
= (unsigned long)lock_user_string(
3693 tswapal(*target_rt_dev_ptr
));
3694 if (!*host_rt_dev_ptr
) {
3695 unlock_user(argptr
, arg
, 0);
3696 return -TARGET_EFAULT
;
3699 *host_rt_dev_ptr
= 0;
3704 field_types
= thunk_convert(buf_temp
+ dst_offsets
[i
],
<