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_loop.h"
109 #include "cpu-uname.h"
113 #if defined(CONFIG_USE_NPTL)
114 #define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
115 CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
117 /* XXX: Hardcode the above values. */
118 #define CLONE_NPTL_FLAGS2 0
123 //#include <linux/msdos_fs.h>
124 #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
125 #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
136 #define _syscall0(type,name) \
137 static type name (void) \
139 return syscall(__NR_##name); \
142 #define _syscall1(type,name,type1,arg1) \
143 static type name (type1 arg1) \
145 return syscall(__NR_##name, arg1); \
148 #define _syscall2(type,name,type1,arg1,type2,arg2) \
149 static type name (type1 arg1,type2 arg2) \
151 return syscall(__NR_##name, arg1, arg2); \
154 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
155 static type name (type1 arg1,type2 arg2,type3 arg3) \
157 return syscall(__NR_##name, arg1, arg2, arg3); \
160 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
161 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
163 return syscall(__NR_##name, arg1, arg2, arg3, arg4); \
166 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
168 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
170 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5); \
174 #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
175 type5,arg5,type6,arg6) \
176 static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
179 return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6); \
183 #define __NR_sys_uname __NR_uname
184 #define __NR_sys_getcwd1 __NR_getcwd
185 #define __NR_sys_getdents __NR_getdents
186 #define __NR_sys_getdents64 __NR_getdents64
187 #define __NR_sys_getpriority __NR_getpriority
188 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
189 #define __NR_sys_syslog __NR_syslog
190 #define __NR_sys_tgkill __NR_tgkill
191 #define __NR_sys_tkill __NR_tkill
192 #define __NR_sys_futex __NR_futex
193 #define __NR_sys_inotify_init __NR_inotify_init
194 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
195 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
197 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
199 #define __NR__llseek __NR_lseek
203 _syscall0(int, gettid
)
205 /* This is a replacement for the host gettid() and must return a host
207 static int gettid(void) {
212 _syscall3(int, sys_getdents
, uint
, fd
, struct linux_dirent
*, dirp
, uint
, count
);
214 #if !defined(__NR_getdents) || \
215 (defined(TARGET_NR_getdents64) && defined(__NR_getdents64))
216 _syscall3(int, sys_getdents64
, uint
, fd
, struct linux_dirent64
*, dirp
, uint
, count
);
218 #if defined(TARGET_NR__llseek) && defined(__NR_llseek)
219 _syscall5(int, _llseek
, uint
, fd
, ulong
, hi
, ulong
, lo
,
220 loff_t
*, res
, uint
, wh
);
222 _syscall3(int,sys_rt_sigqueueinfo
,int,pid
,int,sig
,siginfo_t
*,uinfo
)
223 _syscall3(int,sys_syslog
,int,type
,char*,bufp
,int,len
)
224 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
225 _syscall3(int,sys_tgkill
,int,tgid
,int,pid
,int,sig
)
227 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
228 _syscall2(int,sys_tkill
,int,tid
,int,sig
)
230 #ifdef __NR_exit_group
231 _syscall1(int,exit_group
,int,error_code
)
233 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
234 _syscall1(int,set_tid_address
,int *,tidptr
)
236 #if defined(CONFIG_USE_NPTL)
237 #if defined(TARGET_NR_futex) && defined(__NR_futex)
238 _syscall6(int,sys_futex
,int *,uaddr
,int,op
,int,val
,
239 const struct timespec
*,timeout
,int *,uaddr2
,int,val3
)
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
,
251 static bitmask_transtbl fcntl_flags_tbl
[] = {
252 { TARGET_O_ACCMODE
, TARGET_O_WRONLY
, O_ACCMODE
, O_WRONLY
, },
253 { TARGET_O_ACCMODE
, TARGET_O_RDWR
, O_ACCMODE
, O_RDWR
, },
254 { TARGET_O_CREAT
, TARGET_O_CREAT
, O_CREAT
, O_CREAT
, },
255 { TARGET_O_EXCL
, TARGET_O_EXCL
, O_EXCL
, O_EXCL
, },
256 { TARGET_O_NOCTTY
, TARGET_O_NOCTTY
, O_NOCTTY
, O_NOCTTY
, },
257 { TARGET_O_TRUNC
, TARGET_O_TRUNC
, O_TRUNC
, O_TRUNC
, },
258 { TARGET_O_APPEND
, TARGET_O_APPEND
, O_APPEND
, O_APPEND
, },
259 { TARGET_O_NONBLOCK
, TARGET_O_NONBLOCK
, O_NONBLOCK
, O_NONBLOCK
, },
260 { TARGET_O_SYNC
, TARGET_O_DSYNC
, O_SYNC
, O_DSYNC
, },
261 { TARGET_O_SYNC
, TARGET_O_SYNC
, O_SYNC
, O_SYNC
, },
262 { TARGET_FASYNC
, TARGET_FASYNC
, FASYNC
, FASYNC
, },
263 { TARGET_O_DIRECTORY
, TARGET_O_DIRECTORY
, O_DIRECTORY
, O_DIRECTORY
, },
264 { TARGET_O_NOFOLLOW
, TARGET_O_NOFOLLOW
, O_NOFOLLOW
, O_NOFOLLOW
, },
265 #if defined(O_DIRECT)
266 { TARGET_O_DIRECT
, TARGET_O_DIRECT
, O_DIRECT
, O_DIRECT
, },
268 #if defined(O_NOATIME)
269 { TARGET_O_NOATIME
, TARGET_O_NOATIME
, O_NOATIME
, O_NOATIME
},
271 #if defined(O_CLOEXEC)
272 { TARGET_O_CLOEXEC
, TARGET_O_CLOEXEC
, O_CLOEXEC
, O_CLOEXEC
},
275 { TARGET_O_PATH
, TARGET_O_PATH
, O_PATH
, O_PATH
},
277 /* Don't terminate the list prematurely on 64-bit host+guest. */
278 #if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
279 { TARGET_O_LARGEFILE
, TARGET_O_LARGEFILE
, O_LARGEFILE
, O_LARGEFILE
, },
284 #define COPY_UTSNAME_FIELD(dest, src) \
286 /* __NEW_UTS_LEN doesn't include terminating null */ \
287 (void) strncpy((dest), (src), __NEW_UTS_LEN); \
288 (dest)[__NEW_UTS_LEN] = '\0'; \
291 static int sys_uname(struct new_utsname
*buf
)
293 struct utsname uts_buf
;
295 if (uname(&uts_buf
) < 0)
299 * Just in case these have some differences, we
300 * translate utsname to new_utsname (which is the
301 * struct linux kernel uses).
304 memset(buf
, 0, sizeof(*buf
));
305 COPY_UTSNAME_FIELD(buf
->sysname
, uts_buf
.sysname
);
306 COPY_UTSNAME_FIELD(buf
->nodename
, uts_buf
.nodename
);
307 COPY_UTSNAME_FIELD(buf
->release
, uts_buf
.release
);
308 COPY_UTSNAME_FIELD(buf
->version
, uts_buf
.version
);
309 COPY_UTSNAME_FIELD(buf
->machine
, uts_buf
.machine
);
311 COPY_UTSNAME_FIELD(buf
->domainname
, uts_buf
.domainname
);
315 #undef COPY_UTSNAME_FIELD
318 static int sys_getcwd1(char *buf
, size_t size
)
320 if (getcwd(buf
, size
) == NULL
) {
321 /* getcwd() sets errno */
324 return strlen(buf
)+1;
327 #ifdef TARGET_NR_openat
328 static int sys_openat(int dirfd
, const char *pathname
, int flags
, mode_t mode
)
331 * open(2) has extra parameter 'mode' when called with
334 if ((flags
& O_CREAT
) != 0) {
335 return (openat(dirfd
, pathname
, flags
, mode
));
337 return (openat(dirfd
, pathname
, flags
));
341 #ifdef CONFIG_UTIMENSAT
342 static int sys_utimensat(int dirfd
, const char *pathname
,
343 const struct timespec times
[2], int flags
)
345 if (pathname
== NULL
)
346 return futimens(dirfd
, times
);
348 return utimensat(dirfd
, pathname
, times
, flags
);
351 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
352 _syscall4(int,sys_utimensat
,int,dirfd
,const char *,pathname
,
353 const struct timespec
*,tsp
,int,flags
)
355 #endif /* CONFIG_UTIMENSAT */
357 #ifdef CONFIG_INOTIFY
358 #include <sys/inotify.h>
360 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
361 static int sys_inotify_init(void)
363 return (inotify_init());
366 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
367 static int sys_inotify_add_watch(int fd
,const char *pathname
, int32_t mask
)
369 return (inotify_add_watch(fd
, pathname
, mask
));
372 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
373 static int sys_inotify_rm_watch(int fd
, int32_t wd
)
375 return (inotify_rm_watch(fd
, wd
));
378 #ifdef CONFIG_INOTIFY1
379 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
380 static int sys_inotify_init1(int flags
)
382 return (inotify_init1(flags
));
387 /* Userspace can usually survive runtime without inotify */
388 #undef TARGET_NR_inotify_init
389 #undef TARGET_NR_inotify_init1
390 #undef TARGET_NR_inotify_add_watch
391 #undef TARGET_NR_inotify_rm_watch
392 #endif /* CONFIG_INOTIFY */
394 #if defined(TARGET_NR_ppoll)
396 # define __NR_ppoll -1
398 #define __NR_sys_ppoll __NR_ppoll
399 _syscall5(int, sys_ppoll
, struct pollfd
*, fds
, nfds_t
, nfds
,
400 struct timespec
*, timeout
, const __sigset_t
*, sigmask
,
404 #if defined(TARGET_NR_pselect6)
405 #ifndef __NR_pselect6
406 # define __NR_pselect6 -1
408 #define __NR_sys_pselect6 __NR_pselect6
409 _syscall6(int, sys_pselect6
, int, nfds
, fd_set
*, readfds
, fd_set
*, writefds
,
410 fd_set
*, exceptfds
, struct timespec
*, timeout
, void *, sig
);
413 #if defined(TARGET_NR_prlimit64)
414 #ifndef __NR_prlimit64
415 # define __NR_prlimit64 -1
417 #define __NR_sys_prlimit64 __NR_prlimit64
418 /* The glibc rlimit structure may not be that used by the underlying syscall */
419 struct host_rlimit64
{
423 _syscall4(int, sys_prlimit64
, pid_t
, pid
, int, resource
,
424 const struct host_rlimit64
*, new_limit
,
425 struct host_rlimit64
*, old_limit
)
428 /* ARM EABI and MIPS expect 64bit types aligned even on pairs or registers */
430 static inline int regpairs_aligned(void *cpu_env
) {
431 return ((((CPUARMState
*)cpu_env
)->eabi
) == 1) ;
433 #elif defined(TARGET_MIPS)
434 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
435 #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
436 /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
437 * of registers which translates to the same as ARM/MIPS, because we start with
439 static inline int regpairs_aligned(void *cpu_env
) { return 1; }
441 static inline int regpairs_aligned(void *cpu_env
) { return 0; }
444 #define ERRNO_TABLE_SIZE 1200
446 /* target_to_host_errno_table[] is initialized from
447 * host_to_target_errno_table[] in syscall_init(). */
448 static uint16_t target_to_host_errno_table
[ERRNO_TABLE_SIZE
] = {
452 * This list is the union of errno values overridden in asm-<arch>/errno.h
453 * minus the errnos that are not actually generic to all archs.
455 static uint16_t host_to_target_errno_table
[ERRNO_TABLE_SIZE
] = {
456 [EIDRM
] = TARGET_EIDRM
,
457 [ECHRNG
] = TARGET_ECHRNG
,
458 [EL2NSYNC
] = TARGET_EL2NSYNC
,
459 [EL3HLT
] = TARGET_EL3HLT
,
460 [EL3RST
] = TARGET_EL3RST
,
461 [ELNRNG
] = TARGET_ELNRNG
,
462 [EUNATCH
] = TARGET_EUNATCH
,
463 [ENOCSI
] = TARGET_ENOCSI
,
464 [EL2HLT
] = TARGET_EL2HLT
,
465 [EDEADLK
] = TARGET_EDEADLK
,
466 [ENOLCK
] = TARGET_ENOLCK
,
467 [EBADE
] = TARGET_EBADE
,
468 [EBADR
] = TARGET_EBADR
,
469 [EXFULL
] = TARGET_EXFULL
,
470 [ENOANO
] = TARGET_ENOANO
,
471 [EBADRQC
] = TARGET_EBADRQC
,
472 [EBADSLT
] = TARGET_EBADSLT
,
473 [EBFONT
] = TARGET_EBFONT
,
474 [ENOSTR
] = TARGET_ENOSTR
,
475 [ENODATA
] = TARGET_ENODATA
,
476 [ETIME
] = TARGET_ETIME
,
477 [ENOSR
] = TARGET_ENOSR
,
478 [ENONET
] = TARGET_ENONET
,
479 [ENOPKG
] = TARGET_ENOPKG
,
480 [EREMOTE
] = TARGET_EREMOTE
,
481 [ENOLINK
] = TARGET_ENOLINK
,
482 [EADV
] = TARGET_EADV
,
483 [ESRMNT
] = TARGET_ESRMNT
,
484 [ECOMM
] = TARGET_ECOMM
,
485 [EPROTO
] = TARGET_EPROTO
,
486 [EDOTDOT
] = TARGET_EDOTDOT
,
487 [EMULTIHOP
] = TARGET_EMULTIHOP
,
488 [EBADMSG
] = TARGET_EBADMSG
,
489 [ENAMETOOLONG
] = TARGET_ENAMETOOLONG
,
490 [EOVERFLOW
] = TARGET_EOVERFLOW
,
491 [ENOTUNIQ
] = TARGET_ENOTUNIQ
,
492 [EBADFD
] = TARGET_EBADFD
,
493 [EREMCHG
] = TARGET_EREMCHG
,
494 [ELIBACC
] = TARGET_ELIBACC
,
495 [ELIBBAD
] = TARGET_ELIBBAD
,
496 [ELIBSCN
] = TARGET_ELIBSCN
,
497 [ELIBMAX
] = TARGET_ELIBMAX
,
498 [ELIBEXEC
] = TARGET_ELIBEXEC
,
499 [EILSEQ
] = TARGET_EILSEQ
,
500 [ENOSYS
] = TARGET_ENOSYS
,
501 [ELOOP
] = TARGET_ELOOP
,
502 [ERESTART
] = TARGET_ERESTART
,
503 [ESTRPIPE
] = TARGET_ESTRPIPE
,
504 [ENOTEMPTY
] = TARGET_ENOTEMPTY
,
505 [EUSERS
] = TARGET_EUSERS
,
506 [ENOTSOCK
] = TARGET_ENOTSOCK
,
507 [EDESTADDRREQ
] = TARGET_EDESTADDRREQ
,
508 [EMSGSIZE
] = TARGET_EMSGSIZE
,
509 [EPROTOTYPE
] = TARGET_EPROTOTYPE
,
510 [ENOPROTOOPT
] = TARGET_ENOPROTOOPT
,
511 [EPROTONOSUPPORT
] = TARGET_EPROTONOSUPPORT
,
512 [ESOCKTNOSUPPORT
] = TARGET_ESOCKTNOSUPPORT
,
513 [EOPNOTSUPP
] = TARGET_EOPNOTSUPP
,
514 [EPFNOSUPPORT
] = TARGET_EPFNOSUPPORT
,
515 [EAFNOSUPPORT
] = TARGET_EAFNOSUPPORT
,
516 [EADDRINUSE
] = TARGET_EADDRINUSE
,
517 [EADDRNOTAVAIL
] = TARGET_EADDRNOTAVAIL
,
518 [ENETDOWN
] = TARGET_ENETDOWN
,
519 [ENETUNREACH
] = TARGET_ENETUNREACH
,
520 [ENETRESET
] = TARGET_ENETRESET
,
521 [ECONNABORTED
] = TARGET_ECONNABORTED
,
522 [ECONNRESET
] = TARGET_ECONNRESET
,
523 [ENOBUFS
] = TARGET_ENOBUFS
,
524 [EISCONN
] = TARGET_EISCONN
,
525 [ENOTCONN
] = TARGET_ENOTCONN
,
526 [EUCLEAN
] = TARGET_EUCLEAN
,
527 [ENOTNAM
] = TARGET_ENOTNAM
,
528 [ENAVAIL
] = TARGET_ENAVAIL
,
529 [EISNAM
] = TARGET_EISNAM
,
530 [EREMOTEIO
] = TARGET_EREMOTEIO
,
531 [ESHUTDOWN
] = TARGET_ESHUTDOWN
,
532 [ETOOMANYREFS
] = TARGET_ETOOMANYREFS
,
533 [ETIMEDOUT
] = TARGET_ETIMEDOUT
,
534 [ECONNREFUSED
] = TARGET_ECONNREFUSED
,
535 [EHOSTDOWN
] = TARGET_EHOSTDOWN
,
536 [EHOSTUNREACH
] = TARGET_EHOSTUNREACH
,
537 [EALREADY
] = TARGET_EALREADY
,
538 [EINPROGRESS
] = TARGET_EINPROGRESS
,
539 [ESTALE
] = TARGET_ESTALE
,
540 [ECANCELED
] = TARGET_ECANCELED
,
541 [ENOMEDIUM
] = TARGET_ENOMEDIUM
,
542 [EMEDIUMTYPE
] = TARGET_EMEDIUMTYPE
,
544 [ENOKEY
] = TARGET_ENOKEY
,
547 [EKEYEXPIRED
] = TARGET_EKEYEXPIRED
,
550 [EKEYREVOKED
] = TARGET_EKEYREVOKED
,
553 [EKEYREJECTED
] = TARGET_EKEYREJECTED
,
556 [EOWNERDEAD
] = TARGET_EOWNERDEAD
,
558 #ifdef ENOTRECOVERABLE
559 [ENOTRECOVERABLE
] = TARGET_ENOTRECOVERABLE
,
563 static inline int host_to_target_errno(int err
)
565 if(host_to_target_errno_table
[err
])
566 return host_to_target_errno_table
[err
];
570 static inline int target_to_host_errno(int err
)
572 if (target_to_host_errno_table
[err
])
573 return target_to_host_errno_table
[err
];
577 static inline abi_long
get_errno(abi_long ret
)
580 return -host_to_target_errno(errno
);
585 static inline int is_error(abi_long ret
)
587 return (abi_ulong
)ret
>= (abi_ulong
)(-4096);
590 char *target_strerror(int err
)
592 if ((err
>= ERRNO_TABLE_SIZE
) || (err
< 0)) {
595 return strerror(target_to_host_errno(err
));
598 static abi_ulong target_brk
;
599 static abi_ulong target_original_brk
;
600 static abi_ulong brk_page
;
602 void target_set_brk(abi_ulong new_brk
)
604 target_original_brk
= target_brk
= HOST_PAGE_ALIGN(new_brk
);
605 brk_page
= HOST_PAGE_ALIGN(target_brk
);
608 //#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
609 #define DEBUGF_BRK(message, args...)
611 /* do_brk() must return target values and target errnos. */
612 abi_long
do_brk(abi_ulong new_brk
)
614 abi_long mapped_addr
;
617 DEBUGF_BRK("do_brk(" TARGET_ABI_FMT_lx
") -> ", new_brk
);
620 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (!new_brk)\n", target_brk
);
623 if (new_brk
< target_original_brk
) {
624 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk < target_original_brk)\n",
629 /* If the new brk is less than the highest page reserved to the
630 * target heap allocation, set it and we're almost done... */
631 if (new_brk
<= brk_page
) {
632 /* Heap contents are initialized to zero, as for anonymous
634 if (new_brk
> target_brk
) {
635 memset(g2h(target_brk
), 0, new_brk
- target_brk
);
637 target_brk
= new_brk
;
638 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (new_brk <= brk_page)\n", target_brk
);
642 /* We need to allocate more memory after the brk... Note that
643 * we don't use MAP_FIXED because that will map over the top of
644 * any existing mapping (like the one with the host libc or qemu
645 * itself); instead we treat "mapped but at wrong address" as
646 * a failure and unmap again.
648 new_alloc_size
= HOST_PAGE_ALIGN(new_brk
- brk_page
);
649 mapped_addr
= get_errno(target_mmap(brk_page
, new_alloc_size
,
650 PROT_READ
|PROT_WRITE
,
651 MAP_ANON
|MAP_PRIVATE
, 0, 0));
653 if (mapped_addr
== brk_page
) {
654 /* Heap contents are initialized to zero, as for anonymous
655 * mapped pages. Technically the new pages are already
656 * initialized to zero since they *are* anonymous mapped
657 * pages, however we have to take care with the contents that
658 * come from the remaining part of the previous page: it may
659 * contains garbage data due to a previous heap usage (grown
661 memset(g2h(target_brk
), 0, brk_page
- target_brk
);
663 target_brk
= new_brk
;
664 brk_page
= HOST_PAGE_ALIGN(target_brk
);
665 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr == brk_page)\n",
668 } else if (mapped_addr
!= -1) {
669 /* Mapped but at wrong address, meaning there wasn't actually
670 * enough space for this brk.
672 target_munmap(mapped_addr
, new_alloc_size
);
674 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (mapped_addr != -1)\n", target_brk
);
677 DEBUGF_BRK(TARGET_ABI_FMT_lx
" (otherwise)\n", target_brk
);
680 #if defined(TARGET_ALPHA)
681 /* We (partially) emulate OSF/1 on Alpha, which requires we
682 return a proper errno, not an unchanged brk value. */
683 return -TARGET_ENOMEM
;
685 /* For everything else, return the previous break. */
689 static inline abi_long
copy_from_user_fdset(fd_set
*fds
,
690 abi_ulong target_fds_addr
,
694 abi_ulong b
, *target_fds
;
696 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
697 if (!(target_fds
= lock_user(VERIFY_READ
,
699 sizeof(abi_ulong
) * nw
,
701 return -TARGET_EFAULT
;
705 for (i
= 0; i
< nw
; i
++) {
706 /* grab the abi_ulong */
707 __get_user(b
, &target_fds
[i
]);
708 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
709 /* check the bit inside the abi_ulong */
716 unlock_user(target_fds
, target_fds_addr
, 0);
721 static inline abi_ulong
copy_from_user_fdset_ptr(fd_set
*fds
, fd_set
**fds_ptr
,
722 abi_ulong target_fds_addr
,
725 if (target_fds_addr
) {
726 if (copy_from_user_fdset(fds
, target_fds_addr
, n
))
727 return -TARGET_EFAULT
;
735 static inline abi_long
copy_to_user_fdset(abi_ulong target_fds_addr
,
741 abi_ulong
*target_fds
;
743 nw
= (n
+ TARGET_ABI_BITS
- 1) / TARGET_ABI_BITS
;
744 if (!(target_fds
= lock_user(VERIFY_WRITE
,
746 sizeof(abi_ulong
) * nw
,
748 return -TARGET_EFAULT
;
751 for (i
= 0; i
< nw
; i
++) {
753 for (j
= 0; j
< TARGET_ABI_BITS
; j
++) {
754 v
|= ((abi_ulong
)(FD_ISSET(k
, fds
) != 0) << j
);
757 __put_user(v
, &target_fds
[i
]);
760 unlock_user(target_fds
, target_fds_addr
, sizeof(abi_ulong
) * nw
);
765 #if defined(__alpha__)
771 static inline abi_long
host_to_target_clock_t(long ticks
)
773 #if HOST_HZ == TARGET_HZ
776 return ((int64_t)ticks
* TARGET_HZ
) / HOST_HZ
;
780 static inline abi_long
host_to_target_rusage(abi_ulong target_addr
,
781 const struct rusage
*rusage
)
783 struct target_rusage
*target_rusage
;
785 if (!lock_user_struct(VERIFY_WRITE
, target_rusage
, target_addr
, 0))
786 return -TARGET_EFAULT
;
787 target_rusage
->ru_utime
.tv_sec
= tswapal(rusage
->ru_utime
.tv_sec
);
788 target_rusage
->ru_utime
.tv_usec
= tswapal(rusage
->ru_utime
.tv_usec
);
789 target_rusage
->ru_stime
.tv_sec
= tswapal(rusage
->ru_stime
.tv_sec
);
790 target_rusage
->ru_stime
.tv_usec
= tswapal(rusage
->ru_stime
.tv_usec
);
791 target_rusage
->ru_maxrss
= tswapal(rusage
->ru_maxrss
);
792 target_rusage
->ru_ixrss
= tswapal(rusage
->ru_ixrss
);
793 target_rusage
->ru_idrss
= tswapal(rusage
->ru_idrss
);
794 target_rusage
->ru_isrss
= tswapal(rusage
->ru_isrss
);
795 target_rusage
->ru_minflt
= tswapal(rusage
->ru_minflt
);
796 target_rusage
->ru_majflt
= tswapal(rusage
->ru_majflt
);
797 target_rusage
->ru_nswap
= tswapal(rusage
->ru_nswap
);
798 target_rusage
->ru_inblock
= tswapal(rusage
->ru_inblock
);
799 target_rusage
->ru_oublock
= tswapal(rusage
->ru_oublock
);
800 target_rusage
->ru_msgsnd
= tswapal(rusage
->ru_msgsnd
);
801 target_rusage
->ru_msgrcv
= tswapal(rusage
->ru_msgrcv
);
802 target_rusage
->ru_nsignals
= tswapal(rusage
->ru_nsignals
);
803 target_rusage
->ru_nvcsw
= tswapal(rusage
->ru_nvcsw
);
804 target_rusage
->ru_nivcsw
= tswapal(rusage
->ru_nivcsw
);
805 unlock_user_struct(target_rusage
, target_addr
, 1);
810 static inline rlim_t
target_to_host_rlim(abi_ulong target_rlim
)
812 abi_ulong target_rlim_swap
;
815 target_rlim_swap
= tswapal(target_rlim
);
816 if (target_rlim_swap
== TARGET_RLIM_INFINITY
)
817 return RLIM_INFINITY
;
819 result
= target_rlim_swap
;
820 if (target_rlim_swap
!= (rlim_t
)result
)
821 return RLIM_INFINITY
;
826 static inline abi_ulong
host_to_target_rlim(rlim_t rlim
)
828 abi_ulong target_rlim_swap
;
831 if (rlim
== RLIM_INFINITY
|| rlim
!= (abi_long
)rlim
)
832 target_rlim_swap
= TARGET_RLIM_INFINITY
;
834 target_rlim_swap
= rlim
;
835 result
= tswapal(target_rlim_swap
);
840 static inline int target_to_host_resource(int code
)
843 case TARGET_RLIMIT_AS
:
845 case TARGET_RLIMIT_CORE
:
847 case TARGET_RLIMIT_CPU
:
849 case TARGET_RLIMIT_DATA
:
851 case TARGET_RLIMIT_FSIZE
:
853 case TARGET_RLIMIT_LOCKS
:
855 case TARGET_RLIMIT_MEMLOCK
:
856 return RLIMIT_MEMLOCK
;
857 case TARGET_RLIMIT_MSGQUEUE
:
858 return RLIMIT_MSGQUEUE
;
859 case TARGET_RLIMIT_NICE
:
861 case TARGET_RLIMIT_NOFILE
:
862 return RLIMIT_NOFILE
;
863 case TARGET_RLIMIT_NPROC
:
865 case TARGET_RLIMIT_RSS
:
867 case TARGET_RLIMIT_RTPRIO
:
868 return RLIMIT_RTPRIO
;
869 case TARGET_RLIMIT_SIGPENDING
:
870 return RLIMIT_SIGPENDING
;
871 case TARGET_RLIMIT_STACK
:
878 static inline abi_long
copy_from_user_timeval(struct timeval
*tv
,
879 abi_ulong target_tv_addr
)
881 struct target_timeval
*target_tv
;
883 if (!lock_user_struct(VERIFY_READ
, target_tv
, target_tv_addr
, 1))
884 return -TARGET_EFAULT
;
886 __get_user(tv
->tv_sec
, &target_tv
->tv_sec
);
887 __get_user(tv
->tv_usec
, &target_tv
->tv_usec
);
889 unlock_user_struct(target_tv
, target_tv_addr
, 0);
894 static inline abi_long
copy_to_user_timeval(abi_ulong target_tv_addr
,
895 const struct timeval
*tv
)
897 struct target_timeval
*target_tv
;
899 if (!lock_user_struct(VERIFY_WRITE
, target_tv
, target_tv_addr
, 0))
900 return -TARGET_EFAULT
;
902 __put_user(tv
->tv_sec
, &target_tv
->tv_sec
);
903 __put_user(tv
->tv_usec
, &target_tv
->tv_usec
);
905 unlock_user_struct(target_tv
, target_tv_addr
, 1);
910 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
913 static inline abi_long
copy_from_user_mq_attr(struct mq_attr
*attr
,
914 abi_ulong target_mq_attr_addr
)
916 struct target_mq_attr
*target_mq_attr
;
918 if (!lock_user_struct(VERIFY_READ
, target_mq_attr
,
919 target_mq_attr_addr
, 1))
920 return -TARGET_EFAULT
;
922 __get_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
923 __get_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
924 __get_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
925 __get_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
927 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 0);
932 static inline abi_long
copy_to_user_mq_attr(abi_ulong target_mq_attr_addr
,
933 const struct mq_attr
*attr
)
935 struct target_mq_attr
*target_mq_attr
;
937 if (!lock_user_struct(VERIFY_WRITE
, target_mq_attr
,
938 target_mq_attr_addr
, 0))
939 return -TARGET_EFAULT
;
941 __put_user(attr
->mq_flags
, &target_mq_attr
->mq_flags
);
942 __put_user(attr
->mq_maxmsg
, &target_mq_attr
->mq_maxmsg
);
943 __put_user(attr
->mq_msgsize
, &target_mq_attr
->mq_msgsize
);
944 __put_user(attr
->mq_curmsgs
, &target_mq_attr
->mq_curmsgs
);
946 unlock_user_struct(target_mq_attr
, target_mq_attr_addr
, 1);
952 #if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
953 /* do_select() must return target values and target errnos. */
954 static abi_long
do_select(int n
,
955 abi_ulong rfd_addr
, abi_ulong wfd_addr
,
956 abi_ulong efd_addr
, abi_ulong target_tv_addr
)
958 fd_set rfds
, wfds
, efds
;
959 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
960 struct timeval tv
, *tv_ptr
;
963 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
967 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
971 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
976 if (target_tv_addr
) {
977 if (copy_from_user_timeval(&tv
, target_tv_addr
))
978 return -TARGET_EFAULT
;
984 ret
= get_errno(select(n
, rfds_ptr
, wfds_ptr
, efds_ptr
, tv_ptr
));
986 if (!is_error(ret
)) {
987 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
988 return -TARGET_EFAULT
;
989 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
990 return -TARGET_EFAULT
;
991 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
992 return -TARGET_EFAULT
;
994 if (target_tv_addr
&& copy_to_user_timeval(target_tv_addr
, &tv
))
995 return -TARGET_EFAULT
;
1002 static abi_long
do_pipe2(int host_pipe
[], int flags
)
1005 return pipe2(host_pipe
, flags
);
1011 static abi_long
do_pipe(void *cpu_env
, abi_ulong pipedes
,
1012 int flags
, int is_pipe2
)
1016 ret
= flags
? do_pipe2(host_pipe
, flags
) : pipe(host_pipe
);
1019 return get_errno(ret
);
1021 /* Several targets have special calling conventions for the original
1022 pipe syscall, but didn't replicate this into the pipe2 syscall. */
1024 #if defined(TARGET_ALPHA)
1025 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = host_pipe
[1];
1026 return host_pipe
[0];
1027 #elif defined(TARGET_MIPS)
1028 ((CPUMIPSState
*)cpu_env
)->active_tc
.gpr
[3] = host_pipe
[1];
1029 return host_pipe
[0];
1030 #elif defined(TARGET_SH4)
1031 ((CPUSH4State
*)cpu_env
)->gregs
[1] = host_pipe
[1];
1032 return host_pipe
[0];
1036 if (put_user_s32(host_pipe
[0], pipedes
)
1037 || put_user_s32(host_pipe
[1], pipedes
+ sizeof(host_pipe
[0])))
1038 return -TARGET_EFAULT
;
1039 return get_errno(ret
);
1042 static inline abi_long
target_to_host_ip_mreq(struct ip_mreqn
*mreqn
,
1043 abi_ulong target_addr
,
1046 struct target_ip_mreqn
*target_smreqn
;
1048 target_smreqn
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1050 return -TARGET_EFAULT
;
1051 mreqn
->imr_multiaddr
.s_addr
= target_smreqn
->imr_multiaddr
.s_addr
;
1052 mreqn
->imr_address
.s_addr
= target_smreqn
->imr_address
.s_addr
;
1053 if (len
== sizeof(struct target_ip_mreqn
))
1054 mreqn
->imr_ifindex
= tswapal(target_smreqn
->imr_ifindex
);
1055 unlock_user(target_smreqn
, target_addr
, 0);
1060 static inline abi_long
target_to_host_sockaddr(struct sockaddr
*addr
,
1061 abi_ulong target_addr
,
1064 const socklen_t unix_maxlen
= sizeof (struct sockaddr_un
);
1065 sa_family_t sa_family
;
1066 struct target_sockaddr
*target_saddr
;
1068 target_saddr
= lock_user(VERIFY_READ
, target_addr
, len
, 1);
1070 return -TARGET_EFAULT
;
1072 sa_family
= tswap16(target_saddr
->sa_family
);
1074 /* Oops. The caller might send a incomplete sun_path; sun_path
1075 * must be terminated by \0 (see the manual page), but
1076 * unfortunately it is quite common to specify sockaddr_un
1077 * length as "strlen(x->sun_path)" while it should be
1078 * "strlen(...) + 1". We'll fix that here if needed.
1079 * Linux kernel has a similar feature.
1082 if (sa_family
== AF_UNIX
) {
1083 if (len
< unix_maxlen
&& len
> 0) {
1084 char *cp
= (char*)target_saddr
;
1086 if ( cp
[len
-1] && !cp
[len
] )
1089 if (len
> unix_maxlen
)
1093 memcpy(addr
, target_saddr
, len
);
1094 addr
->sa_family
= sa_family
;
1095 unlock_user(target_saddr
, target_addr
, 0);
1100 static inline abi_long
host_to_target_sockaddr(abi_ulong target_addr
,
1101 struct sockaddr
*addr
,
1104 struct target_sockaddr
*target_saddr
;
1106 target_saddr
= lock_user(VERIFY_WRITE
, target_addr
, len
, 0);
1108 return -TARGET_EFAULT
;
1109 memcpy(target_saddr
, addr
, len
);
1110 target_saddr
->sa_family
= tswap16(addr
->sa_family
);
1111 unlock_user(target_saddr
, target_addr
, len
);
1116 static inline abi_long
target_to_host_cmsg(struct msghdr
*msgh
,
1117 struct target_msghdr
*target_msgh
)
1119 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1120 abi_long msg_controllen
;
1121 abi_ulong target_cmsg_addr
;
1122 struct target_cmsghdr
*target_cmsg
;
1123 socklen_t space
= 0;
1125 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1126 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1128 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1129 target_cmsg
= lock_user(VERIFY_READ
, target_cmsg_addr
, msg_controllen
, 1);
1131 return -TARGET_EFAULT
;
1133 while (cmsg
&& target_cmsg
) {
1134 void *data
= CMSG_DATA(cmsg
);
1135 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1137 int len
= tswapal(target_cmsg
->cmsg_len
)
1138 - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr
));
1140 space
+= CMSG_SPACE(len
);
1141 if (space
> msgh
->msg_controllen
) {
1142 space
-= CMSG_SPACE(len
);
1143 gemu_log("Host cmsg overflow\n");
1147 cmsg
->cmsg_level
= tswap32(target_cmsg
->cmsg_level
);
1148 cmsg
->cmsg_type
= tswap32(target_cmsg
->cmsg_type
);
1149 cmsg
->cmsg_len
= CMSG_LEN(len
);
1151 if (cmsg
->cmsg_level
!= TARGET_SOL_SOCKET
|| cmsg
->cmsg_type
!= SCM_RIGHTS
) {
1152 gemu_log("Unsupported ancillary data: %d/%d\n", cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1153 memcpy(data
, target_data
, len
);
1155 int *fd
= (int *)data
;
1156 int *target_fd
= (int *)target_data
;
1157 int i
, numfds
= len
/ sizeof(int);
1159 for (i
= 0; i
< numfds
; i
++)
1160 fd
[i
] = tswap32(target_fd
[i
]);
1163 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1164 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1166 unlock_user(target_cmsg
, target_cmsg_addr
, 0);
1168 msgh
->msg_controllen
= space
;
1172 static inline abi_long
host_to_target_cmsg(struct target_msghdr
*target_msgh
,
1173 struct msghdr
*msgh
)
1175 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(msgh
);
1176 abi_long msg_controllen
;
1177 abi_ulong target_cmsg_addr
;
1178 struct target_cmsghdr
*target_cmsg
;
1179 socklen_t space
= 0;
1181 msg_controllen
= tswapal(target_msgh
->msg_controllen
);
1182 if (msg_controllen
< sizeof (struct target_cmsghdr
))
1184 target_cmsg_addr
= tswapal(target_msgh
->msg_control
);
1185 target_cmsg
= lock_user(VERIFY_WRITE
, target_cmsg_addr
, msg_controllen
, 0);
1187 return -TARGET_EFAULT
;
1189 while (cmsg
&& target_cmsg
) {
1190 void *data
= CMSG_DATA(cmsg
);
1191 void *target_data
= TARGET_CMSG_DATA(target_cmsg
);
1193 int len
= cmsg
->cmsg_len
- CMSG_ALIGN(sizeof (struct cmsghdr
));
1195 space
+= TARGET_CMSG_SPACE(len
);
1196 if (space
> msg_controllen
) {
1197 space
-= TARGET_CMSG_SPACE(len
);
1198 gemu_log("Target cmsg overflow\n");
1202 target_cmsg
->cmsg_level
= tswap32(cmsg
->cmsg_level
);
1203 target_cmsg
->cmsg_type
= tswap32(cmsg
->cmsg_type
);
1204 target_cmsg
->cmsg_len
= tswapal(TARGET_CMSG_LEN(len
));
1206 if ((cmsg
->cmsg_level
== TARGET_SOL_SOCKET
) &&
1207 (cmsg
->cmsg_type
== SCM_RIGHTS
)) {
1208 int *fd
= (int *)data
;
1209 int *target_fd
= (int *)target_data
;
1210 int i
, numfds
= len
/ sizeof(int);
1212 for (i
= 0; i
< numfds
; i
++)
1213 target_fd
[i
] = tswap32(fd
[i
]);
1214 } else if ((cmsg
->cmsg_level
== TARGET_SOL_SOCKET
) &&
1215 (cmsg
->cmsg_type
== SO_TIMESTAMP
) &&
1216 (len
== sizeof(struct timeval
))) {
1217 /* copy struct timeval to target */
1218 struct timeval
*tv
= (struct timeval
*)data
;
1219 struct target_timeval
*target_tv
=
1220 (struct target_timeval
*)target_data
;
1222 target_tv
->tv_sec
= tswapal(tv
->tv_sec
);
1223 target_tv
->tv_usec
= tswapal(tv
->tv_usec
);
1225 gemu_log("Unsupported ancillary data: %d/%d\n",
1226 cmsg
->cmsg_level
, cmsg
->cmsg_type
);
1227 memcpy(target_data
, data
, len
);
1230 cmsg
= CMSG_NXTHDR(msgh
, cmsg
);
1231 target_cmsg
= TARGET_CMSG_NXTHDR(target_msgh
, target_cmsg
);
1233 unlock_user(target_cmsg
, target_cmsg_addr
, space
);
1235 target_msgh
->msg_controllen
= tswapal(space
);
1239 /* do_setsockopt() Must return target values and target errnos. */
1240 static abi_long
do_setsockopt(int sockfd
, int level
, int optname
,
1241 abi_ulong optval_addr
, socklen_t optlen
)
1245 struct ip_mreqn
*ip_mreq
;
1246 struct ip_mreq_source
*ip_mreq_source
;
1250 /* TCP options all take an 'int' value. */
1251 if (optlen
< sizeof(uint32_t))
1252 return -TARGET_EINVAL
;
1254 if (get_user_u32(val
, optval_addr
))
1255 return -TARGET_EFAULT
;
1256 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1263 case IP_ROUTER_ALERT
:
1267 case IP_MTU_DISCOVER
:
1273 case IP_MULTICAST_TTL
:
1274 case IP_MULTICAST_LOOP
:
1276 if (optlen
>= sizeof(uint32_t)) {
1277 if (get_user_u32(val
, optval_addr
))
1278 return -TARGET_EFAULT
;
1279 } else if (optlen
>= 1) {
1280 if (get_user_u8(val
, optval_addr
))
1281 return -TARGET_EFAULT
;
1283 ret
= get_errno(setsockopt(sockfd
, level
, optname
, &val
, sizeof(val
)));
1285 case IP_ADD_MEMBERSHIP
:
1286 case IP_DROP_MEMBERSHIP
:
1287 if (optlen
< sizeof (struct target_ip_mreq
) ||
1288 optlen
> sizeof (struct target_ip_mreqn
))
1289 return -TARGET_EINVAL
;
1291 ip_mreq
= (struct ip_mreqn
*) alloca(optlen
);
1292 target_to_host_ip_mreq(ip_mreq
, optval_addr
, optlen
);
1293 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq
, optlen
));
1296 case IP_BLOCK_SOURCE
:
1297 case IP_UNBLOCK_SOURCE
:
1298 case IP_ADD_SOURCE_MEMBERSHIP
:
1299 case IP_DROP_SOURCE_MEMBERSHIP
:
1300 if (optlen
!= sizeof (struct target_ip_mreq_source
))
1301 return -TARGET_EINVAL
;
1303 ip_mreq_source
= lock_user(VERIFY_READ
, optval_addr
, optlen
, 1);
1304 ret
= get_errno(setsockopt(sockfd
, level
, optname
, ip_mreq_source
, optlen
));
1305 unlock_user (ip_mreq_source
, optval_addr
, 0);
1315 /* struct icmp_filter takes an u32 value */
1316 if (optlen
< sizeof(uint32_t)) {
1317 return -TARGET_EINVAL
;
1320 if (get_user_u32(val
, optval_addr
)) {
1321 return -TARGET_EFAULT
;
1323 ret
= get_errno(setsockopt(sockfd
, level
, optname
,
1324 &val
, sizeof(val
)));
1331 case TARGET_SOL_SOCKET
:
1333 case TARGET_SO_RCVTIMEO
:
1337 optname
= SO_RCVTIMEO
;
1340 if (optlen
!= sizeof(struct target_timeval
)) {
1341 return -TARGET_EINVAL
;
1344 if (copy_from_user_timeval(&tv
, optval_addr
)) {
1345 return -TARGET_EFAULT
;
1348 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
,
1352 case TARGET_SO_SNDTIMEO
:
1353 optname
= SO_SNDTIMEO
;
1355 /* Options with 'int' argument. */
1356 case TARGET_SO_DEBUG
:
1359 case TARGET_SO_REUSEADDR
:
1360 optname
= SO_REUSEADDR
;
1362 case TARGET_SO_TYPE
:
1365 case TARGET_SO_ERROR
:
1368 case TARGET_SO_DONTROUTE
:
1369 optname
= SO_DONTROUTE
;
1371 case TARGET_SO_BROADCAST
:
1372 optname
= SO_BROADCAST
;
1374 case TARGET_SO_SNDBUF
:
1375 optname
= SO_SNDBUF
;
1377 case TARGET_SO_RCVBUF
:
1378 optname
= SO_RCVBUF
;
1380 case TARGET_SO_KEEPALIVE
:
1381 optname
= SO_KEEPALIVE
;
1383 case TARGET_SO_OOBINLINE
:
1384 optname
= SO_OOBINLINE
;
1386 case TARGET_SO_NO_CHECK
:
1387 optname
= SO_NO_CHECK
;
1389 case TARGET_SO_PRIORITY
:
1390 optname
= SO_PRIORITY
;
1393 case TARGET_SO_BSDCOMPAT
:
1394 optname
= SO_BSDCOMPAT
;
1397 case TARGET_SO_PASSCRED
:
1398 optname
= SO_PASSCRED
;
1400 case TARGET_SO_TIMESTAMP
:
1401 optname
= SO_TIMESTAMP
;
1403 case TARGET_SO_RCVLOWAT
:
1404 optname
= SO_RCVLOWAT
;
1410 if (optlen
< sizeof(uint32_t))
1411 return -TARGET_EINVAL
;
1413 if (get_user_u32(val
, optval_addr
))
1414 return -TARGET_EFAULT
;
1415 ret
= get_errno(setsockopt(sockfd
, SOL_SOCKET
, optname
, &val
, sizeof(val
)));
1419 gemu_log("Unsupported setsockopt level=%d optname=%d\n", level
, optname
);
1420 ret
= -TARGET_ENOPROTOOPT
;
1425 /* do_getsockopt() Must return target values and target errnos. */
1426 static abi_long
do_getsockopt(int sockfd
, int level
, int optname
,
1427 abi_ulong optval_addr
, abi_ulong optlen
)
1434 case TARGET_SOL_SOCKET
:
1437 /* These don't just return a single integer */
1438 case TARGET_SO_LINGER
:
1439 case TARGET_SO_RCVTIMEO
:
1440 case TARGET_SO_SNDTIMEO
:
1441 case TARGET_SO_PEERNAME
:
1443 case TARGET_SO_PEERCRED
: {
1446 struct target_ucred
*tcr
;
1448 if (get_user_u32(len
, optlen
)) {
1449 return -TARGET_EFAULT
;
1452 return -TARGET_EINVAL
;
1456 ret
= get_errno(getsockopt(sockfd
, level
, SO_PEERCRED
,
1464 if (!lock_user_struct(VERIFY_WRITE
, tcr
, optval_addr
, 0)) {
1465 return -TARGET_EFAULT
;
1467 __put_user(cr
.pid
, &tcr
->pid
);
1468 __put_user(cr
.uid
, &tcr
->uid
);
1469 __put_user(cr
.gid
, &tcr
->gid
);
1470 unlock_user_struct(tcr
, optval_addr
, 1);
1471 if (put_user_u32(len
, optlen
)) {
1472 return -TARGET_EFAULT
;
1476 /* Options with 'int' argument. */
1477 case TARGET_SO_DEBUG
:
1480 case TARGET_SO_REUSEADDR
:
1481 optname
= SO_REUSEADDR
;
1483 case TARGET_SO_TYPE
:
1486 case TARGET_SO_ERROR
:
1489 case TARGET_SO_DONTROUTE
:
1490 optname
= SO_DONTROUTE
;
1492 case TARGET_SO_BROADCAST
:
1493 optname
= SO_BROADCAST
;
1495 case TARGET_SO_SNDBUF
:
1496 optname
= SO_SNDBUF
;
1498 case TARGET_SO_RCVBUF
:
1499 optname
= SO_RCVBUF
;
1501 case TARGET_SO_KEEPALIVE
:
1502 optname
= SO_KEEPALIVE
;
1504 case TARGET_SO_OOBINLINE
:
1505 optname
= SO_OOBINLINE
;
1507 case TARGET_SO_NO_CHECK
:
1508 optname
= SO_NO_CHECK
;
1510 case TARGET_SO_PRIORITY
:
1511 optname
= SO_PRIORITY
;
1514 case TARGET_SO_BSDCOMPAT
:
1515 optname
= SO_BSDCOMPAT
;
1518 case TARGET_SO_PASSCRED
:
1519 optname
= SO_PASSCRED
;
1521 case TARGET_SO_TIMESTAMP
:
1522 optname
= SO_TIMESTAMP
;
1524 case TARGET_SO_RCVLOWAT
:
1525 optname
= SO_RCVLOWAT
;
1532 /* TCP options all take an 'int' value. */
1534 if (get_user_u32(len
, optlen
))
1535 return -TARGET_EFAULT
;
1537 return -TARGET_EINVAL
;
1539 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1545 if (put_user_u32(val
, optval_addr
))
1546 return -TARGET_EFAULT
;
1548 if (put_user_u8(val
, optval_addr
))
1549 return -TARGET_EFAULT
;
1551 if (put_user_u32(len
, optlen
))
1552 return -TARGET_EFAULT
;
1559 case IP_ROUTER_ALERT
:
1563 case IP_MTU_DISCOVER
:
1569 case IP_MULTICAST_TTL
:
1570 case IP_MULTICAST_LOOP
:
1571 if (get_user_u32(len
, optlen
))
1572 return -TARGET_EFAULT
;
1574 return -TARGET_EINVAL
;
1576 ret
= get_errno(getsockopt(sockfd
, level
, optname
, &val
, &lv
));
1579 if (len
< sizeof(int) && len
> 0 && val
>= 0 && val
< 255) {
1581 if (put_user_u32(len
, optlen
)
1582 || put_user_u8(val
, optval_addr
))
1583 return -TARGET_EFAULT
;
1585 if (len
> sizeof(int))
1587 if (put_user_u32(len
, optlen
)
1588 || put_user_u32(val
, optval_addr
))
1589 return -TARGET_EFAULT
;
1593 ret
= -TARGET_ENOPROTOOPT
;
1599 gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1601 ret
= -TARGET_EOPNOTSUPP
;
1607 static struct iovec
*lock_iovec(int type
, abi_ulong target_addr
,
1608 int count
, int copy
)
1610 struct target_iovec
*target_vec
;
1612 abi_ulong total_len
, max_len
;
1619 if (count
< 0 || count
> IOV_MAX
) {
1624 vec
= calloc(count
, sizeof(struct iovec
));
1630 target_vec
= lock_user(VERIFY_READ
, target_addr
,
1631 count
* sizeof(struct target_iovec
), 1);
1632 if (target_vec
== NULL
) {
1637 /* ??? If host page size > target page size, this will result in a
1638 value larger than what we can actually support. */
1639 max_len
= 0x7fffffff & TARGET_PAGE_MASK
;
1642 for (i
= 0; i
< count
; i
++) {
1643 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
1644 abi_long len
= tswapal(target_vec
[i
].iov_len
);
1649 } else if (len
== 0) {
1650 /* Zero length pointer is ignored. */
1651 vec
[i
].iov_base
= 0;
1653 vec
[i
].iov_base
= lock_user(type
, base
, len
, copy
);
1654 if (!vec
[i
].iov_base
) {
1658 if (len
> max_len
- total_len
) {
1659 len
= max_len
- total_len
;
1662 vec
[i
].iov_len
= len
;
1666 unlock_user(target_vec
, target_addr
, 0);
1672 unlock_user(target_vec
, target_addr
, 0);
1676 static void unlock_iovec(struct iovec
*vec
, abi_ulong target_addr
,
1677 int count
, int copy
)
1679 struct target_iovec
*target_vec
;
1682 target_vec
= lock_user(VERIFY_READ
, target_addr
,
1683 count
* sizeof(struct target_iovec
), 1);
1685 for (i
= 0; i
< count
; i
++) {
1686 abi_ulong base
= tswapal(target_vec
[i
].iov_base
);
1687 abi_long len
= tswapal(target_vec
[i
].iov_base
);
1691 unlock_user(vec
[i
].iov_base
, base
, copy
? vec
[i
].iov_len
: 0);
1693 unlock_user(target_vec
, target_addr
, 0);
1699 /* do_socket() Must return target values and target errnos. */
1700 static abi_long
do_socket(int domain
, int type
, int protocol
)
1702 #if defined(TARGET_MIPS)
1704 case TARGET_SOCK_DGRAM
:
1707 case TARGET_SOCK_STREAM
:
1710 case TARGET_SOCK_RAW
:
1713 case TARGET_SOCK_RDM
:
1716 case TARGET_SOCK_SEQPACKET
:
1717 type
= SOCK_SEQPACKET
;
1719 case TARGET_SOCK_PACKET
:
1724 if (domain
== PF_NETLINK
)
1725 return -EAFNOSUPPORT
; /* do not NETLINK socket connections possible */
1726 return get_errno(socket(domain
, type
, protocol
));
1729 /* do_bind() Must return target values and target errnos. */
1730 static abi_long
do_bind(int sockfd
, abi_ulong target_addr
,
1736 if ((int)addrlen
< 0) {
1737 return -TARGET_EINVAL
;
1740 addr
= alloca(addrlen
+1);
1742 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1746 return get_errno(bind(sockfd
, addr
, addrlen
));
1749 /* do_connect() Must return target values and target errnos. */
1750 static abi_long
do_connect(int sockfd
, abi_ulong target_addr
,
1756 if ((int)addrlen
< 0) {
1757 return -TARGET_EINVAL
;
1760 addr
= alloca(addrlen
);
1762 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1766 return get_errno(connect(sockfd
, addr
, addrlen
));
1769 /* do_sendrecvmsg() Must return target values and target errnos. */
1770 static abi_long
do_sendrecvmsg(int fd
, abi_ulong target_msg
,
1771 int flags
, int send
)
1774 struct target_msghdr
*msgp
;
1778 abi_ulong target_vec
;
1781 if (!lock_user_struct(send
? VERIFY_READ
: VERIFY_WRITE
,
1785 return -TARGET_EFAULT
;
1786 if (msgp
->msg_name
) {
1787 msg
.msg_namelen
= tswap32(msgp
->msg_namelen
);
1788 msg
.msg_name
= alloca(msg
.msg_namelen
);
1789 ret
= target_to_host_sockaddr(msg
.msg_name
, tswapal(msgp
->msg_name
),
1795 msg
.msg_name
= NULL
;
1796 msg
.msg_namelen
= 0;
1798 msg
.msg_controllen
= 2 * tswapal(msgp
->msg_controllen
);
1799 msg
.msg_control
= alloca(msg
.msg_controllen
);
1800 msg
.msg_flags
= tswap32(msgp
->msg_flags
);
1802 count
= tswapal(msgp
->msg_iovlen
);
1803 target_vec
= tswapal(msgp
->msg_iov
);
1804 vec
= lock_iovec(send
? VERIFY_READ
: VERIFY_WRITE
,
1805 target_vec
, count
, send
);
1807 ret
= -host_to_target_errno(errno
);
1810 msg
.msg_iovlen
= count
;
1814 ret
= target_to_host_cmsg(&msg
, msgp
);
1816 ret
= get_errno(sendmsg(fd
, &msg
, flags
));
1818 ret
= get_errno(recvmsg(fd
, &msg
, flags
));
1819 if (!is_error(ret
)) {
1821 ret
= host_to_target_cmsg(msgp
, &msg
);
1822 if (!is_error(ret
)) {
1823 msgp
->msg_namelen
= tswap32(msg
.msg_namelen
);
1824 if (msg
.msg_name
!= NULL
) {
1825 ret
= host_to_target_sockaddr(tswapal(msgp
->msg_name
),
1826 msg
.msg_name
, msg
.msg_namelen
);
1838 unlock_iovec(vec
, target_vec
, count
, !send
);
1840 unlock_user_struct(msgp
, target_msg
, send
? 0 : 1);
1844 /* If we don't have a system accept4() then just call accept.
1845 * The callsites to do_accept4() will ensure that they don't
1846 * pass a non-zero flags argument in this config.
1848 #ifndef CONFIG_ACCEPT4
1849 static inline int accept4(int sockfd
, struct sockaddr
*addr
,
1850 socklen_t
*addrlen
, int flags
)
1853 return accept(sockfd
, addr
, addrlen
);
1857 /* do_accept4() Must return target values and target errnos. */
1858 static abi_long
do_accept4(int fd
, abi_ulong target_addr
,
1859 abi_ulong target_addrlen_addr
, int flags
)
1865 if (target_addr
== 0) {
1866 return get_errno(accept4(fd
, NULL
, NULL
, flags
));
1869 /* linux returns EINVAL if addrlen pointer is invalid */
1870 if (get_user_u32(addrlen
, target_addrlen_addr
))
1871 return -TARGET_EINVAL
;
1873 if ((int)addrlen
< 0) {
1874 return -TARGET_EINVAL
;
1877 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
1878 return -TARGET_EINVAL
;
1880 addr
= alloca(addrlen
);
1882 ret
= get_errno(accept4(fd
, addr
, &addrlen
, flags
));
1883 if (!is_error(ret
)) {
1884 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1885 if (put_user_u32(addrlen
, target_addrlen_addr
))
1886 ret
= -TARGET_EFAULT
;
1891 /* do_getpeername() Must return target values and target errnos. */
1892 static abi_long
do_getpeername(int fd
, abi_ulong target_addr
,
1893 abi_ulong target_addrlen_addr
)
1899 if (get_user_u32(addrlen
, target_addrlen_addr
))
1900 return -TARGET_EFAULT
;
1902 if ((int)addrlen
< 0) {
1903 return -TARGET_EINVAL
;
1906 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
1907 return -TARGET_EFAULT
;
1909 addr
= alloca(addrlen
);
1911 ret
= get_errno(getpeername(fd
, addr
, &addrlen
));
1912 if (!is_error(ret
)) {
1913 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1914 if (put_user_u32(addrlen
, target_addrlen_addr
))
1915 ret
= -TARGET_EFAULT
;
1920 /* do_getsockname() Must return target values and target errnos. */
1921 static abi_long
do_getsockname(int fd
, abi_ulong target_addr
,
1922 abi_ulong target_addrlen_addr
)
1928 if (get_user_u32(addrlen
, target_addrlen_addr
))
1929 return -TARGET_EFAULT
;
1931 if ((int)addrlen
< 0) {
1932 return -TARGET_EINVAL
;
1935 if (!access_ok(VERIFY_WRITE
, target_addr
, addrlen
))
1936 return -TARGET_EFAULT
;
1938 addr
= alloca(addrlen
);
1940 ret
= get_errno(getsockname(fd
, addr
, &addrlen
));
1941 if (!is_error(ret
)) {
1942 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
1943 if (put_user_u32(addrlen
, target_addrlen_addr
))
1944 ret
= -TARGET_EFAULT
;
1949 /* do_socketpair() Must return target values and target errnos. */
1950 static abi_long
do_socketpair(int domain
, int type
, int protocol
,
1951 abi_ulong target_tab_addr
)
1956 ret
= get_errno(socketpair(domain
, type
, protocol
, tab
));
1957 if (!is_error(ret
)) {
1958 if (put_user_s32(tab
[0], target_tab_addr
)
1959 || put_user_s32(tab
[1], target_tab_addr
+ sizeof(tab
[0])))
1960 ret
= -TARGET_EFAULT
;
1965 /* do_sendto() Must return target values and target errnos. */
1966 static abi_long
do_sendto(int fd
, abi_ulong msg
, size_t len
, int flags
,
1967 abi_ulong target_addr
, socklen_t addrlen
)
1973 if ((int)addrlen
< 0) {
1974 return -TARGET_EINVAL
;
1977 host_msg
= lock_user(VERIFY_READ
, msg
, len
, 1);
1979 return -TARGET_EFAULT
;
1981 addr
= alloca(addrlen
);
1982 ret
= target_to_host_sockaddr(addr
, target_addr
, addrlen
);
1984 unlock_user(host_msg
, msg
, 0);
1987 ret
= get_errno(sendto(fd
, host_msg
, len
, flags
, addr
, addrlen
));
1989 ret
= get_errno(send(fd
, host_msg
, len
, flags
));
1991 unlock_user(host_msg
, msg
, 0);
1995 /* do_recvfrom() Must return target values and target errnos. */
1996 static abi_long
do_recvfrom(int fd
, abi_ulong msg
, size_t len
, int flags
,
1997 abi_ulong target_addr
,
1998 abi_ulong target_addrlen
)
2005 host_msg
= lock_user(VERIFY_WRITE
, msg
, len
, 0);
2007 return -TARGET_EFAULT
;
2009 if (get_user_u32(addrlen
, target_addrlen
)) {
2010 ret
= -TARGET_EFAULT
;
2013 if ((int)addrlen
< 0) {
2014 ret
= -TARGET_EINVAL
;
2017 addr
= alloca(addrlen
);
2018 ret
= get_errno(recvfrom(fd
, host_msg
, len
, flags
, addr
, &addrlen
));
2020 addr
= NULL
; /* To keep compiler quiet. */
2021 ret
= get_errno(qemu_recv(fd
, host_msg
, len
, flags
));
2023 if (!is_error(ret
)) {
2025 host_to_target_sockaddr(target_addr
, addr
, addrlen
);
2026 if (put_user_u32(addrlen
, target_addrlen
)) {
2027 ret
= -TARGET_EFAULT
;
2031 unlock_user(host_msg
, msg
, len
);
2034 unlock_user(host_msg
, msg
, 0);
2039 #ifdef TARGET_NR_socketcall
2040 /* do_socketcall() Must return target values and target errnos. */
2041 static abi_long
do_socketcall(int num
, abi_ulong vptr
)
2044 const int n
= sizeof(abi_ulong
);
2049 abi_ulong domain
, type
, protocol
;
2051 if (get_user_ual(domain
, vptr
)
2052 || get_user_ual(type
, vptr
+ n
)
2053 || get_user_ual(protocol
, vptr
+ 2 * n
))
2054 return -TARGET_EFAULT
;
2056 ret
= do_socket(domain
, type
, protocol
);
2062 abi_ulong target_addr
;
2065 if (get_user_ual(sockfd
, vptr
)
2066 || get_user_ual(target_addr
, vptr
+ n
)
2067 || get_user_ual(addrlen
, vptr
+ 2 * n
))
2068 return -TARGET_EFAULT
;
2070 ret
= do_bind(sockfd
, target_addr
, addrlen
);
2073 case SOCKOP_connect
:
2076 abi_ulong target_addr
;
2079 if (get_user_ual(sockfd
, vptr
)
2080 || get_user_ual(target_addr
, vptr
+ n
)
2081 || get_user_ual(addrlen
, vptr
+ 2 * n
))
2082 return -TARGET_EFAULT
;
2084 ret
= do_connect(sockfd
, target_addr
, addrlen
);
2089 abi_ulong sockfd
, backlog
;
2091 if (get_user_ual(sockfd
, vptr
)
2092 || get_user_ual(backlog
, vptr
+ n
))
2093 return -TARGET_EFAULT
;
2095 ret
= get_errno(listen(sockfd
, backlog
));
2101 abi_ulong target_addr
, target_addrlen
;
2103 if (get_user_ual(sockfd
, vptr
)
2104 || get_user_ual(target_addr
, vptr
+ n
)
2105 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2106 return -TARGET_EFAULT
;
2108 ret
= do_accept4(sockfd
, target_addr
, target_addrlen
, 0);
2111 case SOCKOP_getsockname
:
2114 abi_ulong target_addr
, target_addrlen
;
2116 if (get_user_ual(sockfd
, vptr
)
2117 || get_user_ual(target_addr
, vptr
+ n
)
2118 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2119 return -TARGET_EFAULT
;
2121 ret
= do_getsockname(sockfd
, target_addr
, target_addrlen
);
2124 case SOCKOP_getpeername
:
2127 abi_ulong target_addr
, target_addrlen
;
2129 if (get_user_ual(sockfd
, vptr
)
2130 || get_user_ual(target_addr
, vptr
+ n
)
2131 || get_user_ual(target_addrlen
, vptr
+ 2 * n
))
2132 return -TARGET_EFAULT
;
2134 ret
= do_getpeername(sockfd
, target_addr
, target_addrlen
);
2137 case SOCKOP_socketpair
:
2139 abi_ulong domain
, type
, protocol
;
2142 if (get_user_ual(domain
, vptr
)
2143 || get_user_ual(type
, vptr
+ n
)
2144 || get_user_ual(protocol
, vptr
+ 2 * n
)
2145 || get_user_ual(tab
, vptr
+ 3 * n
))
2146 return -TARGET_EFAULT
;
2148 ret
= do_socketpair(domain
, type
, protocol
, tab
);
2158 if (get_user_ual(sockfd
, vptr
)
2159 || get_user_ual(msg
, vptr
+ n
)
2160 || get_user_ual(len
, vptr
+ 2 * n
)
2161 || get_user_ual(flags
, vptr
+ 3 * n
))
2162 return -TARGET_EFAULT
;
2164 ret
= do_sendto(sockfd
, msg
, len
, flags
, 0, 0);
2174 if (get_user_ual(sockfd
, vptr
)
2175 || get_user_ual(msg
, vptr
+ n
)
2176 || get_user_ual(len
, vptr
+ 2 * n
)
2177 || get_user_ual(flags
, vptr
+ 3 * n
))
2178 return -TARGET_EFAULT
;
2180 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, 0, 0);
2192 if (get_user_ual(sockfd
, vptr
)
2193 || get_user_ual(msg
, vptr
+ n
)
2194 || get_user_ual(len
, vptr
+ 2 * n
)
2195 || get_user_ual(flags
, vptr
+ 3 * n
)
2196 || get_user_ual(addr
, vptr
+ 4 * n
)
2197 || get_user_ual(addrlen
, vptr
+ 5 * n
))
2198 return -TARGET_EFAULT
;
2200 ret
= do_sendto(sockfd
, msg
, len
, flags
, addr
, addrlen
);
2203 case SOCKOP_recvfrom
:
2212 if (get_user_ual(sockfd
, vptr
)
2213 || get_user_ual(msg
, vptr
+ n
)
2214 || get_user_ual(len
, vptr
+ 2 * n
)
2215 || get_user_ual(flags
, vptr
+ 3 * n
)
2216 || get_user_ual(addr
, vptr
+ 4 * n
)
2217 || get_user_ual(addrlen
, vptr
+ 5 * n
))
2218 return -TARGET_EFAULT
;
2220 ret
= do_recvfrom(sockfd
, msg
, len
, flags
, addr
, addrlen
);
2223 case SOCKOP_shutdown
:
2225 abi_ulong sockfd
, how
;
2227 if (get_user_ual(sockfd
, vptr
)
2228 || get_user_ual(how
, vptr
+ n
))
2229 return -TARGET_EFAULT
;
2231 ret
= get_errno(shutdown(sockfd
, how
));
2234 case SOCKOP_sendmsg
:
2235 case SOCKOP_recvmsg
:
2238 abi_ulong target_msg
;
2241 if (get_user_ual(fd
, vptr
)
2242 || get_user_ual(target_msg
, vptr
+ n
)
2243 || get_user_ual(flags
, vptr
+ 2 * n
))
2244 return -TARGET_EFAULT
;
2246 ret
= do_sendrecvmsg(fd
, target_msg
, flags
,
2247 (num
== SOCKOP_sendmsg
));
2250 case SOCKOP_setsockopt
:
2258 if (get_user_ual(sockfd
, vptr
)
2259 || get_user_ual(level
, vptr
+ n
)
2260 || get_user_ual(optname
, vptr
+ 2 * n
)
2261 || get_user_ual(optval
, vptr
+ 3 * n
)
2262 || get_user_ual(optlen
, vptr
+ 4 * n
))
2263 return -TARGET_EFAULT
;
2265 ret
= do_setsockopt(sockfd
, level
, optname
, optval
, optlen
);
2268 case SOCKOP_getsockopt
:
2276 if (get_user_ual(sockfd
, vptr
)
2277 || get_user_ual(level
, vptr
+ n
)
2278 || get_user_ual(optname
, vptr
+ 2 * n
)
2279 || get_user_ual(optval
, vptr
+ 3 * n
)
2280 || get_user_ual(optlen
, vptr
+ 4 * n
))
2281 return -TARGET_EFAULT
;
2283 ret
= do_getsockopt(sockfd
, level
, optname
, optval
, optlen
);
2287 gemu_log("Unsupported socketcall: %d\n", num
);
2288 ret
= -TARGET_ENOSYS
;
2295 #define N_SHM_REGIONS 32
2297 static struct shm_region
{
2300 } shm_regions
[N_SHM_REGIONS
];
2302 struct target_ipc_perm
2309 unsigned short int mode
;
2310 unsigned short int __pad1
;
2311 unsigned short int __seq
;
2312 unsigned short int __pad2
;
2313 abi_ulong __unused1
;
2314 abi_ulong __unused2
;
2317 struct target_semid_ds
2319 struct target_ipc_perm sem_perm
;
2320 abi_ulong sem_otime
;
2321 abi_ulong __unused1
;
2322 abi_ulong sem_ctime
;
2323 abi_ulong __unused2
;
2324 abi_ulong sem_nsems
;
2325 abi_ulong __unused3
;
2326 abi_ulong __unused4
;
2329 static inline abi_long
target_to_host_ipc_perm(struct ipc_perm
*host_ip
,
2330 abi_ulong target_addr
)
2332 struct target_ipc_perm
*target_ip
;
2333 struct target_semid_ds
*target_sd
;
2335 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2336 return -TARGET_EFAULT
;
2337 target_ip
= &(target_sd
->sem_perm
);
2338 host_ip
->__key
= tswapal(target_ip
->__key
);
2339 host_ip
->uid
= tswapal(target_ip
->uid
);
2340 host_ip
->gid
= tswapal(target_ip
->gid
);
2341 host_ip
->cuid
= tswapal(target_ip
->cuid
);
2342 host_ip
->cgid
= tswapal(target_ip
->cgid
);
2343 host_ip
->mode
= tswap16(target_ip
->mode
);
2344 unlock_user_struct(target_sd
, target_addr
, 0);
2348 static inline abi_long
host_to_target_ipc_perm(abi_ulong target_addr
,
2349 struct ipc_perm
*host_ip
)
2351 struct target_ipc_perm
*target_ip
;
2352 struct target_semid_ds
*target_sd
;
2354 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2355 return -TARGET_EFAULT
;
2356 target_ip
= &(target_sd
->sem_perm
);
2357 target_ip
->__key
= tswapal(host_ip
->__key
);
2358 target_ip
->uid
= tswapal(host_ip
->uid
);
2359 target_ip
->gid
= tswapal(host_ip
->gid
);
2360 target_ip
->cuid
= tswapal(host_ip
->cuid
);
2361 target_ip
->cgid
= tswapal(host_ip
->cgid
);
2362 target_ip
->mode
= tswap16(host_ip
->mode
);
2363 unlock_user_struct(target_sd
, target_addr
, 1);
2367 static inline abi_long
target_to_host_semid_ds(struct semid_ds
*host_sd
,
2368 abi_ulong target_addr
)
2370 struct target_semid_ds
*target_sd
;
2372 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2373 return -TARGET_EFAULT
;
2374 if (target_to_host_ipc_perm(&(host_sd
->sem_perm
),target_addr
))
2375 return -TARGET_EFAULT
;
2376 host_sd
->sem_nsems
= tswapal(target_sd
->sem_nsems
);
2377 host_sd
->sem_otime
= tswapal(target_sd
->sem_otime
);
2378 host_sd
->sem_ctime
= tswapal(target_sd
->sem_ctime
);
2379 unlock_user_struct(target_sd
, target_addr
, 0);
2383 static inline abi_long
host_to_target_semid_ds(abi_ulong target_addr
,
2384 struct semid_ds
*host_sd
)
2386 struct target_semid_ds
*target_sd
;
2388 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2389 return -TARGET_EFAULT
;
2390 if (host_to_target_ipc_perm(target_addr
,&(host_sd
->sem_perm
)))
2391 return -TARGET_EFAULT
;
2392 target_sd
->sem_nsems
= tswapal(host_sd
->sem_nsems
);
2393 target_sd
->sem_otime
= tswapal(host_sd
->sem_otime
);
2394 target_sd
->sem_ctime
= tswapal(host_sd
->sem_ctime
);
2395 unlock_user_struct(target_sd
, target_addr
, 1);
2399 struct target_seminfo
{
2412 static inline abi_long
host_to_target_seminfo(abi_ulong target_addr
,
2413 struct seminfo
*host_seminfo
)
2415 struct target_seminfo
*target_seminfo
;
2416 if (!lock_user_struct(VERIFY_WRITE
, target_seminfo
, target_addr
, 0))
2417 return -TARGET_EFAULT
;
2418 __put_user(host_seminfo
->semmap
, &target_seminfo
->semmap
);
2419 __put_user(host_seminfo
->semmni
, &target_seminfo
->semmni
);
2420 __put_user(host_seminfo
->semmns
, &target_seminfo
->semmns
);
2421 __put_user(host_seminfo
->semmnu
, &target_seminfo
->semmnu
);
2422 __put_user(host_seminfo
->semmsl
, &target_seminfo
->semmsl
);
2423 __put_user(host_seminfo
->semopm
, &target_seminfo
->semopm
);
2424 __put_user(host_seminfo
->semume
, &target_seminfo
->semume
);
2425 __put_user(host_seminfo
->semusz
, &target_seminfo
->semusz
);
2426 __put_user(host_seminfo
->semvmx
, &target_seminfo
->semvmx
);
2427 __put_user(host_seminfo
->semaem
, &target_seminfo
->semaem
);
2428 unlock_user_struct(target_seminfo
, target_addr
, 1);
2434 struct semid_ds
*buf
;
2435 unsigned short *array
;
2436 struct seminfo
*__buf
;
2439 union target_semun
{
2446 static inline abi_long
target_to_host_semarray(int semid
, unsigned short **host_array
,
2447 abi_ulong target_addr
)
2450 unsigned short *array
;
2452 struct semid_ds semid_ds
;
2455 semun
.buf
= &semid_ds
;
2457 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2459 return get_errno(ret
);
2461 nsems
= semid_ds
.sem_nsems
;
2463 *host_array
= malloc(nsems
*sizeof(unsigned short));
2464 array
= lock_user(VERIFY_READ
, target_addr
,
2465 nsems
*sizeof(unsigned short), 1);
2467 return -TARGET_EFAULT
;
2469 for(i
=0; i
<nsems
; i
++) {
2470 __get_user((*host_array
)[i
], &array
[i
]);
2472 unlock_user(array
, target_addr
, 0);
2477 static inline abi_long
host_to_target_semarray(int semid
, abi_ulong target_addr
,
2478 unsigned short **host_array
)
2481 unsigned short *array
;
2483 struct semid_ds semid_ds
;
2486 semun
.buf
= &semid_ds
;
2488 ret
= semctl(semid
, 0, IPC_STAT
, semun
);
2490 return get_errno(ret
);
2492 nsems
= semid_ds
.sem_nsems
;
2494 array
= lock_user(VERIFY_WRITE
, target_addr
,
2495 nsems
*sizeof(unsigned short), 0);
2497 return -TARGET_EFAULT
;
2499 for(i
=0; i
<nsems
; i
++) {
2500 __put_user((*host_array
)[i
], &array
[i
]);
2503 unlock_user(array
, target_addr
, 1);
2508 static inline abi_long
do_semctl(int semid
, int semnum
, int cmd
,
2509 union target_semun target_su
)
2512 struct semid_ds dsarg
;
2513 unsigned short *array
= NULL
;
2514 struct seminfo seminfo
;
2515 abi_long ret
= -TARGET_EINVAL
;
2522 arg
.val
= tswap32(target_su
.val
);
2523 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2524 target_su
.val
= tswap32(arg
.val
);
2528 err
= target_to_host_semarray(semid
, &array
, target_su
.array
);
2532 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2533 err
= host_to_target_semarray(semid
, target_su
.array
, &array
);
2540 err
= target_to_host_semid_ds(&dsarg
, target_su
.buf
);
2544 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2545 err
= host_to_target_semid_ds(target_su
.buf
, &dsarg
);
2551 arg
.__buf
= &seminfo
;
2552 ret
= get_errno(semctl(semid
, semnum
, cmd
, arg
));
2553 err
= host_to_target_seminfo(target_su
.__buf
, &seminfo
);
2561 ret
= get_errno(semctl(semid
, semnum
, cmd
, NULL
));
2568 struct target_sembuf
{
2569 unsigned short sem_num
;
2574 static inline abi_long
target_to_host_sembuf(struct sembuf
*host_sembuf
,
2575 abi_ulong target_addr
,
2578 struct target_sembuf
*target_sembuf
;
2581 target_sembuf
= lock_user(VERIFY_READ
, target_addr
,
2582 nsops
*sizeof(struct target_sembuf
), 1);
2584 return -TARGET_EFAULT
;
2586 for(i
=0; i
<nsops
; i
++) {
2587 __get_user(host_sembuf
[i
].sem_num
, &target_sembuf
[i
].sem_num
);
2588 __get_user(host_sembuf
[i
].sem_op
, &target_sembuf
[i
].sem_op
);
2589 __get_user(host_sembuf
[i
].sem_flg
, &target_sembuf
[i
].sem_flg
);
2592 unlock_user(target_sembuf
, target_addr
, 0);
2597 static inline abi_long
do_semop(int semid
, abi_long ptr
, unsigned nsops
)
2599 struct sembuf sops
[nsops
];
2601 if (target_to_host_sembuf(sops
, ptr
, nsops
))
2602 return -TARGET_EFAULT
;
2604 return get_errno(semop(semid
, sops
, nsops
));
2607 struct target_msqid_ds
2609 struct target_ipc_perm msg_perm
;
2610 abi_ulong msg_stime
;
2611 #if TARGET_ABI_BITS == 32
2612 abi_ulong __unused1
;
2614 abi_ulong msg_rtime
;
2615 #if TARGET_ABI_BITS == 32
2616 abi_ulong __unused2
;
2618 abi_ulong msg_ctime
;
2619 #if TARGET_ABI_BITS == 32
2620 abi_ulong __unused3
;
2622 abi_ulong __msg_cbytes
;
2624 abi_ulong msg_qbytes
;
2625 abi_ulong msg_lspid
;
2626 abi_ulong msg_lrpid
;
2627 abi_ulong __unused4
;
2628 abi_ulong __unused5
;
2631 static inline abi_long
target_to_host_msqid_ds(struct msqid_ds
*host_md
,
2632 abi_ulong target_addr
)
2634 struct target_msqid_ds
*target_md
;
2636 if (!lock_user_struct(VERIFY_READ
, target_md
, target_addr
, 1))
2637 return -TARGET_EFAULT
;
2638 if (target_to_host_ipc_perm(&(host_md
->msg_perm
),target_addr
))
2639 return -TARGET_EFAULT
;
2640 host_md
->msg_stime
= tswapal(target_md
->msg_stime
);
2641 host_md
->msg_rtime
= tswapal(target_md
->msg_rtime
);
2642 host_md
->msg_ctime
= tswapal(target_md
->msg_ctime
);
2643 host_md
->__msg_cbytes
= tswapal(target_md
->__msg_cbytes
);
2644 host_md
->msg_qnum
= tswapal(target_md
->msg_qnum
);
2645 host_md
->msg_qbytes
= tswapal(target_md
->msg_qbytes
);
2646 host_md
->msg_lspid
= tswapal(target_md
->msg_lspid
);
2647 host_md
->msg_lrpid
= tswapal(target_md
->msg_lrpid
);
2648 unlock_user_struct(target_md
, target_addr
, 0);
2652 static inline abi_long
host_to_target_msqid_ds(abi_ulong target_addr
,
2653 struct msqid_ds
*host_md
)
2655 struct target_msqid_ds
*target_md
;
2657 if (!lock_user_struct(VERIFY_WRITE
, target_md
, target_addr
, 0))
2658 return -TARGET_EFAULT
;
2659 if (host_to_target_ipc_perm(target_addr
,&(host_md
->msg_perm
)))
2660 return -TARGET_EFAULT
;
2661 target_md
->msg_stime
= tswapal(host_md
->msg_stime
);
2662 target_md
->msg_rtime
= tswapal(host_md
->msg_rtime
);
2663 target_md
->msg_ctime
= tswapal(host_md
->msg_ctime
);
2664 target_md
->__msg_cbytes
= tswapal(host_md
->__msg_cbytes
);
2665 target_md
->msg_qnum
= tswapal(host_md
->msg_qnum
);
2666 target_md
->msg_qbytes
= tswapal(host_md
->msg_qbytes
);
2667 target_md
->msg_lspid
= tswapal(host_md
->msg_lspid
);
2668 target_md
->msg_lrpid
= tswapal(host_md
->msg_lrpid
);
2669 unlock_user_struct(target_md
, target_addr
, 1);
2673 struct target_msginfo
{
2681 unsigned short int msgseg
;
2684 static inline abi_long
host_to_target_msginfo(abi_ulong target_addr
,
2685 struct msginfo
*host_msginfo
)
2687 struct target_msginfo
*target_msginfo
;
2688 if (!lock_user_struct(VERIFY_WRITE
, target_msginfo
, target_addr
, 0))
2689 return -TARGET_EFAULT
;
2690 __put_user(host_msginfo
->msgpool
, &target_msginfo
->msgpool
);
2691 __put_user(host_msginfo
->msgmap
, &target_msginfo
->msgmap
);
2692 __put_user(host_msginfo
->msgmax
, &target_msginfo
->msgmax
);
2693 __put_user(host_msginfo
->msgmnb
, &target_msginfo
->msgmnb
);
2694 __put_user(host_msginfo
->msgmni
, &target_msginfo
->msgmni
);
2695 __put_user(host_msginfo
->msgssz
, &target_msginfo
->msgssz
);
2696 __put_user(host_msginfo
->msgtql
, &target_msginfo
->msgtql
);
2697 __put_user(host_msginfo
->msgseg
, &target_msginfo
->msgseg
);
2698 unlock_user_struct(target_msginfo
, target_addr
, 1);
2702 static inline abi_long
do_msgctl(int msgid
, int cmd
, abi_long ptr
)
2704 struct msqid_ds dsarg
;
2705 struct msginfo msginfo
;
2706 abi_long ret
= -TARGET_EINVAL
;
2714 if (target_to_host_msqid_ds(&dsarg
,ptr
))
2715 return -TARGET_EFAULT
;
2716 ret
= get_errno(msgctl(msgid
, cmd
, &dsarg
));
2717 if (host_to_target_msqid_ds(ptr
,&dsarg
))
2718 return -TARGET_EFAULT
;
2721 ret
= get_errno(msgctl(msgid
, cmd
, NULL
));
2725 ret
= get_errno(msgctl(msgid
, cmd
, (struct msqid_ds
*)&msginfo
));
2726 if (host_to_target_msginfo(ptr
, &msginfo
))
2727 return -TARGET_EFAULT
;
2734 struct target_msgbuf
{
2739 static inline abi_long
do_msgsnd(int msqid
, abi_long msgp
,
2740 unsigned int msgsz
, int msgflg
)
2742 struct target_msgbuf
*target_mb
;
2743 struct msgbuf
*host_mb
;
2746 if (!lock_user_struct(VERIFY_READ
, target_mb
, msgp
, 0))
2747 return -TARGET_EFAULT
;
2748 host_mb
= malloc(msgsz
+sizeof(long));
2749 host_mb
->mtype
= (abi_long
) tswapal(target_mb
->mtype
);
2750 memcpy(host_mb
->mtext
, target_mb
->mtext
, msgsz
);
2751 ret
= get_errno(msgsnd(msqid
, host_mb
, msgsz
, msgflg
));
2753 unlock_user_struct(target_mb
, msgp
, 0);
2758 static inline abi_long
do_msgrcv(int msqid
, abi_long msgp
,
2759 unsigned int msgsz
, abi_long msgtyp
,
2762 struct target_msgbuf
*target_mb
;
2764 struct msgbuf
*host_mb
;
2767 if (!lock_user_struct(VERIFY_WRITE
, target_mb
, msgp
, 0))
2768 return -TARGET_EFAULT
;
2770 host_mb
= g_malloc(msgsz
+sizeof(long));
2771 ret
= get_errno(msgrcv(msqid
, host_mb
, msgsz
, msgtyp
, msgflg
));
2774 abi_ulong target_mtext_addr
= msgp
+ sizeof(abi_ulong
);
2775 target_mtext
= lock_user(VERIFY_WRITE
, target_mtext_addr
, ret
, 0);
2776 if (!target_mtext
) {
2777 ret
= -TARGET_EFAULT
;
2780 memcpy(target_mb
->mtext
, host_mb
->mtext
, ret
);
2781 unlock_user(target_mtext
, target_mtext_addr
, ret
);
2784 target_mb
->mtype
= tswapal(host_mb
->mtype
);
2788 unlock_user_struct(target_mb
, msgp
, 1);
2793 struct target_shmid_ds
2795 struct target_ipc_perm shm_perm
;
2796 abi_ulong shm_segsz
;
2797 abi_ulong shm_atime
;
2798 #if TARGET_ABI_BITS == 32
2799 abi_ulong __unused1
;
2801 abi_ulong shm_dtime
;
2802 #if TARGET_ABI_BITS == 32
2803 abi_ulong __unused2
;
2805 abi_ulong shm_ctime
;
2806 #if TARGET_ABI_BITS == 32
2807 abi_ulong __unused3
;
2811 abi_ulong shm_nattch
;
2812 unsigned long int __unused4
;
2813 unsigned long int __unused5
;
2816 static inline abi_long
target_to_host_shmid_ds(struct shmid_ds
*host_sd
,
2817 abi_ulong target_addr
)
2819 struct target_shmid_ds
*target_sd
;
2821 if (!lock_user_struct(VERIFY_READ
, target_sd
, target_addr
, 1))
2822 return -TARGET_EFAULT
;
2823 if (target_to_host_ipc_perm(&(host_sd
->shm_perm
), target_addr
))
2824 return -TARGET_EFAULT
;
2825 __get_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2826 __get_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2827 __get_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2828 __get_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2829 __get_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2830 __get_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2831 __get_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2832 unlock_user_struct(target_sd
, target_addr
, 0);
2836 static inline abi_long
host_to_target_shmid_ds(abi_ulong target_addr
,
2837 struct shmid_ds
*host_sd
)
2839 struct target_shmid_ds
*target_sd
;
2841 if (!lock_user_struct(VERIFY_WRITE
, target_sd
, target_addr
, 0))
2842 return -TARGET_EFAULT
;
2843 if (host_to_target_ipc_perm(target_addr
, &(host_sd
->shm_perm
)))
2844 return -TARGET_EFAULT
;
2845 __put_user(host_sd
->shm_segsz
, &target_sd
->shm_segsz
);
2846 __put_user(host_sd
->shm_atime
, &target_sd
->shm_atime
);
2847 __put_user(host_sd
->shm_dtime
, &target_sd
->shm_dtime
);
2848 __put_user(host_sd
->shm_ctime
, &target_sd
->shm_ctime
);
2849 __put_user(host_sd
->shm_cpid
, &target_sd
->shm_cpid
);
2850 __put_user(host_sd
->shm_lpid
, &target_sd
->shm_lpid
);
2851 __put_user(host_sd
->shm_nattch
, &target_sd
->shm_nattch
);
2852 unlock_user_struct(target_sd
, target_addr
, 1);
2856 struct target_shminfo
{
2864 static inline abi_long
host_to_target_shminfo(abi_ulong target_addr
,
2865 struct shminfo
*host_shminfo
)
2867 struct target_shminfo
*target_shminfo
;
2868 if (!lock_user_struct(VERIFY_WRITE
, target_shminfo
, target_addr
, 0))
2869 return -TARGET_EFAULT
;
2870 __put_user(host_shminfo
->shmmax
, &target_shminfo
->shmmax
);
2871 __put_user(host_shminfo
->shmmin
, &target_shminfo
->shmmin
);
2872 __put_user(host_shminfo
->shmmni
, &target_shminfo
->shmmni
);
2873 __put_user(host_shminfo
->shmseg
, &target_shminfo
->shmseg
);
2874 __put_user(host_shminfo
->shmall
, &target_shminfo
->shmall
);
2875 unlock_user_struct(target_shminfo
, target_addr
, 1);
2879 struct target_shm_info
{
2884 abi_ulong swap_attempts
;
2885 abi_ulong swap_successes
;
2888 static inline abi_long
host_to_target_shm_info(abi_ulong target_addr
,
2889 struct shm_info
*host_shm_info
)
2891 struct target_shm_info
*target_shm_info
;
2892 if (!lock_user_struct(VERIFY_WRITE
, target_shm_info
, target_addr
, 0))
2893 return -TARGET_EFAULT
;
2894 __put_user(host_shm_info
->used_ids
, &target_shm_info
->used_ids
);
2895 __put_user(host_shm_info
->shm_tot
, &target_shm_info
->shm_tot
);
2896 __put_user(host_shm_info
->shm_rss
, &target_shm_info
->shm_rss
);
2897 __put_user(host_shm_info
->shm_swp
, &target_shm_info
->shm_swp
);
2898 __put_user(host_shm_info
->swap_attempts
, &target_shm_info
->swap_attempts
);
2899 __put_user(host_shm_info
->swap_successes
, &target_shm_info
->swap_successes
);
2900 unlock_user_struct(target_shm_info
, target_addr
, 1);
2904 static inline abi_long
do_shmctl(int shmid
, int cmd
, abi_long buf
)
2906 struct shmid_ds dsarg
;
2907 struct shminfo shminfo
;
2908 struct shm_info shm_info
;
2909 abi_long ret
= -TARGET_EINVAL
;
2917 if (target_to_host_shmid_ds(&dsarg
, buf
))
2918 return -TARGET_EFAULT
;
2919 ret
= get_errno(shmctl(shmid
, cmd
, &dsarg
));
2920 if (host_to_target_shmid_ds(buf
, &dsarg
))
2921 return -TARGET_EFAULT
;
2924 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shminfo
));
2925 if (host_to_target_shminfo(buf
, &shminfo
))
2926 return -TARGET_EFAULT
;
2929 ret
= get_errno(shmctl(shmid
, cmd
, (struct shmid_ds
*)&shm_info
));
2930 if (host_to_target_shm_info(buf
, &shm_info
))
2931 return -TARGET_EFAULT
;
2936 ret
= get_errno(shmctl(shmid
, cmd
, NULL
));
2943 static inline abi_ulong
do_shmat(int shmid
, abi_ulong shmaddr
, int shmflg
)
2947 struct shmid_ds shm_info
;
2950 /* find out the length of the shared memory segment */
2951 ret
= get_errno(shmctl(shmid
, IPC_STAT
, &shm_info
));
2952 if (is_error(ret
)) {
2953 /* can't get length, bail out */
2960 host_raddr
= shmat(shmid
, (void *)g2h(shmaddr
), shmflg
);
2962 abi_ulong mmap_start
;
2964 mmap_start
= mmap_find_vma(0, shm_info
.shm_segsz
);
2966 if (mmap_start
== -1) {
2968 host_raddr
= (void *)-1;
2970 host_raddr
= shmat(shmid
, g2h(mmap_start
), shmflg
| SHM_REMAP
);
2973 if (host_raddr
== (void *)-1) {
2975 return get_errno((long)host_raddr
);
2977 raddr
=h2g((unsigned long)host_raddr
);
2979 page_set_flags(raddr
, raddr
+ shm_info
.shm_segsz
,
2980 PAGE_VALID
| PAGE_READ
|
2981 ((shmflg
& SHM_RDONLY
)? 0 : PAGE_WRITE
));
2983 for (i
= 0; i
< N_SHM_REGIONS
; i
++) {
2984 if (shm_regions
[i
].start
== 0) {
2985 shm_regions
[i
].start
= raddr
;
2986 shm_regions
[i
].size
= shm_info
.shm_segsz
;
2996 static inline abi_long
do_shmdt(abi_ulong shmaddr
)
3000 for (i
= 0; i
< N_SHM_REGIONS
; ++i
) {
3001 if (shm_regions
[i
].start
== shmaddr
) {
3002 shm_regions
[i
].start
= 0;
3003 page_set_flags(shmaddr
, shmaddr
+ shm_regions
[i
].size
, 0);
3008 return get_errno(shmdt(g2h(shmaddr
)));
3011 #ifdef TARGET_NR_ipc
3012 /* ??? This only works with linear mappings. */
3013 /* do_ipc() must return target values and target errnos. */
3014 static abi_long
do_ipc(unsigned int call
, int first
,
3015 int second
, int third
,
3016 abi_long ptr
, abi_long fifth
)
3021 version
= call
>> 16;
3026 ret
= do_semop(first
, ptr
, second
);
3030 ret
= get_errno(semget(first
, second
, third
));
3034 ret
= do_semctl(first
, second
, third
, (union target_semun
)(abi_ulong
) ptr
);
3038 ret
= get_errno(msgget(first
, second
));
3042 ret
= do_msgsnd(first
, ptr
, second
, third
);
3046 ret
= do_msgctl(first
, second
, ptr
);
3053 struct target_ipc_kludge
{
3058 if (!lock_user_struct(VERIFY_READ
, tmp
, ptr
, 1)) {
3059 ret
= -TARGET_EFAULT
;
3063 ret
= do_msgrcv(first
, tswapal(tmp
->msgp
), second
, tswapal(tmp
->msgtyp
), third
);
3065 unlock_user_struct(tmp
, ptr
, 0);
3069 ret
= do_msgrcv(first
, ptr
, second
, fifth
, third
);
3078 raddr
= do_shmat(first
, ptr
, second
);
3079 if (is_error(raddr
))
3080 return get_errno(raddr
);
3081 if (put_user_ual(raddr
, third
))
3082 return -TARGET_EFAULT
;
3086 ret
= -TARGET_EINVAL
;
3091 ret
= do_shmdt(ptr
);
3095 /* IPC_* flag values are the same on all linux platforms */
3096 ret
= get_errno(shmget(first
, second
, third
));
3099 /* IPC_* and SHM_* command values are the same on all linux platforms */
3101 ret
= do_shmctl(first
, second
, third
);
3104 gemu_log("Unsupported ipc call: %d (version %d)\n", call
, version
);
3105 ret
= -TARGET_ENOSYS
;
3112 /* kernel structure types definitions */
3114 #define STRUCT(name, ...) STRUCT_ ## name,
3115 #define STRUCT_SPECIAL(name) STRUCT_ ## name,
3117 #include "syscall_types.h"
3120 #undef STRUCT_SPECIAL
3122 #define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL };
3123 #define STRUCT_SPECIAL(name)
3124 #include "syscall_types.h"
3126 #undef STRUCT_SPECIAL
3128 typedef struct IOCTLEntry IOCTLEntry
;
3130 typedef abi_long
do_ioctl_fn(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3131 int fd
, abi_long cmd
, abi_long arg
);
3134 unsigned int target_cmd
;
3135 unsigned int host_cmd
;
3138 do_ioctl_fn
*do_ioctl
;
3139 const argtype arg_type
[5];
3142 #define IOC_R 0x0001
3143 #define IOC_W 0x0002
3144 #define IOC_RW (IOC_R | IOC_W)
3146 #define MAX_STRUCT_SIZE 4096
3148 #ifdef CONFIG_FIEMAP
3149 /* So fiemap access checks don't overflow on 32 bit systems.
3150 * This is very slightly smaller than the limit imposed by
3151 * the underlying kernel.
3153 #define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap)) \
3154 / sizeof(struct fiemap_extent))
3156 static abi_long
do_ioctl_fs_ioc_fiemap(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3157 int fd
, abi_long cmd
, abi_long arg
)
3159 /* The parameter for this ioctl is a struct fiemap followed
3160 * by an array of struct fiemap_extent whose size is set
3161 * in fiemap->fm_extent_count. The array is filled in by the
3164 int target_size_in
, target_size_out
;
3166 const argtype
*arg_type
= ie
->arg_type
;
3167 const argtype extent_arg_type
[] = { MK_STRUCT(STRUCT_fiemap_extent
) };
3170 int i
, extent_size
= thunk_type_size(extent_arg_type
, 0);
3174 assert(arg_type
[0] == TYPE_PTR
);
3175 assert(ie
->access
== IOC_RW
);
3177 target_size_in
= thunk_type_size(arg_type
, 0);
3178 argptr
= lock_user(VERIFY_READ
, arg
, target_size_in
, 1);
3180 return -TARGET_EFAULT
;
3182 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3183 unlock_user(argptr
, arg
, 0);
3184 fm
= (struct fiemap
*)buf_temp
;
3185 if (fm
->fm_extent_count
> FIEMAP_MAX_EXTENTS
) {
3186 return -TARGET_EINVAL
;
3189 outbufsz
= sizeof (*fm
) +
3190 (sizeof(struct fiemap_extent
) * fm
->fm_extent_count
);
3192 if (outbufsz
> MAX_STRUCT_SIZE
) {
3193 /* We can't fit all the extents into the fixed size buffer.
3194 * Allocate one that is large enough and use it instead.
3196 fm
= malloc(outbufsz
);
3198 return -TARGET_ENOMEM
;
3200 memcpy(fm
, buf_temp
, sizeof(struct fiemap
));
3203 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, fm
));
3204 if (!is_error(ret
)) {
3205 target_size_out
= target_size_in
;
3206 /* An extent_count of 0 means we were only counting the extents
3207 * so there are no structs to copy
3209 if (fm
->fm_extent_count
!= 0) {
3210 target_size_out
+= fm
->fm_mapped_extents
* extent_size
;
3212 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size_out
, 0);
3214 ret
= -TARGET_EFAULT
;
3216 /* Convert the struct fiemap */
3217 thunk_convert(argptr
, fm
, arg_type
, THUNK_TARGET
);
3218 if (fm
->fm_extent_count
!= 0) {
3219 p
= argptr
+ target_size_in
;
3220 /* ...and then all the struct fiemap_extents */
3221 for (i
= 0; i
< fm
->fm_mapped_extents
; i
++) {
3222 thunk_convert(p
, &fm
->fm_extents
[i
], extent_arg_type
,
3227 unlock_user(argptr
, arg
, target_size_out
);
3237 static abi_long
do_ioctl_ifconf(const IOCTLEntry
*ie
, uint8_t *buf_temp
,
3238 int fd
, abi_long cmd
, abi_long arg
)
3240 const argtype
*arg_type
= ie
->arg_type
;
3244 struct ifconf
*host_ifconf
;
3246 const argtype ifreq_arg_type
[] = { MK_STRUCT(STRUCT_sockaddr_ifreq
) };
3247 int target_ifreq_size
;
3252 abi_long target_ifc_buf
;
3256 assert(arg_type
[0] == TYPE_PTR
);
3257 assert(ie
->access
== IOC_RW
);
3260 target_size
= thunk_type_size(arg_type
, 0);
3262 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3264 return -TARGET_EFAULT
;
3265 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3266 unlock_user(argptr
, arg
, 0);
3268 host_ifconf
= (struct ifconf
*)(unsigned long)buf_temp
;
3269 target_ifc_len
= host_ifconf
->ifc_len
;
3270 target_ifc_buf
= (abi_long
)(unsigned long)host_ifconf
->ifc_buf
;
3272 target_ifreq_size
= thunk_type_size(ifreq_arg_type
, 0);
3273 nb_ifreq
= target_ifc_len
/ target_ifreq_size
;
3274 host_ifc_len
= nb_ifreq
* sizeof(struct ifreq
);
3276 outbufsz
= sizeof(*host_ifconf
) + host_ifc_len
;
3277 if (outbufsz
> MAX_STRUCT_SIZE
) {
3278 /* We can't fit all the extents into the fixed size buffer.
3279 * Allocate one that is large enough and use it instead.
3281 host_ifconf
= malloc(outbufsz
);
3283 return -TARGET_ENOMEM
;
3285 memcpy(host_ifconf
, buf_temp
, sizeof(*host_ifconf
));
3288 host_ifc_buf
= (char*)host_ifconf
+ sizeof(*host_ifconf
);
3290 host_ifconf
->ifc_len
= host_ifc_len
;
3291 host_ifconf
->ifc_buf
= host_ifc_buf
;
3293 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, host_ifconf
));
3294 if (!is_error(ret
)) {
3295 /* convert host ifc_len to target ifc_len */
3297 nb_ifreq
= host_ifconf
->ifc_len
/ sizeof(struct ifreq
);
3298 target_ifc_len
= nb_ifreq
* target_ifreq_size
;
3299 host_ifconf
->ifc_len
= target_ifc_len
;
3301 /* restore target ifc_buf */
3303 host_ifconf
->ifc_buf
= (char *)(unsigned long)target_ifc_buf
;
3305 /* copy struct ifconf to target user */
3307 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3309 return -TARGET_EFAULT
;
3310 thunk_convert(argptr
, host_ifconf
, arg_type
, THUNK_TARGET
);
3311 unlock_user(argptr
, arg
, target_size
);
3313 /* copy ifreq[] to target user */
3315 argptr
= lock_user(VERIFY_WRITE
, target_ifc_buf
, target_ifc_len
, 0);
3316 for (i
= 0; i
< nb_ifreq
; i
++) {
3317 thunk_convert(argptr
+ i
* target_ifreq_size
,
3318 host_ifc_buf
+ i
* sizeof(struct ifreq
),
3319 ifreq_arg_type
, THUNK_TARGET
);
3321 unlock_user(argptr
, target_ifc_buf
, target_ifc_len
);
3331 static abi_long
do_ioctl_dm(const IOCTLEntry
*ie
, uint8_t *buf_temp
, int fd
,
3332 abi_long cmd
, abi_long arg
)
3335 struct dm_ioctl
*host_dm
;
3336 abi_long guest_data
;
3337 uint32_t guest_data_size
;
3339 const argtype
*arg_type
= ie
->arg_type
;
3341 void *big_buf
= NULL
;
3345 target_size
= thunk_type_size(arg_type
, 0);
3346 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3348 ret
= -TARGET_EFAULT
;
3351 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3352 unlock_user(argptr
, arg
, 0);
3354 /* buf_temp is too small, so fetch things into a bigger buffer */
3355 big_buf
= g_malloc0(((struct dm_ioctl
*)buf_temp
)->data_size
* 2);
3356 memcpy(big_buf
, buf_temp
, target_size
);
3360 guest_data
= arg
+ host_dm
->data_start
;
3361 if ((guest_data
- arg
) < 0) {
3365 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3366 host_data
= (char*)host_dm
+ host_dm
->data_start
;
3368 argptr
= lock_user(VERIFY_READ
, guest_data
, guest_data_size
, 1);
3369 switch (ie
->host_cmd
) {
3371 case DM_LIST_DEVICES
:
3374 case DM_DEV_SUSPEND
:
3377 case DM_TABLE_STATUS
:
3378 case DM_TABLE_CLEAR
:
3380 case DM_LIST_VERSIONS
:
3384 case DM_DEV_SET_GEOMETRY
:
3385 /* data contains only strings */
3386 memcpy(host_data
, argptr
, guest_data_size
);
3389 memcpy(host_data
, argptr
, guest_data_size
);
3390 *(uint64_t*)host_data
= tswap64(*(uint64_t*)argptr
);
3394 void *gspec
= argptr
;
3395 void *cur_data
= host_data
;
3396 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3397 int spec_size
= thunk_type_size(arg_type
, 0);
3400 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3401 struct dm_target_spec
*spec
= cur_data
;
3405 thunk_convert(spec
, gspec
, arg_type
, THUNK_HOST
);
3406 slen
= strlen((char*)gspec
+ spec_size
) + 1;
3408 spec
->next
= sizeof(*spec
) + slen
;
3409 strcpy((char*)&spec
[1], gspec
+ spec_size
);
3411 cur_data
+= spec
->next
;
3416 ret
= -TARGET_EINVAL
;
3419 unlock_user(argptr
, guest_data
, 0);
3421 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3422 if (!is_error(ret
)) {
3423 guest_data
= arg
+ host_dm
->data_start
;
3424 guest_data_size
= host_dm
->data_size
- host_dm
->data_start
;
3425 argptr
= lock_user(VERIFY_WRITE
, guest_data
, guest_data_size
, 0);
3426 switch (ie
->host_cmd
) {
3431 case DM_DEV_SUSPEND
:
3434 case DM_TABLE_CLEAR
:
3436 case DM_DEV_SET_GEOMETRY
:
3437 /* no return data */
3439 case DM_LIST_DEVICES
:
3441 struct dm_name_list
*nl
= (void*)host_dm
+ host_dm
->data_start
;
3442 uint32_t remaining_data
= guest_data_size
;
3443 void *cur_data
= argptr
;
3444 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_name_list
) };
3445 int nl_size
= 12; /* can't use thunk_size due to alignment */
3448 uint32_t next
= nl
->next
;
3450 nl
->next
= nl_size
+ (strlen(nl
->name
) + 1);
3452 if (remaining_data
< nl
->next
) {
3453 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3456 thunk_convert(cur_data
, nl
, arg_type
, THUNK_TARGET
);
3457 strcpy(cur_data
+ nl_size
, nl
->name
);
3458 cur_data
+= nl
->next
;
3459 remaining_data
-= nl
->next
;
3463 nl
= (void*)nl
+ next
;
3468 case DM_TABLE_STATUS
:
3470 struct dm_target_spec
*spec
= (void*)host_dm
+ host_dm
->data_start
;
3471 void *cur_data
= argptr
;
3472 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_spec
) };
3473 int spec_size
= thunk_type_size(arg_type
, 0);
3476 for (i
= 0; i
< host_dm
->target_count
; i
++) {
3477 uint32_t next
= spec
->next
;
3478 int slen
= strlen((char*)&spec
[1]) + 1;
3479 spec
->next
= (cur_data
- argptr
) + spec_size
+ slen
;
3480 if (guest_data_size
< spec
->next
) {
3481 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3484 thunk_convert(cur_data
, spec
, arg_type
, THUNK_TARGET
);
3485 strcpy(cur_data
+ spec_size
, (char*)&spec
[1]);
3486 cur_data
= argptr
+ spec
->next
;
3487 spec
= (void*)host_dm
+ host_dm
->data_start
+ next
;
3493 void *hdata
= (void*)host_dm
+ host_dm
->data_start
;
3494 int count
= *(uint32_t*)hdata
;
3495 uint64_t *hdev
= hdata
+ 8;
3496 uint64_t *gdev
= argptr
+ 8;
3499 *(uint32_t*)argptr
= tswap32(count
);
3500 for (i
= 0; i
< count
; i
++) {
3501 *gdev
= tswap64(*hdev
);
3507 case DM_LIST_VERSIONS
:
3509 struct dm_target_versions
*vers
= (void*)host_dm
+ host_dm
->data_start
;
3510 uint32_t remaining_data
= guest_data_size
;
3511 void *cur_data
= argptr
;
3512 const argtype arg_type
[] = { MK_STRUCT(STRUCT_dm_target_versions
) };
3513 int vers_size
= thunk_type_size(arg_type
, 0);
3516 uint32_t next
= vers
->next
;
3518 vers
->next
= vers_size
+ (strlen(vers
->name
) + 1);
3520 if (remaining_data
< vers
->next
) {
3521 host_dm
->flags
|= DM_BUFFER_FULL_FLAG
;
3524 thunk_convert(cur_data
, vers
, arg_type
, THUNK_TARGET
);
3525 strcpy(cur_data
+ vers_size
, vers
->name
);
3526 cur_data
+= vers
->next
;
3527 remaining_data
-= vers
->next
;
3531 vers
= (void*)vers
+ next
;
3536 ret
= -TARGET_EINVAL
;
3539 unlock_user(argptr
, guest_data
, guest_data_size
);
3541 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3543 ret
= -TARGET_EFAULT
;
3546 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3547 unlock_user(argptr
, arg
, target_size
);
3554 static IOCTLEntry ioctl_entries
[] = {
3555 #define IOCTL(cmd, access, ...) \
3556 { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
3557 #define IOCTL_SPECIAL(cmd, access, dofn, ...) \
3558 { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } },
3563 /* ??? Implement proper locking for ioctls. */
3564 /* do_ioctl() Must return target values and target errnos. */
3565 static abi_long
do_ioctl(int fd
, abi_long cmd
, abi_long arg
)
3567 const IOCTLEntry
*ie
;
3568 const argtype
*arg_type
;
3570 uint8_t buf_temp
[MAX_STRUCT_SIZE
];
3576 if (ie
->target_cmd
== 0) {
3577 gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd
);
3578 return -TARGET_ENOSYS
;
3580 if (ie
->target_cmd
== cmd
)
3584 arg_type
= ie
->arg_type
;
3586 gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd
, ie
->name
);
3589 return ie
->do_ioctl(ie
, buf_temp
, fd
, cmd
, arg
);
3592 switch(arg_type
[0]) {
3595 ret
= get_errno(ioctl(fd
, ie
->host_cmd
));
3600 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, arg
));
3604 target_size
= thunk_type_size(arg_type
, 0);
3605 switch(ie
->access
) {
3607 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3608 if (!is_error(ret
)) {
3609 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3611 return -TARGET_EFAULT
;
3612 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3613 unlock_user(argptr
, arg
, target_size
);
3617 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3619 return -TARGET_EFAULT
;
3620 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3621 unlock_user(argptr
, arg
, 0);
3622 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3626 argptr
= lock_user(VERIFY_READ
, arg
, target_size
, 1);
3628 return -TARGET_EFAULT
;
3629 thunk_convert(buf_temp
, argptr
, arg_type
, THUNK_HOST
);
3630 unlock_user(argptr
, arg
, 0);
3631 ret
= get_errno(ioctl(fd
, ie
->host_cmd
, buf_temp
));
3632 if (!is_error(ret
)) {
3633 argptr
= lock_user(VERIFY_WRITE
, arg
, target_size
, 0);
3635 return -TARGET_EFAULT
;
3636 thunk_convert(argptr
, buf_temp
, arg_type
, THUNK_TARGET
);
3637 unlock_user(argptr
, arg
, target_size
);
3643 gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3644 (long)cmd
, arg_type
[0]);
3645 ret
= -TARGET_ENOSYS
;
3651 static const bitmask_transtbl iflag_tbl
[] = {
3652 { TARGET_IGNBRK
, TARGET_IGNBRK
, IGNBRK
, IGNBRK
},
3653 { TARGET_BRKINT
, TARGET_BRKINT
, BRKINT
, BRKINT
},
3654 { TARGET_IGNPAR
, TARGET_IGNPAR
, IGNPAR
, IGNPAR
},
3655 { TARGET_PARMRK
, TARGET_PARMRK
, PARMRK
, PARMRK
},
3656 { TARGET_INPCK
, TARGET_INPCK
, INPCK
, INPCK
},
3657 { TARGET_ISTRIP
, TARGET_ISTRIP
, ISTRIP
, ISTRIP
},
3658 { TARGET_INLCR
, TARGET_INLCR
, INLCR
, INLCR
},
3659 { TARGET_IGNCR
, TARGET_IGNCR
, IGNCR
, IGNCR
},
3660 { TARGET_ICRNL
, TARGET_ICRNL
, ICRNL
, ICRNL
},
3661 { TARGET_IUCLC
, TARGET_IUCLC
, IUCLC
, IUCLC
},
3662 { TARGET_IXON
, TARGET_IXON
, IXON
, IXON
},
3663 { TARGET_IXANY
, TARGET_IXANY
, IXANY
, IXANY
},
3664 { TARGET_IXOFF
, TARGET_IXOFF
, IXOFF
, IXOFF
},
3665 { TARGET_IMAXBEL
, TARGET_IMAXBEL
, IMAXBEL
, IMAXBEL
},
3669 static const bitmask_transtbl oflag_tbl
[] = {
3670 { TARGET_OPOST
, TARGET_OPOST
, OPOST
, OPOST
},
3671 { TARGET_OLCUC
, TARGET_OLCUC
, OLCUC
, OLCUC
},
3672 { TARGET_ONLCR
, TARGET_ONLCR
, ONLCR
, ONLCR
},
3673 { TARGET_OCRNL
, TARGET_OCRNL
, OCRNL
, OCRNL
},
3674 { TARGET_ONOCR
, TARGET_ONOCR
, ONOCR
, ONOCR
},
3675 { TARGET_ONLRET
, TARGET_ONLRET
, ONLRET
, ONLRET
},
3676 { TARGET_OFILL
, TARGET_OFILL
, OFILL
, OFILL
},
3677 { TARGET_OFDEL
, TARGET_OFDEL
, OFDEL
, OFDEL
},
3678 { TARGET_NLDLY
, TARGET_NL0
, NLDLY
, NL0
},
3679 { TARGET_NLDLY
, TARGET_NL1
, NLDLY
, NL1
},
3680 { TARGET_CRDLY
, TARGET_CR0
, CRDLY
, CR0
},
3681 { TARGET_CRDLY
, TARGET_CR1
, CRDLY
, CR1
},
3682 { TARGET_CRDLY
, TARGET_CR2
, CRDLY
, CR2
},
3683 { TARGET_CRDLY
, TARGET_CR3
, CRDLY
, CR3
},
3684 { TARGET_TABDLY
, TARGET_TAB0
, TABDLY
, TAB0
},
3685 { TARGET_TABDLY
, TARGET_TAB1
, TABDLY
, TAB1
},
3686 { TARGET_TABDLY
, TARGET_TAB2
, TABDLY
, TAB2
},
3687 { TARGET_TABDLY
, TARGET_TAB3
, TABDLY
, TAB3
},
3688 { TARGET_BSDLY
, TARGET_BS0
, BSDLY
, BS0
},
3689 { TARGET_BSDLY
, TARGET_BS1
, BSDLY
, BS1
},
3690 { TARGET_VTDLY
, TARGET_VT0
, VTDLY
, VT0
},
3691 { TARGET_VTDLY
, TARGET_VT1
, VTDLY
, VT1
},
3692 { TARGET_FFDLY
, TARGET_FF0
, FFDLY
, FF0
},
3693 { TARGET_FFDLY
, TARGET_FF1
, FFDLY
, FF1
},
3697 static const bitmask_transtbl cflag_tbl
[] = {
3698 { TARGET_CBAUD
, TARGET_B0
, CBAUD
, B0
},
3699 { TARGET_CBAUD
, TARGET_B50
, CBAUD
, B50
},
3700 { TARGET_CBAUD
, TARGET_B75
, CBAUD
, B75
},
3701 { TARGET_CBAUD
, TARGET_B110
, CBAUD
, B110
},
3702 { TARGET_CBAUD
, TARGET_B134
, CBAUD
, B134
},
3703 { TARGET_CBAUD
, TARGET_B150
, CBAUD
, B150
},
3704 { TARGET_CBAUD
, TARGET_B200
, CBAUD
, B200
},
3705 { TARGET_CBAUD
, TARGET_B300
, CBAUD
, B300
},
3706 { TARGET_CBAUD
, TARGET_B600
, CBAUD
, B600
},
3707 { TARGET_CBAUD
, TARGET_B1200
, CBAUD
, B1200
},
3708 { TARGET_CBAUD
, TARGET_B1800
, CBAUD
, B1800
},
3709 { TARGET_CBAUD
, TARGET_B2400
, CBAUD
, B2400
},
3710 { TARGET_CBAUD
, TARGET_B4800
, CBAUD
, B4800
},
3711 { TARGET_CBAUD
, TARGET_B9600
, CBAUD
, B9600
},
3712 { TARGET_CBAUD
, TARGET_B19200
, CBAUD
, B19200
},
3713 { TARGET_CBAUD
, TARGET_B38400
, CBAUD
, B38400
},
3714 { TARGET_CBAUD
, TARGET_B57600
, CBAUD
, B57600
},
3715 { TARGET_CBAUD
, TARGET_B115200
, CBAUD
, B115200
},
3716 { TARGET_CBAUD
, TARGET_B230400
, CBAUD
, B230400
},
3717 { TARGET_CBAUD
, TARGET_B460800
, CBAUD
, B460800
},
3718 { TARGET_CSIZE
, TARGET_CS5
, CSIZE
, CS5
},
3719 { TARGET_CSIZE
, TARGET_CS6
, CSIZE
, CS6
},
3720 { TARGET_CSIZE
, TARGET_CS7
, CSIZE
, CS7
},
3721 { TARGET_CSIZE
, TARGET_CS8
, CSIZE
, CS8
},
3722 { TARGET_CSTOPB
, TARGET_CSTOPB
, CSTOPB
, CSTOPB
},
3723 { TARGET_CREAD
, TARGET_CREAD
, CREAD
, CREAD
},
3724 { TARGET_PARENB
, TARGET_PARENB
, PARENB
, PARENB
},
3725 { TARGET_PARODD
, TARGET_PARODD
, PARODD
, PARODD
},
3726 { TARGET_HUPCL
, TARGET_HUPCL
, HUPCL
, HUPCL
},
3727 { TARGET_CLOCAL
, TARGET_CLOCAL
, CLOCAL
, CLOCAL
},
3728 { TARGET_CRTSCTS
, TARGET_CRTSCTS
, CRTSCTS
, CRTSCTS
},
3732 static const bitmask_transtbl lflag_tbl
[] = {
3733 { TARGET_ISIG
, TARGET_ISIG
, ISIG
, ISIG
},
3734 { TARGET_ICANON
, TARGET_ICANON
, ICANON
, ICANON
},
3735 { TARGET_XCASE
, TARGET_XCASE
, XCASE
, XCASE
},
3736 { TARGET_ECHO
, TARGET_ECHO
, ECHO
, ECHO
},
3737 { TARGET_ECHOE
, TARGET_ECHOE
, ECHOE
, ECHOE
},
3738 { TARGET_ECHOK
, TARGET_ECHOK
, ECHOK
, ECHOK
},
3739 { TARGET_ECHONL
, TARGET_ECHONL
, ECHONL
, ECHONL
},
3740 { TARGET_NOFLSH
, TARGET_NOFLSH
, NOFLSH
, NOFLSH
},
3741 { TARGET_TOSTOP
, TARGET_TOSTOP
, TOSTOP
, TOSTOP
},
3742 { TARGET_ECHOCTL
, TARGET_ECHOCTL
, ECHOCTL
, ECHOCTL
},
3743 { TARGET_ECHOPRT
, TARGET_ECHOPRT
, ECHOPRT
, ECHOPRT
},
3744 { TARGET_ECHOKE
, TARGET_ECHOKE
, ECHOKE
, ECHOKE
},
3745 { TARGET_FLUSHO
, TARGET_FLUSHO
, FLUSHO
, FLUSHO
},
3746 { TARGET_PENDIN
, TARGET_PENDIN
, PENDIN
, PENDIN
},
3747 { TARGET_IEXTEN
, TARGET_IEXTEN
, IEXTEN
, IEXTEN
},
3751 static void target_to_host_termios (void *dst
, const void *src
)
3753 struct host_termios
*host
= dst
;
3754 const struct target_termios
*target
= src
;
3757 target_to_host_bitmask(tswap32(target
->c_iflag
), iflag_tbl
);
3759 target_to_host_bitmask(tswap32(target
->c_oflag
), oflag_tbl
);
3761 target_to_host_bitmask(tswap32(target
->c_cflag
), cflag_tbl
);
3763 target_to_host_bitmask(tswap32(target
->c_lflag
), lflag_tbl
);
3764 host
->c_line
= target
->c_line
;
3766 memset(host
->c_cc
, 0, sizeof(host
->c_cc
));
3767 host
->c_cc
[VINTR
] = target
->c_cc
[TARGET_VINTR
];
3768 host
->c_cc
[VQUIT
] = target
->c_cc
[TARGET_VQUIT
];
3769 host
->c_cc
[VERASE
] = target
->c_cc
[TARGET_VERASE
];
3770 host
->c_cc
[VKILL
] = target
->c_cc
[TARGET_VKILL
];
3771 host
->c_cc
[VEOF
] = target
->c_cc
[TARGET_VEOF
];
3772 host
->c_cc
[VTIME
] = target
->c_cc
[TARGET_VTIME
];
3773 host
->c_cc
[VMIN
] = target
->c_cc
[TARGET_VMIN
];
3774 host
->c_cc
[VSWTC
] = target
->c_cc
[TARGET_VSWTC
];
3775 host
->c_cc
[VSTART
] = target
->c_cc
[TARGET_VSTART
];
3776 host
->c_cc
[VSTOP
] = target
->c_cc
[TARGET_VSTOP
];
3777 host
->c_cc
[VSUSP
] = target
->c_cc
[TARGET_VSUSP
];
3778 host
->c_cc
[VEOL
] = target
->c_cc
[TARGET_VEOL
];
3779 host
->c_cc
[VREPRINT
] = target
->c_cc
[TARGET_VREPRINT
];
3780 host
->c_cc
[VDISCARD
] = target
->c_cc
[TARGET_VDISCARD
];
3781 host
->c_cc
[VWERASE
] = target
->c_cc
[TARGET_VWERASE
];
3782 host
->c_cc
[VLNEXT
] = target
->c_cc
[TARGET_VLNEXT
];
3783 host
->c_cc
[VEOL2
] = target
->c_cc
[TARGET_VEOL2
];
3786 static void host_to_target_termios (void *dst
, const void *src
)
3788 struct target_termios
*target
= dst
;
3789 const struct host_termios
*host
= src
;
3792 tswap32(host_to_target_bitmask(host
->c_iflag
, iflag_tbl
));
3794 tswap32(host_to_target_bitmask(host
->c_oflag
, oflag_tbl
));
3796 tswap32(host_to_target_bitmask(host
->c_cflag
, cflag_tbl
));
3798 tswap32(host_to_target_bitmask(host
->c_lflag
, lflag_tbl
));
3799 target
->c_line
= host
->c_line
;
3801 memset(target
->c_cc
, 0, sizeof(target
->c_cc
));
3802 target
->c_cc
[TARGET_VINTR
] = host
->c_cc
[VINTR
];
3803 target
->c_cc
[TARGET_VQUIT
] = host
->c_cc
[VQUIT
];
3804 target
->c_cc
[TARGET_VERASE
] = host
->c_cc
[VERASE
];
3805 target
->c_cc
[TARGET_VKILL
] = host
->c_cc
[VKILL
];
3806 target
->c_cc
[TARGET_VEOF
] = host
->c_cc
[VEOF
];
3807 target
->c_cc
[TARGET_VTIME
] = host
->c_cc
[VTIME
];
3808 target
->c_cc
[TARGET_VMIN
] = host
->c_cc
[VMIN
];
3809 target
->c_cc
[TARGET_VSWTC
] = host
->c_cc
[VSWTC
];
3810 target
->c_cc
[TARGET_VSTART
] = host
->c_cc
[VSTART
];
3811 target
->c_cc
[TARGET_VSTOP
] = host
->c_cc
[VSTOP
];
3812 target
->c_cc
[TARGET_VSUSP
] = host
->c_cc
[VSUSP
];
3813 target
->c_cc
[TARGET_VEOL
] = host
->c_cc
[VEOL
];
3814 target
->c_cc
[TARGET_VREPRINT
] = host
->c_cc
[VREPRINT
];
3815 target
->c_cc
[TARGET_VDISCARD
] = host
->c_cc
[VDISCARD
];
3816 target
->c_cc
[TARGET_VWERASE
] = host
->c_cc
[VWERASE
];
3817 target
->c_cc
[TARGET_VLNEXT
] = host
->c_cc
[VLNEXT
];
3818 target
->c_cc
[TARGET_VEOL2
] = host
->c_cc
[VEOL2
];
3821 static const StructEntry struct_termios_def
= {
3822 .convert
= { host_to_target_termios
, target_to_host_termios
},
3823 .size
= { sizeof(struct target_termios
), sizeof(struct host_termios
) },
3824 .align
= { __alignof__(struct target_termios
), __alignof__(struct host_termios
) },
3827 static bitmask_transtbl mmap_flags_tbl
[] = {
3828 { TARGET_MAP_SHARED
, TARGET_MAP_SHARED
, MAP_SHARED
, MAP_SHARED
},
3829 { TARGET_MAP_PRIVATE
, TARGET_MAP_PRIVATE
, MAP_PRIVATE
, MAP_PRIVATE
},
3830 { TARGET_MAP_FIXED
, TARGET_MAP_FIXED
, MAP_FIXED
, MAP_FIXED
},
3831 { TARGET_MAP_ANONYMOUS
, TARGET_MAP_ANONYMOUS
, MAP_ANONYMOUS
, MAP_ANONYMOUS
},
3832 { TARGET_MAP_GROWSDOWN
, TARGET_MAP_GROWSDOWN
, MAP_GROWSDOWN
, MAP_GROWSDOWN
},
3833 { TARGET_MAP_DENYWRITE
, TARGET_MAP_DENYWRITE
, MAP_DENYWRITE
, MAP_DENYWRITE
},
3834 { TARGET_MAP_EXECUTABLE
, TARGET_MAP_EXECUTABLE
, MAP_EXECUTABLE
, MAP_EXECUTABLE
},
3835 { TARGET_MAP_LOCKED
, TARGET_MAP_LOCKED
, MAP_LOCKED
, MAP_LOCKED
},
3839 #if defined(TARGET_I386)
3841 /* NOTE: there is really one LDT for all the threads */
3842 static uint8_t *ldt_table
;
3844 static abi_long
read_ldt(abi_ulong ptr
, unsigned long bytecount
)
3851 size
= TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
;
3852 if (size
> bytecount
)
3854 p
= lock_user(VERIFY_WRITE
, ptr
, size
, 0);
3856 return -TARGET_EFAULT
;
3857 /* ??? Should this by byteswapped? */
3858 memcpy(p
, ldt_table
, size
);
3859 unlock_user(p
, ptr
, size
);
3863 /* XXX: add locking support */
3864 static abi_long
write_ldt(CPUX86State
*env
,
3865 abi_ulong ptr
, unsigned long bytecount
, int oldmode
)
3867 struct target_modify_ldt_ldt_s ldt_info
;
3868 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3869 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3870 int seg_not_present
, useable
, lm
;
3871 uint32_t *lp
, entry_1
, entry_2
;
3873 if (bytecount
!= sizeof(ldt_info
))
3874 return -TARGET_EINVAL
;
3875 if (!lock_user_struct(VERIFY_READ
, target_ldt_info
, ptr
, 1))
3876 return -TARGET_EFAULT
;
3877 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3878 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
3879 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3880 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3881 unlock_user_struct(target_ldt_info
, ptr
, 0);
3883 if (ldt_info
.entry_number
>= TARGET_LDT_ENTRIES
)
3884 return -TARGET_EINVAL
;
3885 seg_32bit
= ldt_info
.flags
& 1;
3886 contents
= (ldt_info
.flags
>> 1) & 3;
3887 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
3888 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
3889 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
3890 useable
= (ldt_info
.flags
>> 6) & 1;
3894 lm
= (ldt_info
.flags
>> 7) & 1;
3896 if (contents
== 3) {
3898 return -TARGET_EINVAL
;
3899 if (seg_not_present
== 0)
3900 return -TARGET_EINVAL
;
3902 /* allocate the LDT */
3904 env
->ldt
.base
= target_mmap(0,
3905 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
,
3906 PROT_READ
|PROT_WRITE
,
3907 MAP_ANONYMOUS
|MAP_PRIVATE
, -1, 0);
3908 if (env
->ldt
.base
== -1)
3909 return -TARGET_ENOMEM
;
3910 memset(g2h(env
->ldt
.base
), 0,
3911 TARGET_LDT_ENTRIES
* TARGET_LDT_ENTRY_SIZE
);
3912 env
->ldt
.limit
= 0xffff;
3913 ldt_table
= g2h(env
->ldt
.base
);
3916 /* NOTE: same code as Linux kernel */
3917 /* Allow LDTs to be cleared by the user. */
3918 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
3921 read_exec_only
== 1 &&
3923 limit_in_pages
== 0 &&
3924 seg_not_present
== 1 &&
3932 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
3933 (ldt_info
.limit
& 0x0ffff);
3934 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
3935 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
3936 (ldt_info
.limit
& 0xf0000) |
3937 ((read_exec_only
^ 1) << 9) |
3939 ((seg_not_present
^ 1) << 15) |
3941 (limit_in_pages
<< 23) |
3945 entry_2
|= (useable
<< 20);
3947 /* Install the new entry ... */
3949 lp
= (uint32_t *)(ldt_table
+ (ldt_info
.entry_number
<< 3));
3950 lp
[0] = tswap32(entry_1
);
3951 lp
[1] = tswap32(entry_2
);
3955 /* specific and weird i386 syscalls */
3956 static abi_long
do_modify_ldt(CPUX86State
*env
, int func
, abi_ulong ptr
,
3957 unsigned long bytecount
)
3963 ret
= read_ldt(ptr
, bytecount
);
3966 ret
= write_ldt(env
, ptr
, bytecount
, 1);
3969 ret
= write_ldt(env
, ptr
, bytecount
, 0);
3972 ret
= -TARGET_ENOSYS
;
3978 #if defined(TARGET_I386) && defined(TARGET_ABI32)
3979 static abi_long
do_set_thread_area(CPUX86State
*env
, abi_ulong ptr
)
3981 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
3982 struct target_modify_ldt_ldt_s ldt_info
;
3983 struct target_modify_ldt_ldt_s
*target_ldt_info
;
3984 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
;
3985 int seg_not_present
, useable
, lm
;
3986 uint32_t *lp
, entry_1
, entry_2
;
3989 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
3990 if (!target_ldt_info
)
3991 return -TARGET_EFAULT
;
3992 ldt_info
.entry_number
= tswap32(target_ldt_info
->entry_number
);
3993 ldt_info
.base_addr
= tswapal(target_ldt_info
->base_addr
);
3994 ldt_info
.limit
= tswap32(target_ldt_info
->limit
);
3995 ldt_info
.flags
= tswap32(target_ldt_info
->flags
);
3996 if (ldt_info
.entry_number
== -1) {
3997 for (i
=TARGET_GDT_ENTRY_TLS_MIN
; i
<=TARGET_GDT_ENTRY_TLS_MAX
; i
++) {
3998 if (gdt_table
[i
] == 0) {
3999 ldt_info
.entry_number
= i
;
4000 target_ldt_info
->entry_number
= tswap32(i
);
4005 unlock_user_struct(target_ldt_info
, ptr
, 1);
4007 if (ldt_info
.entry_number
< TARGET_GDT_ENTRY_TLS_MIN
||
4008 ldt_info
.entry_number
> TARGET_GDT_ENTRY_TLS_MAX
)
4009 return -TARGET_EINVAL
;
4010 seg_32bit
= ldt_info
.flags
& 1;
4011 contents
= (ldt_info
.flags
>> 1) & 3;
4012 read_exec_only
= (ldt_info
.flags
>> 3) & 1;
4013 limit_in_pages
= (ldt_info
.flags
>> 4) & 1;
4014 seg_not_present
= (ldt_info
.flags
>> 5) & 1;
4015 useable
= (ldt_info
.flags
>> 6) & 1;
4019 lm
= (ldt_info
.flags
>> 7) & 1;
4022 if (contents
== 3) {
4023 if (seg_not_present
== 0)
4024 return -TARGET_EINVAL
;
4027 /* NOTE: same code as Linux kernel */
4028 /* Allow LDTs to be cleared by the user. */
4029 if (ldt_info
.base_addr
== 0 && ldt_info
.limit
== 0) {
4030 if ((contents
== 0 &&
4031 read_exec_only
== 1 &&
4033 limit_in_pages
== 0 &&
4034 seg_not_present
== 1 &&
4042 entry_1
= ((ldt_info
.base_addr
& 0x0000ffff) << 16) |
4043 (ldt_info
.limit
& 0x0ffff);
4044 entry_2
= (ldt_info
.base_addr
& 0xff000000) |
4045 ((ldt_info
.base_addr
& 0x00ff0000) >> 16) |
4046 (ldt_info
.limit
& 0xf0000) |
4047 ((read_exec_only
^ 1) << 9) |
4049 ((seg_not_present
^ 1) << 15) |
4051 (limit_in_pages
<< 23) |
4056 /* Install the new entry ... */
4058 lp
= (uint32_t *)(gdt_table
+ ldt_info
.entry_number
);
4059 lp
[0] = tswap32(entry_1
);
4060 lp
[1] = tswap32(entry_2
);
4064 static abi_long
do_get_thread_area(CPUX86State
*env
, abi_ulong ptr
)
4066 struct target_modify_ldt_ldt_s
*target_ldt_info
;
4067 uint64_t *gdt_table
= g2h(env
->gdt
.base
);
4068 uint32_t base_addr
, limit
, flags
;
4069 int seg_32bit
, contents
, read_exec_only
, limit_in_pages
, idx
;
4070 int seg_not_present
, useable
, lm
;
4071 uint32_t *lp
, entry_1
, entry_2
;
4073 lock_user_struct(VERIFY_WRITE
, target_ldt_info
, ptr
, 1);
4074 if (!target_ldt_info
)
4075 return -TARGET_EFAULT
;
4076 idx
= tswap32(target_ldt_info
->entry_number
);
4077 if (idx
< TARGET_GDT_ENTRY_TLS_MIN
||
4078 idx
> TARGET_GDT_ENTRY_TLS_MAX
) {
4079 unlock_user_struct(target_ldt_info
, ptr
, 1);
4080 return -TARGET_EINVAL
;
4082 lp
= (uint32_t *)(gdt_table
+ idx
);
4083 entry_1
= tswap32(lp
[0]);
4084 entry_2
= tswap32(lp
[1]);
4086 read_exec_only
= ((entry_2
>> 9) & 1) ^ 1;
4087 contents
= (entry_2
>> 10) & 3;
4088 seg_not_present
= ((entry_2
>> 15) & 1) ^ 1;
4089 seg_32bit
= (entry_2
>> 22) & 1;
4090 limit_in_pages
= (entry_2
>> 23) & 1;
4091 useable
= (entry_2
>> 20) & 1;
4095 lm
= (entry_2
>> 21) & 1;
4097 flags
= (seg_32bit
<< 0) | (contents
<< 1) |
4098 (read_exec_only
<< 3) | (limit_in_pages
<< 4) |
4099 (seg_not_present
<< 5) | (useable
<< 6) | (lm
<< 7);
4100 limit
= (entry_1
& 0xffff) | (entry_2
& 0xf0000);
4101 base_addr
= (entry_1
>> 16) |
4102 (entry_2
& 0xff000000) |
4103 ((entry_2
& 0xff) << 16);
4104 target_ldt_info
->base_addr
= tswapal(base_addr
);
4105 target_ldt_info
->limit
= tswap32(limit
);
4106 target_ldt_info
->flags
= tswap32(flags
);
4107 unlock_user_struct(target_ldt_info
, ptr
, 1);
4110 #endif /* TARGET_I386 && TARGET_ABI32 */
4112 #ifndef TARGET_ABI32
4113 static abi_long
do_arch_prctl(CPUX86State
*env
, int code
, abi_ulong addr
)
4120 case TARGET_ARCH_SET_GS
:
4121 case TARGET_ARCH_SET_FS
:
4122 if (code
== TARGET_ARCH_SET_GS
)
4126 cpu_x86_load_seg(env
, idx
, 0);
4127 env
->segs
[idx
].base
= addr
;
4129 case TARGET_ARCH_GET_GS
:
4130 case TARGET_ARCH_GET_FS
:
4131 if (code
== TARGET_ARCH_GET_GS
)
4135 val
= env
->segs
[idx
].base
;
4136 if (put_user(val
, addr
, abi_ulong
))
4137 ret
= -TARGET_EFAULT
;
4140 ret
= -TARGET_EINVAL
;
4147 #endif /* defined(TARGET_I386) */
4149 #define NEW_STACK_SIZE 0x40000
4151 #if defined(CONFIG_USE_NPTL)
4153 static pthread_mutex_t clone_lock
= PTHREAD_MUTEX_INITIALIZER
;
4156 pthread_mutex_t mutex
;
4157 pthread_cond_t cond
;
4160 abi_ulong child_tidptr
;
4161 abi_ulong parent_tidptr
;
4165 static void *clone_func(void *arg
)
4167 new_thread_info
*info
= arg
;
4173 cpu
= ENV_GET_CPU(env
);
4175 ts
= (TaskState
*)env
->opaque
;
4176 info
->tid
= gettid();
4177 cpu
->host_tid
= info
->tid
;
4179 if (info
->child_tidptr
)
4180 put_user_u32(info
->tid
, info
->child_tidptr
);
4181 if (info
->parent_tidptr
)
4182 put_user_u32(info
->tid
, info
->parent_tidptr
);
4183 /* Enable signals. */
4184 sigprocmask(SIG_SETMASK
, &info
->sigmask
, NULL
);
4185 /* Signal to the parent that we're ready. */
4186 pthread_mutex_lock(&info
->mutex
);
4187 pthread_cond_broadcast(&info
->cond
);
4188 pthread_mutex_unlock(&info
->mutex
);
4189 /* Wait until the parent has finshed initializing the tls state. */
4190 pthread_mutex_lock(&clone_lock
);
4191 pthread_mutex_unlock(&clone_lock
);
4198 static int clone_func(void *arg
)
4200 CPUArchState
*env
= arg
;
4207 /* do_fork() Must return host values and target errnos (unlike most
4208 do_*() functions). */
4209 static int do_fork(CPUArchState
*env
, unsigned int flags
, abi_ulong newsp
,
4210 abi_ulong parent_tidptr
, target_ulong newtls
,
4211 abi_ulong child_tidptr
)
4215 CPUArchState
*new_env
;
4216 #if defined(CONFIG_USE_NPTL)
4217 unsigned int nptl_flags
;
4223 /* Emulate vfork() with fork() */
4224 if (flags
& CLONE_VFORK
)
4225 flags
&= ~(CLONE_VFORK
| CLONE_VM
);
4227 if (flags
& CLONE_VM
) {
4228 TaskState
*parent_ts
= (TaskState
*)env
->opaque
;
4229 #if defined(CONFIG_USE_NPTL)
4230 new_thread_info info
;
4231 pthread_attr_t attr
;
4233 ts
= g_malloc0(sizeof(TaskState
));
4234 init_task_state(ts
);
4235 /* we create a new CPU instance. */
4236 new_env
= cpu_copy(env
);
4237 #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
4238 cpu_reset(ENV_GET_CPU(new_env
));
4240 /* Init regs that differ from the parent. */
4241 cpu_clone_regs(new_env
, newsp
);
4242 new_env
->opaque
= ts
;
4243 ts
->bprm
= parent_ts
->bprm
;
4244 ts
->info
= parent_ts
->info
;
4245 #if defined(CONFIG_USE_NPTL)
4247 flags
&= ~CLONE_NPTL_FLAGS2
;
4249 if (nptl_flags
& CLONE_CHILD_CLEARTID
) {
4250 ts
->child_tidptr
= child_tidptr
;
4253 if (nptl_flags
& CLONE_SETTLS
)
4254 cpu_set_tls (new_env
, newtls
);
4256 /* Grab a mutex so that thread setup appears atomic. */
4257 pthread_mutex_lock(&clone_lock
);
4259 memset(&info
, 0, sizeof(info
));
4260 pthread_mutex_init(&info
.mutex
, NULL
);
4261 pthread_mutex_lock(&info
.mutex
);
4262 pthread_cond_init(&info
.cond
, NULL
);
4264 if (nptl_flags
& CLONE_CHILD_SETTID
)
4265 info
.child_tidptr
= child_tidptr
;
4266 if (nptl_flags
& CLONE_PARENT_SETTID
)
4267 info
.parent_tidptr
= parent_tidptr
;
4269 ret
= pthread_attr_init(&attr
);
4270 ret
= pthread_attr_setstacksize(&attr
, NEW_STACK_SIZE
);
4271 ret
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
4272 /* It is not safe to deliver signals until the child has finished
4273 initializing, so temporarily block all signals. */
4274 sigfillset(&sigmask
);
4275 sigprocmask(SIG_BLOCK
, &sigmask
, &info
.sigmask
);
4277 ret
= pthread_create(&info
.thread
, &attr
, clone_func
, &info
);
4278 /* TODO: Free new CPU state if thread creation failed. */
4280 sigprocmask(SIG_SETMASK
, &info
.sigmask
, NULL
);
4281 pthread_attr_destroy(&attr
);
4283 /* Wait for the child to initialize. */
4284 pthread_cond_wait(&info
.cond
, &info
.mutex
);
4286 if (flags
& CLONE_PARENT_SETTID
)
4287 put_user_u32(ret
, parent_tidptr
);
4291 pthread_mutex_unlock(&info
.mutex
);
4292 pthread_cond_destroy(&info
.cond
);
4293 pthread_mutex_destroy(&info
.mutex
);
4294 pthread_mutex_unlock(&clone_lock
);
4296 if (flags
& CLONE_NPTL_FLAGS2
)
4298 /* This is probably going to die very quickly, but do it anyway. */
4299 new_stack
= g_malloc0 (NEW_STACK_SIZE
);
4301 ret
= __clone2(clone_func
, new_stack
, NEW_STACK_SIZE
, flags
, new_env
);
4303 ret
= clone(clone_func
, new_stack
+ NEW_STACK_SIZE
, flags
, new_env
);
4307 /* if no CLONE_VM, we consider it is a fork */
4308 if ((flags
& ~(CSIGNAL
| CLONE_NPTL_FLAGS2
)) != 0)
4313 /* Child Process. */
4314 cpu_clone_regs(env
, newsp
);
4316 #if defined(CONFIG_USE_NPTL)
4317 /* There is a race condition here. The parent process could
4318 theoretically read the TID in the child process before the child
4319 tid is set. This would require using either ptrace
4320 (not implemented) or having *_tidptr to point at a shared memory
4321 mapping. We can't repeat the spinlock hack used above because
4322 the child process gets its own copy of the lock. */
4323 if (flags
& CLONE_CHILD_SETTID
)
4324 put_user_u32(gettid(), child_tidptr
);
4325 if (flags
& CLONE_PARENT_SETTID
)
4326 put_user_u32(gettid(), parent_tidptr
);
4327 ts
= (TaskState
*)env
->opaque
;
4328 if (flags
& CLONE_SETTLS
)
4329 cpu_set_tls (env
, newtls
);
4330 if (flags
& CLONE_CHILD_CLEARTID
)
4331 ts
->child_tidptr
= child_tidptr
;
4340 /* warning : doesn't handle linux specific flags... */
4341 static int target_to_host_fcntl_cmd(int cmd
)
4344 case TARGET_F_DUPFD
:
4345 case TARGET_F_GETFD
:
4346 case TARGET_F_SETFD
:
4347 case TARGET_F_GETFL
:
4348 case TARGET_F_SETFL
:
4350 case TARGET_F_GETLK
:
4352 case TARGET_F_SETLK
:
4354 case TARGET_F_SETLKW
:
4356 case TARGET_F_GETOWN
:
4358 case TARGET_F_SETOWN
:
4360 case TARGET_F_GETSIG
:
4362 case TARGET_F_SETSIG
:
4364 #if TARGET_ABI_BITS == 32
4365 case TARGET_F_GETLK64
:
4367 case TARGET_F_SETLK64
:
4369 case TARGET_F_SETLKW64
:
4372 case TARGET_F_SETLEASE
:
4374 case TARGET_F_GETLEASE
:
4376 #ifdef F_DUPFD_CLOEXEC
4377 case TARGET_F_DUPFD_CLOEXEC
:
4378 return F_DUPFD_CLOEXEC
;
4380 case TARGET_F_NOTIFY
:
4383 return -TARGET_EINVAL
;
4385 return -TARGET_EINVAL
;
4388 #define TRANSTBL_CONVERT(a) { -1, TARGET_##a, -1, a }
4389 static const bitmask_transtbl flock_tbl
[] = {
4390 TRANSTBL_CONVERT(F_RDLCK
),
4391 TRANSTBL_CONVERT(F_WRLCK
),
4392 TRANSTBL_CONVERT(F_UNLCK
),
4393 TRANSTBL_CONVERT(F_EXLCK
),
4394 TRANSTBL_CONVERT(F_SHLCK
),
4398 static abi_long
do_fcntl(int fd
, int cmd
, abi_ulong arg
)
4401 struct target_flock
*target_fl
;
4402 struct flock64 fl64
;
4403 struct target_flock64
*target_fl64
;
4405 int host_cmd
= target_to_host_fcntl_cmd(cmd
);
4407 if (host_cmd
== -TARGET_EINVAL
)
4411 case TARGET_F_GETLK
:
4412 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4413 return -TARGET_EFAULT
;
4415 target_to_host_bitmask(tswap16(target_fl
->l_type
), flock_tbl
);
4416 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4417 fl
.l_start
= tswapal(target_fl
->l_start
);
4418 fl
.l_len
= tswapal(target_fl
->l_len
);
4419 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4420 unlock_user_struct(target_fl
, arg
, 0);
4421 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4423 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg
, 0))
4424 return -TARGET_EFAULT
;
4426 host_to_target_bitmask(tswap16(fl
.l_type
), flock_tbl
);
4427 target_fl
->l_whence
= tswap16(fl
.l_whence
);
4428 target_fl
->l_start
= tswapal(fl
.l_start
);
4429 target_fl
->l_len
= tswapal(fl
.l_len
);
4430 target_fl
->l_pid
= tswap32(fl
.l_pid
);
4431 unlock_user_struct(target_fl
, arg
, 1);
4435 case TARGET_F_SETLK
:
4436 case TARGET_F_SETLKW
:
4437 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg
, 1))
4438 return -TARGET_EFAULT
;
4440 target_to_host_bitmask(tswap16(target_fl
->l_type
), flock_tbl
);
4441 fl
.l_whence
= tswap16(target_fl
->l_whence
);
4442 fl
.l_start
= tswapal(target_fl
->l_start
);
4443 fl
.l_len
= tswapal(target_fl
->l_len
);
4444 fl
.l_pid
= tswap32(target_fl
->l_pid
);
4445 unlock_user_struct(target_fl
, arg
, 0);
4446 ret
= get_errno(fcntl(fd
, host_cmd
, &fl
));
4449 case TARGET_F_GETLK64
:
4450 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4451 return -TARGET_EFAULT
;
4453 target_to_host_bitmask(tswap16(target_fl64
->l_type
), flock_tbl
) >> 1;
4454 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4455 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4456 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4457 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4458 unlock_user_struct(target_fl64
, arg
, 0);
4459 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4461 if (!lock_user_struct(VERIFY_WRITE
, target_fl64
, arg
, 0))
4462 return -TARGET_EFAULT
;
4463 target_fl64
->l_type
=
4464 host_to_target_bitmask(tswap16(fl64
.l_type
), flock_tbl
) >> 1;
4465 target_fl64
->l_whence
= tswap16(fl64
.l_whence
);
4466 target_fl64
->l_start
= tswap64(fl64
.l_start
);
4467 target_fl64
->l_len
= tswap64(fl64
.l_len
);
4468 target_fl64
->l_pid
= tswap32(fl64
.l_pid
);
4469 unlock_user_struct(target_fl64
, arg
, 1);
4472 case TARGET_F_SETLK64
:
4473 case TARGET_F_SETLKW64
:
4474 if (!lock_user_struct(VERIFY_READ
, target_fl64
, arg
, 1))
4475 return -TARGET_EFAULT
;
4477 target_to_host_bitmask(tswap16(target_fl64
->l_type
), flock_tbl
) >> 1;
4478 fl64
.l_whence
= tswap16(target_fl64
->l_whence
);
4479 fl64
.l_start
= tswap64(target_fl64
->l_start
);
4480 fl64
.l_len
= tswap64(target_fl64
->l_len
);
4481 fl64
.l_pid
= tswap32(target_fl64
->l_pid
);
4482 unlock_user_struct(target_fl64
, arg
, 0);
4483 ret
= get_errno(fcntl(fd
, host_cmd
, &fl64
));
4486 case TARGET_F_GETFL
:
4487 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4489 ret
= host_to_target_bitmask(ret
, fcntl_flags_tbl
);
4493 case TARGET_F_SETFL
:
4494 ret
= get_errno(fcntl(fd
, host_cmd
, target_to_host_bitmask(arg
, fcntl_flags_tbl
)));
4497 case TARGET_F_SETOWN
:
4498 case TARGET_F_GETOWN
:
4499 case TARGET_F_SETSIG
:
4500 case TARGET_F_GETSIG
:
4501 case TARGET_F_SETLEASE
:
4502 case TARGET_F_GETLEASE
:
4503 ret
= get_errno(fcntl(fd
, host_cmd
, arg
));
4507 ret
= get_errno(fcntl(fd
, cmd
, arg
));
4515 static inline int high2lowuid(int uid
)
4523 static inline int high2lowgid(int gid
)
4531 static inline int low2highuid(int uid
)
4533 if ((int16_t)uid
== -1)
4539 static inline int low2highgid(int gid
)
4541 if ((int16_t)gid
== -1)
4546 static inline int tswapid(int id
)
4550 #else /* !USE_UID16 */
4551 static inline int high2lowuid(int uid
)
4555 static inline int high2lowgid(int gid
)
4559 static inline int low2highuid(int uid
)
4563 static inline int low2highgid(int gid
)
4567 static inline int tswapid(int id
)
4571 #endif /* USE_UID16 */
4573 void syscall_init(void)
4576 const argtype
*arg_type
;
4580 #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4581 #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4582 #include "syscall_types.h"
4584 #undef STRUCT_SPECIAL
4586 /* Build target_to_host_errno_table[] table from
4587 * host_to_target_errno_table[]. */
4588 for (i
= 0; i
< ERRNO_TABLE_SIZE
; i
++) {
4589 target_to_host_errno_table
[host_to_target_errno_table
[i
]] = i
;
4592 /* we patch the ioctl size if necessary. We rely on the fact that
4593 no ioctl has all the bits at '1' in the size field */
4595 while (ie
->target_cmd
!= 0) {
4596 if (((ie
->target_cmd
>> TARGET_IOC_SIZESHIFT
) & TARGET_IOC_SIZEMASK
) ==
4597 TARGET_IOC_SIZEMASK
) {
4598 arg_type
= ie
->arg_type
;
4599 if (arg_type
[0] != TYPE_PTR
) {
4600 fprintf(stderr
, "cannot patch size for ioctl 0x%x\n",
4605 size
= thunk_type_size(arg_type
, 0);
4606 ie
->target_cmd
= (ie
->target_cmd
&
4607 ~(TARGET_IOC_SIZEMASK
<< TARGET_IOC_SIZESHIFT
)) |
4608 (size
<< TARGET_IOC_SIZESHIFT
);
4611 /* automatic consistency check if same arch */
4612 #if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4613 (defined(__x86_64__) && defined(TARGET_X86_64))
4614 if (unlikely(ie
->target_cmd
!= ie
->host_cmd
)) {
4615 fprintf(stderr
, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4616 ie
->name
, ie
->target_cmd
, ie
->host_cmd
);
4623 #if TARGET_ABI_BITS == 32
4624 static inline uint64_t target_offset64(uint32_t word0
, uint32_t word1
)
4626 #ifdef TARGET_WORDS_BIGENDIAN
4627 return ((uint64_t)word0
<< 32) | word1
;
4629 return ((uint64_t)word1
<< 32) | word0
;
4632 #else /* TARGET_ABI_BITS == 32 */
4633 static inline uint64_t target_offset64(uint64_t word0
, uint64_t word1
)
4637 #endif /* TARGET_ABI_BITS != 32 */
4639 #ifdef TARGET_NR_truncate64
4640 static inline abi_long
target_truncate64(void *cpu_env
, const char *arg1
,
4645 if (regpairs_aligned(cpu_env
)) {
4649 return get_errno(truncate64(arg1
, target_offset64(arg2
, arg3
)));
4653 #ifdef TARGET_NR_ftruncate64
4654 static inline abi_long
target_ftruncate64(void *cpu_env
, abi_long arg1
,
4659 if (regpairs_aligned(cpu_env
)) {
4663 return get_errno(ftruncate64(arg1
, target_offset64(arg2
, arg3
)));
4667 static inline abi_long
target_to_host_timespec(struct timespec
*host_ts
,
4668 abi_ulong target_addr
)
4670 struct target_timespec
*target_ts
;
4672 if (!lock_user_struct(VERIFY_READ
, target_ts
, target_addr
, 1))
4673 return -TARGET_EFAULT
;
4674 host_ts
->tv_sec
= tswapal(target_ts
->tv_sec
);
4675 host_ts
->tv_nsec
= tswapal(target_ts
->tv_nsec
);
4676 unlock_user_struct(target_ts
, target_addr
, 0);
4680 static inline abi_long
host_to_target_timespec(abi_ulong target_addr
,
4681 struct timespec
*host_ts
)
4683 struct target_timespec
*target_ts
;
4685 if (!lock_user_struct(VERIFY_WRITE
, target_ts
, target_addr
, 0))
4686 return -TARGET_EFAULT
;
4687 target_ts
->tv_sec
= tswapal(host_ts
->tv_sec
);
4688 target_ts
->tv_nsec
= tswapal(host_ts
->tv_nsec
);
4689 unlock_user_struct(target_ts
, target_addr
, 1);
4693 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4694 static inline abi_long
host_to_target_stat64(void *cpu_env
,
4695 abi_ulong target_addr
,
4696 struct stat
*host_st
)
4699 if (((CPUARMState
*)cpu_env
)->eabi
) {
4700 struct target_eabi_stat64
*target_st
;
4702 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4703 return -TARGET_EFAULT
;
4704 memset(target_st
, 0, sizeof(struct target_eabi_stat64
));
4705 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4706 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4707 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4708 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4710 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4711 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4712 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4713 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4714 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4715 __put_user(host_st
->st_size
, &target_st
->st_size
);
4716 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4717 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4718 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4719 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4720 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4721 unlock_user_struct(target_st
, target_addr
, 1);
4725 #if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4726 struct target_stat
*target_st
;
4728 struct target_stat64
*target_st
;
4731 if (!lock_user_struct(VERIFY_WRITE
, target_st
, target_addr
, 0))
4732 return -TARGET_EFAULT
;
4733 memset(target_st
, 0, sizeof(*target_st
));
4734 __put_user(host_st
->st_dev
, &target_st
->st_dev
);
4735 __put_user(host_st
->st_ino
, &target_st
->st_ino
);
4736 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4737 __put_user(host_st
->st_ino
, &target_st
->__st_ino
);
4739 __put_user(host_st
->st_mode
, &target_st
->st_mode
);
4740 __put_user(host_st
->st_nlink
, &target_st
->st_nlink
);
4741 __put_user(host_st
->st_uid
, &target_st
->st_uid
);
4742 __put_user(host_st
->st_gid
, &target_st
->st_gid
);
4743 __put_user(host_st
->st_rdev
, &target_st
->st_rdev
);
4744 /* XXX: better use of kernel struct */
4745 __put_user(host_st
->st_size
, &target_st
->st_size
);
4746 __put_user(host_st
->st_blksize
, &target_st
->st_blksize
);
4747 __put_user(host_st
->st_blocks
, &target_st
->st_blocks
);
4748 __put_user(host_st
->st_atime
, &target_st
->target_st_atime
);
4749 __put_user(host_st
->st_mtime
, &target_st
->target_st_mtime
);
4750 __put_user(host_st
->st_ctime
, &target_st
->target_st_ctime
);
4751 unlock_user_struct(target_st
, target_addr
, 1);
4758 #if defined(CONFIG_USE_NPTL)
4759 /* ??? Using host futex calls even when target atomic operations
4760 are not really atomic probably breaks things. However implementing
4761 futexes locally would make futexes shared between multiple processes
4762 tricky. However they're probably useless because guest atomic
4763 operations won't work either. */
4764 static int do_futex(target_ulong uaddr
, int op
, int val
, target_ulong timeout
,
4765 target_ulong uaddr2
, int val3
)
4767 struct timespec ts
, *pts
;
4770 /* ??? We assume FUTEX_* constants are the same on both host
4772 #ifdef FUTEX_CMD_MASK
4773 base_op
= op
& FUTEX_CMD_MASK
;
4779 case FUTEX_WAIT_BITSET
:
4782 target_to_host_timespec(pts
, timeout
);
4786 return get_errno(sys_futex(g2h(uaddr
), op
, tswap32(val
),
4789 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4791 return get_errno(sys_futex(g2h(uaddr
), op
, val
, NULL
, NULL
, 0));
4793 case FUTEX_CMP_REQUEUE
:
4795 /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4796 TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4797 But the prototype takes a `struct timespec *'; insert casts
4798 to satisfy the compiler. We do not need to tswap TIMEOUT
4799 since it's not compared to guest memory. */
4800 pts
= (struct timespec
*)(uintptr_t) timeout
;
4801 return get_errno(sys_futex(g2h(uaddr
), op
, val
, pts
,
4803 (base_op
== FUTEX_CMP_REQUEUE
4807 return -TARGET_ENOSYS
;
4812 /* Map host to target signal numbers for the wait family of syscalls.
4813 Assume all other status bits are the same. */
4814 int host_to_target_waitstatus(int status
)
4816 if (WIFSIGNALED(status
)) {
4817 return host_to_target_signal(WTERMSIG(status
)) | (status
& ~0x7f);
4819 if (WIFSTOPPED(status
)) {
4820 return (host_to_target_signal(WSTOPSIG(status
)) << 8)
4826 int get_osversion(void)
4828 static int osversion
;
4829 struct new_utsname buf
;
4834 if (qemu_uname_release
&& *qemu_uname_release
) {
4835 s
= qemu_uname_release
;
4837 if (sys_uname(&buf
))
4842 for (i
= 0; i
< 3; i
++) {
4844 while (*s
>= '0' && *s
<= '9') {
4849 tmp
= (tmp
<< 8) + n
;
4858 static int open_self_maps(void *cpu_env
, int fd
)
4860 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4861 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4868 fp
= fopen("/proc/self/maps", "r");
4873 while ((read
= getline(&line
, &len
, fp
)) != -1) {
4874 int fields
, dev_maj
, dev_min
, inode
;
4875 uint64_t min
, max
, offset
;
4876 char flag_r
, flag_w
, flag_x
, flag_p
;
4877 char path
[512] = "";
4878 fields
= sscanf(line
, "%"PRIx64
"-%"PRIx64
" %c%c%c%c %"PRIx64
" %x:%x %d"
4879 " %512s", &min
, &max
, &flag_r
, &flag_w
, &flag_x
,
4880 &flag_p
, &offset
, &dev_maj
, &dev_min
, &inode
, path
);
4882 if ((fields
< 10) || (fields
> 11)) {
4885 if (!strncmp(path
, "[stack]", 7)) {
4888 if (h2g_valid(min
) && h2g_valid(max
)) {
4889 dprintf(fd
, TARGET_ABI_FMT_lx
"-" TARGET_ABI_FMT_lx
4890 " %c%c%c%c %08" PRIx64
" %02x:%02x %d %s%s\n",
4891 h2g(min
), h2g(max
), flag_r
, flag_w
,
4892 flag_x
, flag_p
, offset
, dev_maj
, dev_min
, inode
,
4893 path
[0] ? " " : "", path
);
4900 #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
4901 dprintf(fd
, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n",
4902 (unsigned long long)ts
->info
->stack_limit
,
4903 (unsigned long long)(ts
->info
->start_stack
+
4904 (TARGET_PAGE_SIZE
- 1)) & TARGET_PAGE_MASK
,
4905 (unsigned long long)0);
4911 static int open_self_stat(void *cpu_env
, int fd
)
4913 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4914 abi_ulong start_stack
= ts
->info
->start_stack
;
4917 for (i
= 0; i
< 44; i
++) {
4925 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
4926 } else if (i
== 1) {
4928 snprintf(buf
, sizeof(buf
), "(%s) ", ts
->bprm
->argv
[0]);
4929 } else if (i
== 27) {
4932 snprintf(buf
, sizeof(buf
), "%"PRId64
" ", val
);
4934 /* for the rest, there is MasterCard */
4935 snprintf(buf
, sizeof(buf
), "0%c", i
== 43 ? '\n' : ' ');
4939 if (write(fd
, buf
, len
) != len
) {
4947 static int open_self_auxv(void *cpu_env
, int fd
)
4949 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
4950 abi_ulong auxv
= ts
->info
->saved_auxv
;
4951 abi_ulong len
= ts
->info
->auxv_len
;
4955 * Auxiliary vector is stored in target process stack.
4956 * read in whole auxv vector and copy it to file
4958 ptr
= lock_user(VERIFY_READ
, auxv
, len
, 0);
4962 r
= write(fd
, ptr
, len
);
4969 lseek(fd
, 0, SEEK_SET
);
4970 unlock_user(ptr
, auxv
, len
);
4976 static int do_open(void *cpu_env
, const char *pathname
, int flags
, mode_t mode
)
4979 const char *filename
;
4980 int (*fill
)(void *cpu_env
, int fd
);
4982 const struct fake_open
*fake_open
;
4983 static const struct fake_open fakes
[] = {
4984 { "/proc/self/maps", open_self_maps
},
4985 { "/proc/self/stat", open_self_stat
},
4986 { "/proc/self/auxv", open_self_auxv
},
4990 for (fake_open
= fakes
; fake_open
->filename
; fake_open
++) {
4991 if (!strncmp(pathname
, fake_open
->filename
,
4992 strlen(fake_open
->filename
))) {
4997 if (fake_open
->filename
) {
4999 char filename
[PATH_MAX
];
5002 /* create temporary file to map stat to */
5003 tmpdir
= getenv("TMPDIR");
5006 snprintf(filename
, sizeof(filename
), "%s/qemu-open.XXXXXX", tmpdir
);
5007 fd
= mkstemp(filename
);
5013 if ((r
= fake_open
->fill(cpu_env
, fd
))) {
5017 lseek(fd
, 0, SEEK_SET
);
5022 return get_errno(open(path(pathname
), flags
, mode
));
5025 /* do_syscall() should always have a single exit point at the end so
5026 that actions, such as logging of syscall results, can be performed.
5027 All errnos that do_syscall() returns must be -TARGET_<errcode>. */
5028 abi_long
do_syscall(void *cpu_env
, int num
, abi_long arg1
,
5029 abi_long arg2
, abi_long arg3
, abi_long arg4
,
5030 abi_long arg5
, abi_long arg6
, abi_long arg7
,
5033 #ifdef CONFIG_USE_NPTL
5034 CPUState
*cpu
= ENV_GET_CPU(cpu_env
);
5042 gemu_log("syscall %d", num
);
5045 print_syscall(num
, arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
5048 case TARGET_NR_exit
:
5049 #ifdef CONFIG_USE_NPTL
5050 /* In old applications this may be used to implement _exit(2).
5051 However in threaded applictions it is used for thread termination,
5052 and _exit_group is used for application termination.
5053 Do thread termination if we have more then one thread. */
5054 /* FIXME: This probably breaks if a signal arrives. We should probably
5055 be disabling signals. */
5056 if (first_cpu
->next_cpu
) {
5064 while (p
&& p
!= cpu
) {
5065 lastp
= &p
->next_cpu
;
5068 /* If we didn't find the CPU for this thread then something is
5073 /* Remove the CPU from the list. */
5074 *lastp
= p
->next_cpu
;
5076 ts
= ((CPUArchState
*)cpu_env
)->opaque
;
5077 if (ts
->child_tidptr
) {
5078 put_user_u32(0, ts
->child_tidptr
);
5079 sys_futex(g2h(ts
->child_tidptr
), FUTEX_WAKE
, INT_MAX
,
5083 object_unref(OBJECT(ENV_GET_CPU(cpu_env
)));
5091 gdb_exit(cpu_env
, arg1
);
5093 ret
= 0; /* avoid warning */
5095 case TARGET_NR_read
:
5099 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
5101 ret
= get_errno(read(arg1
, p
, arg3
));
5102 unlock_user(p
, arg2
, ret
);
5105 case TARGET_NR_write
:
5106 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
5108 ret
= get_errno(write(arg1
, p
, arg3
));
5109 unlock_user(p
, arg2
, 0);
5111 case TARGET_NR_open
:
5112 if (!(p
= lock_user_string(arg1
)))
5114 ret
= get_errno(do_open(cpu_env
, p
,
5115 target_to_host_bitmask(arg2
, fcntl_flags_tbl
),
5117 unlock_user(p
, arg1
, 0);
5119 #if defined(TARGET_NR_openat) && defined(__NR_openat)
5120 case TARGET_NR_openat
:
5121 if (!(p
= lock_user_string(arg2
)))
5123 ret
= get_errno(sys_openat(arg1
,
5125 target_to_host_bitmask(arg3
, fcntl_flags_tbl
),
5127 unlock_user(p
, arg2
, 0);
5130 case TARGET_NR_close
:
5131 ret
= get_errno(close(arg1
));
5136 case TARGET_NR_fork
:
5137 ret
= get_errno(do_fork(cpu_env
, SIGCHLD
, 0, 0, 0, 0));
5139 #ifdef TARGET_NR_waitpid
5140 case TARGET_NR_waitpid
:
5143 ret
= get_errno(waitpid(arg1
, &status
, arg3
));
5144 if (!is_error(ret
) && arg2
&& ret
5145 && put_user_s32(host_to_target_waitstatus(status
), arg2
))
5150 #ifdef TARGET_NR_waitid
5151 case TARGET_NR_waitid
:
5155 ret
= get_errno(waitid(arg1
, arg2
, &info
, arg4
));
5156 if (!is_error(ret
) && arg3
&& info
.si_pid
!= 0) {
5157 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_siginfo_t
), 0)))
5159 host_to_target_siginfo(p
, &info
);
5160 unlock_user(p
, arg3
, sizeof(target_siginfo_t
));
5165 #ifdef TARGET_NR_creat /* not on alpha */
5166 case TARGET_NR_creat
:
5167 if (!(p
= lock_user_string(arg1
)))
5169 ret
= get_errno(creat(p
, arg2
));
5170 unlock_user(p
, arg1
, 0);
5173 case TARGET_NR_link
:
5176 p
= lock_user_string(arg1
);
5177 p2
= lock_user_string(arg2
);
5179 ret
= -TARGET_EFAULT
;
5181 ret
= get_errno(link(p
, p2
));
5182 unlock_user(p2
, arg2
, 0);
5183 unlock_user(p
, arg1
, 0);
5186 #if defined(TARGET_NR_linkat)
5187 case TARGET_NR_linkat
:
5192 p
= lock_user_string(arg2
);
5193 p2
= lock_user_string(arg4
);
5195 ret
= -TARGET_EFAULT
;
5197 ret
= get_errno(linkat(arg1
, p
, arg3
, p2
, arg5
));
5198 unlock_user(p
, arg2
, 0);
5199 unlock_user(p2
, arg4
, 0);
5203 case TARGET_NR_unlink
:
5204 if (!(p
= lock_user_string(arg1
)))
5206 ret
= get_errno(unlink(p
));
5207 unlock_user(p
, arg1
, 0);
5209 #if defined(TARGET_NR_unlinkat)
5210 case TARGET_NR_unlinkat
:
5211 if (!(p
= lock_user_string(arg2
)))
5213 ret
= get_errno(unlinkat(arg1
, p
, arg3
));
5214 unlock_user(p
, arg2
, 0);
5217 case TARGET_NR_execve
:
5219 char **argp
, **envp
;
5222 abi_ulong guest_argp
;
5223 abi_ulong guest_envp
;
5230 for (gp
= guest_argp
; gp
; gp
+= sizeof(abi_ulong
)) {
5231 if (get_user_ual(addr
, gp
))
5239 for (gp
= guest_envp
; gp
; gp
+= sizeof(abi_ulong
)) {
5240 if (get_user_ual(addr
, gp
))
5247 argp
= alloca((argc
+ 1) * sizeof(void *));
5248 envp
= alloca((envc
+ 1) * sizeof(void *));
5250 for (gp
= guest_argp
, q
= argp
; gp
;
5251 gp
+= sizeof(abi_ulong
), q
++) {
5252 if (get_user_ual(addr
, gp
))
5256 if (!(*q
= lock_user_string(addr
)))
5258 total_size
+= strlen(*q
) + 1;
5262 for (gp
= guest_envp
, q
= envp
; gp
;
5263 gp
+= sizeof(abi_ulong
), q
++) {
5264 if (get_user_ual(addr
, gp
))
5268 if (!(*q
= lock_user_string(addr
)))
5270 total_size
+= strlen(*q
) + 1;
5274 /* This case will not be caught by the host's execve() if its
5275 page size is bigger than the target's. */
5276 if (total_size
> MAX_ARG_PAGES
* TARGET_PAGE_SIZE
) {
5277 ret
= -TARGET_E2BIG
;
5280 if (!(p
= lock_user_string(arg1
)))
5282 ret
= get_errno(execve(p
, argp
, envp
));
5283 unlock_user(p
, arg1
, 0);
5288 ret
= -TARGET_EFAULT
;
5291 for (gp
= guest_argp
, q
= argp
; *q
;
5292 gp
+= sizeof(abi_ulong
), q
++) {
5293 if (get_user_ual(addr
, gp
)
5296 unlock_user(*q
, addr
, 0);
5298 for (gp
= guest_envp
, q
= envp
; *q
;
5299 gp
+= sizeof(abi_ulong
), q
++) {
5300 if (get_user_ual(addr
, gp
)
5303 unlock_user(*q
, addr
, 0);
5307 case TARGET_NR_chdir
:
5308 if (!(p
= lock_user_string(arg1
)))
5310 ret
= get_errno(chdir(p
));
5311 unlock_user(p
, arg1
, 0);
5313 #ifdef TARGET_NR_time
5314 case TARGET_NR_time
:
5317 ret
= get_errno(time(&host_time
));
5320 && put_user_sal(host_time
, arg1
))
5325 case TARGET_NR_mknod
:
5326 if (!(p
= lock_user_string(arg1
)))
5328 ret
= get_errno(mknod(p
, arg2
, arg3
));
5329 unlock_user(p
, arg1
, 0);
5331 #if defined(TARGET_NR_mknodat)
5332 case TARGET_NR_mknodat
:
5333 if (!(p
= lock_user_string(arg2
)))
5335 ret
= get_errno(mknodat(arg1
, p
, arg3
, arg4
));
5336 unlock_user(p
, arg2
, 0);
5339 case TARGET_NR_chmod
:
5340 if (!(p
= lock_user_string(arg1
)))
5342 ret
= get_errno(chmod(p
, arg2
));
5343 unlock_user(p
, arg1
, 0);
5345 #ifdef TARGET_NR_break
5346 case TARGET_NR_break
:
5349 #ifdef TARGET_NR_oldstat
5350 case TARGET_NR_oldstat
:
5353 case TARGET_NR_lseek
:
5354 ret
= get_errno(lseek(arg1
, arg2
, arg3
));
5356 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
5357 /* Alpha specific */
5358 case TARGET_NR_getxpid
:
5359 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
] = getppid();
5360 ret
= get_errno(getpid());
5363 #ifdef TARGET_NR_getpid
5364 case TARGET_NR_getpid
:
5365 ret
= get_errno(getpid());
5368 case TARGET_NR_mount
:
5370 /* need to look at the data field */
5372 p
= lock_user_string(arg1
);
5373 p2
= lock_user_string(arg2
);
5374 p3
= lock_user_string(arg3
);
5375 if (!p
|| !p2
|| !p3
)
5376 ret
= -TARGET_EFAULT
;
5378 /* FIXME - arg5 should be locked, but it isn't clear how to
5379 * do that since it's not guaranteed to be a NULL-terminated
5383 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, NULL
));
5385 ret
= get_errno(mount(p
, p2
, p3
, (unsigned long)arg4
, g2h(arg5
)));
5387 unlock_user(p
, arg1
, 0);
5388 unlock_user(p2
, arg2
, 0);
5389 unlock_user(p3
, arg3
, 0);
5392 #ifdef TARGET_NR_umount
5393 case TARGET_NR_umount
:
5394 if (!(p
= lock_user_string(arg1
)))
5396 ret
= get_errno(umount(p
));
5397 unlock_user(p
, arg1
, 0);
5400 #ifdef TARGET_NR_stime /* not on alpha */
5401 case TARGET_NR_stime
:
5404 if (get_user_sal(host_time
, arg1
))
5406 ret
= get_errno(stime(&host_time
));
5410 case TARGET_NR_ptrace
:
5412 #ifdef TARGET_NR_alarm /* not on alpha */
5413 case TARGET_NR_alarm
:
5417 #ifdef TARGET_NR_oldfstat
5418 case TARGET_NR_oldfstat
:
5421 #ifdef TARGET_NR_pause /* not on alpha */
5422 case TARGET_NR_pause
:
5423 ret
= get_errno(pause());
5426 #ifdef TARGET_NR_utime
5427 case TARGET_NR_utime
:
5429 struct utimbuf tbuf
, *host_tbuf
;
5430 struct target_utimbuf
*target_tbuf
;
5432 if (!lock_user_struct(VERIFY_READ
, target_tbuf
, arg2
, 1))
5434 tbuf
.actime
= tswapal(target_tbuf
->actime
);
5435 tbuf
.modtime
= tswapal(target_tbuf
->modtime
);
5436 unlock_user_struct(target_tbuf
, arg2
, 0);
5441 if (!(p
= lock_user_string(arg1
)))
5443 ret
= get_errno(utime(p
, host_tbuf
));
5444 unlock_user(p
, arg1
, 0);
5448 case TARGET_NR_utimes
:
5450 struct timeval
*tvp
, tv
[2];
5452 if (copy_from_user_timeval(&tv
[0], arg2
)
5453 || copy_from_user_timeval(&tv
[1],
5454 arg2
+ sizeof(struct target_timeval
)))
5460 if (!(p
= lock_user_string(arg1
)))
5462 ret
= get_errno(utimes(p
, tvp
));
5463 unlock_user(p
, arg1
, 0);
5466 #if defined(TARGET_NR_futimesat)
5467 case TARGET_NR_futimesat
:
5469 struct timeval
*tvp
, tv
[2];
5471 if (copy_from_user_timeval(&tv
[0], arg3
)
5472 || copy_from_user_timeval(&tv
[1],
5473 arg3
+ sizeof(struct target_timeval
)))
5479 if (!(p
= lock_user_string(arg2
)))
5481 ret
= get_errno(futimesat(arg1
, path(p
), tvp
));
5482 unlock_user(p
, arg2
, 0);
5486 #ifdef TARGET_NR_stty
5487 case TARGET_NR_stty
:
5490 #ifdef TARGET_NR_gtty
5491 case TARGET_NR_gtty
:
5494 case TARGET_NR_access
:
5495 if (!(p
= lock_user_string(arg1
)))
5497 ret
= get_errno(access(path(p
), arg2
));
5498 unlock_user(p
, arg1
, 0);
5500 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5501 case TARGET_NR_faccessat
:
5502 if (!(p
= lock_user_string(arg2
)))
5504 ret
= get_errno(faccessat(arg1
, p
, arg3
, 0));
5505 unlock_user(p
, arg2
, 0);
5508 #ifdef TARGET_NR_nice /* not on alpha */
5509 case TARGET_NR_nice
:
5510 ret
= get_errno(nice(arg1
));
5513 #ifdef TARGET_NR_ftime
5514 case TARGET_NR_ftime
:
5517 case TARGET_NR_sync
:
5521 case TARGET_NR_kill
:
5522 ret
= get_errno(kill(arg1
, target_to_host_signal(arg2
)));
5524 case TARGET_NR_rename
:
5527 p
= lock_user_string(arg1
);
5528 p2
= lock_user_string(arg2
);
5530 ret
= -TARGET_EFAULT
;
5532 ret
= get_errno(rename(p
, p2
));
5533 unlock_user(p2
, arg2
, 0);
5534 unlock_user(p
, arg1
, 0);
5537 #if defined(TARGET_NR_renameat)
5538 case TARGET_NR_renameat
:
5541 p
= lock_user_string(arg2
);
5542 p2
= lock_user_string(arg4
);
5544 ret
= -TARGET_EFAULT
;
5546 ret
= get_errno(renameat(arg1
, p
, arg3
, p2
));
5547 unlock_user(p2
, arg4
, 0);
5548 unlock_user(p
, arg2
, 0);
5552 case TARGET_NR_mkdir
:
5553 if (!(p
= lock_user_string(arg1
)))
5555 ret
= get_errno(mkdir(p
, arg2
));
5556 unlock_user(p
, arg1
, 0);
5558 #if defined(TARGET_NR_mkdirat)
5559 case TARGET_NR_mkdirat
:
5560 if (!(p
= lock_user_string(arg2
)))
5562 ret
= get_errno(mkdirat(arg1
, p
, arg3
));
5563 unlock_user(p
, arg2
, 0);
5566 case TARGET_NR_rmdir
:
5567 if (!(p
= lock_user_string(arg1
)))
5569 ret
= get_errno(rmdir(p
));
5570 unlock_user(p
, arg1
, 0);
5573 ret
= get_errno(dup(arg1
));
5575 case TARGET_NR_pipe
:
5576 ret
= do_pipe(cpu_env
, arg1
, 0, 0);
5578 #ifdef TARGET_NR_pipe2
5579 case TARGET_NR_pipe2
:
5580 ret
= do_pipe(cpu_env
, arg1
,
5581 target_to_host_bitmask(arg2
, fcntl_flags_tbl
), 1);
5584 case TARGET_NR_times
:
5586 struct target_tms
*tmsp
;
5588 ret
= get_errno(times(&tms
));
5590 tmsp
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_tms
), 0);
5593 tmsp
->tms_utime
= tswapal(host_to_target_clock_t(tms
.tms_utime
));
5594 tmsp
->tms_stime
= tswapal(host_to_target_clock_t(tms
.tms_stime
));
5595 tmsp
->tms_cutime
= tswapal(host_to_target_clock_t(tms
.tms_cutime
));
5596 tmsp
->tms_cstime
= tswapal(host_to_target_clock_t(tms
.tms_cstime
));
5599 ret
= host_to_target_clock_t(ret
);
5602 #ifdef TARGET_NR_prof
5603 case TARGET_NR_prof
:
5606 #ifdef TARGET_NR_signal
5607 case TARGET_NR_signal
:
5610 case TARGET_NR_acct
:
5612 ret
= get_errno(acct(NULL
));
5614 if (!(p
= lock_user_string(arg1
)))
5616 ret
= get_errno(acct(path(p
)));
5617 unlock_user(p
, arg1
, 0);
5620 #ifdef TARGET_NR_umount2 /* not on alpha */
5621 case TARGET_NR_umount2
:
5622 if (!(p
= lock_user_string(arg1
)))
5624 ret
= get_errno(umount2(p
, arg2
));
5625 unlock_user(p
, arg1
, 0);
5628 #ifdef TARGET_NR_lock
5629 case TARGET_NR_lock
:
5632 case TARGET_NR_ioctl
:
5633 ret
= do_ioctl(arg1
, arg2
, arg3
);
5635 case TARGET_NR_fcntl
:
5636 ret
= do_fcntl(arg1
, arg2
, arg3
);
5638 #ifdef TARGET_NR_mpx
5642 case TARGET_NR_setpgid
:
5643 ret
= get_errno(setpgid(arg1
, arg2
));
5645 #ifdef TARGET_NR_ulimit
5646 case TARGET_NR_ulimit
:
5649 #ifdef TARGET_NR_oldolduname
5650 case TARGET_NR_oldolduname
:
5653 case TARGET_NR_umask
:
5654 ret
= get_errno(umask(arg1
));
5656 case TARGET_NR_chroot
:
5657 if (!(p
= lock_user_string(arg1
)))
5659 ret
= get_errno(chroot(p
));
5660 unlock_user(p
, arg1
, 0);
5662 case TARGET_NR_ustat
:
5664 case TARGET_NR_dup2
:
5665 ret
= get_errno(dup2(arg1
, arg2
));
5667 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5668 case TARGET_NR_dup3
:
5669 ret
= get_errno(dup3(arg1
, arg2
, arg3
));
5672 #ifdef TARGET_NR_getppid /* not on alpha */
5673 case TARGET_NR_getppid
:
5674 ret
= get_errno(getppid());
5677 case TARGET_NR_getpgrp
:
5678 ret
= get_errno(getpgrp());
5680 case TARGET_NR_setsid
:
5681 ret
= get_errno(setsid());
5683 #ifdef TARGET_NR_sigaction
5684 case TARGET_NR_sigaction
:
5686 #if defined(TARGET_ALPHA)
5687 struct target_sigaction act
, oact
, *pact
= 0;
5688 struct target_old_sigaction
*old_act
;
5690 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5692 act
._sa_handler
= old_act
->_sa_handler
;
5693 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5694 act
.sa_flags
= old_act
->sa_flags
;
5695 act
.sa_restorer
= 0;
5696 unlock_user_struct(old_act
, arg2
, 0);
5699 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5700 if (!is_error(ret
) && arg3
) {
5701 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5703 old_act
->_sa_handler
= oact
._sa_handler
;
5704 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5705 old_act
->sa_flags
= oact
.sa_flags
;
5706 unlock_user_struct(old_act
, arg3
, 1);
5708 #elif defined(TARGET_MIPS)
5709 struct target_sigaction act
, oact
, *pact
, *old_act
;
5712 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5714 act
._sa_handler
= old_act
->_sa_handler
;
5715 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
.sig
[0]);
5716 act
.sa_flags
= old_act
->sa_flags
;
5717 unlock_user_struct(old_act
, arg2
, 0);
5723 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5725 if (!is_error(ret
) && arg3
) {
5726 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5728 old_act
->_sa_handler
= oact
._sa_handler
;
5729 old_act
->sa_flags
= oact
.sa_flags
;
5730 old_act
->sa_mask
.sig
[0] = oact
.sa_mask
.sig
[0];
5731 old_act
->sa_mask
.sig
[1] = 0;
5732 old_act
->sa_mask
.sig
[2] = 0;
5733 old_act
->sa_mask
.sig
[3] = 0;
5734 unlock_user_struct(old_act
, arg3
, 1);
5737 struct target_old_sigaction
*old_act
;
5738 struct target_sigaction act
, oact
, *pact
;
5740 if (!lock_user_struct(VERIFY_READ
, old_act
, arg2
, 1))
5742 act
._sa_handler
= old_act
->_sa_handler
;
5743 target_siginitset(&act
.sa_mask
, old_act
->sa_mask
);
5744 act
.sa_flags
= old_act
->sa_flags
;
5745 act
.sa_restorer
= old_act
->sa_restorer
;
5746 unlock_user_struct(old_act
, arg2
, 0);
5751 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5752 if (!is_error(ret
) && arg3
) {
5753 if (!lock_user_struct(VERIFY_WRITE
, old_act
, arg3
, 0))
5755 old_act
->_sa_handler
= oact
._sa_handler
;
5756 old_act
->sa_mask
= oact
.sa_mask
.sig
[0];
5757 old_act
->sa_flags
= oact
.sa_flags
;
5758 old_act
->sa_restorer
= oact
.sa_restorer
;
5759 unlock_user_struct(old_act
, arg3
, 1);
5765 case TARGET_NR_rt_sigaction
:
5767 #if defined(TARGET_ALPHA)
5768 struct target_sigaction act
, oact
, *pact
= 0;
5769 struct target_rt_sigaction
*rt_act
;
5770 /* ??? arg4 == sizeof(sigset_t). */
5772 if (!lock_user_struct(VERIFY_READ
, rt_act
, arg2
, 1))
5774 act
._sa_handler
= rt_act
->_sa_handler
;
5775 act
.sa_mask
= rt_act
->sa_mask
;
5776 act
.sa_flags
= rt_act
->sa_flags
;
5777 act
.sa_restorer
= arg5
;
5778 unlock_user_struct(rt_act
, arg2
, 0);
5781 ret
= get_errno(do_sigaction(arg1
, pact
, &oact
));
5782 if (!is_error(ret
) && arg3
) {
5783 if (!lock_user_struct(VERIFY_WRITE
, rt_act
, arg3
, 0))
5785 rt_act
->_sa_handler
= oact
._sa_handler
;
5786 rt_act
->sa_mask
= oact
.sa_mask
;
5787 rt_act
->sa_flags
= oact
.sa_flags
;
5788 unlock_user_struct(rt_act
, arg3
, 1);
5791 struct target_sigaction
*act
;
5792 struct target_sigaction
*oact
;
5795 if (!lock_user_struct(VERIFY_READ
, act
, arg2
, 1))
5800 if (!lock_user_struct(VERIFY_WRITE
, oact
, arg3
, 0)) {
5801 ret
= -TARGET_EFAULT
;
5802 goto rt_sigaction_fail
;
5806 ret
= get_errno(do_sigaction(arg1
, act
, oact
));
5809 unlock_user_struct(act
, arg2
, 0);
5811 unlock_user_struct(oact
, arg3
, 1);
5815 #ifdef TARGET_NR_sgetmask /* not on alpha */
5816 case TARGET_NR_sgetmask
:
5819 abi_ulong target_set
;
5820 sigprocmask(0, NULL
, &cur_set
);
5821 host_to_target_old_sigset(&target_set
, &cur_set
);
5826 #ifdef TARGET_NR_ssetmask /* not on alpha */
5827 case TARGET_NR_ssetmask
:
5829 sigset_t set
, oset
, cur_set
;
5830 abi_ulong target_set
= arg1
;
5831 sigprocmask(0, NULL
, &cur_set
);
5832 target_to_host_old_sigset(&set
, &target_set
);
5833 sigorset(&set
, &set
, &cur_set
);
5834 sigprocmask(SIG_SETMASK
, &set
, &oset
);
5835 host_to_target_old_sigset(&target_set
, &oset
);
5840 #ifdef TARGET_NR_sigprocmask
5841 case TARGET_NR_sigprocmask
:
5843 #if defined(TARGET_ALPHA)
5844 sigset_t set
, oldset
;
5849 case TARGET_SIG_BLOCK
:
5852 case TARGET_SIG_UNBLOCK
:
5855 case TARGET_SIG_SETMASK
:
5859 ret
= -TARGET_EINVAL
;
5863 target_to_host_old_sigset(&set
, &mask
);
5865 ret
= get_errno(sigprocmask(how
, &set
, &oldset
));
5866 if (!is_error(ret
)) {
5867 host_to_target_old_sigset(&mask
, &oldset
);
5869 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0; /* force no error */
5872 sigset_t set
, oldset
, *set_ptr
;
5877 case TARGET_SIG_BLOCK
:
5880 case TARGET_SIG_UNBLOCK
:
5883 case TARGET_SIG_SETMASK
:
5887 ret
= -TARGET_EINVAL
;
5890 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
5892 target_to_host_old_sigset(&set
, p
);
5893 unlock_user(p
, arg2
, 0);
5899 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
5900 if (!is_error(ret
) && arg3
) {
5901 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
5903 host_to_target_old_sigset(p
, &oldset
);
5904 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
5910 case TARGET_NR_rt_sigprocmask
:
5913 sigset_t set
, oldset
, *set_ptr
;
5917 case TARGET_SIG_BLOCK
:
5920 case TARGET_SIG_UNBLOCK
:
5923 case TARGET_SIG_SETMASK
:
5927 ret
= -TARGET_EINVAL
;
5930 if (!(p
= lock_user(VERIFY_READ
, arg2
, sizeof(target_sigset_t
), 1)))
5932 target_to_host_sigset(&set
, p
);
5933 unlock_user(p
, arg2
, 0);
5939 ret
= get_errno(sigprocmask(how
, set_ptr
, &oldset
));
5940 if (!is_error(ret
) && arg3
) {
5941 if (!(p
= lock_user(VERIFY_WRITE
, arg3
, sizeof(target_sigset_t
), 0)))
5943 host_to_target_sigset(p
, &oldset
);
5944 unlock_user(p
, arg3
, sizeof(target_sigset_t
));
5948 #ifdef TARGET_NR_sigpending
5949 case TARGET_NR_sigpending
:
5952 ret
= get_errno(sigpending(&set
));
5953 if (!is_error(ret
)) {
5954 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
5956 host_to_target_old_sigset(p
, &set
);
5957 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
5962 case TARGET_NR_rt_sigpending
:
5965 ret
= get_errno(sigpending(&set
));
5966 if (!is_error(ret
)) {
5967 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, sizeof(target_sigset_t
), 0)))
5969 host_to_target_sigset(p
, &set
);
5970 unlock_user(p
, arg1
, sizeof(target_sigset_t
));
5974 #ifdef TARGET_NR_sigsuspend
5975 case TARGET_NR_sigsuspend
:
5978 #if defined(TARGET_ALPHA)
5979 abi_ulong mask
= arg1
;
5980 target_to_host_old_sigset(&set
, &mask
);
5982 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
5984 target_to_host_old_sigset(&set
, p
);
5985 unlock_user(p
, arg1
, 0);
5987 ret
= get_errno(sigsuspend(&set
));
5991 case TARGET_NR_rt_sigsuspend
:
5994 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
5996 target_to_host_sigset(&set
, p
);
5997 unlock_user(p
, arg1
, 0);
5998 ret
= get_errno(sigsuspend(&set
));
6001 case TARGET_NR_rt_sigtimedwait
:
6004 struct timespec uts
, *puts
;
6007 if (!(p
= lock_user(VERIFY_READ
, arg1
, sizeof(target_sigset_t
), 1)))
6009 target_to_host_sigset(&set
, p
);
6010 unlock_user(p
, arg1
, 0);
6013 target_to_host_timespec(puts
, arg3
);
6017 ret
= get_errno(sigtimedwait(&set
, &uinfo
, puts
));
6018 if (!is_error(ret
) && arg2
) {
6019 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, sizeof(target_siginfo_t
), 0)))
6021 host_to_target_siginfo(p
, &uinfo
);
6022 unlock_user(p
, arg2
, sizeof(target_siginfo_t
));
6026 case TARGET_NR_rt_sigqueueinfo
:
6029 if (!(p
= lock_user(VERIFY_READ
, arg3
, sizeof(target_sigset_t
), 1)))
6031 target_to_host_siginfo(&uinfo
, p
);
6032 unlock_user(p
, arg1
, 0);
6033 ret
= get_errno(sys_rt_sigqueueinfo(arg1
, arg2
, &uinfo
));
6036 #ifdef TARGET_NR_sigreturn
6037 case TARGET_NR_sigreturn
:
6038 /* NOTE: ret is eax, so not transcoding must be done */
6039 ret
= do_sigreturn(cpu_env
);
6042 case TARGET_NR_rt_sigreturn
:
6043 /* NOTE: ret is eax, so not transcoding must be done */
6044 ret
= do_rt_sigreturn(cpu_env
);
6046 case TARGET_NR_sethostname
:
6047 if (!(p
= lock_user_string(arg1
)))
6049 ret
= get_errno(sethostname(p
, arg2
));
6050 unlock_user(p
, arg1
, 0);
6052 case TARGET_NR_setrlimit
:
6054 int resource
= target_to_host_resource(arg1
);
6055 struct target_rlimit
*target_rlim
;
6057 if (!lock_user_struct(VERIFY_READ
, target_rlim
, arg2
, 1))
6059 rlim
.rlim_cur
= target_to_host_rlim(target_rlim
->rlim_cur
);
6060 rlim
.rlim_max
= target_to_host_rlim(target_rlim
->rlim_max
);
6061 unlock_user_struct(target_rlim
, arg2
, 0);
6062 ret
= get_errno(setrlimit(resource
, &rlim
));
6065 case TARGET_NR_getrlimit
:
6067 int resource
= target_to_host_resource(arg1
);
6068 struct target_rlimit
*target_rlim
;
6071 ret
= get_errno(getrlimit(resource
, &rlim
));
6072 if (!is_error(ret
)) {
6073 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
6075 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
6076 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
6077 unlock_user_struct(target_rlim
, arg2
, 1);
6081 case TARGET_NR_getrusage
:
6083 struct rusage rusage
;
6084 ret
= get_errno(getrusage(arg1
, &rusage
));
6085 if (!is_error(ret
)) {
6086 host_to_target_rusage(arg2
, &rusage
);
6090 case TARGET_NR_gettimeofday
:
6093 ret
= get_errno(gettimeofday(&tv
, NULL
));
6094 if (!is_error(ret
)) {
6095 if (copy_to_user_timeval(arg1
, &tv
))
6100 case TARGET_NR_settimeofday
:
6103 if (copy_from_user_timeval(&tv
, arg1
))
6105 ret
= get_errno(settimeofday(&tv
, NULL
));
6108 #if defined(TARGET_NR_select)
6109 case TARGET_NR_select
:
6110 #if defined(TARGET_S390X) || defined(TARGET_ALPHA)
6111 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
6114 struct target_sel_arg_struct
*sel
;
6115 abi_ulong inp
, outp
, exp
, tvp
;
6118 if (!lock_user_struct(VERIFY_READ
, sel
, arg1
, 1))
6120 nsel
= tswapal(sel
->n
);
6121 inp
= tswapal(sel
->inp
);
6122 outp
= tswapal(sel
->outp
);
6123 exp
= tswapal(sel
->exp
);
6124 tvp
= tswapal(sel
->tvp
);
6125 unlock_user_struct(sel
, arg1
, 0);
6126 ret
= do_select(nsel
, inp
, outp
, exp
, tvp
);
6131 #ifdef TARGET_NR_pselect6
6132 case TARGET_NR_pselect6
:
6134 abi_long rfd_addr
, wfd_addr
, efd_addr
, n
, ts_addr
;
6135 fd_set rfds
, wfds
, efds
;
6136 fd_set
*rfds_ptr
, *wfds_ptr
, *efds_ptr
;
6137 struct timespec ts
, *ts_ptr
;
6140 * The 6th arg is actually two args smashed together,
6141 * so we cannot use the C library.
6149 abi_ulong arg_sigset
, arg_sigsize
, *arg7
;
6150 target_sigset_t
*target_sigset
;
6158 ret
= copy_from_user_fdset_ptr(&rfds
, &rfds_ptr
, rfd_addr
, n
);
6162 ret
= copy_from_user_fdset_ptr(&wfds
, &wfds_ptr
, wfd_addr
, n
);
6166 ret
= copy_from_user_fdset_ptr(&efds
, &efds_ptr
, efd_addr
, n
);
6172 * This takes a timespec, and not a timeval, so we cannot
6173 * use the do_select() helper ...
6176 if (target_to_host_timespec(&ts
, ts_addr
)) {
6184 /* Extract the two packed args for the sigset */
6187 sig
.size
= _NSIG
/ 8;
6189 arg7
= lock_user(VERIFY_READ
, arg6
, sizeof(*arg7
) * 2, 1);
6193 arg_sigset
= tswapal(arg7
[0]);
6194 arg_sigsize
= tswapal(arg7
[1]);
6195 unlock_user(arg7
, arg6
, 0);
6199 if (arg_sigsize
!= sizeof(*target_sigset
)) {
6200 /* Like the kernel, we enforce correct size sigsets */
6201 ret
= -TARGET_EINVAL
;
6204 target_sigset
= lock_user(VERIFY_READ
, arg_sigset
,
6205 sizeof(*target_sigset
), 1);
6206 if (!target_sigset
) {
6209 target_to_host_sigset(&set
, target_sigset
);
6210 unlock_user(target_sigset
, arg_sigset
, 0);
6218 ret
= get_errno(sys_pselect6(n
, rfds_ptr
, wfds_ptr
, efds_ptr
,
6221 if (!is_error(ret
)) {
6222 if (rfd_addr
&& copy_to_user_fdset(rfd_addr
, &rfds
, n
))
6224 if (wfd_addr
&& copy_to_user_fdset(wfd_addr
, &wfds
, n
))
6226 if (efd_addr
&& copy_to_user_fdset(efd_addr
, &efds
, n
))
6229 if (ts_addr
&& host_to_target_timespec(ts_addr
, &ts
))
6235 case TARGET_NR_symlink
:
6238 p
= lock_user_string(arg1
);
6239 p2
= lock_user_string(arg2
);
6241 ret
= -TARGET_EFAULT
;
6243 ret
= get_errno(symlink(p
, p2
));
6244 unlock_user(p2
, arg2
, 0);
6245 unlock_user(p
, arg1
, 0);
6248 #if defined(TARGET_NR_symlinkat)
6249 case TARGET_NR_symlinkat
:
6252 p
= lock_user_string(arg1
);
6253 p2
= lock_user_string(arg3
);
6255 ret
= -TARGET_EFAULT
;
6257 ret
= get_errno(symlinkat(p
, arg2
, p2
));
6258 unlock_user(p2
, arg3
, 0);
6259 unlock_user(p
, arg1
, 0);
6263 #ifdef TARGET_NR_oldlstat
6264 case TARGET_NR_oldlstat
:
6267 case TARGET_NR_readlink
:
6270 p
= lock_user_string(arg1
);
6271 p2
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
6273 ret
= -TARGET_EFAULT
;
6275 if (strncmp((const char *)p
, "/proc/self/exe", 14) == 0) {
6276 char real
[PATH_MAX
];
6277 temp
= realpath(exec_path
,real
);
6278 ret
= (temp
==NULL
) ? get_errno(-1) : strlen(real
) ;
6279 snprintf((char *)p2
, arg3
, "%s", real
);
6282 ret
= get_errno(readlink(path(p
), p2
, arg3
));
6284 unlock_user(p2
, arg2
, ret
);
6285 unlock_user(p
, arg1
, 0);
6288 #if defined(TARGET_NR_readlinkat)
6289 case TARGET_NR_readlinkat
:
6292 p
= lock_user_string(arg2
);
6293 p2
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
6295 ret
= -TARGET_EFAULT
;
6297 ret
= get_errno(readlinkat(arg1
, path(p
), p2
, arg4
));
6298 unlock_user(p2
, arg3
, ret
);
6299 unlock_user(p
, arg2
, 0);
6303 #ifdef TARGET_NR_uselib
6304 case TARGET_NR_uselib
:
6307 #ifdef TARGET_NR_swapon
6308 case TARGET_NR_swapon
:
6309 if (!(p
= lock_user_string(arg1
)))
6311 ret
= get_errno(swapon(p
, arg2
));
6312 unlock_user(p
, arg1
, 0);
6315 case TARGET_NR_reboot
:
6316 if (arg3
== LINUX_REBOOT_CMD_RESTART2
) {
6317 /* arg4 must be ignored in all other cases */
6318 p
= lock_user_string(arg4
);
6322 ret
= get_errno(reboot(arg1
, arg2
, arg3
, p
));
6323 unlock_user(p
, arg4
, 0);
6325 ret
= get_errno(reboot(arg1
, arg2
, arg3
, NULL
));
6328 #ifdef TARGET_NR_readdir
6329 case TARGET_NR_readdir
:
6332 #ifdef TARGET_NR_mmap
6333 case TARGET_NR_mmap
:
6334 #if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
6335 defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
6336 || defined(TARGET_S390X)
6339 abi_ulong v1
, v2
, v3
, v4
, v5
, v6
;
6340 if (!(v
= lock_user(VERIFY_READ
, arg1
, 6 * sizeof(abi_ulong
), 1)))
6348 unlock_user(v
, arg1
, 0);
6349 ret
= get_errno(target_mmap(v1
, v2
, v3
,
6350 target_to_host_bitmask(v4
, mmap_flags_tbl
),
6354 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6355 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6361 #ifdef TARGET_NR_mmap2
6362 case TARGET_NR_mmap2
:
6364 #define MMAP_SHIFT 12
6366 ret
= get_errno(target_mmap(arg1
, arg2
, arg3
,
6367 target_to_host_bitmask(arg4
, mmap_flags_tbl
),
6369 arg6
<< MMAP_SHIFT
));
6372 case TARGET_NR_munmap
:
6373 ret
= get_errno(target_munmap(arg1
, arg2
));
6375 case TARGET_NR_mprotect
:
6377 TaskState
*ts
= ((CPUArchState
*)cpu_env
)->opaque
;
6378 /* Special hack to detect libc making the stack executable. */
6379 if ((arg3
& PROT_GROWSDOWN
)
6380 && arg1
>= ts
->info
->stack_limit
6381 && arg1
<= ts
->info
->start_stack
) {
6382 arg3
&= ~PROT_GROWSDOWN
;
6383 arg2
= arg2
+ arg1
- ts
->info
->stack_limit
;
6384 arg1
= ts
->info
->stack_limit
;
6387 ret
= get_errno(target_mprotect(arg1
, arg2
, arg3
));
6389 #ifdef TARGET_NR_mremap
6390 case TARGET_NR_mremap
:
6391 ret
= get_errno(target_mremap(arg1
, arg2
, arg3
, arg4
, arg5
));
6394 /* ??? msync/mlock/munlock are broken for softmmu. */
6395 #ifdef TARGET_NR_msync
6396 case TARGET_NR_msync
:
6397 ret
= get_errno(msync(g2h(arg1
), arg2
, arg3
));
6400 #ifdef TARGET_NR_mlock
6401 case TARGET_NR_mlock
:
6402 ret
= get_errno(mlock(g2h(arg1
), arg2
));
6405 #ifdef TARGET_NR_munlock
6406 case TARGET_NR_munlock
:
6407 ret
= get_errno(munlock(g2h(arg1
), arg2
));
6410 #ifdef TARGET_NR_mlockall
6411 case TARGET_NR_mlockall
:
6412 ret
= get_errno(mlockall(arg1
));
6415 #ifdef TARGET_NR_munlockall
6416 case TARGET_NR_munlockall
:
6417 ret
= get_errno(munlockall());
6420 case TARGET_NR_truncate
:
6421 if (!(p
= lock_user_string(arg1
)))
6423 ret
= get_errno(truncate(p
, arg2
));
6424 unlock_user(p
, arg1
, 0);
6426 case TARGET_NR_ftruncate
:
6427 ret
= get_errno(ftruncate(arg1
, arg2
));
6429 case TARGET_NR_fchmod
:
6430 ret
= get_errno(fchmod(arg1
, arg2
));
6432 #if defined(TARGET_NR_fchmodat)
6433 case TARGET_NR_fchmodat
:
6434 if (!(p
= lock_user_string(arg2
)))
6436 ret
= get_errno(fchmodat(arg1
, p
, arg3
, 0));
6437 unlock_user(p
, arg2
, 0);
6440 case TARGET_NR_getpriority
:
6441 /* Note that negative values are valid for getpriority, so we must
6442 differentiate based on errno settings. */
6444 ret
= getpriority(arg1
, arg2
);
6445 if (ret
== -1 && errno
!= 0) {
6446 ret
= -host_to_target_errno(errno
);
6450 /* Return value is the unbiased priority. Signal no error. */
6451 ((CPUAlphaState
*)cpu_env
)->ir
[IR_V0
] = 0;
6453 /* Return value is a biased priority to avoid negative numbers. */
6457 case TARGET_NR_setpriority
:
6458 ret
= get_errno(setpriority(arg1
, arg2
, arg3
));
6460 #ifdef TARGET_NR_profil
6461 case TARGET_NR_profil
:
6464 case TARGET_NR_statfs
:
6465 if (!(p
= lock_user_string(arg1
)))
6467 ret
= get_errno(statfs(path(p
), &stfs
));
6468 unlock_user(p
, arg1
, 0);
6470 if (!is_error(ret
)) {
6471 struct target_statfs
*target_stfs
;
6473 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg2
, 0))
6475 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6476 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6477 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6478 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6479 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6480 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6481 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6482 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6483 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6484 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6485 __put_user(stfs
.f_frsize
, &target_stfs
->f_frsize
);
6486 memset(target_stfs
->f_spare
, 0, sizeof(target_stfs
->f_spare
));
6487 unlock_user_struct(target_stfs
, arg2
, 1);
6490 case TARGET_NR_fstatfs
:
6491 ret
= get_errno(fstatfs(arg1
, &stfs
));
6492 goto convert_statfs
;
6493 #ifdef TARGET_NR_statfs64
6494 case TARGET_NR_statfs64
:
6495 if (!(p
= lock_user_string(arg1
)))
6497 ret
= get_errno(statfs(path(p
), &stfs
));
6498 unlock_user(p
, arg1
, 0);
6500 if (!is_error(ret
)) {
6501 struct target_statfs64
*target_stfs
;
6503 if (!lock_user_struct(VERIFY_WRITE
, target_stfs
, arg3
, 0))
6505 __put_user(stfs
.f_type
, &target_stfs
->f_type
);
6506 __put_user(stfs
.f_bsize
, &target_stfs
->f_bsize
);
6507 __put_user(stfs
.f_blocks
, &target_stfs
->f_blocks
);
6508 __put_user(stfs
.f_bfree
, &target_stfs
->f_bfree
);
6509 __put_user(stfs
.f_bavail
, &target_stfs
->f_bavail
);
6510 __put_user(stfs
.f_files
, &target_stfs
->f_files
);
6511 __put_user(stfs
.f_ffree
, &target_stfs
->f_ffree
);
6512 __put_user(stfs
.f_fsid
.__val
[0], &target_stfs
->f_fsid
.val
[0]);
6513 __put_user(stfs
.f_fsid
.__val
[1], &target_stfs
->f_fsid
.val
[1]);
6514 __put_user(stfs
.f_namelen
, &target_stfs
->f_namelen
);
6515 __put_user(stfs
.f_frsize
, &target_stfs
->f_frsize
);
6516 memset(target_stfs
->f_spare
, 0, sizeof(target_stfs
->f_spare
));
6517 unlock_user_struct(target_stfs
, arg3
, 1);
6520 case TARGET_NR_fstatfs64
:
6521 ret
= get_errno(fstatfs(arg1
, &stfs
));
6522 goto convert_statfs64
;
6524 #ifdef TARGET_NR_ioperm
6525 case TARGET_NR_ioperm
:
6528 #ifdef TARGET_NR_socketcall
6529 case TARGET_NR_socketcall
:
6530 ret
= do_socketcall(arg1
, arg2
);
6533 #ifdef TARGET_NR_accept
6534 case TARGET_NR_accept
:
6535 ret
= do_accept4(arg1
, arg2
, arg3
, 0);
6538 #ifdef TARGET_NR_accept4
6539 case TARGET_NR_accept4
:
6540 #ifdef CONFIG_ACCEPT4
6541 ret
= do_accept4(arg1
, arg2
, arg3
, arg4
);
6547 #ifdef TARGET_NR_bind
6548 case TARGET_NR_bind
:
6549 ret
= do_bind(arg1
, arg2
, arg3
);
6552 #ifdef TARGET_NR_connect
6553 case TARGET_NR_connect
:
6554 ret
= do_connect(arg1
, arg2
, arg3
);
6557 #ifdef TARGET_NR_getpeername
6558 case TARGET_NR_getpeername
:
6559 ret
= do_getpeername(arg1
, arg2
, arg3
);
6562 #ifdef TARGET_NR_getsockname
6563 case TARGET_NR_getsockname
:
6564 ret
= do_getsockname(arg1
, arg2
, arg3
);
6567 #ifdef TARGET_NR_getsockopt
6568 case TARGET_NR_getsockopt
:
6569 ret
= do_getsockopt(arg1
, arg2
, arg3
, arg4
, arg5
);
6572 #ifdef TARGET_NR_listen
6573 case TARGET_NR_listen
:
6574 ret
= get_errno(listen(arg1
, arg2
));
6577 #ifdef TARGET_NR_recv
6578 case TARGET_NR_recv
:
6579 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, 0, 0);
6582 #ifdef TARGET_NR_recvfrom
6583 case TARGET_NR_recvfrom
:
6584 ret
= do_recvfrom(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6587 #ifdef TARGET_NR_recvmsg
6588 case TARGET_NR_recvmsg
:
6589 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 0);
6592 #ifdef TARGET_NR_send
6593 case TARGET_NR_send
:
6594 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, 0, 0);
6597 #ifdef TARGET_NR_sendmsg
6598 case TARGET_NR_sendmsg
:
6599 ret
= do_sendrecvmsg(arg1
, arg2
, arg3
, 1);
6602 #ifdef TARGET_NR_sendto
6603 case TARGET_NR_sendto
:
6604 ret
= do_sendto(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6607 #ifdef TARGET_NR_shutdown
6608 case TARGET_NR_shutdown
:
6609 ret
= get_errno(shutdown(arg1
, arg2
));
6612 #ifdef TARGET_NR_socket
6613 case TARGET_NR_socket
:
6614 ret
= do_socket(arg1
, arg2
, arg3
);
6617 #ifdef TARGET_NR_socketpair
6618 case TARGET_NR_socketpair
:
6619 ret
= do_socketpair(arg1
, arg2
, arg3
, arg4
);
6622 #ifdef TARGET_NR_setsockopt
6623 case TARGET_NR_setsockopt
:
6624 ret
= do_setsockopt(arg1
, arg2
, arg3
, arg4
, (socklen_t
) arg5
);
6628 case TARGET_NR_syslog
:
6629 if (!(p
= lock_user_string(arg2
)))
6631 ret
= get_errno(sys_syslog((int)arg1
, p
, (int)arg3
));
6632 unlock_user(p
, arg2
, 0);
6635 case TARGET_NR_setitimer
:
6637 struct itimerval value
, ovalue
, *pvalue
;
6641 if (copy_from_user_timeval(&pvalue
->it_interval
, arg2
)
6642 || copy_from_user_timeval(&pvalue
->it_value
,
6643 arg2
+ sizeof(struct target_timeval
)))
6648 ret
= get_errno(setitimer(arg1
, pvalue
, &ovalue
));
6649 if (!is_error(ret
) && arg3
) {
6650 if (copy_to_user_timeval(arg3
,
6651 &ovalue
.it_interval
)
6652 || copy_to_user_timeval(arg3
+ sizeof(struct target_timeval
),
6658 case TARGET_NR_getitimer
:
6660 struct itimerval value
;
6662 ret
= get_errno(getitimer(arg1
, &value
));
6663 if (!is_error(ret
) && arg2
) {
6664 if (copy_to_user_timeval(arg2
,
6666 || copy_to_user_timeval(arg2
+ sizeof(struct target_timeval
),
6672 case TARGET_NR_stat
:
6673 if (!(p
= lock_user_string(arg1
)))
6675 ret
= get_errno(stat(path(p
), &st
));
6676 unlock_user(p
, arg1
, 0);
6678 case TARGET_NR_lstat
:
6679 if (!(p
= lock_user_string(arg1
)))
6681 ret
= get_errno(lstat(path(p
), &st
));
6682 unlock_user(p
, arg1
, 0);
6684 case TARGET_NR_fstat
:
6686 ret
= get_errno(fstat(arg1
, &st
));
6688 if (!is_error(ret
)) {
6689 struct target_stat
*target_st
;
6691 if (!lock_user_struct(VERIFY_WRITE
, target_st
, arg2
, 0))
6693 memset(target_st
, 0, sizeof(*target_st
));
6694 __put_user(st
.st_dev
, &target_st
->st_dev
);
6695 __put_user(st
.st_ino
, &target_st
->st_ino
);
6696 __put_user(st
.st_mode
, &target_st
->st_mode
);
6697 __put_user(st
.st_uid
, &target_st
->st_uid
);
6698 __put_user(st
.st_gid
, &target_st
->st_gid
);
6699 __put_user(st
.st_nlink
, &target_st
->st_nlink
);
6700 __put_user(st
.st_rdev
, &target_st
->st_rdev
);
6701 __put_user(st
.st_size
, &target_st
->st_size
);
6702 __put_user(st
.st_blksize
, &target_st
->st_blksize
);
6703 __put_user(st
.st_blocks
, &target_st
->st_blocks
);
6704 __put_user(st
.st_atime
, &target_st
->target_st_atime
);
6705 __put_user(st
.st_mtime
, &target_st
->target_st_mtime
);
6706 __put_user(st
.st_ctime
, &target_st
->target_st_ctime
);
6707 unlock_user_struct(target_st
, arg2
, 1);
6711 #ifdef TARGET_NR_olduname
6712 case TARGET_NR_olduname
:
6715 #ifdef TARGET_NR_iopl
6716 case TARGET_NR_iopl
:
6719 case TARGET_NR_vhangup
:
6720 ret
= get_errno(vhangup());
6722 #ifdef TARGET_NR_idle
6723 case TARGET_NR_idle
:
6726 #ifdef TARGET_NR_syscall
6727 case TARGET_NR_syscall
:
6728 ret
= do_syscall(cpu_env
, arg1
& 0xffff, arg2
, arg3
, arg4
, arg5
,
6729 arg6
, arg7
, arg8
, 0);
6732 case TARGET_NR_wait4
:
6735 abi_long status_ptr
= arg2
;
6736 struct rusage rusage
, *rusage_ptr
;
6737 abi_ulong target_rusage
= arg4
;
6739 rusage_ptr
= &rusage
;
6742 ret
= get_errno(wait4(arg1
, &status
, arg3
, rusage_ptr
));
6743 if (!is_error(ret
)) {
6744 if (status_ptr
&& ret
) {
6745 status
= host_to_target_waitstatus(status
);
6746 if (put_user_s32(status
, status_ptr
))
6750 host_to_target_rusage(target_rusage
, &rusage
);
6754 #ifdef TARGET_NR_swapoff
6755 case TARGET_NR_swapoff
:
6756 if (!(p
= lock_user_string(arg1
)))
6758 ret
= get_errno(swapoff(p
));
6759 unlock_user(p
, arg1
, 0);
6762 case TARGET_NR_sysinfo
:
6764 struct target_sysinfo
*target_value
;
6765 struct sysinfo value
;
6766 ret
= get_errno(sysinfo(&value
));
6767 if (!is_error(ret
) && arg1
)
6769 if (!lock_user_struct(VERIFY_WRITE
, target_value
, arg1
, 0))
6771 __put_user(value
.uptime
, &target_value
->uptime
);
6772 __put_user(value
.loads
[0], &target_value
->loads
[0]);
6773 __put_user(value
.loads
[1], &target_value
->loads
[1]);
6774 __put_user(value
.loads
[2], &target_value
->loads
[2]);
6775 __put_user(value
.totalram
, &target_value
->totalram
);
6776 __put_user(value
.freeram
, &target_value
->freeram
);
6777 __put_user(value
.sharedram
, &target_value
->sharedram
);
6778 __put_user(value
.bufferram
, &target_value
->bufferram
);
6779 __put_user(value
.totalswap
, &target_value
->totalswap
);
6780 __put_user(value
.freeswap
, &target_value
->freeswap
);
6781 __put_user(value
.procs
, &target_value
->procs
);
6782 __put_user(value
.totalhigh
, &target_value
->totalhigh
);
6783 __put_user(value
.freehigh
, &target_value
->freehigh
);
6784 __put_user(value
.mem_unit
, &target_value
->mem_unit
);
6785 unlock_user_struct(target_value
, arg1
, 1);
6789 #ifdef TARGET_NR_ipc
6791 ret
= do_ipc(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
6794 #ifdef TARGET_NR_semget
6795 case TARGET_NR_semget
:
6796 ret
= get_errno(semget(arg1
, arg2
, arg3
));
6799 #ifdef TARGET_NR_semop
6800 case TARGET_NR_semop
:
6801 ret
= do_semop(arg1
, arg2
, arg3
);
6804 #ifdef TARGET_NR_semctl
6805 case TARGET_NR_semctl
:
6806 ret
= do_semctl(arg1
, arg2
, arg3
, (union target_semun
)(abi_ulong
)arg4
);
6809 #ifdef TARGET_NR_msgctl
6810 case TARGET_NR_msgctl
:
6811 ret
= do_msgctl(arg1
, arg2
, arg3
);
6814 #ifdef TARGET_NR_msgget
6815 case TARGET_NR_msgget
:
6816 ret
= get_errno(msgget(arg1
, arg2
));
6819 #ifdef TARGET_NR_msgrcv
6820 case TARGET_NR_msgrcv
:
6821 ret
= do_msgrcv(arg1
, arg2
, arg3
, arg4
, arg5
);
6824 #ifdef TARGET_NR_msgsnd
6825 case TARGET_NR_msgsnd
:
6826 ret
= do_msgsnd(arg1
, arg2
, arg3
, arg4
);
6829 #ifdef TARGET_NR_shmget
6830 case TARGET_NR_shmget
:
6831 ret
= get_errno(shmget(arg1
, arg2
, arg3
));
6834 #ifdef TARGET_NR_shmctl
6835 case TARGET_NR_shmctl
:
6836 ret
= do_shmctl(arg1
, arg2
, arg3
);
6839 #ifdef TARGET_NR_shmat
6840 case TARGET_NR_shmat
:
6841 ret
= do_shmat(arg1
, arg2
, arg3
);
6844 #ifdef TARGET_NR_shmdt
6845 case TARGET_NR_shmdt
:
6846 ret
= do_shmdt(arg1
);
6849 case TARGET_NR_fsync
:
6850 ret
= get_errno(fsync(arg1
));
6852 case TARGET_NR_clone
:
6853 #if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6854 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg5
, arg4
));
6855 #elif defined(TARGET_CRIS)
6856 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg4
, arg5
));
6857 #elif defined(TARGET_MICROBLAZE)
6858 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg4
, arg6
, arg5
));
6859 #elif defined(TARGET_S390X)
6860 ret
= get_errno(do_fork(cpu_env
, arg2
, arg1
, arg3
, arg5
, arg4
));
6862 ret
= get_errno(do_fork(cpu_env
, arg1
, arg2
, arg3
, arg4
, arg5
));
6865 #ifdef __NR_exit_group
6866 /* new thread calls */
6867 case TARGET_NR_exit_group
:
6871 gdb_exit(cpu_env
, arg1
);
6872 ret
= get_errno(exit_group(arg1
));
6875 case TARGET_NR_setdomainname
:
6876 if (!(p
= lock_user_string(arg1
)))
6878 ret
= get_errno(setdomainname(p
, arg2
));
6879 unlock_user(p
, arg1
, 0);
6881 case TARGET_NR_uname
:
6882 /* no need to transcode because we use the linux syscall */
6884 struct new_utsname
* buf
;
6886 if (!lock_user_struct(VERIFY_WRITE
, buf
, arg1
, 0))
6888 ret
= get_errno(sys_uname(buf
));
6889 if (!is_error(ret
)) {
6890 /* Overrite the native machine name with whatever is being
6892 strcpy (buf
->machine
, cpu_to_uname_machine(cpu_env
));
6893 /* Allow the user to override the reported release. */
6894 if (qemu_uname_release
&& *qemu_uname_release
)
6895 strcpy (buf
->release
, qemu_uname_release
);
6897 unlock_user_struct(buf
, arg1
, 1);
6901 case TARGET_NR_modify_ldt
:
6902 ret
= do_modify_ldt(cpu_env
, arg1
, arg2
, arg3
);
6904 #if !defined(TARGET_X86_64)
6905 case TARGET_NR_vm86old
:
6907 case TARGET_NR_vm86
:
6908 ret
= do_vm86(cpu_env
, arg1
, arg2
);
6912 case TARGET_NR_adjtimex
:
6914 #ifdef TARGET_NR_create_module
6915 case TARGET_NR_create_module
:
6917 case TARGET_NR_init_module
:
6918 case TARGET_NR_delete_module
:
6919 #ifdef TARGET_NR_get_kernel_syms
6920 case TARGET_NR_get_kernel_syms
:
6923 case TARGET_NR_quotactl
:
6925 case TARGET_NR_getpgid
:
6926 ret
= get_errno(getpgid(arg1
));
6928 case TARGET_NR_fchdir
:
6929 ret
= get_errno(fchdir(arg1
));
6931 #ifdef TARGET_NR_bdflush /* not on x86_64 */
6932 case TARGET_NR_bdflush
:
6935 #ifdef TARGET_NR_sysfs
6936 case TARGET_NR_sysfs
:
6939 case TARGET_NR_personality
:
6940 ret
= get_errno(personality(arg1
));
6942 #ifdef TARGET_NR_afs_syscall
6943 case TARGET_NR_afs_syscall
:
6946 #ifdef TARGET_NR__llseek /* Not on alpha */
6947 case TARGET_NR__llseek
:
6950 #if !defined(__NR_llseek)
6951 res
= lseek(arg1
, ((uint64_t)arg2
<< 32) | arg3
, arg5
);
6953 ret
= get_errno(res
);
6958 ret
= get_errno(_llseek(arg1
, arg2
, arg3
, &res
, arg5
));
6960 if ((ret
== 0) && put_user_s64(res
, arg4
)) {
6966 case TARGET_NR_getdents
:
6967 #ifdef __NR_getdents
6968 #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
6970 struct target_dirent
*target_dirp
;
6971 struct linux_dirent
*dirp
;
6972 abi_long count
= arg3
;
6974 dirp
= malloc(count
);
6976 ret
= -TARGET_ENOMEM
;
6980 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
6981 if (!is_error(ret
)) {
6982 struct linux_dirent
*de
;
6983 struct target_dirent
*tde
;
6985 int reclen
, treclen
;
6986 int count1
, tnamelen
;
6990 if (!(target_dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
6994 reclen
= de
->d_reclen
;
6995 tnamelen
= reclen
- offsetof(struct linux_dirent
, d_name
);
6996 assert(tnamelen
>= 0);
6997 treclen
= tnamelen
+ offsetof(struct target_dirent
, d_name
);
6998 assert(count1
+ treclen
<= count
);
6999 tde
->d_reclen
= tswap16(treclen
);
7000 tde
->d_ino
= tswapal(de
->d_ino
);
7001 tde
->d_off
= tswapal(de
->d_off
);
7002 memcpy(tde
->d_name
, de
->d_name
, tnamelen
);
7003 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7005 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
7009 unlock_user(target_dirp
, arg2
, ret
);
7015 struct linux_dirent
*dirp
;
7016 abi_long count
= arg3
;
7018 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7020 ret
= get_errno(sys_getdents(arg1
, dirp
, count
));
7021 if (!is_error(ret
)) {
7022 struct linux_dirent
*de
;
7027 reclen
= de
->d_reclen
;
7030 de
->d_reclen
= tswap16(reclen
);
7031 tswapls(&de
->d_ino
);
7032 tswapls(&de
->d_off
);
7033 de
= (struct linux_dirent
*)((char *)de
+ reclen
);
7037 unlock_user(dirp
, arg2
, ret
);
7041 /* Implement getdents in terms of getdents64 */
7043 struct linux_dirent64
*dirp
;
7044 abi_long count
= arg3
;
7046 dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0);
7050 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
7051 if (!is_error(ret
)) {
7052 /* Convert the dirent64 structs to target dirent. We do this
7053 * in-place, since we can guarantee that a target_dirent is no
7054 * larger than a dirent64; however this means we have to be
7055 * careful to read everything before writing in the new format.
7057 struct linux_dirent64
*de
;
7058 struct target_dirent
*tde
;
7063 tde
= (struct target_dirent
*)dirp
;
7065 int namelen
, treclen
;
7066 int reclen
= de
->d_reclen
;
7067 uint64_t ino
= de
->d_ino
;
7068 int64_t off
= de
->d_off
;
7069 uint8_t type
= de
->d_type
;
7071 namelen
= strlen(de
->d_name
);
7072 treclen
= offsetof(struct target_dirent
, d_name
)
7074 treclen
= QEMU_ALIGN_UP(treclen
, sizeof(abi_long
));
7076 memmove(tde
->d_name
, de
->d_name
, namelen
+ 1);
7077 tde
->d_ino
= tswapal(ino
);
7078 tde
->d_off
= tswapal(off
);
7079 tde
->d_reclen
= tswap16(treclen
);
7080 /* The target_dirent type is in what was formerly a padding
7081 * byte at the end of the structure:
7083 *(((char *)tde
) + treclen
- 1) = type
;
7085 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
7086 tde
= (struct target_dirent
*)((char *)tde
+ treclen
);
7092 unlock_user(dirp
, arg2
, ret
);
7096 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
7097 case TARGET_NR_getdents64
:
7099 struct linux_dirent64
*dirp
;
7100 abi_long count
= arg3
;
7101 if (!(dirp
= lock_user(VERIFY_WRITE
, arg2
, count
, 0)))
7103 ret
= get_errno(sys_getdents64(arg1
, dirp
, count
));
7104 if (!is_error(ret
)) {
7105 struct linux_dirent64
*de
;
7110 reclen
= de
->d_reclen
;
7113 de
->d_reclen
= tswap16(reclen
);
7114 tswap64s((uint64_t *)&de
->d_ino
);
7115 tswap64s((uint64_t *)&de
->d_off
);
7116 de
= (struct linux_dirent64
*)((char *)de
+ reclen
);
7120 unlock_user(dirp
, arg2
, ret
);
7123 #endif /* TARGET_NR_getdents64 */
7124 #if defined(TARGET_NR__newselect)
7125 case TARGET_NR__newselect
:
7126 ret
= do_select(arg1
, arg2
, arg3
, arg4
, arg5
);
7129 #if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
7130 # ifdef TARGET_NR_poll
7131 case TARGET_NR_poll
:
7133 # ifdef TARGET_NR_ppoll
7134 case TARGET_NR_ppoll
:
7137 struct target_pollfd
*target_pfd
;
7138 unsigned int nfds
= arg2
;
7143 target_pfd
= lock_user(VERIFY_WRITE
, arg1
, sizeof(struct target_pollfd
) * nfds
, 1);
7147 pfd
= alloca(sizeof(struct pollfd
) * nfds
);
7148 for(i
= 0; i
< nfds
; i
++) {
7149 pfd
[i
].fd
= tswap32(target_pfd
[i
].fd
);
7150 pfd
[i
].events
= tswap16(target_pfd
[i
].events
);
7153 # ifdef TARGET_NR_ppoll
7154 if (num
== TARGET_NR_ppoll
) {
7155 struct timespec _timeout_ts
, *timeout_ts
= &_timeout_ts
;
7156 target_sigset_t
*target_set
;
7157 sigset_t _set
, *set
= &_set
;
7160 if (target_to_host_timespec(timeout_ts
, arg3
)) {
7161 unlock_user(target_pfd
, arg1
, 0);
7169 target_set
= lock_user(VERIFY_READ
, arg4
, sizeof(target_sigset_t
), 1);
7171 unlock_user(target_pfd
, arg1
, 0);
7174 target_to_host_sigset(set
, target_set
);
7179 ret
= get_errno(sys_ppoll(pfd
, nfds
, timeout_ts
, set
, _NSIG
/8));
7181 if (!is_error(ret
) && arg3
) {
7182 host_to_target_timespec(arg3
, timeout_ts
);
7185 unlock_user(target_set
, arg4
, 0);
7189 ret
= get_errno(poll(pfd
, nfds
, timeout
));
7191 if (!is_error(ret
)) {
7192 for(i
= 0; i
< nfds
; i
++) {
7193 target_pfd
[i
].revents
= tswap16(pfd
[i
].revents
);
7196 unlock_user(target_pfd
, arg1
, sizeof(struct target_pollfd
) * nfds
);
7200 case TARGET_NR_flock
:
7201 /* NOTE: the flock constant seems to be the same for every
7203 ret
= get_errno(flock(arg1
, arg2
));
7205 case TARGET_NR_readv
:
7207 struct iovec
*vec
= lock_iovec(VERIFY_WRITE
, arg2
, arg3
, 0);
7209 ret
= get_errno(readv(arg1
, vec
, arg3
));
7210 unlock_iovec(vec
, arg2
, arg3
, 1);
7212 ret
= -host_to_target_errno(errno
);
7216 case TARGET_NR_writev
:
7218 struct iovec
*vec
= lock_iovec(VERIFY_READ
, arg2
, arg3
, 1);
7220 ret
= get_errno(writev(arg1
, vec
, arg3
));
7221 unlock_iovec(vec
, arg2
, arg3
, 0);
7223 ret
= -host_to_target_errno(errno
);
7227 case TARGET_NR_getsid
:
7228 ret
= get_errno(getsid(arg1
));
7230 #if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
7231 case TARGET_NR_fdatasync
:
7232 ret
= get_errno(fdatasync(arg1
));
7235 case TARGET_NR__sysctl
:
7236 /* We don't implement this, but ENOTDIR is always a safe
7238 ret
= -TARGET_ENOTDIR
;
7240 case TARGET_NR_sched_getaffinity
:
7242 unsigned int mask_size
;
7243 unsigned long *mask
;
7246 * sched_getaffinity needs multiples of ulong, so need to take
7247 * care of mismatches between target ulong and host ulong sizes.
7249 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7250 ret
= -TARGET_EINVAL
;
7253 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7255 mask
= alloca(mask_size
);
7256 ret
= get_errno(sys_sched_getaffinity(arg1
, mask_size
, mask
));
7258 if (!is_error(ret
)) {
7259 if (copy_to_user(arg3
, mask
, ret
)) {
7265 case TARGET_NR_sched_setaffinity
:
7267 unsigned int mask_size
;
7268 unsigned long *mask
;
7271 * sched_setaffinity needs multiples of ulong, so need to take
7272 * care of mismatches between target ulong and host ulong sizes.
7274 if (arg2
& (sizeof(abi_ulong
) - 1)) {
7275 ret
= -TARGET_EINVAL
;
7278 mask_size
= (arg2
+ (sizeof(*mask
) - 1)) & ~(sizeof(*mask
) - 1);
7280 mask
= alloca(mask_size
);
7281 if (!lock_user_struct(VERIFY_READ
, p
, arg3
, 1)) {
7284 memcpy(mask
, p
, arg2
);
7285 unlock_user_struct(p
, arg2
, 0);
7287 ret
= get_errno(sys_sched_setaffinity(arg1
, mask_size
, mask
));
7290 case TARGET_NR_sched_setparam
:
7292 struct sched_param
*target_schp
;
7293 struct sched_param schp
;
7295 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg2
, 1))
7297 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7298 unlock_user_struct(target_schp
, arg2
, 0);
7299 ret
= get_errno(sched_setparam(arg1
, &schp
));
7302 case TARGET_NR_sched_getparam
:
7304 struct sched_param
*target_schp
;
7305 struct sched_param schp
;
7306 ret
= get_errno(sched_getparam(arg1
, &schp
));
7307 if (!is_error(ret
)) {
7308 if (!lock_user_struct(VERIFY_WRITE
, target_schp
, arg2
, 0))
7310 target_schp
->sched_priority
= tswap32(schp
.sched_priority
);
7311 unlock_user_struct(target_schp
, arg2
, 1);
7315 case TARGET_NR_sched_setscheduler
:
7317 struct sched_param
*target_schp
;
7318 struct sched_param schp
;
7319 if (!lock_user_struct(VERIFY_READ
, target_schp
, arg3
, 1))
7321 schp
.sched_priority
= tswap32(target_schp
->sched_priority
);
7322 unlock_user_struct(target_schp
, arg3
, 0);
7323 ret
= get_errno(sched_setscheduler(arg1
, arg2
, &schp
));
7326 case TARGET_NR_sched_getscheduler
:
7327 ret
= get_errno(sched_getscheduler(arg1
));
7329 case TARGET_NR_sched_yield
:
7330 ret
= get_errno(sched_yield());
7332 case TARGET_NR_sched_get_priority_max
:
7333 ret
= get_errno(sched_get_priority_max(arg1
));
7335 case TARGET_NR_sched_get_priority_min
:
7336 ret
= get_errno(sched_get_priority_min(arg1
));
7338 case TARGET_NR_sched_rr_get_interval
:
7341 ret
= get_errno(sched_rr_get_interval(arg1
, &ts
));
7342 if (!is_error(ret
)) {
7343 host_to_target_timespec(arg2
, &ts
);
7347 case TARGET_NR_nanosleep
:
7349 struct timespec req
, rem
;
7350 target_to_host_timespec(&req
, arg1
);
7351 ret
= get_errno(nanosleep(&req
, &rem
));
7352 if (is_error(ret
) && arg2
) {
7353 host_to_target_timespec(arg2
, &rem
);
7357 #ifdef TARGET_NR_query_module
7358 case TARGET_NR_query_module
:
7361 #ifdef TARGET_NR_nfsservctl
7362 case TARGET_NR_nfsservctl
:
7365 case TARGET_NR_prctl
:
7367 case PR_GET_PDEATHSIG
:
7370 ret
= get_errno(prctl(arg1
, &deathsig
, arg3
, arg4
, arg5
));
7371 if (!is_error(ret
) && arg2
7372 && put_user_ual(deathsig
, arg2
)) {
7380 void *name
= lock_user(VERIFY_WRITE
, arg2
, 16, 1);
7384 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7386 unlock_user(name
, arg2
, 16);
7391 void *name
= lock_user(VERIFY_READ
, arg2
, 16, 1);
7395 ret
= get_errno(prctl(arg1
, (unsigned long)name
,
7397 unlock_user(name
, arg2
, 0);
7402 /* Most prctl options have no pointer arguments */
7403 ret
= get_errno(prctl(arg1
, arg2
, arg3
, arg4
, arg5
));
7407 #ifdef TARGET_NR_arch_prctl
7408 case TARGET_NR_arch_prctl
:
7409 #if defined(TARGET_I386) && !defined(TARGET_ABI32)
7410 ret
= do_arch_prctl(cpu_env
, arg1
, arg2
);
7416 #ifdef TARGET_NR_pread64
7417 case TARGET_NR_pread64
:
7418 if (regpairs_aligned(cpu_env
)) {
7422 if (!(p
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0)))
7424 ret
= get_errno(pread64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7425 unlock_user(p
, arg2
, ret
);
7427 case TARGET_NR_pwrite64
:
7428 if (regpairs_aligned(cpu_env
)) {
7432 if (!(p
= lock_user(VERIFY_READ
, arg2
, arg3
, 1)))
7434 ret
= get_errno(pwrite64(arg1
, p
, arg3
, target_offset64(arg4
, arg5
)));
7435 unlock_user(p
, arg2
, 0);
7438 case TARGET_NR_getcwd
:
7439 if (!(p
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0)))
7441 ret
= get_errno(sys_getcwd1(p
, arg2
));
7442 unlock_user(p
, arg1
, ret
);
7444 case TARGET_NR_capget
:
7446 case TARGET_NR_capset
:
7448 case TARGET_NR_sigaltstack
:
7449 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
7450 defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
7451 defined(TARGET_M68K) || defined(TARGET_S390X) || defined(TARGET_OPENRISC)
7452 ret
= do_sigaltstack(arg1
, arg2
, get_sp_from_cpustate((CPUArchState
*)cpu_env
));
7458 #ifdef CONFIG_SENDFILE
7459 case TARGET_NR_sendfile
:
7464 ret
= get_user_sal(off
, arg3
);
7465 if (is_error(ret
)) {
7470 ret
= get_errno(sendfile(arg1
, arg2
, offp
, arg4
));
7471 if (!is_error(ret
) && arg3
) {
7472 abi_long ret2
= put_user_sal(off
, arg3
);
7473 if (is_error(ret2
)) {
7479 #ifdef TARGET_NR_sendfile64
7480 case TARGET_NR_sendfile64
:
7485 ret
= get_user_s64(off
, arg3
);
7486 if (is_error(ret
)) {
7491 ret
= get_errno(sendfile(arg1
, arg2
, offp
, arg4
));
7492 if (!is_error(ret
) && arg3
) {
7493 abi_long ret2
= put_user_s64(off
, arg3
);
7494 if (is_error(ret2
)) {
7502 case TARGET_NR_sendfile
:
7503 #ifdef TARGET_NR_sendfile64
7504 case TARGET_NR_sendfile64
:
7509 #ifdef TARGET_NR_getpmsg
7510 case TARGET_NR_getpmsg
:
7513 #ifdef TARGET_NR_putpmsg
7514 case TARGET_NR_putpmsg
:
7517 #ifdef TARGET_NR_vfork
7518 case TARGET_NR_vfork
:
7519 ret
= get_errno(do_fork(cpu_env
, CLONE_VFORK
| CLONE_VM
| SIGCHLD
,
7523 #ifdef TARGET_NR_ugetrlimit
7524 case TARGET_NR_ugetrlimit
:
7527 int resource
= target_to_host_resource(arg1
);
7528 ret
= get_errno(getrlimit(resource
, &rlim
));
7529 if (!is_error(ret
)) {
7530 struct target_rlimit
*target_rlim
;
7531 if (!lock_user_struct(VERIFY_WRITE
, target_rlim
, arg2
, 0))
7533 target_rlim
->rlim_cur
= host_to_target_rlim(rlim
.rlim_cur
);
7534 target_rlim
->rlim_max
= host_to_target_rlim(rlim
.rlim_max
);
7535 unlock_user_struct(target_rlim
, arg2
, 1);
7540 #ifdef TARGET_NR_truncate64
7541 case TARGET_NR_truncate64
:
7542 if (!(p
= lock_user_string(arg1
)))
7544 ret
= target_truncate64(cpu_env
, p
, arg2
, arg3
, arg4
);
7545 unlock_user(p
, arg1
, 0);
7548 #ifdef TARGET_NR_ftruncate64
7549 case TARGET_NR_ftruncate64
:
7550 ret
= target_ftruncate64(cpu_env
, arg1
, arg2
, arg3
, arg4
);
7553 #ifdef TARGET_NR_stat64
7554 case TARGET_NR_stat64
:
7555 if (!(p
= lock_user_string(arg1
)))
7557 ret
= get_errno(stat(path(p
), &st
));
7558 unlock_user(p
, arg1
, 0);
7560 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7563 #ifdef TARGET_NR_lstat64
7564 case TARGET_NR_lstat64
:
7565 if (!(p
= lock_user_string(arg1
)))
7567 ret
= get_errno(lstat(path(p
), &st
));
7568 unlock_user(p
, arg1
, 0);
7570 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7573 #ifdef TARGET_NR_fstat64
7574 case TARGET_NR_fstat64
:
7575 ret
= get_errno(fstat(arg1
, &st
));
7577 ret
= host_to_target_stat64(cpu_env
, arg2
, &st
);
7580 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat))
7581 #ifdef TARGET_NR_fstatat64
7582 case TARGET_NR_fstatat64
:
7584 #ifdef TARGET_NR_newfstatat
7585 case TARGET_NR_newfstatat
:
7587 if (!(p
= lock_user_string(arg2
)))
7589 ret
= get_errno(fstatat(arg1
, path(p
), &st
, arg4
));
7591 ret
= host_to_target_stat64(cpu_env
, arg3
, &st
);
7594 case TARGET_NR_lchown
:
7595 if (!(p
= lock_user_string(arg1
)))
7597 ret
= get_errno(lchown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7598 unlock_user(p
, arg1
, 0);
7600 #ifdef TARGET_NR_getuid
7601 case TARGET_NR_getuid
:
7602 ret
= get_errno(high2lowuid(getuid()));
7605 #ifdef TARGET_NR_getgid
7606 case TARGET_NR_getgid
:
7607 ret
= get_errno(high2lowgid(getgid()));
7610 #ifdef TARGET_NR_geteuid
7611 case TARGET_NR_geteuid
:
7612 ret
= get_errno(high2lowuid(geteuid()));
7615 #ifdef TARGET_NR_getegid
7616 case TARGET_NR_getegid
:
7617 ret
= get_errno(high2lowgid(getegid()));
7620 case TARGET_NR_setreuid
:
7621 ret
= get_errno(setreuid(low2highuid(arg1
), low2highuid(arg2
)));
7623 case TARGET_NR_setregid
:
7624 ret
= get_errno(setregid(low2highgid(arg1
), low2highgid(arg2
)));
7626 case TARGET_NR_getgroups
:
7628 int gidsetsize
= arg1
;
7629 target_id
*target_grouplist
;
7633 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7634 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7635 if (gidsetsize
== 0)
7637 if (!is_error(ret
)) {
7638 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* sizeof(target_id
), 0);
7639 if (!target_grouplist
)
7641 for(i
= 0;i
< ret
; i
++)
7642 target_grouplist
[i
] = tswapid(high2lowgid(grouplist
[i
]));
7643 unlock_user(target_grouplist
, arg2
, gidsetsize
* sizeof(target_id
));
7647 case TARGET_NR_setgroups
:
7649 int gidsetsize
= arg1
;
7650 target_id
*target_grouplist
;
7651 gid_t
*grouplist
= NULL
;
7654 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7655 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* sizeof(target_id
), 1);
7656 if (!target_grouplist
) {
7657 ret
= -TARGET_EFAULT
;
7660 for (i
= 0; i
< gidsetsize
; i
++) {
7661 grouplist
[i
] = low2highgid(tswapid(target_grouplist
[i
]));
7663 unlock_user(target_grouplist
, arg2
, 0);
7665 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
7668 case TARGET_NR_fchown
:
7669 ret
= get_errno(fchown(arg1
, low2highuid(arg2
), low2highgid(arg3
)));
7671 #if defined(TARGET_NR_fchownat)
7672 case TARGET_NR_fchownat
:
7673 if (!(p
= lock_user_string(arg2
)))
7675 ret
= get_errno(fchownat(arg1
, p
, low2highuid(arg3
),
7676 low2highgid(arg4
), arg5
));
7677 unlock_user(p
, arg2
, 0);
7680 #ifdef TARGET_NR_setresuid
7681 case TARGET_NR_setresuid
:
7682 ret
= get_errno(setresuid(low2highuid(arg1
),
7684 low2highuid(arg3
)));
7687 #ifdef TARGET_NR_getresuid
7688 case TARGET_NR_getresuid
:
7690 uid_t ruid
, euid
, suid
;
7691 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
7692 if (!is_error(ret
)) {
7693 if (put_user_u16(high2lowuid(ruid
), arg1
)
7694 || put_user_u16(high2lowuid(euid
), arg2
)
7695 || put_user_u16(high2lowuid(suid
), arg3
))
7701 #ifdef TARGET_NR_getresgid
7702 case TARGET_NR_setresgid
:
7703 ret
= get_errno(setresgid(low2highgid(arg1
),
7705 low2highgid(arg3
)));
7708 #ifdef TARGET_NR_getresgid
7709 case TARGET_NR_getresgid
:
7711 gid_t rgid
, egid
, sgid
;
7712 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
7713 if (!is_error(ret
)) {
7714 if (put_user_u16(high2lowgid(rgid
), arg1
)
7715 || put_user_u16(high2lowgid(egid
), arg2
)
7716 || put_user_u16(high2lowgid(sgid
), arg3
))
7722 case TARGET_NR_chown
:
7723 if (!(p
= lock_user_string(arg1
)))
7725 ret
= get_errno(chown(p
, low2highuid(arg2
), low2highgid(arg3
)));
7726 unlock_user(p
, arg1
, 0);
7728 case TARGET_NR_setuid
:
7729 ret
= get_errno(setuid(low2highuid(arg1
)));
7731 case TARGET_NR_setgid
:
7732 ret
= get_errno(setgid(low2highgid(arg1
)));
7734 case TARGET_NR_setfsuid
:
7735 ret
= get_errno(setfsuid(arg1
));
7737 case TARGET_NR_setfsgid
:
7738 ret
= get_errno(setfsgid(arg1
));
7741 #ifdef TARGET_NR_lchown32
7742 case TARGET_NR_lchown32
:
7743 if (!(p
= lock_user_string(arg1
)))
7745 ret
= get_errno(lchown(p
, arg2
, arg3
));
7746 unlock_user(p
, arg1
, 0);
7749 #ifdef TARGET_NR_getuid32
7750 case TARGET_NR_getuid32
:
7751 ret
= get_errno(getuid());
7755 #if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7756 /* Alpha specific */
7757 case TARGET_NR_getxuid
:
7761 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=euid
;
7763 ret
= get_errno(getuid());
7766 #if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7767 /* Alpha specific */
7768 case TARGET_NR_getxgid
:
7772 ((CPUAlphaState
*)cpu_env
)->ir
[IR_A4
]=egid
;
7774 ret
= get_errno(getgid());
7777 #if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7778 /* Alpha specific */
7779 case TARGET_NR_osf_getsysinfo
:
7780 ret
= -TARGET_EOPNOTSUPP
;
7782 case TARGET_GSI_IEEE_FP_CONTROL
:
7784 uint64_t swcr
, fpcr
= cpu_alpha_load_fpcr (cpu_env
);
7786 /* Copied from linux ieee_fpcr_to_swcr. */
7787 swcr
= (fpcr
>> 35) & SWCR_STATUS_MASK
;
7788 swcr
|= (fpcr
>> 36) & SWCR_MAP_DMZ
;
7789 swcr
|= (~fpcr
>> 48) & (SWCR_TRAP_ENABLE_INV
7790 | SWCR_TRAP_ENABLE_DZE
7791 | SWCR_TRAP_ENABLE_OVF
);
7792 swcr
|= (~fpcr
>> 57) & (SWCR_TRAP_ENABLE_UNF
7793 | SWCR_TRAP_ENABLE_INE
);
7794 swcr
|= (fpcr
>> 47) & SWCR_MAP_UMZ
;
7795 swcr
|= (~fpcr
>> 41) & SWCR_TRAP_ENABLE_DNO
;
7797 if (put_user_u64 (swcr
, arg2
))
7803 /* case GSI_IEEE_STATE_AT_SIGNAL:
7804 -- Not implemented in linux kernel.
7806 -- Retrieves current unaligned access state; not much used.
7808 -- Retrieves implver information; surely not used.
7810 -- Grabs a copy of the HWRPB; surely not used.
7815 #if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7816 /* Alpha specific */
7817 case TARGET_NR_osf_setsysinfo
:
7818 ret
= -TARGET_EOPNOTSUPP
;
7820 case TARGET_SSI_IEEE_FP_CONTROL
:
7822 uint64_t swcr
, fpcr
, orig_fpcr
;
7824 if (get_user_u64 (swcr
, arg2
)) {
7827 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
7828 fpcr
= orig_fpcr
& FPCR_DYN_MASK
;
7830 /* Copied from linux ieee_swcr_to_fpcr. */
7831 fpcr
|= (swcr
& SWCR_STATUS_MASK
) << 35;
7832 fpcr
|= (swcr
& SWCR_MAP_DMZ
) << 36;
7833 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_INV
7834 | SWCR_TRAP_ENABLE_DZE
7835 | SWCR_TRAP_ENABLE_OVF
)) << 48;
7836 fpcr
|= (~swcr
& (SWCR_TRAP_ENABLE_UNF
7837 | SWCR_TRAP_ENABLE_INE
)) << 57;
7838 fpcr
|= (swcr
& SWCR_MAP_UMZ
? FPCR_UNDZ
| FPCR_UNFD
: 0);
7839 fpcr
|= (~swcr
& SWCR_TRAP_ENABLE_DNO
) << 41;
7841 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
7846 case TARGET_SSI_IEEE_RAISE_EXCEPTION
:
7848 uint64_t exc
, fpcr
, orig_fpcr
;
7851 if (get_user_u64(exc
, arg2
)) {
7855 orig_fpcr
= cpu_alpha_load_fpcr(cpu_env
);
7857 /* We only add to the exception status here. */
7858 fpcr
= orig_fpcr
| ((exc
& SWCR_STATUS_MASK
) << 35);
7860 cpu_alpha_store_fpcr(cpu_env
, fpcr
);
7863 /* Old exceptions are not signaled. */
7864 fpcr
&= ~(orig_fpcr
& FPCR_STATUS_MASK
);
7866 /* If any exceptions set by this call,
7867 and are unmasked, send a signal. */
7869 if ((fpcr
& (FPCR_INE
| FPCR_INED
)) == FPCR_INE
) {
7870 si_code
= TARGET_FPE_FLTRES
;
7872 if ((fpcr
& (FPCR_UNF
| FPCR_UNFD
)) == FPCR_UNF
) {
7873 si_code
= TARGET_FPE_FLTUND
;
7875 if ((fpcr
& (FPCR_OVF
| FPCR_OVFD
)) == FPCR_OVF
) {
7876 si_code
= TARGET_FPE_FLTOVF
;
7878 if ((fpcr
& (FPCR_DZE
| FPCR_DZED
)) == FPCR_DZE
) {
7879 si_code
= TARGET_FPE_FLTDIV
;
7881 if ((fpcr
& (FPCR_INV
| FPCR_INVD
)) == FPCR_INV
) {
7882 si_code
= TARGET_FPE_FLTINV
;
7885 target_siginfo_t info
;
7886 info
.si_signo
= SIGFPE
;
7888 info
.si_code
= si_code
;
7889 info
._sifields
._sigfault
._addr
7890 = ((CPUArchState
*)cpu_env
)->pc
;
7891 queue_signal((CPUArchState
*)cpu_env
, info
.si_signo
, &info
);
7896 /* case SSI_NVPAIRS:
7897 -- Used with SSIN_UACPROC to enable unaligned accesses.
7898 case SSI_IEEE_STATE_AT_SIGNAL:
7899 case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7900 -- Not implemented in linux kernel
7905 #ifdef TARGET_NR_osf_sigprocmask
7906 /* Alpha specific. */
7907 case TARGET_NR_osf_sigprocmask
:
7911 sigset_t set
, oldset
;
7914 case TARGET_SIG_BLOCK
:
7917 case TARGET_SIG_UNBLOCK
:
7920 case TARGET_SIG_SETMASK
:
7924 ret
= -TARGET_EINVAL
;
7928 target_to_host_old_sigset(&set
, &mask
);
7929 sigprocmask(how
, &set
, &oldset
);
7930 host_to_target_old_sigset(&mask
, &oldset
);
7936 #ifdef TARGET_NR_getgid32
7937 case TARGET_NR_getgid32
:
7938 ret
= get_errno(getgid());
7941 #ifdef TARGET_NR_geteuid32
7942 case TARGET_NR_geteuid32
:
7943 ret
= get_errno(geteuid());
7946 #ifdef TARGET_NR_getegid32
7947 case TARGET_NR_getegid32
:
7948 ret
= get_errno(getegid());
7951 #ifdef TARGET_NR_setreuid32
7952 case TARGET_NR_setreuid32
:
7953 ret
= get_errno(setreuid(arg1
, arg2
));
7956 #ifdef TARGET_NR_setregid32
7957 case TARGET_NR_setregid32
:
7958 ret
= get_errno(setregid(arg1
, arg2
));
7961 #ifdef TARGET_NR_getgroups32
7962 case TARGET_NR_getgroups32
:
7964 int gidsetsize
= arg1
;
7965 uint32_t *target_grouplist
;
7969 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7970 ret
= get_errno(getgroups(gidsetsize
, grouplist
));
7971 if (gidsetsize
== 0)
7973 if (!is_error(ret
)) {
7974 target_grouplist
= lock_user(VERIFY_WRITE
, arg2
, gidsetsize
* 4, 0);
7975 if (!target_grouplist
) {
7976 ret
= -TARGET_EFAULT
;
7979 for(i
= 0;i
< ret
; i
++)
7980 target_grouplist
[i
] = tswap32(grouplist
[i
]);
7981 unlock_user(target_grouplist
, arg2
, gidsetsize
* 4);
7986 #ifdef TARGET_NR_setgroups32
7987 case TARGET_NR_setgroups32
:
7989 int gidsetsize
= arg1
;
7990 uint32_t *target_grouplist
;
7994 grouplist
= alloca(gidsetsize
* sizeof(gid_t
));
7995 target_grouplist
= lock_user(VERIFY_READ
, arg2
, gidsetsize
* 4, 1);
7996 if (!target_grouplist
) {
7997 ret
= -TARGET_EFAULT
;
8000 for(i
= 0;i
< gidsetsize
; i
++)
8001 grouplist
[i
] = tswap32(target_grouplist
[i
]);
8002 unlock_user(target_grouplist
, arg2
, 0);
8003 ret
= get_errno(setgroups(gidsetsize
, grouplist
));
8007 #ifdef TARGET_NR_fchown32
8008 case TARGET_NR_fchown32
:
8009 ret
= get_errno(fchown(arg1
, arg2
, arg3
));
8012 #ifdef TARGET_NR_setresuid32
8013 case TARGET_NR_setresuid32
:
8014 ret
= get_errno(setresuid(arg1
, arg2
, arg3
));
8017 #ifdef TARGET_NR_getresuid32
8018 case TARGET_NR_getresuid32
:
8020 uid_t ruid
, euid
, suid
;
8021 ret
= get_errno(getresuid(&ruid
, &euid
, &suid
));
8022 if (!is_error(ret
)) {
8023 if (put_user_u32(ruid
, arg1
)
8024 || put_user_u32(euid
, arg2
)
8025 || put_user_u32(suid
, arg3
))
8031 #ifdef TARGET_NR_setresgid32
8032 case TARGET_NR_setresgid32
:
8033 ret
= get_errno(setresgid(arg1
, arg2
, arg3
));
8036 #ifdef TARGET_NR_getresgid32
8037 case TARGET_NR_getresgid32
:
8039 gid_t rgid
, egid
, sgid
;
8040 ret
= get_errno(getresgid(&rgid
, &egid
, &sgid
));
8041 if (!is_error(ret
)) {
8042 if (put_user_u32(rgid
, arg1
)
8043 || put_user_u32(egid
, arg2
)
8044 || put_user_u32(sgid
, arg3
))
8050 #ifdef TARGET_NR_chown32
8051 case TARGET_NR_chown32
:
8052 if (!(p
= lock_user_string(arg1
)))
8054 ret
= get_errno(chown(p
, arg2
, arg3
));
8055 unlock_user(p
, arg1
, 0);
8058 #ifdef TARGET_NR_setuid32
8059 case TARGET_NR_setuid32
:
8060 ret
= get_errno(setuid(arg1
));
8063 #ifdef TARGET_NR_setgid32
8064 case TARGET_NR_setgid32
:
8065 ret
= get_errno(setgid(arg1
));
8068 #ifdef TARGET_NR_setfsuid32
8069 case TARGET_NR_setfsuid32
:
8070 ret
= get_errno(setfsuid(arg1
));
8073 #ifdef TARGET_NR_setfsgid32
8074 case TARGET_NR_setfsgid32
:
8075 ret
= get_errno(setfsgid(arg1
));
8079 case TARGET_NR_pivot_root
:
8081 #ifdef TARGET_NR_mincore
8082 case TARGET_NR_mincore
:
8085 ret
= -TARGET_EFAULT
;
8086 if (!(a
= lock_user(VERIFY_READ
, arg1
,arg2
, 0)))
8088 if (!(p
= lock_user_string(arg3
)))
8090 ret
= get_errno(mincore(a
, arg2
, p
));
8091 unlock_user(p
, arg3
, ret
);
8093 unlock_user(a
, arg1
, 0);
8097 #ifdef TARGET_NR_arm_fadvise64_64
8098 case TARGET_NR_arm_fadvise64_64
:
8101 * arm_fadvise64_64 looks like fadvise64_64 but
8102 * with different argument order
8110 #if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
8111 #ifdef TARGET_NR_fadvise64_64
8112 case TARGET_NR_fadvise64_64
:
8114 #ifdef TARGET_NR_fadvise64
8115 case TARGET_NR_fadvise64
:
8119 case 4: arg4
= POSIX_FADV_NOREUSE
+ 1; break; /* make sure it's an invalid value */
8120 case 5: arg4
= POSIX_FADV_NOREUSE
+ 2; break; /* ditto */
8121 case 6: arg4
= POSIX_FADV_DONTNEED
; break;
8122 case 7: arg4
= POSIX_FADV_NOREUSE
; break;
8126 ret
= -posix_fadvise(arg1
, arg2
, arg3
, arg4
);
8129 #ifdef TARGET_NR_madvise
8130 case TARGET_NR_madvise
:
8131 /* A straight passthrough may not be safe because qemu sometimes
8132 turns private file-backed mappings into anonymous mappings.
8133 This will break MADV_DONTNEED.
8134 This is a hint, so ignoring and returning success is ok. */
8138 #if TARGET_ABI_BITS == 32
8139 case TARGET_NR_fcntl64
:
8143 struct target_flock64
*target_fl
;
8145 struct target_eabi_flock64
*target_efl
;
8148 cmd
= target_to_host_fcntl_cmd(arg2
);
8149 if (cmd
== -TARGET_EINVAL
) {
8155 case TARGET_F_GETLK64
:
8157 if (((CPUARMState
*)cpu_env
)->eabi
) {
8158 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8160 fl
.l_type
= tswap16(target_efl
->l_type
);
8161 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8162 fl
.l_start
= tswap64(target_efl
->l_start
);
8163 fl
.l_len
= tswap64(target_efl
->l_len
);
8164 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8165 unlock_user_struct(target_efl
, arg3
, 0);
8169 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8171 fl
.l_type
= tswap16(target_fl
->l_type
);
8172 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8173 fl
.l_start
= tswap64(target_fl
->l_start
);
8174 fl
.l_len
= tswap64(target_fl
->l_len
);
8175 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8176 unlock_user_struct(target_fl
, arg3
, 0);
8178 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8181 if (((CPUARMState
*)cpu_env
)->eabi
) {
8182 if (!lock_user_struct(VERIFY_WRITE
, target_efl
, arg3
, 0))
8184 target_efl
->l_type
= tswap16(fl
.l_type
);
8185 target_efl
->l_whence
= tswap16(fl
.l_whence
);
8186 target_efl
->l_start
= tswap64(fl
.l_start
);
8187 target_efl
->l_len
= tswap64(fl
.l_len
);
8188 target_efl
->l_pid
= tswap32(fl
.l_pid
);
8189 unlock_user_struct(target_efl
, arg3
, 1);
8193 if (!lock_user_struct(VERIFY_WRITE
, target_fl
, arg3
, 0))
8195 target_fl
->l_type
= tswap16(fl
.l_type
);
8196 target_fl
->l_whence
= tswap16(fl
.l_whence
);
8197 target_fl
->l_start
= tswap64(fl
.l_start
);
8198 target_fl
->l_len
= tswap64(fl
.l_len
);
8199 target_fl
->l_pid
= tswap32(fl
.l_pid
);
8200 unlock_user_struct(target_fl
, arg3
, 1);
8205 case TARGET_F_SETLK64
:
8206 case TARGET_F_SETLKW64
:
8208 if (((CPUARMState
*)cpu_env
)->eabi
) {
8209 if (!lock_user_struct(VERIFY_READ
, target_efl
, arg3
, 1))
8211 fl
.l_type
= tswap16(target_efl
->l_type
);
8212 fl
.l_whence
= tswap16(target_efl
->l_whence
);
8213 fl
.l_start
= tswap64(target_efl
->l_start
);
8214 fl
.l_len
= tswap64(target_efl
->l_len
);
8215 fl
.l_pid
= tswap32(target_efl
->l_pid
);
8216 unlock_user_struct(target_efl
, arg3
, 0);
8220 if (!lock_user_struct(VERIFY_READ
, target_fl
, arg3
, 1))
8222 fl
.l_type
= tswap16(target_fl
->l_type
);
8223 fl
.l_whence
= tswap16(target_fl
->l_whence
);
8224 fl
.l_start
= tswap64(target_fl
->l_start
);
8225 fl
.l_len
= tswap64(target_fl
->l_len
);
8226 fl
.l_pid
= tswap32(target_fl
->l_pid
);
8227 unlock_user_struct(target_fl
, arg3
, 0);
8229 ret
= get_errno(fcntl(arg1
, cmd
, &fl
));
8232 ret
= do_fcntl(arg1
, arg2
, arg3
);
8238 #ifdef TARGET_NR_cacheflush
8239 case TARGET_NR_cacheflush
:
8240 /* self-modifying code is handled automatically, so nothing needed */
8244 #ifdef TARGET_NR_security
8245 case TARGET_NR_security
:
8248 #ifdef TARGET_NR_getpagesize
8249 case TARGET_NR_getpagesize
:
8250 ret
= TARGET_PAGE_SIZE
;
8253 case TARGET_NR_gettid
:
8254 ret
= get_errno(gettid());
8256 #ifdef TARGET_NR_readahead
8257 case TARGET_NR_readahead
:
8258 #if TARGET_ABI_BITS == 32
8259 if (regpairs_aligned(cpu_env
)) {
8264 ret
= get_errno(readahead(arg1
, ((off64_t
)arg3
<< 32) | arg2
, arg4
));
8266 ret
= get_errno(readahead(arg1
, arg2
, arg3
));
8271 #ifdef TARGET_NR_setxattr
8272 case TARGET_NR_listxattr
:
8273 case TARGET_NR_llistxattr
:
8277 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8279 ret
= -TARGET_EFAULT
;
8283 p
= lock_user_string(arg1
);
8285 if (num
== TARGET_NR_listxattr
) {
8286 ret
= get_errno(listxattr(p
, b
, arg3
));
8288 ret
= get_errno(llistxattr(p
, b
, arg3
));
8291 ret
= -TARGET_EFAULT
;
8293 unlock_user(p
, arg1
, 0);
8294 unlock_user(b
, arg2
, arg3
);
8297 case TARGET_NR_flistxattr
:
8301 b
= lock_user(VERIFY_WRITE
, arg2
, arg3
, 0);
8303 ret
= -TARGET_EFAULT
;
8307 ret
= get_errno(flistxattr(arg1
, b
, arg3
));
8308 unlock_user(b
, arg2
, arg3
);
8311 case TARGET_NR_setxattr
:
8312 case TARGET_NR_lsetxattr
:
8314 void *p
, *n
, *v
= 0;
8316 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8318 ret
= -TARGET_EFAULT
;
8322 p
= lock_user_string(arg1
);
8323 n
= lock_user_string(arg2
);
8325 if (num
== TARGET_NR_setxattr
) {
8326 ret
= get_errno(setxattr(p
, n
, v
, arg4
, arg5
));
8328 ret
= get_errno(lsetxattr(p
, n
, v
, arg4
, arg5
));
8331 ret
= -TARGET_EFAULT
;
8333 unlock_user(p
, arg1
, 0);
8334 unlock_user(n
, arg2
, 0);
8335 unlock_user(v
, arg3
, 0);
8338 case TARGET_NR_fsetxattr
:
8342 v
= lock_user(VERIFY_READ
, arg3
, arg4
, 1);
8344 ret
= -TARGET_EFAULT
;
8348 n
= lock_user_string(arg2
);
8350 ret
= get_errno(fsetxattr(arg1
, n
, v
, arg4
, arg5
));
8352 ret
= -TARGET_EFAULT
;
8354 unlock_user(n
, arg2
, 0);
8355 unlock_user(v
, arg3
, 0);
8358 case TARGET_NR_getxattr
:
8359 case TARGET_NR_lgetxattr
:
8361 void *p
, *n
, *v
= 0;
8363 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8365 ret
= -TARGET_EFAULT
;
8369 p
= lock_user_string(arg1
);
8370 n
= lock_user_string(arg2
);
8372 if (num
== TARGET_NR_getxattr
) {
8373 ret
= get_errno(getxattr(p
, n
, v
, arg4
));
8375 ret
= get_errno(lgetxattr(p
, n
, v
, arg4
));
8378 ret
= -TARGET_EFAULT
;
8380 unlock_user(p
, arg1
, 0);
8381 unlock_user(n
, arg2
, 0);
8382 unlock_user(v
, arg3
, arg4
);
8385 case TARGET_NR_fgetxattr
:
8389 v
= lock_user(VERIFY_WRITE
, arg3
, arg4
, 0);
8391 ret
= -TARGET_EFAULT
;
8395 n
= lock_user_string(arg2
);
8397 ret
= get_errno(fgetxattr(arg1
, n
, v
, arg4
));
8399 ret
= -TARGET_EFAULT
;
8401 unlock_user(n
, arg2
, 0);
8402 unlock_user(v
, arg3
, arg4
);
8405 case TARGET_NR_removexattr
:
8406 case TARGET_NR_lremovexattr
:
8409 p
= lock_user_string(arg1
);
8410 n
= lock_user_string(arg2
);
8412 if (num
== TARGET_NR_removexattr
) {
8413 ret
= get_errno(removexattr(p
, n
));
8415 ret
= get_errno(lremovexattr(p
, n
));
8418 ret
= -TARGET_EFAULT
;
8420 unlock_user(p
, arg1
, 0);
8421 unlock_user(n
, arg2
, 0);
8424 case TARGET_NR_fremovexattr
:
8427 n
= lock_user_string(arg2
);
8429 ret
= get_errno(fremovexattr(arg1
, n
));
8431 ret
= -TARGET_EFAULT
;
8433 unlock_user(n
, arg2
, 0);
8437 #endif /* CONFIG_ATTR */
8438 #ifdef TARGET_NR_set_thread_area
8439 case TARGET_NR_set_thread_area
:
8440 #if defined(TARGET_MIPS)
8441 ((CPUMIPSState
*) cpu_env
)->tls_value
= arg1
;
8444 #elif defined(TARGET_CRIS)
8446 ret
= -TARGET_EINVAL
;
8448 ((CPUCRISState
*) cpu_env
)->pregs
[PR_PID
] = arg1
;
8452 #elif defined(TARGET_I386) && defined(TARGET_ABI32)
8453 ret
= do_set_thread_area(cpu_env
, arg1
);
8456 goto unimplemented_nowarn
;
8459 #ifdef TARGET_NR_get_thread_area
8460 case TARGET_NR_get_thread_area
:
8461 #if defined(TARGET_I386) && defined(TARGET_ABI32)
8462 ret
= do_get_thread_area(cpu_env
, arg1
);
8464 goto unimplemented_nowarn
;
8467 #ifdef TARGET_NR_getdomainname
8468 case TARGET_NR_getdomainname
:
8469 goto unimplemented_nowarn
;
8472 #ifdef TARGET_NR_clock_gettime
8473 case TARGET_NR_clock_gettime
:
8476 ret
= get_errno(clock_gettime(arg1
, &ts
));
8477 if (!is_error(ret
)) {
8478 host_to_target_timespec(arg2
, &ts
);
8483 #ifdef TARGET_NR_clock_getres
8484 case TARGET_NR_clock_getres
:
8487 ret
= get_errno(clock_getres(arg1
, &ts
));
8488 if (!is_error(ret
)) {
8489 host_to_target_timespec(arg2
, &ts
);
8494 #ifdef TARGET_NR_clock_nanosleep
8495 case TARGET_NR_clock_nanosleep
:
8498 target_to_host_timespec(&ts
, arg3
);
8499 ret
= get_errno(clock_nanosleep(arg1
, arg2
, &ts
, arg4
? &ts
: NULL
));
8501 host_to_target_timespec(arg4
, &ts
);
8506 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
8507 case TARGET_NR_set_tid_address
:
8508 ret
= get_errno(set_tid_address((int *)g2h(arg1
)));
8512 #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
8513 case TARGET_NR_tkill
:
8514 ret
= get_errno(sys_tkill((int)arg1
, target_to_host_signal(arg2
)));
8518 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
8519 case TARGET_NR_tgkill
:
8520 ret
= get_errno(sys_tgkill((int)arg1
, (int)arg2
,
8521 target_to_host_signal(arg3
)));
8525 #ifdef TARGET_NR_set_robust_list
8526 case TARGET_NR_set_robust_list
:
8527 case TARGET_NR_get_robust_list
:
8528 /* The ABI for supporting robust futexes has userspace pass
8529 * the kernel a pointer to a linked list which is updated by
8530 * userspace after the syscall; the list is walked by the kernel
8531 * when the thread exits. Since the linked list in QEMU guest
8532 * memory isn't a valid linked list for the host and we have
8533 * no way to reliably intercept the thread-death event, we can't
8534 * support these. Silently return ENOSYS so that guest userspace
8535 * falls back to a non-robust futex implementation (which should
8536 * be OK except in the corner case of the guest crashing while
8537 * holding a mutex that is shared with another process via
8540 goto unimplemented_nowarn
;
8543 #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
8544 case TARGET_NR_utimensat
:
8546 struct timespec
*tsp
, ts
[2];
8550 target_to_host_timespec(ts
, arg3
);
8551 target_to_host_timespec(ts
+1, arg3
+sizeof(struct target_timespec
));
8555 ret
= get_errno(sys_utimensat(arg1
, NULL
, tsp
, arg4
));
8557 if (!(p
= lock_user_string(arg2
))) {
8558 ret
= -TARGET_EFAULT
;
8561 ret
= get_errno(sys_utimensat(arg1
, path(p
), tsp
, arg4
));
8562 unlock_user(p
, arg2
, 0);
8567 #if defined(CONFIG_USE_NPTL)
8568 case TARGET_NR_futex
:
8569 ret
= do_futex(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
);
8572 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
8573 case TARGET_NR_inotify_init
:
8574 ret
= get_errno(sys_inotify_init());
8577 #ifdef CONFIG_INOTIFY1
8578 #if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
8579 case TARGET_NR_inotify_init1
:
8580 ret
= get_errno(sys_inotify_init1(arg1
));
8584 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
8585 case TARGET_NR_inotify_add_watch
:
8586 p
= lock_user_string(arg2
);
8587 ret
= get_errno(sys_inotify_add_watch(arg1
, path(p
), arg3
));
8588 unlock_user(p
, arg2
, 0);
8591 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
8592 case TARGET_NR_inotify_rm_watch
:
8593 ret
= get_errno(sys_inotify_rm_watch(arg1
, arg2
));
8597 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
8598 case TARGET_NR_mq_open
:
8600 struct mq_attr posix_mq_attr
;
8602 p
= lock_user_string(arg1
- 1);
8604 copy_from_user_mq_attr (&posix_mq_attr
, arg4
);
8605 ret
= get_errno(mq_open(p
, arg2
, arg3
, &posix_mq_attr
));
8606 unlock_user (p
, arg1
, 0);
8610 case TARGET_NR_mq_unlink
:
8611 p
= lock_user_string(arg1
- 1);
8612 ret
= get_errno(mq_unlink(p
));
8613 unlock_user (p
, arg1
, 0);
8616 case TARGET_NR_mq_timedsend
:
8620 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8622 target_to_host_timespec(&ts
, arg5
);
8623 ret
= get_errno(mq_timedsend(arg1
, p
, arg3
, arg4
, &ts
));
8624 host_to_target_timespec(arg5
, &ts
);
8627 ret
= get_errno(mq_send(arg1
, p
, arg3
, arg4
));
8628 unlock_user (p
, arg2
, arg3
);
8632 case TARGET_NR_mq_timedreceive
:
8637 p
= lock_user (VERIFY_READ
, arg2
, arg3
, 1);
8639 target_to_host_timespec(&ts
, arg5
);
8640 ret
= get_errno(mq_timedreceive(arg1
, p
, arg3
, &prio
, &ts
));
8641 host_to_target_timespec(arg5
, &ts
);
8644 ret
= get_errno(mq_receive(arg1
, p
, arg3
, &prio
));
8645 unlock_user (p
, arg2
, arg3
);
8647 put_user_u32(prio
, arg4
);
8651 /* Not implemented for now... */
8652 /* case TARGET_NR_mq_notify: */
8655 case TARGET_NR_mq_getsetattr
:
8657 struct mq_attr posix_mq_attr_in
, posix_mq_attr_out
;
8660 ret
= mq_getattr(arg1
, &posix_mq_attr_out
);
8661 copy_to_user_mq_attr(arg3
, &posix_mq_attr_out
);
8664 copy_from_user_mq_attr(&posix_mq_attr_in
, arg2
);
8665 ret
|= mq_setattr(arg1
, &posix_mq_attr_in
, &posix_mq_attr_out
);
8672 #ifdef CONFIG_SPLICE
8673 #ifdef TARGET_NR_tee
8676 ret
= get_errno(tee(arg1
,arg2
,arg3
,arg4
));
8680 #ifdef TARGET_NR_splice
8681 case TARGET_NR_splice
:
8683 loff_t loff_in
, loff_out
;
8684 loff_t
*ploff_in
= NULL
, *ploff_out
= NULL
;
8686 get_user_u64(loff_in
, arg2
);
8687 ploff_in
= &loff_in
;
8690 get_user_u64(loff_out
, arg2
);
8691 ploff_out
= &loff_out
;
8693 ret
= get_errno(splice(arg1
, ploff_in
, arg3
, ploff_out
, arg5
, arg6
));
8697 #ifdef TARGET_NR_vmsplice
8698 case TARGET_NR_vmsplice
:
8700 struct iovec
*vec
= lock_iovec(VERIFY_READ
, arg2
, arg3
, 1);
8702 ret
= get_errno(vmsplice(arg1
, vec
, arg3
, arg4
));
8703 unlock_iovec(vec
, arg2
, arg3
, 0);
8705 ret
= -host_to_target_errno(errno
);
8710 #endif /* CONFIG_SPLICE */
8711 #ifdef CONFIG_EVENTFD
8712 #if defined(TARGET_NR_eventfd)
8713 case TARGET_NR_eventfd
:
8714 ret
= get_errno(eventfd(arg1
, 0));
8717 #if defined(TARGET_NR_eventfd2)
8718 case TARGET_NR_eventfd2
:
8720 int host_flags
= arg2
& (~(TARGET_O_NONBLOCK
| TARGET_O_CLOEXEC
));
8721 if (arg2
& TARGET_O_NONBLOCK
) {
8722 host_flags
|= O_NONBLOCK
;
8724 if (arg2
& TARGET_O_CLOEXEC
) {
8725 host_flags
|= O_CLOEXEC
;
8727 ret
= get_errno(eventfd(arg1
, host_flags
));
8731 #endif /* CONFIG_EVENTFD */
8732 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
8733 case TARGET_NR_fallocate
:
8734 #if TARGET_ABI_BITS == 32
8735 ret
= get_errno(fallocate(arg1
, arg2
, target_offset64(arg3
, arg4
),
8736 target_offset64(arg5
, arg6
)));
8738 ret
= get_errno(fallocate(arg1
, arg2
, arg3
, arg4
));
8742 #if defined(CONFIG_SYNC_FILE_RANGE)
8743 #if defined(TARGET_NR_sync_file_range)
8744 case TARGET_NR_sync_file_range
:
8745 #if TARGET_ABI_BITS == 32
8746 #if defined(TARGET_MIPS)
8747 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
8748 target_offset64(arg5
, arg6
), arg7
));
8750 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg2
, arg3
),
8751 target_offset64(arg4
, arg5
), arg6
));
8752 #endif /* !TARGET_MIPS */
8754 ret
= get_errno(sync_file_range(arg1
, arg2
, arg3
, arg4
));
8758 #if defined(TARGET_NR_sync_file_range2)
8759 case TARGET_NR_sync_file_range2
:
8760 /* This is like sync_file_range but the arguments are reordered */
8761 #if TARGET_ABI_BITS == 32
8762 ret
= get_errno(sync_file_range(arg1
, target_offset64(arg3
, arg4
),
8763 target_offset64(arg5
, arg6
), arg2
));
8765 ret
= get_errno(sync_file_range(arg1
, arg3
, arg4
, arg2
));
8770 #if defined(CONFIG_EPOLL)
8771 #if defined(TARGET_NR_epoll_create)
8772 case TARGET_NR_epoll_create
:
8773 ret
= get_errno(epoll_create(arg1
));
8776 #if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
8777 case TARGET_NR_epoll_create1
:
8778 ret
= get_errno(epoll_create1(arg1
));
8781 #if defined(TARGET_NR_epoll_ctl)
8782 case TARGET_NR_epoll_ctl
:
8784 struct epoll_event ep
;
8785 struct epoll_event
*epp
= 0;
8787 struct target_epoll_event
*target_ep
;
8788 if (!lock_user_struct(VERIFY_READ
, target_ep
, arg4
, 1)) {
8791 ep
.events
= tswap32(target_ep
->events
);
8792 /* The epoll_data_t union is just opaque data to the kernel,
8793 * so we transfer all 64 bits across and need not worry what
8794 * actual data type it is.
8796 ep
.data
.u64
= tswap64(target_ep
->data
.u64
);
8797 unlock_user_struct(target_ep
, arg4
, 0);
8800 ret
= get_errno(epoll_ctl(arg1
, arg2
, arg3
, epp
));
8805 #if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
8806 #define IMPLEMENT_EPOLL_PWAIT
8808 #if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
8809 #if defined(TARGET_NR_epoll_wait)
8810 case TARGET_NR_epoll_wait
:
8812 #if defined(IMPLEMENT_EPOLL_PWAIT)
8813 case TARGET_NR_epoll_pwait
:
8816 struct target_epoll_event
*target_ep
;
8817 struct epoll_event
*ep
;
8819 int maxevents
= arg3
;
8822 target_ep
= lock_user(VERIFY_WRITE
, arg2
,
8823 maxevents
* sizeof(struct target_epoll_event
), 1);
8828 ep
= alloca(maxevents
* sizeof(struct epoll_event
));
8831 #if defined(IMPLEMENT_EPOLL_PWAIT)
8832 case TARGET_NR_epoll_pwait
:
8834 target_sigset_t
*target_set
;
8835 sigset_t _set
, *set
= &_set
;
8838 target_set
= lock_user(VERIFY_READ
, arg5
,
8839 sizeof(target_sigset_t
), 1);
8841 unlock_user(target_ep
, arg2
, 0);
8844 target_to_host_sigset(set
, target_set
);
8845 unlock_user(target_set
, arg5
, 0);
8850 ret
= get_errno(epoll_pwait(epfd
, ep
, maxevents
, timeout
, set
));
8854 #if defined(TARGET_NR_epoll_wait)
8855 case TARGET_NR_epoll_wait
:
8856 ret
= get_errno(epoll_wait(epfd
, ep
, maxevents
, timeout
));
8860 ret
= -TARGET_ENOSYS
;
8862 if (!is_error(ret
)) {
8864 for (i
= 0; i
< ret
; i
++) {
8865 target_ep
[i
].events
= tswap32(ep
[i
].events
);
8866 target_ep
[i
].data
.u64
= tswap64(ep
[i
].data
.u64
);
8869 unlock_user(target_ep
, arg2
, ret
* sizeof(struct target_epoll_event
));
8874 #ifdef TARGET_NR_prlimit64
8875 case TARGET_NR_prlimit64
:
8877 /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8878 struct target_rlimit64
*target_rnew
, *target_rold
;
8879 struct host_rlimit64 rnew
, rold
, *rnewp
= 0;
8881 if (!lock_user_struct(VERIFY_READ
, target_rnew
, arg3
, 1)) {
8884 rnew
.rlim_cur
= tswap64(target_rnew
->rlim_cur
);
8885 rnew
.rlim_max
= tswap64(target_rnew
->rlim_max
);
8886 unlock_user_struct(target_rnew
, arg3
, 0);
8890 ret
= get_errno(sys_prlimit64(arg1
, arg2
, rnewp
, arg4
? &rold
: 0));
8891 if (!is_error(ret
) && arg4
) {
8892 if (!lock_user_struct(VERIFY_WRITE
, target_rold
, arg4
, 1)) {
8895 target_rold
->rlim_cur
= tswap64(rold
.rlim_cur
);
8896 target_rold
->rlim_max
= tswap64(rold
.rlim_max
);
8897 unlock_user_struct(target_rold
, arg4
, 1);
8902 #ifdef TARGET_NR_gethostname
8903 case TARGET_NR_gethostname
:
8905 char *name
= lock_user(VERIFY_WRITE
, arg1
, arg2
, 0);
8907 ret
= get_errno(gethostname(name
, arg2
));
8908 unlock_user(name
, arg1
, arg2
);
8910 ret
= -TARGET_EFAULT
;
8917 gemu_log("qemu: Unsupported syscall: %d\n", num
);
8918 #if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8919 unimplemented_nowarn
:
8921 ret
= -TARGET_ENOSYS
;
8926 gemu_log(" = " TARGET_ABI_FMT_ld
"\n", ret
);
8929 print_syscall_ret(num
, ret
);
8932 ret
= -TARGET_EFAULT
;